unit Game.Base; interface uses System.Classes; type TCustomGame = class(TInterfacedPersistent) private FLocation: string; FLoaded: Boolean; FModified: Boolean; protected procedure PropertyChanged(const APropertyName: string); virtual; procedure DoLoad; virtual; abstract; procedure DoSave; virtual; abstract; public class function GameName: string; virtual; abstract; class function AutoDetect: TCustomGame; virtual; constructor Create(const ALocation: string); virtual; procedure Load; virtual; procedure Save; virtual; function GetExecutable: string; virtual; abstract; function GetParameters: string; virtual; function GetCommandLine: string; virtual; property Loaded: Boolean read FLoaded; property Location: string read FLocation; property Modified: Boolean read FModified; end; TCustomGameClass = class of TCustomGame; implementation uses System.Bindings.Helper, System.SysUtils; { TCustomGame } constructor TCustomGame.Create(const ALocation: string); begin inherited Create; FLocation := IncludeTrailingPathDelimiter(ALocation); end; class function TCustomGame.AutoDetect: TCustomGame; begin Result := nil; end; procedure TCustomGame.Load; var wasModified: Boolean; begin wasModified := FModified; DoLoad; FLoaded := True; FModified := False; if wasModified then TBindings.Notify(Self, 'Modified'); end; procedure TCustomGame.Save; var wasModified: Boolean; begin wasModified := FModified; DoSave; FModified := False; if wasModified then TBindings.Notify(Self, 'Modified'); end; function TCustomGame.GetParameters: string; begin Result := ''; end; function TCustomGame.GetCommandLine: string; var parameters: string; begin Result := '"' + GetExecutable + '"'; parameters := GetParameters; if Length(parameters) > 0 then Result := Result + ' ' + parameters; end; procedure TCustomGame.PropertyChanged(const APropertyName: string); begin if not FModified then begin FModified := True; TBindings.Notify(Self, 'Modified'); end; TBindings.Notify(Self, APropertyName); end; end.