gynt / stronghold-mapeditortools

Map Editor Tool Set for Stronghold and Stronghold Crusader
GNU Affero General Public License v3.0
6 stars 1 forks source link

Add a guard to the configuration tables to also validate direct assignments #9

Closed TheRedDaemon closed 3 years ago

TheRedDaemon commented 3 years ago

Currently, even with the new config-structure, it is still possible to directly assign wrong values to valid fields. For example:

mirror.mirrorMode = true would not throw an error until the value is used.

Now LUA provides two metamethods to react to index manipulations:

Both cases are not called anymore once an index of the name has been assign to the table.

Possible solutions

One idea would be to wrap the actual configuration table yet in another table. This proxy table would stay empty. Instead, all reads or assigns call the tables metamethods __index and __newindex. These methods would then call the guarded functions on the config table, like "setField". This solution would basically add a fourth level to the config (DefaultBase -> DefaultFeature -> Config -> Proxy).

Another suggestion from @gynt would be to instead use a bit of name manipulation and add underscores to the actual values. Example:

Test = {
  new = function(self) 
    local o = {_active = false};
    setmetatable(o, self);
    return o;
  end, 
  __index = function(self, k) 
    print("get: " .. k); 
    return rawget(self, "_" .. k); 
  end, 
  __newindex = function(self, k, v) 
    print("set:" .. k); 
    rawset(self, "_" .. k, v); 
  end
}

t = Test:new()
print(t.active)
t.active = true
print(t.active)

This method would still allow intentional direct access (by using "_" + parameter name), but will otherwise protect the variable from being accidentally set.

TheRedDaemon commented 3 years ago

Decided to use a proxy table approach. Implemented as part of THIS pull request. Issue can be closed.