mirror of
https://gitlab.com/freepascal.org/fpc/pas2js.git
synced 2025-04-21 09:19:27 +02:00
* WASI runtime embedding
This commit is contained in:
parent
6f1f064d16
commit
2626eef7c3
22
demo/asyncawait/asyncawaitdemos.lpg
Normal file
22
demo/asyncawait/asyncawaitdemos.lpg
Normal file
@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CONFIG>
|
||||
<ProjectGroup FileVersion="2">
|
||||
<Targets>
|
||||
<Target FileName="manualpromise.lpi">
|
||||
<BuildModes>
|
||||
<Mode Name="Default"/>
|
||||
</BuildModes>
|
||||
</Target>
|
||||
<Target FileName="tryfetch.lpi">
|
||||
<BuildModes>
|
||||
<Mode Name="Default"/>
|
||||
</BuildModes>
|
||||
</Target>
|
||||
<Target FileName="trymany.lpi">
|
||||
<BuildModes>
|
||||
<Mode Name="Default"/>
|
||||
</BuildModes>
|
||||
</Target>
|
||||
</Targets>
|
||||
</ProjectGroup>
|
||||
</CONFIG>
|
@ -1,75 +1,92 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CONFIG>
|
||||
<ProjectGroup FileVersion="1">
|
||||
<Targets Count="17">
|
||||
<Target0 FileName="demoarea.lpi">
|
||||
<BuildModes Count="1"/>
|
||||
<Mode1 Name="Default"/>
|
||||
</Target0>
|
||||
<Target1 FileName="demobar.lpi">
|
||||
<BuildModes Count="1"/>
|
||||
<Mode1 Name="Default"/>
|
||||
</Target1>
|
||||
<Target2 FileName="demobubble.lpi">
|
||||
<BuildModes Count="1"/>
|
||||
<Mode1 Name="Default"/>
|
||||
</Target2>
|
||||
<Target3 FileName="democustompoints.lpi">
|
||||
<BuildModes Count="1"/>
|
||||
<Mode1 Name="Default"/>
|
||||
</Target3>
|
||||
<Target4 FileName="demodatalabelling.lpi">
|
||||
<BuildModes Count="1"/>
|
||||
<Mode1 Name="Default"/>
|
||||
</Target4>
|
||||
<Target5 FileName="demodate.lpi">
|
||||
<BuildModes Count="1"/>
|
||||
<Mode1 Name="Default"/>
|
||||
</Target5>
|
||||
<Target6 FileName="demodoughnut.lpi">
|
||||
<BuildModes Count="1"/>
|
||||
<Mode1 Name="Default"/>
|
||||
</Target6>
|
||||
<Target7 FileName="demointeractions.lpi">
|
||||
<BuildModes Count="1"/>
|
||||
<Mode1 Name="Default"/>
|
||||
</Target7>
|
||||
<Target8 FileName="demoline.lpi">
|
||||
<BuildModes Count="1"/>
|
||||
<Mode1 Name="Default"/>
|
||||
</Target8>
|
||||
<Target9 FileName="demomixed.lpi">
|
||||
<BuildModes Count="1"/>
|
||||
<Mode1 Name="Default"/>
|
||||
</Target9>
|
||||
<Target10 FileName="demopie.lpi">
|
||||
<BuildModes Count="1"/>
|
||||
<Mode1 Name="Default"/>
|
||||
</Target10>
|
||||
<Target11 FileName="demopolararea.lpi">
|
||||
<BuildModes Count="1"/>
|
||||
<Mode1 Name="Default"/>
|
||||
</Target11>
|
||||
<Target12 FileName="demoprogressbar.lpi">
|
||||
<BuildModes Count="1"/>
|
||||
<Mode1 Name="Default"/>
|
||||
</Target12>
|
||||
<Target13 FileName="demoradar.lpi">
|
||||
<BuildModes Count="1"/>
|
||||
<Mode1 Name="Default"/>
|
||||
</Target13>
|
||||
<Target14 FileName="demoscatter.lpi">
|
||||
<BuildModes Count="1"/>
|
||||
<Mode1 Name="Default"/>
|
||||
</Target14>
|
||||
<Target15 FileName="demoscriptablebubble.lpi">
|
||||
<BuildModes Count="1"/>
|
||||
<Mode1 Name="Default"/>
|
||||
</Target15>
|
||||
<Target16 FileName="demotime.lpi">
|
||||
<BuildModes Count="1"/>
|
||||
<Mode1 Name="Default"/>
|
||||
</Target16>
|
||||
<ProjectGroup FileVersion="2">
|
||||
<Targets>
|
||||
<Target FileName="demoarea.lpi">
|
||||
<BuildModes>
|
||||
<Mode Name="Default"/>
|
||||
</BuildModes>
|
||||
</Target>
|
||||
<Target FileName="demobar.lpi">
|
||||
<BuildModes>
|
||||
<Mode Name="Default"/>
|
||||
</BuildModes>
|
||||
</Target>
|
||||
<Target FileName="demobubble.lpi">
|
||||
<BuildModes>
|
||||
<Mode Name="Default"/>
|
||||
</BuildModes>
|
||||
</Target>
|
||||
<Target FileName="democustompoints.lpi">
|
||||
<BuildModes>
|
||||
<Mode Name="Default"/>
|
||||
</BuildModes>
|
||||
</Target>
|
||||
<Target FileName="demodatalabelling.lpi">
|
||||
<BuildModes>
|
||||
<Mode Name="Default"/>
|
||||
</BuildModes>
|
||||
</Target>
|
||||
<Target FileName="demodate.lpi">
|
||||
<BuildModes>
|
||||
<Mode Name="Default"/>
|
||||
</BuildModes>
|
||||
</Target>
|
||||
<Target FileName="demodoughnut.lpi">
|
||||
<BuildModes>
|
||||
<Mode Name="Default"/>
|
||||
</BuildModes>
|
||||
</Target>
|
||||
<Target FileName="demointeractions.lpi">
|
||||
<BuildModes>
|
||||
<Mode Name="Default"/>
|
||||
</BuildModes>
|
||||
</Target>
|
||||
<Target FileName="demoline.lpi">
|
||||
<BuildModes>
|
||||
<Mode Name="Default"/>
|
||||
</BuildModes>
|
||||
</Target>
|
||||
<Target FileName="demomixed.lpi">
|
||||
<BuildModes>
|
||||
<Mode Name="Default"/>
|
||||
</BuildModes>
|
||||
</Target>
|
||||
<Target FileName="demopie.lpi">
|
||||
<BuildModes>
|
||||
<Mode Name="Default"/>
|
||||
</BuildModes>
|
||||
</Target>
|
||||
<Target FileName="demopolararea.lpi">
|
||||
<BuildModes>
|
||||
<Mode Name="Default"/>
|
||||
</BuildModes>
|
||||
</Target>
|
||||
<Target FileName="demoprogressbar.lpi">
|
||||
<BuildModes>
|
||||
<Mode Name="Default"/>
|
||||
</BuildModes>
|
||||
</Target>
|
||||
<Target FileName="demoradar.lpi">
|
||||
<BuildModes>
|
||||
<Mode Name="Default"/>
|
||||
</BuildModes>
|
||||
</Target>
|
||||
<Target FileName="demoscatter.lpi">
|
||||
<BuildModes>
|
||||
<Mode Name="Default"/>
|
||||
</BuildModes>
|
||||
</Target>
|
||||
<Target FileName="demoscriptablebubble.lpi">
|
||||
<BuildModes>
|
||||
<Mode Name="Default"/>
|
||||
</BuildModes>
|
||||
</Target>
|
||||
<Target FileName="demotime.lpi">
|
||||
<BuildModes>
|
||||
<Mode Name="Default"/>
|
||||
</BuildModes>
|
||||
</Target>
|
||||
</Targets>
|
||||
</ProjectGroup>
|
||||
</CONFIG>
|
||||
|
@ -1,47 +1,119 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CONFIG>
|
||||
<ProjectGroup FileVersion="1">
|
||||
<Targets Count="19">
|
||||
<Target0 FileName="rtl/rtl_demos.lpg"/>
|
||||
<Target1 FileName="promise/promise_demos.lpg"/>
|
||||
<Target2 FileName="chartjs/chartjs_demos.lpg"/>
|
||||
<Target3 FileName="webgl/webgl_demos.lpg"/>
|
||||
<Target4 FileName="router/demorouter.lpi"/>
|
||||
<Target5 FileName="router/demorouter2.lpi"/>
|
||||
<Target6 FileName="trayicon/trayicon.lpi">
|
||||
<BuildModes Count="1"/>
|
||||
<Mode1 Name="Default"/>
|
||||
</Target6>
|
||||
<Target7 FileName="dataabstract/sampleda.lpi">
|
||||
<BuildModes Count="1"/>
|
||||
<Mode1 Name="Default"/>
|
||||
</Target7>
|
||||
<Target8 FileName="fcldb/demodb.lpi"/>
|
||||
<Target9 FileName="fcldb/demoload.lpi"/>
|
||||
<Target10 FileName="fcldb/demorest.lpi"/>
|
||||
<Target11 FileName="fcldb/demorest2.lpi">
|
||||
<BuildModes Count="1"/>
|
||||
<Mode1 Name="Default"/>
|
||||
</Target11>
|
||||
<Target12 FileName="fcldb/restserver.lpi"/>
|
||||
<Target13 FileName="fpcunit/browsertest.lpi">
|
||||
<BuildModes Count="1"/>
|
||||
<Mode1 Name="default"/>
|
||||
</Target13>
|
||||
<Target14 FileName="dynload/testloader.lpi">
|
||||
<BuildModes Count="1"/>
|
||||
<Mode1 Name="Default"/>
|
||||
</Target14>
|
||||
<Target15 FileName="hotreload/hotreload.lpi"/>
|
||||
<Target16 FileName="hotreload/server.lpi">
|
||||
<BuildModes Count="1"/>
|
||||
<Mode1 Name="Default"/>
|
||||
</Target16>
|
||||
<Target17 FileName="jquery/demoadd.lpi"/>
|
||||
<Target18 FileName="jspdf/basic.lpi">
|
||||
<BuildModes Count="1"/>
|
||||
<Mode1 Name="Default"/>
|
||||
</Target18>
|
||||
<ProjectGroup FileVersion="2">
|
||||
<Targets>
|
||||
<Target FileName="rtl/rtl_demos.lpg"/>
|
||||
<Target FileName="promise/promise_demos.lpg"/>
|
||||
<Target FileName="chartjs/chartjs_demos.lpg"/>
|
||||
<Target FileName="webgl/webgl_demos.lpg"/>
|
||||
<Target FileName="asyncawait/asyncawaitdemos.lpg"/>
|
||||
<Target FileName="wasienv/wasienvdemos.lpg"/>
|
||||
<Target FileName="translate/translate_demos.lpg"/>
|
||||
<Target FileName="resources/resourcedemos.lpg"/>
|
||||
<Target FileName="router/demorouter.lpi">
|
||||
<BuildModes>
|
||||
<Mode Name="default"/>
|
||||
</BuildModes>
|
||||
</Target>
|
||||
<Target FileName="router/demorouter2.lpi"/>
|
||||
<Target FileName="dataabstract/sampleda.lpi">
|
||||
<BuildModes>
|
||||
<Mode Name="Default"/>
|
||||
</BuildModes>
|
||||
</Target>
|
||||
<Target FileName="fcldb/demodb.lpi"/>
|
||||
<Target FileName="fcldb/demoload.lpi"/>
|
||||
<Target FileName="fcldb/demorest.lpi"/>
|
||||
<Target FileName="fcldb/restserver.lpi"/>
|
||||
<Target FileName="fpcunit/browsertest.lpi"/>
|
||||
<Target FileName="dynload/testloader.lpi">
|
||||
<BuildModes>
|
||||
<Mode Name="Default"/>
|
||||
</BuildModes>
|
||||
</Target>
|
||||
<Target FileName="hotreload/hotreload.lpi"/>
|
||||
<Target FileName="hotreload/server.lpi">
|
||||
<BuildModes>
|
||||
<Mode Name="Default"/>
|
||||
</BuildModes>
|
||||
</Target>
|
||||
<Target FileName="jquery/demoadd.lpi"/>
|
||||
<Target FileName="jspdf/basic.lpi">
|
||||
<BuildModes>
|
||||
<Mode Name="Default"/>
|
||||
</BuildModes>
|
||||
</Target>
|
||||
<Target FileName="fullcalendar/demofullcalendar.lpi">
|
||||
<BuildModes>
|
||||
<Mode Name="Default"/>
|
||||
</BuildModes>
|
||||
</Target>
|
||||
<Target FileName="fullcalendar/demofullcalendar4.lpi">
|
||||
<BuildModes>
|
||||
<Mode Name="Default"/>
|
||||
</BuildModes>
|
||||
</Target>
|
||||
<Target FileName="fullcalendar/demofullcalendar5.lpi">
|
||||
<BuildModes>
|
||||
<Mode Name="Default"/>
|
||||
</BuildModes>
|
||||
</Target>
|
||||
<Target FileName="fpreport/reportdemo.lpi"/>
|
||||
<Target FileName="jitsimeet/demojitsimeet.lpi">
|
||||
<BuildModes>
|
||||
<Mode Name="Default"/>
|
||||
</BuildModes>
|
||||
</Target>
|
||||
<Target FileName="pushjs/helloworld.lpi">
|
||||
<BuildModes>
|
||||
<Mode Name="Default"/>
|
||||
</BuildModes>
|
||||
</Target>
|
||||
<Target FileName="tetris/tetris.lpi">
|
||||
<BuildModes>
|
||||
<Mode Name="Default"/>
|
||||
</BuildModes>
|
||||
</Target>
|
||||
<Target FileName="websockets/demowebsocket.lpi">
|
||||
<BuildModes>
|
||||
<Mode Name="Default"/>
|
||||
</BuildModes>
|
||||
</Target>
|
||||
<Target FileName="webwidget/widgets/webwidgetsdemo.lpi">
|
||||
<BuildModes>
|
||||
<Mode Name="Default"/>
|
||||
</BuildModes>
|
||||
</Target>
|
||||
<Target FileName="xterm/xtermdemo.lpi">
|
||||
<BuildModes>
|
||||
<Mode Name="Default"/>
|
||||
</BuildModes>
|
||||
</Target>
|
||||
<Target FileName="restbridge/simple/restbridgeclient.lpi">
|
||||
<BuildModes>
|
||||
<Mode Name="Default"/>
|
||||
</BuildModes>
|
||||
</Target>
|
||||
<Target FileName="opentok/demoopentok.lpi">
|
||||
<BuildModes>
|
||||
<Mode Name="default"/>
|
||||
</BuildModes>
|
||||
</Target>
|
||||
<Target FileName="extend_jsclass/ExtendJSFunctionClass1.lpi">
|
||||
<BuildModes>
|
||||
<Mode Name="Default"/>
|
||||
</BuildModes>
|
||||
</Target>
|
||||
<Target FileName="bootstrap/demobootstraptable.lpi">
|
||||
<BuildModes>
|
||||
<Mode Name="Default"/>
|
||||
</BuildModes>
|
||||
</Target>
|
||||
<Target FileName="atom/pas2jsdemopackage.lpi">
|
||||
<BuildModes>
|
||||
<Mode Name="Default"/>
|
||||
</BuildModes>
|
||||
</Target>
|
||||
</Targets>
|
||||
</ProjectGroup>
|
||||
</CONFIG>
|
||||
|
@ -1,12 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CONFIG>
|
||||
<ProjectGroup FileVersion="1">
|
||||
<Targets Count="5">
|
||||
<Target0 FileName="story.lpi"/>
|
||||
<Target1 FileName="story2.lpi"/>
|
||||
<Target2 FileName="story3.lpi"/>
|
||||
<Target3 FileName="demoall.lpi"/>
|
||||
<Target4 FileName="askmom.lpi"/>
|
||||
<ProjectGroup FileVersion="2">
|
||||
<Targets>
|
||||
<Target FileName="story.lpi"/>
|
||||
<Target FileName="story2.lpi"/>
|
||||
<Target FileName="story3.lpi"/>
|
||||
<Target FileName="demoall.lpi"/>
|
||||
<Target FileName="askmom.lpi"/>
|
||||
</Targets>
|
||||
</ProjectGroup>
|
||||
</CONFIG>
|
||||
|
27
demo/resources/resourcedemos.lpg
Normal file
27
demo/resources/resourcedemos.lpg
Normal file
@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CONFIG>
|
||||
<ProjectGroup FileVersion="2">
|
||||
<Targets>
|
||||
<Target FileName="consoledemo.lpi">
|
||||
<BuildModes>
|
||||
<Mode Name="Default"/>
|
||||
</BuildModes>
|
||||
</Target>
|
||||
<Target FileName="htmldemo.lpi">
|
||||
<BuildModes>
|
||||
<Mode Name="Default"/>
|
||||
</BuildModes>
|
||||
</Target>
|
||||
<Target FileName="htmllinkdemo.lpi">
|
||||
<BuildModes>
|
||||
<Mode Name="Default"/>
|
||||
</BuildModes>
|
||||
</Target>
|
||||
<Target FileName="htmlloadlinkdemo.lpi">
|
||||
<BuildModes>
|
||||
<Mode Name="Default"/>
|
||||
</BuildModes>
|
||||
</Target>
|
||||
</Targets>
|
||||
</ProjectGroup>
|
||||
</CONFIG>
|
@ -1,21 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CONFIG>
|
||||
<ProjectGroup FileVersion="1">
|
||||
<Targets Count="14">
|
||||
<Target0 FileName="demoajax.lpi"/>
|
||||
<Target1 FileName="demobrowserconsole.lpi"/>
|
||||
<Target2 FileName="democanvas2d.lpi"/>
|
||||
<Target3 FileName="democlasstopas.lpi"/>
|
||||
<Target4 FileName="democollection.lpi"/>
|
||||
<Target5 FileName="democomponents.lpi"/>
|
||||
<Target6 FileName="demodatetime.lpi"/>
|
||||
<Target7 FileName="demodombuttonevent.lpi"/>
|
||||
<Target8 FileName="demojsarray.lpi"/>
|
||||
<Target9 FileName="demorouter.lpi"/>
|
||||
<Target10 FileName="demortti.lpi"/>
|
||||
<Target11 FileName="demostringlist.lpi"/>
|
||||
<Target12 FileName="demouncaughtexception.lpi"/>
|
||||
<Target13 FileName="demoxhr.lpi"/>
|
||||
<ProjectGroup FileVersion="2">
|
||||
<Targets>
|
||||
<Target FileName="demoajax.lpi"/>
|
||||
<Target FileName="demobrowserconsole.lpi"/>
|
||||
<Target FileName="democanvas2d.lpi"/>
|
||||
<Target FileName="democlasstopas.lpi">
|
||||
<BuildModes>
|
||||
<Mode Name="default"/>
|
||||
</BuildModes>
|
||||
</Target>
|
||||
<Target FileName="democollection.lpi"/>
|
||||
<Target FileName="democomponents.lpi"/>
|
||||
<Target FileName="demodatetime.lpi"/>
|
||||
<Target FileName="demodombuttonevent.lpi"/>
|
||||
<Target FileName="demojsarray.lpi"/>
|
||||
<Target FileName="demorouter.lpi"/>
|
||||
<Target FileName="demortti.lpi"/>
|
||||
<Target FileName="demostringlist.lpi"/>
|
||||
<Target FileName="demouncaughtexception.lpi"/>
|
||||
<Target FileName="demoxhr.lpi"/>
|
||||
</Targets>
|
||||
</ProjectGroup>
|
||||
</CONFIG>
|
||||
|
22
demo/translate/translate_demos.lpg
Normal file
22
demo/translate/translate_demos.lpg
Normal file
@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CONFIG>
|
||||
<ProjectGroup FileVersion="2">
|
||||
<Targets>
|
||||
<Target FileName="translate_basic.lpi">
|
||||
<BuildModes>
|
||||
<Mode Name="Default"/>
|
||||
</BuildModes>
|
||||
</Target>
|
||||
<Target FileName="translate_object.lpi">
|
||||
<BuildModes>
|
||||
<Mode Name="Default"/>
|
||||
</BuildModes>
|
||||
</Target>
|
||||
<Target FileName="translate_url.lpi">
|
||||
<BuildModes>
|
||||
<Mode Name="Default"/>
|
||||
</BuildModes>
|
||||
</Target>
|
||||
</Targets>
|
||||
</ProjectGroup>
|
||||
</CONFIG>
|
56
demo/wasienv/canvas/canvasdraw.lpi
Normal file
56
demo/wasienv/canvas/canvasdraw.lpi
Normal file
@ -0,0 +1,56 @@
|
||||
<?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="canvasdraw"/>
|
||||
<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="canvasdraw.lpr"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit>
|
||||
</Units>
|
||||
</ProjectOptions>
|
||||
<CompilerOptions>
|
||||
<Version Value="11"/>
|
||||
<Target>
|
||||
<Filename Value="canvasdraw"/>
|
||||
</Target>
|
||||
<SearchPaths>
|
||||
<IncludeFiles Value="$(ProjOutDir)"/>
|
||||
<UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/>
|
||||
</SearchPaths>
|
||||
</CompilerOptions>
|
||||
<Debugging>
|
||||
<Exceptions>
|
||||
<Item>
|
||||
<Name Value="EAbort"/>
|
||||
</Item>
|
||||
<Item>
|
||||
<Name Value="ECodetoolError"/>
|
||||
</Item>
|
||||
<Item>
|
||||
<Name Value="EFOpenError"/>
|
||||
</Item>
|
||||
</Exceptions>
|
||||
</Debugging>
|
||||
</CONFIG>
|
138
demo/wasienv/canvas/canvasdraw.lpr
Normal file
138
demo/wasienv/canvas/canvasdraw.lpr
Normal file
@ -0,0 +1,138 @@
|
||||
program canvasdraw;
|
||||
|
||||
{$mode objfpc}
|
||||
{$h+}
|
||||
uses
|
||||
sysutils, webcanvas;
|
||||
|
||||
Type
|
||||
ECanvas = class(Exception);
|
||||
|
||||
{ TWebCanvas }
|
||||
|
||||
TWebCanvas = class(TObject)
|
||||
private
|
||||
FCanvasID : Longint;
|
||||
FHeight: Longint;
|
||||
FWidth: Longint;
|
||||
Protected
|
||||
Procedure Check(aError : TCanvasError; const aMsg : String = '');
|
||||
Public
|
||||
Constructor Create(aWidth,aHeight : Longint);
|
||||
Procedure moveto(X : Longint;Y : Longint);
|
||||
Procedure lineto(X : Longint; Y : Longint);
|
||||
Procedure stroke();
|
||||
Procedure beginpath();
|
||||
Procedure arc(X : Longint;Y : Longint;Radius : Longint;StartAngle : Double;EndAngle : Double);
|
||||
Procedure fillrect(X : Longint; Y : Longint; Width : Longint; Height : Longint);
|
||||
Procedure strokerect(X : Longint;Y : Longint; Width : Longint; Height : Longint);
|
||||
Procedure clearrect(X : Longint;Y : Longint;Width : Longint; Height : Longint );
|
||||
Procedure StrokeText(X : Longint;Y : Longint;S : UTF8String);
|
||||
Procedure FillText(X : Longint;Y : Longint;S : UTF8String);
|
||||
Property CanvasID : Integer Read FCanvasID;
|
||||
Property Width : Longint Read FWidth;
|
||||
Property Height : Longint Read FHeight;
|
||||
end;
|
||||
|
||||
{ TWebCanvas }
|
||||
|
||||
procedure TWebCanvas.Check(aError: TCanvasError; const aMsg: String);
|
||||
begin
|
||||
if aError<>ECANVAS_SUCCESS then
|
||||
if aMsg='' then
|
||||
Raise Exception.CreateFmt('Canvas Operation failed %d',[aError])
|
||||
else
|
||||
Raise Exception.CreateFmt('%s : Error code %d',[aMsg,aError]);
|
||||
|
||||
end;
|
||||
|
||||
constructor TWebCanvas.Create(aWidth, aHeight: Longint);
|
||||
begin
|
||||
Check(__webcanvas_allocate(aWidth,aHeight,@FCanvasID),'Failed to create web canvas');
|
||||
FWidth:=aWidth;
|
||||
FHeight:=aHeight;
|
||||
end;
|
||||
|
||||
procedure TWebCanvas.moveto(X: Longint; Y: Longint);
|
||||
begin
|
||||
Check(__webcanvas_moveto(FCanvasID,X,Y));
|
||||
end;
|
||||
|
||||
procedure TWebCanvas.lineto(X: Longint; Y: Longint);
|
||||
begin
|
||||
Check(__webcanvas_lineto(FCanvasID,X,Y));
|
||||
end;
|
||||
|
||||
procedure TWebCanvas.stroke;
|
||||
begin
|
||||
Check(__webcanvas_stroke(FCanvasID));
|
||||
end;
|
||||
|
||||
procedure TWebCanvas.beginpath;
|
||||
begin
|
||||
Check(__webcanvas_beginpath(FCanvasID));
|
||||
end;
|
||||
|
||||
procedure TWebCanvas.arc(X: Longint; Y: Longint; Radius: Longint;
|
||||
StartAngle: Double; EndAngle: Double);
|
||||
begin
|
||||
Check(__webcanvas_arc(FCanvasID,X,Y,Radius,StartAngle,EndAngle));
|
||||
end;
|
||||
|
||||
procedure TWebCanvas.fillrect(X: Longint; Y: Longint; Width: Longint;
|
||||
Height: Longint);
|
||||
begin
|
||||
Check(__webcanvas_fillrect(FCanvasID,X,Y,Width,Height));
|
||||
end;
|
||||
|
||||
procedure TWebCanvas.strokerect(X: Longint; Y: Longint; Width: Longint;
|
||||
Height: Longint);
|
||||
begin
|
||||
Check(__webcanvas_strokerect(FCanvasID,X,Y,Width,Height));
|
||||
end;
|
||||
|
||||
procedure TWebCanvas.clearrect(X: Longint; Y: Longint; Width: Longint;
|
||||
Height: Longint);
|
||||
begin
|
||||
Check(__webcanvas_clearrect(FCanvasID,X,Y,Width,Height));
|
||||
end;
|
||||
|
||||
procedure TWebCanvas.StrokeText(X: Longint; Y: Longint; S: UTF8String);
|
||||
begin
|
||||
Check(__webcanvas_stroketext(FCanvasID,X,Y,PByte(PAnsichar(S)),Length(S)));
|
||||
end;
|
||||
|
||||
procedure TWebCanvas.FillText(X: Longint; Y: Longint; S: UTF8String);
|
||||
begin
|
||||
Check(__webcanvas_filltext(FCanvasID,X,Y,PByte(PAnsichar(S)),Length(S)));
|
||||
end;
|
||||
|
||||
Var
|
||||
aCanvas : TWebCanvas;
|
||||
|
||||
begin
|
||||
aCanvas:=TWebCanvas.Create(150,150);
|
||||
With aCanvas do
|
||||
try
|
||||
Writeln('Filling rect');
|
||||
fillRect(25, 25, 100, 100);
|
||||
Writeln('Clearing rect');
|
||||
clearRect(45, 45, 60, 60);
|
||||
Writeln('Stroking rect');
|
||||
strokeRect(50, 50, 50, 50);
|
||||
Writeln('Drawing cross');
|
||||
BeginPath;
|
||||
MoveTo(25,25);
|
||||
Writeln('First line');
|
||||
LineTo(125,125);
|
||||
MoveTo(125,25);
|
||||
Writeln('Second line');
|
||||
LineTo(25,125);
|
||||
Stroke;
|
||||
Writeln('Writing text');
|
||||
FillText(8,8,'Greetings on the WebAssembly Canvas!');
|
||||
finally
|
||||
Free;
|
||||
end;
|
||||
end.
|
||||
|
92
demo/wasienv/canvas/demowasicanvas.lpi
Normal file
92
demo/wasienv/canvas/demowasicanvas.lpi
Normal file
@ -0,0 +1,92 @@
|
||||
<?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="demowasicanvas"/>
|
||||
<UseAppBundle Value="False"/>
|
||||
<ResourceType Value="res"/>
|
||||
</General>
|
||||
<CustomData Count="2">
|
||||
<Item0 Name="MaintainHTML" Value="1"/>
|
||||
<Item1 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="demowasicanvas.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="wacanvas.pp"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit>
|
||||
</Units>
|
||||
</ProjectOptions>
|
||||
<CompilerOptions>
|
||||
<Version Value="11"/>
|
||||
<Target FileExt=".js">
|
||||
<Filename Value="demowasicanvas"/>
|
||||
</Target>
|
||||
<SearchPaths>
|
||||
<IncludeFiles Value="$(ProjOutDir)"/>
|
||||
<UnitOutputDirectory Value="js"/>
|
||||
</SearchPaths>
|
||||
<Parsing>
|
||||
<SyntaxOptions>
|
||||
<AllowLabel Value="False"/>
|
||||
<CPPInline Value="False"/>
|
||||
<UseAnsiStrings 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>
|
121
demo/wasienv/canvas/demowasicanvas.lpr
Normal file
121
demo/wasienv/canvas/demowasicanvas.lpr
Normal file
@ -0,0 +1,121 @@
|
||||
program demowasicanvas;
|
||||
|
||||
{$mode objfpc}
|
||||
|
||||
uses
|
||||
browserconsole, browserapp, JS, Classes, SysUtils, Web, WebAssembly, types, wasienv, wacanvas;
|
||||
|
||||
Type
|
||||
|
||||
{ TMyApplication }
|
||||
|
||||
TMyApplication = class(TBrowserApplication)
|
||||
Private
|
||||
FWasiEnv: TPas2JSWASIEnvironment;
|
||||
FMemory : TJSWebAssemblyMemory; // Memory of webassembly
|
||||
FTable : TJSWebAssemblyTable; // Table of exported functions
|
||||
FWACanvas : TWACanvas; // canvas extension
|
||||
function CreateWebAssembly(Path: string; ImportObject: TJSObject
|
||||
): TJSPromise;
|
||||
procedure DoWrite(Sender: TObject; const aOutput: String);
|
||||
function initEnv(aValue: JSValue): JSValue;
|
||||
procedure InitWebAssembly;
|
||||
Public
|
||||
Constructor Create(aOwner : TComponent); override;
|
||||
Destructor Destroy; override;
|
||||
procedure doRun; override;
|
||||
end;
|
||||
|
||||
function TMyApplication.InitEnv(aValue: JSValue): JSValue;
|
||||
|
||||
Var
|
||||
Module : TJSInstantiateResult absolute aValue;
|
||||
exps : TWASIExports;
|
||||
|
||||
begin
|
||||
Result:=True;
|
||||
Exps := TWASIExports(TJSObject(Module.Instance.exports_));
|
||||
FWasiEnv.Instance:=Module.Instance;
|
||||
// console.info('got exports', exps);
|
||||
Exps.Start;
|
||||
end;
|
||||
|
||||
procedure TMyApplication.DoWrite(Sender: TObject; const aOutput: String);
|
||||
begin
|
||||
Writeln(aOutput);
|
||||
end;
|
||||
|
||||
constructor TMyApplication.Create(aOwner: TComponent);
|
||||
begin
|
||||
inherited Create(aOwner);
|
||||
FWasiEnv:=TPas2JSWASIEnvironment.Create;
|
||||
FWasiEnv.OnStdErrorWrite:=@DoWrite;
|
||||
FWasiEnv.OnStdOutputWrite:=@DoWrite;
|
||||
FWACanvas:=TWACanvas.Create(FWasiEnv);
|
||||
FWACanvas.CanvasParent:=GetHTMLElement('canvases');
|
||||
end;
|
||||
|
||||
function TMyApplication.CreateWebAssembly(Path: string; ImportObject: TJSObject): TJSPromise;
|
||||
|
||||
begin
|
||||
Result:=window.fetch(Path)._then(Function (res : jsValue) : JSValue
|
||||
begin
|
||||
Result:=TJSResponse(Res).arrayBuffer._then(Function (res2 : jsValue) : JSValue
|
||||
begin
|
||||
Result:=TJSWebAssembly.instantiate(TJSArrayBuffer(res2),ImportObject);
|
||||
end,Nil)
|
||||
end,Nil
|
||||
);
|
||||
end;
|
||||
|
||||
procedure TMyApplication.InitWebAssembly;
|
||||
|
||||
Var
|
||||
mDesc : TJSWebAssemblyMemoryDescriptor;
|
||||
tDesc: TJSWebAssemblyTableDescriptor;
|
||||
ImportObj : TJSObject;
|
||||
|
||||
begin
|
||||
// Setup memory
|
||||
mDesc.initial:=256;
|
||||
mDesc.maximum:=256;
|
||||
FMemory:=TJSWebAssemblyMemory.New(mDesc);
|
||||
// Setup table
|
||||
tDesc.initial:=0;
|
||||
tDesc.maximum:=0;
|
||||
tDesc.element:='anyfunc';
|
||||
FTable:=TJSWebAssemblyTable.New(tDesc);
|
||||
// Setup ImportObject
|
||||
ImportObj:=new([
|
||||
'js', new([
|
||||
'mem', FMemory,
|
||||
'tbl', FTable
|
||||
])
|
||||
]);
|
||||
FWasiEnv.AddImports(ImportObj);
|
||||
CreateWebAssembly('canvasdraw.wasm',ImportObj)._then(@initEnv)
|
||||
end;
|
||||
|
||||
|
||||
destructor TMyApplication.Destroy;
|
||||
begin
|
||||
FreeAndNil(FWasiEnv);
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
procedure TMyApplication.doRun;
|
||||
|
||||
begin
|
||||
// Your code here
|
||||
Terminate;
|
||||
InitWebAssembly;
|
||||
end;
|
||||
|
||||
var
|
||||
Application : TMyApplication;
|
||||
|
||||
begin
|
||||
Application:=TMyApplication.Create(nil);
|
||||
Application.Initialize;
|
||||
Application.Run;
|
||||
end.
|
51
demo/wasienv/canvas/index.html
Normal file
51
demo/wasienv/canvas/index.html
Normal file
@ -0,0 +1,51 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>FPC-Webassembly and Pas2JS Demo</title>
|
||||
<link href="bulma.min.css" rel="stylesheet">
|
||||
<script src="demowasicanvas.js"></script>
|
||||
<style>
|
||||
|
||||
.source {
|
||||
width: 730px;
|
||||
margin: -45px auto;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
.source-inner {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
width: 482px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="section">
|
||||
<h1 class="title is-3">Canvas</h1>
|
||||
<div id="canvases"></div>
|
||||
</div>
|
||||
<div class="section">
|
||||
<h1 class="title is-3">Console output</h1>
|
||||
<div id="pasjsconsole"></div>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="section">
|
||||
<div class="source">
|
||||
<div class="source-inner">
|
||||
<div>
|
||||
<p>Created using <a target="_blank" href="https://wiki.freepascal.org/pas2js">pas2js.</a> </p>
|
||||
<p>Pas2JS Sources: <a target="new" href="demowasicanvas.lpr">Pas2JS Program</a></p>
|
||||
<p>Webassembly Sources: <a target="new" href="canvasdraw.lpr">FPC Program</a></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
rtl.showUncaughtExceptions=true;
|
||||
rtl.run();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
261
demo/wasienv/canvas/wacanvas.pp
Normal file
261
demo/wasienv/canvas/wacanvas.pp
Normal file
@ -0,0 +1,261 @@
|
||||
{$mode objfpc}
|
||||
{$h+}
|
||||
unit wacanvas;
|
||||
|
||||
interface
|
||||
|
||||
uses js, web, webassembly, wasienv;
|
||||
|
||||
Const
|
||||
ECANVAS_SUCCESS = 0;
|
||||
ECANVAS_NOCANVAS = 1;
|
||||
ECANVAS_UNSPECIFIED = -1;
|
||||
|
||||
Type
|
||||
TCanvasError = Longint;
|
||||
TCanvasID = Longint;
|
||||
|
||||
{ TWACanvas }
|
||||
|
||||
TWACanvas = class(TImportExtension)
|
||||
Private
|
||||
FCanvases : TJSObject;
|
||||
FCurrentID : Integer;
|
||||
FCanvasParent : TJSHTMLELement;
|
||||
Protected
|
||||
function GetCanvas(aID : TCanvasID) : TJSCanvasRenderingContext2D;
|
||||
function allocate(SizeX : Longint; SizeY : Longint; aID: Longint): TCanvasError;
|
||||
function moveto(aID : TCanvasID; X : Longint;Y : Longint): TCanvasError;
|
||||
function lineto(aID : TCanvasID;X : Longint; Y : Longint ): TCanvasError;
|
||||
function stroke(aID : TCanvasID): TCanvasError;
|
||||
function beginpath(aID : TCanvasID): TCanvasError;
|
||||
function arc(aID : TCanvasID;X : Longint;Y : Longint;Radius : Longint;StartAngle : Double;EndAngle : Double): TCanvasError;
|
||||
function fillrect(aID : TCanvasID; X : Longint; Y : Longint; Width : Longint; Height : Longint): TCanvasError;
|
||||
function strokerect(aID : TCanvasID;X : Longint;Y : Longint; Width : Longint; Height : Longint ): TCanvasError;
|
||||
function clearrect(aID : TCanvasID;X : Longint;Y : Longint;Width : Longint; Height : Longint ): TCanvasError;
|
||||
function StrokeText(aID : TCanvasID;X : Longint;Y : Longint; aText : Longint; aTextLen : Longint ): TCanvasError;
|
||||
function FillText(aID : TCanvasID;X : Longint;Y : Longint; aText : Longint; aTextLen : Longint ): TCanvasError;
|
||||
Public
|
||||
Constructor Create(aEnv : TPas2JSWASIEnvironment); override;
|
||||
Procedure FillImportObject(aObject : TJSObject); override;
|
||||
Function ImportName : String; override;
|
||||
Property CanvasParent : TJSHTMLELement Read FCanvasParent Write FCanvasParent;
|
||||
end;
|
||||
|
||||
Implementation
|
||||
|
||||
uses sysutils;
|
||||
|
||||
constructor TWACanvas.Create(aEnv: TPas2JSWASIEnvironment);
|
||||
|
||||
begin
|
||||
Inherited Create(aEnv);
|
||||
FCanvases:=TJSObject.New();
|
||||
end;
|
||||
|
||||
function TWACanvas.ImportName: String;
|
||||
|
||||
begin
|
||||
Result:='web_canvas';
|
||||
end;
|
||||
|
||||
|
||||
function TWACanvas.GetCanvas(aID : TCanvasID) : TJSCanvasRenderingContext2D;
|
||||
|
||||
Var
|
||||
JS : JSValue;
|
||||
begin
|
||||
JS:=FCanvases[IntTostr(AID)];
|
||||
if IsObject(JS) then
|
||||
Result:=TJSCanvasRenderingContext2D(JS)
|
||||
else
|
||||
Result:=Nil;
|
||||
end;
|
||||
|
||||
procedure TWACanvas.FillImportObject(aObject: TJSObject);
|
||||
|
||||
begin
|
||||
aObject['allocate']:=@allocate;
|
||||
aObject['moveto']:=@moveto;
|
||||
aObject['lineto']:=@LineTo;
|
||||
aObject['stroke']:=@stroke;
|
||||
aObject['beginpath']:=@beginpath;
|
||||
aObject['arc']:=@arc;
|
||||
aObject['fillrect']:=@fillrect;
|
||||
aObject['strokerect']:=@strokerect;
|
||||
aObject['clearrect']:=@clearrect;
|
||||
aObject['stroketext']:=@StrokeText;
|
||||
aObject['filltext']:=@FillText;
|
||||
|
||||
end;
|
||||
|
||||
function TWACanvas.allocate(SizeX : Longint; SizeY : Longint; aID: Longint): TCanvasError;
|
||||
|
||||
Var
|
||||
C : TJSElement;
|
||||
V : TJSDataView;
|
||||
|
||||
begin
|
||||
C:=window.document.createElement('CANVAS');
|
||||
CanvasParent.AppendChild(C);
|
||||
Inc(FCurrentID);
|
||||
V:=getModuleMemoryDataView;
|
||||
FCanvases[IntToStr(FCurrentID)]:=TJSHTMLCanvasElement(c).getcontext('2d');
|
||||
v.setUint32(aID, FCurrentID, env.IsLittleEndian);
|
||||
Result:=ECANVAS_SUCCESS;
|
||||
end;
|
||||
|
||||
function TWACanvas.moveto(aID : TCanvasID; X : Longint;Y : Longint): TCanvasError;
|
||||
|
||||
Var
|
||||
C : TJSCanvasRenderingContext2D;
|
||||
|
||||
begin
|
||||
Result:=ECANVAS_NOCANVAS;
|
||||
C:=GetCanvas(aID);
|
||||
if Assigned(C) then
|
||||
begin
|
||||
C.moveto(X,Y);
|
||||
Result:=ECANVAS_SUCCESS;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TWACanvas.lineto(aID : TCanvasID;X : Longint; Y : Longint ): TCanvasError;
|
||||
|
||||
Var
|
||||
C : TJSCanvasRenderingContext2D;
|
||||
|
||||
begin
|
||||
Result:=ECANVAS_NOCANVAS;
|
||||
C:=GetCanvas(aID);
|
||||
if Assigned(C) then
|
||||
begin
|
||||
C.lineto(X,Y);
|
||||
Result:=ECANVAS_SUCCESS;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TWACanvas.stroke(aID : TCanvasID): TCanvasError;
|
||||
|
||||
Var
|
||||
C : TJSCanvasRenderingContext2D;
|
||||
|
||||
begin
|
||||
Result:=ECANVAS_NOCANVAS;
|
||||
C:=GetCanvas(aID);
|
||||
if Assigned(C) then
|
||||
begin
|
||||
C.Stroke;
|
||||
Result:=ECANVAS_SUCCESS;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TWACanvas.beginpath(aID : TCanvasID): TCanvasError;
|
||||
|
||||
Var
|
||||
C : TJSCanvasRenderingContext2D;
|
||||
|
||||
begin
|
||||
Result:=ECANVAS_NOCANVAS;
|
||||
C:=GetCanvas(aID);
|
||||
if Assigned(C) then
|
||||
begin
|
||||
C.beginPath;
|
||||
Result:=ECANVAS_SUCCESS;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TWACanvas.arc(aID : TCanvasID;X : Longint;Y : Longint;Radius : Longint;StartAngle : Double;EndAngle : Double): TCanvasError;
|
||||
|
||||
Var
|
||||
C : TJSCanvasRenderingContext2D;
|
||||
|
||||
begin
|
||||
Result:=ECANVAS_NOCANVAS;
|
||||
C:=GetCanvas(aID);
|
||||
if Assigned(C) then
|
||||
begin
|
||||
C.arc(X,y,radius,Startangle,EndAngle);
|
||||
Result:=ECANVAS_SUCCESS;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TWACanvas.fillrect(aID : TCanvasID; X : Longint; Y : Longint; Width : Longint; Height : Longint): TCanvasError;
|
||||
|
||||
Var
|
||||
C : TJSCanvasRenderingContext2D;
|
||||
|
||||
begin
|
||||
Result:=ECANVAS_NOCANVAS;
|
||||
C:=GetCanvas(aID);
|
||||
if Assigned(C) then
|
||||
begin
|
||||
C.FillRect(X,y,width,Height);
|
||||
Result:=ECANVAS_SUCCESS;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TWACanvas.strokerect(aID : TCanvasID;X : Longint;Y : Longint; Width : Longint; Height : Longint ): TCanvasError;
|
||||
|
||||
Var
|
||||
C : TJSCanvasRenderingContext2D;
|
||||
|
||||
begin
|
||||
Result:=ECANVAS_NOCANVAS;
|
||||
C:=GetCanvas(aID);
|
||||
if Assigned(C) then
|
||||
begin
|
||||
C.StrokeRect(X,Y,Width,Height);
|
||||
Result:=ECANVAS_SUCCESS;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TWACanvas.clearrect(aID : TCanvasID;X : Longint;Y : Longint;Width : Longint; Height : Longint ): TCanvasError;
|
||||
|
||||
Var
|
||||
C : TJSCanvasRenderingContext2D;
|
||||
|
||||
begin
|
||||
Result:=ECANVAS_NOCANVAS;
|
||||
C:=GetCanvas(aID);
|
||||
if Assigned(C) then
|
||||
begin
|
||||
C.ClearRect(X,Y,Width,Height);
|
||||
Result:=ECANVAS_SUCCESS;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TWACanvas.StrokeText(aID: TCanvasID; X: Longint; Y: Longint;
|
||||
aText: Longint; aTextLen: Longint): TCanvasError;
|
||||
|
||||
Var
|
||||
C : TJSCanvasRenderingContext2D;
|
||||
S : String;
|
||||
begin
|
||||
Result:=ECANVAS_NOCANVAS;
|
||||
C:=GetCanvas(aID);
|
||||
if Assigned(C) then
|
||||
begin
|
||||
S:=Env.GetUTF8StringFromMem(aText,aTextLen);
|
||||
C.StrokeText(S,X,Y);
|
||||
Result:=ECANVAS_SUCCESS;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TWACanvas.FillText(aID: TCanvasID; X: Longint; Y: Longint;
|
||||
aText: Longint; aTextLen: Longint): TCanvasError;
|
||||
Var
|
||||
C : TJSCanvasRenderingContext2D;
|
||||
S : String;
|
||||
begin
|
||||
Result:=ECANVAS_NOCANVAS;
|
||||
C:=GetCanvas(aID);
|
||||
if Assigned(C) then
|
||||
begin
|
||||
S:=Env.GetUTF8StringFromMem(aText,aTextLen);
|
||||
C.FillText(S,X,Y);
|
||||
Result:=ECANVAS_SUCCESS;
|
||||
end;
|
||||
end;
|
||||
|
||||
end.
|
97
demo/wasienv/canvas/webcanvas.pp
Normal file
97
demo/wasienv/canvas/webcanvas.pp
Normal file
@ -0,0 +1,97 @@
|
||||
unit webcanvas;
|
||||
|
||||
interface
|
||||
|
||||
// These types and constants could go in a unit shared between pas2js and webassembly !
|
||||
|
||||
Type
|
||||
TCanvasError = longint;
|
||||
TCanvasID = longint;
|
||||
PCanvasID = ^TCanvasID;
|
||||
|
||||
Const
|
||||
ECANVAS_SUCCESS = 0;
|
||||
ECANVAS_NOCANVAS = 1;
|
||||
ECANVAS_UNSPECIFIED = -1;
|
||||
|
||||
function __webcanvas_allocate(
|
||||
SizeX : Longint;
|
||||
SIzeY : Longint;
|
||||
aID: PCanvasID
|
||||
): TCanvasError; external 'web_canvas' name 'allocate';
|
||||
|
||||
function __webcanvas_moveto(
|
||||
aID : TCanvasID;
|
||||
X : Longint;
|
||||
Y : Longint
|
||||
): TCanvasError; external 'web_canvas' name 'moveto';
|
||||
|
||||
function __webcanvas_lineto(
|
||||
aID : TCanvasID;
|
||||
X : Longint;
|
||||
Y : Longint
|
||||
): TCanvasError; external 'web_canvas' name 'lineto';
|
||||
|
||||
function __webcanvas_stroke(
|
||||
aID : TCanvasID
|
||||
): TCanvasError; external 'web_canvas' name 'stroke';
|
||||
|
||||
function __webcanvas_beginpath(
|
||||
aID : TCanvasID
|
||||
): TCanvasError; external 'web_canvas' name 'beginpath';
|
||||
|
||||
function __webcanvas_arc(
|
||||
aID : TCanvasID;
|
||||
X : Longint;
|
||||
Y : Longint;
|
||||
Radius : Longint;
|
||||
StartAngle : Double;
|
||||
EndAngle : Double
|
||||
): TCanvasError; external 'web_canvas' name 'arc';
|
||||
|
||||
|
||||
function __webcanvas_fillrect(
|
||||
aID : TCanvasID;
|
||||
X : Longint;
|
||||
Y : Longint;
|
||||
Width : Longint;
|
||||
Height : Longint
|
||||
): TCanvasError; external 'web_canvas' name 'fillrect';
|
||||
|
||||
function __webcanvas_strokerect(
|
||||
aID : TCanvasID;
|
||||
X : Longint;
|
||||
Y : Longint;
|
||||
Width : Longint;
|
||||
Height : Longint
|
||||
): TCanvasError; external 'web_canvas' name 'strokerect';
|
||||
|
||||
|
||||
function __webcanvas_clearrect(
|
||||
aID : TCanvasID;
|
||||
X : Longint;
|
||||
Y : Longint;
|
||||
Width : Longint;
|
||||
Height : Longint
|
||||
): TCanvasError; external 'web_canvas' name 'clearrect';
|
||||
|
||||
function __webcanvas_stroketext(
|
||||
aID : TCanvasID;
|
||||
X : Longint;
|
||||
Y : Longint;
|
||||
aText : PByte;
|
||||
aTextLen : Longint
|
||||
): TCanvasError; external 'web_canvas' name 'stroketext';
|
||||
|
||||
function __webcanvas_filltext(
|
||||
aID : TCanvasID;
|
||||
X : Longint;
|
||||
Y : Longint;
|
||||
aText : PByte;
|
||||
aTextLen : Longint
|
||||
): TCanvasError; external 'web_canvas' name 'filltext';
|
||||
|
||||
|
||||
implementation
|
||||
|
||||
end.
|
1
demo/wasienv/simple/bulma.min.css
vendored
Normal file
1
demo/wasienv/simple/bulma.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
88
demo/wasienv/simple/demowasienv.lpi
Normal file
88
demo/wasienv/simple/demowasienv.lpi
Normal file
@ -0,0 +1,88 @@
|
||||
<?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="demowasienv"/>
|
||||
<UseAppBundle Value="False"/>
|
||||
<ResourceType Value="res"/>
|
||||
</General>
|
||||
<CustomData Count="2">
|
||||
<Item0 Name="MaintainHTML" Value="1"/>
|
||||
<Item1 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="demowasienv.lpr"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit>
|
||||
<Unit>
|
||||
<Filename Value="index.html"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<CustomData Count="1">
|
||||
<Item0 Name="PasJSIsProjectHTMLFile" Value="1"/>
|
||||
</CustomData>
|
||||
</Unit>
|
||||
</Units>
|
||||
</ProjectOptions>
|
||||
<CompilerOptions>
|
||||
<Version Value="11"/>
|
||||
<Target FileExt=".js">
|
||||
<Filename Value="demowasienv"/>
|
||||
</Target>
|
||||
<SearchPaths>
|
||||
<IncludeFiles Value="$(ProjOutDir)"/>
|
||||
<UnitOutputDirectory Value="js"/>
|
||||
</SearchPaths>
|
||||
<Parsing>
|
||||
<SyntaxOptions>
|
||||
<AllowLabel Value="False"/>
|
||||
<CPPInline Value="False"/>
|
||||
<UseAnsiStrings 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>
|
118
demo/wasienv/simple/demowasienv.lpr
Normal file
118
demo/wasienv/simple/demowasienv.lpr
Normal file
@ -0,0 +1,118 @@
|
||||
program demowasienv;
|
||||
|
||||
{$mode objfpc}
|
||||
|
||||
uses
|
||||
browserconsole, browserapp, JS, Classes, SysUtils, Web, WebAssembly, types, wasienv;
|
||||
|
||||
Type
|
||||
|
||||
{ TMyApplication }
|
||||
|
||||
TMyApplication = class(TBrowserApplication)
|
||||
Private
|
||||
FWasiEnv: TPas2JSWASIEnvironment;
|
||||
FMemory : TJSWebAssemblyMemory; // Memory of webassembly
|
||||
FTable : TJSWebAssemblyTable; // exported functions.
|
||||
function CreateWebAssembly(Path: string; ImportObject: TJSObject
|
||||
): TJSPromise;
|
||||
procedure DoWrite(Sender: TObject; const aOutput: String);
|
||||
function initEnv(aValue: JSValue): JSValue;
|
||||
procedure InitWebAssembly;
|
||||
Public
|
||||
Constructor Create(aOwner : TComponent); override;
|
||||
Destructor Destroy; override;
|
||||
procedure doRun; override;
|
||||
end;
|
||||
|
||||
function TMyApplication.InitEnv(aValue: JSValue): JSValue;
|
||||
|
||||
Var
|
||||
Module : TJSInstantiateResult absolute aValue;
|
||||
exps : TWASIExports;
|
||||
|
||||
begin
|
||||
Result:=True;
|
||||
Exps := TWASIExports(TJSObject(Module.Instance.exports_));
|
||||
FWasiEnv.Instance:=Module.Instance;
|
||||
console.info('got exports', exps);
|
||||
Exps.Start;
|
||||
end;
|
||||
|
||||
procedure TMyApplication.DoWrite(Sender: TObject; const aOutput: String);
|
||||
begin
|
||||
Writeln(aOutput);
|
||||
end;
|
||||
|
||||
constructor TMyApplication.Create(aOwner: TComponent);
|
||||
begin
|
||||
inherited Create(aOwner);
|
||||
FWasiEnv:=TPas2JSWASIEnvironment.Create;
|
||||
FWasiEnv.OnStdErrorWrite:=@DoWrite;
|
||||
FWasiEnv.OnStdOutputWrite:=@DoWrite;
|
||||
end;
|
||||
|
||||
function TMyApplication.CreateWebAssembly(Path: string; ImportObject: TJSObject): TJSPromise;
|
||||
|
||||
begin
|
||||
Result:=window.fetch(Path)._then(Function (res : jsValue) : JSValue
|
||||
begin
|
||||
Result:=TJSResponse(Res).arrayBuffer._then(Function (res2 : jsValue) : JSValue
|
||||
begin
|
||||
Result:=TJSWebAssembly.instantiate(TJSArrayBuffer(res2),ImportObject);
|
||||
end,Nil)
|
||||
end,Nil
|
||||
);
|
||||
end;
|
||||
|
||||
procedure TMyApplication.InitWebAssembly;
|
||||
|
||||
Var
|
||||
mDesc : TJSWebAssemblyMemoryDescriptor;
|
||||
tDesc: TJSWebAssemblyTableDescriptor;
|
||||
ImportObj : TJSObject;
|
||||
|
||||
begin
|
||||
// Setup memory
|
||||
mDesc.initial:=256;
|
||||
mDesc.maximum:=256;
|
||||
FMemory:=TJSWebAssemblyMemory.New(mDesc);
|
||||
// Setup table
|
||||
tDesc.initial:=0;
|
||||
tDesc.maximum:=0;
|
||||
tDesc.element:='anyfunc';
|
||||
FTable:=TJSWebAssemblyTable.New(tDesc);
|
||||
// Setup ImportObject
|
||||
ImportObj:=new([
|
||||
'js', new([
|
||||
'mem', FMemory,
|
||||
'tbl', FTable
|
||||
])
|
||||
]);
|
||||
FWasiEnv.AddImports(ImportObj);
|
||||
CreateWebAssembly('helloworld.wasm',ImportObj)._then(@initEnv)
|
||||
end;
|
||||
|
||||
|
||||
destructor TMyApplication.Destroy;
|
||||
begin
|
||||
FreeAndNil(FWasiEnv);
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
procedure TMyApplication.doRun;
|
||||
|
||||
begin
|
||||
// Your code here
|
||||
Terminate;
|
||||
InitWebAssembly;
|
||||
end;
|
||||
|
||||
var
|
||||
Application : TMyApplication;
|
||||
|
||||
begin
|
||||
Application:=TMyApplication.Create(nil);
|
||||
Application.Initialize;
|
||||
Application.Run;
|
||||
end.
|
6
demo/wasienv/simple/helloworld.pp
Normal file
6
demo/wasienv/simple/helloworld.pp
Normal file
@ -0,0 +1,6 @@
|
||||
program HelloWorld;
|
||||
|
||||
begin
|
||||
Writeln('Hello world from FPC webassembly and Pas2JS!');
|
||||
Writeln('... and a merry Christmas for all!');
|
||||
end.
|
47
demo/wasienv/simple/index.html
Normal file
47
demo/wasienv/simple/index.html
Normal file
@ -0,0 +1,47 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>FPC-Webassembly and Pas2JS Demo</title>
|
||||
<link href="bulma.min.css" rel="stylesheet">
|
||||
<script src="demowasienv.js"></script>
|
||||
<style>
|
||||
|
||||
.source {
|
||||
width: 730px;
|
||||
margin: -45px auto;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
.source-inner {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
width: 482px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="section">
|
||||
<h1 class="title is-4">FPC compiled wasm program console output:</h1>
|
||||
<div id="pasjsconsole"></div>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="section">
|
||||
<div class="source">
|
||||
<div class="source-inner">
|
||||
<div>
|
||||
<p>Created using <a target="_blank" href="https://wiki.freepascal.org/pas2js">pas2js.</a> </p>
|
||||
<p>Pas2JS Sources: <a target="new" href="demowasienv.lpr">Pas2JS Program</a></p>
|
||||
<p>Webassembly Sources: <a target="new" href="helloworld.pp">FPC Program</a></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
rtl.showUncaughtExceptions=true;
|
||||
rtl.run();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
1
demo/wasienv/terminal/bulma.min.css
vendored
Normal file
1
demo/wasienv/terminal/bulma.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
88
demo/wasienv/terminal/demowasiterm.lpi
Normal file
88
demo/wasienv/terminal/demowasiterm.lpi
Normal file
@ -0,0 +1,88 @@
|
||||
<?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="demowasiterm"/>
|
||||
<UseAppBundle Value="False"/>
|
||||
<ResourceType Value="res"/>
|
||||
</General>
|
||||
<CustomData Count="2">
|
||||
<Item0 Name="MaintainHTML" Value="1"/>
|
||||
<Item1 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="demowasiterm.lpr"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit>
|
||||
<Unit>
|
||||
<Filename Value="index.html"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<CustomData Count="1">
|
||||
<Item0 Name="PasJSIsProjectHTMLFile" Value="1"/>
|
||||
</CustomData>
|
||||
</Unit>
|
||||
</Units>
|
||||
</ProjectOptions>
|
||||
<CompilerOptions>
|
||||
<Version Value="11"/>
|
||||
<Target FileExt=".js">
|
||||
<Filename Value="demowasiterm"/>
|
||||
</Target>
|
||||
<SearchPaths>
|
||||
<IncludeFiles Value="$(ProjOutDir)"/>
|
||||
<UnitOutputDirectory Value="js"/>
|
||||
</SearchPaths>
|
||||
<Parsing>
|
||||
<SyntaxOptions>
|
||||
<AllowLabel Value="False"/>
|
||||
<CPPInline Value="False"/>
|
||||
<UseAnsiStrings 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>
|
208
demo/wasienv/terminal/demowasiterm.lpr
Normal file
208
demo/wasienv/terminal/demowasiterm.lpr
Normal file
@ -0,0 +1,208 @@
|
||||
program demowasiterm;
|
||||
|
||||
{$mode objfpc}
|
||||
|
||||
uses
|
||||
browserapp, JS, Classes, SysUtils, Web, WebAssembly, types,
|
||||
xterm, wasienv, strutils;
|
||||
|
||||
Type
|
||||
|
||||
{ TMyApplication }
|
||||
|
||||
TMyApplication = class(TBrowserApplication)
|
||||
Private
|
||||
FTerminal : TXTerm.TTerminal;
|
||||
FTermEl : TJSHTMLElement;
|
||||
FWasiEnv : TPas2JSWASIEnvironment;
|
||||
FMemory : TJSWebAssemblyMemory; // Memory of webassembly
|
||||
FTable:TJSWebAssemblyTable; // Exported functions, directly callable
|
||||
FInputLine : String;
|
||||
Fidx : Integer;
|
||||
FinputLines : TStrings;
|
||||
function CreateWebAssembly(Path: string; ImportObject: TJSObject
|
||||
): TJSPromise;
|
||||
procedure DoGetInputString(Sender: TObject; var AInput: string);
|
||||
function DoKey(keyData: TXTerm.TOnKeyCallbackDataType): Boolean;
|
||||
procedure DoWrite(Sender: TObject; const aOutput: String);
|
||||
function initEnv(aValue: JSValue): JSValue;
|
||||
procedure InitWebAssembly;
|
||||
Public
|
||||
Constructor Create(aOwner : TComponent); override;
|
||||
Destructor Destroy; override;
|
||||
procedure doRun; override;
|
||||
end;
|
||||
|
||||
function TMyApplication.InitEnv(aValue: JSValue): JSValue;
|
||||
|
||||
Var
|
||||
Module : TJSInstantiateResult absolute aValue;
|
||||
exps : TWASIExports;
|
||||
|
||||
begin
|
||||
Result:=True;
|
||||
Exps := TWASIExports(TJSObject(Module.Instance.exports_));
|
||||
FWasiEnv.Instance:=Module.Instance;
|
||||
Exps.Start;
|
||||
end;
|
||||
|
||||
function TMyApplication.DoKey(keyData : TXTerm.TOnKeyCallbackDataType): Boolean;
|
||||
{
|
||||
Experimental code to convert keystrokes to input.
|
||||
Unfortunately, it does not work because the webassembly is executed in the same thread as the javascript.
|
||||
Maybe using a web-worker this can be realized.
|
||||
}
|
||||
Var
|
||||
printable : Boolean;
|
||||
|
||||
begin
|
||||
Result:=true;
|
||||
With keyData do
|
||||
printable :=Not (domEvent.altKey or domEvent.metaKey or domEvent.ctrlKey or domEvent.metaKey);
|
||||
if keyData.domEvent.Key=TJSKeyNames.BackSpace then
|
||||
begin
|
||||
if (Length(FInputLine)>0) then
|
||||
begin
|
||||
FInputLine:=Copy(FInputLine,1,Length(FInputLine)-1);
|
||||
FTerminal.write(#8' '#8);
|
||||
end;
|
||||
end
|
||||
else if (keyData.domEvent.Key=TJSKeyNames.Enter) then
|
||||
begin
|
||||
FInputLine:=FInputLine+#10;
|
||||
FTerminal.writeln('');
|
||||
end
|
||||
else if Printable then
|
||||
begin
|
||||
FInputLine:=FInputLine+keyData.Key;
|
||||
FTerminal.write(keyData.Key);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure TMyApplication.DoWrite(Sender: TObject; const aOutput: String);
|
||||
|
||||
Var
|
||||
S : TStringDynArray;
|
||||
L : String;
|
||||
I,aLen : Integer;
|
||||
|
||||
begin
|
||||
S:=SplitString(aOutput,#10);
|
||||
aLen:=length(S)-1;
|
||||
For I:=0 to aLen do
|
||||
begin
|
||||
L:=S[i];
|
||||
FTerminal.Write(L);
|
||||
if I<aLen then
|
||||
FTerminal.Writeln('')
|
||||
end;
|
||||
end;
|
||||
|
||||
constructor TMyApplication.Create(aOwner: TComponent);
|
||||
Var
|
||||
i : Integer;
|
||||
begin
|
||||
inherited Create(aOwner);
|
||||
FWasiEnv:=TPas2JSWASIEnvironment.Create;
|
||||
FWasiEnv.OnStdErrorWrite:=@DoWrite;
|
||||
FWasiEnv.OnStdOutputWrite:=@DoWrite;
|
||||
FWasiEnv.OnGetConsoleInputString:=@DoGetInputString;
|
||||
FTermEl:=GetHTMLElement('xterm');
|
||||
FTerminal:=TXTerm.TTerminal.New;
|
||||
FTerminal.OnKey(@DoKey);
|
||||
FTerminal.open(FTermEl);
|
||||
FinputLine:='';
|
||||
FinputLines:=TStringList.Create;
|
||||
Fidx:=0;
|
||||
For I:=0 to 9 do
|
||||
FinputLines.Add(IntToStr(Random(200)));
|
||||
FinputLines.Add('-1');
|
||||
end;
|
||||
|
||||
function TMyApplication.CreateWebAssembly(Path: string; ImportObject: TJSObject): TJSPromise;
|
||||
|
||||
begin
|
||||
Result:=window.fetch(Path)._then(Function (res : jsValue) : JSValue
|
||||
begin
|
||||
Result:=TJSResponse(Res).arrayBuffer._then(Function (res2 : jsValue) : JSValue
|
||||
begin
|
||||
Result:=TJSWebAssembly.instantiate(TJSArrayBuffer(res2),ImportObject);
|
||||
end,Nil)
|
||||
end,Nil
|
||||
);
|
||||
end;
|
||||
|
||||
procedure TMyApplication.DoGetInputString(Sender: TObject; var AInput: string);
|
||||
|
||||
Var
|
||||
S : String;
|
||||
|
||||
begin
|
||||
{
|
||||
// Experimental code for use with keyhandler.
|
||||
aInput:=FInputLine;
|
||||
FInputLine:='';
|
||||
}
|
||||
aInput:='';
|
||||
If FIdx<FInputLines.Count then
|
||||
begin
|
||||
S:=FInputLines[FIdx];
|
||||
aInput:=S+#10;
|
||||
FTerminal.writeln(#27'[31m'+S+#27'[37m');
|
||||
inc(FIdx);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TMyApplication.InitWebAssembly;
|
||||
|
||||
Var
|
||||
mDesc : TJSWebAssemblyMemoryDescriptor;
|
||||
tDesc: TJSWebAssemblyTableDescriptor;
|
||||
ImportObj : TJSObject;
|
||||
|
||||
|
||||
begin
|
||||
// Setup memory
|
||||
mDesc.initial:=256;
|
||||
mDesc.maximum:=256;
|
||||
FMemory:=TJSWebAssemblyMemory.New(mDesc);
|
||||
// Setup table
|
||||
tDesc.initial:=0;
|
||||
tDesc.maximum:=0;
|
||||
tDesc.element:='anyfunc';
|
||||
FTable:=TJSWebAssemblyTable.New(tDesc);
|
||||
// Setup ImportObject
|
||||
ImportObj:=new([
|
||||
'js', new([
|
||||
'mem', FMemory,
|
||||
'tbl', FTable
|
||||
])
|
||||
]);
|
||||
FWasiEnv.AddImports(ImportObj);
|
||||
CreateWebAssembly('sums.wasm',ImportObj)._then(@initEnv)
|
||||
end;
|
||||
|
||||
|
||||
destructor TMyApplication.Destroy;
|
||||
begin
|
||||
FreeAndNil(FWasiEnv);
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
procedure TMyApplication.doRun;
|
||||
|
||||
begin
|
||||
// Your code here
|
||||
Terminate;
|
||||
InitWebAssembly;
|
||||
end;
|
||||
|
||||
var
|
||||
Application : TMyApplication;
|
||||
|
||||
begin
|
||||
Application:=TMyApplication.Create(nil);
|
||||
Application.Initialize;
|
||||
Application.Run;
|
||||
end.
|
50
demo/wasienv/terminal/index.html
Normal file
50
demo/wasienv/terminal/index.html
Normal file
@ -0,0 +1,50 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>FPC-Webassembly with Pas2JS Terminal Demo</title>
|
||||
<link href="https://unpkg.com/xterm@4.16.0/css/xterm.css" rel="stylesheet">
|
||||
<script src="https://unpkg.com/xterm@4.16.0/lib/xterm.js"></script>
|
||||
<link href="bulma.min.css" rel="stylesheet">
|
||||
<script src="demowasiterm.js"></script>
|
||||
<style>
|
||||
|
||||
.source {
|
||||
width: 730px;
|
||||
margin: -45px auto;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
.source-inner {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
width: 482px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="section">
|
||||
<h1 class="title is-3">FPC-Webassembly with Pas2JS Terminal Demo</h1>
|
||||
<div class="block">Red color indicates (simulated) terminal input to WebAssembly program</div>
|
||||
<div id="xterm" style="width: 100%; height: 60vh; background-color: black;"></div>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="section">
|
||||
<div class="source">
|
||||
<div class="source-inner">
|
||||
<div>
|
||||
<p>Created using <a target="_blank" href="https://wiki.freepascal.org/pas2js">pas2js.</a> </p>
|
||||
<p>Pas2JS Sources: <a target="new" href="demowasiterm.lpr">Pas2JS Program</a></p>
|
||||
<p>Webassembly Sources: <a target="new" href="sums.pp">FPC Program</a></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
rtl.showUncaughtExceptions=true;
|
||||
window.addEventListener("load", rtl.run);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
19
demo/wasienv/terminal/sums.pp
Normal file
19
demo/wasienv/terminal/sums.pp
Normal file
@ -0,0 +1,19 @@
|
||||
program HelloWorld;
|
||||
|
||||
Var
|
||||
A,B,C : Integer;
|
||||
|
||||
begin
|
||||
Writeln('Answer -1 to end the program');
|
||||
Repeat
|
||||
A:=Random(100);
|
||||
B:=Random(100);
|
||||
Write(A,' + ',B,' = ');
|
||||
Readln(C);
|
||||
if (C=(A+B)) then
|
||||
Writeln('Well done !')
|
||||
else if (C<>-1) then
|
||||
Writeln('Sorry, wrong. The correct answer is ',A+B);
|
||||
Until (C=-1);
|
||||
end.
|
||||
|
27
demo/wasienv/wasienvdemos.lpg
Normal file
27
demo/wasienv/wasienvdemos.lpg
Normal file
@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CONFIG>
|
||||
<ProjectGroup FileVersion="2">
|
||||
<Targets>
|
||||
<Target FileName="canvas/canvasdraw.lpi">
|
||||
<BuildModes>
|
||||
<Mode Name="Default"/>
|
||||
</BuildModes>
|
||||
</Target>
|
||||
<Target FileName="canvas/demowasicanvas.lpi">
|
||||
<BuildModes>
|
||||
<Mode Name="Default"/>
|
||||
</BuildModes>
|
||||
</Target>
|
||||
<Target FileName="simple/demowasienv.lpi">
|
||||
<BuildModes>
|
||||
<Mode Name="Default"/>
|
||||
</BuildModes>
|
||||
</Target>
|
||||
<Target FileName="terminal/demowasiterm.lpi">
|
||||
<BuildModes>
|
||||
<Mode Name="Default"/>
|
||||
</BuildModes>
|
||||
</Target>
|
||||
</Targets>
|
||||
</ProjectGroup>
|
||||
</CONFIG>
|
@ -1,14 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CONFIG>
|
||||
<ProjectGroup FileVersion="1">
|
||||
<Targets Count="4">
|
||||
<Target0 FileName="Pas2JS_WebGL.lpi"/>
|
||||
<Target1 FileName="Pas2JS_WebGL_Minimal.lpi"/>
|
||||
<Target2 FileName="Pas2JS_WebGL_OBJ.lpi">
|
||||
<BuildModes Count="1"/>
|
||||
<Mode1 Name="Default"/>
|
||||
</Target2>
|
||||
<Target3 FileName="Pas2JS_WebGL_Terrain.lpi"/>
|
||||
<ProjectGroup FileVersion="2">
|
||||
<Targets>
|
||||
<Target FileName="Pas2JS_WebGL.lpi"/>
|
||||
<Target FileName="Pas2JS_WebGL_Minimal.lpi"/>
|
||||
<Target FileName="Pas2JS_WebGL_OBJ.lpi">
|
||||
<BuildModes>
|
||||
<Mode Name="Default"/>
|
||||
</BuildModes>
|
||||
</Target>
|
||||
<Target FileName="Pas2JS_WebGL_Terrain.lpi"/>
|
||||
</Targets>
|
||||
</ProjectGroup>
|
||||
</CONFIG>
|
||||
|
1150
packages/wasi/wasienv.pas
Normal file
1150
packages/wasi/wasienv.pas
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user