ScriptInstance create(ScriptWorld& sw, UnitId unit, const ScriptDesc& desc) { CE_ASSERT(!hash_map::has(sw._map, unit), "Unit already has script component"); u32 script_i = hash_map::get(sw._cache , desc.script_resource , UINT32_MAX ); ScriptWorld::ScriptData sd; sd.module_ref = LUA_REFNIL; if (script_i != UINT32_MAX) { sd = sw._script[script_i]; } else { script_i = array::size(sw._script); sw._resource_manager->load(RESOURCE_TYPE_SCRIPT, desc.script_resource); sw._resource_manager->flush(); const LuaResource* lr = (LuaResource*)sw._resource_manager->get(RESOURCE_TYPE_SCRIPT, desc.script_resource); LuaStack stack = sw._lua_environment->execute(lr); stack.push_value(0); sd.module_ref = luaL_ref(stack.L, LUA_REGISTRYINDEX); array::push_back(sw._script, sd); hash_map::set(sw._cache, desc.script_resource, script_i); } ScriptWorld::InstanceData data; data.unit = unit; data.script_i = script_i; u32 instance_i = array::size(sw._data); array::push_back(sw._data, data); hash_map::set(sw._map, unit, instance_i); LuaStack stack(sw._lua_environment->L); lua_rawgeti(stack.L, LUA_REGISTRYINDEX, sd.module_ref); lua_getfield(stack.L, -1, "spawned"); stack.push_world(sw._world); stack.push_table(1); stack.push_key_begin(1); stack.push_unit(unit); stack.push_key_end(); stack.call(0); return script_world_internal::make_instance(instance_i); }