//******************************************************************************
//
// Copyright © 2002 by Lucian Radulescu
// mailto : lucian@ez-delphi.com
// http : http://www.ez-delphi.com/
//
//******************************************************************************
//
// Adapted singleton class from Borland Comunity
//
// My prototype allows for inheritance, such as:
//
// type
//
// // TApplication
// TApplication = class( TSingleton )
// protected
// procedure InitializeInstance; override;
// procedure FinalizeInstance; override;
// end;
//
// // TScreen
// TScreen = class( TSingleton )
// protected
// procedure InitializeInstance; override;
// procedure FinalizeInstance; override;
// end;
//
// all internal members (data/objects) will be created/destroyed
// in InitializeInstance / FinalizeInstance
//
// var
// A1, A2: TApplication;
// S1, S2: TScreen;
// begin
// A1 := TApplication.Create;
// A2 := TApplication.Create;
// S1 := TScreen.Create;
// S2 := TScreen.Create;
// ... // note, my code : A1=A2 and S1=S2 and A1 <> S1
// A1.Free;
// A2.Free;
// S2.Free;
// S1.Free;
// end;
//
// To optimize the code I would suggest using this approach for
// creation of objects inheriting from TSingleton:
//
// function Application: TApplication;
//
// implementation
//
// var
// _Application: TApplication = nil;
//
// function Application: TApplication;
// begin
// if _Application = nil then
// _Application := TApplication.Create;
// Result := _Application;
// end;
// ...
// finalization
// if _Application <> nil then
// _Application.Free;
// end;
//
// --------------------------------------------------------------------------
unit uSingle;
{$I ALLLIB.DEF}
interface
uses
Classes;
type
// you can inherit from TSingleton and create different singleton objects
TSingleton = class
private
FRef: Integer;
protected
procedure InitializeInstance; virtual;
procedure FinalizeInstance; virtual;
public
class function NewInstance: TObject; override;
procedure FreeInstance; override;
end;
implementation
// TSingleton ------------------------------------------------------------------
var
Singletons: TStringList = nil;
procedure TSingleton.FreeInstance;
var
Index: Integer;
Instance: TSingleton;
begin
Singletons.Find( ClassName, Index );
Instance := TSingleton( Singletons.Objects[Index] );
Dec( Instance.FRef );
if Instance.FRef = 0 then
begin
Singletons.Delete( Index );
Instance.FinalizeInstance;
// at this point, Instance = Self. We want to call TObject.FreeInstance
inherited FreeInstance;
end;
end;
procedure TSingleton.FinalizeInstance;
begin
end;
procedure TSingleton.InitializeInstance;
begin
end;
class function TSingleton.NewInstance: TObject;
var
Index: Integer;
begin
if Singletons = nil then
begin
Singletons := TStringList.Create;
Singletons.Sorted := true;
Singletons.Duplicates := dupError;
end;
if not Singletons.Find( ClassName, Index ) then
begin
Result := inherited NewInstance;
TSingleton( Result ).FRef := 1;
TSingleton( Result ).InitializeInstance;
Singletons.AddObject( ClassName, Result );
end
else
begin
Result := Singletons.Objects[Index];
Inc( TSingleton( Result ).FRef );
end;
end;
initialization
finalization
if Singletons <> nil then
Singletons.Free;
end.