Skip to content

Commit

Permalink
[#5] updates to config::Config, definition of cemuhook::Config
Browse files Browse the repository at this point in the history
  • Loading branch information
kmicki committed Jun 14, 2022
1 parent aeb360d commit f3c6e44
Show file tree
Hide file tree
Showing 5 changed files with 249 additions and 11 deletions.
25 changes: 21 additions & 4 deletions inc/cemuhook/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,32 @@ namespace kmicki::cemuhook
Config() = delete;
Config(std::vector<std::unique_ptr<ConfigItemBase>> & _configData);

ConfigInterface const& Interface() const;
int const& Port() const;
ConfigInterface const& Interface() const; // cemuhook.server.interface
int const& Port() const; // cemuhook.server.port

virtual void Load();
virtual void Save();
using SubscriptionCallback = void (*)();

void SubscribeToChange(SubscriptionCallback callback, void* marker = nullptr);
void Unsubscribe(void* marker = nullptr);

virtual void Load() override;
virtual void Save() override;
virtual void ToDefault() override;

private:

ConfigInterface interface;
int port;

struct Subscription
{
void* marker;
SubscriptionCallback callback;
};

std::vector<Subscription> subscriptions;

void FireSubscriptions();
};
}

Expand Down
32 changes: 32 additions & 0 deletions inc/config/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,47 @@ namespace kmicki::config
// values in configData can also be changed without this method being called
virtual void Save() = 0;

// set default values
virtual void ToDefault() = 0;

using SubscriptionCallback = void (*)();

void SubscribeToChange(SubscriptionCallback callback, void* marker = nullptr);
void Unsubscribe(void* marker = nullptr);

protected:
std::vector<std::unique_ptr<ConfigItemBase>> & configData;

template<class T>
void SetValue(std::string const& name, T const& value);

template<class T>
bool GetValue(std::string const& name, T * value) const;

template<class T>
bool GetValue(std::string const& name, T * value, bool & subscription) const;

template<class T>
T const& GetValue(std::string const& name) const;

template<class T>
bool GetItem(std::string const& name, ConfigItem<T> * item) const;

void FireSubscriptions();

private:

struct Subscription
{
void* marker;
SubscriptionCallback callback;
};

std::vector<Subscription> subscriptions;

};
}

#include "config.hpp"

#endif
81 changes: 81 additions & 0 deletions inc/config/config.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#include "config.h"
#include <stdexcept>

namespace kmicki::config
{
template<class T>
ConfigItem<T>::ConfigItem(std::string const& name, T const& val)
{
Name = name;
Val = val;
}

template<class T>
void Config::SetValue<T>(std::string const& name, T const& value)
{
auto item = std::find_if(configData.begin(),configData.end(),
[&](std::unique_ptr<ConfigItemBase> const& x { x->Name == name });

if(item == configData.end())
{
configData.emplace_back(new ConfigItem(name,value));
return;
}

item->Val = value;
}

template<class T>
bool Config::GetItem<T>(std::string const& name, ConfigItem<T> * value) const
{
auto item = std::find_if(configData.begin(),configData.end(),
[&](std::unique_ptr<ConfigItemBase> const& x { x->Name == name });

if(item == configData.end())
{
value = nullptr;
return false;
}

value = &*item;
return true;
}

template<class T>
bool Config::GetValue<T>(std::string const& name, T * value) const
{
ConfigItem<T> * item;
if(!GetItem(name,item))
{
value = nullptr;
return false;
}

value = item->Val;
return true;
}

template<class T>
bool Config::GetValue<T>(std::string const& name, T * value, bool & susbscription) const
{
T * item;
if(!GetItem(name,item))
return false;

if(*value != *item)
susbscription = true;

value = item;
return true;
}

template<class T>
T const& Config::GetValue<T>(std::string const& name) const
{
T* value;
if(!GetValue(name,value))
throw std::invalid_argument("name");

return *value;
}
}
88 changes: 88 additions & 0 deletions src/cemuhook/config.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#include "cemuhook/config.h"
#include <sstream>
#include <algorithm>

namespace kmicki::config
{
using ConfigInterface = cemuhook::ConfigInterface;
static const int cConfigInterfaceEnumLen = 2;
static std::string cConfigInterfaceStrVals[cEnumLen] = { "local" , "all" };

template<>
bool ConfigItem<ConfigInterface>::Update(std::string const& value,std::string & message)
{

std::string strVal(value.length(),' ');
std::transform(value.begin(),value.end(),strVal.begin(),[](char c){ return std::tolower(c); });
for (int i = 0; i < cConfigInterfaceEnumLen; ++i)
if (strVal == cConfigInterfaceStrVals[i])
{
Val = (ConfigInterface)i;
std::ostringstream str;
str << "existing item value updated (type: string), Name=" << Name << " Value=" << strVal;
message = str.str();
return true;
}

std::ostringstream str;
str << "value invalid (type: interface), Name=" << Name << " Value=" << value;
message = str.str();
return false;
}

template<>
std::string ConfigItem<ConfigInterface>::ValToString() const
{
if(Val >= 0 && Val <= cConfigInterfaceEnumLen)
return cConfigInterfaceStrVals[Val];
return "";
}

template struct ConfigItem<ConfigInterface>;
}

namespace kmicki::cemuhook
{
static const std::string cPrefix = "server.";

Config::Config(std::vector<std::unique_ptr<ConfigItemBase>> & _configData)
: config::Config(_configData)
{
ToDefault();
Load();
}

ConfigInterface const& Config::Interface() const
{
return interface;
}

int const& Config::Port() const
{
return port;
}

static const std::string cInterfaceStr = cPrefix + "interface";
static const std::string cPortStr = cPrefix + "port";

void Config::Load()
{
bool subscription = false;
GetValue(cInterfaceStr,&interface,subscription);
GetValue(cPortStr,&port,subscription);
if(subscription)
FireSubscriptions();
}

void Config::Save()
{
SetValue(cInterfaceStr,interface);
SetValue(cPortStr,port);
}

void Config::ToDefault()
{
static const ConfigInterface cInterfaceDefault = CfgIfAll;
static const int cPortDefault = 26760;
}
}
34 changes: 27 additions & 7 deletions src/config/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,6 @@

namespace kmicki::config
{
template<class T>
ConfigItem<T>::ConfigItem(std::string const& name, T const& val)
{
Name = name;
Val = val;
}

template<>
bool ConfigItem<std::string>::Update(std::string const& value,std::string & message)
{
Expand Down Expand Up @@ -107,4 +100,31 @@ namespace kmicki::config
{
return configData;
}

void Config::FireSubscriptions()
{
for(auto& sub : subscriptions)
sub.callback();
}

void Config::SubscribeToChange(SubscriptionCallback callback, void* marker = nullptr)
{
if(callback == nullptr)
return;

Unsubscribe(marker);

auto &sub = subscriptions.emplace_back();
sub.callback = callback;
sub.marker = marker;
}

void Config::Unsubscribe(void* marker = nullptr)
{
auto sub = std::find_if(subscriptions.begin(),subscriptions.end(),[&](auto const& x){ return x.marker == marker; });
if(sub == subscriptions.end())
return;

subscriptions.erase(sub);
}
}

0 comments on commit f3c6e44

Please sign in to comment.