Skip to content

Commit

Permalink
[v3.8.5] Reduce package size for spine module (#17783)
Browse files Browse the repository at this point in the history
  • Loading branch information
dumganhar authored Nov 5, 2024
1 parent 3102bda commit 102d05e
Show file tree
Hide file tree
Showing 121 changed files with 2,295 additions and 2,778 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build-wasm-libs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
uses: dumganhar/setup-emsdk@997d2cde2deabda085a11f98e86e842915b0e846
with:
version: 3.1.41
actions-cache-folder: 'emsdk-cache'
actions-cache-folder: 'emsdk-cache-3.1.41'

- name: Verify
run: |
Expand Down
205 changes: 205 additions & 0 deletions .github/workflows/emscripten-patches/embind/bind.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
// Copyright 2012 The Emscripten Authors. All rights reserved.
// Emscripten is available under two separate licenses, the MIT license and the
// University of Illinois/NCSA Open Source License. Both these licenses can be
// found in the LICENSE file.

#include <emscripten/bind.h>
#ifdef USE_CXA_DEMANGLE
#include <../lib/libcxxabi/include/cxxabi.h>
#endif
#include <algorithm>
#include <climits>
#include <emscripten/emscripten.h>
#include <emscripten/wire.h>
#include <limits>
#include <list>
#include <typeinfo>
#include <vector>

using namespace emscripten;
using namespace internal;

static char* pointerToHexString(const void* ptr) {
static const char hexDigits[] = "0123456789abcdef";
uintptr_t address = reinterpret_cast<uintptr_t>(ptr);
char str[20] = "0x"; // Includes the "0x" prefix
int index = 2;
bool leadingZero = true; // Used to skip leading zeros

// Convert the address to a hexadecimal string
for (int i = (sizeof(address) * 2) - 1; i >= 0; --i) {
char hexChar = hexDigits[(address >> (i * 4)) & 0xF];
if (hexChar != '0' || !leadingZero || i == 0) { // Ensures at least one zero in the final character
str[index++] = hexChar;
leadingZero = false;
}
}
str[index] = '\0';

return strdup(str);
}

extern "C" {
const char* EMSCRIPTEN_KEEPALIVE __getTypeName(const std::type_info* ti) {
if (has_unbound_type_names) {
#ifdef USE_CXA_DEMANGLE
int stat;
char* demangled = abi::__cxa_demangle(ti->name(), NULL, NULL, &stat);
if (stat == 0 && demangled) {
return demangled;
}

switch (stat) {
case -1:
return strdup("<allocation failure>");
case -2:
return strdup("<invalid C++ symbol>");
case -3:
return strdup("<invalid argument>");
default:
return strdup("<unknown error>");
}
#else
return strdup(ti->name());
#endif
} else {
//cjh char str[80];
// sprintf(str, "%p", reinterpret_cast<const void*>(ti));
// return strdup(str);
return pointerToHexString(reinterpret_cast<const void*>(ti));
}
}

static InitFunc* init_funcs = nullptr;

EMSCRIPTEN_KEEPALIVE void _embind_initialize_bindings() {
for (auto* f = init_funcs; f; f = f->next) {
f->init_func();
}
}

void _embind_register_bindings(InitFunc* f) {
f->next = init_funcs;
init_funcs = f;
}

}

namespace {
template <typename T> static void register_integer(const char* name) {
using namespace internal;
_embind_register_integer(TypeID<T>::get(), name, sizeof(T), std::numeric_limits<T>::min(),
std::numeric_limits<T>::max());
}

template <typename T> static void register_bigint(const char* name) {
using namespace internal;
_embind_register_bigint(TypeID<T>::get(), name, sizeof(T), std::numeric_limits<T>::min(),
std::numeric_limits<T>::max());
}

template <typename T> static void register_float(const char* name) {
using namespace internal;
_embind_register_float(TypeID<T>::get(), name, sizeof(T));
}

// matches typeMapping in embind.js
enum TypedArrayIndex {
Int8Array,
Uint8Array,
Int16Array,
Uint16Array,
Int32Array,
Uint32Array,
Float32Array,
Float64Array,
// Only available if WASM_BIGINT
Int64Array,
Uint64Array,
};

template <typename T> constexpr TypedArrayIndex getTypedArrayIndex() {
static_assert(internal::typeSupportsMemoryView<T>(), "type does not map to a typed array");
return std::is_floating_point<T>::value
? (sizeof(T) == 4 ? Float32Array : Float64Array)
: (sizeof(T) == 1
? (std::is_signed<T>::value ? Int8Array : Uint8Array)
: (sizeof(T) == 2 ? (std::is_signed<T>::value ? Int16Array : Uint16Array)
: (sizeof(T) == 4 ? (std::is_signed<T>::value ? Int32Array : Uint32Array)
: (std::is_signed<T>::value ? Int64Array : Uint64Array))));
}

template <typename T> static void register_memory_view(const char* name) {
using namespace internal;
_embind_register_memory_view(TypeID<memory_view<T>>::get(), getTypedArrayIndex<T>(), name);
}
} // namespace

EMSCRIPTEN_BINDINGS(builtin) {
using namespace emscripten::internal;

_embind_register_void(TypeID<void>::get(), "void");

_embind_register_bool(TypeID<bool>::get(), "bool", sizeof(bool), true, false);

register_integer<char>("char");
register_integer<signed char>("signed char");
register_integer<unsigned char>("unsigned char");
register_integer<signed short>("short");
register_integer<unsigned short>("unsigned short");
register_integer<signed int>("int");
register_integer<unsigned int>("unsigned int");
#if __wasm64__
register_bigint<signed long>("long");
register_bigint<unsigned long>("unsigned long");
#else
register_integer<signed long>("long");
register_integer<unsigned long>("unsigned long");
#endif

register_bigint<int64_t>("int64_t");
register_bigint<uint64_t>("uint64_t");

register_float<float>("float");
register_float<double>("double");

/*cjh
_embind_register_std_string(TypeID<std::string>::get(), "std::string");
_embind_register_std_string(
TypeID<std::basic_string<unsigned char>>::get(), "std::basic_string<unsigned char>");
_embind_register_std_wstring(TypeID<std::wstring>::get(), sizeof(wchar_t), "std::wstring");
_embind_register_std_wstring(TypeID<std::u16string>::get(), sizeof(char16_t), "std::u16string");
_embind_register_std_wstring(TypeID<std::u32string>::get(), sizeof(char32_t), "std::u32string");
*/
_embind_register_emval(TypeID<val>::get(), "emscripten::val");
/*cjh
// Some of these types are aliases for each other. Luckily,
// embind.js's _embind_register_memory_view ignores duplicate
// registrations rather than asserting, so the first
// register_memory_view call for a particular type will take
// precedence.
register_memory_view<char>("emscripten::memory_view<char>");
register_memory_view<signed char>("emscripten::memory_view<signed char>");
register_memory_view<unsigned char>("emscripten::memory_view<unsigned char>");
register_memory_view<short>("emscripten::memory_view<short>");
register_memory_view<unsigned short>("emscripten::memory_view<unsigned short>");
register_memory_view<int>("emscripten::memory_view<int>");
register_memory_view<unsigned int>("emscripten::memory_view<unsigned int>");
register_memory_view<long>("emscripten::memory_view<long>");
register_memory_view<unsigned long>("emscripten::memory_view<unsigned long>");
register_memory_view<int8_t>("emscripten::memory_view<int8_t>");
register_memory_view<uint8_t>("emscripten::memory_view<uint8_t>");
register_memory_view<int16_t>("emscripten::memory_view<int16_t>");
register_memory_view<uint16_t>("emscripten::memory_view<uint16_t>");
register_memory_view<int32_t>("emscripten::memory_view<int32_t>");
register_memory_view<uint32_t>("emscripten::memory_view<uint32_t>");
register_memory_view<int64_t>("emscripten::memory_view<int64_t>");
register_memory_view<uint64_t>("emscripten::memory_view<uint64_t>");
register_memory_view<float>("emscripten::memory_view<float>");
register_memory_view<double>("emscripten::memory_view<double>");
*/
}
2 changes: 1 addition & 1 deletion .github/workflows/generate-emsdk-cache.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
uses: dumganhar/setup-emsdk@997d2cde2deabda085a11f98e86e842915b0e846
with:
version: ${{ github.event.inputs.emsdk_version }}
actions-cache-folder: 'emsdk-cache'
actions-cache-folder: 'emsdk-cache-${{ github.event.inputs.emsdk_version }}'

- name: Verify
run: |
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/native-compile-webgpu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ jobs:
uses: dumganhar/setup-emsdk@997d2cde2deabda085a11f98e86e842915b0e846
with:
version: 3.1.45
actions-cache-folder: 'emsdk-cache'
actions-cache-folder: 'emsdk-cache-3.1.45'

- name: Verify
run: |
Expand Down
78 changes: 78 additions & 0 deletions .github/workflows/web-interface-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,90 @@ jobs:
ref: "${{ env.EXT_VERSION_HEAD }}"
fetch-depth: 1

- name: Setup emsdk
uses: dumganhar/setup-emsdk@997d2cde2deabda085a11f98e86e842915b0e846
with:
version: 3.1.41
actions-cache-folder: 'emsdk-cache-3.1.41'

- name: Verify
run: |
which emcc
emcc -v
- name: Apply emscripten patches
run: |
echo "--------------------------------- Save bind.cpp ---------------------------------"
cp $EMSDK/upstream/emscripten/system/lib/embind/bind.cpp $EMSDK/upstream/emscripten/system/lib/embind/bind.cpp.bak
echo "--------------------------------- Apply embind bind.cpp patches ---------------------------------"
cp -f ./engine-HEAD/.github/workflows/emscripten-patches/embind/bind.cpp $EMSDK/upstream/emscripten/system/lib/embind/
echo "--------------------------------- Apply patches DONE! ---------------------------------"
cat $EMSDK/upstream/emscripten/system/lib/embind/bind.cpp
- name: Install ninja
run: |
if ! command -v ninja &> /dev/null; then
echo "Ninja not found, installing..."
# sudo apt update
sudo apt install ninja-build
else
echo "Ninja is already installed."
fi
which ninja
- name: Build Spine WASM
run: |
cd ./engine-HEAD/native/cocos/editor-support/spine-wasm
mkdir build-wasm
cd build-wasm
emcmake cmake .. -GNinja
ninja
ls -l
- name: Build Spine ASMJS
run: |
cd ./engine-HEAD/native/cocos/editor-support/spine-wasm
sed -i 's/set(BUILD_WASM 1)/set(BUILD_WASM 0)/g' CMakeLists.txt
mkdir build-asmjs
cd build-asmjs
emcmake cmake .. -GNinja
ninja
ls -l
- name: Copy files to external directory
run: |
mkdir dist
cp ./engine-HEAD/native/cocos/editor-support/spine-wasm/build-wasm/spine.wasm ./dist/
cp ./engine-HEAD/native/cocos/editor-support/spine-wasm/build-wasm/spine.js ./dist/spine.wasm.js
cp ./engine-HEAD/native/cocos/editor-support/spine-wasm/build-asmjs/spine.js.mem ./dist/
cp ./engine-HEAD/native/cocos/editor-support/spine-wasm/build-asmjs/spine.js ./dist/spine.asm.js
echo "-------- Before replace spine wasm -----------"
ls -l ./engine-HEAD/native/external/emscripten/spine/
cp -f ./dist/* ./engine-HEAD/native/external/emscripten/spine/
echo "-------- After replace spine wasm ------------"
ls -l ./engine-HEAD/native/external/emscripten/spine/
echo "-----------------------------------------------"
- name: Upload Artifact
uses: actions/upload-artifact@v4
with:
name: spine-emscripten
path: dist

- name: Build Head Declarations
working-directory: ./engine-HEAD
run: |
npm install
node ./.github/workflows/package-size-check.js
- name: Restore patches
run: |
echo "-------------------------- Restore patches ---------------------------------"
rm $EMSDK/upstream/emscripten/system/lib/embind/bind.cpp
mv $EMSDK/upstream/emscripten/system/lib/embind/bind.cpp.bak $EMSDK/upstream/emscripten/system/lib/embind/bind.cpp
echo "-------------------------- Restore patches DONE! ---------------------------------"
cat $EMSDK/upstream/emscripten/system/lib/embind/bind.cpp
- uses: LouisBrunner/[email protected]
with:
old: ./engine/bin/.declarations/cc.d.ts
Expand Down
2 changes: 1 addition & 1 deletion cocos/spine/lib/spine-core.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ declare namespace spine {
setFrame(frameIndex: number, time: number, drawOrder: Array<number>): void;
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
}
class IkConstraintTimeline extends Updatable {
class IkConstraintTimeline extends CurveTimeline {
static readonly ENTRIES: number;
frames: ArrayLike<number>;
constructor(frameCount: number);
Expand Down
Loading

0 comments on commit 102d05e

Please sign in to comment.