初始化

This commit is contained in:
SmallMain
2022-06-25 00:23:03 +08:00
commit ef0589e8e5
2264 changed files with 617829 additions and 0 deletions

View File

@@ -0,0 +1,629 @@
/*
* Copyright (c) 2013-2016 Chukong Technologies Inc.
* Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "scripting/js-bindings/manual/JavaScriptJavaBridge.h"
#include "platform/android/jni/JniHelper.h"
#include "cocos/scripting/js-bindings/jswrapper/SeApi.h"
#include "cocos/scripting/js-bindings/manual/jsb_conversions.hpp"
#include "cocos/base/ccUTF8.h"
#include <android/log.h>
#include <vector>
#include <string>
#ifdef LOG_TAG
#undef LOG_TAG
#endif
#define LOG_TAG "JavaScriptJavaBridge"
#ifndef ORG_JAVABRIDGE_CLASS_NAME
#define ORG_JAVABRIDGE_CLASS_NAME org_cocos2dx_lib_Cocos2dxJavascriptJavaBridge
#endif
#define JNI_JSJAVABRIDGE(FUNC) JNI_METHOD1(ORG_JAVABRIDGE_CLASS_NAME,FUNC)
extern "C" {
JNIEXPORT jint JNICALL JNI_JSJAVABRIDGE(evalString)
(JNIEnv *env, jclass cls, jstring value)
{
if (!se::ScriptEngine::getInstance()->isValid()) {
CCLOG("ScriptEngine has not been initialized");
return 0;
}
se::AutoHandleScope hs;
bool strFlag = false;
std::string strValue = cocos2d::StringUtils::getStringUTFCharsJNI(env, value, &strFlag);
if (!strFlag)
{
CCLOG("JavaScriptJavaBridge_evalString error, invalid string code");
return 0;
}
se::ScriptEngine::getInstance()->evalString(strValue.c_str());
return 1;
}
} // extern "C"
#define JSJ_ERR_OK (0)
#define JSJ_ERR_TYPE_NOT_SUPPORT (-1)
#define JSJ_ERR_INVALID_SIGNATURES (-2)
#define JSJ_ERR_METHOD_NOT_FOUND (-3)
#define JSJ_ERR_EXCEPTION_OCCURRED (-4)
#define JSJ_ERR_VM_THREAD_DETACHED (-5)
#define JSJ_ERR_VM_FAILURE (-6)
#define JSJ_ERR_CLASS_NOT_FOUND (-7)
class JavaScriptJavaBridge
{
public:
enum class ValueType: char
{
INVALID,
VOID,
INTEGER,
LONG,
FLOAT,
BOOLEAN,
STRING,
VECTOR,
FUNCTION
};
typedef std::vector<ValueType> ValueTypes;
typedef union
{
int intValue;
long longValue;
float floatValue;
int boolValue;
std::string *stringValue;
} ReturnValue;
class CallInfo
{
public:
CallInfo(const char *className, const char *methodName, const char *methodSig)
: m_valid(false)
, m_error(JSJ_ERR_OK)
, m_className(className)
, m_methodName(methodName)
, m_methodSig(methodSig)
, m_returnType(ValueType::VOID)
, m_argumentsCount(0)
, m_retjstring(NULL)
, m_env(NULL)
, m_classID(NULL)
, m_methodID(NULL)
{
memset(&m_ret, 0, sizeof(m_ret));
m_valid = validateMethodSig() && getMethodInfo();
}
~CallInfo();
bool isValid() {
return m_valid;
}
int getErrorCode() {
return m_error;
}
JNIEnv *getEnv() {
return m_env;
}
ValueType argumentTypeAtIndex(size_t index) {
return m_argumentsType.at(index);
}
int getArgumentsCount(){
return m_argumentsCount;
}
ValueType getReturnValueType(){
return m_returnType;
}
ReturnValue getReturnValue(){
return m_ret;
}
bool execute();
bool executeWithArgs(jvalue *args);
private:
bool m_valid;
int m_error;
std::string m_className;
std::string m_methodName;
std::string m_methodSig;
int m_argumentsCount;
ValueTypes m_argumentsType;
ValueType m_returnType;
ReturnValue m_ret;
jstring m_retjstring;
JNIEnv *m_env;
jclass m_classID;
jmethodID m_methodID;
bool validateMethodSig();
bool getMethodInfo();
ValueType checkType(const std::string& sig, size_t *pos);
};
static bool convertReturnValue(ReturnValue retValue, ValueType type, se::Value* ret);
};
JavaScriptJavaBridge::CallInfo::~CallInfo()
{
m_env->DeleteLocalRef(m_classID);
if (m_returnType == ValueType::STRING && m_ret.stringValue)
{
m_env->DeleteLocalRef(m_retjstring);
delete m_ret.stringValue;
}
}
bool JavaScriptJavaBridge::CallInfo::execute()
{
switch (m_returnType)
{
case JavaScriptJavaBridge::ValueType::VOID:
m_env->CallStaticVoidMethod(m_classID, m_methodID);
break;
case JavaScriptJavaBridge::ValueType::INTEGER:
m_ret.intValue = m_env->CallStaticIntMethod(m_classID, m_methodID);
break;
case JavaScriptJavaBridge::ValueType::LONG:
m_ret.longValue = m_env->CallStaticLongMethod(m_classID, m_methodID);
break;
case JavaScriptJavaBridge::ValueType::FLOAT:
m_ret.floatValue = m_env->CallStaticFloatMethod(m_classID, m_methodID);
break;
case JavaScriptJavaBridge::ValueType::BOOLEAN:
m_ret.boolValue = m_env->CallStaticBooleanMethod(m_classID, m_methodID);
break;
case JavaScriptJavaBridge::ValueType::STRING:
{
m_retjstring = (jstring)m_env->CallStaticObjectMethod(m_classID, m_methodID);
if(m_env->ExceptionCheck()) {
m_env->ExceptionDescribe();
m_env->ExceptionClear();
m_retjstring = nullptr;
}
if (m_retjstring)
{
std::string strValue = cocos2d::StringUtils::getStringUTFCharsJNI(m_env, m_retjstring);
m_ret.stringValue = new std::string(strValue);
}
else
m_ret.stringValue = nullptr;
break;
}
default:
m_error = JSJ_ERR_TYPE_NOT_SUPPORT;
SE_LOGD("Return type '%d' is not supported", static_cast<int>(m_returnType));
return false;
}
if (m_env->ExceptionCheck() == JNI_TRUE)
{
m_env->ExceptionDescribe();
m_env->ExceptionClear();
m_error = JSJ_ERR_EXCEPTION_OCCURRED;
return false;
}
return true;
}
bool JavaScriptJavaBridge::CallInfo::executeWithArgs(jvalue *args)
{
switch (m_returnType)
{
case JavaScriptJavaBridge::ValueType::VOID:
m_env->CallStaticVoidMethodA(m_classID, m_methodID, args);
break;
case JavaScriptJavaBridge::ValueType::INTEGER:
m_ret.intValue = m_env->CallStaticIntMethodA(m_classID, m_methodID, args);
break;
case JavaScriptJavaBridge::ValueType::LONG:
m_ret.longValue = m_env->CallStaticIntMethodA(m_classID, m_methodID, args);
break;
case JavaScriptJavaBridge::ValueType::FLOAT:
m_ret.floatValue = m_env->CallStaticFloatMethodA(m_classID, m_methodID, args);
break;
case JavaScriptJavaBridge::ValueType::BOOLEAN:
m_ret.boolValue = m_env->CallStaticBooleanMethodA(m_classID, m_methodID, args);
break;
case JavaScriptJavaBridge::ValueType::STRING:
{
m_retjstring = (jstring)m_env->CallStaticObjectMethodA(m_classID, m_methodID, args);
std::string strValue = cocos2d::StringUtils::getStringUTFCharsJNI(m_env, m_retjstring);
m_ret.stringValue = new std::string(strValue);
break;
}
default:
m_error = JSJ_ERR_TYPE_NOT_SUPPORT;
SE_LOGD("Return type '%d' is not supported", static_cast<int>(m_returnType));
return false;
}
if (m_env->ExceptionCheck() == JNI_TRUE)
{
m_env->ExceptionDescribe();
m_env->ExceptionClear();
m_error = JSJ_ERR_EXCEPTION_OCCURRED;
return false;
}
return true;
}
bool JavaScriptJavaBridge::CallInfo::validateMethodSig()
{
size_t len = m_methodSig.length();
if (len < 3 || m_methodSig[0] != '(') // min sig is "()V"
{
m_error = JSJ_ERR_INVALID_SIGNATURES;
return false;
}
size_t pos = 1;
while (pos < len && m_methodSig[pos] != ')')
{
JavaScriptJavaBridge::ValueType type = checkType(m_methodSig, &pos);
if (type == ValueType::INVALID) return false;
m_argumentsCount++;
m_argumentsType.push_back(type);
pos++;
}
if (pos >= len || m_methodSig[pos] != ')')
{
m_error = JSJ_ERR_INVALID_SIGNATURES;
return false;
}
pos++;
m_returnType = checkType(m_methodSig, &pos);
return true;
}
JavaScriptJavaBridge::ValueType JavaScriptJavaBridge::CallInfo::checkType(const std::string& sig, size_t *pos)
{
switch (sig[*pos])
{
case 'I':
return JavaScriptJavaBridge::ValueType::INTEGER;
case 'J':
return JavaScriptJavaBridge::ValueType::LONG;
case 'F':
return JavaScriptJavaBridge::ValueType::FLOAT;
case 'Z':
return JavaScriptJavaBridge::ValueType::BOOLEAN;
case 'V':
return JavaScriptJavaBridge::ValueType::VOID;
case 'L':
size_t pos2 = sig.find_first_of(';', *pos + 1);
if (pos2 == std::string::npos)
{
m_error = JSJ_ERR_INVALID_SIGNATURES;
return ValueType::INVALID;
}
const std::string t = sig.substr(*pos, pos2 - *pos + 1);
if (t.compare("Ljava/lang/String;") == 0)
{
*pos = pos2;
return ValueType::STRING;
}
else if (t.compare("Ljava/util/Vector;") == 0)
{
*pos = pos2;
return ValueType::VECTOR;
}
else
{
m_error = JSJ_ERR_TYPE_NOT_SUPPORT;
return ValueType::INVALID;
}
}
m_error = JSJ_ERR_TYPE_NOT_SUPPORT;
return ValueType::INVALID;
}
bool JavaScriptJavaBridge::CallInfo::getMethodInfo()
{
m_methodID = 0;
m_env = 0;
JavaVM* jvm = cocos2d::JniHelper::getJavaVM();
jint ret = jvm->GetEnv((void**)&m_env, JNI_VERSION_1_4);
switch (ret) {
case JNI_OK:
break;
case JNI_EDETACHED :
if (jvm->AttachCurrentThread(&m_env, NULL) < 0)
{
SE_LOGD("%s", "Failed to get the environment using AttachCurrentThread()");
m_error = JSJ_ERR_VM_THREAD_DETACHED;
return false;
}
break;
case JNI_EVERSION :
default :
SE_LOGD("%s", "Failed to get the environment using GetEnv()");
m_error = JSJ_ERR_VM_FAILURE;
return false;
}
jstring _jstrClassName = m_env->NewStringUTF(m_className.c_str());
m_classID = (jclass) m_env->CallObjectMethod(cocos2d::JniHelper::classloader,
cocos2d::JniHelper::loadclassMethod_methodID,
_jstrClassName);
if (NULL == m_classID) {
SE_LOGD("Classloader failed to find class of %s", m_className.c_str());
m_env->DeleteLocalRef(_jstrClassName);
m_env->ExceptionClear();
m_error = JSJ_ERR_CLASS_NOT_FOUND;
return false;
}
m_env->DeleteLocalRef(_jstrClassName);
m_methodID = m_env->GetStaticMethodID(m_classID, m_methodName.c_str(), m_methodSig.c_str());
if (!m_methodID)
{
m_env->ExceptionClear();
SE_LOGD("Failed to find method id of %s.%s %s",
m_className.c_str(),
m_methodName.c_str(),
m_methodSig.c_str());
m_error = JSJ_ERR_METHOD_NOT_FOUND;
return false;
}
return true;
}
bool JavaScriptJavaBridge::convertReturnValue(ReturnValue retValue, ValueType type, se::Value* ret)
{
assert(ret != nullptr);
switch (type)
{
case JavaScriptJavaBridge::ValueType::INTEGER:
ret->setInt32(retValue.intValue);
break;
case JavaScriptJavaBridge::ValueType::LONG:
ret->setLong(retValue.longValue);
break;
case JavaScriptJavaBridge::ValueType::FLOAT:
ret->setFloat(retValue.floatValue);
break;
case JavaScriptJavaBridge::ValueType::BOOLEAN:
ret->setBoolean(retValue.boolValue);
break;
case JavaScriptJavaBridge::ValueType::STRING:
if (retValue.stringValue)
ret->setString(*retValue.stringValue);
else
ret->setNull();
break;
default:
ret->setUndefined();
break;
}
return true;
}
se::Class* __jsb_JavaScriptJavaBridge_class = nullptr;
static bool JavaScriptJavaBridge_finalize(se::State& s)
{
JavaScriptJavaBridge* cobj = (JavaScriptJavaBridge*)s.nativeThisObject();
delete cobj;
return true;
}
SE_BIND_FINALIZE_FUNC(JavaScriptJavaBridge_finalize)
static bool JavaScriptJavaBridge_constructor(se::State& s)
{
JavaScriptJavaBridge* cobj = new (std::nothrow) JavaScriptJavaBridge();
s.thisObject()->setPrivateData(cobj);
return true;
}
SE_BIND_CTOR(JavaScriptJavaBridge_constructor, __jsb_JavaScriptJavaBridge_class, JavaScriptJavaBridge_finalize)
static bool JavaScriptJavaBridge_callStaticMethod(se::State& s)
{
const auto& args = s.args();
int argc = (int)args.size();
if (argc == 3)
{
bool ok = false;
std::string clsName, methodName, methodSig;
ok = seval_to_std_string(args[0], &clsName);
SE_PRECONDITION2(ok, false, "Converting class name failed!");
ok = seval_to_std_string(args[1], &methodName);
SE_PRECONDITION2(ok, false, "Converting method name failed!");
ok = seval_to_std_string(args[2], &methodSig);
SE_PRECONDITION2(ok, false, "Converting method signature failed!");
JavaScriptJavaBridge::CallInfo call(clsName.c_str(), methodName.c_str(), methodSig.c_str());
if (call.isValid())
{
ok = call.execute();
int errorCode = call.getErrorCode();
if (!ok || errorCode < 0)
{
SE_REPORT_ERROR("call result code: %d", call.getErrorCode());
return false;
}
JavaScriptJavaBridge::convertReturnValue(call.getReturnValue(), call.getReturnValueType(), &s.rval());
return true;
}
SE_REPORT_ERROR("JavaScriptJavaBridge::CallInfo isn't valid!");
return false;
}
else if (argc > 3)
{
bool ok = false;
std::string clsName, methodName, methodSig;
ok = seval_to_std_string(args[0], &clsName);
SE_PRECONDITION2(ok, false, "Converting class name failed!");
ok = seval_to_std_string(args[1], &methodName);
SE_PRECONDITION2(ok, false, "Converting method name failed!");
ok = seval_to_std_string(args[2], &methodSig);
SE_PRECONDITION2(ok, false, "Converting method signature failed!");
JavaScriptJavaBridge::CallInfo call(clsName.c_str(), methodName.c_str(), methodSig.c_str());
if (call.isValid() && call.getArgumentsCount() == (argc - 3))
{
int count = argc - 3;
jvalue* jargs = new jvalue[count];
std::vector<jobject> toReleaseObjects;
for (int i = 0; i < count; ++i)
{
int index = i + 3;
switch (call.argumentTypeAtIndex(i))
{
case JavaScriptJavaBridge::ValueType::INTEGER:
{
int integer = 0;
seval_to_int32(args[index], &integer);
jargs[i].i = integer;
break;
}
case JavaScriptJavaBridge::ValueType::LONG:
{
long longVal = 0L;
seval_to_long(args[index], &longVal);
jargs[i].j = longVal;
break;
}
case JavaScriptJavaBridge::ValueType::FLOAT:
{
float floatNumber = 0.0f;
seval_to_float(args[index], &floatNumber);
jargs[i].f = floatNumber;
break;
}
case JavaScriptJavaBridge::ValueType::BOOLEAN:
{
jargs[i].z = args[index].isBoolean() && args[index].toBoolean() ? JNI_TRUE : JNI_FALSE;
break;
}
case JavaScriptJavaBridge::ValueType::STRING:
{
const auto &arg = args[index];
if (arg.isNull() || arg.isUndefined())
jargs[i].l = nullptr;
else
{
std::string str;
seval_to_std_string(args[index], &str);
jargs[i].l = call.getEnv()->NewStringUTF(str.c_str());
toReleaseObjects.push_back(jargs[i].l);
}
break;
}
default:
SE_REPORT_ERROR("Unsupport type of parameter %d", i);
break;
}
}
ok = call.executeWithArgs(jargs);
for (const auto& obj : toReleaseObjects)
{
call.getEnv()->DeleteLocalRef(obj);
}
if (jargs)
delete[] jargs;
int errorCode = call.getErrorCode();
if (!ok || errorCode < 0)
{
SE_REPORT_ERROR("js_JSJavaBridge : call result code: %d", errorCode);
return false;
}
JavaScriptJavaBridge::convertReturnValue(call.getReturnValue(), call.getReturnValueType(), &s.rval());
return true;
}
SE_REPORT_ERROR("call valid: %d, call.getArgumentsCount()= %d", call.isValid(), call.getArgumentsCount());
return false;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting >=3", argc);
return false;
}
SE_BIND_FUNC(JavaScriptJavaBridge_callStaticMethod)
bool register_javascript_java_bridge(se::Object* obj)
{
se::Class* cls = se::Class::create("JavascriptJavaBridge", obj, nullptr, _SE(JavaScriptJavaBridge_constructor));
cls->defineFinalizeFunction(_SE(JavaScriptJavaBridge_finalize));
cls->defineFunction("callStaticMethod", _SE(JavaScriptJavaBridge_callStaticMethod));
cls->install();
__jsb_JavaScriptJavaBridge_class = cls;
se::ScriptEngine::getInstance()->clearException();
return true;
}

View File

@@ -0,0 +1,30 @@
/*
* Copyright (c) 2013-2016 Chukong Technologies Inc.
* Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#pragma once
namespace se {
class Object;
}
bool register_javascript_java_bridge(se::Object* obj);

View File

@@ -0,0 +1,30 @@
/*
* Copyright (c) 2013-2016 Chukong Technologies Inc.
* Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#pragma once
namespace se {
class Object;
}
bool register_javascript_objc_bridge(se::Object* obj);

View File

@@ -0,0 +1,442 @@
/****************************************************************************
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "JavaScriptObjCBridge.h"
#include "cocos/scripting/js-bindings/manual/jsb_conversions.hpp"
#include "cocos/scripting/js-bindings/manual/jsb_global.h"
#include "cocos/scripting/js-bindings/jswrapper/SeApi.h"
#include <string>
#include <vector>
#import <Foundation/Foundation.h>
#define JSO_ERR_OK (0)
#define JSO_ERR_TYPE_NOT_SUPPORT (-1)
#define JSO_ERR_INVALID_ARGUMENTS (-2)
#define JSO_ERR_METHOD_NOT_FOUND (-3)
#define JSO_ERR_EXCEPTION_OCCURRED (-4)
#define JSO_ERR_CLASS_NOT_FOUND (-5)
#define JSO_ERR_VM_FAILURE (-6)
class JavaScriptObjCBridge
{
public:
class CallInfo
{
public:
CallInfo(const char *className, const char* methodName)
:_error(JSO_ERR_OK)
,_methodName(methodName)
,_className(className)
{
}
~CallInfo() {}
int getErrorCode() const
{
return _error;
}
bool execute(const se::ValueArray& argv, se::Value& rval);
private:
se::Value objc_to_seval(id objcVal);
int _error;
std::string _className;
std::string _methodName;
};
};
bool JavaScriptObjCBridge::CallInfo::execute(const se::ValueArray& argv, se::Value& rval)
{
NSString *className =[NSString stringWithCString: _className.c_str() encoding:NSUTF8StringEncoding];
NSString *methodName = [NSString stringWithCString: _methodName.c_str() encoding:NSUTF8StringEncoding];
if(!className || !methodName)
{
_error = JSO_ERR_INVALID_ARGUMENTS;
return false;
}
Class targetClass = NSClassFromString(className);
if(!targetClass)
{
_error = JSO_ERR_CLASS_NOT_FOUND;
return false;
}
SEL methodSel;
methodSel = NSSelectorFromString(methodName);
if (!methodSel)
{
_error = JSO_ERR_METHOD_NOT_FOUND;
return false;
}
methodSel = NSSelectorFromString(methodName);
NSMethodSignature *methodSig = [targetClass methodSignatureForSelector:(SEL)methodSel];
if (methodSig == nil)
{
_error = JSO_ERR_METHOD_NOT_FOUND;
NSLog(@"%@.%@ method isn't found!", className, methodName);
return false;
}
@try
{
int argc = (int)argv.size();
NSUInteger argumentCount = [methodSig numberOfArguments];
if (argumentCount != argc)
{
_error = JSO_ERR_INVALID_ARGUMENTS;
return false;
}
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSig];
[invocation setTarget:targetClass];
[invocation setSelector:methodSel];
for(int i = 2; i < argc; ++i)
{
std::string argumentType = [methodSig getArgumentTypeAtIndex:i];
const se::Value& arg = argv[i];
/* - (void)setArgument:(void *)argumentLocation atIndex:(NSInteger)idx;
*
* Refer to https://developer.apple.com/documentation/foundation/nsinvocation/1437834-setargument?language=objc
*
* This method copies the contents of buffer as the argument at index. The number of bytes copied is determined by the argument size.
* When the argument value is an object, pass a pointer to the variable (or memory) from which the object should be copied:
*/
if (arg.isString())
{
NSString* str = [NSString stringWithCString:arg.toString().c_str() encoding:NSUTF8StringEncoding];
[invocation setArgument:&str atIndex:i];
}
else if (arg.isNumber())
{
if (argumentType == @encode(int))
{
int val = arg.toInt32();
[invocation setArgument:&val atIndex:i];
}
else if (argumentType == @encode(long))
{
long val = arg.toLong();
[invocation setArgument:&val atIndex:i];
}
else if (argumentType == @encode(short))
{
short val = arg.toInt16();
[invocation setArgument:&val atIndex:i];
}
else if (argumentType == @encode(unsigned int))
{
unsigned int val = arg.toUint32();
[invocation setArgument:&val atIndex:i];
}
else if (argumentType == @encode(unsigned long))
{
unsigned long val = arg.toUlong();
[invocation setArgument:&val atIndex:i];
}
else if (argumentType == @encode(unsigned short))
{
unsigned short val = arg.toUint16();
[invocation setArgument:&val atIndex:i];
}
else if (argumentType == @encode(float))
{
float val = arg.toFloat();
[invocation setArgument:&val atIndex:i];
}
else if (argumentType == @encode(double))
{
double val = arg.toNumber();
[invocation setArgument:&val atIndex:i];
}
else if (argumentType == @encode(char))
{
char val = arg.toInt8();
[invocation setArgument:&val atIndex:i];
}
else if (argumentType == @encode(unsigned char))
{
unsigned char val = arg.toUint8();
[invocation setArgument:&val atIndex:i];
}
else if (argumentType == "@")
{ // NSNumber*
NSNumber* number = [NSNumber numberWithDouble:arg.toNumber()];
[invocation setArgument:&number atIndex:i];
}
else
{
NSLog(@"Unsupported argument type: %s", argumentType.c_str());
_error = JSO_ERR_TYPE_NOT_SUPPORT;
return false;
}
}
else if (arg.isBoolean())
{
if (argumentType == @encode(BOOL))
{
BOOL val = arg.toBoolean() ? YES : NO;
[invocation setArgument:&val atIndex:i];
}
else if (argumentType == @encode(bool))
{
bool val = arg.toBoolean();
[invocation setArgument:&val atIndex:i];
}
else
{
NSLog(@"Unsupported argument type: %s", argumentType.c_str());
_error = JSO_ERR_TYPE_NOT_SUPPORT;
return false;
}
}
else if (arg.isNullOrUndefined())
{
// Don't call [invocation setArgument] will pass nil to relevant Objective-C argument.
}
else
{
NSLog(@"Unsupported argument type, se::Value::Type: %d", (int)arg.getType());
_error = JSO_ERR_TYPE_NOT_SUPPORT;
return false;
}
}
NSUInteger returnLength = [methodSig methodReturnLength];
std::string returnType = [methodSig methodReturnType];
[invocation invoke];
if (returnLength > 0)
{
if (returnType == "@")
{
id ret;
[invocation getReturnValue:&ret];
rval = objc_to_seval(ret);
}
else if (returnType == @encode(BOOL) || returnType == @encode(bool))
{
bool ret;
[invocation getReturnValue:&ret];
rval.setBoolean(ret);
}
else if (returnType == @encode(int))
{
int ret;
[invocation getReturnValue:&ret];
rval.setInt32(ret);
}
else if (returnType == @encode(long))
{
long ret;
[invocation getReturnValue:&ret];
rval.setLong(ret);
}
else if (returnType == @encode(short))
{
short ret;
[invocation getReturnValue:&ret];
rval.setInt16(ret);
}
else if (returnType == @encode(unsigned int))
{
unsigned int ret;
[invocation getReturnValue:&ret];
rval.setUint32(ret);
}
else if (returnType == @encode(unsigned long))
{
unsigned long ret;
[invocation getReturnValue:&ret];
rval.setUlong(ret);
}
else if (returnType == @encode(unsigned short))
{
unsigned short ret;
[invocation getReturnValue:&ret];
rval.setUint16(ret);
}
else if (returnType == @encode(float))
{
float ret;
[invocation getReturnValue:&ret];
rval.setFloat(ret);
}
else if (returnType == @encode(double))
{
double ret;
[invocation getReturnValue:&ret];
rval.setNumber(ret);
}
else if (returnType == @encode(char))
{
int8_t ret;
[invocation getReturnValue:&ret];
rval.setInt8(ret);
}
else if (returnType == @encode(unsigned char))
{
uint8_t ret;
[invocation getReturnValue:&ret];
rval.setUint8(ret);
}
else
{
_error = JSO_ERR_TYPE_NOT_SUPPORT;
NSLog(@"not support return type = %s", returnType.c_str());
return false;
}
}
}@catch(NSException *exception)
{
NSLog(@"EXCEPTION THROW: %@", exception);
_error = JSO_ERR_EXCEPTION_OCCURRED;
return false;
}
return true;
}
se::Value JavaScriptObjCBridge::CallInfo::objc_to_seval(id objcVal)
{
se::Value ret;
if (objcVal == nil)
return ret;
if ([objcVal isKindOfClass:[NSNumber class]])
{
NSNumber *number = (NSNumber *)objcVal;
std::string numberType = [number objCType];
if (numberType == @encode(BOOL) || numberType == @encode(bool))
{
ret.setBoolean([number boolValue]);
}
else if (numberType == @encode(int)
|| numberType == @encode(long)
|| numberType == @encode(short)
|| numberType == @encode(unsigned int)
|| numberType == @encode(unsigned long)
|| numberType == @encode(unsigned short)
|| numberType == @encode(float)
|| numberType == @encode(double)
|| numberType == @encode(char)
|| numberType == @encode(unsigned char)
)
{
ret.setNumber([number doubleValue]);
}
else
{
CCLOGERROR("Unknown number type: %s", numberType.c_str());
}
}
else if ([objcVal isKindOfClass:[NSString class]])
{
const char* content = [objcVal cStringUsingEncoding:NSUTF8StringEncoding];
ret.setString(content);
}
else if ([objcVal isKindOfClass:[NSDictionary class]])
{
CCLOGERROR("JavaScriptObjCBridge doesn't support to bind NSDictionary!");
}
else
{
const char* content = [[NSString stringWithFormat:@"%@", objcVal] cStringUsingEncoding:NSUTF8StringEncoding];
ret.setString(content);
}
return ret;
}
se::Class* __jsb_JavaScriptObjCBridge_class = nullptr;
static bool JavaScriptObjCBridge_finalize(se::State& s)
{
JavaScriptObjCBridge* cobj = (JavaScriptObjCBridge*)s.nativeThisObject();
delete cobj;
return true;
}
SE_BIND_FINALIZE_FUNC(JavaScriptObjCBridge_finalize)
static bool JavaScriptObjCBridge_constructor(se::State& s)
{
JavaScriptObjCBridge* cobj = new (std::nothrow) JavaScriptObjCBridge();
s.thisObject()->setPrivateData(cobj);
return true;
}
SE_BIND_CTOR(JavaScriptObjCBridge_constructor, __jsb_JavaScriptObjCBridge_class, JavaScriptObjCBridge_finalize)
static bool JavaScriptObjCBridge_callStaticMethod(se::State& s)
{
const auto& args = s.args();
int argc = (int)args.size();
if (argc >= 2)
{
bool ok = false;
std::string clsName, methodName;
ok = seval_to_std_string(args[0], &clsName);
SE_PRECONDITION2(ok, false, "Converting class name failed!");
ok = seval_to_std_string(args[1], &methodName);
SE_PRECONDITION2(ok, false, "Converting method name failed!");
JavaScriptObjCBridge::CallInfo call(clsName.c_str(), methodName.c_str());
ok = call.execute(args, s.rval());
if(!ok)
{
s.rval().setUndefined();
SE_REPORT_ERROR("call (%s.%s) failed, result code: %d", clsName.c_str(), methodName.c_str(), call.getErrorCode());
return false;
}
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting >=2", argc);
return false;
}
SE_BIND_FUNC(JavaScriptObjCBridge_callStaticMethod)
bool register_javascript_objc_bridge(se::Object* obj)
{
se::Class* cls = se::Class::create("JavaScriptObjCBridge", obj, nullptr, _SE(JavaScriptObjCBridge_constructor));
cls->defineFinalizeFunction(_SE(JavaScriptObjCBridge_finalize));
cls->defineFunction("callStaticMethod", _SE(JavaScriptObjCBridge_callStaticMethod));
cls->install();
__jsb_JavaScriptObjCBridge_class = cls;
se::ScriptEngine::getInstance()->clearException();
return true;
}

View File

@@ -0,0 +1,50 @@
/****************************************************************************
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "jsb_classtype.hpp"
JSBClassType::Map* JSBClassType::__jsbClassTypeMap = nullptr;
bool JSBClassType::init()
{
if (__jsbClassTypeMap == nullptr)
__jsbClassTypeMap = new (std::nothrow) Map();
return __jsbClassTypeMap != nullptr;
}
void JSBClassType::destroy()
{
if (__jsbClassTypeMap != nullptr)
{
delete __jsbClassTypeMap;
__jsbClassTypeMap = nullptr;
}
}
void JSBClassType::cleanup()
{
__jsbClassTypeMap->clear();
}

View File

@@ -0,0 +1,73 @@
/****************************************************************************
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
#include "scripting/js-bindings/jswrapper/SeApi.h"
#include "2d/CCTTFLabelRenderer.h"
#include <typeinfo>
class JSBClassType
{
public:
static bool init();
static void destroy();
template<typename T>
static void registerClass(se::Class* cls)
{
const char* typeName = typeid(T).name();
assert(__jsbClassTypeMap->find(typeName) == __jsbClassTypeMap->end());
__jsbClassTypeMap->emplace(typeName, cls);
}
template<typename T>
static se::Class* findClass(const T* nativeObj)
{
bool found = false;
std::string typeName = typeid(*nativeObj).name();
auto iter = __jsbClassTypeMap->find(typeName);
if (iter == __jsbClassTypeMap->end())
{
typeName = typeid(T).name();
iter = __jsbClassTypeMap->find(typeName);
if (iter != __jsbClassTypeMap->end())
{
found = true;
}
}
else
{
found = true;
}
return found ? iter->second : nullptr;
}
static void cleanup();
private:
using Map = std::unordered_map<std::string, se::Class*>;
static Map* __jsbClassTypeMap;
};

View File

@@ -0,0 +1,246 @@
/****************************************************************************
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "jsb_cocos2dx_extension_manual.hpp"
#include "cocos/scripting/js-bindings/jswrapper/SeApi.h"
#include "cocos/scripting/js-bindings/manual/jsb_conversions.hpp"
#include "cocos/scripting/js-bindings/manual/jsb_global.h"
#include "cocos/scripting/js-bindings/auto/jsb_cocos2dx_extension_auto.hpp"
#include "cocos/base/CCThreadPool.h"
#include "cocos2d.h"
#include "extensions/cocos-ext.h"
using namespace cocos2d;
using namespace cocos2d::extension;
static bool js_cocos2dx_extension_loadRemoteImage(se::State& s)
{
const auto& args = s.args();
int argc = (int)args.size();
if (argc == 2)
{
bool ok = false;
std::string url;
ok = seval_to_std_string(args[0], &url);
SE_PRECONDITION2(ok, false, "Converting 'url' failed!");
se::Value func = args[1];
assert(func.isObject() && func.toObject()->isFunction());
func.toObject()->root();
auto onSuccess = [func](Texture2D* tex) -> bool {
se::ScriptEngine::getInstance()->clearException();
se::AutoHandleScope hs;
se::ValueArray args;
args.resize(2);
if (tex != nullptr)
{
args[0].setBoolean(true);
bool ok = native_ptr_to_seval<Texture2D>(tex, &args[1]);
SE_PRECONDITION2(ok, false, "Converting 'tex' argument failed!");
}
else
{
args[0].setBoolean(false);
args[1].setNull();
}
return func.toObject()->call(args, nullptr);
};
auto onError = [func](){
se::ScriptEngine::getInstance()->clearException();
se::AutoHandleScope hs;
se::ValueArray args;
args.resize(1);
args[0].setBoolean(false);
func.toObject()->call(args, nullptr);
};
Texture2D* texture = Director::getInstance()->getTextureCache()->getTextureForKey(url);
if (texture != nullptr)
{
onSuccess(texture);
}
else
{
auto downloader = new (std::nothrow) cocos2d::network::Downloader();
downloader->onDataTaskSuccess = [downloader, url, onSuccess, onError](const cocos2d::network::DownloadTask& task, std::vector<unsigned char>& data){
Image* img = new (std::nothrow) Image();
Texture2D* tex = nullptr;
do
{
if (!img->initWithImageData(data.data(), data.size()))
break;
tex = Director::getInstance()->getTextureCache()->addImage(img, url);
} while (0);
CC_SAFE_RELEASE(img);
if (tex)
{
onSuccess(tex);
}
else
{
onError();
}
// Downloader may use its member variables after this callback,
// therefore, we need to execute `delete` operation asynchronously, otherwise crash will be triggered.
Director::getInstance()->getScheduler()->performFunctionInCocosThread([downloader](){
delete downloader;
});
};
downloader->onTaskError = [downloader, onError](const cocos2d::network::DownloadTask& task, int errorCode, int errorCodeInternal, const std::string& errorStr)
{
onError();
// Downloader may use its member variables after this callback,
// therefore, we need to execute `delete` operation asynchronously, otherwise crash will be triggered.
Director::getInstance()->getScheduler()->performFunctionInCocosThread([downloader](){
delete downloader;
});
};
downloader->createDownloadDataTask(url);
}
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", argc, 2);
return false;
}
SE_BIND_FUNC(js_cocos2dx_extension_loadRemoteImage)
static bool js_cocos2dx_extension_initRemoteImage(se::State& s)
{
const auto& args = s.args();
int argc = (int)args.size();
if (argc != 3)
{
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", argc, 3);
return false;
}
bool ok = false;
// get texture
cocos2d::Texture2D* texture = nullptr;
ok = seval_to_native_ptr(args[0], &texture);
SE_PRECONDITION2(ok, false, "Converting 'texture' failed!");
// get url
std::string url;
ok = seval_to_std_string(args[1], &url);
SE_PRECONDITION2(ok, false, "Converting 'url' failed!");
// get callback
se::Value func = args[2];
assert(func.isObject() && func.toObject()->isFunction());
func.toObject()->root();
auto onCallback = [=](bool success){
se::ScriptEngine::getInstance()->clearException();
se::AutoHandleScope hs;
se::ValueArray args;
args.resize(1);
args[0].setBoolean(success);
func.toObject()->call(args, nullptr);
};
auto downloader = new (std::nothrow) cocos2d::network::Downloader();
downloader->onDataTaskSuccess = [=](const cocos2d::network::DownloadTask& task, std::vector<unsigned char>& data)
{
bool success = false;
Image* image = new (std::nothrow) Image();
if (image->initWithImageData(data.data(), data.size()))
{
if (texture->initWithImage(image))
{
success = true;
}
else
{
CCLOGERROR("js_extension_loadRemoteImageOn: Failed to initWithImage.");
}
}
CC_SAFE_RELEASE_NULL(image);
onCallback(success);
Director::getInstance()->getScheduler()->performFunctionInCocosThread([downloader](){
delete downloader;
});
};
downloader->onTaskError = [=](const cocos2d::network::DownloadTask& task, int errorCode, int errorCodeInternal, const std::string& errorStr)
{
onCallback(false);
Director::getInstance()->getScheduler()->performFunctionInCocosThread([downloader](){
delete downloader;
});
};
downloader->createDownloadDataTask(url);
return true;
}
SE_BIND_FUNC(js_cocos2dx_extension_initRemoteImage)
static ThreadPool* _threadPool = nullptr;
static EventListenerCustom* _resetThreadPoolListener = nullptr;
static ThreadPool* getThreadPool()
{
if (_threadPool == nullptr)
{
_threadPool = ThreadPool::newSingleThreadPool();
_resetThreadPoolListener = Director::getInstance()->getEventDispatcher()->addCustomEventListener(Director::EVENT_RESET, [](cocos2d::EventCustom*){
CC_SAFE_DELETE(_threadPool);
cocos2d::Director::getInstance()->getEventDispatcher()->removeEventListener(_resetThreadPoolListener);
_resetThreadPoolListener = nullptr;
});
}
return _threadPool;
}
bool register_all_cocos2dx_extension_manual(se::Object* obj)
{
__jsbObj->defineFunction("loadRemoteImg", _SE(js_cocos2dx_extension_loadRemoteImage));
__jsbObj->defineFunction("initRemoteImg", _SE(js_cocos2dx_extension_initRemoteImage));
se::ScriptEngine::getInstance()->clearException();
return true;
}

View File

@@ -0,0 +1,32 @@
/****************************************************************************
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
namespace se {
class Object;
}
bool register_all_cocos2dx_extension_manual(se::Object* obj);

View File

@@ -0,0 +1,796 @@
/****************************************************************************
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "jsb_cocos2dx_manual.hpp"
#include "cocos/scripting/js-bindings/jswrapper/SeApi.h"
#include "cocos/scripting/js-bindings/manual/jsb_conversions.hpp"
#include "cocos/scripting/js-bindings/manual/jsb_global.h"
#include "cocos/scripting/js-bindings/auto/jsb_cocos2dx_auto.hpp"
#include "storage/local-storage/LocalStorage.h"
#include "cocos2d.h"
#include <sstream>
using namespace cocos2d;
extern se::Object* __jsb_cocos2d_FileUtils_proto;
static bool jsb_cocos2dx_empty_func(se::State& s)
{
return true;
}
SE_BIND_FUNC(jsb_cocos2dx_empty_func)
class __JSPlistDelegator: public cocos2d::SAXDelegator
{
public:
static __JSPlistDelegator* getInstance() {
static __JSPlistDelegator* pInstance = NULL;
if (pInstance == NULL) {
pInstance = new (std::nothrow) __JSPlistDelegator();
}
return pInstance;
};
virtual ~__JSPlistDelegator();
cocos2d::SAXParser* getParser();
std::string parse(const std::string& path);
std::string parseText(const std::string& text);
// implement pure virtual methods of SAXDelegator
void startElement(void *ctx, const char *name, const char **atts) override;
void endElement(void *ctx, const char *name) override;
void textHandler(void *ctx, const char *ch, int len) override;
private:
cocos2d::SAXParser _parser;
std::string _result;
bool _isStoringCharacters;
std::string _currentValue;
};
// cc.PlistParser.getInstance()
static bool js_PlistParser_getInstance(se::State& s)
{
__JSPlistDelegator* delegator = __JSPlistDelegator::getInstance();
SAXParser* parser = delegator->getParser();
if (parser) {
native_ptr_to_rooted_seval<SAXParser>(parser, __jsb_cocos2d_SAXParser_class, &s.rval());
return true;
}
return false;
}
SE_BIND_FUNC(js_PlistParser_getInstance)
// cc.PlistParser.getInstance().parse(text)
static bool js_PlistParser_parse(se::State& s)
{
const auto& args = s.args();
size_t argc = args.size();
__JSPlistDelegator* delegator = __JSPlistDelegator::getInstance();
bool ok = true;
if (argc == 1) {
std::string arg0;
ok &= seval_to_std_string(args[0], &arg0);
SE_PRECONDITION2(ok, false, "Error processing arguments");
std::string parsedStr = delegator->parseText(arg0);
std::replace(parsedStr.begin(), parsedStr.end(), '\n', ' ');
se::Value strVal;
std_string_to_seval(parsedStr, &strVal);
se::HandleObject robj(se::Object::createJSONObject(strVal.toString()));
s.rval().setObject(robj);
return true;
}
SE_REPORT_ERROR("js_PlistParser_parse : wrong number of arguments: %d, was expecting %d", (int)argc, 1);
return false;
}
SE_BIND_FUNC(js_PlistParser_parse)
cocos2d::SAXParser* __JSPlistDelegator::getParser() {
return &_parser;
}
std::string __JSPlistDelegator::parse(const std::string& path) {
_result.clear();
SAXParser parser;
if (false != parser.init("UTF-8") )
{
parser.setDelegator(this);
parser.parse(FileUtils::getInstance()->fullPathForFilename(path));
}
return _result;
}
__JSPlistDelegator::~__JSPlistDelegator(){
CCLOGINFO("deallocing __JSSAXDelegator: %p", this);
}
std::string __JSPlistDelegator::parseText(const std::string& text){
_result.clear();
SAXParser parser;
if (false != parser.init("UTF-8") )
{
parser.setDelegator(this);
parser.parse(text.c_str(), text.size());
}
return _result;
}
void __JSPlistDelegator::startElement(void *ctx, const char *name, const char **atts) {
_isStoringCharacters = true;
_currentValue.clear();
std::string elementName = (char*)name;
int end = (int)_result.size() - 1;
if(end >= 0 && _result[end] != '{' && _result[end] != '[' && _result[end] != ':') {
_result += ",";
}
if (elementName == "dict") {
_result += "{";
}
else if (elementName == "array") {
_result += "[";
}
}
void __JSPlistDelegator::endElement(void *ctx, const char *name) {
_isStoringCharacters = false;
std::string elementName = (char*)name;
if (elementName == "dict") {
_result += "}";
}
else if (elementName == "array") {
_result += "]";
}
else if (elementName == "key") {
_result += "\"" + _currentValue + "\":";
}
else if (elementName == "string") {
_result += "\"" + _currentValue + "\"";
}
else if (elementName == "false" || elementName == "true") {
_result += elementName;
}
else if (elementName == "real" || elementName == "integer") {
_result += _currentValue;
}
}
void __JSPlistDelegator::textHandler(void*, const char *ch, int len) {
std::string text((char*)ch, 0, len);
if (_isStoringCharacters)
{
_currentValue += text;
}
}
static bool register_plist_parser(se::Object* obj)
{
se::Value v;
__jsbObj->getProperty("PlistParser", &v);
assert(v.isObject());
v.toObject()->defineFunction("getInstance", _SE(js_PlistParser_getInstance));
__jsb_cocos2d_SAXParser_proto->defineFunction("parse", _SE(js_PlistParser_parse));
se::ScriptEngine::getInstance()->clearException();
return true;
}
// cc.sys.localStorage
static bool JSB_localStorageGetItem(se::State& s)
{
const auto& args = s.args();
size_t argc = args.size();
if (argc == 1)
{
std::string ret_val;
bool ok = true;
std::string key;
ok = seval_to_std_string(args[0], &key);
SE_PRECONDITION2(ok, false, "Error processing arguments");
std::string value;
ok = localStorageGetItem(key, &value);
if (ok)
s.rval().setString(value);
else
s.rval().setNull(); // Should return null to make JSB behavior same as Browser since returning undefined will make JSON.parse(undefined) trigger exception.
return true;
}
SE_REPORT_ERROR("Invalid number of arguments");
return false;
}
SE_BIND_FUNC(JSB_localStorageGetItem)
static bool JSB_localStorageRemoveItem(se::State& s)
{
const auto& args = s.args();
size_t argc = args.size();
if (argc == 1)
{
bool ok = true;
std::string key;
ok = seval_to_std_string(args[0], &key);
SE_PRECONDITION2(ok, false, "Error processing arguments");
localStorageRemoveItem(key);
return true;
}
SE_REPORT_ERROR("Invalid number of arguments");
return false;
}
SE_BIND_FUNC(JSB_localStorageRemoveItem)
static bool JSB_localStorageSetItem(se::State& s)
{
const auto& args = s.args();
size_t argc = args.size();
if (argc == 2)
{
bool ok = true;
std::string key;
ok = seval_to_std_string(args[0], &key);
SE_PRECONDITION2(ok, false, "Error processing arguments");
std::string value;
ok = seval_to_std_string(args[1], &value);
SE_PRECONDITION2(ok, false, "Error processing arguments");
localStorageSetItem(key, value);
return true;
}
SE_REPORT_ERROR("Invalid number of arguments");
return false;
}
SE_BIND_FUNC(JSB_localStorageSetItem)
static bool JSB_localStorageClear(se::State& s)
{
const auto& args = s.args();
size_t argc = args.size();
if (argc == 0)
{
localStorageClear();
return true;
}
SE_REPORT_ERROR("Invalid number of arguments");
return false;
}
SE_BIND_FUNC(JSB_localStorageClear)
static bool JSB_localStorageKey(se::State& s) {
const auto &args = s.args();
size_t argc = args.size();
if (argc == 1) {
bool ok = true;
int nIndex = 0;
ok = seval_to_int32(args[0], &nIndex);
SE_PRECONDITION2(ok, false, "Error processing arguments");
std::string value;
localStorageGetKey(nIndex, &value);
s.rval().setString(value);
return true;
}
SE_REPORT_ERROR("Invalid number of arguments");
return false;
}
SE_BIND_FUNC(JSB_localStorageKey)
static bool JSB_localStorage_getLength(se::State& s)
{
const auto& args = s.args();
size_t argc = args.size();
if (argc == 0) {
int nLength = 0;
localStorageGetLength(nLength);
s.rval().setInt32(nLength);
return true;
}
SE_REPORT_ERROR("Invalid number of arguments");
return false;
}
SE_BIND_PROP_GET(JSB_localStorage_getLength);
static bool register_sys_localStorage(se::Object* obj)
{
se::Value sys;
if (!obj->getProperty("sys", &sys))
{
se::HandleObject sysObj(se::Object::createPlainObject());
obj->setProperty("sys", se::Value(sysObj));
sys.setObject(sysObj);
}
se::HandleObject localStorageObj(se::Object::createPlainObject());
sys.toObject()->setProperty("localStorage", se::Value(localStorageObj));
localStorageObj->defineFunction("getItem", _SE(JSB_localStorageGetItem));
localStorageObj->defineFunction("removeItem", _SE(JSB_localStorageRemoveItem));
localStorageObj->defineFunction("setItem", _SE(JSB_localStorageSetItem));
localStorageObj->defineFunction("clear", _SE(JSB_localStorageClear));
localStorageObj->defineFunction("key", _SE(JSB_localStorageKey));
localStorageObj->defineProperty("length", _SE(JSB_localStorage_getLength), nullptr);
std::string strFilePath = cocos2d::FileUtils::getInstance()->getWritablePath();
strFilePath += "/jsb.sqlite";
localStorageInit(strFilePath);
se::ScriptEngine::getInstance()->addBeforeCleanupHook([](){
localStorageFree();
});
se::ScriptEngine::getInstance()->clearException();
return true;
}
#define BIND_PROP_WITH_TYPE__CONV_FUNC__RETURN(cls, property, type, convertFunc, returnFunc) \
static bool js_##cls_set_##property(se::State& s) \
{ \
cocos2d::cls* cobj = (cocos2d::cls*)s.nativeThisObject(); \
SE_PRECONDITION2(cobj, false, "js_#cls_set_#property : Invalid Native Object"); \
const auto& args = s.args(); \
size_t argc = args.size(); \
bool ok = true; \
if (argc == 1) { \
type arg0; \
ok &= convertFunc(args[0], &arg0); \
SE_PRECONDITION2(ok, false, "js_#cls_set_#property : Error processing arguments"); \
cobj->set_##property(arg0); \
return true; \
} \
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 1); \
return false; \
} \
SE_BIND_PROP_SET(js_##cls_set_##property) \
\
static bool js_##cls_get_##property(se::State& s) \
{ \
cocos2d::cls* cobj = (cocos2d::cls*)s.nativeThisObject(); \
SE_PRECONDITION2(cobj, false, "js_#cls_get_#property : Invalid Native Object"); \
s.rval().returnFunc(cobj->_##property); \
return true; \
} \
SE_BIND_PROP_GET(js_##cls_get_##property)
BIND_PROP_WITH_TYPE__CONV_FUNC__RETURN(CanvasRenderingContext2D, _width, float, seval_to_float, setFloat)
BIND_PROP_WITH_TYPE__CONV_FUNC__RETURN(CanvasRenderingContext2D, _height, float, seval_to_float, setFloat)
BIND_PROP_WITH_TYPE__CONV_FUNC__RETURN(CanvasRenderingContext2D, lineWidth, float, seval_to_float, setFloat)
BIND_PROP_WITH_TYPE__CONV_FUNC__RETURN(CanvasRenderingContext2D, lineJoin, std::string, seval_to_std_string, setString)
BIND_PROP_WITH_TYPE__CONV_FUNC__RETURN(CanvasRenderingContext2D, lineCap, std::string, seval_to_std_string, setString)
BIND_PROP_WITH_TYPE__CONV_FUNC__RETURN(CanvasRenderingContext2D, font, std::string, seval_to_std_string, setString)
BIND_PROP_WITH_TYPE__CONV_FUNC__RETURN(CanvasRenderingContext2D, textAlign, std::string, seval_to_std_string, setString)
BIND_PROP_WITH_TYPE__CONV_FUNC__RETURN(CanvasRenderingContext2D, textBaseline, std::string, seval_to_std_string, setString)
BIND_PROP_WITH_TYPE__CONV_FUNC__RETURN(CanvasRenderingContext2D, fillStyle, std::string, seval_to_std_string, setString)
BIND_PROP_WITH_TYPE__CONV_FUNC__RETURN(CanvasRenderingContext2D, strokeStyle, std::string, seval_to_std_string, setString)
BIND_PROP_WITH_TYPE__CONV_FUNC__RETURN(CanvasRenderingContext2D, globalCompositeOperation, std::string, seval_to_std_string, setString)
#define _SE_DEFINE_PROP(cls, property) \
__jsb_cocos2d_##cls##_proto->defineProperty(#property, _SE(js_##cls_get_##property), _SE(js_##cls_set_##property));
//IDEA: move to auto bindings.
static bool js_CanvasRenderingContext2D_setCanvasBufferUpdatedCallback(se::State& s)
{
cocos2d::CanvasRenderingContext2D* cobj = (cocos2d::CanvasRenderingContext2D*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_CanvasRenderingContext2D_setCanvasBufferUpdatedCallback : Invalid Native Object");
const auto& args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc == 1) {
std::function<void (const cocos2d::Data &)> arg0;
do {
if (args[0].isObject() && args[0].toObject()->isFunction())
{
se::Value jsThis(s.thisObject());
se::Value jsFunc(args[0]);
jsThis.toObject()->attachObject(jsFunc.toObject());
auto lambda = [=](const cocos2d::Data & larg0) -> void {
se::ScriptEngine::getInstance()->clearException();
se::AutoHandleScope hs;
CC_UNUSED bool ok = true;
se::ValueArray args;
args.resize(1);
ok &= Data_to_seval(larg0, &args[0]);
se::Value rval;
se::Object* thisObj = jsThis.isObject() ? jsThis.toObject() : nullptr;
se::Object* funcObj = jsFunc.toObject();
bool succeed = funcObj->call(args, thisObj, &rval);
if (!succeed) {
se::ScriptEngine::getInstance()->clearException();
}
};
// Add an unroot to avoid the root of the copy constructor caused by the internal reference of Lambda.
if (jsThis.isObject())
{
jsThis.toObject()->unroot();
}
jsFunc.toObject()->unroot();
arg0 = lambda;
}
else
{
arg0 = nullptr;
}
} while(false)
;
SE_PRECONDITION2(ok, false, "js_CanvasRenderingContext2D_setCanvasBufferUpdatedCallback : Error processing arguments");
cobj->setCanvasBufferUpdatedCallback(arg0);
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 1);
return false;
}
SE_BIND_FUNC(js_CanvasRenderingContext2D_setCanvasBufferUpdatedCallback)
static bool js_CanvasRenderingContext2D_setPremultiply(se::State& s)
{
cocos2d::CanvasRenderingContext2D* cobj = (cocos2d::CanvasRenderingContext2D*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_CanvasRenderingContext2D_setPremultiply : Invalid Native Object");
const auto& args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc == 1) {
bool arg0;
ok &= seval_to_boolean(args[0], &arg0);
SE_PRECONDITION2(ok, false, "js_CanvasRenderingContext2D_setPremultiply : Error processing arguments");
cobj->setPremultiply(arg0);
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 1);
return false;
}
SE_BIND_FUNC(js_CanvasRenderingContext2D_setPremultiply)
static se::Object* __deviceMotionObject = nullptr;
static bool JSB_getDeviceMotionValue(se::State& s)
{
if (__deviceMotionObject == nullptr)
{
__deviceMotionObject = se::Object::createArrayObject(9);
__deviceMotionObject->root();
}
const auto& v = Device::getDeviceMotionValue();
__deviceMotionObject->setArrayElement(0, se::Value(v.accelerationX));
__deviceMotionObject->setArrayElement(1, se::Value(v.accelerationY));
__deviceMotionObject->setArrayElement(2, se::Value(v.accelerationZ));
__deviceMotionObject->setArrayElement(3, se::Value(v.accelerationIncludingGravityX));
__deviceMotionObject->setArrayElement(4, se::Value(v.accelerationIncludingGravityY));
__deviceMotionObject->setArrayElement(5, se::Value(v.accelerationIncludingGravityZ));
__deviceMotionObject->setArrayElement(6, se::Value(v.rotationRateAlpha));
__deviceMotionObject->setArrayElement(7, se::Value(v.rotationRateBeta));
__deviceMotionObject->setArrayElement(8, se::Value(v.rotationRateGamma));
s.rval().setObject(__deviceMotionObject);
return true;
}
SE_BIND_FUNC(JSB_getDeviceMotionValue)
static bool register_device(se::Object* obj)
{
se::Value device;
__jsbObj->getProperty("Device", &device);
device.toObject()->defineFunction("getDeviceMotionValue", _SE(JSB_getDeviceMotionValue));
se::ScriptEngine::getInstance()->addBeforeCleanupHook([](){
if (__deviceMotionObject != nullptr)
{
__deviceMotionObject->unroot();
__deviceMotionObject->decRef();
__deviceMotionObject = nullptr;
}
});
se::ScriptEngine::getInstance()->clearException();
return true;
}
static bool register_canvas_context2d(se::Object* obj)
{
_SE_DEFINE_PROP(CanvasRenderingContext2D, _width)
_SE_DEFINE_PROP(CanvasRenderingContext2D, _height)
_SE_DEFINE_PROP(CanvasRenderingContext2D, lineWidth)
_SE_DEFINE_PROP(CanvasRenderingContext2D, lineJoin)
_SE_DEFINE_PROP(CanvasRenderingContext2D, lineCap)
_SE_DEFINE_PROP(CanvasRenderingContext2D, font)
_SE_DEFINE_PROP(CanvasRenderingContext2D, textAlign)
_SE_DEFINE_PROP(CanvasRenderingContext2D, textBaseline)
_SE_DEFINE_PROP(CanvasRenderingContext2D, fillStyle)
_SE_DEFINE_PROP(CanvasRenderingContext2D, strokeStyle)
_SE_DEFINE_PROP(CanvasRenderingContext2D, globalCompositeOperation)
__jsb_cocos2d_CanvasRenderingContext2D_proto->defineFunction("_setCanvasBufferUpdatedCallback", _SE(js_CanvasRenderingContext2D_setCanvasBufferUpdatedCallback));
__jsb_cocos2d_CanvasRenderingContext2D_proto->defineFunction("_setPremultiply", _SE(js_CanvasRenderingContext2D_setPremultiply));
se::ScriptEngine::getInstance()->clearException();
return true;
}
static bool js_engine_FileUtils_listFilesRecursively(se::State& s)
{
cocos2d::FileUtils* cobj = (cocos2d::FileUtils*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_engine_FileUtils_listFilesRecursively : Invalid Native Object");
const auto& args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc == 2) {
std::string arg0;
std::vector<std::string> arg1;
ok &= seval_to_std_string(args[0], &arg0);
SE_PRECONDITION2(ok, false, "js_engine_FileUtils_listFilesRecursively : Error processing arguments");
cobj->listFilesRecursively(arg0, &arg1);
se::Object *list = args[1].toObject();
SE_PRECONDITION2(args[1].isObject() && list->isArray(), false, "js_engine_FileUtils_listFilesRecursively : 2nd argument should be an Array");
for(int i = 0; i < arg1.size(); i++ ) {
list->setArrayElement(i, se::Value(arg1[i]));
}
list->setProperty("length", se::Value(arg1.size()));
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 2);
return false;
}
SE_BIND_FUNC(js_engine_FileUtils_listFilesRecursively)
static bool register_filetuils_ext(se::Object* obj) {
__jsb_cocos2d_FileUtils_proto->defineFunction("listFilesRecursively", _SE(js_engine_FileUtils_listFilesRecursively));
return true;
}
static bool js_se_setExceptionCallback(se::State &s) {
auto &args = s.args();
if (args.size() != 1 || !args[0].isObject() || !args[0].toObject()->isFunction()) {
SE_REPORT_ERROR("expect 1 arguments of Function type, %d provided", (int)args.size());
return false;
}
se::Object *objFunc = args[0].toObject();
// se::Value::reset will invoke decRef() while destroying s.args()
// increase ref here
objFunc->incRef();
if (s.thisObject()) {
s.thisObject()->attachObject(objFunc); // prevent GC
} else {
//prevent GC in C++ & JS
objFunc->root();
}
se::ScriptEngine::getInstance()->setJSExceptionCallback([objFunc](const char *location, const char *message, const char *stack) {
se::ValueArray jsArgs;
jsArgs.resize(3);
jsArgs[0] = se::Value(location);
jsArgs[1] = se::Value(message);
jsArgs[2] = se::Value(stack);
objFunc->call(jsArgs, nullptr);
});
return true;
}
SE_BIND_FUNC(js_se_setExceptionCallback)
#define DESCRIPT_FIELD(kls, field, field_type) do {\
ss << "\"" << #field << "\": " << "{" ; \
ss << "\"type\": \"" << field_type << "\"," ; \
ss << "\"offset\": " << offsetof(kls, field) << ","; \
ss << "\"size\": " << sizeof(((kls*)nullptr)->field); \
ss << "}";} while(false)
static bool js_engine_LabelRenderer_init(se::State& s)
{
cocos2d::LabelRenderer* cobj = (cocos2d::LabelRenderer*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_engine_LabelRenderer_init : Invalid Native Object");
const auto& args = s.args();
size_t argc = args.size();
se::Object *self = s.thisObject();
CC_UNUSED bool ok = true;
if (argc == 1 && args[0].isObject()) {
se::Object *comp = args[0].toObject();
cocos2d::LabelRenderer::LabelRendererConfig config;
cocos2d::LabelLayoutInfo layout;
se::Object *cfgBufferObj = se::Object::createArrayBufferObject(nullptr, sizeof(config));
se::Object *layoutBufferObj = se::Object::createArrayBufferObject(nullptr, sizeof(layout));
// attach to js object
self->setProperty("_cfg", se::Value(cfgBufferObj));
self->setProperty("_layout", se::Value(layoutBufferObj));
// attach to C++ object
size_t len;
uint8_t *pcfg = nullptr, *playout = nullptr;
cfgBufferObj->getArrayBufferData(&pcfg, &len);
layoutBufferObj->getArrayBufferData(&playout, &len);
new (pcfg) cocos2d::LabelRenderer::LabelRendererConfig();
new (playout) cocos2d::LabelLayoutInfo();
cobj->bindSharedBlock(self, pcfg, playout);
cobj->setJsComponent(comp);
cfgBufferObj->decRef();
layoutBufferObj->decRef();
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 1);
return false;
}
SE_BIND_FUNC(js_engine_LabelRenderer_init)
static void js_engine_LabelRenderer_export_structs_info(se::Object *obj)
{
// Get the ns
se::Value nsVal;
if (!obj->getProperty("jsb", &nsVal))
{
se::HandleObject jsobj(se::Object::createPlainObject());
nsVal.setObject(jsobj);
obj->setProperty("jsb", nsVal);
}
se::Object* ns = nsVal.toObject();
se::Value labelRenderValue;
ns->getProperty("LabelRenderer", &labelRenderValue);
assert(labelRenderValue.isObject());
se::Object *self = labelRenderValue.toObject();
{
union endianess_union {
int32_t i32;
uint8_t bytes[4];
} test_value;
test_value.i32 = 0x01020304;
bool isLittleEndian = test_value.bytes[0] == 0x04;
ns->setProperty("__isLittleEndian__", se::Value(isLittleEndian));
}
{
std::stringstream ss;
ss << "{";
DESCRIPT_FIELD(cocos2d::LabelRenderer::LabelRendererConfig, updateFlags, "int32");
ss << ",";
DESCRIPT_FIELD(cocos2d::LabelRenderer::LabelRendererConfig, fontSize, "float");
ss << ",";
DESCRIPT_FIELD(cocos2d::LabelRenderer::LabelRendererConfig, fontSizeRetina, "float");
ss << "}";
se::Object *cfgFields = se::Object::createJSONObject(ss.str());
assert(cfgFields);
self->setProperty("_cfgFields", se::Value(cfgFields));
cfgFields->decRef();
}
{
std::stringstream ss;
ss << "{";
DESCRIPT_FIELD(cocos2d::LabelLayoutInfo, lineHeight, "float");
ss << "," ;
DESCRIPT_FIELD(cocos2d::LabelLayoutInfo, outlineSize, "float");
ss << "," ;
DESCRIPT_FIELD(cocos2d::LabelLayoutInfo, spaceX, "float");
ss << "," ;
DESCRIPT_FIELD(cocos2d::LabelLayoutInfo, width, "float");
ss << "," ;
DESCRIPT_FIELD(cocos2d::LabelLayoutInfo, height, "float");
ss << "," ;
DESCRIPT_FIELD(cocos2d::LabelLayoutInfo, anchorX, "float");
ss << "," ;
DESCRIPT_FIELD(cocos2d::LabelLayoutInfo, anchorY, "float");
ss << "," ;
DESCRIPT_FIELD(cocos2d::LabelLayoutInfo, shadowX, "float");
ss << "," ;
DESCRIPT_FIELD(cocos2d::LabelLayoutInfo, shadowY, "float");
ss << "," ;
DESCRIPT_FIELD(cocos2d::LabelLayoutInfo, shadowBlur, "int32");
ss << "," ;
DESCRIPT_FIELD(cocos2d::LabelLayoutInfo, shadowColor, "Color4B");
ss << "," ;
DESCRIPT_FIELD(cocos2d::LabelLayoutInfo, color, "Color4B");
ss << "," ;
DESCRIPT_FIELD(cocos2d::LabelLayoutInfo, outlineColor, "Color4B");
ss << "," ;
DESCRIPT_FIELD(cocos2d::LabelLayoutInfo, wrap, "bool");
ss << "," ;
DESCRIPT_FIELD(cocos2d::LabelLayoutInfo, bold, "bool");
ss << "," ;
DESCRIPT_FIELD(cocos2d::LabelLayoutInfo, italic, "bool");
ss << "," ;
DESCRIPT_FIELD(cocos2d::LabelLayoutInfo, underline, "bool");
ss << "," ;
DESCRIPT_FIELD(cocos2d::LabelLayoutInfo, valign, "int8");
ss << "," ;
DESCRIPT_FIELD(cocos2d::LabelLayoutInfo, halign, "int8");
ss << "," ;
DESCRIPT_FIELD(cocos2d::LabelLayoutInfo, overflow, "int8");
ss << "}";
se::Object *cfgFields = se::Object::createJSONObject(ss.str());
assert(cfgFields);
self->setProperty("_layoutFields", se::Value(cfgFields));
cfgFields->decRef();
}
}
static bool register_labelrenderer_ext(se::Object *obj)
{
__jsb_cocos2d_LabelRenderer_proto->defineFunction("init", _SE(js_engine_LabelRenderer_init));
js_engine_LabelRenderer_export_structs_info(obj);
return true;
}
static bool register_se_setExceptionCallback(se::Object *obj)
{
se::Value jsb;
if (!obj->getProperty("jsb", &jsb)) {
jsb.setObject(se::Object::createPlainObject());
obj->setProperty("jsb", jsb);
}
auto *jsbObj = jsb.toObject();
jsbObj->defineFunction("onError", _SE(js_se_setExceptionCallback));
return true;
}
bool register_all_cocos2dx_manual(se::Object* obj)
{
register_plist_parser(obj);
register_sys_localStorage(obj);
register_device(obj);
register_canvas_context2d(obj);
register_filetuils_ext(obj);
register_labelrenderer_ext(obj);
register_se_setExceptionCallback(obj);
return true;
}

View File

@@ -0,0 +1,32 @@
/****************************************************************************
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
namespace se {
class Object;
}
bool register_all_cocos2dx_manual(se::Object* obj);

View File

@@ -0,0 +1,193 @@
/****************************************************************************
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "base/ccConfig.h"
#include "jsb_cocos2dx_network_manual.h"
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_MAC || CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
#include "scripting/js-bindings/manual/jsb_conversions.hpp"
#include "scripting/js-bindings/manual/jsb_global.h"
#include "network/CCDownloader.h"
#include "scripting/js-bindings/auto/jsb_cocos2dx_network_auto.hpp"
static bool js_cocos2dx_network_Downloader_createDownloadFileTask(se::State &s) {
cocos2d::network::Downloader *cobj = (cocos2d::network::Downloader *) s.nativeThisObject();
SE_PRECONDITION2(cobj, false,
"js_network_Downloader_createDownloadFileTask : Invalid Native Object");
const auto &args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc == 2) {
std::string arg0;
std::string arg1;
ok &= seval_to_std_string(args[0], &arg0);
ok &= seval_to_std_string(args[1], &arg1);
SE_PRECONDITION2(ok, false,
"js_network_Downloader_createDownloadFileTask : Error processing arguments");
std::shared_ptr<const cocos2d::network::DownloadTask> result = cobj->createDownloadFileTask(
arg0, arg1);
ok &= DownloadTask_to_seval(*result, &s.rval());
//ROOT downloader object
s.thisObject()->root();
SE_PRECONDITION2(ok, false,
"js_network_Downloader_createDownloadFileTask : Error processing arguments");
return true;
}
if (argc == 3) {
std::string arg0;
std::string arg1;
std::string arg2;
ok &= seval_to_std_string(args[0], &arg0);
ok &= seval_to_std_string(args[1], &arg1);
ok &= seval_to_std_string(args[2], &arg2);
SE_PRECONDITION2(ok, false,
"js_network_Downloader_createDownloadFileTask : Error processing arguments");
std::shared_ptr<const cocos2d::network::DownloadTask> result = cobj->createDownloadFileTask(
arg0, arg1, arg2);
ok &= DownloadTask_to_seval(*result, &s.rval());
//ROOT downloader object
s.thisObject()->root();
SE_PRECONDITION2(ok, false,
"js_network_Downloader_createDownloadFileTask : Error processing arguments");
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int) argc, 3);
return false;
}
SE_BIND_FUNC(js_cocos2dx_network_Downloader_createDownloadFileTask)
static bool js_network_Downloader_setOnFileTaskSuccess(se::State& s)
{
cocos2d::network::Downloader* cobj = (cocos2d::network::Downloader*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_network_Downloader_setOnFileTaskSuccess : Invalid Native Object");
const auto& args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc == 1) {
std::function<void(const cocos2d::network::DownloadTask &)> arg0;
do {
if (args[0].isObject() && args[0].toObject()->isFunction())
{
se::Value jsThis(s.thisObject());
se::Value jsFunc(args[0]);
jsThis.toObject()->attachObject(jsFunc.toObject());
auto lambda = [=](const cocos2d::network::DownloadTask & larg0) -> void {
se::ScriptEngine::getInstance()->clearException();
se::AutoHandleScope hs;
CC_UNUSED bool ok = true;
se::ValueArray args;
args.resize(1);
ok &= DownloadTask_to_seval(larg0, &args[0]);
se::Value rval;
se::Object* thisObj = jsThis.isObject() ? jsThis.toObject() : nullptr;
se::Object* funcObj = jsFunc.toObject();
bool succeed = funcObj->call(args, thisObj, &rval);
if (!succeed) {
se::ScriptEngine::getInstance()->clearException();
}
thisObj->unroot();
};
arg0 = lambda;
}
else
{
arg0 = nullptr;
}
} while (false)
;
SE_PRECONDITION2(ok, false, "js_network_Downloader_setOnFileTaskSuccess : Error processing arguments");
cobj->setOnFileTaskSuccess(arg0);
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 1);
return false;
}
SE_BIND_FUNC(js_network_Downloader_setOnFileTaskSuccess)
static bool js_network_Downloader_setOnTaskError(se::State& s)
{
cocos2d::network::Downloader* cobj = (cocos2d::network::Downloader*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_network_Downloader_setOnTaskError : Invalid Native Object");
const auto& args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc == 1) {
std::function<void(const cocos2d::network::DownloadTask &, int, int, const std::string&)> arg0;
do {
if (args[0].isObject() && args[0].toObject()->isFunction())
{
se::Value jsThis(s.thisObject());
se::Value jsFunc(args[0]);
jsThis.toObject()->attachObject(jsFunc.toObject());
auto lambda = [=](const cocos2d::network::DownloadTask & larg0, int larg1, int larg2, const std::string& larg3) -> void {
se::ScriptEngine::getInstance()->clearException();
se::AutoHandleScope hs;
CC_UNUSED bool ok = true;
se::ValueArray args;
args.resize(4);
ok &= DownloadTask_to_seval(larg0, &args[0]);
ok &= int32_to_seval(larg1, &args[1]);
ok &= int32_to_seval(larg2, &args[2]);
ok &= std_string_to_seval(larg3, &args[3]);
se::Value rval;
se::Object* thisObj = jsThis.isObject() ? jsThis.toObject() : nullptr;
se::Object* funcObj = jsFunc.toObject();
bool succeed = funcObj->call(args, thisObj, &rval);
if (!succeed) {
se::ScriptEngine::getInstance()->clearException();
}
thisObj->unroot();
};
arg0 = lambda;
}
else
{
arg0 = nullptr;
}
} while (false)
;
SE_PRECONDITION2(ok, false, "js_network_Downloader_setOnTaskError : Error processing arguments");
cobj->setOnTaskError(arg0);
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 1);
return false;
}
SE_BIND_FUNC(js_network_Downloader_setOnTaskError)
bool register_all_cocos2dx_network_manual(se::Object *obj) {
__jsb_cocos2d_network_Downloader_proto->defineFunction("createDownloadFileTask",
_SE(js_cocos2dx_network_Downloader_createDownloadFileTask));
__jsb_cocos2d_network_Downloader_proto->defineFunction("setOnTaskError",
_SE(js_network_Downloader_setOnTaskError));
__jsb_cocos2d_network_Downloader_proto->defineFunction("setOnFileTaskSuccess",
_SE(js_network_Downloader_setOnFileTaskSuccess));
return true;
}
#endif //#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_MAC || CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)

View File

@@ -0,0 +1,32 @@
/****************************************************************************
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
namespace se {
class Object;
}
bool register_all_cocos2dx_network_manual(se::Object* obj);

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,684 @@
/****************************************************************************
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
#include "scripting/js-bindings/jswrapper/SeApi.h"
#include "scripting/js-bindings/manual/jsb_classtype.hpp"
#include "cocos2d.h"
#include "renderer/gfx/GFX.h"
#include "renderer/renderer/Renderer.h"
#include "network/CCDownloader.h"
#include "extensions/cocos-ext.h"
#if USE_SPINE
#include "cocos/editor-support/spine/spine.h"
#endif
//#include "Box2D/Box2D.h"
#define SE_PRECONDITION2_VOID(condition, ...) \
do { \
if ( ! (condition) ) { \
SE_LOGE("jsb: ERROR: File %s: Line: %d, Function: %s\n", __FILE__, __LINE__, __FUNCTION__ ); \
SE_LOGE(__VA_ARGS__); \
return; \
} \
} while(0)
#define SE_PRECONDITION2(condition, ret_value, ...) \
do { \
if ( ! (condition) ) { \
SE_LOGE("jsb: ERROR: File %s: Line: %d, Function: %s\n", __FILE__, __LINE__, __FUNCTION__ ); \
SE_LOGE(__VA_ARGS__); \
return (ret_value); \
} \
} while(0)
#define SE_PRECONDITION3(condition, ret_value, failed_code) \
do { \
if (!(condition)) \
{ \
failed_code; \
return (ret_value); \
} \
} while(0)
#define SE_PRECONDITION4(condition, ret_value, errorCode) \
do { \
if ( ! (condition) ) { \
SE_LOGE("jsb: ERROR: File %s: Line: %d, Function: %s\n", __FILE__, __LINE__, __FUNCTION__ ); \
__glErrorCode = errorCode; \
return (ret_value); \
} \
} while(0)
#define SE_PRECONDITION_ERROR_BREAK(condition, ...) \
if ( ! (condition) ) { \
SE_LOGE("jsb: ERROR: File %s: Line: %d, Function: %s\n", __FILE__, __LINE__, __FUNCTION__ ); \
SE_LOGE(__VA_ARGS__); \
break; \
}
// se value -> native value
bool seval_to_int32(const se::Value& v, int32_t* ret);
bool seval_to_uint32(const se::Value& v, uint32_t* ret);
bool seval_to_int8(const se::Value& v, int8_t* ret);
bool seval_to_uint8(const se::Value& v, uint8_t* ret);
bool seval_to_int16(const se::Value& v, int16_t* ret);
bool seval_to_uint16(const se::Value& v, uint16_t* ret);
bool seval_to_boolean(const se::Value& v, bool* ret);
bool seval_to_float(const se::Value& v, float* ret);
bool seval_to_double(const se::Value& v, double* ret);
bool seval_to_long(const se::Value& v, long* ret);
bool seval_to_ulong(const se::Value& v, unsigned long* ret);
bool seval_to_longlong(const se::Value& v, long long* ret);
bool seval_to_ssize(const se::Value& v, ssize_t* ret);
bool seval_to_size(const se::Value& v, size_t* ret);
bool seval_to_std_string(const se::Value& v, std::string* ret);
bool seval_to_Vec2(const se::Value& v, cocos2d::Vec2* pt);
bool seval_to_Vec3(const se::Value& v, cocos2d::Vec3* pt);
bool seval_to_Vec4(const se::Value& v, cocos2d::Vec4* pt);
bool seval_to_Mat4(const se::Value& v, cocos2d::Mat4* mat);
bool seval_to_Size(const se::Value& v, cocos2d::Size* size);
bool seval_to_Color3B(const se::Value& v, cocos2d::Color3B* color);
bool seval_to_Color4B(const se::Value& v, cocos2d::Color4B* color);
bool seval_to_Color3F(const se::Value& v, cocos2d::Color3F* color);
bool seval_to_Color4F(const se::Value& v, cocos2d::Color4F* color);
bool seval_to_ccvalue(const se::Value& v, cocos2d::Value* ret);
bool seval_to_ccvaluemap(const se::Value& v, cocos2d::ValueMap* ret);
bool seval_to_ccvaluemapintkey(const se::Value& v, cocos2d::ValueMapIntKey* ret);
bool seval_to_ccvaluevector(const se::Value& v, cocos2d::ValueVector* ret);
bool sevals_variadic_to_ccvaluevector(const se::ValueArray& args, cocos2d::ValueVector* ret);
bool seval_to_blendfunc(const se::Value& v, cocos2d::BlendFunc* ret);
bool seval_to_std_vector_string(const se::Value& v, std::vector<std::string>* ret);
bool seval_to_std_vector_int(const se::Value& v, std::vector<int>* ret);
bool seval_to_std_vector_uint16(const se::Value& v, std::vector<uint16_t>* ret);
bool seval_to_std_vector_float(const se::Value& v, std::vector<float>* ret);
bool seval_to_std_vector_Vec2(const se::Value& v, std::vector<cocos2d::Vec2>* ret);
//bool seval_to_Rect(const se::Value& v, cocos2d::Rect* rect);
//bool seval_to_std_vector_Touch(const se::Value& v, std::vector<cocos2d::Touch*>* ret);
bool seval_to_std_map_string_string(const se::Value& v, std::map<std::string, std::string>* ret);
//bool seval_to_Quaternion(const se::Value& v, cocos2d::Quaternion* ret);
//bool seval_to_AffineTransform(const se::Value& v, cocos2d::AffineTransform* ret);
////bool seval_to_Viewport(const se::Value& v, cocos2d::experimental::Viewport* ret);
bool seval_to_Data(const se::Value& v, cocos2d::Data* ret);
bool seval_to_DownloaderHints(const se::Value& v, cocos2d::network::DownloaderHints* ret);
//bool seval_to_TTFConfig(const se::Value& v, cocos2d::TTFConfig* ret);
//box2d seval to native convertion
//bool seval_to_b2Vec2(const se::Value& v, b2Vec2* ret);
//bool seval_to_b2AABB(const se::Value& v, b2AABB* ret);
#if USE_GFX_RENDERER
bool seval_to_Rect(const se::Value& v, cocos2d::renderer::Rect* rect);
bool seval_to_std_vector_Texture(const se::Value& v, std::vector<cocos2d::renderer::Texture*>* ret);
bool seval_to_std_vector_RenderTarget(const se::Value& v, std::vector<cocos2d::renderer::RenderTarget*>* ret);
bool seval_to_TextureOptions(const se::Value& v, cocos2d::renderer::Texture::Options* ret);
bool seval_to_TextureSubImageOption(const se::Value& v, cocos2d::renderer::Texture::SubImageOption* ret);
bool seval_to_TextureImageOption(const se::Value& v, cocos2d::renderer::Texture::ImageOption* ret);
bool seval_to_EffectProperty(const se::Value& v, std::unordered_map<size_t, cocos2d::renderer::Effect::Property>* ret);
bool seval_to_EffectTechnique(const se::Value& v, cocos2d::renderer::Technique** ret);
bool seval_to_EffectDefineTemplate(const se::Value& v, std::vector<cocos2d::ValueMap>* ret);
bool seval_to_Effect_setProperty(std::string& name, const se::Value& v, cocos2d::renderer::EffectBase* effect, int passIdx = -1, bool directly = false);
bool seval_to_TechniqueParameter(const se::Value& v, cocos2d::renderer::Technique::Parameter* ret);
bool seval_to_std_vector_TechniqueParameter(const se::Value& v, std::vector<cocos2d::renderer::Technique::Parameter>* ret);
bool seval_to_std_vector_ProgramLib_Template(const se::Value& v, std::vector<cocos2d::renderer::ProgramLib::Template>* ret);
bool std_vector_RenderTarget_to_seval(const std::vector<cocos2d::renderer::RenderTarget*>& v, se::Value* ret);
bool seval_to_EffectAsset(const se::Value& v, cocos2d::Vector<cocos2d::renderer::Technique*>* ret);
bool ccvaluevector_to_EffectPass(const cocos2d::ValueVector& v, cocos2d::Vector<cocos2d::renderer::Pass*>* passes);
#endif
template<typename T>
bool seval_to_native_ptr(const se::Value& v, T* ret)
{
assert(ret != nullptr);
if (v.isObject())
{
T ptr = (T)v.toObject()->getPrivateData();
if (ptr == nullptr)
{
// This should never happen, return 'false' to mark the conversion fails.
*ret = nullptr;
return false;
}
*ret = ptr;
return true;
}
else if (v.isNullOrUndefined())
{
// If js value is null or undefined, the convertion should be successful.
// So we should return 'true' to indicate the convertion succeeds and mark
// the out value to 'nullptr'.
*ret = nullptr;
return true;
}
// If js value isn't null, undefined and Object, mark the convertion fails.
*ret = nullptr;
return false;
}
template<typename T>
bool seval_to_Vector(const se::Value& v, cocos2d::Vector<T>* ret)
{
assert(ret != nullptr);
assert(v.isObject());
se::Object* obj = v.toObject();
assert(obj->isArray());
bool ok = true;
uint32_t len = 0;
ok = obj->getArrayLength(&len);
if (!ok)
{
ret->clear();
return false;
}
se::Value tmp;
for (uint32_t i = 0; i < len; ++i)
{
ok = obj->getArrayElement(i, &tmp);
if (!ok || !tmp.isObject())
{
ret->clear();
return false;
}
T nativeObj = (T)tmp.toObject()->getPrivateData();
ret->pushBack(nativeObj);
}
return true;
}
template<typename T>
bool seval_to_Map_string_key(const se::Value& v, cocos2d::Map<std::string, T>* ret)
{
assert(ret != nullptr);
assert(v.isObject());
se::Object* obj = v.toObject();
std::vector<std::string> allKeys;
bool ok = obj->getAllKeys(&allKeys);
if (!ok)
{
ret->clear();
return false;
}
se::Value tmp;
for (const auto& key : allKeys)
{
ok = obj->getProperty(key.c_str(), &tmp);
if (!ok || !tmp.isObject())
{
ret->clear();
return false;
}
T nativeObj = (T)tmp.toObject()->getPrivateData();
ret->insert(key, nativeObj);
}
return true;
}
// native value -> se value
bool int8_to_seval(int8_t v, se::Value* ret);
bool uint8_to_seval(uint8_t v, se::Value* ret);
bool int32_to_seval(int32_t v, se::Value* ret);
bool uint32_to_seval(uint32_t v, se::Value* ret);
bool int16_to_seval(uint16_t v, se::Value* ret);
bool uint16_to_seval(uint16_t v, se::Value* ret);
bool boolean_to_seval(bool v, se::Value* ret);
bool float_to_seval(float v, se::Value* ret);
bool double_to_seval(double v, se::Value* ret);
bool long_to_seval(long v, se::Value* ret);
bool ulong_to_seval(unsigned long v, se::Value* ret);
bool longlong_to_seval(long long v, se::Value* ret);
bool ssize_to_seval(ssize_t v, se::Value* ret);
bool size_to_seval(size_t v, se::Value* ret);
bool std_string_to_seval(const std::string& v, se::Value* ret);
bool Vec2_to_seval(const cocos2d::Vec2& v, se::Value* ret);
bool Vec3_to_seval(const cocos2d::Vec3& v, se::Value* ret);
bool Vec4_to_seval(const cocos2d::Vec4& v, se::Value* ret);
bool Mat4_to_seval(const cocos2d::Mat4& v, se::Value* ret);
bool Size_to_seval(const cocos2d::Size& v, se::Value* ret);
bool Rect_to_seval(const cocos2d::Rect& v, se::Value* ret);
bool Color3B_to_seval(const cocos2d::Color3B& v, se::Value* ret);
bool Color4B_to_seval(const cocos2d::Color4B& v, se::Value* ret);
bool Color3F_to_seval(const cocos2d::Color3F& v, se::Value* ret);
bool Color4F_to_seval(const cocos2d::Color4F& v, se::Value* ret);
bool ccvalue_to_seval(const cocos2d::Value& v, se::Value* ret);
bool ccvaluemap_to_seval(const cocos2d::ValueMap& v, se::Value* ret);
bool ccvaluemapintkey_to_seval(const cocos2d::ValueMapIntKey& v, se::Value* ret);
bool ccvaluevector_to_seval(const cocos2d::ValueVector& v, se::Value* ret);
bool blendfunc_to_seval(const cocos2d::BlendFunc& v, se::Value* ret);
bool std_vector_string_to_seval(const std::vector<std::string>& v, se::Value* ret);
bool std_vector_int_to_seval(const std::vector<int>& v, se::Value* ret);
bool std_vector_uint16_to_seval(const std::vector<uint16_t>& v, se::Value* ret);
bool std_vector_float_to_seval(const std::vector<float>& v, se::Value* ret);
//bool std_vector_Touch_to_seval(const std::vector<cocos2d::Touch*>& v, se::Value* ret);
bool std_map_string_string_to_seval(const std::map<std::string, std::string>& v, se::Value* ret);
//bool uniform_to_seval(const cocos2d::Uniform* v, se::Value* ret);
//bool Quaternion_to_seval(const cocos2d::Quaternion& v, se::Value* ret);
bool ManifestAsset_to_seval(const cocos2d::extension::ManifestAsset& v, se::Value* ret);
//bool AffineTransform_to_seval(const cocos2d::AffineTransform& v, se::Value* ret);
////bool Viewport_to_seval(const cocos2d::experimental::Viewport& v, se::Value* ret);
bool Data_to_seval(const cocos2d::Data& v, se::Value* ret);
bool DownloadTask_to_seval(const cocos2d::network::DownloadTask& v, se::Value* ret);
bool std_vector_EffectDefine_to_seval(const std::vector<cocos2d::ValueMap>& v, se::Value* ret);
#if USE_GFX_RENDERER
bool Rect_to_seval(const cocos2d::renderer::Rect& v, se::Value* ret);
bool std_unorderedmap_string_EffectProperty_to_seval(const std::unordered_map<std::string, cocos2d::renderer::Effect::Property>& v, se::Value* ret);
bool EffectProperty_to_seval(const cocos2d::renderer::Effect::Property& v, se::Value* ret);
bool VertexFormat_to_seval(const cocos2d::renderer::VertexFormat& v, se::Value* ret);
bool TechniqueParameter_to_seval(const cocos2d::renderer::Technique::Parameter& v, se::Value* ret);
bool std_vector_TechniqueParameter_to_seval(const std::vector<cocos2d::renderer::Technique::Parameter>& v, se::Value* ret);
#endif
template<typename T>
bool native_ptr_to_seval(typename std::enable_if<!std::is_base_of<cocos2d::Ref,T>::value,T>::type* v, se::Value* ret, bool* isReturnCachedValue = nullptr)
{
assert(ret != nullptr);
if (v == nullptr)
{
ret->setNull();
return true;
}
se::Object* obj = nullptr;
auto iter = se::NativePtrToObjectMap::find(v);
if (iter == se::NativePtrToObjectMap::end())
{ // If we couldn't find native object in map, then the native object is created from native code. e.g. TMXLayer::getTileAt
// CCLOGWARN("WARNING: non-Ref type: (%s) isn't catched!", typeid(*v).name());
se::Class* cls = JSBClassType::findClass<T>(v);
assert(cls != nullptr);
obj = se::Object::createObjectWithClass(cls);
ret->setObject(obj, true);
obj->setPrivateData(v);
if (isReturnCachedValue != nullptr)
{
*isReturnCachedValue = false;
}
}
else
{
obj = iter->second;
if (isReturnCachedValue != nullptr)
{
*isReturnCachedValue = true;
}
ret->setObject(obj);
}
return true;
}
template<typename T>
bool native_ptr_to_rooted_seval(const typename std::enable_if<!std::is_base_of<cocos2d::Ref,T>::value,T>::type* v, se::Value* ret, bool* isReturnCachedValue = nullptr)
{
assert(ret != nullptr);
if (v == nullptr)
{
ret->setNull();
return true;
}
se::Object* obj = nullptr;
auto iter = se::NativePtrToObjectMap::find((void*)v);
if (iter == se::NativePtrToObjectMap::end())
{ // If we couldn't find native object in map, then the native object is created from native code. e.g. TMXLayer::getTileAt
se::Class* cls = JSBClassType::findClass<T>(v);
assert(cls != nullptr);
obj = se::Object::createObjectWithClass(cls);
obj->root();
obj->setPrivateData((void*)v);
if (isReturnCachedValue != nullptr)
{
*isReturnCachedValue = false;
}
// CCLOGWARN("WARNING: non-Ref type: (%s) isn't catched!", typeid(*v).name());
}
else
{
obj = iter->second;
assert(obj->isRooted());
if (isReturnCachedValue != nullptr)
{
*isReturnCachedValue = true;
}
// CCLOG("return cached object: %s, se::Object:%p, native: %p", typeid(*v).name(), obj, v);
}
ret->setObject(obj);
return true;
}
template<typename T>
bool native_ptr_to_seval(typename std::enable_if<!std::is_base_of<cocos2d::Ref,T>::value,T>::type* v, se::Class* cls, se::Value* ret, bool* isReturnCachedValue = nullptr)
{
assert(ret != nullptr);
if (v == nullptr)
{
ret->setNull();
return true;
}
se::Object* obj = nullptr;
auto iter = se::NativePtrToObjectMap::find(v);
if (iter == se::NativePtrToObjectMap::end())
{ // If we couldn't find native object in map, then the native object is created from native code. e.g. TMXLayer::getTileAt
// CCLOGWARN("WARNING: Ref type: (%s) isn't catched!", typeid(*v).name());
assert(cls != nullptr);
obj = se::Object::createObjectWithClass(cls);
ret->setObject(obj, true);
obj->setPrivateData(v);
if (isReturnCachedValue != nullptr)
{
*isReturnCachedValue = false;
}
}
else
{
obj = iter->second;
if (isReturnCachedValue != nullptr)
{
*isReturnCachedValue = true;
}
ret->setObject(obj);
}
return true;
}
template<typename T>
bool native_ptr_to_rooted_seval(typename std::enable_if<!std::is_base_of<cocos2d::Ref,T>::value,T>::type* v, se::Class* cls, se::Value* ret, bool* isReturnCachedValue = nullptr)
{
assert(ret != nullptr);
if (v == nullptr)
{
ret->setNull();
return true;
}
se::Object* obj = nullptr;
auto iter = se::NativePtrToObjectMap::find(v);
if (iter == se::NativePtrToObjectMap::end())
{ // If we couldn't find native object in map, then the native object is created from native code. e.g. TMXLayer::getTileAt
assert(cls != nullptr);
obj = se::Object::createObjectWithClass(cls);
obj->root();
obj->setPrivateData(v);
if (isReturnCachedValue != nullptr)
{
*isReturnCachedValue = false;
}
// CCLOGWARN("WARNING: non-Ref type: (%s) isn't catched, se::Object:%p, native: %p", typeid(*v).name(), obj, v);
}
else
{
obj = iter->second;
assert(obj->isRooted());
if (isReturnCachedValue != nullptr)
{
*isReturnCachedValue = true;
}
// CCLOG("return cached object: %s, se::Object:%p, native: %p", typeid(*v).name(), obj, v);
}
ret->setObject(obj);
return true;
}
template<typename T>
bool native_ptr_to_seval(typename std::enable_if<std::is_base_of<cocos2d::Ref,T>::value,T>::type* v, se::Value* ret, bool* isReturnCachedValue = nullptr)
{
assert(ret != nullptr);
if (v == nullptr)
{
ret->setNull();
return true;
}
se::Object* obj = nullptr;
auto iter = se::NativePtrToObjectMap::find(v);
if (iter == se::NativePtrToObjectMap::end())
{ // If we couldn't find native object in map, then the native object is created from native code. e.g. TMXLayer::getTileAt
// CCLOGWARN("WARNING: Ref type: (%s) isn't catched!", typeid(*v).name());
se::Class* cls = JSBClassType::findClass<T>(v);
assert(cls != nullptr);
obj = se::Object::createObjectWithClass(cls);
ret->setObject(obj, true);
obj->setPrivateData(v);
v->retain(); // Retain the native object to unify the logic in finalize method of js object.
if (isReturnCachedValue != nullptr)
{
*isReturnCachedValue = false;
}
}
else
{
obj = iter->second;
// CCLOG("INFO: Found Ref type: (%s, native: %p, se: %p) from cache!", typeid(*v).name(), v, obj);
if (isReturnCachedValue != nullptr)
{
*isReturnCachedValue = true;
}
ret->setObject(obj);
}
return true;
}
template<typename T>
bool native_ptr_to_seval(typename std::enable_if<std::is_base_of<cocos2d::Ref,T>::value,T>::type* v, se::Class* cls, se::Value* ret, bool* isReturnCachedValue = nullptr)
{
assert(ret != nullptr);
if (v == nullptr)
{
ret->setNull();
return true;
}
se::Object* obj = nullptr;
auto iter = se::NativePtrToObjectMap::find(v);
if (iter == se::NativePtrToObjectMap::end())
{ // If we couldn't find native object in map, then the native object is created from native code. e.g. TMXLayer::getTileAt
// CCLOGWARN("WARNING: Ref type: (%s) isn't catched!", typeid(*v).name());
assert(cls != nullptr);
obj = se::Object::createObjectWithClass(cls);
ret->setObject(obj, true);
obj->setPrivateData(v);
v->retain(); // Retain the native object to unify the logic in finalize method of js object.
if (isReturnCachedValue != nullptr)
{
*isReturnCachedValue = false;
}
}
else
{
obj = iter->second;
if (isReturnCachedValue != nullptr)
{
*isReturnCachedValue = true;
}
ret->setObject(obj);
}
return true;
}
template<typename T>
bool Vector_to_seval(const cocos2d::Vector<T*>& v, se::Value* ret)
{
assert(ret != nullptr);
bool ok = true;
se::HandleObject obj(se::Object::createArrayObject(v.size()));
uint32_t i = 0;
se::Value tmp;
for (const auto& e : v)
{
native_ptr_to_seval<T>(e, &tmp);
obj->setArrayElement(i, tmp);
++i;
}
ret->setObject(obj, true);
return ok;
}
//
//template<typename T>
//bool Map_string_key_to_seval(const cocos2d::Map<std::string, T*>& v, se::Value* ret)
//{
// assert(ret != nullptr);
//
// se::HandleObject obj(se::Object::createPlainObject());
//
// se::Value tmp;
// for (const auto& e : v)
// {
// native_ptr_to_seval<T>(e.second, &tmp);
// obj->setProperty(e.first.c_str(), tmp);
// }
//
// ret->setObject(obj, true);
// return false;
//}
// Spine conversions
#if USE_SPINE
template<typename T>
bool spine_Vector_T_to_seval(const spine::Vector<T>& v, se::Value* ret)
{
assert(ret != nullptr);
se::HandleObject obj(se::Object::createArrayObject(v.size()));
bool ok = true;
spine::Vector<T> tmpv = v;
for (uint32_t i = 0, count = (uint32_t)tmpv.size(); i < count; i++)
{
if (!obj->setArrayElement(i, se::Value(tmpv[i])))
{
ok = false;
ret->setUndefined();
break;
}
}
if (ok)
ret->setObject(obj);
return ok;
}
template<typename T>
bool spine_Vector_T_ptr_to_seval(const spine::Vector<T*>& v, se::Value* ret)
{
assert(ret != nullptr);
se::HandleObject obj(se::Object::createArrayObject(v.size()));
bool ok = true;
spine::Vector<T*> tmpv = v;
for (uint32_t i = 0, count = (uint32_t)tmpv.size(); i < count; i++)
{
se::Value tmp;
ok = native_ptr_to_rooted_seval<T>(tmpv[i], &tmp);
if (!ok || !obj->setArrayElement(i, tmp))
{
ok = false;
ret->setUndefined();
break;
}
}
if (ok) ret->setObject(obj);
return ok;
}
template<typename T>
bool seval_to_spine_Vector_T_ptr(const se::Value& v, spine::Vector<T*>* ret)
{
assert(ret != nullptr);
assert(v.isObject());
se::Object* obj = v.toObject();
assert(obj->isArray());
bool ok = true;
uint32_t len = 0;
ok = obj->getArrayLength(&len);
if (!ok)
{
ret->clear();
return false;
}
se::Value tmp;
for (uint32_t i = 0; i < len; ++i)
{
ok = obj->getArrayElement(i, &tmp);
if (!ok || !tmp.isObject())
{
ret->clear();
return false;
}
T* nativeObj = (T*)tmp.toObject()->getPrivateData();
ret->add(nativeObj);
}
return true;
}
bool seval_to_spine_Vector_String(const se::Value& v, spine::Vector<spine::String>* ret);
bool spine_Vector_String_to_seval(const spine::Vector<spine::String>& v, se::Value* ret);
#endif
//
//// Box2d
//bool b2Vec2_to_seval(const b2Vec2& v, se::Value* ret);
//bool b2Manifold_to_seval(const b2Manifold* v, se::Value* ret);
//bool b2AABB_to_seval(const b2AABB& v, se::Value* ret);

View File

@@ -0,0 +1,571 @@
/****************************************************************************
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "jsb_dragonbones_manual.hpp"
#include "base/ccConfig.h"
#if USE_DRAGONBONES > 0
#include "cocos/scripting/js-bindings/jswrapper/SeApi.h"
#include "cocos/scripting/js-bindings/manual/jsb_conversions.hpp"
#include "cocos/scripting/js-bindings/manual/jsb_global.h"
#include "cocos/scripting/js-bindings/manual/jsb_helper.hpp"
#include "cocos/scripting/js-bindings/auto/jsb_cocos2dx_dragonbones_auto.hpp"
#include "cocos/editor-support/dragonbones-creator-support/CCDragonBonesHeaders.h"
#include "cocos/scripting/js-bindings/auto/jsb_cocos2dx_editor_support_auto.hpp"
#include "cocos2d.h"
using namespace cocos2d;
// add by fins
static bool js_cocos2dx_dragonbones_Slot_get_globalTransformMatrix(se::State &s)
{
dragonBones::Slot *cobj = (dragonBones::Slot *)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_cocos2dx_dragonbones_Slot_get_globalTransformMatrix : Invalid Native Object");
const auto &args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc == 0)
{
dragonBones::Matrix *result = cobj->getGlobalTransformMatrix();
ok &= native_ptr_to_rooted_seval<dragonBones::Matrix>((dragonBones::Matrix *)result, &s.rval());
SE_PRECONDITION2(ok, false, "js_cocos2dx_dragonbones_Slot_get_globalTransformMatrix : Error processing arguments");
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 0);
return false;
}
SE_BIND_PROP_GET(js_cocos2dx_dragonbones_Slot_get_globalTransformMatrix)
// add by fins
static bool js_cocos2dx_dragonbones_Animation_get_animations(se::State &s)
{
dragonBones::Animation *cobj = (dragonBones::Animation *)s.nativeThisObject();
se::HandleObject retObj(se::Object::createPlainObject());
bool ok = false;
se::Value tmp;
for (const auto &e : cobj->getAnimations())
{
if (!e.first.empty())
{
ok = native_ptr_to_rooted_seval<dragonBones::AnimationData>(e.second, __jsb_dragonBones_AnimationData_class, &tmp);
SE_PRECONDITION2(ok, false, "Convert dragonBones::AnimationData to se::Value failed!");
retObj->setProperty(e.first.c_str(), tmp);
}
}
s.rval().setObject(retObj);
return true;
}
SE_BIND_PROP_GET(js_cocos2dx_dragonbones_Animation_get_animations)
static bool js_cocos2dx_dragonbones_Armature_getDisplay(se::State& s)
{
if (s.args().size() == 0)
{
dragonBones::Armature* cobj = (dragonBones::Armature*)s.nativeThisObject();
dragonBones::CCArmatureDisplay* ret = (dragonBones::CCArmatureDisplay*)(cobj->getDisplay());
if (ret != nullptr)
{
bool ok = native_ptr_to_seval<dragonBones::CCArmatureDisplay>(ret, __jsb_dragonBones_CCArmatureDisplay_class, &s.rval());
SE_PRECONDITION2(ok, false, "Convert dragonBones::Animation to se::Value failed!");
}
else
{
s.rval().setNull();
}
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)s.args().size(), 0);
return false;
}
SE_BIND_FUNC(js_cocos2dx_dragonbones_Armature_getDisplay)
static bool js_cocos2dx_dragonbones_Armature_getSlots(se::State& s)
{
dragonBones::Armature* cobj = (dragonBones::Armature*)s.nativeThisObject();
const auto& result = cobj->getSlots();
se::HandleObject arr(se::Object::createArrayObject(result.size()));
uint32_t i = 0;
se::Value tmp;
bool ok = true;
for (const auto& slot : result)
{
if (!native_ptr_to_rooted_seval<dragonBones::Slot>(slot, &tmp))
{
ok = false;
break;
}
arr->setArrayElement(i, tmp);
++i;
}
if (ok)
s.rval().setObject(arr);
SE_PRECONDITION2(ok, false, "Convert getSlots to se::Value failed!");
return true;
}
SE_BIND_FUNC(js_cocos2dx_dragonbones_Armature_getSlots)
static bool js_cocos2dx_dragonbones_Armature_getBones(se::State& s)
{
dragonBones::Armature* cobj = (dragonBones::Armature*)s.nativeThisObject();
const auto& result = cobj->getBones();
se::HandleObject arr(se::Object::createArrayObject(result.size()));
uint32_t i = 0;
se::Value tmp;
bool ok = true;
for (const auto& bone : result)
{
if (!native_ptr_to_rooted_seval<dragonBones::Bone>(bone, &tmp))
{
ok = false;
break;
}
arr->setArrayElement(i, tmp);
++i;
}
if (ok)
s.rval().setObject(arr);
SE_PRECONDITION2(ok, false, "Convert getBones to se::Value failed!");
return true;
}
SE_BIND_FUNC(js_cocos2dx_dragonbones_Armature_getBones)
static bool js_cocos2dx_dragonbones_Armature_getBoneByDisplay(se::State& s)
{
dragonBones::Armature* cobj = (dragonBones::Armature*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_cocos2dx_dragonbones_Armature_getBoneByDisplay : Invalid Native Object");
const auto& args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc == 1) {
dragonBones::CCArmatureDisplay* display = nullptr;
ok = seval_to_native_ptr(args[0], &display);
SE_PRECONDITION2(ok, false, "js_cocos2dx_dragonbones_Armature_getBoneByDisplay : Error processing arguments");
dragonBones::Bone* result = cobj->getBoneByDisplay(display);
ok &= native_ptr_to_rooted_seval<dragonBones::Bone>((dragonBones::Bone*)result, &s.rval());
SE_PRECONDITION2(ok, false, "js_cocos2dx_dragonbones_Armature_getBoneByDisplay : Error processing arguments");
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 1);
return false;
}
SE_BIND_FUNC(js_cocos2dx_dragonbones_Armature_getBoneByDisplay)
static bool js_cocos2dx_dragonbones_Armature_getSlotByDisplay(se::State& s)
{
dragonBones::Armature* cobj = (dragonBones::Armature*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_cocos2dx_dragonbones_Armature_getSlotByDisplay : Invalid Native Object");
const auto& args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc == 1) {
dragonBones::CCArmatureDisplay* display = nullptr;
ok = seval_to_native_ptr(args[0], &display);
SE_PRECONDITION2(ok, false, "js_cocos2dx_dragonbones_Armature_getSlotByDisplay : Error processing arguments");
dragonBones::Slot* result = cobj->getSlotByDisplay(display);
ok &= native_ptr_to_rooted_seval<dragonBones::Slot>((dragonBones::Slot*)result, &s.rval());
SE_PRECONDITION2(ok, false, "js_cocos2dx_dragonbones_Armature_getSlotByDisplay : Error processing arguments");
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 1);
return false;
}
SE_BIND_FUNC(js_cocos2dx_dragonbones_Armature_getSlotByDisplay)
static bool js_cocos2dx_dragonbones_Armature_setReplacedTexture(se::State& s)
{
dragonBones::Armature* cobj = (dragonBones::Armature*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_cocos2dx_dragonbones_Armature_setReplacedTexture : Invalid Native Object");
const auto& args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc == 1) {
middleware::Texture2D* texture = nullptr;
ok = seval_to_native_ptr(args[0], &texture);
SE_PRECONDITION2(ok, false, "js_cocos2dx_dragonbones_Armature_setReplacedTexture : Error processing arguments");
cobj->setReplacedTexture(texture);
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 1);
return false;
}
SE_BIND_FUNC(js_cocos2dx_dragonbones_Armature_setReplacedTexture)
static bool js_cocos2dx_dragonbones_Armature_getReplacedTexture(se::State& s)
{
dragonBones::Armature* cobj = (dragonBones::Armature*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_cocos2dx_dragonbones_Armature_getReplacedTexture : Invalid Native Object");
const auto& args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc == 0) {
middleware::Texture2D* result = (middleware::Texture2D*)cobj->getReplacedTexture();
ok = native_ptr_to_seval<middleware::Texture2D>(result, __jsb_cocos2d_middleware_Texture2D_class, &s.rval());
SE_PRECONDITION2(ok, false, "js_cocos2dx_dragonbones_Armature_getReplacedTexture : Error processing arguments");
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 0);
return false;
}
SE_BIND_FUNC(js_cocos2dx_dragonbones_Armature_getReplacedTexture)
static bool js_cocos2dx_dragonbones_ArmatureData_get_animations(se::State& s)
{
dragonBones::ArmatureData* cobj = (dragonBones::ArmatureData*)s.nativeThisObject();
se::HandleObject retObj(se::Object::createPlainObject());
bool ok = false;
se::Value tmp;
for (const auto& e : cobj->animations)
{
if (!e.first.empty())
{
ok = native_ptr_to_rooted_seval<dragonBones::AnimationData>(e.second, __jsb_dragonBones_AnimationData_class, &tmp);
SE_PRECONDITION2(ok, false, "Convert dragonBones::AnimationData to se::Value failed!");
retObj->setProperty(e.first.c_str(), tmp);
}
}
s.rval().setObject(retObj);
return true;
}
SE_BIND_PROP_GET(js_cocos2dx_dragonbones_ArmatureData_get_animations)
static bool js_cocos2dx_dragonbones_ArmatureData_get_bones(se::State& s)
{
dragonBones::ArmatureData* cobj = (dragonBones::ArmatureData*)s.nativeThisObject();
se::HandleObject retObj(se::Object::createPlainObject());
bool ok = false;
se::Value tmp;
for (const auto& e : cobj->bones)
{
if (!e.first.empty())
{
ok = native_ptr_to_rooted_seval<dragonBones::BoneData>(e.second, __jsb_dragonBones_BoneData_class, &tmp);
SE_PRECONDITION2(ok, false, "Convert dragonBones::AnimationData to se::Value failed!");
retObj->setProperty(e.first.c_str(), tmp);
}
}
s.rval().setObject(retObj);
return true;
}
SE_BIND_PROP_GET(js_cocos2dx_dragonbones_ArmatureData_get_bones)
static bool js_cocos2dx_dragonbones_ArmatureData_get_skins(se::State& s)
{
dragonBones::ArmatureData* cobj = (dragonBones::ArmatureData*)s.nativeThisObject();
se::HandleObject retObj(se::Object::createPlainObject());
bool ok = false;
se::Value tmp;
for (const auto& e : cobj->skins)
{
if (!e.first.empty())
{
ok = native_ptr_to_rooted_seval<dragonBones::SkinData>(e.second, __jsb_dragonBones_SkinData_class, &tmp);
SE_PRECONDITION2(ok, false, "Convert dragonBones::AnimationData to se::Value failed!");
retObj->setProperty(e.first.c_str(), tmp);
}
}
s.rval().setObject(retObj);
return true;
}
SE_BIND_PROP_GET(js_cocos2dx_dragonbones_ArmatureData_get_skins)
static bool js_cocos2dx_dragonbones_ArmatureData_get_slots(se::State& s)
{
dragonBones::ArmatureData* cobj = (dragonBones::ArmatureData*)s.nativeThisObject();
se::HandleObject retObj(se::Object::createPlainObject());
bool ok = false;
se::Value tmp;
for (const auto& e : cobj->slots)
{
if (!e.first.empty())
{
ok = native_ptr_to_rooted_seval<dragonBones::SlotData>(e.second, __jsb_dragonBones_SlotData_class, &tmp);
SE_PRECONDITION2(ok, false, "Convert dragonBones::AnimationData to se::Value failed!");
retObj->setProperty(e.first.c_str(), tmp);
}
}
s.rval().setObject(retObj);
return true;
}
SE_BIND_PROP_GET(js_cocos2dx_dragonbones_ArmatureData_get_slots)
static bool js_cocos2dx_dragonbones_DragonBonesData_get_armatureNames(se::State& s)
{
dragonBones::DragonBonesData* cobj = (dragonBones::DragonBonesData*)s.nativeThisObject();
const auto& ret = cobj->getArmatureNames();
bool ok = std_vector_string_to_seval(ret, &s.rval());
SE_PRECONDITION2(ok, false, "Convert ArmatureNames to se::Value failed!");
return true;
}
SE_BIND_PROP_GET(js_cocos2dx_dragonbones_DragonBonesData_get_armatureNames)
static bool js_cocos2dx_dragonbones_Slot_getDisplay(se::State& s)
{
dragonBones::Slot* cobj = (dragonBones::Slot *)s.nativeThisObject();
dragonBones::CCArmatureDisplay* ret = static_cast<dragonBones::CCArmatureDisplay*>(cobj->getDisplay());
bool ok = native_ptr_to_seval<dragonBones::CCArmatureDisplay>(ret, __jsb_dragonBones_CCArmatureDisplay_class, &s.rval());
SE_PRECONDITION2(ok, false, "Convert dragonBones::DBCCSprite to se::Value failed!");
return true;
}
SE_BIND_FUNC(js_cocos2dx_dragonbones_Slot_getDisplay)
static bool js_cocos2dx_dragonbones_Slot_set_displayIndex(se::State& s)
{
const auto& args = s.args();
dragonBones::Slot* cobj = (dragonBones::Slot*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_cocos2dx_dragonbones_Slot_set_displayIndex : Invalid Native Object");
CC_UNUSED bool ok = true;
int32_t arg0;
ok &= seval_to_int32(args[0], &arg0);
SE_PRECONDITION2(ok, false, "js_cocos2dx_dragonbones_Slot_set_displayIndex : Error processing new value");
cobj->setDisplayIndex(arg0);
return true;
}
SE_BIND_PROP_SET(js_cocos2dx_dragonbones_Slot_set_displayIndex)
static bool js_cocos2dx_dragonbones_Slot_get_displayIndex(se::State& s)
{
dragonBones::Slot* cobj = (dragonBones::Slot*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_cocos2dx_dragonbones_Slot_get_displayIndex : Invalid Native Object");
const int32_t ret = cobj->getDisplayIndex();
bool ok = int32_to_seval(ret, &s.rval());
SE_PRECONDITION2(ok, false, "js_cocos2dx_dragonbones_Slot_get_displayIndex to se::Value failed!");
return true;
}
SE_BIND_PROP_GET(js_cocos2dx_dragonbones_Slot_get_displayIndex)
static bool js_cocos2dx_dragonbones_Slot_setDisplay(se::State& s)
{
const auto& args = s.args();
int argc = (int)args.size();
if (argc == 2)
{
dragonBones::Slot* cobj = (dragonBones::Slot *)s.nativeThisObject();
dragonBones::CCArmatureDisplay* dbSprite = nullptr;
bool ok = seval_to_native_ptr(args[0], &dbSprite);
SE_PRECONDITION2(ok, false, "Convert se::Value to dragonBones::DBCCSprite failed!");
dragonBones::DisplayType type;
ok = seval_to_int32(args[1], (int32_t *)&type);
SE_PRECONDITION2(ok, false, "Convert se::Value to dragonBones::DisplayType failed!");
cobj->setDisplay(dbSprite, type);
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", argc, 2);
return false;
}
SE_BIND_FUNC(js_cocos2dx_dragonbones_Slot_setDisplay)
static bool js_cocos2dx_dragonbones_BaseFactory_parseTextureAtlasData(se::State& s)
{
dragonBones::BaseFactory* cobj = (dragonBones::BaseFactory*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_cocos2dx_dragonbones_BaseFactory_parseTextureAtlasData : Invalid Native Object");
const auto& args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc == 2) {
const char* arg0 = nullptr;
void* arg1 = nullptr;
std::string arg0_tmp; ok &= seval_to_std_string(args[0], &arg0_tmp); arg0 = arg0_tmp.c_str();
ok &= seval_to_native_ptr(args[1], &arg1);
SE_PRECONDITION2(ok, false, "js_cocos2dx_dragonbones_BaseFactory_parseTextureAtlasData : Error processing arguments");
dragonBones::TextureAtlasData* result = cobj->parseTextureAtlasData(arg0, arg1);
ok &= native_ptr_to_rooted_seval<dragonBones::TextureAtlasData>((dragonBones::TextureAtlasData*)result, &s.rval());
SE_PRECONDITION2(ok, false, "js_cocos2dx_dragonbones_BaseFactory_parseTextureAtlasData : Error processing arguments");
return true;
}
if (argc == 3) {
const char* arg0 = nullptr;
void* arg1 = nullptr;
std::string arg2;
std::string arg0_tmp; ok &= seval_to_std_string(args[0], &arg0_tmp); arg0 = arg0_tmp.c_str();
ok &= seval_to_native_ptr(args[1], &arg1);
SE_PRECONDITION2(ok, false, "js_cocos2dx_dragonbones_BaseFactory_parseTextureAtlasData : Error processing arguments");
ok &= seval_to_std_string(args[2], &arg2);
SE_PRECONDITION2(ok, false, "js_cocos2dx_dragonbones_BaseFactory_parseTextureAtlasData : Error processing arguments");
dragonBones::TextureAtlasData* result = cobj->parseTextureAtlasData(arg0, arg1, arg2);
ok &= native_ptr_to_rooted_seval<dragonBones::TextureAtlasData>((dragonBones::TextureAtlasData*)result, &s.rval());
SE_PRECONDITION2(ok, false, "js_cocos2dx_dragonbones_BaseFactory_parseTextureAtlasData : Error processing arguments");
return true;
}
if (argc == 4) {
const char* arg0 = nullptr;
void* arg1 = nullptr;
std::string arg2;
float arg3 = 0;
std::string arg0_tmp; ok &= seval_to_std_string(args[0], &arg0_tmp); arg0 = arg0_tmp.c_str();
ok &= seval_to_native_ptr(args[1], &arg1);
SE_PRECONDITION2(ok, false, "js_cocos2dx_dragonbones_BaseFactory_parseTextureAtlasData : Error processing arguments");
ok &= seval_to_std_string(args[2], &arg2);
ok &= seval_to_float(args[3], &arg3);
SE_PRECONDITION2(ok, false, "js_cocos2dx_dragonbones_BaseFactory_parseTextureAtlasData : Error processing arguments");
dragonBones::TextureAtlasData* result = cobj->parseTextureAtlasData(arg0, arg1, arg2, arg3);
ok &= native_ptr_to_rooted_seval<dragonBones::TextureAtlasData>((dragonBones::TextureAtlasData*)result, &s.rval());
SE_PRECONDITION2(ok, false, "js_cocos2dx_dragonbones_BaseFactory_parseTextureAtlasData : Error processing arguments");
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 4);
return false;
}
SE_BIND_FUNC(js_cocos2dx_dragonbones_BaseFactory_parseTextureAtlasData)
bool register_all_dragonbones_manual(se::Object* obj)
{
// add by fins
__jsb_dragonBones_Slot_proto->defineProperty("globalTransformMatrix", _SE(js_cocos2dx_dragonbones_Slot_get_globalTransformMatrix), nullptr);
// add by fins
__jsb_dragonBones_Animation_proto->defineProperty("animations", _SE(js_cocos2dx_dragonbones_Animation_get_animations), nullptr);
__jsb_dragonBones_Armature_proto->defineFunction("getDisplay", _SE(js_cocos2dx_dragonbones_Armature_getDisplay));
__jsb_dragonBones_Armature_proto->defineFunction("getSlots", _SE(js_cocos2dx_dragonbones_Armature_getSlots));
__jsb_dragonBones_Armature_proto->defineFunction("getBones", _SE(js_cocos2dx_dragonbones_Armature_getBones));
__jsb_dragonBones_Armature_proto->defineFunction("getBoneByDisplay", _SE(js_cocos2dx_dragonbones_Armature_getBoneByDisplay));
__jsb_dragonBones_Armature_proto->defineFunction("getSlotByDisplay", _SE(js_cocos2dx_dragonbones_Armature_getSlotByDisplay));
__jsb_dragonBones_Armature_proto->defineFunction("setReplacedTexture", _SE(js_cocos2dx_dragonbones_Armature_setReplacedTexture));
__jsb_dragonBones_Armature_proto->defineFunction("getReplacedTexture", _SE(js_cocos2dx_dragonbones_Armature_getReplacedTexture));
__jsb_dragonBones_ArmatureData_proto->defineProperty("animations", _SE(js_cocos2dx_dragonbones_ArmatureData_get_animations), nullptr);
__jsb_dragonBones_ArmatureData_proto->defineProperty("bones", _SE(js_cocos2dx_dragonbones_ArmatureData_get_bones), nullptr);
__jsb_dragonBones_ArmatureData_proto->defineProperty("skins", _SE(js_cocos2dx_dragonbones_ArmatureData_get_skins), nullptr);
__jsb_dragonBones_ArmatureData_proto->defineProperty("slots", _SE(js_cocos2dx_dragonbones_ArmatureData_get_slots), nullptr);
__jsb_dragonBones_DragonBonesData_proto->defineProperty("armatureNames", _SE(js_cocos2dx_dragonbones_DragonBonesData_get_armatureNames), nullptr);
__jsb_dragonBones_Slot_proto->defineProperty("displayIndex", _SE(js_cocos2dx_dragonbones_Slot_get_displayIndex), _SE(js_cocos2dx_dragonbones_Slot_set_displayIndex));
__jsb_dragonBones_Slot_proto->defineFunction("getDisplay", _SE(js_cocos2dx_dragonbones_Slot_getDisplay));
__jsb_dragonBones_Slot_proto->defineFunction("setDisplay", _SE(js_cocos2dx_dragonbones_Slot_setDisplay));
__jsb_dragonBones_BaseFactory_proto->defineFunction("parseTextureAtlasData", _SE(js_cocos2dx_dragonbones_BaseFactory_parseTextureAtlasData));
dragonBones::BaseObject::setObjectRecycleOrDestroyCallback([](dragonBones::BaseObject* obj, int type){
std::string typeName = typeid(*obj).name();
se::Object* seObj = nullptr;
auto iter = se::NativePtrToObjectMap::find(obj);
if (iter != se::NativePtrToObjectMap::end())
{
// Save se::Object pointer for being used in cleanup method.
seObj = iter->second;
// Unmap native and js object since native object was destroyed.
// Otherwise, it may trigger 'assertion' in se::Object::setPrivateData later
// since native obj is already released and the new native object may be assigned with
// the same address.
se::NativePtrToObjectMap::erase(iter);
}
else
{
// CCLOG("Didn't find %s, %p in map", typeName, obj);
// assert(false);
return;
}
std::string typeNameStr = typeName;
auto cleanup = [seObj, typeNameStr](){
auto se = se::ScriptEngine::getInstance();
if (!se->isValid() || se->isInCleanup())
return;
se::AutoHandleScope hs;
se->clearException();
// The mapping of native object & se::Object was cleared in above code.
// The private data (native object) may be a different object associated with other se::Object.
// Therefore, don't clear the mapping again.
seObj->clearPrivateData(false);
seObj->unroot();
seObj->decRef();
};
if (!se::ScriptEngine::getInstance()->isGarbageCollecting())
{
cleanup();
}
else
{
CleanupTask::pushTaskToAutoReleasePool(cleanup);
}
});
se::ScriptEngine::getInstance()->addAfterCleanupHook([](){
// If dragonBones has not init,then no need to cleanup.
if (!dragonBones::CCFactory::isInit())
{
return;
}
dragonBones::DragonBones::checkInPool = false;
auto factory = dragonBones::CCFactory::getFactory();
factory->stopSchedule();
// Copy the dragonbones object vector since vector element will be deleted in BaseObject destructor.
std::vector<dragonBones::BaseObject*> allDragonBonesObjects = dragonBones::BaseObject::getAllObjects();
SE_LOGD("Starting to cleanup dragonbones object, count: %d\n", (int)allDragonBonesObjects.size());
for (auto dbObj : allDragonBonesObjects)
{
if (!dbObj->isInPool())
{
dbObj->returnToPool();
}
}
dragonBones::BaseObject::clearPool(0);
dragonBones::CCFactory::destroyFactory();
dragonBones::DragonBones::checkInPool = true;
// Don't need to use copy operator since we only print leak object below.
auto& refAllDragonBonesObjects = dragonBones::BaseObject::getAllObjects();
SE_LOGD("After cleanup, dragonbones object remained count: %d\n", (int)refAllDragonBonesObjects.size());
// Print leak objects
for (auto dbObj : refAllDragonBonesObjects)
{
SE_LOGD("Leak dragonbones object: %s, %p\n", typeid(*dbObj).name(), dbObj);
}
refAllDragonBonesObjects.clear();
});
se::ScriptEngine::getInstance()->clearException();
return true;
}
#endif

View File

@@ -0,0 +1,33 @@
/****************************************************************************
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
namespace se {
class Object;
}
bool register_all_dragonbones_manual(se::Object* obj);

View File

@@ -0,0 +1,885 @@
/****************************************************************************
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "base/ccConfig.h"
#include "jsb_gfx_manual.hpp"
#if (USE_GFX_RENDERER > 0) && (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_MAC || CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
#include "cocos/scripting/js-bindings/auto/jsb_gfx_auto.hpp"
#include "cocos/scripting/js-bindings/manual/jsb_conversions.hpp"
#include "gfx/GFX.h"
using namespace cocos2d;
using namespace cocos2d::renderer;
static bool js_gfx_DeviceGraphics_clear(se::State& s)
{
cocos2d::renderer::DeviceGraphics* cobj = (cocos2d::renderer::DeviceGraphics*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_gfx_DeviceGraphics_clear : Invalid Native Object");
const auto& args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc == 1) {
uint8_t flags = 0;
Color4F color(Color4F::BLACK);
double depth = 1.0;
int32_t stencil = 0;
se::Object* arg1 = args[0].toObject();
se::Value colorVal, depthVal, stencilVal;
if (arg1->getProperty("color", &colorVal))
{
flags |= ClearFlag::COLOR;
if (colorVal.isObject() && colorVal.toObject()->isArray())
{
se::Object* colorObj = colorVal.toObject();
uint32_t length = 0;
if (colorObj->getArrayLength(&length) && length == 4)
{
se::Value tmp;
if (colorObj->getArrayElement(0, &tmp) && tmp.isNumber())
{
color.r = tmp.toFloat();
}
if (colorObj->getArrayElement(1, &tmp) && tmp.isNumber())
{
color.g = tmp.toFloat();
}
if (colorObj->getArrayElement(2, &tmp) && tmp.isNumber())
{
color.b = tmp.toFloat();
}
if (colorObj->getArrayElement(3, &tmp) && tmp.isNumber())
{
color.a = tmp.toFloat();
}
}
}
else
{
SE_LOGE("Invalid clear color flag!\n");
}
}
if (arg1->getProperty("depth", &depthVal))
{
flags |= ClearFlag::DEPTH;
if (depthVal.isNumber())
{
depth = depthVal.toNumber();
}
}
if (arg1->getProperty("stencil", &stencilVal))
{
flags |= ClearFlag::STENCIL;
if (stencilVal.isNumber())
{
stencil = stencilVal.toInt32();
}
}
cobj->clear(flags, &color, depth, stencil);
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 1);
return false;
}
SE_BIND_FUNC(js_gfx_DeviceGraphics_clear)
static bool js_gfx_DeviceGraphics_setUniform(se::State& s)
{
cocos2d::renderer::DeviceGraphics* cobj = (cocos2d::renderer::DeviceGraphics*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_gfx_DeviceGraphics_setUniform : Invalid Native Object");
const auto& args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc == 2) {
std::string name;
ok = seval_to_std_string(args[0], &name);
SE_PRECONDITION2(ok, false, "Convert uniform name failed!");
auto hashName = std::hash<std::string>{}(name);
se::Value arg1 = args[1];
if (arg1.isObject())
{
se::Object* value = arg1.toObject();
if (value->isTypedArray())
{
uint8_t* data = nullptr;
size_t bytes = 0;
if (value->getTypedArrayData(&data, &bytes))
cobj->setUniform(hashName, data, bytes, UniformElementType::FLOAT);
}
else
{
assert(false);
}
}
else if (arg1.isNumber())
{
float number = arg1.toFloat();
cobj->setUniformf(hashName, number);
}
else if (arg1.isBoolean())
{
int v = arg1.toBoolean() ? 1 : 0;
cobj->setUniformi(hashName, v);
}
else
{
assert(false);
}
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 2);
return false;
}
SE_BIND_FUNC(js_gfx_DeviceGraphics_setUniform)
static VertexFormat* getVertexFormatFromValue(const se::Value& elementVal)
{
std::vector<VertexFormat::Info> formatInfos;
if (elementVal.isObject() && elementVal.toObject()->isArray())
{
se::Object* fmtArr = elementVal.toObject();
uint32_t length = 0;
if (fmtArr->getArrayLength(&length) && length > 0)
{
se::Value tmp;
se::Value nameVal;
se::Value typeVal;
se::Value numVal;
se::Value normalizeVal;
bool normalized = false;
for (uint32_t i = 0; i < length; ++i)
{
if (fmtArr->getArrayElement(i, &tmp) && tmp.isObject())
{
tmp.toObject()->getProperty("name", &nameVal);
tmp.toObject()->getProperty("type", &typeVal);
tmp.toObject()->getProperty("num", &numVal);
if (tmp.toObject()->getProperty("normalize", &normalizeVal))
{
seval_to_boolean(normalizeVal, &normalized);
}
formatInfos.push_back({ nameVal.toString(), (AttribType)typeVal.toUint16(), numVal.toUint32(), normalized });
}
}
}
}
auto vertexFormat = new VertexFormat(formatInfos);
return vertexFormat;
}
static bool js_gfx_VertexBuffer_init(se::State& s)
{
cocos2d::renderer::VertexBuffer* cobj = (cocos2d::renderer::VertexBuffer*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_gfx_VertexBuffer_init : Invalid Native Object");
const auto& args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc == 5) {
cocos2d::renderer::DeviceGraphics* device;
ok &= seval_to_native_ptr(args[0], &device);
// VertexFormat* format = getVertexFormatFromValue(args[1]);
VertexFormat* format = static_cast<cocos2d::renderer::VertexFormat*>(args[1].toObject()->getPrivateData());
Usage usage = (Usage) args[2].toUint16();
uint8_t* data = nullptr;
size_t dataByteLength = 0;
uint32_t numVertices = 0;
const se::Value& arg3 = args[3];
se::Object* typedArr = nullptr;
if (arg3.isObject())
{
typedArr = arg3.toObject();
assert(typedArr->isTypedArray());
ok = typedArr->getTypedArrayData(&data, &dataByteLength);
assert(ok);
}
ok = seval_to_uint32(args[4], &numVertices);
assert(ok);
cobj->init(device, format, usage, data, dataByteLength, numVertices);
// delete format;
se::Object* thisObj = s.thisObject();
cobj->setFetchDataCallback([thisObj](size_t* bytes) ->uint8_t* {
uint8_t* ret = nullptr;
se::Value dataVal;
if (thisObj->getProperty("_data", &dataVal) && dataVal.isObject())
{
assert(dataVal.toObject()->isTypedArray());
dataVal.toObject()->getTypedArrayData(&ret, bytes);
}
return ret;
});
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 5);
return false;
}
SE_BIND_FUNC(js_gfx_VertexBuffer_init)
static bool js_gfx_VertexBuffer_self(se::State& s)
{
cocos2d::renderer::VertexBuffer* cobj = (cocos2d::renderer::VertexBuffer*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_gfx_VertexBuffer_update : Invalid Native Object");
auto addr = (unsigned long)cobj;
s.rval().setNumber(addr);
return true;
}
SE_BIND_FUNC(js_gfx_VertexBuffer_self)
// uint32_t offset, const void* data, size_t dataByteLength
static bool js_gfx_VertexBuffer_update(se::State& s)
{
cocos2d::renderer::VertexBuffer* cobj = (cocos2d::renderer::VertexBuffer*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_gfx_VertexBuffer_update : Invalid Native Object");
const auto& args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc == 2) {
uint32_t offset = 0;
ok = seval_to_uint32(args[0], &offset);
SE_PRECONDITION2(ok, false, "Convert arg0 offset failed!");
if (args[1].isObject())
{
se::Object* arg1 = args[1].toObject();
if (arg1->isTypedArray())
{
uint8_t* data = nullptr;
size_t dataLen = 0;
if (arg1->getTypedArrayData(&data, &dataLen))
{
cobj->update(offset, data, dataLen);
}
else
{
SE_PRECONDITION2(false, false, "get typed array data failed!");
}
}
else
{
SE_PRECONDITION2(false, false, "arg1 isn't a typed array!");
}
}
else
{
SE_PRECONDITION2(false, false, "arg1 isn't an object!");
}
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 5);
return false;
}
SE_BIND_FUNC(js_gfx_VertexBuffer_update)
static bool js_gfx_VertexBuffer_prop_setFormat(se::State& s)
{
cocos2d::renderer::VertexBuffer* cobj = (cocos2d::renderer::VertexBuffer*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_gfx_VertexBuffer_prop_setFormat : Invalid Native Object");
const auto& args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc == 1)
{
se::Value formatVal;
args[0].toObject()->getProperty("_nativeObj", &formatVal);
auto format = static_cast<VertexFormat*>(formatVal.toObject()->getPrivateData());
cobj->setFormat(format);
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 1);
return false;
}
SE_BIND_PROP_SET(js_gfx_VertexBuffer_prop_setFormat)
//static bool js_gfx_VertexBuffer_prop_getFormat(se::State& s)
//{
// cocos2d::renderer::VertexBuffer* cobj = (cocos2d::renderer::VertexBuffer*)s.nativeThisObject();
// SE_PRECONDITION2(cobj, false, "js_gfx_VertexBuffer_prop_getFormat : Invalid Native Object");
// const auto& args = s.args();
// size_t argc = args.size();
// CC_UNUSED bool ok = true;
// assert(false); //IDEA:
// if (argc == 0) {
// return true;
// }
//
// SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 0);
// return false;
//}
//SE_BIND_PROP_GET(js_gfx_VertexBuffer_prop_getFormat)
static bool js_gfx_VertexBuffer_prop_setUsage(se::State& s)
{
cocos2d::renderer::VertexBuffer* cobj = (cocos2d::renderer::VertexBuffer*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_gfx_VertexBuffer_prop_setUsage : Invalid Native Object");
const auto& args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc == 1) {
uint16_t usage;
ok = seval_to_uint16(args[0], &usage);
SE_PRECONDITION2(ok, false, "Convert arg0 offset failed!");
cobj->setUsage((cocos2d::renderer::Usage)usage);
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 1);
return false;
}
SE_BIND_PROP_SET(js_gfx_VertexBuffer_prop_setUsage)
static bool js_gfx_VertexBuffer_prop_getUsage(se::State& s)
{
cocos2d::renderer::VertexBuffer* cobj = (cocos2d::renderer::VertexBuffer*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_gfx_VertexBuffer_prop_getUsage : Invalid Native Object");
const auto& args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc == 0) {
cocos2d::renderer::Usage usage = cobj->getUsage();
s.rval().setUint16((uint16_t)usage);
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 0);
return false;
}
SE_BIND_PROP_GET(js_gfx_VertexBuffer_prop_getUsage)
static bool js_gfx_VertexBuffer_prop_setNumVertices(se::State& s)
{
cocos2d::renderer::VertexBuffer* cobj = (cocos2d::renderer::VertexBuffer*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_gfx_VertexBuffer_prop_setNumVertices : Invalid Native Object");
const auto& args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc == 1) {
uint32_t count = 0;
ok = seval_to_uint32(args[0], &count);
SE_PRECONDITION2(ok, false, "Convert arg0 offset failed!");
cobj->setCount(count);
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 1);
return false;
}
SE_BIND_PROP_SET(js_gfx_VertexBuffer_prop_setNumVertices)
static bool js_gfx_VertexBuffer_prop_getNumVertices(se::State& s)
{
cocos2d::renderer::VertexBuffer* cobj = (cocos2d::renderer::VertexBuffer*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_gfx_VertexBuffer_prop_getNumVertices : Invalid Native Object");
const auto& args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc == 0) {
uint32_t count = cobj->getCount();
s.rval().setUint32(count);
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 0);
return false;
}
SE_BIND_PROP_GET(js_gfx_VertexBuffer_prop_getNumVertices)
static bool js_gfx_VertexBuffer_prop_getBytes(se::State& s)
{
cocos2d::renderer::VertexBuffer* cobj = (cocos2d::renderer::VertexBuffer*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_gfx_VertexBuffer_prop_getBytes : Invalid Native Object");
const auto& args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc == 0) {
uint32_t count = cobj->getBytes();
s.rval().setUint32(count);
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 0);
return false;
}
SE_BIND_PROP_GET(js_gfx_VertexBuffer_prop_getBytes)
static bool js_gfx_IndexBuffer_init(se::State& s)
{
cocos2d::renderer::IndexBuffer* cobj = (cocos2d::renderer::IndexBuffer*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_gfx_IndexBuffer_init : Invalid Native Object");
const auto& args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc == 5) {
cocos2d::renderer::DeviceGraphics* device;
ok &= seval_to_native_ptr(args[0], &device);
IndexFormat format = (IndexFormat)args[1].toUint16();
Usage usage = (Usage) args[2].toUint16();
uint8_t* data = nullptr;
size_t dataByteLength = 0;
uint32_t numIndices = 0;
const auto& arg3 = args[3];
if (arg3.isObject())
{
se::Object* typedArr = args[3].toObject();
assert(typedArr->isTypedArray());
ok = typedArr->getTypedArrayData(&data, &dataByteLength);
assert(ok);
}
ok = seval_to_uint32(args[4], &numIndices);
assert(ok);
cobj->init(device, format, usage, data, dataByteLength, numIndices);
se::Object* thisObj = s.thisObject();
cobj->setFetchDataCallback([thisObj](size_t* bytes) ->uint8_t* {
uint8_t* ret = nullptr;
se::Value dataVal;
if (thisObj->getProperty("_data", &dataVal) && dataVal.isObject())
{
assert(dataVal.toObject()->isTypedArray());
dataVal.toObject()->getTypedArrayData(&ret, bytes);
}
return ret;
});
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 5);
return false;
}
SE_BIND_FUNC(js_gfx_IndexBuffer_init)
static bool js_gfx_IndexBuffer_self(se::State& s)
{
cocos2d::renderer::IndexBuffer* cobj = (cocos2d::renderer::IndexBuffer*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_gfx_VertexBuffer_update : Invalid Native Object");
auto addr = (unsigned long)cobj;
s.rval().setNumber(addr);
return true;
}
SE_BIND_FUNC(js_gfx_IndexBuffer_self);
// uint32_t offset, const void* data, size_t dataByteLength
static bool js_gfx_IndexBuffer_update(se::State& s)
{
cocos2d::renderer::IndexBuffer* cobj = (cocos2d::renderer::IndexBuffer*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_gfx_VertexBuffer_update : Invalid Native Object");
const auto& args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc == 2) {
uint32_t offset = 0;
ok = seval_to_uint32(args[0], &offset);
SE_PRECONDITION2(ok, false, "Convert arg0 offset failed!");
if (args[1].isObject())
{
se::Object* arg1 = args[1].toObject();
if (arg1->isTypedArray())
{
uint8_t* data = nullptr;
size_t dataLen = 0;
if (arg1->getTypedArrayData(&data, &dataLen))
{
cobj->update(offset, data, dataLen);
}
else
{
SE_PRECONDITION2(false, false, "get typed array data failed!");
}
}
else
{
SE_PRECONDITION2(false, false, "arg1 isn't a typed array!");
}
}
else
{
SE_PRECONDITION2(false, false, "arg1 isn't an object!");
}
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 5);
return false;
}
SE_BIND_FUNC(js_gfx_IndexBuffer_update)
static bool js_gfx_IndexBuffer_prop_setFormat(se::State& s)
{
cocos2d::renderer::IndexBuffer* cobj = (cocos2d::renderer::IndexBuffer*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_gfx_IndexBuffer_prop_setFormat : Invalid Native Object");
const auto& args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc == 1) {
uint16_t format;
ok = seval_to_uint16(args[0], &format);
SE_PRECONDITION2(ok, false, "Convert arg0 offset failed!");
cobj->setFormat((cocos2d::renderer::IndexFormat)format);
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 1);
return false;
}
SE_BIND_PROP_SET(js_gfx_IndexBuffer_prop_setFormat)
static bool js_gfx_IndexBuffer_prop_getFormat(se::State& s)
{
cocos2d::renderer::IndexBuffer* cobj = (cocos2d::renderer::IndexBuffer*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_gfx_IndexBuffer_prop_getFormat : Invalid Native Object");
const auto& args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc == 0) {
cocos2d::renderer::IndexFormat format = cobj->getFormat();
s.rval().setUint16((uint16_t)format);
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 0);
return false;
}
SE_BIND_PROP_GET(js_gfx_IndexBuffer_prop_getFormat)
static bool js_gfx_IndexBuffer_prop_setUsage(se::State& s)
{
cocos2d::renderer::IndexBuffer* cobj = (cocos2d::renderer::IndexBuffer*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_gfx_IndexBuffer_prop_setUsage : Invalid Native Object");
const auto& args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc == 1) {
uint16_t usage;
ok = seval_to_uint16(args[0], &usage);
SE_PRECONDITION2(ok, false, "Convert arg0 offset failed!");
cobj->setUsage((cocos2d::renderer::Usage)usage);
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 1);
return false;
}
SE_BIND_PROP_SET(js_gfx_IndexBuffer_prop_setUsage)
static bool js_gfx_IndexBuffer_prop_getUsage(se::State& s)
{
cocos2d::renderer::IndexBuffer* cobj = (cocos2d::renderer::IndexBuffer*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_gfx_IndexBuffer_prop_getUsage : Invalid Native Object");
const auto& args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc == 0) {
cocos2d::renderer::Usage usage = cobj->getUsage();
s.rval().setUint16((uint16_t)usage);
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 0);
return false;
}
SE_BIND_PROP_GET(js_gfx_IndexBuffer_prop_getUsage)
static bool js_gfx_IndexBuffer_prop_setNumIndices(se::State& s)
{
cocos2d::renderer::IndexBuffer* cobj = (cocos2d::renderer::IndexBuffer*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_gfx_IndexBuffer_prop_setNumIndices : Invalid Native Object");
const auto& args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc == 1) {
uint32_t count = 0;
ok = seval_to_uint32(args[0], &count);
SE_PRECONDITION2(ok, false, "Convert arg0 offset failed!");
cobj->setCount(count);
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 1);
return false;
}
SE_BIND_PROP_SET(js_gfx_IndexBuffer_prop_setNumIndices)
static bool js_gfx_IndexBuffer_prop_getNumIndices(se::State& s)
{
cocos2d::renderer::IndexBuffer* cobj = (cocos2d::renderer::IndexBuffer*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_gfx_IndexBuffer_prop_getNumIndices : Invalid Native Object");
const auto& args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc == 0) {
uint32_t count = cobj->getCount();
s.rval().setUint32(count);
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 0);
return false;
}
SE_BIND_PROP_GET(js_gfx_IndexBuffer_prop_getNumIndices)
static bool js_gfx_IndexBuffer_prop_setBytesPerIndex(se::State& s)
{
cocos2d::renderer::IndexBuffer* cobj = (cocos2d::renderer::IndexBuffer*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_gfx_IndexBuffer_prop_setBytesPerIndex : Invalid Native Object");
const auto& args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc == 1) {
uint32_t count = 0;
ok = seval_to_uint32(args[0], &count);
SE_PRECONDITION2(ok, false, "Convert arg0 offset failed!");
cobj->setBytesPerIndex(count);
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 1);
return false;
}
SE_BIND_PROP_SET(js_gfx_IndexBuffer_prop_setBytesPerIndex)
static bool js_gfx_IndexBuffer_prop_getBytesPerIndex(se::State& s)
{
cocos2d::renderer::IndexBuffer* cobj = (cocos2d::renderer::IndexBuffer*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_gfx_IndexBuffer_prop_getBytesPerIndex : Invalid Native Object");
const auto& args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc == 0) {
uint32_t count = cobj->getBytesPerIndex();
s.rval().setUint32(count);
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 0);
return false;
}
SE_BIND_PROP_GET(js_gfx_IndexBuffer_prop_getBytesPerIndex)
static bool js_gfx_IndexBuffer_prop_getBytes(se::State& s)
{
cocos2d::renderer::IndexBuffer* cobj = (cocos2d::renderer::IndexBuffer*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_gfx_IndexBuffer_prop_getBytes : Invalid Native Object");
const auto& args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc == 0) {
uint32_t count = cobj->getBytes();
s.rval().setUint32(count);
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 0);
return false;
}
SE_BIND_PROP_GET(js_gfx_IndexBuffer_prop_getBytes)
static bool js_gfx_FrameBuffer_init(se::State& s)
{
cocos2d::renderer::FrameBuffer* cobj = (cocos2d::renderer::FrameBuffer*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_gfx_FrameBuffer_init : Invalid Native Object");
const auto& args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc == 4) {
cocos2d::renderer::DeviceGraphics* device = nullptr;
uint16_t width = 0;
uint16_t height = 0;
ok &= seval_to_native_ptr(args[0], &device);
ok &= seval_to_uint16(args[1], &width);
ok &= seval_to_uint16(args[2], &height);
SE_PRECONDITION2(ok, false, "js_gfx_FrameBuffer_init : Error processing arguments");
SE_PRECONDITION2(args[3].isObject(), false, "options argument isn't an object!");
std::vector<RenderTarget*> colors;
RenderTarget* depth = nullptr;
RenderTarget* stencil = nullptr;
RenderTarget* depthStencil = nullptr;
se::Object* optionsObj = args[3].toObject();
se::Value colorsVal;
bool result = cobj->init(device, width, height);
ok &= boolean_to_seval(result, &s.rval());
SE_PRECONDITION2(ok, false, "js_gfx_FrameBuffer_init : Error processing arguments");
if (optionsObj->getProperty("colors", &colorsVal) && colorsVal.isObject() && colorsVal.toObject()->isArray())
{
uint32_t len = 0;
if (colorsVal.toObject()->getArrayLength(&len) && len > 0)
{
for (uint32_t i = 0; i < len; ++i)
{
RenderTarget* colorTarget = nullptr;
se::Value colorTargetVal;
colorsVal.toObject()->getArrayElement(i, &colorTargetVal);
seval_to_native_ptr(colorTargetVal, &colorTarget);
colors.push_back(colorTarget);
}
cobj->setColorBuffers(colors);
}
}
se::Value depthVal;
if (optionsObj->getProperty("depth", &depthVal) && depthVal.isObject())
{
seval_to_native_ptr(depthVal, &depth);
cobj->setDepthBuffer(depth);
}
se::Value stencilVal;
if (optionsObj->getProperty("stencil", &stencilVal) && stencilVal.isObject())
{
seval_to_native_ptr(stencilVal, &stencil);
cobj->setStencilBuffer(stencil);
}
se::Value depthStencilVal;
if (optionsObj->getProperty("depthStencil", &depthStencilVal) && depthStencilVal.isObject())
{
seval_to_native_ptr(depthStencilVal, &depthStencil);
cobj->setDepthStencilBuffer(depthStencil);
}
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 4);
return false;
}
SE_BIND_FUNC(js_gfx_FrameBuffer_init)
se::Object* __jsb_cocos2d_renderer_VertexFormat_proto = nullptr;
se::Class* __jsb_cocos2d_renderer_VertexFormat_class = nullptr;
static bool js_cocos2d_renderer_VertexFormat_finalize(se::State& s)
{
cocos2d::renderer::VertexFormat* cobj = (cocos2d::renderer::VertexFormat*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_gfx_VertexFormat_getElement : Invalid Native Object");
cobj->release();
return true;
}
SE_BIND_FINALIZE_FUNC(js_cocos2d_renderer_VertexFormat_finalize)
static bool js_gfx_VertexFormat_constructor(se::State& s)
{
CC_UNUSED bool ok = true;
const auto& args = s.args();
size_t argc = args.size();
if (1 == argc)
{
auto vertexFormat = getVertexFormatFromValue(args[0]);
s.thisObject()->setPrivateData(vertexFormat);
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d", (int)argc);
return false;
}
SE_BIND_CTOR(js_gfx_VertexFormat_constructor, __jsb_cocos2d_renderer_VertexFormat_class, js_cocos2d_renderer_VertexFormat_finalize)
bool js_register_gfx_VertexFormat(se::Object* obj)
{
auto cls = se::Class::create("VertexFormatNative", obj, nullptr, _SE(js_gfx_VertexFormat_constructor));
cls->defineFinalizeFunction(_SE(js_cocos2d_renderer_VertexFormat_finalize));
cls->install();
JSBClassType::registerClass<cocos2d::renderer::VertexFormat>(cls);
__jsb_cocos2d_renderer_VertexFormat_proto = cls->getProto();
__jsb_cocos2d_renderer_VertexFormat_class = cls;
se::ScriptEngine::getInstance()->clearException();
return true;
}
bool jsb_register_gfx_manual(se::Object* global)
{
// Get the ns
se::Value nsVal;
if (!global->getProperty("gfx", &nsVal))
{
se::HandleObject jsobj(se::Object::createPlainObject());
nsVal.setObject(jsobj);
global->setProperty("gfx", nsVal);
}
se::Object* ns = nsVal.toObject();
js_register_gfx_VertexFormat(ns);
__jsb_cocos2d_renderer_DeviceGraphics_proto->defineFunction("clear", _SE(js_gfx_DeviceGraphics_clear));
__jsb_cocos2d_renderer_DeviceGraphics_proto->defineFunction("setUniform", _SE(js_gfx_DeviceGraphics_setUniform));
__jsb_cocos2d_renderer_VertexBuffer_proto->defineFunction("init", _SE(js_gfx_VertexBuffer_init));
__jsb_cocos2d_renderer_VertexBuffer_proto->defineFunction("update", _SE(js_gfx_VertexBuffer_update));
__jsb_cocos2d_renderer_VertexBuffer_proto->defineProperty("_format", nullptr, _SE(js_gfx_VertexBuffer_prop_setFormat));
__jsb_cocos2d_renderer_VertexBuffer_proto->defineProperty("_usage", _SE(js_gfx_VertexBuffer_prop_getUsage), _SE(js_gfx_VertexBuffer_prop_setUsage));
__jsb_cocos2d_renderer_VertexBuffer_proto->defineProperty("_bytes", _SE(js_gfx_VertexBuffer_prop_getBytes), nullptr);
__jsb_cocos2d_renderer_VertexBuffer_proto->defineProperty("_numVertices", _SE(js_gfx_VertexBuffer_prop_getNumVertices), _SE(js_gfx_VertexBuffer_prop_setNumVertices));
__jsb_cocos2d_renderer_VertexBuffer_proto->defineFunction("self", _SE(js_gfx_VertexBuffer_self));
__jsb_cocos2d_renderer_IndexBuffer_proto->defineFunction("init", _SE(js_gfx_IndexBuffer_init));
__jsb_cocos2d_renderer_IndexBuffer_proto->defineFunction("update", _SE(js_gfx_IndexBuffer_update));
__jsb_cocos2d_renderer_IndexBuffer_proto->defineProperty("_format", _SE(js_gfx_IndexBuffer_prop_getFormat), _SE(js_gfx_IndexBuffer_prop_setFormat));
__jsb_cocos2d_renderer_IndexBuffer_proto->defineProperty("_usage", _SE(js_gfx_IndexBuffer_prop_getUsage), _SE(js_gfx_IndexBuffer_prop_setUsage));
__jsb_cocos2d_renderer_IndexBuffer_proto->defineProperty("_bytesPerIndex", _SE(js_gfx_IndexBuffer_prop_getBytesPerIndex), _SE(js_gfx_IndexBuffer_prop_setBytesPerIndex));
__jsb_cocos2d_renderer_IndexBuffer_proto->defineProperty("_bytes", _SE(js_gfx_IndexBuffer_prop_getBytes), nullptr);
__jsb_cocos2d_renderer_IndexBuffer_proto->defineProperty("_numIndices", _SE(js_gfx_IndexBuffer_prop_getNumIndices), _SE(js_gfx_IndexBuffer_prop_setNumIndices));
__jsb_cocos2d_renderer_IndexBuffer_proto->defineFunction("self", _SE(js_gfx_IndexBuffer_self));
__jsb_cocos2d_renderer_FrameBuffer_proto->defineFunction("init", _SE(js_gfx_FrameBuffer_init));
se::ScriptEngine::getInstance()->clearException();
return true;
}
#endif //#if (USE_GFX_RENDERER > 0) && (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_MAC || CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)

View File

@@ -0,0 +1,32 @@
/****************************************************************************
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
namespace se {
class Object;
}
bool jsb_register_gfx_manual(se::Object* global);

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,49 @@
/****************************************************************************
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
#include <string>
namespace se {
class Object;
class Class;
class Value;
}
extern se::Object* __jsbObj;
extern se::Object* __glObj;
bool jsb_register_global_variables(se::Object* global);
void jsb_init_file_operation_delegate();
bool jsb_enable_debugger(const std::string& debuggerServerAddr, uint32_t port, bool isWaitForConnect = false);
bool jsb_set_extend_property(const char* ns, const char* clsName);
bool jsb_run_script(const std::string& filePath, se::Value* rval = nullptr);
bool jsb_run_script_module(const std::string& filePath, se::Value* rval = nullptr);
void jsb_set_xxtea_key(const std::string& key);
bool jsb_global_load_image(const std::string& path, const se::Value& callbackVal);

View File

@@ -0,0 +1,48 @@
/****************************************************************************
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "jsb_helper.hpp"
/* static */
void CleanupTask::pushTaskToAutoReleasePool(const std::function<void()>& cb)
{
auto ret = new (std::nothrow) CleanupTask();
ret->_cb = cb;
ret->autorelease();
}
CleanupTask::CleanupTask()
: _cb(nullptr)
{
}
CleanupTask::~CleanupTask()
{
if (_cb != nullptr)
{
_cb();
}
}

View File

@@ -0,0 +1,42 @@
/****************************************************************************
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
#include "base/CCRef.h"
#include <functional>
class CleanupTask : public cocos2d::Ref
{
public:
static void pushTaskToAutoReleasePool(const std::function<void()>& cb);
CleanupTask();
virtual ~CleanupTask();
private:
std::function<void()> _cb;
};

View File

@@ -0,0 +1,194 @@
/****************************************************************************
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "cocos2d.h"
#include "cocos/scripting/js-bindings/manual/jsb_module_register.hpp"
#include "cocos/scripting/js-bindings/jswrapper/SeApi.h"
#include "cocos/scripting/js-bindings/auto/jsb_cocos2dx_auto.hpp"
#include "cocos/scripting/js-bindings/manual/jsb_global.h"
#include "cocos/scripting/js-bindings/manual/jsb_node.hpp"
#include "cocos/scripting/js-bindings/manual/jsb_conversions.hpp"
#include "cocos/scripting/js-bindings/manual/jsb_opengl_manual.hpp"
#include "cocos/scripting/js-bindings/manual/jsb_platform.h"
#include "cocos/scripting/js-bindings/manual/jsb_cocos2dx_manual.hpp"
#include "cocos/scripting/js-bindings/manual/jsb_xmlhttprequest.hpp"
#include "cocos/scripting/js-bindings/manual/jsb_cocos2dx_network_manual.h"
#include "cocos/scripting/js-bindings/auto/jsb_cocos2dx_network_auto.hpp"
#include "cocos/scripting/js-bindings/auto/jsb_cocos2dx_extension_auto.hpp"
#if USE_GFX_RENDERER
#include "cocos/scripting/js-bindings/auto/jsb_gfx_auto.hpp"
#include "cocos/scripting/js-bindings/auto/jsb_renderer_auto.hpp"
#include "cocos/scripting/js-bindings/manual/jsb_gfx_manual.hpp"
#include "cocos/scripting/js-bindings/manual/jsb_renderer_manual.hpp"
#endif
#if USE_SOCKET
#include "cocos/scripting/js-bindings/manual/jsb_websocket.hpp"
#include "cocos/scripting/js-bindings/manual/jsb_socketio.hpp"
#if USE_WEBSOCKET_SERVER
#include "cocos/scripting/js-bindings/manual/jsb_websocket_server.hpp"
#endif
#endif // USE_SOCKET
#if USE_AUDIO
#include "cocos/scripting/js-bindings/auto/jsb_cocos2dx_audioengine_auto.hpp"
#endif
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_MAC)
#include "cocos/scripting/js-bindings/manual/JavaScriptObjCBridge.h"
#endif
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
#include "cocos/scripting/js-bindings/manual/JavaScriptJavaBridge.h"
#endif
#if USE_GFX_RENDERER && USE_MIDDLEWARE
#include "cocos/scripting/js-bindings/auto/jsb_cocos2dx_editor_support_auto.hpp"
#if USE_SPINE
#include "cocos/scripting/js-bindings/auto/jsb_cocos2dx_spine_auto.hpp"
#include "cocos/scripting/js-bindings/manual/jsb_spine_manual.hpp"
#endif
#if USE_DRAGONBONES
#include "cocos/scripting/js-bindings/auto/jsb_cocos2dx_dragonbones_auto.hpp"
#include "cocos/scripting/js-bindings/manual/jsb_dragonbones_manual.hpp"
#endif
#if USE_PARTICLE
#include "cocos/scripting/js-bindings/auto/jsb_cocos2dx_particle_auto.hpp"
#endif
#endif // USE_MIDDLEWARE
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
#if USE_VIDEO
#include "cocos/scripting/js-bindings/auto/jsb_video_auto.hpp"
#endif
#if USE_WEB_VIEW
#include "cocos/scripting/js-bindings/auto/jsb_webview_auto.hpp"
#endif
#endif // (CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
using namespace cocos2d;
bool jsb_register_all_modules()
{
se::ScriptEngine* se = se::ScriptEngine::getInstance();
se->addBeforeInitHook([](){
JSBClassType::init();
});
se->addBeforeCleanupHook([se](){
se->garbageCollect();
PoolManager::getInstance()->getCurrentPool()->clear();
se->garbageCollect();
PoolManager::getInstance()->getCurrentPool()->clear();
});
se->addRegisterCallback(jsb_register_global_variables);
se->addRegisterCallback(JSB_register_opengl);
se->addRegisterCallback(register_all_engine);
se->addRegisterCallback(register_all_cocos2dx_manual);
se->addRegisterCallback(register_platform_bindings);
se->addRegisterCallback(register_all_network);
se->addRegisterCallback(register_all_cocos2dx_network_manual);
se->addRegisterCallback(register_all_xmlhttprequest);
// extension depend on network
se->addRegisterCallback(register_all_extension);
#if USE_GFX_RENDERER
se->addRegisterCallback(register_all_gfx);
se->addRegisterCallback(jsb_register_gfx_manual);
se->addRegisterCallback(register_all_renderer);
se->addRegisterCallback(jsb_register_renderer_manual);
#endif
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_MAC)
se->addRegisterCallback(register_javascript_objc_bridge);
#endif
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
se->addRegisterCallback(register_javascript_java_bridge);
#endif
#if USE_AUDIO
se->addRegisterCallback(register_all_audioengine);
#endif
#if USE_SOCKET
se->addRegisterCallback(register_all_websocket);
se->addRegisterCallback(register_all_socketio);
#if USE_WEBSOCKET_SERVER
se->addRegisterCallback(register_all_websocket_server);
#endif
#endif
#if USE_GFX_RENDERER && USE_MIDDLEWARE
se->addRegisterCallback(register_all_cocos2dx_editor_support);
#if USE_SPINE
se->addRegisterCallback(register_all_cocos2dx_spine);
se->addRegisterCallback(register_all_spine_manual);
#endif
#if USE_DRAGONBONES
se->addRegisterCallback(register_all_cocos2dx_dragonbones);
se->addRegisterCallback(register_all_dragonbones_manual);
#endif
#if USE_PARTICLE
se->addRegisterCallback(register_all_cocos2dx_particle);
#endif
#endif // USE_MIDDLEWARE
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
#if USE_VIDEO
se->addRegisterCallback(register_all_video);
#endif
#if USE_WEB_VIEW
se->addRegisterCallback(register_all_webview);
#endif
#endif // (CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
se->addAfterCleanupHook([](){
PoolManager::getInstance()->getCurrentPool()->clear();
JSBClassType::destroy();
});
return true;
}

View File

@@ -0,0 +1,31 @@
/****************************************************************************
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
#include <string>
bool jsb_register_all_modules();

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,36 @@
/****************************************************************************
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
namespace se {
class Object;
class Class;
}
extern se::Object* __jsb_Node_proto;
extern se::Class* __jsb_Node_class;
bool jsb_register_Node_manual(se::Object* global);

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,32 @@
/****************************************************************************
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
namespace se {
class Object;
}
bool JSB_register_opengl(se::Object* obj);

View File

@@ -0,0 +1,25 @@
/****************************************************************************
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "jsb_opengl_utils.hpp"

View File

@@ -0,0 +1,64 @@
/****************************************************************************
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
#include "cocos/renderer/gfx/GFXUtils.h"
#define _JSB_GL_CHECK(_call) \
do { \
_call; \
GLenum gl_err = glGetError(); \
if (0 != gl_err) { \
SE_REPORT_ERROR(#_call "; GL error 0x%x: %s", gl_err, glEnumName(gl_err)); \
return false; \
} \
} while(false)
#define _JSB_GL_CHECK_VOID(_call) \
do { \
_call; \
GLenum gl_err = glGetError(); \
if (0 != gl_err) { \
SE_REPORT_ERROR(#_call "; GL error 0x%x: %s", gl_err, glEnumName(gl_err)); \
} \
} while(false)
#if COCOS2D_DEBUG > 0
#define JSB_GL_CHECK(_call) _JSB_GL_CHECK(_call)
#define JSB_GL_CHECK_VOID(_call) _JSB_GL_CHECK_VOID(_call)
#define JSB_GL_CHECK_ERROR() \
do { \
GLenum gl_err = glGetError(); \
if (0 != gl_err) { \
SE_REPORT_ERROR("line: %d: GL error 0x%x: %s", __LINE__, gl_err, glEnumName(gl_err)); \
return false; \
} \
} while(false)
#else
#define JSB_GL_CHECK(_call) _call
#define JSB_GL_CHECK_VOID(_call) _call
#define JSB_GL_CHECK_ERROR()
#endif // BRENDERER_CONFIG_DEBUG

View File

@@ -0,0 +1,35 @@
/****************************************************************************
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
#include <unordered_map>
namespace se {
class Object;
}
bool register_platform_bindings(se::Object* obj);
const std::unordered_map<std::string, std::string>& getFontFamilyNameMap();

View File

@@ -0,0 +1,96 @@
/****************************************************************************
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "jsb_platform.h"
#include "cocos/scripting/js-bindings/jswrapper/SeApi.h"
#include "cocos/scripting/js-bindings/manual/jsb_conversions.hpp"
#include "cocos/scripting/js-bindings/manual/jsb_global.h"
#include "cocos/platform/CCFileUtils.h"
#include <regex>
#ifndef JCLS_CANVASIMPL
#define JCLS_CANVASIMPL "org/cocos2dx/lib/CanvasRenderingContext2DImpl"
#endif
using namespace cocos2d;
static std::unordered_map<std::string, std::string> _fontFamilyNameMap;
const std::unordered_map<std::string, std::string>& getFontFamilyNameMap()
{
return _fontFamilyNameMap;
}
static bool JSB_loadFont(se::State& s)
{
const auto& args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc >= 1) {
s.rval().setNull();
std::string originalFamilyName;
ok &= seval_to_std_string(args[0], &originalFamilyName);
SE_PRECONDITION2(ok, false, "JSB_loadFont : Error processing argument: originalFamilyName");
std::string source;
ok &= seval_to_std_string(args[1], &source);
SE_PRECONDITION2(ok, false, "JSB_loadFont : Error processing argument: source");
std::string fontFilePath;
std::regex re("url\\(\\s*'\\s*(.*?)\\s*'\\s*\\)");
std::match_results<std::string::const_iterator> results;
if (std::regex_search(source.cbegin(), source.cend(), results, re))
{
fontFilePath = results[1].str();
}
fontFilePath = FileUtils::getInstance()->fullPathForFilename(fontFilePath);
if (fontFilePath.empty())
{
SE_LOGE("Font (%s) doesn't exist!", fontFilePath.c_str());
return true;
}
JniHelper::callStaticVoidMethod(JCLS_CANVASIMPL, "loadTypeface", originalFamilyName, fontFilePath);
s.rval().setString(originalFamilyName);
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 1);
return false;
}
SE_BIND_FUNC(JSB_loadFont)
bool register_platform_bindings(se::Object* obj)
{
__jsbObj->defineFunction("loadFont", _SE(JSB_loadFont));
return true;
}

View File

@@ -0,0 +1,208 @@
/****************************************************************************
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#import "jsb_platform.h"
#include "cocos/scripting/js-bindings/jswrapper/SeApi.h"
#include "cocos/scripting/js-bindings/manual/jsb_conversions.hpp"
#include "cocos/scripting/js-bindings/manual/jsb_global.h"
#include "cocos/platform/CCFileUtils.h"
#import <Foundation/Foundation.h>
#import <CoreText/CoreText.h>
#include <regex>
#include <unordered_set>
using namespace cocos2d;
static std::unordered_set<CGFontRef> _fontSet;
static std::unordered_map<std::string, std::string> _fontFamilyNameMap;
const std::unordered_map<std::string, std::string>& getFontFamilyNameMap()
{
return _fontFamilyNameMap;
}
static std::vector<std::string> getAvailableFontFamilyNames()
{
std::vector<std::string> ret;
#if CC_TARGET_PLATFORM == CC_PLATFORM_MAC
CFArrayRef allFamilyNames = CTFontManagerCopyAvailableFontFamilyNames();
#else
CFArrayRef allFamilyNames = (CFArrayRef) [[UIFont familyNames] retain];
#endif
char buf[256] = {0};
for(CFIndex i = 0; i < CFArrayGetCount(allFamilyNames); i++)
{
CFStringRef fontName = (CFStringRef)CFArrayGetValueAtIndex(allFamilyNames, i);
if (CFStringGetCString(fontName, buf, sizeof(buf), kCFStringEncodingUTF8) != 0)
{
ret.push_back(buf);
}
}
CFRelease(allFamilyNames);
return ret;
}
static std::string getFontFamilyByCompareAvailableFontFamilyNames(const std::vector<std::string>& before, const std::vector<std::string>& after)
{
std::string ret;
size_t beforeLen = before.size();
size_t afterLen = after.size();
if (afterLen > beforeLen)
{
for(size_t i = 0;i < afterLen; ++i)
{
bool hasFont = false;
for(size_t j = 0;j < beforeLen; ++j)
{
if (after[i] == before[j])
{
hasFont = true;
break;
}
}
if (!hasFont)
{
ret = after[i];
break;
}
if (ret.empty())
ret = after.back();
}
}
return ret;
}
static bool JSB_loadFont(se::State& s)
{
const auto& args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc >= 1) {
s.rval().setNull();
std::string originalFamilyName;
ok &= seval_to_std_string(args[0], &originalFamilyName);
SE_PRECONDITION2(ok, false, "JSB_loadFont : Error processing argument: originalFamilyName");
// Don't reload font again to avoid memory leak.
if (_fontFamilyNameMap.find(originalFamilyName) != _fontFamilyNameMap.end())
{
s.rval().setString(_fontFamilyNameMap[originalFamilyName]);
return true;
}
std::string source;
ok &= seval_to_std_string(args[1], &source);
SE_PRECONDITION2(ok, false, "JSB_loadFont : Error processing argument: source");
std::string fontFilePath;
std::regex re("url\\(\\s*'\\s*(.*?)\\s*'\\s*\\)");
std::match_results<std::string::const_iterator> results;
if (std::regex_search(source.cbegin(), source.cend(), results, re))
{
fontFilePath = results[1].str();
}
fontFilePath = FileUtils::getInstance()->fullPathForFilename(fontFilePath);
if (fontFilePath.empty())
{
SE_LOGE("Font (%s) doesn't exist!", fontFilePath.c_str());
return true;
}
NSURL* url = [NSURL fileURLWithPath: [NSString stringWithUTF8String:fontFilePath.c_str()]];
NSData* dynamicFontData = [NSData dataWithContentsOfURL:url];
if (!dynamicFontData)
{
SE_LOGE("load font (%s) failed!", source.c_str());
return true;
}
const auto& familyNamesBeforeRegister = getAvailableFontFamilyNames();
bool succeed = true;
CFErrorRef error;
CGDataProviderRef providerRef = CGDataProviderCreateWithCFData((CFDataRef)dynamicFontData);
CGFontRef font = CGFontCreateWithDataProvider(providerRef);
if (!CTFontManagerRegisterGraphicsFont(font, &error))
{
CFStringRef errorDescription = CFErrorCopyDescription(error);
const char* cErrorStr = CFStringGetCStringPtr(errorDescription, kCFStringEncodingUTF8);
SE_LOGE("Failed to load font: %s", cErrorStr);
CFRelease(errorDescription);
succeed = false;
}
if (succeed)
{
const auto& familyNamesAfterRegister = getAvailableFontFamilyNames();
std::string familyName = getFontFamilyByCompareAvailableFontFamilyNames(familyNamesBeforeRegister, familyNamesAfterRegister);
if (!familyName.empty())
{
_fontFamilyNameMap.emplace(originalFamilyName, familyName);
s.rval().setString(familyName);
}
_fontSet.insert(font);
}
else {
CFRelease(font);
}
CFRelease(providerRef);
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 1);
return false;
}
SE_BIND_FUNC(JSB_loadFont)
bool register_platform_bindings(se::Object* obj)
{
__jsbObj->defineFunction("loadFont", _SE(JSB_loadFont));
se::ScriptEngine::getInstance()->addBeforeCleanupHook([](){
CFErrorRef error;
for (auto font : _fontSet) {
CTFontManagerUnregisterGraphicsFont(font, &error);
CFRelease(font);
}
_fontSet.clear();
_fontFamilyNameMap.clear();
});
return true;
}

View File

@@ -0,0 +1,93 @@
/****************************************************************************
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "jsb_platform.h"
#include "cocos/scripting/js-bindings/jswrapper/SeApi.h"
#include "cocos/scripting/js-bindings/manual/jsb_conversions.hpp"
#include "cocos/scripting/js-bindings/manual/jsb_global.h"
#include "cocos/platform/CCFileUtils.h"
#include <regex>
using namespace cocos2d;
static std::unordered_map<std::string, std::string> _fontFamilyNameMap;
const std::unordered_map<std::string, std::string>& getFontFamilyNameMap()
{
return _fontFamilyNameMap;
}
static bool JSB_loadFont(se::State& s)
{
const auto& args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc >= 1) {
s.rval().setNull();
std::string originalFamilyName;
ok &= seval_to_std_string(args[0], &originalFamilyName);
SE_PRECONDITION2(ok, false, "JSB_loadFont : Error processing argument: originalFamilyName");
std::string source;
ok &= seval_to_std_string(args[1], &source);
SE_PRECONDITION2(ok, false, "JSB_loadFont : Error processing argument: source");
std::string fontFilePath;
std::regex re("url\\(\\s*'\\s*(.*?)\\s*'\\s*\\)");
std::match_results<std::string::const_iterator> results;
if (std::regex_search(source.cbegin(), source.cend(), results, re))
{
fontFilePath = results[1].str();
}
fontFilePath = FileUtils::getInstance()->fullPathForFilename(fontFilePath);
if (fontFilePath.empty())
{
SE_LOGE("Font (%s) doesn't exist!", fontFilePath.c_str());
return true;
}
// just put the path info, used at CanvasRenderingContext2DImpl::updateFont()
_fontFamilyNameMap.emplace(originalFamilyName, fontFilePath);
s.rval().setString(originalFamilyName);
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 1);
return false;
}
SE_BIND_FUNC(JSB_loadFont)
bool register_platform_bindings(se::Object* obj)
{
__jsbObj->defineFunction("loadFont", _SE(JSB_loadFont));
return true;
}

View File

@@ -0,0 +1,470 @@
/****************************************************************************
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "base/ccConfig.h"
#include "jsb_renderer_manual.hpp"
#if (USE_GFX_RENDERER > 0) && (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_MAC || CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
#include "cocos/scripting/js-bindings/auto/jsb_renderer_auto.hpp"
#include "cocos/scripting/js-bindings/manual/jsb_conversions.hpp"
#include "scene/NodeProxy.hpp"
#include "scene/assembler/Assembler.hpp"
#include "jsb_conversions.hpp"
using namespace cocos2d;
using namespace cocos2d::renderer;
static bool js_renderer_Camera_getColor(se::State& s)
{
cocos2d::renderer::Camera* cobj = (cocos2d::renderer::Camera*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_renderer_Camera_getColor : Invalid Native Object");
auto& args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc == 1) {
Color4F color;
cobj->getColor(color);
se::Object* arg0Obj = args[0].toObject();
arg0Obj->setProperty("r", se::Value(color.r));
arg0Obj->setProperty("g", se::Value(color.g));
arg0Obj->setProperty("b", se::Value(color.b));
s.rval().setObject(arg0Obj);
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 1);
return false;
}
SE_BIND_FUNC(js_renderer_Camera_getColor)
static bool js_renderer_Camera_getRect(se::State& s)
{
cocos2d::renderer::Camera* cobj = (cocos2d::renderer::Camera*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_renderer_Camera_getRect : Invalid Native Object");
auto& args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc == 1) {
cocos2d::renderer::Rect rect;
cobj->getRect(rect);
se::Object* arg0Obj = args[0].toObject();
arg0Obj->setProperty("x", se::Value(rect.x));
arg0Obj->setProperty("y", se::Value(rect.y));
arg0Obj->setProperty("w", se::Value(rect.w));
arg0Obj->setProperty("h", se::Value(rect.h));
s.rval().setObject(arg0Obj);
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 1);
return false;
}
SE_BIND_FUNC(js_renderer_Camera_getRect)
static bool js_renderer_Camera_screenToWorld(se::State& s)
{
cocos2d::renderer::Camera* cobj = (cocos2d::renderer::Camera*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_renderer_Camera_screenToWorld : Invalid Native Object");
auto& args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc == 4) {
cocos2d::Vec3 out;
cocos2d::Vec3 screenPos;
ok = seval_to_Vec3(args[1], &screenPos);
SE_PRECONDITION2(ok, false, "Convert arg1 failed!");
int32_t width = 0;
ok = seval_to_int32(args[2], &width);
SE_PRECONDITION2(ok, false, "Convert arg2 failed!");
int32_t height = 0;
ok = seval_to_int32(args[3], &height);
SE_PRECONDITION2(ok, false, "Convert arg3 failed!");
cobj->screenToWorld(out, screenPos, width, height);
se::Object* arg0Obj = args[0].toObject();
arg0Obj->setProperty("x", se::Value(out.x));
arg0Obj->setProperty("y", se::Value(out.y));
arg0Obj->setProperty("z", se::Value(out.z));
s.rval().setObject(arg0Obj);
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 4);
return false;
}
SE_BIND_FUNC(js_renderer_Camera_screenToWorld)
static bool js_renderer_Camera_worldToScreen(se::State& s)
{
cocos2d::renderer::Camera* cobj = (cocos2d::renderer::Camera*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_renderer_Camera_worldToScreen : Invalid Native Object");
auto& args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc == 4) {
cocos2d::Vec3 out;
cocos2d::Vec3 worldPos;
ok = seval_to_Vec3(args[1], &worldPos);
SE_PRECONDITION2(ok, false, "Convert arg1 failed!");
int32_t width = 0;
ok = seval_to_int32(args[2], &width);
SE_PRECONDITION2(ok, false, "Convert arg2 failed!");
int32_t height = 0;
ok = seval_to_int32(args[3], &height);
SE_PRECONDITION2(ok, false, "Convert arg3 failed!");
cobj->worldToScreen(out, worldPos, width, height);
se::Object* arg0Obj = args[0].toObject();
arg0Obj->setProperty("x", se::Value(out.x));
arg0Obj->setProperty("y", se::Value(out.y));
arg0Obj->setProperty("z", se::Value(out.z));
s.rval().setObject(arg0Obj);
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 4);
return false;
}
SE_BIND_FUNC(js_renderer_Camera_worldToScreen)
static bool js_renderer_Effect_self(se::State& s)
{
cocos2d::renderer::Effect* cobj = (cocos2d::renderer::Effect*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_renderer_Effect_self : Invalid Native Object");
auto addr = (unsigned long)cobj;
s.rval().setNumber(addr);
return true;
}
SE_BIND_FUNC(js_renderer_Effect_self);
static bool js_renderer_Light_extractView(se::State& s)
{
cocos2d::renderer::Light* cobj = (cocos2d::renderer::Light*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_renderer_Light_extractView : Invalid Native Object");
auto& args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc == 2) {
cocos2d::renderer::View* view;
ok = seval_to_native_ptr(args[0], &view);
SE_PRECONDITION2(ok, false, "Convert arg0 failed!");
std::vector<std::string> stages;
ok = seval_to_std_vector_string(args[1], &stages);
SE_PRECONDITION2(ok, false, "Convert arg1 failed!");
cobj->extractView(*view, stages);
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 2);
return false;
}
SE_BIND_FUNC(js_renderer_Light_extractView)
static bool js_renderer_Light_setNode(se::State& s)
{
cocos2d::renderer::Light* cobj = (cocos2d::renderer::Light*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_renderer_Light_setNode : Invalid Native Object");
auto& args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc == 1) {
se::Value jsproxy;
ok = args[0].toObject()->getProperty("_proxy", &jsproxy);
SE_PRECONDITION2(ok, false, "js_renderer_Light_setNode : Cannot find node proxy form Node");
NodeProxy* proxy = nullptr;
ok = seval_to_native_ptr(jsproxy, &proxy);
SE_PRECONDITION2(ok, false, "js_renderer_Light_setNode : Invalid Node Proxy");
cobj->setNode(proxy);
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 1);
return false;
}
SE_BIND_FUNC(js_renderer_Light_setNode)
static bool js_renderer_View_getForward(se::State& s)
{
cocos2d::renderer::View* cobj = (cocos2d::renderer::View*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_renderer_View_getForward : Invalid Native Object");
auto& args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc == 1) {
cocos2d::Vec3 out;
cobj->getForward(out);
se::Object* arg0Obj = args[0].toObject();
arg0Obj->setProperty("x", se::Value(out.x));
arg0Obj->setProperty("y", se::Value(out.y));
arg0Obj->setProperty("z", se::Value(out.z));
s.rval().setObject(arg0Obj);
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 4);
return false;
}
SE_BIND_FUNC(js_renderer_View_getForward)
static bool js_renderer_View_getPosition(se::State& s)
{
cocos2d::renderer::View* cobj = (cocos2d::renderer::View*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_renderer_View_getPosition : Invalid Native Object");
auto& args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc == 1) {
cocos2d::Vec3 out;
cobj->getPosition(out);
se::Object* arg0Obj = args[0].toObject();
arg0Obj->setProperty("x", se::Value(out.x));
arg0Obj->setProperty("y", se::Value(out.y));
arg0Obj->setProperty("z", se::Value(out.z));
s.rval().setObject(arg0Obj);
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 4);
return false;
}
SE_BIND_FUNC(js_renderer_View_getPosition)
static bool js_renderer_addStage(se::State& s)
{
auto& args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc == 1) {
std::string stageName;
ok = seval_to_std_string(args[0], &stageName);
SE_PRECONDITION2(ok, false, "Convert arg0 failed!");
Config::addStage(stageName);
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 1);
return false;
}
SE_BIND_FUNC(js_renderer_addStage)
static bool js_renderer_getStageIDs(se::State& s)
{
auto& args = s.args();
size_t argc = args.size();
if (argc == 1)
{
std::vector<std::string> stageNames;
CC_UNUSED bool ok = seval_to_std_vector_string(args[0], &stageNames);
SE_PRECONDITION2(ok, false, "Convert arg0 failed!");
unsigned int stageIDs = cocos2d::renderer::Config::getStageIDs(stageNames);
uint32_to_seval(stageIDs, &s.rval());
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 1);
return false;
}
SE_BIND_FUNC(js_renderer_getStageIDs);
static bool js_renderer_getStageID(se::State& s)
{
auto& args = s.args();
size_t argc = args.size();
if (argc == 1)
{
std::string stageName;
CC_UNUSED bool ok = seval_to_std_string(args[0], &stageName);
SE_PRECONDITION2(ok, false, "Convert arg0 failed!");
int stageID = cocos2d::renderer::Config::getStageID(stageName);
int32_to_seval(stageID, &s.rval());
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 1);
return false;
}
SE_BIND_FUNC(js_renderer_getStageID);
static bool js_renderer_Camera_setNode(se::State& s)
{
cocos2d::renderer::Camera* cobj = (cocos2d::renderer::Camera*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_renderer_Camera_setNode : Invalid Native Object");
auto& args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc == 1) {
se::Value jsproxy;
ok = args[0].toObject()->getProperty("_proxy", &jsproxy);
SE_PRECONDITION2(ok, false, "js_renderer_Camera_setNode : Cannot find node proxy form Node");
NodeProxy* proxy = nullptr;
ok = seval_to_native_ptr(jsproxy, &proxy);
SE_PRECONDITION2(ok, false, "js_renderer_Camera_setNode : Invalid Node Proxy");
cobj->setNode(proxy);
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 1);
return false;
}
SE_BIND_FUNC(js_renderer_Camera_setNode)
static bool js_renderer_Camera_getNode(se::State& s)
{
cocos2d::renderer::Camera* cobj = (cocos2d::renderer::Camera*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_renderer_Camera_getNode : Invalid Native Object");
cocos2d::renderer::NodeProxy* node = cobj->getNode();
se::Value jsproxy;
native_ptr_to_seval<cocos2d::renderer::NodeProxy>(node, &jsproxy);
se::Value jsnode;
jsproxy.toObject()->getProperty("_owner", &jsnode);
s.rval().setObject(jsnode.toObject());
return true;
}
SE_BIND_FUNC(js_renderer_Camera_getNode)
static bool js_renderer_Config_addStage(se::State& s)
{
const auto& args = s.args();
size_t argc = args.size();
if (argc == 1)
{
std::string arg0;
bool ok = seval_to_std_string(args[0], &arg0);
SE_PRECONDITION2(ok, false, "js_renderer_Scene_addCamera : Error processing arguments");
cocos2d::renderer::Config::addStage(arg0);
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 0);
return false;
}
SE_BIND_FUNC(js_renderer_Config_addStage);
static bool js_renderer_BaseRenderer_prop_getProgramLib(se::State& s)
{
cocos2d::renderer::BaseRenderer* cobj = (cocos2d::renderer::BaseRenderer*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_renderer_BaseRenderer_prop_getProgramLib: Invalid Native Object.");
const auto& args = s.args();
size_t argc = args.size();
if (argc == 0)
{
auto programLib = cobj->getProgramLib();
native_ptr_to_seval<cocos2d::renderer::ProgramLib>(programLib, &s.rval());
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 0);
return false;
}
SE_BIND_PROP_GET(js_renderer_BaseRenderer_prop_getProgramLib);
static bool js_register_renderer_Config(se::Object* obj)
{
auto cls = se::Class::create("Config", obj, nullptr, nullptr);
cls->defineStaticFunction("addStage", _SE(js_renderer_Config_addStage));
cls->install();
JSBClassType::registerClass<cocos2d::renderer::Config>(cls);
se::ScriptEngine::getInstance()->clearException();
return true;
}
static bool js_renderer_Effect_init(se::State& s)
{
cocos2d::renderer::Effect* cobj = (cocos2d::renderer::Effect*)s.nativeThisObject();
CC_UNUSED bool ok = true;
const auto& args = s.args();
std::string asset;
seval_to_std_string(args[0], &asset);
cocos2d::Vector<cocos2d::renderer::Technique*> arg0;
ok &= seval_to_EffectAsset(args[0], &arg0);
SE_PRECONDITION2(ok, false, "js_renderer_Effect_init : Error processing arguments");
cobj->init(arg0);
return true;
}
SE_BIND_FUNC(js_renderer_Effect_init);
static bool js_renderer_EffectBase_setProperty(se::State& s)
{
cocos2d::renderer::EffectVariant* cobj = (cocos2d::renderer::EffectVariant*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_renderer_EffectBase_setProperty : Invalid Native Object");
const auto& args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc == 4) {
std::string arg0;
int passIdx;
bool directly;
ok &= seval_to_std_string(args[0], &arg0);
SE_PRECONDITION2(ok, false, "js_renderer_EffectBase_setProperty : Name Error");
ok &= seval_to_int32(args[2], &passIdx);
SE_PRECONDITION2(ok, false, "js_renderer_EffectBase_setProperty : passIdx Error");
ok &= seval_to_boolean(args[3], &directly);
SE_PRECONDITION2(ok, false, "js_renderer_EffectBase_setProperty : directly Error");
ok &= seval_to_Effect_setProperty(arg0, args[1], cobj, passIdx, directly);
SE_PRECONDITION2(ok, false, "js_renderer_EffectBase_setProperty : Error processing arguments");
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 2);
return false;
}
SE_BIND_FUNC(js_renderer_EffectBase_setProperty);
bool jsb_register_renderer_manual(se::Object* global)
{
// Get the ns
se::Value nsVal;
if (!global->getProperty("renderer", &nsVal))
{
se::HandleObject jsobj(se::Object::createPlainObject());
nsVal.setObject(jsobj);
global->setProperty("renderer", nsVal);
}
se::Object* ns = nsVal.toObject();
js_register_renderer_Config(ns);
// Effect
__jsb_cocos2d_renderer_Effect_proto->defineFunction("self", _SE(js_renderer_Effect_self));
// Light
__jsb_cocos2d_renderer_Light_proto->defineFunction("extractView", _SE(js_renderer_Light_extractView));
__jsb_cocos2d_renderer_Light_proto->defineFunction("setNode", _SE(js_renderer_Light_setNode));
// View
__jsb_cocos2d_renderer_View_proto->defineFunction("getForward", _SE(js_renderer_View_getForward));
__jsb_cocos2d_renderer_View_proto->defineFunction("getPosition", _SE(js_renderer_View_getPosition));
// Config
se::Value rendererVal;
global->getProperty("renderer", &rendererVal);
rendererVal.toObject()->defineFunction("addStage", _SE(js_renderer_addStage));
rendererVal.toObject()->defineFunction("stageIDs", _SE(js_renderer_getStageIDs));
rendererVal.toObject()->defineFunction("stageID", _SE(js_renderer_getStageID));
// Camera
__jsb_cocos2d_renderer_Camera_proto->defineFunction("setNode", _SE(js_renderer_Camera_setNode));
__jsb_cocos2d_renderer_Camera_proto->defineFunction("getNode", _SE(js_renderer_Camera_getNode));
__jsb_cocos2d_renderer_Camera_proto->defineFunction("screenToWorld", _SE(js_renderer_Camera_screenToWorld));
__jsb_cocos2d_renderer_Camera_proto->defineFunction("worldToScreen", _SE(js_renderer_Camera_worldToScreen));
// Effect
__jsb_cocos2d_renderer_Effect_proto->defineFunction("init", _SE(js_renderer_Effect_init));
// EffectVariant
__jsb_cocos2d_renderer_EffectBase_proto->defineFunction("setProperty", _SE(js_renderer_EffectBase_setProperty));
return true;
}
#endif //#if (USE_GFX_RENDERER > 0) && (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_MAC || CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)

View File

@@ -0,0 +1,32 @@
/****************************************************************************
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
namespace se {
class Object;
}
bool jsb_register_renderer_manual(se::Object* global);

View File

@@ -0,0 +1,404 @@
/****************************************************************************
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "jsb_socketio.hpp"
#include "cocos/scripting/js-bindings/jswrapper/SeApi.h"
#include "cocos/scripting/js-bindings/manual/jsb_conversions.hpp"
#include "cocos/scripting/js-bindings/manual/jsb_global.h"
#include "cocos/network/SocketIO.h"
#include "base/ccUTF8.h"
#include "platform/CCApplication.h"
using namespace cocos2d;
using namespace cocos2d::network;
se::Class* __jsb_SocketIO_class = nullptr;
class JSB_SocketIODelegate : public Ref, public SocketIO::SIODelegate
{
public:
//c++11 map to callbacks
typedef std::unordered_map<std::string/* eventName */, se::ValueArray/* 0:callbackFunc, 1:target */> JSB_SIOCallbackRegistry;
JSB_SocketIODelegate()
{
}
virtual ~JSB_SocketIODelegate()
{
CCLOGINFO("In the destructor of JSB_SocketIODelegate(%p)", this);
}
virtual void onConnect(SIOClient* client) override
{
}
virtual void onMessage(SIOClient* client, const std::string& data) override
{
}
virtual void onClose(SIOClient* client) override
{
CCLOG("JSB SocketIO::SIODelegate->onClose method called from native");
this->fireEventToScript(client, "disconnect", "");
auto iter = se::NativePtrToObjectMap::find(client);
if (iter != se::NativePtrToObjectMap::end())
{
iter->second->unroot();
}
if (getReferenceCount() == 1)
{
autorelease();
}
else
{
release();
}
}
virtual void onError(SIOClient* client, const std::string& data) override
{
CCLOG("JSB SocketIO::SIODelegate->onError method called from native with data: %s", data.c_str());
this->fireEventToScript(client, "error", data);
auto iter = se::NativePtrToObjectMap::find(client);
if (iter != se::NativePtrToObjectMap::end())
{
iter->second->unroot();
}
}
virtual void fireEventToScript(SIOClient* client, const std::string& eventName, const std::string& data) override
{
CCLOG("JSB SocketIO::SIODelegate->fireEventToScript method called from native with name '%s' data: %s", eventName.c_str(), data.c_str());
se::ScriptEngine::getInstance()->clearException();
se::AutoHandleScope hs;
if (cocos2d::Application::getInstance() == nullptr)
return;
auto iter = se::NativePtrToObjectMap::find(client); //IDEA: client probably be a new value with the same address as the old one, it may cause undefined result.
if (iter == se::NativePtrToObjectMap::end())
return;
se::Value dataVal;
if (data.empty())
{
dataVal.setNull();
}
else
{
dataVal.setString(data);
}
JSB_SIOCallbackRegistry::iterator it = _eventRegistry.find(eventName);
if (it != _eventRegistry.end())
{
const se::ValueArray& cbStruct = it->second;
assert(cbStruct.size() == 2);
const se::Value& callback = cbStruct[0];
const se::Value& target = cbStruct[1];
if (callback.isObject() && callback.toObject()->isFunction() && target.isObject())
{
se::ValueArray args;
args.push_back(dataVal);
callback.toObject()->call(args, target.toObject());
}
}
if (eventName == "disconnect")
{
cocos2d::log("disconnect ... "); //IDEA:
}
}
void addEvent(const std::string& eventName, const se::Value& callback, const se::Value& target)
{
assert(callback.isObject() && callback.toObject()->isFunction());
assert(target.isObject());
_eventRegistry[eventName].clear();
_eventRegistry[eventName].push_back(callback);
_eventRegistry[eventName].push_back(target);
target.toObject()->attachObject(callback.toObject());
}
private:
JSB_SIOCallbackRegistry _eventRegistry;
};
static bool SocketIO_finalize(se::State& s)
{
SIOClient* cobj = (SIOClient*)s.nativeThisObject();
CCLOGINFO("jsbindings: finalizing JS object %p (SocketIO)", cobj);
cobj->disconnect();
JSB_SocketIODelegate* delegate = static_cast<JSB_SocketIODelegate*>(cobj->getDelegate());
if (delegate->getReferenceCount() == 1)
{
delegate->autorelease();
}
else
{
delegate->release();
}
cobj->release();
return true;
}
SE_BIND_FINALIZE_FUNC(SocketIO_finalize)
static bool SocketIO_prop_getTag(se::State& s)
{
SIOClient* cobj = (SIOClient*)s.nativeThisObject();
s.rval().setString(cobj->getTag());
return true;
}
SE_BIND_PROP_GET(SocketIO_prop_getTag)
static bool SocketIO_prop_setTag(se::State& s)
{
SIOClient* cobj = (SIOClient*)s.nativeThisObject();
cobj->setTag(s.args()[0].toString().c_str());
return true;
}
SE_BIND_PROP_SET(SocketIO_prop_setTag)
static bool SocketIO_send(se::State& s)
{
const auto& args = s.args();
int argc = (int)args.size();
SIOClient* cobj = (SIOClient*)s.nativeThisObject();
if (argc == 1)
{
std::string payload;
bool ok = seval_to_std_string(args[0], &payload);
SE_PRECONDITION2(ok, false, "Converting payload failed!");
cobj->send(payload);
return true;
}
SE_REPORT_ERROR("Wrong number of arguments: %d, expected: %d", argc, 1);
return false;
}
SE_BIND_FUNC(SocketIO_send)
static bool SocketIO_emit(se::State& s)
{
const auto& args = s.args();
int argc = (int)args.size();
SIOClient* cobj = (SIOClient*)s.nativeThisObject();
if (argc >= 1)
{
bool ok = false;
std::string eventName;
ok = seval_to_std_string(args[0], &eventName);
SE_PRECONDITION2(ok, false, "Converting eventName failed!");
std::string payload;
if (argc >= 2)
{
const auto& arg1 = args[1];
// Add this check to make it compatible with old version.
// jsval_to_std_string in v1.6 returns empty string if arg1 is null or undefined
// while seval_to_std_string since 1.7.2 follows JS standard to return "null" or "undefined".
// Therefore, we need a workaround to make it be compatible with versions lower than v1.7.
if (!arg1.isNullOrUndefined())
{
ok = seval_to_std_string(arg1, &payload);
SE_PRECONDITION2(ok, false, "Converting payload failed!");
}
}
cobj->emit(eventName, payload);
return true;
}
SE_REPORT_ERROR("Wrong number of arguments: %d, expected: %d", argc, 2);
return false;
}
SE_BIND_FUNC(SocketIO_emit)
static bool SocketIO_disconnect(se::State& s)
{
const auto& args = s.args();
int argc = (int)args.size();
SIOClient* cobj = (SIOClient*)s.nativeThisObject();
if (argc == 0)
{
cobj->disconnect();
return true;
}
SE_REPORT_ERROR("Wrong number of arguments: %d, expected: %d", argc, 0);
return false;
}
SE_BIND_FUNC(SocketIO_disconnect)
static bool SocketIO_on(se::State& s)
{
const auto& args = s.args();
int argc = (int)args.size();
SIOClient* cobj = (SIOClient*)s.nativeThisObject();
if (argc == 2)
{
bool ok = false;
std::string eventName;
ok = seval_to_std_string(args[0], &eventName);
SE_PRECONDITION2(ok, false, "Converting eventName failed!");
CCLOG("JSB SocketIO eventName to: '%s'", eventName.c_str());
((JSB_SocketIODelegate *)cobj->getDelegate())->addEvent(eventName, args[1], se::Value(s.thisObject()));
return true;
}
SE_REPORT_ERROR("Wrong number of arguments: %d, expected: %d", argc, 2);
return false;
}
SE_BIND_FUNC(SocketIO_on)
// static
static bool SocketIO_connect(se::State& s)
{
const auto& args = s.args();
int argc = (int)args.size();
CCLOG("JSB SocketIO.connect method called");
if (argc >= 1 && argc <= 3)
{
std::string url;
std::string caFilePath;
bool ok = false;
ok = seval_to_std_string(args[0], &url);
SE_PRECONDITION2(ok, false, "Error processing arguments");
if (argc == 2)
{
if (args[1].isObject())
{
// Just ignore the option argument
}
else if (args[1].isString())
{
// Assume it's CA root file path
ok = seval_to_std_string(args[1], &caFilePath);
SE_PRECONDITION2( ok, false, "Error processing arguments");
}
}
if (argc == 3)
{
// Just ignore the option argument
if (args[2].isString())
{
// Assume it's CA root file path
ok = seval_to_std_string(args[2], &caFilePath);
SE_PRECONDITION2( ok, false, "Error processing arguments");
}
}
JSB_SocketIODelegate* siodelegate = new (std::nothrow) JSB_SocketIODelegate();
CCLOG("Calling native SocketIO.connect method");
SIOClient* ret = SocketIO::connect(url, *siodelegate, caFilePath);
if (ret != nullptr)
{
ret->retain();
siodelegate->retain();
se::Object* obj = se::Object::createObjectWithClass(__jsb_SocketIO_class);
obj->setPrivateData(ret);
s.rval().setObject(obj);
obj->root();
return true;
}
else
{
siodelegate->release();
SE_REPORT_ERROR("SocketIO.connect return nullptr!");
return false;
}
}
SE_REPORT_ERROR("JSB SocketIO.connect: Wrong number of arguments");
return false;
}
SE_BIND_FUNC(SocketIO_connect)
// static
static bool SocketIO_close(se::State& s)
{
const auto& args = s.args();
int argc = (int)args.size();
if (argc == 0)
{
return true;
}
SE_REPORT_ERROR("Wrong number of arguments: %d, expected: %d", argc, 0);
return false;
}
SE_BIND_FUNC(SocketIO_close)
bool register_all_socketio(se::Object* obj)
{
se::Class* cls = se::Class::create("SocketIO", obj, nullptr, nullptr);
cls->defineFinalizeFunction(_SE(SocketIO_finalize));
cls->defineProperty("tag", _SE(SocketIO_prop_getTag), _SE(SocketIO_prop_setTag));
cls->defineFunction("send", _SE(SocketIO_send));
cls->defineFunction("emit", _SE(SocketIO_emit));
cls->defineFunction("disconnect", _SE(SocketIO_disconnect));
cls->defineFunction("on", _SE(SocketIO_on));
cls->install();
JSBClassType::registerClass<SocketIO>(cls);
se::Value ctorVal;
obj->getProperty("SocketIO", &ctorVal);
ctorVal.toObject()->defineFunction("connect", _SE(SocketIO_connect));
ctorVal.toObject()->defineFunction("close", _SE(SocketIO_close));
__jsb_SocketIO_class = cls;
se::ScriptEngine::getInstance()->clearException();
return true;
}

View File

@@ -0,0 +1,33 @@
/****************************************************************************
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
namespace se {
class Object;
}
bool register_all_socketio(se::Object* obj);

View File

@@ -0,0 +1,308 @@
/****************************************************************************
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
//
// jsb_spine_manual.cpp
// cocos2d_js_bindings
//
// Created by James Chen on 6/14/17.
//
//
#include "base/ccConfig.h"
#include "jsb_spine_manual.hpp"
#if USE_SPINE > 0
#include "cocos/scripting/js-bindings/jswrapper/SeApi.h"
#include "cocos/scripting/js-bindings/manual/jsb_conversions.hpp"
#include "cocos/scripting/js-bindings/manual/jsb_global.h"
#include "cocos/scripting/js-bindings/manual/jsb_helper.hpp"
#include "cocos/scripting/js-bindings/auto/jsb_cocos2dx_spine_auto.hpp"
#include "middleware-adapter.h"
#include "spine-creator-support/SkeletonDataMgr.h"
#include "spine-creator-support/SkeletonRenderer.h"
#include "spine-creator-support/spine-cocos2dx.h"
#include "cocos2d.h"
#include "cocos/editor-support/spine/spine.h"
#include "cocos/editor-support/spine-creator-support/spine-cocos2dx.h"
using namespace cocos2d;
static spine::Cocos2dTextureLoader textureLoader;
static cocos2d::Map<std::string, middleware::Texture2D*>* _preloadedAtlasTextures = nullptr;
static middleware::Texture2D* _getPreloadedAtlasTexture(const char* path)
{
assert(_preloadedAtlasTextures);
auto it = _preloadedAtlasTextures->find(path);
return it != _preloadedAtlasTextures->end() ? it->second : nullptr;
}
static bool js_register_spine_initSkeletonData (se::State& s)
{
const auto& args = s.args();
int argc = (int)args.size();
if (argc != 5) {
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", argc, 5);
return false;
}
bool ok = false;
std::string uuid;
ok = seval_to_std_string(args[0], &uuid);
SE_PRECONDITION2(ok, false, "js_register_spine_initSkeletonData: Invalid uuid content!");
auto mgr = spine::SkeletonDataMgr::getInstance();
bool hasSkeletonData = mgr->hasSkeletonData(uuid);
if (hasSkeletonData) {
spine::SkeletonData* skeletonData = mgr->retainByUUID(uuid);
native_ptr_to_rooted_seval<spine::SkeletonData>(skeletonData, &s.rval());
return true;
}
std::string skeletonDataFile;
ok = seval_to_std_string(args[1], &skeletonDataFile);
SE_PRECONDITION2(ok, false, "js_register_spine_initSkeletonData: Invalid json path!");
std::string atlasText;
ok = seval_to_std_string(args[2], &atlasText);
SE_PRECONDITION2(ok, false, "js_register_spine_initSkeletonData: Invalid atlas content!");
cocos2d::Map<std::string, middleware::Texture2D*> textures;
ok = seval_to_Map_string_key(args[3], &textures);
SE_PRECONDITION2(ok, false, "js_register_spine_initSkeletonData: Invalid textures!");
float scale = 1.0f;
ok = seval_to_float(args[4], &scale);
SE_PRECONDITION2(ok, false, "js_register_spine_initSkeletonData: Invalid scale!");
// create atlas from preloaded texture
_preloadedAtlasTextures = &textures;
spine::spAtlasPage_setCustomTextureLoader(_getPreloadedAtlasTexture);
spine::Atlas* atlas = new (__FILE__, __LINE__) spine::Atlas(atlasText.c_str(), (int)atlasText.size(), "", &textureLoader);
_preloadedAtlasTextures = nullptr;
spine::spAtlasPage_setCustomTextureLoader(nullptr);
spine::AttachmentLoader* attachmentLoader = new (__FILE__, __LINE__) spine::Cocos2dAtlasAttachmentLoader(atlas);
spine::SkeletonData* skeletonData = nullptr;
std::size_t length = skeletonDataFile.length();
auto binPos = skeletonDataFile.find(".skel", length - 5);
if (binPos == std::string::npos) binPos = skeletonDataFile.find(".bin", length - 4);
if (binPos != std::string::npos) {
auto fileUtils = cocos2d::FileUtils::getInstance();
if (fileUtils->isFileExist(skeletonDataFile))
{
cocos2d::Data cocos2dData;
const auto fullpath = fileUtils->fullPathForFilename(skeletonDataFile);
fileUtils->getContents(fullpath, &cocos2dData);
spine::SkeletonBinary binary(attachmentLoader);
binary.setScale(scale);
skeletonData = binary.readSkeletonData(cocos2dData.getBytes(), (int)cocos2dData.getSize());
CCASSERT(skeletonData, !binary.getError().isEmpty() ? binary.getError().buffer() : "Error reading binary skeleton data.");
}
} else {
spine::SkeletonJson json(attachmentLoader);
json.setScale(scale);
skeletonData = json.readSkeletonData(skeletonDataFile.c_str());
CCASSERT(skeletonData, !json.getError().isEmpty() ? json.getError().buffer() : "Error reading json skeleton data.");
}
if (skeletonData) {
std::vector<int> texturesIndex;
for (auto it = textures.begin(); it != textures.end(); it++)
{
texturesIndex.push_back(it->second->getRealTextureIndex());
}
mgr->setSkeletonData(uuid, skeletonData, atlas, attachmentLoader, texturesIndex);
native_ptr_to_rooted_seval<spine::SkeletonData>(skeletonData, &s.rval());
} else {
if (atlas) {
delete atlas;
atlas = nullptr;
}
if (attachmentLoader) {
delete attachmentLoader;
attachmentLoader = nullptr;
}
}
return true;
}
SE_BIND_FUNC(js_register_spine_initSkeletonData)
static bool js_register_spine_disposeSkeletonData (se::State& s)
{
const auto& args = s.args();
int argc = (int)args.size();
if (argc != 1) {
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", argc, 5);
return false;
}
bool ok = false;
std::string uuid;
ok = seval_to_std_string(args[0], &uuid);
SE_PRECONDITION2(ok, false, "js_register_spine_disposeSkeletonData: Invalid uuid content!");
auto mgr = spine::SkeletonDataMgr::getInstance();
bool hasSkeletonData = mgr->hasSkeletonData(uuid);
if (!hasSkeletonData) return true;
mgr->releaseByUUID(uuid);
return true;
}
SE_BIND_FUNC(js_register_spine_disposeSkeletonData)
static bool js_register_spine_initSkeletonRenderer(se::State& s)
{
// renderer, jsonPath, atlasText, textures, scale
const auto& args = s.args();
int argc = (int)args.size();
if (argc != 2) {
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", argc, 5);
return false;
}
bool ok = false;
spine::SkeletonRenderer* node = nullptr;
ok = seval_to_native_ptr(args[0], &node);
SE_PRECONDITION2(ok, false, "js_register_spine_initSkeletonData: Converting SpineRenderer failed!");
std::string uuid;
ok = seval_to_std_string(args[1], &uuid);
SE_PRECONDITION2(ok, false, "js_register_spine_initSkeletonData: Invalid uuid content!");
auto mgr = spine::SkeletonDataMgr::getInstance();
bool hasSkeletonData = mgr->hasSkeletonData(uuid);
if (hasSkeletonData) {
node->initWithUUID(uuid);
}
return true;
}
SE_BIND_FUNC(js_register_spine_initSkeletonRenderer)
static bool js_register_spine_retainSkeletonData(se::State& s)
{
const auto& args = s.args();
int argc = (int)args.size();
if (argc != 1) {
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", argc, 1);
return false;
}
bool ok = false;
std::string uuid;
ok = seval_to_std_string(args[0], &uuid);
SE_PRECONDITION2(ok, false, "js_register_spine_hasSkeletonData: Invalid uuid content!");
auto mgr = spine::SkeletonDataMgr::getInstance();
bool hasSkeletonData = mgr->hasSkeletonData(uuid);
if (hasSkeletonData) {
spine::SkeletonData* skeletonData = mgr->retainByUUID(uuid);
native_ptr_to_rooted_seval<spine::SkeletonData>(skeletonData, &s.rval());
}
return true;
}
SE_BIND_FUNC(js_register_spine_retainSkeletonData)
bool register_all_spine_manual(se::Object* obj)
{
// Get the ns
se::Value nsVal;
if (!obj->getProperty("spine", &nsVal))
{
se::HandleObject jsobj(se::Object::createPlainObject());
nsVal.setObject(jsobj);
obj->setProperty("spine", nsVal);
}
se::Object* ns = nsVal.toObject();
ns->defineFunction("initSkeletonRenderer", _SE(js_register_spine_initSkeletonRenderer));
ns->defineFunction("initSkeletonData", _SE(js_register_spine_initSkeletonData));
ns->defineFunction("retainSkeletonData", _SE(js_register_spine_retainSkeletonData));
ns->defineFunction("disposeSkeletonData", _SE(js_register_spine_disposeSkeletonData));
spine::setSpineObjectDisposeCallback([](void* spineObj){
se::Object* seObj = nullptr;
auto iter = se::NativePtrToObjectMap::find(spineObj);
if (iter != se::NativePtrToObjectMap::end())
{
// Save se::Object pointer for being used in cleanup method.
seObj = iter->second;
// Unmap native and js object since native object was destroyed.
// Otherwise, it may trigger 'assertion' in se::Object::setPrivateData later
// since native obj is already released and the new native object may be assigned with
// the same address.
se::NativePtrToObjectMap::erase(iter);
}
else
{
return;
}
auto cleanup = [seObj](){
auto se = se::ScriptEngine::getInstance();
if (!se->isValid() || se->isInCleanup())
return;
se::AutoHandleScope hs;
se->clearException();
// The mapping of native object & se::Object was cleared in above code.
// The private data (native object) may be a different object associated with other se::Object.
// Therefore, don't clear the mapping again.
seObj->clearPrivateData(false);
seObj->unroot();
seObj->decRef();
};
if (!se::ScriptEngine::getInstance()->isGarbageCollecting())
{
cleanup();
}
else
{
CleanupTask::pushTaskToAutoReleasePool(cleanup);
}
});
se::ScriptEngine::getInstance()->addBeforeCleanupHook([](){
spine::SkeletonDataMgr::destroyInstance();
});
se::ScriptEngine::getInstance()->clearException();
return true;
}
#endif

View File

@@ -0,0 +1,33 @@
/****************************************************************************
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
#include "cocos/scripting/js-bindings/jswrapper/SeApi.h"
namespace se {
class Object;
}
bool register_all_spine_manual(se::Object* obj);

View File

@@ -0,0 +1,606 @@
/****************************************************************************
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "base/ccConfig.h"
#include "jsb_websocket.hpp"
#if (USE_SOCKET > 0) && (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_MAC || CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
#include "cocos/scripting/js-bindings/jswrapper/SeApi.h"
#include "cocos/scripting/js-bindings/manual/jsb_conversions.hpp"
#include "cocos/scripting/js-bindings/manual/jsb_global.h"
#include "base/ccUTF8.h"
#include "platform/CCApplication.h"
using namespace cocos2d;
using namespace cocos2d::network;
/*
[Constructor(in DOMString url, in optional DOMString protocols)]
[Constructor(in DOMString url, in optional DOMString[] protocols)]
interface WebSocket {
readonly attribute DOMString url;
// ready state
const unsigned short CONNECTING = 0;
const unsigned short OPEN = 1;
const unsigned short CLOSING = 2;
const unsigned short CLOSED = 3;
readonly attribute unsigned short readyState;
readonly attribute unsigned long bufferedAmount;
// networking
attribute Function onopen;
attribute Function onmessage;
attribute Function onerror;
attribute Function onclose;
readonly attribute DOMString protocol;
void send(in DOMString data);
void close();
};
WebSocket implements EventTarget;
*/
se::Class* __jsb_WebSocket_class = nullptr;
JSB_WebSocketDelegate::JSB_WebSocketDelegate()
{
}
JSB_WebSocketDelegate::~JSB_WebSocketDelegate()
{
CCLOGINFO("In the destructor of JSB_WebSocketDelegate(%p)", this);
}
void JSB_WebSocketDelegate::onOpen(WebSocket* ws)
{
se::ScriptEngine::getInstance()->clearException();
se::AutoHandleScope hs;
if (cocos2d::Application::getInstance() == nullptr)
return;
auto iter = se::NativePtrToObjectMap::find(ws);
if (iter == se::NativePtrToObjectMap::end())
return;
se::Object* wsObj = iter->second;
wsObj->setProperty("protocol", se::Value(ws->getProtocol()));
se::HandleObject jsObj(se::Object::createPlainObject());
jsObj->setProperty("type", se::Value("open"));
se::Value target;
native_ptr_to_seval<WebSocket>(ws, &target);
jsObj->setProperty("target", target);
se::Value func;
bool ok = _JSDelegate.toObject()->getProperty("onopen", &func);
if (ok && func.isObject() && func.toObject()->isFunction())
{
se::ValueArray args;
args.push_back(se::Value(jsObj));
func.toObject()->call(args, wsObj);
}
else
{
SE_REPORT_ERROR("Can't get onopen function!");
}
}
void JSB_WebSocketDelegate::onMessage(WebSocket* ws, const WebSocket::Data& data)
{
se::ScriptEngine::getInstance()->clearException();
se::AutoHandleScope hs;
if (cocos2d::Application::getInstance() == nullptr)
return;
auto iter = se::NativePtrToObjectMap::find(ws);
if (iter == se::NativePtrToObjectMap::end())
return;
se::Object* wsObj = iter->second;
se::HandleObject jsObj(se::Object::createPlainObject());
jsObj->setProperty("type", se::Value("message"));
se::Value target;
native_ptr_to_seval<WebSocket>(ws, &target);
jsObj->setProperty("target", target);
se::Value func;
bool ok = _JSDelegate.toObject()->getProperty("onmessage", &func);
if (ok && func.isObject() && func.toObject()->isFunction())
{
se::ValueArray args;
args.push_back(se::Value(jsObj));
if (data.isBinary)
{
se::HandleObject dataObj(se::Object::createArrayBufferObject(data.bytes, data.len));
jsObj->setProperty("data", se::Value(dataObj));
}
else
{
se::Value dataVal;
if (strlen(data.bytes) == 0 && data.len > 0)
{// String with 0x00 prefix
std::string str(data.bytes, data.len);
dataVal.setString(str);
}
else
{// Normal string
dataVal.setString(std::string(data.bytes, data.len));
}
if (dataVal.isNullOrUndefined())
{
ws->closeAsync();
}
else
{
jsObj->setProperty("data", se::Value(dataVal));
}
}
func.toObject()->call(args, wsObj);
}
else
{
SE_REPORT_ERROR("Can't get onmessage function!");
}
}
void JSB_WebSocketDelegate::onClose(WebSocket* ws)
{
se::ScriptEngine::getInstance()->clearException();
se::AutoHandleScope hs;
if (cocos2d::Application::getInstance() == nullptr)
return;
auto iter = se::NativePtrToObjectMap::find(ws);
do
{
if (iter == se::NativePtrToObjectMap::end())
{
CCLOGINFO("WebSocket js instance was destroyted, don't need to invoke onclose callback!");
break;
}
se::Object* wsObj = iter->second;
se::HandleObject jsObj(se::Object::createPlainObject());
jsObj->setProperty("type", se::Value("close"));
se::Value target;
native_ptr_to_seval<WebSocket>(ws, &target);
jsObj->setProperty("target", target);
se::Value func;
bool ok = _JSDelegate.toObject()->getProperty("onclose", &func);
if (ok && func.isObject() && func.toObject()->isFunction())
{
se::ValueArray args;
args.push_back(se::Value(jsObj));
func.toObject()->call(args, wsObj);
}
else
{
SE_REPORT_ERROR("Can't get onclose function!");
}
//JS Websocket object now can be GC, since the connection is closed.
wsObj->unroot();
// Websocket instance is attached to global object in 'WebSocket_close'
// It's safe to detach it here since JS 'onclose' method has been already invoked.
se::ScriptEngine::getInstance()->getGlobalObject()->detachObject(wsObj);
} while(false);
ws->release();
release(); // Release delegate self at last
}
void JSB_WebSocketDelegate::onError(WebSocket* ws, const WebSocket::ErrorCode& error)
{
se::ScriptEngine::getInstance()->clearException();
se::AutoHandleScope hs;
if (cocos2d::Application::getInstance() == nullptr)
return;
auto iter = se::NativePtrToObjectMap::find(ws);
if (iter == se::NativePtrToObjectMap::end())
return;
se::Object* wsObj = iter->second;
se::HandleObject jsObj(se::Object::createPlainObject());
jsObj->setProperty("type", se::Value("error"));
se::Value target;
native_ptr_to_seval<WebSocket>(ws, &target);
jsObj->setProperty("target", target);
se::Value func;
bool ok = _JSDelegate.toObject()->getProperty("onerror", &func);
if (ok && func.isObject() && func.toObject()->isFunction())
{
se::ValueArray args;
args.push_back(se::Value(jsObj));
func.toObject()->call(args, wsObj);
}
else
{
SE_REPORT_ERROR("Can't get onerror function!");
}
wsObj->unroot();
}
void JSB_WebSocketDelegate::setJSDelegate(const se::Value& jsDelegate)
{
assert(jsDelegate.isObject());
_JSDelegate = jsDelegate;
}
static bool WebSocket_finalize(se::State& s)
{
WebSocket* cobj = (WebSocket*)s.nativeThisObject();
CCLOGINFO("jsbindings: finalizing JS object %p (WebSocket)", cobj);
// Manually close if web socket is not closed
if (cobj->getReadyState() != WebSocket::State::CLOSED)
{
CCLOGINFO("WebSocket (%p) isn't closed, try to close it!", cobj);
cobj->closeAsync();
}
static_cast<JSB_WebSocketDelegate*>(cobj->getDelegate())->release();
if (cobj->getReferenceCount() == 1)
cobj->autorelease();
else
cobj->release();
return true;
}
SE_BIND_FINALIZE_FUNC(WebSocket_finalize)
static bool WebSocket_constructor(se::State& s)
{
const auto& args = s.args();
int argc = (int)args.size();
if (argc == 1 || argc == 2 || argc == 3)
{
std::string url;
bool ok = seval_to_std_string(args[0], &url);
SE_PRECONDITION2(ok, false, "Error processing url argument");
se::Object* obj = s.thisObject();
WebSocket* cobj = nullptr;
if (argc >= 2)
{
std::string caFilePath;
std::vector<std::string> protocols;
if (args[1].isString())
{
std::string protocol;
ok = seval_to_std_string(args[1], &protocol);
SE_PRECONDITION2(ok, false, "Error processing protocol string");
protocols.push_back(protocol);
}
else if (args[1].isObject() && args[1].toObject()->isArray())
{
se::Object* protocolArr = args[1].toObject();
uint32_t len = 0;
ok = protocolArr->getArrayLength(&len);
SE_PRECONDITION2(ok, false, "getArrayLength failed!");
se::Value tmp;
for (uint32_t i=0; i < len; ++i)
{
if (!protocolArr->getArrayElement(i, &tmp))
continue;
std::string protocol;
ok = seval_to_std_string(tmp, &protocol);
SE_PRECONDITION2(ok, false, "Error processing protocol object");
protocols.push_back(protocol);
}
}
if (argc > 2)
{
ok = seval_to_std_string(args[2], &caFilePath);
SE_PRECONDITION2(ok, false, "Error processing caFilePath");
}
cobj = new (std::nothrow) WebSocket();
JSB_WebSocketDelegate* delegate = new (std::nothrow) JSB_WebSocketDelegate();
if (cobj->init(*delegate, url, &protocols, caFilePath))
{
delegate->setJSDelegate(se::Value(obj, true));
cobj->retain(); // release in finalize function and onClose delegate method
delegate->retain(); // release in finalize function and onClose delegate method
}
else
{
cobj->release();
delegate->release();
SE_REPORT_ERROR("WebSocket init failed!");
return false;
}
}
else
{
cobj = new (std::nothrow) WebSocket();
JSB_WebSocketDelegate* delegate = new (std::nothrow) JSB_WebSocketDelegate();
if (cobj->init(*delegate, url))
{
delegate->setJSDelegate(se::Value(obj, true));
cobj->retain(); // release in finalize function and onClose delegate method
delegate->retain(); // release in finalize function and onClose delegate method
}
else
{
cobj->release();
delegate->release();
SE_REPORT_ERROR("WebSocket init failed!");
return false;
}
}
obj->setProperty("url", args[0]);
// The websocket draft uses lowercase 'url', so 'URL' need to be deprecated.
obj->setProperty("URL", args[0]);
// Initialize protocol property with an empty string, it will be assigned in onOpen delegate.
obj->setProperty("protocol", se::Value(""));
obj->setPrivateData(cobj);
obj->root();
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting 1<= and <=3", argc);
return false;
}
SE_BIND_CTOR(WebSocket_constructor, __jsb_WebSocket_class, WebSocket_finalize)
static bool WebSocket_send(se::State& s)
{
const auto& args = s.args();
int argc = (int)args.size();
if (argc == 1)
{
WebSocket* cobj = (WebSocket*)s.nativeThisObject();
bool ok = false;
if (args[0].isString())
{
std::string data;
ok = seval_to_std_string(args[0], &data);
SE_PRECONDITION2(ok, false, "Convert string failed");
//IDEA: We didn't find a way to get the JS string length in JSB2.0.
// if (data.empty() && len > 0)
// {
// CCLOGWARN("Text message to send is empty, but its length is greater than 0!");
// //IDEA: Note that this text message contains '0x00' prefix, so its length calcuted by strlen is 0.
// // we need to fix that if there is '0x00' in text message,
// // since javascript language could support '0x00' inserted at the beginning or the middle of text message
// }
cobj->send(data);
}
else if (args[0].isObject())
{
se::Object* dataObj = args[0].toObject();
uint8_t* ptr = nullptr;
size_t length = 0;
if (dataObj->isArrayBuffer())
{
ok = dataObj->getArrayBufferData(&ptr, &length);
SE_PRECONDITION2(ok, false, "getArrayBufferData failed!");
}
else if (dataObj->isTypedArray())
{
ok = dataObj->getTypedArrayData(&ptr, &length);
SE_PRECONDITION2(ok, false, "getTypedArrayData failed!");
}
else
{
assert(false);
}
cobj->send(ptr, (unsigned int)length);
}
else
{
assert(false);
}
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting 1", argc);
return false;
}
SE_BIND_FUNC(WebSocket_send)
static bool WebSocket_close(se::State& s)
{
const auto& args = s.args();
int argc = (int)args.size();
WebSocket* cobj = (WebSocket*)s.nativeThisObject();
if(argc == 0)
{
cobj->closeAsync();
}
else if (argc == 1)
{
if (args[0].isNumber())
{
int reason;
seval_to_int32(args[0], &reason);
cobj->closeAsync(reason, "no_reason");
}
else if (args[0].isString())
{
std::string reason;
seval_to_std_string(args[0], &reason);
cobj->closeAsync(1005, reason);
}
else
{
assert(false);
}
}
else if (argc == 2)
{
assert(args[0].isNumber());
assert(args[1].isString());
int reasonCode;
std::string reasonString;
seval_to_int32(args[0], &reasonCode);
seval_to_std_string(args[1], &reasonString);
cobj->closeAsync(reasonCode, reasonString);
}
else
{
assert(false);
}
// Attach current WebSocket instance to global object to prevent WebSocket instance
// being garbage collected after "ws.close(); ws = null;"
// There is a state that current WebSocket JS instance is being garbaged but its finalize
// callback has not be invoked. Then in "JSB_WebSocketDelegate::onClose", se::Object is
// still be able to be found and while invoking JS 'onclose' method, crash will happen since
// JS instance is invalid and is going to be collected. This bug is easiler reproduced on iOS
// because JavaScriptCore is more GC sensitive.
// Please note that we need to detach it from global object in "JSB_WebSocketDelegate::onClose".
se::ScriptEngine::getInstance()->getGlobalObject()->attachObject(s.thisObject());
return true;
}
SE_BIND_FUNC(WebSocket_close)
static bool WebSocket_getReadyState(se::State& s)
{
const auto& args = s.args();
int argc = (int)args.size();
if (argc == 0)
{
WebSocket* cobj = (WebSocket*)s.nativeThisObject();
s.rval().setInt32((int)cobj->getReadyState());
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting 0", argc);
return false;
}
SE_BIND_PROP_GET(WebSocket_getReadyState)
static bool WebSocket_getBufferedAmount(se::State& s)
{
const auto& args = s.args();
int argc = (int)args.size();
if (argc == 0)
{
WebSocket* cobj = (WebSocket*)s.nativeThisObject();
s.rval().setUint32((uint32_t)cobj->getBufferedAmount());
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting 0", argc);
return false;
}
SE_BIND_PROP_GET(WebSocket_getBufferedAmount)
static bool WebSocket_getExtensions(se::State& s)
{
const auto& args = s.args();
int argc = (int)args.size();
if (argc == 0)
{
WebSocket* cobj = (WebSocket*)s.nativeThisObject();
s.rval().setString(cobj->getExtensions());
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting 0", argc);
return false;
}
SE_BIND_PROP_GET(WebSocket_getExtensions)
#define WEBSOCKET_DEFINE_READONLY_INT_FIELD(full_name, value) \
static bool full_name(se::State& s) \
{ \
const auto& args = s.args(); \
int argc = (int)args.size(); \
if (argc == 0) \
{ \
s.rval().setInt32(value); \
return true; \
} \
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting 0", argc); \
return false; \
} \
SE_BIND_PROP_GET(full_name)
WEBSOCKET_DEFINE_READONLY_INT_FIELD(Websocket_CONNECTING, (int)WebSocket::State::CONNECTING)
WEBSOCKET_DEFINE_READONLY_INT_FIELD(Websocket_OPEN, (int)WebSocket::State::OPEN)
WEBSOCKET_DEFINE_READONLY_INT_FIELD(Websocket_CLOSING, (int)WebSocket::State::CLOSING)
WEBSOCKET_DEFINE_READONLY_INT_FIELD(Websocket_CLOSED, (int)WebSocket::State::CLOSED)
bool register_all_websocket(se::Object* obj)
{
se::Class* cls = se::Class::create("WebSocket", obj, nullptr, _SE(WebSocket_constructor));
cls->defineFinalizeFunction(_SE(WebSocket_finalize));
cls->defineFunction("send", _SE(WebSocket_send));
cls->defineFunction("close", _SE(WebSocket_close));
cls->defineProperty("readyState", _SE(WebSocket_getReadyState), nullptr);
cls->defineProperty("bufferedAmount", _SE(WebSocket_getBufferedAmount), nullptr);
cls->defineProperty("extensions", _SE(WebSocket_getExtensions), nullptr);
cls->defineProperty("CONNECTING", _SE(Websocket_CONNECTING), nullptr);
cls->defineProperty("CLOSING", _SE(Websocket_CLOSING), nullptr);
cls->defineProperty("OPEN", _SE(Websocket_OPEN), nullptr);
cls->defineProperty("CLOSED", _SE(Websocket_CLOSED), nullptr);
cls->install();
se::Value tmp;
obj->getProperty("WebSocket", &tmp);
tmp.toObject()->defineProperty("CONNECTING", _SE(Websocket_CONNECTING), nullptr);
tmp.toObject()->defineProperty("CLOSING", _SE(Websocket_CLOSING), nullptr);
tmp.toObject()->defineProperty("OPEN", _SE(Websocket_OPEN), nullptr);
tmp.toObject()->defineProperty("CLOSED", _SE(Websocket_CLOSED), nullptr);
JSBClassType::registerClass<WebSocket>(cls);
__jsb_WebSocket_class = cls;
se::ScriptEngine::getInstance()->clearException();
return true;
}
#endif //#if (USE_SOCKET > 0) && (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_MAC || CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)

View File

@@ -0,0 +1,68 @@
/****************************************************************************
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
#include "cocos/scripting/js-bindings/jswrapper/SeApi.h"
#include "cocos/network/WebSocket.h"
namespace se {
class Object;
class Value;
}
class JSB_WebSocketDelegate : public cocos2d::Ref, public cocos2d::network::WebSocket::Delegate {
public:
JSB_WebSocketDelegate();
virtual void onOpen(cocos2d::network::WebSocket *ws) override;
virtual void onMessage(cocos2d::network::WebSocket *ws,
const cocos2d::network::WebSocket::Data &data) override;
virtual void onClose(cocos2d::network::WebSocket *ws) override;
virtual void onError(cocos2d::network::WebSocket *ws,
const cocos2d::network::WebSocket::ErrorCode &error) override;
void setJSDelegate(const se::Value &jsDelegate);
private:
virtual ~JSB_WebSocketDelegate();
se::Value _JSDelegate;
};
SE_DECLARE_FINALIZE_FUNC(WebSocket_finalize);
SE_DECLARE_FUNC(WebSocket_constructor);
SE_DECLARE_FUNC(WebSocket_send);
SE_DECLARE_FUNC(WebSocket_close);
bool register_all_websocket(se::Object *obj);

View File

@@ -0,0 +1,946 @@
/****************************************************************************
Copyright (c) 2019 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "base/ccConfig.h"
#if (USE_SOCKET > 0) && (USE_WEBSOCKET_SERVER > 0) && (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_MAC || CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
#include "jsb_websocket_server.hpp"
#include "uv/uv.h"
#include "cocos/scripting/js-bindings/jswrapper/SeApi.h"
#include "cocos/scripting/js-bindings/manual/jsb_conversions.hpp"
#include "cocos/scripting/js-bindings/manual/jsb_global.h"
#include "cocos/network/WebSocketServer.h"
using namespace cocos2d;
using namespace cocos2d::network;
se::Class* __jsb_WebSocketServer_class = nullptr;
se::Class* __jsb_WebSocketServer_Connection_class = nullptr;
typedef std::shared_ptr<WebSocketServer>* WSSPTR;
typedef std::shared_ptr<WebSocketServerConnection>* WSCONNPTR;
static int __sendIndex = 1;
static std::string gen_send_index() {
char buf[128] = { 0 };
snprintf(buf, 127, "__send_[%d]", __sendIndex++);
return buf;
}
static bool WebSocketServer_finalize(se::State& s)
{
WSSPTR cobj = (WSSPTR)s.nativeThisObject();
CCLOGINFO("jsbindings: finalizing JS object %p (WebSocketServer)", cobj);
delete cobj;
return true;
}
SE_BIND_FINALIZE_FUNC(WebSocketServer_finalize)
static bool WebSocketServer_constructor(se::State& s)
{
const auto& args = s.args();
int argc = (int)args.size();
if(argc == 0)
{
se::Object* obj = s.thisObject();
WSSPTR cobj = new std::shared_ptr<WebSocketServer>(new WebSocketServer());
obj->setPrivateData(cobj);
(*cobj)->setData(obj);
(*cobj)->setOnBegin([obj]() {
obj->root();
});
(*cobj)->setOnEnd([obj]() {
obj->unroot();
});
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting 0", argc);
return false;
}
SE_BIND_CTOR(WebSocketServer_constructor, __jsb_WebSocketServer_class, WebSocketServer_finalize)
static bool WebSocketServer_listen(se::State& s) {
const auto& args = s.args();
int argc = (int)args.size();
if (argc == 0)
{
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting 1,2,3", argc);
return false;
}
WSSPTR cobj = (WSSPTR)s.nativeThisObject();
int arg_port = 0;
std::string arg_host = "";
std::function<void(const std::string&)> arg_callback;
bool ok;
if (argc >= 1) { // port
ok = seval_to_int32(args[0], &arg_port);
SE_PRECONDITION2(ok, false, "Convert args[0] to port failed");
}
if (argc >= 2) { // host or callback
if (args[1].isString()) { //to host
ok = seval_to_std_string(args[1], &arg_host);
SE_PRECONDITION2(ok, false, "Convert args[1] to host failed");
}
se::Object* funObj = nullptr;
if (args[1].isObject() && args[1].toObject()->isFunction()) {
funObj = args[1].toObject();
}
if (argc > 2 && args[2].isObject() && args[2].toObject()->isFunction())
{
funObj = args[2].toObject();
}
if (funObj) {
s.thisObject()->setProperty("__onlisten", se::Value(funObj));
std::weak_ptr<WebSocketServer> serverWeak = *cobj;
arg_callback = [serverWeak](const std::string &err) {
se::AutoHandleScope hs;
auto serverPtr = serverWeak.lock();
if (!serverPtr) {
return;
}
se::Object *sobj = (se::Object*) serverPtr->getData();
if (!sobj) {
return;
}
se::Value callback;
if (!sobj->getProperty("__onlisten", &callback))
{
SE_REPORT_ERROR("onlisten attribute not set!");
return;
}
se::ValueArray args;
if(!err.empty())
{
args.push_back(se::Value(err));
}
bool success = callback.toObject()->call(args, sobj, nullptr);
if (!success) {
se::ScriptEngine::getInstance()->clearException();
}
};
}
}
WebSocketServer::listenAsync(*cobj, arg_port, arg_host, arg_callback);
return true;
}
SE_BIND_FUNC(WebSocketServer_listen)
static bool WebSocketServer_onconnection(se::State& s) {
const auto& args = s.args();
int argc = (int)args.size();
if (!(argc ==1 && args[0].isObject() && args[0].toObject()->isFunction()))
{
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting 1 & function", argc);
return false;
}
WSSPTR cobj = (WSSPTR)s.nativeThisObject();
s.thisObject()->setProperty("__onconnection", args[0]);
std::weak_ptr<WebSocketServer> serverWeak = *cobj;
cobj->get()->setOnConnection([serverWeak](std::shared_ptr<WebSocketServerConnection> conn) {
se::AutoHandleScope hs;
auto server = serverWeak.lock();
if (!server) {
return;
}
se::Object* sobj= (se::Object*)server->getData();
if (!sobj) {
return;
}
se::Value callback;
if (!sobj->getProperty("__onconnection", &callback)) {
SE_REPORT_ERROR("onconnection callback not found!");
return;
}
se::Object* obj = se::Object::createObjectWithClass(__jsb_WebSocketServer_Connection_class);
WSCONNPTR prv = new std::shared_ptr<WebSocketServerConnection>(conn);
// a connection is dead only if no reference & closed!
obj->root();
obj->setPrivateData(prv);
conn->setData(obj);
std::weak_ptr<WebSocketServerConnection> connWeak = conn;
prv->get()->setOnEnd([connWeak]() {
// release we connection is gone!
auto ptr = connWeak.lock();
if (ptr) {
se::Object* sobj = (se::Object*)ptr->getData();
sobj->unroot();
}
});
se::ValueArray args;
args.push_back(se::Value(obj));
bool success = callback.toObject()->call(args, sobj, nullptr);;
if (!success) {
se::ScriptEngine::getInstance()->clearException();
}
});
return true;
}
SE_BIND_PROP_SET(WebSocketServer_onconnection)
static bool WebSocketServer_onclose(se::State& s) {
const auto& args = s.args();
int argc = (int)args.size();
if (argc != 1)
{
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting 1", argc);
return false;
}
if(!(args[0].isObject() && args[0].toObject()->isFunction())){
SE_REPORT_ERROR("argument type error, function expected!");
}
WSSPTR cobj = (WSSPTR)s.nativeThisObject();
std::function<void(const std::string&)> callback;
std::weak_ptr<WebSocketServer> serverWeak = *cobj;
s.thisObject()->setProperty("__onclose", args[0]);
callback = [serverWeak](const std::string& err) {
se::AutoHandleScope hs;
auto server = serverWeak.lock();
if (!server) {
return;
}
se::Object* sobj = (se::Object*)server->getData();
if (!sobj) {
return;
}
se::Value callback;
if (!sobj->getProperty("__onclose", &callback)) {
SE_REPORT_ERROR("onclose callback not found!");
return;
}
se::ValueArray args;
if (!err.empty())
{
args.push_back(se::Value(err));
}
bool success = callback.toObject()->call(args, sobj, nullptr);
if (!success) {
se::ScriptEngine::getInstance()->clearException();
}
};
(*cobj)->setOnClose(callback);
return true;
}
SE_BIND_PROP_SET(WebSocketServer_onclose)
static bool WebSocketServer_close(se::State& s)
{
const auto& args = s.args();
int argc = (int)args.size();
if (argc > 1)
{
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting 0, 1", argc);
return false;
}
WSSPTR cobj = (WSSPTR)s.nativeThisObject();
std::function<void(const std::string&)> callback;
if (argc == 1) {
if(args[0].isObject() && args[0].toObject()->isFunction()) {
s.thisObject()->setProperty("__close", args[0]);
std::weak_ptr<WebSocketServer> serverWeak = *cobj;
callback = [serverWeak](const std::string& err) {
se::AutoHandleScope hs;
auto server = serverWeak.lock();
if (!server) {
return;
}
se::Object* sobj = (se::Object*)server->getData();
if (!sobj) {
return;
}
se::Value callback;
if (!sobj->getProperty("__close", &callback)) {
SE_REPORT_ERROR("onclose callback not found!");
return;
}
se::ValueArray args;
if (!err.empty())
{
args.push_back(se::Value(err));
}
bool success = callback.toObject()->call(args, sobj, nullptr);
if (!success) {
se::ScriptEngine::getInstance()->clearException();
}
};
(*cobj)->closeAsync(callback);
}
else {
SE_REPORT_ERROR("wrong argument type, function expected");
return false;
}
}
else {
(*cobj)->closeAsync();
}
return true;
}
SE_BIND_FUNC(WebSocketServer_close)
static bool WebSocketServer_connections(se::State& s) {
const auto& args = s.args();
int argc = (int)args.size();
if (argc == 0)
{
WSSPTR cobj = (WSSPTR)s.nativeThisObject();
auto conns = cobj->get()->getConnections();
se::Object* ret = se::Object::createArrayObject(conns.size());
for (auto i = 0;i < conns.size(); i++) {
std::shared_ptr<WebSocketServerConnection>& con = conns[i];
se::Object *obj = (se::Object*)con->getData();
ret->setArrayElement(i, se::Value(obj));
}
s.rval().setObject(ret);
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting 0", argc);
return false;
}
SE_BIND_PROP_GET(WebSocketServer_connections)
static bool WebSocketServer_Connection_finalize(se::State& s)
{
WSCONNPTR cob = (WSCONNPTR)s.nativeThisObject();
CCLOGINFO("jsbindings: finalizing JS object %p (WebSocketServer_Connection)", cobj);
delete cob;
return true;
}
SE_BIND_FINALIZE_FUNC(WebSocketServer_Connection_finalize)
static bool WebSocketServer_Connection_constructor(se::State& s)
{
const auto& args = s.args();
int argc = (int)args.size();
if (argc == 0)
{
se::Object* obj = s.thisObject();
//private data should be set when connected
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting 0", argc);
return false;
}
SE_BIND_CTOR(WebSocketServer_Connection_constructor, __jsb_WebSocketServer_Connection_class, WebSocketServer_Connection_finalize)
static bool WebSocketServer_Connection_send(se::State& s)
{
const auto& args = s.args();
int argc = (int)args.size();
WSCONNPTR cobj = (WSCONNPTR)s.nativeThisObject();
if (!cobj) {
SE_REPORT_ERROR("Connection is not constructed by WebSocketServer, invalidate format!!");
return false;
}
if (argc >= 1)
{
std::function<void(const std::string & cb)> callback;
if (args[argc - 1].isObject() && args[argc - 1].toObject()->isFunction())
{
std::string callbackId = gen_send_index();
s.thisObject()->setProperty(callbackId.c_str(), args[argc - 1]);
std::weak_ptr<WebSocketServerConnection> connWeak = *cobj;
callback = [callbackId, connWeak](const std::string& err) {
se::AutoHandleScope hs;
auto conn = connWeak.lock();
if (!conn) {
return;
}
se::Object* sobj = (se::Object*)conn->getData();
if (!sobj) {
return;
}
se::Value callback;
if (!sobj->getProperty(callbackId.c_str(), &callback)) {
SE_REPORT_ERROR("send[%s] callback not found!", callbackId.c_str());
return;
}
se::ValueArray args;
if (!err.empty())
{
args.push_back(se::Value(err));
}
bool success = callback.toObject()->call(args, sobj, nullptr);
if (!success) {
se::ScriptEngine::getInstance()->clearException();
}
sobj->deleteProperty(callbackId.c_str());
};
}
bool ok = false;
if (args[0].isString())
{
std::string data;
ok = seval_to_std_string(args[0], &data);
SE_PRECONDITION2(ok, false, "Convert string failed");
(*cobj)->sendTextAsync(data, callback);
}
else if (args[0].isObject())
{
se::Object* dataObj = args[0].toObject();
uint8_t* ptr = nullptr;
size_t length = 0;
if (dataObj->isArrayBuffer())
{
ok = dataObj->getArrayBufferData(&ptr, &length);
SE_PRECONDITION2(ok, false, "getArrayBufferData failed!");
}
else if (dataObj->isTypedArray())
{
ok = dataObj->getTypedArrayData(&ptr, &length);
SE_PRECONDITION2(ok, false, "getTypedArrayData failed!");
}
else
{
assert(false);
}
(*cobj)->sendBinaryAsync(ptr, (unsigned int)length, callback);
}
else
{
assert(false);
}
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting 1", argc);
return false;
}
SE_BIND_FUNC(WebSocketServer_Connection_send)
static bool WebSocketServer_Connection_close(se::State& s)
{
const auto& args = s.args();
int argc = (int)args.size();
if (argc > 1)
{
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting 0, 1", argc);
return false;
}
WSCONNPTR cobj = (WSCONNPTR)s.nativeThisObject();
if (!cobj) {
SE_REPORT_ERROR("Connection is not constructed by WebSocketServer, invalidate format!!");
return false;
}
std::function<void(const std::string&)> callback;
int arg_code = -1;
std::string arg_reason;
bool ok;
if (argc >= 1) {
ok = seval_to_int32(args[0], &arg_code);
SE_PRECONDITION2(ok, false, "Convert args[0] should be a number");
if (argc >= 2) {
ok = seval_to_std_string(args[1], &arg_reason);
SE_PRECONDITION2(ok, false, "Convert args[1] should be a string");
}
}
if (arg_code > 0 && !arg_reason.empty()) {
(*cobj)->closeAsync(arg_code, arg_reason);
}
else if (arg_code > 0) {
(*cobj)->closeAsync(arg_code, "unknown reason");
}
else {
(*cobj)->closeAsync(1000, "default close reason");
}
return true;
}
SE_BIND_FUNC(WebSocketServer_Connection_close)
static bool WebSocketServer_Connection_onconnect(se::State& s) {
const auto& args = s.args();
int argc = (int)args.size();
if (!(argc == 1 && args[0].isObject() && args[0].toObject()->isFunction()))
{
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting 1 & function", argc);
return false;
}
WSCONNPTR cobj = (WSCONNPTR)s.nativeThisObject();
if (!cobj) {
SE_REPORT_ERROR("Connection is not constructed by WebSocketServer, invalidate format!!");
return false;
}
s.thisObject()->setProperty("__onconnect", args[0]);
std::weak_ptr<WebSocketServerConnection> connWeak = *cobj;
cobj->get()->setOnConnect([connWeak]() {
se::AutoHandleScope hs;
auto conn = connWeak.lock();
if (!conn) {
return;
}
se::Object* sobj = (se::Object*)conn->getData();
if (!sobj) {
return;
}
se::Value callback;
if (!sobj->getProperty("__onconnect", &callback)) {
SE_REPORT_ERROR("__onconnect callback not found!");
return;
}
se::ValueArray args;
bool success = callback.toObject()->call(args, sobj, nullptr);;
if (!success) {
se::ScriptEngine::getInstance()->clearException();
}
});
return true;
}
SE_BIND_PROP_SET(WebSocketServer_Connection_onconnect)
static bool WebSocketServer_Connection_onerror(se::State& s) {
const auto& args = s.args();
int argc = (int)args.size();
if (!(argc == 1 && args[0].isObject() && args[0].toObject()->isFunction()))
{
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting 1 & function", argc);
return false;
}
WSCONNPTR cobj = (WSCONNPTR)s.nativeThisObject();
if (!cobj) {
SE_REPORT_ERROR("Connection is not constructed by WebSocketServer, invalidate format!!");
return false;
}
s.thisObject()->setProperty("__onerror", args[0]);
std::weak_ptr<WebSocketServerConnection> connWeak = *cobj;
cobj->get()->setOnError([connWeak](const std::string &err) {
se::AutoHandleScope hs;
auto conn = connWeak.lock();
if (!conn) {
return;
}
se::Object* sobj = (se::Object*)conn->getData();
if (!sobj) {
return;
}
se::Value callback;
if (!sobj->getProperty("__onerror", &callback)) {
SE_REPORT_ERROR("__onerror callback not found!");
return;
}
se::ValueArray args;
if (!err.empty())
{
args.push_back(se::Value(err));
}
bool success = callback.toObject()->call(args, sobj, nullptr);;
if (!success) {
se::ScriptEngine::getInstance()->clearException();
}
});
return true;
}
SE_BIND_PROP_SET(WebSocketServer_Connection_onerror)
static bool WebSocketServer_Connection_onclose(se::State& s) {
const auto& args = s.args();
int argc = (int)args.size();
if (!(argc == 1 && args[0].isObject() && args[0].toObject()->isFunction()))
{
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting 1 & function", argc);
return false;
}
WSCONNPTR cobj = (WSCONNPTR)s.nativeThisObject();
if (!cobj) {
SE_REPORT_ERROR("Connection is not constructed by WebSocketServer, invalidate format!!");
return false;
}
s.thisObject()->setProperty("__onclose", args[0]);
std::weak_ptr<WebSocketServerConnection> connWeak = *cobj;
cobj->get()->setOnClose([connWeak](int code, const std::string& err) {
se::AutoHandleScope hs;
auto conn = connWeak.lock();
if (!conn) {
return;
}
se::Object* sobj = (se::Object*)conn->getData();
if (!sobj) {
return;
}
se::Value callback;
if (!sobj->getProperty("__onclose", &callback)) {
SE_REPORT_ERROR("__onclose callback not found!");
return;
}
se::ValueArray args;
args.push_back(se::Value(code));
if (!err.empty())
{
args.push_back(se::Value(err));
}
bool success = callback.toObject()->call(args, sobj, nullptr);;
if (!success) {
se::ScriptEngine::getInstance()->clearException();
}
});
return true;
}
SE_BIND_PROP_SET(WebSocketServer_Connection_onclose)
static bool WebSocketServer_Connection_ontext(se::State& s) {
const auto& args = s.args();
int argc = (int)args.size();
if (!(argc == 1 && args[0].isObject() && args[0].toObject()->isFunction()))
{
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting 1 & function", argc);
return false;
}
WSCONNPTR cobj = (WSCONNPTR)s.nativeThisObject();
if (!cobj) {
SE_REPORT_ERROR("Connection is not constructed by WebSocketServer, invalidate format!!");
return false;
}
s.thisObject()->setProperty("__ontext", args[0]);
std::weak_ptr<WebSocketServerConnection> connWeak = *cobj;
cobj->get()->setOnText([connWeak](const std::shared_ptr<DataFrame> text) {
se::AutoHandleScope hs;
auto conn = connWeak.lock();
if (!conn) {
return;
}
se::Object* sobj = (se::Object*)conn->getData();
if (!sobj) {
return;
}
se::Value callback;
if (!sobj->getProperty("__ontext", &callback)) {
SE_REPORT_ERROR("__ontext callback not found!");
return;
}
se::ValueArray args;
args.push_back(se::Value(text->toString()));
bool success = callback.toObject()->call(args, sobj, nullptr);;
if (!success) {
se::ScriptEngine::getInstance()->clearException();
}
});
return true;
}
SE_BIND_PROP_SET(WebSocketServer_Connection_ontext)
static bool WebSocketServer_Connection_onbinary(se::State& s) {
const auto& args = s.args();
int argc = (int)args.size();
if (!(argc == 1 && args[0].isObject() && args[0].toObject()->isFunction()))
{
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting 1 & function", argc);
return false;
}
WSCONNPTR cobj = (WSCONNPTR)s.nativeThisObject();
if (!cobj) {
SE_REPORT_ERROR("Connection is not constructed by WebSocketServer, invalidate format!!");
return false;
}
s.thisObject()->setProperty("__onbinary", args[0]);
std::weak_ptr<WebSocketServerConnection> connWeak = *cobj;
cobj->get()->setOnBinary([connWeak](const std::shared_ptr<DataFrame> text) {
se::AutoHandleScope hs;
auto conn = connWeak.lock();
if (!conn) {
return;
}
se::Object* sobj = (se::Object*)conn->getData();
if (!sobj) {
return;
}
se::Value callback;
if (!sobj->getProperty("__onbinary", &callback)) {
SE_REPORT_ERROR("__onbinary callback not found!");
return;
}
se::ValueArray args;
se::Object* buffer = se::Object::createArrayBufferObject(text->getData(), text->size());
args.push_back(se::Value(buffer));
bool success = callback.toObject()->call(args, sobj, nullptr);;
if (!success) {
se::ScriptEngine::getInstance()->clearException();
}
});
return true;
}
SE_BIND_PROP_SET(WebSocketServer_Connection_onbinary)
static bool WebSocketServer_Connection_ondata(se::State& s) {
const auto& args = s.args();
int argc = (int)args.size();
if (!(argc == 1 && args[0].isObject() && args[0].toObject()->isFunction()))
{
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting 1 & function", argc);
return false;
}
WSCONNPTR cobj = (WSCONNPTR)s.nativeThisObject();
if (!cobj) {
SE_REPORT_ERROR("Connection is not constructed by WebSocketServer, invalidate format!!");
return false;
}
s.thisObject()->setProperty("__ondata", args[0]);
std::weak_ptr<WebSocketServerConnection> connWeak = *cobj;
cobj->get()->setOnData([connWeak](const std::shared_ptr<DataFrame> text) {
se::AutoHandleScope hs;
auto connPtr = connWeak.lock();
if (!connPtr) {
return;
}
se::Object *sobj = (se::Object*) connPtr->getData();
if (!sobj) {
return;
}
se::Value callback;
if (!sobj->getProperty("__ondata", &callback)) {
return;
}
se::ValueArray args;
if(text->isBinary())
{
se::Object* buffer = se::Object::createArrayBufferObject(text->getData(), text->size());
args.push_back(se::Value(buffer));
}
else if (text->isString())
{
args.push_back(se::Value(text->toString()));
}
bool success = callback.toObject()->call(args, sobj, nullptr);;
if (!success) {
se::ScriptEngine::getInstance()->clearException();
}
});
return true;
}
SE_BIND_PROP_SET(WebSocketServer_Connection_ondata)
static bool WebSocketServer_Connection_headers(se::State& s) {
const auto& args = s.args();
int argc = (int)args.size();
if (argc == 0)
{
WSCONNPTR cobj = (WSCONNPTR)s.nativeThisObject();
auto headers = cobj->get()->getHeaders();
se::Object* ret = se::Object::createPlainObject();
for (auto &itr : headers) {
ret->setProperty(itr.first.c_str(), se::Value(itr.second));
}
s.rval().setObject(ret);
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting 0", argc);
return false;
}
SE_BIND_PROP_GET(WebSocketServer_Connection_headers)
static bool WebSocketServer_Connection_protocols(se::State& s) {
const auto& args = s.args();
int argc = (int)args.size();
if (argc == 0)
{
WSCONNPTR cobj = (WSCONNPTR)s.nativeThisObject();
auto protocols= cobj->get()->getProtocols();
se::Object* ret = se::Object::createArrayObject(protocols.size());
for (int i = 0; i < protocols.size(); i++) {
ret->setArrayElement(i, se::Value(protocols[i]));
}
s.rval().setObject(ret);
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting 0", argc);
return false;
}
SE_BIND_PROP_GET(WebSocketServer_Connection_protocols)
static bool WebSocketServer_Connection_protocol(se::State& s) {
const auto& args = s.args();
int argc = (int)args.size();
if (argc == 0)
{
WSCONNPTR cobj = (WSCONNPTR)s.nativeThisObject();
auto protocols = cobj->get()->getProtocols();
if (protocols.size() > 0) {
s.rval().setString(protocols[0]);
}
else {
s.rval().setUndefined();
}
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting 0", argc);
return false;
}
SE_BIND_PROP_GET(WebSocketServer_Connection_protocol)
static bool WebSocketServer_Connection_readyState(se::State& s) {
const auto& args = s.args();
int argc = (int)args.size();
if (argc == 0)
{
WSCONNPTR cobj = (WSCONNPTR)s.nativeThisObject();
auto state = cobj->get()->getReadyState();
s.rval().setInt32(state);
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting 0", argc);
return false;
}
SE_BIND_PROP_GET(WebSocketServer_Connection_readyState)
bool register_all_websocket_server(se::Object* obj)
{
se::Class* cls = se::Class::create("WebSocketServer", obj, nullptr, _SE(WebSocketServer_constructor));
cls->defineFinalizeFunction(_SE(WebSocketServer_finalize));
cls->defineFunction("close", _SE(WebSocketServer_close));
cls->defineFunction("listen", _SE(WebSocketServer_listen));
cls->defineProperty("onconnection", nullptr, _SE(WebSocketServer_onconnection));
cls->defineProperty("onclose", nullptr, _SE(WebSocketServer_onclose));
cls->defineProperty("connections", _SE(WebSocketServer_connections), nullptr);
cls->install();
JSBClassType::registerClass<WebSocketServer>(cls);
__jsb_WebSocketServer_class = cls;
se::ScriptEngine::getInstance()->clearException();
cls = se::Class::create("WebSocketServerConnection", obj, nullptr, _SE(WebSocketServer_Connection_constructor));
cls->defineFinalizeFunction(_SE(WebSocketServer_Connection_finalize));
cls->defineFunction("close", _SE(WebSocketServer_Connection_close));
cls->defineFunction("send", _SE(WebSocketServer_Connection_send));
cls->defineProperty("ontext", nullptr, _SE(WebSocketServer_Connection_ontext));
cls->defineProperty("onbinary", nullptr, _SE(WebSocketServer_Connection_onbinary));
cls->defineProperty("onconnect", nullptr, _SE(WebSocketServer_Connection_onconnect));
cls->defineProperty("onerror", nullptr, _SE(WebSocketServer_Connection_onerror));
cls->defineProperty("onclose", nullptr, _SE(WebSocketServer_Connection_onclose));
cls->defineProperty("ondata", nullptr, _SE(WebSocketServer_Connection_ondata));
cls->defineProperty("headers", _SE(WebSocketServer_Connection_headers), nullptr);
cls->defineProperty("protocols", _SE(WebSocketServer_Connection_protocols), nullptr);
cls->defineProperty("protocol", _SE(WebSocketServer_Connection_protocol), nullptr);
cls->defineProperty("readyState", _SE(WebSocketServer_Connection_readyState), nullptr);
cls->install();
se::Value tmp;
obj->getProperty("WebSocketServerConnection", &tmp);
tmp.toObject()->setProperty("CONNECTIONG", se::Value(WebSocketServerConnection::CONNECTING));
tmp.toObject()->setProperty("OPEN", se::Value(WebSocketServerConnection::OPEN));
tmp.toObject()->setProperty("CLOSING", se::Value(WebSocketServerConnection::CLOSING));
tmp.toObject()->setProperty("CLOSED", se::Value(WebSocketServerConnection::CLOSED));
JSBClassType::registerClass<WebSocketServerConnection>(cls);
__jsb_WebSocketServer_Connection_class = cls;
se::ScriptEngine::getInstance()->clearException();
return true;
}
#endif //#if (USE_SOCKET > 0) && (USE_WEBSOCKET_SERVER > 0)

View File

@@ -0,0 +1,64 @@
/****************************************************************************
Copyright (c) 2019 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
#include "base/ccConfig.h"
#if (USE_SOCKET > 0) && (USE_WEBSOCKET_SERVER > 0)
#include "cocos/scripting/js-bindings/jswrapper/SeApi.h"
namespace se {
class Object;
class Value;
}
SE_DECLARE_FINALIZE_FUNC(WebSocketServer_finalize);
SE_DECLARE_FUNC(WebSocketServer_constructor);
SE_DECLARE_FUNC(WebSocketServer_listen);
SE_DECLARE_FUNC(WebSocketServer_close);
SE_DECLARE_FUNC(WebSocketServer_onconnection);
SE_DECLARE_FUNC(WebSocketServer_onclose);
SE_DECLARE_FUNC(WebSocketServer_connections);
SE_DECLARE_FUNC(WebSocketServer_Connection_constructor);
SE_DECLARE_FUNC(WebSocketServer_Connection_finalize);
SE_DECLARE_FUNC(WebSocketServer_Connection_close);
SE_DECLARE_FUNC(WebSocketServer_Connection_send);
SE_DECLARE_FUNC(WebSocketServer_Connection_ontext);
SE_DECLARE_FUNC(WebSocketServer_Connection_onbinary);
SE_DECLARE_FUNC(WebSocketServer_Connection_onconnect);
SE_DECLARE_FUNC(WebSocketServer_Connection_onerror);
SE_DECLARE_FUNC(WebSocketServer_Connection_onclose);
SE_DECLARE_FUNC(WebSocketServer_Connection_ondata);
SE_DECLARE_FUNC(WebSocketServer_Connection_headers);
SE_DECLARE_FUNC(WebSocketServer_Connection_protocols);
SE_DECLARE_FUNC(WebSocketServer_Connection_protocol);
SE_DECLARE_FUNC(WebSocketServer_Connection_readyState);
bool register_all_websocket_server(se::Object *obj);
#endif //#if (USE_SOCKET > 0) && (USE_WEBSOCKET_SERVER > 0)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,32 @@
/****************************************************************************
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
namespace se {
class Object;
}
bool register_all_xmlhttprequest(se::Object* global);