Skip to content

Commit

Permalink
Merge pull request #4628 from LandSandBoat/singleton_crtp
Browse files Browse the repository at this point in the history
[core] Consolidate all singleton logic into CRTP common/singleton.h
  • Loading branch information
zach2good authored Oct 22, 2023
2 parents 95f3610 + 60008e3 commit c302a64
Show file tree
Hide file tree
Showing 12 changed files with 103 additions and 132 deletions.
39 changes: 12 additions & 27 deletions src/common/async.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,37 +24,21 @@
#include "sql.h"
#include <task_system.hpp>

// Allocated on and owned the main thread
Async* Async::_instance = nullptr;
ts::task_system* Async::_ts = nullptr;

// Allocated on and owned by by _ts
SqlConnection* Async::_sql = nullptr;

Async* Async::getInstance()
Async::Async()
: ts::task_system(1)
{
if (_instance == nullptr)
{
_instance = new Async();

// NOTE: We only create a single worker thread in the task_system
// : because we're going to be using _sql, which isn't thread safe.
// TODO: Wrap access to _sql in a mutex so it can be shared between
// : threads, and then bump the worker thread count.
_ts = new ts::task_system(1);
}
return _instance;
}

void Async::query(std::string const& query)
{
// clang-format off
_ts->schedule([query]()
this->schedule([query]()
{
TracySetThreadName("Async Worker Thread");
if (_sql == nullptr)
static thread_local std::unique_ptr<SqlConnection> _sql;
if (!_sql)
{
_sql = new SqlConnection();
_sql = std::make_unique<SqlConnection>();
}
_sql->Query(query.c_str());
});
Expand All @@ -68,22 +52,23 @@ void Async::query(std::string const& query)
void Async::query(std::function<void(SqlConnection*)> const& func)
{
// clang-format off
_ts->schedule([func]()
this->schedule([func]()
{
TracySetThreadName("Async Worker Thread");
if (_sql == nullptr)
static thread_local std::unique_ptr<SqlConnection> _sql;
if (!_sql)
{
_sql = new SqlConnection();
_sql = std::make_unique<SqlConnection>();
}
func(_sql);
func(_sql.get());
});
// clang-format on
}

void Async::submit(std::function<void()> const& func)
{
// clang-format off
_ts->schedule([func]()
this->schedule([func]()
{
TracySetThreadName("Async Worker Thread");
func();
Expand Down
15 changes: 4 additions & 11 deletions src/common/async.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,27 +21,20 @@

#pragma once

#include "singleton.h"
#include "sql.h"
#include <task_system.hpp>

#include <functional>
#include <string>

class Async
class Async : public Singleton<Async>, private ts::task_system
{
public:
~Async() = default;

static Async* getInstance();

void query(std::string const& query);
void query(std::function<void(SqlConnection*)> const& func);
void submit(std::function<void()> const& func);

private:
Async() = default;

static Async* _instance;
static SqlConnection* _sql;
static ts::task_system* _ts;
protected:
Async();
};
68 changes: 68 additions & 0 deletions src/common/singleton.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
===========================================================================
Copyright (c) 2023 LandSandBoat Dev Teams
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see http://www.gnu.org/licenses/
===========================================================================
*/

#pragma once

#include <memory>

template <class T>
class Singleton
{
public:
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;

static T* getInstance()
{
if (!_instance)
{
_instance = std::make_unique<T_Instance>();
}

return _instance.get();
}

static void delInstance()
{
_instance = nullptr;
}

protected:
Singleton()
{
}

virtual ~Singleton()
{
}

private:
// https://stackoverflow.com/a/55932298
struct T_Instance : public T
{
T_Instance()
: T()
{
}
};

static inline std::unique_ptr<T> _instance = nullptr;
};
20 changes: 0 additions & 20 deletions src/common/taskmgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,26 +27,6 @@
#include "common/tracy.h"
#include "common/utils.h"

CTaskMgr* CTaskMgr::_instance = nullptr;

CTaskMgr* CTaskMgr::getInstance()
{
TracyZoneScoped;
if (_instance == nullptr)
{
_instance = new CTaskMgr();
}
return _instance;
}

void CTaskMgr::delInstance()
{
if (_instance)
{
destroy(_instance);
}
}

CTaskMgr::CTask* CTaskMgr::AddTask(std::string const& InitName, time_point InitTick, std::any InitData, TASKTYPE InitType, TaskFunc_t InitFunc, duration InitInterval)
{
TracyZoneScoped;
Expand Down
15 changes: 5 additions & 10 deletions src/common/taskmgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@
#ifndef _TASK_MGR_H
#define _TASK_MGR_H

#include "common/cbasetypes.h"
#include "cbasetypes.h"
#include "singleton.h"

#include <any>
#include <functional>
Expand All @@ -38,7 +39,7 @@ struct greater_equal
}
};

class CTaskMgr
class CTaskMgr : public Singleton<CTaskMgr>
{
public:
class CTask;
Expand All @@ -63,17 +64,11 @@ class CTaskMgr
duration DoTimer(time_point tick);
void RemoveTask(std::string const& TaskName);

static CTaskMgr* getInstance();
static void delInstance();

~CTaskMgr(){};
protected:
CTaskMgr() = default;

private:
static CTaskMgr* _instance;

TaskList_t m_TaskList;

CTaskMgr(){};
};

class CTaskMgr::CTask
Expand Down
19 changes: 0 additions & 19 deletions src/common/vana_time.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,30 +25,11 @@

#include "vana_time.h"

CVanaTime* CVanaTime::_instance = nullptr;

CVanaTime::CVanaTime()
{
setCustomEpoch(0);
}

CVanaTime* CVanaTime::getInstance()
{
if (_instance == nullptr)
{
_instance = new CVanaTime();
}
return _instance;
}

void CVanaTime::delInstance()
{
if (_instance)
{
destroy(_instance);
}
}

uint32 CVanaTime::getDate() const
{
return m_vanaDate;
Expand Down
11 changes: 4 additions & 7 deletions src/common/vana_time.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#define JST_OFFSET 32400 // JST +offset from UTC

#include "cbasetypes.h"
#include "singleton.h"

enum DAYTYPE : uint8
{
Expand All @@ -61,12 +62,9 @@ enum TIMETYPE : uint8
TIME_NIGHT = 7
};

class CVanaTime
class CVanaTime : public Singleton<CVanaTime>
{
public:
static CVanaTime* getInstance();
static void delInstance();

TIMETYPE SyncTime();
TIMETYPE GetCurrentTOTD();

Expand Down Expand Up @@ -101,11 +99,10 @@ class CVanaTime

void setCustomEpoch(int32 epoch);

private:
static CVanaTime* _instance;

protected:
CVanaTime();

private:
uint32 m_vYear{}; // Vanadiel Year
uint32 m_vMon{}; // Vanadiel Month
uint32 m_vDate{}; // Vanadiel Date (day of the month)
Expand Down
2 changes: 2 additions & 0 deletions src/map/map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ along with this program. If not, see http://www.gnu.org/licenses/

#include "map.h"

#include "common/async.h"
#include "common/blowfish.h"
#include "common/console_service.h"
#include "common/logging.h"
Expand Down Expand Up @@ -408,6 +409,7 @@ void do_final(int code)

CTaskMgr::delInstance();
CVanaTime::delInstance();
Async::delInstance();

timer_final();
socket_final();
Expand Down
12 changes: 0 additions & 12 deletions src/map/timetriggers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,6 @@

#include "lua/luautils.h"

std::unique_ptr<CTriggerHandler> CTriggerHandler::_instance;

CTriggerHandler* CTriggerHandler::getInstance()
{
if (!_instance)
{
_instance.reset(new CTriggerHandler);
}

return _instance.get();
}

void CTriggerHandler::insertTrigger(Trigger_t trigger)
{
trigger.lastTrigger = (CVanaTime::getInstance()->getDate() - trigger.minuteOffset) / trigger.period;
Expand Down
11 changes: 4 additions & 7 deletions src/map/timetriggers.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#define _CTIMETRIGGERS_H

#include "common/cbasetypes.h"
#include "common/singleton.h"
#include "entities/npcentity.h"
#include <vector>

Expand All @@ -38,20 +39,16 @@ struct Trigger_t
uint32 lastTrigger; // Used to store the last firing of the trigger
};

class CTriggerHandler
class CTriggerHandler : public Singleton<CTriggerHandler>
{
public:
virtual ~CTriggerHandler() = default;
static CTriggerHandler* getInstance();

void insertTrigger(Trigger_t);
void triggerTimer();

private:
static std::unique_ptr<CTriggerHandler> _instance;

protected:
CTriggerHandler() = default;

private:
std::vector<Trigger_t> triggerList;
};
#endif
12 changes: 0 additions & 12 deletions src/map/transport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,6 @@
#include "utils/zoneutils.h"
#include "zone.h"

std::unique_ptr<CTransportHandler> CTransportHandler::_instance;

CTransportHandler* CTransportHandler::getInstance()
{
if (!_instance)
{
_instance.reset(new CTransportHandler);
}

return _instance.get();
}

void Transport_Ship::setVisible(bool visible) const
{
if (visible)
Expand Down
Loading

0 comments on commit c302a64

Please sign in to comment.