mirror of
https://github.com/azerothcore/mod-ale
synced 2025-11-29 15:38:17 +08:00
Eluna fix problem with reloading timed events
This commit is contained in:
@@ -41,9 +41,11 @@ void ElunaEventProcessor::Update(uint32 diff)
|
|||||||
{
|
{
|
||||||
LuaEvent* luaEvent = it->second;
|
LuaEvent* luaEvent = it->second;
|
||||||
eventList.erase(it);
|
eventList.erase(it);
|
||||||
|
|
||||||
|
if (luaEvent->state != LUAEVENT_STATE_ERASE)
|
||||||
eventMap.erase(luaEvent->funcRef);
|
eventMap.erase(luaEvent->funcRef);
|
||||||
|
|
||||||
if (!luaEvent->abort)
|
if (luaEvent->state == LUAEVENT_STATE_RUN)
|
||||||
{
|
{
|
||||||
bool remove = luaEvent->repeats == 1;
|
bool remove = luaEvent->repeats == 1;
|
||||||
if (!remove)
|
if (!remove)
|
||||||
@@ -61,10 +63,12 @@ void ElunaEventProcessor::Update(uint32 diff)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ElunaEventProcessor::RemoveEvents()
|
void ElunaEventProcessor::SetStates(LuaEventState state)
|
||||||
{
|
{
|
||||||
for (EventList::iterator it = eventList.begin(); it != eventList.end(); ++it)
|
for (EventList::iterator it = eventList.begin(); it != eventList.end(); ++it)
|
||||||
it->second->abort = true;
|
it->second->SetState(state);
|
||||||
|
if (state == LUAEVENT_STATE_ERASE)
|
||||||
|
eventMap.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ElunaEventProcessor::RemoveEvents_internal()
|
void ElunaEventProcessor::RemoveEvents_internal()
|
||||||
@@ -83,10 +87,12 @@ void ElunaEventProcessor::RemoveEvents_internal()
|
|||||||
eventMap.clear();
|
eventMap.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ElunaEventProcessor::RemoveEvent(int eventId)
|
void ElunaEventProcessor::SetState(int eventId, LuaEventState state)
|
||||||
{
|
{
|
||||||
if (eventMap.find(eventId) != eventMap.end())
|
if (eventMap.find(eventId) != eventMap.end())
|
||||||
eventMap[eventId]->abort = true;
|
eventMap[eventId]->SetState(state);
|
||||||
|
if (state == LUAEVENT_STATE_ERASE)
|
||||||
|
eventMap.erase(eventId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ElunaEventProcessor::AddEvent(LuaEvent* luaEvent)
|
void ElunaEventProcessor::AddEvent(LuaEvent* luaEvent)
|
||||||
@@ -101,9 +107,12 @@ void ElunaEventProcessor::AddEvent(int funcRef, uint32 delay, uint32 repeats)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ElunaEventProcessor::RemoveEvent(LuaEvent* luaEvent)
|
void ElunaEventProcessor::RemoveEvent(LuaEvent* luaEvent)
|
||||||
|
{
|
||||||
|
if (luaEvent->state != LUAEVENT_STATE_ERASE && Eluna::IsInitialized())
|
||||||
{
|
{
|
||||||
// Free lua function ref
|
// Free lua function ref
|
||||||
luaL_unref((*E)->L, LUA_REGISTRYINDEX, luaEvent->funcRef);
|
luaL_unref((*E)->L, LUA_REGISTRYINDEX, luaEvent->funcRef);
|
||||||
|
}
|
||||||
delete luaEvent;
|
delete luaEvent;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,20 +133,20 @@ EventMgr::~EventMgr()
|
|||||||
globalProcessor = NULL;
|
globalProcessor = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EventMgr::RemoveEvents()
|
void EventMgr::SetStates(LuaEventState state)
|
||||||
{
|
{
|
||||||
ReadGuard guard(GetLock());
|
ReadGuard guard(GetLock());
|
||||||
if (!processors.empty())
|
if (!processors.empty())
|
||||||
for (ProcessorSet::const_iterator it = processors.begin(); it != processors.end(); ++it) // loop processors
|
for (ProcessorSet::const_iterator it = processors.begin(); it != processors.end(); ++it) // loop processors
|
||||||
(*it)->RemoveEvents();
|
(*it)->SetStates(state);
|
||||||
globalProcessor->RemoveEvents();
|
globalProcessor->SetStates(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EventMgr::RemoveEvent(int eventId)
|
void EventMgr::SetState(int eventId, LuaEventState state)
|
||||||
{
|
{
|
||||||
ReadGuard guard(GetLock());
|
ReadGuard guard(GetLock());
|
||||||
if (!processors.empty())
|
if (!processors.empty())
|
||||||
for (ProcessorSet::const_iterator it = processors.begin(); it != processors.end(); ++it) // loop processors
|
for (ProcessorSet::const_iterator it = processors.begin(); it != processors.end(); ++it) // loop processors
|
||||||
(*it)->RemoveEvent(eventId);
|
(*it)->SetState(eventId, state);
|
||||||
globalProcessor->RemoveEvent(eventId);
|
globalProcessor->SetState(eventId, state);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,16 +22,30 @@ class EventMgr;
|
|||||||
class ElunaEventProcessor;
|
class ElunaEventProcessor;
|
||||||
class WorldObject;
|
class WorldObject;
|
||||||
|
|
||||||
|
enum LuaEventState
|
||||||
|
{
|
||||||
|
LUAEVENT_STATE_RUN, // On next call run the function normally
|
||||||
|
LUAEVENT_STATE_ABORT, // On next call unregisters reffed function and erases the data
|
||||||
|
LUAEVENT_STATE_ERASE, // On next call just erases the data
|
||||||
|
};
|
||||||
|
|
||||||
struct LuaEvent
|
struct LuaEvent
|
||||||
{
|
{
|
||||||
LuaEvent(int _funcRef, uint32 _delay, uint32 _repeats) :
|
LuaEvent(int _funcRef, uint32 _delay, uint32 _repeats) :
|
||||||
delay(_delay), repeats(_repeats), funcRef(_funcRef), abort(false)
|
delay(_delay), repeats(_repeats), funcRef(_funcRef), state(LUAEVENT_STATE_RUN)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetState(LuaEventState _state)
|
||||||
|
{
|
||||||
|
if (state != LUAEVENT_STATE_ERASE)
|
||||||
|
state = _state;
|
||||||
|
}
|
||||||
|
|
||||||
uint32 delay; // Delay between event calls
|
uint32 delay; // Delay between event calls
|
||||||
uint32 repeats; // Amount of repeats to make, 0 for infinite
|
uint32 repeats; // Amount of repeats to make, 0 for infinite
|
||||||
int funcRef; // Lua function reference ID, also used as event ID
|
int funcRef; // Lua function reference ID, also used as event ID
|
||||||
bool abort; // True if aborted and should not execute anymore
|
LuaEventState state; // State for next call
|
||||||
};
|
};
|
||||||
|
|
||||||
class ElunaEventProcessor
|
class ElunaEventProcessor
|
||||||
@@ -47,9 +61,9 @@ public:
|
|||||||
|
|
||||||
void Update(uint32 diff);
|
void Update(uint32 diff);
|
||||||
// removes all timed events on next tick or at tick end
|
// removes all timed events on next tick or at tick end
|
||||||
void RemoveEvents();
|
void SetStates(LuaEventState state);
|
||||||
// set the event to be removed when executing
|
// set the event to be removed when executing
|
||||||
void RemoveEvent(int eventId);
|
void SetState(int eventId, LuaEventState state);
|
||||||
void AddEvent(int funcRef, uint32 delay, uint32 repeats);
|
void AddEvent(int funcRef, uint32 delay, uint32 repeats);
|
||||||
EventMap eventMap;
|
EventMap eventMap;
|
||||||
|
|
||||||
@@ -74,13 +88,13 @@ public:
|
|||||||
EventMgr(Eluna** _E);
|
EventMgr(Eluna** _E);
|
||||||
~EventMgr();
|
~EventMgr();
|
||||||
|
|
||||||
// Remove all timed events
|
// Set the state of all timed events
|
||||||
// Execute only in safe env
|
// Execute only in safe env
|
||||||
void RemoveEvents();
|
void SetStates(LuaEventState state);
|
||||||
|
|
||||||
// Removes the eventId from all events
|
// Sets the eventId's state in all processors
|
||||||
// Execute only in safe env
|
// Execute only in safe env
|
||||||
void RemoveEvent(int eventId);
|
void SetState(int eventId, LuaEventState state);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1244,9 +1244,9 @@ namespace LuaGlobalFunctions
|
|||||||
|
|
||||||
// not thread safe
|
// not thread safe
|
||||||
if (all_Events)
|
if (all_Events)
|
||||||
E->eventMgr->RemoveEvent(eventId);
|
E->eventMgr->SetState(eventId, LUAEVENT_STATE_ABORT);
|
||||||
else
|
else
|
||||||
E->eventMgr->globalProcessor->RemoveEvent(eventId);
|
E->eventMgr->globalProcessor->SetState(eventId, LUAEVENT_STATE_ABORT);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1261,9 +1261,9 @@ namespace LuaGlobalFunctions
|
|||||||
|
|
||||||
// not thread safe
|
// not thread safe
|
||||||
if (all_Events)
|
if (all_Events)
|
||||||
E->eventMgr->RemoveEvents();
|
E->eventMgr->SetStates(LUAEVENT_STATE_ABORT);
|
||||||
else
|
else
|
||||||
E->eventMgr->globalProcessor->RemoveEvents();
|
E->eventMgr->globalProcessor->SetStates(LUAEVENT_STATE_ABORT);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ void Eluna::_ReloadEluna()
|
|||||||
eWorld->SendServerMessage(SERVER_MSG_STRING, "Reloading Eluna...");
|
eWorld->SendServerMessage(SERVER_MSG_STRING, "Reloading Eluna...");
|
||||||
|
|
||||||
// Remove all timed events
|
// Remove all timed events
|
||||||
sEluna->eventMgr->RemoveEvents();
|
sEluna->eventMgr->SetStates(LUAEVENT_STATE_ERASE);
|
||||||
|
|
||||||
// Close lua
|
// Close lua
|
||||||
sEluna->CloseLua();
|
sEluna->CloseLua();
|
||||||
|
|||||||
@@ -645,7 +645,7 @@ namespace LuaWorldObject
|
|||||||
int RemoveEventById(Eluna* /*E*/, lua_State* L, WorldObject* obj)
|
int RemoveEventById(Eluna* /*E*/, lua_State* L, WorldObject* obj)
|
||||||
{
|
{
|
||||||
int eventId = Eluna::CHECKVAL<int>(L, 2);
|
int eventId = Eluna::CHECKVAL<int>(L, 2);
|
||||||
obj->elunaEvents->RemoveEvent(eventId);
|
obj->elunaEvents->SetState(eventId, LUAEVENT_STATE_ABORT);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -655,7 +655,7 @@ namespace LuaWorldObject
|
|||||||
*/
|
*/
|
||||||
int RemoveEvents(Eluna* /*E*/, lua_State* /*L*/, WorldObject* obj)
|
int RemoveEvents(Eluna* /*E*/, lua_State* /*L*/, WorldObject* obj)
|
||||||
{
|
{
|
||||||
obj->elunaEvents->RemoveEvents();
|
obj->elunaEvents->SetStates(LUAEVENT_STATE_ABORT);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user