diff --git a/.gitignore b/.gitignore index 411d866..5638b57 100644 --- a/.gitignore +++ b/.gitignore @@ -56,3 +56,4 @@ __history/ # Castalia statistics file *.stat dunitx-results.xml +*.res diff --git a/Examples/PurchaseProcess/PurchaseProcess.Bus.pas b/Examples/PurchaseProcess/PurchaseProcess.Bus.pas new file mode 100755 index 0000000..a20642d --- /dev/null +++ b/Examples/PurchaseProcess/PurchaseProcess.Bus.pas @@ -0,0 +1,122 @@ +unit PurchaseProcess.Bus; + +interface + +uses + System.Classes, + System.Generics.Collections, + System.SysUtils, + PurchaseProcess.Types; + +type + TBus = class( TInterfacedPersistent, IBus, IOrderChannel ) + private + FMachines : TObjectDictionary; + FOrders : TObjectDictionary; + FResources: TDictionary; + public + constructor Create; + destructor Destroy; override; + + procedure RegisterResource( const AResource: TResource ); + procedure Dispatch( + const ATransition: TOrderSM.TTransition; + const AOrderId : TOrderId ); + procedure SendMessage( + const AOrderMessage: TOrderMessage; + const AOrderEvent : TOrderEvent ); + end; + +implementation + +uses + Stateless.Utils, + PurchaseProcess.MachineFactory; + +{ TBus } + +constructor TBus.Create; +begin + inherited; + FMachines := TObjectDictionary.Create( [ doOwnsValues ] ); + FOrders := TObjectDictionary.Create( [ doOwnsValues ] ); + FResources := TDictionary.Create; +end; + +destructor TBus.Destroy; +begin + FResources.Free; + FOrders.Free; + FMachines.Free; + inherited; +end; + +procedure TBus.Dispatch( + const ATransition: TOrderSM.TTransition; + const AOrderId : TOrderId ); +begin +{$IFDEF DEBUG}Writeln( 'LOG Dispatch( ', ATransition.ToString, ', ', AOrderId, ' )' ); {$ENDIF} + case ATransition.Destination of + osNoOrder: + begin + FMachines.Remove( AOrderId ); + FOrders.Remove( AOrderId ); + end; + osEmpty: + begin + if not FResources.ContainsKey( ortShop ) + then + raise EInvalidOpException.Create( 'does not contain shop' ); + FResources[ ortShop ].ReceiveMessage( FOrders[ AOrderId ] ); + end; + osFilled: + begin + if not FResources.ContainsKey( ortSeller ) + then + raise EInvalidOpException.Create( 'does not contain seller' ); + FResources[ ortSeller ].ReceiveMessage( FOrders[ AOrderId ] ); + end; + osPaid: + begin + if not FResources.ContainsKey( ortSender ) + then + raise EInvalidOpException.Create( 'does not contain sender' ); + FResources[ ortSender ].ReceiveMessage( FOrders[ AOrderId ] ); + end; + else + raise ENotImplemented.CreateFmt( 'Dispatch for "%s" not implemented', [ TEnum.AsString( ATransition.Destination ) ] ); + end; +end; + +procedure TBus.RegisterResource( const AResource: TResource ); +begin + FResources.Add( AResource.ResourceType, AResource ); +end; + +procedure TBus.SendMessage( + const AOrderMessage: TOrderMessage; + const AOrderEvent : TOrderEvent ); +begin +{$IFDEF DEBUG}Writeln( 'LOG SendMessage( ', AOrderMessage.OrderId, ', ', TEnum.AsString( AOrderEvent ), ' )' ); {$ENDIF} + if AOrderEvent = oeAccess + then + begin + FMachines.Add( AOrderMessage.OrderId, MachineFactory.CreateInstance( Self, AOrderMessage.OrderId ) ); + FOrders.Add( AOrderMessage.OrderId, AOrderMessage ); + end + else + begin + if FOrders[ AOrderMessage.OrderId ] <> AOrderMessage + then + FOrders[ AOrderMessage.OrderId ] := AOrderMessage; + end; + + if FMachines[ AOrderMessage.OrderId ].CanFire( AOrderEvent ) + then + FMachines[ AOrderMessage.OrderId ].Fire( AOrderEvent ) + else + raise EInvalidOperation.CreateFmt( 'Trigger "%s" is not valid in "%s" order state', + [ TEnum.AsString( AOrderEvent ), TEnum.AsString( FMachines[ AOrderMessage.OrderId ].State ) ] ); +end; + +end. diff --git a/Examples/PurchaseProcess/PurchaseProcess.MachineFactory.pas b/Examples/PurchaseProcess/PurchaseProcess.MachineFactory.pas new file mode 100755 index 0000000..deec5b2 --- /dev/null +++ b/Examples/PurchaseProcess/PurchaseProcess.MachineFactory.pas @@ -0,0 +1,63 @@ +unit PurchaseProcess.MachineFactory; + +interface + +uses + PurchaseProcess.Types; + +type + MachineFactory = class abstract + public + class function CreateInstance( const AChannel: IOrderChannel; const Id: TOrderId ): TOrderSM; + end; + +implementation + +{ MachineFactory } + +class function MachineFactory.CreateInstance( + const AChannel: IOrderChannel; + const Id : TOrderId ): TOrderSM; +var + LId : TOrderId; +begin + LId := Id; + + Result := TOrderSM.Create( osNone ); + + Result.Configure( osNone ) + {} .Permit( oeAccess, osEmpty ) + {} .OnEntry( + procedure( const t: TOrderSM.TTransition ) + begin + AChannel.Dispatch( t, LId ); + end ); + + Result.Configure( osEmpty ) + {} .Permit( oeOrder, osFilled ) + {} .Permit( oeExit, osNoOrder ) + {} .OnEntry( + procedure( const t: TOrderSM.TTransition ) + begin + AChannel.Dispatch( t, LId ); + end ); + + Result.Configure( osFilled ) + {} .Permit( oePay, osPaid ) + {} .Permit( oeModify, osEmpty ) + {} .OnEntry( + procedure( const t: TOrderSM.TTransition ) + begin + AChannel.Dispatch( t, LId ); + end ); + + Result.Configure( osPaid ) + {} .Permit( oeExit, osNoOrder ) + {} .OnEntry( + procedure( const t: TOrderSM.TTransition ) + begin + AChannel.Dispatch( t, LId ); + end ); +end; + +end. diff --git a/Examples/PurchaseProcess/PurchaseProcess.Resources.pas b/Examples/PurchaseProcess/PurchaseProcess.Resources.pas new file mode 100755 index 0000000..fda3bf9 --- /dev/null +++ b/Examples/PurchaseProcess/PurchaseProcess.Resources.pas @@ -0,0 +1,182 @@ +unit PurchaseProcess.Resources; + +interface + +uses + System.SysUtils, + PurchaseProcess.Types; + +type + TSeller = class( TResource ) + protected + function GetResourceType: TOrderResourceType; override; + public + procedure ReceiveMessage( const AMessage: TOrderMessage ); override; + end; + + TSender = class( TResource ) + protected + function GetResourceType: TOrderResourceType; override; + public + procedure ReceiveMessage( const AMessage: TOrderMessage ); override; + end; + + TShop = class( TResource ) + protected + function GetResourceType: TOrderResourceType; override; + public + procedure ReceiveMessage( const AMessage: TOrderMessage ); override; + end; + + TSite = class( TResource ) + protected + function GetResourceType: TOrderResourceType; override; + public + procedure ReceiveMessage( const AMessage: TOrderMessage ); override; + procedure EnterNewOrder( ); + end; + +implementation + +{ TSeller } + +function TSeller.GetResourceType: TOrderResourceType; +begin + Result := ortSeller; +end; + +procedure TSeller.ReceiveMessage( const AMessage: TOrderMessage ); +var + LKey: Char; +begin + inherited; + WriteLn( 'Total to pay: ', CurrToStr( AMessage.Total ) ); + while True do + begin + write( 'Enter P to pay or M to modify the product quantity ' ); + ReadLn( LKey ); + case LKey of + 'p', 'P': + begin + FBus.SendMessage( AMessage, oePay ); + Break; + end; + 'm', 'M': + begin + FBus.SendMessage( AMessage, oeModify ); + Break; + end; + else + WriteLn( 'Input not valid' ); + end; + end; +end; + +{ TSender } + +function TSender.GetResourceType: TOrderResourceType; +begin + Result := ortSender; +end; + +procedure TSender.ReceiveMessage( const AMessage: TOrderMessage ); +var + LKey: Char; +begin + inherited; + WriteLn( 'You have bought a quantity of ', AMessage.Quantity, ' and paid ', CurrToStr( AMessage.Total ) ); + WriteLn( 'The products will be shipped soon' ); + WriteLn( 'Thank you for your purchase' ); + while True do + begin + write( 'Enter O to place a new order or E to exit ' ); + ReadLn( LKey ); + case LKey of + 'e', 'E': + begin + FBus.SendMessage( AMessage, oeExit ); + WriteLn( 'Bye!' ); + ReadLn; + Break; + end; + 'o', 'O': + begin + WriteLn( '-----------------------------------------------' ); + WriteLn; + FBus.SendMessage( TOrderMessage.Create, oeAccess ); + Break; + end; + else + WriteLn( 'Input not valid' ); + end; + end; +end; + +{ TShop } + +function TShop.GetResourceType: TOrderResourceType; +begin + Result := ortShop; +end; + +procedure TShop.ReceiveMessage( const AMessage: TOrderMessage ); +var + LInput : string; + LQuantity : Integer; + LProvisory: TMutableOrder; +begin + inherited; + WriteLn( 'Welcome to the shop' ); + WriteLn( 'The unit price is 34' ); + WriteLn( 'You have ', AMessage.Quantity, ' products in your basket' ); + while True do + begin + WriteLn( 'Enter product quantity to order or E to exit' ); + ReadLn( LInput ); + if LInput.Trim.ToUpper = 'E' + then + begin + FBus.SendMessage( AMessage, oeExit ); + WriteLn( 'You have exited without buying' ); + ReadLn; + Break; + end + else if TryStrToInt( LInput, LQuantity ) + then + begin + LProvisory := AMessage.CreateOrder; + try + LProvisory.Quantity := LQuantity; + LProvisory.Total := LQuantity * 34; + FBus.SendMessage( LProvisory.CreateOrderMessage, oeOrder ); + finally + LProvisory.Free; + end; + Break; + end + else + begin + WriteLn( 'Input not valid' ); + end; + end; +end; + +{ TSite } + +procedure TSite.EnterNewOrder; +begin + FBus.SendMessage( TOrderMessage.Create, oeAccess ); +end; + +function TSite.GetResourceType: TOrderResourceType; +begin + Result := ortSite; +end; + +procedure TSite.ReceiveMessage( const AMessage: TOrderMessage ); +begin + inherited; + raise ENotImplemented.CreateFmt( '%s.ReceiveMessage', [ Self.ClassName ] ); +end; + +end. diff --git a/Examples/PurchaseProcess/PurchaseProcess.Types.pas b/Examples/PurchaseProcess/PurchaseProcess.Types.pas new file mode 100755 index 0000000..aca5c8b --- /dev/null +++ b/Examples/PurchaseProcess/PurchaseProcess.Types.pas @@ -0,0 +1,155 @@ +unit PurchaseProcess.Types; + +interface + +uses + System.SysUtils, + Stateless; + +type + TOrderId = type string; + + TOrderIdHelper = record helper for TOrderId + class function NewOrderId: TOrderId; static; + function ToString( ): string; + end; + +type + IBus = interface; + IOrderChannel = interface; + TMutableOrder = class; + TOrderMessage = class; + TResource = class; + + TOrderResourceType = ( ortShop, ortSeller, ortSender, ortSite ); + TOrderEvent = ( oeAccess, oeOrder, oePay, oeExit, oeModify ); + TOrderState = ( osEmpty, osFilled, osNoOrder, osPaid, osNone ); + + TOrderSM = TStateMachine; + + IBus = interface + [ '{705A25C4-8217-481B-B333-C55568AF5B78}' ] + procedure RegisterResource( const AResource: TResource ); + procedure SendMessage( const AOrderMessage: TOrderMessage; const AOrderEvent: TOrderEvent ); + end; + + IOrderChannel = interface + [ '{AB7F47D9-6AA5-4B05-9315-E6CF57F21BE7}' ] + procedure Dispatch( const ATransition: TOrderSM.TTransition; const AOrderId: TOrderId ); + end; + + TMutableOrder = class + private + FTotal : Currency; + FQuantity: Integer; + FOrderId : TOrderId; + public + constructor Create( const AOrder: TOrderMessage ); + + function CreateOrderMessage( ): TOrderMessage; + + property Total: Currency read FTotal write FTotal; + property Quantity: Integer read FQuantity write FQuantity; + property OrderId: TOrderId read FOrderId write FOrderId; + end; + + TOrderMessage = class + private + FTotal : Currency; + FQuantity: Integer; + FOrderId : TOrderId; + public + constructor Create( ); overload; + constructor Create( const AOrder: TMutableOrder ); overload; + function CreateOrder( ): TMutableOrder; + + function ToString: string; override; + + property Total: Currency read FTotal; + property Quantity: Integer read FQuantity; + property OrderId: TOrderId read FOrderId; + end; + + TResource = class abstract + protected + FBus: IBus; + function GetResourceType: TOrderResourceType; virtual; abstract; + public + procedure Subscribe( const ABus: IBus ); + procedure ReceiveMessage( const AMessage: TOrderMessage ); virtual; + property ResourceType: TOrderResourceType read GetResourceType; + end; + +implementation + +{ TResource } + +procedure TResource.ReceiveMessage( const AMessage: TOrderMessage ); +begin +{$IFDEF DEBUG}Writeln( 'LOG ReceiveMessage( ', AMessage.ToString, ' )' ); {$ENDIF} +end; + +procedure TResource.Subscribe( const ABus: IBus ); +begin + ABus.RegisterResource( Self ); + FBus := ABus; +end; + +{ TOrderMessage } + +constructor TOrderMessage.Create; +begin + inherited; + FOrderId := TOrderId.NewOrderId; +end; + +constructor TOrderMessage.Create( const AOrder: TMutableOrder ); +begin + inherited Create; + FTotal := AOrder.Total; + FQuantity := AOrder.Quantity; + FOrderId := AOrder.OrderId; +end; + +function TOrderMessage.CreateOrder: TMutableOrder; +begin + Result := TMutableOrder.Create( Self ); +end; + +function TOrderMessage.ToString: string; +begin + if Self = nil + then + Result := 'OrderMessage( nil )' + else + Result := 'OrderMessage { OrderId:' + FOrderId.ToString + ', Quantity:' + Quantity.ToString + ', Total:' + CurrToStr( FTotal ) + '}'; +end; + +{ TMutableOrder } + +constructor TMutableOrder.Create( const AOrder: TOrderMessage ); +begin + inherited Create; + FTotal := AOrder.Total; + FQuantity := AOrder.Quantity; + FOrderId := AOrder.OrderId; +end; + +function TMutableOrder.CreateOrderMessage: TOrderMessage; +begin + Result := TOrderMessage.Create( Self ); +end; + +{ TOrderIdHelper } + +class function TOrderIdHelper.NewOrderId: TOrderId; +begin + Result := TGUID.NewGuid.ToString; +end; + +function TOrderIdHelper.ToString: string; +begin + Result := Self; +end; + +end. diff --git a/Examples/PurchaseProcess/PurchaseProcess.dpr b/Examples/PurchaseProcess/PurchaseProcess.dpr new file mode 100755 index 0000000..300234d --- /dev/null +++ b/Examples/PurchaseProcess/PurchaseProcess.dpr @@ -0,0 +1,58 @@ +program PurchaseProcess; + +{$APPTYPE CONSOLE} +{$R *.res} + +uses + System.SysUtils, + PurchaseProcess.Types in 'PurchaseProcess.Types.pas', + PurchaseProcess.Resources in 'PurchaseProcess.Resources.pas', + PurchaseProcess.MachineFactory in 'PurchaseProcess.MachineFactory.pas', + PurchaseProcess.Bus in 'PurchaseProcess.Bus.pas'; + +procedure Main; +var + Bus : TBus; + Site : TSite; + Shop : TShop; + Seller: TSeller; + Sender: TSender; +begin + Bus := nil; + Site := nil; + Shop := nil; + Seller := nil; + Sender := nil; + try + + Bus := TBus.Create; + Site := TSite.Create; + Shop := TShop.Create; + Seller := TSeller.Create; + Sender := TSender.Create; + + Site.Subscribe( Bus ); + Shop.Subscribe( Bus ); + Seller.Subscribe( Bus ); + Sender.Subscribe( Bus ); + + Site.EnterNewOrder( ); + + finally + Bus.Free; + Site.Free; + Shop.Free; + Seller.Free; + Sender.Free; + end; +end; + +begin + try + Main; + except + on E: Exception do + Writeln( E.ClassName, ': ', E.Message ); + end; + +end. diff --git a/Examples/PurchaseProcess/PurchaseProcess.dproj b/Examples/PurchaseProcess/PurchaseProcess.dproj new file mode 100755 index 0000000..9ad1320 --- /dev/null +++ b/Examples/PurchaseProcess/PurchaseProcess.dproj @@ -0,0 +1,597 @@ + + + {FFA828B3-1CDC-4D1F-97A8-BB6CA14EB439} + 18.0 + None + PurchaseProcess.dpr + True + Debug + Win32 + 1 + Console + + + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Cfg_1 + true + true + + + true + Base + true + + + System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace) + CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= + ..\..\Stateless;$(DCC_UnitSearchPath) + PurchaseProcess + 1031 + .\$(Platform)\$(Config) + .\$(Platform)\$(Config) + false + false + false + false + false + + + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_144x144.png + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_72x72.png + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_36x36.png + android-support-v4.dex.jar;apk-expansion.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.dex.jar + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_48x48.png + $(BDS)\bin\Artwork\Android\FM_SplashImage_426x320.png + $(BDS)\bin\Artwork\Android\FM_SplashImage_470x320.png + $(BDS)\bin\Artwork\Android\FM_SplashImage_960x720.png + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_96x96.png + DBXSqliteDriver;RESTComponents;DBXInterBaseDriver;emsclientfiredac;DataSnapFireDAC;tethering;bindcompfmx;FmxTeeUI;FireDACIBDriver;fmx;FireDACDBXDriver;dbexpress;IndyCore;dsnap;DataSnapCommon;emsclient;FireDACCommon;RESTBackendComponents;soapserver;bindengine;CloudService;FireDACCommonDriver;DataSnapClient;inet;bindcompdbx;IndyIPCommon;IndyIPServer;IndySystem;fmxFireDAC;FireDAC;FireDACSqliteDriver;FMXTee;soaprtl;DbxCommonDriver;xmlrtl;soapmidas;DataSnapNativeClient;FireDACDSDriver;rtl;DbxClientDriver;CustomIPTransport;bindcomp;IndyIPClient;dbxcds;dsnapxml;DataSnapProviderClient;dbrtl;IndyProtocols;BackgroundWorker;$(DCC_UsePackage) + $(BDS)\bin\Artwork\Android\FM_SplashImage_640x480.png + + + DBXSqliteDriver;RESTComponents;DBXInterBaseDriver;emsclientfiredac;DataSnapFireDAC;tethering;bindcompfmx;FmxTeeUI;FireDACIBDriver;fmx;FireDACDBXDriver;dbexpress;IndyCore;dsnap;DataSnapCommon;emsclient;FireDACCommon;RESTBackendComponents;soapserver;bindengine;CloudService;FireDACCommonDriver;DataSnapClient;inet;bindcompdbx;IndyIPCommon;IndyIPServer;IndySystem;fmxFireDAC;FireDAC;FireDACSqliteDriver;FMXTee;soaprtl;DbxCommonDriver;xmlrtl;soapmidas;DataSnapNativeClient;FireDACDSDriver;rtl;DbxClientDriver;CustomIPTransport;bindcomp;IndyIPClient;dbxcds;dsnapxml;DataSnapProviderClient;dbrtl;IndyProtocols;BackgroundWorker;fmxase;$(DCC_UsePackage) + + + DBXSqliteDriver;RESTComponents;DBXInterBaseDriver;emsclientfiredac;DataSnapFireDAC;tethering;bindcompfmx;FmxTeeUI;FireDACIBDriver;fmx;FireDACDBXDriver;dbexpress;IndyCore;dsnap;DataSnapCommon;emsclient;FireDACCommon;RESTBackendComponents;soapserver;bindengine;CloudService;FireDACCommonDriver;DataSnapClient;inet;bindcompdbx;IndyIPCommon;IndyIPServer;IndySystem;fmxFireDAC;FireDAC;FireDACSqliteDriver;FMXTee;soaprtl;DbxCommonDriver;xmlrtl;soapmidas;DataSnapNativeClient;FireDACDSDriver;rtl;DbxClientDriver;CustomIPTransport;bindcomp;IndyIPClient;dbxcds;dsnapxml;DataSnapProviderClient;dbrtl;IndyProtocols;BackgroundWorker;fmxase;$(DCC_UsePackage) + + + DBXSqliteDriver;RESTComponents;DBXInterBaseDriver;emsclientfiredac;DataSnapFireDAC;tethering;bindcompfmx;FmxTeeUI;FireDACIBDriver;fmx;FireDACDBXDriver;dbexpress;IndyCore;dsnap;DataSnapCommon;emsclient;FireDACCommon;RESTBackendComponents;soapserver;bindengine;CloudService;FireDACCommonDriver;DataSnapClient;inet;bindcompdbx;IndyIPCommon;IndyIPServer;IndySystem;fmxFireDAC;FireDAC;FireDACSqliteDriver;FMXTee;soaprtl;DbxCommonDriver;xmlrtl;soapmidas;DataSnapNativeClient;FireDACDSDriver;rtl;DbxClientDriver;CustomIPTransport;bindcomp;IndyIPClient;dbxcds;dsnapxml;DataSnapProviderClient;dbrtl;IndyProtocols;BackgroundWorker;fmxase;$(DCC_UsePackage) + + + DBXSqliteDriver;RESTComponents;DataSnapServerMidas;DBXInterBaseDriver;emsclientfiredac;DataSnapFireDAC;tethering;FireDACMSSQLDriver;bindcompfmx;DBXOracleDriver;inetdb;FmxTeeUI;FireDACIBDriver;fmx;fmxdae;FireDACDBXDriver;dbexpress;IndyCore;dsnap;DataSnapCommon;emsclient;FireDACCommon;RESTBackendComponents;soapserver;bindengine;DBXMySQLDriver;FireDACOracleDriver;CloudService;FireDACMySQLDriver;DBXFirebirdDriver;FireDACCommonDriver;DataSnapClient;inet;bindcompdbx;IndyIPCommon;IndyIPServer;IndySystem;fmxFireDAC;FireDAC;FireDACSqliteDriver;FireDACPgDriver;FireDACASADriver;FireDACTDataDriver;FMXTee;soaprtl;DbxCommonDriver;DataSnapServer;xmlrtl;soapmidas;DataSnapNativeClient;fmxobj;FireDACDSDriver;rtl;DbxClientDriver;DBXSybaseASADriver;CustomIPTransport;bindcomp;DBXInformixDriver;IndyIPClient;dbxcds;FireDACODBCDriver;DataSnapIndy10ServerTransport;dsnapxml;DataSnapProviderClient;dbrtl;inetdbxpress;FireDACMongoDBDriver;IndyProtocols;BackgroundWorker;fmxase;$(DCC_UsePackage) + true + + + Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) + 1033 + DBXSqliteDriver;RESTComponents;DataSnapServerMidas;DBXDb2Driver;DBXInterBaseDriver;vclactnband;frxe23;vclFireDAC;emsclientfiredac;DataSnapFireDAC;svnui;tethering;FireDACADSDriver;DBXMSSQLDriver;DatasnapConnectorsFreePascal;FireDACMSSQLDriver;vcltouch;vcldb;bindcompfmx;svn;DBXOracleDriver;inetdb;FmxTeeUI;FireDACIBDriver;fmx;fmxdae;FireDACDBXDriver;dbexpress;IndyCore;vclx;dsnap;DataSnapCommon;emsclient;FireDACCommon;RESTBackendComponents;DataSnapConnectors;VCLRESTComponents;soapserver;frxTee23;vclie;bindengine;DBXMySQLDriver;FireDACOracleDriver;CloudService;FireDACMySQLDriver;DBXFirebirdDriver;FireDACCommonDriver;DataSnapClient;inet;bindcompdbx;IndyIPCommon;vcl;DBXSybaseASEDriver;IndyIPServer;IndySystem;FireDACDb2Driver;dsnapcon;FireDACMSAccDriver;fmxFireDAC;FireDACInfxDriver;vclimg;TeeDB;FireDAC;FireDACSqliteDriver;FireDACPgDriver;FireDACASADriver;DBXOdbcDriver;FireDACTDataDriver;FMXTee;soaprtl;DbxCommonDriver;Tee;DataSnapServer;xmlrtl;soapmidas;DataSnapNativeClient;fmxobj;vclwinx;FireDACDSDriver;rtl;DbxClientDriver;DBXSybaseASADriver;CustomIPTransport;vcldsnap;bindcomp;appanalytics;DBXInformixDriver;IndyIPClient;bindcompvcl;frxDB23;TeeUI;vclribbon;dbxcds;VclSmp;adortl;FireDACODBCDriver;DataSnapIndy10ServerTransport;dsnapxml;DataSnapProviderClient;dbrtl;inetdbxpress;FireDACMongoDBDriver;IndyProtocols;frx23;BackgroundWorker;fmxase;$(DCC_UsePackage) + CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= + true + + + DBXSqliteDriver;RESTComponents;DataSnapServerMidas;DBXDb2Driver;DBXInterBaseDriver;vclactnband;vclFireDAC;emsclientfiredac;DataSnapFireDAC;tethering;FireDACADSDriver;DBXMSSQLDriver;DatasnapConnectorsFreePascal;FireDACMSSQLDriver;vcltouch;vcldb;bindcompfmx;DBXOracleDriver;inetdb;FmxTeeUI;FireDACIBDriver;fmx;fmxdae;FireDACDBXDriver;dbexpress;IndyCore;vclx;dsnap;DataSnapCommon;emsclient;FireDACCommon;RESTBackendComponents;DataSnapConnectors;VCLRESTComponents;soapserver;vclie;bindengine;DBXMySQLDriver;FireDACOracleDriver;CloudService;FireDACMySQLDriver;DBXFirebirdDriver;FireDACCommonDriver;DataSnapClient;inet;bindcompdbx;IndyIPCommon;vcl;DBXSybaseASEDriver;IndyIPServer;IndySystem;FireDACDb2Driver;dsnapcon;FireDACMSAccDriver;fmxFireDAC;FireDACInfxDriver;vclimg;TeeDB;FireDAC;FireDACSqliteDriver;FireDACPgDriver;FireDACASADriver;DBXOdbcDriver;FireDACTDataDriver;FMXTee;soaprtl;DbxCommonDriver;Tee;DataSnapServer;xmlrtl;soapmidas;DataSnapNativeClient;fmxobj;vclwinx;FireDACDSDriver;rtl;DbxClientDriver;DBXSybaseASADriver;CustomIPTransport;vcldsnap;bindcomp;appanalytics;DBXInformixDriver;IndyIPClient;bindcompvcl;TeeUI;vclribbon;dbxcds;VclSmp;adortl;FireDACODBCDriver;DataSnapIndy10ServerTransport;dsnapxml;DataSnapProviderClient;dbrtl;inetdbxpress;FireDACMongoDBDriver;IndyProtocols;BackgroundWorker;fmxase;$(DCC_UsePackage) + true + + + DEBUG;$(DCC_Define) + true + false + true + true + true + + + 1033 + None + false + + + false + RELEASE;$(DCC_Define) + 0 + 0 + + + + MainSource + + + + + + + Cfg_2 + Base + + + Base + + + Cfg_1 + Base + + + + Delphi.Personality.12 + Application + + + + PurchaseProcess.dpr + + + Microsoft Office 2000 Beispiele für gekapselte Komponenten für Automatisierungsserver + Microsoft Office XP Beispiele für gekapselte Komponenten für Automation Server + + + + + + true + + + + + true + + + + + true + + + + + PurchaseProcess.exe + true + + + + + 0 + .dll;.bpl + + + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + + + Contents\Resources + 1 + + + + + classes + 1 + + + + + Contents\MacOS + 0 + + + 1 + + + Contents\MacOS + 1 + + + + + 1 + + + 1 + + + 1 + + + + + res\drawable-xxhdpi + 1 + + + + + library\lib\mips + 1 + + + + + 0 + + + 1 + + + Contents\MacOS + 1 + + + 1 + + + library\lib\armeabi-v7a + 1 + + + 1 + + + + + 0 + + + Contents\MacOS + 1 + .framework + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + + + library\lib\x86 + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + library\lib\armeabi + 1 + + + + + 0 + + + 1 + + + Contents\MacOS + 1 + + + + + 1 + + + 1 + + + 1 + + + + + res\drawable-normal + 1 + + + + + res\drawable-xhdpi + 1 + + + + + res\drawable-large + 1 + + + + + 1 + + + 1 + + + 1 + + + + + ../ + 1 + + + ../ + 1 + + + + + res\drawable-hdpi + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + Contents + 1 + + + + + ../ + 1 + + + + + 1 + + + 1 + + + 1 + + + + + res\values + 1 + + + + + res\drawable-small + 1 + + + + + res\drawable + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + + + res\drawable + 1 + + + + + 0 + + + 0 + + + Contents\Resources\StartUp\ + 0 + + + 0 + + + 0 + + + 0 + + + + + library\lib\armeabi-v7a + 1 + + + + + 0 + .bpl + + + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + + + res\drawable-mdpi + 1 + + + + + res\drawable-xlarge + 1 + + + + + res\drawable-ldpi + 1 + + + + + 1 + + + 1 + + + + + + + + + + + + False + False + False + False + False + True + False + + + 12 + + + + + diff --git a/Stateless.groupproj b/Stateless.groupproj index bd9ef95..0f020eb 100755 --- a/Stateless.groupproj +++ b/Stateless.groupproj @@ -24,6 +24,9 @@ + + + Default.Personality.12 @@ -95,14 +98,23 @@ + + + + + + + + + - + - + - +