Add has_policy<> and remove has_yield<>.
[luabind.git] / src / class_registry.cpp
blob79df30ade5525f9279fa0eaf2dc09e96711864f4
1 // Copyright (c) 2004 Daniel Wallin
3 // Permission is hereby granted, free of charge, to any person obtaining a
4 // copy of this software and associated documentation files (the "Software"),
5 // to deal in the Software without restriction, including without limitation
6 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
7 // and/or sell copies of the Software, and to permit persons to whom the
8 // Software is furnished to do so, subject to the following conditions:
10 // The above copyright notice and this permission notice shall be included
11 // in all copies or substantial portions of the Software.
13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
14 // ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
15 // TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
16 // PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
17 // SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
18 // ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
19 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
21 // OR OTHER DEALINGS IN THE SOFTWARE.
23 #define LUABIND_BUILDING
25 #include <luabind/lua_include.hpp>
27 #include <luabind/luabind.hpp>
28 #include <luabind/detail/class_registry.hpp>
29 #include <luabind/detail/class_rep.hpp>
30 #include <luabind/detail/operator_id.hpp>
32 namespace luabind { namespace detail {
34 LUABIND_API void push_instance_metatable(lua_State* L);
36 namespace {
38 int create_cpp_class_metatable(lua_State* L)
40 lua_newtable(L);
42 // mark the table with our (hopefully) unique tag
43 // that says that the user data that has this
44 // metatable is a class_rep
45 lua_pushstring(L, "__luabind_classrep");
46 lua_pushboolean(L, 1);
47 lua_rawset(L, -3);
49 lua_pushstring(L, "__gc");
50 lua_pushcclosure(
52 , &garbage_collector_s<
53 detail::class_rep
54 >::apply
55 , 0);
57 lua_rawset(L, -3);
59 lua_pushstring(L, "__call");
60 lua_pushcclosure(L, &class_rep::constructor_dispatcher, 0);
61 lua_rawset(L, -3);
63 lua_pushstring(L, "__index");
64 lua_pushcclosure(L, &class_rep::static_class_gettable, 0);
65 lua_rawset(L, -3);
67 lua_pushstring(L, "__newindex");
68 lua_pushcclosure(L, &class_rep::lua_settable_dispatcher, 0);
69 lua_rawset(L, -3);
71 return luaL_ref(L, LUA_REGISTRYINDEX);
74 int create_lua_class_metatable(lua_State* L)
76 lua_newtable(L);
78 lua_pushstring(L, "__luabind_classrep");
79 lua_pushboolean(L, 1);
80 lua_rawset(L, -3);
82 lua_pushstring(L, "__gc");
83 lua_pushcclosure(
85 , &detail::garbage_collector_s<
86 detail::class_rep
87 >::apply
88 , 0);
90 lua_rawset(L, -3);
92 lua_pushstring(L, "__newindex");
93 lua_pushcclosure(L, &class_rep::lua_settable_dispatcher, 0);
94 lua_rawset(L, -3);
96 lua_pushstring(L, "__call");
97 lua_pushcclosure(L, &class_rep::constructor_dispatcher, 0);
98 lua_rawset(L, -3);
100 lua_pushstring(L, "__index");
101 lua_pushcclosure(L, &class_rep::static_class_gettable, 0);
102 lua_rawset(L, -3);
104 return luaL_ref(L, LUA_REGISTRYINDEX);
107 } // namespace unnamed
109 class class_rep;
111 class_registry::class_registry(lua_State* L)
112 : m_cpp_class_metatable(create_cpp_class_metatable(L))
113 , m_lua_class_metatable(create_lua_class_metatable(L))
115 push_instance_metatable(L);
116 m_instance_metatable = luaL_ref(L, LUA_REGISTRYINDEX);
119 class_registry* class_registry::get_registry(lua_State* L)
122 #ifdef LUABIND_NOT_THREADSAFE
124 // if we don't have to be thread safe, we can keep a
125 // chache of the class_registry pointer without the
126 // need of a mutex
127 static lua_State* cache_key = 0;
128 static class_registry* registry_cache = 0;
129 if (cache_key == L) return registry_cache;
131 #endif
133 lua_pushstring(L, "__luabind_classes");
134 lua_gettable(L, LUA_REGISTRYINDEX);
135 class_registry* p = static_cast<class_registry*>(lua_touserdata(L, -1));
136 lua_pop(L, 1);
138 #ifdef LUABIND_NOT_THREADSAFE
140 cache_key = L;
141 registry_cache = p;
143 #endif
145 return p;
148 void class_registry::add_class(type_id const& info, class_rep* crep)
150 // class is already registered
151 assert((m_classes.find(info) == m_classes.end())
152 && "you are trying to register a class twice");
153 m_classes[info] = crep;
156 class_rep* class_registry::find_class(type_id const& info) const
158 std::map<type_id, class_rep*>::const_iterator i(
159 m_classes.find(info));
161 if (i == m_classes.end()) return 0; // the type is not registered
162 return i->second;
165 }} // namespace luabind::detail