fixed vc7.1 issues
[luabind.git] / luabind / scope.hpp
blob003e0717bc9d60b4521291884540de1539123629
1 #ifndef LUABIND_SCOPE_HPP_INCLUDED
2 #define LUABIND_SCOPE_HPP_INCLUDED
4 #include <vector>
5 #include <string>
6 #include <stack>
8 #include <luabind/detail/ref.hpp>
10 namespace luabind
12 namespace detail
14 struct scoped_sequence;
16 struct scoped_object
18 scoped_object()
22 virtual ~scoped_object() {}
24 virtual void commit(lua_State*) const = 0;
25 virtual scoped_object* clone() const = 0;
27 scoped_sequence operator,(const scoped_object& rhs) const;
30 struct scoped_sequence : scoped_object
32 scoped_sequence(scoped_object* a, scoped_object* b)
34 this->objects.push_back(a);
35 this->objects.push_back(b);
38 scoped_sequence() {}
40 virtual ~scoped_sequence()
42 for (std::vector<scoped_object*>
43 ::const_iterator i = this->objects.begin()
44 ; i != this->objects.end()
45 ; ++i)
47 scoped_object* ptr = *i;
48 delete ptr;
52 scoped_sequence& operator,(const scoped_object& rhs)
54 objects.push_back(rhs.clone());
55 return *this;
58 virtual scoped_object* clone() const
60 scoped_sequence* copy = new scoped_sequence();
61 copy->objects.swap(this->objects);
62 return copy;
65 virtual void commit(lua_State* L) const
67 for (std::vector<scoped_object*>
68 ::const_iterator i = this->objects.begin()
69 ; i != this->objects.end()
70 ; ++i)
72 scoped_object* ptr = *i;
73 ptr->commit(L);
77 mutable std::vector<scoped_object*> objects;
80 inline scoped_sequence scoped_object::operator,(const scoped_object& rhs) const
82 return scoped_sequence(this->clone(), rhs.clone());
86 def(..),
87 def(..)
89 function_obj1, function_obj2
90 function_obj1.push_back(function_obj2.doclone());
92 struct scope_stack
94 std::stack<int> scopes;
96 static int gc(lua_State* L)
98 scope_stack* scopes = static_cast<scope_stack*>(
99 lua_touserdata(L, -1)
102 assert(scopes->scopes.size() == 1);
104 int top = scopes->scopes.top();
105 scopes->scopes.pop();
107 detail::unref(L, top);
109 scopes->~scope_stack();
111 return 0;
114 static int top(lua_State* L)
116 lua_pushstring(L, "__luabind_scope_stack");
117 lua_gettable(L, LUA_REGISTRYINDEX);
119 scope_stack* scopes = static_cast<scope_stack*>(
120 lua_touserdata(L, -1)
123 lua_pop(L, 1);
125 return scopes->scopes.top();
128 static void push(lua_State* L)
130 lua_pushstring(L, "__luabind_scope_stack");
131 lua_gettable(L, LUA_REGISTRYINDEX);
133 scope_stack* scopes = static_cast<scope_stack*>(
134 lua_touserdata(L, -1)
137 lua_pop(L, 1);
139 return scopes->scopes.push(detail::ref(L));
142 static void pop(lua_State* L)
144 lua_pushstring(L, "__luabind_scope_stack");
145 lua_gettable(L, LUA_REGISTRYINDEX);
147 scope_stack* scopes = static_cast<scope_stack*>(
148 lua_touserdata(L, -1)
151 lua_pop(L, 1);
153 int n = scopes->scopes.top();
154 scopes->scopes.pop();
155 detail::unref(L, n);
159 class scope : public detail::scoped_object
161 public:
163 static void init(lua_State* L)
165 lua_pushstring(L, "__luabind_scope_stack");
166 lua_gettable(L, LUA_REGISTRYINDEX);
168 scope_stack* scopes = static_cast<scope_stack*>(
169 lua_touserdata(L, -1)
172 lua_pop(L, 1);
174 if (scopes == 0)
176 scopes = static_cast<scope_stack*>(
177 lua_newuserdata(L, sizeof(scope_stack))
180 lua_pushstring(L, "__luabind_scope_stack");
181 lua_pushvalue(L, -2);
182 lua_settable(L, LUA_REGISTRYINDEX);
184 new (scopes) scope_stack();
186 lua_pushvalue(L, LUA_GLOBALSINDEX);
187 scopes->scopes.push(detail::ref(L));
189 lua_newtable(L);
190 lua_pushstring(L, "__gc");
191 lua_pushcclosure(L, scope_stack::gc, 0);
192 lua_settable(L, -3);
193 lua_setmetatable(L, -2);
195 lua_pop(L, 1);
199 scope(lua_State* L, const char* name)
200 : m_state(L)
201 , m_name(name)
203 init(L);
206 scope(const char* name)
207 : m_state(0)
208 , m_name(name)
212 virtual ~scope()
214 for (std::vector<scoped_object*>
215 ::const_iterator i = m_children.begin()
216 ; i != m_children.end()
217 ; ++i)
219 scoped_object* ptr = *i;
220 delete ptr;
224 scope& operator[](const detail::scoped_object& x)
226 m_children.push_back(x.clone());
228 if (m_state)
230 this->commit(m_state);
232 for (std::vector<scoped_object*>
233 ::const_iterator i = m_children.begin()
234 ; i != m_children.end()
235 ; ++i)
237 scoped_object* ptr = *i;
238 delete ptr;
241 m_children.clear();
244 return *this;
247 virtual detail::scoped_object* clone() const
249 std::vector<detail::scoped_object*> tmp;
250 tmp.swap(this->m_children);
251 scope* copy = new scope(*this);
252 copy->m_children.swap(tmp);
253 return copy;
256 virtual void commit(lua_State* L) const
258 init(L);
260 detail::getref(L, scope_stack::top(L)); // get current scope
261 lua_pushstring(L, m_name.c_str());
262 lua_gettable(L, -2);
263 lua_remove(L, -2); // remove scope
265 if (lua_isnil(L, -1))
267 lua_pop(L, 1);
269 lua_newtable(L);
270 detail::getref(L, scope_stack::top(L));
271 lua_pushstring(L, m_name.c_str());
272 lua_pushvalue(L, -3);
273 lua_settable(L, -3);
274 lua_pop(L, 1);
277 scope_stack::push(L);
279 for (std::vector<detail::scoped_object*>
280 ::const_iterator i = m_children.begin()
281 ; i != m_children.end()
282 ; ++i)
284 scoped_object* ptr = *i;
285 ptr->commit(L);
288 scope_stack::pop(L);
291 private:
293 mutable std::vector<scoped_object*> m_children;
294 lua_State* m_state;
295 std::string m_name;
298 typedef scope namespace_;
301 scope dwarf("dwarf");
303 dwarf
305 def(..),
306 def(..),
308 class<vec3>("vec3")
309 .def(constructor<float,float,float>())
310 .def(self + self)
311 .def(self - self)
312 .def(self == self)
315 def("getDirection", &get_direction),
316 def("getPosition", &get_position)
319 dwarf
321 def(..)
324 dwarf.commit(L);
327 #endif