Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- GMS2 Event Framework
- Purpose:
- To implement Event-driven Architecture in Game Maker
- Details:
- Event-driven Architecture is perfect for ensuring that:
- - Events (significant changes in program state) are checked for
- only once (as opposed to multiple times from different instances)
- - Single Responsibility Principle can be applied, avoiding performance of several
- non-related tasks in a single object.
- Using events ensures that an instance (emitter) emits an event, and all responsible instances (listeners)
- are alerted so they can perform their tasks for that event occurrence.
- How it works:
- 0. Create an instance of EventManager (persistent) in your first room
- (I do this in an initialization room)
- 1. Set up Event Types in an enum (initEventTypes script)
- for any kind of event you might be interested into
- 2. Instruct instances (listeners) to listen for occurrences of an Event Type (e.g. a mouse click),
- specifying a callback script for the event
- 3. Make instances (emitters) emit events of a specific type, passing event-related data as args
- (e.g. clicked mouse button, mouse coordinates)
- 4. The EventManager triggers the callback for all listeners for that event
- Usage Example:
- //initEventTypes script
- EventTypes { MOUSE_CLICK, KEY_PRESS, GAME_WIN, SCORE_REACH_9000, SIZE }
- //Your object's create code
- subscribe(EventTypes.SCORE_REACH_9000, callbackOver9000)
- //From the instance responsible for score tracking
- if (score > 9000) emitEvent(EventTypes.SCORE_REACH_9000, score)
- //Script callbackOver9000(eventArgs)
- var score = argument0
- show_message_async("IT'S OVER 9000!!! Your score is: " + string(score))
- //Your object's step code
- //Stop listening for events of this type
- unsubscribe(EventTypes.SCORE_REACH_9000)
- Listener scripts:
- //Listen for event type emitted from any instance
- subscribe(eventType, callback)
- //Listen to event type emitted from specific instances
- subscribeToInstance(eventType, target, callback) //Pass an instance ID
- subscribeToInstanceByVar(eventType, "target", callback) //Pass the name of a variable which contains an instance ID
- subscribeToInstancesByList(eventType, targetList, callback) //Pass a list of instance IDs
- subscribeToInstancesByKeyMap(eventType, targetMapKeys, callback) //Pass a map of instance IDs (keys)
- subscribeToInstancesByValueMap(eventType, targetMapValues, callback) //Pass a map of instance IDs (values)
- //Listen to event type emitted from specific objects
- subscribeToObject(eventType, targetObj, true, callback) //Pass an object index
- subscribeToObjectByVar(eventType, "targetObj", true, callback) //Pass the name of a variable which contains an object index
- subscribeToObjectsByList(eventType, targetObjList, true, callback) //Pass a list of object indices
- subscribeToObjectsByKeyMap(eventType, targetObjMapKeys, true, callback) //Pass a map of object indices (keys)
- subscribeToObjectsByValueMap(eventType, targetObjMapValues, true, callback) //Pass a map of object indices (values)
- Stop Listener scripts:
- //Stop the current instance from listening to all events or a specific type
- unsubscribeFromAll()
- unsubscribe(eventType)
- //Stop the current instance from listening to an event type
- //From a specific instance / instances
- unsubscribeFromInstance(eventType, target) //Pass an instance ID
- unsubscribeFromInstanceByVar(eventType, "target") //Pass the name of a variable which contains an instance ID
- unsubscribeFromInstancesByList(eventType, targetList) //Pass a list of instance IDs
- unsubscribeFromInstancesByKeyMap(eventType, targetMap) //Pass a map of instance IDs (keys)
- unsubscribeFromInstancesByValueMap(eventType, targetMap) //Pass a map of instance IDs (values)
- unsubscribeFromObject(eventType, targetObj) //Pass an object index
- unsubscribeFromObjectByVar(eventType, "targetObj") //Pass the name of a variable which contains an object index
- unsubscribeFromObjectsByList(eventType, targetObjList) //Pass a list of object indices
- unsubscribeFromObjectsByKeyMap(eventType, targetObjMap) //Pass a map of object indices (keys)
- unsubscribeFromObjectsByValueMap(eventType, targetObjMap) //Pass a map of object indices (values)
- Listening to Vars/Lists/Maps:
- - subscribeToInstanceByVar/subscribeToObjectByVar
- Require the name of a variable (e.g. "target") containing an instance ID / object index.
- If you update the var to another ID / object index, the listener will update automatically.
- - subscribeToInstancesByList/subscribeToObjectsByList
- Require a list containing instance IDs / object indices
- - subscribeToInstancesByKeyMap/subscribeToObjectsByKeyMap
- Require a map where the map KEYS are instance IDs / object indices
- - subscribeToInstancesByValueMap/subscribeToObjectsByValueMap
- Require a map where the map VALUES are instance IDs / object indices
- Important info:
- - You can add Event Types as you go, they don't need to all be added at the start of development
- - Use the right unsubscribe script (should be the same as your subscribe() script),
- if you use an incorrect unsubscribe script the subscription won't be deleted and the object will keep listening
- Example:
- subscribeToInstancesByList(eventType, myList, callback)
- stopListengInstanceList(eventType, myList)
- - Destroyed listener instances are automatically cleaned up from the EventManager periodically
- - Callbacks are performed within listener scope ( with(listener) )
- - Callbacks now receive event data as regular arguments, for example:
- emitEvent(EventTypes.MOUSE_CLICK, mouse_button, mouse_x, mouse_y)
- //Callback script
- var mouseButton = argument0
- var mouseX = argument1
- var mouseY = argument2
- IMPORTANT: It is up to you to know what data you're returning when emitting the event using emitEvent(type, arg, arg, ...)
- You have to ensure the script you're using will either:
- - Use variable arguments (e.g. argument[0], argument[1])
- - Use the correct number of arguments as passed by emitEvent
- Any other behavior will result in a crash
- Updates:
- - Replaced Event object with ds_map
- - Added possibility to listen to events emitted from specific instance/object, from lists and maps of instances/objects
- - Replaced Event Data array which argument list for more natural callback handling
- Future updates (pending stable Game Maker 2.3 update):
- - Possibility to use anonymous function callbacks instead of scripts
- Contacts:
- mikecazzarolli@gmail.com
- twitter.com/mikecazzarolli
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement