Announcement

Collapse
No announcement yet.

Const

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Const

    CONST
    After reading a for a long while and reviewing other people's code on the subject of read-only tables, I've hacked together some code (thanks to the interweb's numerous forums and the lua manual) that let's you define and use constants.

    This is my first run, thought I'd post it in case anyone else has a need for it.

    EDIT: Updated code to a new version.
    (0.3.0.0)

    Code:
    local tConst = {
        AllowedValueTypes = {"boolean", "number", "string"},
        ThrowErrorsByDefault = true, --this can be changed individually for each CONST type created using :SetThrowErrors(boolean);
        Types = {},
    }
    
    --determines whether or not this CONST type will throw errors
    local function GetThrowErrors(sName)
        local bRet = false;
        
        if (tConst.Types[sName]) then
            bRet = tConst.Types[sName].ThrowErrors;
        end
        
        return bRet;
    end
    
    --determines whether or not the sumbitted type is an allowed CONST value type
    local function IsAllowedValueType(sValueType)
        local bRet = false;
        
        for _, sAllowedValueType in pairs(tConst.AllowedValueTypes) do
        
            if (sValueType == sAllowedValueType) then
                bRet = true;
                break;
            end    
            
        end
        
        return bRet;
    end
    
    
    
    function tConst.Create(sName)
        --make sure the input is good
        assert(type(sName) == "string" and sName:gsub("%s", "") ~= "",
               "Error creating CONST type. Input must be a non-blank string.");    
        local tReturnTable = {};
        
        --ensure the CONST type doesn't already exist
        if (not tConst.Types[sName]) then
                
            --create the CONST shadow table
            local tShadow = {};
            
            --store the CONST type name and set the default error flag
            tConst.Types[sName] = {ThrowErrors=tConst.ThrowErrorsByDefault};
            
            --============================================
            -- Begin Metamethods
            --===========================================
            
            --==========
            -- NewIndex
            --==========
            --this is called whenever a new index is created within the new CONST type table
            local function NewIndex(tTable, nKey, nValue)
                local sType = type(nValue);
                
                --make sure the CONST has not already been defined
                if (tShadow[nKey]) then
                
                    if (GetThrowErrors(sName)) then
                        error('"'..sName..'.'..nKey..
                              '" has already been defined with value "'..
                              tostring(tShadow[nKey])..'" and is of type "'..
                              type(tShadow[nKey])..'".');
                    end
                    
                else                        
                    
                    --make sure the CONST is of the correct type
                    if (IsAllowedValueType(sType)) then
                        tShadow[nKey] = nValue;                
                                    
                    else                    
                        --throw an error (if errors are on)
                        if (GetThrowErrors(sName)) then
                            error('A "'..sName..
                                  '" may be of type "boolean", "number" or "string" only. Input was of type "'..
                                  sType..'".');
                        end
                        
                    end        
                    
                end
                
            end
            
            
            --=========
            -- GetAll
            --=========
            local function GetAll()
                local tRet = {};
                
                for k, v in pairs(tShadow) do
                    local sVType = type(v);
                
                    if (type(k) == "string" and IsAllowedValueType(sVType)) then                
                        tRet[k] = v;
                    end
                    
                end
                
                return tRet;
            end
            
            --============================================
            -- End Metamethods
            --
            -- Begin CONST type exposed functions
            --============================================
            --this is the table whose metatable is set and is used to set functions
            local tConstType = {};
            
            --================
            -- SetThrowErrors
            --================
            function tConstType.SetThrowErrors(bValue)
                local sType = type(bValue);
                local bFlag = bValue;
    
                if (sType ~= "boolean") then            
                    bFlag = false;
                end
    
                tConst.Types[sName].ThrowErrors = bFlag;
            end
            
            --adjust the metatable of the new tConstType and return that value        
            tReturnTable = setmetatable(tConstType, {
                __call = GetAll,
                __index = tShadow, --the shadow reference
                __newindex = NewIndex,        
                __type = sName,
            });
                    
        else
            
            tReturnTable = _G[sName];
            
            if (GetThrowErrors(sName)) then
                error("Error creating CONST type. CONST type already exists.");
            end
        
        end
        
        return tReturnTable;    
    end
    
    CONST = tConst.Create;

    Usage Example

    Code:
    RESOURCE = CONST("RESOURCE");
    
    RESOURCE.AMMO = "Ammo";
    RESOURCE.FUEL = "Fuel";
    RESOURCE.FUEL_BASE_COST = 25;
    RESOURCE.IS_FREE = false;
    
    --RESOURCE.SetThrowError(false);--uncomment to ignore errors for this CONST type
    RESOURCE.AMMO = "stuff"; --throws an error, already set (even if errors are ignored, the value cannot be changed)

    These constants cannot be overwritten (by normal means).
    Last edited by Centauri Soldier; 01-21-2020, 04:41 PM. Reason: Code Error
    https://github.com/CentauriSoldier

  • #2
    Added the ability to set and get a description for each CONST.

    Code:
    local tConst = {
        AllowedValueTypes = {"boolean", "number", "string"},
        ThrowErrorsByDefault = true, --this can be changed individually for each CONST type created using :SetThrowErrors(boolean);
        Types = {},
    }
    
    --determines whether or not this CONST type will throw errors
    local function GetThrowErrors(sName)
        local bRet = false;
    
        if (tConst.Types[sName]) then
            bRet = tConst.Types[sName].ThrowErrors;
        end
    
        return bRet;
    end
    
    --determines whether or not the sumbitted type is an allowed CONST value type
    local function IsAllowedValueType(sValueType)
        local bRet = false;
    
        for _, sAllowedValueType in pairs(tConst.AllowedValueTypes) do
    
            if (sValueType == sAllowedValueType) then
                bRet = true;
                break;
            end
    
        end
    
        return bRet;  
    end
    
    
    
    --TODO create destroy function
    function tConst.Create(sName, sDescription)
        --make sure the name input is good
        assert(type(sName) == "string" and sName:gsub("s%", "") ~= "",
               "Error creating CONST type. Input must be a non-blank string.");
        local tReturnTable = {};
    
        --ensure the CONST type doesn't already exist
        if (not tConst.Types[sName]) then
        
            if (type(sDescription) ~= "string") then
                sDescription = "";
            end
            
            --create the CONST shadow table
            local tShadow = {
                Descriptions = {},
            };
    
            --store the CONST type name
            tConst.Types[sName] = {
                ThrowErrors = tConst.ThrowErrorsByDefault,  --set the default error flag for this CONST type
                ConstNames = {},
            };
    
            --============================================
            -- Begin Metamethods
            --===========================================
    
            --==========
            -- NewIndex
            --==========
            --this is called whenever a new index is created within the new CONST type table
            local function NewIndex(tTable, vKey, vValue)
                local sType = type(vValue);
    
                --make sure the CONST has not already been defined
                if (tShadow[vKey]) then
    
                    if (GetThrowErrors(sName)) then
                        error('Error creating CONST type. "'..sName..'.'..vKey..
                              '" has already been defined with value "'..
                              tostring(tShadow[vKey])..'" and is of type "'..
                              type(tShadow[vKey])..'".');
                    end
    
                else
    
                    --make sure the CONST is of the correct type
                    if (IsAllowedValueType(sType)) then
                        tShadow[vKey] = vValue;
                        tShadow.Descriptions[vKey] = sDescription;
                        --add this CONST name to the list of names for this CONST type
                        tConst.Types[sName].ConstNames[#tConst.Types[sName].ConstNames + 1] = vKey;
    
                    else
                        --throw an error (if errors are on)
                        if (GetThrowErrors(sName)) then
                            error('Error creating CONST type. A CONST type "'..sName..
                                  '" value may be of type "boolean", "number" or "string" only. Input was of type "'..
                                  sType..'".');
                        end
    
                    end
    
                end
    
            end
    
    
            --=========
            -- GetAll
            --=========
            --__call
            local function GetAll()
                local tRet = {};
    
                for k, v in pairs(tShadow) do
                    local sVType = type(v);
    
                    if (type(k) == "string" and IsAllowedValueType(sVType)) then
                        tRet[k] = v;
                    end
    
                end
    
                return tRet;
            end
    
    
            --============================================
            -- End Metamethods
            --
            -- Begin CONST type exposed functions
            --============================================
            --this is the table whose metatable is set and is used to set functions
            local tConstType = {};
    
    
            --================
            -- GetDescription
            --================
            function tConstType.GetDescription(sKey)
                assert(tShadow[sKey], "Error getting CONST description. CONST does not exist.");
                return tShadow.Descriptions[sKey];
            end
        
            
            --================
            -- SetThrowErrors
            --================
            function tConstType.SetThrowErrors(bValue)
                local sType = type(bValue);
                local bFlag = bValue;
    
                if (sType ~= "boolean") then
                    bFlag = false;
                end
    
                tConst.Types[sName].ThrowErrors = bFlag;
            end
                    
            --================
            -- IsConstOfType
            --[[================
            Note: this method will return true if the
                  input value matches *any* value in the table.
            ]]
            function tConstType.IsMyConst(vValue)
                local bRet = false;
                local sType = type(vValue);
                
                if (sType ~= "nil") then
                    
                    for sCONST, vConstValue in pairs(tConstType()) do
                        
                        if vValue == vConstValue then
                            bRet = true;
                            break;
                        end
                        
                    end
                    
                end
                
                return bRet
            end
            
            
            --================
            -- SetDescription
            --================
            function tConstType.SetDescription(sKey, sDescription)
                assert(tShadow[sKey], "Error setting CONST description. CONST does not exist.");
                assert(type(sDescription) == "string", "Error setting CONST description. Description must be a string.");
                tShadow.Descriptions[sKey] = sDescription;
            end
    
    
            --adjust the metatable of the new tConstType and return that value
            tReturnTable = setmetatable(tConstType, {
                __call = GetAll,
                __len = function() return #tConst.Types[sName].ConstNames end, --does not work with Lua Version <= 5.1
                __index = tShadow, --the shadow reference
                __newindex = NewIndex,
                __type = sName,
            });
    
        else
    
            tReturnTable = _G[sName];
    
            if (GetThrowErrors(sName)) then
                error("Error creating CONST type. CONST type already exists.");
            end
    
        end
    
        return tReturnTable;
    end
    
    CONST = tConst.Create;
    https://github.com/CentauriSoldier

    Comment

    Working...
    X