LuaValue LuaTable::get(const LuaValue& k, bool raw) const { if (k.isTypeOf(LVT_Number)) { int idx = (int)k.getNumber() - 1; if (idx >= 0 && idx < (int)m_vec.size()) return m_vec[idx]; } auto iter = m_hashTable.find(k); if (iter != m_hashTable.end()) return iter->second; if (!raw && m_metaTable != NULL) { LuaValue f = m_metaTable->get(LuaValue("__index")); if (f.isTypeOf(LVT_Nil)) {} else if (f.isTypeOf(LVT_Table)) return f.getTable()->get(k); else if (f.isTypeOf(LVT_Function)) { vector<LuaValue> args, rets; { auto t = const_cast<LuaTable*>(this); t->addRef(); args.push_back(LuaValue(t)); args.push_back(k); } f.getFunction()->call(args, rets); if (!rets.empty()) return rets[0]; } else ASSERT(0); } return LuaValue::NIL; }
void LuaTable::set(const LuaValue& k, const LuaValue& v, bool raw) { if (!raw && m_metaTable != NULL && !v.isTypeOf(LVT_Nil)) { if (!hasKey(k)) { LuaValue f = m_metaTable->get(LuaValue("__newindex")); if (f.isTypeOf(LVT_Nil)) {} else if (f.isTypeOf(LVT_Table)) { f.getTable()->set(k, v); return; } else if (f.isTypeOf(LVT_Function)) { vector<LuaValue> args, rets; addRef(); args.push_back(LuaValue(this)); args.push_back(k); args.push_back(v); f.getFunction()->call(args, rets); return; } else ASSERT(0); } } if (k.isTypeOf(LVT_Number)) { int idx = (int)k.getNumber() - 1; if (idx >= 0 && idx < (int)m_vec.size()) { m_vec[idx] = v; return; } if (idx == (int)m_vec.size()) { m_vec.push_back(v); return; } } if (v.isTypeOf(LVT_Nil)) { m_hashTable.erase(k); } else m_hashTable[k] = v; return; }
int luaL_ref(LuaThread* L) { LuaTable* registry = L->l_G->getRegistry(); LuaValue val = L->stack_.top_[-1]; L->stack_.pop(); if(val.isNil()) return LUA_REFNIL; LuaValue ref1 = registry->get(LuaValue(freelist)); int ref = ref1.isInteger() ? ref1.getInteger() : 0; if (ref != 0) { // any free element? LuaValue temp = registry->get( LuaValue(ref) ); registry->set( LuaValue(freelist), temp ); registry->set( LuaValue(ref), val ); return ref; } else { // no free elements, get a new reference. ref = (int)registry->getLength() + 1; registry->set( LuaValue(ref), val ); return ref; } }
static void buildin_collectgarbage(const vector<LuaValue>& args, vector<LuaValue>& rets) { auto mgr = LuaVM::instance()->getGCObjManager(); int oldObjCount = mgr->getObjCount(); mgr->performFullGC(); int newObjCount = mgr->getObjCount(); rets.push_back(LuaValue(oldObjCount)); rets.push_back(LuaValue(newObjCount)); }
static LuaValue invokeMeta(LuaTable* table, LuaTable *metaTable, const char* metaName, const LuaValue& arg1, const LuaValue& arg2) { LuaValue f = metaTable->get(LuaValue(metaName)); vector<LuaValue> args, rets; table->addRef(); args.push_back(LuaValue(table)); args.push_back(arg1); args.push_back(arg2); f.getFunction()->call(args, rets); return rets.empty() ? LuaValue::NIL : rets[0]; }
void LuaTable::meta_call(const vector<LuaValue>& args, vector<LuaValue>& rets) { LuaValue f = m_metaTable->get(LuaValue("__call")); vector<LuaValue> _args; addRef(); _args.push_back(LuaValue(this)); _args.insert(_args.end(), args.begin(), args.end()); f.getFunction()->call(_args, rets); }
static void buildin_loadfile(const vector<LuaValue>& args, vector<LuaValue>& rets) { try { auto func = loadFile(args[0].getString()); func->addRef(); rets.push_back(LuaValue(func.get())); } catch(const exception& e) { rets.push_back(LuaValue::NIL); rets.push_back(LuaValue(e.what())); } }
void luaL_unref(LuaThread* L, int ref) { THREAD_CHECK(L); if(ref >= 0) { LuaTable* registry = L->l_G->getRegistry(); LuaValue a = registry->get( LuaValue(freelist) ); registry->set( LuaValue(ref), a ); registry->set( LuaValue(freelist), LuaValue(ref) ); } }
static void buildin_loadstring(const vector<LuaValue>& args, vector<LuaValue>& rets) { FILE *f = tmpfile(); try { fprintf(f, "%s", args[0].getString()); rewind(f); auto func = loadFile(f); fclose(f); func->addRef(); rets.push_back(LuaValue(func.get())); } catch(const exception& e) { fclose(f); rets.push_back(LuaValue::NIL); rets.push_back(LuaValue(e.what())); } }
void net_recv_game_init_data(SerializeBuffer& sb, int sender, GameStateInitData& init_data, PlayerData& pd) { //Write seed sb.read(init_data); init_data.received_init_data = true; //Read player data int localidx; sb.read_int(localidx); int playern; sb.read_int(playern); LANARTS_ASSERT(pd.all_players().empty()); for (int i = 0; i < playern; i++) { std::string name; std::string classtype; int net_id; sb.read(name); sb.read(classtype); sb.read_int(net_id); pd.register_player(name, NULL, classtype, LuaValue(), (i == localidx), net_id); } printf( "Received init packet: seed = 0x%X, localid = %d, nplayers = %d, " "frame_action_repeat = %d, regen_level_on_death = %d, network_debug_mode = %d, time_per_step = %f\n", init_data.seed, localidx, playern, init_data.frame_action_repeat, (int) init_data.regen_on_death, (int) init_data.network_debug_mode, init_data.time_per_step); }
void LuaValue::concatFrom(const LuaValue& l, const LuaValue& r) { if (l.isTypeOf(LVT_String)) { auto str1 = l.getString(), str2 = r.getString(); int nsize = str1->size() + str2->size(); vector<char> buf(nsize); if (nsize > 0) { memcpy(&buf[0], str1->buf(), str1->size()); memcpy(&buf[0] + str1->size(), str2->buf(), str2->size()); *this = LuaValue(&buf[0], nsize); } else { *this = LuaValue("", 0); } } else { *this = meta_concat(l.getTable(), r); } }
static void buildin_loadfile(const vector<LuaValue>& args, vector<LuaValue>& rets) { try { rets.push_back(loadFile(args[0].getString()->buf())); } catch(const exception& e) { rets.push_back(LuaValue::NIL); rets.push_back(LuaValue(e.what())); } }
static void buildin_getmetatable(const vector<LuaValue>& args, vector<LuaValue>& rets) { auto table = args[0].getTable()->getMetaTable(); if (table == NULL) rets.push_back(LuaValue::NIL); else { table->addRef(); rets.push_back(LuaValue(table)); } }
// - LuaState::call --------------------------------------------------------- LuaValueList LuaState::call (LuaFunction& func, const LuaValueList& params, const std::string& chunkName) { func.setReaderFlag (false); PushLuaValue (state_, LuaValue (func)); return Impl::CallFunctionOnTop (state_, params); }
void LuaLazyValue::initialize(const LuaValue& value) { if (value.empty() || value.isnil()) { _value = LuaValue(); } else { _value = value; } _expression = std::string(); }
const LuaValue& LuaTable::getINext(LuaValue& k) const { if (k.isTypeOf(LVT_Nil)) { if (!m_vec.empty()) { k = LuaValue(NumberType(1)); return m_vec.front(); } return LuaValue::NIL; } else { int idx = (int)k.getNumber(); if (idx >= 0 && idx < (int)m_vec.size()) { k = LuaValue(NumberType(idx + 1)); return m_vec[idx]; } k = LuaValue::NIL; return LuaValue::NIL; } }
void EquipmentEntry::parse_lua_table(const LuaValue& table) { ItemEntry::parse_lua_table(table); if (type == EquipmentEntry::NONE) { type = name2type(table["type"].to_str()); } stackable = false; use_action = LuaAction(LuaValue()); stat_modifiers = parse_stat_modifiers(table); cooldown_modifiers = parse_cooldown_modifiers(table); }
static void collectvalidlines (LuaThread *L, LuaClosure *f) { THREAD_CHECK(L); if (f == NULL || f->isC) { LuaResult result = L->stack_.push_reserve2(LuaValue::Nil()); handleResult(result); } else { LuaTable* t = new LuaTable(); /* new table to store active lines */ LuaResult result = L->stack_.push_reserve2(LuaValue(t)); handleResult(result); LuaValue v = LuaValue(true); for (int i = 0; i < (int)f->proto_->lineinfo.size(); i++) { /* for all lines with code */ LuaValue key(f->proto_->lineinfo[i]); t->set(key, v); /* table[line] = true */ } } }
static void buildin_disassemble(const vector<LuaValue>& args, vector<LuaValue>& rets) { Function* func = NULL; if (args.empty()) func = LuaVM::instance()->getCurrentStack()->topFrame(-1)->func; else if (args[0].isTypeOf(LVT_Number)) { auto n = (int)args[0].getNumber(); ASSERT(n >= 0); if (n > 0) func = LuaVM::instance()->getCurrentStack()->topFrame(-n)->func; } else { func = args[0].getFunction(); } if (func != NULL && func->funcType == Function::FT_Lua) { ostringstream so; disassemble(so, static_cast<LuaFunction*>(func)->meta.get()); rets.push_back(LuaValue(so.str().c_str())); } else { rets.push_back(LuaValue("invalid function")); } }
static void buildin_pcall(const vector<LuaValue>& args, vector<LuaValue>& rets) { try { vector<LuaValue> _args(args.begin() + 1, args.end()); callFunc(args[0], _args, rets); rets.insert(rets.begin(), LuaValue::TRUE); } catch(const exception& e) { rets.push_back(LuaValue::FALSE); rets.push_back(LuaValue(e.what())); } }
int luaopen_os (LuaThread *L) { THREAD_CHECK(L); LuaTable* lib = new LuaTable(); for(const luaL_Reg* cursor = syslib; cursor->name; cursor++) { lib->set( cursor->name, LuaValue(cursor->func) ); } L->stack_.push(lib); return 1; }
// Only the server is concerned with this message void net_recv_connection_affirm(SerializeBuffer& sb, int sender, PlayerData& pd) { printf("Recv conn with size=%d\n", sb.size()); std::string name; std::string classtype; sb.read(name); sb.read(classtype); printf("connection affirm read\n"); pd.register_player(name, NULL, classtype, LuaValue(), /* is local player */ false, sender); printf("now there are %d players\n", (int) pd.all_players().size()); }
static void buildin_select(const vector<LuaValue>& args, vector<LuaValue>& rets) { auto &index = args[0]; if (index.isTypeOf(LVT_String) && index.toString() == "#") { rets.push_back(LuaValue(NumberType(args.size() - 1))); } else if (index.isTypeOf(LVT_Number)) { for (int i = (int)index.getNumber(); i < (int)args.size(); ++i) { rets.push_back(args[i]); } } else ASSERT(0); }
static void buildin_type(const vector<LuaValue>& args, vector<LuaValue>& rets) { switch (args[0].getType()) { case LVT_Nil: rets.push_back(LuaValue("nil")); break; case LVT_Boolean: rets.push_back(LuaValue("boolean")); break; case LVT_Number: rets.push_back(LuaValue("number")); break; case LVT_String: rets.push_back(LuaValue("string")); break; case LVT_Table: rets.push_back(LuaValue("table")); break; case LVT_Function: rets.push_back(LuaValue("function")); break; case LVT_LightUserData: rets.push_back(LuaValue("lightuserdata")); break; default: ASSERT(0); break; } }
static void buildin_tonumber(const vector<LuaValue>& args, vector<LuaValue>& rets) { auto &v = args[0]; if (v.isTypeOf(LVT_Number)) rets.push_back(v); else if (v.isTypeOf(LVT_String)) { int base = 10; if (args.size() > 1) base = (int)args[1].getNumber(); NumberType n = 0; for (const char *str = v.getString()->buf(); *str; ++str) { n *= base; n += char2Int(*str); } rets.push_back(LuaValue(n)); } else rets.push_back(LuaValue::NIL); }
const LuaValue& LuaTable::getNext(LuaValue& k) const { if (k.isTypeOf(LVT_Nil)) { if (!m_vec.empty()) { k = LuaValue(NumberType(1)); return m_vec.front(); } if (!m_hashTable.empty()) { auto iter = m_hashTable.begin(); k = iter->first; return iter->second; } } else { if (k.isTypeOf(LVT_Number)) { int idx = (int)k.getNumber(); if (idx >= 0 && idx < (int)m_vec.size()) { k = LuaValue(NumberType(idx + 1)); return m_vec[idx]; } if (idx == (int)m_vec.size() && !m_hashTable.empty()) { auto iter = m_hashTable.begin(); k = iter->first; return iter->second; } } auto iter = m_hashTable.find(k); if (iter != m_hashTable.end()) { ++iter; if (iter != m_hashTable.end()) { k = iter->first; return iter->second; } } } k = LuaValue::NIL; return LuaValue::NIL; }
static void buildin_getfenv(const vector<LuaValue>& args, vector<LuaValue>& rets) { IFunction *func = NULL; if (args.empty()) func = Runtime::instance()->getFrame(-2)->getFunc(); else if (args[0].isTypeOf(LVT_Number)) { auto n = (int)args[0].getNumber(); ASSERT(n >= 0); if (n > 0) func = Runtime::instance()->getFrame(-n - 1)->getFunc(); } else func = args[0].getFunction(); LuaTable* table = NULL; if (func == NULL) table = Runtime::instance()->getGlobalTable(); else table = func->getfenv(); table->addRef(); rets.push_back(LuaValue(table)); }
void EffectStats::step(GameState* gs, CombatGameInst* inst) { lua_State* L = gs->get_luastate(); for (int i = 0; i < EFFECTS_MAX; i++) { if (effects[i].t_remaining > 0) { EffectEntry& eentry = game_effect_data.at(effects[i].effectid); effects[i].t_remaining--; effects[i].state.table_set_number(L, "time_left", effects[i].t_remaining); lua_effect_func_callback(L, eentry.step_func, effects[i], inst); effects[i].state.table_get_number(L, "time_left", effects[i].t_remaining); if (effects[i].t_remaining == 0) { lua_effect_func_callback(L, eentry.finish_func, effects[i], inst); effects[i].state = LuaValue(); } } } }
static void buildin_getfenv(const vector<LuaValue>& args, vector<LuaValue>& rets) { Function* func = NULL; if (args.empty()) func = LuaVM::instance()->getCurrentStack()->topFrame(-1)->func; else if (args[0].isTypeOf(LVT_Number)) { auto n = (int)args[0].getNumber(); ASSERT(n >= 0); if (n > 0) func = LuaVM::instance()->getCurrentStack()->topFrame(-n)->func; } else { func = args[0].getFunction(); } LuaTable* table = NULL; if (func == NULL) table = LuaVM::instance()->getGlobalTable(); else { ASSERT(func->funcType == Function::FT_Lua); table = static_cast<LuaFunction*>(func)->fenvTable; } rets.push_back(LuaValue(table)); }
LuaValue EffectStats::add(GameState* gs, CombatGameInst* inst, effect_id effect, int length) { lua_State* L = gs->get_luastate(); for (int i = 0; i < EFFECTS_MAX; i++) { if (effects[i].t_remaining == 0 || effects[i].effectid == effect) { effects[i].effectid = effect; effects[i].t_remaining = std::max(effects[i].t_remaining, length); if (effects[i].state.empty()) { lua_init_effect(L, effects[i].state, effect); } effects[i].state.table_set_number(L, "time_left", effects[i].t_remaining); EffectEntry& eentry = game_effect_data.at(effects[i].effectid); lua_effect_func_callback(L, eentry.init_func, effects[i], inst); return effects[i].state; } } return LuaValue(); }