unit TestMustacheUnit; interface {$I Synopse.inc} // define HASINLINE CPU32 CPU64 OWNNORMTOUPPER uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, SynCrtSock, {$ifndef CPU64} // SpiderMonkey library is not available yet in 64 bit SynSM, SynSMAPI, {$endif} SynCommons, SynMustache; type TMainForm = class(TForm) mmoTemplate: TMemo; lblTemplate: TLabel; mmoContext: TMemo; lblContext: TLabel; btnExecSynMustache: TButton; btnExecSpiderMonkey: TButton; mmoResult: TMemo; btnOpenBrowser: TButton; lblIteration: TLabel; edtIteration: TEdit; procedure Render(Sender: TObject); procedure btnOpenBrowserClick(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure FormShow(Sender: TObject); private { Private declarations } public { Public declarations } {$ifndef CPU64} // SpiderMonkey library is not available yet in 64 bit fEngineManager: TSMEngineManager; fEngine: TSMEngine; {$endif} end; var MainForm: TMainForm; implementation uses ShellAPI; {$R *.dfm} {$ifndef FPC} {$R vista.RES} // includes Win10 manifest - use .RES for linux cross-compilation {$endif} procedure TMainForm.Render(Sender: TObject); var Template, Context, Result: RawUTF8; data: variant; i,n: Integer; Timer: TPrecisionTimer; SynMustacheTemplate: TSynMustache; {$ifndef CPU64} // SpiderMonkey library is not available yet in 64 bit person: RawUTF8; partial: variant; nn: Variant; {$endif} begin Template := StringToUTF8(mmoTemplate.Lines.Text); Context := StringToUTF8(mmoContext.Lines.Text); data := _JsonFast(Context); n := StrToIntDef(edtIteration.Text,1000); if Sender=btnExecSynMustache then begin SynMustacheTemplate := TSynMustache.Parse(Template); Timer.Start; for i := 1 to n do result := SynMustacheTemplate.Render(data); end else {$ifndef CPU64} // SpiderMonkey library is not available yet in 64 bit if Sender=btnExecSpiderMonkey then begin fEngine.MaybeGarbageCollect; i := PosEx('{{0 then begin // extract any inlined partial (should be at the end) person := Copy(Template,i+12,maxInt); SetLength(Template,i-1); i := PosEx('{{/person}}',person); if i>0 then SetLength(person,i-1); partial := _ObjFast(['person',person]); end; fEngine.Global.testMustache(Template, data, partial, 1); //compile template Timer.Start; nn := n; result := VariantToUTF8(fEngine.Global.testMustache(Template, data, partial, nn)); // test below slow because of 2 things: // 1) marsalling argumnets between Delphi & JS // 2) we measure "prepare" time // for i := 1 to n do // result := VariantToUTF8(fEngine.Global.Mustache.render(Template, data, partial)); end else {$endif} exit; mmoResult.Lines.Text := Format('Rendered %d times in %s (%d/sec):'#13#10#13#10'%s', [n,Timer.Stop,Timer.PerSec(n),result]); FileFromString(Result,ChangeFileExt(ExeVersion.ProgramFileName,'.html')); end; procedure TMainForm.btnOpenBrowserClick(Sender: TObject); begin ShellExecute(0,'open',Pointer(ChangeFileExt(ExeVersion.ProgramFileName,'.html')),nil,nil,SW_SHOWNORMAL); end; procedure TMainForm.FormShow(Sender: TObject); {$ifdef CPU64} // SpiderMonkey library is not available yet in 64 bit begin btnExecSpiderMonkey.Hide; end; {$else} const testMustacheFunc = 'function testMustache(template, data, partial, iterCount){ ' + ' var result = ""; ' + ' for(var i=0; i0 then insert('return ',mustache,i); // fix syntax error in official libary! :) end; FileFromString(mustache,mustacheFN); mSource := SynUnicode(mustache); end; fEngine.Evaluate(mSource,'mustache.js'); fEngine.Evaluate(testMustacheFunc,'testMustacheFunc.js'); end; {$endif} procedure TMainForm.FormDestroy(Sender: TObject); begin {$ifndef CPU64} // SpiderMonkey library is not available yet in 64 bit fEngineManager.Free; {$endif} end; end.