Added: Define implementation, needs some more thought as to the usefulness of ranges
This commit is contained in:
parent
dd627c8b74
commit
594de2b48a
155
X2UtSettings.pas
155
X2UtSettings.pas
@ -28,16 +28,31 @@ type
|
|||||||
//:$ Raised when the specified range is invalid.
|
//:$ Raised when the specified range is invalid.
|
||||||
EX2SettingsRange = class(Exception);
|
EX2SettingsRange = class(Exception);
|
||||||
|
|
||||||
|
//:$ Raised when the specified define already exists
|
||||||
|
EX2SettingsExists = class(Exception);
|
||||||
|
|
||||||
//:$ Callback method for defines
|
//:$ Callback method for defines
|
||||||
TX2SettingsCallback = procedure(const ASection, AName: String;
|
TX2SettingsCallback = procedure(const ASection, AName: String;
|
||||||
var AValue: Variant) of object;
|
var AValue: Variant) of object;
|
||||||
|
|
||||||
{
|
{
|
||||||
:$ Internal representation of defines
|
:$ Internal representation of a persistent setting
|
||||||
}
|
}
|
||||||
|
TX2SettingsRanges = array of array[0..1] of Variant;
|
||||||
|
|
||||||
TX2SettingsDefine = class(TObject)
|
TX2SettingsDefine = class(TObject)
|
||||||
private
|
private
|
||||||
|
FCallback: TX2SettingsCallback;
|
||||||
|
FRanges: TX2SettingsRanges;
|
||||||
|
FValue: Variant;
|
||||||
|
public
|
||||||
|
constructor Create(const AValue: Variant;
|
||||||
|
const ARanges: array of const;
|
||||||
|
const ACallback: TX2SettingsCallback);
|
||||||
|
|
||||||
|
property Callback: TX2SettingsCallback read FCallback;
|
||||||
|
property Ranges: TX2SettingsRanges read FRanges;
|
||||||
|
property Value: Variant read FValue;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -128,9 +143,14 @@ type
|
|||||||
:: create to provide application-wide access to the same settings.
|
:: create to provide application-wide access to the same settings.
|
||||||
}
|
}
|
||||||
TX2SettingsFactory = class(TObject)
|
TX2SettingsFactory = class(TObject)
|
||||||
|
private
|
||||||
|
FDefines: TX2ObjectHash;
|
||||||
protected
|
protected
|
||||||
function GetSection(const ASection: String): TX2Settings; virtual; abstract;
|
function GetSection(const ASection: String): TX2Settings; virtual; abstract;
|
||||||
public
|
public
|
||||||
|
constructor Create();
|
||||||
|
destructor Destroy(); override;
|
||||||
|
|
||||||
//:$ Loads a section from the settings.
|
//:$ Loads a section from the settings.
|
||||||
//:: Sub-sections are indicated by seperating the sections with a dot ('.')
|
//:: Sub-sections are indicated by seperating the sections with a dot ('.')
|
||||||
//:: characters, ex: Sub.Section. The underlying extension will translate
|
//:: characters, ex: Sub.Section. The underlying extension will translate
|
||||||
@ -161,9 +181,10 @@ type
|
|||||||
|
|
||||||
implementation
|
implementation
|
||||||
resourcestring
|
resourcestring
|
||||||
RSInvalidRange = 'Invalid range';
|
RSInvalidRange = 'Invalid range!';
|
||||||
RSInvalidType = 'Invalid type';
|
RSInvalidType = 'Invalid type!';
|
||||||
RSUndefined = 'Undefined setting: %s';
|
RSUndefined = 'Undefined setting: %s!';
|
||||||
|
RSDefineExists = 'Define already exists!';
|
||||||
|
|
||||||
|
|
||||||
{============================ TX2Settings
|
{============================ TX2Settings
|
||||||
@ -236,9 +257,131 @@ end;
|
|||||||
{===================== TX2SettingsFactory
|
{===================== TX2SettingsFactory
|
||||||
Defines
|
Defines
|
||||||
========================================}
|
========================================}
|
||||||
procedure TX2SettingsFactory.Define;
|
constructor TX2SettingsFactory.Create;
|
||||||
begin
|
begin
|
||||||
//
|
inherited;
|
||||||
|
|
||||||
|
FDefines := TX2ObjectHash.Create();
|
||||||
|
end;
|
||||||
|
|
||||||
|
destructor TX2SettingsFactory.Destroy;
|
||||||
|
begin
|
||||||
|
FreeAndNil(FDefines);
|
||||||
|
|
||||||
|
inherited;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TX2SettingsFactory.Define;
|
||||||
|
function CheckVarType(const AValue: Variant): TVarType;
|
||||||
|
begin
|
||||||
|
case VarType(AValue) of
|
||||||
|
varBoolean: break;
|
||||||
|
varByte,
|
||||||
|
varSmallint,
|
||||||
|
varInteger,
|
||||||
|
varWord,
|
||||||
|
varLongWord: Result := varInteger;
|
||||||
|
varSingle,
|
||||||
|
varDouble,
|
||||||
|
varDate: Result := varDouble;
|
||||||
|
varOleStr,
|
||||||
|
varStrArg,
|
||||||
|
varString: Result := varString;
|
||||||
|
else
|
||||||
|
raise EX2SettingsType.Create(RSInvalidType);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
iIndex: Integer;
|
||||||
|
sHash: String;
|
||||||
|
vtValue: TVarType;
|
||||||
|
|
||||||
|
begin
|
||||||
|
sHash := ASection + #0 + AName;
|
||||||
|
if FDefines.Exists(sHash) then
|
||||||
|
raise EX2SettingsExists.Create(RSDefineExists);
|
||||||
|
|
||||||
|
// Validate type
|
||||||
|
vtValue := CheckVarType(AValue);
|
||||||
|
|
||||||
|
// Validate ranges
|
||||||
|
if High(ARanges) mod 2 <> 0 then
|
||||||
|
raise EX2SettingsRange.Create(RSInvalidRange);
|
||||||
|
|
||||||
|
for iIndex := 0 to High(ARanges) do
|
||||||
|
case ARanges[iIndex].VType of
|
||||||
|
vtBoolean:
|
||||||
|
if vtValue <> varBoolean then
|
||||||
|
raise EX2SettingsType.Create(RSInvalidType);
|
||||||
|
vtInteger:
|
||||||
|
if not (vtValue in [varInteger, varDouble]) then
|
||||||
|
raise EX2SettingsType.Create(RSInvalidType);
|
||||||
|
vtExtended:
|
||||||
|
if vtValue <> varDouble then
|
||||||
|
raise EX2SettingsType.Create(RSInvalidType);
|
||||||
|
vtString,
|
||||||
|
vtPChar,
|
||||||
|
vtChar,
|
||||||
|
vtWideChar,
|
||||||
|
vtPWideChar,
|
||||||
|
vtWideString,
|
||||||
|
vtAnsiString:
|
||||||
|
if vtValue <> varString then
|
||||||
|
raise EX2SettingsType.Create(RSInvalidType);
|
||||||
|
vtVariant:
|
||||||
|
if vtValue <> CheckVarType(ARanges[iIndex].VVariant^) then
|
||||||
|
raise EX2SettingsType.Create(RSInvalidType);
|
||||||
|
end;
|
||||||
|
|
||||||
|
FDefines[sHash] := TX2SettingsDefine.Create(VarAsType(AValue, vtValue),
|
||||||
|
ARanges, ACallback);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
{====================== TX2SettingsDefine
|
||||||
|
Initialization
|
||||||
|
========================================}
|
||||||
|
constructor TX2SettingsDefine.Create;
|
||||||
|
function VarRecToVariant(const AVarRec: TVarRec): Variant;
|
||||||
|
begin
|
||||||
|
case AVarRec.VType of
|
||||||
|
vtBoolean: Result := AVarRec.VBoolean;
|
||||||
|
vtInteger: Result := AVarRec.VInteger;
|
||||||
|
vtExtended: Result := VarAsType(AVarRec.VExtended^, varDouble);
|
||||||
|
vtString: Result := AVarRec.VString^;
|
||||||
|
vtPChar: Result := String(AVarRec.VPChar);
|
||||||
|
vtPWideChar: Result := String(AVarRec.VPWideChar^);
|
||||||
|
vtWideChar: Result := String(AVarRec.VWideChar);
|
||||||
|
vtWideString: Result := String(AVarRec.VWideString^);
|
||||||
|
vtAnsiString: Result := String(AVarRec.VAnsiString^);
|
||||||
|
vtVariant: Result := AVarRec.VVariant^;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
iCount: Integer;
|
||||||
|
iIndex: Integer;
|
||||||
|
iRange: Integer;
|
||||||
|
|
||||||
|
begin
|
||||||
|
FValue := AValue;
|
||||||
|
FCallback := ACallback;
|
||||||
|
|
||||||
|
// Copy ranges
|
||||||
|
iCount := (High(ARanges) + 1) div 2;
|
||||||
|
iIndex := 0;
|
||||||
|
|
||||||
|
SetLength(FRanges, iCount);
|
||||||
|
|
||||||
|
for iRange := 0 to iCount - 1 do
|
||||||
|
begin
|
||||||
|
FRanges[iRange][0] := VarRecToVariant(ARanges[iIndex]);
|
||||||
|
FRanges[iRange][1] := VarRecToVariant(ARanges[iIndex + 1]);
|
||||||
|
|
||||||
|
Inc(iIndex, 2);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
Loading…
Reference in New Issue
Block a user