Skip to content

Commit

Permalink
version bump: 0.8.6; updated timelines to be unmanaged and burst comp…
Browse files Browse the repository at this point in the history
…atible;
  • Loading branch information
dyonng committed Mar 6, 2023
1 parent b512257 commit 1e96e3f
Show file tree
Hide file tree
Showing 12 changed files with 191 additions and 59 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog

## [0.8.6] 2023.03.06

### Changed
- Timelines are now unmanaged and burst compatible.

## [0.8.5] 2023.03.04

### Added
Expand Down
20 changes: 11 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,13 +119,15 @@ Now uses Entities Graphics library from Unity.

## Installation

Entity Tween is a Unity package. You can [install it from the git URL](https://docs.unity3d.com/2020.1/Documentation/Manual/upm-ui-giturl.html) in Unity package manager.
Entity Tween is a Unity package. You can [install it from the git URL](https://docs.unity3d.com/2022.1/Documentation/Manual/upm-ui-giturl.html) in Unity package manager.

Or, you can edit `Packages/manifest.json` manually, adding git URL as a dependency:

```json
"dependencies": {
"com.dyonng.dotstween": "https://github.com/dyonng/dots-tween.git"
{
"dependencies": {
"com.dyonng.dotstween": "https://github.com/dyonng/dots-tween.git"
}
}
```

Expand Down Expand Up @@ -188,12 +190,12 @@ Tweens with infinite LoopCounts are not supported within a timeline.
```csharp
var duration = 1.5f;

Tween.Timeline.Create()
.Append(obj, new TweenScaleCommand(1f, 2.2f, duration))
.Insert(2f, obj, new TweenTranslationCommand(float3.zero, new float3(1f, 2f, 3f), duration))
.SetStartDelay(0.5f)
.AddOnComplete(new ComponentOperations { Add = ComponentType.ReadOnly<ExampleTag>() })
.Play(ref entityCommandBuffer);
Tween.Timeline.Create(out var timeline);
timeline.Append(obj, new TweenScaleCommand(1f, 2.2f, duration))
timeline.Insert(2f, obj, new TweenTranslationCommand(float3.zero, new float3(1f, 2f, 3f), duration))
timeline.SetStartDelay(0.5f)
timeline.AddOnComplete(new ComponentOperations { Add = ComponentType.ReadOnly<ExampleTag>() })
timeline.Play(ref entityCommandBuffer);
```

### Check if the entity is tweening
Expand Down
4 changes: 2 additions & 2 deletions Runtime/Static/Tween.Timeline.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ public static partial class Tween
[BurstCompile]
public static class Timeline
{
[BurstDiscard]
public static TimelineComponent Create() => new(0f);
[BurstCompile]
public static void Create(out TimelineComponent timelineComponent) => timelineComponent = new TimelineComponent(0f);

[BurstCompile]
public static void Pause(ref EntityManager entityManager, int timelinePlaybackId)
Expand Down
63 changes: 48 additions & 15 deletions Runtime/Timelines/Components/TimelineComponent.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using DotsTween.Tweens;
using System.Runtime.InteropServices;
using DotsTween.Tweens;
using Unity.Burst;
using Unity.Collections;
using Unity.Collections.LowLevel.Unsafe;
Expand All @@ -11,22 +12,23 @@ namespace DotsTween.Timelines
[BurstCompile]
public struct TimelineComponent : IComponentData, INativeDisposable
{
internal int PlaybackId { get; private set; }
internal float Duration { get; private set; }
internal float StartDelay { get; private set; }
internal float LoopDelay { get; private set; }
internal int LoopCount { get; set; }
internal int PlaybackId;
internal float Duration;
internal float StartDelay;
internal float LoopDelay;
internal int LoopCount;

internal NativeList<TimelineComponentOperationTuple> OnStart;
internal NativeList<TimelineComponentOperationTuple> OnComplete;
internal NativeList<int> ActiveElementIds;
internal NativeList<ComponentType> TimelineElementTypes;
internal UnsafeAppendBuffer TimelineElements;
private NativeHashSet<int> ActiveElementIds;
private NativeList<ComponentType> TimelineElementTypes;
private UnsafeAppendBuffer TimelineElements;

internal float CurrentTime;
internal bool IsPlaying;
[MarshalAs(UnmanagedType.U1)] internal bool IsPlaying;

public float DurationWithLoopDelay => Duration + LoopDelay;
public int Size => TimelineElements.Length;

internal TimelineComponent(float startDelay = 0f)
{
Expand All @@ -40,7 +42,7 @@ internal TimelineComponent(float startDelay = 0f)

OnStart = new NativeList<TimelineComponentOperationTuple>(Allocator.Persistent);
OnComplete = new NativeList<TimelineComponentOperationTuple>(Allocator.Persistent);
ActiveElementIds = new NativeList<int>(Allocator.Persistent);
ActiveElementIds = new NativeHashSet<int>(1, Allocator.Persistent);
TimelineElementTypes = new NativeList<ComponentType>(Allocator.Persistent);
TimelineElements = new UnsafeAppendBuffer(1, 4, Allocator.Persistent);
}
Expand All @@ -59,7 +61,7 @@ public void Insert<T>(float atPosition, in Entity target, in T command) where T

float totalDuration = tweenParams.Duration * (tweenParams.LoopCount + 1); // +1 for first non-loop playback
tweenParams.StartDelay = 0;
tweenParams.SetTimelinePositions(atPosition, totalDuration);
tweenParams.SetTimelinePositions(atPosition, atPosition + totalDuration);

if (tweenParams.TimelineEndPosition > Duration)
{
Expand Down Expand Up @@ -183,6 +185,26 @@ public int Play(EntityManager entityManager, ref EntityCommandBuffer entityComma
return PlaybackId;
}

[BurstCompile]
public int Play(ref EntityCommandBuffer.ParallelWriter parallelWriter, in int sortKey)
{
var e = parallelWriter.CreateEntity(sortKey);

SetupPlaybackId(ref e, sortKey);
parallelWriter.AddComponent(sortKey, e, this);
return PlaybackId;
}

[BurstCompile]
public int Play(EntityManager entityManager, ref EntityCommandBuffer.ParallelWriter parallelWriter, in int sortKey)
{
var e = entityManager.CreateEntity();

SetupPlaybackId(ref e, sortKey);
parallelWriter.AddComponent(sortKey, e, this);
return PlaybackId;
}

[BurstCompile]
public void Dispose()
{
Expand All @@ -206,20 +228,31 @@ public JobHandle Dispose(JobHandle inputDeps)
}

[BurstCompile]
private void SetupPlaybackId(ref Entity e, in int extraHash)
internal void SetupPlaybackId(ref Entity e, in int extraHash)
{
unchecked
{
int hashCode = TimelineElements.GetHashCode();
int hashCode = extraHash.GetHashCode();
hashCode = (hashCode * 421) ^ Duration.GetHashCode();
hashCode = (hashCode * 421) ^ LoopCount.GetHashCode();
hashCode = (hashCode * 421) ^ extraHash.GetHashCode();
hashCode = (hashCode * 421) ^ DurationWithLoopDelay.GetHashCode();
hashCode = (hashCode * 421) ^ StartDelay.GetHashCode();
hashCode = (hashCode * 421) ^ e.Index.GetHashCode();
hashCode = (hashCode * 421) ^ e.Version.GetHashCode();

foreach (var type in TimelineElementTypes)
{
hashCode = (hashCode * 421) ^ type.GetHashCode();
}

PlaybackId = hashCode;
}
}

internal void AddTimelineElementIdToActive(int timelineElementId) => ActiveElementIds.Add(timelineElementId);
internal void RemoveTimelineElementIdFromActive(int timelineElementId) => ActiveElementIds.Remove(timelineElementId);
internal bool IsTimelineElementActive(int timelineElementId) => ActiveElementIds.Contains(timelineElementId);
internal UnsafeAppendBuffer.Reader GetTimelineReader() => TimelineElements.AsReader();
internal ComponentType GetTimelineElementType(int index) => TimelineElementTypes[index];
}
}
18 changes: 9 additions & 9 deletions Runtime/Timelines/Systems/TimelineControlSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,14 +63,14 @@ private void PauseTimeline(ref EntityCommandBuffer ecb, Entity timelineEntity, r
{
ecb.AddComponent<TimelinePausedTag>(timelineEntity);

var bufferReader = timeline.TimelineElements.AsReader();
var bufferReader = timeline.GetTimelineReader();
var index = 0;

while (!bufferReader.EndOfBuffer && index < timeline.TimelineElementTypes.Length)
while (!bufferReader.EndOfBuffer && index < timeline.Size)
{
var timelineElement = TimelineSystemCommandTypeHelper.DereferenceNextTimelineElement(timeline.TimelineElementTypes[index], ref bufferReader);
var timelineElement = TimelineSystemCommandTypeHelper.DereferenceNextTimelineElement(timeline.GetTimelineElementType(index), ref bufferReader);
++index;
if (timeline.ActiveElementIds.Contains(timelineElement.GetId()))
if (timeline.IsTimelineElementActive(timelineElement.GetId()))
{
Tween.Controls.Pause(ref ecb, timelineElement.GetTargetEntity());
}
Expand All @@ -82,14 +82,14 @@ private void ResumeTimeline(ref EntityCommandBuffer ecb, Entity timelineEntity,
{
ecb.RemoveComponent<TimelinePausedTag>(timelineEntity);

var bufferReader = timeline.TimelineElements.AsReader();
var bufferReader = timeline.GetTimelineReader();
var index = 0;
while (!bufferReader.EndOfBuffer && index < timeline.TimelineElementTypes.Length)

while (!bufferReader.EndOfBuffer && index < timeline.Size)
{
var timelineElement = TimelineSystemCommandTypeHelper.DereferenceNextTimelineElement(timeline.TimelineElementTypes[index], ref bufferReader);
var timelineElement = TimelineSystemCommandTypeHelper.DereferenceNextTimelineElement(timeline.GetTimelineElementType(index), ref bufferReader);
++index;
if (timeline.ActiveElementIds.Contains(timelineElement.GetId()))
if (timeline.IsTimelineElementActive(timelineElement.GetId()))
{
Tween.Controls.Resume(ref ecb, timelineElement.GetTargetEntity());
}
Expand Down
9 changes: 4 additions & 5 deletions Runtime/Timelines/Systems/TimelineDestroySystem.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using Unity.Burst;
using Unity.Collections;
using Unity.Entities;

namespace DotsTween.Timelines.Systems
Expand All @@ -22,13 +21,13 @@ protected override void OnUpdate()

foreach (var (timelineRef, destroyTag, entity) in SystemAPI.Query<RefRW<TimelineComponent>, TimelineDestroyTag>().WithEntityAccess())
{
var bufferReader = timelineRef.ValueRO.TimelineElements.AsReader();
var bufferReader = timelineRef.ValueRW.GetTimelineReader();
var index = 0;

while (!bufferReader.EndOfBuffer && index < timelineRef.ValueRO.TimelineElementTypes.Length)
while (!bufferReader.EndOfBuffer && index < timelineRef.ValueRO.Size)
{
var timelineElement = TimelineSystemCommandTypeHelper.DereferenceNextTimelineElement(timelineRef.ValueRO.TimelineElementTypes[index], ref bufferReader);
if (timelineRef.ValueRO.ActiveElementIds.Contains(timelineElement.GetId()))
var timelineElement = TimelineSystemCommandTypeHelper.DereferenceNextTimelineElement(timelineRef.ValueRO.GetTimelineElementType(index), ref bufferReader);
if (timelineRef.ValueRO.IsTimelineElementActive(timelineElement.GetId()))
{
Tween.Controls.Stop(ref ecb, timelineElement.GetTargetEntity());
}
Expand Down
27 changes: 15 additions & 12 deletions Runtime/Timelines/Systems/TimelinePlaybackSystem.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using DotsTween.Tweens;
using Unity.Burst;
using Unity.Burst;
using Unity.Collections;
using Unity.Entities;

Expand Down Expand Up @@ -32,13 +31,14 @@ protected override void OnUpdate()
PerformComponentOperations(ref ecb, ref timeline.ValueRW.OnStart);
}

var bufferReader = timeline.ValueRW.TimelineElements.AsReader();
var bufferReader = timeline.ValueRW.GetTimelineReader();
var index = 0;

while (!bufferReader.EndOfBuffer && index < timeline.ValueRO.TimelineElementTypes.Length)
while (!bufferReader.EndOfBuffer && index < timeline.ValueRO.Size)
{
var timelineElement = TimelineSystemCommandTypeHelper.DereferenceNextTimelineElement(timeline.ValueRO.TimelineElementTypes[index], ref bufferReader);
TryToStartPlayingTimelineElement(ref timelineElement, ref timeline.ValueRW, ref ecb);
var componentType = timeline.ValueRO.GetTimelineElementType(index);
var timelineElement = TimelineSystemCommandTypeHelper.DereferenceNextTimelineElement(componentType, ref bufferReader);
TryToStartPlayingTimelineElement(componentType, ref timelineElement, ref timeline.ValueRW, ref ecb);
TryToRemoveTimelineElementIdFromActiveList(ref timelineElement, ref timeline.ValueRW);
++index;
}
Expand Down Expand Up @@ -77,21 +77,24 @@ private void TryToDestroyTimeline(ref TimelineComponent timeline, Entity timelin
}

[BurstCompile]
private void TryToStartPlayingTimelineElement(ref ITimelineElement timelineElement, ref TimelineComponent timeline, ref EntityCommandBuffer ecb)
private void TryToStartPlayingTimelineElement(in ComponentType componentType, ref ITimelineElement timelineElement, ref TimelineComponent timeline, ref EntityCommandBuffer ecb)
{
if (!(timelineElement.GetStartTime() <= timeline.CurrentTime) || timeline.ActiveElementIds.Contains(timelineElement.GetId())) return;
var pastStartTime = timelineElement.GetStartTime() <= timeline.CurrentTime;
var alreadyPlaying = timeline.IsTimelineElementActive(timelineElement.GetId());
var hasAlreadyPlayed = timelineElement.GetEndTime() <= timeline.CurrentTime;

timeline.ActiveElementIds.Add(timelineElement.GetId());
var command = timelineElement.GetCommand();
ecb.AddComponent(timelineElement.GetTargetEntity(), command);
if (!pastStartTime || alreadyPlaying || hasAlreadyPlayed) return;

timeline.AddTimelineElementIdToActive(timelineElement.GetId());
TimelineSystemCommandTypeHelper.Add(ref ecb, componentType, ref timelineElement);
}

[BurstCompile]
private void TryToRemoveTimelineElementIdFromActiveList(ref ITimelineElement timelineElement, ref TimelineComponent timeline)
{
if (timeline.CurrentTime >= timelineElement.GetEndTime())
{
timeline.ActiveElementIds.RemoveAt(timeline.ActiveElementIds.IndexOf(timelineElement.GetId()));
timeline.RemoveTimelineElementIdFromActive(timelineElement.GetId());
}
}
}
Expand Down
Loading

0 comments on commit 1e96e3f

Please sign in to comment.