ソースを参照

* Timer implementation, javascript side

Michael Van Canneyt 10 ヶ月 前
コミット
53569c9ee9

+ 122 - 0
packages/wasm-utils/src/wasm.pas2js.timer.pas

@@ -0,0 +1,122 @@
+unit wasm.pas2js.timer;
+
+{$mode ObjFPC}
+
+// Uncomment/Define this if you do not want logging code
+{ $DEFINE NOLOGAPICALLS}
+
+interface
+
+uses
+  sysutils, js, wasienv, web, wasm.timer.shared;
+
+Type
+  TWasmPointer = longint;
+  TTimerTickCallback = Function (aTimerID : TWasmTimerID; UserData : TWasmPointer) : Boolean;
+
+  { TWasmTimerAPI }
+
+  TWasmTimerAPI = class(TImportExtension)
+  private
+    FLogApiCalls: Boolean;
+    function AllocateTimer(ainterval: longint; userdata: TWasmPointer): TWasmTimerID;
+    procedure DeallocateTimer(timerid: TWasmTimerID);
+  Protected
+    Procedure LogCall(const Msg : String);
+    Procedure LogCall(Const Fmt : String; const Args : Array of const);
+  Public
+    function ImportName: String; override;
+    procedure FillImportObject(aObject: TJSObject); override;
+    property LogAPICalls : Boolean Read FLogApiCalls Write FLogApiCalls;
+  end;
+
+
+implementation
+
+{ TWasmTimerAPI }
+
+procedure TWasmTimerAPI.LogCall(const Msg: String);
+begin
+{$IFNDEF NOLOGAPICALLS}
+  If not LogAPICalls then exit;
+  Writeln('TimerApi.'+Msg);
+{$ENDIF}
+end;
+
+procedure TWasmTimerAPI.LogCall(const Fmt: String; const Args: array of const);
+begin
+{$IFNDEF NOLOGAPICALLS}
+  If not LogAPICalls then exit;
+  Writeln('TimerApi.'+Format(Fmt,Args));
+{$ENDIF}
+end;
+
+
+function TWasmTimerAPI.ImportName: String;
+begin
+  Result:=TimerExportName;
+end;
+
+procedure TWasmTimerAPI.FillImportObject(aObject: TJSObject);
+begin
+  aObject[TimerFN_Allocate]:=@AllocateTimer;
+  aObject[TimerFN_DeAllocate]:=@DeAllocateTimer;
+end;
+
+
+function TWasmTimerApi.AllocateTimer(ainterval: longint; userdata: TWasmPointer): TWasmTimerID;
+
+var
+  aTimerID : TWasmTimerID;
+  CallBack:jsvalue;
+
+
+  Procedure HandleTimer;
+
+  var
+    Continue : boolean;
+
+  begin
+    // The instance/timer could have disappeared
+    Callback:=InstanceExports['__wasm_timer_tick'];
+    Continue:=Assigned(Callback);
+    if Continue then
+      Continue:=TTimerTickCallback(CallBack)(aTimerID,userData)
+    else
+      Console.Error('No more tick callback !');
+    if not Continue then
+      begin
+      {$IFNDEF NOLOGAPICALLS}
+      If LogAPICalls then
+        LogCall('TimerTick(%d), return value false, deactivate',[aTimerID]);
+      {$ENDIF}
+      DeAllocateTimer(aTimerID);
+      end;
+  end;
+
+begin
+  {$IFNDEF NOLOGAPICALLS}
+  If LogAPICalls then
+    LogCall('AllocateTimer(%d,[%x])',[aInterval,UserData]);
+  {$ENDIF}
+  Callback:=InstanceExports['__wasm_timer_tick'];
+  if Not Assigned(Callback) then
+    Exit(0);
+  aTimerID:=Window.setInterval(@HandleTimer,aInterval);
+  Result:=aTimerID;
+  {$IFNDEF NOLOGAPICALLS}
+  If LogAPICalls then
+    LogCall('AllocateTimer(%d,[%x] => %d)',[aInterval,UserData,Result]);
+  {$ENDIF}
+end;
+
+procedure TWasmTimerApi.DeallocateTimer(timerid: TWasmTimerID);
+begin
+  If LogAPICalls then
+    LogCall('DeAllocateTimer(%d)',[TimerID]);
+  window.clearInterval(TimerID);
+end;
+
+
+end.
+

+ 19 - 0
packages/wasm-utils/src/wasm.timer.shared.pas

@@ -0,0 +1,19 @@
+unit wasm.timer.shared;
+
+{$mode ObjFPC}{$H+}
+
+interface
+
+Type
+  TWasmTimerID = Longint;
+
+const
+  TimerExportName  = 'timer';
+  TimerFN_Allocate = 'allocate';
+  TimerFN_DeAllocate = 'deallocate';
+
+
+implementation
+
+end.
+