[engine] [cocos2d-x] [jsb-adapter] 适配引擎 v2.4.13 版本

This commit is contained in:
SmallMain 2024-10-16 16:23:25 +08:00
parent 7f956acda7
commit 887d4a96c9
No known key found for this signature in database
61 changed files with 1313 additions and 981 deletions

8
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,8 @@
{
"editor.formatOnSave": false,
"editor.codeActionsOnSave": {},
"[javascript][typescript][javascriptreact][typescriptreact]": {
"editor.formatOnSave": false,
"editor.codeActionsOnSave": {},
},
}

View File

@ -869,7 +869,7 @@ function(cc_apply_definations target)
target_compile_definitions(${target} PUBLIC
$<IF:$<BOOL:${CC_USE_GFX_RENDERER}>,USE_GFX_RENDERER=1,USE_GFX_RENDERER=0>
$<IF:$<BOOL:${CC_USE_VIDEO}>,USE_VIDEO=1,USE_VIDEO=0>
$<IF:$<BOOL:${CC_USE_WEBVIEW}>,USE_WEBVIEW=1,USE_WEBVIEW=0>
$<IF:$<BOOL:${CC_USE_WEBVIEW}>,USE_WEB_VIEW=1,USE_WEB_VIEW=0>
$<IF:$<BOOL:${CC_USE_AUDIO}>,USE_AUDIO=1,USE_AUDIO=0>
$<IF:$<BOOL:${CC_USE_SOCKET}>,USE_SOCKET=1,USE_SOCKET=0>
$<IF:$<BOOL:${CC_USE_WEBSOCKET_SERVER}>,USE_WEBSOCKET_SERVER=1,USE_WEBSOCKET_SERVER=0>

View File

@ -32,7 +32,7 @@ NS_CC_BEGIN
CC_DLL const char* cocos2dVersion()
{
return "2.4.12";
return "2.4.13";
}
NS_CC_END

View File

@ -34,7 +34,7 @@ DRAGONBONES_NAMESPACE_BEGIN
class CacheModeAttachUtil;
class CCArmatureCacheDisplay : public cocos2d::middleware::IMiddleware, public cocos2d::Ref
class CCArmatureCacheDisplay : public cocos2d::Ref, public cocos2d::middleware::IMiddleware
{
public:
CCArmatureCacheDisplay(const std::string& armatureName, const std::string& armatureKey, const std::string& atlasUUID, bool isShare);

View File

@ -106,7 +106,7 @@ enum EmitterMode
RADIUS = 1
};
class ParticleSimulator : public cocos2d::middleware::IMiddleware, public cocos2d::Ref {
class ParticleSimulator : public cocos2d::Ref, public cocos2d::middleware::IMiddleware {
//* @enum
enum {

View File

@ -130,6 +130,10 @@ SkeletonAnimation::SkeletonAnimation ()
}
SkeletonAnimation::~SkeletonAnimation () {
SkeletonAnimation::destroy();
}
void SkeletonAnimation::destroy() {
_startListener = nullptr;
_interruptListener = nullptr;
_endListener = nullptr;
@ -139,9 +143,12 @@ SkeletonAnimation::~SkeletonAnimation () {
if (_state) {
clearTracks();
if (_ownsAnimationStateData) delete _state->getData();
delete _state;
if (_ownsAnimationStateData) {
delete _state->getData();
}
CC_SAFE_DELETE(_state);
}
SkeletonRenderer::destroy();
}
void SkeletonAnimation::update (float deltaTime) {

View File

@ -92,6 +92,7 @@ public:
virtual void onAnimationStateEvent (TrackEntry* entry, EventType type, Event* event);
virtual void onTrackEntryEvent (TrackEntry* entry, EventType type, Event* event);
virtual void destroy();
AnimationState* getState() const;

View File

@ -76,7 +76,7 @@ namespace spine {
bool inEffect = false;
std::vector<TextureMultiData> textureDatas;
};
struct BoneData {
cocos2d::Mat4 globalTransformMatrix;
};

View File

@ -63,6 +63,11 @@ namespace spine {
}
SkeletonCacheAnimation::~SkeletonCacheAnimation () {
destroy();
}
void SkeletonCacheAnimation::destroy() {
stopSchedule();
if (_skeletonCache) {
_skeletonCache->release();
_skeletonCache = nullptr;
@ -73,9 +78,8 @@ namespace spine {
delete ani;
}
CC_SAFE_RELEASE_NULL(_attachUtil);
CC_SAFE_RELEASE(_nodeProxy);
CC_SAFE_RELEASE(_effect);
stopSchedule();
CC_SAFE_RELEASE_NULL(_nodeProxy);
CC_SAFE_RELEASE_NULL(_effect);
}
void SkeletonCacheAnimation::update(float dt) {
@ -207,13 +211,13 @@ namespace spine {
return multiSegments;
}
void SkeletonCacheAnimation::render(float dt) {
if (_useMulti) {
renderMulti(dt);
return;
}
if (!_nodeProxy || !_effect) {
return;
}
@ -826,7 +830,7 @@ namespace spine {
void SkeletonCacheAnimation::setUseMulti(bool enabled) {
_useMulti = enabled;
}
void SkeletonCacheAnimation::setAnimation (const std::string& name, bool loop) {
_playTimes = loop ? 0 : 1;
_animationName = name;

View File

@ -39,7 +39,7 @@ namespace spine {
class CacheModeAttachUtil;
class SkeletonCacheAnimation : public cocos2d::middleware::IMiddleware, public cocos2d::Ref {
class SkeletonCacheAnimation : public cocos2d::Ref, public cocos2d::middleware::IMiddleware {
public:
SkeletonCacheAnimation (const std::string& uuid, bool isShare);
virtual ~SkeletonCacheAnimation ();
@ -47,7 +47,7 @@ namespace spine {
virtual void update(float dt) override;
virtual void render(float dt) override;
virtual uint32_t getRenderOrder() const override;
void renderMulti(float dt);
std::vector<spine::SkeletonCache::SegmentMultiData> toMultiSegments(
const std::vector<spine::SkeletonCache::SegmentData*>& segments);
@ -83,7 +83,7 @@ namespace spine {
void onDisable();
void setUseTint(bool enabled);
void setUseMulti(bool enabled);
void setAnimation (const std::string& name, bool loop);
void addAnimation (const std::string& name, bool loop, float delay = 0);
Animation* findAnimation(const std::string& name) const;
@ -98,6 +98,7 @@ namespace spine {
void setToSetupPose ();
void setBonesToSetupPose ();
void setSlotsToSetupPose ();
void destroy();
private:
float _timeScale = 1;
bool _paused = false;
@ -124,7 +125,7 @@ namespace spine {
std::string _animationName = "";
bool _useTint = false;
bool _useMulti = false;
struct AniQueueData {
std::string animationName = "";
bool loop = false;

View File

@ -151,23 +151,37 @@ SkeletonRenderer::SkeletonRenderer (const std::string& skeletonDataFile, const s
}
SkeletonRenderer::~SkeletonRenderer () {
CC_SAFE_RELEASE(_effectDelegate);
if (_ownsSkeletonData) delete _skeleton->getData();
if (_ownsSkeleton) delete _skeleton;
if (_ownsAtlas && _atlas) delete _atlas;
if (_attachmentLoader) delete _attachmentLoader;
if (_uuid != "") SkeletonDataMgr::getInstance()->releaseByUUID(_uuid);
if (_clipper) delete _clipper;
if (_debugBuffer) {
delete _debugBuffer;
_debugBuffer = nullptr;
}
CC_SAFE_RELEASE(_attachUtil);
CC_SAFE_RELEASE(_nodeProxy);
CC_SAFE_RELEASE(_effect);
SkeletonRenderer::destroy();
}
void SkeletonRenderer::destroy() {
stopSchedule();
CC_SAFE_RELEASE_NULL(_effectDelegate);
if (_ownsSkeletonData) {
if (_skeleton) {
delete _skeleton->getData();
}
_ownsSkeletonData = false;
}
if (_ownsSkeleton) {
CC_SAFE_DELETE(_skeleton);
}
if (_ownsAtlas && _atlas) {
CC_SAFE_DELETE(_atlas);
}
_skeleton = nullptr;
_atlas = nullptr;
CC_SAFE_DELETE(_attachmentLoader);
if (_uuid != "") {
SkeletonDataMgr::getInstance()->releaseByUUID(_uuid);
_uuid = "";
}
CC_SAFE_DELETE(_clipper);
CC_SAFE_DELETE(_debugBuffer);
CC_SAFE_RELEASE_NULL(_attachUtil);
CC_SAFE_RELEASE_NULL(_nodeProxy);
CC_SAFE_RELEASE_NULL(_effect);
}
void SkeletonRenderer::initWithUUID(const std::string& uuid) {
@ -298,7 +312,7 @@ void SkeletonRenderer::render (float deltaTime) {
// vertex size int bytes with one color
int vbs1 = _useMulti ? sizeof(V2F_T2F_C4B_T1F) : sizeof(V2F_T2F_C4B);
// vertex size in floats with one color
// vertex size in floats with one color
int vs1 = vbs1 / sizeof(float);
// vertex size int bytes with two color
int vbs2 = _useMulti ? sizeof(V2F_T2F_C4B_C4B_T1F) :sizeof(V2F_T2F_C4B_C4B);
@ -315,11 +329,11 @@ void SkeletonRenderer::render (float deltaTime) {
int preBlendMode = -1;
GLuint preTextureIndex = -1;
GLuint curTextureIndex = -1;
float curTextureId = -1;
bool texInEffect = false;
int preISegWritePos = -1;
int preISegWritePos = -1;
int curISegLen = 0;
int materialLen = 0;
@ -361,7 +375,7 @@ void SkeletonRenderer::render (float deltaTime) {
curBlendSrc = _premultipliedAlpha ? BlendFactor::ONE : BlendFactor::SRC_ALPHA;
curBlendDst = BlendFactor::ONE_MINUS_SRC_ALPHA;
}
double curHash =
(_useMulti && texInEffect)
? ((curBlendMode << 16) + ((int)_useTint << 24) +
@ -470,34 +484,34 @@ void SkeletonRenderer::render (float deltaTime) {
}
if (!_useMulti) {
if (!_useTint) {
triangles.vertCount = attachmentVertices->_triangles->vertCount;
vbSize = triangles.vertCount * sizeof(V2F_T2F_C4B);
isFull |= vb.checkSpace(vbSize, true);
triangles.verts = (V2F_T2F_C4B*)vb.getCurBuffer();
memcpy(triangles.verts, attachmentVertices->_triangles->verts, vbSize);
attachment->computeWorldVertices(slot->getBone(), (float*)triangles.verts, 0, vs1);
if (!_useTint) {
triangles.vertCount = attachmentVertices->_triangles->vertCount;
vbSize = triangles.vertCount * sizeof(V2F_T2F_C4B);
isFull |= vb.checkSpace(vbSize, true);
triangles.verts = (V2F_T2F_C4B*)vb.getCurBuffer();
memcpy(triangles.verts, attachmentVertices->_triangles->verts, vbSize);
attachment->computeWorldVertices(slot->getBone(), (float*)triangles.verts, 0, vs1);
triangles.indexCount = attachmentVertices->_triangles->indexCount;
ibSize = triangles.indexCount * sizeof(unsigned short);
ib.checkSpace(ibSize, true);
triangles.indices = (unsigned short*)ib.getCurBuffer();
memcpy(triangles.indices, attachmentVertices->_triangles->indices, ibSize);
} else {
trianglesTwoColor.vertCount = attachmentVertices->_triangles->vertCount;
vbSize = trianglesTwoColor.vertCount * sizeof(V2F_T2F_C4B_C4B);
isFull |= vb.checkSpace(vbSize, true);
trianglesTwoColor.verts = (V2F_T2F_C4B_C4B*)vb.getCurBuffer();
for (int ii = 0; ii < trianglesTwoColor.vertCount; ii++) {
trianglesTwoColor.verts[ii].texCoord = attachmentVertices->_triangles->verts[ii].texCoord;
}
attachment->computeWorldVertices(slot->getBone(), (float*)trianglesTwoColor.verts, 0, vs2);
trianglesTwoColor.indexCount = attachmentVertices->_triangles->indexCount;
ibSize = trianglesTwoColor.indexCount * sizeof(unsigned short);
ib.checkSpace(ibSize, true);
trianglesTwoColor.indices = (unsigned short*)ib.getCurBuffer();
memcpy(trianglesTwoColor.indices, attachmentVertices->_triangles->indices, ibSize);
triangles.indexCount = attachmentVertices->_triangles->indexCount;
ibSize = triangles.indexCount * sizeof(unsigned short);
ib.checkSpace(ibSize, true);
triangles.indices = (unsigned short*)ib.getCurBuffer();
memcpy(triangles.indices, attachmentVertices->_triangles->indices, ibSize);
} else {
trianglesTwoColor.vertCount = attachmentVertices->_triangles->vertCount;
vbSize = trianglesTwoColor.vertCount * sizeof(V2F_T2F_C4B_C4B);
isFull |= vb.checkSpace(vbSize, true);
trianglesTwoColor.verts = (V2F_T2F_C4B_C4B*)vb.getCurBuffer();
for (int ii = 0; ii < trianglesTwoColor.vertCount; ii++) {
trianglesTwoColor.verts[ii].texCoord = attachmentVertices->_triangles->verts[ii].texCoord;
}
attachment->computeWorldVertices(slot->getBone(), (float*)trianglesTwoColor.verts, 0, vs2);
trianglesTwoColor.indexCount = attachmentVertices->_triangles->indexCount;
ibSize = trianglesTwoColor.indexCount * sizeof(unsigned short);
ib.checkSpace(ibSize, true);
trianglesTwoColor.indices = (unsigned short*)ib.getCurBuffer();
memcpy(trianglesTwoColor.indices, attachmentVertices->_triangles->indices, ibSize);
}
} else {
if (!_useTint) {
@ -565,34 +579,34 @@ void SkeletonRenderer::render (float deltaTime) {
}
if (!_useMulti) {
if (!_useTint) {
triangles.vertCount = attachmentVertices->_triangles->vertCount;
vbSize = triangles.vertCount * sizeof(V2F_T2F_C4B);
isFull |= vb.checkSpace(vbSize, true);
triangles.verts = (V2F_T2F_C4B*)vb.getCurBuffer();
memcpy(triangles.verts, attachmentVertices->_triangles->verts, vbSize);
attachment->computeWorldVertices(*slot, 0, attachment->getWorldVerticesLength(), (float*)triangles.verts, 0, vs1);
if (!_useTint) {
triangles.vertCount = attachmentVertices->_triangles->vertCount;
vbSize = triangles.vertCount * sizeof(V2F_T2F_C4B);
isFull |= vb.checkSpace(vbSize, true);
triangles.verts = (V2F_T2F_C4B*)vb.getCurBuffer();
memcpy(triangles.verts, attachmentVertices->_triangles->verts, vbSize);
attachment->computeWorldVertices(*slot, 0, attachment->getWorldVerticesLength(), (float*)triangles.verts, 0, vs1);
triangles.indexCount = attachmentVertices->_triangles->indexCount;
ibSize = triangles.indexCount * sizeof(unsigned short);
ib.checkSpace(ibSize, true);
triangles.indices = (unsigned short*)ib.getCurBuffer();
memcpy(triangles.indices, attachmentVertices->_triangles->indices, ibSize);
} else {
trianglesTwoColor.vertCount = attachmentVertices->_triangles->vertCount;
vbSize = trianglesTwoColor.vertCount * sizeof(V2F_T2F_C4B_C4B);
isFull |= vb.checkSpace(vbSize, true);
trianglesTwoColor.verts = (V2F_T2F_C4B_C4B*)vb.getCurBuffer();
for (int ii = 0; ii < trianglesTwoColor.vertCount; ii++) {
trianglesTwoColor.verts[ii].texCoord = attachmentVertices->_triangles->verts[ii].texCoord;
}
attachment->computeWorldVertices(*slot, 0, attachment->getWorldVerticesLength(), (float*)trianglesTwoColor.verts, 0, vs2);
trianglesTwoColor.indexCount = attachmentVertices->_triangles->indexCount;
ibSize = trianglesTwoColor.indexCount * sizeof(unsigned short);
ib.checkSpace(ibSize, true);
trianglesTwoColor.indices = (unsigned short*)ib.getCurBuffer();
memcpy(trianglesTwoColor.indices, attachmentVertices->_triangles->indices, ibSize);
triangles.indexCount = attachmentVertices->_triangles->indexCount;
ibSize = triangles.indexCount * sizeof(unsigned short);
ib.checkSpace(ibSize, true);
triangles.indices = (unsigned short*)ib.getCurBuffer();
memcpy(triangles.indices, attachmentVertices->_triangles->indices, ibSize);
} else {
trianglesTwoColor.vertCount = attachmentVertices->_triangles->vertCount;
vbSize = trianglesTwoColor.vertCount * sizeof(V2F_T2F_C4B_C4B);
isFull |= vb.checkSpace(vbSize, true);
trianglesTwoColor.verts = (V2F_T2F_C4B_C4B*)vb.getCurBuffer();
for (int ii = 0; ii < trianglesTwoColor.vertCount; ii++) {
trianglesTwoColor.verts[ii].texCoord = attachmentVertices->_triangles->verts[ii].texCoord;
}
attachment->computeWorldVertices(*slot, 0, attachment->getWorldVerticesLength(), (float*)trianglesTwoColor.verts, 0, vs2);
trianglesTwoColor.indexCount = attachmentVertices->_triangles->indexCount;
ibSize = trianglesTwoColor.indexCount * sizeof(unsigned short);
ib.checkSpace(ibSize, true);
trianglesTwoColor.indices = (unsigned short*)ib.getCurBuffer();
memcpy(trianglesTwoColor.indices, attachmentVertices->_triangles->indices, ibSize);
}
} else {
if (!_useTint) {
@ -650,7 +664,7 @@ void SkeletonRenderer::render (float deltaTime) {
: (float*)trianglesTexId.verts)
: (_useTint ? (float*)trianglesTwoColor.verts
: (float*)triangles.verts);
int stride = _useTint ? vs2 : vs1;
_debugBuffer->writeFloat32(DebugType::Mesh);
_debugBuffer->writeFloat32(indexCount * 2);
@ -702,217 +716,217 @@ void SkeletonRenderer::render (float deltaTime) {
darkColor.b = 0;
}
darkColor.a = _premultipliedAlpha ? 255 : 0;
if (!_useMulti) {
// One color tint logic
if (!_useTint) {
// Cliping logic
if (_clipper->isClipping()) {
_clipper->clipTriangles((float*)&triangles.verts[0].vertex, triangles.indices, triangles.indexCount, (float*)&triangles.verts[0].texCoord, vs1);
if (_clipper->getClippedTriangles().size() == 0) {
_clipper->clipEnd(*slot);
continue;
// One color tint logic
if (!_useTint) {
// Cliping logic
if (_clipper->isClipping()) {
_clipper->clipTriangles((float*)&triangles.verts[0].vertex, triangles.indices, triangles.indexCount, (float*)&triangles.verts[0].texCoord, vs1);
if (_clipper->getClippedTriangles().size() == 0) {
_clipper->clipEnd(*slot);
continue;
}
triangles.vertCount = (int)_clipper->getClippedVertices().size() >> 1;
vbSize = triangles.vertCount * sizeof(V2F_T2F_C4B);
isFull |= vb.checkSpace(vbSize, true);
triangles.verts = (V2F_T2F_C4B*)vb.getCurBuffer();
triangles.indexCount = (int)_clipper->getClippedTriangles().size();
ibSize = triangles.indexCount * sizeof(unsigned short);
ib.checkSpace(ibSize, true);
triangles.indices = (unsigned short*)ib.getCurBuffer();
memcpy(triangles.indices, _clipper->getClippedTriangles().buffer(), sizeof(unsigned short) * _clipper->getClippedTriangles().size());
float* verts = _clipper->getClippedVertices().buffer();
float* uvs = _clipper->getClippedUVs().buffer();
if (effect) {
Color light;
Color dark;
light.r = color.r / 255.0f;
light.g = color.g / 255.0f;
light.b = color.b / 255.0f;
light.a = color.a / 255.0f;
dark.r = dark.g = dark.b = dark.a = 0;
for (int v = 0, vn = triangles.vertCount, vv = 0; v < vn; ++v, vv+=2) {
V2F_T2F_C4B* vertex = triangles.verts + v;
Color lightCopy = light;
Color darkCopy = dark;
vertex->vertex.x = verts[vv];
vertex->vertex.y = verts[vv + 1];
vertex->texCoord.u = uvs[vv];
vertex->texCoord.v = uvs[vv + 1];
effect->transform(vertex->vertex.x, vertex->vertex.y, vertex->texCoord.u, vertex->texCoord.v, lightCopy, darkCopy);
vertex->color.r = (GLubyte)(lightCopy.r * 255);
vertex->color.g = (GLubyte)(lightCopy.g * 255);
vertex->color.b = (GLubyte)(lightCopy.b * 255);
vertex->color.a = (GLubyte)(lightCopy.a * 255);
}
triangles.vertCount = (int)_clipper->getClippedVertices().size() >> 1;
vbSize = triangles.vertCount * sizeof(V2F_T2F_C4B);
isFull |= vb.checkSpace(vbSize, true);
triangles.verts = (V2F_T2F_C4B*)vb.getCurBuffer();
triangles.indexCount = (int)_clipper->getClippedTriangles().size();
ibSize = triangles.indexCount * sizeof(unsigned short);
ib.checkSpace(ibSize, true);
triangles.indices = (unsigned short*)ib.getCurBuffer();
memcpy(triangles.indices, _clipper->getClippedTriangles().buffer(), sizeof(unsigned short) * _clipper->getClippedTriangles().size());
float* verts = _clipper->getClippedVertices().buffer();
float* uvs = _clipper->getClippedUVs().buffer();
if (effect) {
Color light;
Color dark;
light.r = color.r / 255.0f;
light.g = color.g / 255.0f;
light.b = color.b / 255.0f;
light.a = color.a / 255.0f;
dark.r = dark.g = dark.b = dark.a = 0;
for (int v = 0, vn = triangles.vertCount, vv = 0; v < vn; ++v, vv+=2) {
V2F_T2F_C4B* vertex = triangles.verts + v;
Color lightCopy = light;
Color darkCopy = dark;
vertex->vertex.x = verts[vv];
vertex->vertex.y = verts[vv + 1];
vertex->texCoord.u = uvs[vv];
vertex->texCoord.v = uvs[vv + 1];
effect->transform(vertex->vertex.x, vertex->vertex.y, vertex->texCoord.u, vertex->texCoord.v, lightCopy, darkCopy);
vertex->color.r = (GLubyte)(lightCopy.r * 255);
vertex->color.g = (GLubyte)(lightCopy.g * 255);
vertex->color.b = (GLubyte)(lightCopy.b * 255);
vertex->color.a = (GLubyte)(lightCopy.a * 255);
}
} else {
for (int v = 0, vn = triangles.vertCount, vv = 0; v < vn; ++v, vv+=2) {
V2F_T2F_C4B* vertex = triangles.verts + v;
vertex->vertex.x = verts[vv];
vertex->vertex.y = verts[vv + 1];
vertex->texCoord.u = uvs[vv];
vertex->texCoord.v = uvs[vv + 1];
vertex->color.r = (GLubyte)color.r;
vertex->color.g = (GLubyte)color.g;
vertex->color.b = (GLubyte)color.b;
vertex->color.a = (GLubyte)color.a;
}
}
// No cliping logic
} else {
if (effect) {
Color light;
Color dark;
light.r = color.r / 255.0f;
light.g = color.g / 255.0f;
light.b = color.b / 255.0f;
light.a = color.a / 255.0f;
dark.r = dark.g = dark.b = dark.a = 0;
for (int v = 0, vn = triangles.vertCount; v < vn; ++v) {
V2F_T2F_C4B* vertex = triangles.verts + v;
Color lightCopy = light;
Color darkCopy = dark;
effect->transform(vertex->vertex.x, vertex->vertex.y, vertex->texCoord.u, vertex->texCoord.v, lightCopy, darkCopy);
vertex->color.r = (GLubyte)(lightCopy.r * 255);
vertex->color.g = (GLubyte)(lightCopy.g * 255);
vertex->color.b = (GLubyte)(lightCopy.b * 255);
vertex->color.a = (GLubyte)(lightCopy.a * 255);
}
} else {
for (int v = 0, vn = triangles.vertCount; v < vn; ++v) {
V2F_T2F_C4B* vertex = triangles.verts + v;
vertex->color.r = (GLubyte)color.r;
vertex->color.g = (GLubyte)color.g;
vertex->color.b = (GLubyte)color.b;
vertex->color.a = (GLubyte)color.a;
}
for (int v = 0, vn = triangles.vertCount, vv = 0; v < vn; ++v, vv+=2) {
V2F_T2F_C4B* vertex = triangles.verts + v;
vertex->vertex.x = verts[vv];
vertex->vertex.y = verts[vv + 1];
vertex->texCoord.u = uvs[vv];
vertex->texCoord.v = uvs[vv + 1];
vertex->color.r = (GLubyte)color.r;
vertex->color.g = (GLubyte)color.g;
vertex->color.b = (GLubyte)color.b;
vertex->color.a = (GLubyte)color.a;
}
}
// No cliping logic
} else {
if (effect) {
Color light;
Color dark;
light.r = color.r / 255.0f;
light.g = color.g / 255.0f;
light.b = color.b / 255.0f;
light.a = color.a / 255.0f;
dark.r = dark.g = dark.b = dark.a = 0;
for (int v = 0, vn = triangles.vertCount; v < vn; ++v) {
V2F_T2F_C4B* vertex = triangles.verts + v;
Color lightCopy = light;
Color darkCopy = dark;
effect->transform(vertex->vertex.x, vertex->vertex.y, vertex->texCoord.u, vertex->texCoord.v, lightCopy, darkCopy);
vertex->color.r = (GLubyte)(lightCopy.r * 255);
vertex->color.g = (GLubyte)(lightCopy.g * 255);
vertex->color.b = (GLubyte)(lightCopy.b * 255);
vertex->color.a = (GLubyte)(lightCopy.a * 255);
}
} else {
for (int v = 0, vn = triangles.vertCount; v < vn; ++v) {
V2F_T2F_C4B* vertex = triangles.verts + v;
vertex->color.r = (GLubyte)color.r;
vertex->color.g = (GLubyte)color.g;
vertex->color.b = (GLubyte)color.b;
vertex->color.a = (GLubyte)color.a;
}
}
}
// Two color tint logic
else {
if (_clipper->isClipping()) {
_clipper->clipTriangles((float*)&trianglesTwoColor.verts[0].vertex, trianglesTwoColor.indices, trianglesTwoColor.indexCount, (float*)&trianglesTwoColor.verts[0].texCoord, vs2);
if (_clipper->getClippedTriangles().size() == 0) {
_clipper->clipEnd(*slot);
continue;
}
trianglesTwoColor.vertCount = (int)_clipper->getClippedVertices().size() >> 1;
vbSize = trianglesTwoColor.vertCount * sizeof(V2F_T2F_C4B_C4B);
isFull |= vb.checkSpace(vbSize, true);
trianglesTwoColor.verts = (V2F_T2F_C4B_C4B*)vb.getCurBuffer();
trianglesTwoColor.indexCount = (int)_clipper->getClippedTriangles().size();
ibSize = trianglesTwoColor.indexCount * sizeof(unsigned short);
trianglesTwoColor.indices = (unsigned short*)ib.getCurBuffer();
memcpy(trianglesTwoColor.indices, _clipper->getClippedTriangles().buffer(), sizeof(unsigned short) * _clipper->getClippedTriangles().size());
float* verts = _clipper->getClippedVertices().buffer();
float* uvs = _clipper->getClippedUVs().buffer();
if (effect) {
Color light;
Color dark;
light.r = color.r / 255.0f;
light.g = color.g / 255.0f;
light.b = color.b / 255.0f;
light.a = color.a / 255.0f;
dark.r = darkColor.r / 255.0f;
dark.g = darkColor.g / 255.0f;
dark.b = darkColor.b / 255.0f;
dark.a = darkColor.a / 255.0f;
for (int v = 0, vn = trianglesTwoColor.vertCount, vv = 0; v < vn; ++v, vv += 2) {
V2F_T2F_C4B_C4B* vertex = trianglesTwoColor.verts + v;
Color lightCopy = light;
Color darkCopy = dark;
vertex->vertex.x = verts[vv];
vertex->vertex.y = verts[vv + 1];
vertex->texCoord.u = uvs[vv];
vertex->texCoord.v = uvs[vv + 1];
effect->transform(vertex->vertex.x, vertex->vertex.y, vertex->texCoord.u, vertex->texCoord.v, lightCopy, darkCopy);
vertex->color.r = (GLubyte)(lightCopy.r * 255);
vertex->color.g = (GLubyte)(lightCopy.g * 255);
vertex->color.b = (GLubyte)(lightCopy.b * 255);
vertex->color.a = (GLubyte)(lightCopy.a * 255);
vertex->color2.r = (GLubyte)(darkCopy.r * 255);
vertex->color2.g = (GLubyte)(darkCopy.g * 255);
vertex->color2.b = (GLubyte)(darkCopy.b * 255);
vertex->color2.a = (GLubyte)darkColor.a;
}
} else {
for (int v = 0, vn = trianglesTwoColor.vertCount, vv = 0; v < vn; ++v, vv += 2) {
V2F_T2F_C4B_C4B* vertex = trianglesTwoColor.verts + v;
vertex->vertex.x = verts[vv];
vertex->vertex.y = verts[vv + 1];
vertex->texCoord.u = uvs[vv];
vertex->texCoord.v = uvs[vv + 1];
vertex->color.r = (GLubyte)color.r;
vertex->color.g = (GLubyte)color.g;
vertex->color.b = (GLubyte)color.b;
vertex->color.a = (GLubyte)color.a;
vertex->color2.r = (GLubyte)darkColor.r;
vertex->color2.g = (GLubyte)darkColor.g;
vertex->color2.b = (GLubyte)darkColor.b;
vertex->color2.a = (GLubyte)darkColor.a;
}
}
// Two color tint logic
else {
if (_clipper->isClipping()) {
_clipper->clipTriangles((float*)&trianglesTwoColor.verts[0].vertex, trianglesTwoColor.indices, trianglesTwoColor.indexCount, (float*)&trianglesTwoColor.verts[0].texCoord, vs2);
if (_clipper->getClippedTriangles().size() == 0) {
_clipper->clipEnd(*slot);
continue;
}
trianglesTwoColor.vertCount = (int)_clipper->getClippedVertices().size() >> 1;
vbSize = trianglesTwoColor.vertCount * sizeof(V2F_T2F_C4B_C4B);
isFull |= vb.checkSpace(vbSize, true);
trianglesTwoColor.verts = (V2F_T2F_C4B_C4B*)vb.getCurBuffer();
trianglesTwoColor.indexCount = (int)_clipper->getClippedTriangles().size();
ibSize = trianglesTwoColor.indexCount * sizeof(unsigned short);
trianglesTwoColor.indices = (unsigned short*)ib.getCurBuffer();
memcpy(trianglesTwoColor.indices, _clipper->getClippedTriangles().buffer(), sizeof(unsigned short) * _clipper->getClippedTriangles().size());
float* verts = _clipper->getClippedVertices().buffer();
float* uvs = _clipper->getClippedUVs().buffer();
if (effect) {
Color light;
Color dark;
light.r = color.r / 255.0f;
light.g = color.g / 255.0f;
light.b = color.b / 255.0f;
light.a = color.a / 255.0f;
dark.r = darkColor.r / 255.0f;
dark.g = darkColor.g / 255.0f;
dark.b = darkColor.b / 255.0f;
dark.a = darkColor.a / 255.0f;
for (int v = 0, vn = trianglesTwoColor.vertCount, vv = 0; v < vn; ++v, vv += 2) {
V2F_T2F_C4B_C4B* vertex = trianglesTwoColor.verts + v;
Color lightCopy = light;
Color darkCopy = dark;
vertex->vertex.x = verts[vv];
vertex->vertex.y = verts[vv + 1];
vertex->texCoord.u = uvs[vv];
vertex->texCoord.v = uvs[vv + 1];
effect->transform(vertex->vertex.x, vertex->vertex.y, vertex->texCoord.u, vertex->texCoord.v, lightCopy, darkCopy);
vertex->color.r = (GLubyte)(lightCopy.r * 255);
vertex->color.g = (GLubyte)(lightCopy.g * 255);
vertex->color.b = (GLubyte)(lightCopy.b * 255);
vertex->color.a = (GLubyte)(lightCopy.a * 255);
vertex->color2.r = (GLubyte)(darkCopy.r * 255);
vertex->color2.g = (GLubyte)(darkCopy.g * 255);
vertex->color2.b = (GLubyte)(darkCopy.b * 255);
vertex->color2.a = (GLubyte)darkColor.a;
}
} else {
if (effect) {
Color light;
Color dark;
light.r = color.r / 255.0f;
light.g = color.g / 255.0f;
light.b = color.b / 255.0f;
light.a = color.a / 255.0f;
dark.r = darkColor.r / 255.0f;
dark.g = darkColor.g / 255.0f;
dark.b = darkColor.b / 255.0f;
dark.a = darkColor.a / 255.0f;
for (int v = 0, vn = trianglesTwoColor.vertCount; v < vn; ++v) {
V2F_T2F_C4B_C4B* vertex = trianglesTwoColor.verts + v;
Color lightCopy = light;
Color darkCopy = dark;
effect->transform(vertex->vertex.x, vertex->vertex.y, vertex->texCoord.u, vertex->texCoord.v, lightCopy, darkCopy);
vertex->color.r = (GLubyte)(lightCopy.r * 255);
vertex->color.g = (GLubyte)(lightCopy.g * 255);
vertex->color.b = (GLubyte)(lightCopy.b * 255);
vertex->color.a = (GLubyte)(lightCopy.a * 255);
vertex->color2.r = (GLubyte)(darkCopy.r * 255);
vertex->color2.g = (GLubyte)(darkCopy.g * 255);
vertex->color2.b = (GLubyte)(darkCopy.b * 255);
vertex->color2.a = (GLubyte)darkColor.a;
}
} else {
for (int v = 0, vn = trianglesTwoColor.vertCount; v < vn; ++v) {
V2F_T2F_C4B_C4B* vertex = trianglesTwoColor.verts + v;
vertex->color.r = (GLubyte)color.r;
vertex->color.g = (GLubyte)color.g;
vertex->color.b = (GLubyte)color.b;
vertex->color.a = (GLubyte)color.a;
vertex->color2.r = (GLubyte)darkColor.r;
vertex->color2.g = (GLubyte)darkColor.g;
vertex->color2.b = (GLubyte)darkColor.b;
vertex->color2.a = (GLubyte)darkColor.a;
}
for (int v = 0, vn = trianglesTwoColor.vertCount, vv = 0; v < vn; ++v, vv += 2) {
V2F_T2F_C4B_C4B* vertex = trianglesTwoColor.verts + v;
vertex->vertex.x = verts[vv];
vertex->vertex.y = verts[vv + 1];
vertex->texCoord.u = uvs[vv];
vertex->texCoord.v = uvs[vv + 1];
vertex->color.r = (GLubyte)color.r;
vertex->color.g = (GLubyte)color.g;
vertex->color.b = (GLubyte)color.b;
vertex->color.a = (GLubyte)color.a;
vertex->color2.r = (GLubyte)darkColor.r;
vertex->color2.g = (GLubyte)darkColor.g;
vertex->color2.b = (GLubyte)darkColor.b;
vertex->color2.a = (GLubyte)darkColor.a;
}
}
} else {
if (effect) {
Color light;
Color dark;
light.r = color.r / 255.0f;
light.g = color.g / 255.0f;
light.b = color.b / 255.0f;
light.a = color.a / 255.0f;
dark.r = darkColor.r / 255.0f;
dark.g = darkColor.g / 255.0f;
dark.b = darkColor.b / 255.0f;
dark.a = darkColor.a / 255.0f;
for (int v = 0, vn = trianglesTwoColor.vertCount; v < vn; ++v) {
V2F_T2F_C4B_C4B* vertex = trianglesTwoColor.verts + v;
Color lightCopy = light;
Color darkCopy = dark;
effect->transform(vertex->vertex.x, vertex->vertex.y, vertex->texCoord.u, vertex->texCoord.v, lightCopy, darkCopy);
vertex->color.r = (GLubyte)(lightCopy.r * 255);
vertex->color.g = (GLubyte)(lightCopy.g * 255);
vertex->color.b = (GLubyte)(lightCopy.b * 255);
vertex->color.a = (GLubyte)(lightCopy.a * 255);
vertex->color2.r = (GLubyte)(darkCopy.r * 255);
vertex->color2.g = (GLubyte)(darkCopy.g * 255);
vertex->color2.b = (GLubyte)(darkCopy.b * 255);
vertex->color2.a = (GLubyte)darkColor.a;
}
} else {
for (int v = 0, vn = trianglesTwoColor.vertCount; v < vn; ++v) {
V2F_T2F_C4B_C4B* vertex = trianglesTwoColor.verts + v;
vertex->color.r = (GLubyte)color.r;
vertex->color.g = (GLubyte)color.g;
vertex->color.b = (GLubyte)color.b;
vertex->color.a = (GLubyte)color.a;
vertex->color2.r = (GLubyte)darkColor.r;
vertex->color2.g = (GLubyte)darkColor.g;
vertex->color2.b = (GLubyte)darkColor.b;
vertex->color2.a = (GLubyte)darkColor.a;
}
}
}
texture = attachmentVertices->_texture;
}
texture = attachmentVertices->_texture;
curTextureIndex =
attachmentVertices->_texture->getNativeTexture()->getHandle();
// If texture or blendMode change,will change material.
// If texture or blendMode change,will change material.
if (preTextureIndex != curTextureIndex ||
preBlendMode != slot->getData().getBlendMode() || isFull) {
flush();
flush();
}
}
else {

View File

@ -50,7 +50,7 @@ namespace spine {
/** Draws a skeleton.
*/
class SkeletonRenderer: public cocos2d::middleware::IMiddleware, public cocos2d::Ref {
class SkeletonRenderer: public cocos2d::Ref, public cocos2d::middleware::IMiddleware {
public:
static SkeletonRenderer* create ();
static SkeletonRenderer* createWithSkeleton(Skeleton* skeleton, bool ownsSkeleton = false, bool ownsSkeletonData = false);
@ -99,7 +99,7 @@ namespace spine {
void setUseTint(bool enabled);
void setUseMulti(bool enabled);
/* Sets the vertex effect to be used, set to 0 to disable vertex effects */
void setVertexEffectDelegate(VertexEffectDelegate* effectDelegate);
/* Sets the range of slots that should be rendered. Use -1, -1 to clear the range */
@ -126,6 +126,7 @@ namespace spine {
virtual void stopSchedule();
void onEnable();
void onDisable();
virtual void destroy();
CC_CONSTRUCTOR_ACCESS:
SkeletonRenderer ();

View File

@ -273,19 +273,31 @@ void OpenHarmonyPlatform::onSurfaceChanged(OH_NativeXComponent* component, void*
void OpenHarmonyPlatform::onSurfaceDestroyed(OH_NativeXComponent* component, void* window) {
}
void OpenHarmonyPlatform::tick() {
static std::chrono::steady_clock::time_point prevTime;
static std::chrono::steady_clock::time_point now;
static float dt = 0.f;
static float dtSum = 0.f;
static uint32_t jsbInvocationTotalCount = 0;
static uint32_t jsbInvocationTotalFrames = 0;
std::shared_ptr<Scheduler> scheduler = g_app->getScheduler();
scheduler->update(dt);
EventDispatcher::dispatchTickEvent(dt);
PoolManager::getInstance()->getCurrentPool()->clear();
now = std::chrono::steady_clock::now();
dt = std::chrono::duration_cast<std::chrono::microseconds>(now - prevTime).count() / 1000000.f;
prevTime = std::chrono::steady_clock::now();
void OpenHarmonyPlatform::setPreferedFramePersecond(int fps) {
if (fps == 0) {
return;
}
_prefererredNanosecondsPerFrame = static_cast<long>(1.0 / fps * NANOSECONDS_PER_SECOND); // NOLINT(google-runtime-int)
}
void OpenHarmonyPlatform::tick() {
static std::chrono::steady_clock::time_point prevTime;
static std::chrono::steady_clock::time_point now;
static float dt = 0.f;
static double dtNS = NANOSECONDS_60FPS;
if (dtNS < static_cast<double>(_prefererredNanosecondsPerFrame)) {
std::this_thread::sleep_for(std::chrono::nanoseconds(
_prefererredNanosecondsPerFrame - static_cast<int64_t>(dtNS)));
dtNS = static_cast<double>(_prefererredNanosecondsPerFrame);
}
prevTime = std::chrono::steady_clock::now();
std::shared_ptr<Scheduler> scheduler = g_app->getScheduler();
scheduler->update(dt);
EventDispatcher::dispatchTickEvent(dt);
PoolManager::getInstance()->getCurrentPool()->clear();
now = std::chrono::steady_clock::now();
dtNS = dtNS * 0.1 + 0.9 * static_cast<double>(std::chrono::duration_cast<std::chrono::nanoseconds>(now - prevTime).count());
dt = static_cast<float>(dtNS) / NANOSECONDS_PER_SECOND;
}
}; // namespace cc

View File

@ -78,7 +78,9 @@ public:
static void onMessageCallback(const uv_async_t* req);
static void timerCb(uv_timer_t* handle);
void tick();
void setPreferedFramePersecond(int fps);
int64_t _prefererredNanosecondsPerFrame{NANOSECONDS_60FPS};
OH_NativeXComponent* _component{nullptr};
OH_NativeXComponent_Callback _callback;
uv_timer_t _timerHandle;

View File

@ -121,7 +121,8 @@ void Application::onResume()
void Application::setPreferredFramesPerSecond(int fps)
{
_fps = fps;
// setPreferredFramesPerSecondJNI(_fps);
cocos2d::OpenHarmonyPlatform* platform = cocos2d::OpenHarmonyPlatform::getInstance();
platform->setPreferedFramePersecond(_fps);
}
bool Application::isDisplayStats() {

View File

@ -13203,6 +13203,21 @@ static bool js_cocos2dx_spine_SkeletonRenderer_paused(se::State& s)
}
SE_BIND_FUNC(js_cocos2dx_spine_SkeletonRenderer_paused)
static bool js_cocos2dx_spine_SkeletonRenderer_destroy(se::State& s)
{
spine::SkeletonRenderer* cobj = (spine::SkeletonRenderer*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_cocos2dx_spine_SkeletonRenderer_destroy : Invalid Native Object");
const auto& args = s.args();
size_t argc = args.size();
if (argc == 0) {
cobj->destroy();
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 0);
return false;
}
SE_BIND_FUNC(js_cocos2dx_spine_SkeletonRenderer_destroy)
static bool js_cocos2dx_spine_SkeletonRenderer_setAttachment(se::State& s)
{
CC_UNUSED bool ok = true;
@ -14133,6 +14148,7 @@ bool js_register_cocos2dx_spine_SkeletonRenderer(se::Object* obj)
cls->defineFunction("setAttachUtil", _SE(js_cocos2dx_spine_SkeletonRenderer_setAttachUtil));
cls->defineFunction("setOpacityModifyRGB", _SE(js_cocos2dx_spine_SkeletonRenderer_setOpacityModifyRGB));
cls->defineFunction("paused", _SE(js_cocos2dx_spine_SkeletonRenderer_paused));
cls->defineFunction("destroy", _SE(js_cocos2dx_spine_SkeletonRenderer_destroy));
cls->defineFunction("setAttachment", _SE(js_cocos2dx_spine_SkeletonRenderer_setAttachment));
cls->defineFunction("setBonesToSetupPose", _SE(js_cocos2dx_spine_SkeletonRenderer_setBonesToSetupPose));
cls->defineFunction("onEnable", _SE(js_cocos2dx_spine_SkeletonRenderer_onEnable));
@ -14600,6 +14616,21 @@ static bool js_cocos2dx_spine_SkeletonAnimation_setEndListener(se::State& s)
}
SE_BIND_FUNC(js_cocos2dx_spine_SkeletonAnimation_setEndListener)
static bool js_cocos2dx_spine_SkeletonAnimation_destroy(se::State& s)
{
spine::SkeletonAnimation* cobj = (spine::SkeletonAnimation*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_cocos2dx_spine_SkeletonAnimation_destroy : Invalid Native Object");
const auto& args = s.args();
size_t argc = args.size();
if (argc == 0) {
cobj->destroy();
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 0);
return false;
}
SE_BIND_FUNC(js_cocos2dx_spine_SkeletonAnimation_destroy)
static bool js_cocos2dx_spine_SkeletonAnimation_getState(se::State& s)
{
spine::SkeletonAnimation* cobj = (spine::SkeletonAnimation*)s.nativeThisObject();
@ -15284,6 +15315,7 @@ bool js_register_cocos2dx_spine_SkeletonAnimation(se::Object* obj)
cls->defineFunction("setTrackCompleteListenerNative", _SE(js_cocos2dx_spine_SkeletonAnimation_setTrackCompleteListener));
cls->defineFunction("setAnimationStateData", _SE(js_cocos2dx_spine_SkeletonAnimation_setAnimationStateData));
cls->defineFunction("setEndListener", _SE(js_cocos2dx_spine_SkeletonAnimation_setEndListener));
cls->defineFunction("destroy", _SE(js_cocos2dx_spine_SkeletonAnimation_destroy));
cls->defineFunction("getState", _SE(js_cocos2dx_spine_SkeletonAnimation_getState));
cls->defineFunction("setCompleteListenerNative", _SE(js_cocos2dx_spine_SkeletonAnimation_setCompleteListener));
cls->defineFunction("setTrackDisposeListener", _SE(js_cocos2dx_spine_SkeletonAnimation_setTrackDisposeListener));
@ -15652,6 +15684,21 @@ static bool js_cocos2dx_spine_SkeletonCacheAnimation_paused(se::State& s)
}
SE_BIND_FUNC(js_cocos2dx_spine_SkeletonCacheAnimation_paused)
static bool js_cocos2dx_spine_SkeletonCacheAnimation_destroy(se::State& s)
{
spine::SkeletonCacheAnimation* cobj = (spine::SkeletonCacheAnimation*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_cocos2dx_spine_SkeletonCacheAnimation_destroy : Invalid Native Object");
const auto& args = s.args();
size_t argc = args.size();
if (argc == 0) {
cobj->destroy();
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 0);
return false;
}
SE_BIND_FUNC(js_cocos2dx_spine_SkeletonCacheAnimation_destroy)
static bool js_cocos2dx_spine_SkeletonCacheAnimation_setAttachment(se::State& s)
{
CC_UNUSED bool ok = true;
@ -16334,6 +16381,7 @@ bool js_register_cocos2dx_spine_SkeletonCacheAnimation(se::Object* obj)
cls->defineFunction("findAnimation", _SE(js_cocos2dx_spine_SkeletonCacheAnimation_findAnimation));
cls->defineFunction("setAttachUtil", _SE(js_cocos2dx_spine_SkeletonCacheAnimation_setAttachUtil));
cls->defineFunction("paused", _SE(js_cocos2dx_spine_SkeletonCacheAnimation_paused));
cls->defineFunction("destroy", _SE(js_cocos2dx_spine_SkeletonCacheAnimation_destroy));
cls->defineFunction("setAttachment", _SE(js_cocos2dx_spine_SkeletonCacheAnimation_setAttachment));
cls->defineFunction("setAnimation", _SE(js_cocos2dx_spine_SkeletonCacheAnimation_setAnimation));
cls->defineFunction("setBonesToSetupPose", _SE(js_cocos2dx_spine_SkeletonCacheAnimation_setBonesToSetupPose));

View File

@ -923,6 +923,7 @@ SE_DECLARE_FUNC(js_cocos2dx_spine_SkeletonRenderer_initWithUUID);
SE_DECLARE_FUNC(js_cocos2dx_spine_SkeletonRenderer_setAttachUtil);
SE_DECLARE_FUNC(js_cocos2dx_spine_SkeletonRenderer_setOpacityModifyRGB);
SE_DECLARE_FUNC(js_cocos2dx_spine_SkeletonRenderer_paused);
SE_DECLARE_FUNC(js_cocos2dx_spine_SkeletonRenderer_destroy);
SE_DECLARE_FUNC(js_cocos2dx_spine_SkeletonRenderer_setAttachment);
SE_DECLARE_FUNC(js_cocos2dx_spine_SkeletonRenderer_setBonesToSetupPose);
SE_DECLARE_FUNC(js_cocos2dx_spine_SkeletonRenderer_onEnable);
@ -973,6 +974,7 @@ SE_DECLARE_FUNC(js_cocos2dx_spine_SkeletonAnimation_setTrackInterruptListener);
SE_DECLARE_FUNC(js_cocos2dx_spine_SkeletonAnimation_setTrackCompleteListener);
SE_DECLARE_FUNC(js_cocos2dx_spine_SkeletonAnimation_setAnimationStateData);
SE_DECLARE_FUNC(js_cocos2dx_spine_SkeletonAnimation_setEndListener);
SE_DECLARE_FUNC(js_cocos2dx_spine_SkeletonAnimation_destroy);
SE_DECLARE_FUNC(js_cocos2dx_spine_SkeletonAnimation_getState);
SE_DECLARE_FUNC(js_cocos2dx_spine_SkeletonAnimation_setCompleteListener);
SE_DECLARE_FUNC(js_cocos2dx_spine_SkeletonAnimation_setTrackDisposeListener);
@ -1022,6 +1024,7 @@ SE_DECLARE_FUNC(js_cocos2dx_spine_SkeletonCacheAnimation_setTimeScale);
SE_DECLARE_FUNC(js_cocos2dx_spine_SkeletonCacheAnimation_findAnimation);
SE_DECLARE_FUNC(js_cocos2dx_spine_SkeletonCacheAnimation_setAttachUtil);
SE_DECLARE_FUNC(js_cocos2dx_spine_SkeletonCacheAnimation_paused);
SE_DECLARE_FUNC(js_cocos2dx_spine_SkeletonCacheAnimation_destroy);
SE_DECLARE_FUNC(js_cocos2dx_spine_SkeletonCacheAnimation_setAttachment);
SE_DECLARE_FUNC(js_cocos2dx_spine_SkeletonCacheAnimation_setAnimation);
SE_DECLARE_FUNC(js_cocos2dx_spine_SkeletonCacheAnimation_setBonesToSetupPose);

View File

@ -509,10 +509,9 @@ void Object::setPrivateData(void* data){
//issue https://github.com/nodejs/node/issues/23999
auto tmpThis = _objRef.getValue(_env);
//_objRef.deleteRef();
napi_ref result = nullptr;
NODE_API_CALL(status, _env,
napi_wrap(_env, tmpThis, data, weakCallback,
(void*)this /* finalize_hint */, &result));
(void*)this /* finalize_hint */, nullptr));
//_objRef.setWeakref(_env, result);
setProperty("__native_ptr__", se::Value(static_cast<long>(reinterpret_cast<uintptr_t>(data))));
}

View File

@ -180,13 +180,13 @@ bool jsb_register_all_modules()
se->addRegisterCallback(register_all_video);
#endif
#if USE_WEBVIEW
#if USE_WEB_VIEW
se->addRegisterCallback(register_all_webview);
#endif
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY)
#if USE_WEBVIEW
#if USE_WEB_VIEW
se->addRegisterCallback(register_all_webview);
#endif

View File

@ -379,6 +379,12 @@ void XMLHttpRequest::getHeader(const std::string& header)
// Transform field name to lower case as they are case-insensitive
std::transform(http_field.begin(), http_field.end(), http_field.begin(), ::tolower);
if (CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY && _httpHeader.find(http_field) != _httpHeader.end()) {
_httpHeader[http_field].insert(strlen(_httpHeader[http_field].c_str()) - 1, ",");
_httpHeader[http_field].insert(strlen(_httpHeader[http_field].c_str()) - 1, http_value);
http_value = _httpHeader[http_field];
}
_httpHeader[http_field] = http_value;
}

View File

@ -1,6 +1,6 @@
{
"version": "v24-11",
"zip_file_size": "181264997",
"version": "v24-12",
"zip_file_size": "181682416",
"repo_name": "cocos-engine-external",
"repo_parent": "https://github.com/cocos/"
}

View File

@ -6,7 +6,7 @@
#endif
#endif
#define LWS_INSTALL_DATADIR "/home/cloud_dragon/lsy/lycium/usr/libwebsockets-arm64-v8a-install/share"
#define LWS_INSTALL_DATADIR "/Users/cocos/Github/cocos2d-x-3rd-party-libs-src/contrib/install-android/arm64/share"
/* Define to 1 to use wolfSSL/CyaSSL as a replacement for OpenSSL.
* LWS_OPENSSL_SUPPORT needs to be set also for this to work. */
@ -35,7 +35,7 @@
#define LWS_LIBRARY_VERSION_NUMBER (LWS_LIBRARY_VERSION_MAJOR*1000000)+(LWS_LIBRARY_VERSION_MINOR*1000)+LWS_LIBRARY_VERSION_PATCH
/* The current git commit hash that we're building from */
/* #undef LWS_BUILD_HASH */
#define LWS_BUILD_HASH "cocos@cocoss-MacBook-Pro.local-v3.4-182-g408ba56"
/* Build with OpenSSL support */
#define LWS_OPENSSL_SUPPORT
@ -83,16 +83,16 @@
/* #undef LWS_MINGW_SUPPORT */
/* Use the BSD getifaddrs that comes with libwebsocket, for uclibc support */
/* #undef LWS_BUILTIN_GETIFADDRS */
#define LWS_BUILTIN_GETIFADDRS
/* use SHA1() not internal libwebsockets_SHA1 */
/* #undef LWS_SHA1_USE_OPENSSL_NAME */
/* SSL server using ECDH certificate */
/* #undef LWS_SSL_SERVER_WITH_ECDH_CERT */
#define LWS_HAVE_SSL_CTX_set1_param
#define LWS_HAVE_X509_VERIFY_PARAM_set1_host
#define LWS_HAVE_RSA_SET0_KEY
/* #undef LWS_HAVE_SSL_CTX_set1_param */
/* #undef LWS_HAVE_X509_VERIFY_PARAM_set1_host */
/* #undef LWS_HAVE_RSA_SET0_KEY */
/* #undef LWS_HAVE_UV_VERSION_H */
@ -147,9 +147,9 @@
/* OpenSSL various APIs */
#define LWS_HAVE_TLS_CLIENT_METHOD
#define LWS_HAVE_TLSV1_2_CLIENT_METHOD
#define LWS_HAVE_SSL_SET_INFO_CALLBACK
/* #undef LWS_HAVE_TLS_CLIENT_METHOD */
/* #undef LWS_HAVE_TLSV1_2_CLIENT_METHOD */
/* #undef LWS_HAVE_SSL_SET_INFO_CALLBACK */
#define LWS_HAS_INTPTR_T

View File

@ -1,6 +1,6 @@
{
"name": "cocos2d-x-lite",
"version": "2.4.12",
"version": "2.4.13",
"description": "Cocos2d-x, compact version",
"main": "gulpfile.js",
"devDependencies": {

View File

@ -0,0 +1,27 @@
import { ContextType } from '../../../ets/common/Constants';
interface context {
onPageShow: () => void;
onPageHide: () => void;
workerInit: () => void;
postMessage: (msgType: string, msgData: string) => void;
postSyncMessage: (msgType: string, msgData: string) => Promise<boolean | string | number>;
setPostMessageFunction: (postMessage: (msgType: string, msgData: string) => void) => void;
setPostSyncMessageFunction: (postSyncMessage: (msgType: string, msgData: string) => void) => void;
nativeEngineInit: () => void;
nativeEngineStart: () => void;
onTextChange: (param: string) => void;
onComplete: (param: string) => void;
shouldStartLoading: (viewTag: number, url: string) => void;
finishLoading: (viewTag: number, url: string) => void;
failLoading: (viewTag: number, url: string) => void;
onBackPress: () => void;
onCreate: () => void;
onDestroy: () => void;
onShow: () => void;
onHide: () => void;
resourceManagerInit: (resourceManager: any) => void;
writablePathInit: (cacheDir: string) => void;
}
export const getContext: (type: ContextType) => context;

View File

@ -0,0 +1,6 @@
{
"name": "libcocos.so",
"types": "./index.d.ts",
"version": "",
"description": "Please describe the basic information."
}

View File

@ -24,31 +24,34 @@
****************************************************************************/
import worker from '@ohos.worker';
import {Constants} from '../common/Constants'
import { Constants } from '../common/Constants'
export class WorkerManager {
private static instance: WorkerManager;
private cocosWorker: any;
private cocosWorker: worker.Worker;
private constructor() {
this.cocosWorker = new worker.Worker("entry/ets/workers/cocos_worker.ts", {type:"classic", name: "CocosWorker"});
this.cocosWorker.onerror = function (e) {
var msg = e.message;
var filename = e.filename;
var lineno = e.lineno;
var colno = e.colno;
console.error(`on Error ${msg} ${filename} ${lineno} ${colno}`);
}
private constructor() {
this.cocosWorker = new worker.Worker("entry/ets/workers/cocos_worker.ts", {
type: "classic",
name: "CocosWorker"
});
this.cocosWorker.onerror = (e) => {
let msg = e.message;
let filename = e.filename;
let lineno = e.lineno;
let colno = e.colno;
console.error(`on Error ${msg} ${filename} ${lineno} ${colno}`);
}
}
public static getInstance(): WorkerManager {
if (AppStorage.Get(Constants.APP_KEY_WORKER_MANAGER) == null) {
AppStorage.SetOrCreate(Constants.APP_KEY_WORKER_MANAGER, new WorkerManager);
}
return AppStorage.Get(Constants.APP_KEY_WORKER_MANAGER);
}
public getWorker(): any {
return this.cocosWorker;
public static getInstance(): WorkerManager {
if (AppStorage.Get(Constants.APP_KEY_WORKER_MANAGER) as WorkerManager == undefined) {
AppStorage.SetOrCreate(Constants.APP_KEY_WORKER_MANAGER, new WorkerManager);
}
return AppStorage.Get(Constants.APP_KEY_WORKER_MANAGER) as WorkerManager;
}
public getWorker(): worker.Worker {
return this.cocosWorker;
}
}

View File

@ -1,4 +1,5 @@
globalThis.oh = {};
globalThis.oh = {} as any;
function boot() {
const cc = globalThis.cc;
var settings = globalThis._CCSettings;
@ -74,8 +75,8 @@ function boot() {
}
}
globalThis.oh.loadJsList(settings.jsList,cb);
globalThis.oh.loadJsList(settings.jsList, cb);
for (var i = 0; i < bundleRoot.length; i++) {
cc.assetManager.loadBundle(bundleRoot[i], cb);
}

View File

@ -21,57 +21,56 @@
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 worker from '@ohos.worker';
import {DedicatedWorkerGlobalScope} from '@ohos.worker';
// NOTE: don't use this import all statement, because this has compile issue.
// import * as wk from '@ohos.worker';
****************************************************************************/
import { DedicatedWorkerGlobalScope } from '@ohos.worker';
import { MessageEvent } from '@ohos.worker';
export class PortProxy {
private autoId: number = 0;
public actionHandleMap = {}
private port :DedicatedWorkerGlobalScope = null;
private autoId: number = 0;
public actionHandleMap = {}
private port: DedicatedWorkerGlobalScope = null;
public _messageHandle?:(e: MessageEvent<any>) => void;
public _messageHandle?: (e: MessageEvent<any>) => void;
constructor (port) {
this.port = port;
this.port.onmessage = this.onMessage.bind(this);
}
constructor(worker) {
this.port = worker;
this.port.onmessage = this.onMessage.bind(this);
}
public onMessage(e) {
let data = e['data'];
if(data.type != "syncResult" && this._messageHandle) {
this._messageHandle(e);
} else if(data.type == "syncResult") {
const {id, response} = data.data;
if (!this.actionHandleMap[id]) {
return;
}
this.actionHandleMap[id].call(this, response)
delete this.actionHandleMap[id];
}
}
public postReturnMessage(e:any, res: any) {
if(e.type == "sync" && res != null && res != undefined) {
this.port.postMessage({type:"syncResult", data:{id:e.data.cbId, response:res}});
}
}
public postMessage(msgName: string, msgData:any) {
this.port.postMessage({type:"async", data:{name:msgName, param:msgData}});
public onMessage(e) {
let data = e['data'];
if (data.type != "syncResult" && this._messageHandle) {
this._messageHandle(e);
} else if (data.type == "syncResult") {
const { id, response } = data.data;
if (!this.actionHandleMap[id]) {
return;
}
this.actionHandleMap[id].call(this, response);
delete this.actionHandleMap[id];
}
}
public postSyncMessage(msgName: string, msgData:any) {
const id = this.autoId++;
return new Promise((resolve, reject) => {
const message = {
type:"sync", data:{cbId:id, name:msgName, param:msgData}
}
this.port.postMessage(message);
this.actionHandleMap[id] = (response) => {
resolve(response)
}
})
public postReturnMessage(e: any, res: any) {
if (e.type == "sync" && res != null && res != undefined) {
this.port.postMessage({ type: "syncResult", data: { id: e.data.cbId, response: res } });
}
}
public postMessage(msgName: string, msgData: any) {
this.port.postMessage({ type: "async", data: { name: msgName, param: msgData } });
}
public postSyncMessage(msgName: string, msgData: any) {
const id = this.autoId++;
return new Promise((resolve, reject) => {
const message = {
type: "sync", data: { cbId: id, name: msgName, param: msgData }
}
this.port.postMessage(message);
this.actionHandleMap[id] = (response) => {
resolve(response)
}
})
}
}

View File

@ -21,9 +21,8 @@
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 { WorkerManager } from '../cocos/WorkerManager'
import { PortProxy } from '../common/PortProxy'
****************************************************************************/
import { PortProxy } from '../common/PortProxy';
enum EventType {
PLAYING = 0,
@ -35,7 +34,13 @@ enum EventType {
READY_TO_PLAY,
UPDATE,
QUIT_FULLSCREEN = 1000
};
}
interface param {
videoTag?: number,
videoEvent?: EventType,
args?: number
}
@Observed
export class VideoInfo {
@ -44,24 +49,21 @@ export class VideoInfo {
public w: number = 0;
public h: number = 0;
// url
public url: string | Resource = ""
public viewTag: string = ''
public visible: boolean = true
public url: string | Resource = "";
public viewTag: number = 0;
public visible: boolean = true;
public duration: number = 0;
public currentTime: number = 0;
public isFullScreen: boolean = false;
public currentProgressRate:number | string | PlaybackSpeed;
public currentProgressRate?: number | string | PlaybackSpeed;
public resourceType: number = 0;
/**
* https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-ts/ts-media-components-video.md#videocontroller
*
*/
public controller: VideoController = new VideoController()
constructor(x: number, y: number, w: number, h: number, viewTag: string) {
constructor(x: number, y: number, w: number, h: number, viewTag: number) {
this.x = x;
this.y = y;
this.w = w;
@ -70,49 +72,70 @@ export class VideoInfo {
}
}
@Component
export struct CocosVideoPlayer {
@ObjectLink videoInfo: VideoInfo;
public workPort: PortProxy;
public workPort: PortProxy | null = null;
build() {
Video({ src: this.videoInfo.url, controller: this.videoInfo.controller, currentProgressRate:this.videoInfo.currentProgressRate })
Video({
src: this.videoInfo.url,
controller: this.videoInfo.controller,
currentProgressRate: this.videoInfo.currentProgressRate as number | string | PlaybackSpeed
})
.position({ x: this.videoInfo.x, y: this.videoInfo.y })
.width(this.videoInfo.w)
.height(this.videoInfo.h)
.controls(false)
.autoPlay(false)
.onStart(() => {
this.workPort.postMessage("onVideoEvent",{videoTag:this.videoInfo.viewTag, videoEvent:EventType.PLAYING});
this.workPort?.postMessage("onVideoEvent", {
videoTag: this.videoInfo.viewTag as number,
videoEvent: EventType.PLAYING as EventType
} as param);
})
.onPause(() => {
this.workPort.postMessage("onVideoEvent",{videoTag:this.videoInfo.viewTag, videoEvent:EventType.PAUSED});
this.workPort?.postMessage("onVideoEvent", {
videoTag: this.videoInfo.viewTag as number,
videoEvent: EventType.PAUSED as EventType
} as param);
})
.onFinish(() => {
this.workPort.postMessage("onVideoEvent",{videoTag:this.videoInfo.viewTag, videoEvent:EventType.COMPLETED});
this.workPort?.postMessage("onVideoEvent", {
videoTag: this.videoInfo.viewTag,
videoEvent: EventType.COMPLETED
} as param);
})
.onPrepared((event: {
duration: number;
}) => {
this.videoInfo.duration = event.duration;
this.workPort.postMessage("onVideoEvent",{videoTag:this.videoInfo.viewTag, videoEvent:EventType.READY_TO_PLAY, args:event.duration});
.onPrepared((event): void => {
this.videoInfo.duration = event?.duration as number;
this.workPort?.postMessage("onVideoEvent", {
videoTag: this.videoInfo.viewTag,
videoEvent: EventType.READY_TO_PLAY,
args: event?.duration
} as param);
})
.onClick((event: ClickEvent) => {
this.workPort.postMessage("onVideoEvent",{videoTag:this.videoInfo.viewTag, videoEvent:EventType.CLICKED});
.onClick((event): void => {
this.workPort?.postMessage("onVideoEvent", {
videoTag: this.videoInfo.viewTag,
videoEvent: EventType.CLICKED
} as param);
})
.onUpdate((event?: {
time: number;
}) => {
this.videoInfo.currentTime = event.time
this.workPort.postMessage("onVideoEvent",{videoTag:this.videoInfo.viewTag, videoEvent:EventType.UPDATE, args:event.time});
.onUpdate((event) => {
this.videoInfo.currentTime = event?.time as number;
this.workPort?.postMessage("onVideoEvent", {
videoTag: this.videoInfo.viewTag,
videoEvent: EventType.UPDATE,
args: event?.time
} as param);
})
.onFullscreenChange((event?: {
fullscreen: boolean;
}) => {
if (!event.fullscreen) {
this.workPort.postMessage("onVideoEvent",{videoTag:this.videoInfo.viewTag, videoEvent:EventType.QUIT_FULLSCREEN});
.onFullscreenChange((event) => {
if (!event?.fullscreen) {
this.workPort?.postMessage("onVideoEvent", {
videoTag: this.videoInfo.viewTag,
videoEvent: EventType.QUIT_FULLSCREEN
} as param);
}
this.videoInfo.isFullScreen = event.fullscreen
this.videoInfo.isFullScreen = event?.fullscreen as boolean;
})
.visibility(this.videoInfo.visible ? Visibility.Visible : Visibility.None)
}

View File

@ -22,9 +22,14 @@
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
import { WorkerManager } from '../cocos/WorkerManager'
import { PortProxy } from '../common/PortProxy'
import web from '@ohos.web.webview'
import { PortProxy } from '../common/PortProxy';
import web from '@ohos.web.webview';
interface param {
viewTag: number,
url: string,
}
@Observed
export class WebViewInfo {
// position
@ -34,27 +39,26 @@ export class WebViewInfo {
public w: number = 0;
public h: number = 0;
// url
public url: string = ''
public url: string = '';
// tag
public viewTag: string = ''
public viewTag: number = 0;
// Whether to display
public visible: boolean = true
public visible: boolean = true;
/*
* doc : https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-web.md#webcontroller
*/
public controller: WebController = new WebController()
public controller: web.WebviewController = new web.WebviewController();
constructor(x: number, y: number, w: number, h: number, viewTag: string) {
constructor(x: number, y: number, w: number, h: number, viewTag: number) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.viewTag = viewTag;
web.once("webInited", ()=>{
if (this.url!= '') {
this.controller.loadUrl({url: this.url});
web.once("webInited", () => {
if (this.url != '') {
this.controller.loadUrl(this.url);
}
});
}
@ -63,33 +67,33 @@ export class WebViewInfo {
@Component
export struct CocosWebView {
@ObjectLink viewInfo: WebViewInfo;
public workPort: PortProxy;
public workPort: PortProxy | null = null;
build() {
Web({ src: "", controller: this.viewInfo.controller })
Web({ src: this.viewInfo.url, controller: this.viewInfo.controller })
.position({ x: this.viewInfo.x, y: this.viewInfo.y })
.width(this.viewInfo.w)
.height(this.viewInfo.h)
.border({ width: 1 })
.onPageBegin((event) => {
this.workPort.postMessage("onPageBegin", {viewTag:this.viewInfo.viewTag, url:event.url});
this.workPort?.postMessage("onPageBegin", {
viewTag: this.viewInfo.viewTag as number,
url: event?.url as string
} as param);
})
.onPageEnd((event) => {
this.workPort.postMessage("onPageEnd", {viewTag:this.viewInfo.viewTag, url:event.url})
this.workPort?.postMessage("onPageEnd", { viewTag: this.viewInfo.viewTag as number, url: event?.url as string } as param)
})
.onErrorReceive((event) => {
this.workPort.postMessage("onErrorReceive", {viewTag:this.viewInfo.viewTag, url:this.viewInfo.url})
this.workPort?.postMessage("onErrorReceive", { viewTag: this.viewInfo.viewTag as number, url: this.viewInfo.url as string } as param)
})
.onHttpErrorReceive((event) => {
this.workPort.postMessage("onErrorReceive", {viewTag:this.viewInfo.viewTag, url:this.viewInfo.url})
this.workPort?.postMessage("onErrorReceive", { viewTag: this.viewInfo.viewTag as number, url: this.viewInfo.url as string } as param)
})
// 开启DOM存储权限
.domStorageAccess(true)
// 开启数据库存储权限
.databaseAccess(true)
// 图片加载相关权限
.imageAccess(true)
// 支持JS代码运行
.javaScriptAccess(true)
.domStorageAccess(true)// enable DOM storage permissions
.databaseAccess(true)// enable database storage permissions
.imageAccess(true)// enable image loading permissions
.javaScriptAccess(true)// support JS code running
.visibility(this.viewInfo.visible ? Visibility.Visible : Visibility.None)
}
}

View File

@ -21,16 +21,16 @@
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.
****************************************************************************/
****************************************************************************/
@CustomDialog
export struct EditBoxDialog {
private showMessage: string = ''
private inputMessage: string = ''
onTextChange: (msg: string) => void
accept: (msg: string) => void
controller: CustomDialogController
cancel: () => void
confirm: () => void
onTextChange?: (msg: string) => void;
accept?: (msg: string) => void;
controller?: CustomDialogController;
cancel?: () => void;
confirm?: () => void;
build() {
Column() {
@ -48,14 +48,14 @@ export struct EditBoxDialog {
if (this.accept) {
this.accept(this.inputMessage);
}
this.controller.close();
this.controller?.close();
})
Blank(8).width(16)
Button('完成').onClick(() => {
if (this.accept) {
this.accept(this.inputMessage);
}
this.controller.close();
this.controller?.close();
})
}.padding({ left: 8, right: 8, top: 8, bottom: 8 })
.backgroundColor(Color.Gray)

View File

@ -1,6 +1,6 @@
import UIAbility from '@ohos.app.ability.UIAbility';
import cocos from "libcocos.so";
import { ContextType } from "../common/Constants"
import cocos from 'libcocos.so';
import { ContextType } from '../common/Constants';
import window from '@ohos.window';
const nativeContext = cocos.getContext(ContextType.ENGINE_UTILS);
@ -29,9 +29,9 @@ export default class EntryAbility extends UIAbility {
}
windowClass = data;
console.info('Succeeded in obtaining the main window. Data: ' + JSON.stringify(data));
// 设置窗口为全屏布局,配合设置导航栏、状态栏是否显示,与主窗口显示保持协调一致。
let isLayoutFullScreen= true;
let isLayoutFullScreen = true;
windowClass.setWindowLayoutFullScreen(isLayoutFullScreen, (err) => {
if (err.code) {
console.error('Failed to set the window layout to full-screen mode. Cause: ' + JSON.stringify(err));
@ -39,7 +39,7 @@ export default class EntryAbility extends UIAbility {
}
console.info('Succeeded in setting the window layout to full-screen mode.');
});
// 设置状态栏和导航栏是否显示。例如,需全部显示,该参数设置为['status', 'navigation'];不设置,则默认不显示。
let visibleBar = [];
windowClass.setWindowSystemBarEnable(visibleBar, (err) => {

View File

@ -21,227 +21,264 @@
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 nativerender from "libcocos.so";
****************************************************************************/
import nativerender from 'libcocos.so';
import { WorkerManager } from '../cocos/WorkerManager'
import { ContextType } from "../common/Constants"
import featureAbility from '@ohos.ability.featureAbility'
import { EditBoxDialog } from '../components/EditBoxDialog'
import { WebViewInfo, CocosWebView } from '../components/CocosWebView'
import { VideoInfo, CocosVideoPlayer } from '../components/CocosVideoPlayer'
import { WorkerManager } from '../cocos/WorkerManager';
import { ContextType } from '../common/Constants';
import { EditBoxDialog } from '../components/EditBoxDialog';
import { CocosWebView, WebViewInfo } from '../components/CocosWebView';
import { CocosVideoPlayer, VideoInfo } from '../components/CocosVideoPlayer';
import { MessageEvent } from '@ohos.worker';
import { PortProxy } from '../common/PortProxy';
import {PortProxy} from '../common/PortProxy'
const nativePageLifecycle = nativerender.getContext(ContextType.JSPAGE_LIFECYCLE);
const engineUtils = nativerender.getContext(ContextType.ENGINE_UTILS);
interface WorkerMessage {
type: string;
data: data;
}
interface data {
id: string,
name: string,
param: number | string | param
}
interface param {
tag?: number,
url?: string,
contents?: string,
mimeType?: string,
encoding?: string,
baseUrl?: string,
jsContents?: string,
x?: number,
y?: number,
w?: number,
h?: number,
visible?: boolean,
resourceType?: number,
time?: number,
fullScreen?: boolean
}
@Entry
@Component
struct Index {
@State showMessage: string = ''
@State webViewArray: WebViewInfo[] = [];
@State videoArray:VideoInfo[] = [];
//private index: number = 0;
private webViewIndexMap: Map<number, number> = new Map;
private videoIndexMap: Map<number, number> = new Map;
private workPort : PortProxy = new PortProxy(WorkerManager.getInstance().getWorker());
@State videoArray: VideoInfo[] = [];
private webViewIndexMap: Map<number, number> = new Map<number, number>();
private videoIndexMap: Map<number, number> = new Map<number, number>();
private workPort: PortProxy = new PortProxy(WorkerManager.getInstance().getWorker());
dialogController: CustomDialogController = new CustomDialogController({
builder: EditBoxDialog({
showMessage: this.showMessage,
onTextChange: (msg: string) => {
onTextChange: (msg: string): void => {
this.showMessage = msg;
this.workPort.postMessage('onTextInput', msg)
this.workPort.postMessage('onTextInput', msg);
},
accept: (msg: string) => {
accept: (msg: string): void => {
this.showMessage = msg;
this.workPort.postMessage('onComplete', msg)
},
this.workPort.postMessage('onComplete', msg);
}
}),
cancel: () => {
this.workPort.postMessage('onComplete', this.showMessage)
cancel: (): void => {
this.workPort.postMessage('onComplete', this.showMessage);
},
autoCancel: true,
alignment: DialogAlignment.Bottom,
customStyle: true,
})
aboutToAppear(): void {
aboutToAppear(): void {
console.log('[LIFECYCLE-Index] cocos aboutToAppear');
this.workPort._messageHandle = (e) => {
//let data = e['data'];
var data = e.data;
var msg = data.data;
var result;
this.workPort._messageHandle = async (e: MessageEvent<WorkerMessage>): Promise<void> => {
let data: WorkerMessage = e.data;
let msg = data.data;
let result: boolean | string | number | null = null;
switch (msg.name) {
// EditBox
// EditBox
case "showEditBox": {
this.showMessage = msg.param
this.dialogController.open()
this.showMessage = msg.param as string;
this.dialogController.open();
break;
}
case "hideEditBox": {
this.showMessage = ''
this.dialogController.close()
this.showMessage = '';
this.dialogController.close();
break;
}
// WebView
// WebView
case "createWebView": {
this.webViewArray.push(new WebViewInfo(0, 0, 0, 0, msg.param))
this.webViewIndexMap.set(msg.param, this.webViewArray.length - 1);
this.webViewArray.push(new WebViewInfo(0, 0, 0, 0, msg.param as number));
this.webViewIndexMap.set(msg.param as number, this.webViewArray.length - 1);
break;
}
case "removeWebView": {
if (this.webViewArray.length > 0) {
this.webViewArray.splice(this.webViewIndexMap.get(msg.param), 1)
this.webViewArray.splice(this.webViewIndexMap.get(msg?.param as number) as number, 1);
}
break;
}
case "loadUrl": {
var web = msg.param;
var index = this.webViewIndexMap.get(web.tag);
this.webViewArray[index].url = web.url;
this.webViewArray[index].controller.loadUrl({url: web.url});
let web = msg.param as param;
let index = this.webViewIndexMap.get(web?.tag as number) as number;
this.webViewArray[index].url = web?.url as string;
this.webViewArray[index].controller.loadUrl(web?.url as string);
break;
}
case "loadHTMLString": {
var web = msg.param;
var index = this.webViewIndexMap.get(web.tag);
this.webViewArray[index].controller.loadData({data: web.contents, mimeType:"text/html",encoding:"UTF-8", baseUrl:web.baseUrl});
let web = msg.param as param;
let index = this.webViewIndexMap.get(web?.tag as number) as number;
this.webViewArray[index].controller.loadData(
web?.contents as string,
"text/html",
"UTF-8",
web?.baseUrl
);
break;
}
case "loadData": {
var web = msg.param;
var index = this.webViewIndexMap.get(web.tag);
this.webViewArray[index].controller.loadData({data: web.contents, mimeType:web.mimeType,encoding:web.encoding, baseUrl:web.baseUrl});
let web = msg.param as param;
let index = this.webViewIndexMap.get(web?.tag as number) as number;
this.webViewArray[index].controller.loadData(
web?.contents as string,
web?.mimeType as string,
web?.encoding as string,
web?.baseUrl as string
);
break;
}
case "evaluateJS": {
var web = msg.param;
var index = this.webViewIndexMap.get(web.tag)
this.webViewArray[index].controller.runJavaScript({
script: web.jsContents
});
let web = msg.param as param;
let index = this.webViewIndexMap.get(web?.tag as number) as number;
this.webViewArray[index].controller.runJavaScript(web?.jsContents as string);
break;
}
case "reload": {
var index = this.webViewIndexMap.get(msg.param);
let index = this.webViewIndexMap.get(msg.param as number) as number;
this.webViewArray[index].controller.refresh();
break;
}
case "stopLoading": {
var index = this.webViewIndexMap.get(msg.param);
let index = this.webViewIndexMap.get(msg.param as number) as number;
this.webViewArray[index].controller.stop();
break;
}
case "canGoForward": {
var index = this.webViewIndexMap.get(msg.param);
let index = this.webViewIndexMap.get(msg.param as number) as number;
result = this.webViewArray[index].controller.accessForward();
break;
}
case "canGoBack": {
var index = this.webViewIndexMap.get(msg.param);
let index = this.webViewIndexMap.get(msg.param as number) as number;
result = this.webViewArray[index].controller.accessBackward();
break;
}
case "goForward": {
var index = this.webViewIndexMap.get(msg.param);
let index = this.webViewIndexMap.get(msg.param as number) as number;
this.webViewArray[index].controller.forward();
break;
}
case "goBack": {
var index = this.webViewIndexMap.get(msg.param);
let index = this.webViewIndexMap.get(msg.param as number) as number;
this.webViewArray[index].controller.backward();
break;
}
case "setWebViewRect": {
var web = msg.param;
var index = this.webViewIndexMap.get(web.tag);
this.webViewArray[index].x = px2vp(web.x);
this.webViewArray[index].y = px2vp(web.y);
this.webViewArray[index].w = px2vp(web.w);
this.webViewArray[index].h = px2vp(web.h);
let web = msg.param as param
let index = this.webViewIndexMap.get(web?.tag as number) as number;
this.webViewArray[index].x = px2vp(web?.x as number) as number;
this.webViewArray[index].y = px2vp(web?.y as number) as number;
this.webViewArray[index].w = px2vp(web?.w as number) as number;
this.webViewArray[index].h = px2vp(web?.h as number) as number;
break;
}
case "setVisible":
var web = msg.param;
var index = this.webViewIndexMap.get(web.tag);
this.webViewArray[index].visible = web.visible;
case "setVisible": {
let web = msg.param as param;
let index = this.webViewIndexMap.get(web?.tag as number) as number;
this.webViewArray[index].visible = web?.visible as boolean;
break;
// video
case "createVideo":
this.videoArray.push(new VideoInfo(0, 0, 0, 0, msg.param))
this.videoIndexMap.set(msg.param, this.videoArray.length - 1);
}
// video
case "createVideo": {
this.videoArray.push(new VideoInfo(0, 0, 0, 0, msg.param as number));
this.videoIndexMap.set(msg.param as number, this.videoArray.length - 1);
break;
case "removeVideo":
}
case "removeVideo": {
if (this.videoArray.length > 0) {
this.videoArray.splice(this.videoIndexMap.get(msg.param), 1)
this.videoArray.splice(this.videoIndexMap.get(msg.param as number) as number, 1);
}
break;
}
case "setVideoUrl":
var video = msg.param;
var index = this.videoIndexMap.get(video.tag);
var resourceType = video.resourceType;
let video = msg.param as param;
let index = this.videoIndexMap.get(video?.tag as number) as number;
let resourceType = video.resourceType;
if (resourceType == 1) {
this.videoArray[index].url = $rawfile(video.url);
this.videoArray[index].url = $rawfile(video.url as string);
} else {
this.videoArray[index].url = video.url;
this.videoArray[index].url = video.url as string;
}
break;
case "setVideoRect": {
var video = msg.param;
var index = this.videoIndexMap.get(video.tag);
this.videoArray[index].x = px2vp(video.x);
this.videoArray[index].y = px2vp(video.y);
this.videoArray[index].w = px2vp(video.w);
this.videoArray[index].h = px2vp(video.h);
let video = msg.param as param;
let index = this.videoIndexMap.get(video?.tag as number) as number;
this.videoArray[index].x = px2vp(video?.x as number) as number;
this.videoArray[index].y = px2vp(video?.y as number) as number;
this.videoArray[index].w = px2vp(video?.w as number) as number;
this.videoArray[index].h = px2vp(video?.h as number) as number;
break;
}
case "startVideo": {
var index = this.videoIndexMap.get(msg.param);
let index = this.videoIndexMap.get(msg.param as number) as number;
this.videoArray[index].controller.start();
break;
}
case "pauseVideo" : {
var index = this.videoIndexMap.get(msg.param);
case "pauseVideo": {
let index = this.videoIndexMap.get(msg.param as number) as number;
this.videoArray[index].controller.pause();
break;
}
case "stopVideo" : {
var index = this.videoIndexMap.get(msg.param);
case "stopVideo": {
let index = this.videoIndexMap.get(msg.param as number) as number;
this.videoArray[index].controller.stop();
break;
}
case "resumeVideo": {
var index = this.videoIndexMap.get(msg.param);
let index = this.videoIndexMap.get(msg.param as number) as number;
this.videoArray[index].controller.start();
break;
}
case "getVideoDuration": {
var index = this.videoIndexMap.get(msg.param);
let index = this.videoIndexMap.get(msg.param as number) as number;
result = this.videoArray[index].duration;
break;
}
case "seekVideoTo" : {
var video = msg.param;
var index = this.videoIndexMap.get(video.tag);
this.videoArray[index].controller.setCurrentTime(video.time, SeekMode.Accurate);
case "seekVideoTo": {
let video = msg.param as param;
let index = this.videoIndexMap.get(video?.tag as number) as number;
this.videoArray[index].controller.setCurrentTime(video?.time as number, SeekMode.Accurate);
break;
}
case "setVideoVisible" : {
var video = msg.param;
var index = this.videoIndexMap.get(video.tag);
this.videoArray[index].visible = video.visible;
case "setVideoVisible": {
let video = msg.param as param;
let index = this.videoIndexMap.get(video?.tag as number) as number;
this.videoArray[index].visible = video.visible as boolean;
break;
}
case "setFullScreenEnabled": {
var video = msg.param;
var index = this.videoIndexMap.get(video.tag);
this.videoArray[index].isFullScreen = video.fullScreen;
let video = msg.param as param;
let index = this.videoIndexMap.get(video?.tag as number) as number;
this.videoArray[index].isFullScreen = video.fullScreen as boolean;
break;
}
case "currentTime": {
var index = this.videoIndexMap.get(msg.param);
let index = this.videoIndexMap.get(msg.param as number) as number;
result = this.videoArray[index].currentTime;
break;
}
@ -257,16 +294,16 @@ struct Index {
aboutToDisappear(): void {
console.log('[LIFECYCLE-Index] cocos aboutToDisappear');
// this.cocosWorker.postMessage({type: "JSPageLifecycle", data: "aboutToAppear"});
// nativePageLifecycle.aboutToDisappear();
// this.cocosWorker.postMessage({type: "JSPageLifecycle", data: "aboutToAppear"});
// nativePageLifecycle.aboutToDisappear();
}
onPageShow(): void {
onPageShow(): void {
console.log('[LIFECYCLE-Page] cocos onPageShow');
nativePageLifecycle.onPageShow();
}
onPageHide(): void {
onPageHide(): void {
console.log('[LIFECYCLE-Page] cocos onPageHide');
nativePageLifecycle.onPageHide();
}
@ -279,8 +316,12 @@ struct Index {
}
build() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
XComponent({ id: 'xcomponentId', type: 'surface', libraryname: 'cocos'})
Flex({
direction: FlexDirection.Column,
alignItems: ItemAlign.Center,
justifyContent: FlexAlign.Center
} as FlexOptions) {
XComponent({ id: 'xcomponentId', type: 'surface', libraryname: 'cocos' })
.onLoad((context) => {
// Set the cache directory in the ts layer.
this.workPort.postMessage("onXCLoad", "XComponent");
@ -289,13 +330,13 @@ struct Index {
console.log('cocos onDestroy')
})
ForEach(this.webViewArray, (item: WebViewInfo, index: number) => {
CocosWebView({ viewInfo: item, workPort: this.workPort})
}, item => item.viewTag)
ForEach(this.webViewArray, (item: WebViewInfo) => {
CocosWebView({ viewInfo: item, workPort: this.workPort })
}, (item: WebViewInfo): string => item.viewTag.toString())
ForEach(this.videoArray, (item: VideoInfo, index: number) => {
CocosVideoPlayer({ videoInfo: item, workPort: this.workPort})
}, item => item.viewTag)
ForEach(this.videoArray, (item: VideoInfo) => {
CocosVideoPlayer({ videoInfo: item, workPort: this.workPort })
}, (item: VideoInfo): string => item.viewTag.toString())
}
.width('100%')
.height('100%')

View File

@ -22,16 +22,15 @@ import hilog from '@ohos.hilog';
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 worker from '@ohos.worker';
import cocos from "libcocos.so";
import { ContextType } from "../common/Constants"
import { launchEngine } from '../cocos/game'
import cocos from 'libcocos.so';
import { ContextType } from '../common/Constants';
import { launchEngine } from '../cocos/game';
import { PortProxy } from '../common/PortProxy';
const nativeContext = cocos.getContext(ContextType.WORKER_INIT);
nativeContext.workerInit()
nativeContext.workerInit();
const nativeEditBox = cocos.getContext(ContextType.EDITBOX_UTILS);
const nativeWebView = cocos.getContext(ContextType.WEBVIEW_UTILS);
@ -39,73 +38,66 @@ const appLifecycle = cocos.getContext(ContextType.APP_LIFECYCLE);
let uiPort = new PortProxy(worker.parentPort);
nativeContext.postMessage = function(msgType: string, msgData:string) {
uiPort.postMessage(msgType, msgData);
nativeContext.postMessage = function (msgType: string, msgData: string): void {
uiPort.postMessage(msgType, msgData);
}
nativeContext.postSyncMessage = async function(msgType: string, msgData:string) {
const result = await uiPort.postSyncMessage(msgType, msgData);
return result;
nativeContext.postSyncMessage = async function (msgType: string, msgData: string): Promise<boolean | string | number> {
const result = await uiPort.postSyncMessage(msgType, msgData) as boolean | string | number;
return result;
}
// The purpose of this is to avoid being GC
nativeContext.setPostMessageFunction.call(nativeContext, nativeContext.postMessage)
nativeContext.setPostSyncMessageFunction.call(nativeContext, nativeContext.postSyncMessage)
uiPort._messageHandle = function(e) {
var data = e.data;
var msg = data.data;
hilog.info(0x0000, 'testTag',msg.name,msg.param);
uiPort._messageHandle = function (e) {
var data = e.data;
var msg = data.data;
switch(msg.name) {
case "onXCLoad":
hilog.info(0x0000, 'testTag', '%{public}s', '_messageHandle onXCLoad');
console.info("cocos worker:_messageHandle onXCLoad");
const renderContext = cocos.getContext(ContextType.NATIVE_RENDER_API);
renderContext.nativeEngineInit();
hilog.info(0x0000, 'testTag', '%{public}s', 'begin invoke launchEngine');
launchEngine().then(() => {
hilog.info(0x0000, 'testTag', '%{public}s', 'launch CC engine finished');
console.info('launch CC engine finished');
}).catch(e => {
hilog.info(0x0000, 'testTag', '%{public}s', 'launch CC engine failed');
console.error('launch CC engine failed');
});
// @ts-ignore
globalThis.oh.postMessage = nativeContext.postMessage;
// @ts-ignore
globalThis.oh.postSyncMessage = nativeContext.postSyncMessage;
renderContext.nativeEngineStart();
break;
case "onTextInput":
nativeEditBox.onTextChange(msg.param);
break;
case "onComplete":
nativeEditBox.onComplete(msg.param);
break;
case "onPageBegin":
nativeWebView.shouldStartLoading(msg.param.viewTag, msg.param.url);
break;
case "onPageEnd":
nativeWebView.finishLoading(msg.param.viewTag, msg.param.url);
break;
case "onErrorReceive":
nativeWebView.failLoading(msg.param.viewTag, msg.param.url);
break;
case "onVideoEvent":
// @ts-ignore
if(globalThis.oh && typeof globalThis.oh.onVideoEvent === "function") {
// @ts-ignore
globalThis.oh.onVideoEvent(msg.param.videoTag, msg.param.videoEvent, msg.param.args);
}
break;
case "backPress":
appLifecycle.onBackPress();
break;
default:
hilog.info(0x0000, 'testTag', 'cocos worker: message type unknown:%{public}s', msg.name);
console.error("cocos worker: message type unknown");
break;
}
switch (msg.name) {
case "onXCLoad":
const renderContext = cocos.getContext(ContextType.NATIVE_RENDER_API);
renderContext.nativeEngineInit();
launchEngine().then(() => {
console.info('launch CC engine finished');
}).catch(e => {
console.error('launch CC engine failed');
});
// @ts-ignore
globalThis.oh.postMessage = nativeContext.postMessage;
// @ts-ignore
globalThis.oh.postSyncMessage = nativeContext.postSyncMessage;
renderContext.nativeEngineStart();
break;
case "onTextInput":
nativeEditBox.onTextChange(msg.param);
break;
case "onComplete":
nativeEditBox.onComplete(msg.param);
break;
case "onPageBegin":
nativeWebView.shouldStartLoading(msg.param.viewTag, msg.param.url);
break;
case "onPageEnd":
nativeWebView.finishLoading(msg.param.viewTag, msg.param.url);
break;
case "onErrorReceive":
nativeWebView.failLoading(msg.param.viewTag, msg.param.url);
break;
case "onVideoEvent":
// @ts-ignore
if (globalThis.oh && typeof globalThis.oh.onVideoEvent === "function") {
// @ts-ignore
globalThis.oh.onVideoEvent(msg.param.videoTag, msg.param.videoEvent, msg.param.args);
}
break;
case "backPress":
appLifecycle.onBackPress();
break;
default:
hilog.info(0x0000, 'testTag', 'cocos worker: message type unknown:%{public}s', msg.name);
console.error("cocos worker: message type unknown");
break;
}
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,27 @@
import { ContextType } from '../../../ets/common/Constants';
interface context {
onPageShow: () => void;
onPageHide: () => void;
workerInit: () => void;
postMessage: (msgType: string, msgData: string) => void;
postSyncMessage: (msgType: string, msgData: string) => Promise<boolean | string | number>;
setPostMessageFunction: (postMessage: (msgType: string, msgData: string) => void) => void;
setPostSyncMessageFunction: (postSyncMessage: (msgType: string, msgData: string) => void) => void;
nativeEngineInit: () => void;
nativeEngineStart: () => void;
onTextChange: (param: string) => void;
onComplete: (param: string) => void;
shouldStartLoading: (viewTag: number, url: string) => void;
finishLoading: (viewTag: number, url: string) => void;
failLoading: (viewTag: number, url: string) => void;
onBackPress: () => void;
onCreate: () => void;
onDestroy: () => void;
onShow: () => void;
onHide: () => void;
resourceManagerInit: (resourceManager: any) => void;
writablePathInit: (cacheDir: string) => void;
}
export const getContext: (type: ContextType) => context;

View File

@ -0,0 +1,6 @@
{
"name": "libcocos.so",
"types": "./index.d.ts",
"version": "",
"description": "Please describe the basic information."
}

View File

@ -24,31 +24,34 @@
****************************************************************************/
import worker from '@ohos.worker';
import {Constants} from '../common/Constants'
import { Constants } from '../common/Constants'
export class WorkerManager {
private static instance: WorkerManager;
private cocosWorker: any;
private cocosWorker: worker.Worker;
private constructor() {
this.cocosWorker = new worker.Worker("entry/ets/workers/cocos_worker.ts", {type:"classic", name: "CocosWorker"});
this.cocosWorker.onerror = function (e) {
var msg = e.message;
var filename = e.filename;
var lineno = e.lineno;
var colno = e.colno;
console.error(`on Error ${msg} ${filename} ${lineno} ${colno}`);
}
private constructor() {
this.cocosWorker = new worker.Worker("entry/ets/workers/cocos_worker.ts", {
type: "classic",
name: "CocosWorker"
});
this.cocosWorker.onerror = (e) => {
let msg = e.message;
let filename = e.filename;
let lineno = e.lineno;
let colno = e.colno;
console.error(`on Error ${msg} ${filename} ${lineno} ${colno}`);
}
}
public static getInstance(): WorkerManager {
if (AppStorage.Get(Constants.APP_KEY_WORKER_MANAGER) == null) {
AppStorage.SetOrCreate(Constants.APP_KEY_WORKER_MANAGER, new WorkerManager);
}
return AppStorage.Get(Constants.APP_KEY_WORKER_MANAGER);
}
public getWorker(): any {
return this.cocosWorker;
public static getInstance(): WorkerManager {
if (AppStorage.Get(Constants.APP_KEY_WORKER_MANAGER) as WorkerManager == undefined) {
AppStorage.SetOrCreate(Constants.APP_KEY_WORKER_MANAGER, new WorkerManager);
}
return AppStorage.Get(Constants.APP_KEY_WORKER_MANAGER) as WorkerManager;
}
public getWorker(): worker.Worker {
return this.cocosWorker;
}
}

View File

@ -1,4 +1,5 @@
globalThis.oh = {};
globalThis.oh = {} as any;
function boot() {
const cc = globalThis.cc;
var settings = globalThis._CCSettings;
@ -74,8 +75,8 @@ function boot() {
}
}
globalThis.oh.loadJsList(settings.jsList,cb);
globalThis.oh.loadJsList(settings.jsList, cb);
for (var i = 0; i < bundleRoot.length; i++) {
cc.assetManager.loadBundle(bundleRoot[i], cb);
}

View File

@ -11,4 +11,4 @@ globalThis.oh.loadModule = (name) => {
};
globalThis.oh.loadJsList = (jsList, cb) => {
globalThis.cc.assetManager.loadScript(jsList.map(function (x) { return x; }), cb);
};
};

View File

@ -21,57 +21,56 @@
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 worker from '@ohos.worker';
import {DedicatedWorkerGlobalScope} from '@ohos.worker';
// NOTE: don't use this import all statement, because this has compile issue.
// import * as wk from '@ohos.worker';
****************************************************************************/
import { DedicatedWorkerGlobalScope } from '@ohos.worker';
import { MessageEvent } from '@ohos.worker';
export class PortProxy {
private autoId: number = 0;
public actionHandleMap = {}
private port :DedicatedWorkerGlobalScope = null;
private autoId: number = 0;
public actionHandleMap = {}
private port: DedicatedWorkerGlobalScope = null;
public _messageHandle?:(e: MessageEvent<any>) => void;
public _messageHandle?: (e: MessageEvent<any>) => void;
constructor (port) {
this.port = port;
this.port.onmessage = this.onMessage.bind(this);
}
constructor(worker) {
this.port = worker;
this.port.onmessage = this.onMessage.bind(this);
}
public onMessage(e) {
let data = e['data'];
if(data.type != "syncResult" && this._messageHandle) {
this._messageHandle(e);
} else if(data.type == "syncResult") {
const {id, response} = data.data;
if (!this.actionHandleMap[id]) {
return;
}
this.actionHandleMap[id].call(this, response)
delete this.actionHandleMap[id];
}
}
public postReturnMessage(e:any, res: any) {
if(e.type == "sync" && res != null && res != undefined) {
this.port.postMessage({type:"syncResult", data:{id:e.data.cbId, response:res}});
}
}
public postMessage(msgName: string, msgData:any) {
this.port.postMessage({type:"async", data:{name:msgName, param:msgData}});
public onMessage(e) {
let data = e['data'];
if (data.type != "syncResult" && this._messageHandle) {
this._messageHandle(e);
} else if (data.type == "syncResult") {
const { id, response } = data.data;
if (!this.actionHandleMap[id]) {
return;
}
this.actionHandleMap[id].call(this, response);
delete this.actionHandleMap[id];
}
}
public postSyncMessage(msgName: string, msgData:any) {
const id = this.autoId++;
return new Promise((resolve, reject) => {
const message = {
type:"sync", data:{cbId:id, name:msgName, param:msgData}
}
this.port.postMessage(message);
this.actionHandleMap[id] = (response) => {
resolve(response)
}
})
public postReturnMessage(e: any, res: any) {
if (e.type == "sync" && res != null && res != undefined) {
this.port.postMessage({ type: "syncResult", data: { id: e.data.cbId, response: res } });
}
}
public postMessage(msgName: string, msgData: any) {
this.port.postMessage({ type: "async", data: { name: msgName, param: msgData } });
}
public postSyncMessage(msgName: string, msgData: any) {
const id = this.autoId++;
return new Promise((resolve, reject) => {
const message = {
type: "sync", data: { cbId: id, name: msgName, param: msgData }
}
this.port.postMessage(message);
this.actionHandleMap[id] = (response) => {
resolve(response)
}
})
}
}

View File

@ -21,9 +21,8 @@
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 { WorkerManager } from '../cocos/WorkerManager'
import { PortProxy } from '../common/PortProxy'
****************************************************************************/
import { PortProxy } from '../common/PortProxy';
enum EventType {
PLAYING = 0,
@ -35,7 +34,13 @@ enum EventType {
READY_TO_PLAY,
UPDATE,
QUIT_FULLSCREEN = 1000
};
}
interface param {
videoTag?: number,
videoEvent?: EventType,
args?: number
}
@Observed
export class VideoInfo {
@ -44,24 +49,21 @@ export class VideoInfo {
public w: number = 0;
public h: number = 0;
// url
public url: string | Resource = ""
public viewTag: string = ''
public visible: boolean = true
public url: string | Resource = "";
public viewTag: number = 0;
public visible: boolean = true;
public duration: number = 0;
public currentTime: number = 0;
public isFullScreen: boolean = false;
public currentProgressRate:number | string | PlaybackSpeed;
public currentProgressRate?: number | string | PlaybackSpeed;
public resourceType: number = 0;
/**
* https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-ts/ts-media-components-video.md#videocontroller
*
*/
public controller: VideoController = new VideoController()
constructor(x: number, y: number, w: number, h: number, viewTag: string) {
constructor(x: number, y: number, w: number, h: number, viewTag: number) {
this.x = x;
this.y = y;
this.w = w;
@ -70,49 +72,70 @@ export class VideoInfo {
}
}
@Component
export struct CocosVideoPlayer {
@ObjectLink videoInfo: VideoInfo;
public workPort: PortProxy;
public workPort: PortProxy | null = null;
build() {
Video({ src: this.videoInfo.url, controller: this.videoInfo.controller, currentProgressRate:this.videoInfo.currentProgressRate })
Video({
src: this.videoInfo.url,
controller: this.videoInfo.controller,
currentProgressRate: this.videoInfo.currentProgressRate as number | string | PlaybackSpeed
})
.position({ x: this.videoInfo.x, y: this.videoInfo.y })
.width(this.videoInfo.w)
.height(this.videoInfo.h)
.controls(false)
.autoPlay(false)
.onStart(() => {
this.workPort.postMessage("onVideoEvent",{videoTag:this.videoInfo.viewTag, videoEvent:EventType.PLAYING});
this.workPort?.postMessage("onVideoEvent", {
videoTag: this.videoInfo.viewTag as number,
videoEvent: EventType.PLAYING as EventType
} as param);
})
.onPause(() => {
this.workPort.postMessage("onVideoEvent",{videoTag:this.videoInfo.viewTag, videoEvent:EventType.PAUSED});
this.workPort?.postMessage("onVideoEvent", {
videoTag: this.videoInfo.viewTag as number,
videoEvent: EventType.PAUSED as EventType
} as param);
})
.onFinish(() => {
this.workPort.postMessage("onVideoEvent",{videoTag:this.videoInfo.viewTag, videoEvent:EventType.COMPLETED});
this.workPort?.postMessage("onVideoEvent", {
videoTag: this.videoInfo.viewTag,
videoEvent: EventType.COMPLETED
} as param);
})
.onPrepared((event: {
duration: number;
}) => {
this.videoInfo.duration = event.duration;
this.workPort.postMessage("onVideoEvent",{videoTag:this.videoInfo.viewTag, videoEvent:EventType.READY_TO_PLAY, args:event.duration});
.onPrepared((event): void => {
this.videoInfo.duration = event?.duration as number;
this.workPort?.postMessage("onVideoEvent", {
videoTag: this.videoInfo.viewTag,
videoEvent: EventType.READY_TO_PLAY,
args: event?.duration
} as param);
})
.onClick((event: ClickEvent) => {
this.workPort.postMessage("onVideoEvent",{videoTag:this.videoInfo.viewTag, videoEvent:EventType.CLICKED});
.onClick((event): void => {
this.workPort?.postMessage("onVideoEvent", {
videoTag: this.videoInfo.viewTag,
videoEvent: EventType.CLICKED
} as param);
})
.onUpdate((event?: {
time: number;
}) => {
this.videoInfo.currentTime = event.time
this.workPort.postMessage("onVideoEvent",{videoTag:this.videoInfo.viewTag, videoEvent:EventType.UPDATE, args:event.time});
.onUpdate((event) => {
this.videoInfo.currentTime = event?.time as number;
this.workPort?.postMessage("onVideoEvent", {
videoTag: this.videoInfo.viewTag,
videoEvent: EventType.UPDATE,
args: event?.time
} as param);
})
.onFullscreenChange((event?: {
fullscreen: boolean;
}) => {
if (!event.fullscreen) {
this.workPort.postMessage("onVideoEvent",{videoTag:this.videoInfo.viewTag, videoEvent:EventType.QUIT_FULLSCREEN});
.onFullscreenChange((event) => {
if (!event?.fullscreen) {
this.workPort?.postMessage("onVideoEvent", {
videoTag: this.videoInfo.viewTag,
videoEvent: EventType.QUIT_FULLSCREEN
} as param);
}
this.videoInfo.isFullScreen = event.fullscreen
this.videoInfo.isFullScreen = event?.fullscreen as boolean;
})
.visibility(this.videoInfo.visible ? Visibility.Visible : Visibility.None)
}

View File

@ -22,9 +22,14 @@
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
import { WorkerManager } from '../cocos/WorkerManager'
import { PortProxy } from '../common/PortProxy'
import web from '@ohos.web.webview'
import { PortProxy } from '../common/PortProxy';
import web from '@ohos.web.webview';
interface param {
viewTag: number,
url: string,
}
@Observed
export class WebViewInfo {
// position
@ -34,27 +39,26 @@ export class WebViewInfo {
public w: number = 0;
public h: number = 0;
// url
public url: string = ''
public url: string = '';
// tag
public viewTag: string = ''
public viewTag: number = 0;
// Whether to display
public visible: boolean = true
public visible: boolean = true;
/*
* doc : https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-web.md#webcontroller
*/
public controller: WebController = new WebController()
public controller: web.WebviewController = new web.WebviewController();
constructor(x: number, y: number, w: number, h: number, viewTag: string) {
constructor(x: number, y: number, w: number, h: number, viewTag: number) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.viewTag = viewTag;
web.once("webInited", ()=>{
if (this.url!= '') {
this.controller.loadUrl({url: this.url});
web.once("webInited", () => {
if (this.url != '') {
this.controller.loadUrl(this.url);
}
});
}
@ -63,33 +67,33 @@ export class WebViewInfo {
@Component
export struct CocosWebView {
@ObjectLink viewInfo: WebViewInfo;
public workPort: PortProxy;
public workPort: PortProxy | null = null;
build() {
Web({ src: "", controller: this.viewInfo.controller })
Web({ src: this.viewInfo.url, controller: this.viewInfo.controller })
.position({ x: this.viewInfo.x, y: this.viewInfo.y })
.width(this.viewInfo.w)
.height(this.viewInfo.h)
.border({ width: 1 })
.onPageBegin((event) => {
this.workPort.postMessage("onPageBegin", {viewTag:this.viewInfo.viewTag, url:event.url});
this.workPort?.postMessage("onPageBegin", {
viewTag: this.viewInfo.viewTag as number,
url: event?.url as string
} as param);
})
.onPageEnd((event) => {
this.workPort.postMessage("onPageEnd", {viewTag:this.viewInfo.viewTag, url:event.url})
this.workPort?.postMessage("onPageEnd", { viewTag: this.viewInfo.viewTag as number, url: event?.url as string } as param)
})
.onErrorReceive((event) => {
this.workPort.postMessage("onErrorReceive", {viewTag:this.viewInfo.viewTag, url:this.viewInfo.url})
this.workPort?.postMessage("onErrorReceive", { viewTag: this.viewInfo.viewTag as number, url: this.viewInfo.url as string } as param)
})
.onHttpErrorReceive((event) => {
this.workPort.postMessage("onErrorReceive", {viewTag:this.viewInfo.viewTag, url:this.viewInfo.url})
this.workPort?.postMessage("onErrorReceive", { viewTag: this.viewInfo.viewTag as number, url: this.viewInfo.url as string } as param)
})
// 开启DOM存储权限
.domStorageAccess(true)
// 开启数据库存储权限
.databaseAccess(true)
// 图片加载相关权限
.imageAccess(true)
// 支持JS代码运行
.javaScriptAccess(true)
.domStorageAccess(true)// enable DOM storage permissions
.databaseAccess(true)// enable database storage permissions
.imageAccess(true)// enable image loading permissions
.javaScriptAccess(true)// support JS code running
.visibility(this.viewInfo.visible ? Visibility.Visible : Visibility.None)
}
}

View File

@ -21,16 +21,16 @@
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.
****************************************************************************/
****************************************************************************/
@CustomDialog
export struct EditBoxDialog {
private showMessage: string = ''
private inputMessage: string = ''
onTextChange: (msg: string) => void
accept: (msg: string) => void
controller: CustomDialogController
cancel: () => void
confirm: () => void
onTextChange?: (msg: string) => void;
accept?: (msg: string) => void;
controller?: CustomDialogController;
cancel?: () => void;
confirm?: () => void;
build() {
Column() {
@ -48,14 +48,14 @@ export struct EditBoxDialog {
if (this.accept) {
this.accept(this.inputMessage);
}
this.controller.close();
this.controller?.close();
})
Blank(8).width(16)
Button('完成').onClick(() => {
if (this.accept) {
this.accept(this.inputMessage);
}
this.controller.close();
this.controller?.close();
})
}.padding({ left: 8, right: 8, top: 8, bottom: 8 })
.backgroundColor(Color.Gray)

View File

@ -1,6 +1,6 @@
import UIAbility from '@ohos.app.ability.UIAbility';
import cocos from "libcocos.so";
import { ContextType } from "../common/Constants"
import cocos from 'libcocos.so';
import { ContextType } from '../common/Constants';
import window from '@ohos.window';
const nativeContext = cocos.getContext(ContextType.ENGINE_UTILS);
@ -29,9 +29,9 @@ export default class EntryAbility extends UIAbility {
}
windowClass = data;
console.info('Succeeded in obtaining the main window. Data: ' + JSON.stringify(data));
// 设置窗口为全屏布局,配合设置导航栏、状态栏是否显示,与主窗口显示保持协调一致。
let isLayoutFullScreen= true;
let isLayoutFullScreen = true;
windowClass.setWindowLayoutFullScreen(isLayoutFullScreen, (err) => {
if (err.code) {
console.error('Failed to set the window layout to full-screen mode. Cause: ' + JSON.stringify(err));
@ -39,7 +39,7 @@ export default class EntryAbility extends UIAbility {
}
console.info('Succeeded in setting the window layout to full-screen mode.');
});
// 设置状态栏和导航栏是否显示。例如,需全部显示,该参数设置为['status', 'navigation'];不设置,则默认不显示。
let visibleBar = [];
windowClass.setWindowSystemBarEnable(visibleBar, (err) => {

View File

@ -21,227 +21,264 @@
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 nativerender from "libcocos.so";
****************************************************************************/
import nativerender from 'libcocos.so';
import { WorkerManager } from '../cocos/WorkerManager'
import { ContextType } from "../common/Constants"
import featureAbility from '@ohos.ability.featureAbility'
import { EditBoxDialog } from '../components/EditBoxDialog'
import { WebViewInfo, CocosWebView } from '../components/CocosWebView'
import { VideoInfo, CocosVideoPlayer } from '../components/CocosVideoPlayer'
import { WorkerManager } from '../cocos/WorkerManager';
import { ContextType } from '../common/Constants';
import { EditBoxDialog } from '../components/EditBoxDialog';
import { CocosWebView, WebViewInfo } from '../components/CocosWebView';
import { CocosVideoPlayer, VideoInfo } from '../components/CocosVideoPlayer';
import { MessageEvent } from '@ohos.worker';
import { PortProxy } from '../common/PortProxy';
import {PortProxy} from '../common/PortProxy'
const nativePageLifecycle = nativerender.getContext(ContextType.JSPAGE_LIFECYCLE);
const engineUtils = nativerender.getContext(ContextType.ENGINE_UTILS);
interface WorkerMessage {
type: string;
data: data;
}
interface data {
id: string,
name: string,
param: number | string | param
}
interface param {
tag?: number,
url?: string,
contents?: string,
mimeType?: string,
encoding?: string,
baseUrl?: string,
jsContents?: string,
x?: number,
y?: number,
w?: number,
h?: number,
visible?: boolean,
resourceType?: number,
time?: number,
fullScreen?: boolean
}
@Entry
@Component
struct Index {
@State showMessage: string = ''
@State webViewArray: WebViewInfo[] = [];
@State videoArray:VideoInfo[] = [];
//private index: number = 0;
private webViewIndexMap: Map<number, number> = new Map;
private videoIndexMap: Map<number, number> = new Map;
private workPort : PortProxy = new PortProxy(WorkerManager.getInstance().getWorker());
@State videoArray: VideoInfo[] = [];
private webViewIndexMap: Map<number, number> = new Map<number, number>();
private videoIndexMap: Map<number, number> = new Map<number, number>();
private workPort: PortProxy = new PortProxy(WorkerManager.getInstance().getWorker());
dialogController: CustomDialogController = new CustomDialogController({
builder: EditBoxDialog({
showMessage: this.showMessage,
onTextChange: (msg: string) => {
onTextChange: (msg: string): void => {
this.showMessage = msg;
this.workPort.postMessage('onTextInput', msg)
this.workPort.postMessage('onTextInput', msg);
},
accept: (msg: string) => {
accept: (msg: string): void => {
this.showMessage = msg;
this.workPort.postMessage('onComplete', msg)
},
this.workPort.postMessage('onComplete', msg);
}
}),
cancel: () => {
this.workPort.postMessage('onComplete', this.showMessage)
cancel: (): void => {
this.workPort.postMessage('onComplete', this.showMessage);
},
autoCancel: true,
alignment: DialogAlignment.Bottom,
customStyle: true,
})
aboutToAppear(): void {
aboutToAppear(): void {
console.log('[LIFECYCLE-Index] cocos aboutToAppear');
this.workPort._messageHandle = (e) => {
//let data = e['data'];
var data = e.data;
var msg = data.data;
var result;
this.workPort._messageHandle = async (e: MessageEvent<WorkerMessage>): Promise<void> => {
let data: WorkerMessage = e.data;
let msg = data.data;
let result: boolean | string | number | null = null;
switch (msg.name) {
// EditBox
// EditBox
case "showEditBox": {
this.showMessage = msg.param
this.dialogController.open()
this.showMessage = msg.param as string;
this.dialogController.open();
break;
}
case "hideEditBox": {
this.showMessage = ''
this.dialogController.close()
this.showMessage = '';
this.dialogController.close();
break;
}
// WebView
// WebView
case "createWebView": {
this.webViewArray.push(new WebViewInfo(0, 0, 0, 0, msg.param))
this.webViewIndexMap.set(msg.param, this.webViewArray.length - 1);
this.webViewArray.push(new WebViewInfo(0, 0, 0, 0, msg.param as number));
this.webViewIndexMap.set(msg.param as number, this.webViewArray.length - 1);
break;
}
case "removeWebView": {
if (this.webViewArray.length > 0) {
this.webViewArray.splice(this.webViewIndexMap.get(msg.param), 1)
this.webViewArray.splice(this.webViewIndexMap.get(msg?.param as number) as number, 1);
}
break;
}
case "loadUrl": {
var web = msg.param;
var index = this.webViewIndexMap.get(web.tag);
this.webViewArray[index].url = web.url;
this.webViewArray[index].controller.loadUrl({url: web.url});
let web = msg.param as param;
let index = this.webViewIndexMap.get(web?.tag as number) as number;
this.webViewArray[index].url = web?.url as string;
this.webViewArray[index].controller.loadUrl(web?.url as string);
break;
}
case "loadHTMLString": {
var web = msg.param;
var index = this.webViewIndexMap.get(web.tag);
this.webViewArray[index].controller.loadData({data: web.contents, mimeType:"text/html",encoding:"UTF-8", baseUrl:web.baseUrl});
let web = msg.param as param;
let index = this.webViewIndexMap.get(web?.tag as number) as number;
this.webViewArray[index].controller.loadData(
web?.contents as string,
"text/html",
"UTF-8",
web?.baseUrl
);
break;
}
case "loadData": {
var web = msg.param;
var index = this.webViewIndexMap.get(web.tag);
this.webViewArray[index].controller.loadData({data: web.contents, mimeType:web.mimeType,encoding:web.encoding, baseUrl:web.baseUrl});
let web = msg.param as param;
let index = this.webViewIndexMap.get(web?.tag as number) as number;
this.webViewArray[index].controller.loadData(
web?.contents as string,
web?.mimeType as string,
web?.encoding as string,
web?.baseUrl as string
);
break;
}
case "evaluateJS": {
var web = msg.param;
var index = this.webViewIndexMap.get(web.tag)
this.webViewArray[index].controller.runJavaScript({
script: web.jsContents
});
let web = msg.param as param;
let index = this.webViewIndexMap.get(web?.tag as number) as number;
this.webViewArray[index].controller.runJavaScript(web?.jsContents as string);
break;
}
case "reload": {
var index = this.webViewIndexMap.get(msg.param);
let index = this.webViewIndexMap.get(msg.param as number) as number;
this.webViewArray[index].controller.refresh();
break;
}
case "stopLoading": {
var index = this.webViewIndexMap.get(msg.param);
let index = this.webViewIndexMap.get(msg.param as number) as number;
this.webViewArray[index].controller.stop();
break;
}
case "canGoForward": {
var index = this.webViewIndexMap.get(msg.param);
let index = this.webViewIndexMap.get(msg.param as number) as number;
result = this.webViewArray[index].controller.accessForward();
break;
}
case "canGoBack": {
var index = this.webViewIndexMap.get(msg.param);
let index = this.webViewIndexMap.get(msg.param as number) as number;
result = this.webViewArray[index].controller.accessBackward();
break;
}
case "goForward": {
var index = this.webViewIndexMap.get(msg.param);
let index = this.webViewIndexMap.get(msg.param as number) as number;
this.webViewArray[index].controller.forward();
break;
}
case "goBack": {
var index = this.webViewIndexMap.get(msg.param);
let index = this.webViewIndexMap.get(msg.param as number) as number;
this.webViewArray[index].controller.backward();
break;
}
case "setWebViewRect": {
var web = msg.param;
var index = this.webViewIndexMap.get(web.tag);
this.webViewArray[index].x = px2vp(web.x);
this.webViewArray[index].y = px2vp(web.y);
this.webViewArray[index].w = px2vp(web.w);
this.webViewArray[index].h = px2vp(web.h);
let web = msg.param as param
let index = this.webViewIndexMap.get(web?.tag as number) as number;
this.webViewArray[index].x = px2vp(web?.x as number) as number;
this.webViewArray[index].y = px2vp(web?.y as number) as number;
this.webViewArray[index].w = px2vp(web?.w as number) as number;
this.webViewArray[index].h = px2vp(web?.h as number) as number;
break;
}
case "setVisible":
var web = msg.param;
var index = this.webViewIndexMap.get(web.tag);
this.webViewArray[index].visible = web.visible;
case "setVisible": {
let web = msg.param as param;
let index = this.webViewIndexMap.get(web?.tag as number) as number;
this.webViewArray[index].visible = web?.visible as boolean;
break;
// video
case "createVideo":
this.videoArray.push(new VideoInfo(0, 0, 0, 0, msg.param))
this.videoIndexMap.set(msg.param, this.videoArray.length - 1);
}
// video
case "createVideo": {
this.videoArray.push(new VideoInfo(0, 0, 0, 0, msg.param as number));
this.videoIndexMap.set(msg.param as number, this.videoArray.length - 1);
break;
case "removeVideo":
}
case "removeVideo": {
if (this.videoArray.length > 0) {
this.videoArray.splice(this.videoIndexMap.get(msg.param), 1)
this.videoArray.splice(this.videoIndexMap.get(msg.param as number) as number, 1);
}
break;
}
case "setVideoUrl":
var video = msg.param;
var index = this.videoIndexMap.get(video.tag);
var resourceType = video.resourceType;
let video = msg.param as param;
let index = this.videoIndexMap.get(video?.tag as number) as number;
let resourceType = video.resourceType;
if (resourceType == 1) {
this.videoArray[index].url = $rawfile(video.url);
this.videoArray[index].url = $rawfile(video.url as string);
} else {
this.videoArray[index].url = video.url;
this.videoArray[index].url = video.url as string;
}
break;
case "setVideoRect": {
var video = msg.param;
var index = this.videoIndexMap.get(video.tag);
this.videoArray[index].x = px2vp(video.x);
this.videoArray[index].y = px2vp(video.y);
this.videoArray[index].w = px2vp(video.w);
this.videoArray[index].h = px2vp(video.h);
let video = msg.param as param;
let index = this.videoIndexMap.get(video?.tag as number) as number;
this.videoArray[index].x = px2vp(video?.x as number) as number;
this.videoArray[index].y = px2vp(video?.y as number) as number;
this.videoArray[index].w = px2vp(video?.w as number) as number;
this.videoArray[index].h = px2vp(video?.h as number) as number;
break;
}
case "startVideo": {
var index = this.videoIndexMap.get(msg.param);
let index = this.videoIndexMap.get(msg.param as number) as number;
this.videoArray[index].controller.start();
break;
}
case "pauseVideo" : {
var index = this.videoIndexMap.get(msg.param);
case "pauseVideo": {
let index = this.videoIndexMap.get(msg.param as number) as number;
this.videoArray[index].controller.pause();
break;
}
case "stopVideo" : {
var index = this.videoIndexMap.get(msg.param);
case "stopVideo": {
let index = this.videoIndexMap.get(msg.param as number) as number;
this.videoArray[index].controller.stop();
break;
}
case "resumeVideo": {
var index = this.videoIndexMap.get(msg.param);
let index = this.videoIndexMap.get(msg.param as number) as number;
this.videoArray[index].controller.start();
break;
}
case "getVideoDuration": {
var index = this.videoIndexMap.get(msg.param);
let index = this.videoIndexMap.get(msg.param as number) as number;
result = this.videoArray[index].duration;
break;
}
case "seekVideoTo" : {
var video = msg.param;
var index = this.videoIndexMap.get(video.tag);
this.videoArray[index].controller.setCurrentTime(video.time, SeekMode.Accurate);
case "seekVideoTo": {
let video = msg.param as param;
let index = this.videoIndexMap.get(video?.tag as number) as number;
this.videoArray[index].controller.setCurrentTime(video?.time as number, SeekMode.Accurate);
break;
}
case "setVideoVisible" : {
var video = msg.param;
var index = this.videoIndexMap.get(video.tag);
this.videoArray[index].visible = video.visible;
case "setVideoVisible": {
let video = msg.param as param;
let index = this.videoIndexMap.get(video?.tag as number) as number;
this.videoArray[index].visible = video.visible as boolean;
break;
}
case "setFullScreenEnabled": {
var video = msg.param;
var index = this.videoIndexMap.get(video.tag);
this.videoArray[index].isFullScreen = video.fullScreen;
let video = msg.param as param;
let index = this.videoIndexMap.get(video?.tag as number) as number;
this.videoArray[index].isFullScreen = video.fullScreen as boolean;
break;
}
case "currentTime": {
var index = this.videoIndexMap.get(msg.param);
let index = this.videoIndexMap.get(msg.param as number) as number;
result = this.videoArray[index].currentTime;
break;
}
@ -257,16 +294,16 @@ struct Index {
aboutToDisappear(): void {
console.log('[LIFECYCLE-Index] cocos aboutToDisappear');
// this.cocosWorker.postMessage({type: "JSPageLifecycle", data: "aboutToAppear"});
// nativePageLifecycle.aboutToDisappear();
// this.cocosWorker.postMessage({type: "JSPageLifecycle", data: "aboutToAppear"});
// nativePageLifecycle.aboutToDisappear();
}
onPageShow(): void {
onPageShow(): void {
console.log('[LIFECYCLE-Page] cocos onPageShow');
nativePageLifecycle.onPageShow();
}
onPageHide(): void {
onPageHide(): void {
console.log('[LIFECYCLE-Page] cocos onPageHide');
nativePageLifecycle.onPageHide();
}
@ -279,8 +316,12 @@ struct Index {
}
build() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
XComponent({ id: 'xcomponentId', type: 'surface', libraryname: 'cocos'})
Flex({
direction: FlexDirection.Column,
alignItems: ItemAlign.Center,
justifyContent: FlexAlign.Center
} as FlexOptions) {
XComponent({ id: 'xcomponentId', type: 'surface', libraryname: 'cocos' })
.onLoad((context) => {
// Set the cache directory in the ts layer.
this.workPort.postMessage("onXCLoad", "XComponent");
@ -289,13 +330,13 @@ struct Index {
console.log('cocos onDestroy')
})
ForEach(this.webViewArray, (item: WebViewInfo, index: number) => {
CocosWebView({ viewInfo: item, workPort: this.workPort})
}, item => item.viewTag)
ForEach(this.webViewArray, (item: WebViewInfo) => {
CocosWebView({ viewInfo: item, workPort: this.workPort })
}, (item: WebViewInfo): string => item.viewTag.toString())
ForEach(this.videoArray, (item: VideoInfo, index: number) => {
CocosVideoPlayer({ videoInfo: item, workPort: this.workPort})
}, item => item.viewTag)
ForEach(this.videoArray, (item: VideoInfo) => {
CocosVideoPlayer({ videoInfo: item, workPort: this.workPort })
}, (item: VideoInfo): string => item.viewTag.toString())
}
.width('100%')
.height('100%')

View File

@ -22,16 +22,15 @@ import hilog from '@ohos.hilog';
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 worker from '@ohos.worker';
import cocos from "libcocos.so";
import { ContextType } from "../common/Constants"
import { launchEngine } from '../cocos/game'
import cocos from 'libcocos.so';
import { ContextType } from '../common/Constants';
import { launchEngine } from '../cocos/game';
import { PortProxy } from '../common/PortProxy';
const nativeContext = cocos.getContext(ContextType.WORKER_INIT);
nativeContext.workerInit()
nativeContext.workerInit();
const nativeEditBox = cocos.getContext(ContextType.EDITBOX_UTILS);
const nativeWebView = cocos.getContext(ContextType.WEBVIEW_UTILS);
@ -39,73 +38,66 @@ const appLifecycle = cocos.getContext(ContextType.APP_LIFECYCLE);
let uiPort = new PortProxy(worker.parentPort);
nativeContext.postMessage = function(msgType: string, msgData:string) {
uiPort.postMessage(msgType, msgData);
nativeContext.postMessage = function (msgType: string, msgData: string): void {
uiPort.postMessage(msgType, msgData);
}
nativeContext.postSyncMessage = async function(msgType: string, msgData:string) {
const result = await uiPort.postSyncMessage(msgType, msgData);
return result;
nativeContext.postSyncMessage = async function (msgType: string, msgData: string): Promise<boolean | string | number> {
const result = await uiPort.postSyncMessage(msgType, msgData) as boolean | string | number;
return result;
}
// The purpose of this is to avoid being GC
nativeContext.setPostMessageFunction.call(nativeContext, nativeContext.postMessage)
nativeContext.setPostSyncMessageFunction.call(nativeContext, nativeContext.postSyncMessage)
uiPort._messageHandle = function(e) {
var data = e.data;
var msg = data.data;
hilog.info(0x0000, 'testTag',msg.name,msg.param);
uiPort._messageHandle = function (e) {
var data = e.data;
var msg = data.data;
switch(msg.name) {
case "onXCLoad":
hilog.info(0x0000, 'testTag', '%{public}s', '_messageHandle onXCLoad');
console.info("cocos worker:_messageHandle onXCLoad");
const renderContext = cocos.getContext(ContextType.NATIVE_RENDER_API);
renderContext.nativeEngineInit();
hilog.info(0x0000, 'testTag', '%{public}s', 'begin invoke launchEngine');
launchEngine().then(() => {
hilog.info(0x0000, 'testTag', '%{public}s', 'launch CC engine finished');
console.info('launch CC engine finished');
}).catch(e => {
hilog.info(0x0000, 'testTag', '%{public}s', 'launch CC engine failed');
console.error('launch CC engine failed');
});
// @ts-ignore
globalThis.oh.postMessage = nativeContext.postMessage;
// @ts-ignore
globalThis.oh.postSyncMessage = nativeContext.postSyncMessage;
renderContext.nativeEngineStart();
break;
case "onTextInput":
nativeEditBox.onTextChange(msg.param);
break;
case "onComplete":
nativeEditBox.onComplete(msg.param);
break;
case "onPageBegin":
nativeWebView.shouldStartLoading(msg.param.viewTag, msg.param.url);
break;
case "onPageEnd":
nativeWebView.finishLoading(msg.param.viewTag, msg.param.url);
break;
case "onErrorReceive":
nativeWebView.failLoading(msg.param.viewTag, msg.param.url);
break;
case "onVideoEvent":
// @ts-ignore
if(globalThis.oh && typeof globalThis.oh.onVideoEvent === "function") {
// @ts-ignore
globalThis.oh.onVideoEvent(msg.param.videoTag, msg.param.videoEvent, msg.param.args);
}
break;
case "backPress":
appLifecycle.onBackPress();
break;
default:
hilog.info(0x0000, 'testTag', 'cocos worker: message type unknown:%{public}s', msg.name);
console.error("cocos worker: message type unknown");
break;
}
switch (msg.name) {
case "onXCLoad":
const renderContext = cocos.getContext(ContextType.NATIVE_RENDER_API);
renderContext.nativeEngineInit();
launchEngine().then(() => {
console.info('launch CC engine finished');
}).catch(e => {
console.error('launch CC engine failed');
});
// @ts-ignore
globalThis.oh.postMessage = nativeContext.postMessage;
// @ts-ignore
globalThis.oh.postSyncMessage = nativeContext.postSyncMessage;
renderContext.nativeEngineStart();
break;
case "onTextInput":
nativeEditBox.onTextChange(msg.param);
break;
case "onComplete":
nativeEditBox.onComplete(msg.param);
break;
case "onPageBegin":
nativeWebView.shouldStartLoading(msg.param.viewTag, msg.param.url);
break;
case "onPageEnd":
nativeWebView.finishLoading(msg.param.viewTag, msg.param.url);
break;
case "onErrorReceive":
nativeWebView.failLoading(msg.param.viewTag, msg.param.url);
break;
case "onVideoEvent":
// @ts-ignore
if (globalThis.oh && typeof globalThis.oh.onVideoEvent === "function") {
// @ts-ignore
globalThis.oh.onVideoEvent(msg.param.videoTag, msg.param.videoEvent, msg.param.args);
}
break;
case "backPress":
appLifecycle.onBackPress();
break;
default:
hilog.info(0x0000, 'testTag', 'cocos worker: message type unknown:%{public}s', msg.name);
console.error("cocos worker: message type unknown");
break;
}
}

View File

@ -46,6 +46,15 @@ xcuserdata/
DerivedData/
.idea/*
# Ignore the files from download
bin/sdkbox*
plugins/plugin_compile/build_web/bin
plugins/plugin_jscompile/
plugins/plugin_luacompile/bin/msvcr110.dll
plugins/plugin_generate/proj_modifier/plutil-win32/
version.json
v*-console-*.zip
# vim
*~

View File

@ -404,7 +404,7 @@ class CCPlugin(object):
if os.path.isdir(cocos2dx_path):
return cocos2dx_path
if cls.get_cocos2d_mode() is not "distro":
if cls.get_cocos2d_mode() != "distro":
# In 'distro' mode this is not a warning since
# the source code is not expected to be installed
Logging.warning(MultiLanguage.get_string('COCOS_WARNING_ENGINE_NOT_FOUND'))
@ -940,7 +940,7 @@ def _check_python_version():
ret = False
if not ret:
print(MultiLanguage.get_string('COCOS_PYTHON_VERSION_TIP_FMT') % (major_ver, minor_ver))
print(str('COCOS PYTHON VERSION DOES NOT MATCH: %d.%d, WHILE 2.7+ IS REQUIRED') % (major_ver, minor_ver))
return ret

View File

@ -525,6 +525,12 @@ class AndroidBuilder(object):
if match:
package = match.group(1)
break
else :
pattern = r'namespace[ \t]+[\'\"](.*)[\'\"]'
match = re.match(pattern, line_str)
if match:
package = match.group(1)
break
if package is None:
# get package name from AndroidManifest.xml
package = self._xml_attr(manifest_path, 'AndroidManifest.xml', 'manifest', 'package')

View File

@ -38,7 +38,7 @@
PLAYER_NS_BEGIN
class CC_LIBSIM_DLL PlayerWin : public PlayerProtocol, public cocos2d::Ref
class CC_LIBSIM_DLL PlayerWin : public cocos2d::Ref, public PlayerProtocol
{
public:
static PlayerWin *createWithHwnd(HWND hWnd);

View File

@ -43,6 +43,7 @@ let LabelOutline = cc.Class({
extends: require('./CCComponent'),
editor: CC_EDITOR && {
menu: 'i18n:MAIN_MENU.component.renderers/LabelOutline',
help: 'i18n:COMPONENT.help_url.labelOutline',
executeInEditMode: true,
requireComponent: cc.Label,
},

View File

@ -43,6 +43,7 @@ let LabelShadow = cc.Class({
extends: require('./CCComponent'),
editor: CC_EDITOR && {
menu: 'i18n:MAIN_MENU.component.renderers/LabelShadow',
help: 'i18n:COMPONENT.help_url.labelShadow',
executeInEditMode: true,
requireComponent: cc.Label,
},

View File

@ -5,6 +5,8 @@ module.exports = {
"animation": "https://docs.cocos.com/creator/2.4/manual/en/components/animation.html",
"sprite": "https://docs.cocos.com/creator/2.4/manual/en/components/sprite.html",
"label": "https://docs.cocos.com/creator/2.4/manual/en/components/label.html",
"labelOutline": "https://docs.cocos.com/creator/2.4/manual/en/components/label-outline.html",
"labelShadow": "https://docs.cocos.com/creator/2.4/manual/en/components/label-shadow.html",
"canvas": "https://docs.cocos.com/creator/2.4/manual/en/components/canvas.html",
"spine": "https://docs.cocos.com/creator/2.4/manual/en/components/spine.html",
"widget": "https://docs.cocos.com/creator/2.4/manual/en/components/widget.html",

View File

@ -5,6 +5,8 @@ module.exports = {
"animation": "https://docs.cocos.com/creator/2.4/manual/zh/components/animation.html",
"sprite": "https://docs.cocos.com/creator/2.4/manual/zh/components/sprite.html",
"label": "https://docs.cocos.com/creator/2.4/manual/zh/components/label.html",
"labelOutline": "https://docs.cocos.com/creator/2.4/manual/zh/components/label-outline.html",
"labelShadow": "https://docs.cocos.com/creator/2.4/manual/zh/components/label-shadow.html",
"canvas": "https://docs.cocos.com/creator/2.4/manual/zh/components/canvas.html",
"spine": "https://docs.cocos.com/creator/2.4/manual/zh/components/spine.html",
"widget": "https://docs.cocos.com/creator/2.4/manual/zh/components/widget.html",

View File

@ -12631,6 +12631,7 @@ var dragonBones;
var rawTimeline = rawTimelines_3[_b];
this._parseSlotTimeline(rawTimeline);
}
this._actionFrames.sort((a, b) => { return a.frameStart - b.frameStart; });
}
if (dragonBones.DataParser.FFD in rawData) {
var rawTimelines = rawData[dragonBones.DataParser.FFD];

View File

@ -1,6 +1,6 @@
{
"name": "cocos-creator-js",
"version": "2.4.12",
"version": "2.4.13",
"description": "Cocos Creator is a complete package of game development tools and workflow, including a game engine, resource management, scene editing, game preview, debug and publish one project to multiple platforms.",
"homepage": "https://www.cocos.com",
"license": "MIT",

View File

@ -211,5 +211,5 @@ if (CC_DEV) {
* If you post a bug to forum, please attach this flag.
* @property {String} ENGINE_VERSION
*/
const engineVersion = '2.4.12';
const engineVersion = '2.4.13';
_global['CocosEngine'] = cc.ENGINE_VERSION = engineVersion;

View File

@ -354,8 +354,8 @@ const cacheManager = require('./jsb-cache-manager');
}
if (this._nativeSkeleton) {
this._nativeSkeleton.stopSchedule();
this._nativeSkeleton._comp = null;
this._nativeSkeleton.destroy();
this._nativeSkeleton = null;
}
@ -763,8 +763,8 @@ const cacheManager = require('./jsb-cache-manager');
this.animation = this.defaultAnimation;
} else {
if (this._nativeSkeleton) {
this._nativeSkeleton.stopSchedule();
this._nativeSkeleton._comp = null;
this._nativeSkeleton.destroy();
this._nativeSkeleton = null;
}
}
@ -774,8 +774,8 @@ const cacheManager = require('./jsb-cache-manager');
skeleton.onDestroy = function(){
_onDestroy.call(this);
if (this._nativeSkeleton) {
this._nativeSkeleton.stopSchedule();
this._nativeSkeleton._comp = null;
this._nativeSkeleton.destroy();
this._nativeSkeleton = null;
}
this._stateData = null;

View File

@ -35,7 +35,7 @@
var _topLeft = new vec3();
var _bottomRight = new vec3();
let kWebViewTag = 0;
let kVideoTag = 0;
let videoPlayers = [];
const VideoEvent = {
PLAYING: 0,
@ -143,6 +143,16 @@
video.setVisible(false)
let cbs = this.__eventListeners;
video.removeEventListener("loadedmetadata", cbs.loadedmetadata);
video.removeEventListener("ended", cbs.ended);
video.removeEventListener("play", cbs.play);
video.removeEventListener("pause", cbs.pause);
video.removeEventListener("click", cbs.click);
video.removeEventListener("canplay", cbs.onCanPlay);
video.removeEventListener("canplaythrough", cbs.onCanPlay);
video.removeEventListener("suspend", cbs.onCanPlay);
cbs.loadedmetadata = null;
cbs.ended = null;
cbs.play = null;
@ -218,7 +228,7 @@
let video = this._video;
if (!video || !this._visible) return;
// TODO(qgh) : In the openharmony platform, there is no stop event when the video stops, instead a pause event is sent.
// We can't ignore the pause event here.
// We can't ignore the pause event here.
// this._ignorePause = true;
video.seekTo(0);
video.stop();
@ -480,7 +490,7 @@
this._events = {};
this._currentTime = 0;
this._duration = 0;
this._videoIndex = kWebViewTag++;
this._videoIndex = kVideoTag++;
this._matViewProj_temp = new mat4();
window.oh.postMessage("createVideo", this._videoIndex);
videoPlayers.push(this);