Created
          January 22, 2020 09:47 
        
      - 
      
 - 
        
Save untodesu/164e5a28c7a4202ff7b21ca2f388550d to your computer and use it in GitHub Desktop.  
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | #include <cstdint> // uint32_t | |
| #include <cstddef> // size_t | |
| #include <cstring> // strcmp, strncpy | |
| #include <cstdlib> // atoi, atof | |
| #include <string> // std::to_string | |
| #include "cvardef.h" | |
| #include "cvar.h" | |
| //----------------------------------------------------------------------------- | |
| // s_cvars | |
| // Global list head | |
| //----------------------------------------------------------------------------- | |
| static cvar_t *s_cvars = nullptr; | |
| //----------------------------------------------------------------------------- | |
| // CVar_FindVar | |
| // Find and return the pointer to existing variable | |
| // Returns null if not found | |
| //----------------------------------------------------------------------------- | |
| cvar_t * CVar_FindVar(const char *name) | |
| { | |
| for(cvar_t *cvar = s_cvars; cvar; cvar = cvar->next) { | |
| if(!strcmp(cvar->name, name)) { | |
| return cvar; | |
| } | |
| } | |
| return nullptr; | |
| } | |
| //----------------------------------------------------------------------------- | |
| // CVar_Register | |
| // Registers new variable | |
| //----------------------------------------------------------------------------- | |
| void CVar_Register(cvar_t *cvar, const char *value) | |
| { | |
| if(CVar_FindVar(cvar.name)) { | |
| // Already defined? | |
| return; | |
| } | |
| // todo: concommand checks - UNUSED: COMMANDS WRAP CVARS | |
| // Registering will force heap allocation | |
| // so we pick this values | |
| const char *oldstr = cvar.value; | |
| const size_t len = strlen(oldstr); | |
| // Make cvar use heap for values | |
| cvar.value = new char[len + 1]; | |
| cvar.value[len] = 0; // null terminator | |
| strncpy(cvar.value, oldstr, len); | |
| // Add new cvar to list | |
| cvar.next = s_cvars; | |
| s_cvars = &cvar; | |
| } | |
| //----------------------------------------------------------------------------- | |
| // CVar_Unregister | |
| // Revert CVar_Register | |
| //----------------------------------------------------------------------------- | |
| void CVar_Unregister(cvar_t &cvar) | |
| { | |
| cvar_t *prev = s_cvars; | |
| for(cvar_t *node = s_cvars; node; node = node->next) { | |
| if(node == &cvar) { | |
| // If we have last added node, | |
| // we don't have prev value, so we just move previous thing forward | |
| if(node == s_cvars) { | |
| s_cvars = s_cvars->next; | |
| } | |
| // else - we have valid prev value, so replace em | |
| else { | |
| prev->next = node->next; | |
| } | |
| delete[] cvar.value; | |
| cvar.value = nullptr; | |
| cvar.next = nullptr; | |
| return; | |
| } | |
| prev = node; | |
| } | |
| } | |
| //----------------------------------------------------------------------------- | |
| // CVar_SetValue | |
| // Sets string value of cvar | |
| //----------------------------------------------------------------------------- | |
| void CVar_SetValue(const char *name, const char *value) | |
| { | |
| cvar_t *cvar = CVar_FindVar(name); | |
| if(!cvar) { | |
| // we cannot set the empty variable | |
| return; | |
| } | |
| // We can set variable only if the FCVAR_READONLY is not set | |
| if(!(cvar->flags & FCVAR_READONLY)) { | |
| const size_t len = strlen(value); | |
| // Re-allocate | |
| delete cvar->value; | |
| cvar->value = new char[len + 1]; | |
| cvar->value[len] = 0; // null-terminator | |
| strncpy(cvar->value, value, len); | |
| // todo: Do some other stuff | |
| } | |
| } | |
| //----------------------------------------------------------------------------- | |
| // CVar_GetValue | |
| // | |
| //----------------------------------------------------------------------------- | |
| const char * CVar_GetValue(const char *name) | |
| { | |
| static const char *s_defaultValue = ""; | |
| cvar_t *cvar = CVar_FindVar(name); | |
| if(!cvar) { | |
| return s_defaultValue; | |
| } | |
| return cvar->value; | |
| } | |
| //----------------------------------------------------------------------------- | |
| //----------------------------------------------------------------------------- | |
| //----------------------------------------------------------------------------- | |
| //----------------------------------------------------------------------------- | |
| // CVar::CVar | |
| // Constructor | |
| //----------------------------------------------------------------------------- | |
| CVar::CVar(const char *name, const char *value, uint32_t flags) : cvar_t(*this) | |
| { | |
| const size_t vlen = strlen(value); | |
| char *dummy = new char[vlen]; | |
| strncpy(dummy, value, vlen); | |
| // cvar_t inherited | |
| this->name = name; | |
| this->value = dummy; | |
| this->flags = flags; | |
| CVar_Register(*this); | |
| delete[] dummy; | |
| } | |
| //----------------------------------------------------------------------------- | |
| // CVar::~CVar | |
| // Destructor | |
| //----------------------------------------------------------------------------- | |
| CVar::~CVar(void) | |
| { | |
| CVar_Unregister(*this); | |
| } | |
| //----------------------------------------------------------------------------- | |
| // CVar::IsValid | |
| // | |
| //----------------------------------------------------------------------------- | |
| bool CVar::IsValid(void) const | |
| { | |
| // we cannot use m_me here cuz reference | |
| return !!CVar_FindVar(this->name); | |
| } | |
| //----------------------------------------------------------------------------- | |
| // CVar::GetString | |
| // Data accessor | |
| //----------------------------------------------------------------------------- | |
| const char * CVar::GetString(void) const | |
| { | |
| return this->value; | |
| } | |
| //----------------------------------------------------------------------------- | |
| // CVar::GetInt | |
| // Data accessor | |
| //----------------------------------------------------------------------------- | |
| int CVar::GetInt(void) const | |
| { | |
| if(IsValid()) { | |
| return std::atoi(this->value); | |
| } | |
| return 0; | |
| } | |
| //----------------------------------------------------------------------------- | |
| // CVar::GetFloat | |
| // Data accessor | |
| //----------------------------------------------------------------------------- | |
| double CVar::GetFloat(void) const | |
| { | |
| if(IsValid()) { | |
| return std::atof(this->value); | |
| } | |
| return 0.0; | |
| } | |
| //----------------------------------------------------------------------------- | |
| // CVar::GetBool | |
| // Data accessor | |
| //----------------------------------------------------------------------------- | |
| bool CVar::GetBool(void) const | |
| { | |
| return !!GetInt(); | |
| } | |
| //----------------------------------------------------------------------------- | |
| // CVar::SetValue <- const char * | |
| // Data accessor | |
| //----------------------------------------------------------------------------- | |
| void CVar::SetValue(const char *value) const | |
| { | |
| if(IsValid()) { | |
| // Now we have a different function to set value | |
| // because cvar is reallocating memory in heap | |
| CVar_SetValue(this->name, value); | |
| } | |
| } | |
| //----------------------------------------------------------------------------- | |
| // CVar::SetValue <- int | |
| // Data accessor | |
| //----------------------------------------------------------------------------- | |
| void CVar::SetValue(const int value) const | |
| { | |
| SetValue(std::to_string(value).c_str()); | |
| } | |
| //----------------------------------------------------------------------------- | |
| // CVar::SetValue <- double | |
| // Data accessor | |
| //----------------------------------------------------------------------------- | |
| void CVar::SetValue(const double value) const | |
| { | |
| SetValue(std::to_string(value).c_str()); | |
| } | |
| //----------------------------------------------------------------------------- | |
| // CVar::SetValue <- bool | |
| // Data accessor | |
| //----------------------------------------------------------------------------- | |
| void CVar::SetValue(const bool value) const | |
| { | |
| SetValue(value ? 1 : 0); | |
| } | 
  
    Sign up for free
    to join this conversation on GitHub.
    Already have an account?
    Sign in to comment