mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-12 12:05:57 +02:00
* Hosting example for webassembly module
This commit is contained in:
parent
0e11fe0fc5
commit
ec21c75e05
18
packages/wasm-job/examples/WebHost/README.md
Normal file
18
packages/wasm-job/examples/WebHost/README.md
Normal file
@ -0,0 +1,18 @@
|
||||
This directory contains a generic HTML loader page for a WebAssembly module
|
||||
that needs a WASI and JOB hosting environment.
|
||||
|
||||
Compile the .lpr with pas2js, and load the page in your browser.
|
||||
By default the page will attempt to load a demo.wasm module.
|
||||
|
||||
You can specify the module to load in 1 of 3 ways:
|
||||
|
||||
1. from external variable wasmFilename.
|
||||
To this end, copy hostconfig-template.js to hostconfig.js.
|
||||
In this file, change the name of the webassembly to load.
|
||||
|
||||
2. from the first part of hash: #moduleName/
|
||||
|
||||
3. from query varable wasmmodule: ?wasmmodule=x
|
||||
|
||||
the extension .wasm must be specified.
|
||||
|
1
packages/wasm-job/examples/WebHost/bulma.min.css
vendored
Normal file
1
packages/wasm-job/examples/WebHost/bulma.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -0,0 +1,5 @@
|
||||
/*
|
||||
* copy this template as hostconfig.js and adapt to your situation.
|
||||
*/
|
||||
var
|
||||
wasmFilename = 'promisedemo.wasm';
|
26
packages/wasm-job/examples/WebHost/index.html
Normal file
26
packages/wasm-job/examples/WebHost/index.html
Normal file
@ -0,0 +1,26 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Wasm Javascript Object Bindings - Test bed</title>
|
||||
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate"> <!-- Prevents caching -->
|
||||
<meta http-equiv="Pragma" content="no-cache"> <!-- Legacy HTTP 1.0 backward compatibility -->
|
||||
<meta http-equiv="Expires" content="0"> <!-- Proxies -->
|
||||
<link href="bulma.min.css" rel="stylesheet">
|
||||
<link type="stylesheet" src="bulma.min.css">
|
||||
<script src="hostconfig.js"></script>
|
||||
<script src="webhost.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="box">
|
||||
<p class="title is-3">Webassembly JOB test bed</p>
|
||||
<p class="subtitle is-5">Console output:</p>
|
||||
<div id="pasjsconsole">
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
rtl.showUncaughtExceptions=true;
|
||||
rtl.run();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
4
packages/wasm-job/examples/WebHost/simpleserver.ini
Normal file
4
packages/wasm-job/examples/WebHost/simpleserver.ini
Normal file
@ -0,0 +1,4 @@
|
||||
[Server]
|
||||
Port=3030
|
||||
Directory=/home/tixeo/fpc/packages/wasm-job/examples
|
||||
|
104
packages/wasm-job/examples/WebHost/webhost.lpi
Normal file
104
packages/wasm-job/examples/WebHost/webhost.lpi
Normal file
@ -0,0 +1,104 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CONFIG>
|
||||
<ProjectOptions>
|
||||
<Version Value="12"/>
|
||||
<General>
|
||||
<Flags>
|
||||
<MainUnitHasCreateFormStatements Value="False"/>
|
||||
<MainUnitHasTitleStatement Value="False"/>
|
||||
<MainUnitHasScaledStatement Value="False"/>
|
||||
<Runnable Value="False"/>
|
||||
</Flags>
|
||||
<SessionStorage Value="InProjectDir"/>
|
||||
<Title Value="Browser loader for Webassembly module with JOB functionality."/>
|
||||
<UseAppBundle Value="False"/>
|
||||
<ResourceType Value="res"/>
|
||||
</General>
|
||||
<CustomData Count="4">
|
||||
<Item0 Name="MaintainHTML" Value="1"/>
|
||||
<Item1 Name="Pas2JSProject" Value="1"/>
|
||||
<Item2 Name="PasJSLocation" Value="BrowserTixeoDom"/>
|
||||
<Item3 Name="PasJSWebBrowserProject" Value="1"/>
|
||||
</CustomData>
|
||||
<BuildModes>
|
||||
<Item Name="Default" Default="True"/>
|
||||
</BuildModes>
|
||||
<PublishOptions>
|
||||
<Version Value="2"/>
|
||||
<UseFileFilters Value="True"/>
|
||||
</PublishOptions>
|
||||
<RunParams>
|
||||
<FormatVersion Value="2"/>
|
||||
</RunParams>
|
||||
<Units>
|
||||
<Unit>
|
||||
<Filename Value="webhost.lpr"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit>
|
||||
<Unit>
|
||||
<Filename Value="../index.html"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<CustomData Count="1">
|
||||
<Item0 Name="PasJSIsProjectHTMLFile" Value="1"/>
|
||||
</CustomData>
|
||||
</Unit>
|
||||
<Unit>
|
||||
<Filename Value="../../../job/job_browser.pp"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<UnitName Value="JOB_Browser"/>
|
||||
</Unit>
|
||||
<Unit>
|
||||
<Filename Value="../../../job/job_shared.pp"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<UnitName Value="JOB_Shared"/>
|
||||
</Unit>
|
||||
</Units>
|
||||
</ProjectOptions>
|
||||
<CompilerOptions>
|
||||
<Version Value="11"/>
|
||||
<Target FileExt=".js">
|
||||
<Filename Value="webhost"/>
|
||||
</Target>
|
||||
<SearchPaths>
|
||||
<IncludeFiles Value="$(ProjOutDir)"/>
|
||||
<OtherUnitFiles Value="../../../job"/>
|
||||
<UnitOutputDirectory Value="js"/>
|
||||
</SearchPaths>
|
||||
<Parsing>
|
||||
<SyntaxOptions>
|
||||
<AllowLabel Value="False"/>
|
||||
<UseAnsiStrings Value="False"/>
|
||||
<CPPInline Value="False"/>
|
||||
</SyntaxOptions>
|
||||
</Parsing>
|
||||
<CodeGeneration>
|
||||
<TargetOS Value="browser"/>
|
||||
</CodeGeneration>
|
||||
<Linking>
|
||||
<Debugging>
|
||||
<GenerateDebugInfo Value="False"/>
|
||||
<UseLineInfoUnit Value="False"/>
|
||||
</Debugging>
|
||||
</Linking>
|
||||
<Other>
|
||||
<CustomOptions Value="-Jeutf-8
|
||||
-Jirtl.js
|
||||
-Jc
|
||||
-Jminclude"/>
|
||||
<CompilerPath Value="$(pas2js)"/>
|
||||
</Other>
|
||||
</CompilerOptions>
|
||||
<Debugging>
|
||||
<Exceptions>
|
||||
<Item>
|
||||
<Name Value="EAbort"/>
|
||||
</Item>
|
||||
<Item>
|
||||
<Name Value="ECodetoolError"/>
|
||||
</Item>
|
||||
<Item>
|
||||
<Name Value="EFOpenError"/>
|
||||
</Item>
|
||||
</Exceptions>
|
||||
</Debugging>
|
||||
</CONFIG>
|
74
packages/wasm-job/examples/WebHost/webhost.lpr
Normal file
74
packages/wasm-job/examples/WebHost/webhost.lpr
Normal file
@ -0,0 +1,74 @@
|
||||
program webhost;
|
||||
|
||||
{$mode objfpc}
|
||||
|
||||
uses
|
||||
BrowserConsole, JS, Types, Classes, SysUtils, Web, WasiEnv, WasiHostApp, JOB_Browser, JOB_Shared;
|
||||
|
||||
|
||||
var
|
||||
wasmFilename : string; external name 'wasmFilename';
|
||||
|
||||
Type
|
||||
|
||||
{ TMyApplication }
|
||||
|
||||
TMyApplication = class(TBrowserWASIHostApplication)
|
||||
Private
|
||||
FJOB : TJSObjectBridge;
|
||||
function GetWasmModuleName: String;
|
||||
Public
|
||||
constructor Create(aOwner : TComponent); override;
|
||||
procedure DoRun; override;
|
||||
end;
|
||||
|
||||
{ TMyApplication }
|
||||
|
||||
constructor TMyApplication.Create(aOwner: TComponent);
|
||||
begin
|
||||
inherited Create(aOwner);
|
||||
FJOB:=TJSObjectBridge.Create(WasiEnvironment);
|
||||
RunEntryFunction:='_initialize';
|
||||
end;
|
||||
|
||||
function TMyApplication.GetWasmModuleName : String;
|
||||
{ Determine webassembly module to run
|
||||
1. from external variable wasmFilename
|
||||
2. from first part of hash: #moduleName/
|
||||
3. from query varable wasmmodule: ?wasmmodule=x
|
||||
4. Hardcoded 'demo.wasm';
|
||||
}
|
||||
|
||||
begin
|
||||
Result:='';
|
||||
if IsString(wasmFilename) then
|
||||
Result:=wasmFilename;
|
||||
if (Result='') then
|
||||
Result:=ParamStr(1);
|
||||
if (Result='') then
|
||||
Result:=GetEnvironmentVar('wasmmodule');
|
||||
if Result='' then
|
||||
Result:='demo.wasm';
|
||||
end;
|
||||
|
||||
procedure TMyApplication.DoRun;
|
||||
|
||||
var
|
||||
WasmModule : String;
|
||||
|
||||
begin
|
||||
Terminate;
|
||||
WasmModule:=GetWasmModuleName;
|
||||
Writeln('Loading & starting webassembly module :' ,WasmModule);
|
||||
StartWebAssembly('WasmModule.wasm',true);
|
||||
end;
|
||||
|
||||
var
|
||||
Application : TMyApplication;
|
||||
begin
|
||||
ConsoleStyle:=DefaultCRTConsoleStyle;
|
||||
HookConsole;
|
||||
Application:=TMyApplication.Create(nil);
|
||||
Application.Initialize;
|
||||
Application.Run;
|
||||
end.
|
73
packages/wasm-job/examples/promise-2/promisedemo2.lpi
Normal file
73
packages/wasm-job/examples/promise-2/promisedemo2.lpi
Normal file
@ -0,0 +1,73 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CONFIG>
|
||||
<ProjectOptions>
|
||||
<Version Value="12"/>
|
||||
<General>
|
||||
<Flags>
|
||||
<MainUnitHasCreateFormStatements Value="False"/>
|
||||
<MainUnitHasTitleStatement Value="False"/>
|
||||
<MainUnitHasScaledStatement Value="False"/>
|
||||
</Flags>
|
||||
<SessionStorage Value="InProjectDir"/>
|
||||
<Title Value="promise demo: delayed resolve"/>
|
||||
<UseAppBundle Value="False"/>
|
||||
<ResourceType Value="res"/>
|
||||
</General>
|
||||
<BuildModes>
|
||||
<Item Name="Default" Default="True"/>
|
||||
</BuildModes>
|
||||
<PublishOptions>
|
||||
<Version Value="2"/>
|
||||
<UseFileFilters Value="True"/>
|
||||
</PublishOptions>
|
||||
<RunParams>
|
||||
<FormatVersion Value="2"/>
|
||||
</RunParams>
|
||||
<Units>
|
||||
<Unit>
|
||||
<Filename Value="promisedemo2.lpr"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<UnitName Value="promisedemo"/>
|
||||
</Unit>
|
||||
</Units>
|
||||
</ProjectOptions>
|
||||
<CompilerOptions>
|
||||
<Version Value="11"/>
|
||||
<Target>
|
||||
<Filename Value="promisedemo2.wasm" ApplyConventions="False"/>
|
||||
</Target>
|
||||
<SearchPaths>
|
||||
<IncludeFiles Value="$(ProjOutDir)"/>
|
||||
<OtherUnitFiles Value="../src"/>
|
||||
<UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/>
|
||||
</SearchPaths>
|
||||
<CodeGeneration>
|
||||
<TargetCPU Value="wasm32"/>
|
||||
<TargetOS Value="wasi"/>
|
||||
</CodeGeneration>
|
||||
<Linking>
|
||||
<Debugging>
|
||||
<GenerateDebugInfo Value="False"/>
|
||||
</Debugging>
|
||||
<Options>
|
||||
<ExecutableType Value="Library"/>
|
||||
</Options>
|
||||
</Linking>
|
||||
<Other>
|
||||
<CustomOptions Value="-Ur"/>
|
||||
</Other>
|
||||
</CompilerOptions>
|
||||
<Debugging>
|
||||
<Exceptions>
|
||||
<Item>
|
||||
<Name Value="EAbort"/>
|
||||
</Item>
|
||||
<Item>
|
||||
<Name Value="ECodetoolError"/>
|
||||
</Item>
|
||||
<Item>
|
||||
<Name Value="EFOpenError"/>
|
||||
</Item>
|
||||
</Exceptions>
|
||||
</Debugging>
|
||||
</CONFIG>
|
134
packages/wasm-job/examples/promise-2/promisedemo2.lpr
Normal file
134
packages/wasm-job/examples/promise-2/promisedemo2.lpr
Normal file
@ -0,0 +1,134 @@
|
||||
library promisedemo;
|
||||
{$mode objfpc}
|
||||
{$h+}
|
||||
uses nothreads, sysutils, job.js, variants;
|
||||
|
||||
Type
|
||||
TFunction = function (const arguments: Variant): Variant of object;
|
||||
|
||||
IJSWindow = interface(IJSObject)
|
||||
function setTimeout(const aHandler: TFunction; aTimeout: LongInt; const aArguments: Variant): LongInt{; ToDo:varargs};
|
||||
function setTimeout(const aHandler: TFunction): LongInt{; ToDo:varargs};
|
||||
function setTimeout(const aHandler: UnicodeString; aTimeout: LongInt; const aUnused: Variant): LongInt{; ToDo:varargs};
|
||||
function setTimeout(const aHandler: UnicodeString): LongInt{; ToDo:varargs};
|
||||
end;
|
||||
|
||||
TJSWindow = class(TJSObject,IJSWindow)
|
||||
function setTimeout(const aHandler: TFunction; aTimeout: LongInt; const aArguments: Variant): LongInt{; ToDo:varargs};
|
||||
function setTimeout(const aHandler: TFunction): LongInt{; ToDo:varargs};
|
||||
function setTimeout(const aHandler: UnicodeString; aTimeout: LongInt; const aUnused: Variant): LongInt{; ToDo:varargs};
|
||||
function setTimeout(const aHandler: UnicodeString): LongInt{; ToDo:varargs};
|
||||
end;
|
||||
|
||||
TApp = Class(TObject)
|
||||
private
|
||||
FOnResolve: TJSPromiseResolver;
|
||||
FOnReject: TJSPromiseResolver;
|
||||
public
|
||||
function DoTimeout(const arguments: Variant): Variant;
|
||||
function DoResolve(const aValue: Variant): Variant;
|
||||
procedure DoPromiseExecutor(const OnResolve, OnReject:TJSPromiseResolver);
|
||||
function ResolveTest: TJSPromise;
|
||||
procedure Run;
|
||||
end;
|
||||
|
||||
var
|
||||
JSWindow : IJSWindow;
|
||||
|
||||
function JOBCallFunction_(const aMethod: TMethod; var H: TJOBCallbackHelper): PByte;
|
||||
var
|
||||
arguments: Variant;
|
||||
begin
|
||||
arguments:=H.GetVariant;
|
||||
Result:=H.AllocVariant(TFunction(aMethod)(arguments));
|
||||
end;
|
||||
|
||||
|
||||
function TJSWindow.setTimeout(const aHandler: TFunction; aTimeout: LongInt; const aArguments: Variant): LongInt{; ToDo:varargs};
|
||||
var
|
||||
m: TJOB_Method;
|
||||
begin
|
||||
m:=TJOB_Method.Create(TMethod(aHandler),@JOBCallFunction_);
|
||||
try
|
||||
Result:=InvokeJSLongIntResult('setTimeout',[m,aTimeout,aArguments]);
|
||||
finally
|
||||
m.free;
|
||||
end;
|
||||
end;
|
||||
function TJSWindow.setTimeout(const aHandler: TFunction): LongInt{; ToDo:varargs};
|
||||
var
|
||||
m: TJOB_Method;
|
||||
begin
|
||||
m:=TJOB_Method.Create(TMethod(aHandler),@JOBCallFunction_);
|
||||
try
|
||||
Result:=InvokeJSLongIntResult('setTimeout',[m]);
|
||||
finally
|
||||
m.free;
|
||||
end;
|
||||
end;
|
||||
function TJSWindow.setTimeout(const aHandler: UnicodeString; aTimeout: LongInt; const aUnused: Variant): LongInt{; ToDo:varargs};
|
||||
begin
|
||||
Result:=InvokeJSLongIntResult('setTimeout',[aHandler,aTimeout,aUnused]);
|
||||
end;
|
||||
function TJSWindow.setTimeout(const aHandler: UnicodeString): LongInt{; ToDo:varargs};
|
||||
begin
|
||||
Result:=InvokeJSLongIntResult('setTimeout',[aHandler]);
|
||||
end;
|
||||
|
||||
|
||||
{ TApp }
|
||||
|
||||
function TApp.DoTimeout(const arguments: Variant): Variant;
|
||||
begin
|
||||
if not Assigned(FOnResolve) then
|
||||
Writeln('Wasm ERROR: no resolve callback');
|
||||
if not Assigned(FOnReject) then
|
||||
Writeln('Wasm ERROR: no reject callback');
|
||||
|
||||
if Assigned(FOnResolve) then
|
||||
FOnResolve('resolved');
|
||||
end;
|
||||
|
||||
function TApp.DoResolve(const aValue: Variant): Variant;
|
||||
begin
|
||||
Writeln('Wasm: in DoResolve: success. Argument vartype: ', vartype(aValue));
|
||||
if vartype(aValue)=varOleStr then
|
||||
Writeln('Wasm: DoResolve received value: ', VarToStr(aValue));
|
||||
result:=unassigned;
|
||||
end;
|
||||
|
||||
procedure TApp.DoPromiseExecutor(const OnResolve, OnReject: TJSPromiseResolver);
|
||||
begin
|
||||
FOnResolve := OnResolve;
|
||||
FOnReject := OnReject;
|
||||
|
||||
JSWindow.setTimeout(@DoTimeout, 1000, nil);
|
||||
end;
|
||||
|
||||
function TApp.ResolveTest: TJSPromise;
|
||||
begin
|
||||
Result:=TJSPromise.Create(@DoPromiseExecutor);
|
||||
end;
|
||||
|
||||
procedure TApp.Run;
|
||||
|
||||
Var
|
||||
P : TJSPromise;
|
||||
|
||||
begin
|
||||
try
|
||||
P:=ResolveTest;
|
||||
P._then(@DoResolve);
|
||||
except
|
||||
on E: Exception do
|
||||
Writeln(e.Message);
|
||||
end;
|
||||
end;
|
||||
|
||||
var
|
||||
App : TApp;
|
||||
begin
|
||||
JSWindow:=TJSWindow.JOBCreateGlobal('window');
|
||||
App:=TApp.Create;
|
||||
App.Run;
|
||||
end.
|
Loading…
Reference in New Issue
Block a user