@next2d/builder 0.1.7 → 0.1.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.d.ts +59 -0
- package/dist/cli.js +141 -0
- package/dist/constants.d.ts +53 -0
- package/dist/constants.js +64 -0
- package/dist/context.d.ts +29 -0
- package/dist/context.js +19 -0
- package/dist/electron.d.ts +10 -0
- package/dist/electron.js +142 -0
- package/dist/index.js +18 -754
- package/dist/native.d.ts +27 -0
- package/dist/native.js +123 -0
- package/dist/utils.d.ts +27 -0
- package/dist/utils.js +40 -0
- package/dist/web.d.ts +18 -0
- package/dist/web.js +70 -0
- package/dist/xbox.d.ts +62 -0
- package/dist/xbox.js +426 -0
- package/package.json +12 -9
- package/templates/xbox/CMakeLists.txt +116 -11
- package/templates/xbox/README.md +34 -8
- package/templates/xbox/cmake/FetchDawn.cmake +47 -6
- package/templates/xbox/cmake/FindV8.cmake +15 -0
- package/templates/xbox/js/bootstrap.js +151 -28
- package/templates/xbox/js/selftest.js +740 -90
- package/templates/xbox/src/AssetLoader.cpp +115 -12
- package/templates/xbox/src/AssetLoader.h +4 -0
- package/templates/xbox/src/EmbeddedAssets.cpp +149 -0
- package/templates/xbox/src/EmbeddedAssets.h +60 -0
- package/templates/xbox/src/EventLoop.cpp +13 -1
- package/templates/xbox/src/EventLoop.h +12 -0
- package/templates/xbox/src/bindings/Audio.cpp +211 -31
- package/templates/xbox/src/bindings/Bindings.h +10 -0
- package/templates/xbox/src/bindings/Canvas.cpp +77 -2
- package/templates/xbox/src/bindings/Canvas2D.cpp +496 -43
- package/templates/xbox/src/bindings/Console.cpp +6 -1
- package/templates/xbox/src/bindings/DomShims.cpp +143 -0
- package/templates/xbox/src/bindings/EventTarget.cpp +11 -0
- package/templates/xbox/src/bindings/Fetch.cpp +2 -8
- package/templates/xbox/src/bindings/Image.cpp +243 -15
- package/templates/xbox/src/bindings/Polyfills.cpp +1226 -0
- package/templates/xbox/src/bindings/RasterCore.h +105 -1
- package/templates/xbox/src/bindings/Video.cpp +153 -10
- package/templates/xbox/src/bindings/webgpu/WebGPU.cpp +844 -18
- package/templates/xbox/src/bindings/webgpu/WebGPUCommon.h +7 -9
- package/templates/xbox/src/bindings/webgpu/WebGPUEnums.h +32 -0
- package/templates/xbox/src/gpu/DawnContext.cpp +245 -7
- package/templates/xbox/src/gpu/DawnContext.h +18 -0
- package/templates/xbox/src/main.cpp +459 -8
- package/templates/xbox/src/platform/AudioDecoder.cpp +121 -0
- package/templates/xbox/src/platform/AudioDecoder.h +18 -0
- package/templates/xbox/src/platform/AudioEngine.cpp +37 -6
- package/templates/xbox/src/platform/DecodeQueue.cpp +136 -0
- package/templates/xbox/src/platform/DecodeQueue.h +27 -0
- package/templates/xbox/src/platform/ImageDecoder.cpp +44 -0
- package/templates/xbox/src/platform/ImageDecoder.h +18 -0
- package/templates/xbox/src/platform/StbTextRasterizer.cpp +324 -0
- package/templates/xbox/src/platform/StbTextRasterizer.h +37 -0
- package/templates/xbox/src/platform/TextRasterizer.cpp +32 -0
- package/templates/xbox/src/platform/WicDecoder.cpp +19 -0
- package/templates/xbox/src/v8/CodeCache.h +223 -0
- package/templates/xbox/src/v8/V8Runtime.cpp +76 -11
- package/templates/xbox/src/v8/V8Util.h +79 -0
- package/templates/xbox/src/v8/WeakHandle.h +45 -0
- package/templates/xbox/src/worker/WorkerRuntime.cpp +432 -48
- package/templates/xbox/src/worker/WorkerRuntime.h +43 -13
- package/templates/xbox/tests/check_local.sh +7 -2
- package/templates/xbox/tests/gamecore_api_probe.cpp +172 -0
- package/templates/xbox/tests/raster_test.cpp +50 -0
- package/templates/xbox/tests/windows_platform_test.cpp +75 -3
- package/templates/xbox/third_party/LICENSES.md +14 -0
- package/templates/xbox/third_party/dr_mp3.h +5412 -0
- package/templates/xbox/third_party/dr_wav.h +9131 -0
- package/templates/xbox/third_party/stb_image.h +7988 -0
- package/templates/xbox/third_party/stb_truetype.h +5079 -0
- package/templates/xbox/third_party/stb_vorbis.c +5584 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#include "AssetLoader.h"
|
|
2
|
+
#include "EmbeddedAssets.h"
|
|
2
3
|
|
|
3
4
|
#include <filesystem>
|
|
4
5
|
#include <fstream>
|
|
@@ -14,9 +15,10 @@ AssetLoader::AssetLoader(std::string root)
|
|
|
14
15
|
{
|
|
15
16
|
}
|
|
16
17
|
|
|
17
|
-
std::string AssetLoader::
|
|
18
|
+
std::string AssetLoader::RelativeKey(const std::string& url) const
|
|
18
19
|
{
|
|
19
|
-
// 先頭の "/" や "./"、絶対 URL のオリジンを剥がして assets/app
|
|
20
|
+
// 先頭の "/" や "./"、絶対 URL のオリジンを剥がして assets/app 基準の相対パスにする。
|
|
21
|
+
// 埋め込み pak のキー(フォワードスラッシュ相対)と一致させるためのもの。
|
|
20
22
|
std::string path = url;
|
|
21
23
|
|
|
22
24
|
// スキーム付き (file://, http://localhost/...) はパス部だけ取り出す
|
|
@@ -39,11 +41,101 @@ std::string AssetLoader::Resolve(const std::string& url) const
|
|
|
39
41
|
path = path.substr(2);
|
|
40
42
|
}
|
|
41
43
|
|
|
42
|
-
|
|
44
|
+
// バックスラッシュはフォワードスラッシュへ正規化 (pak キーと一致させる)。
|
|
45
|
+
for (char& c : path) {
|
|
46
|
+
if (c == '\\') c = '/';
|
|
47
|
+
}
|
|
48
|
+
return path;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
std::string AssetLoader::Resolve(const std::string& url) const
|
|
52
|
+
{
|
|
53
|
+
return (fs::path(root_) / RelativeKey(url)).string();
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// base64 デコード (data: URI 用)。Image.cpp の同等実装と同じ仕様。
|
|
57
|
+
static bool DecodeBase64(const std::string& in, std::vector<uint8_t>* out)
|
|
58
|
+
{
|
|
59
|
+
auto val = [](char c) -> int {
|
|
60
|
+
if (c >= 'A' && c <= 'Z') return c - 'A';
|
|
61
|
+
if (c >= 'a' && c <= 'z') return c - 'a' + 26;
|
|
62
|
+
if (c >= '0' && c <= '9') return c - '0' + 52;
|
|
63
|
+
if (c == '+') return 62;
|
|
64
|
+
if (c == '/') return 63;
|
|
65
|
+
return -1;
|
|
66
|
+
};
|
|
67
|
+
out->clear();
|
|
68
|
+
out->reserve(in.size() / 4 * 3);
|
|
69
|
+
int buf = 0, bits = 0;
|
|
70
|
+
for (char c : in) {
|
|
71
|
+
if (c == '=' || c == '\r' || c == '\n' || c == ' ') continue;
|
|
72
|
+
const int v = val(c);
|
|
73
|
+
if (v < 0) return false;
|
|
74
|
+
buf = buf << 6 | v;
|
|
75
|
+
bits += 6;
|
|
76
|
+
if (bits >= 8) {
|
|
77
|
+
bits -= 8;
|
|
78
|
+
out->push_back(static_cast<uint8_t>(buf >> bits & 0xFF));
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return true;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// data: URI を「%xx」percent-decode する (base64 でない稀なケース用)。
|
|
85
|
+
static std::vector<uint8_t> PercentDecode(const std::string& in)
|
|
86
|
+
{
|
|
87
|
+
std::vector<uint8_t> out;
|
|
88
|
+
out.reserve(in.size());
|
|
89
|
+
auto hex = [](char c) -> int {
|
|
90
|
+
if (c >= '0' && c <= '9') return c - '0';
|
|
91
|
+
if (c >= 'a' && c <= 'f') return c - 'a' + 10;
|
|
92
|
+
if (c >= 'A' && c <= 'F') return c - 'A' + 10;
|
|
93
|
+
return -1;
|
|
94
|
+
};
|
|
95
|
+
for (size_t i = 0; i < in.size(); ++i) {
|
|
96
|
+
if (in[i] == '%' && i + 2 < in.size()) {
|
|
97
|
+
const int hi = hex(in[i + 1]);
|
|
98
|
+
const int lo = hex(in[i + 2]);
|
|
99
|
+
if (hi >= 0 && lo >= 0) {
|
|
100
|
+
out.push_back(static_cast<uint8_t>(hi << 4 | lo));
|
|
101
|
+
i += 2;
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
out.push_back(static_cast<uint8_t>(in[i]));
|
|
106
|
+
}
|
|
107
|
+
return out;
|
|
43
108
|
}
|
|
44
109
|
|
|
45
110
|
std::optional<std::vector<uint8_t>> AssetLoader::ReadBinary(const std::string& url) const
|
|
46
111
|
{
|
|
112
|
+
// data: URI (Vite の ?inline はアセットを data:<mime>;base64,<payload> に埋め込む)。
|
|
113
|
+
// このゲームは全サウンドを ?inline で取り込むため実体は data URI。画像は Image.cpp が
|
|
114
|
+
// 対応済みだが、音声 (new Audio / Sound の XHR fetch) もこの ReadBinary を通るので
|
|
115
|
+
// ここで一括デコードする。未対応だと data: をファイルパス扱いして開けず、全 SFX/BGM が
|
|
116
|
+
// 無音になる (XAudio2 の可否とは無関係に実機でも無音)。
|
|
117
|
+
if (url.rfind("data:", 0) == 0) {
|
|
118
|
+
const auto comma = url.find(',');
|
|
119
|
+
if (comma == std::string::npos) {
|
|
120
|
+
return std::nullopt;
|
|
121
|
+
}
|
|
122
|
+
const std::string meta = url.substr(5, comma - 5); // 例: "audio/mpeg;base64"
|
|
123
|
+
const std::string payload = url.substr(comma + 1);
|
|
124
|
+
if (meta.find("base64") != std::string::npos) {
|
|
125
|
+
std::vector<uint8_t> out;
|
|
126
|
+
if (!DecodeBase64(payload, &out)) {
|
|
127
|
+
return std::nullopt;
|
|
128
|
+
}
|
|
129
|
+
return out;
|
|
130
|
+
}
|
|
131
|
+
return PercentDecode(payload);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// 埋め込みモード優先: exe 内 pak に同じ相対キーがあれば実ファイルより先に返す。
|
|
135
|
+
if (const auto* embedded = GetEmbeddedAsset(RelativeKey(url))) {
|
|
136
|
+
return *embedded;
|
|
137
|
+
}
|
|
138
|
+
|
|
47
139
|
const std::string path = Resolve(url);
|
|
48
140
|
std::ifstream ifs(path, std::ios::binary | std::ios::ate);
|
|
49
141
|
if (!ifs) {
|
|
@@ -61,6 +153,10 @@ std::optional<std::vector<uint8_t>> AssetLoader::ReadBinary(const std::string& u
|
|
|
61
153
|
|
|
62
154
|
std::optional<std::string> AssetLoader::ReadText(const std::string& url) const
|
|
63
155
|
{
|
|
156
|
+
if (const auto* embedded = GetEmbeddedAsset(RelativeKey(url))) {
|
|
157
|
+
return std::string(embedded->begin(), embedded->end());
|
|
158
|
+
}
|
|
159
|
+
|
|
64
160
|
const std::string path = Resolve(url);
|
|
65
161
|
std::ifstream ifs(path, std::ios::binary);
|
|
66
162
|
if (!ifs) {
|
|
@@ -74,22 +170,29 @@ std::optional<std::string> AssetLoader::ReadText(const std::string& url) const
|
|
|
74
170
|
std::optional<std::string> AssetLoader::ResolveEntryModule() const
|
|
75
171
|
{
|
|
76
172
|
// vite が出力する index.html から <script type="module" src="..."> を抽出する。
|
|
77
|
-
|
|
78
|
-
std::
|
|
79
|
-
if (
|
|
80
|
-
|
|
173
|
+
// 埋め込みモードでは pak から、無ければ実ファイルから読む。
|
|
174
|
+
std::string html;
|
|
175
|
+
if (const auto* embedded = GetEmbeddedAsset("index.html")) {
|
|
176
|
+
html.assign(embedded->begin(), embedded->end());
|
|
177
|
+
} else {
|
|
178
|
+
const fs::path index = fs::path(root_) / "index.html";
|
|
179
|
+
std::ifstream ifs(index, std::ios::binary);
|
|
180
|
+
if (!ifs) {
|
|
181
|
+
return std::nullopt;
|
|
182
|
+
}
|
|
183
|
+
std::ostringstream oss;
|
|
184
|
+
oss << ifs.rdbuf();
|
|
185
|
+
html = oss.str();
|
|
81
186
|
}
|
|
82
|
-
std::ostringstream oss;
|
|
83
|
-
oss << ifs.rdbuf();
|
|
84
|
-
const std::string html = oss.str();
|
|
85
187
|
|
|
86
188
|
// type="module" を含む <script ... src="..."> を優先して拾う。
|
|
189
|
+
// 返す値は assets/app 基準の絶対パス。モジュールローダ側で埋め込み/実ファイルを解決する。
|
|
87
190
|
std::regex module_re(
|
|
88
191
|
R"(<script[^>]*type=["']module["'][^>]*src=["']([^"']+)["'])",
|
|
89
192
|
std::regex::icase);
|
|
90
193
|
std::smatch m;
|
|
91
194
|
if (std::regex_search(html, m, module_re)) {
|
|
92
|
-
return
|
|
195
|
+
return Resolve(m[1].str());
|
|
93
196
|
}
|
|
94
197
|
|
|
95
198
|
// 逆順 (src が先) も試す
|
|
@@ -97,7 +200,7 @@ std::optional<std::string> AssetLoader::ResolveEntryModule() const
|
|
|
97
200
|
R"(<script[^>]*src=["']([^"']+)["'][^>]*type=["']module["'])",
|
|
98
201
|
std::regex::icase);
|
|
99
202
|
if (std::regex_search(html, m, module_re2)) {
|
|
100
|
-
return
|
|
203
|
+
return Resolve(m[1].str());
|
|
101
204
|
}
|
|
102
205
|
|
|
103
206
|
return std::nullopt;
|
|
@@ -20,6 +20,10 @@ public:
|
|
|
20
20
|
// 相対 URL/パスを assets/app 基準の絶対パスへ解決する。
|
|
21
21
|
std::string Resolve(const std::string& url) const;
|
|
22
22
|
|
|
23
|
+
// URL を assets/app 基準の相対キー(フォワードスラッシュ)へ正規化する。
|
|
24
|
+
// 埋め込み pak のキーと一致させるために使う。
|
|
25
|
+
std::string RelativeKey(const std::string& url) const;
|
|
26
|
+
|
|
23
27
|
// バイナリ読み込み。存在しなければ nullopt。
|
|
24
28
|
std::optional<std::vector<uint8_t>> ReadBinary(const std::string& url) const;
|
|
25
29
|
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
#include "EmbeddedAssets.h"
|
|
2
|
+
|
|
3
|
+
#include <filesystem>
|
|
4
|
+
#include <map>
|
|
5
|
+
#include <utility>
|
|
6
|
+
|
|
7
|
+
#ifdef _WIN32
|
|
8
|
+
#ifndef WIN32_LEAN_AND_MEAN
|
|
9
|
+
#define WIN32_LEAN_AND_MEAN
|
|
10
|
+
#endif
|
|
11
|
+
#include <Windows.h>
|
|
12
|
+
#endif
|
|
13
|
+
|
|
14
|
+
namespace fs = std::filesystem;
|
|
15
|
+
|
|
16
|
+
namespace next2d {
|
|
17
|
+
|
|
18
|
+
namespace {
|
|
19
|
+
|
|
20
|
+
std::map<std::string, std::vector<uint8_t>> g_assets;
|
|
21
|
+
std::string g_root; // assets/app の正規化済み絶対パス
|
|
22
|
+
bool g_loaded = false;
|
|
23
|
+
bool g_has = false;
|
|
24
|
+
|
|
25
|
+
inline uint32_t Read32LE(const uint8_t* p)
|
|
26
|
+
{
|
|
27
|
+
return static_cast<uint32_t>(p[0])
|
|
28
|
+
| static_cast<uint32_t>(p[1]) << 8
|
|
29
|
+
| static_cast<uint32_t>(p[2]) << 16
|
|
30
|
+
| static_cast<uint32_t>(p[3]) << 24;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
} // namespace
|
|
34
|
+
|
|
35
|
+
bool ParseEmbeddedPak(const uint8_t* data, std::size_t size,
|
|
36
|
+
std::vector<std::pair<std::string, std::vector<uint8_t>>>* out)
|
|
37
|
+
{
|
|
38
|
+
if (!data || size < 12) {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
if (data[0] != 'N' || data[1] != '2' || data[2] != 'D' || data[3] != 'A') {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
// data[4..7] = version (現状 1 のみ。将来の互換のため値は検査しない)
|
|
45
|
+
const uint32_t count = Read32LE(data + 8);
|
|
46
|
+
std::size_t off = 12;
|
|
47
|
+
for (uint32_t i = 0; i < count; ++i) {
|
|
48
|
+
if (off + 4 > size) return false;
|
|
49
|
+
const uint32_t key_len = Read32LE(data + off);
|
|
50
|
+
off += 4;
|
|
51
|
+
if (key_len > size || off + key_len > size) return false;
|
|
52
|
+
std::string key(reinterpret_cast<const char*>(data + off), key_len);
|
|
53
|
+
off += key_len;
|
|
54
|
+
|
|
55
|
+
if (off + 4 > size) return false;
|
|
56
|
+
const uint32_t data_len = Read32LE(data + off);
|
|
57
|
+
off += 4;
|
|
58
|
+
if (data_len > size || off + data_len > size) return false;
|
|
59
|
+
std::vector<uint8_t> bytes(data + off, data + off + data_len);
|
|
60
|
+
off += data_len;
|
|
61
|
+
|
|
62
|
+
if (out) {
|
|
63
|
+
out->emplace_back(std::move(key), std::move(bytes));
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
bool InitEmbeddedAssets()
|
|
70
|
+
{
|
|
71
|
+
if (g_loaded) {
|
|
72
|
+
return g_has;
|
|
73
|
+
}
|
|
74
|
+
g_loaded = true;
|
|
75
|
+
|
|
76
|
+
#ifdef _WIN32
|
|
77
|
+
// 実行ファイル自身のリソースから "N2DASSETS" (RCDATA) を取り出す。
|
|
78
|
+
HRSRC res = FindResourceW(nullptr, L"N2DASSETS", RT_RCDATA);
|
|
79
|
+
if (res) {
|
|
80
|
+
HGLOBAL handle = LoadResource(nullptr, res);
|
|
81
|
+
const DWORD sz = SizeofResource(nullptr, res);
|
|
82
|
+
const void* ptr = handle ? LockResource(handle) : nullptr;
|
|
83
|
+
if (ptr && sz >= 12) {
|
|
84
|
+
std::vector<std::pair<std::string, std::vector<uint8_t>>> entries;
|
|
85
|
+
if (ParseEmbeddedPak(static_cast<const uint8_t*>(ptr), sz, &entries)) {
|
|
86
|
+
for (auto& e : entries) {
|
|
87
|
+
g_assets.emplace(std::move(e.first), std::move(e.second));
|
|
88
|
+
}
|
|
89
|
+
g_has = true;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
#endif
|
|
94
|
+
|
|
95
|
+
return g_has;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
bool HasEmbeddedAssets()
|
|
99
|
+
{
|
|
100
|
+
return g_has;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
void SetEmbeddedAssetsRoot(const std::string& abs_root)
|
|
104
|
+
{
|
|
105
|
+
std::error_code ec;
|
|
106
|
+
fs::path canon = fs::weakly_canonical(fs::path(abs_root), ec);
|
|
107
|
+
g_root = ec ? abs_root : canon.string();
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const std::vector<uint8_t>* GetEmbeddedAsset(const std::string& key)
|
|
111
|
+
{
|
|
112
|
+
if (!g_has) {
|
|
113
|
+
return nullptr;
|
|
114
|
+
}
|
|
115
|
+
auto it = g_assets.find(key);
|
|
116
|
+
return it == g_assets.end() ? nullptr : &it->second;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
void ForEachEmbeddedAsset(
|
|
120
|
+
const std::function<void(const std::string& key,
|
|
121
|
+
const std::vector<uint8_t>& data)>& callback)
|
|
122
|
+
{
|
|
123
|
+
if (!g_has) {
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
for (const auto& [key, data] : g_assets) {
|
|
127
|
+
callback(key, data);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const std::vector<uint8_t>* GetEmbeddedAssetByAbsPath(const std::string& abs)
|
|
132
|
+
{
|
|
133
|
+
if (!g_has || g_root.empty()) {
|
|
134
|
+
return nullptr;
|
|
135
|
+
}
|
|
136
|
+
// 純粋に字句的な相対化 (FS 参照なし)。abs も root も weakly_canonical 済みを前提。
|
|
137
|
+
const fs::path rel = fs::path(abs).lexically_relative(fs::path(g_root));
|
|
138
|
+
if (rel.empty()) {
|
|
139
|
+
return nullptr;
|
|
140
|
+
}
|
|
141
|
+
const std::string key = rel.generic_string();
|
|
142
|
+
// root 外 ("../..") は埋め込み対象外。
|
|
143
|
+
if (key.rfind("..", 0) == 0) {
|
|
144
|
+
return nullptr;
|
|
145
|
+
}
|
|
146
|
+
return GetEmbeddedAsset(key);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
} // namespace next2d
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// EmbeddedAssets: exe に埋め込んだ assets pak (Windows RCDATA) を解析して提供する。
|
|
2
|
+
//
|
|
3
|
+
// 目的: 書き出した *.exe の隣に平文の JS/HTML を置かず、ゲーム資産(assets/app 一式 +
|
|
4
|
+
// js/bootstrap.js)を exe 内リソースへ格納する。埋め込みが無い(開発ビルド等)場合は
|
|
5
|
+
// 全 API が「見つからない」を返し、呼び出し側はファイルシステムへフォールバックする。
|
|
6
|
+
// これにより埋め込みは純粋に加算的で、既存のファイル読み経路を壊さない。
|
|
7
|
+
//
|
|
8
|
+
// pak フォーマット (リトルエンディアン uint32):
|
|
9
|
+
// [4] magic "N2DA"
|
|
10
|
+
// [4] uint32 version (=1)
|
|
11
|
+
// [4] uint32 count
|
|
12
|
+
// count 回:
|
|
13
|
+
// [4] uint32 key_len
|
|
14
|
+
// [key_len] key (UTF-8, フォワードスラッシュ相対パス)
|
|
15
|
+
// [4] uint32 data_len
|
|
16
|
+
// [data_len] data
|
|
17
|
+
//
|
|
18
|
+
// key は次のいずれか:
|
|
19
|
+
// - assets/app 基準の相対パス (例 "app.js", "index.html", "assets/xxx.js")
|
|
20
|
+
// - "js/bootstrap.js" / "js/selftest.js" (exe_dir 基準)
|
|
21
|
+
#pragma once
|
|
22
|
+
|
|
23
|
+
#include <cstddef>
|
|
24
|
+
#include <cstdint>
|
|
25
|
+
#include <functional>
|
|
26
|
+
#include <string>
|
|
27
|
+
#include <vector>
|
|
28
|
+
|
|
29
|
+
namespace next2d {
|
|
30
|
+
|
|
31
|
+
// exe リソースから pak をロードして解析する (プロセスで一度だけ)。
|
|
32
|
+
// 埋め込みが存在し解析に成功したとき true。以後の Has/Get はこの結果に従う。
|
|
33
|
+
bool InitEmbeddedAssets();
|
|
34
|
+
|
|
35
|
+
// 埋め込みが利用可能か。
|
|
36
|
+
bool HasEmbeddedAssets();
|
|
37
|
+
|
|
38
|
+
// assets/app のルート絶対パスを登録する。GetEmbeddedAssetByAbsPath の
|
|
39
|
+
// 相対キー算出に使う。main で AssetLoader の root と同じ値を渡す。
|
|
40
|
+
void SetEmbeddedAssetsRoot(const std::string& abs_root);
|
|
41
|
+
|
|
42
|
+
// 相対キー直接指定で検索する。見つかればバイト列ポインタ(プロセス生存中有効)、無ければ nullptr。
|
|
43
|
+
const std::vector<uint8_t>* GetEmbeddedAsset(const std::string& key);
|
|
44
|
+
|
|
45
|
+
// 全エントリを列挙する (フォント等、キーが事前に分からない資材の収集用)。
|
|
46
|
+
// callback には key とデータ (プロセス生存中有効) が渡る。
|
|
47
|
+
void ForEachEmbeddedAsset(
|
|
48
|
+
const std::function<void(const std::string& key,
|
|
49
|
+
const std::vector<uint8_t>& data)>& callback);
|
|
50
|
+
|
|
51
|
+
// モジュールローダ用: assets/app 配下の絶対パスを相対キーへ変換して検索する。
|
|
52
|
+
// root 未登録 / abs が root 配下でない場合は nullptr。
|
|
53
|
+
const std::vector<uint8_t>* GetEmbeddedAssetByAbsPath(const std::string& abs);
|
|
54
|
+
|
|
55
|
+
// テスト用: 生の pak バッファを解析して (key -> data) を out へ格納する。
|
|
56
|
+
// プラットフォーム非依存で macOS 上でも検証できる。成功時 true。
|
|
57
|
+
bool ParseEmbeddedPak(const uint8_t* data, std::size_t size,
|
|
58
|
+
std::vector<std::pair<std::string, std::vector<uint8_t>>>* out);
|
|
59
|
+
|
|
60
|
+
} // namespace next2d
|
|
@@ -63,6 +63,7 @@ void EventLoop::ClearTimer(uint32_t id)
|
|
|
63
63
|
uint32_t EventLoop::RequestAnimationFrame(v8::Local<v8::Function> callback)
|
|
64
64
|
{
|
|
65
65
|
const uint32_t id = next_raf_id_++;
|
|
66
|
+
|
|
66
67
|
v8::Global<v8::Function> global;
|
|
67
68
|
global.Reset(isolate_, callback);
|
|
68
69
|
raf_callbacks_.emplace_back(id, std::move(global));
|
|
@@ -71,6 +72,16 @@ uint32_t EventLoop::RequestAnimationFrame(v8::Local<v8::Function> callback)
|
|
|
71
72
|
|
|
72
73
|
void EventLoop::CancelAnimationFrame(uint32_t id)
|
|
73
74
|
{
|
|
75
|
+
// 未実行分は即座に取り除く。raf_cancelled_ だけに頼ると、RunAnimationFrame の
|
|
76
|
+
// 実行中に登録されたコールバックへのキャンセルが同フレーム末尾の clear で失われ、
|
|
77
|
+
// キャンセル済みのはずの rAF が翌フレームに実行されてしまう (ticker/Tween の多重化)。
|
|
78
|
+
for (auto it = raf_callbacks_.begin(); it != raf_callbacks_.end(); ++it) {
|
|
79
|
+
if (it->first == id) {
|
|
80
|
+
raf_callbacks_.erase(it);
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
// 実行中バッチ (RunAnimationFrame の current) 内のものはフラグで無効化する
|
|
74
85
|
raf_cancelled_.push_back(id);
|
|
75
86
|
}
|
|
76
87
|
|
|
@@ -104,7 +115,7 @@ void EventLoop::PumpTimers()
|
|
|
104
115
|
|
|
105
116
|
v8::TryCatch try_catch(isolate_);
|
|
106
117
|
(void) fn->Call(ctx, global, 0, nullptr);
|
|
107
|
-
|
|
118
|
+
v8util::ReportCaught(isolate_, &try_catch, "setTimeout/setInterval callback");
|
|
108
119
|
|
|
109
120
|
if (!it->second.repeat) {
|
|
110
121
|
// 単発は実行後に破棄
|
|
@@ -149,6 +160,7 @@ void EventLoop::RunAnimationFrame(double timestamp_ms)
|
|
|
149
160
|
v8::TryCatch try_catch(isolate_);
|
|
150
161
|
v8::Local<v8::Value> args[1] = { arg };
|
|
151
162
|
(void) fn->Call(ctx, global, 1, args);
|
|
163
|
+
v8util::ReportCaught(isolate_, &try_catch, "requestAnimationFrame callback");
|
|
152
164
|
}
|
|
153
165
|
|
|
154
166
|
raf_cancelled_.clear();
|
|
@@ -50,6 +50,18 @@ public:
|
|
|
50
50
|
// 保留タスクが残っているか (終了判定用)
|
|
51
51
|
bool HasPendingWork() const;
|
|
52
52
|
|
|
53
|
+
// 診断用: 登録中の rAF コールバック数 / タイマー数
|
|
54
|
+
size_t PendingAnimationFrameCount() const { return raf_callbacks_.size(); }
|
|
55
|
+
size_t PendingTimerCount() const { return timers_.size(); }
|
|
56
|
+
|
|
57
|
+
// 全タイマー/rAF コールバック (v8::Global) を解放する。Isolate::Dispose より
|
|
58
|
+
// 前に必ず呼ぶこと (スタック巻き戻しでの破棄は Isolate 破棄後になり fail-fast)。
|
|
59
|
+
void Shutdown() {
|
|
60
|
+
timers_.clear();
|
|
61
|
+
raf_callbacks_.clear();
|
|
62
|
+
raf_cancelled_.clear();
|
|
63
|
+
}
|
|
64
|
+
|
|
53
65
|
private:
|
|
54
66
|
struct TimerEntry {
|
|
55
67
|
v8::Global<v8::Function> callback;
|