Index: compiled/bindings.ipp |
=================================================================== |
--- a/compiled/bindings.ipp |
+++ b/compiled/bindings.ipp |
@@ -17,16 +17,17 @@ |
#pragma once |
#include <cstddef> |
#include <cstdint> |
#include <cstdio> |
#include <cstdlib> |
#include <exception> |
+#include <functional> |
#include <map> |
#include <string> |
#include <type_traits> |
#include <utility> |
#include <vector> |
#include <emscripten.h> |
@@ -331,22 +332,24 @@ namespace bindings_internal |
}; |
struct ClassInfo |
{ |
ClassInfo* baseClass; |
std::string name; |
std::vector<PropertyInfo> properties; |
std::vector<MethodInfo> methods; |
- std::vector<FunctionInfo> initializers; |
DifferentiatorInfo subclass_differentiator; |
ptrdiff_t ref_counted_offset; |
}; |
+ typedef std::function<void()> CustomGenerator; |
+ |
std::map<TYPEID, ClassInfo> classes; |
+ std::vector<CustomGenerator> customGenerators; |
void register_class(const char* name, TYPEID classID, TYPEID baseClassID, |
ptrdiff_t ref_counted_offset) |
{ |
auto it = classes.find(classID); |
if (it != classes.end()) |
throw std::runtime_error(std::string("Duplicate definition for class ") + name); |
@@ -391,25 +394,16 @@ namespace bindings_internal |
throw std::runtime_error(std::string("Method defined on unknown class: ") + name); |
MethodInfo methodInfo; |
methodInfo.name = name; |
methodInfo.call = call; |
it->second.methods.push_back(methodInfo); |
} |
- void register_initializer(TYPEID classID, const FunctionInfo& call) |
- { |
- auto it = classes.find(classID); |
- if (it == classes.end()) |
- throw std::runtime_error("Initializer defined on unknown class"); |
- |
- it->second.initializers.push_back(call); |
- } |
- |
void register_differentiator(TYPEID classID, size_t offset, |
std::vector<std::pair<int, std::string>>& mapping) |
{ |
auto it = classes.find(classID); |
if (it == classes.end()) |
throw std::runtime_error("Subclass differentiator defined on unknown class"); |
if (it->second.subclass_differentiator.offset != SIZE_MAX) |
@@ -635,54 +629,53 @@ namespace bindings_internal |
for (const auto& item : cls.methods) |
{ |
std::string obj("exports." + cls.name); |
if (item.call.instance_function) |
obj += ".prototype"; |
printf("%s.%s = %s;\n", obj.c_str(), item.name.c_str(), |
wrapCall(item.call).c_str()); |
} |
- |
- for (const auto& item : cls.initializers) |
- printf("%s()\n", item.name); |
} |
void printBindings() |
{ |
printHelpers(); |
for (const auto& item : classes) |
printClass(item.second); |
+ |
+ for (const auto& item : customGenerators) |
+ item(); |
} |
} |
#if defined(PRINT_BINDINGS) |
// Bindings generation step: collect bindings information and print |
// corresponding JS code. |
#define EMSCRIPTEN_BINDINGS \ |
- struct BindingsInitializer {\ |
- BindingsInitializer();\ |
- BindingsInitializer(bool dummy)\ |
- {\ |
- try\ |
- {\ |
- BindingsInitializer();\ |
- bindings_internal::printBindings();\ |
- }\ |
- catch (const std::exception& e)\ |
- {\ |
- EM_ASM_ARGS(\ |
- console.error("Error occurred generating JavaScript bindings: " +\ |
- Module.AsciiToString($0)), e.what()\ |
- );\ |
- abort();\ |
- }\ |
- }\ |
- } BindingsInitializer_instance(true);\ |
- BindingsInitializer::BindingsInitializer() |
+ void InitializeBindings();\ |
+ int main()\ |
+ {\ |
+ try\ |
+ {\ |
+ InitializeBindings();\ |
+ bindings_internal::printBindings();\ |
+ }\ |
+ catch (const std::exception& e)\ |
+ {\ |
+ EM_ASM_ARGS(\ |
+ console.error("Error occurred generating JavaScript bindings: " +\ |
+ Module.AsciiToString($0)), e.what()\ |
+ );\ |
+ abort();\ |
+ }\ |
+ return 0;\ |
+ }\ |
+ void InitializeBindings() |
#else |
// Actual compilation step: ignore bindings information but define some |
// exported helper functions necessary for the bindings. |
#define EMSCRIPTEN_BINDINGS \ |
extern "C"\ |
{\ |
void EMSCRIPTEN_KEEPALIVE InitString(DependentString* str,\ |
String::value_type* data, String::size_type len)\ |
@@ -773,23 +766,16 @@ public: |
template<typename ReturnType, typename... Args> |
const class_& class_function(const char* name, ReturnType (*method)(Args...)) const |
{ |
bindings_internal::register_method( |
bindings_internal::TypeInfo<ClassType>(), name, method); |
return *this; |
} |
- const class_& class_initializer(void (*function)()) const |
- { |
- bindings_internal::register_initializer( |
- bindings_internal::TypeInfo<ClassType>(), function); |
- return *this; |
- } |
- |
template<typename ReturnType, |
typename std::enable_if<std::is_convertible<ReturnType, int32_t>::value>::type* = nullptr> |
const class_& subclass_differentiator(ReturnType ClassType::* member, |
std::initializer_list<std::pair<ReturnType, const char*>> list) const |
{ |
ClassType* instance = nullptr; |
size_t offset = (char*)&(instance->*member) - (char*)instance; |
@@ -797,8 +783,13 @@ public: |
for (const auto& item : list) |
mapping.emplace_back(item.first, item.second); |
bindings_internal::register_differentiator( |
bindings_internal::TypeInfo<ClassType>(), offset, mapping); |
return *this; |
} |
}; |
+ |
+void custom_generator(bindings_internal::CustomGenerator generator) |
+{ |
+ bindings_internal::customGenerators.push_back(generator); |
+} |