[Server] Add possibility to use previous state of data in events

sol2-server-rewrite
Koncord 7 years ago
parent 7deff7a42a
commit d0eef7c98e

@ -400,13 +400,13 @@ PacketPreInit::PluginContainer Networking::getPluginListSample()
while (true) while (true)
{ {
unsigned field = 0; unsigned field = 0;
auto name = luaState.getEventCtrl().Call<CoreEvent::ON_REQUEST_PLUGIN_LIST, string>(id, field++); auto name = luaState.getEventCtrl().Call<CoreEvent::ON_REQUEST_PLUGIN_LIST, false, string>(id, field++);
if (name.empty()) if (name.empty())
break; break;
PacketPreInit::HashList hashList; PacketPreInit::HashList hashList;
while (true) while (true)
{ {
auto hash = luaState.getEventCtrl().Call<CoreEvent::ON_REQUEST_PLUGIN_LIST, string>(id, field++); auto hash = luaState.getEventCtrl().Call<CoreEvent::ON_REQUEST_PLUGIN_LIST, false, string>(id, field++);
if (hash.empty()) if (hash.empty())
break; break;
hashList.push_back((unsigned)stoul(hash)); hashList.push_back((unsigned)stoul(hash));

@ -13,7 +13,7 @@ void EventController::Init(LuaState &lua)
eventsTable["register"] = [&lua](int event, sol::function func, sol::this_environment te) { eventsTable["register"] = [&lua](int event, sol::function func, sol::this_environment te) {
sol::environment& env = te; sol::environment& env = te;
lua.getEventCtrl().registerEvent(event, env, func); lua.getEventCtrl().registerEvent(event, env, func, false);
}; };
eventsTable["stop"] = [&lua](int event) { eventsTable["stop"] = [&lua](int event) {
lua.getEventCtrl().stop(event); lua.getEventCtrl().stop(event);
@ -112,11 +112,11 @@ EventController::EventController(LuaState *luaCtrl)
} }
} }
void EventController::registerEvent(int event, sol::environment &env, sol::function& func) void EventController::registerEvent(int event, sol::environment &env, sol::function& func, bool needsOldState)
{ {
auto iter = events.find(event); auto iter = events.find(event);
if (iter != events.end()) if (iter != events.end())
iter->second.push(env, func); iter->second.push(env, func, needsOldState);
} }
void EventController::stop(int event) void EventController::stop(int event)
@ -146,12 +146,12 @@ void EventController::raiseEvent(Event id, sol::table data, const string &module
if (!moduleName.empty()) if (!moduleName.empty())
{ {
auto f = std::find_if(iter->second.begin(), iter->second.end(), [&moduleName](const auto &item){ auto f = std::find_if(iter->second.begin(), iter->second.end(), [&moduleName](const auto &item){
return item.first["ModuleName"]["name"] == moduleName; return item.env["ModuleName"]["name"] == moduleName;
}); });
if (f != iter->second.end()) if (f != iter->second.end())
f->second.call(data); // call only specified mod f->fn.call(data); // call only specified mod
} }
iter->second.call(CallbackCollection::type_tag<void>(), data); // call all registered events with this id iter->second.call(CallbackCollection::type_tag<void>(), false, data); // call all registered events with this id
} }
else else
cerr << "Event with id: " << id << " is not registered" << endl; cerr << "Event with id: " << id << " is not registered" << endl;

@ -79,13 +79,21 @@ namespace CoreEvent
class CallbackCollection // todo: add sort by dependencies class CallbackCollection // todo: add sort by dependencies
{ {
public: public:
typedef std::vector<std::pair<sol::environment, sol::function>> Container; struct CBType
{
sol::environment env;
sol::function fn;
bool needsOldState;
CBType(sol::environment _env, sol::function _fn, bool _needsOldState): env(_env), fn(_fn), needsOldState(_needsOldState) {}
};
typedef std::vector<CBType> Container;
typedef Container::iterator Iterator; typedef Container::iterator Iterator;
typedef Container::const_iterator CIterator; typedef Container::const_iterator CIterator;
template<typename> struct type_tag {}; template<typename> struct type_tag {};
void push(sol::environment &env, sol::function &func) { functions.emplace_back(env, func); } void push(sol::environment &env, sol::function &func, bool needsOldState) { functions.emplace_back(env, func, needsOldState); }
CIterator begin() const { return functions.begin(); } CIterator begin() const { return functions.begin(); }
CIterator end() const { return functions.end(); } CIterator end() const { return functions.end(); }
@ -93,6 +101,30 @@ public:
bool isStoped() const {return _stop;} bool isStoped() const {return _stop;}
CIterator stopedAt() const { return lastCalled; } CIterator stopedAt() const { return lastCalled; }
template<typename... Args, typename OldData>
void callWOld(const OldData &oldData, Args&&... args)
{
lastCalled = functions.end();
_stop = false;
for (CIterator iter = functions.begin(); iter != functions.end(); ++iter)
{
if (!_stop)
{
if (!iter->needsOldState)
{
iter->fn.call(std::forward<Args>(args)...);
continue;
}
iter->fn.call(std::forward<Args>(args)..., oldData);
}
else
{
lastCalled = iter;
break;
}
}
}
template<typename... Args> template<typename... Args>
void call(type_tag<void>, Args&&... args) void call(type_tag<void>, Args&&... args)
{ {
@ -101,14 +133,13 @@ public:
for (CIterator iter = functions.begin(); iter != functions.end(); ++iter) for (CIterator iter = functions.begin(); iter != functions.end(); ++iter)
{ {
if (!_stop) if (!_stop)
iter->second.call(std::forward<Args>(args)...); iter->fn.call(std::forward<Args>(args)...);
else else
{ {
lastCalled = iter; lastCalled = iter;
break; break;
} }
} }
} }
template<typename R, typename... Args> template<typename R, typename... Args>
@ -121,7 +152,7 @@ public:
for (CIterator iter = functions.begin(); iter != functions.end(); ++iter) for (CIterator iter = functions.begin(); iter != functions.end(); ++iter)
{ {
if (!_stop) if (!_stop)
ret = iter->second.call(std::forward<Args>(args)...); ret = iter->fn.call(std::forward<Args>(args)...);
else else
{ {
lastCalled = iter; lastCalled = iter;
@ -145,17 +176,26 @@ public:
explicit EventController(LuaState *luaCtrl); explicit EventController(LuaState *luaCtrl);
typedef std::unordered_map<int, CallbackCollection> Container; typedef std::unordered_map<int, CallbackCollection> Container;
void registerEvent(int event, sol::environment &env, sol::function& func); void registerEvent(int event, sol::environment &env, sol::function& func, bool needsOldState);
CallbackCollection& GetEvents(Event event); CallbackCollection& GetEvents(Event event);
Event createEvent(); Event createEvent();
void raiseEvent(Event id, sol::table data, const std::string &moduleName = ""); void raiseEvent(Event id, sol::table data, const std::string &moduleName = "");
void stop(int event); void stop(int event);
template<Event event, typename R = void, typename... Args> template<Event event, bool canProvideOldState = false, typename R = void, typename... Args>
R Call(Args&&... args) R Call(Args&&... args)
{ {
if(canProvideOldState)
events.at(event).callWOld(std::forward<Args>(args)...);
else
return events.at(event).call(CallbackCollection::type_tag<R>{}, std::forward<Args>(args)...); return events.at(event).call(CallbackCollection::type_tag<R>{}, std::forward<Args>(args)...);
} }
template<Event event, bool canProvideOldState = false, typename R = void>
R Call()
{
return events.at(event).call(CallbackCollection::type_tag<R>{});
}
private: private:
Container events; Container events;
Event lastEvent = CoreEvent::LAST; Event lastEvent = CoreEvent::LAST;

Loading…
Cancel
Save