lua_State *lua_engine::hook::precall() { lua_State *T = lua_newthread(L); lua_rawgeti(T, LUA_REGISTRYINDEX, cb); return T; }
/* ** Read the options specified in the ini file. ** */ void MeasureScript::ReadOptions(ConfigParser& parser, const WCHAR* section) { Measure::ReadOptions(parser, section); std::wstring scriptFile = parser.ReadString(section, L"ScriptFile", L""); if (!scriptFile.empty()) { if (m_Skin) { m_Skin->MakePathAbsolute(scriptFile); } if (!m_Initialized || wcscmp(scriptFile.c_str(), m_LuaScript.GetFile().c_str()) != 0) { UninitializeLuaScript(); if (m_LuaScript.Initialize(scriptFile)) { bool hasInitializeFunction = m_LuaScript.IsFunction(g_InitializeFunctionName); m_HasUpdateFunction = m_LuaScript.IsFunction(g_UpdateFunctionName); auto L = m_LuaScript.GetState(); lua_rawgeti(L, LUA_GLOBALSINDEX, m_LuaScript.GetRef()); *(Skin**)lua_newuserdata(L, sizeof(Skin*)) = m_Skin; lua_getglobal(L, "MeterWindow"); lua_setmetatable(L, -2); lua_setfield(L, -2, "SKIN"); *(Measure**)lua_newuserdata(L, sizeof(Measure*)) = this; lua_getglobal(L, "Measure"); lua_setmetatable(L, -2); lua_setfield(L, -2, "SELF"); if (!m_LuaScript.IsUnicode()) { // For backwards compatibility. m_HasGetStringFunction = m_LuaScript.IsFunction(g_GetStringFunctionName); if (m_HasGetStringFunction) { LogWarningF(this, L"Script: Using deprecated GetStringValue()"); } 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); const std::wstring wstrKey = StringUtil::Widen(strKey); const std::wstring& wstrValue = parser.ReadString(section, wstrKey.c_str(), L""); if (!wstrValue.empty()) { const std::string strStrVal = StringUtil::Narrow(wstrValue); lua_pushstring(L, strStrVal.c_str()); lua_setfield(L, -3, strKey); } } } // Pop PROPERTIES table. lua_pop(L, 1); } // Pop our table. lua_pop(L, 1); if (m_Initialized) { // If the measure is already initialized and the script has changed, we need to // manually call Initialize(). Initialize(); } // Valid script. return; } } else if (m_LuaScript.IsInitialized()) { // Already initialized. return; } } LogErrorF(this, L"Script: File not valid"); UninitializeLuaScript(); }
// Removes item from registry and pushes on the top of stack. void luah_remove_from_registry(lua_State* L, int item_index) { lua_rawgeti(L, LUA_REGISTRYINDEX, item_index); luaL_unref(L, LUA_REGISTRYINDEX, item_index); }
static void _get_array_value(lua_State *L, pbc_array array, char type) { switch(type) { case 'I': { int32_t v = luaL_checkinteger(L, -1); uint32_t hi = 0; if (v<0) { hi = ~0; } pbc_array_push_integer(array, v, hi); break; } case 'U' : { uint64_t v = (uint64_t)luaL_checknumber(L, -1); pbc_array_push_integer(array, (uint32_t)v, (uint32_t)(v >> 32)); break; } case 'D' : { int64_t v = (int64_t)luaL_checknumber(L, -1); pbc_array_push_integer(array, (uint32_t)v, (uint32_t)(v >> 32)); break; } case 'B': { int32_t v = lua_toboolean(L, -1); pbc_array_push_integer(array, v ? 1: 0, 0); break; } case 'P': { void *p = lua_touserdata(L, -1); uint32_t v = (uint32_t)(intptr_t)p; pbc_array_push_integer(array, v, 0); break; } case 'X': { const char * i64 = luaL_checkstring(L, -1); uint64_t v = *(uint64_t *)i64; pbc_array_push_integer(array, (uint32_t)v, (uint32_t)(v >> 32)); break; } case 'R': { double v = luaL_checknumber(L, -1); pbc_array_push_real(array, v); break; } case 'S': { size_t sz = 0; const char * str = luaL_checklstring(L, -1, &sz); struct pbc_slice slice; slice.buffer = (void*)str; slice.len = sz; pbc_array_push_slice(array, &slice); break; } case 'M': { struct pbc_slice slice; if (lua_istable(L,-1)) { lua_rawgeti(L,-1,1); slice.buffer = lua_touserdata(L,-1); lua_rawgeti(L,-2,2); slice.len = lua_tointeger(L,-1); lua_pop(L,2); } else { size_t sz = 0; const char * buffer = luaL_checklstring(L, -1, &sz); slice.buffer = (void *)buffer; slice.len = sz; } pbc_array_push_slice(array, &slice); break; } } }
/** {{{ proto LuaClosure::invoke(mxied $args) */ PHP_METHOD(lua_closure, invoke) { lua_closure_object *objval = php_lua_closure_object_from_zend_object(Z_OBJ_P(getThis())); int bp, sp; zval *arguments = NULL; lua_State *L = NULL; zval rv; if (ZEND_NUM_ARGS()) { arguments = emalloc(sizeof(zval*) * ZEND_NUM_ARGS()); if (zend_get_parameters_array_ex(ZEND_NUM_ARGS(), arguments) == FAILURE) { efree(arguments); zend_throw_exception_ex(NULL, 0, "cannot get arguments for calling closure"); return; } } if (Z_TYPE(objval->lua) != IS_OBJECT || !instanceof_function(Z_OBJCE(objval->lua), lua_ce)) { zend_throw_exception_ex(NULL, 0, "corrupted Lua object"); return; } L = (Z_LUAVAL(objval->lua))->L; bp = lua_gettop(L); lua_rawgeti(L, LUA_REGISTRYINDEX, objval->closure); if (LUA_TFUNCTION != lua_type(L, lua_gettop(L))) { lua_pop(L, -1); zend_throw_exception_ex(NULL, 0, "call to lua closure failed"); return; } if (ZEND_NUM_ARGS()) { int i = 0; for(;i<ZEND_NUM_ARGS();i++) { php_lua_send_zval_to_lua(L, &arguments[i]); } } if (lua_pcall(L, ZEND_NUM_ARGS(), LUA_MULTRET, 0) != 0) { if (arguments) { efree(arguments); } lua_pop(L, lua_gettop(L) - bp); zend_throw_exception_ex(NULL, 0, "call to lua function %s failed", lua_tostring(L, -1)); return; } sp = lua_gettop(L) - bp; if (!sp) { RETURN_NULL(); } else if (sp == 1) { php_lua_get_zval_from_lua(L, -1, &(objval->lua), return_value); } else { zval rv; int i = 0; array_init(return_value); for (i = -sp; i < 0; i++) { php_lua_get_zval_from_lua(L, i, &(objval->lua), &rv); add_next_index_zval(return_value, &rv); } } lua_pop(L, sp); if (arguments) { efree(arguments); } }
int JPLua_Push_Pairs( lua_State *L ) { lua_rawgeti( L, LUA_REGISTRYINDEX, JPLua_Framework[JPLUA_FRAMEWORK_PAIRS] ); return 1; }
/* ** Returns the table with column types. */ static int cur_coltypes (lua_State *L) { cur_data *cur = (cur_data *) getcursor (L); lua_rawgeti (L, LUA_REGISTRYINDEX, cur->coltypes); return 1; }
static int ngx_http_lua_ngx_header_set(lua_State *L) { ngx_http_request_t *r; u_char *p; ngx_str_t key; ngx_str_t value; ngx_uint_t i; size_t len; ngx_http_lua_ctx_t *ctx; ngx_int_t rc; ngx_uint_t n; lua_getglobal(L, GLOBALS_SYMBOL_REQUEST); r = lua_touserdata(L, -1); lua_pop(L, 1); if (r == NULL) { return luaL_error(L, "no request object found"); } ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); if (ctx->headers_sent) { return luaL_error(L, "attempt to set ngx.header.HEADER after " "sending out response headers"); } /* we skip the first argument that is the table */ p = (u_char *) luaL_checklstring(L, 2, &len); dd("key: %.*s, len %d", (int) len, p, (int) len); /* replace "_" with "-" */ for (i = 0; i < len; i++) { if (p[i] == '_') { p[i] = '-'; } } key.data = ngx_palloc(r->pool, len + 1); if (key.data == NULL) { return luaL_error(L, "out of memory"); } ngx_memcpy(key.data, p, len); key.data[len] = '\0'; key.len = len; if (! ctx->headers_set) { rc = ngx_http_set_content_type(r); if (rc != NGX_OK) { return luaL_error(L, "failed to set default content type: %d", (int) rc); } ctx->headers_set = 1; } if (lua_type(L, 3) == LUA_TNIL) { value.data = NULL; value.len = 0; } else if (lua_type(L, 3) == LUA_TTABLE) { n = luaL_getn(L, 3); if (n == 0) { value.data = NULL; value.len = 0; } else { for (i = 1; i <= n; i++) { dd("header value table index %d", (int) i); lua_rawgeti(L, 3, i); p = (u_char *) luaL_checklstring(L, -1, &len); value.data = ngx_palloc(r->pool, len); if (value.data == NULL) { return luaL_error(L, "out of memory"); } ngx_memcpy(value.data, p, len); value.len = len; rc = ngx_http_lua_set_output_header(r, key, value, i == 1 /* override */); if (rc != NGX_OK) { return luaL_error(L, "failed to set header %s (error: %d)", key.data, (int) rc); } } return 0; } } else { p = (u_char *) luaL_checklstring(L, 3, &len); value.data = ngx_palloc(r->pool, len); if (value.data == NULL) { return luaL_error(L, "out of memory"); } ngx_memcpy(value.data, p, len); value.len = len; } dd("key: %.*s, value: %.*s", (int) key.len, key.data, (int) value.len, value.data); rc = ngx_http_lua_set_output_header(r, key, value, 1 /* override */); if (rc != NGX_OK) { return luaL_error(L, "failed to set header %s (error: %d)", key.data, (int) rc); } return 0; }
static int ngx_http_lua_ngx_req_header_set_helper(lua_State *L) { ngx_http_request_t *r; u_char *p; ngx_str_t key; ngx_str_t value; ngx_uint_t i; size_t len; ngx_int_t rc; ngx_uint_t n; lua_getglobal(L, GLOBALS_SYMBOL_REQUEST); r = lua_touserdata(L, -1); lua_pop(L, 1); if (r == NULL) { return luaL_error(L, "no request object found"); } p = (u_char *) luaL_checklstring(L, 1, &len); dd("key: %.*s, len %d", (int) len, p, (int) len); /* replace "_" with "-" */ for (i = 0; i < len; i++) { if (p[i] == '_') { p[i] = '-'; } } key.data = ngx_palloc(r->pool, len + 1); if (key.data == NULL) { return luaL_error(L, "out of memory"); } ngx_memcpy(key.data, p, len); key.data[len] = '\0'; key.len = len; if (lua_type(L, 2) == LUA_TNIL) { value.data = NULL; value.len = 0; } else if (lua_type(L, 2) == LUA_TTABLE) { n = luaL_getn(L, 2); if (n == 0) { value.data = NULL; value.len = 0; } else { for (i = 1; i <= n; i++) { dd("header value table index %d", (int) i); lua_rawgeti(L, 2, i); p = (u_char *) luaL_checklstring(L, -1, &len); /* * we also copy the trailling '\0' char here because nginx * header values must be null-terminated * */ value.data = ngx_palloc(r->pool, len + 1); if (value.data == NULL) { return luaL_error(L, "out of memory"); } ngx_memcpy(value.data, p, len + 1); value.len = len; rc = ngx_http_lua_set_input_header(r, key, value, i == 1 /* override */); if (rc != NGX_OK) { return luaL_error(L, "failed to set header %s (error: %d)", key.data, (int) rc); } } return 0; } } else { /* * we also copy the trailling '\0' char here because nginx * header values must be null-terminated * */ p = (u_char *) luaL_checklstring(L, 2, &len); value.data = ngx_palloc(r->pool, len + 1); if (value.data == NULL) { return luaL_error(L, "out of memory"); } ngx_memcpy(value.data, p, len + 1); value.len = len; } dd("key: %.*s, value: %.*s", (int) key.len, key.data, (int) value.len, value.data); rc = ngx_http_lua_set_input_header(r, key, value, 1 /* override */); if (rc != NGX_OK) { return luaL_error(L, "failed to set header %s (error: %d)", key.data, (int) rc); } return 0; }
void ThreadScheduler::Tick(){ if(!waitingFuncTasks.empty()){ while(!waitingFuncTasks.empty()){ try{ WaitingFuncTask task = waitingFuncTasks.at(waitingFuncTasks.size() - 1); if(task.at < currentTimeMillis()){ task.func(task.args); va_end(task.args); waitingFuncTasks.pop_back(); }else{ break; } }catch(const std::out_of_range& e){} } } if(!tasks.empty()){ long curTime = currentTimeMillis(); try{ Task task = tasks.at(tasks.size() - 1); if(task.at < curTime){ lua_State* L = task.origin; if(L == NULL){ return; } if(lua_status(L) != LUA_YIELD){ tasks.pop_back(); return; } if(task.ref != -1){ lua_resume(L, 0); lua_rawgeti(L, LUA_REGISTRYINDEX, task.ref); long appStartTime = OpenBlox::BaseGame::appStarted(); long elapsedTime = (curTime - task.start) / 1000; lua_pushnumber(L, elapsedTime); lua_pushnumber(L, (curTime - appStartTime) / 1000.0); int stat = lua_pcall(L, 2, LUA_MULTRET, 0); if(stat != 0 && stat != LUA_YIELD){ OpenBlox::BaseGame::getInstance()->handle_lua_errors(L); } luaL_unref(L, LUA_REGISTRYINDEX, task.ref); tasks.pop_back(); return; } long appStartTime = OpenBlox::BaseGame::appStarted(); long elapsedTime = (curTime - task.start) / 1000; lua_pushnumber(L, elapsedTime); lua_pushnumber(L, (curTime - appStartTime) / 1000.0); tasks.pop_back(); int stat = lua_resume(L, 2); if(stat != 0 && stat != LUA_YIELD){ OpenBlox::BaseGame::getInstance()->handle_lua_errors(L); } } }catch(const std::out_of_range& e){} } if(!waitingTasks.empty()){ while(!waitingTasks.empty()){ try{ WaitingTask task = waitingTasks.at(waitingTasks.size() - 1); lua_State* L = task.state; if(L != NULL){ if(lua_status(L) == LUA_YIELD){ int stat = 0; if(task.isCall){ stat = lua_pcall(L, task.resumeArgs, LUA_MULTRET, 0); }else{ stat = lua_resume(L, task.resumeArgs); } if(stat != 0 && stat != LUA_YIELD){ OpenBlox::BaseGame::getInstance()->handle_lua_errors(L); } } } waitingTasks.pop_back(); }catch(const std::out_of_range& e){} } } if(!waitingEvents.empty()){ while(!waitingEvents.empty()){ try{ WaitingEvent evt = waitingEvents.at(waitingEvents.size() - 1); lua_State* oL = evt.state; if(oL != NULL){ lua_State* L = lua_newthread(oL); //LOGW("[ThreadScheduler::Tick() tasks - Func Type] %s", lua_typename(L, lua_type(L, -1))); //lua_resume(L, 0); lua_rawgeti(L, LUA_REGISTRYINDEX, evt.ref); ob_type::LuaEvent::pushWrappersToLua(L, evt.argList); int stat = lua_pcall(L, evt.numArgs, LUA_MULTRET, 0); if(stat != 0 && stat != LUA_YIELD){ OpenBlox::BaseGame::getInstance()->handle_lua_errors(L); } }waitingEvents.pop_back(); }catch(const std::out_of_range& e){} } } }
void CPlayer::Load(lua_State *l) { const int args = lua_gettop(l); this->Units.resize(0); this->FreeWorkers.resize(0); // j = 0 represent player Index. for (int j = 1; j < args; ++j) { const char *value = LuaToString(l, j + 1); ++j; if (!strcmp(value, "name")) { this->SetName(LuaToString(l, j + 1)); } else if (!strcmp(value, "type")) { value = LuaToString(l, j + 1); if (!strcmp(value, "neutral")) { this->Type = PlayerNeutral; } else if (!strcmp(value, "nobody")) { this->Type = PlayerNobody; } else if (!strcmp(value, "computer")) { this->Type = PlayerComputer; } else if (!strcmp(value, "person")) { this->Type = PlayerPerson; } else if (!strcmp(value, "rescue-passive")) { this->Type = PlayerRescuePassive; } else if (!strcmp(value, "rescue-active")) { this->Type = PlayerRescueActive; } else { LuaError(l, "Unsupported tag: %s" _C_ value); } } else if (!strcmp(value, "race")) { const char *raceName = LuaToString(l, j + 1); this->Race = PlayerRaces.GetRaceIndexByName(raceName); if (this->Race == -1) { LuaError(l, "Unsupported race: %s" _C_ raceName); } } else if (!strcmp(value, "ai-name")) { this->AiName = LuaToString(l, j + 1); } else if (!strcmp(value, "team")) { this->Team = LuaToNumber(l, j + 1); } else if (!strcmp(value, "enemy")) { value = LuaToString(l, j + 1); for (int i = 0; i < PlayerMax && *value; ++i, ++value) { if (*value == '-' || *value == '_' || *value == ' ') { this->Enemy &= ~(1 << i); } else { this->Enemy |= (1 << i); } } } else if (!strcmp(value, "allied")) { value = LuaToString(l, j + 1); for (int i = 0; i < PlayerMax && *value; ++i, ++value) { if (*value == '-' || *value == '_' || *value == ' ') { this->Allied &= ~(1 << i); } else { this->Allied |= (1 << i); } } } else if (!strcmp(value, "shared-vision")) { value = LuaToString(l, j + 1); for (int i = 0; i < PlayerMax && *value; ++i, ++value) { if (*value == '-' || *value == '_' || *value == ' ') { this->SharedVision &= ~(1 << i); } else { this->SharedVision |= (1 << i); } } } else if (!strcmp(value, "start")) { if (!lua_istable(l, j + 1) || lua_rawlen(l, j + 1) != 2) { LuaError(l, "incorrect argument"); } lua_rawgeti(l, j + 1, 1); this->StartPos.x = LuaToNumber(l, -1); lua_pop(l, 1); lua_rawgeti(l, j + 1, 2); this->StartPos.y = LuaToNumber(l, -1); lua_pop(l, 1); } else if (!strcmp(value, "resources")) { if (!lua_istable(l, j + 1)) { LuaError(l, "incorrect argument"); } const int subargs = lua_rawlen(l, j + 1); for (int k = 0; k < subargs; ++k) { lua_rawgeti(l, j + 1, k + 1); value = LuaToString(l, -1); lua_pop(l, 1); ++k; const int resId = GetResourceIdByName(l, value); lua_rawgeti(l, j + 1, k + 1); this->Resources[resId] = LuaToNumber(l, -1); lua_pop(l, 1); } } else if (!strcmp(value, "stored-resources")) { if (!lua_istable(l, j + 1)) { LuaError(l, "incorrect argument"); } const int subargs = lua_rawlen(l, j + 1); for (int k = 0; k < subargs; ++k) { lua_rawgeti(l, j + 1, k + 1); value = LuaToString(l, -1); lua_pop(l, 1); ++k; const int resId = GetResourceIdByName(l, value); lua_rawgeti(l, j + 1, k + 1); this->StoredResources[resId] = LuaToNumber(l, -1); lua_pop(l, 1); } } else if (!strcmp(value, "max-resources")) { if (!lua_istable(l, j + 1)) { LuaError(l, "incorrect argument"); } const int subargs = lua_rawlen(l, j + 1); for (int k = 0; k < subargs; ++k) { lua_rawgeti(l, j + 1, k + 1); value = LuaToString(l, -1); lua_pop(l, 1); ++k; const int resId = GetResourceIdByName(l, value); lua_rawgeti(l, j + 1, k + 1); this->MaxResources[resId] = LuaToNumber(l, -1); lua_pop(l, 1); } } else if (!strcmp(value, "last-resources")) { if (!lua_istable(l, j + 1)) { LuaError(l, "incorrect argument"); } const int subargs = lua_rawlen(l, j + 1); for (int k = 0; k < subargs; ++k) { lua_rawgeti(l, j + 1, k + 1); value = LuaToString(l, -1); lua_pop(l, 1); ++k; const int resId = GetResourceIdByName(l, value); lua_rawgeti(l, j + 1, k + 1); this->LastResources[resId] = LuaToNumber(l, -1); lua_pop(l, 1); } } else if (!strcmp(value, "incomes")) { if (!lua_istable(l, j + 1)) { LuaError(l, "incorrect argument"); } const int subargs = lua_rawlen(l, j + 1); for (int k = 0; k < subargs; ++k) { lua_rawgeti(l, j + 1, k + 1); value = LuaToString(l, -1); lua_pop(l, 1); ++k; const int resId = GetResourceIdByName(l, value); lua_rawgeti(l, j + 1, k + 1); this->Incomes[resId] = LuaToNumber(l, -1); lua_pop(l, 1); } } else if (!strcmp(value, "revenue")) { if (!lua_istable(l, j + 1)) { LuaError(l, "incorrect argument"); } const int subargs = lua_rawlen(l, j + 1); for (int k = 0; k < subargs; ++k) { lua_rawgeti(l, j + 1, k + 1); value = LuaToString(l, -1); lua_pop(l, 1); ++k; const int resId = GetResourceIdByName(l, value); lua_rawgeti(l, j + 1, k + 1); this->Revenue[resId] = LuaToNumber(l, -1); lua_pop(l, 1); } } else if (!strcmp(value, "ai-enabled")) { this->AiEnabled = true; --j; } else if (!strcmp(value, "ai-disabled")) { this->AiEnabled = false; --j; } else if (!strcmp(value, "supply")) { this->Supply = LuaToNumber(l, j + 1); } else if (!strcmp(value, "demand")) { this->Demand = LuaToNumber(l, j + 1); } else if (!strcmp(value, "unit-limit")) { this->UnitLimit = LuaToNumber(l, j + 1); } else if (!strcmp(value, "building-limit")) { this->BuildingLimit = LuaToNumber(l, j + 1); } else if (!strcmp(value, "total-unit-limit")) { this->TotalUnitLimit = LuaToNumber(l, j + 1); } else if (!strcmp(value, "score")) { this->Score = LuaToNumber(l, j + 1); } else if (!strcmp(value, "total-units")) { this->TotalUnits = LuaToNumber(l, j + 1); } else if (!strcmp(value, "total-buildings")) { this->TotalBuildings = LuaToNumber(l, j + 1); } else if (!strcmp(value, "total-razings")) { this->TotalRazings = LuaToNumber(l, j + 1); } else if (!strcmp(value, "total-kills")) { this->TotalKills = LuaToNumber(l, j + 1); } else if (!strcmp(value, "total-resources")) { if (!lua_istable(l, j + 1)) { LuaError(l, "incorrect argument"); } const int subargs = lua_rawlen(l, j + 1); if (subargs != MaxCosts) { LuaError(l, "Wrong number of total-resources: %d" _C_ subargs); } for (int k = 0; k < subargs; ++k) { lua_rawgeti(l, j + 1, k + 1); this->TotalResources[k] = LuaToNumber(l, -1); lua_pop(l, 1); } } else if (!strcmp(value, "speed-resource-harvest")) { if (!lua_istable(l, j + 1)) { LuaError(l, "incorrect argument"); } const int subargs = lua_rawlen(l, j + 1); if (subargs != MaxCosts) { LuaError(l, "Wrong number of speed-resource-harvest: %d" _C_ subargs); } for (int k = 0; k < subargs; ++k) { lua_rawgeti(l, j + 1, k + 1); this->SpeedResourcesHarvest[k] = LuaToNumber(l, -1); lua_pop(l, 1); } } else if (!strcmp(value, "speed-resource-return")) { if (!lua_istable(l, j + 1)) { LuaError(l, "incorrect argument"); } const int subargs = lua_rawlen(l, j + 1); if (subargs != MaxCosts) { LuaError(l, "Wrong number of speed-resource-harvest: %d" _C_ subargs); } for (int k = 0; k < subargs; ++k) { lua_rawgeti(l, j + 1, k + 1); this->SpeedResourcesReturn[k] = LuaToNumber(l, -1); lua_pop(l, 1); } } else if (!strcmp(value, "speed-build")) { this->SpeedBuild = LuaToNumber(l, j + 1); } else if (!strcmp(value, "speed-train")) { this->SpeedTrain = LuaToNumber(l, j + 1); } else if (!strcmp(value, "speed-upgrade")) { this->SpeedUpgrade = LuaToNumber(l, j + 1); } else if (!strcmp(value, "speed-research")) { this->SpeedResearch = LuaToNumber(l, j + 1); } else if (!strcmp(value, "color")) { if (!lua_istable(l, j + 1) || lua_rawlen(l, j + 1) != 3) { LuaError(l, "incorrect argument"); } lua_rawgeti(l, j + 1, 1); const int r = LuaToNumber(l, -1); lua_pop(l, 1); lua_rawgeti(l, j + 1, 2); const int g = LuaToNumber(l, -1); lua_pop(l, 1); lua_rawgeti(l, j + 1, 3); const int b = LuaToNumber(l, -1); lua_pop(l, 1); this->Color = Video.MapRGB(TheScreen->format, r, g, b); } else if (!strcmp(value, "timers")) { if (!lua_istable(l, j + 1)) { LuaError(l, "incorrect argument"); } const int subargs = lua_rawlen(l, j + 1); if (subargs != UpgradeMax) { LuaError(l, "Wrong upgrade timer length: %d" _C_ subargs); } for (int k = 0; k < subargs; ++k) { lua_rawgeti(l, j + 1, k + 1); this->UpgradeTimers.Upgrades[k] = LuaToNumber(l, -1); lua_pop(l, 1); } } else { LuaError(l, "Unsupported tag: %s" _C_ value); } } // Manage max for (int i = 0; i < MaxCosts; ++i) { if (this->MaxResources[i] != -1) { this->SetResource(i, this->Resources[i] + this->StoredResources[i], STORE_BOTH); } } }
// register_decoration({lots of stuff}) int ModApiMapgen::l_register_decoration(lua_State *L) { int index = 1; luaL_checktype(L, index, LUA_TTABLE); EmergeManager *emerge = getServer(L)->getEmergeManager(); BiomeDefManager *bdef = emerge->biomedef; enum DecorationType decotype = (DecorationType)getenumfield(L, index, "deco_type", es_DecorationType, 0); if (decotype == 0) { errorstream << "register_decoration: unrecognized " "decoration placement type"; return 0; } Decoration *deco = createDecoration(decotype); if (!deco) { errorstream << "register_decoration: decoration placement type " << decotype << " not implemented"; return 0; } deco->c_place_on = CONTENT_IGNORE; deco->place_on_name = getstringfield_default(L, index, "place_on", "ignore"); deco->fill_ratio = getfloatfield_default(L, index, "fill_ratio", 0.02); deco->sidelen = getintfield_default(L, index, "sidelen", 8); if (deco->sidelen <= 0) { errorstream << "register_decoration: sidelen must be " "greater than 0" << std::endl; delete deco; return 0; } lua_getfield(L, index, "noise_params"); deco->np = read_noiseparams(L, -1); lua_pop(L, 1); lua_getfield(L, index, "biomes"); if (lua_istable(L, -1)) { lua_pushnil(L); while (lua_next(L, -2)) { const char *s = lua_tostring(L, -1); u8 biomeid = bdef->getBiomeIdByName(s); if (biomeid) deco->biomes.insert(biomeid); lua_pop(L, 1); } lua_pop(L, 1); } switch (decotype) { case DECO_SIMPLE: { DecoSimple *dsimple = (DecoSimple *)deco; dsimple->c_deco = CONTENT_IGNORE; dsimple->c_spawnby = CONTENT_IGNORE; dsimple->spawnby_name = getstringfield_default(L, index, "spawn_by", "air"); dsimple->deco_height = getintfield_default(L, index, "height", 1); dsimple->deco_height_max = getintfield_default(L, index, "height_max", 0); dsimple->nspawnby = getintfield_default(L, index, "num_spawn_by", -1); lua_getfield(L, index, "decoration"); if (lua_istable(L, -1)) { lua_pushnil(L); while (lua_next(L, -2)) { const char *s = lua_tostring(L, -1); std::string str(s); dsimple->decolist_names.push_back(str); lua_pop(L, 1); } } else if (lua_isstring(L, -1)) { dsimple->deco_name = std::string(lua_tostring(L, -1)); } else { dsimple->deco_name = std::string("air"); } lua_pop(L, 1); if (dsimple->deco_height <= 0) { errorstream << "register_decoration: simple decoration height" " must be greater than 0" << std::endl; delete dsimple; return 0; } break; } case DECO_SCHEMATIC: { DecoSchematic *dschem = (DecoSchematic *)deco; dschem->flags = 0; getflagsfield(L, index, "flags", flagdesc_deco_schematic, &dschem->flags, NULL); dschem->rotation = (Rotation)getenumfield(L, index, "rotation", es_Rotation, ROTATE_0); lua_getfield(L, index, "replacements"); if (lua_istable(L, -1)) { int i = lua_gettop(L); lua_pushnil(L); while (lua_next(L, i) != 0) { // key at index -2 and value at index -1 lua_rawgeti(L, -1, 1); std::string replace_from = lua_tostring(L, -1); lua_pop(L, 1); lua_rawgeti(L, -1, 2); std::string replace_to = lua_tostring(L, -1); lua_pop(L, 1); dschem->replacements[replace_from] = replace_to; // removes value, keeps key for next iteration lua_pop(L, 1); } } lua_pop(L, 1); lua_getfield(L, index, "schematic"); if (!read_schematic(L, -1, dschem, getServer(L))) { delete dschem; return 0; } lua_pop(L, -1); if (!dschem->filename.empty() && !dschem->loadSchematicFile()) { errorstream << "register_decoration: failed to load schematic file '" << dschem->filename << "'" << std::endl; delete dschem; return 0; } break; } case DECO_LSYSTEM: { //DecoLSystem *decolsystem = (DecoLSystem *)deco; break; } } emerge->decorations.push_back(deco); verbosestream << "register_decoration: decoration '" << deco->getName() << "' registered" << std::endl; return 0; }
// get_current_modname() int ModApiServer::l_get_current_modname(lua_State *L) { NO_MAP_LOCK_REQUIRED; lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_CURRENT_MOD_NAME); return 1; }
static int io_close (lua_State *L) { if (lua_isnone(L, 1)) lua_rawgeti(L, LUA_ENVIRONINDEX, IO_OUTPUT); tofile(L); /* make sure argument is a file */ return aux_close(L); }
/* * Initialize keeper states * * If there is a problem, return an error message (NULL for okay). * * Note: Any problems would be design flaws; the created Lua state is left * unclosed, because it does not really matter. In production code, this * function never fails. */ char const* init_keepers( lua_State* L, int _on_state_create, int const _nbKeepers) { int i; assert( _nbKeepers >= 1); GNbKeepers = _nbKeepers; GKeepers = malloc( _nbKeepers * sizeof( struct s_Keeper)); for( i = 0; i < _nbKeepers; ++ i) { lua_State* K; DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "### init_keepers %d BEGIN\n" INDENT_END, i)); DEBUGSPEW_CODE( ++ debugspew_indent_depth); // We need to load all base libraries in the keeper states so that the transfer databases are populated properly // // 'io' for debugging messages, 'package' because we need to require modules exporting idfuncs // the others because they export functions that we may store in a keeper for transfer between lanes K = luaG_newstate( L, _on_state_create, "K"); STACK_CHECK( K); // replace default 'package' contents with stuff gotten from the master state lua_getglobal( L, "package"); luaG_inter_copy_package( L, K, -1); lua_pop( L, 1); DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "### init_keepers %d END\n" INDENT_END, i)); DEBUGSPEW_CODE( -- debugspew_indent_depth); // to see VM name in Decoda debugger lua_pushliteral( K, "Keeper #"); lua_pushinteger( K, i + 1); lua_concat( K, 2); lua_setglobal( K, "decoda_name"); #if KEEPER_MODEL == KEEPER_MODEL_C // create the fifos table in the keeper state lua_pushlightuserdata( K, fifos_key); lua_newtable( K); lua_rawset( K, LUA_REGISTRYINDEX); #endif // KEEPER_MODEL == KEEPER_MODEL_C #if KEEPER_MODEL == KEEPER_MODEL_LUA // use package.loaders[2] to find keeper microcode (NOTE: this works only if nobody tampered with the loaders table...) lua_getglobal( K, "package"); // package lua_getfield( K, -1, "loaders"); // package package.loaders lua_rawgeti( K, -1, 2); // package package.loaders package.loaders[2] lua_pushliteral( K, "lanes-keeper"); // package package.loaders package.loaders[2] "lanes-keeper" STACK_MID( K, 4); // first pcall loads lanes-keeper.lua, second one runs the chunk if( lua_pcall( K, 1 /*args*/, 1 /*results*/, 0 /*errfunc*/) || lua_pcall( K, 0 /*args*/, 0 /*results*/, 0 /*errfunc*/)) { // LUA_ERRRUN / LUA_ERRMEM / LUA_ERRERR // char const* err = lua_tostring( K, -1); assert( err); return err; } // package package.loaders STACK_MID( K, 2); lua_pop( K, 2); #endif // KEEPER_MODEL == KEEPER_MODEL_LUA STACK_END( K, 0); MUTEX_INIT( &GKeepers[i].lock_); GKeepers[i].L = K; //GKeepers[i].count = 0; } #if HAVE_KEEPER_ATEXIT_DESINIT atexit( atexit_close_keepers); #endif // HAVE_KEEPER_ATEXIT_DESINIT return NULL; // ok }
char *Event_ChatMessageRecieved( const char *msg ) { #elif defined(PROJECT_GAME) char *Event_ChatMessageRecieved(int clientNum, const char *msg, int type ) { #endif static char tmpMsg[MAX_SAY_TEXT] = { 0 }; // although a chat message can only be MAX_SAY_TEXT long..-name? #ifdef JPLUA plugin_t *plugin = NULL; #endif Q_strncpyz( tmpMsg, msg, MAX_SAY_TEXT ); #ifdef JPLUA while ( IteratePlugins( &plugin ) ) { if ( plugin->eventListeners[JPLUA_EVENT_CHATMSGRECV] ) { lua_rawgeti( ls.L, LUA_REGISTRYINDEX, plugin->eventListeners[JPLUA_EVENT_CHATMSGRECV] ); #if defined(PROJECT_CGAME) lua_pushstring( ls.L, tmpMsg ); Call( ls.L, 1, 1 ); #elif defined(PROJECT_GAME) Player_CreateRef( ls.L, clientNum ); lua_pushstring( ls.L, tmpMsg ); lua_pushinteger(ls.L, type); Call( ls.L, 3, 1 ); #endif int retType = lua_type( ls.L, -1 ); // returned nil, no use passing it to other plugins if ( retType == LUA_TNIL ) { return NULL; } else if ( retType == LUA_TSTRING ) { Q_strncpyz( tmpMsg, lua_tostring( ls.L, -1 ), sizeof(tmpMsg) ); } else { trap->Print( "Invalid return value in %s (JPLUA_EVENT_CHATMSGRECV), expected string or nil but got " "%s", plugin->name, lua_typename( ls.L, -1 ) ); } } } #endif // JPLUA return tmpMsg; } #ifdef PROJECT_CGAME char *Event_ChatMessageSent( const char *msg, messageMode_e mode, int targetClient ) { static char tmpMsg[MAX_STRING_CHARS] = { 0 }; // although a chat message can only be MAX_SAY_TEXT long..-name? #ifdef JPLUA plugin_t *plugin = NULL; #endif Q_strncpyz( tmpMsg, msg, sizeof(tmpMsg) ); #ifdef JPLUA while ( IteratePlugins( &plugin ) ) { if ( plugin->eventListeners[JPLUA_EVENT_CHATMSGSEND] ) { lua_rawgeti( ls.L, LUA_REGISTRYINDEX, plugin->eventListeners[JPLUA_EVENT_CHATMSGSEND] ); lua_pushstring( ls.L, tmpMsg ); lua_pushinteger( ls.L, mode ); lua_pushinteger( ls.L, targetClient ); Call( ls.L, 3, 1 ); // returned nil, no use passing it to other plugins if ( lua_type( ls.L, -1 ) == LUA_TNIL ) return NULL; else if ( lua_type( ls.L, -1 ) == LUA_TSTRING ) Q_strncpyz( tmpMsg, lua_tostring( ls.L, -1 ), MAX_SAY_TEXT ); else { trap->Print( "Invalid return value in %s (JPLUA_EVENT_CHATMSGSEND), expected string or nil but got " "%s\n", plugin->name, lua_typename( ls.L, -1 ) ); return NULL; } } } #endif // JPLUA return tmpMsg; } #endif #ifdef PROJECT_GAME void Event_ClientBegin( int clientNum ) { #ifdef JPLUA plugin_t *plugin = NULL; while ( IteratePlugins( &plugin ) ) { if ( plugin->eventListeners[JPLUA_EVENT_CLIENTBEGIN] ) { lua_rawgeti( ls.L, LUA_REGISTRYINDEX, plugin->eventListeners[JPLUA_EVENT_CLIENTBEGIN] ); Player_CreateRef( ls.L, clientNum ); Call( ls.L, 1, 0 ); } } #endif }
int JPLua_Push_ToString( lua_State *L ) { lua_rawgeti( L, LUA_REGISTRYINDEX, JPLua_Framework[JPLUA_FRAMEWORK_TOSTRING] ); return 1; }
qboolean Event_ClientCommand( int clientNum ) { qboolean ret = qfalse; #ifdef JPLUA int top, numArgs = trap->Argc(); char cmd[MAX_TOKEN_CHARS] = {}; trap->Argv( 0, cmd, sizeof(cmd) ); plugin_t *plugin = NULL; while ( IteratePlugins( &plugin ) ) { if ( plugin->eventListeners[JPLUA_EVENT_CLIENTCOMMAND] ) { lua_rawgeti( ls.L, LUA_REGISTRYINDEX, plugin->eventListeners[JPLUA_EVENT_CLIENTCOMMAND] ); Player_CreateRef( ls.L, clientNum ); //Push table of arguments lua_newtable( ls.L ); top = lua_gettop( ls.L ); for ( int i = 0; i < numArgs; i++) { char argN[MAX_TOKEN_CHARS]; trap->Argv( i, argN, sizeof(argN) ); lua_pushnumber( ls.L, i + 1 ); lua_pushstring( ls.L, argN ); lua_settable( ls.L, top ); } Call( ls.L, 2, 1 ); int retType = lua_type( ls.L, -1 ); if ( retType == LUA_TNIL ) { continue; } else if ( retType == LUA_TNUMBER ) { ret = qtrue; break; } else { trap->Print( "Invalid return value in %s (JPLUA_EVENT_CLIENTCOMMAND), expected integer or nil but " "got %s\n", plugin->name, lua_typename( ls.L, -1 ) ); } } } command_t &comm = clientCommands[cmd]; if ( comm.handle ) { ret = qtrue; lua_rawgeti( ls.L, LUA_REGISTRYINDEX, comm.handle ); Player_CreateRef( ls.L, clientNum ); //Push table of arguments lua_newtable( ls.L ); top = lua_gettop( ls.L ); for ( int i = 1; i < numArgs; i++ ) { char argN[MAX_TOKEN_CHARS]; trap->Argv( i, argN, sizeof(argN) ); lua_pushnumber( ls.L, i ); lua_pushstring( ls.L, argN ); lua_settable( ls.L, top ); } Call( ls.L, 2, 0 ); } #endif return ret; }
/* ** Retrieves data from the i_th column in the current row ** Input ** types: index in stack of column types table ** hstmt: statement handle ** i: column number ** Returns: ** 0 if successfull, non-zero otherwise; */ static int push_column(lua_State *L, int coltypes, const SQLHSTMT hstmt, SQLUSMALLINT i) { const char *tname; char type; /* get column type from types table */ lua_rawgeti (L, LUA_REGISTRYINDEX, coltypes); lua_rawgeti (L, -1, i); /* typename of the column */ tname = lua_tostring(L, -1); if (!tname) return luasql_faildirect(L, "invalid type in table."); type = tname[1]; lua_pop(L, 2); /* pops type name and coltypes table */ /* deal with data according to type */ switch (type) { /* nUmber */ case 'u': { double num; SQLLEN got; SQLRETURN rc = SQLGetData(hstmt, i, SQL_C_DOUBLE, &num, 0, &got); if (error(rc)) return fail(L, hSTMT, hstmt); if (got == SQL_NULL_DATA) lua_pushnil(L); else lua_pushnumber(L, num); return 0; } #if LUA_VERSION_NUM>=503 /* iNteger */ case 'n': { long int num; SQLLEN got; SQLRETURN rc = SQLGetData(hstmt, i, SQL_C_SLONG, &num, 0, &got); if (error(rc)) return fail(L, hSTMT, hstmt); if (got == SQL_NULL_DATA) lua_pushnil(L); else lua_pushinteger(L, num); return 0; } #endif /* bOol */ case 'o': { char b; SQLLEN got; SQLRETURN rc = SQLGetData(hstmt, i, SQL_C_BIT, &b, 0, &got); if (error(rc)) return fail(L, hSTMT, hstmt); if (got == SQL_NULL_DATA) lua_pushnil(L); else lua_pushboolean(L, b); return 0; } /* sTring */ case 't': /* bInary */ case 'i': { SQLSMALLINT stype = (type == 't') ? SQL_C_CHAR : SQL_C_BINARY; SQLLEN got; char *buffer; luaL_Buffer b; SQLRETURN rc; luaL_buffinit(L, &b); buffer = luaL_prepbuffer(&b); rc = SQLGetData(hstmt, i, stype, buffer, LUAL_BUFFERSIZE, &got); if (got == SQL_NULL_DATA) { lua_pushnil(L); return 0; } /* concat intermediary chunks */ while (rc == SQL_SUCCESS_WITH_INFO) { if (got >= LUAL_BUFFERSIZE || got == SQL_NO_TOTAL) { got = LUAL_BUFFERSIZE; /* get rid of null termination in string block */ if (stype == SQL_C_CHAR) got--; } luaL_addsize(&b, got); buffer = luaL_prepbuffer(&b); rc = SQLGetData(hstmt, i, stype, buffer, LUAL_BUFFERSIZE, &got); } /* concat last chunk */ if (rc == SQL_SUCCESS) { if (got >= LUAL_BUFFERSIZE || got == SQL_NO_TOTAL) { got = LUAL_BUFFERSIZE; /* get rid of null termination in string block */ if (stype == SQL_C_CHAR) got--; } luaL_addsize(&b, got); } if (rc == SQL_ERROR) return fail(L, hSTMT, hstmt); /* return everything we got */ luaL_pushresult(&b); return 0; } } return 0; }
void Event_ClientInfoUpdate( int clientNum, clientInfo_t *oldInfo, clientInfo_t *newInfo ) { #ifdef JPLUA plugin_t *plugin = NULL; while ( IteratePlugins( &plugin ) ) { if ( plugin->eventListeners[JPLUA_EVENT_CLIENTINFO] ) { lua_rawgeti( ls.L, LUA_REGISTRYINDEX, plugin->eventListeners[JPLUA_EVENT_CLIENTINFO] ); // Create a player instance for this client number and push on stack Player_CreateRef( ls.L, clientNum ); for ( int i = 0; i < 2; i++ ) { clientInfo_t *ci = i ? newInfo : oldInfo; lua_newtable( ls.L ); int top1 = lua_gettop( ls.L ); lua_pushstring( ls.L, "colorOverride" ); lua_newtable( ls.L ); int top2 = lua_gettop( ls.L ); lua_pushstring( ls.L, "r" ); lua_pushnumber( ls.L, ci->colorOverride.r ); lua_settable( ls.L, top2 ); lua_pushstring( ls.L, "g" ); lua_pushnumber( ls.L, ci->colorOverride.g ); lua_settable( ls.L, top2 ); lua_pushstring( ls.L, "b" ); lua_pushnumber( ls.L, ci->colorOverride.b ); lua_settable( ls.L, top2 ); lua_pushstring( ls.L, "a" ); lua_pushnumber( ls.L, ci->colorOverride.a ); lua_settable( ls.L, top2 ); lua_settable( ls.L, top1 ); lua_pushstring( ls.L, "saberName" ); lua_pushstring( ls.L, ci->saberName ); lua_settable( ls.L, top1 ); lua_pushstring( ls.L, "saber2Name" ); lua_pushstring( ls.L, ci->saber2Name ); lua_settable( ls.L, top1 ); lua_pushstring( ls.L, "name" ); lua_pushstring( ls.L, ci->name ); lua_settable( ls.L, top1 ); lua_pushstring( ls.L, "team" ); lua_pushnumber( ls.L, ci->team ); lua_settable( ls.L, top1 ); lua_pushstring( ls.L, "duelTeam" ); lua_pushnumber( ls.L, ci->duelTeam ); lua_settable( ls.L, top1 ); lua_pushstring( ls.L, "botSkill" ); lua_pushnumber( ls.L, ci->botSkill ); lua_settable( ls.L, top1 ); lua_pushstring( ls.L, "color1" ); Vector_CreateRef( ls.L, &ci->color1 ); lua_settable( ls.L, top1 ); lua_pushstring( ls.L, "color2" ); Vector_CreateRef( ls.L, &ci->color2 ); lua_settable( ls.L, top1 ); lua_pushstring( ls.L, "rgb1" ); Vector_CreateRef( ls.L, ci->rgb1.r, ci->rgb1.g, ci->rgb1.b ); lua_settable( ls.L, top1 ); lua_pushstring( ls.L, "rgb2" ); Vector_CreateRef( ls.L, ci->rgb2.r, ci->rgb2.g, ci->rgb2.b ); lua_settable( ls.L, top1 ); lua_pushstring( ls.L, "icolor1" ); lua_pushnumber( ls.L, ci->icolor1 ); lua_settable( ls.L, top1 ); lua_pushstring( ls.L, "icolor2" ); lua_pushnumber( ls.L, ci->icolor2 ); lua_settable( ls.L, top1 ); lua_pushstring( ls.L, "score" ); lua_pushnumber( ls.L, ci->score ); lua_settable( ls.L, top1 ); lua_pushstring( ls.L, "location" ); lua_pushnumber( ls.L, ci->location ); lua_settable( ls.L, top1 ); lua_pushstring( ls.L, "health" ); lua_pushnumber( ls.L, ci->health ); lua_settable( ls.L, top1 ); lua_pushstring( ls.L, "armor" ); lua_pushnumber( ls.L, ci->armor ); lua_settable( ls.L, top1 ); lua_pushstring( ls.L, "curWeapon" ); lua_pushnumber( ls.L, ci->curWeapon ); lua_settable( ls.L, top1 ); lua_pushstring( ls.L, "handicap" ); lua_pushnumber( ls.L, ci->handicap ); lua_settable( ls.L, top1 ); lua_pushstring( ls.L, "wins" ); lua_pushnumber( ls.L, ci->wins ); lua_settable( ls.L, top1 ); lua_pushstring( ls.L, "losses" ); lua_pushnumber( ls.L, ci->losses ); lua_settable( ls.L, top1 ); lua_pushstring( ls.L, "teamTask" ); lua_pushnumber( ls.L, ci->teamTask ); lua_settable( ls.L, top1 ); lua_pushstring( ls.L, "powerups" ); lua_pushnumber( ls.L, ci->powerups ); lua_settable( ls.L, top1 ); lua_pushstring( ls.L, "modelName" ); lua_pushstring( ls.L, ci->saberName ); lua_settable( ls.L, top1 ); lua_pushstring( ls.L, "skinName" ); lua_pushstring( ls.L, ci->saberName ); lua_settable( ls.L, top1 ); lua_pushstring( ls.L, "forcePowers" ); lua_pushstring( ls.L, ci->forcePowers ); lua_settable( ls.L, top1 ); lua_pushstring( ls.L, "teamName" ); lua_pushstring( ls.L, ci->teamName ); lua_settable( ls.L, top1 ); lua_pushstring( ls.L, "deferred" ); lua_pushboolean( ls.L, ci->deferred ); lua_settable( ls.L, top1 ); lua_pushstring( ls.L, "gender" ); lua_pushnumber( ls.L, ci->gender ); lua_settable( ls.L, top1 ); } Call( ls.L, 3, 0 ); } } #endif }
static char * _get_value(lua_State *L, int index, char * ptr, char type) { switch(type) { case 'i': { int32_t v = luaL_checkinteger(L, index); memcpy(ptr, &v, 4); return ptr + 4; } case 'u': { uint64_t v = (uint64_t)luaL_checknumber(L, index); memcpy(ptr, &v, 8); return ptr + 8; } case 'd': { int64_t v = (int64_t)luaL_checknumber(L, index); memcpy(ptr, &v, 8); return ptr + 8; } case 'b': { int32_t v = lua_toboolean(L, index); memcpy(ptr, &v, 4); return ptr + 4; } case 'p': { void *p = lua_touserdata(L, index); uint32_t v = (uint32_t)(intptr_t)p; memcpy(ptr, &v , 4); return ptr + 4; } case 'x': { const char * i64 = luaL_checkstring(L, index); memcpy(ptr, i64, 8); return ptr + 8; } case 'r': { double v = luaL_checknumber(L, index); memcpy(ptr, &v, 8); return ptr + 8; } case 's': { size_t sz = 0; const char * str = luaL_checklstring(L, index, &sz); struct pbc_slice * slice = (struct pbc_slice *)ptr; slice->buffer = (void*)str; slice->len = sz; return ptr + sizeof(struct pbc_slice); } case 'm': { struct pbc_slice * slice = (struct pbc_slice *)ptr; if (lua_istable(L,index)) { lua_rawgeti(L,index,1); slice->buffer = lua_touserdata(L,-1); lua_rawgeti(L,index,2); slice->len = lua_tointeger(L,-1); lua_pop(L,2); } else { size_t sz = 0; const char * buffer = luaL_checklstring(L, index, &sz); slice->buffer = (void *)buffer; slice->len = sz; } return ptr + sizeof(struct pbc_slice); } default: luaL_error(L,"unknown format %c", type); return ptr; } }
//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ int LuaMethod::operator()(lua_State* L) { try { // Get the user data from the first argument as it's the I_ObjectReference* lua_pushliteral(L, "__zen_userdata"); lua_gettable(L, 1); pObjectReference_type* pObj = (pObjectReference_type*)lua_touserdata(L, -1); lua_pop(L, 1); switch(m_functionType) { case VOID_FUNCTION_NO_ARGS: m_function0(*pObj); return 0; case VOID_FUNCTION_ARGS: case OBJ_FUNCTION_ARGS: case STRING_FUNCTION_ARGS: case BOOL_FUNCTION_ARGS: case INT_FUNCTION_ARGS: case GENERIC_FUNCTION_ARGS: { int top = lua_gettop(L); std::vector<boost::any> parms; for(int x = 2; x <= lua_gettop(L); x++) { switch(lua_type(L, x)) { case LUA_TBOOLEAN: { bool value = lua_toboolean(L, x); parms.push_back(value); } break; case LUA_TNUMBER: { Math::Real value = (Math::Real)lua_tonumber(L, x); parms.push_back(value); } break; case LUA_TSTRING: { std::string value = lua_tostring(L, x); parms.push_back(value); } break; case LUA_TUSERDATA: { // Should we get here anymore? pObjectReference_type* pValue = (pObjectReference_type*)lua_touserdata(L, x); parms.push_back(*pValue); } break; case LUA_TTABLE: // A script object { const int tmpTop = lua_gettop(L); //lua_topointer lua_pushstring(L, "__zen_userdata"); lua_gettable(L, x); int newType = lua_type(L, -1); // Check to see if this is a user data if (newType == LUA_TUSERDATA) { // Check what type of user data lua_getmetatable(L, x); lua_getfield(L, LUA_REGISTRYINDEX, "Matrix4"); if (lua_rawequal(L, -1, -2)) { Math::Matrix4* pMatrix4 = (Math::Matrix4*)lua_touserdata(L, -3); // Note that we're pushing a pointer, not a copy of the object parms.push_back(pMatrix4); // Pop the table and the two meta tables lua_pop(L, 3); assert(tmpTop == lua_gettop(L)); continue; } lua_pop(L, 1); lua_getfield(L, LUA_REGISTRYINDEX, "Quaternion4"); if (lua_rawequal(L, -1, -2)) { Math::Quaternion4* pQuaternion4 = (Math::Quaternion4*)lua_touserdata(L, -3); // Note that we're pushing a pointer, not a copy of the object parms.push_back(pQuaternion4); // Pop the table and the two meta tables lua_pop(L, 3); assert(tmpTop == lua_gettop(L)); continue; } lua_pop(L, 1); lua_getfield(L, LUA_REGISTRYINDEX, "Vector3"); if (lua_rawequal(L, -1, -2)) { Math::Vector3* pVector3 = (Math::Vector3*)lua_touserdata(L, -3); // Note that we're pushing a pointer, not a copy of the object parms.push_back(pVector3); // Pop the table and the two meta tables lua_pop(L, 3); assert(tmpTop == lua_gettop(L)); continue; } lua_pop(L, 1); lua_getfield(L, LUA_REGISTRYINDEX, "Vector4"); if (lua_rawequal(L, -1, -2)) { Math::Vector4* pVector4 = (Math::Vector4*)lua_touserdata(L, -3); // Note that we're pushing a pointer, not a copy of the object parms.push_back(pVector4); // Pop the table and the two meta tables lua_pop(L, 3); assert(tmpTop == lua_gettop(L)); continue; } lua_pop(L, 1); lua_getfield(L, LUA_REGISTRYINDEX, "Point3"); if (lua_rawequal(L, -1, -2)) { Math::Point3* pPoint3 = (Math::Point3*)lua_touserdata(L, -3); // Note that we're pushing a pointer, not a copy of the object parms.push_back(pPoint3); // Pop the table and the two meta tables lua_pop(L, 3); assert(tmpTop == lua_gettop(L)); continue; } lua_pop(L,1); lua_getfield(L, LUA_REGISTRYINDEX, "Radian"); if (lua_rawequal(L, -1, -2)) { // Get the user data, which is a Math::Radian* Math::Radian* pRadian = (Math::Radian*)lua_touserdata(L, -3); // Push the value onto the list of arguments being passed // to the function being called by Lua. // Note that we're pushing a <b>pointer</b>, of the // Math::Radian and not the value. parms.push_back(pRadian); // Pop the table and the two meta tables. lua_pop(L, 3); assert(tmpTop == lua_gettop(L)); continue; } lua_pop(L,1); lua_getfield(L, LUA_REGISTRYINDEX, "Degree"); if (lua_rawequal(L, -1, -2)) { // Get the user data, which is a Math::Degree* Math::Degree* pDegree = (Math::Degree*)lua_touserdata(L, -3); // Push the value onto the list of arguments being passed // to the function being called by Lua. // Note that we're pushing a <b>pointer</b>, of the // Math::Radian and not the value. parms.push_back(pDegree); // Pop the table and the two meta tables. lua_pop(L, 3); assert(tmpTop == lua_gettop(L)); continue; } // Check to see if the argument is a Config type. lua_pop(L, 1); lua_getfield(L, LUA_REGISTRYINDEX, "Config"); if (lua_rawequal(L, -1, -2)) { // Get the user data, which is a Config* Config* pConfig = (Config*)lua_touserdata(L, -3); // Push the value onto the list of arguments being passed // to the function being called by Lua. // Note that we're pushing a <b>pointer</b>, of the // std::map<std::string, std::string> and not the value. parms.push_back(&pConfig->m_config); // Pop the table and the two meta tables lua_pop(L, 3); assert(tmpTop == lua_gettop(L)); continue; } pObjectReference_type* pValue = (pObjectReference_type*)lua_touserdata(L, -3); parms.push_back(*pValue); lua_pop(L, 2); } else { // Push a non C++ script object lua_pushvalue(L, x); int ref = luaL_ref(L, LUA_REGISTRYINDEX); parms.push_back(ref); } lua_pop(L, 1); assert(tmpTop == lua_gettop(L)); } break; case LUA_TFUNCTION: // As script function (not C++) { lua_pushvalue(L, x); int ref = luaL_ref(L, LUA_REGISTRYINDEX); parms.push_back(ref); } break; } } if (m_functionType == VOID_FUNCTION_ARGS) { // Pop everything off the stack lua_pop(L, lua_gettop(L)); m_function1(*pObj, parms); // No return value return 0; } else if (m_functionType == STRING_FUNCTION_ARGS) { // Pop everything off the stack lua_pop(L, lua_gettop(L)); std::string returnValue = m_function5(*pObj, parms); lua_pushstring(L, returnValue.c_str()); return 1; } else if (m_functionType == BOOL_FUNCTION_ARGS) { // Pop everything off the stack lua_pop(L, lua_gettop(L)); bool returnValue = m_function7(*pObj, parms); lua_pushboolean(L, returnValue); return 1; } else if (m_functionType == INT_FUNCTION_ARGS) { // Pop everything off the stack lua_pop(L, lua_gettop(L)); int returnValue = m_function9(*pObj, parms); lua_pushinteger(L, returnValue); return 1; } else if (m_functionType == OBJ_FUNCTION_ARGS) { // Pop everything off the stack lua_pop(L, lua_gettop(L)); pObjectReference_type pReturn = m_function2(*pObj, parms); lua_rawgeti(L, LUA_REGISTRYINDEX, (lua_Integer)pReturn->getScriptUserData()); // Return 1 item on the stack, which is the object we're returning assert(lua_gettop(L) == 1); return 1; } else if (m_functionType == GENERIC_FUNCTION_ARGS) { // Pop everything off the stack lua_pop(L, lua_gettop(L)); boost::any anyReturn = m_function10->dispatch(*pObj, parms); // TODO this is inefficient... do a map of functors instead. if (anyReturn.type() == typeid(void)) { // no return, don't bother doing anything return 0; } else if (anyReturn.type() == typeid(Zen::Scripting::I_ObjectReference*)) { // object pObjectReference_type pReturn = boost::any_cast<pObjectReference_type>(anyReturn); lua_rawgeti(L, LUA_REGISTRYINDEX, (lua_Integer)pReturn->getScriptUserData()); assert(lua_gettop(L) == 1); return 1; } else if (anyReturn.type() == typeid(std::string)) { std::string returnValue = boost::any_cast<std::string>(anyReturn); lua_pushstring(L, returnValue.c_str()); return 1; } else if(anyReturn.type() == typeid(bool)) { bool returnValue = boost::any_cast<bool>(anyReturn); lua_pushboolean(L, returnValue); return 1; } else if (anyReturn.type() == typeid(int)) { int returnValue = boost::any_cast<int>(anyReturn); lua_pushinteger(L, returnValue); return 1; } else if (anyReturn.type() == typeid(unsigned int)) { int returnValue = boost::any_cast<unsigned int>(anyReturn); lua_pushinteger(L, returnValue); return 1; } else if (anyReturn.type() == typeid(Zen::Math::Real)) { Zen::Math::Real returnValue = boost::any_cast<Zen::Math::Real>(anyReturn); lua_pushnumber(L, returnValue); return 1; } // TODO This is a hack. else if (anyReturn.type() == typeid(Zen::Math::Vector3)) { const int top = lua_gettop(L); lua_newtable(L); const int table = lua_gettop(L); Math::Vector3* pVector3 = new (lua_newuserdata(L, sizeof(Math::Vector3))) Math::Vector3(); const int userdata = lua_gettop(L); // T["__zen_userdata"] = UD lua_pushvalue(L, userdata); lua_setfield(L, table, "__zen_userdata"); // Get the meta table for this class type and set it for this object luaL_getmetatable(L, "Vector3"); lua_setmetatable(L, table); // Get the meta table for this class type and set it for the user data luaL_getmetatable(L, "Vector3"); lua_setmetatable(L, userdata); // Pop the userdata so only the table is left lua_pop(L, 1); *pVector3 = boost::any_cast<Zen::Math::Vector3>(anyReturn); return 1; } else if (anyReturn.type() == typeid(Zen::Math::Point3)) { const int top = lua_gettop(L); lua_newtable(L); const int table = lua_gettop(L); Math::Point3* pPoint3 = new (lua_newuserdata(L, sizeof(Math::Point3))) Math::Point3(); const int userdata = lua_gettop(L); // T["__zen_userdata"] = UD lua_pushvalue(L, userdata); lua_setfield(L, table, "__zen_userdata"); // Get the meta table for this class type and set it for this object luaL_getmetatable(L, "Point3"); lua_setmetatable(L, table); // Get the meta table for this class type and set it for the user data luaL_getmetatable(L, "Point3"); lua_setmetatable(L, userdata); // Pop the userdata so only the table is left lua_pop(L, 1); *pPoint3 = boost::any_cast<Zen::Math::Point3>(anyReturn); return 1; } else { // TODO Make this error message a little more detailed throw Zen::Utility::runtime_exception("Script method returned unknown type."); } // TODO Throw an exception since the type wasn't assert(lua_gettop(L) == 0); return 0; } } break; case OBJ_FUNCTION_NO_ARGS: { // Pop everything off the stack lua_pop(L, lua_gettop(L)); pObjectReference_type pReturn = m_function3(*pObj); lua_rawgeti(L, LUA_REGISTRYINDEX, (lua_Integer)pReturn->getScriptUserData()); // Return 1 item on the stack, which is the object we're returning assert(lua_gettop(L) == 1); return 1; } break; case STRING_FUNCTION_NO_ARGS: { // Pop everything off the stack lua_pop(L, lua_gettop(L)); std::string returnValue = m_function4(*pObj); lua_pushstring(L, returnValue.c_str()); return 1; } break; case BOOL_FUNCTION_NO_ARGS: { // Pop everything off the stack lua_pop(L, lua_gettop(L)); bool returnValue = m_function6(*pObj); lua_pushboolean(L, returnValue); return 1; } break; case INT_FUNCTION_NO_ARGS: { // Pop everything off the stack lua_pop(L, lua_gettop(L)); int returnValue = m_function8(*pObj); lua_pushinteger(L, returnValue); return 1; } break; } } catch(Utility::runtime_exception& ex) { std::cout << "ERROR: Caught exception handling call to C++ from Lua. " << ex.what() << std::endl; throw ex; } catch(std::exception& ex) { std::cout << "ERROR: Caught exception handling call to C++ from Lua. " << ex.what() << std::endl; throw ex; } catch(...) { std::cout << "ERROR: Caught unknown exception handling call to C++ from Lua." << std::endl; throw; } // TODO Return the number of items on the stack. return 0; }
/* lightuserdata pattern string format "ixrsmbp" integer size */ static int _pattern_pack(lua_State *L) { struct pbc_pattern * pat = (struct pbc_pattern *)checkuserdata(L,1); if (pat == NULL) { return luaL_error(L, "pack pattern is NULL"); } size_t format_sz = 0; const char * format = lua_tolstring(L,2,&format_sz); int size = lua_tointeger(L,3); char * data = (char *)alloca(size); // A trick , we don't need default value. zero buffer for array and message field. // pbc_pattern_set_default(pat, data); memset(data, 0 , size); char * ptr = data; int i; for (i=0;i<format_sz;i++) { if (format[i] >= 'a' && format[i] <='z') { ptr = _get_value(L, 4+i, ptr, format[i]); } else { if (!lua_istable(L,4+i)) { luaL_error(L,"need table for array type"); } int j; int n = lua_rawlen(L,4+i); for (j=0;j<n;j++) { lua_rawgeti(L,4+i,j+1); _get_array_value(L,(struct _pbc_array *)ptr,format[i]); lua_pop(L,1); } ptr += sizeof(pbc_array); } } luaL_Buffer b; luaL_buffinit(L, &b); int cap = 128; for (;;) { char * temp = (char *)luaL_prepbuffsize(&b , cap); struct pbc_slice slice; slice.buffer = temp; slice.len = cap; int ret = pbc_pattern_pack(pat, data, &slice); if (ret < 0) { cap = cap * 2; _Free(temp); continue; } luaL_addsize(&b , slice.len); break; } luaL_pushresult(&b); pbc_pattern_close_arrays(pat, data); return 1; }
const char *LuaSerializer::unpickle(lua_State *l, const char *pos) { LUA_DEBUG_START(l); char type = *pos++; switch (type) { case 'f': { char *end; double f = strtod(pos, &end); if (pos == end) throw SavedGameCorruptException(); lua_pushnumber(l, f); pos = end+1; // skip newline break; } case 'b': { if (*pos != '0' && *pos != '1') throw SavedGameCorruptException(); bool b = (*pos == '0') ? false : true; lua_pushboolean(l, b); pos++; break; } case 's': { char *end; int len = strtol(pos, const_cast<char**>(&end), 0); if (pos == end) throw SavedGameCorruptException(); end++; // skip newline lua_pushlstring(l, end, len); pos = end + len; break; } case 't': { lua_newtable(l); lua_getfield(l, LUA_REGISTRYINDEX, "PiSerializerTableRefs"); pos = unpickle(l, pos); lua_pushvalue(l, -3); lua_rawset(l, -3); lua_pop(l, 1); while (*pos != 'n') { pos = unpickle(l, pos); pos = unpickle(l, pos); lua_rawset(l, -3); } pos++; break; } case 'r': { pos = unpickle(l, pos); lua_getfield(l, LUA_REGISTRYINDEX, "PiSerializerTableRefs"); lua_pushvalue(l, -2); lua_rawget(l, -2); if (lua_isnil(l, -1)) throw SavedGameCorruptException(); lua_insert(l, -3); lua_pop(l, 2); break; } case 'u': { const char *end = strchr(pos, '\n'); if (!end) throw SavedGameCorruptException(); int len = end - pos; end++; // skip newline if (len == 10 && strncmp(pos, "SystemPath", 10) == 0) { pos = end; Sint32 sectorX = strtol(pos, const_cast<char**>(&end), 0); if (pos == end) throw SavedGameCorruptException(); pos = end+1; // skip newline Sint32 sectorY = strtol(pos, const_cast<char**>(&end), 0); if (pos == end) throw SavedGameCorruptException(); pos = end+1; // skip newline Sint32 sectorZ = strtol(pos, const_cast<char**>(&end), 0); if (pos == end) throw SavedGameCorruptException(); pos = end+1; // skip newline Uint32 systemNum = strtoul(pos, const_cast<char**>(&end), 0); if (pos == end) throw SavedGameCorruptException(); pos = end+1; // skip newline Uint32 sbodyId = strtoul(pos, const_cast<char**>(&end), 0); if (pos == end) throw SavedGameCorruptException(); pos = end+1; // skip newline SystemPath *sbp = new SystemPath(sectorX, sectorY, sectorZ, systemNum, sbodyId); LuaSystemPath::PushToLuaGC(sbp); break; } if (len == 4 && strncmp(pos, "Body", 4) == 0) { pos = end; Uint32 n = strtoul(pos, const_cast<char**>(&end), 0); if (pos == end) throw SavedGameCorruptException(); pos = end+1; // skip newline Body *body = Pi::game->GetSpace()->GetBodyByIndex(n); if (pos == end) throw SavedGameCorruptException(); switch (body->GetType()) { case Object::BODY: LuaBody::PushToLua(body); break; case Object::SHIP: LuaShip::PushToLua(dynamic_cast<Ship*>(body)); break; case Object::SPACESTATION: LuaSpaceStation::PushToLua(dynamic_cast<SpaceStation*>(body)); break; case Object::PLANET: LuaPlanet::PushToLua(dynamic_cast<Planet*>(body)); break; case Object::STAR: LuaStar::PushToLua(dynamic_cast<Star*>(body)); break; case Object::PLAYER: LuaPlayer::PushToLua(dynamic_cast<Player*>(body)); break; default: throw SavedGameCorruptException(); } break; } throw SavedGameCorruptException(); } case 'o': { const char *end = strchr(pos, '\n'); if (!end) throw SavedGameCorruptException(); int len = end - pos; end++; // skip newline const char *cl = pos; // unpickle the object, and insert it beneath the method table value pos = unpickle(l, end); // get _G[typename] lua_rawgeti(l, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS); lua_pushlstring(l, cl, len); lua_gettable(l, -2); lua_remove(l, -2); if (lua_isnil(l, -1)) { lua_pop(l, 2); break; } lua_getfield(l, -1, "Unserialize"); if (lua_isnil(l, -1)) { lua_pushlstring(l, cl, len); luaL_error(l, "No Unserialize method found for class '%s'\n", lua_tostring(l, -1)); } lua_insert(l, -3); lua_pop(l, 1); pi_lua_protected_call(l, 1, 1); break; } default: throw SavedGameCorruptException(); } LUA_DEBUG_END(l, 1); return pos; }
static void lluv_on_getaddrinfo(uv_getaddrinfo_t* arg, int status, struct addrinfo* res){ lluv_req_t *req = lluv_req_byptr((uv_req_t*)arg); lluv_loop_t *loop = lluv_loop_byptr(arg->loop); lua_State *L = loop->L; struct addrinfo* a = res; int i = 0; LLUV_CHECK_LOOP_CB_INVARIANT(L); lua_rawgeti(L, LLUV_LUA_REGISTRY, req->cb); lluv_req_free(L, req); assert(!lua_isnil(L, -1)); lluv_loop_pushself(L, loop); if(status < 0){ uv_freeaddrinfo(res); lluv_error_create(L, LLUV_ERR_UV, (uv_errno_t)status, NULL); LLUV_LOOP_CALL_CB(L, loop, 2); LLUV_CHECK_LOOP_CB_INVARIANT(L); return; } lua_pushnil(L); lua_newtable(L); for(a = res; a; a = a->ai_next){ char buf[INET6_ADDRSTRLEN + 1]; int port; lua_newtable(L); switch (a->ai_family){ case AF_INET:{ struct sockaddr_in *sa = (struct sockaddr_in*)a->ai_addr; uv_ip4_name(sa, buf, sizeof(buf)); lua_pushstring(L, buf); lua_setfield(L, -2, "address"); if((port = ntohs(sa->sin_port))){ lua_pushinteger(L, port); lua_setfield(L, -2, "port"); } break; } case AF_INET6:{ struct sockaddr_in6 *sa = (struct sockaddr_in6*)a->ai_addr; uv_ip6_name(sa, buf, sizeof(buf)); lua_pushstring(L, buf); lua_setfield(L, -2, "address"); if((port = ntohs(sa->sin6_port))){ lua_pushinteger(L, port); lua_setfield(L, -2, "port"); } break; } } if(a->ai_canonname){ lua_pushstring(L, a->ai_canonname); lua_setfield(L, -2, "canonname"); } lluv_push_ai_family(L, a->ai_family); lua_setfield(L, -2, "family"); lluv_push_ai_stype(L, a->ai_socktype); lua_setfield(L, -2, "socktype"); lluv_push_ai_proto(L, a->ai_protocol); lua_setfield(L, -2, "protocol"); lua_rawseti(L, -2, ++i); } uv_freeaddrinfo(res); LLUV_LOOP_CALL_CB(L, loop, 3); LLUV_CHECK_LOOP_CB_INVARIANT(L); }
/** Get indexed value without invoking meta methods. * Pushes t[n] onto the stack, where t is a table at index idx. * @param idx index of the table * @param n index in the table */ void LuaContext::raw_geti(int idx, int n) { lua_rawgeti(__L, idx, n); }
void CLuaRules::Cob2Lua(const LuaHashString& name, const CUnit* unit, int& argsCount, int args[MAX_LUA_COB_ARGS]) { static int callDepth = 0; if (callDepth >= 16) { LOG_L(L_WARNING, "CLuaRules::Cob2Lua() call overflow: %s", name.GetString().c_str()); args[0] = 0; // failure return; } LUA_CALL_IN_CHECK(L); const int top = lua_gettop(L); if (!lua_checkstack(L, 1 + 3 + argsCount)) { LOG_L(L_WARNING, "CLuaRules::Cob2Lua() lua_checkstack() error: %s", name.GetString().c_str()); args[0] = 0; // failure lua_settop(L, top); return; } if (!name.GetGlobalFunc(L)) { LOG_L(L_WARNING, "CLuaRules::Cob2Lua() missing function: %s", name.GetString().c_str()); args[0] = 0; // failure lua_settop(L, top); return; } lua_pushnumber(L, unit->id); lua_pushnumber(L, unit->unitDef->id); lua_pushnumber(L, unit->team); for (int a = 0; a < argsCount; a++) { lua_pushnumber(L, args[a]); } // call the routine callDepth++; const int* oldArgs = currentCobArgs; currentCobArgs = args; const bool error = !RunCallIn(name, 3 + argsCount, LUA_MULTRET); currentCobArgs = oldArgs; callDepth--; // bail on error if (error) { args[0] = 0; // failure lua_settop(L, top); return; } // get the results const int retArgs = std::min(lua_gettop(L) - top, (MAX_LUA_COB_ARGS - 1)); for (int a = 1; a <= retArgs; a++) { const int index = (a + top); if (lua_isnumber(L, index)) { args[a] = lua_toint(L, index); } else if (lua_isboolean(L, index)) { args[a] = lua_toboolean(L, index) ? 1 : 0; } else if (lua_istable(L, index)) { lua_rawgeti(L, index, 1); lua_rawgeti(L, index, 2); if (lua_isnumber(L, -2) && lua_isnumber(L, -1)) { const int x = lua_toint(L, -2); const int z = lua_toint(L, -1); args[a] = PACKXZ(x, z); } else { args[a] = 0; } lua_pop(L, 2); } else { args[a] = 0; } } args[0] = 1; // success lua_settop(L, top); return; }
static int lsave(lua_State *L) { int color_type; int step; int bit_depth = 8; const char *filename = luaL_checkstring(L,1); const char *type = luaL_checkstring(L,2); if (!strcmp(type, "RGBA8")) { color_type = PNG_COLOR_TYPE_RGB_ALPHA; step = 4; } else if (!strcmp(type, "RGB8")) { color_type = PNG_COLOR_TYPE_RGB; step = 3; } else if (!strcmp(type, "GRAY")) { color_type = PNG_COLOR_TYPE_GRAY; step = 1; } else { return luaL_error(L, "png type %s not support", type); } int width = luaL_checkinteger(L,3); int height = luaL_checkinteger(L,4); luaL_checktype(L,5, LUA_TTABLE); int n = lua_rawlen(L,5); if (n != width * height * step) { return luaL_error(L, "Data number %d invalid, should be %d*%d*%d = %d", n, width, height, step, width * height * step); } FILE *fp = fopen(filename, "wb"); if (fp == NULL) { return luaL_error(L, strerror(errno)); } png_structp png_ptr; png_infop info_ptr; png_colorp palette; png_bytep *row_pointers; png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL); if (png_ptr == NULL) { return luaL_error(L, "png_create_write_struct fail"); } info_ptr = png_create_info_struct(png_ptr); if (info_ptr == NULL) { png_destroy_write_struct(&png_ptr, NULL); return luaL_error(L, "png_destroy_write_struct fail"); } if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_write_struct(&png_ptr, &info_ptr); return 0; } uint8_t *buffer = (uint8_t *)malloc(width * height *step); int i; for (i=0; i<height *width; ++i) { lua_rawgeti(L,5,i*step+1); lua_rawgeti(L,5,i*step+2); lua_rawgeti(L,5,i*step+3); lua_rawgeti(L,5,i*step+4); buffer[i*step+0] = (uint8_t)lua_tointeger(L,-4); buffer[i*step+1] = (uint8_t)lua_tointeger(L,-3); buffer[i*step+2] = (uint8_t)lua_tointeger(L,-2); buffer[i*step+3] = (uint8_t)lua_tointeger(L,-1); lua_pop(L,4); } png_init_io(png_ptr, fp); png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, color_type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); palette = (png_colorp)png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH * (sizeof (png_color))); png_set_PLTE(png_ptr, info_ptr, palette, PNG_MAX_PALETTE_LENGTH); png_write_info(png_ptr, info_ptr); png_set_packing(png_ptr); row_pointers = (png_bytep*)malloc(height * sizeof(png_bytep)); for (i = 0; i<height; i++) row_pointers[i] = buffer + i* width* step; png_write_image(png_ptr, row_pointers); png_write_end(png_ptr, info_ptr); png_free(png_ptr, palette); png_destroy_write_struct(&png_ptr, &info_ptr); free(row_pointers); free(buffer); fclose(fp); return 0; }
// If we're not using lua, need to define Use_function in a way to always call the C++ function int use_function::call(player* player_instance, item* item_instance, bool active) { if (function_type == USE_FUNCTION_NONE) { if (player_instance != NULL && player_instance->is_player()) { g->add_msg(_("You can't do anything interesting with your %s."), item_instance->tname().c_str()); } } else if (function_type == USE_FUNCTION_CPP) { // If it's a C++ function, simply call it with the given arguments. iuse tmp; return (tmp.*cpp_function)(player_instance, item_instance, active); } else if (function_type == USE_FUNCTION_ACTOR_PTR) { return actor_ptr->use(player_instance, item_instance, active); } else { #ifdef LUA // We'll be using lua_state a lot! lua_State* L = lua_state; // If it's a lua function, the arguments have to be wrapped in // lua userdata's and passed on the lua stack. // We will now call the function f(player, item, active) update_globals(L); // Push the lua function on top of the stack lua_rawgeti(L, LUA_REGISTRYINDEX, lua_function); // Push the item on top of the stack. int item_in_registry; { item** item_userdata = (item**) lua_newuserdata(L, sizeof(item*)); *item_userdata = item_instance; // Save a reference to the item in the registry so that we can deallocate it // when we're done. item_in_registry = luah_store_in_registry(L, -1); // Set the metatable for the item. luah_setmetatable(L, "item_metatable"); } // Push the "active" parameter on top of the stack. lua_pushboolean(L, active); // Call the iuse function int err = lua_pcall(L, 2, 1, 0); if(err) { // Error handling. const char* error = lua_tostring(L, -1); debugmsg("Error in lua iuse function: %s", error); } // Make sure the now outdated parameters we passed to lua aren't // being used anymore by setting a metatable that will error on // access. luah_remove_from_registry(L, item_in_registry); luah_setmetatable(L, "outdated_metatable"); return lua_tointeger(L, -1); #else // If LUA isn't defined and for some reason we registered a lua function, // simply do nothing. return 0; #endif } return 0; }
void Eluna::BeginCall(int fReference) { lua_settop(LuaState, 0); //stack should be empty lua_rawgeti(LuaState, LUA_REGISTRYINDEX, (fReference)); }