| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411 |
- #ifndef SCRIPTTARGET_H_
- #define SCRIPTTARGET_H_
- #include "Script.h"
- namespace gameplay
- {
- /**
- * Macro to indidate the start of script event definitions for a class.
- *
- * This macro should be used at the top of a class declaration. The class
- * should extend ScriptTarget and the lines immediately following this
- * macro should be one or more GP_SCRIPT_EVENT macros, followed by
- * exactly one GP_SCRIPT_EVENTS_END macro.
- *
- * @script{ignore}
- */
- #define GP_SCRIPT_EVENTS_START() \
- public: \
- class ScriptEvents { \
- public: \
- static ScriptEvents* getInstance() \
- { \
- static ScriptEvents instance; \
- return &instance; \
- } \
- static ScriptTarget::EventRegistry* getRegistry() \
- { \
- static ScriptTarget::EventRegistry registry; \
- return ®istry; \
- }
- /**
- * Macro to define a single supported script event for a class.
- *
- * This macro should follow exactly one prior GP_SCRIPT_EVENTS_START macro
- * and zero or more other GP_SCRIPT_EVENT macros.
- *
- * @param eventName The name of the script event.
- * @param eventArgs A string of arguments to be passed to the script event, using
- * the format specified in ScriptController::executeFunction.
- *
- * @script{ignore}
- */
- #define GP_SCRIPT_EVENT(eventName, eventArgs) \
- struct SCRIPT_EVENT_ ## eventName \
- { \
- SCRIPT_EVENT_ ## eventName() \
- { \
- _event = ScriptEvents::getRegistry()->addEvent(#eventName, eventArgs); \
- } \
- const ScriptTarget::Event* getEvent() \
- { \
- return _event; \
- } \
- private: \
- const ScriptTarget::Event* _event; \
- }; \
- SCRIPT_EVENT_ ## eventName eventName;
- /**
- * Macro to indiate the end of a series of script event defintions.
- *
- * @script{ignore}
- */
- #define GP_SCRIPT_EVENTS_END() \
- private: \
- ScriptEvents() { } \
- };
- /**
- * Macro used to retrieve a script event object the given class name.
- *
- * @param eventClass The C++ class that contains the specified script event.
- * @param eventName The name of the registered script event to retrieve.
- *
- * @script{ignore}
- */
- #define GP_GET_SCRIPT_EVENT(eventClass, eventName) \
- eventClass::ScriptEvents::getInstance()->eventName.getEvent()
- /**
- * Registers the defined script events for a ScriptTarget.
- *
- * This macro should be called at the beginning of all constructors of a
- * ScriptTarget child class that contains one or more script event
- * declarations (via the GP_SCRIPT_EVENT macro).
- *
- * @script{ignore}
- */
- #define GP_REGISTER_SCRIPT_EVENTS() \
- ScriptTarget::registerEvents(ScriptEvents::getInstance()->getRegistry())
- /**
- * Defines an interface for supporting script callbacks.
- *
- * Classes that extend ScriptTarget can expose script events using the GP_SCRIPT_EVENT macros.
- * Custom events should be registered using these macros at the top of the class definition.
- * Events can be fired by calling the ScriptTarget::fireScriptEvent method, passing the
- * registered ScriptTarget::Event object and any required parameters.
- *
- * In addition to script events that are explicitly defined by a custom ScriptTarget class,
- * all ScriptTarget scripts implicitly support an "attached" event. This event is called
- * immediately after such a script is attached to a ScriptTarget and it takes a single
- * parameter: the ScriptTarget object.
- */
- class ScriptTarget
- {
- friend class Game;
- public:
- /**
- * Defines a single script event.
- */
- class Event
- {
- friend class ScriptTarget;
- public:
- /**
- * Returns the name of this event.
- *
- * @return The event name.
- */
- const char* getName() const;
- /**
- * Returns the argument string for this event.
- *
- * @return The argument string.
- */
- const char* getArgs() const;
- private:
- /**
- * The event name.
- */
- std::string name;
- /**
- * The event arguments.
- *
- * @see ScriptController::executeFunction
- */
- std::string args;
- };
- /**
- * Script event registry that defines the supported script events
- * for a ScriptTarget.
- *
- * This class should generally only be used via the GP_REGISTER_SCRIPT_EVENTS macro.
- */
- class EventRegistry
- {
- friend class ScriptTarget;
- public:
- /**
- * Creates an empty event registry.
- */
- EventRegistry();
- /**
- * Destructor.
- */
- ~EventRegistry();
- /**
- * Adds a registered event to the registry.
- *
- * @param name The name of the script event.
- * @param args The argument string for the event.
- *
- * @return The added event.
- *
- * @see ScriptController::executeFunction
- */
- const Event* addEvent(const char* name, const char* args = NULL);
- /**
- * Returns the number of registered script events.
- *
- * @return The number of script events registered.
- */
- unsigned int getEventCount() const;
- /**
- * Returns the event with the given index.
- *
- * @param index The index of the event to retrieve.
- *
- * @return The event for the given index.
- */
- const Event* getEvent(unsigned int index) const;
- /**
- * Returns the event that matches the given name.
- *
- * @param name The name of the event to search for.
- *
- * @return The matching event, or NULL if no such event exists.
- */
- const Event* getEvent(const char* name) const;
- private:
- std::vector<Event*> _events;
- };
- /**
- * Implemented by child classes to return the type name identifier for
- * the class that extends ScriptTarget.
- *
- * @return A string describing the type name of the ScriptTarget child
- * class, as it is defined in the lua bindings (i.e. "Node").
- */
- virtual const char* getTypeName() const = 0;
- /**
- * Attaches a script to this object.
- *
- * Scripts attached to a ScriptTarget are loaded using the PROTECTED scope,
- * which loads scripts into their own protected script environment, allowing
- * variables with the same name to be used without colliding with other scripts.
- *
- * @param path Path to the script.
- *
- * @return A pointer to the successfully loaded script, or NULL if unsuccessful.
- */
- Script* addScript(const char* path);
- /**
- * Removes a previously attached script from this object.
- *
- * @param path The same path that was used to load the script being removed.
- *
- * @return True if a script is successfully removed, false otherwise.
- */
- bool removeScript(const char* path);
- /**
- * Adds the given global script function as a callback for the given event.
- *
- * Individual script callback events registered via this method are expected
- * to be global script functions. Registering individual callbacks in this
- * manner is generally slower than registering a single script to handle script
- * events for an object.
- *
- * @param event The event to add the callback for.
- * @param function The name of the script function to call when the event is fired; can either be
- * just the name of a function (if the function's script file has already been loaded), or can be
- * a URL of the form scriptFile.lua#functionName.
- */
- void addScriptCallback(const Event* event, const char* function);
- /**
- * Removes the given script function as a callback for the given event.
- *
- * @param event The event to remove the callback for.
- * @param function The name of the script function.
- */
- void removeScriptCallback(const Event* event, const char* function);
- /**
- * Removes all scripts and callbacks from this object.
- */
- void clearScripts();
- /**
- * Determines if there is a script installed that is listening for the given script
- * event (i.e. has a function callback defined for the given event).
- *
- * @param eventName The script event to check.
- *
- * @return True if there is a listener for the specified event, false otherwise.
- */
- bool hasScriptListener(const char* eventName) const;
- /**
- * Determines if there is a script installed that is listening for the given script
- * event (i.e. has a function callback defined for the given event).
- *
- * @param event The script event to check.
- *
- * @return True if there is a listener for the specified event, false otherwise.
- */
- bool hasScriptListener(const Event* event) const;
- /**
- * Returns the event object for the given event name, if it exists.
- *
- * @param eventName Name of the event.
- *
- * @return The event object for the given name, or NULL if no such event exists.
- */
- const Event* getScriptEvent(const char* eventName) const;
- /**
- * Fires the specified script event, passing the specified arguments.
- *
- * The only supported return types are void and boolean. When a boolean
- * return type is used and there are multiple scripts registered for the
- * given script event, event delegation will stop at the first script
- * that returns a value of true.
- *
- * @param event The script event to fire, which was returned from EventRegistry::addEvent.
- * @param ... Optional list of arguments to pass to the script event (should match the
- * script event argument definition).
- *
- * @script{ignore}
- */
- template<typename T> T fireScriptEvent(const Event* event, ...);
- protected:
- /**
- * Stores an EventRegistry entry for a ScriptTarget.
- */
- struct RegistryEntry
- {
- EventRegistry* registry;
- RegistryEntry* next;
- RegistryEntry* prev;
- RegistryEntry(EventRegistry* registry) : registry(registry), next(NULL), prev(NULL) { }
- };
- /**
- * Stores a Script that is registered for a ScriptTarget.
- */
- struct ScriptEntry
- {
- Script* script;
- ScriptEntry* next;
- ScriptEntry* prev;
- ScriptEntry(Script* script) : script(script), next(NULL), prev(NULL) { }
- };
- /**
- * Stores a single registered script callback function.
- */
- struct CallbackFunction
- {
- // The script the callback belongs to (or NULL if the callback is a global function)
- Script* script;
- // The function within the script to call
- std::string function;
- CallbackFunction(Script* script, const char* function) : script(script), function(function) { }
- };
- /**
- * Constructor.
- */
- ScriptTarget();
- /**
- * Destructor.
- */
- virtual ~ScriptTarget();
- /**
- * Removes the specified script.
- */
- void removeScript(ScriptEntry* se);
- /**
- * Registers a set of supported script events and event arguments for this ScriptTarget.
- *
- * The passed in EventRegistry object should contain a list of all script events to
- * be supported by this ScriptTarget, along with their parameter definitions. This
- * registry object will be held onto for the lifetime of the ScriptTarget and it is
- * recommended that it be shared among all ScriptTargets of the same class/type.
- *
- * This should normally be set using the GP_REGISTER_SCRIPT_EVENTS macro in the
- * constructor of the child class.
- *
- * @param registry The EventRegistry containing the list of supported script events.
- */
- void registerEvents(EventRegistry* registry);
- /** Holds the event registries for this script target. */
- RegistryEntry* _scriptRegistries;
- /** Holds the list of scripts referenced by this ScriptTarget. */
- ScriptEntry* _scripts;
- /** Holds the list of callback functions registered for this ScriptTarget. */
- std::map<const Event*, std::vector<CallbackFunction> >* _scriptCallbacks;
- };
- template<typename T> T ScriptTarget::fireScriptEvent(const Event* evt, ...)
- {
- GP_ERROR("Unsupported return type for template function ScriptTarget::fireScriptEvent.");
- }
- /** Template specialization. */
- template<> void ScriptTarget::fireScriptEvent<void>(const Event* event, ...);
- /** Template specialization. */
- template<> bool ScriptTarget::fireScriptEvent<bool>(const Event* event, ...);
- }
- #endif
|