static int UnitDefNewIndex(lua_State* L) { // not a default value, set it if (!lua_isstring(L, 2)) { lua_rawset(L, 1); return 0; } const char* name = lua_tostring(L, 2); ParamMap::const_iterator it = paramMap.find(name); // not a default value, set it if (paramMap.find(name) == paramMap.end()) { lua_rawset(L, 1); return 0; } const void* userData = lua_touserdata(L, lua_upvalueindex(1)); const UnitDef* ud = (const UnitDef*)userData; // write-protected if (!gs->editDefsEnabled) { luaL_error(L, "Attempt to write UnitDefs[%d].%s", ud->id, name); return 0; } // Definition editing const DataElement& elem = it->second; const char* p = ((const char*)ud) + elem.offset; switch (elem.type) { case FUNCTION_TYPE: case READONLY_TYPE: { luaL_error(L, "Can not write to %s", name); return 0; } case INT_TYPE: { *((int*)p) = (int)lua_tonumber(L, -1); return 0; } case BOOL_TYPE: { *((bool*)p) = lua_toboolean(L, -1); return 0; } case FLOAT_TYPE: { *((float*)p) = (float)lua_tonumber(L, -1); return 0; } case STRING_TYPE: { *((string*)p) = lua_tostring(L, -1); return 0; } case ERROR_TYPE:{ luaL_error(L, "ERROR_TYPE in UnitDefs __newindex"); } } return 0; }
static int UnitDefIndex(lua_State* L) { // not a default value if (!lua_isstring(L, 2)) { lua_rawget(L, 1); return 1; } const char* name = lua_tostring(L, 2); ParamMap::const_iterator it = paramMap.find(name); // not a default value if (paramMap.find(name) == paramMap.end()) { lua_rawget(L, 1); return 1; } const void* userData = lua_touserdata(L, lua_upvalueindex(1)); const UnitDef* ud = (const UnitDef*)userData; const DataElement& elem = it->second; const char* p = ((const char*)ud) + elem.offset; switch (elem.type) { case READONLY_TYPE: { lua_rawget(L, 1); return 1; } case INT_TYPE: { lua_pushnumber(L, *((int*)p)); return 1; } case BOOL_TYPE: { lua_pushboolean(L, *((bool*)p)); return 1; } case FLOAT_TYPE: { lua_pushnumber(L, *((float*)p)); return 1; } case STRING_TYPE: { lua_pushstring(L, ((string*)p)->c_str()); return 1; } case FUNCTION_TYPE: { return elem.func(L, p); } case ERROR_TYPE:{ luaL_error(L, "ERROR_TYPE in UnitDefs __index"); } } return 0; }
bool LuaFeatureDefs::IsDefaultParam(const string& word) { if (paramMap.empty()) { InitParamMap(); } return (paramMap.find(word) != paramMap.end()); }
static int UnitDefIndex(lua_State* L) { // not a default value if (!lua_isstring(L, 2)) { lua_rawget(L, 1); return 1; } const char* name = lua_tostring(L, 2); ParamMap::const_iterator it = paramMap.find(name); // not a default value if (it == paramMap.end()) { lua_rawget(L, 1); return 1; } const void* userData = lua_touserdata(L, lua_upvalueindex(1)); const UnitDef* ud = static_cast<const UnitDef*>(userData); const DataElement& elem = it->second; const char* p = ((const char*)ud) + elem.offset; switch (elem.type) { case READONLY_TYPE: { lua_rawget(L, 1); return 1; } case INT_TYPE: { lua_pushnumber(L, *((int*)p)); return 1; } case BOOL_TYPE: { lua_pushboolean(L, *((bool*)p)); return 1; } case FLOAT_TYPE: { lua_pushnumber(L, *((float*)p)); return 1; } case STRING_TYPE: { lua_pushsstring(L, *((string*)p)); return 1; } case FUNCTION_TYPE: { return elem.func(L, p); } case ERROR_TYPE: { LOG_L(L_ERROR, "[%s] ERROR_TYPE for key \"%s\" in UnitDefs __index", __FUNCTION__, name); lua_pushnil(L); return 1; } } return 0; }
int LuaUtils::Next(const ParamMap& paramMap, lua_State* L) { luaL_checktype(L, 1, LUA_TTABLE); lua_settop(L, 2); // create a 2nd argument if there isn't one // internal parameters first if (lua_isnil(L, 2)) { const string& nextKey = paramMap.begin()->first; lua_pushsstring(L, nextKey); // push the key lua_pushvalue(L, 3); // copy the key lua_gettable(L, 1); // get the value return 2; } // all internal parameters use strings as keys if (lua_isstring(L, 2)) { const char* key = lua_tostring(L, 2); ParamMap::const_iterator it = paramMap.find(key); if ((it != paramMap.end()) && (it->second.type != READONLY_TYPE)) { // last key was an internal parameter ++it; while ((it != paramMap.end()) && (it->second.type == READONLY_TYPE)) { ++it; // skip read-only parameters } if ((it != paramMap.end()) && (it->second.type != READONLY_TYPE)) { // next key is an internal parameter const string& nextKey = it->first; lua_pushsstring(L, nextKey); // push the key lua_pushvalue(L, 3); // copy the key lua_gettable(L, 1); // get the value (proxied) return 2; } // start the user parameters, // remove the internal key and push a nil lua_settop(L, 1); lua_pushnil(L); } } // user parameter if (lua_next(L, 1)) { return 2; } // end of the line lua_pushnil(L); return 1; }
static int WeaponDefNewIndex(lua_State* L) { // not a default value, set it if (!lua_isstring(L, 2)) { lua_rawset(L, 1); return 0; } const char* name = lua_tostring(L, 2); ParamMap::const_iterator it = paramMap.find(name); // not a default value, set it if (it == paramMap.end()) { lua_rawset(L, 1); return 0; } const void* userData = lua_touserdata(L, lua_upvalueindex(1)); const WeaponDef* wd = (const WeaponDef*)userData; // write-protected if (!gs->editDefsEnabled) { luaL_error(L, "Attempt to write WeaponDefs[%d].%s", wd->id, name); return 0; } // Definition editing const DataElement& elem = it->second; const char* p = ((const char*)wd) + elem.offset; switch (elem.type) { case FUNCTION_TYPE: case READONLY_TYPE: { luaL_error(L, "Can not write to %s", name); return 0; } case INT_TYPE: { *((int*)p) = lua_toint(L, -1); return 0; } case BOOL_TYPE: { *((bool*)p) = lua_toboolean(L, -1); return 0; } case FLOAT_TYPE: { *((float*)p) = lua_tofloat(L, -1); return 0; } case STRING_TYPE: { *((string*)p) = lua_tostring(L, -1); return 0; } case ERROR_TYPE: { LOG_L(L_ERROR, "[%s] ERROR_TYPE for key \"%s\" in WeaponDefs __newindex", __FUNCTION__, name); lua_pushnil(L); return 1; } } return 0; }