1 /// module for animations
2 module ysge.animation;
3 
4 import std.algorithm;
5 import ysge.project;
6 
7 /// structure for animations
8 struct Animation {
9 	RenderInfo[] frames;      /// each frame of the animation
10 	int          updateTicks; /// how long a frame will stay on
11 }
12 
13 /// structure for ongoing animations
14 struct AnimationProcess {
15 	int         animation;
16 	size_t      frame;
17 	RenderInfo* target;
18 }
19 
20 /// used for managing animations
21 class AnimationManager {
22 	Animation[int]     animations;
23 	AnimationProcess[] processes;
24 
25 	/// creates a new animation
26 	void CreateAnimation(int id, RenderInfo[] frames) {
27 		animations[id] = Animation(frames);
28 	}
29 
30 	/// sets a texture to be animated
31 	void StartAnimation(RenderInfo* target, int animation) {
32 		foreach (i, ref process ; processes) {
33 			if (process.target == target) {
34 				processes = processes.remove(i);
35 				break;
36 			}
37 		}
38 	
39 		AnimationProcess process = AnimationProcess(
40 			animation, 0, target
41 		);
42 
43 		*process.target = animations[animation].frames[0];
44 
45 		processes ~= process;
46 	}
47 
48 	/// stops an animation
49 	void StopAnimation(int animation) {
50 		foreach (i, ref process ; processes) {
51 			if (process.animation == animation) {
52 				processes = processes.remove(i);
53 				return;
54 			}
55 		}
56 
57 		throw new ProjectException("Animation already stopped");
58 	}
59 
60 	/// checks if an animation is running
61 	bool IsAnimationRunning(int animation) {
62 		foreach (ref process ; processes) {
63 			if (process.animation == animation) {
64 				return true;
65 			}
66 		}
67 
68 		return false;
69 	}
70 
71 	AnimationProcess GetProcess(int animation) {
72 		foreach (ref process ; processes) {
73 			if (process.animation == animation) {
74 				return process;
75 			}
76 		}
77 
78 		throw new ProjectException("Could not find animation process");
79 	}
80 
81 	void Update(Project project, Scene scene) {
82 		foreach (ref process ; processes) {
83 			auto animationData = animations[process.animation];
84 
85 			if (project.frames % animationData.updateTicks == 0) {
86 				process.frame = (process.frame + 1) % animationData.frames.length;
87 
88 				*process.target = animationData.frames[process.frame];
89 			}
90 		}
91 	}
92 }