Code archives/Algorithms/Swift Event System

This code has been declared by its author to be Public Domain code.

Download source code

Swift Event System by sswift2003
This system allows you to create events which trigger at a certain time, remain active for a while, and expire.

There are 1001 uses for this. Event systems are a must have for games. All professional games use an event driven architecture.

For example, let's say that your player picks up a key and uses it on a door and the door opens.

Right there you could have a ton of events:


* Make object dissapear and add to inventory.

Which Triggers:
* Emit particles for 3 seconds.

Which Triggers:
* Animate particle for 1 second.

* Player open door.

Which triggers:
* Play click noise.
* Play creak noise.
* Rotate door 90 degrees on Y axis.
* Remove key from inventory.


Any time you need something to happen immediately, or happen 10 seconds from now, or you need something to appear, rotate for 30 seconds, and then dissapear, you need events!

One event can even trigger several others when it is in progress or expires.


You'll notice the code isn't all that complex. Adding the cool stuff is up to you. Just make functions to do the things you want each event to do, and stick the function call in the case staements in the appropriate functions.

Don't add your code directly into the library, that will just make it messy and hard to read. Just add function calls to code in your main game source.

Events can have data attached to them, but you have to modify the event type to do that. I provided some data storage within the type already for ints floats and strings. You should try to keep the data variables having general names and use the same ones for multiply types of events. You only need one int if one event needs a counter and the other needs to store an entity pointer. Though you might decide that you use entity ponters so often that you want a specific Entity data variable for storing just that. What you do is up to you, I merely offer suggestions. :-)

Ideally I would have liked to have just used C like Structures and a single pointer for event data and you could create on structure for each type of event, but that leads to the necessity of deleting that data as well as the event data and I couldn't automate that if types were used for example... And banks are a pain to use. So adding a few variables to the event data as needed seems like the best solution for now.


I hoe you find this useful!

I worked on it for several days to try to find the best and most generally useful way to do everyhting. I was going to make it so that events could retrigger themselves and do it at random intervals, but then I realised that you can just add some simple code to specific events to do that so why bother making the system much more complicated for functionality people may only use for one or two events?
; -------------------------------------------------------------------------------------------------------------------
; Swift Event System for Blitz Basic - Copyright 2003 Shawn C. Swift - sswift@earthlink.net
; -------------------------------------------------------------------------------------------------------------------
; 
; License:
; 	
; 	You may use tand modify this code for free.
;
; 	If you find it useful, a small donation would be appreciated!
; 	To send a donation, go to http://www.paypal.com and send your donation to sswift@earthlink.net.
;
; --
;
; Code usage:
;
;	1. Add fields for data you want to store with your events to the Event type.
;
;	2. Add code to the Event_Start, Event_Active, and Event_End functions to perform specific actions for each type
; 	of event in your game.
;
; 	3. Create an event using NewEvent().
;
;  	4. Call UpdateEvents() every game loop, passing it the current game time.
;
; -- 
;
; Notes:
;
; 	ALL events trigger Event_Start() when they begin, Event_Active() every update during the time they are active,
; 	and Event_End() when they expire.  These triggers can all occur, in that order, in a single update.
;
;	If you want an event to trigger another event when it expires, place code in Event_End() which calls NewEvent().
; -------------------------------------------------------------------------------------------------------------------
                   

Type Event

	Field Event_Type

	Field Time_Start
	Field Time_End
	
	Field Active
	

	; -- Add data for your events here:
	; -- All variables below are not used by the system and can be deleted at will.

	Field Data_Int[3]
	;Field Data_Float#[3]
	;Field Data_String$[1]
		
End Type


; -------------------------------------------------------------------------------------------------------------------
; Call this function to create a new event. 
; The function returns a pointer to the newly created event so you can add data to it.
;
; Time_Start and Time_End are optional.
;
; If Time_Start is not specified, the event will trigger on the next call to UpdateEvents().
; If Time_End is not specified, the event will trigger AND expire on the next call to UpdateEvents().
; -------------------------------------------------------------------------------------------------------------------
Function NewEvent.Event(Event_Type, Time_Start=-1, Time_End=-1)

	If (Time_End = -1) Then Time_End = Time_Start

	ThisEvent.Event = New Event
	
	ThisEvent\Event_Type   = Event_Type
	ThisEvent\Time_Start   = Time_Start
	ThisEvent\Time_End     = Time_End
	ThisEvent\Active       = False

	Return ThisEvent
	
End Function


; -------------------------------------------------------------------------------------------------------------------
; Call this function every loop to update your events.
;
; You should pass the current time, in milliseconds, to the function.
; (Time must always be a positive value.)
;
; (The reason I don't just grab millisecs() is so that your game time can be independent of the system time, which
; allows you to do effects like slow-mo and fast-forward while still having your events trigger at the right time.)
; -------------------------------------------------------------------------------------------------------------------
Function UpdateEvents(Time)

	; Loop through all events.
	For ThisEvent.Event = Each Event

		; If it past the start time for this event...
		If (Time >= ThisEvent\Time_Start)  
				
			; If the event is not currently active...
			If Not ThisEvent\Active 
	
				; Call the code which should be executed when the event starts, and set the event as active. 
				Event_Start(ThisEvent, Time)
				ThisEvent\Active = True

			EndIf
		
			; Call the code which should be run continuously while this event is in progress.
			Event_Active(ThisEvent, Time)

			; If it is time for this event to end...		
			If Time >= ThisEvent\Time_End

				; Call the code which should be executed when this event ends, and delete the event.
				Event_End(ThisEvent, Time)
				Delete ThisEvent
				
			EndIf
		
		EndIf	

	Next

End Function


; -------------------------------------------------------------------------------------------------------------------
; This function is called when an event first starts.
; -------------------------------------------------------------------------------------------------------------------
Function Event_Start(ThisEvent.Event, Time)

	Select ThisEvent\Event_Type
	
	
	End Select

End Function 


; -------------------------------------------------------------------------------------------------------------------
; This function is called continuously while an event is in progress. 
;
; To find out how much time has passed since an event started when animating an object, do this:
; Time_Elasped = ThisEvent\Time_Start - Time
;
; To find out where, 0..1, in the event you are do this:
; Event_Point# = Float(ThisEvent\Time_Start-Time) / Float(ThisEvent\Time_End-ThisEvent\Time_Start)
;
; I don't do this for all events because some events are instantaneous, which would cause a divide by 0 error, and
; others trigger immediately and have a Time_Start of -1.
; -------------------------------------------------------------------------------------------------------------------
Function Event_Active(ThisEvent.Event, Time)

	Select ThisEvent\Event_Type
	
	
	End Select

End Function


; -------------------------------------------------------------------------------------------------------------------
; This function is called when an event ends.
; -------------------------------------------------------------------------------------------------------------------
Function Event_End(ThisEvent.Event, Time)

	Select ThisEvent\Event_Type
	
	
	End Select

End Function

Comments

None.

Code Archives Forum