/**************************************************************************** Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ****************************************************************************/ #include #include "base/DeferredReleasePool.h" #include "base/TemplateUtils.h" #include "base/Value.h" #include "cocos/base/RefMap.h" #include "cocos/base/RefVector.h" #include "cocos/core/TypedArray.h" #include "cocos/editor-support/middleware-adapter.h" #include "cocos/math/Geometry.h" #include "cocos/math/Quaternion.h" #include "cocos/math/Vec2.h" #include "cocos/math/Vec3.h" #include "core/ArrayBuffer.h" #include "core/assets/ImageAsset.h" #include "core/assets/TextureCube.h" #include "core/geometry/AABB.h" #include "extensions/cocos-ext.h" #include "jsb_conversions.h" #include "network/Downloader.h" #include "bindings/auto/jsb_assets_auto.h" #include "bindings/auto/jsb_cocos_auto.h" #if CC_USE_PHYSICS_PHYSX #include "bindings/auto/jsb_physics_auto.h" #endif #include "cocos/core/geometry/Geometry.h" #include "scene/Fog.h" #include "scene/Shadow.h" #include "scene/Skybox.h" #if CC_USE_SPINE #include "cocos/editor-support/spine-creator-support/Vector2.h" #endif ///////////////////////// utils ///////////////////////// #define CHECK_ASSIGN_PRVOBJ_RET(jsObj, nativeObj) \ se::PrivateObjectBase *_privateObjL = jsObj->getPrivateObject(); \ if (_privateObjL) { \ using target_type = typename std::decay::type; \ *nativeObj = *_privateObjL->get(); \ return true; \ } template typename std::enable_if::value, bool>::type set_member_field(se::Object *obj, T *to, const ccstd::string &property, F f, se::Value &tmp) { // NOLINT bool ok = obj->getProperty(property.data(), &tmp, true); SE_PRECONDITION2(ok, false, "Property '%s' is not set", property.data()); A m; ok = sevalue_to_native(tmp, &m, obj); SE_PRECONDITION2(ok, false, "Convert property '%s' failed", property.data()); (to->*f)(m); return true; } template typename std::enable_if::value, bool>::type set_member_field(se::Object *obj, T *to, const ccstd::string &property, F f, se::Value &tmp) { // NOLINT bool ok = obj->getProperty(property.data(), &tmp, true); SE_PRECONDITION2(ok, false, "Property '%s' is not set", property.data()); ok = sevalue_to_native(tmp, &(to->*f), obj); SE_PRECONDITION2(ok, false, "Convert property '%s' failed", property.data()); return true; } static bool isNumberString(const ccstd::string &str) { for (const auto &c : str) { // NOLINT(readability-use-anyofallof) // remove after using c++20 if (!isdigit(c)) { return false; } } return true; } namespace { enum class DataType { INT, FLOAT }; enum class MathType { VEC2 = 0, VEC3, VEC4, QUATERNION, MAT3, MAT4, SIZE, RECT, COLOR, }; } // namespace bool Vec2_to_seval(const cc::Vec2 &v, se::Value *ret) { // NOLINT(readability-identifier-naming) return ret ? nativevalue_to_se(v, *ret, nullptr) : false; } bool Vec3_to_seval(const cc::Vec3 &v, se::Value *ret) { // NOLINT(readability-identifier-naming) return ret ? nativevalue_to_se(v, *ret, nullptr) : false; } bool Vec4_to_seval(const cc::Vec4 &v, se::Value *ret) { // NOLINT(readability-identifier-naming) return ret ? nativevalue_to_se(v, *ret, nullptr) : false; } bool Mat4_to_seval(const cc::Mat4 &v, se::Value *ret) { // NOLINT(readability-identifier-naming) CC_ASSERT_NOT_NULL(ret); se::HandleObject obj(se::Object::createArrayObject(16)); for (uint8_t i = 0; i < 16; ++i) { obj->setArrayElement(i, se::Value(v.m[i])); } obj->setProperty("type", se::Value(static_cast(MathType::MAT4))); ret->setObject(obj); return true; } bool Size_to_seval(const cc::Size &v, se::Value *ret) { // NOLINT(readability-identifier-naming) return ret ? nativevalue_to_se(v, *ret, nullptr) : false; } bool Rect_to_seval(const cc::Rect &v, se::Value *ret) { // NOLINT(readability-identifier-naming) return ret ? nativevalue_to_se(v, *ret, nullptr) : false; } //////////////////////////////////////////////////////////////////////////// /////////////////sevalue to native////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// // NOLINTNEXTLINE(readability-identifier-naming) bool seval_to_ccvalue(const se::Value &v, cc::Value *ret) { // NOLINT return sevalue_to_native(v, ret, nullptr); } bool sevalue_to_native(const se::Value &from, cc::Value *to, se::Object * /*ctx*/) { // NOLINT CC_ASSERT_NOT_NULL(to); bool ok = true; if (from.isObject()) { se::Object *jsobj = from.toObject(); if (!jsobj->isArray()) { // It's a normal js object. cc::ValueMap dictVal; ok = sevalue_to_native(from, &dictVal, nullptr); SE_PRECONDITION3(ok, false, *to = cc::Value::VALUE_NULL); *to = cc::Value(dictVal); } else { // It's a js array object. cc::ValueVector arrVal; ok = sevalue_to_native(from, &arrVal, nullptr); SE_PRECONDITION3(ok, false, *to = cc::Value::VALUE_NULL); *to = cc::Value(arrVal); } } else if (from.isString()) { *to = from.toString(); } else if (from.isNumber()) { *to = from.toDouble(); } else if (from.isBoolean()) { *to = from.toBoolean(); } else if (from.isNullOrUndefined()) { *to = cc::Value::VALUE_NULL; } else { SE_PRECONDITION2(false, false, "type not supported!"); } return ok; } // NOLINTNEXTLINE(readability-identifier-naming) bool seval_to_ccvaluemap(const se::Value &v, cc::ValueMap *ret) { // NOLINT return sevalue_to_native(v, ret, nullptr); } bool sevalue_to_native(const se::Value &from, cc::ValueMap *to, se::Object * /*ctx*/) { // NOLINT CC_ASSERT_NOT_NULL(to); if (from.isNullOrUndefined()) { to->clear(); return true; } SE_PRECONDITION3(from.isObject(), false, to->clear()); SE_PRECONDITION3(!from.isNullOrUndefined(), false, to->clear()); se::Object *obj = from.toObject(); cc::ValueMap &dict = *to; ccstd::vector allKeys; SE_PRECONDITION3(obj->getAllKeys(&allKeys), false, to->clear()); bool ok = false; se::Value value; cc::Value ccvalue; for (const auto &key : allKeys) { SE_PRECONDITION3(obj->getProperty(key.c_str(), &value), false, to->clear()); ok = sevalue_to_native(value, &ccvalue, nullptr); SE_PRECONDITION3(ok, false, to->clear()); dict.emplace(key, ccvalue); } return true; } // NOLINTNEXTLINE(readability-identifier-naming) bool seval_to_ccvaluemapintkey(const se::Value &v, cc::ValueMapIntKey *ret) { CC_ASSERT_NOT_NULL(ret); if (v.isNullOrUndefined()) { ret->clear(); return true; } SE_PRECONDITION3(v.isObject(), false, ret->clear()); SE_PRECONDITION3(!v.isNullOrUndefined(), false, ret->clear()); se::Object *obj = v.toObject(); cc::ValueMapIntKey &dict = *ret; ccstd::vector allKeys; SE_PRECONDITION3(obj->getAllKeys(&allKeys), false, ret->clear()); bool ok = false; se::Value value; cc::Value ccvalue; for (const auto &key : allKeys) { SE_PRECONDITION3(obj->getProperty(key.c_str(), &value), false, ret->clear()); if (!isNumberString(key)) { SE_LOGD("seval_to_ccvaluemapintkey, found not numeric key: %s", key.c_str()); continue; } int intKey = atoi(key.c_str()); ok = seval_to_ccvalue(value, &ccvalue); SE_PRECONDITION3(ok, false, ret->clear()); dict.emplace(intKey, ccvalue); } return true; } // NOLINTNEXTLINE(readability-identifier-naming) bool seval_to_ccvaluevector(const se::Value &v, cc::ValueVector *ret) { // NOLINT CC_ASSERT_NOT_NULL(ret); SE_PRECONDITION3(v.isObject(), false, ret->clear()); se::Object *obj = v.toObject(); SE_PRECONDITION3(obj->isArray(), false, ret->clear()); uint32_t len = 0; obj->getArrayLength(&len); bool ok = false; se::Value value; cc::Value ccvalue; for (uint32_t i = 0; i < len; ++i) { if (obj->getArrayElement(i, &value)) { ok = seval_to_ccvalue(value, &ccvalue); SE_PRECONDITION3(ok, false, ret->clear()); ret->push_back(ccvalue); } } return true; } // NOLINTNEXTLINE(readability-identifier-naming) bool sevals_variadic_to_ccvaluevector(const se::ValueArray &args, cc::ValueVector *ret) { bool ok = false; cc::Value ccvalue; for (const auto &arg : args) { ok = seval_to_ccvalue(arg, &ccvalue); SE_PRECONDITION3(ok, false, ret->clear()); ret->push_back(ccvalue); } return true; } // NOLINTNEXTLINE(readability-identifier-naming) bool seval_to_Data(const se::Value &v, cc::Data *ret) { return sevalue_to_native(v, ret, nullptr); } bool sevalue_to_native(const se::Value &v, cc::Data *ret, se::Object * /*ctx*/) { // NOLINT CC_ASSERT_NOT_NULL(ret); SE_PRECONDITION2(v.isObject() && (v.toObject()->isTypedArray() || v.toObject()->isArrayBuffer()), false, "Convert parameter to Data failed!"); uint8_t *ptr = nullptr; size_t length = 0; se::Object *buffer = v.toObject(); bool ok = false; if (buffer->isTypedArray()) { ok = buffer->getTypedArrayData(&ptr, &length); } else { ok = buffer->getArrayBufferData(&ptr, &length); } if (ok) { ret->copy(ptr, static_cast(length)); } else { ret->clear(); } return ok; } // NOLINTNEXTLINE(readability-identifier-naming) bool seval_to_DownloaderHints(const se::Value &v, cc::network::DownloaderHints *ret) { const static cc::network::DownloaderHints ZERO{0, 0, ""}; CC_ASSERT_NOT_NULL(ret); SE_PRECONDITION2(v.isObject(), false, "Convert parameter to DownloaderHints failed!"); se::Value tmp; se::Object *obj = v.toObject(); bool ok = false; ok = obj->getProperty("countOfMaxProcessingTasks", &tmp); SE_PRECONDITION3(ok && tmp.isNumber(), false, *ret = ZERO); ret->countOfMaxProcessingTasks = tmp.toUint32(); ok = obj->getProperty("timeoutInSeconds", &tmp); SE_PRECONDITION3(ok && tmp.isNumber(), false, *ret = ZERO); ret->timeoutInSeconds = tmp.toUint32(); ok = obj->getProperty("tempFileNameSuffix", &tmp); SE_PRECONDITION3(ok && tmp.isString(), false, *ret = ZERO); ret->tempFileNameSuffix = tmp.toString(); return ok; } // NOLINTNEXTLINE(readability-identifier-naming) bool sevalue_to_native(const se::Value &from, cc::Vec4 *to, se::Object * /*ctx*/) { SE_PRECONDITION2(from.isObject(), false, "Convert parameter to Vec4 failed!"); se::Object *obj = from.toObject(); CHECK_ASSIGN_PRVOBJ_RET(obj, to) se::Value tmp; set_member_field(obj, to, "x", &cc::Vec4::x, tmp); set_member_field(obj, to, "y", &cc::Vec4::y, tmp); set_member_field(obj, to, "z", &cc::Vec4::z, tmp); set_member_field(obj, to, "w", &cc::Vec4::w, tmp); return true; } // NOLINTNEXTLINE(readability-identifier-naming) bool sevalue_to_native(const se::Value &from, cc::gfx::Rect *to, se::Object * /*ctx*/) { SE_PRECONDITION2(from.isObject(), false, "Convert parameter to Rect failed!"); se::Object *obj = from.toObject(); se::Value tmp; set_member_field(obj, to, "x", &cc::gfx::Rect::x, tmp); set_member_field(obj, to, "y", &cc::gfx::Rect::y, tmp); set_member_field(obj, to, "width", &cc::gfx::Rect::width, tmp); set_member_field(obj, to, "height", &cc::gfx::Rect::height, tmp); return true; } // NOLINTNEXTLINE(readability-identifier-naming) bool sevalue_to_native(const se::Value &from, cc::Rect *to, se::Object * /*ctx*/) { SE_PRECONDITION2(from.isObject(), false, "Convert parameter to Rect failed!"); se::Object *obj = from.toObject(); se::Value tmp; set_member_field(obj, to, "x", &cc::Rect::x, tmp); set_member_field(obj, to, "y", &cc::Rect::y, tmp); set_member_field(obj, to, "width", &cc::Rect::width, tmp); set_member_field(obj, to, "height", &cc::Rect::height, tmp); return true; } // NOLINTNEXTLINE(readability-identifier-naming) bool sevalue_to_native(const se::Value &from, cc::Mat3 *to, se::Object * /*ctx*/) { SE_PRECONDITION2(from.isObject(), false, "Convert parameter to Matrix3 failed!"); se::Object *obj = from.toObject(); CHECK_ASSIGN_PRVOBJ_RET(obj, to) if (obj->isTypedArray()) { // typed array SE_PRECONDITION2(obj->isTypedArray(), false, "Convert parameter to Matrix3 failed!"); size_t length = 0; uint8_t *ptr = nullptr; obj->getTypedArrayData(&ptr, &length); memcpy(to->m, ptr, length); } else { bool ok = false; se::Value tmp; ccstd::string prefix = "m"; for (uint32_t i = 0; i < 9; ++i) { ccstd::string name; if (i < 10) { name = prefix + "0" + std::to_string(i); } else { name = prefix + std::to_string(i); } ok = obj->getProperty(name.c_str(), &tmp, true); SE_PRECONDITION3(ok, false, *to = cc::Mat3::IDENTITY); if (tmp.isNumber()) { to->m[i] = tmp.toFloat(); } else { SE_REPORT_ERROR("%u, not supported type in matrix", i); *to = cc::Mat3::IDENTITY; return false; } tmp.setUndefined(); } } return true; } // NOLINTNEXTLINE(readability-identifier-naming) bool sevalue_to_native(const se::Value &from, cc::Mat4 *to, se::Object * /*unused*/) { SE_PRECONDITION2(from.isObject(), false, "Convert parameter to Matrix4 failed!"); se::Object *obj = from.toObject(); CHECK_ASSIGN_PRVOBJ_RET(obj, to) if (obj->isTypedArray()) { // typed array SE_PRECONDITION2(obj->isTypedArray(), false, "Convert parameter to Matrix4 failed!"); size_t length = 0; uint8_t *ptr = nullptr; obj->getTypedArrayData(&ptr, &length); memcpy(to->m, ptr, length); } else { bool ok = false; se::Value tmp; ccstd::string prefix = "m"; for (uint32_t i = 0; i < 16; ++i) { ccstd::string name; if (i < 10) { name = prefix + "0" + std::to_string(i); } else { name = prefix + std::to_string(i); } ok = obj->getProperty(name.c_str(), &tmp, true); SE_PRECONDITION3(ok, false, *to = cc::Mat4::IDENTITY); if (tmp.isNumber()) { to->m[i] = tmp.toFloat(); } else { SE_REPORT_ERROR("%u, not supported type in matrix", i); *to = cc::Mat4::IDENTITY; return false; } tmp.setUndefined(); } } return true; } // NOLINTNEXTLINE(readability-identifier-naming) bool sevalue_to_native(const se::Value &from, cc::Vec3 *to, se::Object * /*unused*/) { SE_PRECONDITION2(from.isObject(), false, "Convert parameter to Vec3 failed!"); se::Object *obj = from.toObject(); CHECK_ASSIGN_PRVOBJ_RET(obj, to) se::Value tmp; set_member_field(obj, to, "x", &cc::Vec3::x, tmp); set_member_field(obj, to, "y", &cc::Vec3::y, tmp); set_member_field(obj, to, "z", &cc::Vec3::z, tmp); return true; } // NOLINTNEXTLINE(readability-identifier-naming) bool sevalue_to_native(const se::Value &from, cc::Color *to, se::Object * /*unused*/) { SE_PRECONDITION2(from.isObject(), false, "Convert parameter to Color failed!"); se::Object *obj = from.toObject(); CHECK_ASSIGN_PRVOBJ_RET(obj, to) se::Value t; set_member_field(obj, to, "r", &cc::Color::r, t); set_member_field(obj, to, "g", &cc::Color::g, t); set_member_field(obj, to, "b", &cc::Color::b, t); set_member_field(obj, to, "a", &cc::Color::a, t); return true; } // NOLINTNEXTLINE(readability-identifier-naming) bool sevalue_to_native(const se::Value &from, cc::Vec2 *to, se::Object * /*unused*/) { SE_PRECONDITION2(from.isObject(), false, "Convert parameter to Vec2 failed!"); se::Object *obj = from.toObject(); CHECK_ASSIGN_PRVOBJ_RET(obj, to) se::Value tmp; set_member_field(obj, to, "x", &cc::Vec2::x, tmp); set_member_field(obj, to, "y", &cc::Vec2::y, tmp); return true; } // NOLINTNEXTLINE(readability-identifier-naming) bool sevalue_to_native(const se::Value &from, cc::Size *to, se::Object * /*unused*/) { SE_PRECONDITION2(from.isObject(), false, "Convert parameter to Size failed!"); se::Object *obj = from.toObject(); se::Value tmp; set_member_field(obj, to, "width", &cc::Size::width, tmp); set_member_field(obj, to, "height", &cc::Size::height, tmp); return true; } // NOLINTNEXTLINE(readability-identifier-naming) bool sevalue_to_native(const se::Value &from, cc::Quaternion *to, se::Object * /*unused*/) { SE_PRECONDITION2(from.isObject(), false, "Convert parameter to Quaternion failed!"); se::Object *obj = from.toObject(); CHECK_ASSIGN_PRVOBJ_RET(obj, to); se::Value tmp; set_member_field(obj, to, "x", &cc::Quaternion::x, tmp); set_member_field(obj, to, "y", &cc::Quaternion::y, tmp); set_member_field(obj, to, "z", &cc::Quaternion::z, tmp); set_member_field(obj, to, "w", &cc::Quaternion::w, tmp); return true; } //////////////////// geometry // NOLINTNEXTLINE(readability-identifier-naming) bool sevalue_to_native(const se::Value &from, cc::geometry::AABB *to, se::Object * /*ctx*/) { SE_PRECONDITION2(from.isObject(), false, "Convert parameter to AABB failed!"); se::Object *obj = from.toObject(); CHECK_ASSIGN_PRVOBJ_RET(obj, to) se::Value tmp; set_member_field(obj, to, "halfExtents", &cc::geometry::AABB::halfExtents, tmp); set_member_field(obj, to, "center", &cc::geometry::AABB::center, tmp); return true; } // NOLINTNEXTLINE(readability-identifier-naming) bool sevalue_to_native(const se::Value &from, cc::geometry::Capsule *to, se::Object * /*ctx*/) { SE_PRECONDITION2(from.isObject(), false, "Convert parameter to Capsule failed!"); se::Object *obj = from.toObject(); CHECK_ASSIGN_PRVOBJ_RET(obj, to) se::Value tmp; set_member_field(obj, to, "radius", &cc::geometry::Capsule::radius, tmp); set_member_field(obj, to, "halfHeight", &cc::geometry::Capsule::halfHeight, tmp); set_member_field(obj, to, "axis", &cc::geometry::Capsule::axis, tmp); return true; } // NOLINTNEXTLINE(readability-identifier-naming) bool sevalue_to_native(const se::Value &from, cc::geometry::Line *to, se::Object * /*ctx*/) { SE_PRECONDITION2(from.isObject(), false, "Convert parameter to Line failed!"); se::Object *obj = from.toObject(); CHECK_ASSIGN_PRVOBJ_RET(obj, to) se::Value tmp; set_member_field(obj, to, "s", &cc::geometry::Line::s, tmp); set_member_field(obj, to, "e", &cc::geometry::Line::e, tmp); return true; } // NOLINTNEXTLINE(readability-identifier-naming) bool sevalue_to_native(const se::Value &from, cc::geometry::Ray *to, se::Object * /*ctx*/) { SE_PRECONDITION2(from.isObject(), false, "Convert parameter to Ray failed!"); se::Object *obj = from.toObject(); CHECK_ASSIGN_PRVOBJ_RET(obj, to) se::Value tmp; set_member_field(obj, to, "o", &cc::geometry::Ray::o, tmp); set_member_field(obj, to, "d", &cc::geometry::Ray::d, tmp); return true; } // NOLINTNEXTLINE(readability-identifier-naming) bool sevalue_to_native(const se::Value &from, cc::geometry::Sphere *to, se::Object * /*ctx*/) { SE_PRECONDITION2(from.isObject(), false, "Convert parameter to Sphere failed!"); se::Object *obj = from.toObject(); CHECK_ASSIGN_PRVOBJ_RET(obj, to) se::Value tmp; set_member_field(obj, to, "radius", &cc::geometry::Sphere::setRadius, tmp); set_member_field(obj, to, "center", &cc::geometry::Sphere::setCenter, tmp); return true; } // NOLINTNEXTLINE(readability-identifier-naming) bool sevalue_to_native(const se::Value &from, cc::geometry::Triangle *to, se::Object * /*ctx*/) { SE_PRECONDITION2(from.isObject(), false, "Convert parameter to Plane failed!"); se::Object *obj = from.toObject(); CHECK_ASSIGN_PRVOBJ_RET(obj, to) se::Value tmp; set_member_field(obj, to, "a", &cc::geometry::Triangle::a, tmp); set_member_field(obj, to, "b", &cc::geometry::Triangle::b, tmp); set_member_field(obj, to, "c", &cc::geometry::Triangle::c, tmp); return true; } // NOLINTNEXTLINE(readability-identifier-naming) bool sevalue_to_native(const se::Value &from, cc::geometry::Plane *to, se::Object * /*unused*/) { SE_PRECONDITION2(from.isObject(), false, "Convert parameter to Plane failed!"); se::Object *obj = from.toObject(); CHECK_ASSIGN_PRVOBJ_RET(obj, to) se::Value tmp; set_member_field(obj, to, "n", &cc::geometry::Plane::n, tmp); set_member_field(obj, to, "d", &cc::geometry::Plane::d, tmp); return true; } // NOLINTNEXTLINE(readability-identifier-naming) bool sevalue_to_native(const se::Value &from, cc::geometry::Plane **to, se::Object *ctx) { return sevalue_to_native(from, *to, ctx); } // NOLINTNEXTLINE(readability-identifier-naming) bool sevalue_to_native(const se::Value &from, cc::geometry::Frustum *to, se::Object * /*unused*/) { SE_PRECONDITION2(from.isObject(), false, "Convert parameter to Frustum failed!"); se::Object *obj = from.toObject(); CHECK_ASSIGN_PRVOBJ_RET(obj, to) se::Value tmp; set_member_field(obj, to, "planes", &cc::geometry::Frustum::planes, tmp); set_member_field(obj, to, "vertices", &cc::geometry::Frustum::vertices, tmp); return true; } // NOLINTNEXTLINE(readability-identifier-naming) bool sevalue_to_native(const se::Value &from, cc::geometry::Spline *to, se::Object * /*unused*/) { SE_PRECONDITION2(from.isObject(), false, "Convert parameter to Spline failed!"); se::Object *obj = from.toObject(); CHECK_ASSIGN_PRVOBJ_RET(obj, to) se::Value tmp; set_member_field(obj, to, "_mode", &cc::geometry::Spline::setMode, tmp); set_member_field>(obj, to, "_knots", &cc::geometry::Spline::setKnots, tmp); return true; } ////////////////////////// scene info // NOLINTNEXTLINE(readability-identifier-naming) bool sevalue_to_native(const se::Value &from, cc::scene::FogInfo *to, se::Object * /*ctx*/) { SE_PRECONDITION2(from.isObject(), false, "Convert parameter to FogInfo failed!"); se::Object *obj = from.toObject(); se::Value tmp; set_member_field(obj, to, "type", &cc::scene::FogInfo::setType, tmp); set_member_field(obj, to, "fogColor", &cc::scene::FogInfo::setFogColor, tmp); set_member_field(obj, to, "enabled", &cc::scene::FogInfo::setEnabled, tmp); set_member_field(obj, to, "fogDensity", &cc::scene::FogInfo::setFogDensity, tmp); set_member_field(obj, to, "fogStart", &cc::scene::FogInfo::setFogStart, tmp); set_member_field(obj, to, "fogEnd", &cc::scene::FogInfo::setFogEnd, tmp); set_member_field(obj, to, "fogAtten", &cc::scene::FogInfo::setFogAtten, tmp); set_member_field(obj, to, "fogTop", &cc::scene::FogInfo::setFogTop, tmp); set_member_field(obj, to, "fogRange", &cc::scene::FogInfo::setFogRange, tmp); set_member_field(obj, to, "accurate", &cc::scene::FogInfo::setAccurate, tmp); return true; } // NOLINTNEXTLINE(readability-identifier-naming) bool sevalue_to_native(const se::Value &from, cc::scene::ShadowsInfo *to, se::Object * /*ctx*/) { SE_PRECONDITION2(from.isObject(), false, "Convert parameter to ShadowInfo failed!"); se::Object *obj = from.toObject(); se::Value tmp; set_member_field(obj, to, "type", &cc::scene::ShadowsInfo::setType, tmp); set_member_field(obj, to, "enabled", &cc::scene::ShadowsInfo::setEnabled, tmp); set_member_field(obj, to, "planeDirection", &cc::scene::ShadowsInfo::setPlaneDirection, tmp); set_member_field(obj, to, "planeHeight", &cc::scene::ShadowsInfo::setPlaneHeight, tmp); set_member_field(obj, to, "shadowColor", &cc::scene::ShadowsInfo::setShadowColor, tmp); set_member_field(obj, to, "maxReceived", &cc::scene::ShadowsInfo::setMaxReceived, tmp); set_member_field(obj, to, "size", &cc::scene::ShadowsInfo::setShadowMapSize, tmp); return true; } // NOLINTNEXTLINE(readability-identifier-naming) bool sevalue_to_native(const se::Value &from, cc::scene::SkyboxInfo *to, se::Object * /*ctx*/) { SE_PRECONDITION2(from.isObject(), false, "Convert parameter to SkyboxInfo failed!"); se::Object *obj = from.toObject(); se::Value tmp; set_member_field(obj, to, "envmap", &cc::scene::SkyboxInfo::setEnvmap, tmp); set_member_field(obj, to, "diffuseMap", &cc::scene::SkyboxInfo::setDiffuseMap, tmp); set_member_field(obj, to, "enabled", &cc::scene::SkyboxInfo::setEnabled, tmp); set_member_field(obj, to, "useIBL", &cc::scene::SkyboxInfo::setUseIBL, tmp); set_member_field(obj, to, "useHDR", &cc::scene::SkyboxInfo::setUseHDR, tmp); set_member_field(obj, to, "applyDiffuseMap", &cc::scene::SkyboxInfo::setApplyDiffuseMap, tmp); return true; } // NOLINTNEXTLINE(readability-identifier-naming) bool sevalue_to_native(const se::Value &from, cc::MacroValue *to, se::Object * /*ctx*/) { bool ret = true; if (from.isBoolean()) { *to = from.toBoolean(); } else if (from.isNumber()) { *to = from.toInt32(); // NOTE: We only support macro with int32_t type now. } else if (from.isString()) { *to = from.toString(); } else { ret = false; } return ret; } // NOLINTNEXTLINE(readability-identifier-naming) bool sevalue_to_native(const se::Value &from, ccstd::vector *to, se::Object * /*ctx*/) { if (from.isNullOrUndefined()) { to->clear(); return true; } SE_PRECONDITION2(from.isObject(), false, "sevalue_to_native(ccstd::vector), not an object"); auto *fromObj = from.toObject(); CC_ASSERT(fromObj->isArray()); uint32_t len = 0; bool ok = fromObj->getArrayLength(&len); if (ok) { to->resize(len); se::Value arrElement; for (uint32_t i = 0; i < len; ++i) { ok = fromObj->getArrayElement(i, &arrElement); if (!ok || !arrElement.isObject()) { continue; } cc::MacroRecord macroRecord; ccstd::vector keys; ok = arrElement.toObject()->getAllKeys(&keys); if (ok) { se::Value seMacroVal; for (const auto &key : keys) { ok = arrElement.toObject()->getProperty(key, &seMacroVal); cc::MacroValue macroVal; sevalue_to_native(seMacroVal, ¯oVal, nullptr); macroRecord.emplace(key, std::move(macroVal)); } } (*to)[i] = std::move(macroRecord); } } return true; } // NOLINTNEXTLINE(readability-identifier-naming) bool sevalue_to_native(const se::Value &from, cc::MaterialProperty *to, se::Object *ctx) { if (from.isNullOrUndefined()) { *to = ccstd::monostate(); return true; } // TODO(PatriceJiang): float/int32_t from js number if (from.isNumber()) { double v = from.toDouble(); if (std::trunc(v) != v) { *to = static_cast(v); } else { *to = static_cast(v); } return true; } if (from.isObject()) { auto *obj = const_cast(from.toObject()); bool hasX; bool hasY; bool hasZ; bool hasW; bool hasEuler; bool hasM01; bool hasM08; bool hasM15; bool hasAssetID; bool hasColorVal; se::Value tmp0; se::Value tmp1; se::Value tmp2; se::Value tmp3; se::Value tmp4; hasColorVal = obj->getProperty("_val", &tmp0, true); if (hasColorVal) { *to = cc::Color{tmp0.toUint32()}; return true; } hasX = obj->getProperty("x", &tmp0, true); hasY = hasX && obj->getProperty("y", &tmp1, true); hasZ = hasY && obj->getProperty("z", &tmp2, true); hasW = hasZ && obj->getProperty("w", &tmp3, true); hasEuler = hasW && obj->getProperty("getEulerAngles", &tmp4, true); if (hasW) { if (hasEuler) { *to = cc::Quaternion(tmp0.toFloat(), tmp1.toFloat(), tmp2.toFloat(), tmp3.toFloat()); } else { *to = cc::Vec4(tmp0.toFloat(), tmp1.toFloat(), tmp2.toFloat(), tmp3.toFloat()); } return true; } if (hasZ) { *to = cc::Vec3(tmp0.toFloat(), tmp1.toFloat(), tmp2.toFloat()); return true; } if (hasY) { *to = cc::Vec2(tmp0.toFloat(), tmp1.toFloat()); return true; } hasM01 = obj->getProperty("m00", &tmp0, true); hasM08 = hasM01 && obj->getProperty("m08", &tmp1, true); hasM15 = hasM08 && obj->getProperty("m15", &tmp2, true); if (hasM15) { cc::Mat4 m4; sevalue_to_native(from, &m4, ctx); *to = m4; return true; } if (hasM08) { cc::Mat3 m3; sevalue_to_native(from, &m3, ctx); *to = m3; return true; } hasAssetID = obj->getProperty("_id", &tmp3, true); if (hasAssetID) { *to = reinterpret_cast(obj->getPrivateData()); return true; } if (obj->_getClass() != nullptr) { const auto *name = obj->_getClass()->getName(); if (0 == strcmp(name, "Texture2D")) { *to = reinterpret_cast(obj->getPrivateData()); return true; } if (0 == strcmp(name, "TextureCube")) { *to = reinterpret_cast(obj->getPrivateData()); return true; } if (0 == strcmp(name, "RenderTexture")) { *to = reinterpret_cast(obj->getPrivateData()); return true; } } // gfx::Texture? *to = reinterpret_cast(obj->getPrivateData()); return true; } return false; } // NOLINTNEXTLINE(readability-identifier-naming) bool sevalue_to_native(const se::Value &from, cc::IPreCompileInfoValueType *to, se::Object *ctx) { se::Object *obj = from.toObject(); SE_PRECONDITION2(obj->isArray(), false, "faild to convert to IPreCompileInfoValueType"); uint32_t len; obj->getArrayLength(&len); if (len == 0) { // TODO(PatriceJiang): judge type of empty array? *to = ccstd::vector{}; return false; } se::Value firstEle; obj->getArrayElement(0, &firstEle); if (firstEle.isBoolean()) { ccstd::vector result; sevalue_to_native(from, &result, ctx); *to = result; return true; } if (firstEle.isNumber()) { ccstd::vector result; sevalue_to_native(from, &result, ctx); *to = result; return true; } if (firstEle.isString()) { ccstd::vector result; sevalue_to_native(from, &result, ctx); *to = result; return true; } return false; } // NOLINTNEXTLINE(readability-identifier-naming) bool sevalue_to_native(const se::Value &from, cc::IPropertyEditorValueType *to, se::Object *ctx) { bool ret = true; switch (from.getType()) { case se::Value::Type::String: { ccstd::string str; ret = sevalue_to_native(from, &str, ctx); *to = std::move(str); } break; case se::Value::Type::Boolean: { bool v{false}; ret = sevalue_to_native(from, &v, ctx); *to = v; } break; case se::Value::Type::Number: { float v{0.F}; ret = sevalue_to_native(from, &v, ctx); *to = v; } break; case se::Value::Type::Object: { CC_ASSERT_TRUE(from.toObject()->isArray()); ccstd::vector v; ret = sevalue_to_native(from, &v, ctx); *to = std::move(v); } break; default: *to = {}; break; } return ret; } // NOLINTNEXTLINE(readability-identifier-naming) bool sevalue_to_native(const se::Value &from, cc::IPropertyValue *to, se::Object * /*ctx*/) { if (from.isObject() && from.toObject()->isArray()) { uint32_t len = 0; bool ok = from.toObject()->getArrayLength(&len); ccstd::vector arr; arr.resize(len); for (uint32_t i = 0; i < len; ++i) { se::Value e; ok = from.toObject()->getArrayElement(i, &e); if (ok) { if (e.isNumber()) { arr[i] = e.toFloat(); } } } *to = std::move(arr); } else if (from.isString()) { *to = from.toString(); } else { CC_ABORT(); } return true; } // NOLINTNEXTLINE(readability-identifier-naming) bool sevalue_to_native(const se::Value &from, cc::ArrayBuffer *to, se::Object * /*ctx*/) { CC_ASSERT(from.isObject()); to->setJSArrayBuffer(from.toObject()); return true; } // NOLINTNEXTLINE(readability-identifier-naming) bool sevalue_to_native(const se::Value &from, cc::ArrayBuffer **to, se::Object * /*ctx*/) { CC_ASSERT(from.isObject()); auto *obj = from.toObject(); CC_ASSERT((obj->isArrayBuffer() || obj->isTypedArray())); auto *ab = ccnew cc::ArrayBuffer(); ab->addRef(); if (obj->isArrayBuffer()) { ab->setJSArrayBuffer(obj); } else if (obj->isTypedArray()) { se::Value bufferVal; obj->getProperty("buffer", &bufferVal); ab->setJSArrayBuffer(bufferVal.toObject()); } else { ab->release(); return false; } *to = ab; cc::DeferredReleasePool::add(*to); return true; } // NOLINTNEXTLINE(readability-identifier-naming) bool sevalue_to_native(const se::Value &from, ccstd::vector *to, se::Object * /*ctx*/) { if (from.isNullOrUndefined()) { to->clear(); return true; } se::Object *arr = from.toObject(); uint32_t size; se::Value tmp; arr->getArrayLength(&size); to->resize(size); for (uint32_t i = 0; i < size; i++) { arr->getArrayElement(i, &tmp); (*to)[i] = tmp.toBoolean(); } return true; } // NOLINTNEXTLINE(readability-identifier-naming) bool sevalue_to_native(const se::Value &from, ccstd::variant *to, se::Object * /*ctx*/) { if (from.isBoolean()) { *to = from.toBoolean(); } else if (from.isString()) { *to = from.toString(); } else { CC_ASSERT(false); } return true; } // NOLINTNEXTLINE(readability-identifier-naming) bool sevalue_to_native(const se::Value &from, ccstd::vector *to, se::Object * /*ctx*/) { if (from.isNullOrUndefined()) { to->clear(); return true; } CC_ASSERT(from.isObject()); se::Object *in = from.toObject(); if (in->isTypedArray()) { uint8_t *data = nullptr; size_t dataLen = 0; in->getTypedArrayData(&data, &dataLen); to->resize(dataLen); to->assign(data, data + dataLen); return true; } if (in->isArrayBuffer()) { uint8_t *data = nullptr; size_t dataLen = 0; in->getArrayBufferData(&data, &dataLen); to->resize(dataLen); to->assign(data, data + dataLen); return true; } if (in->isArray()) { uint32_t len = 0; in->getArrayLength(&len); to->resize(len); se::Value ele; for (uint32_t i = 0; i < len; i++) { in->getArrayElement(i, &ele); (*to)[i] = ele.toUint8(); } return true; } SE_LOGE("type error, ArrayBuffer/TypedArray/Array expected!"); return false; } // NOLINTNEXTLINE(readability-identifier-naming) bool sevalue_to_native(const se::Value &from, cc::TypedArray *to, se::Object * /*ctx*/) { CC_ASSERT(from.isObject()); CC_ASSERT(from.toObject()->isTypedArray()); if (to->index() == 0) { se::Object::TypedArrayType type = from.toObject()->getTypedArrayType(); switch (type) { case se::Object::TypedArrayType::FLOAT32: *to = cc::Float32Array(); break; case se::Object::TypedArrayType::UINT16: *to = cc::Uint16Array(); break; case se::Object::TypedArrayType::UINT32: *to = cc::Uint32Array(); break; case se::Object::TypedArrayType::UINT8: *to = cc::Uint8Array(); break; case se::Object::TypedArrayType::INT32: *to = cc::Int32Array(); break; case se::Object::TypedArrayType::INT16: *to = cc::Int16Array(); break; case se::Object::TypedArrayType::INT8: *to = cc::Int8Array(); break; case se::Object::TypedArrayType::FLOAT64: *to = cc::Float64Array(); break; default: CC_ABORT(); } } ccstd::visit(cc::overloaded{ [&](auto &typedArray) { typedArray.setJSTypedArray(from.toObject()); }, [](ccstd::monostate & /*unused*/) {}}, *to); return true; } // NOLINTNEXTLINE(readability-identifier-naming) bool sevalue_to_native(const se::Value &from, cc::IBArray *to, se::Object * /*ctx*/) { ccstd::visit(cc::overloaded{ [&](auto &typedArray) { typedArray.setJSTypedArray(from.toObject()); }, [](ccstd::monostate & /*unused*/) {}}, *to); return true; } #if CC_USE_SPINE // NOLINTNEXTLINE(readability-identifier-naming) bool sevalue_to_native(const se::Value &val, spine::String *obj, se::Object * /*unused*/) { *obj = val.toString().data(); return true; } // NOLINTNEXTLINE(readability-identifier-naming) bool sevalue_to_native(const se::Value &v, spine::Vector *ret, se::Object * /*unused*/) { CC_ASSERT(v.isObject()); se::Object *obj = v.toObject(); CC_ASSERT(obj->isArray()); bool ok = true; uint32_t len = 0; ok = obj->getArrayLength(&len); if (!ok) { ret->clear(); return false; } se::Value tmp; for (uint32_t i = 0; i < len; ++i) { ok = obj->getArrayElement(i, &tmp); if (!ok || !tmp.isObject()) { ret->clear(); return false; } const char *str = tmp.toString().c_str(); ret->add(str); } return true; } bool sevalue_to_native(const se::Value &from, spine::Vector2 *to, se::Object * /*unused*/) { SE_PRECONDITION2(from.isObject(), false, "Convert parameter to Vec2 failed!"); se::Object *obj = from.toObject(); CHECK_ASSIGN_PRVOBJ_RET(obj, to) se::Value tmp; set_member_field(obj, to, "x", &spine::Vector2::x, tmp); set_member_field(obj, to, "y", &spine::Vector2::y, tmp); return true; } bool nativevalue_to_se(const spine::Vector2 &from, se::Value &to, se::Object * /*unused*/) { se::HandleObject obj(se::Object::createPlainObject()); obj->setProperty("x", se::Value(from.x)); obj->setProperty("y", se::Value(from.y)); to.setObject(obj); return true; } #endif #if CC_USE_MIDDLEWARE // NOLINTNEXTLINE(readability-identifier-naming) bool seval_to_Map_string_key(const se::Value &v, cc::RefMap *ret) { CC_ASSERT_NOT_NULL(ret); CC_ASSERT(v.isObject()); se::Object *obj = v.toObject(); ccstd::vector allKeys; bool ok = obj->getAllKeys(&allKeys); if (!ok) { ret->clear(); return false; } se::Value tmp; for (const auto &key : allKeys) { auto pngPos = key.find(".png"); if (pngPos == ccstd::string::npos) { continue; } ok = obj->getProperty(key.c_str(), &tmp); if (!ok || !tmp.isObject()) { ret->clear(); return false; } auto *nativeObj = static_cast(tmp.toObject()->getPrivateData()); ret->insert(key, nativeObj); } return true; } #endif //////////////////////////////////////////////////////////////////////////// /////////////////nativevalue_to_se////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// // native to seval // NOLINTNEXTLINE(readability-identifier-naming) bool ccvalue_to_seval(const cc::Value &v, se::Value *ret) { // NOLINT return ret ? nativevalue_to_se(v, *ret, nullptr) : false; } // NOLINTNEXTLINE(readability-identifier-naming) bool ccvaluemap_to_seval(const cc::ValueMap &v, se::Value *ret) { // NOLINT return ret ? nativevalue_to_se(v, *ret, nullptr) : false; } // NOLINTNEXTLINE(readability-identifier-naming) bool ccvaluemapintkey_to_seval(const cc::ValueMapIntKey &v, se::Value *ret) { // NOLINT CC_ASSERT_NOT_NULL(ret); se::HandleObject obj(se::Object::createPlainObject()); bool ok = true; for (const auto &e : v) { std::stringstream keyss; keyss << e.first; ccstd::string key = keyss.str(); const cc::Value &value = e.second; if (key.empty()) { continue; } se::Value tmp; if (!ccvalue_to_seval(value, &tmp)) { ok = false; ret->setUndefined(); break; } obj->setProperty(key.c_str(), tmp); } if (ok) { ret->setObject(obj); } return ok; } // NOLINTNEXTLINE(readability-identifier-naming) bool ccvaluevector_to_seval(const cc::ValueVector &v, se::Value *ret) { // NOLINT CC_ASSERT_NOT_NULL(ret); se::HandleObject obj(se::Object::createArrayObject(v.size())); bool ok = true; uint32_t i = 0; for (const auto &value : v) { se::Value tmp; if (!ccvalue_to_seval(value, &tmp)) { ok = false; ret->setUndefined(); break; } obj->setArrayElement(i, tmp); ++i; } if (ok) { ret->setObject(obj); } return ok; } // NOLINTNEXTLINE(readability-identifier-naming) bool ManifestAsset_to_seval(const cc::extension::ManifestAsset &v, se::Value *ret) { return ret ? nativevalue_to_se(v, *ret, nullptr) : false; } // NOLINTNEXTLINE(readability-identifier-naming) bool Data_to_seval(const cc::Data &v, se::Value *ret) { // NOTICE: should remove this function, kept for backward compatibility return Data_to_TypedArray(v, ret); } bool Data_to_TypedArray(const cc::Data &v, se::Value *ret) { // NOLINT(readability-identifier-naming) // NOTICE: should remove this function, kept for backward compatibility CC_ASSERT_NOT_NULL(ret); if (v.isNull()) { ret->setNull(); } else { se::HandleObject obj(se::Object::createTypedArray(se::Object::TypedArrayType::UINT8, v.getBytes(), v.getSize())); ret->setObject(obj, true); } return true; } // NOLINTNEXTLINE(readability-identifier-naming) bool DownloadTask_to_seval(const cc::network::DownloadTask &v, se::Value *ret) { return ret ? nativevalue_to_se(v, *ret, nullptr) : false; } bool nativevalue_to_se(const cc::network::DownloadTask &from, se::Value &to, se::Object * /*ctx*/) { // NOLINT(readability-identifier-naming) se::HandleObject obj(se::Object::createPlainObject()); obj->setProperty("identifier", se::Value(from.identifier)); obj->setProperty("requestURL", se::Value(from.requestURL)); obj->setProperty("storagePath", se::Value(from.storagePath)); to.setObject(obj); return true; } #if CC_USE_SPINE // NOLINTNEXTLINE(readability-identifier-naming) bool nativevalue_to_se(const spine::String &obj, se::Value &val, se::Object * /*unused*/) { val.setString(obj.buffer()); return true; } // NOLINTNEXTLINE(readability-identifier-naming) bool nativevalue_to_se(const spine::Vector &v, se::Value &ret, se::Object * /*unused*/) { se::HandleObject obj(se::Object::createArrayObject(v.size())); bool ok = true; spine::Vector tmpv = v; for (uint32_t i = 0, count = static_cast(tmpv.size()); i < count; i++) { if (!obj->setArrayElement(i, se::Value(tmpv[i].buffer()))) { ok = false; ret.setUndefined(); break; } } if (ok) { ret.setObject(obj); } return ok; } #endif ////////////////// custom types // NOLINTNEXTLINE(readability-identifier-naming) bool nativevalue_to_se(const cc::Data &from, se::Value &to, se::Object * /*unused*/) { se::HandleObject buffer{se::Object::createArrayBufferObject(from.getBytes(), from.getSize())}; to.setObject(buffer); return true; } // NOLINTNEXTLINE bool nativevalue_to_se(const cc::Value &from, se::Value &to, se::Object * /*unused*/) { bool ok = true; switch (from.getType()) { case cc::Value::Type::NONE: to.setNull(); break; case cc::Value::Type::UNSIGNED: to.setUint32(from.asUnsignedInt()); break; case cc::Value::Type::BOOLEAN: to.setBoolean(from.asBool()); break; case cc::Value::Type::FLOAT: case cc::Value::Type::DOUBLE: to.setDouble(from.asDouble()); break; case cc::Value::Type::INTEGER: to.setInt32(from.asInt()); break; case cc::Value::Type::STRING: to.setString(from.asString()); break; case cc::Value::Type::VECTOR: ok = nativevalue_to_se(from.asValueVector(), to, nullptr); break; case cc::Value::Type::MAP: ok = nativevalue_to_se(from.asValueMap(), to, nullptr); break; case cc::Value::Type::INT_KEY_MAP: ok = nativevalue_to_se(from.asIntKeyMap(), to, nullptr); break; default: SE_LOGE("Could not the way to convert cc::Value::Type (%d) type!", (int)from.getType()); ok = false; break; } return ok; } // NOLINTNEXTLINE bool nativevalue_to_se(const ccstd::unordered_map &from, se::Value &to, se::Object * /*unused*/) { se::HandleObject obj(se::Object::createPlainObject()); bool ok = true; for (const auto &e : from) { const ccstd::string &key = e.first; const cc::Value &value = e.second; if (key.empty()) { continue; } se::Value tmp; if (!nativevalue_to_se(value, tmp, nullptr)) { ok = false; to.setUndefined(); break; } obj->setProperty(key.c_str(), tmp); } if (ok) { to.setObject(obj); } return ok; } // NOLINTNEXTLINE(readability-identifier-naming) bool nativevalue_to_se(const cc::Size &from, se::Value &to, se::Object * /*unused*/) { se::HandleObject obj(se::Object::createPlainObject()); obj->setProperty("width", se::Value(from.width)); obj->setProperty("height", se::Value(from.height)); obj->setProperty("type", se::Value(static_cast(MathType::SIZE))); to.setObject(obj); return true; } // NOLINTNEXTLINE(readability-identifier-naming) bool nativevalue_to_se(const cc::extension::ManifestAsset &from, se::Value &to, se::Object * /*unused*/) { se::HandleObject obj(se::Object::createPlainObject()); obj->setProperty("md5", se::Value(from.md5)); obj->setProperty("path", se::Value(from.path)); obj->setProperty("compressed", se::Value(from.compressed)); obj->setProperty("size", se::Value(from.size)); obj->setProperty("downloadState", se::Value(from.downloadState)); to.setObject(obj); return true; } // NOLINTNEXTLINE(readability-identifier-naming) bool nativevalue_to_se(const cc::Rect &from, se::Value &to, se::Object * /*unused*/) { se::HandleObject obj(se::Object::createPlainObject()); obj->setProperty("x", se::Value(from.x)); obj->setProperty("y", se::Value(from.y)); obj->setProperty("width", se::Value(from.width)); obj->setProperty("height", se::Value(from.height)); obj->setProperty("type", se::Value(static_cast(MathType::RECT))); to.setObject(obj); return true; } // NOLINTNEXTLINE(readability-identifier-naming) bool nativevalue_to_se(const cc::gfx::Rect &from, se::Value &to, se::Object * /*unused*/) { se::HandleObject obj(se::Object::createPlainObject()); obj->setProperty("x", se::Value(from.x)); obj->setProperty("y", se::Value(from.y)); obj->setProperty("width", se::Value(from.width)); obj->setProperty("height", se::Value(from.height)); to.setObject(obj); return true; } // NOLINTNEXTLINE(readability-identifier-naming) bool nativevalue_to_se(const cc::gfx::FormatInfo *from, se::Value &to, se::Object * /*unused*/) { se::HandleObject obj(se::Object::createPlainObject()); if (from) { obj->setProperty("name", se::Value(from->name)); obj->setProperty("size", se::Value(from->size)); obj->setProperty("count", se::Value(from->count)); obj->setProperty("type", se::Value(static_cast(from->type))); obj->setProperty("hasAlpha", se::Value(from->hasAlpha)); obj->setProperty("hasDepth", se::Value(from->hasDepth)); obj->setProperty("hasStencil", se::Value(from->hasStencil)); obj->setProperty("isCompressed", se::Value(from->isCompressed)); to.setObject(obj); } else { to.setNull(); } return true; } // NOLINTNEXTLINE(readability-identifier-naming) bool nativevalue_to_se(const cc::ArrayBuffer &arrayBuffer, se::Value &to, se::Object * /*ctx*/) { to.setObject(arrayBuffer.getJSArrayBuffer()); return true; } //// NOLINTNEXTLINE(readability-identifier-naming) // bool nativevalue_to_se(const cc::TypedArray &from, se::Value &to, se::Object * /*ctx*/) { // std::visit([&](auto &typedArray) { // to.setObject(typedArray.getJSTypedArray()); // }, // from); // return true; // } // NOLINTNEXTLINE(readability-identifier-naming) bool nativevalue_to_se(const cc::NativeDep &from, se::Value &to, se::Object * /*ctx*/) { se::HandleObject obj(se::Object::createPlainObject()); obj->setProperty("uuid", se::Value(from.uuid)); obj->setProperty("ext", se::Value(from.ext)); obj->setProperty("__isNative__", se::Value(from.__isNative__)); to.setObject(obj); return true; } #if CC_USE_PHYSICS_PHYSX bool nativevalue_to_se(const ccstd::vector> &from, se::Value &to, se::Object * /*ctx*/) { se::HandleObject array(se::Object::createArrayObject(from.size() * cc::physics::TriggerEventPair::COUNT)); for (size_t i = 0; i < from.size(); i++) { auto t = i * cc::physics::TriggerEventPair::COUNT; array->setArrayElement(static_cast(t + 0), se::Value(from[i]->shapeA)); array->setArrayElement(static_cast(t + 1), se::Value(from[i]->shapeB)); array->setArrayElement(static_cast(t + 2), se::Value(static_cast(from[i]->state))); } to.setObject(array); return true; } bool nativevalue_to_se(const ccstd::vector &from, se::Value &to, se::Object * /*ctx*/) { const auto contactCount = from.size(); se::HandleObject array(se::Object::createArrayObject(contactCount)); for (size_t i = 0; i < contactCount; i++) { auto t = i * cc::physics::ContactPoint::COUNT; uint32_t j = 0; array->setArrayElement(static_cast(t + j++), se::Value(from[i].position.x)); array->setArrayElement(static_cast(t + j++), se::Value(from[i].position.y)); array->setArrayElement(static_cast(t + j++), se::Value(from[i].position.z)); array->setArrayElement(static_cast(t + j++), se::Value(from[i].normal.x)); array->setArrayElement(static_cast(t + j++), se::Value(from[i].normal.y)); array->setArrayElement(static_cast(t + j++), se::Value(from[i].normal.z)); array->setArrayElement(static_cast(t + j++), se::Value(from[i].impulse.x)); array->setArrayElement(static_cast(t + j++), se::Value(from[i].impulse.y)); array->setArrayElement(static_cast(t + j++), se::Value(from[i].impulse.z)); array->setArrayElement(static_cast(t + j++), se::Value(from[i].separation)); array->setArrayElement(static_cast(t + j++), se::Value(from[i].internalFaceIndex0)); array->setArrayElement(static_cast(t + j++), se::Value(from[i].internalFaceIndex1)); } to.setObject(array); return true; } bool nativevalue_to_se(const ccstd::vector> &from, se::Value &to, se::Object *ctx) { se::HandleObject array(se::Object::createArrayObject(from.size() * cc::physics::ContactEventPair::COUNT)); for (size_t i = 0; i < from.size(); i++) { auto t = i * cc::physics::ContactEventPair::COUNT; array->setArrayElement(static_cast(t + 0), se::Value(from[i]->shapeA)); array->setArrayElement(static_cast(t + 1), se::Value(from[i]->shapeB)); array->setArrayElement(static_cast(t + 2), se::Value(static_cast(from[i]->state))); array->setArrayElement(static_cast(t + 3), [&]() -> se::Value { auto obj = se::Value(); nativevalue_to_se(from[i]->contacts, obj, ctx); return obj; }()); } to.setObject(array); return true; } bool nativevalue_to_se(const ccstd::vector &from, se::Value &to, se::Object * /*ctx*/) { const auto contactCount = from.size(); se::HandleObject array(se::Object::createArrayObject(contactCount)); for (size_t i = 0; i < contactCount; i++) { auto t = i * cc::physics::CharacterControllerContact::COUNT; uint32_t j = 0; array->setArrayElement(static_cast(t + j++), se::Value(from[i].worldPosition.x)); array->setArrayElement(static_cast(t + j++), se::Value(from[i].worldPosition.y)); array->setArrayElement(static_cast(t + j++), se::Value(from[i].worldPosition.z)); array->setArrayElement(static_cast(t + j++), se::Value(from[i].worldNormal.x)); array->setArrayElement(static_cast(t + j++), se::Value(from[i].worldNormal.y)); array->setArrayElement(static_cast(t + j++), se::Value(from[i].worldNormal.z)); array->setArrayElement(static_cast(t + j++), se::Value(from[i].motionDirection.x)); array->setArrayElement(static_cast(t + j++), se::Value(from[i].motionDirection.y)); array->setArrayElement(static_cast(t + j++), se::Value(from[i].motionDirection.z)); array->setArrayElement(static_cast(t + j++), se::Value(from[i].motionLength)); } to.setObject(array); return true; } bool nativevalue_to_se(const ccstd::vector> &from, se::Value &to, se::Object *ctx) { se::HandleObject array(se::Object::createArrayObject(from.size() * cc::physics::CCTShapeEventPair::COUNT)); for (size_t i = 0; i < from.size(); i++) { auto t = i * cc::physics::CCTShapeEventPair::COUNT; array->setArrayElement(static_cast(t + 0), se::Value(from[i]->cct)); array->setArrayElement(static_cast(t + 1), se::Value(from[i]->shape)); //array->setArrayElement(static_cast(t + 2), se::Value(static_cast(from[i]->state))); array->setArrayElement(static_cast(t + 2), [&]() -> se::Value { auto obj = se::Value(); nativevalue_to_se(from[i]->contacts, obj, ctx); return obj; }()); } to.setObject(array); return true; } bool nativevalue_to_se(const ccstd::vector> &from, se::Value &to, se::Object * /*ctx*/) { se::HandleObject array(se::Object::createArrayObject(from.size() * cc::physics::CCTTriggerEventPair::COUNT)); for (size_t i = 0; i < from.size(); i++) { auto t = i * cc::physics::CCTTriggerEventPair::COUNT; array->setArrayElement(static_cast(t + 0), se::Value(from[i]->cct)); array->setArrayElement(static_cast(t + 1), se::Value(from[i]->shape)); array->setArrayElement(static_cast(t + 2), se::Value(static_cast(from[i]->state))); } to.setObject(array); return true; } bool nativevalue_to_se(const cc::physics::RaycastResult &from, se::Value &to, se::Object *ctx) { se::HandleObject obj(se::Object::createPlainObject()); obj->setProperty("shape", se::Value(from.shape)); obj->setProperty("distance", se::Value(from.distance)); se::Value tmp; if (nativevalue_to_se(from.hitPoint, tmp, ctx)) obj->setProperty("hitPoint", tmp); if (nativevalue_to_se(from.hitNormal, tmp, ctx)) obj->setProperty("hitNormal", tmp); to.setObject(obj); return true; } bool sevalue_to_native(const se::Value &from, cc::physics::ConvexDesc *to, se::Object *ctx) { CC_ASSERT(from.isObject()); se::Object *json = from.toObject(); auto *data = static_cast(json->getPrivateData()); if (data) { *to = *data; return true; } se::Value field; bool ok = true; json->getProperty("positionLength", &field); if (!field.isNullOrUndefined()) ok &= sevalue_to_native(field, &to->positionLength, ctx); CC_UNUSED size_t dataLength = 0; json->getProperty("positions", &field); if (!field.isNullOrUndefined()) { se::Object *obj = field.toObject(); if (obj->isArrayBuffer()) { ok &= obj->getArrayBufferData(reinterpret_cast(&to->positions), &dataLength); SE_PRECONDITION2(ok, false, "getArrayBufferData failed!"); } else if (obj->isTypedArray()) { ok &= obj->getTypedArrayData(reinterpret_cast(&to->positions), &dataLength); SE_PRECONDITION2(ok, false, "getTypedArrayData failed!"); } else { ok &= false; } } return ok; } bool sevalue_to_native(const se::Value &from, cc::physics::TrimeshDesc *to, se::Object *ctx) { if (!sevalue_to_native(from, reinterpret_cast(to), ctx)) { return false; } CC_ASSERT(from.isObject()); se::Object *json = from.toObject(); auto *data = static_cast(json->getPrivateData()); if (data) { *to = *data; return true; } se::Value field; bool ok = true; json->getProperty("triangleLength", &field); if (!field.isNullOrUndefined()) ok &= sevalue_to_native(field, &(to->triangleLength), ctx); json->getProperty("isU16", &field); if (!field.isNullOrUndefined()) ok &= sevalue_to_native(field, &(to->isU16), ctx); CC_UNUSED size_t dataLength = 0; json->getProperty("triangles", &field); if (!field.isNullOrUndefined()) { se::Object *obj = field.toObject(); if (obj->isArrayBuffer()) { ok &= obj->getArrayBufferData(reinterpret_cast(&to->triangles), &dataLength); SE_PRECONDITION2(ok, false, "getArrayBufferData failed!"); } else if (obj->isTypedArray()) { ok &= obj->getTypedArrayData(reinterpret_cast(&to->triangles), &dataLength); SE_PRECONDITION2(ok, false, "getTypedArrayData failed!"); } else { ok &= false; } } return ok; } bool sevalue_to_native(const se::Value &from, cc::physics::HeightFieldDesc *to, se::Object *ctx) { CC_ASSERT(from.isObject()); se::Object *json = from.toObject(); auto *data = static_cast(json->getPrivateData()); if (data) { *to = *data; return true; } se::Value field; bool ok = true; json->getProperty("rows", &field); if (!field.isNullOrUndefined()) ok &= sevalue_to_native(field, &to->rows, ctx); json->getProperty("columns", &field); if (!field.isNullOrUndefined()) ok &= sevalue_to_native(field, &to->columns, ctx); CC_UNUSED size_t dataLength = 0; json->getProperty("samples", &field); if (!field.isNullOrUndefined()) { se::Object *obj = field.toObject(); if (obj->isArrayBuffer()) { ok &= obj->getArrayBufferData(reinterpret_cast(&to->samples), &dataLength); SE_PRECONDITION2(ok, false, "getArrayBufferData failed!"); } else if (obj->isTypedArray()) { ok &= obj->getTypedArrayData(reinterpret_cast(&to->samples), &dataLength); SE_PRECONDITION2(ok, false, "getTypedArrayData failed!"); } else { ok &= false; } } return ok; } bool sevalue_to_native(const se::Value &from, cc::physics::RaycastOptions *to, se::Object *ctx) { CC_ASSERT(from.isObject()); se::Object *json = from.toObject(); auto *data = static_cast(json->getPrivateData()); if (data) { *to = *data; return true; } se::Value field; bool ok = true; json->getProperty("origin", &field); if (!field.isNullOrUndefined()) ok &= sevalue_to_native(field, &to->origin, ctx); json->getProperty("unitDir", &field); if (!field.isNullOrUndefined()) ok &= sevalue_to_native(field, &to->unitDir, ctx); json->getProperty("mask", &field); if (!field.isNullOrUndefined()) ok &= sevalue_to_native(field, &to->mask, ctx); json->getProperty("distance", &field); if (!field.isNullOrUndefined()) ok &= sevalue_to_native(field, &to->distance, ctx); json->getProperty("queryTrigger", &field); if (!field.isNullOrUndefined()) ok &= sevalue_to_native(field, &to->queryTrigger, ctx); return ok; } #endif // CC_USE_PHYSICS_PHYSX