@next2d/builder 0.1.6 → 0.1.8

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.
Files changed (34) hide show
  1. package/README.md +5 -1
  2. package/dist/index.js +140 -36
  3. package/package.json +3 -2
  4. package/templates/xbox/CMakeLists.txt +74 -2
  5. package/templates/xbox/README.md +73 -12
  6. package/templates/xbox/cmake/FetchDawn.cmake +47 -6
  7. package/templates/xbox/cmake/FindV8.cmake +22 -1
  8. package/templates/xbox/js/bootstrap.js +31 -28
  9. package/templates/xbox/js/selftest.js +740 -90
  10. package/templates/xbox/src/EventLoop.cpp +28 -1
  11. package/templates/xbox/src/EventLoop.h +12 -0
  12. package/templates/xbox/src/bindings/Audio.cpp +99 -15
  13. package/templates/xbox/src/bindings/Bindings.h +10 -0
  14. package/templates/xbox/src/bindings/Canvas.cpp +45 -0
  15. package/templates/xbox/src/bindings/Canvas2D.cpp +2 -5
  16. package/templates/xbox/src/bindings/DomShims.cpp +127 -0
  17. package/templates/xbox/src/bindings/EventTarget.cpp +2 -0
  18. package/templates/xbox/src/bindings/Fetch.cpp +2 -8
  19. package/templates/xbox/src/bindings/Image.cpp +212 -10
  20. package/templates/xbox/src/bindings/Polyfills.cpp +791 -0
  21. package/templates/xbox/src/bindings/Video.cpp +96 -7
  22. package/templates/xbox/src/bindings/webgpu/WebGPU.cpp +815 -15
  23. package/templates/xbox/src/bindings/webgpu/WebGPUCommon.h +3 -8
  24. package/templates/xbox/src/gpu/DawnContext.cpp +90 -3
  25. package/templates/xbox/src/gpu/DawnContext.h +18 -0
  26. package/templates/xbox/src/main.cpp +88 -6
  27. package/templates/xbox/src/platform/AudioEngine.cpp +9 -3
  28. package/templates/xbox/src/v8/V8Runtime.cpp +69 -4
  29. package/templates/xbox/src/v8/V8Util.h +29 -0
  30. package/templates/xbox/src/v8/WeakHandle.h +45 -0
  31. package/templates/xbox/src/worker/WorkerRuntime.cpp +325 -41
  32. package/templates/xbox/src/worker/WorkerRuntime.h +20 -10
  33. package/templates/xbox/tests/check_local.sh +3 -2
  34. package/templates/xbox/tests/raster_test.bin +0 -0
@@ -13,6 +13,7 @@
13
13
  #include "ImageSource.h"
14
14
  #include "EventTarget.h"
15
15
  #include "v8/V8Util.h"
16
+ #include "v8/WeakHandle.h"
16
17
 
17
18
  #include <mfapi.h>
18
19
  #include <mfidl.h>
@@ -47,6 +48,24 @@ struct VideoDecoder {
47
48
  bool playing = false;
48
49
  bool ended = false;
49
50
  double duration = 0.0;
51
+ double position = 0.0; // 現在位置 (秒, サンプルタイムスタンプ由来)
52
+
53
+ // 先頭 (または指定秒) へシークする。loop 再生と currentTime 設定で使用。
54
+ bool Seek(double seconds)
55
+ {
56
+ if (!reader) return false;
57
+ PROPVARIANT var;
58
+ PropVariantInit(&var);
59
+ var.vt = VT_I8;
60
+ var.hVal.QuadPart = static_cast<LONGLONG>(seconds * 1e7); // s -> 100ns
61
+ const bool ok = SUCCEEDED(reader->SetCurrentPosition(GUID_NULL, var));
62
+ PropVariantClear(&var);
63
+ if (ok) {
64
+ ended = false;
65
+ position = seconds;
66
+ }
67
+ return ok;
68
+ }
50
69
 
51
70
  bool Open(const std::vector<uint8_t>& bytes)
52
71
  {
@@ -87,13 +106,15 @@ struct VideoDecoder {
87
106
  {
88
107
  if (!reader) return false;
89
108
  DWORD flags = 0;
109
+ LONGLONG timestamp = 0;
90
110
  ComPtr<IMFSample> sample;
91
111
  if (FAILED(reader->ReadSample(MF_SOURCE_READER_FIRST_VIDEO_STREAM, 0,
92
- nullptr, &flags, nullptr, &sample))) {
112
+ nullptr, &flags, &timestamp, &sample))) {
93
113
  return false;
94
114
  }
95
115
  if (flags & MF_SOURCE_READERF_ENDOFSTREAM) { ended = true; return false; }
96
116
  if (!sample) return false;
117
+ position = static_cast<double>(timestamp) / 1e7; // 100ns -> s
97
118
 
98
119
  ComPtr<IMFMediaBuffer> buffer;
99
120
  sample->ConvertToContiguousBuffer(&buffer);
@@ -112,8 +133,6 @@ struct VideoDecoder {
112
133
  }
113
134
  };
114
135
 
115
- void ReleaseVideo(const v8::WeakCallbackInfo<VideoDecoder>& info) { delete info.GetParameter(); }
116
-
117
136
  VideoDecoder* Decoder(v8::Local<v8::Object> obj)
118
137
  {
119
138
  return static_cast<VideoDecoder*>(obj->GetInternalField(0).As<v8::External>()->Value());
@@ -144,7 +163,10 @@ void LoadVideo(v8::Isolate* isolate, v8::Local<v8::Object> self, const std::stri
144
163
  SetValue(isolate, self, "videoHeight", v8::Integer::NewFromUnsigned(isolate, dec->height));
145
164
  SetValue(isolate, self, "duration", v8::Number::New(isolate, dec->duration));
146
165
  SetValue(isolate, self, "readyState", v8::Integer::New(isolate, 4));
166
+ // player は loadedmetadata / progress / canplaythrough を購読する
167
+ // (VideoRegisterEventUseCase)。ローカル読み込みは即完了のため順に発火する。
147
168
  FireVideoEvent(isolate, self, "loadedmetadata");
169
+ FireVideoEvent(isolate, self, "progress");
148
170
  FireVideoEvent(isolate, self, "canplaythrough");
149
171
  } else {
150
172
  FireVideoEvent(isolate, self, "error");
@@ -162,7 +184,20 @@ bool GetVideoFramePixels(v8::Isolate* isolate, v8::Local<v8::Object> obj,
162
184
  if (dec->playing && !dec->ended) {
163
185
  dec->ReadNextFrame(); // 描画のたびに次フレームへ進める(簡易フレーム進行)
164
186
  if (dec->ended) {
165
- FireVideoEvent(isolate, obj, "ended");
187
+ // loop 指定時は先頭へ戻して継続、そうでなければ ended を通知
188
+ v8::Local<v8::Value> loop_v;
189
+ const bool loop =
190
+ obj->Get(isolate->GetCurrentContext(),
191
+ v8util::Str(isolate, "loop")).ToLocal(&loop_v) &&
192
+ loop_v->BooleanValue(isolate);
193
+ if (loop && dec->Seek(0.0)) {
194
+ dec->ReadNextFrame();
195
+ } else {
196
+ dec->playing = false;
197
+ SetValue(isolate, obj, "ended", v8::Boolean::New(isolate, true));
198
+ SetValue(isolate, obj, "paused", v8::Boolean::New(isolate, true));
199
+ FireVideoEvent(isolate, obj, "ended");
200
+ }
166
201
  }
167
202
  }
168
203
  *out_rgba = dec->frame.data();
@@ -180,19 +215,69 @@ v8::Local<v8::Object> CreateVideoElement(v8::Isolate* isolate, HostContext* /*ho
180
215
 
181
216
  auto* dec = new VideoDecoder();
182
217
  self->SetInternalField(0, v8::External::New(isolate, dec));
183
- auto* handle = new v8::Global<v8::Object>(isolate, self);
184
- handle->SetWeak(dec, ReleaseVideo, v8::WeakCallbackType::kParameter);
218
+ v8util::AttachWeak(isolate, self, dec);
185
219
 
186
220
  SetValue(isolate, self, "__isVideoElement", v8::Boolean::New(isolate, true));
187
221
  SetValue(isolate, self, "tagName", Str(isolate, "VIDEO"));
188
222
  SetValue(isolate, self, "videoWidth", v8::Integer::New(isolate, 0));
189
223
  SetValue(isolate, self, "videoHeight", v8::Integer::New(isolate, 0));
190
- SetValue(isolate, self, "currentTime", v8::Number::New(isolate, 0));
191
224
  SetValue(isolate, self, "readyState", v8::Integer::New(isolate, 0));
192
225
  SetValue(isolate, self, "loop", v8::Boolean::New(isolate, false));
226
+ SetValue(isolate, self, "paused", v8::Boolean::New(isolate, true));
227
+ SetValue(isolate, self, "ended", v8::Boolean::New(isolate, false));
228
+ SetValue(isolate, self, "muted", v8::Boolean::New(isolate, false));
229
+ SetValue(isolate, self, "volume", v8::Number::New(isolate, 1.0));
230
+ SetValue(isolate, self, "autoplay", v8::Boolean::New(isolate, false));
193
231
  SetValue(isolate, self, "style", v8::Object::New(isolate));
194
232
  InstallEventTarget(isolate, self);
195
233
 
234
+ // currentTime: 取得はデコーダの現在位置、設定はシーク
235
+ self->SetNativeDataProperty(ctx, Str(isolate, "currentTime"),
236
+ [](v8::Local<v8::Name>, const v8::PropertyCallbackInfo<v8::Value>& info) {
237
+ VideoDecoder* d = Decoder(info.This());
238
+ info.GetReturnValue().Set(
239
+ v8::Number::New(info.GetIsolate(), d ? d->position : 0.0));
240
+ },
241
+ [](v8::Local<v8::Name>, v8::Local<v8::Value> value,
242
+ const v8::PropertyCallbackInfo<void>& info) {
243
+ if (!value->IsNumber()) return;
244
+ VideoDecoder* d = Decoder(info.This());
245
+ if (d) {
246
+ d->Seek(value.As<v8::Number>()->Value());
247
+ }
248
+ }).Check();
249
+
250
+ // setAttribute / getAttribute (player は playsinline を設定する)
251
+ SetMethod(isolate, self, "setAttribute",
252
+ [](const v8::FunctionCallbackInfo<v8::Value>& a) {
253
+ if (a.Length() < 2) return;
254
+ v8::Isolate* iso = a.GetIsolate();
255
+ v8::Local<v8::Context> c = iso->GetCurrentContext();
256
+ v8::Local<v8::Value> attrs;
257
+ v8::Local<v8::Object> store;
258
+ if (a.This()->Get(c, v8util::Str(iso, "__attrs")).ToLocal(&attrs) && attrs->IsObject()) {
259
+ store = attrs.As<v8::Object>();
260
+ } else {
261
+ store = v8::Object::New(iso);
262
+ SetValue(iso, a.This(), "__attrs", store);
263
+ }
264
+ store->Set(c, a[0], a[1]).Check();
265
+ });
266
+ SetMethod(isolate, self, "getAttribute",
267
+ [](const v8::FunctionCallbackInfo<v8::Value>& a) {
268
+ a.GetReturnValue().SetNull();
269
+ if (a.Length() < 1) return;
270
+ v8::Isolate* iso = a.GetIsolate();
271
+ v8::Local<v8::Context> c = iso->GetCurrentContext();
272
+ v8::Local<v8::Value> attrs;
273
+ if (a.This()->Get(c, v8util::Str(iso, "__attrs")).ToLocal(&attrs) && attrs->IsObject()) {
274
+ v8::Local<v8::Value> v;
275
+ if (attrs.As<v8::Object>()->Get(c, a[0]).ToLocal(&v) && !v->IsUndefined()) {
276
+ a.GetReturnValue().Set(v);
277
+ }
278
+ }
279
+ });
280
+
196
281
  // src セッター: 代入で読み込み開始
197
282
  self->SetNativeDataProperty(ctx, Str(isolate, "src"),
198
283
  [](v8::Local<v8::Name>, const v8::PropertyCallbackInfo<v8::Value>& info) {
@@ -218,12 +303,16 @@ v8::Local<v8::Object> CreateVideoElement(v8::Isolate* isolate, HostContext* /*ho
218
303
  SetMethod(isolate, self, "play", [](const v8::FunctionCallbackInfo<v8::Value>& a) {
219
304
  v8::Isolate* iso = a.GetIsolate();
220
305
  Decoder(a.This())->playing = true;
306
+ SetValue(iso, a.This(), "paused", v8::Boolean::New(iso, false));
307
+ SetValue(iso, a.This(), "ended", v8::Boolean::New(iso, false));
221
308
  auto r = v8::Promise::Resolver::New(iso->GetCurrentContext()).ToLocalChecked();
222
309
  r->Resolve(iso->GetCurrentContext(), v8::Undefined(iso)).Check();
223
310
  a.GetReturnValue().Set(r->GetPromise());
224
311
  });
225
312
  SetMethod(isolate, self, "pause", [](const v8::FunctionCallbackInfo<v8::Value>& a) {
313
+ v8::Isolate* iso = a.GetIsolate();
226
314
  Decoder(a.This())->playing = false;
315
+ SetValue(iso, a.This(), "paused", v8::Boolean::New(iso, true));
227
316
  });
228
317
  SetMethod(isolate, self, "canPlayType", [](const v8::FunctionCallbackInfo<v8::Value>& a) {
229
318
  a.GetReturnValue().Set(Str(a.GetIsolate(), "maybe"));