Skip to content

Commit c4c6c02

Browse files
committed
Implementing event callbacks.
1 parent 025671c commit c4c6c02

9 files changed

+248
-9
lines changed

Source/Actor.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,16 @@ Actor::Actor() :
2020
m_Components(nullptr),
2121
m_Nodes(nullptr),
2222
m_Root(nullptr),
23+
m_EventCallbackUserData(nullptr),
24+
m_EventCallback(nullptr),
2325
m_MaxTextureIndex(0),
2426
m_ImageNodeCount(0),
2527
m_SolverNodeCount(0),
2628
m_AnimationsCount(0),
2729
m_ImageNodes(nullptr),
2830
m_Solvers(nullptr),
2931
m_Animations(nullptr)
32+
3033
{
3134

3235
}
@@ -93,6 +96,12 @@ ActorComponent* Actor::component(const std::string& name) const
9396
return nullptr;
9497
}
9598

99+
void Actor::eventCallback(ActorAnimationEvent::Callback callback, void* userdata)
100+
{
101+
m_EventCallbackUserData = userdata;
102+
m_EventCallback = callback;
103+
}
104+
96105
ActorAnimation* Actor::animation(const std::string& name) const
97106
{
98107
for(int i = 0; i < m_AnimationsCount; i++)
@@ -106,6 +115,16 @@ ActorAnimation* Actor::animation(const std::string& name) const
106115
return nullptr;
107116
}
108117

118+
ActorAnimationInstance* Actor::animationInstance(const std::string& name)
119+
{
120+
ActorAnimation* a = animation(name);
121+
if(a == nullptr)
122+
{
123+
return nullptr;
124+
}
125+
return new ActorAnimationInstance(this, a);
126+
}
127+
109128
void Actor::load(unsigned char* bytes, unsigned int length)
110129
{
111130
dispose();

Source/Actor.hpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "BlockReader.hpp"
77
#include "Solver.hpp"
88
#include "Animation/ActorAnimation.hpp"
9+
#include "Animation/ActorAnimationInstance.hpp"
910

1011
namespace nima
1112
{
@@ -25,9 +26,10 @@ namespace nima
2526
ActorIKTarget = 11,
2627
ActorEvent = 12
2728
};
28-
29+
2930
class Actor
3031
{
32+
friend class ActorAnimationInstance;
3133
public:
3234
Actor();
3335
virtual ~Actor();
@@ -45,6 +47,8 @@ namespace nima
4547
ActorComponent** m_Components;
4648
ActorNode** m_Nodes;
4749
ActorNode* m_Root;
50+
void* m_EventCallbackUserData;
51+
ActorAnimationEvent::Callback m_EventCallback;
4852
void readComponentsBlock(BlockReader* block);
4953
void readAnimationsBlock(BlockReader* block);
5054

@@ -70,6 +74,8 @@ namespace nima
7074
ActorComponent* component(unsigned int index) const;
7175
ActorComponent* component(unsigned short index) const;
7276
ActorComponent* component(const std::string& name) const;
77+
78+
void eventCallback(ActorAnimationEvent::Callback callback, void* userdata = nullptr);
7379

7480
template<typename T>
7581
T component(const std::string& name) const
@@ -79,6 +85,7 @@ namespace nima
7985

8086
ActorNode* root() const;
8187
ActorAnimation* animation(const std::string& name) const;
88+
ActorAnimationInstance* animationInstance(const std::string& name);
8289

8390
void copy(const Actor& actor);
8491
const int textureCount() const;

Source/Animation/ActorAnimation.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,11 @@ void ActorAnimation::apply(float time, Actor* actor, float mix)
4242
}
4343
}
4444

45-
void ActorAnimation::triggerEvents(ActorComponent** components, float fromTime, float toTime, std::vector<ActorAnimationEvent>& events)
45+
void ActorAnimation::triggerEvents(Actor* actor, float fromTime, float toTime, std::vector<ActorAnimationEvent>& events)
4646
{
4747
for(auto keyedComponent : m_TriggerComponents)
4848
{
49-
keyedComponent->triggerEvents(components, fromTime, toTime, events);
49+
keyedComponent->triggerEvents(actor, fromTime, toTime, events);
5050
}
5151
}
5252

Source/Animation/ActorAnimation.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
#include <string>
55
#include <vector>
6+
#include <functional>
67
#include "ComponentAnimation.hpp"
78

89
namespace nima
@@ -13,6 +14,7 @@ namespace nima
1314

1415
struct ActorAnimationEvent
1516
{
17+
typedef std::function<void(const ActorAnimationEvent&, void*)> Callback;
1618
ActorEvent* actorEvent;
1719
float keyFrameTime;
1820
float elapsedTime;
@@ -50,7 +52,7 @@ namespace nima
5052

5153
void apply(float time, Actor* actor, float mix);
5254

53-
void triggerEvents(ActorComponent** components, float fromTime, float toTime, std::vector<ActorAnimationEvent>& events);
55+
void triggerEvents(Actor* actor, float fromTime, float toTime, std::vector<ActorAnimationEvent>& events);
5456

5557
};
5658
}
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
#include "ActorAnimationInstance.hpp"
2+
#include "../Actor.hpp"
3+
#include <cmath>
4+
5+
using namespace nima;
6+
7+
ActorAnimationInstance::ActorAnimationInstance(Actor* actor, ActorAnimation* animation) :
8+
m_Actor(actor),
9+
m_Animation(animation),
10+
m_Time(0.0f),
11+
m_Min(0.0f),
12+
m_Max(animation->duration()),
13+
m_Range(animation->duration()),
14+
m_Loop(animation->isLooping()),
15+
m_EventCallbackUserData(nullptr),
16+
m_EventCallback(nullptr)
17+
{
18+
19+
}
20+
21+
ActorAnimationInstance::~ActorAnimationInstance()
22+
{
23+
24+
}
25+
26+
float ActorAnimationInstance::duration() const
27+
{
28+
return m_Range;
29+
}
30+
31+
float ActorAnimationInstance::min() const
32+
{
33+
return m_Min;
34+
}
35+
36+
float ActorAnimationInstance::max() const
37+
{
38+
return m_Max;
39+
}
40+
41+
float ActorAnimationInstance::time() const
42+
{
43+
return m_Time;
44+
}
45+
46+
void ActorAnimationInstance::time(float value)
47+
{
48+
float delta = value - m_Time;
49+
float time = m_Time + std::fmod(delta, m_Range);
50+
51+
if(time < m_Min)
52+
{
53+
if(m_Loop)
54+
{
55+
time = m_Max - (m_Min - time);
56+
}
57+
else
58+
{
59+
time = m_Min;
60+
}
61+
}
62+
else if(time > m_Max)
63+
{
64+
if(m_Loop)
65+
{
66+
time = m_Min + (time - m_Max);
67+
}
68+
else
69+
{
70+
time = m_Max;
71+
}
72+
}
73+
m_Time = time;
74+
}
75+
76+
bool ActorAnimationInstance::isLooping() const
77+
{
78+
return m_Loop;
79+
}
80+
81+
void ActorAnimationInstance::isLooping(bool isIt)
82+
{
83+
m_Loop = isIt;
84+
}
85+
86+
void ActorAnimationInstance::eventCallback(ActorAnimationEvent::Callback callback, void* userdata)
87+
{
88+
m_EventCallbackUserData = userdata;
89+
m_EventCallback = callback;
90+
}
91+
92+
void ActorAnimationInstance::advance(float seconds)
93+
{
94+
float time = m_Time;
95+
time += std::fmod(seconds, m_Range);
96+
if(time < m_Min)
97+
{
98+
if(m_Loop)
99+
{
100+
m_Animation->triggerEvents(m_Actor, time, m_Time, m_Events);
101+
time = m_Max - (m_Min - time);
102+
m_Animation->triggerEvents(m_Actor, time, m_Max, m_Events);
103+
}
104+
else
105+
{
106+
time = m_Min;
107+
if(m_Time != time)
108+
{
109+
m_Animation->triggerEvents(m_Actor, m_Min, m_Time, m_Events);
110+
}
111+
}
112+
}
113+
else if(time > m_Max)
114+
{
115+
if(m_Loop)
116+
{
117+
m_Animation->triggerEvents(m_Actor, time, m_Time, m_Events);
118+
time = m_Min + (time - m_Max);
119+
m_Animation->triggerEvents(m_Actor, m_Min-0.001f, time, m_Events);
120+
}
121+
else
122+
{
123+
time = m_Max;
124+
if(m_Time != time)
125+
{
126+
m_Animation->triggerEvents(m_Actor, m_Time, m_Max, m_Events);
127+
}
128+
}
129+
}
130+
else if(time > m_Time)
131+
{
132+
m_Animation->triggerEvents(m_Actor, m_Time, time, m_Events);
133+
}
134+
else
135+
{
136+
m_Animation->triggerEvents(m_Actor, time, m_Time, m_Events);
137+
}
138+
139+
for(const ActorAnimationEvent& ev : m_Events)
140+
{
141+
if(m_EventCallback != nullptr)
142+
{
143+
m_EventCallback(ev, m_EventCallbackUserData);
144+
}
145+
if(m_Actor->m_EventCallback != nullptr)
146+
{
147+
m_Actor->m_EventCallback(ev, m_Actor->m_EventCallbackUserData);
148+
}
149+
/*if (AnimationEvent != null)
150+
{
151+
AnimationEvent(this, ev);
152+
}
153+
m_Actor.OnAnimationEvent(ev);*/
154+
}
155+
m_Events.clear();
156+
/*for(var i = 0; i < triggeredEvents.length; i++)
157+
{
158+
var event = triggeredEvents[i];
159+
this.dispatch("animationEvent", event);
160+
m_Actor.dispatch("animationEvent", event);
161+
}*/
162+
m_Time = time;
163+
}
164+
165+
void ActorAnimationInstance::apply(float mix)
166+
{
167+
m_Animation->apply(m_Time, m_Actor, mix);
168+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#ifndef _NIMA_ACTORANIMATIONINSTANCE_HPP_
2+
#define _NIMA_ACTORANIMATIONINSTANCE_HPP_
3+
4+
#include <string>
5+
#include <vector>
6+
#include "ActorAnimation.hpp"
7+
8+
namespace nima
9+
{
10+
class ActorAnimationInstance
11+
{
12+
private:
13+
Actor* m_Actor;
14+
ActorAnimation* m_Animation;
15+
float m_Time;
16+
float m_Min;
17+
float m_Max;
18+
float m_Range;
19+
bool m_Loop;
20+
std::vector<ActorAnimationEvent> m_Events;
21+
void* m_EventCallbackUserData;
22+
ActorAnimationEvent::Callback m_EventCallback;
23+
24+
public:
25+
26+
ActorAnimationInstance(Actor* actor, ActorAnimation* animation);
27+
~ActorAnimationInstance();
28+
29+
float duration() const;
30+
float min() const;
31+
float max() const;
32+
float time() const;
33+
void time(float value);
34+
bool isLooping() const;
35+
void isLooping(bool isIt);
36+
37+
void advance(float seconds);
38+
void apply(float mix);
39+
40+
void eventCallback(ActorAnimationEvent::Callback callback, void* userdata = nullptr);
41+
42+
};
43+
}
44+
#endif

Source/Animation/ComponentAnimation.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ void ComponentAnimation::apply(float time, Actor* actor, float mix)
3333
}
3434
}
3535

36-
void ComponentAnimation::triggerEvents(ActorComponent** components, float fromTime, float toTime, std::vector<ActorAnimationEvent>& events)
36+
void ComponentAnimation::triggerEvents(Actor* actor, float fromTime, float toTime, std::vector<ActorAnimationEvent>& events)
3737
{
3838
for(int i = 0; i < m_PropertiesCount; i++)
3939
{
@@ -81,7 +81,7 @@ void ComponentAnimation::triggerEvents(ActorComponent** components, float fromTi
8181
{
8282
if(property.keyFrame(0)->time() == toTime)
8383
{
84-
ActorEvent* actorEvent = reinterpret_cast<ActorEvent*>(components[m_ComponentIndex]);
84+
ActorEvent* actorEvent = reinterpret_cast<ActorEvent*>(actor->component(m_ComponentIndex));
8585
events.emplace_back(ActorAnimationEvent(actorEvent, toTime, 0.0f));
8686
//ActorComponent component = components[keyedComponent.ComponentIndex];
8787
//triggerEvents.Add(new AnimationEventArgs(component.Name, component, property.PropertyType, toTime, 0.0f));
@@ -95,7 +95,7 @@ void ComponentAnimation::triggerEvents(ActorComponent** components, float fromTi
9595

9696
if(frameTime > fromTime)
9797
{
98-
ActorEvent* actorEvent = reinterpret_cast<ActorEvent*>(components[m_ComponentIndex]);
98+
ActorEvent* actorEvent = reinterpret_cast<ActorEvent*>(actor->component(m_ComponentIndex));
9999
events.emplace_back(ActorAnimationEvent(actorEvent, frameTime, toTime-frameTime));
100100

101101
//ActorComponent component = components[keyedComponent.ComponentIndex];

Source/Animation/ComponentAnimation.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ namespace nima
2626

2727
void read(BlockReader* reader, ActorComponent** components);
2828
void apply(float time, Actor* actor, float mix);
29-
void triggerEvents(ActorComponent** components, float fromTime, float toTime, std::vector<ActorAnimationEvent>& events);
29+
void triggerEvents(Actor* actor, float fromTime, float toTime, std::vector<ActorAnimationEvent>& events);
3030

3131
};
3232
}

Source/BlockReader.hpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ namespace nima
1010
class Vec2D;
1111

1212
class BlockReader;
13-
typedef std::shared_ptr<BlockReader> BlockReaderPtr;
1413

1514
class BlockReader : public BinaryReader
1615
{

0 commit comments

Comments
 (0)