/ src / libsmoke /
src/libsmoke/smoke.cpp
1 #include "cl_smoke.h"
2 #include "smokebinding.h"
3
4 #include <smoke.h>
5 #include <QtGlobal>
6
7 /** @file
8 * @brief C wrapper the Smoke bindings.
9 */
10
11 using namespace cl_smoke;
12
13 extern "C" {
14
15 /** Creates a new Smoke binding.
16 * The binding is allocated on the heap an can be freed with smoke_destruct().
17 * When method dispatching is not needed, a null pointer can be passed for @a dispatch.
18 * @related cl_smoke::Binding
19 * @related cl_smoke::NoDispatchBinding
20 * @related cl_smoke_destruct_binding
21 * @param smoke pointer to a Smoke module instance
22 * @param destruct callback for object destruction
23 * @param dispatch method dispatch callback
24 *
25 * @return a pointer to a new Smoke binding.
26 */
27 CL_SMOKE_EXPORT smoke_binding
28 cl_smoke_construct_binding(void* destruct, void* dispatch)
29 {
30 if (NULL == dispatch)
31 return new NoDispatchBinding(reinterpret_cast<NoDispatchBinding::destructed>(destruct));
32 else
33 return new Binding(reinterpret_cast<NoDispatchBinding::destructed>(destruct),
34 reinterpret_cast<Binding::dispatch_method>(dispatch));
35 }
36
37 /** Deletes the Smoke binding.
38 * @related cl_smoke_construct_binding
39 */
40 CL_SMOKE_EXPORT void
41 cl_smoke_destruct_binding(smoke_binding binding)
42 {
43 // Destructor is virtual; thus we can do this.
44 delete static_cast<SmokeBinding*>(binding);
45 }
46
47 /** Gets a Smoke module name.
48 * @param smoke the Smoke module
49 *
50 * @return the module name
51 */
52 CL_SMOKE_EXPORT const char*
53 cl_smoke_get_module_name(void* smoke)
54 {
55 return get_smoke(smoke)->moduleName();
56 }
57
58
59 /** Returns the pointer to the array @a array of @a smoke.
60 * @param smoke the Smoke module
61 * @param array the array type
62 *
63 * @return a pointer to the array
64 */
65 CL_SMOKE_EXPORT void*
66 cl_smoke_array(void* smoke, cl_smoke_module_array array)
67 {
68 switch (array)
69 {
70 case classes:
71 return get_smoke(smoke)->classes;
72 case methods:
73 return get_smoke(smoke)->methods;
74 case method_maps:
75 return get_smoke(smoke)->methodMaps;
76 case method_names:
77 return get_smoke(smoke)->methodNames;
78 case types:
79 return get_smoke(smoke)->types;
80 case inheritance_list:
81 return get_smoke(smoke)->inheritanceList;
82 case argument_list:
83 return get_smoke(smoke)->argumentList;
84 case ambiguous_method_list:
85 return get_smoke(smoke)->ambiguousMethodList;
86 }
87 qFatal("cl_smoke_array(): Unknown smoke_array %d", array);
88 }
89
90 /** Returns the size of the array @a array of @a smoke.
91 * The size if inclusive the bound.
92 * @param smoke the Smoke module
93 * @param array the array type
94 *
95 * @return the size
96 */
97 CL_SMOKE_EXPORT Smoke::Index
98 cl_smoke_array_size(void* smoke, cl_smoke_module_array array)
99 {
100 switch (array)
101 {
102 case classes:
103 return get_smoke(smoke)->numClasses;
104 case methods:
105 return get_smoke(smoke)->numMethods;
106 case method_maps:
107 return get_smoke(smoke)->numMethodMaps;
108 case method_names:
109 return get_smoke(smoke)->numMethodNames;
110 case types:
111 return get_smoke(smoke)->numTypes;
112 case inheritance_list:
113 case argument_list:
114 case ambiguous_method_list:
115 qFatal("cl_smoke_array_size(): size of %d not known.", array);
116 }
117 qFatal("cl_smoke_array_size(): Unknown smoke_array %d.", array);
118 }
119
120 ///////////////////////////
121 /// Class
122 ///////////////////////////
123
124 /** Finds a class.
125 * @param c pointer to write the result to
126 * @param name the name of the class
127 */
128 CL_SMOKE_EXPORT void
129 cl_smoke_find_class(Smoke::ModuleIndex* c, const char* name)
130 {
131 *c = Smoke::findClass(name);
132 }
133
134 /** Gets the class ID for a Smoke module.
135 * @param smoke the Smoke module
136 * @param name the class name
137 *
138 * @return the class ID in the supplied Smoke module
139 */
140 CL_SMOKE_EXPORT Smoke::Index
141 cl_smoke_class_id(void* smoke, const char* name)
142 {
143 Smoke::ModuleIndex m = get_smoke(smoke)->idClass(name, true);
144 Q_ASSERT(m.smoke == smoke);
145
146 return m.index;
147 }
148
149 /** Gets a class
150 * @param smoke the smoke binding
151 * @param class_index the index of the class
152 *
153 * @return A pointer to the class into the array of class structs
154 */
155 CL_SMOKE_EXPORT const struct Smoke::Class*
156 cl_smoke_get_class(void* smoke, Smoke::Index class_index)
157 {
158 Q_ASSERT(class_index >= 0 && class_index <= get_smoke(smoke)->numClasses);
159 return &get_smoke(smoke)->classes[class_index];
160 }
161
162 /** Determines werter a class is from a base class.
163 * @param smoke the Smoke module of @a class_index
164 * @param class_index the class index
165 * @param smoke_base the Smoke module of the base class @a base_index
166 * @param base_index the index of the base class
167 *
168 * @return Returns 0 when the class is not derived from the base class and nonzero value otherwise.
169 */
170 CL_SMOKE_EXPORT int
171 cl_smoke_is_derived_from(void* smoke, Smoke::Index class_index, void* smoke_base,
172 Smoke::Index base_index)
173 {
174 Q_ASSERT(!cl_smoke_get_class(smoke, class_index)->external);
175 Q_ASSERT(!cl_smoke_get_class(smoke_base, base_index)->external);
176
177 return Smoke::isDerivedFrom(get_smoke(smoke), class_index,
178 get_smoke(smoke_base), base_index);
179 }
180
181 //////////////////////////////
182 /// Method
183 //////////////////////////////
184
185 /** Finds a method of a class.
186 * @param m pointer to write the result to
187 * @param smoke the smoke module
188 * @param class_index index of the class
189 * @param method_name method name
190 */
191 CL_SMOKE_EXPORT void
192 cl_smoke_find_method(Smoke::ModuleIndex* m, void* smoke,
193 Smoke::Index class_index, const char* method_name)
194 {
195 Q_ASSERT(class_index >= 0 && class_index <= get_smoke(smoke)->numClasses);
196
197 const char* class_name = get_smoke(smoke)->className(class_index);
198 Smoke::ModuleIndex id_class(get_smoke(smoke), class_index);
199
200 Smoke::ModuleIndex id_method_name = get_smoke(smoke)->findMethodName(class_name, method_name);
201 *m = get_smoke(smoke)->findMethod(id_class, id_method_name);
202
203 if(m->index > 0)
204 m->index = m->smoke->methodMaps[m->index].method;
205 }
206
207 ///////////////////////////
208 /// Type
209 //////////////////////////
210
211 /** Gets the index of a type.
212 * @param smoke the Smoke module
213 * @param name the types name
214 *
215 * @return the index of the type
216 */
217 CL_SMOKE_EXPORT Smoke::Index
218 cl_smoke_find_type(void* smoke, const char* name)
219 {
220 return get_smoke(smoke)->idType(name);
221 }
222
223 /** Casts an object.
224 * @param smoke the Smoke module
225 * @param object the object
226 * @param from the class index of @a object
227 * @param to the class index to cast to
228 *
229 * @return the casted object
230 */
231 CL_SMOKE_EXPORT void*
232 cl_smoke_cast(void* smoke, void* object, Smoke::Index from, Smoke::Index to)
233 {
234 Q_ASSERT(from > 0 && from <= get_smoke(smoke)->numClasses);
235 Q_ASSERT(to > 0 && to <= get_smoke(smoke)->numClasses);
236
237 return get_smoke(smoke)->cast(object, from, to);
238 }
239
240 } // extern "C"