#include "cl_smoke.h" #include "smokebinding.h" #include #include /** @file * @brief C wrapper the Smoke bindings. */ using namespace cl_smoke; extern "C" { /** Creates a new Smoke binding. * The binding is allocated on the heap an can be freed with smoke_destruct(). * When method dispatching is not needed, a null pointer can be passed for @a dispatch. * @related cl_smoke::Binding * @related cl_smoke::NoDispatchBinding * @related cl_smoke_destruct_binding * @param smoke pointer to a Smoke module instance * @param destruct callback for object destruction * @param dispatch method dispatch callback * * @return a pointer to a new Smoke binding. */ CL_SMOKE_EXPORT smoke_binding cl_smoke_construct_binding(void* destruct, void* dispatch) { if (NULL == dispatch) return new NoDispatchBinding(reinterpret_cast(destruct)); else return new Binding(reinterpret_cast(destruct), reinterpret_cast(dispatch)); } /** Deletes the Smoke binding. * @related cl_smoke_construct_binding */ CL_SMOKE_EXPORT void cl_smoke_destruct_binding(smoke_binding binding) { // Destructor is virtual; thus we can do this. delete static_cast(binding); } /** Gets a Smoke module name. * @param smoke the Smoke module * * @return the module name */ CL_SMOKE_EXPORT const char* cl_smoke_get_module_name(void* smoke) { return get_smoke(smoke)->moduleName(); } /** Returns the pointer to the array @a array of @a smoke. * @param smoke the Smoke module * @param array the array type * * @return a pointer to the array */ CL_SMOKE_EXPORT void* cl_smoke_array(void* smoke, cl_smoke_module_array array) { switch (array) { case classes: return get_smoke(smoke)->classes; case methods: return get_smoke(smoke)->methods; case method_maps: return get_smoke(smoke)->methodMaps; case method_names: return get_smoke(smoke)->methodNames; case types: return get_smoke(smoke)->types; case inheritance_list: return get_smoke(smoke)->inheritanceList; case argument_list: return get_smoke(smoke)->argumentList; case ambiguous_method_list: return get_smoke(smoke)->ambiguousMethodList; } qFatal("cl_smoke_array(): Unknown smoke_array %d", array); } /** Returns the size of the array @a array of @a smoke. * The size if inclusive the bound. * @param smoke the Smoke module * @param array the array type * * @return the size */ CL_SMOKE_EXPORT Smoke::Index cl_smoke_array_size(void* smoke, cl_smoke_module_array array) { switch (array) { case classes: return get_smoke(smoke)->numClasses; case methods: return get_smoke(smoke)->numMethods; case method_maps: return get_smoke(smoke)->numMethodMaps; case method_names: return get_smoke(smoke)->numMethodNames; case types: return get_smoke(smoke)->numTypes; case inheritance_list: case argument_list: case ambiguous_method_list: qFatal("cl_smoke_array_size(): size of %d not known.", array); } qFatal("cl_smoke_array_size(): Unknown smoke_array %d.", array); } /////////////////////////// /// Class /////////////////////////// /** Finds a class. * @param c pointer to write the result to * @param name the name of the class */ CL_SMOKE_EXPORT void cl_smoke_find_class(Smoke::ModuleIndex* c, const char* name) { *c = Smoke::findClass(name); } /** Gets the class ID for a Smoke module. * @param smoke the Smoke module * @param name the class name * * @return the class ID in the supplied Smoke module */ CL_SMOKE_EXPORT Smoke::Index cl_smoke_class_id(void* smoke, const char* name) { Smoke::ModuleIndex m = get_smoke(smoke)->idClass(name, true); Q_ASSERT(m.smoke == smoke); return m.index; } /** Gets a class * @param smoke the smoke binding * @param class_index the index of the class * * @return A pointer to the class into the array of class structs */ CL_SMOKE_EXPORT const struct Smoke::Class* cl_smoke_get_class(void* smoke, Smoke::Index class_index) { Q_ASSERT(class_index >= 0 && class_index <= get_smoke(smoke)->numClasses); return &get_smoke(smoke)->classes[class_index]; } /** Determines werter a class is from a base class. * @param smoke the Smoke module of @a class_index * @param class_index the class index * @param smoke_base the Smoke module of the base class @a base_index * @param base_index the index of the base class * * @return Returns 0 when the class is not derived from the base class and nonzero value otherwise. */ CL_SMOKE_EXPORT int cl_smoke_is_derived_from(void* smoke, Smoke::Index class_index, void* smoke_base, Smoke::Index base_index) { Q_ASSERT(!cl_smoke_get_class(smoke, class_index)->external); Q_ASSERT(!cl_smoke_get_class(smoke_base, base_index)->external); return Smoke::isDerivedFrom(get_smoke(smoke), class_index, get_smoke(smoke_base), base_index); } ////////////////////////////// /// Method ////////////////////////////// /** Finds a method of a class. * @param m pointer to write the result to * @param smoke the smoke module * @param class_index index of the class * @param method_name method name */ CL_SMOKE_EXPORT void cl_smoke_find_method(Smoke::ModuleIndex* m, void* smoke, Smoke::Index class_index, const char* method_name) { Q_ASSERT(class_index >= 0 && class_index <= get_smoke(smoke)->numClasses); const char* class_name = get_smoke(smoke)->className(class_index); Smoke::ModuleIndex id_class(get_smoke(smoke), class_index); Smoke::ModuleIndex id_method_name = get_smoke(smoke)->findMethodName(class_name, method_name); *m = get_smoke(smoke)->findMethod(id_class, id_method_name); if(m->index > 0) m->index = m->smoke->methodMaps[m->index].method; } /////////////////////////// /// Type ////////////////////////// /** Gets the index of a type. * @param smoke the Smoke module * @param name the types name * * @return the index of the type */ CL_SMOKE_EXPORT Smoke::Index cl_smoke_find_type(void* smoke, const char* name) { return get_smoke(smoke)->idType(name); } /** Casts an object. * @param smoke the Smoke module * @param object the object * @param from the class index of @a object * @param to the class index to cast to * * @return the casted object */ CL_SMOKE_EXPORT void* cl_smoke_cast(void* smoke, void* object, Smoke::Index from, Smoke::Index to) { Q_ASSERT(from > 0 && from <= get_smoke(smoke)->numClasses); Q_ASSERT(to > 0 && to <= get_smoke(smoke)->numClasses); return get_smoke(smoke)->cast(object, from, to); } } // extern "C"