Skip to content

Commit

Permalink
[Enhancement] Decouple all global variables from extern in true singl…
Browse files Browse the repository at this point in the history
…eton (#325)

All the global variables * g_* were decoupled to true singletons, reducing the dependencies between the objects and simplifying the amount of calls and instances. They used to be partial singletons mixed with global variables, that way we have one, and only one instance that is accessed via the getInstance methods, that are now the * g_* functions.

Changes:

g_actions
g_chat
g_config
g_creatureEvents
g_database
g_databaseTasks
g_decay
g_dispatcher
g_events
g_game
g_globalEvents
g_luaEnvironment
g_modules
g_monsters
g_moveEvents
g_npc
g_npcs
g_RSA
g_scheduler
g_scripts
g_spells
g_talkActions
g_vocations
g_weapons

The * g_luaEnvironment has been decoupled using inline, new feature of c++17
  • Loading branch information
beats-dh committed Apr 24, 2022
1 parent 1da1ac1 commit b87372f
Show file tree
Hide file tree
Showing 97 changed files with 663 additions and 701 deletions.
17 changes: 7 additions & 10 deletions src/creatures/combat/combat.cpp
Expand Up @@ -28,9 +28,6 @@
#include "creatures/monsters/monsters.h"
#include "items/weapons/weapons.h"

extern Weapons* g_weapons;
extern Events* g_events;
extern Monsters g_monsters;

CombatDamage Combat::getCombatDamage(Creature* creature, Creature* target) const
{
Expand All @@ -57,7 +54,7 @@ CombatDamage Combat::getCombatDamage(Creature* creature, Creature* target) const
);
} else if (formulaType == COMBAT_FORMULA_SKILL) {
Item* tool = player->getWeapon();
const Weapon* weapon = g_weapons->getWeapon(tool);
const Weapon* weapon = g_weapons().getWeapon(tool);
if (weapon) {
damage.primary.value = normal_random(
static_cast<int32_t>(minb),
Expand Down Expand Up @@ -265,7 +262,7 @@ ReturnValue Combat::canDoCombat(Creature* caster, Tile* tile, bool aggressive)
return RETURNVALUE_ACTIONNOTPERMITTEDINPROTECTIONZONE;
}

return g_events->eventCreatureOnAreaCombat(caster, tile, aggressive);
return g_events().eventCreatureOnAreaCombat(caster, tile, aggressive);
}

bool Combat::isInPvpZone(const Creature* attacker, const Creature* target)
Expand Down Expand Up @@ -381,7 +378,7 @@ ReturnValue Combat::canDoCombat(Creature* attacker, Creature* target)
}
}
}
return g_events->eventCreatureOnTargetCombat(attacker, target);
return g_events().eventCreatureOnTargetCombat(attacker, target);
}

void Combat::setPlayerCombatValues(formulaType_t newFormulaType, double newMina, double newMinb, double newMaxa, double newMaxb)
Expand Down Expand Up @@ -501,7 +498,7 @@ void Combat::CombatHealthFunc(Creature* caster, Creature* target, const CombatPa
if (caster && caster->getPlayer()) {
Item *item = caster->getPlayer()->getWeapon();
damage = applyImbuementElementalDamage(item, damage);
g_events->eventPlayerOnCombat(caster->getPlayer(), target, item, damage);
g_events().eventPlayerOnCombat(caster->getPlayer(), target, item, damage);

if (target && target->getSkull() != SKULL_BLACK && target->getPlayer()) {
damage.primary.value /= 2;
Expand Down Expand Up @@ -578,7 +575,7 @@ void Combat::CombatConditionFunc(Creature* caster, Creature* target, const Comba
} else if (caster && caster->getMonster()) {
uint16_t playerCharmRaceid = player->parseRacebyCharm(CHARM_CLEANSE, false, 0);
if (playerCharmRaceid != 0) {
MonsterType* mType = g_monsters.getMonsterType(caster->getName());
const MonsterType* mType = g_monsters().getMonsterType(caster->getName());
if (mType && playerCharmRaceid == mType->info.raceid) {
IOBestiary g_bestiary;
Charm* charm = g_bestiary.getBestiaryCharm(CHARM_CLEANSE);
Expand Down Expand Up @@ -903,7 +900,7 @@ void Combat::doCombatHealth(Creature* caster, Creature* target, CombatDamage& da
if (target && target->getMonster() && damage.primary.type != COMBAT_HEALING) {
uint16_t playerCharmRaceid = caster->getPlayer()->parseRacebyCharm(CHARM_LOW, false, 0);
if (playerCharmRaceid != 0) {
MonsterType* mType = g_monsters.getMonsterType(target->getName());
const MonsterType* mType = g_monsters().getMonsterType(target->getName());
if (mType && playerCharmRaceid == mType->info.raceid) {
IOBestiary g_bestiary;
Charm* charm = g_bestiary.getBestiaryCharm(CHARM_LOW);
Expand Down Expand Up @@ -1106,7 +1103,7 @@ void ValueCallback::getMinMaxValues(Player* player, CombatDamage& damage, bool u
case COMBAT_FORMULA_SKILL: {
//onGetPlayerMinMaxValues(player, attackSkill, attackValue, attackFactor)
Item* tool = player->getWeapon();
const Weapon* weapon = g_weapons->getWeapon(tool);
const Weapon* weapon = g_weapons().getWeapon(tool);
Item* item = nullptr;

if (weapon) {
Expand Down
5 changes: 2 additions & 3 deletions src/creatures/combat/condition.cpp
Expand Up @@ -22,7 +22,6 @@
#include "creatures/combat/condition.h"
#include "game/game.h"

extern Monsters g_monsters;

bool Condition::setParam(ConditionParam_t param, int32_t value)
{
Expand Down Expand Up @@ -1655,7 +1654,7 @@ void ConditionOutfit::serialize(PropWriteStream& propWriteStream)
bool ConditionOutfit::startCondition(Creature* creature)
{
if ((outfit.lookType == 0 && outfit.lookTypeEx == 0) && !monsterName.empty()) {
MonsterType* monsterType = g_monsters.getMonsterType(monsterName);
const MonsterType* monsterType = g_monsters().getMonsterType(monsterName);
if (monsterType) {
setOutfit(monsterType->info.outfit);
} else {
Expand Down Expand Up @@ -1689,7 +1688,7 @@ void ConditionOutfit::addCondition(Creature* creature, const Condition* addCondi

const ConditionOutfit& conditionOutfit = static_cast<const ConditionOutfit&>(*addCondition);
if (!conditionOutfit.monsterName.empty() && conditionOutfit.monsterName.compare(monsterName) != 0) {
MonsterType* monsterType = g_monsters.getMonsterType(conditionOutfit.monsterName);
const MonsterType* monsterType = g_monsters().getMonsterType(conditionOutfit.monsterName);
if (monsterType) {
setOutfit(monsterType->info.outfit);
} else {
Expand Down
10 changes: 2 additions & 8 deletions src/creatures/combat/spells.cpp
Expand Up @@ -25,12 +25,6 @@
#include "game/game.h"
#include "lua/scripts/lua_environment.hpp"
#include "utils/pugicast.h"

extern Spells* g_spells;
extern Monsters g_monsters;
extern Vocations g_vocations;
extern LuaEnvironment g_luaEnvironment;

Spells::Spells()
{
scriptInterface.initState();
Expand Down Expand Up @@ -333,7 +327,7 @@ Position Spells::getCasterPosition(Creature* creature, Direction dir)
}

CombatSpell::CombatSpell(Combat* initCombat, bool initNeedTarget, bool initNeedDirection) :
Event(&g_spells->getScriptInterface()),
Event(&g_spells().getScriptInterface()),
combat(initCombat),
needDirection(initNeedDirection),
needTarget(initNeedTarget)
Expand Down Expand Up @@ -611,7 +605,7 @@ bool Spell::configureSpell(const pugi::xml_node& node)
continue;
}

int32_t vocationId = g_vocations.getVocationId(attr.as_string());
int32_t vocationId = g_vocations().getVocationId(attr.as_string());
if (vocationId != -1) {
attr = vocationNode.attribute("showInDescription");
vocSpellMap[vocationId] = !attr || attr.as_bool();
Expand Down
9 changes: 9 additions & 0 deletions src/creatures/combat/spells.h
Expand Up @@ -44,6 +44,13 @@ class Spells final : public BaseEvents
Spells(const Spells&) = delete;
Spells& operator=(const Spells&) = delete;

static Spells& getInstance() {
// Guaranteed to be destroyed
static Spells instance;
// Instantiated on first use
return instance;
}

Spell* getSpellByName(const std::string& name);
RuneSpell* getRuneSpell(uint32_t id);
RuneSpell* getRuneSpellByName(const std::string& name);
Expand Down Expand Up @@ -88,6 +95,8 @@ class Spells final : public BaseEvents
LuaScriptInterface scriptInterface { "Spell Interface" };
};

constexpr auto g_spells = &Spells::getInstance;

using RuneSpellFunction = std::function<bool(const RuneSpell* spell, Player* player, const Position& posTo)>;

class BaseSpell
Expand Down
19 changes: 9 additions & 10 deletions src/creatures/creature.cpp
Expand Up @@ -29,7 +29,6 @@ double Creature::speedA = 857.36;
double Creature::speedB = 261.29;
double Creature::speedC = -4795.01;

extern CreatureEvents* g_creatureEvents;

Creature::Creature()
{
Expand Down Expand Up @@ -282,13 +281,13 @@ void Creature::addEventWalk(bool firstStep)
g_game().checkCreatureWalk(getID());
}

eventWalk = g_scheduler.addEvent(createSchedulerTask(static_cast<uint32_t>(ticks), std::bind(&Game::checkCreatureWalk, &g_game(), getID())));
eventWalk = g_scheduler().addEvent(createSchedulerTask(static_cast<uint32_t>(ticks), std::bind(&Game::checkCreatureWalk, &g_game(), getID())));
}

void Creature::stopEventWalk()
{
if (eventWalk != 0) {
g_scheduler.stopEvent(eventWalk);
g_scheduler().stopEvent(eventWalk);
eventWalk = 0;
}
}
Expand Down Expand Up @@ -606,7 +605,7 @@ void Creature::onCreatureMove(Creature* creature, const Tile* newTile, const Pos
if (followCreature && (creature == this || creature == followCreature)) {
if (hasFollowPath) {
isUpdatingPath = true;
g_dispatcher.addTask(createTask(std::bind(&Game::updateCreatureWalk, &g_game(), getID())));
g_dispatcher().addTask(createTask(std::bind(&Game::updateCreatureWalk, &g_game(), getID())));
}

if (newPos.z != oldPos.z || !canSee(followCreature->getPosition())) {
Expand All @@ -620,7 +619,7 @@ void Creature::onCreatureMove(Creature* creature, const Tile* newTile, const Pos
} else {
if (hasExtraSwing()) {
//our target is moving lets see if we can get in hit
g_dispatcher.addTask(createTask(std::bind(&Game::checkCreatureAttack, &g_game(), getID())));
g_dispatcher().addTask(createTask(std::bind(&Game::checkCreatureAttack, &g_game(), getID())));
}

if (newTile->getZone() != oldTile->getZone()) {
Expand Down Expand Up @@ -769,7 +768,7 @@ bool Creature::dropCorpse(Creature* lastHitCreature, Creature* mostDamageCreatur

if (g_configManager().getBoolean(AUTOLOOT)) {
int32_t pos = tile->getStackposOfItem(player, corpse);
g_dispatcher.addTask(createTask(std::bind(&Game::playerQuickLoot, &g_game(), mostDamageCreature->getID(), this->getPosition(), corpse->getClientID(), pos - 1, nullptr, false, true)));
g_dispatcher().addTask(createTask(std::bind(&Game::playerQuickLoot, &g_game(), mostDamageCreature->getID(), this->getPosition(), corpse->getClientID(), pos - 1, nullptr, false, true)));
}
}
}
Expand Down Expand Up @@ -813,7 +812,7 @@ void Creature::changeHealth(int32_t healthChange, bool sendHealthChange/* = true
g_game().addCreatureHealth(this);
}
if (health <= 0) {
g_dispatcher.addTask(createTask(std::bind(&Game::executeDeath, &g_game(), getID())));
g_dispatcher().addTask(createTask(std::bind(&Game::executeDeath, &g_game(), getID())));
}
}

Expand Down Expand Up @@ -1285,7 +1284,7 @@ void Creature::removeCondition(ConditionType_t conditionType, ConditionId_t cond
if (!force && conditionType == CONDITION_PARALYZE) {
int32_t walkDelay = getWalkDelay();
if (walkDelay > 0) {
g_scheduler.addEvent(createSchedulerTask(walkDelay, std::bind(&Game::forceRemoveCondition, &g_game(), getID(), conditionType, conditionId)));
g_scheduler().addEvent(createSchedulerTask(walkDelay, std::bind(&Game::forceRemoveCondition, &g_game(), getID(), conditionType, conditionId)));
return;
}
}
Expand Down Expand Up @@ -1468,7 +1467,7 @@ void Creature::setNormalCreatureLight()

bool Creature::registerCreatureEvent(const std::string& name)
{
CreatureEvent* event = g_creatureEvents->getEventByName(name);
CreatureEvent* event = g_creatureEvents().getEventByName(name);
if (!event) {
return false;
}
Expand All @@ -1490,7 +1489,7 @@ bool Creature::registerCreatureEvent(const std::string& name)

bool Creature::unregisterCreatureEvent(const std::string& name)
{
CreatureEvent* event = g_creatureEvents->getEventByName(name);
const CreatureEvent* event = g_creatureEvents().getEventByName(name);
if (!event) {
return false;
}
Expand Down
11 changes: 5 additions & 6 deletions src/creatures/interactions/chat.cpp
Expand Up @@ -24,7 +24,6 @@
#include "utils/pugicast.h"
#include "game/scheduling/scheduler.h"

extern Chat* g_chat;

bool PrivateChatChannel::isInvited(uint32_t guid) const
{
Expand Down Expand Up @@ -99,7 +98,7 @@ bool ChatChannel::addUser(Player& player)
if (id == CHANNEL_GUILD) {
Guild* guild = player.getGuild();
if (guild && !guild->getMotd().empty()) {
g_scheduler.addEvent(createSchedulerTask(150, std::bind(&Game::sendGuildMotd, &g_game(), player.getID())));
g_scheduler().addEvent(createSchedulerTask(150, std::bind(&Game::sendGuildMotd, &g_game(), player.getID())));
}
}

Expand Down Expand Up @@ -162,7 +161,7 @@ bool ChatChannel::executeCanJoinEvent(const Player& player)
}

//canJoin(player)
LuaScriptInterface* scriptInterface = g_chat->getScriptInterface();
LuaScriptInterface* scriptInterface = g_chat().getScriptInterface();
if (!scriptInterface->reserveScriptEnv()) {
SPDLOG_ERROR("[CanJoinChannelEvent::execute - Player {}, on channel {}] "
"Call stack overflow. Too many lua script calls being nested.",
Expand All @@ -189,7 +188,7 @@ bool ChatChannel::executeOnJoinEvent(const Player& player)
}

//onJoin(player)
LuaScriptInterface* scriptInterface = g_chat->getScriptInterface();
LuaScriptInterface* scriptInterface = g_chat().getScriptInterface();
if (!scriptInterface->reserveScriptEnv()) {
SPDLOG_ERROR("[OnJoinChannelEvent::execute - Player {}, on channel {}] "
"Call stack overflow. Too many lua script calls being nested",
Expand All @@ -216,7 +215,7 @@ bool ChatChannel::executeOnLeaveEvent(const Player& player)
}

//onLeave(player)
LuaScriptInterface* scriptInterface = g_chat->getScriptInterface();
LuaScriptInterface* scriptInterface = g_chat().getScriptInterface();
if (!scriptInterface->reserveScriptEnv()) {
SPDLOG_ERROR("[OnLeaveChannelEvent::execute - Player {}, on channel {}] "
"Call stack overflow. Too many lua script calls being nested.",
Expand All @@ -243,7 +242,7 @@ bool ChatChannel::executeOnSpeakEvent(const Player& player, SpeakClasses& type,
}

//onSpeak(player, type, message)
LuaScriptInterface* scriptInterface = g_chat->getScriptInterface();
LuaScriptInterface* scriptInterface = g_chat().getScriptInterface();
if (!scriptInterface->reserveScriptEnv()) {
SPDLOG_ERROR("[OnSpeakChannelEvent::execute - Player {}, type {}] "
"Call stack overflow. Too many lua script calls being nested.",
Expand Down
9 changes: 9 additions & 0 deletions src/creatures/interactions/chat.h
Expand Up @@ -127,6 +127,13 @@ class Chat
Chat(const Chat&) = delete;
Chat& operator=(const Chat&) = delete;

static Chat& getInstance() {
// Guaranteed to be destroyed
static Chat instance;
// Instantiated on first use
return instance;
}

bool load();

ChatChannel* createChannel(const Player& player, uint16_t channelId);
Expand Down Expand Up @@ -160,4 +167,6 @@ class Chat
PrivateChatChannel dummyPrivate;
};

constexpr auto g_chat = &Chat::getInstance;

#endif // SRC_CREATURES_INTERACTIONS_CHAT_H_
8 changes: 3 additions & 5 deletions src/creatures/monsters/monster.cpp
Expand Up @@ -26,8 +26,6 @@
#include "creatures/combat/spells.h"
#include "lua/creature/events.h"

extern Monsters g_monsters;
extern Events* g_events;

int32_t Monster::despawnRange;
int32_t Monster::despawnRadius;
Expand All @@ -36,7 +34,7 @@ uint32_t Monster::monsterAutoID = 0x40000000;

Monster* Monster::createMonster(const std::string& name)
{
MonsterType* mType = g_monsters.getMonsterType(name);
MonsterType* mType = g_monsters().getMonsterType(name);
if (!mType) {
return nullptr;
}
Expand Down Expand Up @@ -737,7 +735,7 @@ bool Monster::selectTarget(Creature* creature)

if (isHostile() || isSummon()) {
if (setAttackedCreature(creature) && !isSummon()) {
g_dispatcher.addTask(createTask(std::bind(&Game::checkCreatureAttack, &g_game(), getID())));
g_dispatcher().addTask(createTask(std::bind(&Game::checkCreatureAttack, &g_game(), getID())));
}
}
return setFollowCreature(creature);
Expand Down Expand Up @@ -2042,7 +2040,7 @@ void Monster::updateLookDirection()
void Monster::dropLoot(Container* corpse, Creature*)
{
if (corpse && lootDrop) {
g_events->eventMonsterOnDropLoot(this, corpse);
g_events().eventMonsterOnDropLoot(this, corpse);
}
}

Expand Down

0 comments on commit b87372f

Please sign in to comment.