int main() { L = luaL_newstate(); luaL_openlibs(L); luaL_requiref(L, "love", initLove, 1); sf2d_init(); // 2D Drawing lib. sftd_init(); // Text Drawing lib. cfguInit(); ptmuInit(); // consoleInit(GFX_BOTTOM, NULL); sf2d_set_clear_color(RGBA8(0x0, 0x0, 0x0, 0xFF)); // Reset background color. osSetSpeedupEnable(true); // Enables CPU speedup for a free performance boost. // Detect if we are running on a .cia, because if we are // we load from RomFS rather than the SD Card. // TODO: Load RomFS from .3dsx's aswell. Result rc = romfsInit(); romfsExists = (rc) ? false : true; // Change working directory if (romfsExists) { chdir("romfs:/"); } else { char cwd[256]; getcwd(cwd, 256); char newCwd[261]; strcat(newCwd, cwd); strcat(newCwd, "game"); chdir(newCwd); } luaL_dobuffer(L, boot_lua, boot_lua_size, "boot"); // Do some setup Lua side. // If main.lua exists, execute it. // If not then just load the nogame screen. if (fileExists("main.lua")) { if (luaL_dofile(L, "main.lua")) displayError(); } else { if (luaL_dobuffer(L, nogame_lua, nogame_lua_size, "nogame")) displayError(); } if (luaL_dostring(L, "love.timer.step()")) displayError(); if (luaL_dostring(L, "if love.load then love.load() end")) displayError(); while (aptMainLoop()) { if (shouldQuit) { if (forceQuit) break; bool shouldAbort = false; // lua_getfield(L, LUA_GLOBALSINDEX, "love"); // lua_getfield(L, -1, "quit"); // lua_remove(L, -2); // if (!lua_isnil(L, -1)) { // lua_call(L, 0, 1); // shouldAbort = lua_toboolean(L, 1); // lua_pop(L, 1); // }; TODO: Do this properly. if (luaL_dostring(L, "if love.quit then love.quit() end")) displayError(); if (!shouldAbort && !errorOccured) break; } // Quit event if (!errorOccured) { if (luaL_dostring(L, "love.keyboard.scan()\n" "love.timer.step()\n" "if love.update then love.update(love.timer.getDelta()) end")) { displayError(); } // Top screen // Left side sf2d_start_frame(GFX_TOP, GFX_LEFT); if (luaL_dostring(L, "if love.draw then love.draw() end")) displayError(); sf2d_end_frame(); // Right side if (is3D) { sf2d_start_frame(GFX_TOP, GFX_RIGHT); if (luaL_dostring(L, "if love.draw then love.draw() end")) displayError(); sf2d_end_frame(); } // Bot screen sf2d_start_frame(GFX_BOTTOM, GFX_LEFT); if (luaL_dostring(L, "if love.draw then love.draw() end")) displayError(); sf2d_end_frame(); luaL_dostring(L, "love.graphics.present()"); } else { hidScanInput(); u32 kTempDown = hidKeysDown(); if (kTempDown & KEY_START) { forceQuit = true; shouldQuit = true; } char *errMsg = lua_tostring(L, -1); sf2d_start_frame(GFX_TOP, GFX_LEFT); lua_getfield(L, LUA_GLOBALSINDEX, "love"); lua_getfield(L, -1, "errhand"); lua_remove(L, -2); if (!lua_isnil(L, -1)) { lua_pushstring(L, errMsg); lua_call(L, 1, 0); } sf2d_end_frame(); sf2d_start_frame(GFX_BOTTOM, GFX_LEFT); lua_getfield(L, LUA_GLOBALSINDEX, "love"); lua_getfield(L, -1, "errhand"); lua_remove(L, -2); if (!lua_isnil(L, -1)) { lua_pushstring(L, errMsg); lua_call(L, 1, 0); } sf2d_end_frame(); luaL_dostring(L, "love.graphics.present()"); } } luaL_dostring(L, "love.audio.stop()"); lua_close(L); sftd_fini(); sf2d_fini(); cfguExit(); ptmuExit(); if (soundEnabled) ndspExit(); if (romfsExists) romfsExit(); return 0; }
ContentFeatures read_content_features(lua_State *L, int index) { if(index < 0) index = lua_gettop(L) + 1 + index; ContentFeatures f; /* Cache existence of some callbacks */ lua_getfield(L, index, "on_construct"); if(!lua_isnil(L, -1)) f.has_on_construct = true; lua_pop(L, 1); lua_getfield(L, index, "on_destruct"); if(!lua_isnil(L, -1)) f.has_on_destruct = true; lua_pop(L, 1); lua_getfield(L, index, "after_destruct"); if(!lua_isnil(L, -1)) f.has_after_destruct = true; lua_pop(L, 1); lua_getfield(L, index, "on_rightclick"); f.rightclickable = lua_isfunction(L, -1); lua_pop(L, 1); /* Name */ getstringfield(L, index, "name", f.name); /* Groups */ lua_getfield(L, index, "groups"); read_groups(L, -1, f.groups); lua_pop(L, 1); /* Visual definition */ f.drawtype = (NodeDrawType)getenumfield(L, index, "drawtype", ScriptApiNode::es_DrawType,NDT_NORMAL); getfloatfield(L, index, "visual_scale", f.visual_scale); /* Meshnode model filename */ getstringfield(L, index, "mesh", f.mesh); // tiles = {} lua_getfield(L, index, "tiles"); // If nil, try the deprecated name "tile_images" instead if(lua_isnil(L, -1)){ lua_pop(L, 1); warn_if_field_exists(L, index, "tile_images", "Deprecated; new name is \"tiles\"."); lua_getfield(L, index, "tile_images"); } if(lua_istable(L, -1)){ int table = lua_gettop(L); lua_pushnil(L); int i = 0; while(lua_next(L, table) != 0){ // Read tiledef from value f.tiledef[i] = read_tiledef(L, -1); // removes value, keeps key for next iteration lua_pop(L, 1); i++; if(i==6){ lua_pop(L, 1); break; } } // Copy last value to all remaining textures if(i >= 1){ TileDef lasttile = f.tiledef[i-1]; while(i < 6){ f.tiledef[i] = lasttile; i++; } } } lua_pop(L, 1); // special_tiles = {} lua_getfield(L, index, "special_tiles"); // If nil, try the deprecated name "special_materials" instead if(lua_isnil(L, -1)){ lua_pop(L, 1); warn_if_field_exists(L, index, "special_materials", "Deprecated; new name is \"special_tiles\"."); lua_getfield(L, index, "special_materials"); } if(lua_istable(L, -1)){ int table = lua_gettop(L); lua_pushnil(L); int i = 0; while(lua_next(L, table) != 0){ // Read tiledef from value f.tiledef_special[i] = read_tiledef(L, -1); // removes value, keeps key for next iteration lua_pop(L, 1); i++; if(i==CF_SPECIAL_COUNT){ lua_pop(L, 1); break; } } } lua_pop(L, 1); f.alpha = getintfield_default(L, index, "alpha", 255); bool usealpha = getboolfield_default(L, index, "use_texture_alpha", false); if (usealpha) f.alpha = 0; /* Other stuff */ lua_getfield(L, index, "post_effect_color"); read_color(L, -1, &f.post_effect_color); lua_pop(L, 1); f.param_type = (ContentParamType)getenumfield(L, index, "paramtype", ScriptApiNode::es_ContentParamType, CPT_NONE); f.param_type_2 = (ContentParamType2)getenumfield(L, index, "paramtype2", ScriptApiNode::es_ContentParamType2, CPT2_NONE); // Warn about some deprecated fields warn_if_field_exists(L, index, "wall_mounted", "deprecated: use paramtype2 = 'wallmounted'"); warn_if_field_exists(L, index, "light_propagates", "deprecated: determined from paramtype"); warn_if_field_exists(L, index, "dug_item", "deprecated: use 'drop' field"); warn_if_field_exists(L, index, "extra_dug_item", "deprecated: use 'drop' field"); warn_if_field_exists(L, index, "extra_dug_item_rarity", "deprecated: use 'drop' field"); warn_if_field_exists(L, index, "metadata_name", "deprecated: use on_add and metadata callbacks"); // True for all ground-like things like stone and mud, false for eg. trees getboolfield(L, index, "is_ground_content", f.is_ground_content); f.light_propagates = (f.param_type == CPT_LIGHT); getboolfield(L, index, "sunlight_propagates", f.sunlight_propagates); // This is used for collision detection. // Also for general solidness queries. getboolfield(L, index, "walkable", f.walkable); // Player can point to these getboolfield(L, index, "pointable", f.pointable); // Player can dig these getboolfield(L, index, "diggable", f.diggable); // Player can climb these getboolfield(L, index, "climbable", f.climbable); // Player can build on these getboolfield(L, index, "buildable_to", f.buildable_to); // Whether the node is non-liquid, source liquid or flowing liquid f.liquid_type = (LiquidType)getenumfield(L, index, "liquidtype", ScriptApiNode::es_LiquidType, LIQUID_NONE); // If the content is liquid, this is the flowing version of the liquid. getstringfield(L, index, "liquid_alternative_flowing", f.liquid_alternative_flowing); // If the content is liquid, this is the source version of the liquid. getstringfield(L, index, "liquid_alternative_source", f.liquid_alternative_source); // Viscosity for fluid flow, ranging from 1 to 7, with // 1 giving almost instantaneous propagation and 7 being // the slowest possible f.liquid_viscosity = getintfield_default(L, index, "liquid_viscosity", f.liquid_viscosity); f.liquid_range = getintfield_default(L, index, "liquid_range", f.liquid_range); f.leveled = getintfield_default(L, index, "leveled", f.leveled); getboolfield(L, index, "liquid_renewable", f.liquid_renewable); f.drowning = getintfield_default(L, index, "drowning", f.drowning); // Amount of light the node emits f.light_source = getintfield_default(L, index, "light_source", f.light_source); f.damage_per_second = getintfield_default(L, index, "damage_per_second", f.damage_per_second); lua_getfield(L, index, "node_box"); if(lua_istable(L, -1)) f.node_box = read_nodebox(L, -1); lua_pop(L, 1); lua_getfield(L, index, "selection_box"); if(lua_istable(L, -1)) f.selection_box = read_nodebox(L, -1); lua_pop(L, 1); lua_getfield(L, index, "collision_box"); if(lua_istable(L, -1)) f.collision_box = read_nodebox(L, -1); lua_pop(L, 1); f.waving = getintfield_default(L, index, "waving", f.waving); // Set to true if paramtype used to be 'facedir_simple' getboolfield(L, index, "legacy_facedir_simple", f.legacy_facedir_simple); // Set to true if wall_mounted used to be set to true getboolfield(L, index, "legacy_wallmounted", f.legacy_wallmounted); // Sound table lua_getfield(L, index, "sounds"); if(lua_istable(L, -1)){ lua_getfield(L, -1, "footstep"); read_soundspec(L, -1, f.sound_footstep); lua_pop(L, 1); lua_getfield(L, -1, "dig"); read_soundspec(L, -1, f.sound_dig); lua_pop(L, 1); lua_getfield(L, -1, "dug"); read_soundspec(L, -1, f.sound_dug); lua_pop(L, 1); } lua_pop(L, 1); return f; }
void evalGenericCommand(redisClient *c, int evalsha) { lua_State *lua = server.lua; char funcname[43]; long long numkeys; int delhook = 0, err; /* We want the same PRNG sequence at every call so that our PRNG is * not affected by external state. */ redisSrand48(0); /* We set this flag to zero to remember that so far no random command * was called. This way we can allow the user to call commands like * SRANDMEMBER or RANDOMKEY from Lua scripts as far as no write command * is called (otherwise the replication and AOF would end with non * deterministic sequences). * * Thanks to this flag we'll raise an error every time a write command * is called after a random command was used. */ server.lua_random_dirty = 0; server.lua_write_dirty = 0; /* Get the number of arguments that are keys */ if (getLongLongFromObjectOrReply(c,c->argv[2],&numkeys,NULL) != REDIS_OK) return; if (numkeys > (c->argc - 3)) { addReplyError(c,"Number of keys can't be greater than number of args"); return; } /* We obtain the script SHA1, then check if this function is already * defined into the Lua state */ funcname[0] = 'f'; funcname[1] = '_'; if (!evalsha) { /* Hash the code if this is an EVAL call */ sha1hex(funcname+2,c->argv[1]->ptr,sdslen(c->argv[1]->ptr)); } else { /* We already have the SHA if it is a EVALSHA */ int j; char *sha = c->argv[1]->ptr; /* Convert to lowercase. We don't use tolower since the function * managed to always show up in the profiler output consuming * a non trivial amount of time. */ for (j = 0; j < 40; j++) funcname[j+2] = (sha[j] >= 'A' && sha[j] <= 'Z') ? sha[j]+('a'-'A') : sha[j]; funcname[42] = '\0'; } /* Push the pcall error handler function on the stack. */ lua_getglobal(lua, "__redis__err__handler"); /* Try to lookup the Lua function */ lua_getglobal(lua, funcname); if (lua_isnil(lua,-1)) { lua_pop(lua,1); /* remove the nil from the stack */ /* Function not defined... let's define it if we have the * body of the function. If this is an EVALSHA call we can just * return an error. */ if (evalsha) { lua_pop(lua,1); /* remove the error handler from the stack. */ addReply(c, shared.noscripterr); return; } if (luaCreateFunction(c,lua,funcname,c->argv[1]) == REDIS_ERR) { lua_pop(lua,1); /* remove the error handler from the stack. */ /* The error is sent to the client by luaCreateFunction() * itself when it returns REDIS_ERR. */ return; } /* Now the following is guaranteed to return non nil */ lua_getglobal(lua, funcname); redisAssert(!lua_isnil(lua,-1)); } /* Populate the argv and keys table accordingly to the arguments that * EVAL received. */ luaSetGlobalArray(lua,"KEYS",c->argv+3,(int)numkeys); luaSetGlobalArray(lua,"ARGV",c->argv+3+numkeys,(int)(c->argc-3-numkeys)); /* Select the right DB in the context of the Lua client */ selectDb(server.lua_client,c->db->id); /* Set a hook in order to be able to stop the script execution if it * is running for too much time. * We set the hook only if the time limit is enabled as the hook will * make the Lua script execution slower. */ server.lua_caller = c; server.lua_time_start = mstime(); server.lua_kill = 0; if (server.lua_time_limit > 0 && server.masterhost == NULL) { lua_sethook(lua,luaMaskCountHook,LUA_MASKCOUNT,100000); delhook = 1; } /* At this point whether this script was never seen before or if it was * already defined, we can call it. We have zero arguments and expect * a single return value. */ err = lua_pcall(lua,0,1,-2); /* Perform some cleanup that we need to do both on error and success. */ if (delhook) lua_sethook(lua,luaMaskCountHook,0,0); /* Disable hook */ if (server.lua_timedout) { server.lua_timedout = 0; /* Restore the readable handler that was unregistered when the * script timeout was detected. */ aeCreateFileEvent(server.el,c->fd,AE_READABLE, readQueryFromClient,c); } server.lua_caller = NULL; /* Call the Lua garbage collector from time to time to avoid a * full cycle performed by Lua, which adds too latency. * * The call is performed every LUA_GC_CYCLE_PERIOD executed commands * (and for LUA_GC_CYCLE_PERIOD collection steps) because calling it * for every command uses too much CPU. */ #define LUA_GC_CYCLE_PERIOD 50 { static long gc_count = 0; gc_count++; if (gc_count == LUA_GC_CYCLE_PERIOD) { lua_gc(lua,LUA_GCSTEP,LUA_GC_CYCLE_PERIOD); gc_count = 0; } } if (err) { addReplyErrorFormat(c,"Error running script (call to %s): %s\n", funcname, lua_tostring(lua,-1)); lua_pop(lua,2); /* Consume the Lua reply and remove error handler. */ } else { /* On success convert the Lua return value into Redis protocol, and * send it to * the client. */ luaReplyToRedisReply(c,lua); /* Convert and consume the reply. */ lua_pop(lua,1); /* Remove the error handler. */ } /* EVALSHA should be propagated to Slave and AOF file as full EVAL, unless * we are sure that the script was already in the context of all the * attached slaves *and* the current AOF file if enabled. * * To do so we use a cache of SHA1s of scripts that we already propagated * as full EVAL, that's called the Replication Script Cache. * * For repliation, everytime a new slave attaches to the master, we need to * flush our cache of scripts that can be replicated as EVALSHA, while * for AOF we need to do so every time we rewrite the AOF file. */ if (evalsha) { if (!replicationScriptCacheExists(c->argv[1]->ptr)) { /* This script is not in our script cache, replicate it as * EVAL, then add it into the script cache, as from now on * slaves and AOF know about it. */ robj *script = dictFetchValue(server.lua_scripts,c->argv[1]->ptr); replicationScriptCacheAdd(c->argv[1]->ptr); redisAssertWithInfo(c,NULL,script != NULL); rewriteClientCommandArgument(c,0, resetRefCount(createStringObject("EVAL",4))); rewriteClientCommandArgument(c,1,script); forceCommandPropagation(c,REDIS_PROPAGATE_REPL|REDIS_PROPAGATE_AOF); } } }
/* | Allows user scripts to observe filedescriptors | | Params on Lua stack: | 1: file descriptor | 2: function to call when read becomes ready | 3: function to call when write becomes ready */ static int l_observe_fd( lua_State *L ) { int fd = luaL_checknumber( L, 1 ); bool ready = false; bool writey = false; // Stores the user function in the lua registry. // It uses the address of the cores ready/write functions // for the user as key if( !lua_isnoneornil( L, 2 ) ) { lua_pushlightuserdata( L, (void *) user_obs_ready ); lua_gettable( L, LUA_REGISTRYINDEX ); if( lua_isnil( L, -1 ) ) { lua_pop ( L, 1 ); lua_newtable ( L ); lua_pushlightuserdata ( L, (void *) user_obs_ready ); lua_pushvalue ( L, -2 ); lua_settable ( L, LUA_REGISTRYINDEX ); } lua_pushnumber ( L, fd ); lua_pushvalue ( L, 2 ); lua_settable ( L, -3 ); lua_pop ( L, 1 ); ready = true; } if( !lua_isnoneornil( L, 3 ) ) { lua_pushlightuserdata( L, (void *) user_obs_writey ); lua_gettable (L, LUA_REGISTRYINDEX ); if( lua_isnil(L, -1) ) { lua_pop ( L, 1 ); lua_newtable ( L ); lua_pushlightuserdata ( L, (void *) user_obs_writey ); lua_pushvalue ( L, -2 ); lua_settable ( L, LUA_REGISTRYINDEX ); } lua_pushnumber ( L, fd ); lua_pushvalue ( L, 3 ); lua_settable ( L, -3 ); lua_pop ( L, 1 ); writey = true; } // tells the core to watch the fd observe_fd( fd, ready ? user_obs_ready : NULL, writey ? user_obs_writey : NULL, user_obs_tidy, NULL ); return 0; }
static UINT8 UnArchiveValue(int TABLESINDEX) { UINT8 type = READUINT8(save_p); switch (type) { case ARCH_NULL: lua_pushnil(gL); break; case ARCH_BOOLEAN: lua_pushboolean(gL, READUINT8(save_p)); break; case ARCH_SIGNED: lua_pushinteger(gL, READFIXED(save_p)); break; case ARCH_UNSIGNED: lua_pushinteger(gL, READANGLE(save_p)); break; case ARCH_STRING: { char value[1024]; READSTRING(save_p, value); lua_pushstring(gL, value); break; } case ARCH_TABLE: { UINT16 tid = READUINT16(save_p); lua_rawgeti(gL, TABLESINDEX, tid); if (lua_isnil(gL, -1)) { lua_pop(gL, 1); lua_newtable(gL); lua_pushvalue(gL, -1); lua_rawseti(gL, TABLESINDEX, tid); return 2; } break; } case ARCH_MOBJINFO: LUA_PushUserdata(gL, &mobjinfo[READUINT16(save_p)], META_MOBJINFO); break; case ARCH_STATE: LUA_PushUserdata(gL, &states[READUINT16(save_p)], META_STATE); break; case ARCH_MOBJ: LUA_PushUserdata(gL, P_FindNewPosition(READUINT32(save_p)), META_MOBJ); break; case ARCH_PLAYER: LUA_PushUserdata(gL, &players[READUINT8(save_p)], META_PLAYER); break; case ARCH_MAPTHING: LUA_PushUserdata(gL, &mapthings[READUINT16(save_p)], META_MAPTHING); break; case ARCH_VERTEX: LUA_PushUserdata(gL, &vertexes[READUINT16(save_p)], META_VERTEX); break; case ARCH_LINE: LUA_PushUserdata(gL, &lines[READUINT16(save_p)], META_LINE); break; case ARCH_SIDE: LUA_PushUserdata(gL, &sides[READUINT16(save_p)], META_SIDE); break; case ARCH_SUBSECTOR: LUA_PushUserdata(gL, &subsectors[READUINT16(save_p)], META_SUBSECTOR); break; case ARCH_SECTOR: LUA_PushUserdata(gL, §ors[READUINT16(save_p)], META_SECTOR); break; case ARCH_MAPHEADER: LUA_PushUserdata(gL, §ors[READUINT16(save_p)], META_MAPHEADER); break; case ARCH_TEND: return 1; } return 0; }
/*cfg={} cfg.ssid="" cfg.pwd="" cfg.ip (optional,default:11.11.11.1) cfg.netmask(optional,default:255.255.255.0) cfg.gateway(optional,default:11.11.11.1) cfg.dnsSrv(optional,default:11.11.11.1) cfg.retry_interval(optional,default:1000ms) wifi.startap(cfg,function(optional))*/ static int lwifi_startap( lua_State* L ) {//4 stations Max network_InitTypeDef_st wNetConfig; size_t len=0; memset(&wNetConfig, 0x0, sizeof(network_InitTypeDef_st)); if (!lua_istable(L, 1)) return luaL_error( L, "table arg needed" ); //ssid lua_getfield(L, 1, "ssid"); if (!lua_isnil(L, -1)){ /* found? */ if( lua_isstring(L, -1) ) // deal with the string { const char *ssid = luaL_checklstring( L, -1, &len ); if(len>32) return luaL_error( L, "ssid:<32" ); strncpy(wNetConfig.wifi_ssid,ssid,len); } else return luaL_error( L, "wrong arg type:ssid" ); } else return luaL_error( L, "arg: ssid needed" ); //pwd lua_getfield(L, 1, "pwd"); if (!lua_isnil(L, -1)){ /* found? */ if( lua_isstring(L, -1) ) // deal with the string { const char *pwd = luaL_checklstring( L, -1, &len ); if(len>64) return luaL_error( L, "pwd:<64" ); if(len>0) strncpy(wNetConfig.wifi_key,pwd,len); else strcpy(wNetConfig.wifi_key,""); } else return luaL_error( L, "wrong arg type:pwd" ); } else return luaL_error( L, "arg: pwd needed" ); //ip lua_getfield(L, 1, "ip"); if (!lua_isnil(L, -1)){ /* found? */ if( lua_isstring(L, -1) ) // deal with the ssid string { const char *ip = luaL_checklstring( L, -1, &len ); if(len>16) return luaL_error( L, "ip:<16" ); if(is_valid_ip(ip)==false) return luaL_error( L, "ip invalid" ); strncpy(wNetConfig.local_ip_addr,ip,len); } else return luaL_error( L, "wrong arg type:ip" ); } else { strcpy(wNetConfig.local_ip_addr,"11.11.11.1"); //return luaL_error( L, "arg: ip needed" ); } //netmask lua_getfield(L, 1, "netmask"); if (!lua_isnil(L, -1)){ /* found? */ if( lua_isstring(L, -1) ) // deal with the ssid string { const char *netmask = luaL_checklstring( L, -1, &len ); if(len>16) return luaL_error( L, "netmask:<16" ); if(is_valid_ip(netmask)==false) return luaL_error( L, "netmask invalid" ); strncpy(wNetConfig.net_mask,netmask,len); } else return luaL_error( L, "wrong arg type:netmask" ); } else { strcpy(wNetConfig.net_mask,"255.255.255.0"); //return luaL_error( L, "arg: netmask needed" ); } //gateway lua_getfield(L, 1, "gateway"); if (!lua_isnil(L, -1)){ /* found? */ if( lua_isstring(L, -1) ) // deal with the ssid string { const char *gateway = luaL_checklstring( L, -1, &len ); if(len>16) return luaL_error( L, "gateway:<16" ); if(is_valid_ip(gateway)==false) return luaL_error( L, "gateway invalid" ); strncpy(wNetConfig.gateway_ip_addr,gateway,len); } else return luaL_error( L, "wrong arg type:gateway" ); } else { strcpy(wNetConfig.gateway_ip_addr,"11.11.11.1"); // return luaL_error( L, "arg: gateway needed" ); } //dnsSrv lua_getfield(L, 1, "dnsSrv"); if (!lua_isnil(L, -1)){ /* found? */ if( lua_isstring(L, -1) ) // deal with the ssid string { const char *dnsSrv = luaL_checklstring( L, -1, &len ); if(len>16) return luaL_error( L, "dnsSrv:<16" ); if(is_valid_ip(dnsSrv)==false) return luaL_error( L, "dnsSrv invalid" ); strncpy(wNetConfig.dnsServer_ip_addr,dnsSrv,len); } else return luaL_error( L, "wrong arg type:dnsSrv" ); } else { strcpy(wNetConfig.dnsServer_ip_addr,"11.11.11.1"); //return luaL_error( L, "arg: dnsSrv needed" ); } //retry_interval signed retry_interval=0; lua_getfield(L, 1, "retry_interval"); if (!lua_isnil(L, -1)){ /* found? */ retry_interval= luaL_checknumber( L, -1 ); if(retry_interval<=0) return luaL_error( L, "retry_interval:>0ms" ); } else retry_interval = 1000; wNetConfig.wifi_retry_interval = retry_interval; /*MCU_DBG("wifi_ssid:%s\r\n",wNetConfig.wifi_ssid); MCU_DBG("wifi_key:%s\r\n",wNetConfig.wifi_key); MCU_DBG("local_ip_addr:%s\r\n",wNetConfig.local_ip_addr); MCU_DBG("net_mask:%s\r\n",wNetConfig.net_mask); MCU_DBG("gateway_ip_addr:%s\r\n",wNetConfig.gateway_ip_addr); MCU_DBG("dnsServer_ip_addr:%s\r\n",wNetConfig.dnsServer_ip_addr); MCU_DBG("wifi_retry_interval:%d\r\n",wNetConfig.wifi_retry_interval);*/ //notify gL = L; if (lua_type(L, 2) == LUA_TFUNCTION || lua_type(L, 2) == LUA_TLIGHTFUNCTION) { lua_pushvalue(L, 2); // copy argument (func) to the top of stack if(wifi_status_changed_AP != LUA_NOREF) luaL_unref(L, LUA_REGISTRYINDEX, wifi_status_changed_AP); wifi_status_changed_AP = luaL_ref(L, LUA_REGISTRYINDEX); MICOAddNotification( mico_notify_WIFI_STATUS_CHANGED, (void *)_micoNotify_WifiStatusHandler ); } else { if(wifi_status_changed_AP != LUA_NOREF) luaL_unref(L, LUA_REGISTRYINDEX, wifi_status_changed_AP); wifi_status_changed_AP = LUA_NOREF; } //start wNetConfig.dhcpMode = DHCP_Server; wNetConfig.wifi_mode = Soft_AP; micoWlanStart(&wNetConfig); return 0; }
int os_locate(lua_State* L) { int i, nArgs, vars; const char* premake_path = getenv("PREMAKE_PATH"); nArgs = lua_gettop(L); /* see if the global environment variables have been set yet */ lua_getglobal(L, "_USER_HOME_DIR"); vars = !lua_isnil(L, -1); lua_pop(L, 1); for (i = 1; i <= nArgs; ++i) { /* Direct path to file? Return fully qualified version */ if (do_isfile(lua_tostring(L, i))) { lua_pushcfunction(L, path_getabsolute); lua_pushvalue(L, i); lua_call(L, 1, 1); return 1; } /* Search for it... */ lua_pushcfunction(L, os_pathsearch); lua_pushvalue(L, i); /* ...relative to the main project script */ if (vars) { lua_getglobal(L, "_MAIN_SCRIPT_DIR"); } /* ...relative to the CWD */ lua_pushstring(L, "."); /* ...on the paths specified by --scripts, if set */ if (scripts_path) { lua_pushstring(L, scripts_path); } /* ... relative to ~/.premake */ if (vars) { lua_getglobal(L, "_USER_HOME_DIR"); lua_pushstring(L, "/.premake"); lua_concat(L, 2); } /* ...on the PREMAKE_PATH environment variable, if set */ if (premake_path) { lua_pushstring(L, premake_path); } /* ...relative to the Premake executable */ if (vars) { lua_getglobal(L, "_PREMAKE_DIR"); } /* ...in ~/Library/Application Support/Premake (for OS X) */ if (vars) { lua_getglobal(L, "_USER_HOME_DIR"); lua_pushstring(L, "/Library/Application Support/Premake"); lua_concat(L, 2); } /* ...in the expected Unix-y places */ lua_pushstring(L, "/usr/local/share/premake"); lua_pushstring(L, "/usr/share/premake"); lua_call(L, lua_gettop(L) - nArgs - 1, 1); if (!lua_isnil(L, -1)) { lua_pushcfunction(L, path_join); lua_pushvalue(L, -2); lua_pushvalue(L, i); lua_call(L, 2, 1); return 1; } lua_pop(L, 1); } return 0; }
// Called from C to open a pload static int addon_output_pload_open(void *obj, void **priv, struct pload *pload) { struct addon_instance_priv *p = obj; // Lock the output pom_mutex_lock(&p->lock); lua_getfield(p->L, LUA_REGISTRYINDEX, ADDON_INSTANCE); // Stack : self struct addon_output_pload_priv *ppriv = malloc(sizeof(struct addon_output_pload_priv)); if (!ppriv) { pom_mutex_unlock(&p->lock); pom_oom(sizeof(struct addon_output_pload_priv)); return POM_ERR; } memset(ppriv, 0, sizeof(struct addon_output_pload_priv)); *priv = ppriv; // Get the __pload_listener table lua_getfield(p->L, -1, "__pload_listener"); // Stack : self, __pload_listener // Get the open function lua_getfield(p->L, -1, "open"); // Stack : self, __pload_listener, open_func // Check if there is an open function if (lua_isnil(p->L, -1)) { pom_mutex_unlock(&p->lock); lua_pop(p->L, 3); // Stack : empty return POM_OK; } // Add self lua_pushvalue(p->L, -3); // Stack : self, __pload_listener, open_func, self // Create a new table for the pload priv and store it into __pload_listener lua_newtable(p->L); // Stack : self, __pload_listener, open_func, self, pload_priv_table // Add output_pload_data to it addon_pload_data_push(p->L); // Stack : self, __pload_listener, open_func, self, pload_priv_table, pload_data lua_setfield(p->L, -2, "__pload_data"); // Stack : self, __pload_listener, open_func, self, pload_priv_table // Add the new priv to the __pload_listener table lua_pushlightuserdata(p->L, ppriv); // Stack : self, __pload_listener, open_func, self, pload_priv_table, pload_priv lua_pushvalue(p->L, -2); // Stack : self, __pload_listener, open_func, self, pload_priv_table, pload_priv, pload_priv_table lua_settable(p->L, -6); // Stack : self, __pload_listener, open_func, self, pload_priv_table // Add the pload to the args addon_pload_push(p->L, pload, ppriv); // Stack : self, __pload_listener, open_func, self, pload_priv_table, pload // Call the open function addon_pcall(p->L, 3, 1); // Stack : self, __pload_listener, result int res = 0; if (!lua_isboolean(p->L, -1)) { pomlog(POMLOG_WARN "LUA coding error: pload open function result must be a boolean"); } else { res = lua_toboolean(p->L, -1); } if (!res) { // The payload doesn't need to be processed, remove the payload_priv_table and the __pload_data lua_pushlightuserdata(p->L, ppriv); // Stack : self, __pload_listener, result, pload_priv lua_pushnil(p->L); // Stack : self, __pload_listener, result, pload_priv, nil lua_settable(p->L, -4); // Stack : self, __pload_listener, result lua_pushnil(p->L); // Stack : self, __pload_listener, result, nil lua_setfield(p->L, -3, "__pload_data"); // Stack : self, __pload_listener, result } // Remove leftovers lua_pop(p->L, 3); // Stack : empty pom_mutex_unlock(&p->lock); return POM_OK; }
// Called from C to write a pload static int addon_output_pload_write(void *output_priv, void *pload_instance_priv, void *data, size_t len) { struct addon_output_pload_priv *ppriv = pload_instance_priv; struct addon_instance_priv *p = output_priv; pom_mutex_lock(&p->lock); // First process all the plugins attached to this pload struct addon_output_pload_plugin *tmp; for (tmp = ppriv->plugins; tmp; tmp = tmp->next) { if (tmp->is_err) continue; if (addon_plugin_pload_write(tmp->addon_reg, ppriv->plugin_priv, tmp->pload_priv, data, len) != POM_OK) { addon_plugin_pload_close(tmp->addon_reg, ppriv->plugin_priv, tmp->pload_priv); tmp->is_err = 1; } } lua_getfield(p->L, LUA_REGISTRYINDEX, ADDON_INSTANCE); // Stack : self lua_getfield(p->L, -1, "__pload_listener"); // Stack : self, __pload_listener // Get the write function lua_getfield(p->L, -1, "write"); // Stack : self, __pload_listener, write_func // Check if there is a write function if (lua_isnil(p->L, -1)) { lua_pop(p->L, 3); // Stack : empty pom_mutex_unlock(&p->lock); return POM_OK; } // Setup args lua_pushvalue(p->L, -3); // Stack : self, __pload_listener, write_func, self lua_pushlightuserdata(p->L, pload_instance_priv); // Stack : self, __pload_listener, write_func, self, pload_priv lua_gettable(p->L, -4); // Stack : self, __pload_listener, write_func, self, pload_priv_table if (lua_isnil(p->L, -1)) { // There is no pload_priv_table, payload doesn't need to be processed lua_pop(p->L, 5); // Stack : empty pom_mutex_unlock(&p->lock); return POM_OK; } lua_getfield(p->L, -1, "__pload_data"); // Stack : self, __pload_listener, write_func, self, pload_priv_table, pload_data // Update the pload_data addon_pload_data_update(p->L, -1, data, len); pom_mutex_unlock(&p->lock); int res = addon_pcall(p->L, 3, 1); // Stack : self, __pload_listener, result int write_res = 0; if (res == POM_OK) { if (!lua_isboolean(p->L, -1)) { pomlog(POMLOG_WARN "LUA coding error: pload write function result must be a boolean"); } else { write_res = lua_toboolean(p->L, -1); } } if (!write_res) { // Remove the pload_priv_table since it failed lua_pushlightuserdata(p->L, pload_instance_priv); // Stack : self, __pload_listener, result, pload_priv lua_pushnil(p->L); // Stack : self, __pload_listener, result, pload_priv, nil lua_settable(p->L, -4); // Stack : self, __pload_listener, result } lua_pop(p->L, 3); // Stack : empty pom_mutex_unlock(&p->lock); return POM_OK; }
/* args-opts -- proc/nil error */ static int ex_spawn(lua_State *L) { struct spawn_params *params; int have_options; switch (lua_type(L, 1)) { default: return luaL_typerror(L, 1, "string or table"); case LUA_TSTRING: switch (lua_type(L, 2)) { default: return luaL_typerror(L, 2, "table"); case LUA_TNONE: have_options = 0; break; case LUA_TTABLE: have_options = 1; break; } break; case LUA_TTABLE: have_options = 1; /* avoid issues with strict.lua */ lua_pushstring(L, "command"); /* opts ... cmd */ lua_rawget(L, 1); if (!lua_isnil(L, -1)) { /* convert {command=command,arg1,...} to command {arg1,...} */ lua_insert(L, 1); /* cmd opts ... */ } else { /* convert {arg0,arg1,...} to arg0 {arg1,...} */ size_t i, n = lua_objlen(L, 1); lua_rawgeti(L, 1, 1); /* opts ... nil cmd */ lua_insert(L, 1); /* cmd opts ... nil */ for (i = 2; i <= n; i++) { lua_rawgeti(L, 2, i); /* cmd opts ... nil argi */ lua_rawseti(L, 2, i - 1); /* cmd opts ... nil */ } lua_rawseti(L, 2, n); /* cmd opts ... */ } if (lua_type(L, 1) != LUA_TSTRING) return luaL_error(L, "bad command option (string expected, got %s)", luaL_typename(L, 1)); break; } params = spawn_param_init(L); /* get filename to execute */ spawn_param_filename(params); /* get arguments, environment, and redirections */ if (have_options) { lua_getfield(L, 2, "args"); /* cmd opts ... argtab */ switch (lua_type(L, -1)) { default: return luaL_error(L, "bad args option (table expected, got %s)", luaL_typename(L, -1)); case LUA_TNIL: lua_pop(L, 1); /* cmd opts ... */ lua_pushvalue(L, 2); /* cmd opts ... opts */ if (0) /*FALLTHRU*/ case LUA_TTABLE: if (lua_objlen(L, 2) > 0) return luaL_error(L, "cannot specify both the args option and array values"); spawn_param_args(params); /* cmd opts ... */ break; } lua_getfield(L, 2, "env"); /* cmd opts ... envtab */ switch (lua_type(L, -1)) { default: return luaL_error(L, "bad env option (table expected, got %s)", luaL_typename(L, -1)); case LUA_TNIL: break; case LUA_TTABLE: spawn_param_env(params); /* cmd opts ... */ break; } lua_getfield(L, 2, "show"); /* cmd opts ... envtab */ spawn_param_show(params, lua_type(L, -1) == LUA_TBOOLEAN ? lua_toboolean(L, -1) : 0); lua_getfield(L, 2, "shell"); /* cmd opts ... envtab */ spawn_param_useshell(params, lua_type(L, -1) == LUA_TBOOLEAN ? lua_toboolean(L, -1) : 1); lua_getfield(L, 2, "detach"); /* cmd opts ... envtab */ spawn_param_detach(params, lua_type(L, -1) == LUA_TBOOLEAN ? lua_toboolean(L, -1) : 0); get_redirect(L, 2, "stdin", params); /* cmd opts ... */ get_redirect(L, 2, "stdout", params); /* cmd opts ... */ get_redirect(L, 2, "stderr", params); /* cmd opts ... */ } return spawn_param_execute(params); /* proc/nil error */ }
LUAMODULE_API int luaopen_ex_core(lua_State *L) { const char *name = lua_tostring(L, 1); int ex; const luaL_reg ex_iolib[] = { {"pipe", ex_pipe}, #define ex_iofile_methods (ex_iolib + 1) {"lock", ex_lock}, {"unlock", ex_lock}, {0,0} }; const luaL_reg ex_oslib[] = { /* environment */ {"getenv", ex_getenv}, {"setenv", ex_setenv}, {"environ", ex_environ}, /* file system */ {"access", ex_access}, {"getcwd", ex_getcwd}, {"chdir", ex_chdir}, {"chmod", ex_chmod}, {"mkdir", ex_mkdir}, {"remove", ex_remove}, {"dir", ex_dir}, {"dirent", ex_dirent}, {"copyfile", ex_copyfile}, {"movefile", ex_movefile}, {"touch", ex_touch}, {"stdin_binary", ex_stdin_binary}, {"stdout_binary", ex_stdout_binary}, /* process control */ {"sleep", ex_sleep}, {"spawn", ex_spawn}, {0,0} }; const luaL_reg ex_diriter_methods[] = { {"__gc", diriter_close}, {0,0} }; const luaL_reg ex_process_methods[] = { {"__tostring", process_tostring}, #define ex_process_functions (ex_process_methods + 1) {"wait", process_wait}, {"__gc", process_close}, {0,0} }; /* diriter metatable */ luaL_newmetatable(L, DIR_HANDLE); /* . D */ luaL_register(L, 0, ex_diriter_methods); /* . D */ /* proc metatable */ luaL_newmetatable(L, PROCESS_HANDLE); /* . P */ luaL_register(L, 0, ex_process_methods); /* . P */ lua_pushvalue(L, -1); /* . P P */ lua_setfield(L, -2, "__index"); /* . P */ /* make all functions available via ex. namespace */ luaL_register(L, name, ex_oslib); /* . P ex */ luaL_register(L, 0, ex_iolib); copyfields(L, ex_process_functions, -2, -1); ex = lua_gettop(L); /* extend the os table */ lua_getglobal(L, "os"); /* . os */ if (lua_isnil(L, -1)) return luaL_error(L, "os not loaded"); copyfields(L, ex_oslib, ex, -1); luaopen_os_path(L); /* extend the io table */ lua_getglobal(L, "io"); /* . io */ if (lua_isnil(L, -1)) return luaL_error(L, "io not loaded"); copyfields(L, ex_iolib, ex, -1); // copyfields(L, ex_iolib, ex, -1); lua_getfield(L, ex, "pipe"); /* . io ex_pipe */ newfenv(L, pipe_close); /* create environment for 'popen' */ lua_setfenv(L, -2); /* set fenv for 'popen' */ lua_pop(L, 1); /* pop 'popen' */ /* extend the io.file metatable */ luaL_getmetatable(L, LUA_FILEHANDLE); /* . F */ if (lua_isnil(L, -1)) return luaL_error(L, "can't find FILE* metatable"); copyfields(L, ex_iofile_methods, ex, -1); luaopen_windows_hkey(L); return 1; }
static int gritobj_newindex (lua_State *L) { TRY_START check_args(L,3); GET_UD_MACRO(GritObjectPtr,self,1,GRITOBJ_TAG); std::string key = check_string(L,2); if (key=="destroy") { my_lua_error(L,"Not a writeable GritObject member: "+key); } else if (key=="near") { if (lua_isnil(L,3)) { self->setNearObj(self,GritObjectPtr()); } else { GET_UD_MACRO(GritObjectPtr,v,3,GRITOBJ_TAG); self->setNearObj(self,v); } } else if (key=="far") { if (lua_isnil(L,3)) { self->setNearObj(self,GritObjectPtr()); } else { GET_UD_MACRO(GritObjectPtr,v,3,GRITOBJ_TAG); self->setFarObj(self,v); } } else if (key=="fade") { my_lua_error(L,"Not a writeable GritObject member: "+key); } else if (key=="updateSphere") { my_lua_error(L,"Not a writeable GritObject member: "+key); } else if (key=="pos") { self->updateSphere(check_v3(L,3)); } else if (key=="renderingDistance") { self->updateSphere(check_float(L,3)); } else if (key=="getSphere") { my_lua_error(L,"Not a writeable GritObject member: "+key); } else if (key=="activated") { my_lua_error(L,"Not a writeable GritObject member: "+key); } else if (key=="deactivate") { my_lua_error(L,"Not a writeable GritObject member: "+key); } else if (key=="activate") { my_lua_error(L,"Not a writeable GritObject member: "+key); } else if (key=="instance") { my_lua_error(L,"Not a writeable GritObject member: "+key); } else if (key=="hintAdvancePrepare") { my_lua_error(L,"Not a writeable GritObject member: "+key); } else if (key=="getAdvancePrepareHints") { my_lua_error(L,"Not a writeable GritObject member: "+key); } else if (key=="destroyed") { my_lua_error(L,"Not a writeable GritObject member: "+key); } else if (key=="class") { my_lua_error(L,"Not a writeable GritObject member: "+key); } else if (key=="className") { my_lua_error(L,"Not a writeable GritObject member: "+key); } else if (key=="name") { my_lua_error(L,"Not a writeable GritObject member: "+key); } else if (key=="needsFrameCallbacks") { self->setNeedsFrameCallbacks(self, check_bool(L,3)); } else if (key=="needsStepCallbacks") { self->setNeedsStepCallbacks(self, check_bool(L,3)); } else { GritClass *c = self->getClass(); if (c==NULL) my_lua_error(L,"GritObject destroyed"); const char *err = self->userValues.luaSet(L); if (err) my_lua_error(L, err); } return 0; TRY_END }
static int gritobj_index (lua_State *L) { TRY_START check_args(L,2); GET_UD_MACRO(GritObjectPtr,self,1,GRITOBJ_TAG); std::string key = check_string(L,2); if (key=="destroy") { push_cfunction(L,gritobj_destroy); } else if (key=="activated") { lua_pushboolean(L,self->isActivated()); } else if (key=="near") { push_gritobj(L,self->getNearObj()); } else if (key=="far") { push_gritobj(L,self->getFarObj()); } else if (key=="fade") { lua_pushnumber(L,self->getFade()); } else if (key=="updateSphere") { push_cfunction(L,gritobj_update_sphere); } else if (key=="pos") { push_v3(L, self->getPos()); } else if (key=="renderingDistance") { lua_pushnumber(L, self->getR()); } else if (key=="deactivate") { push_cfunction(L,gritobj_deactivate); } else if (key=="activate") { push_cfunction(L,gritobj_activate); } else if (key=="instance") { self->pushLuaTable(L); } else if (key=="addDiskResource") { push_cfunction(L,gritobj_add_disk_resource); } else if (key=="reloadDiskResources") { push_cfunction(L,gritobj_reload_disk_resource); /* } else if (key=="getAdvancePrepareHints") { push_cfunction(L,gritobj_get_advance_prepare_hints); */ } else if (key=="destroyed") { lua_pushboolean(L,self->getClass()==NULL); } else if (key=="class") { GritClass *c = self->getClass(); if (c==NULL) my_lua_error(L,"GritObject destroyed"); push_gritcls(L,c); } else if (key=="className") { GritClass *c = self->getClass(); if (c==NULL) my_lua_error(L,"GritObject destroyed"); lua_pushstring(L,c->name.c_str()); } else if (key=="name") { lua_pushstring(L,self->name.c_str()); } else if (key=="needsFrameCallbacks") { lua_pushboolean(L,self->getNeedsFrameCallbacks()); } else if (key=="needsStepCallbacks") { lua_pushboolean(L,self->getNeedsStepCallbacks()); } else if (key=="dump") { self->userValues.dump(L); } else { GritClass *c = self->getClass(); if (c==NULL) my_lua_error(L,"GritObject destroyed"); const char *err = self->userValues.luaGet(L); if (err) my_lua_error(L, err); if (!lua_isnil(L,-1)) return 1; lua_pop(L,1); // try class instead c->get(L,key); } return 1; TRY_END }
typedef typename boost::mpl::if_<boost::is_void<R> , luabind::detail::proxy_member_void_caller<boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> > , luabind::detail::proxy_member_caller<R, boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> > >::type proxy_type; // this will be cleaned up by the proxy object // once the call has been made // TODO: what happens if this virtual function is // dispatched from a lua thread where the state // pointer is different? // get the function lua_State* L = m_self.state(); m_self.get(L); assert(!lua_isnil(L, -1)); detail::do_call_member_selection(L, name); if (lua_isnil(L, -1)) { lua_pop(L, 1); throw std::runtime_error("Attempt to call nonexistent function"); } // push the self reference as the first parameter m_self.get(L); // now the function and self objects // are on the stack. These will both // be popped by pcall return proxy_type(L, args);
jass::jreal_t read_real(lua_State* L, int index) { if (lua_isnil(L, index)) return 0; return jass::to_real(jreal::read<float>(L, index)); }
// Called from C to close a pload static int addon_output_pload_close(void *output_priv, void *pload_instance_priv) { struct addon_output_pload_priv *ppriv = pload_instance_priv; struct addon_instance_priv *p = output_priv; int res = POM_OK; pom_mutex_lock(&p->lock); // Process all the plugins attached to this pload struct addon_output_pload_plugin *tmp; for (tmp = ppriv->plugins; tmp; tmp = tmp->next) { if (tmp->is_err) continue; addon_plugin_pload_close(tmp->addon_reg, ppriv->plugin_priv, tmp->pload_priv); } lua_getfield(p->L, LUA_REGISTRYINDEX, ADDON_INSTANCE); // Stack : self lua_getfield(p->L, -1, "__pload_listener"); // Stack : self, __pload_listener // Get the pload_priv_table lua_pushlightuserdata(p->L, pload_instance_priv); // Stack : self, __pload_listener, pload_priv lua_gettable(p->L, -2); // Stack : self, __pload_listener, pload_priv_table if (lua_isnil(p->L, -1)) { // There is no pload_priv_table, the payload doesn't need to be processed lua_pop(p->L, 3); goto cleanup; } // Remove the payload_priv_table from __pload_listener lua_pushlightuserdata(p->L, pload_instance_priv); // Stack : self, __pload_listener, pload_priv_table, pload_priv lua_pushnil(p->L); // Stack : self, __pload_listener, pload_priv_table, pload_priv, nil lua_settable(p->L, -4); // Stack : self, __pload_listener, pload_priv_table // Get the close function lua_getfield(p->L, -2, "close"); // Stack : self, __pload_listener, pload_priv_table, close_func if (lua_isnil(p->L, -1)) { // There is no close function lua_pop(p->L, 4); // Stack : empty goto cleanup; } // Setup args lua_pushvalue(p->L, 1); // Stack : self, __pload_listener, pload_priv_table, close_func, self lua_pushvalue(p->L, -3); // Stack : self, __pload_listener, pload_priv_table, close_func, self, pload_priv_table res = addon_pcall(p->L, 2, 0); // Stack : self, __pload_listener, pload_priv_table lua_pop(p->L, 3); // Stack : empty cleanup: pom_mutex_unlock(&p->lock); while (ppriv->plugins) { tmp = ppriv->plugins; ppriv->plugins = tmp->next; free(tmp); } free(ppriv); return res; }
/* ** Read the options specified in the ini file. ** */ void CMeasureScript::ReadOptions(CConfigParser& parser, const WCHAR* section) { CMeasure::ReadOptions(parser, section); std::wstring file = parser.ReadString(section, L"ScriptFile", L""); if (!file.empty()) { if (m_MeterWindow) { m_MeterWindow->MakePathAbsolute(file); } if (!m_Initialized || wcscmp(file.c_str(), m_ScriptFile.c_str()) != 0) { DeleteLuaScript(); lua_State* L = LuaManager::GetState(); m_ScriptFile = file; m_LuaScript = new LuaScript(m_ScriptFile.c_str()); if (m_LuaScript->IsInitialized()) { m_HasInitializeFunction = m_LuaScript->IsFunction(g_InitializeFunctionName); m_HasUpdateFunction = m_LuaScript->IsFunction(g_UpdateFunctionName); m_HasGetStringFunction = m_LuaScript->IsFunction(g_GetStringFunctionName); // For backwards compatbility if (m_HasGetStringFunction) { LogWithArgs(LOG_WARNING, L"Script: Using deprecated GetStringValue() in [%s]", m_Name.c_str()); } lua_rawgeti(L, LUA_GLOBALSINDEX, m_LuaScript->GetRef()); *(CMeterWindow**)lua_newuserdata(L, sizeof(CMeterWindow*)) = m_MeterWindow; lua_getglobal(L, "CMeterWindow"); lua_setmetatable(L, -2); lua_setfield(L, -2, "SKIN"); *(CMeasure**)lua_newuserdata(L, sizeof(CMeasure*)) = this; lua_getglobal(L, "CMeasure"); lua_setmetatable(L, -2); lua_setfield(L, -2, "SELF"); // For backwards compatibility lua_getfield(L, -1, "PROPERTIES"); if (lua_isnil(L, -1) == 0) { lua_pushnil(L); // Look in the table for values to read from the section while (lua_next(L, -2)) { lua_pop(L, 1); const char* strKey = lua_tostring(L, -1); std::wstring wstrKey = ConvertToWide(strKey); const std::wstring& wstrValue = parser.ReadString(section, wstrKey.c_str(), L""); if (!wstrValue.empty()) { LuaManager::PushWide(L, wstrValue.c_str()); lua_setfield(L, -3, strKey); } } } // Pop PROPERTIES table and our table lua_pop(L, 2); } else { DeleteLuaScript(); } } } else { LogWithArgs(LOG_ERROR, L"Script: File not valid in [%s]", m_Name.c_str()); DeleteLuaScript(); } }
// Called from lua to start listening to files static int addon_output_pload_listen_start(lua_State *L) { // Args should be : // 1) self // 2) open function // 3) write function // 4) close function // 5) filter if any // Push nill if additional functions are missing while (lua_gettop(L) < 5) lua_pushnil(L); // Stack : instance, read_func, write_func, close_func // Get the output struct addon_instance_priv *p = addon_output_get_priv(L, 1); if (!lua_isfunction(L, 2) && !lua_isfunction(L, 3) && !lua_isfunction(L, 4)) luaL_error(L, "At least one function should be provided to pload_listen_start()"); // Check if we are already listening or not lua_getfield(L, 1, "__pload_listener"); if (!lua_isnil(L, -1)) luaL_error(L, "The output is already listening for payloads"); struct filter *filter = NULL; if (!lua_isnoneornil(L, 5)) { const char *filter_str = luaL_checkstring(L, 5); filter = pload_filter_compile((char*)filter_str); if (!filter) luaL_error(L, "Error while parsing filter \"%s\"", filter_str); } if (pload_listen_start(p, NULL, filter, addon_output_pload_open, addon_output_pload_write, addon_output_pload_close) != POM_OK) luaL_error(L, "Error while registering the payload listener"); // Create table to track pload listener functions lua_pushliteral(L, "__pload_listener"); lua_newtable(L); if (!lua_isnil(L, 2)) { lua_pushliteral(L, "open"); lua_pushvalue(L, 2); lua_settable(L, -3); } if (!lua_isnil(L, 3)) { lua_pushliteral(L, "write"); lua_pushvalue(L, 3); lua_settable(L, -3); } if (!lua_isnil(L, 4)) { lua_pushliteral(L, "close"); lua_pushvalue(L, 4); lua_settable(L, -3); } lua_settable(L, 1); return 0; }
bool LuaInterface::isNil(int index) { assert(hasIndex(index)); return lua_isnil(L, index); }
void evalGenericCommand(redisClient *c, int evalsha) { lua_State *lua = server.lua; char funcname[43]; long long numkeys; int delhook = 0; /* We want the same PRNG sequence at every call so that our PRNG is * not affected by external state. * * 在每次执行 EVAL 时重置随机 seed ,从而保证可以生成相同的随机序列。 */ redisSrand48(0); /* We set this flag to zero to remember that so far no random command * was called. This way we can allow the user to call commands like * SRANDMEMBER or RANDOMKEY from Lua scripts as far as no write command * is called (otherwise the replication and AOF would end with non * deterministic sequences). * * Thanks to this flag we'll raise an error every time a write command * is called after a random command was used. * * 用两个变量,对命令进行检查 * 确保在调用随机命令之后,再调用写命令将出现错误 */ server.lua_random_dirty = 0; server.lua_write_dirty = 0; /* Get the number of arguments that are keys */ // 获取输入键的数量 if (getLongLongFromObjectOrReply(c,c->argv[2],&numkeys,NULL) != REDIS_OK) return; // 对键的正确性做一个快速检查 if (numkeys > (c->argc - 3)) { addReplyError(c,"Number of keys can't be greater than number of args"); return; } /* We obtain the script SHA1, then check if this function is already * defined into the Lua state */ // 组合出函数的名字,例如 f_282297a0228f48cd3fc6a55de6316f31422f5d17 funcname[0] = 'f'; funcname[1] = '_'; if (!evalsha) { /* Hash the code if this is an EVAL call */ // 如果执行的是 EVAL 命令,那么计算脚本的 SHA1 校验和 sha1hex(funcname+2,c->argv[1]->ptr,sdslen(c->argv[1]->ptr)); } else { // 如果执行的是 EVALSHA 命令,直接使用传入的 SHA1 值 /* We already have the SHA if it is a EVALSHA */ int j; char *sha = c->argv[1]->ptr; for (j = 0; j < 40; j++) funcname[j+2] = tolower(sha[j]); funcname[42] = '\0'; } /* Try to lookup the Lua function */ // 按名查找函数 lua_getglobal(lua, funcname); if (lua_isnil(lua,1)) { // 没找到脚本相应的脚本 lua_pop(lua,1); /* remove the nil from the stack */ /* Function not defined... let's define it if we have the * body of the funciton. If this is an EVALSHA call we can just * return an error. */ if (evalsha) { // 如果执行的是 EVALSHA ,返回脚本未找到错误 addReply(c, shared.noscripterr); return; } // 如果执行的是 EVAL ,那么创建并执行新函数,然后将代码添加到脚本字典中 if (luaCreateFunction(c,lua,funcname,c->argv[1]) == REDIS_ERR) return; /* Now the following is guaranteed to return non nil */ lua_getglobal(lua, funcname); redisAssert(!lua_isnil(lua,1)); } /* Populate the argv and keys table accordingly to the arguments that * EVAL received. */ // 设置 KEYS 和 ARGV 全局变量到 Lua 环境 luaSetGlobalArray(lua,"KEYS",c->argv+3,numkeys); luaSetGlobalArray(lua,"ARGV",c->argv+3+numkeys,c->argc-3-numkeys); /* Select the right DB in the context of the Lua client */ // 为 Lua 所属的(伪)客户端设置数据库 selectDb(server.lua_client,c->db->id); /* Set an hook in order to be able to stop the script execution if it * is running for too much time. * * 设置一个钩子,用于在运行时间过长时停止脚本的运作。 * * We set the hook only if the time limit is enabled as the hook will * make the Lua script execution slower. * * 只在开启了时间限制选项时使用钩子,因为它会拖慢脚本的运行速度。 */ // 调用客户端 server.lua_caller = c; // 脚本开始时间 server.lua_time_start = ustime()/1000; // 是否杀死脚本 server.lua_kill = 0; // 只在开启时间限制时使用钩子 if (server.lua_time_limit > 0 && server.masterhost == NULL) { lua_sethook(lua,luaMaskCountHook,LUA_MASKCOUNT,100000); delhook = 1; } /* At this point whatever this script was never seen before or if it was * already defined, we can call it. We have zero arguments and expect * a single return value. */ // 执行脚本(所属的函数) if (lua_pcall(lua,0,1,0)) { // 以下是脚本执行出错的代码。。。 // 删除钩子 if (delhook) lua_sethook(lua,luaMaskCountHook,0,0); /* Disable hook */ // 脚本执行已超时 if (server.lua_timedout) { // 清除超时 FLAG server.lua_timedout = 0; /* Restore the readable handler that was unregistered when the * script timeout was detected. */ // 将超时钩子里删除的读事件重新加上 aeCreateFileEvent(server.el,c->fd,AE_READABLE, readQueryFromClient,c); } // 清空调用者 server.lua_caller = NULL; // 更新目标数据库 selectDb(c,server.lua_client->db->id); /* set DB ID from Lua client */ addReplyErrorFormat(c,"Error running script (call to %s): %s\n", funcname, lua_tostring(lua,-1)); // 弹出函数 lua_pop(lua,1); // 执行完整的废料回首循环(full garbage-collection cycle) lua_gc(lua,LUA_GCCOLLECT,0); // 返回 return; } // 以下是脚本执行成功时执行的代码。。。 // 删除钩子 if (delhook) lua_sethook(lua,luaMaskCountHook,0,0); /* Disable hook */ // 清空超时 FLAG server.lua_timedout = 0; // 清空调用者 server.lua_caller = NULL; // 更新 DB selectDb(c,server.lua_client->db->id); /* set DB ID from Lua client */ // 将 Lua 回复转换成 Redis 回复 luaReplyToRedisReply(c,lua); // 执行 1 步渐进式 GC lua_gc(lua,LUA_GCSTEP,1); /* If we have slaves attached we want to replicate this command as * EVAL instead of EVALSHA. We do this also in the AOF as currently there * is no easy way to propagate a command in a different way in the AOF * and in the replication link. * * 如果有附属节点,那么使用 EVAL 而不是 EVALSHA 来传播脚本 * 因为目前还没有代码可以检测脚本是否已经传送到附属节点中 * * IMPROVEMENT POSSIBLE: * 1) Replicate this command as EVALSHA in the AOF. * 2) Remember what slave already received a given script, and replicate * the EVALSHA against this slaves when possible. */ // 如果执行的是 EVALSHA 命令 if (evalsha) { // 取出脚本代码体(body) robj *script = dictFetchValue(server.lua_scripts,c->argv[1]->ptr); redisAssertWithInfo(c,NULL,script != NULL); // 重写客户端命令为 EVAL rewriteClientCommandArgument(c,0, resetRefCount(createStringObject("EVAL",4))); rewriteClientCommandArgument(c,1,script); } }
/* | Executes a subprocess. Does not wait for it to return. | | Params on Lua stack: | | 1: Path to binary to call | 2: List of string as arguments | or "<" in which case the next argument is a string | that will be piped on stdin. | The arguments will follow that one. | | Returns (Lua stack) the pid on success, 0 on failure. */ static int l_exec( lua_State *L ) { // the binary to call const char *binary = luaL_checkstring(L, 1); // number of arguments int argc = lua_gettop( L ) - 1; // the pid spawned pid_t pid; // the arguments position in the lua arguments int li = 1; // the pipe to text char const * pipe_text = NULL; // the pipes length size_t pipe_len = 0; // the arguments char const ** argv; // pipe file descriptors int pipefd[ 2 ]; int i; // expands tables // and removes nils for( i = 1; i <= lua_gettop( L ); i++ ) { if( lua_isnil( L, i ) ) { lua_remove( L, i ); i--; argc--; continue; } if( lua_istable( L, i ) ) { int tlen; int it; lua_checkstack( L, lua_gettop( L ) + lua_objlen( L, i ) + 1 ); // moves table to top of stack lua_pushvalue( L, i ); lua_remove( L, i ); argc--; tlen = lua_objlen( L, -1 ); for( it = 1; it <= tlen; it++ ) { lua_pushinteger( L, it ); lua_gettable( L, -2 ); lua_insert( L, i ); i++; argc++; } i--; lua_pop( L, 1 ); } } // writes a log message (if needed). if( check_logcat( "Exec" ) <= settings.log_level ) { lua_checkstack( L, lua_gettop( L ) + argc * 3 + 2 ); lua_pushvalue( L, 1 ); for( i = 1; i <= argc; i++ ) { lua_pushstring( L, " [" ); lua_pushvalue( L, i + 1 ); lua_pushstring( L, "]" ); } lua_concat( L, 3 * argc + 1 ); // replaces midfile 0 chars by linefeed size_t len = 0; const char * cs = lua_tolstring( L, -1, &len ); char * s = s_calloc( len + 1, sizeof( char ) ); for( i = 0; i < len; i++ ) { s[ i ] = cs[ i ] ? cs[ i ] : '\n'; } logstring0( LOG_DEBUG, "Exec", s ); free( s ); lua_pop( L, 1 ); } if( argc >= 2 && !strcmp( luaL_checkstring( L, 2 ), "<" ) ) { // pipes something into stdin if( !lua_isstring( L, 3 ) ) { logstring( "Error", "in spawn(), expected a string after pipe '<'" ); exit( -1 ); } pipe_text = lua_tolstring( L, 3, &pipe_len ); if( strlen( pipe_text ) > 0 ) { // creates the pipe if( pipe( pipefd ) == -1 ) { logstring( "Error", "cannot create a pipe!" ); exit( -1 ); } // always closes the write end for child processes close_exec_fd( pipefd[ 1 ] ); // sets the write end on non-blocking non_block_fd( pipefd[ 1 ] ); } else { pipe_text = NULL; } argc -= 2; li += 2; } // prepares the arguments argv = s_calloc( argc + 2, sizeof( char * ) ); argv[ 0 ] = binary; for( i = 1; i <= argc; i++ ) { argv[i] = luaL_checkstring( L, i + li ); } argv[ i ] = NULL; // the fork! pid = fork( ); if( pid == 0 ) { // replaces stdin for pipes if( pipe_text ) { dup2( pipefd[ 0 ], STDIN_FILENO ); } // if lsyncd runs as a daemon and has a logfile it will redirect // stdout/stderr of child processes to the logfile. if( is_daemon && settings.log_file ) { if( !freopen( settings.log_file, "a", stdout ) ) { printlogf( L, "Error", "cannot redirect stdout to '%s'.", settings.log_file ); } if( !freopen( settings.log_file, "a", stderr ) ) { printlogf( L, "Error", "cannot redirect stderr to '%s'.", settings.log_file ); } } execv( binary, ( char ** ) argv ); // in a sane world execv does not return! printlogf( L, "Error", "Failed executing [ %s ]!", binary ); exit( -1 ); } if( pipe_text ) { int len; // first closes read-end of pipe, this is for child process only close( pipefd[ 0 ] ); // starts filling the pipe len = write( pipefd[ 1 ], pipe_text, pipe_len ); if( len < 0 ) { logstring( "Normal", "immediatly broken pipe." ); close( pipefd[ 1 ] ); } else if( len == pipe_len ) { // usual and best case, the pipe accepted all input -> close close( pipefd[ 1 ] ); logstring( "Exec", "one-sweeped pipe" ); } else { struct pipemsg *pm; logstring( "Exec", "adding pipe observance" ); pm = s_calloc( 1, sizeof( struct pipemsg ) ); pm->text = s_calloc( pipe_len + 1, sizeof( char ) ); memcpy( pm->text, pipe_text, pipe_len + 1 ); pm->tlen = pipe_len; pm->pos = len; observe_fd( pipefd[ 1 ], NULL, pipe_writey, pipe_tidy, pm ); } } free( argv ); lua_pushnumber( L, pid ); return 1; }
static int aux_getfenv (lua_State *L) { lua_getfenv(L, -1); lua_pushliteral(L, "__fenv"); lua_rawget(L, -2); return !lua_isnil(L, -1); }
const char *luaex_cmd_Reslist(cmd_parms *cmd, void *dcfg, const char *resource, const char *script) { struct dir_config *conf = dcfg; const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT); module* lua_module = ml_find_module(cmd->server, "lua_module"); if (err != NULL) return err; if (conf->resource == NULL) { conf->resource = apr_hash_make(cmd->pool); } if (conf->L == NULL) { conf->L = luaL_newstate(); #ifdef AP_ENABLE_LUAJIT luaopen_jit(conf->L); #endif luaL_openlibs(conf->L); } if (apr_hash_get(conf->resource, resource, strlen(resource)) == NULL) { lua_State *L = conf->L; int err = luaL_loadfile(L, script); if (err == LUA_ERRFILE) return apr_psprintf(cmd->pool, "cannot open/read: %s. ", script); if (err == LUA_ERRSYNTAX) return apr_psprintf(cmd->pool, "syntax error during pre-compilation for: %s. ", script); if (err == LUA_ERRMEM) return apr_psprintf(cmd->pool, "memory allocation error for load: %s. ", script); if (err) return apr_psprintf(cmd->pool, "unknown error)(%d) for load: %s. ", err, script); err = lua_pcall(L, 0, LUA_MULTRET, 0); if (err == LUA_ERRRUN) return apr_psprintf(cmd->pool, "a runtime error. %s", lua_tostring(L, -1)); if (err == LUA_ERRMEM) return apr_psprintf(cmd->pool, "memory allocation error. %s", lua_tostring(L, -1)); if (err == LUA_ERRERR) return apr_psprintf(cmd->pool, "error while running the error handler function. %s", lua_tostring(L, -1)); if (err) return apr_psprintf(cmd->pool, "unknown error(%d:%s) for load: %s. ", err, lua_tostring(L, -1), script); { int min, smax, hmax, ttl; apr_reslist_t* reslist; reslist_cb_t* cb = apr_palloc(cmd->pool, sizeof(reslist_cb_t)); luaL_getmetatable(L, resource); if (lua_isnil(L, -1)) return apr_psprintf(cmd->pool, "%s not support %s object(metatable)", script, resource); cb->name = resource; lua_pop(L, 1); if (!lua_istable(L, -1)) return apr_psprintf(cmd->pool, "%s not return a table which makes a reslist for %s", script, resource); cb->L = conf->L; lua_getfield(L, -1, "constructor"); if (!lua_isfunction(L, -1)) return apr_psprintf(cmd->pool, "%s not have a table field(constructor) function", script); cb->constructor_ref = luaL_ref(L, LUA_REGISTRYINDEX); lua_getfield(L, -1, "destructor"); if (!lua_isfunction(L, -1)) return apr_psprintf(cmd->pool, "%s not have a table field(destructor) function", script); cb->destructor_ref = luaL_ref(L, LUA_REGISTRYINDEX); lua_getfield(L, -1, "min"); min = luaL_optint(L, -1, 0); lua_pop(L, 1); lua_getfield(L, -1, "smax"); smax = luaL_optint(L, -1, 16); lua_pop(L, 1); lua_getfield(L, -1, "hmax"); hmax = luaL_optint(L, -1, 16); lua_pop(L, 1); lua_getfield(L, -1, "ttl"); ttl = luaL_optint(L, -1, 0); lua_pop(L, 1); if (apr_reslist_create(&reslist, min, smax, hmax, ttl, ml_apr_reslist_constructor, ml_apr_reslist_destructor, cb, cmd->pool) == APR_SUCCESS) { apr_hash_set(conf->resource, resource, strlen(resource), reslist); } else return "apr_reslist_create failed"; } } if (conf->resource == NULL) return "Out of memory"; return NULL; }
// add_particlespawner({amount=, time=, // minpos=, maxpos=, // minvel=, maxvel=, // minacc=, maxacc=, // minexptime=, maxexptime=, // minsize=, maxsize=, // collisiondetection=, // collision_removal=, // vertical=, // texture=, // player=}) // minpos/maxpos/minvel/maxvel/minacc/maxacc = {x=num, y=num, z=num} // minexptime/maxexptime = num (seconds) // minsize/maxsize = num // collisiondetection = bool // collision_removal = bool // vertical = bool // texture = e.g."default_wood.png" // animation = TileAnimation definition // glow = num int ModApiParticles::l_add_particlespawner(lua_State *L) { MAP_LOCK_REQUIRED; // Get parameters u16 amount = 1; v3f minpos, maxpos, minvel, maxvel, minacc, maxacc; minpos= maxpos= minvel= maxvel= minacc= maxacc= v3f(0, 0, 0); float time, minexptime, maxexptime, minsize, maxsize; time= minexptime= maxexptime= minsize= maxsize= 1; bool collisiondetection, vertical, collision_removal; collisiondetection = vertical = collision_removal = false; struct TileAnimationParams animation; animation.type = TAT_NONE; ServerActiveObject *attached = NULL; std::string texture = ""; std::string playername = ""; u8 glow = 0; if (lua_gettop(L) > 1) //deprecated { log_deprecated(L,"Deprecated add_particlespawner call with individual parameters instead of definition"); amount = luaL_checknumber(L, 1); time = luaL_checknumber(L, 2); minpos = check_v3f(L, 3); maxpos = check_v3f(L, 4); minvel = check_v3f(L, 5); maxvel = check_v3f(L, 6); minacc = check_v3f(L, 7); maxacc = check_v3f(L, 8); minexptime = luaL_checknumber(L, 9); maxexptime = luaL_checknumber(L, 10); minsize = luaL_checknumber(L, 11); maxsize = luaL_checknumber(L, 12); collisiondetection = lua_toboolean(L, 13); texture = luaL_checkstring(L, 14); if (lua_gettop(L) == 15) // only spawn for a single player playername = luaL_checkstring(L, 15); } else if (lua_istable(L, 1)) { amount = getintfield_default(L, 1, "amount", amount); time = getfloatfield_default(L, 1, "time", time); lua_getfield(L, 1, "minpos"); minpos = lua_istable(L, -1) ? check_v3f(L, -1) : minpos; lua_pop(L, 1); lua_getfield(L, 1, "maxpos"); maxpos = lua_istable(L, -1) ? check_v3f(L, -1) : maxpos; lua_pop(L, 1); lua_getfield(L, 1, "minvel"); minvel = lua_istable(L, -1) ? check_v3f(L, -1) : minvel; lua_pop(L, 1); lua_getfield(L, 1, "maxvel"); maxvel = lua_istable(L, -1) ? check_v3f(L, -1) : maxvel; lua_pop(L, 1); lua_getfield(L, 1, "minacc"); minacc = lua_istable(L, -1) ? check_v3f(L, -1) : minacc; lua_pop(L, 1); lua_getfield(L, 1, "maxacc"); maxacc = lua_istable(L, -1) ? check_v3f(L, -1) : maxacc; lua_pop(L, 1); minexptime = getfloatfield_default(L, 1, "minexptime", minexptime); maxexptime = getfloatfield_default(L, 1, "maxexptime", maxexptime); minsize = getfloatfield_default(L, 1, "minsize", minsize); maxsize = getfloatfield_default(L, 1, "maxsize", maxsize); collisiondetection = getboolfield_default(L, 1, "collisiondetection", collisiondetection); collision_removal = getboolfield_default(L, 1, "collision_removal", collision_removal); lua_getfield(L, 1, "animation"); animation = read_animation_definition(L, -1); lua_pop(L, 1); lua_getfield(L, 1, "attached"); if (!lua_isnil(L, -1)) { ObjectRef *ref = ObjectRef::checkobject(L, -1); lua_pop(L, 1); attached = ObjectRef::getobject(ref); } vertical = getboolfield_default(L, 1, "vertical", vertical); texture = getstringfield_default(L, 1, "texture", ""); playername = getstringfield_default(L, 1, "playername", ""); glow = getintfield_default(L, 1, "glow", 0); } u32 id = getServer(L)->addParticleSpawner(amount, time, minpos, maxpos, minvel, maxvel, minacc, maxacc, minexptime, maxexptime, minsize, maxsize, collisiondetection, collision_removal, attached, vertical, texture, playername, animation, glow); lua_pushnumber(L, id); return 1; }
// implements IVisCallbackHandler_cl void vHavokBehaviorModule::OnHandleCallback(IVisCallbackDataObject_cl *pData) { // Setup // Register vision callbacks if( pData->m_pSender == &Vision::Callbacks.OnUpdateSceneBegin ) { checkEditorModeChanged(); stepModule(); } else if( pData->m_pSender == &Vision::Callbacks.OnAfterSceneLoaded ) { // Set physics module vHavokPhysicsModule* physicsModule = vHavokPhysicsModule::GetInstance(); if( physicsModule != HK_NULL ) { hkpWorld* physicsWorld = physicsModule->GetPhysicsWorld(); // Set world gravity physicsWorld->markForRead(); { hkVector4 up; up.setNeg3( physicsWorld->getGravity() ); up.normalize3(); m_behaviorWorld->setUp( up ); } physicsWorld->unmarkForRead(); } else { hkVector4 up; vHavokConversionUtils::VisVecToPhysVec_noscale( m_visionCharacters[0]->getEntityOwner()->GetObjDir_Up(), up ); m_behaviorWorld->setUp( up ); } } else if( pData->m_pSender == &Vision::Callbacks.OnAfterSceneUnloaded ) { /*#if defined(HAVOK_SDK_VERSION_MAJOR) && (HAVOK_SDK_VERSION_MAJOR >= 2012) // destroy all unreferenced navmesh instances m_projectAssetManager->clearAssets(); hkbOnHeapAssetLoader* assetLoader = static_cast<hkbOnHeapAssetLoader*>( m_assetLoader ); assetLoader->unloadAllAssets(); HK_ASSERT(0x21e79cc1, m_visionCharacters.getSize() == 0 ); // unload all unused resources vHavokBehaviorResourceManager::GetInstance()->PurgeUnusedResources(); HK_ASSERT(0xc5b3c4e, vHavokBehaviorResourceManager::GetInstance()->GetResourceCount() == 0 ); #endif*/ } else if( pData->m_pSender == &vHavokPhysicsModule::OnBeforeInitializePhysics ) { vHavokPhysicsModuleCallbackData *pHavokData = (vHavokPhysicsModuleCallbackData*)pData; VISION_HAVOK_SYNC_STATICS(); VISION_HAVOK_SYNC_PER_THREAD_STATICS( pHavokData->GetHavokModule() ); // Register Behavior classes { hkDefaultClassNameRegistry& dcnReg = hkDefaultClassNameRegistry::getInstance(); hkTypeInfoRegistry& tyReg = hkTypeInfoRegistry::getInstance(); hkVtableClassRegistry& vtcReg = hkVtableClassRegistry::getInstance(); #ifndef VBASE_LIB // DLL, so have a full set dcnReg.registerList(hkBuiltinTypeRegistry::StaticLinkedClasses); tyReg.registerList(hkBuiltinTypeRegistry::StaticLinkedTypeInfos); vtcReg.registerList(hkBuiltinTypeRegistry::StaticLinkedTypeInfos, hkBuiltinTypeRegistry::StaticLinkedClasses); #else // Static lib, just need to add Behavior ones and reg the Behavior patches which would not have been done yet dcnReg.registerList(hkBuiltinBehaviorTypeRegistry::StaticLinkedClasses); tyReg.registerList(hkBuiltinBehaviorTypeRegistry::StaticLinkedTypeInfos); vtcReg.registerList(hkBuiltinBehaviorTypeRegistry::StaticLinkedTypeInfos, hkBuiltinBehaviorTypeRegistry::StaticLinkedClasses); #endif } registerAnimationBehaviorPatches(); hkVersionPatchManager::getInstance().recomputePatchDependencies(); OneTimeInit(); } else if( pData->m_pSender == &vHavokPhysicsModule::OnAfterInitializePhysics ) { vHavokPhysicsModuleCallbackData *pHavokData = (vHavokPhysicsModuleCallbackData*)pData; vHavokPhysicsModule* physicsModule = pHavokData->GetHavokModule(); InitWorld( physicsModule ); } else if( pData->m_pSender == &vHavokPhysicsModule::OnBeforeDeInitializePhysics ) { DeInitWorld(); } else if( pData->m_pSender == &vHavokPhysicsModule::OnAfterDeInitializePhysics ) { // Unload everything, the scene gets deleted! OneTimeDeInit(); } else if( pData->m_pSender == &vHavokPhysicsModule::OnUnsyncHavokStatics ) { vHavokPhysicsModuleCallbackData *pHavokData = (vHavokPhysicsModuleCallbackData*)pData; VISION_HAVOK_UNSYNC_STATICS(); VISION_HAVOK_UNSYNC_PER_THREAD_STATICS( pHavokData->GetHavokModule() ); } else if( pData->m_pSender == &vHavokPhysicsModule::OnBeforeWorldCreated ) { vHavokBeforeWorldCreateDataObject_cl *pEventData = (vHavokBeforeWorldCreateDataObject_cl *)pData; hkJobQueue* jobQueue = pEventData->GetHavokModule()->GetJobQueue(); if( jobQueue != HK_NULL ) { hkbBehaviorJobQueueUtils::registerWithJobQueue( jobQueue ); } } else if( pData->m_pSender == &vHavokVisualDebugger::OnCreatingContexts ) { hkbBehaviorContext::registerAllBehaviorViewers(); vHavokVisualDebuggerCallbackData_cl *pEventData = (vHavokVisualDebuggerCallbackData_cl *)pData; pEventData->m_contexts->pushBack( m_behaviorContext ); } else if( pData->m_pSender == &vHavokVisualDebugger::OnAddingDefaultViewers ) { vHavokVisualDebuggerCallbackData_cl *pEventData = (vHavokVisualDebuggerCallbackData_cl *)pData; if( pEventData->m_pVisualDebugger != HK_NULL ) { hkbBehaviorContext::addDefaultViewers( pEventData->m_pVisualDebugger ); } } #ifdef VLUA_USE_SWIG_BINDING else if( pData->m_pSender == &IVScriptManager::OnRegisterScriptFunctions ) { EnsureHavokBehaviorScriptRegistration(); } else if (pData->m_pSender==&IVScriptManager::OnScriptProxyCreation) { VScriptCreateStackProxyObject * pScriptData = (VScriptCreateStackProxyObject *)pData; // process data only if no other callback did that if(!pScriptData->m_bProcessed) { int iRetParams = 0; // call appropriate LUA cast function if(pScriptData->m_pInstance->IsOfType(V_RUNTIME_CLASS(vHavokBehaviorComponent))) { iRetParams = LUA_CallStaticFunction( pScriptData->m_pLuaState, "Behavior", "vHavokBehaviorComponent", "Cast", "E>E", pScriptData->m_pInstance ); } // could we handle the object? if(iRetParams>0) { // the cast failed if the result is a nil value if(lua_isnil(pScriptData->m_pLuaState, -1)) lua_pop(pScriptData->m_pLuaState, iRetParams); //in case of a nil value we drop the params from the lua stack else pScriptData->m_bProcessed = true; //avoid further processing } } } #endif }
static int ngx_http_lua_shlist_push(lua_State *L) { ngx_http_lua_shlist_node_t *node; ngx_shm_zone_t *zone; ngx_str_t value; ngx_http_lua_shlist_ctx_t *ctx; double num; int n; int value_type; n = lua_gettop(L); if (n != 2) { return luaL_error(L, "expecting 2 arguments, but seen %d", n); } if (lua_type(L, 1) != LUA_TTABLE) { return luaL_error(L, "bad \"temp table zone\" argument"); } zone = ngx_http_lua_shlist_get_zone(L, 1); if (zone == NULL) { return luaL_error(L, "bad \"zone\" argument"); } ctx = zone->data; if (lua_isnil(L, 2)) { // 不允许插入空值 lua_pushnil(L); lua_pushliteral(L, "nil value"); } value_type = lua_type(L, 2); // 第二个参数就是要入栈的 // dd("value_type: %n", &value_type); switch (value_type) { case LUA_TSTRING: value.data = (u_char *) lua_tolstring(L, 2, &value.len); break; case LUA_TNUMBER: value.len = sizeof(double); num = lua_tonumber(L, 2); value.data = (u_char *) # break; case LUA_TNIL: lua_pushnil(L); lua_pushliteral(L, "attempt to add nil to list"); return 2; default: lua_pushnil(L); lua_pushliteral(L, "bad value type"); return 2; } ngx_shmtx_lock(&ctx->shpool->mutex); n = offsetof(ngx_http_lua_shlist_node_t, data) // 计算足够大小的空间 + value.len; node = ngx_slab_alloc_locked(ctx->shpool, n); // 申请 if (node == NULL) { ngx_shmtx_unlock(&ctx->shpool->mutex); lua_pushboolean(L, 0); lua_pushliteral(L, "no memory"); return 2; } node->value_len = (uint32_t) value.len; node->value_type = (uint8_t) value_type; ngx_memcpy(node->data, value.data, value.len); ngx_queue_insert_tail(&ctx->sh->queue, &node->queue); ngx_shmtx_unlock(&ctx->shpool->mutex); lua_pushboolean(L, 1); // push success flag lua_pushnil(L); // no error return 2; }
/// Wrapper around lua_isnil. /// /// \param index The second parameter to lua_isnil. /// /// \return The return value of lua_isnil. bool lutok::state::is_nil(const int index) { return lua_isnil(_pimpl->lua_state, index); }
//box[], particles[], shapes[] static int luaScene_load(lua_State* L){ SimConfig config; for(lua_pushnil(L); lua_next(L, 1); lua_pop(L, 1)){ long long int i = lua_tointeger(L, -2) - 1; if(i < 0 || i >= 9){ fprintf(stderr, "Invalid index for box table encountered while loading scene.\n"); return 0; } config.box[i % 3][i / 3] = lua_tonumber(L, -1); } config.n_particles = lua_rawlen(L, 2); config.particles = new Particle[config.n_particles]; size_t pid = 0; for(lua_pushnil(L); lua_next(L, 2);){ config.particles[pid++] = maan::get_LuaValue<Particle>(L); } config.n_shapes = lua_rawlen(L, 3); config.shapes = new Shape[config.n_shapes]; //TODO: Add a is_class(lua_State* L, int idx) function to maan. size_t sid = 0; for(lua_pushnil(L); lua_next(L, 3);){ if(!lua_isuserdata(L, -1)){ fprintf(stderr, "Unknown item type encountered in shapes table while loading scene. 'Shape' expected, got '%s'.\n", luaL_typename(L, -1)); delete[] config.particles; delete[] config.shapes; return 0; } lua_getmetatable(L, -1); lua_pushstring(L, "__class_id"); lua_rawget(L, -2); if(lua_isnil(L, -1)){ fprintf(stderr, "Unknown userdata type encountered in shapes table while loading scene.\n"); delete[] config.particles; delete[] config.shapes; return 0; } void* class_id = lua_touserdata(L, -1); lua_pop(L, 2); auto shape = Shape(); if(maan::detail::ClassInfo<Sphere>::get_metatable_key() == class_id){ shape.type = Shape::SPHERE; lua_pop(L, 1); } else if(maan::detail::ClassInfo<Mesh>::get_metatable_key() == class_id){ shape.type = Shape::MESH; auto mesh = maan::get_LuaValue<Mesh>(L); shape.mesh.n_vertices = mesh.vertices_.size(); shape.mesh.vertices = new Vertex[shape.mesh.n_vertices]; int i = 0; for(auto vertex: mesh.vertices_){ shape.mesh.vertices[i++] = vertex; } } else{ lua_getmetatable(L, -1); lua_pushstring(L, "__name"); lua_rawget(L, -2); fprintf(stderr, "Unknown class type encountered in shapes table while loading scene. 'Shape' expected, got '%s'.\n", lua_tostring(L, -1)); lua_pop(L, 2); delete[] config.particles; delete[] config.shapes; return 0; } config.shapes[sid++] = shape; } auto scene = reinterpret_cast<Scene*>(lua_touserdata(L, lua_upvalueindex(1))); scene->load_scene(config); delete[] config.particles; delete[] config.shapes; return 0; }
int NativeDelegate::__op_minusassignment(lua_State *L) { NativeDelegate *delegate = (NativeDelegate *)lualoom_getnativepointer(L, 1, "system.NativeDelegate"); if (!delegate) { LSError("Unable to get native delegate on += operator"); } if (!delegate->_callbackCount) { return 0; } delegate->setVM(L); delegate->getCallbacks(L); int tidx = lua_gettop(L); if (!lua_istable(L, tidx)) { LSError("Bad native delegates table"); } if (lua_isfunction(L, 2) || lua_iscfunction(L, 2)) { int idx = -1; for (int i = 0; i < delegate->_callbackCount; i++) { lua_rawgeti(L, tidx, i); if (lua_equal(L, 2, -1)) { idx = i; lua_pop(L, 1); break; } lua_pop(L, 1); } // this function was never added in the first place if (idx == -1) { return 0; } // shift the other delegates down lua_pushnumber(L, (double)idx); lua_pushnil(L); lua_settable(L, tidx); int ntable = 0; if (delegate->_callbackCount > 1) { // temp table lua_newtable(L); ntable = lua_gettop(L); int c = 0; for (int nidx = 0; nidx < delegate->_callbackCount; nidx++) { lua_pushnumber(L, (double)nidx); lua_gettable(L, tidx); if (lua_isnil(L, -1)) { lua_pop(L, 1); continue; } lua_pushnumber(L, (double)c); lua_pushvalue(L, -2); lua_settable(L, ntable); // pop lua_function lua_pop(L, 1); c++; } } // clear it delegate->_callbackCount--; // and copy from new temp table for (int nidx = 0; nidx < delegate->_callbackCount; nidx++) { lua_pushnumber(L, (double)nidx); lua_pushnumber(L, (double)nidx); lua_gettable(L, ntable); lua_settable(L, tidx); } } else { LSError("Unknown type on NativeDelegate -= operator"); } return 0; }
/* Top-level delegating persist function */ static void persist(PersistInfo *pi) { /* Grab the object's type. */ int type = lua_type(pi->L, -1); int simple = type == LUA_TNIL || type == LUA_TBOOLEAN || type == LUA_TNUMBER || type == LUA_TLIGHTUSERDATA; /* Increment the number of objects persisted. */ ++(pi->counter); /* If the type isn't simple, check to see if one is already in the reftable. */ if(!simple) { /* perms reftbl ... obj */ lua_checkstack(pi->L, 2); /* If the object has already been written, write a reference to it */ lua_pushvalue(pi->L, -1); /* perms reftbl ... obj obj */ lua_rawget(pi->L, 2); /* perms reftbl ... obj ref? */ if(!lua_isnil(pi->L, -1)) { /* perms reftbl ... obj ref */ int zero = 0; int ref = (intptr_t)lua_touserdata(pi->L, -1); pi->writer(pi->L, &zero, sizeof(int), pi->ud); pi->writer(pi->L, &ref, sizeof(int), pi->ud); lua_pop(pi->L, 1); /* perms reftbl ... obj ref */ #ifdef PLUTO_DEBUG printindent(pi->level); printf("0 %d\n", ref); #endif return; } /* perms reftbl ... obj nil */ lua_pop(pi->L, 1); } /* perms reftbl ... obj */ /* If the object is nil, write the pseudoreference 0 */ if(lua_isnil(pi->L, -1)) { int zero = 0; /* firsttime */ pi->writer(pi->L, &zero, sizeof(int), pi->ud); /* ref */ pi->writer(pi->L, &zero, sizeof(int), pi->ud); #ifdef PLUTO_DEBUG printindent(pi->level); printf("0 0\n"); #endif return; } { /* indicate that it's the first time */ int one = 1; pi->writer(pi->L, &one, sizeof(int), pi->ud); } /* put the value in the reftable if necessary. Simple types don't need to be put in the reftable. */ if(!simple) { lua_pushvalue(pi->L, -1); /* perms reftbl ... obj obj */ lua_pushlightuserdata(pi->L, (void*)((intptr_t) pi->counter)); /* perms reftbl ... obj obj ref */ lua_rawset(pi->L, 2); /* perms reftbl ... obj */ } pi->writer(pi->L, &pi->counter, sizeof(int), pi->ud); /* At this point, we'll give the permanents table a chance to play. */ { lua_pushvalue(pi->L, -1); /* perms reftbl ... obj obj */ lua_gettable(pi->L, 1); /* perms reftbl ... obj permkey? */ if(!lua_isnil(pi->L, -1)) { /* perms reftbl ... obj permkey */ int type = PLUTO_TPERMANENT; #ifdef PLUTO_DEBUG printindent(pi->level); printf("1 %d PERM\n", pi->counter); pi->level++; #endif pi->writer(pi->L, &type, sizeof(int), pi->ud); persist(pi); lua_pop(pi->L, 1); /* perms reftbl ... obj */ #ifdef PLUTO_DEBUG pi->level--; #endif return; } else { /* perms reftbl ... obj nil */ lua_pop(pi->L, 1); /* perms reftbl ... obj */ } /* perms reftbl ... obj */ } { int type = lua_type(pi->L, -1); pi->writer(pi->L, &type, sizeof(int), pi->ud); #ifdef PLUTO_DEBUG printindent(pi->level); printf("1 %d %d\n", pi->counter, type); pi->level++; #endif } switch(lua_type(pi->L, -1)) { case LUA_TBOOLEAN: persistboolean(pi); break; case LUA_TLIGHTUSERDATA: persistlightuserdata(pi); break; case LUA_TNUMBER: persistnumber(pi); break; case LUA_TSTRING: persiststring(pi); break; case LUA_TTABLE: persisttable(pi); break; case LUA_TFUNCTION: persistfunction(pi); break; case LUA_TTHREAD: persistthread(pi); break; case LUA_TPROTO: persistproto(pi); break; case LUA_TUPVAL: persistupval(pi); break; case LUA_TUSERDATA: persistuserdata(pi); break; default: lua_assert(0); } #ifdef PLUTO_DEBUG pi->level--; #endif }