diff --git a/BUGS b/BUGS index 4018afa8..b27f73c2 100644 --- a/BUGS +++ b/BUGS @@ -20,6 +20,7 @@ ERROR: [Map::setCentralPosition] invalid creature battle sometimes doesn't clear attacked/followed creatures when they go out of range when looking from floor 5 in floor 7, sometimes a tile have 2 invisible grounds in floor 6 that should be ignored invisible creatures name offset is incorrect +walk does not work properly when a creature is paralyzed == P3 BUGS widgets may have been destroyed when adding event in onSetup (UIResizeBorder), generating invalid events diff --git a/modules/client_topmenu/topmenu.otui b/modules/client_topmenu/topmenu.otui index 67e3190f..523609ae 100644 --- a/modules/client_topmenu/topmenu.otui +++ b/modules/client_topmenu/topmenu.otui @@ -80,9 +80,6 @@ TopPanel margin-top: 8 margin-right: 5 @onSetup: | - local updateFunc - updateFunc = function() + cycleEvent(function() rootWidget:recursiveGetChildById('frameCounter'):setText('FPS: ' .. g_app.getBackgroundPaneFps()) - scheduleEvent(updateFunc, 250) - end - addEvent(updateFunc) + end, 250) diff --git a/modules/core_lib/globals.lua b/modules/core_lib/globals.lua index a5f41813..75669e2a 100644 --- a/modules/core_lib/globals.lua +++ b/modules/core_lib/globals.lua @@ -41,6 +41,13 @@ function addEvent(callback, front) return event end +function cycleEvent(callback, front) + local event = g_eventDispatcher.cycleEvent(callback, front) + -- must hold a reference to the callback, otherwise it would be collected + event._callback = callback + return event +end + function periodicalEvent(eventFunc, conditionFunc, delay, autoRepeatDelay) delay = delay or 30 diff --git a/src/framework/core/eventdispatcher.cpp b/src/framework/core/eventdispatcher.cpp index 5248dc13..c6a8689b 100644 --- a/src/framework/core/eventdispatcher.cpp +++ b/src/framework/core/eventdispatcher.cpp @@ -44,6 +44,9 @@ void EventDispatcher::poll() break; m_scheduledEventList.pop(); scheduledEvent->execute(); + + if(scheduledEvent->nextCycle()) + m_scheduledEventList.push(scheduledEvent); } // execute events list up to 10 times, this is needed because some events can schedule new events that would @@ -75,7 +78,15 @@ void EventDispatcher::poll() ScheduledEventPtr EventDispatcher::scheduleEvent(const std::function& callback, int delay) { assert(delay >= 0); - ScheduledEventPtr scheduledEvent(new ScheduledEvent(callback, delay)); + ScheduledEventPtr scheduledEvent(new ScheduledEvent(callback, delay, 1)); + m_scheduledEventList.push(scheduledEvent); + return scheduledEvent; +} + +ScheduledEventPtr EventDispatcher::cycleEvent(const std::function& callback, int delay) +{ + assert(delay > 0); + ScheduledEventPtr scheduledEvent(new ScheduledEvent(callback, delay, 0)); m_scheduledEventList.push(scheduledEvent); return scheduledEvent; } diff --git a/src/framework/core/eventdispatcher.h b/src/framework/core/eventdispatcher.h index c803c9d5..7b8bf582 100644 --- a/src/framework/core/eventdispatcher.h +++ b/src/framework/core/eventdispatcher.h @@ -32,7 +32,7 @@ class Event : public LuaObject public: Event(const std::function& callback) : m_callback(callback), m_canceled(false), m_executed(false) { } - void execute() { + virtual void execute() { if(!m_canceled && !m_executed && m_callback) { m_callback(); m_executed = true; @@ -52,15 +52,42 @@ protected: class ScheduledEvent : public Event { public: - ScheduledEvent(const std::function& callback, int delay) : Event(callback) { + ScheduledEvent(const std::function& callback, int delay, int maxCycles) : Event(callback) { m_ticks = g_clock.millis() + delay; + m_delay = delay; + m_maxCycles = maxCycles; + m_cyclesExecuted = 0; + } + + void execute() { + if(!m_canceled && m_callback && (m_maxCycles == 0 || m_cyclesExecuted < m_maxCycles)) { + m_callback(); + m_executed = true; + } + m_cyclesExecuted++; + } + + bool nextCycle() { + if(m_canceled) + return false; + if(m_maxCycles == 0 || m_cyclesExecuted < m_maxCycles) { + m_ticks += m_delay; + return true; + } + return false; } int ticks() const { return m_ticks; } int reamaningTicks() const { return m_ticks - g_clock.millis(); } + int delay() const { return m_delay; } + int cyclesExecuted() { return m_cyclesExecuted; } + int maxCycles() { return m_maxCycles; } private: ticks_t m_ticks; + int m_delay; + int m_maxCycles; + int m_cyclesExecuted; }; struct lessScheduledEvent : std::binary_function { @@ -77,6 +104,7 @@ public: EventPtr addEvent(const std::function& callback, bool pushFront = false); ScheduledEventPtr scheduleEvent(const std::function& callback, int delay); + ScheduledEventPtr cycleEvent(const std::function& callback, int delay); private: std::list m_eventList; diff --git a/src/framework/luafunctions.cpp b/src/framework/luafunctions.cpp index bbdf1143..c2d95310 100644 --- a/src/framework/luafunctions.cpp +++ b/src/framework/luafunctions.cpp @@ -61,8 +61,12 @@ void Application::registerLuaFunctions() // ScheduledEvent g_lua.registerClass(); - g_lua.bindClassMemberFunction("reamaningTicks", &ScheduledEvent::reamaningTicks); + g_lua.bindClassMemberFunction("nextCycle", &ScheduledEvent::nextCycle); g_lua.bindClassMemberFunction("ticks", &ScheduledEvent::ticks); + g_lua.bindClassMemberFunction("reamaningTicks", &ScheduledEvent::reamaningTicks); + g_lua.bindClassMemberFunction("delay", &ScheduledEvent::delay); + g_lua.bindClassMemberFunction("cyclesExecuted", &ScheduledEvent::cyclesExecuted); + g_lua.bindClassMemberFunction("maxCycles", &ScheduledEvent::maxCycles); // UIWidget g_lua.registerClass(); @@ -600,4 +604,5 @@ void Application::registerLuaFunctions() g_lua.registerStaticClass("g_eventDispatcher"); g_lua.bindClassStaticFunction("g_eventDispatcher", "addEvent", std::bind(&EventDispatcher::addEvent, &g_eventDispatcher, std::placeholders::_1, std::placeholders::_2)); g_lua.bindClassStaticFunction("g_eventDispatcher", "scheduleEvent", std::bind(&EventDispatcher::scheduleEvent, &g_eventDispatcher, std::placeholders::_1, std::placeholders::_2)); + g_lua.bindClassStaticFunction("g_eventDispatcher", "cycleEvent", std::bind(&EventDispatcher::cycleEvent, &g_eventDispatcher, std::placeholders::_1, std::placeholders::_2)); }