+ New built-in Profiler (check Profiling sample), new Context.ActionQualifiedName property

This commit is contained in:
Daniele Teti 2022-10-20 17:29:04 +02:00
parent 761bcb2e5d
commit 1a9f1deba3
33 changed files with 4941 additions and 1163 deletions

View File

@ -1415,16 +1415,75 @@ The current beta release is named 3.2.3-radium-beta. If you want to stay on the-
### What's New in 3.2.3-radium-beta
- Fixed a rendering problem in swagger interface format in case of specific JSON structure
- Default error responses contains the official "reason string" associated to the HTTP status code (this can be a breaking change for some generic client which doesn't correctly interpret the http status code)
- Added static method `HTTP_STATUS.ReasonStringFor(HTTPStatusCode)` wich returns the standard `ReasonString` for a given HTTP status code.
- Improved handling of `TMVCErrorResponse` information
- mid-air-collision handling now uses SHA1 instead of MD5
- Added `MVCFramework.Commons.MVC_HTTP_STATUS_CODES` const array containing all the HTTP status codes wich its `ReasonString`
- Added `MVCFramework.Commons.MVC_HTTP_STATUS_CODES` const array containing all the HTTP status codes with its `ReasonString`
- New built-in profiler (usable with Delphi 10.4+) - to profile a block of code, write the following
```delphi
procedure TMyController.ProfilerSample1;
begin
NotProfiled(); //this line is not profiled
//the following begin..end block will be profiled
//timing will be saved in a "profiler" log
begin var lProf := Profiler.Start(Context.ActionQualifiedName);
DoSomething();
DoSomethingElse();
Render('Just executed ' + Context.ActionQualifiedName);
end; // profiler writes automatically to the log
NotProfiled(); //this line is not profiled
end;
procedure TMyController.DoSomething;
begin
begin var lProf := Profiler.Start('DoSomething');
Sleep(100);
end;
end;
procedure TMyController.DoSomethingElse;
begin
begin var lProf := Profiler.Start('DoSomethingElse');
Sleep(100);
DoSomething();
end;
end;
procedure TMyController.NotProfiled;
begin
Sleep(100);
end;
```
The log contains the following lines - check the caller/called relationship shown using `>>` and `<<` and the deep level
```
[>>][ 1][MainControllerU.TMyController.ProfilerSample1] [profiler]
[ >>][ 2][DoSomething] [profiler]
[ <<][ 2][DoSomething][ELAPSED: 00:00:00.1088214] [profiler]
[ >>][ 2][DoSomethingElse] [profiler]
[ >>][ 3][DoSomething] [profiler]
[ <<][ 3][DoSomething][ELAPSED: 00:00:00.1096617] [profiler]
[ <<][ 2][DoSomethingElse][ELAPSED: 00:00:00.2188468] [profiler]
[<<][ 1][MainControllerU.TMyController.ProfilerSample1][ELAPSED: 00:00:00.3277806] [profiler]
```
To get more info check the "profiling" example
- New `Context` property named `ActionQualifiedName` which contains the currently executed action in the form `UnitName.ClassName.ActionName`. It is available where the `Context` property is available. Obviously is not available in the `OnBeforeRouting` middleware events.
## Trainings, consultancy or custom development service
As you know, good support on open source software is a must for professional users.
If you need trainings, consultancy or custom developments on DelphiMVCFramework, send an email to *dmvcframework at bittime dot it*. Alternatively you can send a request using the [contacts forms](http://www.bittimeprofessionals.it/contatti) on [bit Time Professionals website](http://www.bittimeprofessionals.it). bit Time Professionals is the company behind DelphiMVCFramework, all the main developers works there.
If you need trainings, consultancy or custom developments on DelphiMVCFramework, send an email to *dmvcframework at bittime dot it*. Alternatively you can send a request using the [contacts forms](http://www.bittimeprofessionals.it/contatti) on [bit Time Professionals website](http://www.bittimeprofessionals.it). bit Time Professionals is the company behind DelphiMVCFramework, the lead developer works there.
## Samples and documentation
DMVCFramework is provided with a lot of examples focused on specific functionality.

View File

@ -34,7 +34,7 @@
Swag.Doc.SecurityDefinitionBasic in '..\..\lib\swagdoc\Source\Swag.Doc.SecurityDefinitionBasic.pas',
Swag.Doc.SecurityDefinitionOAuth2 in '..\..\lib\swagdoc\Source\Swag.Doc.SecurityDefinitionOAuth2.pas',
Swag.Doc.Tags in '..\..\lib\swagdoc\Source\Swag.Doc.Tags.pas',
MVCFramework.AsyncTask in '..\..\sources\MVCFramework.AsyncTask.pas',
MVCFramework.Middleware.Swagger in '..\..\sources\MVCFramework.Middleware.Swagger.pas',
MVCFramework.Middleware.Trace in '..\..\sources\MVCFramework.Middleware.Trace.pas',
MVCFramework.Middleware.ETag in '..\..\sources\MVCFramework.Middleware.ETag.pas',

View File

@ -107,3 +107,4 @@ end.

View File

@ -8,6 +8,7 @@ uses
FireDAC.Phys.MySQL,
FireDAC.Phys.SQLite,
System.SysUtils,
MVCFramework,
MVCFramework.Commons,
MVCFramework.REPLCommandsHandlerU,
Web.ReqMulti,
@ -34,7 +35,6 @@ uses
procedure RunServer(APort: Integer);
var
lServer: TIdHTTPWebBrokerBridge;
lCustomHandler: TMVCCustomREPLCommandsHandler;
lCmd: string;
begin
ConnectionDefinitionName := CON_DEF_NAME;
@ -63,6 +63,7 @@ begin
lServer := TIdHTTPWebBrokerBridge.Create(nil);
try
lServer.KeepAlive := True;
lServer.DefaultPort := APort;
lServer.MaxConnections := 0;
lServer.ListenQueue := 200;
@ -70,6 +71,7 @@ begin
WriteLn('Running on port ', APort);
Write('CTRL+C to Quit');
WaitForTerminationSignal;
EnterInShutdownState;
finally
lServer.Free;
end;

View File

@ -1,7 +1,7 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{BA0288C3-D569-4C85-892B-129456126E1E}</ProjectGuid>
<ProjectVersion>18.8</ProjectVersion>
<ProjectVersion>19.5</ProjectVersion>
<FrameworkType>None</FrameworkType>
<MainSource>concurrency_speed_test.dpr</MainSource>
<Base>True</Base>
@ -13,6 +13,11 @@
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Android' and '$(Base)'=='true') or '$(Base_Android)'!=''">
<Base_Android>true</Base_Android>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Android64' and '$(Base)'=='true') or '$(Base_Android64)'!=''">
<Base_Android64>true</Base_Android64>
<CfgParent>Base</CfgParent>
@ -23,11 +28,6 @@
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='OSX64' and '$(Base)'=='true') or '$(Base_OSX64)'!=''">
<Base_OSX64>true</Base_OSX64>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
<Base_Win32>true</Base_Win32>
<CfgParent>Base</CfgParent>
@ -76,29 +76,29 @@
<DCC_Framework>VCL;$(DCC_Framework)</DCC_Framework>
<SanitizedProjectName>concurrency_speed_test</SanitizedProjectName>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Android)'!=''">
<Android_LauncherIcon192>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png</Android_LauncherIcon192>
<VerInfo_Keys>package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey=</VerInfo_Keys>
<BT_BuildType>Debug</BT_BuildType>
<EnabledSysJars>annotation-1.2.0.dex.jar;asynclayoutinflater-1.0.0.dex.jar;billing-4.0.0.dex.jar;browser-1.0.0.dex.jar;cloud-messaging.dex.jar;collection-1.0.0.dex.jar;coordinatorlayout-1.0.0.dex.jar;core-1.5.0-rc02.dex.jar;core-common-2.0.1.dex.jar;core-runtime-2.0.1.dex.jar;cursoradapter-1.0.0.dex.jar;customview-1.0.0.dex.jar;documentfile-1.0.0.dex.jar;drawerlayout-1.0.0.dex.jar;firebase-annotations-16.0.0.dex.jar;firebase-common-20.0.0.dex.jar;firebase-components-17.0.0.dex.jar;firebase-datatransport-18.0.0.dex.jar;firebase-encoders-17.0.0.dex.jar;firebase-encoders-json-18.0.0.dex.jar;firebase-iid-interop-17.1.0.dex.jar;firebase-installations-17.0.0.dex.jar;firebase-installations-interop-17.0.0.dex.jar;firebase-measurement-connector-19.0.0.dex.jar;firebase-messaging-22.0.0.dex.jar;fmx.dex.jar;fragment-1.0.0.dex.jar;google-play-licensing.dex.jar;interpolator-1.0.0.dex.jar;javax.inject-1.dex.jar;legacy-support-core-ui-1.0.0.dex.jar;legacy-support-core-utils-1.0.0.dex.jar;lifecycle-common-2.0.0.dex.jar;lifecycle-livedata-2.0.0.dex.jar;lifecycle-livedata-core-2.0.0.dex.jar;lifecycle-runtime-2.0.0.dex.jar;lifecycle-service-2.0.0.dex.jar;lifecycle-viewmodel-2.0.0.dex.jar;listenablefuture-1.0.dex.jar;loader-1.0.0.dex.jar;localbroadcastmanager-1.0.0.dex.jar;play-services-ads-20.1.0.dex.jar;play-services-ads-base-20.1.0.dex.jar;play-services-ads-identifier-17.0.0.dex.jar;play-services-ads-lite-20.1.0.dex.jar;play-services-base-17.5.0.dex.jar;play-services-basement-17.6.0.dex.jar;play-services-cloud-messaging-16.0.0.dex.jar;play-services-drive-17.0.0.dex.jar;play-services-games-21.0.0.dex.jar;play-services-location-18.0.0.dex.jar;play-services-maps-17.0.1.dex.jar;play-services-measurement-base-18.0.0.dex.jar;play-services-measurement-sdk-api-18.0.0.dex.jar;play-services-places-placereport-17.0.0.dex.jar;play-services-stats-17.0.0.dex.jar;play-services-tasks-17.2.0.dex.jar;print-1.0.0.dex.jar;room-common-2.1.0.dex.jar;room-runtime-2.1.0.dex.jar;slidingpanelayout-1.0.0.dex.jar;sqlite-2.0.1.dex.jar;sqlite-framework-2.0.1.dex.jar;swiperefreshlayout-1.0.0.dex.jar;transport-api-3.0.0.dex.jar;transport-backend-cct-3.0.0.dex.jar;transport-runtime-3.0.0.dex.jar;user-messaging-platform-1.0.0.dex.jar;versionedparcelable-1.1.1.dex.jar;viewpager-1.0.0.dex.jar;work-runtime-2.1.0.dex.jar</EnabledSysJars>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Android64)'!=''">
<Base_Android>true</Base_Android>
<CfgParent>Base</CfgParent>
<Base>true</Base>
<DCC_UsePackage>DBXSqliteDriver;RESTComponents;DBXInterBaseDriver;emsclientfiredac;tethering;DataSnapFireDAC;bindcompfmx;FmxTeeUI;fmx;FireDACIBDriver;RadiantShapesFmx;FireDACDBXDriver;dbexpress;IndyCore;dsnap;emsclient;DataSnapCommon;FireDACCommon;RESTBackendComponents;soapserver;bindengine;CloudService;FireDACCommonDriver;DataSnapClient;inet;IndyIPCommon;bindcompdbx;IndyIPServer;IndySystem;fmxFireDAC;FireDAC;FireDACSqliteDriver;ibmonitor;FMXTee;soaprtl;DbxCommonDriver;ibxpress;xmlrtl;soapmidas;DataSnapNativeClient;FireDACDSDriver;rtl;DbxClientDriver;ibxbindings;CustomIPTransport;bindcomp;IndyIPClient;dbxcds;RadiantShapesFmx_Design;dsnapxml;DataSnapProviderClient;dbrtl;IndyProtocols;$(DCC_UsePackage);$(DCC_UsePackage)</DCC_UsePackage>
<EnabledSysJars>android-support-v4.dex.jar;cloud-messaging.dex.jar;fmx.dex.jar;google-analytics-v2.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar;google-play-services-ads-7.0.0.dex.jar;google-play-services-analytics-7.0.0.dex.jar;google-play-services-base-7.0.0.dex.jar;google-play-services-gcm-7.0.0.dex.jar;google-play-services-identity-7.0.0.dex.jar;google-play-services-maps-7.0.0.dex.jar;google-play-services-panorama-7.0.0.dex.jar;google-play-services-plus-7.0.0.dex.jar;google-play-services-wallet-7.0.0.dex.jar</EnabledSysJars>
<Android_LauncherIcon192>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png</Android_LauncherIcon192>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Linux64)'!=''">
<DCC_UsePackage>RESTComponents;emsclientfiredac;DataSnapFireDAC;FireDACADSDriver;DatasnapConnectorsFreePascal;FireDACMSSQLDriver;Spring.Data;inetdb;emsedge;FireDACIBDriver;dbexpress;IndyCore;dsnap;emsclient;DataSnapCommon;FireDACCommon;RESTBackendComponents;DataSnapConnectors;soapserver;bindengine;CloudService;FireDACOracleDriver;FireDACMySQLDriver;FireDACCommonODBC;FireDACCommonDriver;DataSnapClient;inet;IndySystem;FireDACDb2Driver;FireDACInfxDriver;FireDAC;emshosting;FireDACSqliteDriver;FireDACPgDriver;FireDACASADriver;FireDACTDataDriver;soaprtl;DbxCommonDriver;DataSnapServer;xmlrtl;soapmidas;DataSnapNativeClient;rtl;emsserverresource;DbxClientDriver;CustomIPTransport;bindcomp;dbxcds;FireDACODBCDriver;DataSnapIndy10ServerTransport;dsnapxml;dbrtl;IndyProtocols;FireDACMongoDBDriver;DataSnapServerMidas;$(DCC_UsePackage)</DCC_UsePackage>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_OSX64)'!=''">
<Base_OSX32>true</Base_OSX32>
<CfgParent>Base</CfgParent>
<Base>true</Base>
<DCC_UsePackage>DBXSqliteDriver;RESTComponents;fmxase;DBXInterBaseDriver;emsclientfiredac;tethering;DataSnapFireDAC;FireDACMSSQLDriver;bindcompfmx;DBXOracleDriver;Spring.Data;inetdb;FmxTeeUI;fmx;FireDACIBDriver;fmxdae;RadiantShapesFmx;FireDACDBXDriver;dbexpress;IndyCore;dsnap;emsclient;DataSnapCommon;FireDACCommon;RESTBackendComponents;soapserver;bindengine;DBXMySQLDriver;CloudService;FireDACOracleDriver;FireDACMySQLDriver;DBXFirebirdDriver;FireDACCommonODBC;FireDACCommonDriver;DataSnapClient;inet;IndyIPCommon;bindcompdbx;IndyIPServer;IndySystem;fmxFireDAC;FireDAC;FireDACSqliteDriver;FireDACPgDriver;ibmonitor;FireDACASADriver;FireDACTDataDriver;FMXTee;soaprtl;DbxCommonDriver;ibxpress;DataSnapServer;xmlrtl;soapmidas;DataSnapNativeClient;fmxobj;FireDACDSDriver;rtl;DbxClientDriver;ibxbindings;DBXSybaseASADriver;CustomIPTransport;bindcomp;DBXInformixDriver;IndyIPClient;dbxcds;FireDACODBCDriver;RadiantShapesFmx_Design;DataSnapIndy10ServerTransport;dsnapxml;DataSnapProviderClient;dbrtl;IndyProtocols;inetdbxpress;FireDACMongoDBDriver;DataSnapServerMidas;$(DCC_UsePackage);$(DCC_UsePackage)</DCC_UsePackage>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win32)'!=''">
<DCC_UsePackage>DBXSqliteDriver;RESTComponents;fmxase;DBXDb2Driver;DBXInterBaseDriver;vclactnband;vclFireDAC;emsclientfiredac;tethering;svnui;DataSnapFireDAC;FireDACADSDriver;DBXMSSQLDriver;DatasnapConnectorsFreePascal;FireDACMSSQLDriver;vcltouch;vcldb;bindcompfmx;svn;DBXOracleDriver;Spring.Data;inetdb;FmxTeeUI;emsedge;fmx;FireDACIBDriver;fmxdae;RadiantShapesFmx;vclib;frxTee26;FireDACDBXDriver;dbexpress;IndyCore;vclx;dsnap;emsclient;DataSnapCommon;FireDACCommon;RESTBackendComponents;DataSnapConnectors;VCLRESTComponents;soapserver;JclDeveloperTools;vclie;bindengine;DBXMySQLDriver;CloudService;FireDACOracleDriver;FireDACMySQLDriver;DBXFirebirdDriver;frx26;FireDACCommonODBC;FireDACCommonDriver;DataSnapClient;inet;IndyIPCommon;bindcompdbx;vcl;IndyIPServer;DBXSybaseASEDriver;frxDB26;IndySystem;FireDACDb2Driver;dsnapcon;FireDACMSAccDriver;fmxFireDAC;FireDACInfxDriver;vclimg;TeeDB;FireDAC;Jcl;emshosting;frxe26;FireDACSqliteDriver;FireDACPgDriver;ibmonitor;FireDACASADriver;DBXOdbcDriver;FireDACTDataDriver;FMXTee;soaprtl;DbxCommonDriver;ibxpress;Tee;DataSnapServer;xmlrtl;soapmidas;DataSnapNativeClient;fmxobj;vclwinx;FireDACDSDriver;rtl;emsserverresource;DbxClientDriver;ibxbindings;DBXSybaseASADriver;CustomIPTransport;vcldsnap;bindcomp;appanalytics;DBXInformixDriver;IndyIPClient;bindcompvcl;TeeUI;dmvcframeworkRT;dbxcds;VclSmp;adortl;FireDACODBCDriver;RadiantShapesFmx_Design;JclVcl;DataSnapIndy10ServerTransport;dmvcframeworkDT;dsnapxml;DataSnapProviderClient;dbrtl;IndyProtocols;inetdbxpress;FireDACMongoDBDriver;JclContainers;DataSnapServerMidas;$(DCC_UsePackage)</DCC_UsePackage>
<DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
<BT_BuildType>Debug</BT_BuildType>
<VerInfo_Keys>CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
<VerInfo_Locale>1033</VerInfo_Locale>
<DCC_ExeOutput>.\bin</DCC_ExeOutput>
<Manifest_File>(None)</Manifest_File>
<DCC_Optimize>false</DCC_Optimize>
<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
@ -117,10 +117,15 @@
<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
<DCC_DebugInfoInExe>true</DCC_DebugInfoInExe>
<DCC_RemoteDebug>true</DCC_RemoteDebug>
<VerInfo_Locale>1040</VerInfo_Locale>
<VerInfo_Keys>CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1_Win32)'!=''">
<DCC_RemoteDebug>false</DCC_RemoteDebug>
<VerInfo_Locale>1033</VerInfo_Locale>
<DCC_UnitSearchPath>C:\DEV\dmvcframework\sources\;$(DCC_UnitSearchPath)</DCC_UnitSearchPath>
<AppDPIAwarenessMode>none</AppDPIAwarenessMode>
<DCC_Define>PROFILE;$(DCC_Define)</DCC_Define>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2)'!=''">
<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
@ -141,10 +146,6 @@
<FormType>dfm</FormType>
<DesignClass>TWebModule</DesignClass>
</DCCReference>
<BuildConfiguration Include="Release">
<Key>Cfg_2</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
<BuildConfiguration Include="Base">
<Key>Base</Key>
</BuildConfiguration>
@ -152,6 +153,10 @@
<Key>Cfg_1</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
<BuildConfiguration Include="Release">
<Key>Cfg_2</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
</ItemGroup>
<ProjectExtensions>
<Borland.Personality>Delphi.Personality.12</Borland.Personality>
@ -162,23 +167,11 @@
<Source Name="MainSource">concurrency_speed_test.dpr</Source>
</Source>
<Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\bcboffice2k260.bpl">Embarcadero C++Builder Office 2000 Servers Package</Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\bcbofficexp260.bpl">Embarcadero C++Builder Office XP Servers Package</Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dcloffice2k260.bpl">Microsoft Office 2000 Sample Automation Server Wrapper Components</Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dclofficexp260.bpl">Microsoft Office XP Sample Automation Server Wrapper Components</Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dcloffice2k280.bpl">Microsoft Office 2000 Sample Automation Server Wrapper Components</Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dclofficexp280.bpl">Microsoft Office XP Sample Automation Server Wrapper Components</Excluded_Packages>
</Excluded_Packages>
</Delphi.Personality>
<Deployment Version="3">
<DeployFile LocalName="$(BDS)\Redist\osx64\libcgsqlite3.dylib" Class="DependencyModule">
<Platform Name="OSX64">
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="$(BDS)\Redist\osx32\libcgunwind.1.0.dylib" Class="DependencyModule">
<Platform Name="OSX32">
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<Deployment Version="4">
<DeployFile LocalName="$(BDS)\Redist\iossimulator\libcgunwind.1.0.dylib" Class="DependencyModule">
<Platform Name="iOSSimulator">
<Overwrite>true</Overwrite>
@ -189,17 +182,14 @@
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="$(BDS)\Redist\osx32\libcgsqlite3.dylib" Class="DependencyModule">
<DeployFile LocalName="$(BDS)\Redist\osx32\libcgsqlite3.dylib" Class="DependencyModule"/>
<DeployFile LocalName="$(BDS)\Redist\osx32\libcgunwind.1.0.dylib" Class="DependencyModule">
<Platform Name="OSX32">
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="bin\concurrency_speed_test.exe" Configuration="Debug" Class="ProjectOutput">
<Platform Name="Win32">
<RemoteName>concurrency_speed_test.exe</RemoteName>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="$(BDS)\Redist\osx64\libcgsqlite3.dylib" Class="DependencyModule"/>
<DeployFile LocalName="bin\concurrency_speed_test.exe" Configuration="Debug" Class="ProjectOutput"/>
<DeployClass Name="AdditionalDebugSymbols">
<Platform Name="OSX32">
<Operation>1</Operation>
@ -208,14 +198,14 @@
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidClassesDexFile">
<DeployClass Name="AndroidClasses">
<Platform Name="Android">
<RemoteDir>classes</RemoteDir>
<Operation>1</Operation>
<Operation>64</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>classes</RemoteDir>
<Operation>1</Operation>
<Operation>64</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidFileProvider">
@ -336,6 +326,16 @@
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon192">
<Platform Name="Android">
<RemoteDir>res\drawable-xxxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xxxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon36">
<Platform Name="Android">
<RemoteDir>res\drawable-ldpi</RemoteDir>
@ -496,6 +496,10 @@
<Operation>1</Operation>
<Extensions>.framework</Extensions>
</Platform>
<Platform Name="OSXARM64">
<Operation>1</Operation>
<Extensions>.framework</Extensions>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
@ -509,6 +513,10 @@
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSXARM64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
<Extensions>.dll;.bpl</Extensions>
@ -523,7 +531,7 @@
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
@ -535,6 +543,10 @@
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSXARM64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
<Extensions>.bpl</Extensions>
@ -553,7 +565,7 @@
<Platform Name="iOSDevice64">
<Operation>0</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<Operation>0</Operation>
</Platform>
<Platform Name="OSX32">
@ -562,315 +574,210 @@
<Platform Name="OSX64">
<Operation>0</Operation>
</Platform>
<Platform Name="OSXARM64">
<Operation>0</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch1024">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<DeployClass Name="iOS_AppStore1024">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch1024x768">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<DeployClass Name="iPad_AppIcon152">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch1536">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<DeployClass Name="iPad_AppIcon167">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch1536x2048">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<DeployClass Name="iPad_Launch2x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch1668">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<DeployClass Name="iPad_LaunchDark2x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch1668x2388">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<DeployClass Name="iPad_Notification40">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch2048">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<DeployClass Name="iPad_Setting58">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch2048x1536">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<DeployClass Name="iPad_SpotLight80">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch2048x2732">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<DeployClass Name="iPhone_AppIcon120">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch2224">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<DeployClass Name="iPhone_AppIcon180">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch2388x1668">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<DeployClass Name="iPhone_Launch2x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch2732x2048">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<DeployClass Name="iPhone_Launch3x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch768">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<DeployClass Name="iPhone_LaunchDark2x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch768x1024">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<DeployClass Name="iPhone_LaunchDark3x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch1125">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<DeployClass Name="iPhone_Notification40">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch1136x640">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<DeployClass Name="iPhone_Notification60">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch1242">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<DeployClass Name="iPhone_Setting58">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch1242x2688">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<DeployClass Name="iPhone_Setting87">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch1334">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<DeployClass Name="iPhone_Spotlight120">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch1792">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<DeployClass Name="iPhone_Spotlight80">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch2208">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch2436">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch2688x1242">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch320">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch640">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch640x1136">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch750">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch828">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
@ -891,10 +798,14 @@
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSDeviceResourceRules"/>
<DeployClass Name="ProjectiOSEntitlements"/>
<DeployClass Name="ProjectiOSInfoPList"/>
<DeployClass Name="ProjectiOSLaunchScreen"/>
<DeployClass Name="ProjectiOSResource">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
@ -902,7 +813,7 @@
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<Operation>1</Operation>
</Platform>
</DeployClass>
@ -918,6 +829,10 @@
<RemoteDir>Contents\Resources</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="OSXARM64">
<RemoteDir>Contents\Resources</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Required="true" Name="ProjectOutput">
<Platform Name="Android">
@ -934,7 +849,7 @@
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<Operation>1</Operation>
</Platform>
<Platform Name="Linux64">
@ -946,6 +861,9 @@
<Platform Name="OSX64">
<Operation>1</Operation>
</Platform>
<Platform Name="OSXARM64">
<Operation>1</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
@ -984,21 +902,23 @@
<Operation>1</Operation>
</Platform>
</DeployClass>
<ProjectRoot Platform="iOSDevice64" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="Win64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="iOSDevice32" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="Linux64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="Win32" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="OSX32" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="Android" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="OSX64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="iOSSimulator" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="Android64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="iOSDevice32" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="iOSDevice64" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="iOSSimARM64" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="iOSSimulator" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="Linux64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="OSX32" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="OSX64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="OSXARM64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="Win32" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="Win64" Name="$(PROJECTNAME)"/>
</Deployment>
<Platforms>
<Platform value="Android">False</Platform>
<Platform value="Android64">False</Platform>
<Platform value="Linux64">False</Platform>
<Platform value="OSX64">False</Platform>
<Platform value="Win32">True</Platform>
<Platform value="Win64">False</Platform>
</Platforms>

View File

@ -9,7 +9,7 @@ uses
MVCFramework.Console;
var
F, B, I: Integer;
F, B: Integer;
lFGColorName, lBGColorName: String;
lSize: TMVCConsoleSize;

View File

@ -7,12 +7,22 @@
<TargetedPlatforms>129</TargetedPlatforms>
<AppType>Console</AppType>
<FrameworkType>None</FrameworkType>
<ProjectVersion>19.0</ProjectVersion>
<Platform Condition="'$(Platform)'==''">Linux64</Platform>
<ProjectVersion>19.5</ProjectVersion>
<Platform Condition="'$(Platform)'==''">Win32</Platform>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Android' and '$(Base)'=='true') or '$(Base_Android)'!=''">
<Base_Android>true</Base_Android>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Android64' and '$(Base)'=='true') or '$(Base_Android64)'!=''">
<Base_Android64>true</Base_Android64>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
<Base_Win32>true</Base_Win32>
<CfgParent>Base</CfgParent>
@ -42,6 +52,18 @@
<Icon_MainIcon>$(BDS)\bin\delphi_PROJECTICON.ico</Icon_MainIcon>
<Icns_MainIcns>$(BDS)\bin\delphi_PROJECTICNS.icns</Icns_MainIcns>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Android)'!=''">
<Android_LauncherIcon192>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png</Android_LauncherIcon192>
<VerInfo_Keys>package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey=</VerInfo_Keys>
<BT_BuildType>Debug</BT_BuildType>
<EnabledSysJars>annotation-1.2.0.dex.jar;asynclayoutinflater-1.0.0.dex.jar;billing-4.0.0.dex.jar;browser-1.0.0.dex.jar;cloud-messaging.dex.jar;collection-1.0.0.dex.jar;coordinatorlayout-1.0.0.dex.jar;core-1.5.0-rc02.dex.jar;core-common-2.0.1.dex.jar;core-runtime-2.0.1.dex.jar;cursoradapter-1.0.0.dex.jar;customview-1.0.0.dex.jar;documentfile-1.0.0.dex.jar;drawerlayout-1.0.0.dex.jar;firebase-annotations-16.0.0.dex.jar;firebase-common-20.0.0.dex.jar;firebase-components-17.0.0.dex.jar;firebase-datatransport-18.0.0.dex.jar;firebase-encoders-17.0.0.dex.jar;firebase-encoders-json-18.0.0.dex.jar;firebase-iid-interop-17.1.0.dex.jar;firebase-installations-17.0.0.dex.jar;firebase-installations-interop-17.0.0.dex.jar;firebase-measurement-connector-19.0.0.dex.jar;firebase-messaging-22.0.0.dex.jar;fmx.dex.jar;fragment-1.0.0.dex.jar;google-play-licensing.dex.jar;interpolator-1.0.0.dex.jar;javax.inject-1.dex.jar;legacy-support-core-ui-1.0.0.dex.jar;legacy-support-core-utils-1.0.0.dex.jar;lifecycle-common-2.0.0.dex.jar;lifecycle-livedata-2.0.0.dex.jar;lifecycle-livedata-core-2.0.0.dex.jar;lifecycle-runtime-2.0.0.dex.jar;lifecycle-service-2.0.0.dex.jar;lifecycle-viewmodel-2.0.0.dex.jar;listenablefuture-1.0.dex.jar;loader-1.0.0.dex.jar;localbroadcastmanager-1.0.0.dex.jar;play-services-ads-20.1.0.dex.jar;play-services-ads-base-20.1.0.dex.jar;play-services-ads-identifier-17.0.0.dex.jar;play-services-ads-lite-20.1.0.dex.jar;play-services-base-17.5.0.dex.jar;play-services-basement-17.6.0.dex.jar;play-services-cloud-messaging-16.0.0.dex.jar;play-services-drive-17.0.0.dex.jar;play-services-games-21.0.0.dex.jar;play-services-location-18.0.0.dex.jar;play-services-maps-17.0.1.dex.jar;play-services-measurement-base-18.0.0.dex.jar;play-services-measurement-sdk-api-18.0.0.dex.jar;play-services-places-placereport-17.0.0.dex.jar;play-services-stats-17.0.0.dex.jar;play-services-tasks-17.2.0.dex.jar;print-1.0.0.dex.jar;room-common-2.1.0.dex.jar;room-runtime-2.1.0.dex.jar;slidingpanelayout-1.0.0.dex.jar;sqlite-2.0.1.dex.jar;sqlite-framework-2.0.1.dex.jar;swiperefreshlayout-1.0.0.dex.jar;transport-api-3.0.0.dex.jar;transport-backend-cct-3.0.0.dex.jar;transport-runtime-3.0.0.dex.jar;user-messaging-platform-1.0.0.dex.jar;versionedparcelable-1.1.1.dex.jar;viewpager-1.0.0.dex.jar;work-runtime-2.1.0.dex.jar</EnabledSysJars>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Android64)'!=''">
<Android_LauncherIcon192>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png</Android_LauncherIcon192>
<VerInfo_Keys>package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey=</VerInfo_Keys>
<BT_BuildType>Debug</BT_BuildType>
<EnabledSysJars>annotation-1.2.0.dex.jar;asynclayoutinflater-1.0.0.dex.jar;billing-4.0.0.dex.jar;browser-1.0.0.dex.jar;cloud-messaging.dex.jar;collection-1.0.0.dex.jar;coordinatorlayout-1.0.0.dex.jar;core-1.5.0-rc02.dex.jar;core-common-2.0.1.dex.jar;core-runtime-2.0.1.dex.jar;cursoradapter-1.0.0.dex.jar;customview-1.0.0.dex.jar;documentfile-1.0.0.dex.jar;drawerlayout-1.0.0.dex.jar;firebase-annotations-16.0.0.dex.jar;firebase-common-20.0.0.dex.jar;firebase-components-17.0.0.dex.jar;firebase-datatransport-18.0.0.dex.jar;firebase-encoders-17.0.0.dex.jar;firebase-encoders-json-18.0.0.dex.jar;firebase-iid-interop-17.1.0.dex.jar;firebase-installations-17.0.0.dex.jar;firebase-installations-interop-17.0.0.dex.jar;firebase-measurement-connector-19.0.0.dex.jar;firebase-messaging-22.0.0.dex.jar;fmx.dex.jar;fragment-1.0.0.dex.jar;google-play-licensing.dex.jar;interpolator-1.0.0.dex.jar;javax.inject-1.dex.jar;legacy-support-core-ui-1.0.0.dex.jar;legacy-support-core-utils-1.0.0.dex.jar;lifecycle-common-2.0.0.dex.jar;lifecycle-livedata-2.0.0.dex.jar;lifecycle-livedata-core-2.0.0.dex.jar;lifecycle-runtime-2.0.0.dex.jar;lifecycle-service-2.0.0.dex.jar;lifecycle-viewmodel-2.0.0.dex.jar;listenablefuture-1.0.dex.jar;loader-1.0.0.dex.jar;localbroadcastmanager-1.0.0.dex.jar;play-services-ads-20.1.0.dex.jar;play-services-ads-base-20.1.0.dex.jar;play-services-ads-identifier-17.0.0.dex.jar;play-services-ads-lite-20.1.0.dex.jar;play-services-base-17.5.0.dex.jar;play-services-basement-17.6.0.dex.jar;play-services-cloud-messaging-16.0.0.dex.jar;play-services-drive-17.0.0.dex.jar;play-services-games-21.0.0.dex.jar;play-services-location-18.0.0.dex.jar;play-services-maps-17.0.1.dex.jar;play-services-measurement-base-18.0.0.dex.jar;play-services-measurement-sdk-api-18.0.0.dex.jar;play-services-places-placereport-17.0.0.dex.jar;play-services-stats-17.0.0.dex.jar;play-services-tasks-17.2.0.dex.jar;print-1.0.0.dex.jar;room-common-2.1.0.dex.jar;room-runtime-2.1.0.dex.jar;slidingpanelayout-1.0.0.dex.jar;sqlite-2.0.1.dex.jar;sqlite-framework-2.0.1.dex.jar;swiperefreshlayout-1.0.0.dex.jar;transport-api-3.0.0.dex.jar;transport-backend-cct-3.0.0.dex.jar;transport-runtime-3.0.0.dex.jar;user-messaging-platform-1.0.0.dex.jar;versionedparcelable-1.1.1.dex.jar;viewpager-1.0.0.dex.jar;work-runtime-2.1.0.dex.jar</EnabledSysJars>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win32)'!=''">
<DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
<BT_BuildType>Debug</BT_BuildType>
@ -63,10 +85,6 @@
<DelphiCompile Include="$(MainSource)">
<MainSource>MainSource</MainSource>
</DelphiCompile>
<BuildConfiguration Include="Debug">
<Key>Cfg_2</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
<BuildConfiguration Include="Base">
<Key>Base</Key>
</BuildConfiguration>
@ -74,6 +92,10 @@
<Key>Cfg_1</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
<BuildConfiguration Include="Debug">
<Key>Cfg_2</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
</ItemGroup>
<ProjectExtensions>
<Borland.Personality>Delphi.Personality.12</Borland.Personality>
@ -85,6 +107,8 @@
</Source>
</Delphi.Personality>
<Platforms>
<Platform value="Android">False</Platform>
<Platform value="Android64">False</Platform>
<Platform value="Linux64">True</Platform>
<Platform value="Win32">True</Platform>
<Platform value="Win64">False</Platform>

View File

@ -0,0 +1,637 @@
object MainForm: TMainForm
Left = 0
Top = 0
Caption = 'JSON-RPC 2.0 Async Client'
ClientHeight = 603
ClientWidth = 838
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OnCreate = FormCreate
TextHeight = 13
object PageControl1: TPageControl
Left = 0
Top = 0
Width = 838
Height = 603
ActivePage = TabSheet1
Align = alClient
TabOrder = 0
ExplicitWidth = 834
ExplicitHeight = 602
object TabSheet1: TTabSheet
Caption = 'Invoking Plain PODO'
object GroupBox1: TGroupBox
Left = 3
Top = 22
Width = 815
Height = 174
Caption = 'Simple Types'
TabOrder = 0
object edtValue1: TEdit
Left = 17
Top = 32
Width = 32
Height = 21
TabOrder = 0
Text = '42'
end
object edtValue2: TEdit
Left = 55
Top = 32
Width = 26
Height = 21
TabOrder = 1
Text = '10'
end
object btnSubstract: TButton
Left = 87
Top = 30
Width = 100
Height = 25
Caption = 'Subtract'
TabOrder = 2
OnClick = btnSubstractClick
end
object edtResult: TEdit
Left = 193
Top = 32
Width = 27
Height = 21
ReadOnly = True
TabOrder = 3
end
object edtReverseString: TEdit
Left = 17
Top = 80
Width = 88
Height = 21
TabOrder = 4
Text = 'Daniele Teti'
end
object btnReverseString: TButton
Left = 111
Top = 78
Width = 109
Height = 25
Caption = 'Reverse String'
TabOrder = 5
OnClick = btnReverseStringClick
end
object edtReversedString: TEdit
Left = 320
Top = 80
Width = 131
Height = 21
ReadOnly = True
TabOrder = 6
end
object dtNextMonday: TDateTimePicker
Left = 253
Top = 32
Width = 102
Height = 21
Date = 43018.000000000000000000
Time = 0.469176562502980200
TabOrder = 7
end
object btnAddDay: TButton
Left = 361
Top = 30
Width = 104
Height = 25
Caption = 'Get Next Monday'
TabOrder = 8
OnClick = btnAddDayClick
end
object btnInvalid1: TButton
Left = 626
Top = 78
Width = 84
Height = 43
Caption = 'Passing VAR parameters'
Font.Charset = DEFAULT_CHARSET
Font.Color = clScrollBar
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
ParentFont = False
TabOrder = 9
WordWrap = True
OnClick = btnInvalid1Click
end
object btnInvalid2: TButton
Left = 716
Top = 78
Width = 84
Height = 43
Caption = 'Passing OUT parameters'
Font.Charset = DEFAULT_CHARSET
Font.Color = clScrollBar
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
ParentFont = False
TabOrder = 10
WordWrap = True
OnClick = btnInvalid2Click
end
object btnNotification: TButton
Left = 464
Top = 78
Width = 75
Height = 43
Caption = 'Send Notification'
Font.Charset = DEFAULT_CHARSET
Font.Color = clScrollBar
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
ParentFont = False
TabOrder = 11
WordWrap = True
OnClick = btnNotificationClick
end
object btnInvalidMethod: TButton
Left = 545
Top = 78
Width = 75
Height = 43
Caption = 'Invalid Method'
Font.Charset = DEFAULT_CHARSET
Font.Color = clScrollBar
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
ParentFont = False
TabOrder = 12
WordWrap = True
OnClick = btnInvalidMethodClick
end
object CheckBox1: TCheckBox
Left = 226
Top = 82
Width = 88
Height = 17
Caption = 'As Uppercase'
TabOrder = 13
end
object btnDates: TButton
Left = 716
Top = 30
Width = 84
Height = 25
Caption = 'PlayWithDates'
TabOrder = 14
OnClick = btnDatesClick
end
object btnFloatsTests: TButton
Left = 626
Top = 30
Width = 84
Height = 25
Caption = 'Floats'
TabOrder = 15
OnClick = btnFloatsTestsClick
end
object btnWithJSON: TButton
Left = 545
Top = 30
Width = 75
Height = 25
Caption = 'JSON Prop'
TabOrder = 16
OnClick = btnWithJSONClick
end
object Edit1: TEdit
Left = 17
Top = 136
Width = 32
Height = 21
TabOrder = 17
Text = '42'
end
object Edit2: TEdit
Left = 55
Top = 136
Width = 26
Height = 21
TabOrder = 18
Text = '10'
end
object btnSubtractWithNamedParams: TButton
Left = 87
Top = 134
Width = 160
Height = 25
Caption = 'Subtract (named params)'
TabOrder = 19
OnClick = btnSubtractWithNamedParamsClick
end
object Edit3: TEdit
Left = 253
Top = 136
Width = 27
Height = 21
ReadOnly = True
TabOrder = 20
end
object btnGenericException: TButton
Left = 464
Top = 127
Width = 156
Height = 32
Caption = 'Raise Generic Exception'
TabOrder = 21
OnClick = btnGenericExceptionClick
end
object btnException: TButton
Left = 626
Top = 127
Width = 170
Height = 32
Caption = 'Raise Custom Exception'
TabOrder = 22
OnClick = btnExceptionClick
end
object btnParallel: TButton
Left = 320
Top = 134
Width = 131
Height = 25
Caption = 'Parallel Calls'
TabOrder = 23
OnClick = btnParallelClick
end
end
object GroupBox2: TGroupBox
Left = 3
Top = 202
Width = 489
Height = 159
Caption = 'Returning Objects'
TabOrder = 1
object edtUserName: TEdit
Left = 16
Top = 24
Width = 184
Height = 21
TabOrder = 0
Text = 'dteti'
end
object btnGetUser: TButton
Left = 206
Top = 22
Width = 91
Height = 25
Caption = 'Get User'
TabOrder = 1
OnClick = btnGetUserClick
end
object lbPerson: TListBox
Left = 16
Top = 53
Width = 435
Height = 82
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -13
Font.Name = 'Courier New'
Font.Style = []
ParentFont = False
TabOrder = 2
end
end
object GroupBox4: TGroupBox
Left = 3
Top = 383
Width = 489
Height = 129
Caption = 'Passing Objects as parameters'
TabOrder = 2
object edtFirstName: TLabeledEdit
Left = 16
Top = 40
Width = 121
Height = 21
EditLabel.Width = 51
EditLabel.Height = 13
EditLabel.Caption = 'First Name'
TabOrder = 0
Text = 'Daniele'
end
object edtLastName: TLabeledEdit
Left = 16
Top = 88
Width = 121
Height = 21
EditLabel.Width = 50
EditLabel.Height = 13
EditLabel.Caption = 'Last Name'
TabOrder = 1
Text = 'Teti'
end
object chkMarried: TCheckBox
Left = 172
Top = 40
Width = 97
Height = 17
Caption = 'Married'
Checked = True
State = cbChecked
TabOrder = 2
end
object dtDOB: TDateTimePicker
Left = 169
Top = 88
Width = 102
Height = 21
Date = 29163.000000000000000000
Time = 0.469176562499342300
TabOrder = 3
end
object btnSave: TButton
Left = 376
Top = 88
Width = 75
Height = 25
Caption = 'Save'
TabOrder = 4
OnClick = btnSaveClick
end
end
object PageControl2: TPageControl
Left = 514
Top = 202
Width = 304
Height = 367
ActivePage = TabSheet3
TabOrder = 3
object TabSheet3: TTabSheet
Caption = 'Get DataSet'
object edtFilter: TEdit
Left = 3
Top = 5
Width = 184
Height = 21
TabOrder = 0
end
object edtGetCustomers: TButton
Left = 193
Top = 3
Width = 91
Height = 25
Caption = 'Get Customers'
TabOrder = 1
OnClick = edtGetCustomersClick
end
object DBGrid1: TDBGrid
Left = 3
Top = 34
Width = 279
Height = 302
DataSource = DataSource1
TabOrder = 2
TitleFont.Charset = DEFAULT_CHARSET
TitleFont.Color = clWindowText
TitleFont.Height = -11
TitleFont.Name = 'Tahoma'
TitleFont.Style = []
end
end
object TabSheet4: TTabSheet
Caption = 'Get Multi Dataset'
ImageIndex = 1
object btnGetMulti: TButton
Left = 13
Top = 16
Width = 268
Height = 41
Caption = 'Get Multiple Datasets'
TabOrder = 0
OnClick = btnGetMultiClick
end
object lbMulti: TListBox
Left = 16
Top = 63
Width = 265
Height = 266
Font.Charset = ANSI_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Courier New'
Font.Style = []
ItemHeight = 14
ParentFont = False
TabOrder = 1
end
end
end
end
object TabSheet2: TTabSheet
Caption = 'Invoking DataModule Methods'
ImageIndex = 1
object GroupBox5: TGroupBox
Left = 11
Top = 18
Width = 489
Height = 391
Caption = 'Returning Objects'
TabOrder = 0
DesignSize = (
489
391)
object edtSearchText: TEdit
Left = 16
Top = 24
Width = 184
Height = 21
TabOrder = 0
Text = 'pizz'
end
object btnSearch: TButton
Left = 206
Top = 22
Width = 91
Height = 25
Caption = 'Search Article'
TabOrder = 1
OnClick = btnSearchClick
end
object ListBox1: TListBox
Left = 16
Top = 53
Width = 435
Height = 316
Anchors = [akLeft, akTop, akRight, akBottom]
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -13
Font.Name = 'Courier New'
Font.Style = []
ParentFont = False
TabOrder = 2
end
end
end
object TabSheet5: TTabSheet
Caption = 'Custom Exceptions Handling'
ImageIndex = 2
object Label1: TLabel
AlignWithMargins = True
Left = 3
Top = 3
Width = 808
Height = 69
Align = alTop
Caption =
'If an exception raised by the serve doesn'#39't inherith from EMVCJS' +
'ONRPCErrorResponse can be handled by a custom global exception b' +
'lock. This custom handling can modify error code, error message ' +
'and can add a custom data property to the exception.'
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -19
Font.Name = 'Tahoma'
Font.Style = []
ParentFont = False
WordWrap = True
end
object btnGenericExcWithCustomHandling: TButton
Left = 0
Top = 103
Width = 217
Height = 82
Caption = 'Raise Generic Exception with custom handling (DATA is a String)'
TabOrder = 0
WordWrap = True
OnClick = btnGenericExcWithCustomHandlingClick
end
object btnGenericExcWithCustomHAndling2: TButton
Left = 223
Top = 103
Width = 217
Height = 82
Caption =
'Raise Generic Exception with custom handling (DATA is a JSONObje' +
'ct)'
TabOrder = 1
WordWrap = True
OnClick = btnGenericExcWithCustomHAndling2Click
end
object btnGenericExcWithoutCustomHandling: TButton
Left = 446
Top = 103
Width = 217
Height = 82
Caption = 'Raise Generic Exception without custom handling'
TabOrder = 2
WordWrap = True
OnClick = btnGenericExcWithoutCustomHandlingClick
end
end
object TabSheet6: TTabSheet
Caption = 'Using record as parameters'
ImageIndex = 3
DesignSize = (
830
575)
object btnSingleRec: TButton
Left = 16
Top = 16
Width = 185
Height = 41
Caption = 'Returning Single Record'
TabOrder = 0
OnClick = btnSingleRecClick
end
object lbLogRec: TMemo
Left = 216
Top = 16
Width = 589
Height = 544
Anchors = [akLeft, akTop, akRight, akBottom]
Font.Charset = ANSI_CHARSET
Font.Color = clWindowText
Font.Height = -13
Font.Name = 'Consolas'
Font.Style = []
ParentFont = False
ReadOnly = True
ScrollBars = ssBoth
TabOrder = 1
WordWrap = False
end
object btnGetArrayOfRecords: TButton
Left = 16
Top = 63
Width = 185
Height = 40
Caption = 'Returning Array of Records'
TabOrder = 2
OnClick = btnGetArrayOfRecordsClick
end
object btnGetDynArray: TButton
Left = 16
Top = 109
Width = 185
Height = 40
Caption = 'Returning DynArray of Records'
TabOrder = 3
OnClick = btnGetDynArrayClick
end
object btnPassAndGetRecord: TButton
Left = 16
Top = 155
Width = 185
Height = 40
Caption = 'Using record parameters'
TabOrder = 4
OnClick = btnPassAndGetRecordClick
end
object btnEchoComplexArray: TButton
Left = 16
Top = 201
Width = 185
Height = 40
Caption = 'Using Array as Parameter'
TabOrder = 5
OnClick = btnEchoComplexArrayClick
end
object btnComplex: TButton
Left = 16
Top = 247
Width = 185
Height = 40
Caption = 'Using parameter with multiple arrays'
TabOrder = 6
OnClick = btnComplexClick
end
end
end
object DataSource1: TDataSource
DataSet = FDMemTable1
Left = 455
Top = 216
end
object FDMemTable1: TFDMemTable
FetchOptions.AssignedValues = [evMode]
FetchOptions.Mode = fmAll
ResourceOptions.AssignedValues = [rvSilentMode]
ResourceOptions.SilentMode = True
UpdateOptions.AssignedValues = [uvCheckRequired, uvAutoCommitUpdates]
UpdateOptions.CheckRequired = False
UpdateOptions.AutoCommitUpdates = True
Left = 767
Top = 328
object FDMemTable1Code: TIntegerField
FieldName = 'Code'
end
object FDMemTable1Name: TStringField
FieldName = 'Name'
end
end
end

View File

@ -0,0 +1,845 @@
unit MainClientFormU;
interface
uses
Winapi.Windows,
Winapi.Messages,
System.SysUtils,
System.Variants,
System.Classes,
Vcl.Graphics,
Vcl.Controls,
Vcl.Forms,
Vcl.Dialogs,
System.Net.HttpClientComponent,
Vcl.StdCtrls,
System.Net.URLClient,
System.Net.HttpClient,
Data.DB,
Vcl.Grids,
Vcl.DBGrids,
FireDAC.Stan.Intf,
FireDAC.Stan.Option,
FireDAC.Stan.Param,
FireDAC.Stan.Error,
FireDAC.DatS,
FireDAC.Phys.Intf,
FireDAC.DApt.Intf,
FireDAC.Comp.DataSet,
FireDAC.Comp.Client,
Vcl.ComCtrls,
Vcl.ExtCtrls,
MVCFramework.JSONRPC.Client, Vcl.Mask, WaitingFormU;
type
TMainForm = class(TForm)
DataSource1: TDataSource;
FDMemTable1: TFDMemTable;
FDMemTable1Code: TIntegerField;
FDMemTable1Name: TStringField;
GroupBox1: TGroupBox;
edtValue1: TEdit;
edtValue2: TEdit;
btnSubstract: TButton;
edtResult: TEdit;
edtReverseString: TEdit;
btnReverseString: TButton;
edtReversedString: TEdit;
GroupBox2: TGroupBox;
edtUserName: TEdit;
btnGetUser: TButton;
lbPerson: TListBox;
GroupBox4: TGroupBox;
edtFirstName: TLabeledEdit;
edtLastName: TLabeledEdit;
chkMarried: TCheckBox;
dtDOB: TDateTimePicker;
btnSave: TButton;
dtNextMonday: TDateTimePicker;
btnAddDay: TButton;
btnInvalid1: TButton;
btnInvalid2: TButton;
btnNotification: TButton;
btnInvalidMethod: TButton;
PageControl1: TPageControl;
TabSheet1: TTabSheet;
TabSheet2: TTabSheet;
GroupBox5: TGroupBox;
edtSearchText: TEdit;
btnSearch: TButton;
ListBox1: TListBox;
CheckBox1: TCheckBox;
btnDates: TButton;
btnFloatsTests: TButton;
btnWithJSON: TButton;
Edit1: TEdit;
Edit2: TEdit;
btnSubtractWithNamedParams: TButton;
Edit3: TEdit;
PageControl2: TPageControl;
TabSheet3: TTabSheet;
TabSheet4: TTabSheet;
edtFilter: TEdit;
edtGetCustomers: TButton;
DBGrid1: TDBGrid;
btnGetMulti: TButton;
lbMulti: TListBox;
btnGenericException: TButton;
TabSheet5: TTabSheet;
Label1: TLabel;
btnException: TButton;
btnGenericExcWithCustomHandling: TButton;
btnGenericExcWithCustomHAndling2: TButton;
btnGenericExcWithoutCustomHandling: TButton;
TabSheet6: TTabSheet;
btnSingleRec: TButton;
lbLogRec: TMemo;
btnGetArrayOfRecords: TButton;
btnGetDynArray: TButton;
btnPassAndGetRecord: TButton;
btnEchoComplexArray: TButton;
btnComplex: TButton;
btnParallel: TButton;
procedure btnSubstractClick(Sender: TObject);
procedure btnReverseStringClick(Sender: TObject);
procedure edtGetCustomersClick(Sender: TObject);
procedure btnGetUserClick(Sender: TObject);
procedure btnSaveClick(Sender: TObject);
procedure btnAddDayClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure btnInvalid1Click(Sender: TObject);
procedure btnInvalid2Click(Sender: TObject);
procedure btnNotificationClick(Sender: TObject);
procedure btnInvalidMethodClick(Sender: TObject);
procedure btnSearchClick(Sender: TObject);
procedure btnDatesClick(Sender: TObject);
procedure btnFloatsTestsClick(Sender: TObject);
procedure btnWithJSONClick(Sender: TObject);
procedure btnSubtractWithNamedParamsClick(Sender: TObject);
procedure btnGetMultiClick(Sender: TObject);
procedure btnGetListOfDatasetClick(Sender: TObject);
procedure btnObjDictClick(Sender: TObject);
procedure btnExceptionClick(Sender: TObject);
procedure btnGenericExceptionClick(Sender: TObject);
procedure btnGenericExcWithCustomHandlingClick(Sender: TObject);
procedure btnGenericExcWithCustomHAndling2Click(Sender: TObject);
procedure btnGenericExcWithoutCustomHandlingClick(Sender: TObject);
procedure btnSingleRecClick(Sender: TObject);
procedure btnGetArrayOfRecordsClick(Sender: TObject);
procedure btnGetDynArrayClick(Sender: TObject);
procedure btnPassAndGetRecordClick(Sender: TObject);
procedure btnEchoComplexArrayClick(Sender: TObject);
procedure btnComplexClick(Sender: TObject);
procedure btnParallelClick(Sender: TObject);
private
FExecutor: IMVCJSONRPCExecutor;
fGeneralErrorHandler : TJSONRPCErrorHandlerProc;
fWaiting: TWaitingForm;
public
{ Public declarations }
end;
var
MainForm: TMainForm;
implementation
uses
System.Generics.Collections,
MVCFramework.JSONRPC,
MVCFramework.Serializer.JsonDataObjects,
JsonDataObjects,
System.UITypes,
MVCFramework.Serializer.Commons,
MVCFramework.Commons,
MVCFramework.Logger,
MVCFramework.Serializer.Defaults,
MVCFramework.DataSet.Utils,
SyncObjs,
BusinessObjectsU,
System.Math,
System.Rtti, CommonTypesU, MVCFramework.AsyncTask;
{$R *.dfm}
procedure TMainForm.btnAddDayClick(Sender: TObject);
var
lReq: IJSONRPCRequest;
begin
lReq := TJSONRPCRequest.Create;
lReq.Method := 'getnextmonday';
lReq.RequestID := Random(1000);
lReq.Params.Add(dtNextMonday.Date);
FExecutor.ExecuteRequestAsync('/jsonrpc', lReq,
procedure(Resp: IJSONRPCResponse)
begin
dtNextMonday.Date := ISODateToDate(Resp.Result.AsString);
end);
end;
procedure TMainForm.btnComplexClick(Sender: TObject);
var
lReq: IJSONRPCRequest;
lComplex: TNestedArraysRec;
begin
lReq := TJSONRPCRequest.Create;
lReq.Method := 'EchoComplexArrayOfRecords2';
lReq.RequestID := Random(1000);
lComplex.TestRecProp := TTestRec.Create(10);
SetLength(lComplex.ArrayProp1, 2);
SetLength(lComplex.ArrayProp2, 2);
lComplex.ArrayProp1[0] := TTestRec.Create(10);
lComplex.ArrayProp1[1] := TTestRec.Create(10);
lComplex.ArrayProp2[0] := TTestRec.Create(10);
lComplex.ArrayProp2[1] := TTestRec.Create(10);
lReq.Params.Add(TValue.From<TNestedArraysRec>(lComplex), pdtRecordOrArrayOfRecord);
FExecutor.ExecuteRequestAsync('/jsonrpc', lReq,
procedure(Resp: IJSONRPCResponse)
begin
lComplex := TJSONUtils.JSONObjectToRecord<TNestedArraysRec>(Resp);
lbLogRec.Lines.Clear;
lbLogRec.Lines.Add(lComplex.ToString);
end,
procedure (Exc: Exception)
begin
ShowMessage(Exc.ClassName + ': ' + Exc.Message);
end);
end;
procedure TMainForm.btnDatesClick(Sender: TObject);
var
lReq: IJSONRPCRequest;
begin
lReq := TJSONRPCRequest.Create(1234, 'playwithdatesandtimes');
lReq.Params.Add(1234.5678, pdtFloat);
lReq.Params.Add(Time(), pdtTime);
lReq.Params.Add(Date(), pdtDate);
lReq.Params.Add(Now(), pdtDateTime);
FExecutor.ExecuteRequestAsync('/jsonrpc', lReq,
procedure(Resp: IJSONRPCResponse)
begin
ShowMessage(Resp.Result.AsString);
end);
end;
procedure TMainForm.btnEchoComplexArrayClick(Sender: TObject);
var
lReq: IJSONRPCRequest;
lPeople: TTestRecDynArray;
I: Integer;
begin
lReq := TJSONRPCRequest.Create;
lReq.Method := 'EchoComplexArrayOfRecords';
lReq.RequestID := Random(1000);
SetLength(lPeople, 2);
lPeople[0] := TTestRec.Create(1);
lPeople[1] := TTestRec.Create(2);
lReq.Params.Add(TValue.From<TTestRecDynArray>(lPeople), pdtRecordOrArrayOfRecord);
FExecutor.ExecuteRequestAsync('/jsonrpc', lReq,
procedure(Resp: IJSONRPCResponse)
begin
lPeople := TJSONUtils.JSONArrayToArrayOfRecord<TTestRec>(Resp);
lbLogRec.Lines.Clear;
lbLogRec.Lines.Add('--- array of record elements ---');
I := 1;
for var lPRec in lPeople do
begin
lbLogRec.Lines.Add('ITEM: ' + I.ToString);
lbLogRec.Lines.Add(lPRec.ToString);
Inc(I);
end;
end);
end;
procedure TMainForm.btnExceptionClick(Sender: TObject);
var
lReq: IJSONRPCNotification;
begin
ShowMessage('Now will be raised a custom exception on the server. This exception will be catched by the client');
lReq := TJSONRPCNotification.Create('RaiseCustomException');
FExecutor.ExecuteNotificationAsync('/jsonrpc', lReq, fGeneralErrorHandler);
end;
procedure TMainForm.btnFloatsTestsClick(Sender: TObject);
var
lReq: IJSONRPCRequest;
lRes: Extended;
begin
lReq := TJSONRPCRequest.Create(1234, 'floatstest');
lReq.Params.Add(1234.5678, pdtFloat);
lReq.Params.Add(2345.6789, pdtFloat);
FExecutor.ExecuteRequestAsync('/jsonrpc', lReq,
procedure(Resp: IJSONRPCResponse)
begin
lRes := Resp.Result.AsType<Extended>;
lRes := RoundTo(lRes, -4);
Assert(SameValue(lRes, 3580.2467), 'Wrong result: ' + FloatToStrF(lRes, ffGeneral, 18, 9));
lReq := TJSONRPCRequest.Create(1234, 'floatstest');
lReq.Params.Add(123);
lReq.Params.Add(234);
FExecutor.ExecuteRequestAsync('/jsonrpc', lReq,
procedure(Resp: IJSONRPCResponse)
var
lRes: Extended;
begin
lRes := Resp.Result.AsType<Extended>;
lRes := RoundTo(lRes, -4);
Assert(SameValue(lRes, 357), 'Wrong result: ' + FloatToStrF(lRes, ffGeneral, 18, 9));
end);
end);
end;
procedure TMainForm.btnGetUserClick(Sender: TObject);
var
lReq: IJSONRPCRequest;
begin
lbPerson.Clear;
lReq := TJSONRPCRequest.Create;
lReq.Method := 'getuser';
lReq.RequestID := Random(1000);
lReq.Params.Add(edtUserName.Text);
FExecutor.ExecuteRequestAsync('/jsonrpc', lReq,
procedure(Resp: IJSONRPCResponse)
var
lJSON: TJsonObject;
begin
// Remember that TObject descendants (but TDataset, TJDOJSONObject and TJDOJSONArray)
// are serialized as JSON objects
lJSON := Resp.Result.AsObject as TJsonObject;
lbPerson.Items.Add('First Name:'.PadRight(15) + lJSON.S['firstname']);
lbPerson.Items.Add('Last Name:'.PadRight(15) + lJSON.S['lastname']);
lbPerson.Items.Add('Married:'.PadRight(15) + lJSON.B['married'].ToString(TUseBoolStrs.True));
lbPerson.Items.Add('DOB:'.PadRight(15) + DateToStr(lJSON.D['dob']));
end);
end;
procedure TMainForm.btnInvalid1Click(Sender: TObject);
var
lReq: IJSONRPCRequest;
begin
lReq := TJSONRPCRequest.Create(1234);
lReq.Method := 'invalidmethod1';
lReq.Params.Add(1);
FExecutor.ExecuteRequestAsync('/jsonrpc', lReq,
procedure(Resp: IJSONRPCResponse)
begin
ShowMessage(Resp.Error.ErrMessage);
end);
end;
procedure TMainForm.btnInvalid2Click(Sender: TObject);
var
lReq: IJSONRPCRequest;
lResp: IJSONRPCResponse;
begin
lReq := TJSONRPCRequest.Create(1234);
lReq.Method := 'invalidmethod2';
lReq.Params.Add(1);
lResp := FExecutor.ExecuteNotification('/jsonrpc', lReq);
ShowMessage(lResp.Error.ErrMessage);
end;
procedure TMainForm.btnInvalidMethodClick(Sender: TObject);
var
lNotification: IJSONRPCNotification;
begin
lNotification := TJSONRPCNotification.Create;
lNotification.Method := 'notexists';
FExecutor.ExecuteNotificationAsync('/jsonrpc', lNotification);
end;
procedure TMainForm.btnNotificationClick(Sender: TObject);
var
lNotification: IJSONRPCNotification;
begin
lNotification := TJSONRPCNotification.Create;
lNotification.Method := 'dosomething';
FExecutor.ExecuteNotificationAsync('/jsonrpc', lNotification);
end;
procedure TMainForm.btnObjDictClick(Sender: TObject);
var
lReq: IJSONRPCRequest;
lResp: IJSONRPCResponse;
lMultiDS: TMultiDataset;
begin
FDMemTable1.Active := False;
lReq := TJSONRPCRequest.Create(Random(1000), 'getobjdict');
FExecutor.ExecuteRequestAsync('/jsonrpc', lReq,
procedure(JSONRPCResponse: IJSONRPCResponse)
begin
lMultiDS := TMultiDataset.Create;
try
JsonObjectToObject(lResp.ResultAsJSONObject, lMultiDS);
lbMulti.Clear;
lMultiDS.Customers.First;
lbMulti.Items.Add('** CUSTOMERS **');
while not lMultiDS.Customers.Eof do
begin
lbMulti.Items.Add(Format('%-20s (Code %3s)', [lMultiDS.Customers.FieldByName('Name').AsString,
lMultiDS.Customers.FieldByName('Code').AsString]));
lMultiDS.Customers.Next;
end;
lMultiDS.People.First;
lbMulti.Items.Add('** PEOPLE **');
while not lMultiDS.People.Eof do
begin
lbMulti.Items.Add(Format('%s %s', [lMultiDS.People.FieldByName('FirstName').AsString,
lMultiDS.People.FieldByName('LastName').AsString]));
lMultiDS.People.Next;
end;
finally
lMultiDS.Free;
end;
end);
end;
procedure TMainForm.btnReverseStringClick(Sender: TObject);
var
lReq: IJSONRPCRequest;
begin
lReq := TJSONRPCRequest.Create;
lReq.Method := 'reversestring';
lReq.RequestID := Random(1000);
lReq.Params.AddByName('aString', edtReverseString.Text);
lReq.Params.AddByName('aUpperCase', CheckBox1.Checked);
FExecutor.ExecuteRequestAsync('/jsonrpc', lReq,
procedure (Resp: IJSONRPCResponse)
begin
edtReversedString.Text := Resp.Result.AsString;
end);
end;
procedure TMainForm.btnSaveClick(Sender: TObject);
var
lPerson: TPerson;
lReq: IJSONRPCRequest;
begin
lReq := TJSONRPCRequest.Create;
lReq.Method := 'saveperson';
lReq.RequestID := Random(1000);
lPerson := TPerson.Create;
lReq.Params.AddByName('Person', lPerson, pdtObject);
lPerson.FirstName := edtFirstName.Text;
lPerson.LastName := edtLastName.Text;
lPerson.Married := chkMarried.Checked;
lPerson.DOB := dtDOB.Date;
FExecutor.ExecuteRequestAsync('/jsonrpc', lReq,
procedure(Resp: IJSONRPCResponse)
begin
ShowMessage('Person saved with ID = ' + Resp.Result.AsInteger.ToString);
end);
end;
procedure TMainForm.btnSearchClick(Sender: TObject);
var
lReq: IJSONRPCRequest;
lJSON: TJsonArray;
lJObj: TJsonObject;
begin
ListBox1.Clear;
lReq := TJSONRPCRequest.Create;
lReq.Method := 'searchproducts';
lReq.RequestID := 1234;
lReq.Params.Add(edtSearchText.Text);
FExecutor.ExecuteRequestAsync('/rpcdatamodule', lReq,
procedure(Resp: IJSONRPCResponse)
var
I: Integer;
begin
// Remember that TObject descendants (but TDataset, TJDOJSONObject and TJDOJSONArray)
// are serialized as JSON objects
lJSON := Resp.Result.AsObject as TJsonArray;
for I := 0 to lJSON.Count - 1 do
begin
lJObj := lJSON[I].ObjectValue;
ListBox1.Items.Add(Format('%6s: %-34s € %5.2f', [lJObj.S['codice'], lJObj.S['descrizione'], lJObj.F['prezzo']]));
end;
end);
end;
procedure TMainForm.btnSingleRecClick(Sender: TObject);
var
lReq: IJSONRPCRequest;
begin
lReq := TJSONRPCRequest.Create;
lReq.Method := 'GetPersonRec';
lReq.RequestID := Random(1000);
FExecutor.ExecuteRequestAsync('/jsonrpc', lReq,
procedure(Resp: IJSONRPCResponse)
var
lPersonRec: TTestRec;
begin
lPersonRec := TJSONUtils.JSONObjectToRecord<TTestRec>(Resp);
lbLogRec.Lines.Text := Resp.ResultAsJSONObject.ToJSON(False);
lbLogRec.Lines.Add('-- record --');
lbLogRec.Lines.Add(lPersonRec.ToString);
end, fGeneralErrorHandler);
end;
procedure TMainForm.btnSubstractClick(Sender: TObject);
var
lReq: IJSONRPCRequest;
begin
lReq := TJSONRPCRequest.Create;
lReq.Method := 'subtract';
lReq.RequestID := Random(1000);
lReq.Params.Add(StrToInt(edtValue1.Text));
lReq.Params.Add(StrToInt(edtValue2.Text));
FExecutor.ExecuteRequestAsync('/jsonrpc', lReq,
procedure(JSONRPCResp: IJSONRPCResponse)
begin
edtResult.Text := JSONRPCResp.Result.AsInteger.ToString;
end);
end;
procedure TMainForm.btnSubtractWithNamedParamsClick(Sender: TObject);
var
lReq: IJSONRPCRequest;
begin
lReq := TJSONRPCRequest.Create;
lReq.Method := 'subtract';
lReq.RequestID := Random(1000);
lReq.Params.AddByName('Value1', StrToInt(Edit1.Text));
lReq.Params.AddByName('Value2', StrToInt(Edit2.Text));
FExecutor.ExecuteRequestAsync('/jsonrpc', lReq,
procedure(Resp: IJSONRPCResponse)
begin
Edit3.Text := Resp.Result.AsInteger.ToString;
end);
end;
procedure TMainForm.btnWithJSONClick(Sender: TObject);
var
lPerson: TJsonObject;
lReq: IJSONRPCRequest;
begin
lReq := TJSONRPCRequest.Create;
lReq.Method := 'SaveObjectWithJSON';
lReq.RequestID := 1234;
lPerson := TJsonObject.Create;
lReq.Params.Add(lPerson, pdTJDOJsonObject);
lPerson.S['StringProp'] := 'Hello World';
lPerson.O['JSONObject'] := TJsonObject.Parse('{"name":"Daniele"}') as TJsonObject;
FExecutor.ExecuteRequestAsync('/jsonrpc', lReq,
procedure(Resp: IJSONRPCResponse)
begin
lPerson := Resp.Result.AsObject as TJsonObject;
ShowMessage(lPerson.ToJSON(False));
end);
end;
procedure TMainForm.btnParallelClick(Sender: TObject);
var
lReq: IJSONRPCRequest;
lThreadCount: Int64;
Val1, Val2, Val3, Val4: String;
begin
lReq := TJSONRPCRequest.Create;
lReq.Method := 'subtract';
lReq.RequestID := Random(1000);
lReq.Params.AddByName('Value1', StrToInt(Edit1.Text));
lReq.Params.AddByName('Value2', StrToInt(Edit2.Text));
lThreadCount := 4;
TThread.CreateAnonymousThread(
procedure
begin
while TInterlocked.Read(lThreadCount) > 0 do
begin
Sleep(100);
end;
TThread.Synchronize(nil,
procedure
begin
ShowMessage(
Val1 + sLineBreak +
Val2 + sLineBreak +
Val3 + sLineBreak +
Val4 + sLineBreak
);
end);
end).Start;
FExecutor.ExecuteRequestAsync('/jsonrpc', lReq,
procedure(Resp: IJSONRPCResponse)
begin
Val1 := Resp.Result.AsInteger.ToString;
TInterlocked.Decrement(lThreadCount);
end);
FExecutor.ExecuteRequestAsync('/jsonrpc', lReq,
procedure(Resp: IJSONRPCResponse)
begin
Val2 := Resp.Result.AsInteger.ToString;
TInterlocked.Decrement(lThreadCount);
end);
FExecutor.ExecuteRequestAsync('/jsonrpc', lReq,
procedure(Resp: IJSONRPCResponse)
begin
Val3 := Resp.Result.AsInteger.ToString;
TInterlocked.Decrement(lThreadCount);
end);
FExecutor.ExecuteRequestAsync('/jsonrpc', lReq,
procedure(Resp: IJSONRPCResponse)
begin
Val4 := Resp.Result.AsInteger.ToString;
TInterlocked.Decrement(lThreadCount);
end);
end;
procedure TMainForm.btnPassAndGetRecordClick(Sender: TObject);
var
lReq: IJSONRPCRequest;
lPersonRec: TTestRec;
begin
lReq := TJSONRPCRequest.Create;
lReq.Method := 'SavePersonRec';
lReq.RequestID := Random(1000);
lPersonRec := TTestRec.Create(2);
lReq.Params.Add(TValue.From<TTestRec>(lPersonRec), pdtRecordOrArrayOfRecord);
FExecutor.ExecuteRequestAsync('/jsonrpc', lReq,
procedure (Resp: IJSONRPCResponse)
var
lResPersonRec: TTestRec;
begin
lResPersonRec := TJSONUtils.JSONObjectToRecord<TTestRec>(Resp);
lbLogRec.Lines.Text := Resp.ResultAsJSONObject.ToJSON(False);
end);
end;
procedure TMainForm.btnGenericExceptionClick(Sender: TObject);
var
lReq: IJSONRPCNotification;
begin
ShowMessage('Now will be raised a EDivByZero exception on the server. This exception will be catched by the client');
lReq := TJSONRPCRequest.Create(1234, 'RaiseGenericException');
FExecutor.ExecuteNotificationAsync('/jsonrpc', lReq);
end;
procedure TMainForm.btnGenericExcWithCustomHAndling2Click(Sender: TObject);
var
lReq: IJSONRPCRequest;
begin
ShowMessage
('Now will be raised a EInvalidPointerOperation exception on the server. However this exception will be handled by a custom exception handler wich will add a data property with extra data');
lReq := TJSONRPCRequest.Create(1234, 'RaiseGenericException');
lReq.Params.Add(2);
FExecutor.ExecuteRequestAsync('/jsonrpcex', lReq, nil);
end;
procedure TMainForm.btnGenericExcWithCustomHandlingClick(Sender: TObject);
var
lReq: IJSONRPCRequest;
begin
ShowMessage
('Now will be raised a EDivByZero exception on the server. However this exception will be handled by a custom exception handler wich will add a data property with extra data');
lReq := TJSONRPCRequest.Create(1234, 'RaiseGenericException');
lReq.Params.Add(1);
FExecutor.ExecuteRequestAsync('/jsonrpcex', lReq, nil);
end;
procedure TMainForm.btnGenericExcWithoutCustomHandlingClick(Sender: TObject);
var
lReq: IJSONRPCRequest;
begin
ShowMessage('Now will be raised a Exception exception on the server.');
lReq := TJSONRPCRequest.Create(1234, 'RaiseGenericException');
lReq.Params.Add(99);
FExecutor.ExecuteRequestAsync('/jsonrpcex', lReq, nil, fGeneralErrorHandler);
end;
procedure TMainForm.btnGetArrayOfRecordsClick(Sender: TObject);
var
lReq: IJSONRPCRequest;
lPeopleRec: TArray<TTestRec>; // server serializes a static array, we read it as dynarray
I: Integer;
begin
lReq := TJSONRPCRequest.Create;
lReq.Method := 'GetPeopleRecStaticArray';
lReq.RequestID := Random(1000);
FExecutor.ExecuteRequestAsync('/jsonrpc', lReq,
procedure(Resp: IJSONRPCResponse)
begin
lPeopleRec := TJSONUtils.JSONArrayToArrayOfRecord<TTestRec>(Resp);
lbLogRec.Lines.Text := Resp.ResultAsJSONArray.ToJSON(False);
lbLogRec.Lines.Add('-- array of record elements --');
I := 1;
for var lPRec in lPeopleRec do
begin
lbLogRec.Lines.Add('ITEM : ' + I.ToString);
lbLogRec.Lines.Add(lPRec.ToString);
Inc(I);
end;
end, fGeneralErrorHandler);
end;
procedure TMainForm.btnGetDynArrayClick(Sender: TObject);
var
lReq: IJSONRPCRequest;
begin
lReq := TJSONRPCRequest.Create;
lReq.Method := 'GetPeopleRecDynArray';
lReq.RequestID := Random(1000);
FExecutor.ExecuteRequestAsync('/jsonrpc', lReq,
procedure(Resp: IJSONRPCResponse)
var
lPeopleRec : TArray<TTestRec>;
begin
lPeopleRec := TJSONUtils.JSONArrayToArrayOfRecord<TTestRec>(Resp);
lbLogRec.Lines.Text := Resp.ResultAsJSONArray.ToJSON(False);
end, fGeneralErrorHandler);
end;
procedure TMainForm.btnGetListOfDatasetClick(Sender: TObject);
var
lReq: IJSONRPCRequest;
begin
FDMemTable1.Active := False;
lReq := TJSONRPCRequest.Create(Random(1000), 'GetDataSetList');
FExecutor.ExecuteRequestAsync('/jsonrpc', lReq,
procedure(Resp: IJSONRPCResponse)
var
lMultiDS: TObjectList<TDataSet>;
begin
lMultiDS := TObjectList<TDataSet>.Create(True);
try
JsonArrayToList(Resp.ResultAsJSONArray, WrapAsList(lMultiDS), TDataSet, TMVCSerializationType.stDefault, nil);
finally
lMultiDS.Free;
end;
end);
end;
procedure TMainForm.btnGetMultiClick(Sender: TObject);
var
lReq: IJSONRPCRequest;
begin
FDMemTable1.Active := False;
lReq := TJSONRPCRequest.Create(Random(1000), 'getmulti');
FExecutor.ExecuteRequestAsync('/jsonrpc', lReq,
procedure(Resp: IJSONRPCResponse)
var
lMultiDS: TMultiDataset;
begin
lMultiDS := TMultiDataset.Create;
try
JsonObjectToObject(Resp.ResultAsJSONObject, lMultiDS);
lbMulti.Clear;
lMultiDS.Customers.First;
lbMulti.Items.Add('** CUSTOMERS **');
while not lMultiDS.Customers.Eof do
begin
lbMulti.Items.Add(Format('%-20s (Code %3s)', [lMultiDS.Customers.FieldByName('Name').AsString,
lMultiDS.Customers.FieldByName('Code').AsString]));
lMultiDS.Customers.Next;
end;
lMultiDS.People.First;
lbMulti.Items.Add('** PEOPLE **');
while not lMultiDS.People.Eof do
begin
lbMulti.Items.Add(Format('%s %s', [lMultiDS.People.FieldByName('FirstName').AsString,
lMultiDS.People.FieldByName('LastName').AsString]));
lMultiDS.People.Next;
end;
finally
lMultiDS.Free;
end;
end,
nil,
jrpcGET);
end;
procedure TMainForm.edtGetCustomersClick(Sender: TObject);
var
lReq: IJSONRPCRequest;
begin
FDMemTable1.Active := False;
lReq := TJSONRPCRequest.Create(Random(1000), 'getcustomers');
lReq.Params.AddByName('FilterString', edtFilter.Text);
FExecutor.ExecuteRequestAsync('/jsonrpc', lReq,
procedure(Resp: IJSONRPCResponse)
begin
FDMemTable1.Active := True;
FDMemTable1.LoadFromTValue(Resp.Result);
FDMemTable1.First;
end,
procedure(Exc: Exception)
begin
ShowMessage(Exc.ClassName + ': ' + Exc.Message);
end,
jrpcGET);
end;
procedure TMainForm.FormCreate(Sender: TObject);
const
SIMULATE_SLOW_NETWORK = False;
begin
FExecutor := TMVCJSONRPCExecutor.Create('http://localhost:8080');
FExecutor.SetOnSendCommandAsync(
procedure(JSONRPCObject: IJSONRPCObject)
begin
if SIMULATE_SLOW_NETWORK then
begin
Sleep(1000 + Random(3000));
end;
Log.Debug('REQUEST : ' + JSONRPCObject.ToString(True), 'jsonrpc');
end);
FExecutor.SetOnReceiveResponseAsync(
procedure(Req, Resp: IJSONRPCObject)
begin
Log.Debug('>> OnReceiveResponse // start', 'jsonrpc');
Log.Debug(' REQUEST : ' + Req.ToString(True), 'jsonrpc');
Log.Debug(' RESPONSE: ' + Resp.ToString(True), 'jsonrpc');
Log.Debug('<< OnReceiveResponse // end', 'jsonrpc');
end);
FExecutor.SetOnReceiveHTTPResponseAsync(
procedure(HTTPResp: IHTTPResponse)
begin
Log.Debug('RESPONSE: ' + HTTPResp.ContentAsString(), 'jsonrpc');
end);
dtNextMonday.Date := Date;
// these are the methods to handle http headers in JSONRPC
// the following line and the check on the server is just for demo
Assert(FExecutor.HTTPHeadersCount = 0);
FExecutor.AddHTTPHeader(TNetHeader.Create('x-token', TGUID.NewGuid.ToString));
Assert(FExecutor.HTTPHeadersCount = 1);
FExecutor.ClearHTTPHeaders;
Assert(FExecutor.HTTPHeadersCount = 0);
FExecutor.AddHTTPHeader(TNetHeader.Create('x-token', TGUID.NewGuid.ToString));
PageControl1.ActivePageIndex := 0;
fGeneralErrorHandler := procedure(Exc: Exception)
begin
ShowMessage(Exc.ClassName + ': ' + Exc.Message);
end;
fWaiting := TWaitingForm.Create(Self);
fWaiting.PopupParent := Self;
FExecutor.SetOnBeginAsyncRequest(
procedure
begin
fWaiting.IncreaseWaitingCount;
end);
FExecutor.SetOnEndAsyncRequest(
procedure
begin
fWaiting.DecreaseWaitingCount;
end);
end;
end.

View File

@ -0,0 +1,69 @@
object WaitingForm: TWaitingForm
Left = 0
Top = 0
BorderIcons = []
BorderStyle = bsNone
ClientHeight = 149
ClientWidth = 616
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -12
Font.Name = 'Segoe UI'
Font.Style = []
PopupMode = pmAuto
Position = poOwnerFormCenter
OnDestroy = FormDestroy
TextHeight = 15
object Shape1: TShape
Left = 0
Top = 0
Width = 616
Height = 149
Align = alClient
Pen.Color = clSilver
Pen.Style = psInsideFrame
ExplicitLeft = 256
ExplicitTop = 56
ExplicitWidth = 65
ExplicitHeight = 65
end
object lblMessage: TLabel
Left = 0
Top = 0
Width = 616
Height = 149
Align = alClient
Alignment = taCenter
Caption = 'Please wait'
Font.Charset = DEFAULT_CHARSET
Font.Color = clGray
Font.Height = -32
Font.Name = 'Segoe UI Light'
Font.Style = []
ParentFont = False
Layout = tlCenter
ExplicitWidth = 148
ExplicitHeight = 45
end
object lblRunningRequests: TLabel
Left = 8
Top = 126
Width = 92
Height = 15
Caption = 'Running requests'
Font.Charset = DEFAULT_CHARSET
Font.Color = clGray
Font.Height = -12
Font.Name = 'Segoe UI'
Font.Style = []
ParentFont = False
end
object TimerWaiting: TTimer
Enabled = False
Interval = 900
OnTimer = TimerWaitingTimer
Left = 56
Top = 40
end
end

View File

@ -0,0 +1,88 @@
unit WaitingFormU;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls;
type
TWaitingForm = class(TForm)
lblMessage: TLabel;
Shape1: TShape;
lblRunningRequests: TLabel;
TimerWaiting: TTimer;
procedure TimerWaitingTimer(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
FWaitingCount: Integer;
fPoints: Integer;
procedure SetWaitingCount(const Value: Integer);
{ Private declarations }
public
property WaitingCount: Integer read FWaitingCount write SetWaitingCount;
procedure IncreaseWaitingCount;
procedure DecreaseWaitingCount;
end;
implementation
uses
System.Math, System.StrUtils;
{$R *.dfm}
{ TWaitingForm }
procedure TWaitingForm.DecreaseWaitingCount;
begin
WaitingCount := WaitingCount - 1;
end;
procedure TWaitingForm.FormDestroy(Sender: TObject);
begin
Screen.Cursor := crDefault;
end;
procedure TWaitingForm.IncreaseWaitingCount;
begin
WaitingCount := WaitingCount + 1;
end;
procedure TWaitingForm.SetWaitingCount(const Value: Integer);
begin
FWaitingCount := Max(0, Value);
if FWaitingCount = 0 then
begin
TimerWaiting.Enabled := False;
Hide;
Screen.Cursor := crDefault;
end
else
begin
if not Visible then
begin
Screen.Cursor := crHourGlass;
fPoints := 0;
TimerWaiting.Enabled := True;
Show;
end;
lblRunningRequests.Caption := FWaitingCount.ToString + ' running request' + ifthen(FWaitingCount > 1, 's');
lblRunningRequests.Update;
end;
end;
procedure TWaitingForm.TimerWaitingTimer(Sender: TObject);
begin
if fPoints = 3 then
begin
fPoints := 0;
end
else
begin
Inc(fPoints);
end;
lblMessage.Caption := 'Please wait' + StringOfChar('.', fPoints);
end;
end.

View File

@ -1,12 +1,12 @@
program jsonrpcclientwithobjects;
program jsonrpcclientwithobjects_async;
uses
Vcl.Forms,
MainClientFormU in 'MainClientFormU.pas' {MainForm},
MVCFramework.JSONRPC.Client in '..\..\sources\MVCFramework.JSONRPC.Client.pas',
RandomUtilsU in '..\commons\RandomUtilsU.pas',
BusinessObjectsU in '..\commons\BusinessObjectsU.pas',
CommonTypesU in 'CommonTypesU.pas';
RandomUtilsU in '..\..\commons\RandomUtilsU.pas',
BusinessObjectsU in '..\..\commons\BusinessObjectsU.pas',
CommonTypesU in '..\CommonTypesU.pas',
WaitingFormU in 'WaitingFormU.pas' {WaitingForm};
{$R *.res}

View File

@ -0,0 +1,981 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{192C33A7-36AC-4357-8D52-AE88D4C974E7}</ProjectGuid>
<ProjectVersion>19.5</ProjectVersion>
<FrameworkType>VCL</FrameworkType>
<Base>True</Base>
<Config Condition="'$(Config)'==''">Debug</Config>
<Platform Condition="'$(Platform)'==''">Win32</Platform>
<TargetedPlatforms>1</TargetedPlatforms>
<AppType>Application</AppType>
<MainSource>jsonrpcclientwithobjects_async.dpr</MainSource>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
<Base_Win32>true</Base_Win32>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Base)'=='true') or '$(Base_Win64)'!=''">
<Base_Win64>true</Base_Win64>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_1)'!=''">
<Cfg_1>true</Cfg_1>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_1)'=='true') or '$(Cfg_1_Win32)'!=''">
<Cfg_1_Win32>true</Cfg_1_Win32>
<CfgParent>Cfg_1</CfgParent>
<Cfg_1>true</Cfg_1>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_2)'!=''">
<Cfg_2>true</Cfg_2>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_2)'=='true') or '$(Cfg_2_Win32)'!=''">
<Cfg_2_Win32>true</Cfg_2_Win32>
<CfgParent>Cfg_2</CfgParent>
<Cfg_2>true</Cfg_2>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Base)'!=''">
<DCC_DcuOutput>.\$(Platform)\$(Config)</DCC_DcuOutput>
<DCC_ExeOutput>..\bin</DCC_ExeOutput>
<DCC_E>false</DCC_E>
<DCC_N>false</DCC_N>
<DCC_S>false</DCC_S>
<DCC_F>false</DCC_F>
<DCC_K>false</DCC_K>
<DCC_Namespace>System;Xml;Data;Datasnap;Web;Soap;Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;$(DCC_Namespace)</DCC_Namespace>
<Icon_MainIcon>$(BDS)\bin\delphi_PROJECTICON.ico</Icon_MainIcon>
<UWP_DelphiLogo44>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png</UWP_DelphiLogo44>
<UWP_DelphiLogo150>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png</UWP_DelphiLogo150>
<SanitizedProjectName>jsonrpcclientwithobjects_async</SanitizedProjectName>
<VerInfo_Locale>1040</VerInfo_Locale>
<VerInfo_Keys>CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win32)'!=''">
<DCC_UsePackage>RaizeComponentsVcl;vclwinx;DataSnapServer;fmx;emshosting;vclie;DbxCommonDriver;bindengine;IndyIPCommon;VCLRESTComponents;DBXMSSQLDriver;FireDACCommonODBC;emsclient;FireDACCommonDriver;appanalytics;IndyProtocols;vclx;IndyIPClient;dbxcds;vcledge;bindcompvclwinx;FmxTeeUI;emsedge;bindcompfmx;DBXFirebirdDriver;inetdb;ibmonitor;FireDACSqliteDriver;DbxClientDriver;FireDACASADriver;Tee;soapmidas;SVGIconImageListFMX;vclactnband;TeeUI;fmxFireDAC;dbexpress;Python;FireDACInfxDriver;DBXMySQLDriver;VclSmp;inet;DataSnapCommon;PythonVcl;vcltouch;fmxase;DBXOdbcDriver;dbrtl;FireDACDBXDriver;FireDACOracleDriver;fmxdae;TeeDB;FireDACMSAccDriver;CustomIPTransport;FireDACMSSQLDriver;SVGIconPackage;DataSnapIndy10ServerTransport;DataSnapConnectors;vcldsnap;DBXInterBaseDriver;FireDACMongoDBDriver;IndySystem;FireDACTDataDriver;vcldb;ibxbindings;SynEditDR;vclFireDAC;bindcomp;FireDACCommon;DataSnapServerMidas;FireDACODBCDriver;emsserverresource;IndyCore;RESTBackendComponents;dmvcframeworkDT;bindcompdbx;rtl;FireDACMySQLDriver;FireDACADSDriver;RaizeComponentsVclDb;RESTComponents;DBXSqliteDriver;vcl;IndyIPServer;dsnapxml;dsnapcon;DataSnapClient;DataSnapProviderClient;adortl;DBXSybaseASEDriver;LockBoxDR;DBXDb2Driver;vclimg;DataSnapFireDAC;emsclientfiredac;FireDACPgDriver;FireDAC;FireDACDSDriver;inetdbxpress;xmlrtl;tethering;dmvcframeworkRT;ibxpress;bindcompvcl;dsnap;CloudService;DBXSybaseASADriver;DBXOracleDriver;FireDACDb2Driver;DBXInformixDriver;vclib;fmxobj;bindcompvclsmp;FMXTee;DataSnapNativeClient;PythonFmx;DatasnapConnectorsFreePascal;soaprtl;SVGIconImageList;soapserver;FireDACIBDriver;$(DCC_UsePackage)</DCC_UsePackage>
<DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
<BT_BuildType>Debug</BT_BuildType>
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
<VerInfo_Keys>CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
<VerInfo_Locale>1033</VerInfo_Locale>
<Manifest_File>$(BDS)\bin\default_app.manifest</Manifest_File>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win64)'!=''">
<DCC_UsePackage>RaizeComponentsVcl;vclwinx;DataSnapServer;fmx;emshosting;vclie;DbxCommonDriver;bindengine;IndyIPCommon;VCLRESTComponents;DBXMSSQLDriver;FireDACCommonODBC;emsclient;FireDACCommonDriver;appanalytics;IndyProtocols;vclx;IndyIPClient;dbxcds;vcledge;bindcompvclwinx;FmxTeeUI;emsedge;bindcompfmx;DBXFirebirdDriver;inetdb;ibmonitor;FireDACSqliteDriver;DbxClientDriver;FireDACASADriver;Tee;soapmidas;SVGIconImageListFMX;vclactnband;TeeUI;fmxFireDAC;dbexpress;Python;FireDACInfxDriver;DBXMySQLDriver;VclSmp;inet;DataSnapCommon;PythonVcl;vcltouch;fmxase;DBXOdbcDriver;dbrtl;FireDACDBXDriver;FireDACOracleDriver;fmxdae;TeeDB;FireDACMSAccDriver;CustomIPTransport;FireDACMSSQLDriver;SVGIconPackage;DataSnapIndy10ServerTransport;DataSnapConnectors;vcldsnap;DBXInterBaseDriver;FireDACMongoDBDriver;IndySystem;FireDACTDataDriver;vcldb;ibxbindings;SynEditDR;vclFireDAC;bindcomp;FireDACCommon;DataSnapServerMidas;FireDACODBCDriver;emsserverresource;IndyCore;RESTBackendComponents;bindcompdbx;rtl;FireDACMySQLDriver;FireDACADSDriver;RaizeComponentsVclDb;RESTComponents;DBXSqliteDriver;vcl;IndyIPServer;dsnapxml;dsnapcon;DataSnapClient;DataSnapProviderClient;adortl;DBXSybaseASEDriver;LockBoxDR;DBXDb2Driver;vclimg;DataSnapFireDAC;emsclientfiredac;FireDACPgDriver;FireDAC;FireDACDSDriver;inetdbxpress;xmlrtl;tethering;ibxpress;bindcompvcl;dsnap;CloudService;DBXSybaseASADriver;DBXOracleDriver;FireDACDb2Driver;DBXInformixDriver;vclib;fmxobj;bindcompvclsmp;FMXTee;DataSnapNativeClient;PythonFmx;DatasnapConnectorsFreePascal;soaprtl;SVGIconImageList;soapserver;FireDACIBDriver;$(DCC_UsePackage)</DCC_UsePackage>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1)'!=''">
<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
<DCC_DebugDCUs>true</DCC_DebugDCUs>
<DCC_Optimize>false</DCC_Optimize>
<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
<DCC_DebugInfoInExe>true</DCC_DebugInfoInExe>
<DCC_RemoteDebug>true</DCC_RemoteDebug>
<DCC_IntegerOverflowCheck>true</DCC_IntegerOverflowCheck>
<DCC_RangeChecking>true</DCC_RangeChecking>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1_Win32)'!=''">
<DCC_RemoteDebug>false</DCC_RemoteDebug>
<AppDPIAwarenessMode>PerMonitorV2</AppDPIAwarenessMode>
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
<VerInfo_Locale>1033</VerInfo_Locale>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2)'!=''">
<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
<DCC_DebugInformation>0</DCC_DebugInformation>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2_Win32)'!=''">
<AppDPIAwarenessMode>PerMonitorV2</AppDPIAwarenessMode>
</PropertyGroup>
<ItemGroup>
<DelphiCompile Include="$(MainSource)">
<MainSource>MainSource</MainSource>
</DelphiCompile>
<DCCReference Include="MainClientFormU.pas">
<Form>MainForm</Form>
<FormType>dfm</FormType>
</DCCReference>
<DCCReference Include="..\..\commons\RandomUtilsU.pas"/>
<DCCReference Include="..\..\commons\BusinessObjectsU.pas"/>
<DCCReference Include="..\CommonTypesU.pas"/>
<DCCReference Include="WaitingFormU.pas">
<Form>WaitingForm</Form>
<FormType>dfm</FormType>
</DCCReference>
<BuildConfiguration Include="Base">
<Key>Base</Key>
</BuildConfiguration>
<BuildConfiguration Include="Debug">
<Key>Cfg_1</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
<BuildConfiguration Include="Release">
<Key>Cfg_2</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
</ItemGroup>
<ProjectExtensions>
<Borland.Personality>Delphi.Personality.12</Borland.Personality>
<Borland.ProjectType>Application</Borland.ProjectType>
<BorlandProject>
<Delphi.Personality>
<Source>
<Source Name="MainSource">jsonrpcclientwithobjects_async.dpr</Source>
</Source>
<Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dcloffice2k280.bpl">Microsoft Office 2000 Sample Automation Server Wrapper Components</Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dclofficexp280.bpl">Microsoft Office XP Sample Automation Server Wrapper Components</Excluded_Packages>
</Excluded_Packages>
</Delphi.Personality>
<Deployment Version="4">
<DeployFile LocalName="Win32\Debug\jsonrpcclientwithobjects_async.exe" Configuration="Debug" Class="ProjectOutput">
<Platform Name="Win32">
<RemoteName>jsonrpcclientwithobjects_async.exe</RemoteName>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployClass Name="AdditionalDebugSymbols">
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
<Platform Name="OSX32">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidClasses">
<Platform Name="Android">
<RemoteDir>classes</RemoteDir>
<Operation>64</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>classes</RemoteDir>
<Operation>64</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidFileProvider">
<Platform Name="Android">
<RemoteDir>res\xml</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\xml</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidGDBServer">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidLibnativeArmeabiFile">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>library\lib\armeabi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidLibnativeArmeabiv7aFile">
<Platform Name="Android64">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidLibnativeMipsFile">
<Platform Name="Android">
<RemoteDir>library\lib\mips</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>library\lib\mips</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidServiceOutput">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>library\lib\arm64-v8a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidServiceOutput_Android32">
<Platform Name="Android64">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidSplashImageDef">
<Platform Name="Android">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidSplashStyles">
<Platform Name="Android">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidSplashStylesV21">
<Platform Name="Android">
<RemoteDir>res\values-v21</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\values-v21</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_Colors">
<Platform Name="Android">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_DefaultAppIcon">
<Platform Name="Android">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon144">
<Platform Name="Android">
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon192">
<Platform Name="Android">
<RemoteDir>res\drawable-xxxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xxxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon36">
<Platform Name="Android">
<RemoteDir>res\drawable-ldpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-ldpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon48">
<Platform Name="Android">
<RemoteDir>res\drawable-mdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-mdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon72">
<Platform Name="Android">
<RemoteDir>res\drawable-hdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-hdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon96">
<Platform Name="Android">
<RemoteDir>res\drawable-xhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon24">
<Platform Name="Android">
<RemoteDir>res\drawable-mdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-mdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon36">
<Platform Name="Android">
<RemoteDir>res\drawable-hdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-hdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon48">
<Platform Name="Android">
<RemoteDir>res\drawable-xhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon72">
<Platform Name="Android">
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon96">
<Platform Name="Android">
<RemoteDir>res\drawable-xxxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xxxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage426">
<Platform Name="Android">
<RemoteDir>res\drawable-small</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-small</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage470">
<Platform Name="Android">
<RemoteDir>res\drawable-normal</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-normal</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage640">
<Platform Name="Android">
<RemoteDir>res\drawable-large</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-large</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage960">
<Platform Name="Android">
<RemoteDir>res\drawable-xlarge</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xlarge</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_Strings">
<Platform Name="Android">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="DebugSymbols">
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
<Platform Name="OSX32">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="DependencyFramework">
<Platform Name="OSX32">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
<Extensions>.framework</Extensions>
</Platform>
<Platform Name="OSX64">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
<Extensions>.framework</Extensions>
</Platform>
<Platform Name="OSXARM64">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
<Extensions>.framework</Extensions>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="DependencyModule">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="iOSSimARM64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSX32">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSX64">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSXARM64">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
<Extensions>.dll;.bpl</Extensions>
</Platform>
</DeployClass>
<DeployClass Required="true" Name="DependencyPackage">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="iOSSimARM64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSX32">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSX64">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSXARM64">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
<Extensions>.bpl</Extensions>
</Platform>
</DeployClass>
<DeployClass Name="File">
<Platform Name="Android">
<Operation>0</Operation>
</Platform>
<Platform Name="Android64">
<Operation>0</Operation>
</Platform>
<Platform Name="iOSDevice32">
<Operation>0</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>0</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<Operation>0</Operation>
</Platform>
<Platform Name="OSX32">
<RemoteDir>Contents\Resources\StartUp\</RemoteDir>
<Operation>0</Operation>
</Platform>
<Platform Name="OSX64">
<RemoteDir>Contents\Resources\StartUp\</RemoteDir>
<Operation>0</Operation>
</Platform>
<Platform Name="OSXARM64">
<RemoteDir>Contents\Resources\StartUp\</RemoteDir>
<Operation>0</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iOS_AppStore1024">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_AppIcon152">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_AppIcon167">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch2x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_LaunchDark2x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Notification40">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Setting58">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_SpotLight80">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_AppIcon120">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_AppIcon180">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch2x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch3x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_LaunchDark2x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_LaunchDark3x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Notification40">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Notification60">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Setting58">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Setting87">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Spotlight120">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Spotlight80">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectAndroidManifest">
<Platform Name="Android">
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSDeviceDebug">
<Platform Name="iOSDevice32">
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSEntitlements">
<Platform Name="iOSDevice32">
<RemoteDir>..\</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<RemoteDir>..\</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSInfoPList">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSLaunchScreen">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen</RemoteDir>
<Operation>64</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen</RemoteDir>
<Operation>64</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSResource">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectOSXDebug">
<Platform Name="OSX64">
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="OSXARM64">
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectOSXEntitlements">
<Platform Name="OSX32">
<RemoteDir>..\</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="OSX64">
<RemoteDir>..\</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="OSXARM64">
<RemoteDir>..\</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectOSXInfoPList">
<Platform Name="OSX32">
<RemoteDir>Contents</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="OSX64">
<RemoteDir>Contents</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="OSXARM64">
<RemoteDir>Contents</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectOSXResource">
<Platform Name="OSX32">
<RemoteDir>Contents\Resources</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="OSX64">
<RemoteDir>Contents\Resources</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="OSXARM64">
<RemoteDir>Contents\Resources</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Required="true" Name="ProjectOutput">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>library\lib\arm64-v8a</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<Operation>1</Operation>
</Platform>
<Platform Name="Linux64">
<Operation>1</Operation>
</Platform>
<Platform Name="OSX32">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="OSX64">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="OSXARM64">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectOutput_Android32">
<Platform Name="Android64">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectUWPManifest">
<Platform Name="Win32">
<Operation>1</Operation>
</Platform>
<Platform Name="Win64">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="UWP_DelphiLogo150">
<Platform Name="Win32">
<RemoteDir>Assets</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Win64">
<RemoteDir>Assets</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="UWP_DelphiLogo44">
<Platform Name="Win32">
<RemoteDir>Assets</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Win64">
<RemoteDir>Assets</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<ProjectRoot Platform="Android" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="Android64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="iOSDevice32" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="iOSDevice64" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="iOSSimARM64" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="Linux64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="OSX32" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="OSX64" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="OSXARM64" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="Win32" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="Win64" Name="$(PROJECTNAME)"/>
</Deployment>
<Platforms>
<Platform value="Win32">True</Platform>
<Platform value="Win64">False</Platform>
</Platforms>
</BorlandProject>
<ProjectFileVersion>12</ProjectFileVersion>
</ProjectExtensions>
<Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/>
<Import Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj" Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')"/>
<Import Project="$(MSBuildProjectName).deployproj" Condition="Exists('$(MSBuildProjectName).deployproj')"/>
</Project>

View File

@ -3,10 +3,13 @@
<ProjectGuid>{AFDF54C5-5184-4A5F-A230-FB7F37B3B2F0}</ProjectGuid>
</PropertyGroup>
<ItemGroup>
<Projects Include="jsonrpcserverwithobjects.dproj">
<Projects Include="jsonrpcserver\jsonrpcserverwithobjects.dproj">
<Dependencies/>
</Projects>
<Projects Include="jsonrpcclientwithobjects.dproj">
<Projects Include="sync_client\jsonrpcclientwithobjects_sync.dproj">
<Dependencies/>
</Projects>
<Projects Include="async_client\jsonrpcclientwithobjects_async.dproj">
<Dependencies/>
</Projects>
</ItemGroup>
@ -18,31 +21,40 @@
</BorlandProject>
</ProjectExtensions>
<Target Name="jsonrpcserverwithobjects">
<MSBuild Projects="jsonrpcserverwithobjects.dproj"/>
<MSBuild Projects="jsonrpcserver\jsonrpcserverwithobjects.dproj"/>
</Target>
<Target Name="jsonrpcserverwithobjects:Clean">
<MSBuild Projects="jsonrpcserverwithobjects.dproj" Targets="Clean"/>
<MSBuild Projects="jsonrpcserver\jsonrpcserverwithobjects.dproj" Targets="Clean"/>
</Target>
<Target Name="jsonrpcserverwithobjects:Make">
<MSBuild Projects="jsonrpcserverwithobjects.dproj" Targets="Make"/>
<MSBuild Projects="jsonrpcserver\jsonrpcserverwithobjects.dproj" Targets="Make"/>
</Target>
<Target Name="jsonrpcclientwithobjects">
<MSBuild Projects="jsonrpcclientwithobjects.dproj"/>
<Target Name="jsonrpcclientwithobjects_sync">
<MSBuild Projects="sync_client\jsonrpcclientwithobjects_sync.dproj"/>
</Target>
<Target Name="jsonrpcclientwithobjects:Clean">
<MSBuild Projects="jsonrpcclientwithobjects.dproj" Targets="Clean"/>
<Target Name="jsonrpcclientwithobjects_sync:Clean">
<MSBuild Projects="sync_client\jsonrpcclientwithobjects_sync.dproj" Targets="Clean"/>
</Target>
<Target Name="jsonrpcclientwithobjects:Make">
<MSBuild Projects="jsonrpcclientwithobjects.dproj" Targets="Make"/>
<Target Name="jsonrpcclientwithobjects_sync:Make">
<MSBuild Projects="sync_client\jsonrpcclientwithobjects_sync.dproj" Targets="Make"/>
</Target>
<Target Name="jsonrpcclientwithobjects_async">
<MSBuild Projects="async_client\jsonrpcclientwithobjects_async.dproj"/>
</Target>
<Target Name="jsonrpcclientwithobjects_async:Clean">
<MSBuild Projects="async_client\jsonrpcclientwithobjects_async.dproj" Targets="Clean"/>
</Target>
<Target Name="jsonrpcclientwithobjects_async:Make">
<MSBuild Projects="async_client\jsonrpcclientwithobjects_async.dproj" Targets="Make"/>
</Target>
<Target Name="Build">
<CallTarget Targets="jsonrpcserverwithobjects;jsonrpcclientwithobjects"/>
<CallTarget Targets="jsonrpcserverwithobjects;jsonrpcclientwithobjects_sync;jsonrpcclientwithobjects_async"/>
</Target>
<Target Name="Clean">
<CallTarget Targets="jsonrpcserverwithobjects:Clean;jsonrpcclientwithobjects:Clean"/>
<CallTarget Targets="jsonrpcserverwithobjects:Clean;jsonrpcclientwithobjects_sync:Clean;jsonrpcclientwithobjects_async:Clean"/>
</Target>
<Target Name="Make">
<CallTarget Targets="jsonrpcserverwithobjects:Make;jsonrpcclientwithobjects:Make"/>
<CallTarget Targets="jsonrpcserverwithobjects:Make;jsonrpcclientwithobjects_sync:Make;jsonrpcclientwithobjects_async:Make"/>
</Target>
<Import Project="$(BDS)\Bin\CodeGear.Group.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Group.Targets')"/>
</Project>

View File

@ -15,11 +15,10 @@ uses
MVCFramework.Signal,
MyObjectU in 'MyObjectU.pas',
MainWebModuleU in 'MainWebModuleU.pas' {MyWebModule: TWebModule},
MVCFramework.JSONRPC in '..\..\sources\MVCFramework.JSONRPC.pas',
BusinessObjectsU in '..\commons\BusinessObjectsU.pas',
RandomUtilsU in '..\commons\RandomUtilsU.pas',
MainDM in '..\articles_crud_server\MainDM.pas' {dmMain: TDataModule},
CommonTypesU in 'CommonTypesU.pas';
BusinessObjectsU in '..\..\commons\BusinessObjectsU.pas',
RandomUtilsU in '..\..\commons\RandomUtilsU.pas',
MainDM in '..\..\articles_crud_server\MainDM.pas' {dmMain: TDataModule},
CommonTypesU in '..\CommonTypesU.pas';
{$R *.res}

View File

@ -1,7 +1,7 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{AF5FBC36-0D1D-4C07-B2E3-C2A2E688AC6F}</ProjectGuid>
<ProjectVersion>19.4</ProjectVersion>
<ProjectVersion>19.5</ProjectVersion>
<FrameworkType>VCL</FrameworkType>
<MainSource>jsonrpcserverwithobjects.dpr</MainSource>
<Base>True</Base>
@ -54,9 +54,14 @@
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_2)'=='true') or '$(Cfg_2_Win32)'!=''">
<Cfg_2_Win32>true</Cfg_2_Win32>
<CfgParent>Cfg_2</CfgParent>
<Cfg_2>true</Cfg_2>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Base)'!=''">
<DCC_DcuOutput>.\$(Platform)\$(Config)</DCC_DcuOutput>
<DCC_ExeOutput>.\$(Platform)\$(Config)</DCC_ExeOutput>
<DCC_E>false</DCC_E>
<DCC_N>false</DCC_N>
<DCC_S>false</DCC_S>
@ -71,6 +76,8 @@
<DCC_Framework>VCL;$(DCC_Framework)</DCC_Framework>
<SanitizedProjectName>jsonrpcserverwithobjects</SanitizedProjectName>
<VerInfo_Locale>1040</VerInfo_Locale>
<DCC_ExeOutput>..\bin</DCC_ExeOutput>
<VerInfo_Keys>CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Android)'!=''">
<DCC_UsePackage>DBXSqliteDriver;DBXInterBaseDriver;tethering;bindcompfmx;FmxTeeUI;fmx;FireDACDBXDriver;dbexpress;IndyCore;dsnap;DataSnapCommon;bindengine;DataSnapClient;IndyIPCommon;bindcompdbx;IndyIPServer;IndySystem;fmxFireDAC;ibmonitor;FMXTee;DbxCommonDriver;ibxpress;xmlrtl;DataSnapNativeClient;FireDACDSDriver;rtl;ibxbindings;DbxClientDriver;CustomIPTransport;bindcomp;IndyIPClient;dbxcds;dsnapxml;DataSnapProviderClient;dbrtl;IndyProtocols;$(DCC_UsePackage)</DCC_UsePackage>
@ -106,6 +113,8 @@
<BT_BuildType>Debug</BT_BuildType>
<VerInfo_Keys>CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
<VerInfo_Locale>1033</VerInfo_Locale>
<Manifest_File>..\(None)</Manifest_File>
<AppDPIAwarenessMode>none</AppDPIAwarenessMode>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win64)'!=''">
<DCC_UsePackage>DBXSqliteDriver;fmxase;DBXDb2Driver;DBXInterBaseDriver;vclactnband;vclFireDAC;tethering;FireDACADSDriver;DBXMSSQLDriver;DatasnapConnectorsFreePascal;FireDACMSSQLDriver;vcltouch;vcldb;bindcompfmx;Intraweb;DBXOracleDriver;Spring.Data;inetdb;FmxTeeUI;emsedge;fmx;fmxdae;vclib;FireDACDBXDriver;dbexpress;IndyCore;vclx;dsnap;DataSnapCommon;DataSnapConnectors;VCLRESTComponents;vclie;bindengine;DBXMySQLDriver;FireDACOracleDriver;FireDACMySQLDriver;DBXFirebirdDriver;FireDACCommonODBC;DataSnapClient;IndyIPCommon;bindcompdbx;vcl;IndyIPServer;DBXSybaseASEDriver;IndySystem;FireDACDb2Driver;dsnapcon;FireDACMSAccDriver;fmxFireDAC;FireDACInfxDriver;vclimg;TeeDB;emshosting;FireDACPgDriver;ibmonitor;FireDACASADriver;DBXOdbcDriver;FireDACTDataDriver;FMXTee;DbxCommonDriver;ibxpress;Tee;DataSnapServer;xmlrtl;DataSnapNativeClient;fmxobj;vclwinx;FireDACDSDriver;rtl;ibxbindings;DbxClientDriver;DBXSybaseASADriver;CustomIPTransport;vcldsnap;bindcomp;appanalytics;DBXInformixDriver;IndyIPClient;bindcompvcl;TeeUI;dbxcds;VclSmp;adortl;FireDACODBCDriver;DataSnapIndy10ServerTransport;dsnapxml;DataSnapProviderClient;dbrtl;IndyProtocols;inetdbxpress;FireDACMongoDBDriver;DataSnapServerMidas;$(DCC_UsePackage)</DCC_UsePackage>
@ -120,6 +129,8 @@
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1_Win32)'!=''">
<DCC_RemoteDebug>false</DCC_RemoteDebug>
<VerInfo_Locale>1033</VerInfo_Locale>
<AppDPIAwarenessMode>none</AppDPIAwarenessMode>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2)'!=''">
<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
@ -127,6 +138,9 @@
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
<DCC_DebugInformation>0</DCC_DebugInformation>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2_Win32)'!=''">
<Manifest_File>..\..\(None)</Manifest_File>
</PropertyGroup>
<ItemGroup>
<DelphiCompile Include="$(MainSource)">
<MainSource>MainSource</MainSource>
@ -136,14 +150,13 @@
<Form>MyWebModule</Form>
<DesignClass>TWebModule</DesignClass>
</DCCReference>
<DCCReference Include="..\..\sources\MVCFramework.JSONRPC.pas"/>
<DCCReference Include="..\commons\BusinessObjectsU.pas"/>
<DCCReference Include="..\commons\RandomUtilsU.pas"/>
<DCCReference Include="..\articles_crud_server\MainDM.pas">
<DCCReference Include="..\..\commons\BusinessObjectsU.pas"/>
<DCCReference Include="..\..\commons\RandomUtilsU.pas"/>
<DCCReference Include="..\..\articles_crud_server\MainDM.pas">
<Form>dmMain</Form>
<DesignClass>TDataModule</DesignClass>
</DCCReference>
<DCCReference Include="CommonTypesU.pas"/>
<DCCReference Include="..\CommonTypesU.pas"/>
<BuildConfiguration Include="Base">
<Key>Base</Key>
</BuildConfiguration>
@ -169,33 +182,18 @@
<Excluded_Packages Name="$(BDSBIN)\dclofficexp280.bpl">Microsoft Office XP Sample Automation Server Wrapper Components</Excluded_Packages>
</Excluded_Packages>
</Delphi.Personality>
<Deployment Version="3">
<DeployFile LocalName="$(BDS)\Redist\iossimulator\libcgunwind.1.0.dylib" Class="DependencyModule">
<Platform Name="iOSSimulator">
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="$(BDS)\Redist\iossimulator\libPCRE.dylib" Class="DependencyModule">
<Platform Name="iOSSimulator">
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="$(BDS)\Redist\osx32\libcgsqlite3.dylib" Class="DependencyModule">
<Platform Name="OSX32">
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="$(BDS)\Redist\osx32\libcgunwind.1.0.dylib" Class="DependencyModule">
<Platform Name="OSX32">
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="Win32\Debug\jsonrpcserverwithobjects.exe" Configuration="Debug" Class="ProjectOutput">
<Deployment Version="4">
<DeployFile LocalName="$(BDS)\Redist\iossimulator\libcgunwind.1.0.dylib" Class="DependencyModule"/>
<DeployFile LocalName="$(BDS)\Redist\iossimulator\libPCRE.dylib" Class="DependencyModule"/>
<DeployFile LocalName="$(BDS)\Redist\osx32\libcgsqlite3.dylib" Class="DependencyModule"/>
<DeployFile LocalName="$(BDS)\Redist\osx32\libcgunwind.1.0.dylib" Class="DependencyModule"/>
<DeployFile LocalName="bin\jsonrpcserverwithobjects.exe" Configuration="Debug" Class="ProjectOutput">
<Platform Name="Win32">
<RemoteName>jsonrpcserverwithobjects.exe</RemoteName>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="Win32\Debug\jsonrpcserverwithobjects.exe" Configuration="Debug" Class="ProjectOutput"/>
<DeployClass Name="AdditionalDebugSymbols">
<Platform Name="OSX32">
<Operation>1</Operation>
@ -214,16 +212,6 @@
<Operation>64</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidClassesDexFile">
<Platform Name="Android">
<RemoteDir>classes</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>classes</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidFileProvider">
<Platform Name="Android">
<RemoteDir>res\xml</RemoteDir>
@ -547,7 +535,7 @@
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
@ -581,7 +569,7 @@
<Platform Name="iOSDevice64">
<Operation>0</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<Operation>0</Operation>
</Platform>
<Platform Name="OSX32">
@ -602,13 +590,17 @@
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_AppIcon152">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
@ -618,181 +610,27 @@
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch1024">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch1024x768">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch1536">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch1536x2048">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch1668">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch1668x2388">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch2048">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch2048x1536">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch2048x2732">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch2224">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch2388x1668">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch2732x2048">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch2x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch768">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch768x1024">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_LaunchDark2x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
@ -802,7 +640,7 @@
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
@ -812,7 +650,7 @@
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
@ -822,7 +660,7 @@
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
@ -832,7 +670,7 @@
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
@ -842,191 +680,37 @@
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch1125">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch1136x640">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch1242">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch1242x2688">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch1334">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch1792">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch2208">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch2436">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch2688x1242">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch2x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch320">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch3x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch640">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch640x1136">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch750">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch828">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_LaunchDark2x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
@ -1036,7 +720,7 @@
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
@ -1046,7 +730,7 @@
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
@ -1056,7 +740,7 @@
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
@ -1066,7 +750,7 @@
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
@ -1076,7 +760,7 @@
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
@ -1086,7 +770,7 @@
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
@ -1096,7 +780,7 @@
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
@ -1118,8 +802,11 @@
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSDeviceResourceRules"/>
<DeployClass Name="ProjectiOSEntitlements"/>
<DeployClass Name="ProjectiOSInfoPList"/>
<DeployClass Name="ProjectiOSLaunchScreen"/>
@ -1130,7 +817,7 @@
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<Operation>1</Operation>
</Platform>
</DeployClass>
@ -1166,7 +853,7 @@
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<Operation>1</Operation>
</Platform>
<Platform Name="Linux64">
@ -1223,6 +910,7 @@
<ProjectRoot Platform="Android64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="iOSDevice32" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="iOSDevice64" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="iOSSimARM64" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="iOSSimulator" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="Linux64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="OSX32" Name="$(PROJECTNAME)"/>

View File

@ -17,9 +17,11 @@ object MainForm: TMainForm
Top = 0
Width = 842
Height = 604
ActivePage = TabSheet6
ActivePage = TabSheet1
Align = alClient
TabOrder = 0
ExplicitWidth = 838
ExplicitHeight = 603
object TabSheet1: TTabSheet
Caption = 'Invoking Plain PODO'
object GroupBox1: TGroupBox
@ -540,7 +542,7 @@ object MainForm: TMainForm
object lbLogRec: TMemo
Left = 216
Top = 16
Width = 601
Width = 597
Height = 545
Anchors = [akLeft, akTop, akRight, akBottom]
Font.Charset = ANSI_CHARSET
@ -553,6 +555,7 @@ object MainForm: TMainForm
ScrollBars = ssBoth
TabOrder = 1
WordWrap = False
ExplicitHeight = 544
end
object btnGetArrayOfRecords: TButton
Left = 16

View File

@ -0,0 +1,18 @@
program jsonrpcclientwithobjects_sync;
uses
Vcl.Forms,
MainClientFormU in 'MainClientFormU.pas' {MainForm},
RandomUtilsU in '..\..\commons\RandomUtilsU.pas',
BusinessObjectsU in '..\..\commons\BusinessObjectsU.pas',
CommonTypesU in '..\CommonTypesU.pas';
{$R *.res}
begin
ReportMemoryLeaksOnShutdown := True;
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.CreateForm(TMainForm, MainForm);
Application.Run;
end.

View File

@ -1,9 +1,9 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{300F83FF-8F7B-43FD-B740-A3DFDF7238ED}</ProjectGuid>
<ProjectVersion>19.4</ProjectVersion>
<ProjectVersion>19.5</ProjectVersion>
<FrameworkType>VCL</FrameworkType>
<MainSource>jsonrpcclientwithobjects.dpr</MainSource>
<MainSource>jsonrpcclientwithobjects_sync.dpr</MainSource>
<Base>True</Base>
<Config Condition="'$(Config)'==''">Debug</Config>
<Platform Condition="'$(Platform)'==''">Win32</Platform>
@ -47,7 +47,7 @@
</PropertyGroup>
<PropertyGroup Condition="'$(Base)'!=''">
<DCC_DcuOutput>.\$(Platform)\$(Config)</DCC_DcuOutput>
<DCC_ExeOutput>.\$(Platform)\$(Config)</DCC_ExeOutput>
<DCC_ExeOutput>..\bin</DCC_ExeOutput>
<DCC_E>false</DCC_E>
<DCC_N>false</DCC_N>
<DCC_S>false</DCC_S>
@ -58,7 +58,9 @@
<Icon_MainIcon>$(BDS)\bin\delphi_PROJECTICON.ico</Icon_MainIcon>
<UWP_DelphiLogo44>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png</UWP_DelphiLogo44>
<UWP_DelphiLogo150>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png</UWP_DelphiLogo150>
<SanitizedProjectName>jsonrpcclientwithobjects</SanitizedProjectName>
<SanitizedProjectName>jsonrpcclientwithobjects_sync</SanitizedProjectName>
<VerInfo_Locale>1040</VerInfo_Locale>
<VerInfo_Keys>CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win32)'!=''">
<DCC_UsePackage>DBXSqliteDriver;fmxase;DBXDb2Driver;DBXInterBaseDriver;vclactnband;vclFireDAC;tethering;svnui;FireDACADSDriver;DBXMSSQLDriver;DatasnapConnectorsFreePascal;FireDACMSSQLDriver;vcltouch;vcldb;bindcompfmx;svn;Intraweb;DBXOracleDriver;Spring.Data;inetdb;FmxTeeUI;emsedge;fmx;fmxdae;vclib;FireDACDBXDriver;dbexpress;IndyCore;vclx;dsnap;DataSnapCommon;FixInsight_10_2;DataSnapConnectors;VCLRESTComponents;vclie;bindengine;DBXMySQLDriver;FireDACOracleDriver;FireDACMySQLDriver;DBXFirebirdDriver;FireDACCommonODBC;DataSnapClient;IndyIPCommon;bindcompdbx;vcl;IndyIPServer;DBXSybaseASEDriver;IndySystem;FireDACDb2Driver;TelegaPiBot;dsnapcon;DMVC_IDE_Expert_D102Tokyo;FireDACMSAccDriver;fmxFireDAC;FireDACInfxDriver;vclimg;TeeDB;emshosting;FireDACPgDriver;ibmonitor;FireDACASADriver;DBXOdbcDriver;FireDACTDataDriver;FMXTee;DbxCommonDriver;ibxpress;Tee;DataSnapServer;xmlrtl;DataSnapNativeClient;fmxobj;vclwinx;FireDACDSDriver;rtl;ibxbindings;DbxClientDriver;DBXSybaseASADriver;CustomIPTransport;vcldsnap;bindcomp;appanalytics;DBXInformixDriver;IndyIPClient;bindcompvcl;TeeUI;dbxcds;VclSmp;adortl;FireDACODBCDriver;DataSnapIndy10ServerTransport;dsnapxml;DataSnapProviderClient;dbrtl;IndyProtocols;inetdbxpress;FireDACMongoDBDriver;JSPack_Tokyo;DataSnapServerMidas;$(DCC_UsePackage)</DCC_UsePackage>
@ -68,7 +70,6 @@
<VerInfo_Keys>CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
<VerInfo_Locale>1033</VerInfo_Locale>
<Manifest_File>$(BDS)\bin\default_app.manifest</Manifest_File>
<DCC_ExeOutput>.\bin</DCC_ExeOutput>
<AppDPIAwarenessMode>none</AppDPIAwarenessMode>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win64)'!=''">
@ -84,7 +85,6 @@
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1_Win32)'!=''">
<DCC_RemoteDebug>false</DCC_RemoteDebug>
<AppEnableRuntimeThemes>true</AppEnableRuntimeThemes>
<AppDPIAwarenessMode>PerMonitor</AppDPIAwarenessMode>
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
<VerInfo_Locale>1033</VerInfo_Locale>
@ -107,10 +107,9 @@
<Form>MainForm</Form>
<FormType>dfm</FormType>
</DCCReference>
<DCCReference Include="..\..\sources\MVCFramework.JSONRPC.Client.pas"/>
<DCCReference Include="..\commons\RandomUtilsU.pas"/>
<DCCReference Include="..\commons\BusinessObjectsU.pas"/>
<DCCReference Include="CommonTypesU.pas"/>
<DCCReference Include="..\..\commons\RandomUtilsU.pas"/>
<DCCReference Include="..\..\commons\BusinessObjectsU.pas"/>
<DCCReference Include="..\CommonTypesU.pas"/>
<BuildConfiguration Include="Base">
<Key>Base</Key>
</BuildConfiguration>
@ -129,22 +128,21 @@
<BorlandProject>
<Delphi.Personality>
<Source>
<Source Name="MainSource">jsonrpcclientwithobjects.dpr</Source>
<Source Name="MainSource">jsonrpcclientwithobjects_sync.dpr</Source>
</Source>
<Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dcloffice2k280.bpl">Microsoft Office 2000 Sample Automation Server Wrapper Components</Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dclofficexp280.bpl">Microsoft Office XP Sample Automation Server Wrapper Components</Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\bcboffice2k280.bpl">Embarcadero C++Builder Office 2000 Servers Package</Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\bcbofficexp280.bpl">Embarcadero C++Builder Office XP Servers Package</Excluded_Packages>
</Excluded_Packages>
</Delphi.Personality>
<Deployment Version="3">
<DeployFile LocalName="Win32\Debug\jsonrpcclientwithobjects.exe" Configuration="Debug" Class="ProjectOutput">
<Deployment Version="4">
<DeployFile LocalName="bin\jsonrpcclientwithobjects_sync.exe" Configuration="Debug" Class="ProjectOutput">
<Platform Name="Win32">
<RemoteName>jsonrpcclientwithobjects.exe</RemoteName>
<RemoteName>jsonrpcclientwithobjects_sync.exe</RemoteName>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="Win32\Debug\jsonrpcclientwithobjects.exe" Configuration="Debug" Class="ProjectOutput"/>
<DeployClass Name="AdditionalDebugSymbols">
<Platform Name="iOSSimulator">
<Operation>1</Operation>
@ -167,16 +165,6 @@
<Operation>64</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidClassesDexFile">
<Platform Name="Android">
<RemoteDir>classes</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>classes</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidFileProvider">
<Platform Name="Android">
<RemoteDir>res\xml</RemoteDir>
@ -486,7 +474,7 @@
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
@ -519,7 +507,7 @@
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
@ -556,7 +544,7 @@
<Platform Name="iOSDevice64">
<Operation>0</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<Operation>0</Operation>
</Platform>
<Platform Name="OSX32">
@ -580,13 +568,17 @@
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_AppIcon152">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
@ -596,181 +588,27 @@
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch1024">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch1024x768">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch1536">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch1536x2048">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch1668">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch1668x2388">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch2048">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch2048x1536">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch2048x2732">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch2224">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch2388x1668">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch2732x2048">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch2x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch768">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch768x1024">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_LaunchDark2x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
@ -780,7 +618,7 @@
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
@ -790,7 +628,7 @@
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
@ -800,7 +638,7 @@
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
@ -810,7 +648,7 @@
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
@ -820,191 +658,37 @@
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch1125">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch1136x640">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch1242">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch1242x2688">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch1334">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch1792">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch2208">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch2436">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch2688x1242">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch2x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch320">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch3x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch640">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch640x1136">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch750">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch828">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_LaunchDark2x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
@ -1014,7 +698,7 @@
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
@ -1024,7 +708,7 @@
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
@ -1034,7 +718,7 @@
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
@ -1044,7 +728,7 @@
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
@ -1054,7 +738,7 @@
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
@ -1064,7 +748,7 @@
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
@ -1074,7 +758,7 @@
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
@ -1096,12 +780,8 @@
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSDeviceResourceRules">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
@ -1114,6 +794,10 @@
<RemoteDir>..\</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSInfoPList">
<Platform Name="iOSDevice32">
@ -1122,7 +806,7 @@
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<Operation>1</Operation>
</Platform>
</DeployClass>
@ -1131,7 +815,7 @@
<RemoteDir>..\$(PROJECTNAME).launchscreen</RemoteDir>
<Operation>64</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen</RemoteDir>
<Operation>64</Operation>
</Platform>
@ -1143,7 +827,7 @@
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<Operation>1</Operation>
</Platform>
</DeployClass>
@ -1214,7 +898,7 @@
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<Operation>1</Operation>
</Platform>
<Platform Name="Linux64">
@ -1274,6 +958,7 @@
<ProjectRoot Platform="Android64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="iOSDevice32" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="iOSDevice64" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="iOSSimARM64" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="iOSSimulator" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="Linux64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="OSX32" Name="$(PROJECTNAME).app"/>

View File

@ -0,0 +1,99 @@
unit MainControllerU;
interface
uses
MVCFramework, MVCFramework.Commons, MVCFramework.Serializer.Commons,
MVCFramework.Logger;
type
[MVCPath('/api')]
TMyController = class(TMVCController)
public
[MVCPath]
[MVCHTTPMethod([httpGET])]
procedure Index;
[MVCPath('/profilersample1')]
[MVCHTTPMethod([httpGET])]
procedure ProfilerSample1;
protected
fCalls: Integer;
procedure ProcA;
procedure ProcB;
procedure DoSomething;
procedure DoSomethingElse;
procedure NotProfiled;
end;
implementation
uses
System.SysUtils, System.StrUtils;
procedure TMyController.ProfilerSample1;
begin
NotProfiled(); //this line is not profiled
//the following begin..end block will be profiled
//timing will be saved in a "profiler" log
begin var lProf := Profiler.Start(Context.ActionQualifiedName);
DoSomething();
DoSomethingElse();
Render('Just executed ' + Context.ActionQualifiedName);
end; // profiler writes to the log
NotProfiled(); //this line is not profiled
end;
procedure TMyController.DoSomething;
begin
begin var lProf := Profiler.Start('DoSomething');
Sleep(100);
end;
end;
procedure TMyController.DoSomethingElse;
begin
begin var lProf := Profiler.Start('DoSomethingElse');
Sleep(100);
DoSomething();
end;
end;
procedure TMyController.NotProfiled;
begin
Sleep(100);
end;
procedure TMyController.Index;
begin
fCalls := 0;
begin var lProf := Profiler.Start(Context.ActionQualifiedName, []);
ProcA;
Render('Hello DelphiMVCFramework (profiled) World');
end;
end;
procedure TMyController.ProcA;
begin
begin var lProf := Profiler.Start('TMyController.ProcA');
Inc(fCalls);
ProcB;
end;
end;
procedure TMyController.ProcB;
begin
begin var lProf := Profiler.Start('TMyController.ProcB');
Inc(fCalls);
if fCalls < 20 then
begin
ProcA;
end;
end;
end;
end.

View File

@ -0,0 +1,68 @@
program ProfilingSample;
{$APPTYPE CONSOLE}
uses
System.SysUtils,
MVCFramework,
MVCFramework.Commons,
MVCFramework.Signal,
Web.ReqMulti,
Web.WebReq,
Web.WebBroker,
IdContext,
IdHTTPWebBrokerBridge,
MainControllerU in 'MainControllerU.pas',
WebModuleU in 'WebModuleU.pas' {MyWebModule: TWebModule},
MVCFramework.Logger in '..\..\sources\MVCFramework.Logger.pas';
{$R *.res}
procedure RunServer(APort: Integer);
var
LServer: TIdHTTPWebBrokerBridge;
begin
Writeln('** DMVCFramework Server ** build ' + DMVCFRAMEWORK_VERSION);
LServer := TIdHTTPWebBrokerBridge.Create(nil);
try
LServer.OnParseAuthentication := TMVCParseAuthentication.OnParseAuthentication;
LServer.DefaultPort := APort;
LServer.KeepAlive := True;
{ more info about MaxConnections
http://ww2.indyproject.org/docsite/html/frames.html?frmname=topic&frmfile=index.html }
LServer.MaxConnections := 0;
{ more info about ListenQueue
http://ww2.indyproject.org/docsite/html/frames.html?frmname=topic&frmfile=index.html }
LServer.ListenQueue := 200;
LServer.Active := True;
WriteLn('Listening on port ', APort);
Write('CTRL+C to shutdown the server');
WaitForTerminationSignal;
EnterInShutdownState;
LServer.Active := False;
finally
LServer.Free;
end;
end;
begin
ReportMemoryLeaksOnShutdown := True;
IsMultiThread := True;
try
if WebRequestHandler <> nil then
WebRequestHandler.WebModuleClass := WebModuleClass;
WebRequestHandlerProc.MaxConnections := 1024;
{ this line allows to use "Profiler" in actions code}
Profiler.ProfileLogger := Log; {set to nil to disable profiling}
{ end -- this line allows to use "Profiler" in actions code}
RunServer(8080);
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.

View File

@ -0,0 +1,913 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{9A719B2E-ABBC-406A-9B25-20444D1F53B3}</ProjectGuid>
<ProjectVersion>19.5</ProjectVersion>
<FrameworkType>None</FrameworkType>
<Base>True</Base>
<Config Condition="'$(Config)'==''">Debug</Config>
<Platform Condition="'$(Platform)'==''">Win32</Platform>
<TargetedPlatforms>1</TargetedPlatforms>
<AppType>Console</AppType>
<MainSource>ProfilingSample.dpr</MainSource>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Android' and '$(Base)'=='true') or '$(Base_Android)'!=''">
<Base_Android>true</Base_Android>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Android64' and '$(Base)'=='true') or '$(Base_Android64)'!=''">
<Base_Android64>true</Base_Android64>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Linux64' and '$(Base)'=='true') or '$(Base_Linux64)'!=''">
<Base_Linux64>true</Base_Linux64>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
<Base_Win32>true</Base_Win32>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Base)'=='true') or '$(Base_Win64)'!=''">
<Base_Win64>true</Base_Win64>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_1)'!=''">
<Cfg_1>true</Cfg_1>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_1)'=='true') or '$(Cfg_1_Win32)'!=''">
<Cfg_1_Win32>true</Cfg_1_Win32>
<CfgParent>Cfg_1</CfgParent>
<Cfg_1>true</Cfg_1>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_2)'!=''">
<Cfg_2>true</Cfg_2>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Base)'!=''">
<DCC_DcuOutput>.\$(Platform)\$(Config)</DCC_DcuOutput>
<DCC_ExeOutput>.\bin</DCC_ExeOutput>
<DCC_E>false</DCC_E>
<DCC_N>false</DCC_N>
<DCC_S>false</DCC_S>
<DCC_F>false</DCC_F>
<DCC_K>false</DCC_K>
<DCC_Namespace>System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace)</DCC_Namespace>
<UsingDelphiRTL>true</UsingDelphiRTL>
<Icon_MainIcon>$(BDS)\bin\delphi_PROJECTICON.ico</Icon_MainIcon>
<Icns_MainIcns>$(BDS)\bin\delphi_PROJECTICNS.icns</Icns_MainIcns>
<DCC_UnitSearchPath>$(DMVC);$(DCC_UnitSearchPath)</DCC_UnitSearchPath>
<DCC_Framework>VCL;$(DCC_Framework)</DCC_Framework>
<SanitizedProjectName>ProfilingSample</SanitizedProjectName>
<VerInfo_Locale>1040</VerInfo_Locale>
<VerInfo_Keys>CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Android)'!=''">
<DCC_UsePackage>fmx;DbxCommonDriver;bindengine;IndyIPCommon;emsclient;FireDACCommonDriver;IndyProtocols;IndyIPClient;dbxcds;FmxTeeUI;bindcompfmx;ibmonitor;FireDACSqliteDriver;DbxClientDriver;soapmidas;fmxFireDAC;dbexpress;Python;inet;DataSnapCommon;fmxase;dbrtl;FireDACDBXDriver;CustomIPTransport;DBXInterBaseDriver;IndySystem;ibxbindings;bindcomp;FireDACCommon;IndyCore;RESTBackendComponents;bindcompdbx;rtl;RESTComponents;DBXSqliteDriver;IndyIPServer;dsnapxml;DataSnapClient;DataSnapProviderClient;DataSnapFireDAC;emsclientfiredac;FireDAC;FireDACDSDriver;xmlrtl;tethering;ibxpress;dsnap;CloudService;FMXTee;DataSnapNativeClient;PythonFmx;soaprtl;soapserver;FireDACIBDriver;$(DCC_UsePackage)</DCC_UsePackage>
<EnabledSysJars>annotation-1.2.0.dex.jar;asynclayoutinflater-1.0.0.dex.jar;billing-4.0.0.dex.jar;browser-1.0.0.dex.jar;cloud-messaging.dex.jar;collection-1.0.0.dex.jar;coordinatorlayout-1.0.0.dex.jar;core-1.5.0-rc02.dex.jar;core-common-2.0.1.dex.jar;core-runtime-2.0.1.dex.jar;cursoradapter-1.0.0.dex.jar;customview-1.0.0.dex.jar;documentfile-1.0.0.dex.jar;drawerlayout-1.0.0.dex.jar;firebase-annotations-16.0.0.dex.jar;firebase-common-20.0.0.dex.jar;firebase-components-17.0.0.dex.jar;firebase-datatransport-18.0.0.dex.jar;firebase-encoders-17.0.0.dex.jar;firebase-encoders-json-18.0.0.dex.jar;firebase-iid-interop-17.1.0.dex.jar;firebase-installations-17.0.0.dex.jar;firebase-installations-interop-17.0.0.dex.jar;firebase-measurement-connector-19.0.0.dex.jar;firebase-messaging-22.0.0.dex.jar;fmx.dex.jar;fragment-1.0.0.dex.jar;google-play-licensing.dex.jar;interpolator-1.0.0.dex.jar;javax.inject-1.dex.jar;legacy-support-core-ui-1.0.0.dex.jar;legacy-support-core-utils-1.0.0.dex.jar;lifecycle-common-2.0.0.dex.jar;lifecycle-livedata-2.0.0.dex.jar;lifecycle-livedata-core-2.0.0.dex.jar;lifecycle-runtime-2.0.0.dex.jar;lifecycle-service-2.0.0.dex.jar;lifecycle-viewmodel-2.0.0.dex.jar;listenablefuture-1.0.dex.jar;loader-1.0.0.dex.jar;localbroadcastmanager-1.0.0.dex.jar;play-services-ads-20.1.0.dex.jar;play-services-ads-base-20.1.0.dex.jar;play-services-ads-identifier-17.0.0.dex.jar;play-services-ads-lite-20.1.0.dex.jar;play-services-base-17.5.0.dex.jar;play-services-basement-17.6.0.dex.jar;play-services-cloud-messaging-16.0.0.dex.jar;play-services-drive-17.0.0.dex.jar;play-services-games-21.0.0.dex.jar;play-services-location-18.0.0.dex.jar;play-services-maps-17.0.1.dex.jar;play-services-measurement-base-18.0.0.dex.jar;play-services-measurement-sdk-api-18.0.0.dex.jar;play-services-places-placereport-17.0.0.dex.jar;play-services-stats-17.0.0.dex.jar;play-services-tasks-17.2.0.dex.jar;print-1.0.0.dex.jar;room-common-2.1.0.dex.jar;room-runtime-2.1.0.dex.jar;slidingpanelayout-1.0.0.dex.jar;sqlite-2.0.1.dex.jar;sqlite-framework-2.0.1.dex.jar;swiperefreshlayout-1.0.0.dex.jar;transport-api-3.0.0.dex.jar;transport-backend-cct-3.0.0.dex.jar;transport-runtime-3.0.0.dex.jar;user-messaging-platform-1.0.0.dex.jar;versionedparcelable-1.1.1.dex.jar;viewpager-1.0.0.dex.jar;work-runtime-2.1.0.dex.jar</EnabledSysJars>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Android64)'!=''">
<DCC_UsePackage>fmx;DbxCommonDriver;bindengine;IndyIPCommon;emsclient;FireDACCommonDriver;IndyProtocols;IndyIPClient;dbxcds;FmxTeeUI;bindcompfmx;ibmonitor;FireDACSqliteDriver;DbxClientDriver;soapmidas;fmxFireDAC;dbexpress;Python;inet;DataSnapCommon;dbrtl;FireDACDBXDriver;CustomIPTransport;DBXInterBaseDriver;IndySystem;ibxbindings;bindcomp;FireDACCommon;IndyCore;RESTBackendComponents;bindcompdbx;rtl;RESTComponents;DBXSqliteDriver;IndyIPServer;dsnapxml;DataSnapClient;DataSnapProviderClient;DataSnapFireDAC;emsclientfiredac;FireDAC;FireDACDSDriver;xmlrtl;tethering;ibxpress;dsnap;CloudService;FMXTee;DataSnapNativeClient;PythonFmx;soaprtl;soapserver;FireDACIBDriver;$(DCC_UsePackage)</DCC_UsePackage>
<EnabledSysJars>annotation-1.2.0.dex.jar;asynclayoutinflater-1.0.0.dex.jar;billing-4.0.0.dex.jar;browser-1.0.0.dex.jar;cloud-messaging.dex.jar;collection-1.0.0.dex.jar;coordinatorlayout-1.0.0.dex.jar;core-1.5.0-rc02.dex.jar;core-common-2.0.1.dex.jar;core-runtime-2.0.1.dex.jar;cursoradapter-1.0.0.dex.jar;customview-1.0.0.dex.jar;documentfile-1.0.0.dex.jar;drawerlayout-1.0.0.dex.jar;firebase-annotations-16.0.0.dex.jar;firebase-common-20.0.0.dex.jar;firebase-components-17.0.0.dex.jar;firebase-datatransport-18.0.0.dex.jar;firebase-encoders-17.0.0.dex.jar;firebase-encoders-json-18.0.0.dex.jar;firebase-iid-interop-17.1.0.dex.jar;firebase-installations-17.0.0.dex.jar;firebase-installations-interop-17.0.0.dex.jar;firebase-measurement-connector-19.0.0.dex.jar;firebase-messaging-22.0.0.dex.jar;fmx.dex.jar;fragment-1.0.0.dex.jar;google-play-licensing.dex.jar;interpolator-1.0.0.dex.jar;javax.inject-1.dex.jar;legacy-support-core-ui-1.0.0.dex.jar;legacy-support-core-utils-1.0.0.dex.jar;lifecycle-common-2.0.0.dex.jar;lifecycle-livedata-2.0.0.dex.jar;lifecycle-livedata-core-2.0.0.dex.jar;lifecycle-runtime-2.0.0.dex.jar;lifecycle-service-2.0.0.dex.jar;lifecycle-viewmodel-2.0.0.dex.jar;listenablefuture-1.0.dex.jar;loader-1.0.0.dex.jar;localbroadcastmanager-1.0.0.dex.jar;play-services-ads-20.1.0.dex.jar;play-services-ads-base-20.1.0.dex.jar;play-services-ads-identifier-17.0.0.dex.jar;play-services-ads-lite-20.1.0.dex.jar;play-services-base-17.5.0.dex.jar;play-services-basement-17.6.0.dex.jar;play-services-cloud-messaging-16.0.0.dex.jar;play-services-drive-17.0.0.dex.jar;play-services-games-21.0.0.dex.jar;play-services-location-18.0.0.dex.jar;play-services-maps-17.0.1.dex.jar;play-services-measurement-base-18.0.0.dex.jar;play-services-measurement-sdk-api-18.0.0.dex.jar;play-services-places-placereport-17.0.0.dex.jar;play-services-stats-17.0.0.dex.jar;play-services-tasks-17.2.0.dex.jar;print-1.0.0.dex.jar;room-common-2.1.0.dex.jar;room-runtime-2.1.0.dex.jar;slidingpanelayout-1.0.0.dex.jar;sqlite-2.0.1.dex.jar;sqlite-framework-2.0.1.dex.jar;swiperefreshlayout-1.0.0.dex.jar;transport-api-3.0.0.dex.jar;transport-backend-cct-3.0.0.dex.jar;transport-runtime-3.0.0.dex.jar;user-messaging-platform-1.0.0.dex.jar;versionedparcelable-1.1.1.dex.jar;viewpager-1.0.0.dex.jar;work-runtime-2.1.0.dex.jar</EnabledSysJars>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Linux64)'!=''">
<DCC_UsePackage>DataSnapServer;fmx;emshosting;DbxCommonDriver;bindengine;FireDACCommonODBC;emsclient;FireDACCommonDriver;IndyProtocols;dbxcds;emsedge;inetdb;FireDACSqliteDriver;DbxClientDriver;FireDACASADriver;soapmidas;dbexpress;Python;FireDACInfxDriver;inet;DataSnapCommon;dbrtl;FireDACOracleDriver;CustomIPTransport;FireDACMSSQLDriver;DataSnapIndy10ServerTransport;DataSnapConnectors;FireDACMongoDBDriver;IndySystem;FireDACTDataDriver;bindcomp;FireDACCommon;DataSnapServerMidas;FireDACODBCDriver;emsserverresource;IndyCore;RESTBackendComponents;rtl;FireDACMySQLDriver;FireDACADSDriver;RESTComponents;dsnapxml;DataSnapClient;LockBoxDR;DataSnapFireDAC;emsclientfiredac;FireDACPgDriver;FireDAC;xmlrtl;dsnap;CloudService;FireDACDb2Driver;DataSnapNativeClient;DatasnapConnectorsFreePascal;soaprtl;soapserver;FireDACIBDriver;$(DCC_UsePackage)</DCC_UsePackage>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win32)'!=''">
<DCC_UsePackage>RaizeComponentsVcl;JvNet;vclwinx;DataSnapServer;fmx;emshosting;vclie;DbxCommonDriver;bindengine;IndyIPCommon;VCLRESTComponents;DBXMSSQLDriver;FireDACCommonODBC;emsclient;FireDACCommonDriver;appanalytics;IndyProtocols;vclx;IndyIPClient;dbxcds;vcledge;bindcompvclwinx;FmxTeeUI;emsedge;bindcompfmx;DBXFirebirdDriver;JvBands;inetdb;JvAppFrm;ibmonitor;FireDACSqliteDriver;DbxClientDriver;FireDACASADriver;Tee;soapmidas;SVGIconImageListFMX;JclVcl;vclactnband;TeeUI;fmxFireDAC;dbexpress;Python;Jcl;FireDACInfxDriver;JvManagedThreads;DBXMySQLDriver;VclSmp;inet;DataSnapCommon;JvPascalInterpreter;PythonVcl;vcltouch;fmxase;JvPluginSystem;DBXOdbcDriver;JvDB;dbrtl;JvTimeFramework;FireDACDBXDriver;FireDACOracleDriver;fmxdae;TeeDB;FireDACMSAccDriver;JvCustom;CustomIPTransport;FireDACMSSQLDriver;SVGIconPackage;JvSystem;DataSnapIndy10ServerTransport;JclDeveloperTools;JvControls;DataSnapConnectors;vcldsnap;DBXInterBaseDriver;JvCrypt;FireDACMongoDBDriver;JvJans;JvMM;IndySystem;JvWizards;FireDACTDataDriver;JvGlobus;vcldb;ibxbindings;SynEditDR;JclContainers;JvPageComps;vclFireDAC;JvCore;bindcomp;FireDACCommon;DataSnapServerMidas;FireDACODBCDriver;emsserverresource;IndyCore;RESTBackendComponents;dmvcframeworkDT;bindcompdbx;rtl;FireDACMySQLDriver;FireDACADSDriver;RaizeComponentsVclDb;RESTComponents;DBXSqliteDriver;vcl;IndyIPServer;dsnapxml;dsnapcon;DataSnapClient;DataSnapProviderClient;adortl;JvDotNetCtrls;JvHMI;DBXSybaseASEDriver;LockBoxDR;JvRuntimeDesign;DBXDb2Driver;JvXPCtrls;vclimg;DataSnapFireDAC;emsclientfiredac;FireDACPgDriver;FireDAC;FireDACDSDriver;inetdbxpress;xmlrtl;tethering;dmvcframeworkRT;ibxpress;JvStdCtrls;JvDlgs;bindcompvcl;dsnap;JvDocking;JvCmp;JvPrintPreview;CloudService;DBXSybaseASADriver;DBXOracleDriver;FireDACDb2Driver;DBXInformixDriver;vclib;fmxobj;bindcompvclsmp;FMXTee;DataSnapNativeClient;PythonFmx;DatasnapConnectorsFreePascal;soaprtl;SVGIconImageList;soapserver;FireDACIBDriver;$(DCC_UsePackage)</DCC_UsePackage>
<DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
<BT_BuildType>Debug</BT_BuildType>
<VerInfo_Keys>CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
<VerInfo_Locale>1033</VerInfo_Locale>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win64)'!=''">
<DCC_UsePackage>RaizeComponentsVcl;vclwinx;DataSnapServer;fmx;emshosting;vclie;DbxCommonDriver;bindengine;IndyIPCommon;VCLRESTComponents;DBXMSSQLDriver;FireDACCommonODBC;emsclient;FireDACCommonDriver;appanalytics;IndyProtocols;vclx;IndyIPClient;dbxcds;vcledge;bindcompvclwinx;FmxTeeUI;emsedge;bindcompfmx;DBXFirebirdDriver;inetdb;ibmonitor;FireDACSqliteDriver;DbxClientDriver;FireDACASADriver;Tee;soapmidas;SVGIconImageListFMX;vclactnband;TeeUI;fmxFireDAC;dbexpress;Python;FireDACInfxDriver;DBXMySQLDriver;VclSmp;inet;DataSnapCommon;PythonVcl;vcltouch;fmxase;DBXOdbcDriver;dbrtl;FireDACDBXDriver;FireDACOracleDriver;fmxdae;TeeDB;FireDACMSAccDriver;CustomIPTransport;FireDACMSSQLDriver;SVGIconPackage;DataSnapIndy10ServerTransport;DataSnapConnectors;vcldsnap;DBXInterBaseDriver;FireDACMongoDBDriver;IndySystem;FireDACTDataDriver;vcldb;ibxbindings;SynEditDR;vclFireDAC;bindcomp;FireDACCommon;DataSnapServerMidas;FireDACODBCDriver;emsserverresource;IndyCore;RESTBackendComponents;bindcompdbx;rtl;FireDACMySQLDriver;FireDACADSDriver;RaizeComponentsVclDb;RESTComponents;DBXSqliteDriver;vcl;IndyIPServer;dsnapxml;dsnapcon;DataSnapClient;DataSnapProviderClient;adortl;DBXSybaseASEDriver;LockBoxDR;DBXDb2Driver;vclimg;DataSnapFireDAC;emsclientfiredac;FireDACPgDriver;FireDAC;FireDACDSDriver;inetdbxpress;xmlrtl;tethering;ibxpress;bindcompvcl;dsnap;CloudService;DBXSybaseASADriver;DBXOracleDriver;FireDACDb2Driver;DBXInformixDriver;vclib;fmxobj;bindcompvclsmp;FMXTee;DataSnapNativeClient;PythonFmx;DatasnapConnectorsFreePascal;soaprtl;SVGIconImageList;soapserver;FireDACIBDriver;$(DCC_UsePackage)</DCC_UsePackage>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1)'!=''">
<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
<DCC_DebugDCUs>true</DCC_DebugDCUs>
<DCC_Optimize>false</DCC_Optimize>
<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
<DCC_DebugInfoInExe>true</DCC_DebugInfoInExe>
<DCC_RemoteDebug>true</DCC_RemoteDebug>
<DCC_IntegerOverflowCheck>true</DCC_IntegerOverflowCheck>
<DCC_RangeChecking>true</DCC_RangeChecking>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1_Win32)'!=''">
<DCC_RemoteDebug>false</DCC_RemoteDebug>
<VerInfo_Locale>1033</VerInfo_Locale>
<Manifest_File>(None)</Manifest_File>
<AppDPIAwarenessMode>none</AppDPIAwarenessMode>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2)'!=''">
<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
<DCC_DebugInformation>0</DCC_DebugInformation>
</PropertyGroup>
<ItemGroup>
<DelphiCompile Include="$(MainSource)">
<MainSource>MainSource</MainSource>
</DelphiCompile>
<DCCReference Include="MainControllerU.pas"/>
<DCCReference Include="WebModuleU.pas">
<Form>MyWebModule</Form>
<FormType>dfm</FormType>
<DesignClass>TWebModule</DesignClass>
</DCCReference>
<DCCReference Include="..\..\sources\MVCFramework.Logger.pas"/>
<BuildConfiguration Include="Base">
<Key>Base</Key>
</BuildConfiguration>
<BuildConfiguration Include="Debug">
<Key>Cfg_1</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
<BuildConfiguration Include="Release">
<Key>Cfg_2</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
</ItemGroup>
<ProjectExtensions>
<Borland.Personality>Delphi.Personality.12</Borland.Personality>
<Borland.ProjectType>Console</Borland.ProjectType>
<BorlandProject>
<Delphi.Personality>
<Source>
<Source Name="MainSource">ProfilingSample.dpr</Source>
</Source>
<Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dcloffice2k280.bpl">Microsoft Office 2000 Sample Automation Server Wrapper Components</Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dclofficexp280.bpl">Microsoft Office XP Sample Automation Server Wrapper Components</Excluded_Packages>
</Excluded_Packages>
</Delphi.Personality>
<Deployment Version="4">
<DeployFile LocalName="$(BDS)\Redist\iossimulator\libcgunwind.1.0.dylib" Class="DependencyModule">
<Platform Name="iOSSimulator">
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="$(BDS)\Redist\iossimulator\libpcre.dylib" Class="DependencyModule">
<Platform Name="iOSSimulator">
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="$(BDS)\Redist\osx32\libcgunwind.1.0.dylib" Class="DependencyModule">
<Platform Name="OSX32">
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="bin\ProfilingSample.exe" Configuration="Debug" Class="ProjectOutput">
<Platform Name="Win32">
<RemoteName>ProfilingSample.exe</RemoteName>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployClass Name="AdditionalDebugSymbols">
<Platform Name="OSX32">
<Operation>1</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidClasses">
<Platform Name="Android">
<RemoteDir>classes</RemoteDir>
<Operation>64</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>classes</RemoteDir>
<Operation>64</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidFileProvider">
<Platform Name="Android">
<RemoteDir>res\xml</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\xml</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidGDBServer">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidLibnativeArmeabiFile">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>library\lib\armeabi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidLibnativeArmeabiv7aFile">
<Platform Name="Android64">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidLibnativeMipsFile">
<Platform Name="Android">
<RemoteDir>library\lib\mips</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>library\lib\mips</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidServiceOutput">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>library\lib\arm64-v8a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidServiceOutput_Android32">
<Platform Name="Android64">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidSplashImageDef">
<Platform Name="Android">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidSplashStyles">
<Platform Name="Android">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidSplashStylesV21">
<Platform Name="Android">
<RemoteDir>res\values-v21</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\values-v21</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_Colors">
<Platform Name="Android">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_DefaultAppIcon">
<Platform Name="Android">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon144">
<Platform Name="Android">
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon192">
<Platform Name="Android">
<RemoteDir>res\drawable-xxxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xxxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon36">
<Platform Name="Android">
<RemoteDir>res\drawable-ldpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-ldpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon48">
<Platform Name="Android">
<RemoteDir>res\drawable-mdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-mdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon72">
<Platform Name="Android">
<RemoteDir>res\drawable-hdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-hdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon96">
<Platform Name="Android">
<RemoteDir>res\drawable-xhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon24">
<Platform Name="Android">
<RemoteDir>res\drawable-mdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-mdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon36">
<Platform Name="Android">
<RemoteDir>res\drawable-hdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-hdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon48">
<Platform Name="Android">
<RemoteDir>res\drawable-xhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon72">
<Platform Name="Android">
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon96">
<Platform Name="Android">
<RemoteDir>res\drawable-xxxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xxxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage426">
<Platform Name="Android">
<RemoteDir>res\drawable-small</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-small</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage470">
<Platform Name="Android">
<RemoteDir>res\drawable-normal</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-normal</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage640">
<Platform Name="Android">
<RemoteDir>res\drawable-large</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-large</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage960">
<Platform Name="Android">
<RemoteDir>res\drawable-xlarge</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xlarge</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_Strings">
<Platform Name="Android">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="DebugSymbols">
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
<Platform Name="OSX32">
<Operation>1</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="DependencyFramework">
<Platform Name="OSX32">
<Operation>1</Operation>
<Extensions>.framework</Extensions>
</Platform>
<Platform Name="OSX64">
<Operation>1</Operation>
<Extensions>.framework</Extensions>
</Platform>
<Platform Name="OSXARM64">
<Operation>1</Operation>
<Extensions>.framework</Extensions>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="DependencyModule">
<Platform Name="OSX32">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSX64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSXARM64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
<Extensions>.dll;.bpl</Extensions>
</Platform>
</DeployClass>
<DeployClass Required="true" Name="DependencyPackage">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="iOSSimARM64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSX32">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSX64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSXARM64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
<Extensions>.bpl</Extensions>
</Platform>
</DeployClass>
<DeployClass Name="File">
<Platform Name="Android">
<Operation>0</Operation>
</Platform>
<Platform Name="Android64">
<Operation>0</Operation>
</Platform>
<Platform Name="iOSDevice32">
<Operation>0</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>0</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<Operation>0</Operation>
</Platform>
<Platform Name="OSX32">
<Operation>0</Operation>
</Platform>
<Platform Name="OSX64">
<Operation>0</Operation>
</Platform>
<Platform Name="OSXARM64">
<Operation>0</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iOS_AppStore1024">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_AppIcon152">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_AppIcon167">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch2x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_LaunchDark2x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Notification40">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Setting58">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_SpotLight80">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_AppIcon120">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_AppIcon180">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch2x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch3x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_LaunchDark2x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_LaunchDark3x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Notification40">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Notification60">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Setting58">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Setting87">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Spotlight120">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Spotlight80">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectAndroidManifest">
<Platform Name="Android">
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSDeviceDebug">
<Platform Name="iOSDevice32">
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSEntitlements"/>
<DeployClass Name="ProjectiOSInfoPList"/>
<DeployClass Name="ProjectiOSLaunchScreen"/>
<DeployClass Name="ProjectiOSResource">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectOSXDebug"/>
<DeployClass Name="ProjectOSXEntitlements"/>
<DeployClass Name="ProjectOSXInfoPList"/>
<DeployClass Name="ProjectOSXResource">
<Platform Name="OSX32">
<RemoteDir>Contents\Resources</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="OSX64">
<RemoteDir>Contents\Resources</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="OSXARM64">
<RemoteDir>Contents\Resources</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Required="true" Name="ProjectOutput">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>library\lib\arm64-v8a</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<Operation>1</Operation>
</Platform>
<Platform Name="Linux64">
<Operation>1</Operation>
</Platform>
<Platform Name="OSX32">
<Operation>1</Operation>
</Platform>
<Platform Name="OSX64">
<Operation>1</Operation>
</Platform>
<Platform Name="OSXARM64">
<Operation>1</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectOutput_Android32">
<Platform Name="Android64">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectUWPManifest">
<Platform Name="Win32">
<Operation>1</Operation>
</Platform>
<Platform Name="Win64">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="UWP_DelphiLogo150">
<Platform Name="Win32">
<RemoteDir>Assets</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Win64">
<RemoteDir>Assets</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="UWP_DelphiLogo44">
<Platform Name="Win32">
<RemoteDir>Assets</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Win64">
<RemoteDir>Assets</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<ProjectRoot Platform="Android" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="Android64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="iOSDevice32" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="iOSDevice64" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="iOSSimARM64" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="Linux64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="OSX32" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="OSX64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="OSXARM64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="Win32" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="Win64" Name="$(PROJECTNAME)"/>
</Deployment>
<Platforms>
<Platform value="Android">False</Platform>
<Platform value="Android64">False</Platform>
<Platform value="Linux64">False</Platform>
<Platform value="Win32">True</Platform>
<Platform value="Win64">False</Platform>
</Platforms>
</BorlandProject>
<ProjectFileVersion>12</ProjectFileVersion>
</ProjectExtensions>
<Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/>
<Import Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj" Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')"/>
<Import Project="$(MSBuildProjectName).deployproj" Condition="Exists('$(MSBuildProjectName).deployproj')"/>
</Project>

View File

@ -0,0 +1,7 @@
object MyWebModule: TMyWebModule
OnCreate = WebModuleCreate
OnDestroy = WebModuleDestroy
Actions = <>
Height = 230
Width = 415
end

View File

@ -0,0 +1,100 @@
unit WebModuleU;
interface
uses
System.SysUtils,
System.Classes,
Web.HTTPApp,
MVCFramework;
type
TMyWebModule = class(TWebModule)
procedure WebModuleCreate(Sender: TObject);
procedure WebModuleDestroy(Sender: TObject);
private
FMVC: TMVCEngine;
public
{ Public declarations }
end;
var
WebModuleClass: TComponentClass = TMyWebModule;
implementation
{$R *.dfm}
uses
System.IOUtils,
MVCFramework.Commons,
MVCFramework.Middleware.ActiveRecord,
MVCFramework.Middleware.StaticFiles,
MVCFramework.Middleware.Analytics,
MVCFramework.Middleware.Trace,
MVCFramework.Middleware.CORS,
MVCFramework.Middleware.ETag,
MVCFramework.Middleware.Compression, MainControllerU;
procedure TMyWebModule.WebModuleCreate(Sender: TObject);
begin
FMVC := TMVCEngine.Create(Self,
procedure(Config: TMVCConfig)
begin
// session timeout (0 means session cookie)
Config[TMVCConfigKey.SessionTimeout] := '0';
//default content-type
Config[TMVCConfigKey.DefaultContentType] := TMVCConstants.DEFAULT_CONTENT_TYPE;
//default content charset
Config[TMVCConfigKey.DefaultContentCharset] := TMVCConstants.DEFAULT_CONTENT_CHARSET;
//unhandled actions are permitted?
Config[TMVCConfigKey.AllowUnhandledAction] := 'false';
//enables or not system controllers loading (available only from localhost requests)
Config[TMVCConfigKey.LoadSystemControllers] := 'true';
//default view file extension
Config[TMVCConfigKey.DefaultViewFileExtension] := 'html';
//view path
Config[TMVCConfigKey.ViewPath] := 'templates';
//Max Record Count for automatic Entities CRUD
Config[TMVCConfigKey.MaxEntitiesRecordCount] := '20';
//Enable Server Signature in response
Config[TMVCConfigKey.ExposeServerSignature] := 'true';
//Enable X-Powered-By Header in response
Config[TMVCConfigKey.ExposeXPoweredBy] := 'true';
// Max request size in bytes
Config[TMVCConfigKey.MaxRequestSize] := IntToStr(TMVCConstants.DEFAULT_MAX_REQUEST_SIZE);
end);
FMVC.AddController(TMyController);
// Analytics middleware generates a csv log, useful to do trafic analysis
//FMVC.AddMiddleware(TMVCAnalyticsMiddleware.Create(GetAnalyticsDefaultLogger));
// The folder mapped as documentroot for TMVCStaticFilesMiddleware must exists!
//FMVC.AddMiddleware(TMVCStaticFilesMiddleware.Create('/static', TPath.Combine(ExtractFilePath(GetModuleName(HInstance)), 'www')));
// Trace middlewares produces a much detailed log for debug purposes
//FMVC.AddMiddleware(TMVCTraceMiddleware.Create);
// CORS middleware handles... well, CORS
//FMVC.AddMiddleware(TMVCCORSMiddleware.Create);
// Simplifies TMVCActiveRecord connection definition
//FMVC.AddMiddleware(TMVCActiveRecordMiddleware.Create('MyConnDef','FDConnectionDefs.ini'));
// Compression middleware must be the last in the chain, just before the ETag, if present.
//FMVC.AddMiddleware(TMVCCompressionMiddleware.Create);
// ETag middleware must be the latest in the chain
//FMVC.AddMiddleware(TMVCETagMiddleware.Create);
end;
procedure TMyWebModule.WebModuleDestroy(Sender: TObject);
begin
FMVC.Free;
end;
end.

View File

@ -0,0 +1,111 @@
// ***************************************************************************
//
// Delphi MVC Framework
//
// Copyright (c) 2010-2022 Daniele Teti and the DMVCFramework Team
//
// https://github.com/danieleteti/delphimvcframework
//
// ***************************************************************************
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// *************************************************************************** }
unit MVCFramework.AsyncTask;
interface
uses
System.SysUtils,
System.Threading;
type
TAsyncBackgroundTask<T> = reference to function: T;
TAsyncSuccessCallback<T> = reference to procedure(const TaskResult: T);
TAsyncErrorCallback = reference to procedure(const E: Exception);
TAsyncDefaultErrorCallback = reference to procedure(const E: Exception;
const ExptAddress: Pointer);
Async = class sealed
public
class function Run<T>(
Task: TAsyncBackgroundTask<T>;
Success: TAsyncSuccessCallback<T>;
Error: TAsyncErrorCallback = nil): ITask;
end;
var
DefaultTaskErrorHandler: TAsyncDefaultErrorCallback = nil;
implementation
uses
System.Classes;
{ Async }
class function Async.Run<T>(Task: TAsyncBackgroundTask<T>;
Success: TAsyncSuccessCallback<T>;
Error: TAsyncErrorCallback): ITask;
var
LRes: T;
begin
Result := TTask.Run(
procedure
var
Ex: Pointer;
ExceptionAddress: Pointer;
begin
Ex := nil;
try
LRes := Task();
if Assigned(Success) then
begin
TThread.Queue(nil,
procedure
begin
Success(LRes);
end);
end;
except
Ex := AcquireExceptionObject;
ExceptionAddress := ExceptAddr;
TThread.Queue(nil,
procedure
var
LCurrException: Exception;
begin
LCurrException := Exception(Ex);
try
if Assigned(Error) then
Error(LCurrException)
else
DefaultTaskErrorHandler(LCurrException, ExceptionAddress);
finally
FreeAndNil(LCurrException);
end;
end);
end;
end);
end;
initialization
DefaultTaskErrorHandler :=
procedure(const E: Exception; const ExceptionAddress: Pointer)
begin
ShowException(E, ExceptionAddress);
end;
end.

View File

@ -36,31 +36,80 @@ uses
JsonDataObjects;
type
TJSONRPCResponseHandlerProc = reference to procedure(JSONRPCResponse: IJSONRPCResponse);
TJSONRPCErrorHandlerProc = reference to procedure(Exc: Exception);
IMVCJSONRPCExecutor = interface
['{55415094-9D28-4707-AEC5-5FCF925E82BC}']
function ExecuteRequest(const aJSONRPCRequest: IJSONRPCRequest; const UseVerb: TJSONRPCHTTPVerb = jrpcDefault)
: IJSONRPCResponse; overload;
function ExecuteRequest(const aLastEndPointSegment: string; const aJSONRPCRequest: IJSONRPCRequest;
//sync
function ExecuteRequest(
const aJSONRPCRequest: IJSONRPCRequest;
const UseVerb: TJSONRPCHTTPVerb = jrpcDefault): IJSONRPCResponse; overload;
function ExecuteNotification(const aJSONRPCNotification: IJSONRPCNotification;
function ExecuteRequest(
const aLastEndPointSegment: string;
const aJSONRPCRequest: IJSONRPCRequest;
const UseVerb: TJSONRPCHTTPVerb = jrpcDefault): IJSONRPCResponse; overload;
function ExecuteNotification(const aLastEndPointSegment: string; const aJSONRPCNotification: IJSONRPCNotification;
function ExecuteNotification(
const aJSONRPCNotification: IJSONRPCNotification;
const UseVerb: TJSONRPCHTTPVerb = jrpcDefault): IJSONRPCResponse; overload;
function ExecuteNotification(
const aLastEndPointSegment: string;
const aJSONRPCNotification: IJSONRPCNotification;
const UseVerb: TJSONRPCHTTPVerb = jrpcDefault): IJSONRPCResponse; overload;
//async
procedure InternalExecuteAsync(
const aEndPoint: string;
const aJSONRPCObject: IJSONRPCObject;
const AJSONRPCResponseHandler: TJSONRPCResponseHandlerProc;
const AJSONRPCErrorHandler: TJSONRPCErrorHandlerProc;
const UseVerb: TJSONRPCHTTPVerb = jrpcDefault);
procedure ExecuteRequestAsync(
const aJSONRPCRequest: IJSONRPCRequest;
const AJSONRPCResponseHandler: TJSONRPCResponseHandlerProc;
const AJSONRPCErrorHandler: TJSONRPCErrorHandlerProc = nil;
const UseVerb: TJSONRPCHTTPVerb = jrpcDefault); overload;
procedure ExecuteRequestAsync(
const aLastEndPointSegment: string;
const aJSONRPCRequest: IJSONRPCRequest;
const AJSONRPCResponseHandler: TJSONRPCResponseHandlerProc;
const AJSONRPCErrorHandler: TJSONRPCErrorHandlerProc = nil;
const UseVerb: TJSONRPCHTTPVerb = jrpcDefault); overload;
procedure ExecuteNotificationAsync(
const aJSONRPCNotification: IJSONRPCNotification;
const AJSONRPCErrorHandler: TJSONRPCErrorHandlerProc = nil;
const UseVerb: TJSONRPCHTTPVerb = jrpcDefault); overload;
procedure ExecuteNotificationAsync(
const aLastEndPointSegment: string;
const aJSONRPCNotification: IJSONRPCNotification;
const AJSONRPCErrorHandler: TJSONRPCErrorHandlerProc = nil;
const UseVerb: TJSONRPCHTTPVerb = jrpcDefault); overload;
// end async
function HTTPResponse: IHTTPResponse;
// Http headers handling
procedure AddHTTPHeader(const aNetHeader: TNetHeader);
procedure ClearHTTPHeaders;
function HTTPHeadersCount: Integer;
function SetOnReceiveData(const aOnReceiveData: TReceiveDataEvent): IMVCJSONRPCExecutor;
function SetOnReceiveResponse(const aOnReceiveResponseProc: TProc<IJSONRPCObject, IJSONRPCObject>)
: IMVCJSONRPCExecutor;
function SetOnSendCommand(const aOnSendCommandProc: TProc<IJSONRPCObject>): IMVCJSONRPCExecutor;
function SetOnNeedClientCertificate(const aOnNeedClientCertificate: TNeedClientCertificateEvent)
: IMVCJSONRPCExecutor;
function SetOnValidateServerCertificate(const aOnValidateServerCertificate: TValidateCertificateEvent)
: IMVCJSONRPCExecutor;
function SetOnReceiveHTTPResponse(const aOnReceiveHTTPResponse: TProc<IHTTPResponse>): IMVCJSONRPCExecutor;
function ConfigureHTTPClient(const aConfigProc: TProc<THTTPClient>): IMVCJSONRPCExecutor;
//events
//sync
function SetOnReceiveData(const aOnReceiveData: TReceiveDataEvent): IMVCJSONRPCExecutor;
function SetOnReceiveResponse(const aOnReceiveResponseProc: TProc<IJSONRPCObject, IJSONRPCObject>)
: IMVCJSONRPCExecutor;
function SetOnSendCommand(const aOnSendCommandProc: TProc<IJSONRPCObject>): IMVCJSONRPCExecutor;
function SetOnReceiveHTTPResponse(const aOnReceiveHTTPResponse: TProc<IHTTPResponse>): IMVCJSONRPCExecutor;
//async
function SetOnReceiveResponseAsync(const aOnReceiveResponseAsyncProc: TProc<IJSONRPCObject, IJSONRPCObject>)
: IMVCJSONRPCExecutor;
function SetOnSendCommandAsync(const aOnSendCommandAsyncProc: TProc<IJSONRPCObject>): IMVCJSONRPCExecutor;
function SetOnReceiveHTTPResponseAsync(const aOnReceiveHTTPResponseAsync: TProc<IHTTPResponse>): IMVCJSONRPCExecutor;
function SetOnBeginAsyncRequest(const Proc: TProc): IMVCJSONRPCExecutor;
function SetOnEndAsyncRequest(const Proc: TProc): IMVCJSONRPCExecutor;
//end events
end;
TMVCJSONRPCExecutor = class(TInterfacedObject, IMVCJSONRPCExecutor)
@ -71,27 +120,78 @@ type
fRaiseExceptionOnError: Boolean;
fHTTPRequestHeaders: TList<TNetHeader>;
fHTTPResponse: IHTTPResponse;
//the following sync events are used only with sync execution
fOnReceiveResponse: TProc<IJSONRPCObject, IJSONRPCObject>;
fOnReceiveHTTPResponse: TProc<IHTTPResponse>;
fOnSendCommand: TProc<IJSONRPCObject>;
//end sync events
//the following async events are used only with async execution
fOnReceiveHTTPResponseAsync: TProc<IHTTPResponse>;
fOnSendCommandAsync: TProc<IJSONRPCObject>;
fOnReceiveResponseAsync: TProc<IJSONRPCObject, IJSONRPCObject>;
fOnBeginAsyncRequest: TProc;
fOnEndAsyncRequest: TProc;
//end async events
function GetHTTPRequestHeaders: TList<TNetHeader>;
procedure DoBeginAsyncRequest;
procedure DoEndAsyncRequest;
protected
function GetQueryStringParameters(const aJSONRPCObject: IJSONRPCObject): String;
function HTTPResponse: IHTTPResponse;
function InternalExecute(const aEndPoint: string; const aJSONRPCObject: IJSONRPCObject;
//sync
function InternalExecute(
const aEndPoint: string;
const aJSONRPCObject: IJSONRPCObject;
const UseVerb: TJSONRPCHTTPVerb): IJSONRPCResponse;
function ExecuteRequest(const aJSONRPCRequest: IJSONRPCRequest; const UseVerb: TJSONRPCHTTPVerb)
: IJSONRPCResponse; overload;
function ExecuteRequest(const aLastEndPointSegment: string; const aJSONRPCRequest: IJSONRPCRequest;
function ExecuteRequest(
const aJSONRPCRequest: IJSONRPCRequest;
const UseVerb: TJSONRPCHTTPVerb): IJSONRPCResponse; overload;
function ExecuteRequest(
const aLastEndPointSegment: string;
const aJSONRPCRequest: IJSONRPCRequest;
const UseVerb: TJSONRPCHTTPVerb): IJSONRPCResponse; overload;
function ExecuteNotification(const aJSONRPCNotification: IJSONRPCNotification; const UseVerb: TJSONRPCHTTPVerb)
: IJSONRPCResponse; overload;
function ExecuteNotification(const aLastEndPointSegment: string; const aJSONRPCNotification: IJSONRPCNotification;
const UseVerb: TJSONRPCHTTPVerb): IJSONRPCResponse; overload;
//async
procedure InternalExecuteAsync(
const AEndPoint: string;
const AJSONRPCObject: IJSONRPCObject;
const AJSONRPCResponseHandler: TJSONRPCResponseHandlerProc;
const AJSONRPCErrorHandler: TJSONRPCErrorHandlerProc;
const UseVerb: TJSONRPCHTTPVerb);
procedure ExecuteRequestAsync(
const aJSONRPCRequest: IJSONRPCRequest;
const AJSONRPCResponseHandler: TJSONRPCResponseHandlerProc;
const AJSONRPCErrorHandler: TJSONRPCErrorHandlerProc;
const UseVerb: TJSONRPCHTTPVerb); overload;
procedure ExecuteRequestAsync(
const aLastEndPointSegment: string;
const AJSONRPCRequest: IJSONRPCRequest;
const AJSONRPCResponseHandler: TJSONRPCResponseHandlerProc;
const AJSONRPCErrorHandler: TJSONRPCErrorHandlerProc;
const UseVerb: TJSONRPCHTTPVerb); overload;
procedure ExecuteNotificationAsync(
const AJSONRPCNotification: IJSONRPCNotification;
const AJSONRPCErrorHandler: TJSONRPCErrorHandlerProc;
const UseVerb: TJSONRPCHTTPVerb); overload;
procedure ExecuteNotificationAsync(
const ALastEndPointSegment: string;
const AJSONRPCNotification: IJSONRPCNotification;
const AJSONRPCErrorHandler: TJSONRPCErrorHandlerProc;
const UseVerb: TJSONRPCHTTPVerb); overload;
function SetOnBeginAsyncRequest(const Proc: TProc): IMVCJSONRPCExecutor;
function SetOnEndAsyncRequest(const Proc: TProc): IMVCJSONRPCExecutor;
// Http headers handling
procedure AddHTTPHeader(const aNetHeader: TNetHeader);
procedure ClearHTTPHeaders;
function HTTPHeadersCount: Integer;
//events
//sync
function SetOnReceiveData(const aOnReceiveData: TReceiveDataEvent): IMVCJSONRPCExecutor;
function SetOnReceiveResponse(const aOnReceiveResponseProc: TProc<IJSONRPCObject, IJSONRPCObject>)
: IMVCJSONRPCExecutor;
@ -101,9 +201,15 @@ type
function SetOnValidateServerCertificate(const aOnValidateServerCertificate: TValidateCertificateEvent)
: IMVCJSONRPCExecutor;
function SetOnReceiveHTTPResponse(const aOnReceiveHTTPResponse: TProc<IHTTPResponse>): IMVCJSONRPCExecutor;
//async
function SetOnReceiveResponseAsync(const aOnReceiveResponseAsyncProc: TProc<IJSONRPCObject, IJSONRPCObject>): IMVCJSONRPCExecutor;
function SetOnSendCommandAsync(const aOnSendCommandAsyncProc: TProc<IJSONRPCObject>): IMVCJSONRPCExecutor;
function SetOnReceiveHTTPResponseAsync(const aOnReceiveHTTPResponseAsync: TProc<IHTTPResponse>): IMVCJSONRPCExecutor;
//end events
function ConfigureHTTPClient(const aConfigProc: TProc<THTTPClient>): IMVCJSONRPCExecutor;
public
constructor Create(const aURL: string; const aRaiseExceptionOnError: Boolean = True;
constructor Create(const aURL: string;
const aRaiseExceptionOnError: Boolean = True;
const aDefaultHTTPVerb: TJSONRPCHTTPVerb = jrpcDefault); virtual;
destructor Destroy; override;
end;
@ -111,7 +217,7 @@ type
implementation
uses
System.Classes;
System.Classes, System.Types, MVCFramework.AsyncTask;
procedure JSONRPCExec(const aJSONRPCURL: string; const aJSONRPCRequest: IJSONRPCRequest;
out aJSONRPCResponse: IJSONRPCResponse);
@ -174,7 +280,10 @@ begin
fHTTP.ResponseTimeout := MaxInt;
{$ENDIF}
fHTTPRequestHeaders := nil;
SetOnReceiveResponse(nil).SetOnReceiveData(nil).SetOnNeedClientCertificate(nil).SetOnValidateServerCertificate(nil);
SetOnReceiveResponse(nil)
.SetOnReceiveData(nil)
.SetOnNeedClientCertificate(nil)
.SetOnValidateServerCertificate(nil);
end;
destructor TMVCJSONRPCExecutor.Destroy;
@ -184,6 +293,30 @@ begin
inherited;
end;
procedure TMVCJSONRPCExecutor.DoBeginAsyncRequest;
begin
if Assigned(fOnBeginAsyncRequest) then
begin
TThread.Queue(nil,
procedure
begin
fOnBeginAsyncRequest();
end);
end;
end;
procedure TMVCJSONRPCExecutor.DoEndAsyncRequest;
begin
if Assigned(fOnEndAsyncRequest) then
begin
TThread.Queue(nil,
procedure
begin
fOnEndAsyncRequest();
end);
end;
end;
function TMVCJSONRPCExecutor.ExecuteNotification(const aJSONRPCNotification: IJSONRPCNotification;
const UseVerb: TJSONRPCHTTPVerb): IJSONRPCResponse;
begin
@ -246,7 +379,9 @@ begin
end;
end;
function TMVCJSONRPCExecutor.InternalExecute(const aEndPoint: string; const aJSONRPCObject: IJSONRPCObject;
function TMVCJSONRPCExecutor.InternalExecute(
const aEndPoint: string;
const aJSONRPCObject: IJSONRPCObject;
const UseVerb: TJSONRPCHTTPVerb): IJSONRPCResponse;
var
lSS: TStringStream;
@ -328,11 +463,161 @@ begin
end;
end;
procedure TMVCJSONRPCExecutor.InternalExecuteAsync(
const AEndPoint: string;
const AJSONRPCObject: IJSONRPCObject;
const AJSONRPCResponseHandler: TJSONRPCResponseHandlerProc;
const AJSONRPCErrorHandler: TJSONRPCErrorHandlerProc;
const UseVerb: TJSONRPCHTTPVerb);
var
lCustomHeaders: TNetHeaders;
lProc: TProc;
begin
lCustomHeaders := [];
if Assigned(fHTTPRequestHeaders) then
begin
lCustomHeaders := fHTTPRequestHeaders.ToArray;
end;
lProc := procedure
var
lSS: TStringStream;
lHttpResp: IHTTPResponse;
lJSONRPCResponse: IJSONRPCResponse;
lEx: Pointer;
lExceptionAddress: Pointer;
lHTTP: THTTPClient;
begin
lHTTP := THTTPClient.Create;
try
lHTTP.OnNeedClientCertificate := fHTTP.OnNeedClientCertificate;
lHTTP.OnReceiveData := fHTTP.OnReceiveData;
lHTTP.OnValidateServerCertificate := fHTTP.OnValidateServerCertificate;
lSS := TStringStream.Create(AJSONRPCObject.AsJSONString, TEncoding.UTF8);
try
lSS.Position := 0;
fHTTPResponse := nil;
try
DoBeginAsyncRequest;
try
if Assigned(fOnSendCommandAsync) then
begin
fOnSendCommandAsync(AJSONRPCObject);
end;
case UseVerb of
jrpcPOST, jrpcDefault:
begin
lHttpResp := lHTTP.Post(fURL + aEndPoint, lSS, nil,
[TNetHeader.Create('content-type', 'application/json;charset=utf8'), TNetHeader.Create('accept',
'application/json;charset=utf8')] + lCustomHeaders);
end;
jrpcGET:
begin
lHttpResp := lHTTP.Get(fURL + aEndPoint + '?' + GetQueryStringParameters(AJSONRPCObject), nil,
[TNetHeader.Create('accept', 'application/json;charset=utf8')] + lCustomHeaders);
end;
end;
if Assigned(fOnReceiveHTTPResponseAsync) then
begin
fOnReceiveHTTPResponseAsync(lHttpResp);
end;
lJSONRPCResponse := nil;
if lHttpResp.StatusCode = HTTP_STATUS.NoContent then
begin
lJSONRPCResponse := TJSONRPCNullResponse.Create;
end
else
begin
if lHttpResp.HeaderValue['content-type'].Contains(TMVCMediaType.APPLICATION_JSON) then
begin
lJSONRPCResponse := TJSONRPCResponse.Create;
lJSONRPCResponse.AsJSONString := lHttpResp.ContentAsString;
end
else
begin
raise EMVCJSONRPCProtocolException.CreateFmt(
'Expected content-type "%s", got "%s"',
[
TMVCMediaType.APPLICATION_JSON,
lHttpResp.HeaderValue['content-type']
]);
end;
end;
if Assigned(fOnReceiveResponseAsync) then
begin
fOnReceiveResponseAsync(aJSONRPCObject, lJSONRPCResponse);
end;
if Assigned(lJSONRPCResponse.Error) then
begin
raise EMVCJSONRPCRemoteException.Create(
lJSONRPCResponse.Error.Code,
lJSONRPCResponse.Error.ErrMessage,
lJSONRPCResponse.Error.Data
);
end;
finally
DoEndAsyncRequest;
end;
if Assigned(AJSONRPCResponseHandler) then
begin
TThread.Queue(nil,
procedure
begin
AJSONRPCResponseHandler(lJSONRPCResponse);
end);
end;
except
lEx := AcquireExceptionObject;
lExceptionAddress := ExceptAddr;
TThread.Queue(nil,
procedure
var
lCurrException: Exception;
begin
lCurrException := Exception(lEx);
try
if Assigned(AJSONRPCErrorHandler) then
AJSONRPCErrorHandler(lCurrException)
else
DefaultTaskErrorHandler(lCurrException, lExceptionAddress);
finally
FreeAndNil(lCurrException);
end;
end);
end;
finally
lSS.Free;
end;
finally
lHTTP.Free;
end;
end; //end proc
TThread.CreateAnonymousThread(lProc).Start;
end;
function TMVCJSONRPCExecutor.HTTPResponse: IHTTPResponse;
begin
Result := fHTTPResponse;
end;
function TMVCJSONRPCExecutor.SetOnBeginAsyncRequest(
const Proc: TProc): IMVCJSONRPCExecutor;
begin
fOnBeginAsyncRequest := Proc;
Result := Self;
end;
function TMVCJSONRPCExecutor.SetOnEndAsyncRequest(
const Proc: TProc): IMVCJSONRPCExecutor;
begin
fOnEndAsyncRequest := Proc;
Result := Self;
end;
function TMVCJSONRPCExecutor.SetOnNeedClientCertificate(const aOnNeedClientCertificate: TNeedClientCertificateEvent)
: IMVCJSONRPCExecutor;
begin
@ -346,6 +631,7 @@ begin
Result := Self;
end;
function TMVCJSONRPCExecutor.SetOnReceiveHTTPResponse(const aOnReceiveHTTPResponse: TProc<IHTTPResponse>)
: IMVCJSONRPCExecutor;
begin
@ -353,6 +639,13 @@ begin
Result := Self;
end;
function TMVCJSONRPCExecutor.SetOnReceiveHTTPResponseAsync(
const aOnReceiveHTTPResponseAsync: TProc<IHTTPResponse>): IMVCJSONRPCExecutor;
begin
fOnReceiveHTTPResponseAsync := aOnReceiveHTTPResponseAsync;
Result := Self;
end;
function TMVCJSONRPCExecutor.SetOnReceiveResponse(const aOnReceiveResponseProc: TProc<IJSONRPCObject, IJSONRPCObject>)
: IMVCJSONRPCExecutor;
begin
@ -360,12 +653,26 @@ begin
Result := Self;
end;
function TMVCJSONRPCExecutor.SetOnReceiveResponseAsync(
const aOnReceiveResponseAsyncProc: TProc<IJSONRPCObject, IJSONRPCObject>): IMVCJSONRPCExecutor;
begin
fOnReceiveResponseAsync := aOnReceiveResponseAsyncProc;
Result := Self;
end;
function TMVCJSONRPCExecutor.SetOnSendCommand(const aOnSendCommandProc: TProc<IJSONRPCObject>): IMVCJSONRPCExecutor;
begin
fOnSendCommand := aOnSendCommandProc;
Result := Self;
end;
function TMVCJSONRPCExecutor.SetOnSendCommandAsync(
const aOnSendCommandAsyncProc: TProc<IJSONRPCObject>): IMVCJSONRPCExecutor;
begin
fOnSendCommandAsync := aOnSendCommandAsyncProc;
Result := Self;
end;
function TMVCJSONRPCExecutor.SetOnValidateServerCertificate(const aOnValidateServerCertificate
: TValidateCertificateEvent): IMVCJSONRPCExecutor;
begin
@ -379,10 +686,45 @@ begin
Result := InternalExecute(aLastEndPointSegment, aJSONRPCNotification as TJSONRPCObject, UseVerb);
end;
procedure TMVCJSONRPCExecutor.ExecuteNotificationAsync(
const aJSONRPCNotification: IJSONRPCNotification;
const AJSONRPCErrorHandler: TJSONRPCErrorHandlerProc;
const UseVerb: TJSONRPCHTTPVerb);
begin
ExecuteNotificationAsync('', aJSONRPCNotification, AJSONRPCErrorHandler, UseVerb);
end;
procedure TMVCJSONRPCExecutor.ExecuteNotificationAsync(
const aLastEndPointSegment: string;
const aJSONRPCNotification: IJSONRPCNotification;
const AJSONRPCErrorHandler: TJSONRPCErrorHandlerProc;
const UseVerb: TJSONRPCHTTPVerb);
begin
InternalExecuteAsync(aLastEndPointSegment, aJSONRPCNotification as TJSONRPCObject, nil, AJSONRPCErrorHandler, UseVerb);
end;
function TMVCJSONRPCExecutor.ExecuteRequest(const aLastEndPointSegment: string; const aJSONRPCRequest: IJSONRPCRequest;
const UseVerb: TJSONRPCHTTPVerb): IJSONRPCResponse;
begin
Result := InternalExecute(aLastEndPointSegment, aJSONRPCRequest, UseVerb);
end;
procedure TMVCJSONRPCExecutor.ExecuteRequestAsync(
const aLastEndPointSegment: string; const aJSONRPCRequest: IJSONRPCRequest;
const AJSONRPCResponseHandler: TJSONRPCResponseHandlerProc;
const AJSONRPCErrorHandler: TJSONRPCErrorHandlerProc;
const UseVerb: TJSONRPCHTTPVerb);
begin
InternalExecuteAsync(aLastEndPointSegment, aJSONRPCRequest, AJSONRPCResponseHandler, AJSONRPCErrorHandler, UseVerb);
end;
procedure TMVCJSONRPCExecutor.ExecuteRequestAsync(
const AJSONRPCRequest: IJSONRPCRequest;
const AJSONRPCResponseHandler: TJSONRPCResponseHandlerProc;
const AJSONRPCErrorHandler: TJSONRPCErrorHandlerProc;
const UseVerb: TJSONRPCHTTPVerb);
begin
ExecuteRequestAsync('', aJSONRPCRequest, AJSONRPCResponseHandler, AJSONRPCErrorHandler, UseVerb);
end;
end.

View File

@ -306,6 +306,7 @@ type
function GetError: TJSONRPCResponseError;
function GetID: TValue;
function GetResult: TValue;
procedure CheckForError;
function ResultAsJSONObject: TJDOJsonObject;
function ResultAsJSONArray: TJDOJsonArray;
function IsError: Boolean;
@ -335,6 +336,9 @@ type
property ErrMessage: String read fErrMessage;
end;
EMVCJSONRPCProtocolException = class(EMVCJSONRPCRemoteException)
end;
EMVCJSONRPCErrorResponse = class abstract(Exception)
protected
@ -2182,7 +2186,6 @@ begin
end;
{ TJSONRCPResponse }
constructor TJSONRPCResponse.Create;
begin
inherited;
@ -2699,6 +2702,11 @@ end;
{ TJSONRPCNullResponse }
procedure TJSONRPCNullResponse.CheckForError;
begin
end;
function TJSONRPCNullResponse.GetError: TJSONRPCResponseError;
begin
Result := FError;

View File

@ -32,6 +32,7 @@ uses
System.Classes,
System.SysUtils,
MVCFramework.Commons,
System.Diagnostics,
LoggerPro,
LoggerPro.FileAppender;
@ -41,6 +42,23 @@ const
type
TLogLevel = (levDebug = 0, levNormal = 1, levWarning = 2, levError = 3, levException = 4);
{$IF Defined(SYDNEYORBETTER)}
Profiler = record
private
fMessage: string;
fStopWatch: TStopWatch;
fIndent: string;
public
class operator Finalize(var Dest: Profiler);
constructor Start(const Message: string); overload;
constructor Start(const Message: string; const Params: array of TVarRec); overload;
constructor Start(const Message: string; const Params: array of TVarRec; const TAG: String); overload;
class var ProfileLogger: ILogWriter;
class var LoggerTag: String;
end;
{$ENDIF}
function LogLevelAsString(ALogLevel: TLogLevel): string;
procedure Log(AMessage: string); overload;
procedure Log(AObject: TObject); overload;
@ -72,6 +90,8 @@ procedure InitializeDefaultLogger;
}
procedure ReleaseGlobalLogger;
procedure InitThreadVars;
var
LogLevelLimit: TLogLevel = TLogLevel.levNormal;
@ -82,6 +102,12 @@ uses
MVCFramework.Serializer.JsonDataObjects,
MVCFramework.DuckTyping;
{$IF Defined(SYDNEYORBETTER)}
threadvar
gIndent: NativeUInt;
gReqNr: NativeUInt;
{$ENDIF}
var
_lock: TObject;
_DefaultLogger: ILogWriter;
@ -103,64 +129,66 @@ var
)
);
function Log: ILogWriter;
begin
if _DefaultLogger = nil then
begin
SetDefaultLogger(nil);
end;
if _DefaultLogger = nil then
begin
SetDefaultLogger(nil);
end;
Result := _DefaultLogger;
Result := _DefaultLogger;
end;
function LogLevelAsString(ALogLevel: TLogLevel): string;
begin
case ALogLevel of
levNormal:
Result := ''; // normal is '' because is more readable
levWarning:
Result := 'WARNING';
levError:
Result := 'ERROR';
levException:
Result := 'EXCEPTION';
else
Result := 'UNKNOWN';
end;
case ALogLevel of
levNormal:
Result := ''; // normal is '' because is more readable
levWarning:
Result := 'WARNING';
levError:
Result := 'ERROR';
levException:
Result := 'EXCEPTION';
else
Result := 'UNKNOWN';
end;
end;
function ObjectToJSON(const AObject: TObject): String;
var
lSer: TMVCJsonDataObjectsSerializer;
begin
lSer := TMVCJsonDataObjectsSerializer.Create;
try
if TDuckTypedList.CanBeWrappedAsList(AObject) then
begin
Result := '[' + AObject.QualifiedClassName + '] ' + lSer.SerializeCollection(AObject);
end
else
begin
Result := '[' + AObject.QualifiedClassName + '] ' + lSer.SerializeObject(AObject);
lSer := TMVCJsonDataObjectsSerializer.Create;
try
if TDuckTypedList.CanBeWrappedAsList(AObject) then
begin
Result := '[' + AObject.QualifiedClassName + '] ' + lSer.SerializeCollection(AObject);
end
else
begin
Result := '[' + AObject.QualifiedClassName + '] ' + lSer.SerializeObject(AObject);
end;
finally
lSer.Free;
end;
finally
lSer.Free;
end;
end;
procedure LogW(AMessage: string);
begin
Log.Warn(AMessage, LOGGERPRO_TAG);
Log.Warn(AMessage, LOGGERPRO_TAG);
end;
procedure LogE(AMessage: string);
begin
Log.Error(AMessage, LOGGERPRO_TAG);
Log.Error(AMessage, LOGGERPRO_TAG);
end;
procedure LogException(const E: Exception; const AMessage: String);
begin
LogE(E.ClassName + ': ' + AMessage);
LogE(E.ClassName + ': ' + AMessage);
end;
// procedure LogException(
@ -173,166 +201,224 @@ end;
procedure LogEnterMethod(const AMethodName: string);
begin
LogI('>> ' + AMethodName);
LogI('>> ' + AMethodName);
end;
procedure LogExitMethod(const AMethodName: string);
begin
LogI('<< ' + AMethodName);
LogI('<< ' + AMethodName);
end;
procedure Log(LogLevel: TLogLevel; const AMessage: string);
begin
case _LevelsMap[LogLevel] of
TLogType.Debug:
Log.Debug(AMessage, LOGGERPRO_TAG);
TLogType.Info:
Log.Info(AMessage, LOGGERPRO_TAG);
TLogType.Warning:
Log.Warn(AMessage, LOGGERPRO_TAG);
TLogType.Error:
Log.Error(AMessage, LOGGERPRO_TAG);
else
raise Exception.Create('Invalid LOG LEVEL! Original message was: ' + AMessage);
end;
case _LevelsMap[LogLevel] of
TLogType.Debug:
Log.Debug(AMessage, LOGGERPRO_TAG);
TLogType.Info:
Log.Info(AMessage, LOGGERPRO_TAG);
TLogType.Warning:
Log.Warn(AMessage, LOGGERPRO_TAG);
TLogType.Error:
Log.Error(AMessage, LOGGERPRO_TAG);
else
raise Exception.Create('Invalid LOG LEVEL! Original message was: ' + AMessage);
end;
end;
procedure Log(AMessage: string); overload;
begin
LogI(AMessage);
LogI(AMessage);
end;
procedure Log(AObject: TObject); overload;
begin
Log(ObjectToJSON(AObject));
Log(ObjectToJSON(AObject));
end;
procedure LogI(AMessage: string); overload;
begin
Log.Info(AMessage, LOGGERPRO_TAG);
Log.Info(AMessage, LOGGERPRO_TAG);
end;
procedure LogD(AMessage: string); overload;
begin
Log.Debug(AMessage, LOGGERPRO_TAG);
Log.Debug(AMessage, LOGGERPRO_TAG);
end;
procedure LogD(AMessage: TObject); overload;
begin
LogD(ObjectToJSON(AMessage));
LogD(ObjectToJSON(AMessage));
end;
procedure LogI(AObject: TObject); overload;
begin
LogI(ObjectToJSON(AObject));
LogI(ObjectToJSON(AObject));
end;
procedure LogW(AObject: TObject); overload;
begin
LogW(ObjectToJSON(AObject));
LogW(ObjectToJSON(AObject));
end;
procedure SetDefaultLogger(const aLogWriter: ILogWriter);
begin
if _DefaultLogger = nil then
begin
TMonitor.Enter(_lock); // double check here
try
if _DefaultLogger = nil then
begin
if aLogWriter <> nil then
if _DefaultLogger = nil then
begin
TMonitor.Enter(_lock); // double check here
try
if _DefaultLogger = nil then
begin
_DefaultLogger := aLogWriter;
Log.Info('Custom Logger initialized', LOGGERPRO_TAG);
end
else
begin
InitializeDefaultLogger;
Log.Info('Default Logger initialized', LOGGERPRO_TAG);
if aLogWriter <> nil then
begin
_DefaultLogger := aLogWriter;
Log.Info('Custom Logger initialized', LOGGERPRO_TAG);
end
else
begin
InitializeDefaultLogger;
Log.Info('Default Logger initialized', LOGGERPRO_TAG);
end;
end;
finally
TMonitor.Exit(_lock);
end;
finally
TMonitor.Exit(_lock);
end;
end;
end;
procedure InitializeDefaultLogger;
var
lLogsFolder: String;
begin
{ This procedure must be called in a synchronized context
(Normally only SetDefaultLogger should be the caller) }
if not Assigned(_DefaultLogger) then
begin
{ This procedure must be called in a synchronized context
(Normally only SetDefaultLogger should be the caller) }
if not Assigned(_DefaultLogger) then
begin
{$IF NOT DEFINED(MOBILE)}
lLogsFolder := AppPath + 'logs';
lLogsFolder := AppPath + 'logs';
{$ELSE}
lLogsFolder := TPath.Combine(TPath.GetDocumentsPath, 'logs');
lLogsFolder := TPath.Combine(TPath.GetDocumentsPath, 'logs');
{$ENDIF}
_DefaultLogger := BuildLogWriter([TLoggerProFileAppender.Create(5, 2000, lLogsFolder)]);
end;
_DefaultLogger := BuildLogWriter([TLoggerProFileAppender.Create(5, 2000, lLogsFolder)]);
end;
end;
procedure ReleaseGlobalLogger;
begin
if _DefaultLogger <> nil then
begin
TMonitor.Enter(_lock);
try
if _DefaultLogger <> nil then // double check
begin
_DefaultLogger := nil;
if _DefaultLogger <> nil then
begin
TMonitor.Enter(_lock);
try
if _DefaultLogger <> nil then // double check
begin
_DefaultLogger := nil;
end;
finally
TMonitor.Exit(_lock);
end;
finally
TMonitor.Exit(_lock);
end;
end;
end;
{ *************** PROFILER ***************** }
{ *************** PROFILER ***************** }
{ *************** PROFILER ***************** }
{$IF Defined(SYDNEYORBETTER)}
constructor Profiler.Start(const Message: string; const Params: array of TVarRec);
begin
Start(Message, Params, LoggerTag);
end;
constructor Profiler.Start(const Message: string; const Params: array of TVarRec; const TAG: String);
begin
if Profiler.ProfileLogger = nil then
Exit;
fMessage := Format(Message, Params);
fStopWatch := TStopWatch.StartNew;
fIndent := StringOfChar(' ', gIndent);
Inc(gReqNr);
ProfileLogger.Info('[%s>>][%6d][%s]', [
fIndent,
gReqNr,
fMessage], TAG);
Inc(gIndent);
end;
class operator Profiler.Finalize(var Dest: Profiler);
begin
if Profiler.ProfileLogger = nil then
Exit;
ProfileLogger.Info('[%s<<][%6d][%s][ELAPSED: %s]', [
Dest.fIndent,
gReqNr,
Dest.fMessage,
Dest.fStopWatch.Elapsed.ToString], LoggerTag);
Dec(gIndent);
Dec(gReqNr);
end;
constructor Profiler.Start(const Message: string);
begin
Start(Message, []);
end;
{$ENDIF}
procedure InitThreadVars;
begin
{$IF Defined(SYDNEYORBETTER)}
gIndent := 0;
gReqNr := 0;
{$ENDIF}
end;
initialization
_lock := TObject.Create;
_lock := TObject.Create;
{ The TLoggerProFileAppender has its defaults defined as follows:
DEFAULT_LOG_FORMAT = '%0:s [TID %1:-8d][%2:-10s] %3:s [%4:s]';
DEFAULT_MAX_BACKUP_FILE_COUNT = 5;
DEFAULT_MAX_FILE_SIZE_KB = 1000;
{$IF Defined(SYDNEYORBETTER)}
Profiler.LoggerTag := 'profiler';
{$ENDIF}
{ The TLoggerProFileAppender has its defaults defined as follows:
DEFAULT_LOG_FORMAT = '%0:s [TID %1:-8d][%2:-10s] %3:s [%4:s]';
DEFAULT_MAX_BACKUP_FILE_COUNT = 5;
DEFAULT_MAX_FILE_SIZE_KB = 1000;
You can override these dafaults passing parameters to the constructor.
Here's some configuration examples:
@longcode(#
// Creates log in the same exe folder without PID in the filename
_Log := BuildLogWriter([TLoggerProFileAppender.Create(10, 5,
[TFileAppenderOption.LogsInTheSameFolder])]);
You can override these dafaults passing parameters to the constructor.
Here's some configuration examples:
@longcode(#
// Creates log in the same exe folder without PID in the filename
_Log := BuildLogWriter([TLoggerProFileAppender.Create(10, 5,
[TFileAppenderOption.LogsInTheSameFolder])]);
// Creates log in the AppData/Roaming with PID in the filename
_Log := BuildLogWriter([TLoggerProFileAppender.Create(10, 5,
[TFileAppenderOption.IncludePID])]);
// Creates log in the same folder with PID in the filename
_Log := BuildLogWriter([TLoggerProFileAppender.Create(10, 5,
[TFileAppenderOption.IncludePID])]);
#)
}
// Creates log in the ..\..\ folder without PID in the filename
// DefaultDMVCFrameworkLogger := BuildLogWriter([TLoggerProFileAppender.Create(10, 5)]);
// Create logs in the exe' same folder
// _Log := BuildLogWriter([TLoggerProFileAppender.Create(10, 5)]);
// Creates log in the AppData/Roaming with PID in the filename
_Log := BuildLogWriter([TLoggerProFileAppender.Create(10, 5,
[TFileAppenderOption.IncludePID])]);
// _Log := BuildLogWriter([TLoggerProFileAppender.Create(10, 5,
// [TFileAppenderOption.IncludePID])]);
// Creates log in the same folder with PID in the filename
_Log := BuildLogWriter([TLoggerProFileAppender.Create(10, 5,
[TFileAppenderOption.IncludePID])]);
#)
}
// _Log := BuildLogWriter([TLoggerProFileAppender.Create(10, 5,
// [TFileAppenderOption.IncludePID])]);
// Creates log in the ..\..\ folder without PID in the filename
// DefaultDMVCFrameworkLogger := BuildLogWriter([TLoggerProFileAppender.Create(10, 5)]);
// Create logs in the exe' same folder
// _Log := BuildLogWriter([TLoggerProFileAppender.Create(10, 5)]);
// Creates log in the AppData/Roaming with PID in the filename
// _Log := BuildLogWriter([TLoggerProFileAppender.Create(10, 5,
// [TFileAppenderOption.IncludePID])]);
// Creates log in the same folder with PID in the filename
// _Log := BuildLogWriter([TLoggerProFileAppender.Create(10, 5,
// [TFileAppenderOption.IncludePID])]);
finalization
_lock.Free;
_lock.Free;
end.

View File

@ -536,6 +536,7 @@ type
function GetIntfObject: IInterface;
procedure SetIntfObject(const Value: IInterface);
protected
fActionQualifiedName: String;
procedure Flush; virtual;
procedure BindToSession(const ASessionId: string);
function SendSessionCookie(const AContext: TWebContext): string;
@ -564,6 +565,7 @@ type
property Data: TMVCStringDictionary read GetData;
property CustomIntfObject: IInterface read GetIntfObject write SetIntfObject;
property ParamsTable: TMVCRequestParamsTable read GetParamsTable write SetParamsTable;
property ActionQualifiedName: String read fActionQualifiedName;
end;
TMVCJSONRPCExceptionErrorInfo = record
@ -2396,6 +2398,8 @@ var
lHandled: Boolean;
lResponseContentMediaType: string;
lResponseContentCharset: string;
lRouterMethodToCallName: string;
lRouterControllerClazzQualifiedClassName: string;
lSelectedController: TMVCController;
lActionFormalParams: TArray<TRttiParameter>;
lActualParams: TArray<TValue>;
@ -2457,12 +2461,21 @@ begin
'Cannot create controller');
end;
end;
lRouterMethodToCallName := lRouter.MethodToCall.Name;
lRouterControllerClazzQualifiedClassName := lRouter.ControllerClazz.QualifiedClassName;
MVCFramework.Logger.InitThreadVars;
lContext.fActionQualifiedName := lRouterControllerClazzQualifiedClassName + '.'+ lRouterMethodToCallName;
lSelectedController.Engine := Self;
lSelectedController.Context := lContext;
lSelectedController.ApplicationSession := FApplicationSession;
lContext.ParamsTable := lParamsTable;
ExecuteBeforeControllerActionMiddleware(lContext,
lRouter.ControllerClazz.QualifiedClassName, lRouter.MethodToCall.name, lHandled);
ExecuteBeforeControllerActionMiddleware(
lContext,
lRouterControllerClazzQualifiedClassName,
lRouterMethodToCallName,
lHandled);
if lHandled then
Exit(True);
@ -2485,15 +2498,15 @@ begin
else
begin
FillActualParamsForAction(lSelectedController, lContext, lActionFormalParams,
lRouter.MethodToCall.name, lActualParams, lBodyParameter);
lRouterMethodToCallName, lActualParams, lBodyParameter);
end;
lSelectedController.OnBeforeAction(lContext, lRouter.MethodToCall.name, lHandled);
lSelectedController.OnBeforeAction(lContext, lRouterMethodToCallName, lHandled);
if not lHandled then
begin
try
lRouter.MethodToCall.Invoke(lSelectedController, lActualParams);
finally
lSelectedController.OnAfterAction(lContext, lRouter.MethodToCall.name);
lSelectedController.OnAfterAction(lContext, lRouterMethodToCallName);
end;
end;
finally
@ -2509,8 +2522,8 @@ begin
lSelectedController.MVCControllerBeforeDestroy;
end;
ExecuteAfterControllerActionMiddleware(lContext,
lRouter.ControllerClazz.QualifiedClassName,
lRouter.MethodToCall.name,
lRouterControllerClazzQualifiedClassName,
lRouterMethodToCallName,
lHandled);
lContext.Response.ContentType := lSelectedController.ContentType;
fOnRouterLog(lRouter, rlsRouteFound, lContext);