TOLUA_API int tolua_isusertypearray (lua_State* L, int lo, const char* type, int dim, int def, tolua_Error* err) { if (!tolua_istable(L,lo,def,err)) return 0; else { int i; if (dim == -1) // Urho3D - auto detect the array size if -1 is given dim = (int)lua_objlen(L, lo); for (i=1; i<=dim; ++i) { lua_pushnumber(L,i); lua_gettable(L,lo); if (!(lua_isnil(L,-1) || lua_isusertype(L,-1, type)) && // Urho3D - bug fix to check user type instead of user data !(def && lua_isnil(L,-1)) ) { err->index = lo; err->type = type; err->array = 1; return 0; } lua_pop(L,1); } } return 1; }
TOLUA_API int tolua_isusertype (lua_State* L, int lo, const char* type, int def, tolua_Error* err) { if (def && lua_gettop(L)<abs(lo)) return 1; if (lua_isnil(L,lo) || lua_isusertype(L,lo,type)) return 1; err->index = lo; err->array = 0; err->type = type; return 0; }
static int entity_SetProperty(lua_State *L) { int n = lua_gettop(L); if (n != 3) { return luaL_error(L, "Entity::SetProperty(name, value) requires 2 parameters."); } Entity *entity = (Entity *)tolua_tousertype(L, 1, 0); const char *propName = tolua_tostring(L, 2, 0); switch (lua_type(L, 3)) { case LUA_TSTRING: entity->SetProperty(propName, TYPE_STRING, (void*)lua_tostring(L, 3)); break; case LUA_TNUMBER: { float f = lua_tonumber(L, 3); entity->SetProperty(propName, TYPE_NUMBER, (void*)&f); break; } case LUA_TBOOLEAN: { bool b = lua_toboolean(L, 3); entity->SetProperty(propName, TYPE_BOOLEAN, (void*)&b); break; } case LUA_TUSERDATA: { if (lua_isusertype(L, 3, "Rect")) { entity->SetProperty(propName, TYPE_RECT, tolua_tousertype(L, 3, 0)); } else if (lua_isusertype(L, 3, "Vector")) { entity->SetProperty(propName, TYPE_VECTOR, tolua_tousertype(L, 3, 0)); } else { return luaL_error(L, "The type of the value passed must be one of: String, Number, Boolean, Rect, Vector"); } break; } default: return luaL_error(L, "The type of the value passed must be one of: String, Number, Boolean, Rect, Vector"); } return 0; }
int tolua_isusertypefield (lua_State* L, int lo, const char* type, int i, int def, tolua_Error* err) { lua_pushnumber(L,i); lua_gettable(L,lo); if (!(lua_isnil(L,-1) || lua_isusertype(L,-1,type)) && !(def && lua_isnil(L,-1)) ) { err->index = lo; err->type = type; err->array = 1; return 0; } lua_pop(L,1); return 1; }
Entity *LuaScripting::LoadEntity(const char *_entityFile) { if (RunScript(_entityFile)) { lua_getglobal(m_luaState, "name"); if (lua_isstring(m_luaState, -1)) { Entity *e = new Entity(0, lua_tostring(m_luaState, -1)); Vector position; position.x = position.y = 100; position.z = 0; e->SetProperty("position", TYPE_VECTOR, (void*)&position); lua_pop(m_luaState, 1); lua_getglobal(m_luaState, "properties"); if (lua_istable(m_luaState, -1)) { lua_pushnil(m_luaState); while(lua_next(m_luaState, -2) != 0) { const char *propertyName = NULL; if (!lua_isnumber(m_luaState, -2) && lua_isstring(m_luaState, -2)) { propertyName = lua_tostring(m_luaState, -2); int type = lua_type(m_luaState, -1); if (propertyName != NULL) { switch (type) { case LUA_TSTRING: e->SetProperty(propertyName, TYPE_STRING, (void*)lua_tostring(m_luaState, -1)); break; case LUA_TNUMBER: { float f = lua_tonumber(m_luaState, -1); e->SetProperty(propertyName, TYPE_NUMBER, (void*)&f); break; } case LUA_TBOOLEAN: { bool b = lua_toboolean(m_luaState, -1); e->SetProperty(propertyName, TYPE_BOOLEAN, (void*)&b); break; } case LUA_TUSERDATA: if (lua_isusertype(m_luaState, -1, "Rect")) { e->SetProperty(propertyName, TYPE_RECT, tolua_tousertype(m_luaState, -1, 0)); break; } else if (lua_isusertype(m_luaState, -1, "Vector")) { e->SetProperty(propertyName, TYPE_VECTOR, tolua_tousertype(m_luaState, -1, 0)); break; } else { g_console->WriteLine("WARN: Unknown property type detected, please fix."); } break; default: g_console->WriteLine("WARN: Property values must one of the following types: String, Number, Boolean, Rect, Vector"); break; } } } lua_pop(m_luaState, 1); } } lua_getglobal(m_luaState, "behaviors"); if (lua_istable(m_luaState, -1)) { // -1 is the table // Loop through behaviors table lua_pushnil(m_luaState); // -1 is the first key while(lua_next(m_luaState, -2) != 0) { // -2: behaviors table const char *behaviorName = NULL; if (!lua_isnumber(m_luaState, -1) && lua_isstring(m_luaState, -1)) { behaviorName = lua_tostring(m_luaState, -1); } else if (!lua_isnumber(m_luaState, -2) && lua_isstring(m_luaState, -2)) { behaviorName = lua_tostring(m_luaState, -2); } else { g_console->WriteLine("WARN: Non-string entry found in behaviors table, please fix."); } if (behaviorName != NULL) { behaviorFunc f = get_behavior(behaviorName); if (f == NULL) { g_console->WriteLine("WARN: '%s' is not a registered behavior.", behaviorName); } else { e->AddBehavior(behaviorName, f); } } lua_pop(m_luaState, 1); } } /* Look for input hooks */ /* onKeyUp */ lua_getglobal(m_luaState, "onKeyUp"); if (lua_isfunction(m_luaState, -1)) { g_input->RegisterEventObserver(SDL_KEYUP, e); } /* onKeyDown */ lua_getglobal(m_luaState, "onKeyDown"); if (lua_isfunction(m_luaState, -1)) { g_input->RegisterEventObserver(SDL_KEYDOWN, e); } /* onMouseDown */ lua_getglobal(m_luaState, "onMouseDown"); if (lua_isfunction(m_luaState, -1)) { g_input->RegisterEventObserver(SDL_MOUSEBUTTONDOWN, e); } /* onMouseUp */ lua_getglobal(m_luaState, "onMouseUp"); if (lua_isfunction(m_luaState, -1)) { g_input->RegisterEventObserver(SDL_MOUSEBUTTONUP, e); } /* onMouseOver */ lua_getglobal(m_luaState, "onMouseOver"); if (lua_isfunction(m_luaState, -1)) { g_input->RegisterEventObserver(MOUSE_OVER, e); } /* onMouseLeave */ lua_getglobal(m_luaState, "onMouseLeave"); if (lua_isfunction(m_luaState, -1)) { g_input->RegisterEventObserver(MOUSE_LEAVE, e); } ResetEntityFileGlobals(); return e; } ResetEntityFileGlobals(); g_console->WriteLine("ERROR: Missing field: 'name'"); } g_console->WriteLine("FAIL: Could not parse the entity file."); return NULL; }