Skip to content

Instantly share code, notes, and snippets.

@veryjos
Created August 19, 2017 02:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save veryjos/8d6649e6fd24b482757b9a12d38aa4cc to your computer and use it in GitHub Desktop.
Save veryjos/8d6649e6fd24b482757b9a12d38aa4cc to your computer and use it in GitHub Desktop.
legacy currychakra example
#include "CC_Config.hpp"
using namespace CurryChakra;
// Shims for JS types
// JsValueRef
JsValueRef CppToJs(JsValueRef& value) {
return value;
};
void JsToCpp(JsValueRef& obj, JsValueRef& value) {
obj = value;
};
// Doubles
JsValueRef CppToJs(double& value) {
JsValueRef jsValue;
ExceptIfError(JsDoubleToNumber(value, &jsValue));
return jsValue;
};
void JsToCpp(double& obj, JsValueRef &jsValue) {
ExceptIfError(JsNumberToDouble(jsValue, &obj));
};
// Ints (implicitly doubles)
JsValueRef CppToJs(int& value) {
JsValueRef jsValue;
ExceptIfError(JsDoubleToNumber(value, &jsValue));
return jsValue;
};
void JsToCpp(int& obj, JsValueRef &jsValue) {
double v;
ExceptIfError(JsNumberToDouble(jsValue, &v));
obj = v;
};
JsValueRef CppToJs(unsigned int& value) {
JsValueRef jsValue;
ExceptIfError(JsDoubleToNumber(value, &jsValue));
return jsValue;
};
void JsToCpp(unsigned int& obj, JsValueRef &jsValue) {
double v;
ExceptIfError(JsNumberToDouble(jsValue, &v));
obj = v;
};
// Floats
JsValueRef CppToJs(float& value) {
JsValueRef jsValue;
ExceptIfError(JsDoubleToNumber(value, &jsValue));
return jsValue;
};
void JsToCpp(float& obj, JsValueRef &jsValue) {
double v;
ExceptIfError(JsNumberToDouble(jsValue, &v));
obj = v;
};
// Strings (only by copy)
JsValueRef CppToJs(std::string& value) {
JsValueRef jsValue;
ExceptIfError(JsCreateString(value.c_str(), value.length(), &jsValue));
return jsValue;
};
void JsToCpp(std::string& obj, JsValueRef& jsValue) {
obj = ch::ReadStdString(jsValue);
};
// Vectors (only by copy)
template <typename T>
JsValueRef CppToJs(std::vector<T>& obj) {
JsValueRef arr;
ExceptIfError(JsCreateArray(obj.size(), &arr));
for (uint32_t i=0;i<obj.size();++i)
ExceptIfError(JsSetIndexedProperty(arr, CppToJs(i), CppToJs(obj[i])));
return arr;
};
template <typename T>
void JsToCpp(std::vector<T>& obj, JsValueRef& arr) {
// Get the number of elements in the JS array
JsValueRef length;
ExceptIfError(ch::GetPropertyValueByName(arr, "length", &length));
// Just in case the elements are ref counted, create a new vector and
// copy it into it.
std::vector<T> copy;
copy.reserve(obj.size());
// Convert it to cpp
uint32_t num_elements;
JsToCpp(num_elements, length);
for (uint32_t i=0;i<num_elements;++i) {
// Get the JS element
JsValueRef jsElement;
JsGetIndexedProperty(arr, CppToJs(i), &jsElement);
// Copy each element over
T elementCopy;
JsToCpp(elementCopy, jsElement);
copy.push_back(elementCopy);
}
obj = copy;
};
// End shims for JS types
// Shims for Vec2
static JsValueRef __js_prototype_Vec2;
JsValueRef CppToJs(Vec2*& obj) {
JsValueRef jsValue = obj->GetCCHandle();
if (!jsValue) {
CC_CppHandle<Vec2>* handle = new CC_CppHandle<Vec2>(obj);
ExceptIfError(JsCreateExternalObject(handle, nullptr/*finalizeCallback*/, &jsValue));
ExceptIfError(JsSetPrototype(jsValue, __js_prototype_Vec2));
obj->SetCCHandle(jsValue);
}
return jsValue;
};
void JsToCpp(Vec2*& obj, JsValueRef& jsValue) {
CC_CppHandle<Vec2>* handle;
ExceptIfError(JsGetExternalData(jsValue, (void**)&handle));
obj = handle->GetPointer();
};
JsValueRef CppToJs(Vec2& obj) {
// turn this cpp value into a js value by copy
Vec2* heapObj = new Vec2(obj);
CC_CppHandle<Vec2>* handle = new CC_CppHandle<Vec2>(new Vec2(obj));
JsValueRef jsValue;
ExceptIfError(JsCreateExternalObject(handle, nullptr/*finalizeCallback*/, &jsValue));
ExceptIfError(JsSetPrototype(jsValue, __js_prototype_Vec2));
heapObj->SetCCHandle(jsValue);
return jsValue;
};
JsValueRef CppToJs(std::shared_ptr<Vec2>& obj) {
std::shared_ptr<Vec2> heapObj = std::shared_ptr<Vec2>(obj);
CC_CppHandle<Vec2>* handle = new CC_CppHandle<Vec2>(obj);
JsValueRef jsValue;
ExceptIfError(JsCreateExternalObject(handle, nullptr/*finalizeCallback*/, &jsValue));
ExceptIfError(JsSetPrototype(jsValue, __js_prototype_Vec2));
heapObj->SetCCHandle(jsValue);
return jsValue;
};
void JsToCpp(std::shared_ptr<Vec2>& obj, JsValueRef& jsValue) {
CC_CppHandle<Vec2>* handle;
ExceptIfError(JsGetExternalData(jsValue, (void**)&handle));
obj = handle->GetSmart();
};
void JsToCpp(Vec2& obj, JsValueRef& jsValue) {
CC_CppHandle<Vec2>* handle;
ExceptIfError(JsGetExternalData(jsValue, (void**)&handle));
obj = *handle->GetPointer();
};
// End shims for Vec2
void CC_InitializeBindings() {
// Get the global JS object
JsValueRef globalObject;
ExceptIfError(JsGetGlobalObject(&globalObject));
{
// Binding class Vec2
// Create new JS prototype
ExceptIfError(JsCreateObject(&__js_prototype_Vec2));
JsValueRef bindTarget = __js_prototype_Vec2;
{
// Generating binding for constructor Vec2
JsValueRef jsConstructor;
ExceptIfError(ch::WrapNativeMethod(&jsConstructor,
[](JsValueRef callee, bool isConstructCall, JsValueRef* arguments, unsigned short argCount, void* callbackState) -> JsValueRef {
// Get metadata from function declaration
CC_ConstructorMeta* meta = (CC_ConstructorMeta*)callbackState;
// Unpack each argument
float argument_x;
JsToCpp(argument_x, arguments[1]);
float argument_y;
JsToCpp(argument_y, arguments[2]);
// Create C++ object
Vec2* external = new Vec2(
argument_x,
argument_y
);
// Wrap the C++ object, attach the prototype, and return
auto jsReturnValue = CppToJs(external);
return jsReturnValue;
}));
// Get the namespace object to define the ctor on
bool has;
ExceptIfError(ch::HasPropertyByName(globalObject, "Math", has));
JsValueRef namespaceObject;
if (!has) {
// If the namespace doesn't exist yet, create it
ExceptIfError(JsCreateObject(&namespaceObject));
ExceptIfError(ch::SetPropertyValueByName(globalObject, "Math", namespaceObject));
} else {
// The namespace already exists, just get it
ExceptIfError(ch::GetPropertyValueByName(globalObject, "Math", &namespaceObject));
}
// Push constructor onto namespace object
ExceptIfError(ch::SetPropertyValueByName(namespaceObject, "Vec2", jsConstructor));
// End binding for constructor Vec2
}
{
// Generating binding for method Length
JsValueRef jsFuncValue;
ExceptIfError(ch::WrapNativeMethod(&jsFuncValue,
[](JsValueRef callee, bool isConstructCall, JsValueRef* arguments, unsigned short argCount, void* callbackState) -> JsValueRef {
Vec2* external;
JsToCpp(external, arguments[0]);
// Call native function
auto returnValue =
external->Length(
);
// Wrap and return native return value
return CppToJs(returnValue);
}));
// Set the property on the prototype
ExceptIfError(ch::SetPropertyValueByName(bindTarget, "Length", jsFuncValue));
// End binding for method Length
}
{
// Generating binding for method Add
JsValueRef jsFuncValue;
ExceptIfError(ch::WrapNativeMethod(&jsFuncValue,
[](JsValueRef callee, bool isConstructCall, JsValueRef* arguments, unsigned short argCount, void* callbackState) -> JsValueRef {
Vec2* external;
JsToCpp(external, arguments[0]);
// Unpack each argument
Vec2 argument_other;
JsToCpp(argument_other, arguments[1]);
// Call native function
auto returnValue =
external->Add(
argument_other
);
// Wrap and return native return value
return CppToJs(returnValue);
}));
// Set the property on the prototype
ExceptIfError(ch::SetPropertyValueByName(bindTarget, "Add", jsFuncValue));
// End binding for method Add
}
{
// Generating binding for method Mul
JsValueRef jsFuncValue;
ExceptIfError(ch::WrapNativeMethod(&jsFuncValue,
[](JsValueRef callee, bool isConstructCall, JsValueRef* arguments, unsigned short argCount, void* callbackState) -> JsValueRef {
Vec2* external;
JsToCpp(external, arguments[0]);
// Unpack each argument
Vec2 argument_other;
JsToCpp(argument_other, arguments[1]);
// Call native function
auto returnValue =
external->Mul(
argument_other
);
// Wrap and return native return value
return CppToJs(returnValue);
}));
// Set the property on the prototype
ExceptIfError(ch::SetPropertyValueByName(bindTarget, "Mul", jsFuncValue));
// End binding for method Mul
}
{
// Generating binding for method Scale
JsValueRef jsFuncValue;
ExceptIfError(ch::WrapNativeMethod(&jsFuncValue,
[](JsValueRef callee, bool isConstructCall, JsValueRef* arguments, unsigned short argCount, void* callbackState) -> JsValueRef {
Vec2* external;
JsToCpp(external, arguments[0]);
// Unpack each argument
float argument_scale;
JsToCpp(argument_scale, arguments[1]);
// Call native function
auto returnValue =
external->Scale(
argument_scale
);
// Wrap and return native return value
return CppToJs(returnValue);
}));
// Set the property on the prototype
ExceptIfError(ch::SetPropertyValueByName(bindTarget, "Scale", jsFuncValue));
// End binding for method Scale
}
{
// Generating binding for method toString
JsValueRef jsFuncValue;
ExceptIfError(ch::WrapNativeMethod(&jsFuncValue,
[](JsValueRef callee, bool isConstructCall, JsValueRef* arguments, unsigned short argCount, void* callbackState) -> JsValueRef {
Vec2* external;
JsToCpp(external, arguments[0]);
// Call native function
auto returnValue =
external->toString(
);
// Wrap and return native return value
return CppToJs(returnValue);
}));
// Set the property on the prototype
ExceptIfError(ch::SetPropertyValueByName(bindTarget, "toString", jsFuncValue));
// End binding for method toString
}
{
// Generating binding for method AsArray
JsValueRef jsFuncValue;
ExceptIfError(ch::WrapNativeMethod(&jsFuncValue,
[](JsValueRef callee, bool isConstructCall, JsValueRef* arguments, unsigned short argCount, void* callbackState) -> JsValueRef {
Vec2* external;
JsToCpp(external, arguments[0]);
// Call native function
auto returnValue =
external->AsArray(
);
// Wrap and return native return value
return CppToJs(returnValue);
}));
// Set the property on the prototype
ExceptIfError(ch::SetPropertyValueByName(bindTarget, "AsArray", jsFuncValue));
// End binding for method AsArray
}
{
// Generating binding for method FromArray
JsValueRef jsFuncValue;
ExceptIfError(ch::WrapNativeMethod(&jsFuncValue,
[](JsValueRef callee, bool isConstructCall, JsValueRef* arguments, unsigned short argCount, void* callbackState) -> JsValueRef {
Vec2* external;
JsToCpp(external, arguments[0]);
// Unpack each argument
std::vector<float> argument_vec;
JsToCpp(argument_vec, arguments[1]);
// Call native function
auto returnValue =
external->FromArray(
argument_vec
);
// Wrap and return native return value
return CppToJs(returnValue);
}));
// Set the property on the prototype
ExceptIfError(ch::SetPropertyValueByName(bindTarget, "FromArray", jsFuncValue));
// End binding for method FromArray
}
{
// Generating binding for property x
ExceptIfError(ch::DefineProperty(bindTarget, "x", false,
[](JsValueRef callee, bool isConstructCall, JsValueRef* arguments, unsigned short argCount, void* callbackState) -> JsValueRef {
Vec2* external;
JsToCpp(external, arguments[0]);
return CppToJs(external->x);
},
[](JsValueRef callee, bool isConstructCall, JsValueRef* arguments, unsigned short argCount, void* callbackState) -> JsValueRef {
Vec2* external;
JsToCpp(external, arguments[0]);
JsToCpp(external->x, arguments[1]);
return ch::Undefined();
}, true));
// End binding for property x
}
{
// Generating binding for property y
ExceptIfError(ch::DefineProperty(bindTarget, "y", false,
[](JsValueRef callee, bool isConstructCall, JsValueRef* arguments, unsigned short argCount, void* callbackState) -> JsValueRef {
Vec2* external;
JsToCpp(external, arguments[0]);
return CppToJs(external->y);
},
[](JsValueRef callee, bool isConstructCall, JsValueRef* arguments, unsigned short argCount, void* callbackState) -> JsValueRef {
Vec2* external;
JsToCpp(external, arguments[0]);
JsToCpp(external->y, arguments[1]);
return ch::Undefined();
}, true));
// End binding for property y
}
// Done binding class Vec2
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment