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
);
38 int create_cpp_class_metatable(lua_State
* 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);
49 lua_pushstring(L
, "__gc");
52 , &garbage_collector_s
<
59 lua_pushstring(L
, "__call");
60 lua_pushcclosure(L
, &class_rep::constructor_dispatcher
, 0);
63 lua_pushstring(L
, "__index");
64 lua_pushcclosure(L
, &class_rep::static_class_gettable
, 0);
67 lua_pushstring(L
, "__newindex");
68 lua_pushcclosure(L
, &class_rep::lua_settable_dispatcher
, 0);
71 return luaL_ref(L
, LUA_REGISTRYINDEX
);
74 int create_lua_class_metatable(lua_State
* L
)
78 lua_pushstring(L
, "__luabind_classrep");
79 lua_pushboolean(L
, 1);
82 lua_pushstring(L
, "__gc");
85 , &detail::garbage_collector_s
<
92 lua_pushstring(L
, "__newindex");
93 lua_pushcclosure(L
, &class_rep::lua_settable_dispatcher
, 0);
96 lua_pushstring(L
, "__call");
97 lua_pushcclosure(L
, &class_rep::constructor_dispatcher
, 0);
100 lua_pushstring(L
, "__index");
101 lua_pushcclosure(L
, &class_rep::static_class_gettable
, 0);
104 return luaL_ref(L
, LUA_REGISTRYINDEX
);
107 } // namespace unnamed
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
127 static lua_State
* cache_key
= 0;
128 static class_registry
* registry_cache
= 0;
129 if (cache_key
== L
) return registry_cache
;
133 lua_pushstring(L
, "__luabind_classes");
134 lua_gettable(L
, LUA_REGISTRYINDEX
);
135 class_registry
* p
= static_cast<class_registry
*>(lua_touserdata(L
, -1));
138 #ifdef LUABIND_NOT_THREADSAFE
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
165 }} // namespace luabind::detail