← Back to file list Raw

src/CConVarManager.cpp

#include "CConVarManager.h"
#include "CEngine.h"
#include "CScriptingManager.h"
#include "ILuaWrapableBase.h"
#include "CWrapable.h"
#include "CAngle.h"
#include <stdexcept>
#include <functional>
#include <map>
#include <vector>
#include <string>
#include <glm/gtc/quaternion.hpp>
#include <glm/glm.hpp>
template<typename T>
std::function<CWrapableBase*(sol::object)> CVarCreateFunction()
{
return [](sol::object obj) -> CWrapableBase*
{
CWrapable<T>* ret = new CWrapable<T>();
if(obj.valid())
{
ILuaWrapableBase* luawrap = dynamic_cast<ILuaWrapableBase*>(ret);
luawrap->SetFromLua(obj);
}
return ret;
};
}
std::vector<std::pair<std::string, std::function<CWrapableBase*(sol::object)>>> CVarTypesTable = //TODO more types! unify types with QuatVecNewFunction (CScriptingEngine)
{
{ "bool", CVarCreateFunction<bool>() },
{ "int", CVarCreateFunction<long long>() },
{ "uint", CVarCreateFunction<unsigned long long>() },
{ "float", CVarCreateFunction<float>() },
{ "double", CVarCreateFunction<double>() },
{ "angle", CVarCreateFunction<CAngle>() },
{ "angles", CVarCreateFunction<CAngles>() },
{ "quat", CVarCreateFunction<glm::quat>() },
{ "vec2", CVarCreateFunction<glm::vec2>() },
{ "vec3", CVarCreateFunction<glm::vec3>() },
{ "vec4", CVarCreateFunction<glm::vec4>() },
{ "string", CVarCreateFunction<std::wstring>() },
{ "string8", CVarCreateFunction<std::string>() },
{ "wstring", CVarCreateFunction<std::wstring>() }
};
std::map<std::string, std::pair<int, std::function<CWrapableBase*(sol::object)>>> CVarTypesTabl =
{
{ "int", { 0, CVarCreateFunction<long long>() } },
{ "uint", { 1, CVarCreateFunction<unsigned long long>() } },
{ "float", { 2, CVarCreateFunction<float>() } },
{ "double", { 3, CVarCreateFunction<double>() } },
{ "angle", { 4, CVarCreateFunction<CAngle>() } },
{ "angles", { 5, CVarCreateFunction<CAngles>() } },
{ "quat", { 6, CVarCreateFunction<glm::quat>() } },
{ "vec2", { 7, CVarCreateFunction<glm::vec2>() } },
{ "vec3", { 8, CVarCreateFunction<glm::vec3>() } },
{ "vec4", { 9, CVarCreateFunction<glm::vec4>() } },
{ "string", { 10, CVarCreateFunction<std::wstring>() } },
{ "string8", { 11, CVarCreateFunction<std::string>() } },
{ "wstring", { 12, CVarCreateFunction<std::wstring>() } },
};
bool CConVarManager::V_Init()
{
return true;
}
bool CConVarManager::IsConVarExist(const std::string& path)
{
return GetConVar(path);
}
CConVarManager::CVarRawPtr CConVarManager::GetConVar(const std::string& path)
{
//std::shared_lock guard(m_Mutex); //TODO is required?
CVarNode* nod = Root.GetNode(path);
if(!nod) { return nullptr; }
return nod->Value.Wrapable ? nod->Value.Wrapable.get() : nullptr;
}
CConVarManager::CVarNode* CConVarManager::AddConVar(const std::string& path, CConVarManager::CVarRawPtr ptr)
{
if(!ptr) { return nullptr; }
//std::lock_guard guard(m_Mutex); //TODO is required?
CVarNode* nod = Root.CreateNode(path);
if(nod->Value.Wrapable) { throw std::runtime_error("Convar already exist"); }
nod->Value.Wrapable = CVarPtr(ptr);
return nod;
}
bool CConVarManager::DeleteConVar(const std::string& path)
{
//std::lock_guard guard(m_Mutex); //TODO is required?
CVarNode* nod = Root.GetNode(path);
if(!nod) { return false; }
Root.DeleteNode(nod);
return true;
}
CConVarManager::CVarNode* CConVarManager::GetRealConVarNode(const std::string& path)
{
//std::shared_lock guard(m_Mutex); //TODO is required?
return Root.GetNode(path);
}
CConVarManager::RealCVar& CConVarManager::GetRealConVar(const std::string& path)
{
//std::shared_lock guard(m_Mutex); //TODO is required?
CVarNode* nod = Root.GetNode(path);
if(!nod) { throw std::runtime_error("No such convar"); }
return nod->Value;
}
bool CConVarManager::V_ScriptInit(std::shared_ptr<sol::state> state, sol::table table)
{
if(state->get<sol::object>("cvar") == sol::lua_nil)
{
sol::table cvar = state->create_named_table("cvar");
sol::table type = cvar.create_named("type");
size_t index = 0;
for(auto& kv : CVarTypesTable)
{
type.set(kv.first, index);
index++;
}
}
table.set_function("getcvar", [this](const std::string& path, sol::this_state ts) -> sol::object
{
if(!IsConVarExist(path)) { return sol::lua_nil; }
auto engine = CEngine::GetInstance()->Components.GetComponentTyped<CScriptingManager>()->GetEngine(ts);
auto cvar = GetRealConVarNode(path);
sol::table ret = cvar->Value.GetScriptTable(ts);
//sol::table ret = engine->ConvarCache.GatedDeleteOrGet(cvar ? cvar->GetPath() : "", cvar);
return ret;
});
table.set_function("createcvar", [this](const std::string& path, int type, sol::object obj, sol::this_state ts) -> sol::object
{
auto cvar = GetConVar(path);
if(cvar) { return sol::lua_nil; }
if(type < 0 || type >= CVarTypesTable.size()) { return sol::lua_nil; }
auto node = AddConVar(path, CVarTypesTable.at(type).second(obj));
auto engine = CEngine::GetInstance()->Components.GetComponentTyped<CScriptingManager>()->GetEngine(ts);
//return engine->ConvarCache.Get(node->GetPath());
return node->Value.GetScriptTable(ts);
});
table.set_function("deletecvar", [this](const std::string& path) -> int
{
return DeleteConVar(path) ? 0 : 1;
});
return true;
}
LINK_SOL_USERTYPE(CConVarManager);
LINK_COMPONENT_TO_CLASS(CConVarManager, convarmanager);