2
* This file is part of the dis-Emi-A HaXe Library. Copyright (c) edA-qa mort-ora-y
3
* For full copyright and license information please refer to doc/license.txt.
9
//these classes as the target specific implementations
10
typedef BackingEventDispatcher = flash.events.EventDispatcher;
14
* A generic driver for a game which handles game events as well
17
* A class should derive from this and override the _stepTime function
18
* to hook into the basic logic.
20
* NOTE: The standard Animation framework is used for timing, this allows
21
* more code sharing and proper placement in a display list.
23
class BaseGameDriver<GameObjectType : GameObject> implements ui.Animation,
24
implements ui.AnimationMaster, implements TimerDispatcher
26
/*hidden*/ var __events : BackingEventDispatcher;
28
//this is heavily influence by the overall framerate, which has been pushed up tp 50
29
//to get a better timing...
30
/*hidden*/ private var __preferredInterval : Int;
31
//the ratio between real time and game time
32
/*hidden*/ private var __realToGameRatio : Float;
34
public function new( ?interval : Null<Int>, ?ratio : Null<Float> )
36
MixinAnimationMaster(true);
38
__preferredInterval = (interval == null) ? 50 : interval;
39
__realToGameRatio = (ratio == null) ? 1.0 : ratio;
41
__events = new BackingEventDispatcher();
44
__timerRunning = false;
46
__postEvents = new Array<BaseEvent>();
48
gameObjects = new Array<GameObjectType>();
52
* @param weak [in] specifies a weak/non-weak reference. By default everything is
53
* weak so that when children are removed from the display they will stop being
56
/*final*/ public function addEventListener( evt : String, listener : Dynamic -> Void, ?priority : Int,
59
if( priority == null )
61
__events.addEventListener( evt, listener, false, priority, weak );
64
/*final*/ public function removeEventListener( evt : String, listener : Dynamic -> Void )
66
__events.removeEventListener( evt, listener, false );
70
* Our events will be posted during the timer stepping, this avoids a bit of overhead
71
* using the asyncEvent.post and it can better time what is going on. Even if the
72
* game is paused (timer not running) these events will be posted!
74
/*hidden*/ var __postEvents : Array<BaseEvent>;
75
/*final*/ public function postEvent( evt : BaseEvent )
77
Assert.is( evt, BaseEvent );
79
//trace( "POST: " + evt.type );
80
//okay, if we aren't started then revert to AsyncEvent (so that events are always dispatched)
82
AsyncEvent.post( __events, evt );
84
__postEvents.push( evt );
88
* Unlike postEvent this indicates the event is part of the running game and should not
89
* be always dispatched -- if the timer is not running it will not be posted.
91
/*final*/ public function queueEvent( evt : BaseEvent )
93
__postEvents.push( evt );
96
/*hidden*/ function __dispatchPostEvents( )
98
while( __postEvents.length > 0 )
100
var p = __postEvents.`shift'();
101
AsyncEvent.dispatch( __events, p );
106
* This can be used by callers who are sure they aren't within the game timer step but
107
* suspect events may have been posted that need dispatching. It is to be used only
108
* in special cases where a visual synchronization needs to be forced. Alternate methods
109
* are typically preferred.
111
/*final*/ public function forceDispatchNow()
113
__dispatchPostEvents();
117
* Immediately dispatches an event. This happens even if the timer is not running.
119
/*final*/ public function dispatchEvent( evt : BaseEvent )
121
//trace( "dispatch: " + evt );
122
Assert.is( evt, BaseEvent );
123
AsyncEvent.dispatch( __events, evt );
127
/////////////////////////////////////////////////////////////////////////////////
131
* The use of the Flash timer (as opposed to haxe ) allows us to call updateAfterEvent, though
132
* in practive this is no more effective than increasing the frameRate of the application.
134
/*hidden*/ private var __timerRunning : Bool;
135
/*hidden*/ private var __lastTime : Float;
137
/*final*/ public function startTimer()
145
__lastTime = flash.Lib.getTimer();
150
ui.AnimationManager.s_addListener( this, __preferredInterval );
151
__timerRunning = true;
155
public var elapsedTotal : Float;
156
public var elapsedSteps : Int;
157
public var procTotal : Float;
159
/*final*/ public function animate( elapsed : Float ) : Bool
161
__lastTime = flash.Lib.getTimer();
164
elapsedTotal += elapsed;
170
var gameTime = elapsed * __realToGameRatio;
172
for( go in gameObjects )
173
go.stepTime( gameTime );
175
_stepTime( gameTime );
176
__animationMasterStep( gameTime ); //NOTE: animations in this holder step in GameTime, not real time
179
//always process these, even when halted, this allows debug mode to work...
180
__dispatchPostEvents();
183
var newTime = flash.Lib.getTimer();
184
procTotal += (newTime - __lastTime) / 1000.0;
191
* This function must be overriden by a derived class. It is the main hook
192
* into the GameDriver, it is called each interval with the actual time that
195
/*abstract*/ function _stepTime( elapsed : Float )
197
Assert.pureVirtual();
200
/*final*/ public function stopTimer()
202
ui.AnimationManager.s_removeListener( this );
203
__timerRunning = false;
205
//ensure we have no pending post events
206
__dispatchPostEvents();
209
/*final*/ public function pause( )
219
* Discards timer events. This is meant to be used temporarily, such as during
220
* a popup menu when you don't really wish to alter the status of the timer, but
221
* wish nonetheless for nothing to happen temporarily.
223
/*final*/ public function haltPause()
225
__halted = !__halted;
228
//////////////////////////////////////////////////////////////////////////////////////////////////////////
231
/*protected*/ var gameObjects : Array<GameObjectType>;
232
public function addGameObject( go : GameObjectType )
234
gameObjects.push( go );
235
postEvent( ObjectEvent.newRemoved( go ) );
238
public function removeGameObject( go : GameObjectType )
240
gameObjects.remove( go );
241
postEvent( ObjectEvent.newRemoved( go ) );
244
include(`ui/MixinAnimationMaster.ihx')