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; 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; 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.