// // Created by koncord on 30.07.17. // #pragma once #include "sol.hpp" #include "Utils.hpp" #include "LuaState.hpp" typedef unsigned Event; namespace CoreEvent { enum { ON_EXIT = 0, ON_POST_INIT, ON_REQUEST_PLUGIN_LIST, ON_PLAYER_CONNECT, ON_PLAYER_DISCONNECT, ON_PLAYER_DEATH, ON_PLAYER_RESURRECT, ON_PLAYER_CELLCHANGE, ON_PLAYER_KILLCOUNT, ON_PLAYER_ATTRIBUTE, ON_PLAYER_SKILL, ON_PLAYER_LEVEL, ON_PLAYER_BOUNTY, ON_PLAYER_EQUIPMENT, ON_PLAYER_INVENTORY, ON_PLAYER_JOURNAL, ON_PLAYER_FACTION, ON_PLAYER_SHAPESHIFT, ON_PLAYER_SPELLBOOK, ON_PLAYER_TOPIC, ON_PLAYER_DISPOSITION, ON_PLAYER_BOOK, ON_PLAYER_MAP, ON_PLAYER_REST, ON_PLAYER_SENDMESSAGE, ON_PLAYER_ENDCHARGEN, ON_PLAYER_WEATHER, ON_CHANNEL_ACTION, ON_GUI_ACTION, ON_MP_REFNUM, ON_ACTOR_EQUIPMENT, ON_ACTOR_CELL_CHANGE, ON_ACTOR_LIST, ON_ACTOR_TEST, ON_CELL_LOAD, ON_CELL_UNLOAD, ON_CELL_DELETION, ON_CONTAINER, ON_DOOR_STATE, ON_OBJECT_PLACE, ON_OBJECT_STATE, ON_OBJECT_SPAWN, ON_OBJECT_DELETE, ON_OBJECT_LOCK, ON_OBJECT_SCALE, ON_OBJECT_TRAP, LAST, }; const int FIRST = ON_EXIT; } class CallbackCollection // todo: add sort by dependencies { public: typedef std::vector> Container; typedef Container::iterator Iterator; typedef Container::const_iterator CIterator; template struct type_tag {}; void push(sol::environment &env, sol::function &func) { functions.emplace_back(env, func); } CIterator begin() const { return functions.begin(); } CIterator end() const { return functions.end(); } void stop() {_stop = true;} bool isStoped() const {return _stop;} CIterator stopedAt() const { return lastCalled; } template void call(type_tag, Args&&... args) { lastCalled = functions.end(); _stop = false; for (CIterator iter = functions.begin(); iter != functions.end(); ++iter) { if (!_stop) iter->second.call(std::forward(args)...); else { lastCalled = iter; break; } } } template decltype(auto) call(type_tag, Args&&... args) { R ret; lastCalled = functions.end(); _stop = false; for (CIterator iter = functions.begin(); iter != functions.end(); ++iter) { if (!_stop) ret = iter->second.call(std::forward(args)...); else { lastCalled = iter; break; } } return ret; } private: Container functions; CIterator lastCalled; bool _stop = false; }; class EventController { public: static void Init(LuaState &lua); public: explicit EventController(LuaState *luaCtrl); typedef std::unordered_map Container; void registerEvent(int event, sol::environment &env, sol::function& func); CallbackCollection& GetEvents(Event event); Event createEvent(); void raiseEvent(Event id, sol::table data, const std::string &moduleName = ""); void stop(int event); template R Call(Args&&... args) { return events.at(event).call(CallbackCollection::type_tag{}, std::forward(args)...); } private: Container events; Event lastEvent = CoreEvent::LAST; LuaState *luaCtrl; };