Otclient  14/8/2020
luaobject.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010-2020 OTClient <https://github.com/edubart/otclient>
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to deal
6  * in the Software without restriction, including without limitation the rights
7  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8  * copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20  * THE SOFTWARE.
21  */
22 
23 #include "luaobject.h"
24 #include "luainterface.h"
25 
26 #include <typeinfo>
28 
30  m_fieldsTableRef(-1)
31 {
32 }
33 
35 {
36 #ifndef NDEBUG
37  assert(!g_app.isTerminated());
38 #endif
40 }
41 
42 bool LuaObject::hasLuaField(const std::string& field)
43 {
44  bool ret = false;
45  if(m_fieldsTableRef != -1) {
46  g_lua.getRef(m_fieldsTableRef);
47  g_lua.getField(field); // push the field value
48  ret = !g_lua.isNil();
49  g_lua.pop(2);
50  }
51  return ret;
52 }
53 
55 {
56  if(m_fieldsTableRef != -1) {
57  g_lua.unref(m_fieldsTableRef);
58  m_fieldsTableRef = -1;
59  }
60 }
61 
62 void LuaObject::luaSetField(const std::string& key)
63 {
64  // create fields table on the fly
65  if(m_fieldsTableRef == -1) {
66  g_lua.newTable(); // create fields table
67  m_fieldsTableRef = g_lua.ref(); // save a reference for it
68  }
69 
70  g_lua.getRef(m_fieldsTableRef); // push the table
71  g_lua.insert(-2); // move the value to the top
72  g_lua.setField(key); // set the field
73  g_lua.pop(); // pop the fields table
74 }
75 
76 void LuaObject::luaGetField(const std::string& key)
77 {
78  if(m_fieldsTableRef != -1) {
79  g_lua.getRef(m_fieldsTableRef); // push the obj's fields table
80  g_lua.getField(key); // push the field value
81  g_lua.remove(-2); // remove the table
82  } else {
83  g_lua.pushNil();
84  }
85 }
86 
88 {
89  static std::unordered_map<const std::type_info*, int> metatableMap;
90  const std::type_info& tinfo = typeid(*this);
91  auto it = metatableMap.find(&tinfo);
92 
93  int metatableRef;
94  if(it == metatableMap.end()) {
95  g_lua.getGlobal(getClassName() + "_mt");
96  metatableRef = g_lua.ref();
97  metatableMap[&tinfo] = metatableRef;
98  } else
99  metatableRef = it->second;
100 
101  g_lua.getRef(metatableRef);
102 }
103 
105 {
106  if(m_fieldsTableRef != -1)
107  g_lua.getRef(m_fieldsTableRef);
108  else
109  g_lua.pushNil();
110 }
111 
113 {
114  return ref_count();
115 }
116 
118 {
119  // TODO: this could be cached for more performance
120 #ifdef _MSC_VER
121  return stdext::demangle_name(typeid(*this).name()) + 6;
122 #else
123  return stdext::demangle_name(typeid(*this).name());
124 #endif
125 }
LuaInterface::insert
void insert(int index)
Definition: luainterface.cpp:819
LuaObject::luaGetMetatable
void luaGetMetatable()
Get object's metatable.
Definition: luaobject.cpp:87
LuaInterface::ref
int ref()
Definition: luainterface.cpp:756
stdext::shared_object::ref_count
refcount_t ref_count()
Definition: shared_object.h:48
LuaObject::luaGetFieldsTable
void luaGetFieldsTable()
Gets the table containing all stored fields of this lua object, the result is pushed onto the stack.
Definition: luaobject.cpp:104
luainterface.h
LuaInterface::getGlobal
void getGlobal(const std::string &key)
Definition: luainterface.cpp:939
luaobject.h
LuaObject::getClassName
std::string getClassName()
Returns the derived class name, its the same name used in Lua.
Definition: luaobject.cpp:117
LuaObject::~LuaObject
virtual ~LuaObject()
Definition: luaobject.cpp:34
LuaInterface::getField
void getField(const char *key, int index=-1)
Definition: luainterface.cpp:880
stdext::demangle_name
const char * demangle_name(const char *name)
Demangle names for GNU g++ compiler.
Definition: demangle.cpp:45
LuaObject::releaseLuaFieldsTable
void releaseLuaFieldsTable()
Release fields table reference.
Definition: luaobject.cpp:54
LuaInterface::isNil
bool isNil(int index=-1)
Definition: luainterface.cpp:1150
g_lua
LuaInterface g_lua
Definition: luainterface.cpp:31
LuaInterface::unref
void unref(int ref)
Definition: luainterface.cpp:786
LuaObject::luaSetField
void luaSetField(const std::string &key)
Sets a field from this lua object, the value must be on the stack.
Definition: luaobject.cpp:62
LuaObject::luaGetField
void luaGetField(const std::string &key)
Gets a field from this lua object, the result is pushed onto the stack.
Definition: luaobject.cpp:76
LuaObject::getUseCount
int getUseCount()
Definition: luaobject.cpp:112
g_app
ConsoleApplication g_app
Definition: consoleapplication.cpp:32
LuaInterface::pop
void pop(int n=1)
Definition: luainterface.cpp:999
LuaInterface::setField
void setField(const char *key, int index=-2)
Definition: luainterface.cpp:887
LuaObject::hasLuaField
bool hasLuaField(const std::string &field)
Returns true if the lua field exists.
Definition: luaobject.cpp:42
Application::isTerminated
bool isTerminated()
Definition: application.h:50
LuaInterface::pushNil
void pushNil()
Definition: luainterface.cpp:1060
LuaInterface::getRef
void getRef(int ref)
Definition: luainterface.cpp:846
LuaInterface::remove
void remove(int index)
Definition: luainterface.cpp:825
LuaObject::LuaObject
LuaObject()
Definition: luaobject.cpp:29
application.h
LuaInterface::newTable
void newTable()
Definition: luainterface.cpp:984