2015-05-05 10:50:19 +08:00
|
|
|
/*
|
|
|
|
* Created by Rolando Abarca on 3/14/12.
|
|
|
|
* Copyright (c) 2012 Zynga Inc. All rights reserved.
|
2016-08-05 09:42:15 +08:00
|
|
|
* Copyright (c) 2013-2016 Chukong Technologies Inc.
|
2015-05-05 10:50:19 +08:00
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef __SCRIPTING_CORE_H__
|
|
|
|
#define __SCRIPTING_CORE_H__
|
|
|
|
|
|
|
|
|
|
|
|
#include "jsapi.h"
|
|
|
|
#include "jsfriendapi.h"
|
2016-04-18 15:09:21 +08:00
|
|
|
|
2015-05-05 10:50:19 +08:00
|
|
|
#include "ui/CocosGUI.h"
|
2016-03-20 21:53:44 +08:00
|
|
|
#include "scripting/js-bindings/manual/js_bindings_config.h"
|
|
|
|
#include "scripting/js-bindings/manual/js_bindings_core.h"
|
|
|
|
#include "scripting/js-bindings/manual/spidermonkey_specifics.h"
|
|
|
|
#include "scripting/js-bindings/manual/js_manual_conversions.h"
|
2015-05-05 10:50:19 +08:00
|
|
|
#include "mozilla/Maybe.h"
|
2016-03-20 21:53:44 +08:00
|
|
|
#include "scripting/js-bindings/manual/js-BindingsExport.h"
|
2015-05-05 10:50:19 +08:00
|
|
|
|
|
|
|
#include <assert.h>
|
|
|
|
#include <memory>
|
2016-11-04 11:58:48 +08:00
|
|
|
#include <chrono>
|
2015-05-05 10:50:19 +08:00
|
|
|
|
2016-12-21 13:39:34 +08:00
|
|
|
#define ENGINE_VERSION "Cocos2d-JS v3.14"
|
2015-05-05 10:50:19 +08:00
|
|
|
|
|
|
|
void js_log(const char *format, ...);
|
|
|
|
|
|
|
|
typedef void (*sc_register_sth)(JSContext* cx, JS::HandleObject global);
|
|
|
|
|
|
|
|
void registerDefaultClasses(JSContext* cx, JS::HandleObject global);
|
|
|
|
|
|
|
|
|
|
|
|
class SimpleRunLoop : public cocos2d::Ref
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
void update(float d);
|
|
|
|
};
|
|
|
|
|
2015-09-19 00:18:28 +08:00
|
|
|
/**
|
|
|
|
* @addtogroup jsb
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief @~english ScriptingCore is the main class which manages interaction with JavaScript environment
|
|
|
|
* @details @~english It creates the JavaScript context and its global object.
|
|
|
|
* It also manages object bindings between C++ scope and JavaScript scope,
|
|
|
|
* for most cocos2d classes, if you create an object in JavaScript scope, it will also create a C++ object,
|
|
|
|
* ScriptingCore will manage a proxy between them and synchronize the life cycle.
|
|
|
|
* It can:
|
|
|
|
* - Execute JavaScript functions in different ways with different parameters
|
|
|
|
* - Evaluate JavaScript commands or string
|
|
|
|
* - Execute a JavaScript file
|
|
|
|
* - Clean a JavaScript file cache
|
|
|
|
* - Clean all JavaScript files
|
|
|
|
* - Cleanup or reset the JavaScript context
|
|
|
|
* - Invoke garbage collection of JavaScript context
|
|
|
|
* - etc...
|
|
|
|
*/
|
2015-11-25 22:35:02 +08:00
|
|
|
class CC_JS_DLL ScriptingCore : public cocos2d::ScriptEngineProtocol
|
2015-05-05 10:50:19 +08:00
|
|
|
{
|
|
|
|
private:
|
|
|
|
JSRuntime *_rt;
|
|
|
|
JSContext *_cx;
|
2016-08-19 16:28:47 +08:00
|
|
|
JS::PersistentRootedObject *_global;
|
|
|
|
JS::PersistentRootedObject *_debugGlobal;
|
2015-05-05 10:50:19 +08:00
|
|
|
SimpleRunLoop* _runLoop;
|
2016-02-02 23:39:18 +08:00
|
|
|
bool _jsInited;
|
2016-05-07 14:37:36 +08:00
|
|
|
bool _needCleanup;
|
2015-05-05 10:50:19 +08:00
|
|
|
bool _callFromScript;
|
2016-12-14 09:27:47 +08:00
|
|
|
JSObject *_finalizing;
|
|
|
|
|
2015-05-05 10:50:19 +08:00
|
|
|
ScriptingCore();
|
2016-11-04 11:58:48 +08:00
|
|
|
|
|
|
|
std::chrono::steady_clock::time_point _engineStartTime;
|
2015-05-05 10:50:19 +08:00
|
|
|
public:
|
|
|
|
~ScriptingCore();
|
|
|
|
|
2015-09-19 00:18:28 +08:00
|
|
|
/**@~english
|
|
|
|
* ScriptingCore is a singleton class, you can retrieve its instance with this function.
|
|
|
|
* @return @~english The ScriptingCore instance.
|
|
|
|
*/
|
2015-09-08 11:04:51 +08:00
|
|
|
static ScriptingCore *getInstance();
|
2015-09-19 00:18:28 +08:00
|
|
|
|
|
|
|
/**@~english
|
|
|
|
* Gets the script type, for ScriptingCore, it will return `cocos2d::kScriptTypeJavascript`
|
|
|
|
* @return `cocos2d::kScriptTypeJavascript`
|
|
|
|
*/
|
2015-10-16 13:58:53 +08:00
|
|
|
virtual cocos2d::ccScriptType getScriptType() override { return cocos2d::kScriptTypeJavascript; };
|
2015-09-19 00:18:28 +08:00
|
|
|
|
2015-12-17 21:53:40 +08:00
|
|
|
/**
|
|
|
|
* Reflect the retain relationship to script scope
|
|
|
|
*/
|
|
|
|
virtual void retainScriptObject(cocos2d::Ref* owner, cocos2d::Ref* target) override;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Add the script object to root object
|
|
|
|
*/
|
|
|
|
virtual void rootScriptObject(cocos2d::Ref* target) override;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Reflect the release relationship to script scope
|
|
|
|
*/
|
|
|
|
virtual void releaseScriptObject(cocos2d::Ref* owner, cocos2d::Ref* target) override;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Remove the script object from root object
|
|
|
|
*/
|
|
|
|
virtual void unrootScriptObject(cocos2d::Ref* target) override;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Release all children in script scope
|
|
|
|
*/
|
|
|
|
virtual void releaseAllChildrenRecursive(cocos2d::Node *node) override;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Release all native refs for the given owner in script scope
|
|
|
|
*/
|
|
|
|
virtual void releaseAllNativeRefs(cocos2d::Ref* owner) override;
|
|
|
|
|
2015-05-05 10:50:19 +08:00
|
|
|
/**
|
2015-09-19 00:18:28 +08:00
|
|
|
* @brief @~english Removes the C++ object's linked JavaScript proxy object from JavaScript context
|
|
|
|
* @param obj @~english Object to be removed
|
2015-05-05 10:50:19 +08:00
|
|
|
*/
|
2015-10-16 13:58:53 +08:00
|
|
|
virtual void removeScriptObjectByObject(cocos2d::Ref* obj) override;
|
2015-09-19 00:18:28 +08:00
|
|
|
|
2015-05-05 10:50:19 +08:00
|
|
|
/**
|
2015-09-19 00:18:28 +08:00
|
|
|
* @brief @~english Useless in ScriptingCore, please use evalString
|
|
|
|
* @see evalString
|
2015-05-05 10:50:19 +08:00
|
|
|
*/
|
2015-10-16 13:58:53 +08:00
|
|
|
virtual int executeString(const char* codes) override { return 0; }
|
2015-09-19 00:18:28 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief @~english Pause scheduled tasks and actions for an object proxy.
|
|
|
|
* @param p @~english The object proxy
|
|
|
|
*/
|
2015-05-05 10:50:19 +08:00
|
|
|
void pauseSchedulesAndActions(js_proxy_t* p);
|
2015-09-19 00:18:28 +08:00
|
|
|
/**
|
|
|
|
* @brief @~english Resume scheduled tasks and actions for an object proxy.
|
|
|
|
* @param p @~english The object proxy
|
|
|
|
*/
|
2015-05-05 10:50:19 +08:00
|
|
|
void resumeSchedulesAndActions(js_proxy_t* p);
|
2015-09-19 00:18:28 +08:00
|
|
|
/**
|
|
|
|
* @brief @~english Cleanup scheduled tasks and actions for an object proxy.
|
|
|
|
* @param p @~english The object proxy
|
|
|
|
*/
|
2015-05-05 10:50:19 +08:00
|
|
|
void cleanupSchedulesAndActions(js_proxy_t* p);
|
|
|
|
|
|
|
|
/**
|
2015-09-19 00:18:28 +08:00
|
|
|
@brief Useless in ScriptingCore, please use runScript
|
2015-05-05 10:50:19 +08:00
|
|
|
@param filename String object holding the filename of the script file that is to be executed
|
|
|
|
*/
|
2015-10-16 13:58:53 +08:00
|
|
|
virtual int executeScriptFile(const char* filename) override { return 0; }
|
2015-05-05 10:50:19 +08:00
|
|
|
|
|
|
|
/**
|
2015-09-19 00:18:28 +08:00
|
|
|
@brief @~english Useless in ScriptingCore, please use executeFunctionWithOwner
|
2015-05-05 10:50:19 +08:00
|
|
|
@param functionName String object holding the name of the function, in the global script environment, that is to be executed.
|
|
|
|
@return The integer value returned from the script function.
|
|
|
|
*/
|
2015-10-16 13:58:53 +08:00
|
|
|
virtual int executeGlobalFunction(const char* functionName) override { return 0; }
|
2015-05-05 10:50:19 +08:00
|
|
|
|
|
|
|
virtual int sendEvent(cocos2d::ScriptEvent* message) override;
|
|
|
|
|
|
|
|
virtual bool parseConfig(ConfigType type, const std::string& str) override;
|
2015-09-19 00:18:28 +08:00
|
|
|
/**
|
|
|
|
* @brief @~english Useless in ScriptingCore
|
|
|
|
* @return @~english false
|
|
|
|
*/
|
2015-10-16 13:58:53 +08:00
|
|
|
virtual bool handleAssert(const char *msg) override { return false; }
|
2015-05-05 10:50:19 +08:00
|
|
|
|
2015-10-16 13:58:53 +08:00
|
|
|
virtual void setCalledFromScript(bool callFromScript) override { _callFromScript = callFromScript; };
|
|
|
|
virtual bool isCalledFromScript() override { return _callFromScript; };
|
2015-05-05 10:50:19 +08:00
|
|
|
|
2015-09-19 00:18:28 +08:00
|
|
|
/**
|
|
|
|
* @brief @~english Execute a js function with a JavaScript object as parameter.
|
|
|
|
* By passing a native object, ScriptingCore will found its JavaScript object with the proxy.
|
|
|
|
* Then the function will be invoked with the native object's js proxy as caller.
|
|
|
|
* @param nativeObj @~english The caller object's C++ proxy.
|
|
|
|
* @param name @~english The function name.
|
|
|
|
* @param obj @~english The JavaScript object as parameter.
|
|
|
|
* @return @~english Return the js function's boolean result if successfully invoked, otherwise return false.
|
|
|
|
*/
|
2015-05-05 10:50:19 +08:00
|
|
|
bool executeFunctionWithObjectData(void* nativeObj, const char *name, JSObject *obj);
|
2015-09-19 00:18:28 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief @~english Execute a js function with a JavaScript caller, function name, arguments count and arguments.
|
|
|
|
* @param owner @~english The caller object.
|
|
|
|
* @param name @~english The function name.
|
|
|
|
* @param argc @~english The arguments count.
|
|
|
|
* @param vp @~english The arguments.
|
|
|
|
* @return @~english Return true if successfully invoked, otherwise return false.
|
|
|
|
*/
|
2015-05-05 10:50:19 +08:00
|
|
|
bool executeFunctionWithOwner(jsval owner, const char *name, uint32_t argc, jsval *vp);
|
2015-09-19 00:18:28 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief @~english Execute a js function with a JavaScript caller, function name, arguments count, arguments and a return value.
|
|
|
|
* @param owner @~english The caller object.
|
|
|
|
* @param name @~english The function name.
|
|
|
|
* @param argc @~english The arguments count.
|
|
|
|
* @param vp @~english The arguments.
|
|
|
|
* @param retVal @~english The js object to save the return value.
|
|
|
|
* @return @~english Return true if successfully invoked, otherwise return false.
|
|
|
|
*/
|
2015-05-05 10:50:19 +08:00
|
|
|
bool executeFunctionWithOwner(jsval owner, const char *name, uint32_t argc, jsval *vp, JS::MutableHandleValue retVal);
|
2015-09-19 00:18:28 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief @~english Execute a js function with a JavaScript caller, function name, arguments array.
|
|
|
|
* This is more reliable in js memory management
|
|
|
|
* @param owner @~english The caller object.
|
|
|
|
* @param name @~english The function name.
|
|
|
|
* @param args @~english The arguments array.
|
|
|
|
* @return @~english Return true if successfully invoked, otherwise return false.
|
|
|
|
*/
|
2015-05-05 10:50:19 +08:00
|
|
|
bool executeFunctionWithOwner(jsval owner, const char *name, const JS::HandleValueArray& args);
|
2015-09-19 00:18:28 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief @~english Execute a js function with a JavaScript caller, function name, arguments array and a return value.
|
|
|
|
* This is more reliable in js memory management
|
|
|
|
* @param owner @~english The caller object.
|
|
|
|
* @param name @~english The function name.
|
|
|
|
* @param args @~english The arguments array.
|
|
|
|
* @param retVal @~english The js object to save the return value.
|
|
|
|
* @return @~english Return true if successfully invoked, otherwise return false.
|
|
|
|
*/
|
2015-05-05 10:50:19 +08:00
|
|
|
bool executeFunctionWithOwner(jsval owner, const char *name, const JS::HandleValueArray& args, JS::MutableHandleValue retVal);
|
2015-09-19 00:18:28 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief @~english Execute a js function with a js this object and the js function object.
|
|
|
|
* @param thisObj @~english The js this object.
|
|
|
|
* @param callback @~english The js function object.
|
|
|
|
* @return @~english Return true if successfully invoked, otherwise return false.
|
|
|
|
*/
|
2015-05-05 10:50:19 +08:00
|
|
|
void executeJSFunctionWithThisObj(JS::HandleValue thisObj, JS::HandleValue callback);
|
|
|
|
/**
|
2015-09-19 00:18:28 +08:00
|
|
|
* @brief @~english Execute a js function with a js this object, the js function object, arguments and a return value.
|
|
|
|
* @param thisObj @~english The js this object.
|
|
|
|
* @param callback @~english The js function object.
|
|
|
|
* @param vp @~english The arguments array.
|
|
|
|
* @param retVal @~english The js object to save the return value.
|
|
|
|
* @return @~english Return true if successfully invoked, otherwise return false.
|
|
|
|
*/
|
|
|
|
void executeJSFunctionWithThisObj(JS::HandleValue thisObj, JS::HandleValue callback, const JS::HandleValueArray& vp, JS::MutableHandleValue retVal);
|
|
|
|
|
|
|
|
/**@~english
|
|
|
|
* Evaluate the specified js code string
|
|
|
|
* @param string @~english The string with the javascript code to be evaluated
|
|
|
|
* @param outVal @~english The jsval that will hold the return value of the evaluation.
|
|
|
|
* @param filename @~english The filename
|
|
|
|
* @param cx @~english The js context
|
|
|
|
* @param global @~english The js global object
|
|
|
|
* @return @~english Return true if successfully invoked, otherwise return false.
|
2015-05-05 10:50:19 +08:00
|
|
|
*/
|
2015-12-14 13:55:17 +08:00
|
|
|
bool evalString(const char *string, JS::MutableHandleValue outVal, const char *filename, JSContext* cx, JS::HandleObject global);
|
|
|
|
|
|
|
|
/**@~english
|
|
|
|
* Evaluate the specified js code string
|
|
|
|
* @param string @~english The string with the javascript code to be evaluated
|
|
|
|
* @param outVal @~english The jsval that will hold the return value of the evaluation.
|
|
|
|
* @return @~english Return true if successfully invoked, otherwise return false.
|
|
|
|
*/
|
|
|
|
bool evalString(const char *string, JS::MutableHandleValue outVal);
|
|
|
|
|
|
|
|
/**@~english
|
|
|
|
* Evaluate the specified js code string
|
|
|
|
* @param string @~english The string with the javascript code to be evaluated
|
|
|
|
* @return @~english Return true if successfully invoked, otherwise return false.
|
|
|
|
*/
|
|
|
|
bool evalString(const char *string);
|
2015-05-05 10:50:19 +08:00
|
|
|
|
|
|
|
/**
|
2015-09-19 00:18:28 +08:00
|
|
|
@brief @~english Get script object for the given path
|
|
|
|
@param path @~english The script file path
|
|
|
|
@return @~english Script object
|
2015-05-05 10:50:19 +08:00
|
|
|
*/
|
2016-08-19 16:28:47 +08:00
|
|
|
JS::PersistentRootedScript* getScript(const std::string& path);
|
|
|
|
|
2015-09-19 00:18:28 +08:00
|
|
|
/**@~english
|
|
|
|
* Compile the specified js file
|
2016-01-11 18:15:34 +08:00
|
|
|
* @param path @~english The path of the script to be compiled
|
2015-09-19 00:18:28 +08:00
|
|
|
* @param global @~english The js global object
|
|
|
|
* @param cx @~english The js context
|
2015-05-05 10:50:19 +08:00
|
|
|
*/
|
2016-08-19 16:28:47 +08:00
|
|
|
JS::PersistentRootedScript* compileScript(const std::string& path, JS::HandleObject global, JSContext* cx = nullptr);
|
|
|
|
|
2015-09-19 00:18:28 +08:00
|
|
|
/**@~english
|
|
|
|
* Run the specified js file
|
|
|
|
* @param path @~english The path of the script to be executed
|
|
|
|
* @return @~english Return true if succeed, otherwise return false.
|
2015-05-05 10:50:19 +08:00
|
|
|
*/
|
2016-08-19 16:28:47 +08:00
|
|
|
bool runScript(const std::string& path);
|
2015-09-19 00:18:28 +08:00
|
|
|
/**@~english
|
|
|
|
* Run the specified js file
|
|
|
|
* @param path @~english The path of the script to be executed
|
|
|
|
* @param global @~english The global object to execute the script
|
|
|
|
* @param global @~english The context to execute the script
|
|
|
|
* @return @~english Return true if succeed, otherwise return false.
|
|
|
|
*/
|
2016-08-19 16:28:47 +08:00
|
|
|
bool runScript(const std::string& path, JS::HandleObject global, JSContext* cx = NULL);
|
|
|
|
|
2015-09-19 00:18:28 +08:00
|
|
|
/**@~english
|
|
|
|
* Require the specified js file
|
|
|
|
* The difference between run and require is that require returns the export object of the script
|
|
|
|
* @param path @~english The path of the script to be executed
|
|
|
|
* @param jsvalRet @~english On success, return the value from the last executed expression statement processed in the script
|
|
|
|
* @return @~english Return true if succeed, otherwise return false.
|
|
|
|
* @see https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/JSAPI_reference/JS_ExecuteScript
|
|
|
|
*/
|
|
|
|
bool requireScript(const char *path, JS::MutableHandleValue jsvalRet);
|
|
|
|
/**@~english
|
|
|
|
* Require the specified js file
|
|
|
|
* The difference between run and require is that require returns the export object of the script
|
|
|
|
* @param path @~english The path of the script to be executed
|
|
|
|
* @param global @~english The global object to execute the script
|
|
|
|
* @param global @~english The context to execute the script
|
|
|
|
* @param jsvalRet @~english On success, return the value from the last executed expression statement processed in the script
|
|
|
|
* @return @~english Return true if succeed, otherwise return false.
|
|
|
|
* @see https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/JSAPI_reference/JS_ExecuteScript
|
|
|
|
*/
|
|
|
|
bool requireScript(const char *path, JS::HandleObject global, JSContext* cx, JS::MutableHandleValue jsvalRet);
|
|
|
|
|
|
|
|
/**@~english
|
|
|
|
* Clean script object for the specified js file
|
|
|
|
* @param path @~english The path of the js file to be cleaned
|
2015-05-05 10:50:19 +08:00
|
|
|
*/
|
|
|
|
void cleanScript(const char *path);
|
|
|
|
|
2015-09-19 00:18:28 +08:00
|
|
|
/**@~english
|
|
|
|
* Gets the cached script objects for all executed js file
|
|
|
|
* @return @~english The cached script object map
|
|
|
|
*/
|
2016-06-22 16:18:20 +08:00
|
|
|
std::unordered_map<std::string, JS::PersistentRootedScript*>& getFileScript();
|
2015-09-19 00:18:28 +08:00
|
|
|
/**@~english
|
|
|
|
* Clean all script objects
|
2015-05-05 10:50:19 +08:00
|
|
|
*/
|
|
|
|
void cleanAllScript();
|
2016-11-04 11:58:48 +08:00
|
|
|
|
|
|
|
/**@~english
|
|
|
|
* Gets the time that the ScriptingCore was initalized
|
|
|
|
*/
|
|
|
|
std::chrono::steady_clock::time_point getEngineStartTime() const;
|
2015-05-05 10:50:19 +08:00
|
|
|
|
2015-09-19 00:18:28 +08:00
|
|
|
/**@~english
|
|
|
|
* Initialize everything, including the js context, js global object etc.
|
2015-05-05 10:50:19 +08:00
|
|
|
*/
|
|
|
|
void start();
|
2015-09-19 00:18:28 +08:00
|
|
|
|
|
|
|
/**@~english
|
|
|
|
* Cleanup everything, including script cache, js context, global object etc.
|
2015-05-05 10:50:19 +08:00
|
|
|
*/
|
|
|
|
void cleanup();
|
2015-09-19 00:18:28 +08:00
|
|
|
|
|
|
|
/**@~english
|
|
|
|
* Cleanup everything then initialize everything
|
2015-05-05 10:50:19 +08:00
|
|
|
*/
|
|
|
|
void reset();
|
2015-09-19 00:18:28 +08:00
|
|
|
|
|
|
|
/**@~english
|
|
|
|
* Add the register_sth callback to the list of functions that need to be called after the creation of the context.
|
|
|
|
* It's normally used to register script bindings in the js context for bound classes
|
|
|
|
* @param callback @~english The callback to register something to the js context
|
2015-05-05 10:50:19 +08:00
|
|
|
*/
|
|
|
|
void addRegisterCallback(sc_register_sth callback);
|
2015-09-19 00:18:28 +08:00
|
|
|
|
|
|
|
/**@~english
|
|
|
|
* Create a new context. If one is already there, it will destroy the old context and create a new one.
|
2015-05-05 10:50:19 +08:00
|
|
|
*/
|
|
|
|
void createGlobalContext();
|
2015-09-19 00:18:28 +08:00
|
|
|
|
|
|
|
/**@~english
|
|
|
|
* Removes all rooted object in the given js context, rooted object won't be garbage collected.
|
|
|
|
* @param cx @~english The js context
|
|
|
|
*/
|
2015-05-05 10:50:19 +08:00
|
|
|
static void removeAllRoots(JSContext *cx);
|
2015-09-19 00:18:28 +08:00
|
|
|
|
|
|
|
/**@~english
|
|
|
|
* Simulate a touch event and dispatch it to a js object.
|
|
|
|
* @param eventType @~english The touch event type
|
|
|
|
* @param pTouch @~english The touch object
|
|
|
|
* @param obj @~english The js object
|
|
|
|
* @param retval @~english The return value of the touch event callback
|
|
|
|
* @return @~english Return 1 if succeed, otherwise return 0.
|
|
|
|
*/
|
2015-05-05 10:50:19 +08:00
|
|
|
int executeCustomTouchEvent(cocos2d::EventTouch::EventCode eventType,
|
|
|
|
cocos2d::Touch *pTouch, JSObject *obj, JS::MutableHandleValue retval);
|
2015-09-19 00:18:28 +08:00
|
|
|
/**@~english
|
|
|
|
* Simulate a touch event and dispatch it to a js object.
|
|
|
|
* @param eventType @~english The touch event type
|
|
|
|
* @param pTouch @~english The touch object
|
|
|
|
* @param obj @~english The js object
|
|
|
|
* @return @~english Return 1 if succeed, otherwise return 0.
|
|
|
|
*/
|
2015-05-05 10:50:19 +08:00
|
|
|
int executeCustomTouchEvent(cocos2d::EventTouch::EventCode eventType,
|
|
|
|
cocos2d::Touch *pTouch, JSObject *obj);
|
2015-09-19 00:18:28 +08:00
|
|
|
/**@~english
|
|
|
|
* Simulate a multi touch event and dispatch it to a js object.
|
|
|
|
* @param eventType @~english The touch event type
|
2016-07-03 23:42:10 +08:00
|
|
|
* @param touches @~english Touches list for multitouch
|
2015-09-19 00:18:28 +08:00
|
|
|
* @param obj @~english The js object
|
|
|
|
* @return @~english Return 1 if succeed, otherwise return 0.
|
|
|
|
*/
|
2015-05-05 10:50:19 +08:00
|
|
|
int executeCustomTouchesEvent(cocos2d::EventTouch::EventCode eventType,
|
|
|
|
const std::vector<cocos2d::Touch*>& touches, JSObject *obj);
|
2015-09-19 00:18:28 +08:00
|
|
|
/**@~english
|
|
|
|
* Gets the current global context.
|
|
|
|
* @return @~english the global context
|
2015-05-05 10:50:19 +08:00
|
|
|
*/
|
|
|
|
JSContext* getGlobalContext() {
|
|
|
|
return _cx;
|
|
|
|
};
|
2015-09-19 00:18:28 +08:00
|
|
|
|
|
|
|
/**@~english
|
|
|
|
* Report an error in the js context
|
|
|
|
* @param cx @~english The js context
|
|
|
|
* @param message @~english The error message
|
|
|
|
* @param report @~english The js error report object
|
2015-05-05 10:50:19 +08:00
|
|
|
*/
|
|
|
|
static void reportError(JSContext *cx, const char *message, JSErrorReport *report);
|
2015-09-19 00:18:28 +08:00
|
|
|
|
|
|
|
/**@~english
|
|
|
|
* Log something to the js context using CCLog.
|
|
|
|
* @param cx @~english The js context
|
|
|
|
* @param argc @~english The arguments count
|
|
|
|
* @param vp @~english The arguments
|
|
|
|
* @return @~english Return true if succeed, otherwise return false.
|
2015-05-05 10:50:19 +08:00
|
|
|
*/
|
|
|
|
static bool log(JSContext *cx, uint32_t argc, jsval *vp);
|
2015-09-19 00:18:28 +08:00
|
|
|
|
|
|
|
/**@~english
|
2016-01-11 18:15:34 +08:00
|
|
|
* Sets a js value to the targeted js object's reserved slot, which is not exposed to script environment.
|
2015-09-19 00:18:28 +08:00
|
|
|
* @param i @~english The slot index
|
|
|
|
* @param obj @~english The targeted object
|
|
|
|
* @param value @~english The js value to set to the slot
|
|
|
|
* @return @~english Return true if succeed, otherwise return false.
|
|
|
|
*/
|
2015-05-05 10:50:19 +08:00
|
|
|
bool setReservedSpot(uint32_t i, JSObject *obj, jsval value);
|
2015-09-19 00:18:28 +08:00
|
|
|
|
|
|
|
/**@~english
|
|
|
|
* Runs a script from script environment, it should be invoked from script environment
|
|
|
|
* Bound to `__jsc__.executeScript` and `window.executeScript`
|
|
|
|
* @param cx @~english The js context
|
|
|
|
* @param argc @~english The arguments count
|
|
|
|
* @param vp @~english The arguments
|
|
|
|
* @return @~english Return true if succeed, otherwise return false.
|
2015-05-05 10:50:19 +08:00
|
|
|
*/
|
|
|
|
static bool executeScript(JSContext *cx, uint32_t argc, jsval *vp);
|
2015-09-19 00:18:28 +08:00
|
|
|
/**@~english
|
|
|
|
* Forces a cycle of garbage collection, it should be invoked from script environment
|
|
|
|
* Bound to `__jsc__.garbageCollect` and `window.garbageCollect`
|
|
|
|
* @param cx @~english The js context
|
|
|
|
* @param argc @~english The arguments count
|
|
|
|
* @param vp @~english The arguments
|
2015-05-05 10:50:19 +08:00
|
|
|
*/
|
|
|
|
static bool forceGC(JSContext *cx, uint32_t argc, jsval *vp);
|
2015-09-19 00:18:28 +08:00
|
|
|
/**@~english
|
|
|
|
* Dump all named rooted objects, it should be invoked from script environment
|
|
|
|
* Bound to `__jsc__.dumpRoot`
|
|
|
|
* @param cx @~english The js context
|
|
|
|
* @param argc @~english The arguments count
|
|
|
|
* @param vp @~english The arguments
|
|
|
|
*/
|
2015-05-05 10:50:19 +08:00
|
|
|
static bool dumpRoot(JSContext *cx, uint32_t argc, jsval *vp);
|
2015-09-19 00:18:28 +08:00
|
|
|
/**@~english
|
|
|
|
* Check whether a js object's C++ proxy is still valid, it should be invoked from script environment
|
|
|
|
* Bound to `window.__isObjectValid`
|
|
|
|
* @param cx @~english The js context
|
|
|
|
* @param argc @~english The arguments count
|
|
|
|
* @param vp @~english The arguments
|
|
|
|
*/
|
2015-05-05 10:50:19 +08:00
|
|
|
static bool isObjectValid(JSContext *cx, uint32_t argc, jsval *vp);
|
2015-09-19 00:18:28 +08:00
|
|
|
|
|
|
|
/**@~english
|
|
|
|
* Log a string to the debug environment.
|
|
|
|
* Enable the debug environment so that it can be invoked.
|
|
|
|
* @param str @~english The message to log
|
2015-05-05 10:50:19 +08:00
|
|
|
*/
|
|
|
|
void debugProcessInput(const std::string& str);
|
2015-09-19 00:18:28 +08:00
|
|
|
/**@~english
|
|
|
|
* Enable the debug environment, mozilla Firefox's remote debugger or Code IDE can connect to it.
|
2015-11-03 03:31:17 +08:00
|
|
|
* @param port @~english The port to connect with the debug environment, default value is 5086
|
2015-09-19 00:18:28 +08:00
|
|
|
*/
|
2015-05-05 10:50:19 +08:00
|
|
|
void enableDebugger(unsigned int port = 5086);
|
2015-09-19 00:18:28 +08:00
|
|
|
/**@~english
|
|
|
|
* Gets the debug environment's global object
|
|
|
|
* @return @~english The debug environment's global object
|
|
|
|
*/
|
2016-08-19 16:28:47 +08:00
|
|
|
JSObject* getDebugGlobal() { return _debugGlobal->get(); }
|
2015-09-19 00:18:28 +08:00
|
|
|
/**@~english
|
|
|
|
* Gets the global object
|
|
|
|
* @return @~english The global object
|
|
|
|
*/
|
2016-08-19 16:28:47 +08:00
|
|
|
JSObject* getGlobalObject() { return _global->get(); }
|
2015-09-19 00:18:28 +08:00
|
|
|
|
|
|
|
/**@~english
|
|
|
|
* Checks whether a C++ function is overrided in js prototype chain
|
|
|
|
* @param obj @~english The js object
|
|
|
|
* @param name @~english The function name
|
|
|
|
* @param native @~english The native function
|
|
|
|
* @return @~english The global object
|
|
|
|
*/
|
2015-05-05 10:50:19 +08:00
|
|
|
bool isFunctionOverridedInJS(JS::HandleObject obj, const std::string& name, JSNative native);
|
2015-12-17 21:53:40 +08:00
|
|
|
|
2015-12-03 06:45:13 +08:00
|
|
|
/**
|
|
|
|
* Roots the associated JSObj.
|
|
|
|
* The GC won't collected rooted objects. This function is only called
|
|
|
|
* when compiled with CC_ENABLE_GC_FOR_NATIVE_OBJECTS=1
|
|
|
|
*/
|
|
|
|
virtual void rootObject(cocos2d::Ref* ref) override;
|
|
|
|
/**
|
|
|
|
* Unroots the associated JSObj.
|
|
|
|
* The GC will collect this object the next time the GC
|
|
|
|
* is called.
|
|
|
|
* This function is only called when compiled with CC_ENABLE_GC_FOR_NATIVE_OBJECTS=1
|
|
|
|
*/
|
|
|
|
virtual void unrootObject(cocos2d::Ref* ref) override;
|
|
|
|
|
2015-12-24 00:54:00 +08:00
|
|
|
/**
|
|
|
|
* Calls the Garbage Collector
|
|
|
|
*/
|
|
|
|
virtual void garbageCollect() override;
|
|
|
|
|
2016-12-14 09:27:47 +08:00
|
|
|
/**
|
|
|
|
* Sets the js object that is being finalizing in the script engine, internal use only, please do not call this function
|
|
|
|
*/
|
|
|
|
void setFinalizing (JSObject *finalizing) {_finalizing = finalizing;};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets the js object that is being finalizing in the script engine
|
|
|
|
*/
|
|
|
|
JSObject *getFinalizing () {return _finalizing;};
|
|
|
|
|
2015-05-05 10:50:19 +08:00
|
|
|
private:
|
|
|
|
void string_report(JS::HandleValue val);
|
|
|
|
void initRegister();
|
|
|
|
|
|
|
|
public:
|
|
|
|
int handleNodeEvent(void* data);
|
2015-08-27 17:55:38 +08:00
|
|
|
int handleActionEvent(void* data);
|
2015-05-05 10:50:19 +08:00
|
|
|
int handleComponentEvent(void* data);
|
|
|
|
|
|
|
|
bool handleTouchesEvent(void* nativeObj, cocos2d::EventTouch::EventCode eventCode, const std::vector<cocos2d::Touch*>& touches, cocos2d::Event* event);
|
|
|
|
bool handleTouchesEvent(void* nativeObj, cocos2d::EventTouch::EventCode eventCode, const std::vector<cocos2d::Touch*>& touches, cocos2d::Event* event, JS::MutableHandleValue jsvalRet);
|
|
|
|
|
|
|
|
bool handleTouchEvent(void* nativeObj, cocos2d::EventTouch::EventCode eventCode, cocos2d::Touch* touch, cocos2d::Event* event);
|
|
|
|
bool handleTouchEvent(void* nativeObj, cocos2d::EventTouch::EventCode eventCode, cocos2d::Touch* touch, cocos2d::Event* event, JS::MutableHandleValue jsvalRet);
|
|
|
|
|
|
|
|
bool handleMouseEvent(void* nativeObj, cocos2d::EventMouse::MouseEventType eventType, cocos2d::Event* event);
|
|
|
|
bool handleMouseEvent(void* nativeObj, cocos2d::EventMouse::MouseEventType eventType, cocos2d::Event* event, JS::MutableHandleValue jsvalRet);
|
|
|
|
|
2016-05-24 09:14:36 +08:00
|
|
|
bool handleKeyboardEvent(void* nativeObj, cocos2d::EventKeyboard::KeyCode keyCode, bool isPressed, cocos2d::Event* event);
|
2015-05-05 10:50:19 +08:00
|
|
|
bool handleFocusEvent(void* nativeObj, cocos2d::ui::Widget* widgetLoseFocus, cocos2d::ui::Widget* widgetGetFocus);
|
|
|
|
|
|
|
|
void restartVM();
|
|
|
|
};
|
|
|
|
|
2015-12-14 10:27:11 +08:00
|
|
|
JSObject* NewGlobalObject(JSContext* cx, bool debug = false);
|
2015-05-05 10:50:19 +08:00
|
|
|
|
|
|
|
bool jsb_set_reserved_slot(JSObject *obj, uint32_t idx, jsval value);
|
|
|
|
bool jsb_get_reserved_slot(JSObject *obj, uint32_t idx, jsval& ret);
|
|
|
|
|
2015-11-27 01:26:54 +08:00
|
|
|
template <class T>
|
|
|
|
js_type_class_t *jsb_register_class(JSContext *cx, JSClass *jsClass, JS::HandleObject proto, JS::HandleObject parentProto)
|
|
|
|
{
|
|
|
|
js_type_class_t *p = nullptr;
|
2016-09-15 01:49:14 +08:00
|
|
|
std::string typeName = TypeTest<T>::s_name();
|
2015-11-27 01:26:54 +08:00
|
|
|
if (_js_global_type_map.find(typeName) == _js_global_type_map.end())
|
|
|
|
{
|
2016-08-19 16:28:47 +08:00
|
|
|
JS::RootedObject protoRoot(cx, proto);
|
|
|
|
JS::RootedObject protoParentRoot(cx, parentProto);
|
2015-11-27 01:26:54 +08:00
|
|
|
p = (js_type_class_t *)malloc(sizeof(js_type_class_t));
|
2016-08-19 16:28:47 +08:00
|
|
|
memset(p, 0, sizeof(js_type_class_t));
|
2015-11-27 01:26:54 +08:00
|
|
|
p->jsclass = jsClass;
|
2016-08-19 16:28:47 +08:00
|
|
|
auto persistentProtoRoot = new (std::nothrow) JS::PersistentRootedObject(cx, protoRoot);
|
|
|
|
p->proto.set(persistentProtoRoot);
|
|
|
|
|
|
|
|
auto persistentProtoParentRoot = new (std::nothrow) JS::PersistentRootedObject(cx, protoParentRoot);
|
|
|
|
p->parentProto.set(persistentProtoParentRoot);
|
2015-11-27 01:26:54 +08:00
|
|
|
_js_global_type_map.insert(std::make_pair(typeName, p));
|
|
|
|
}
|
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
2016-01-11 18:15:34 +08:00
|
|
|
/** creates two new proxies: one associated with the nativeObj,
|
2015-12-17 09:37:44 +08:00
|
|
|
and another one associated with the JsObj */
|
2015-11-27 10:20:51 +08:00
|
|
|
js_proxy_t* jsb_new_proxy(void* nativeObj, JS::HandleObject jsObj);
|
2015-12-17 09:37:44 +08:00
|
|
|
/** returns the proxy associated with the Native* */
|
2015-05-05 10:50:19 +08:00
|
|
|
js_proxy_t* jsb_get_native_proxy(void* nativeObj);
|
2015-12-17 09:37:44 +08:00
|
|
|
/** returns the proxy associated with the JSObject* */
|
2016-08-19 16:28:47 +08:00
|
|
|
js_proxy_t* jsb_get_js_proxy(JS::HandleObject jsObj);
|
2015-12-17 09:37:44 +08:00
|
|
|
/** deprecated: use jsb_remove_proxy(js_proxy_t* proxy) instead */
|
2015-05-05 10:50:19 +08:00
|
|
|
void jsb_remove_proxy(js_proxy_t* nativeProxy, js_proxy_t* jsProxy);
|
2015-12-17 09:37:44 +08:00
|
|
|
/** removes both the native and js proxies */
|
|
|
|
void jsb_remove_proxy(js_proxy_t* proxy);
|
2015-12-17 21:53:40 +08:00
|
|
|
/** removes the native js object proxy and unroot the js object (if necessary),
|
|
|
|
it's often used when JS object is created by native object */
|
|
|
|
void removeJSObject(JSContext* cx, cocos2d::Ref* nativeObj);
|
2015-05-05 10:50:19 +08:00
|
|
|
|
2015-12-03 06:45:13 +08:00
|
|
|
/**
|
|
|
|
* Generic initialization function for subclasses of Ref
|
|
|
|
*/
|
|
|
|
void jsb_ref_init(JSContext* cx, JS::Heap<JSObject*> *obj, cocos2d::Ref* ref, const char* debug);
|
|
|
|
|
2015-12-05 10:42:31 +08:00
|
|
|
/**
|
|
|
|
* Generic initialization function for subclasses of Ref.
|
|
|
|
* Similar to jsb_ref_init(), but call it if you know that Ref has been autoreleased
|
|
|
|
* This function should never be called. It is only added as way to fix
|
|
|
|
* an issue with the static auto-bindings with the "create" function
|
|
|
|
*/
|
|
|
|
void jsb_ref_autoreleased_init(JSContext* cx, JS::Heap<JSObject*> *obj, cocos2d::Ref* ref, const char* debug);
|
|
|
|
|
2015-12-03 06:45:13 +08:00
|
|
|
/**
|
2015-12-17 21:53:40 +08:00
|
|
|
* Disassociates oldRef from jsobj, and associates a new Ref.
|
|
|
|
* Useful for the EaseActions and others
|
2015-12-03 06:45:13 +08:00
|
|
|
*/
|
|
|
|
void jsb_ref_rebind(JSContext* cx, JS::HandleObject jsobj, js_proxy_t *js2native_proxy, cocos2d::Ref* oldRef, cocos2d::Ref* newRef, const char* debug);
|
|
|
|
|
|
|
|
/**
|
2015-12-17 21:53:40 +08:00
|
|
|
* Creates a new JSObject of a certain type (typeClass) and creates a proxy associated with and the Ref
|
2015-12-03 06:45:13 +08:00
|
|
|
*/
|
2015-12-21 11:07:40 +08:00
|
|
|
JSObject* jsb_ref_create_jsobject(JSContext *cx, cocos2d::Ref *ref, js_type_class_t *typeClass, const char* debug);
|
2015-12-03 06:45:13 +08:00
|
|
|
|
2015-12-05 10:42:31 +08:00
|
|
|
/**
|
|
|
|
* Creates a new JSObject of a certain type (typeClass) and creates a proxy associated with and the Ref
|
|
|
|
* Similar to jsb_ref_create_jsobject(), but call it if you know that Ref has been autoreleased
|
|
|
|
* This function should never be called. It is only added as way to fix
|
|
|
|
* an issue with the static auto-bindings with the "create" function
|
|
|
|
*/
|
2015-12-21 11:07:40 +08:00
|
|
|
JSObject* jsb_ref_autoreleased_create_jsobject(JSContext *cx, cocos2d::Ref *ref, js_type_class_t *typeClass, const char* debug);
|
2015-12-17 21:53:40 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* It will try to get the associated JSObjct for the native object.
|
|
|
|
* The reference created from JSObject to native object is weak because it won't retain it.
|
2016-07-03 23:42:10 +08:00
|
|
|
* The behavior is exactly the same with 'jsb_ref_create_jsobject' when CC_ENABLE_GC_FOR_NATIVE_OBJECTS deactivated.
|
2015-12-17 21:53:40 +08:00
|
|
|
*/
|
2015-12-21 11:07:40 +08:00
|
|
|
JSObject* jsb_create_weak_jsobject(JSContext *cx, void *native, js_type_class_t *typeClass, const char* debug);
|
2015-12-17 21:53:40 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* It will try to get the associated JSObjct for ref.
|
|
|
|
* If it can't find it, it will create a new one associating it to Ref.
|
|
|
|
* Call this function for objects that were already created and initialized, when returning `getChild()`
|
|
|
|
*/
|
2015-12-21 11:07:40 +08:00
|
|
|
JSObject* jsb_ref_get_or_create_jsobject(JSContext *cx, cocos2d::Ref *ref, js_type_class_t *typeClass, const char* debug);
|
2015-12-17 21:53:40 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* It will try to get the associated JSObjct for ref.
|
|
|
|
* If it can't find it, it will create a new one associating it to Ref
|
|
|
|
* Call this function for objects that might return an already existing copy when you create them. For example, `Animation3D::create()`;
|
|
|
|
*/
|
2016-12-21 13:39:34 +08:00
|
|
|
JSObject* jsb_ref_autoreleased_get_or_create_jsobject(JSContext *cx, cocos2d::Ref *ref, js_type_class_t *typeClass, const char* debug=nullptr);
|
2015-12-17 21:53:40 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* It will try to get the associated JSObjct for the native object.
|
|
|
|
* If it can't find it, it will create a new one associating it to the native object.
|
|
|
|
* The reference created from JSObject to native object is weak because it won't retain it.
|
2016-07-03 23:42:10 +08:00
|
|
|
* The behavior is exactly the same with 'jsb_ref_get_or_create_jsobject' when CC_ENABLE_GC_FOR_NATIVE_OBJECTS deactivated.
|
2015-12-17 21:53:40 +08:00
|
|
|
*/
|
2016-12-21 13:39:34 +08:00
|
|
|
CC_JS_DLL JSObject* jsb_get_or_create_weak_jsobject(JSContext *cx, void *native, js_type_class_t *typeClass, const char* debug=nullptr);
|
2015-12-05 10:42:31 +08:00
|
|
|
|
2015-12-04 07:40:52 +08:00
|
|
|
/**
|
2015-12-17 21:53:40 +08:00
|
|
|
* Register finalize hook and its owner as an entry in _js_hook_owner_map,
|
|
|
|
* so that we can find the owner of a FinalizeHook in its finalize function
|
2015-12-04 07:40:52 +08:00
|
|
|
*/
|
2015-12-17 21:53:40 +08:00
|
|
|
void jsb_register_finalize_hook(JSObject *hook, JSObject *owner);
|
2015-12-04 07:40:52 +08:00
|
|
|
|
2015-12-08 11:05:23 +08:00
|
|
|
/**
|
2015-12-17 21:53:40 +08:00
|
|
|
* Remove the entry of finalize hook and its owner in _js_hook_owner_map
|
2015-12-08 11:05:23 +08:00
|
|
|
*/
|
2015-12-17 21:53:40 +08:00
|
|
|
JSObject *jsb_get_and_remove_hook_owner(JSObject *hook);
|
2015-12-11 10:02:55 +08:00
|
|
|
|
2015-05-05 10:50:19 +08:00
|
|
|
#endif /* __SCRIPTING_CORE_H__ */
|