Skip to content

Commit 116741b

Browse files
committed
[Animation] Optimize Animator
1 parent 0c44941 commit 116741b

File tree

4 files changed

+45
-47
lines changed

4 files changed

+45
-47
lines changed

src/Aardvark.UI.Primitives/Animation/Animator/AnimatorApp.fs

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -68,28 +68,29 @@ module Animator =
6868
let inline untyped (animation : #IAnimation<'Model>) =
6969
animation :> IAnimation<'Model>
7070

71-
let tick (lens : Lens<'Model, Animator<'Model>>) (time : GlobalTime) (model : 'Model) =
72-
let getSlots model = (Optic.get lens model).Slots
71+
let inline getSlots (lens : Lens<'Model, Animator<'Model>>) (model : 'Model) =
72+
HashMap.toValueSeq (Optic.get lens model).Slots
7373

74+
let tick (lens : Lens<'Model, Animator<'Model>>) (time : GlobalTime) (model : 'Model) =
7475
// Set the current tick
75-
let animator = { Optic.get lens model with CurrentTick = ValueSome time }
76+
let animator = { Optic.get lens model with CurrentTick = time }
7677
let mutable model = model |> Optic.set lens animator
7778

7879
// Process pending actions
79-
for _, s in getSlots model do
80+
for s in getSlots lens model do
8081
model <- s.Commit(model, time)
8182

8283
// Update all running animations by generating and enqueuing Update actions
83-
for _, s in getSlots model do
84+
for s in getSlots lens model do
8485
s.Update time
8586

8687
// Process Update actions
87-
for _, s in getSlots model do
88+
for s in getSlots lens model do
8889
model <- s.Commit(model, time)
8990

9091
// Reset current tick
9192
model |> Optic.map lens (fun animator ->
92-
{ animator with CurrentTick = ValueNone }
93+
{ animator with CurrentTick = GlobalTime.infinite }
9394
)
9495

9596
let set (lens : Lens<'Model, Animator<'Model>>)
@@ -99,11 +100,11 @@ module Animator =
99100

100101
let animator = model |> Optic.get lens
101102

102-
match animator.Slots |> HashMap.tryFind name with
103-
| Some slot ->
103+
match animator.Slots |> HashMap.tryFindV name with
104+
| ValueSome slot ->
104105
slot.Set(animation)
105106
slot.Perform(action)
106-
slot.Commit(model, &animator.CurrentTick)
107+
slot.Commit(model, animator.CurrentTick)
107108

108109
| _ ->
109110
let slot = AnimatorSlot(name, animation.Create name)
@@ -114,7 +115,7 @@ module Animator =
114115
)
115116

116117
slot.Perform(action)
117-
slot.Commit(model, &animator.CurrentTick)
118+
slot.Commit(model, animator.CurrentTick)
118119

119120
let enqueue (lens : Lens<'Model, Animator<'Model>>)
120121
(name : Symbol) (animation : 'Model -> IAnimation<'Model>)
@@ -123,10 +124,10 @@ module Animator =
123124

124125
let animator = model |> Optic.get lens
125126

126-
match animator.Slots |> HashMap.tryFind name with
127-
| Some slot ->
127+
match animator.Slots |> HashMap.tryFindV name with
128+
| ValueSome slot ->
128129
slot.Enqueue(animation, action)
129-
slot.Commit(model, &animator.CurrentTick)
130+
slot.Commit(model, animator.CurrentTick)
130131

131132
| _ ->
132133
let slot = AnimatorSlot(name, (animation model).Create name)
@@ -137,7 +138,7 @@ module Animator =
137138
)
138139

139140
slot.Perform(action)
140-
slot.Commit(model, &animator.CurrentTick)
141+
slot.Commit(model, animator.CurrentTick)
141142

142143
let remove (lens : Lens<'Model, Animator<'Model>>) (name : Symbol) (model : 'Model) =
143144
model |> Optic.map lens (fun animator ->
@@ -147,24 +148,24 @@ module Animator =
147148
let perform (lens : Lens<'Model, Animator<'Model>>) (name : Symbol) (action : IAnimationInstance<'Model> -> unit) (model : 'Model) =
148149
let animator = model |> Optic.get lens
149150

150-
match animator.Slots |> HashMap.tryFind name with
151-
| Some slot ->
151+
match animator.Slots |> HashMap.tryFindV name with
152+
| ValueSome slot ->
152153
slot.Perform(action)
153-
slot.Commit(model, &animator.CurrentTick)
154+
slot.Commit(model, animator.CurrentTick)
154155

155156
| _ ->
156157
model
157158

158159
let iterate (lens : Lens<'Model, Animator<'Model>>) (action : IAnimationInstance<'Model> -> unit) (model : 'Model) =
159160
let animator = model |> Optic.get lens
160161

161-
for _, s in animator.Slots do
162+
for s in getSlots lens model do
162163
s.Perform(action)
163164

164165
let mutable model = model
165166

166-
for _, s in animator.Slots do
167-
model <- s.Commit(model, &animator.CurrentTick)
167+
for s in getSlots lens model do
168+
model <- s.Commit(model, animator.CurrentTick)
168169

169170
model
170171

@@ -374,8 +375,8 @@ module Animator =
374375
lens |> Lenses.set
375376
{
376377
Slots = HashMap.empty
377-
TickRate = 60
378-
CurrentTick = ValueNone
378+
TickRate = 30
379+
CurrentTick = GlobalTime.infinite
379380
}
380381

381382
/// Thread pool that generates real-time tick messages at a fixed rate.

src/Aardvark.UI.Primitives/Animation/Animator/AnimatorModel.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ type Animator<'Model> =
77
{
88
Slots : HashMap<Symbol, AnimatorSlot<'Model>>
99
TickRate : int
10-
CurrentTick : GlobalTime voption
10+
CurrentTick : GlobalTime
1111
}
1212

1313
[<RequireQualifiedAccess>]

src/Aardvark.UI.Primitives/Animation/Animator/AnimatorSlot.fs

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -48,26 +48,23 @@ type AnimatorSlot<'Model>(name : Symbol, instance : IAnimationInstance<'Model>)
4848

4949
/// Commits the current animation instance and prepares the next in the queue if required.
5050
member internal x.Commit(model : 'Model, tick : GlobalTime) =
51-
let model = current.Commit(model, tick)
52-
53-
if current.IsFinished then
54-
if queue.Count > 0 then
55-
let delayed = queue.Dequeue()
56-
let animation = delayed.Animation model
57-
current <- animation.Create(name)
58-
x.Perform(delayed.Action)
59-
x.Commit(model, tick)
51+
if tick.IsFinite then
52+
let model = current.Commit(model, tick)
53+
54+
if current.IsFinished then
55+
if queue.Count > 0 then
56+
let delayed = queue.Dequeue()
57+
let animation = delayed.Animation model
58+
current <- animation.Create(name)
59+
x.Perform(delayed.Action)
60+
x.Commit(model, tick)
61+
else
62+
model
6063
else
6164
model
6265
else
6366
model
6467

65-
/// Commits the current animation instance and prepares the next in the queue if required.
66-
member internal x.Commit(model : 'Model, tick : ValueOption<GlobalTime> inref) =
67-
match tick with
68-
| ValueSome t -> x.Commit(model, t)
69-
| _ -> model
70-
7168
/// Creates an instance of the given animation and sets it as current.
7269
/// Pending instances are removed.
7370
member internal x.Set(animation : IAnimation<'Model>) =

src/Aardvark.UI.Primitives/Animation/Animator/Querying.fs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,15 @@ module AnimatorQuerying =
3434
/// The name can be a string or Symbol. Returns None if the
3535
/// slot does not exist.
3636
let inline tryGetUntyped (name : ^Name) (model : 'Model) =
37-
model |> tryGetSlot name |> Option.map (fun s -> s.Current)
37+
model |> tryGetSlot name |> Option.map _.Current
3838

3939
/// <summary>
4040
/// Gets the current (untyped) animation instance in the slot with the given name.
4141
/// The name can be a string or Symbol.
4242
/// </summary>
4343
/// <exception cref="KeyNotFoundException">Thrown if the slot does not exist.</exception>
4444
let inline getUntyped (name : ^Name) (model : 'Model) =
45-
model |> getSlot name |> fun s -> s.Current
45+
model |> getSlot name |> _.Current
4646

4747
/// Tries to get the current animation instance in the slot with the given name.
4848
/// The name can be a string or Symbol. Returns None if
@@ -70,32 +70,32 @@ module AnimatorQuerying =
7070
/// Tries to get the state of the current animation instance in the slot with the given name.
7171
/// The name can be a string or Symbol. Returns None if the slot does not exist.
7272
let inline tryGetState (name : ^Name) (model : 'Model) =
73-
model |> tryGetUntyped name |> Option.map (fun a -> a.State)
73+
model |> tryGetUntyped name |> Option.map _.State
7474

7575
/// <summary>
7676
/// Gets the state of the current animation instance in the slot with the given name.
7777
/// The name can be a string or Symbol.
7878
/// </summary>
7979
/// <exception cref="KeyNotFoundException">Thrown if the slot does not exist.</exception>
8080
let inline getState (name : ^Name) (model : 'Model) =
81-
model |> getUntyped name |> fun a -> a.State
81+
model |> getUntyped name |> _.State
8282

8383
/// Returns whether the current animation instance in the slot with the given name is running.
8484
/// The name can be a string or Symbol. Returns false if the slot does not exist.
8585
let inline isRunning (name : ^Name) (model : 'Model) =
86-
model |> tryGetUntyped name |> Option.map (fun a -> a.IsRunning) |> Option.defaultValue false
86+
model |> tryGetUntyped name |> Option.map _.IsRunning |> Option.defaultValue false
8787

8888
/// Returns whether the current animation instance in the slot with the given name is stopped.
8989
/// The name can be a string or Symbol. Returns true if the slot does not exist.
9090
let inline isStopped (name : ^Name) (model : 'Model) =
91-
model |> tryGetUntyped name |> Option.map (fun a -> a.IsStopped) |> Option.defaultValue true
91+
model |> tryGetUntyped name |> Option.map _.IsStopped |> Option.defaultValue true
9292

9393
/// Returns whether the current animation instance in the slot with the given name is finished.
9494
/// The name can be a string or Symbol. Returns true if the slot does not exist.
9595
let inline isFinished (name : ^Name) (model : 'Model) =
96-
model |> tryGetUntyped name |> Option.map (fun a -> a.IsFinished) |> Option.defaultValue true
96+
model |> tryGetUntyped name |> Option.map _.IsFinished |> Option.defaultValue true
9797

9898
/// Returns whether the current animation instance in the slot with the given name is paused.
9999
/// The name can be a string or Symbol. Returns false if the slot does not exist.
100100
let inline isPaused (name : ^Name) (model : 'Model) =
101-
model |> tryGetUntyped name |> Option.map (fun a -> a.IsPaused) |> Option.defaultValue false
101+
model |> tryGetUntyped name |> Option.map _.IsPaused |> Option.defaultValue false

0 commit comments

Comments
 (0)