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; }
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; }
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); }
void LuaTable::sort(const LuaValue& cmp) { auto func = cmp.getFunction(); vector<LuaValue> args, rets; std::sort(m_vec.begin(), m_vec.end(), [func, &args, &rets](const LuaValue& a, const LuaValue& b){ args.push_back(a); args.push_back(b); func->call(args, rets); bool r = rets[0].getBoolean(); args.clear(); rets.clear(); return r; }); }