Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add worker for cocos native #16547

Open
wants to merge 7 commits into
base: v3.8.2
Choose a base branch
from
Open

Add worker for cocos native #16547

wants to merge 7 commits into from

Conversation

haroel
Copy link

@haroel haroel commented Nov 29, 2023

Re: #

Changelog

  • Add USE_WORKER and Macro CC_USE_WORKER ( default ON)
  • Add jsb_worker_maunal.cpp/jsb_worker_maunal.h and Worker.cpp/Worker.h
  • Modify jsb_module_register.cpp

简中说明

只支持v8引擎

支持特性

主线程Worker接口:

  • 支持 postMessage 发送数据
  • 支持 onmessage 和 onerror 监听Worker发出来的消息,注意onmessage的回调参数是一个对象,通过event.data可以获取到Worker发回来的数据值。
  • 支持terminate()关闭worker。
  • 和微信小游戏不同的是,我们支持同时创建多个Worker并行处理 。

Worker内部接口:

  • 支持 self 调用,支持 console.log/console.warn/console.error 日志打印接口。
  • 支持 self.onmessage 、self.postMessage、self.close 接口。
  • 支持importScripts。
  • Worker内部可以使用setInterval/setTimeout、clearInterval/clearTimeout计时器接口。
  • 额外扩展接口:
    • 设备可写目录路径 self.writablePath(等同于jsb.fileUtils.getWritablePath())。
    • 文件同步读取 self.readFileSync(filepath, "utf8" | "binary"); 返回字符串类型或Uint8Array类型(文件不存在则返回null)
    • 文件同步写入 self.writeFileSync(fullpath, data); 注意fullpath必须是在可写目录下面的全路径,否则无法写入,如果data是ArrayBuffer或类型数组,则按二进制保存,否则以字符串形式保存本地。

不支持特性

  • 不支持XMLHttpRequest (后续可以基于c++类XMLHttpRequest进行集成)。
  • 由于Worker线程和主游戏线程之间数据的序列化依赖的是JSON,所以请勿使用postMessage传输非JSON标准的数据字段,也不要传递类型化数组。

PS: 根据我的测试,额外开启一个空Worker约增加10M内存

English

v8 engine only

Supported Features

Main Thread Worker Interface:

  • Supports postMessage to send data
  • Supports onmessage and onerror to listen to messages sent by Worker. Note that the callback parameter of onmessage is an object, and the data value sent by Worker can be obtained through event.data.
  • Supports terminate() to close worker.
  • Unlike WeChat Mini Games, we support creating multiple Workers in parallel.

Worker Internal Interface:

  • Supports self calls, and supports console.log/console.warn/console.error log printing interfaces.
  • Supports self.onmessage, self.postMessage, and self.close interfaces.
  • Supports importScripts.
  • Workers can use setInterval/setTimeout, clearInterval/clearTimeout timer interfaces internally.
    Additional extended interfaces:
  • Device writable directory path self.writablePath (equivalent to jsb.fileUtils.getWritablePath()).
  • Synchronous file read self.readFileSync(filepath, "utf8" | "binary"); Returns string type or Uint8Array type (returns null if the file does not exist).
  • Synchronous file write self.writeFileSync(fullpath, data); Note that fullpath must be the full path under the writable directory, otherwise it cannot be written. If data is ArrayBuffer or typed array, it is saved in binary format, otherwise it is saved locally in string form.

Unsupported Features

  • Does not support XMLHttpRequest (can be integrated based on the C++ class XMLHttpRequest in the future).
  • Since the serialization of data between Worker thread and main game thread depends on JSON, do not use postMessage to transmit non-JSON standard data fields, and do not pass typed arrays.

PS: According to my test, opening an empty Worker will increase the memory usage by about 10M.

Copy link

Interface Check Report

This pull request does not change any public interfaces !

std::deque<std::string> messageQueue;
/**
* 发送信息到主线程
* type:0表示普通信息,1表示错误, 2 表示关闭
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's better to define a enum class {} for the type.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For example:

enum class MessageType {
    NORMAL,
    ERROR,
    CLOSE
};

#include <cocos/base/Macros.h>
#include <cocos/base/Log.h>
#include <cocos/platform/FileUtils.h>
#include <cocos/bindings/jswrapper/config.h>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use double quotes to include files in engine. And cocos prefix is not needed.

Suggested change
#include <cocos/bindings/jswrapper/config.h>
#include "bindings/jswrapper/config.h"

function createTimeoutInfo(prevFuncArgs,isRepeat){let cb=prevFuncArgs[0];if(!cb){console.error("createTimeoutInfo doesn't pass a callback ...");return 0;}
let delay=prevFuncArgs.length>1?prevFuncArgs[1]:0;let args;if(prevFuncArgs.length>2){args=Array.prototype.slice.call(prevFuncArgs,2);}
let info=new TimeInfo(cb,delay,isRepeat,root,args);scheduleDataModel.timeoutInfos.set(info.id,info);return info.id;}
root.setTimeout=function(cb){return createTimeoutInfo(arguments,false);};root.clearTimeout=function(id){scheduleDataModel.timeoutInfos.delete(id);};root.setInterval=function(cb){return createTimeoutInfo(arguments,true);};root.clearInterval=root.clearTimeout;root["$globalTick"]=function(nowMilliSeconds){handlerTimerInfos(nowMilliSeconds);}})(globalThis)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where does this code come from?
If there is a bug in this code, how could we fix it since it was minified.


namespace ccex {
namespace helper {
std::unordered_map<uintptr_t, Worker*> workers;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not just use v8::Isolate * as the map's key?

)";

namespace {
class WorkerImp {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the relationship between class Worker and class WorkerImp?

void setWeak(){
_weakCount.fetch_add(1);
if (_weakCount == 3) {
delete this;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why delete this only when the weak count is 3?

}
static void destroyAll();
public:
std::deque<std::string> messageQueue;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could messageQueue variable be private ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants