mirror of
https://github.com/edubart/otclient.git
synced 2025-12-14 12:49:47 +01:00
Fix memory leaks
* Fix recursive reference memory leak in UIWidget * Make Event/ScheduledEvent memory-leak safe * Fix exit crashs by freeing graphics resources before destroying GL context * Add many asserts to avoid any leak regression
This commit is contained in:
@@ -57,6 +57,11 @@ bool ConfigManager::save()
|
||||
return m_confsDoc->save(m_fileName);
|
||||
}
|
||||
|
||||
void ConfigManager::clear()
|
||||
{
|
||||
m_confsDoc->clear();
|
||||
}
|
||||
|
||||
void ConfigManager::set(const std::string& key, const std::string& value)
|
||||
{
|
||||
if(key == "") {
|
||||
|
||||
@@ -32,6 +32,7 @@ public:
|
||||
ConfigManager();
|
||||
bool load(const std::string& file);
|
||||
bool save();
|
||||
void clear();
|
||||
|
||||
void set(const std::string& key, const std::string& value);
|
||||
void setList(const std::string& key, const std::vector<std::string>& list);
|
||||
|
||||
@@ -32,8 +32,12 @@ void EventDispatcher::flush()
|
||||
while(!m_eventList.empty())
|
||||
poll();
|
||||
|
||||
while(!m_scheduledEventList.empty())
|
||||
while(!m_scheduledEventList.empty()) {
|
||||
ScheduledEventPtr scheduledEvent = m_scheduledEventList.top();
|
||||
scheduledEvent->cancel();
|
||||
m_scheduledEventList.pop();
|
||||
}
|
||||
m_disabled = true;
|
||||
}
|
||||
|
||||
void EventDispatcher::poll()
|
||||
@@ -77,6 +81,9 @@ void EventDispatcher::poll()
|
||||
|
||||
ScheduledEventPtr EventDispatcher::scheduleEvent(const std::function<void()>& callback, int delay)
|
||||
{
|
||||
if(m_disabled)
|
||||
return ScheduledEventPtr(new ScheduledEvent(nullptr, delay, 1));
|
||||
|
||||
assert(delay >= 0);
|
||||
ScheduledEventPtr scheduledEvent(new ScheduledEvent(callback, delay, 1));
|
||||
m_scheduledEventList.push(scheduledEvent);
|
||||
@@ -85,6 +92,9 @@ ScheduledEventPtr EventDispatcher::scheduleEvent(const std::function<void()>& ca
|
||||
|
||||
ScheduledEventPtr EventDispatcher::cycleEvent(const std::function<void()>& callback, int delay)
|
||||
{
|
||||
if(m_disabled)
|
||||
return ScheduledEventPtr(new ScheduledEvent(nullptr, delay, 0));
|
||||
|
||||
assert(delay > 0);
|
||||
ScheduledEventPtr scheduledEvent(new ScheduledEvent(callback, delay, 0));
|
||||
m_scheduledEventList.push(scheduledEvent);
|
||||
@@ -93,6 +103,9 @@ ScheduledEventPtr EventDispatcher::cycleEvent(const std::function<void()>& callb
|
||||
|
||||
EventPtr EventDispatcher::addEvent(const std::function<void()>& callback, bool pushFront)
|
||||
{
|
||||
if(m_disabled)
|
||||
return EventPtr(new Event(nullptr));
|
||||
|
||||
EventPtr event(new Event(callback));
|
||||
// front pushing is a way to execute an event before others
|
||||
if(pushFront) {
|
||||
|
||||
@@ -31,14 +31,24 @@ class Event : public LuaObject
|
||||
{
|
||||
public:
|
||||
Event(const std::function<void()>& callback) : m_callback(callback), m_canceled(false), m_executed(false) { }
|
||||
virtual ~Event() {
|
||||
// assure that we lost callback refs
|
||||
assert(m_callback == nullptr);
|
||||
}
|
||||
|
||||
virtual void execute() {
|
||||
if(!m_canceled && !m_executed && m_callback) {
|
||||
m_callback();
|
||||
m_executed = true;
|
||||
}
|
||||
|
||||
// reset callback to free object refs
|
||||
m_callback = nullptr;
|
||||
}
|
||||
void cancel() {
|
||||
m_canceled = true;
|
||||
m_callback = nullptr;
|
||||
}
|
||||
void cancel() { m_canceled = true; }
|
||||
|
||||
bool isCanceled() { return m_canceled; }
|
||||
bool isExecuted() { return m_executed; }
|
||||
@@ -63,17 +73,21 @@ public:
|
||||
if(!m_canceled && m_callback && (m_maxCycles == 0 || m_cyclesExecuted < m_maxCycles)) {
|
||||
m_callback();
|
||||
m_executed = true;
|
||||
// callback may be used in the next cycle
|
||||
} else {
|
||||
// reset callback to free object refs
|
||||
m_callback = nullptr;
|
||||
}
|
||||
m_cyclesExecuted++;
|
||||
}
|
||||
|
||||
bool nextCycle() {
|
||||
if(m_canceled)
|
||||
return false;
|
||||
if(m_maxCycles == 0 || m_cyclesExecuted < m_maxCycles) {
|
||||
if(m_callback && !m_canceled && (m_maxCycles == 0 || m_cyclesExecuted < m_maxCycles)) {
|
||||
m_ticks += m_delay;
|
||||
return true;
|
||||
}
|
||||
// reset callback to free object refs
|
||||
m_callback = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -109,6 +123,7 @@ public:
|
||||
private:
|
||||
std::list<EventPtr> m_eventList;
|
||||
int m_pollEventsSize;
|
||||
Boolean<false> m_disabled;
|
||||
std::priority_queue<ScheduledEventPtr, std::vector<ScheduledEventPtr>, lessScheduledEvent> m_scheduledEventList;
|
||||
};
|
||||
|
||||
|
||||
@@ -28,6 +28,12 @@
|
||||
|
||||
ModuleManager g_modules;
|
||||
|
||||
void ModuleManager::clear()
|
||||
{
|
||||
m_modules.clear();
|
||||
m_autoLoadModules.clear();
|
||||
}
|
||||
|
||||
void ModuleManager::discoverModules()
|
||||
{
|
||||
// remove modules that are not loaded
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
class ModuleManager
|
||||
{
|
||||
public:
|
||||
void clear();
|
||||
|
||||
void discoverModulesPath();
|
||||
void discoverModules();
|
||||
void autoLoadModules(int maxPriority);
|
||||
|
||||
Reference in New Issue
Block a user