Skip to content

Commit

Permalink
Merge pull request #120 from tiltedphoques/feat/modular-server
Browse files Browse the repository at this point in the history
Modular Server
  • Loading branch information
Yamashi authored Apr 22, 2022
2 parents 86dfa13 + 87b2362 commit d47637d
Show file tree
Hide file tree
Showing 39 changed files with 800 additions and 408 deletions.
3 changes: 3 additions & 0 deletions Code/admin_protocol/xmake.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
target("AdminProtocol")
set_kind("static")
set_group("common")
if is_plat("linux") then
add_cxflags("-fPIC")
end
add_includedirs(".", "../", {public = true})
add_headerfiles("**.h", {prefixdir = "AdminProtocol"})
add_files("**.cpp")
Expand Down
2 changes: 1 addition & 1 deletion Code/client/Services/Generic/InputService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ void ProcessKeyboard(uint16_t aKey, uint16_t aScanCode, cef_key_event_type_t aTy
pRenderer->SetVisible(!active);
#endif

pRenderer->SetCursorVisible(!active);
// pRenderer->SetCursorVisible(!active);

// This is to disable the Windows cursor
while (ShowCursor(FALSE) >= 0)
Expand Down
17 changes: 17 additions & 0 deletions Code/common/GameServerInstance.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#pragma once

class IGameServerInstance
{
public:
virtual ~IGameServerInstance() = default;

// lifetime control
virtual bool Initialize() = 0;
virtual void Shutdown() = 0;

virtual bool IsListening() = 0;
virtual bool IsRunning() = 0;

// update the server logic
virtual void Update() = 0;
};
58 changes: 34 additions & 24 deletions Code/components/console/ConsoleRegistry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,16 @@ ConsoleRegistry::ConsoleRegistry(const char* acLoggerName)
m_out = spdlog::get(acLoggerName);
BASE_ASSERT(m_out.get(), "Output logger not found");

BindStaticItems();
RegisterNatives();
}

ConsoleRegistry::~ConsoleRegistry() = default;

void ConsoleRegistry::BindStaticItems()
{
spdlog::info("ConsoleRegistry::BindStaticItems()");

auto* i = CommandBase::ROOT();
CommandBase::ROOT() = nullptr;
while (i)
Expand All @@ -74,20 +84,12 @@ ConsoleRegistry::ConsoleRegistry(const char* acLoggerName)
k->next = nullptr;
k = j;
}

RegisterNatives();
}

ConsoleRegistry::~ConsoleRegistry()
{
for (CommandBase* c : m_ownedCommands)
delete c;
for (SettingBase* s : m_ownedSettings)
delete s;
}

void ConsoleRegistry::RegisterNatives()
{
spdlog::info("ConsoleRegistry::RegisterNatives()");

RegisterCommand<>("help", "Show a list of commands", [&](const ArgStack&) {
m_out->info("<------Commands-({})--->", m_commands.size());
for (CommandBase* c : m_commands)
Expand Down Expand Up @@ -149,6 +151,9 @@ void ConsoleRegistry::RegisterNatives()
}
}

// signal to the worker thread that we need to flush the settings
MarkDirty();

m_out->info("Set {} to {}", variableName, value);
return;
}
Expand All @@ -157,23 +162,23 @@ void ConsoleRegistry::RegisterNatives()
});
}

void ConsoleRegistry::AddCommand(CommandBase* apCommand)
void ConsoleRegistry::AddCommand(TiltedPhoques::UniquePtr<CommandBase> apCommand)
{
std::lock_guard<std::mutex> _(m_listLock);
(void)_;

// Add to global and tracking pool
m_commands.push_back(apCommand);
m_ownedCommands.push_back(apCommand);
m_commands.push_back(apCommand.get());
m_dynamicCommands.push_back(std::move(apCommand));
}

void ConsoleRegistry::AddSetting(SettingBase* apSetting)
void ConsoleRegistry::AddSetting(TiltedPhoques::UniquePtr<SettingBase> apSetting)
{
std::lock_guard<std::mutex> guard(m_listLock);
(void)guard;

m_settings.push_back(apSetting);
m_ownedSettings.push_back(apSetting);
m_settings.push_back(apSetting.get());
m_dynamicSettings.push_back(std::move(apSetting));
}

CommandBase* ConsoleRegistry::FindCommand(const char* acName)
Expand All @@ -196,28 +201,27 @@ SettingBase* ConsoleRegistry::FindSetting(const char* acName)
return *it;
}

// NOTE(Force): Maybe make this return a status instead?
bool ConsoleRegistry::TryExecuteCommand(const std::string& acLine)
ConsoleRegistry::ExecutionResult ConsoleRegistry::TryExecuteCommand(const std::string& acLine)
{
if (acLine.length() <= 2 || acLine[0] != kCommandPrefix)
{
m_out->error("Commands must begin with /");
return false;
return ExecutionResult::kFailure;
}

size_t tokenCount = 0;
auto tokens = SplitLineTokens(acLine, tokenCount);
if (!tokenCount)
{
m_out->error("Failed to parse line");
return false;
return ExecutionResult::kFailure;
}

auto* pCommand = FindCommand(tokens[0].c_str());
if (!pCommand)
{
m_out->error("Unknown command. Type /help for help.");
return false;
return ExecutionResult::kFailure;
}

// Must subtract one, since the first is the literal command.
Expand All @@ -226,22 +230,28 @@ bool ConsoleRegistry::TryExecuteCommand(const std::string& acLine)
if (tokenCount != pCommand->m_argCount)
{
m_out->error("Expected {} arguments but got {}", pCommand->m_argCount, tokenCount);
return false;
return ExecutionResult::kFailure;
}

ArgStack stack(pCommand->m_argCount);
auto result = CreateArgStack(pCommand, &tokens[1], stack);
if (!result.val)
{
m_out->error(result.msg);
return false;
return ExecutionResult::kFailure;
}

stack.ResetCounter();
m_queue.Upload(pCommand, stack);
StoreCommandInHistory(acLine);

return true;
if (m_requestFlush)
{
m_requestFlush = false;
return ExecutionResult::kDirty;
}

return ExecutionResult::kSuccess;
}

void ConsoleRegistry::StoreCommandInHistory(const std::string& acLine)
Expand Down
51 changes: 40 additions & 11 deletions Code/components/console/ConsoleRegistry.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
// For licensing information see LICENSE at the root of this distribution.
#pragma once

#include <spdlog/spdlog-inl.h>
#include <console/Command.h>
#include <console/Setting.h>
#include <console/CommandQueue.h>
#include <console/Setting.h>
#include <spdlog/spdlog-inl.h>

namespace Console
{
Expand Down Expand Up @@ -34,28 +34,39 @@ template <typename T> struct ResultAnd
class ConsoleRegistry
{
public:
ConsoleRegistry(const char *acLoggerName);
ConsoleRegistry(const char* acLoggerName);
~ConsoleRegistry();

void RegisterNatives();
void BindStaticItems();

template <typename... Ts>
inline void RegisterCommand(const char* acName, const char* acDesc, std::function<void(ArgStack&)> func)
{
AddCommand(new Command<Ts...>(acName, acDesc, func));
AddCommand(
TiltedPhoques::CastUnique<CommandBase>(TiltedPhoques::MakeUnique<Command<Ts...>>(acName, acDesc, func)));
}

inline void RegisterSetting(const char* acName, const char* acDesc, const char* acString)
{
AddSetting(new StringSetting(acName, acDesc, acString));
AddSetting(
TiltedPhoques::CastUnique<SettingBase>(TiltedPhoques::MakeUnique<StringSetting>(acName, acDesc, acString)));
}

template <typename T> inline void RegisterSetting(const char* acName, const char* acDesc, const T acDefault)
{
AddSetting(new Setting<T>(acName, acDesc, acDefault));
AddSetting(
TiltedPhoques::CastUnique<SettingBase>(TiltedPhoques::MakeUnique<Setting<T>>(acName, acDesc, acDefault)));
}

bool TryExecuteCommand(const std::string& acLine);
enum class ExecutionResult
{
kFailure,
kSuccess,
kDirty
};

ExecutionResult TryExecuteCommand(const std::string& acLine);

CommandBase* FindCommand(const char* acName);
SettingBase* FindSetting(const char* acName);
Expand All @@ -70,21 +81,39 @@ class ConsoleRegistry
// Call this from your main thread, this will drain the work item queue.
bool Update();

template <typename T> void ForAllCommands(T functor)
{
for (auto& c : m_commands)
functor(c);
}

template <typename T> void ForAllSettings(T functor)
{
for (auto& c : m_settings)
functor(c);
}

void MarkDirty() noexcept
{
m_requestFlush = true;
}

private:
void AddCommand(CommandBase* apCommand);
void AddSetting(SettingBase* apSetting);
void AddCommand(TiltedPhoques::UniquePtr<CommandBase> apCommand);
void AddSetting(TiltedPhoques::UniquePtr<SettingBase> apSetting);
void StoreCommandInHistory(const std::string& acLine);

ResultAnd<bool> CreateArgStack(const CommandBase* apCommand, const std::string* acStringArgs, ArgStack& aStackOut);

private:
std::mutex m_listLock;
TiltedPhoques::Vector<CommandBase*> m_commands;
TiltedPhoques::Vector<CommandBase*> m_ownedCommands;
TiltedPhoques::Vector<SettingBase*> m_settings;
TiltedPhoques::Vector<SettingBase*> m_ownedSettings;
TiltedPhoques::Vector<UniquePtr<CommandBase>> m_dynamicCommands;
TiltedPhoques::Vector<UniquePtr<SettingBase>> m_dynamicSettings;
TiltedPhoques::Vector<std::string> m_commandHistory;
CommandQueue m_queue;
bool m_requestFlush = true;

std::shared_ptr<spdlog::logger> m_out;
};
Expand Down
34 changes: 10 additions & 24 deletions Code/components/console/IniSettingsProvider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <console/IniSettingsProvider.h>
#include <console/ConsoleUtils.h>
#include <console/Setting.h>
#include <console/ConsoleRegistry.h>

#include <charconv>
#include <fstream>
Expand All @@ -17,14 +18,6 @@ namespace Console
{
namespace
{
static void ShittyFileWrite(const std::filesystem::path& path, const std::string& data)
{
// TODO: Get rid of this, its horrible.
std::ofstream myfile(path.c_str());
myfile << data.c_str();
myfile.close();
}

template <typename T, typename TVal>
static SI_Error SetIniValue(CSimpleIni& ini, const T* a_pSection, const T* a_pKey, const TVal a_nValue,
const T* a_pComment = nullptr)
Expand Down Expand Up @@ -70,21 +63,12 @@ std::pair<std::string, std::string> SplitSection(const SettingBase* setting)
}
} // namespace

void SaveSettingsToIni(const std::filesystem::path& aPath, bool aFirstRun)
void SaveSettingsToIni(ConsoleRegistry& aReg, const std::filesystem::path& aPath)
{
CSimpleIni ini;

SI_Error error{SI_Error::SI_OK};

SettingBase::VisitAll([&](SettingBase* setting) {
// In first run mode we dont write hidden settings. so the user will be less
// aware of them
if (aFirstRun)
{
if (setting->IsHidden())
return;
}

aReg.ForAllSettings([&](SettingBase* setting) {
auto items = SplitSection(setting);
auto& section = items.first;
auto& name = items.second;
Expand Down Expand Up @@ -124,20 +108,22 @@ void SaveSettingsToIni(const std::filesystem::path& aPath, bool aFirstRun)
});

std::string buf;
ini.Save(buf, true);
error = ini.Save(buf, true);
BASE_ASSERT(error == SI_Error::SI_OK, "Saving the ini failed");

ShittyFileWrite(aPath, buf);
// TODO(Vince): eventually we shall burn the ini library
TiltedPhoques::SaveFile(aPath, TiltedPhoques::String(buf));
}

void LoadSettingsFromIni(const std::filesystem::path& aPath)
void LoadSettingsFromIni(ConsoleRegistry& aReg, const std::filesystem::path& aPath)
{
CSimpleIni ini;
{
auto buf = TiltedPhoques::LoadFile(aPath);
ini.LoadData(buf.c_str());
BASE_ASSERT(ini.LoadData(buf.c_str()) == SI_Error::SI_OK, "Failed to load ini data");
}

SettingBase::VisitAll([&](SettingBase* setting) {
aReg.ForAllSettings([&](SettingBase* setting) {
auto items = SplitSection(setting);
auto& section = items.first;
auto& name = items.second;
Expand Down
6 changes: 4 additions & 2 deletions Code/components/console/IniSettingsProvider.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

namespace Console
{
void SaveSettingsToIni(const std::filesystem::path& aPath, bool aFirstRun = false);
void LoadSettingsFromIni(const std::filesystem::path& aPath);
class ConsoleRegistry;

void SaveSettingsToIni(ConsoleRegistry& aReg, const std::filesystem::path& path);
void LoadSettingsFromIni(ConsoleRegistry& aReg, const std::filesystem::path& path);
} // namespace base
Loading

0 comments on commit d47637d

Please sign in to comment.