Object Status (SubSet)

I need help on this:

im saving the properties of an object in the DataPacket class. Properties are defined as follows:

type
  TProperty = class
  private
    FName: string;
  public
    constructor Create(const AName: string);
    property Name: string read FName;
  end;

  TIntegerProperty = class(TProperty)
  private
    FValue: Integer;
  protected
    procedure SetValue(const AValue:integer);
  public
    property Value: Integer read FValue write SetValue;
  end;

DataPacket class:

type
  TDataPacket = class
  private
    FProperties: TStringList;
  public
    function GetIntegerValue(const APropertyName: string): integer;
    .....
    procedure SetIntegerValue(const APropertyName: string; AValue: integer);
end;

and they are implemented as follows:

function TDataPacket.GetIntegerValue(const APropertyName: string): integer;
var
  Pos: integer;
begin
  Pos := FProperties.IndexOf(APropertyName);
  if Pos > -1 then
    Result := TIntegerProperty(FProperties.Objects[Pos]).Value
  else
    Result := 0;
end;

procedure TDataPacket.SetIntegerValue(const APropertyName: string; AValue: integer);
var
  Pos: integer;
  AProperty: TIntegerProperty;
begin
  Pos := FProperties.IndexOf(APropertyName);
  if Pos >- 1 then
    TIntegerProperty(FProperties.Objects[Pos]).Value := AValue
  else
    begin
      AProperty:= TIntegerProperty.Create(APropertyName);
      AProperty.Value := AValue;
      FProperties.AddObject(APropertyName, AProperty);
    end;
end;

Now the question is: I need to define the Status property, defined as TObjectStatus, where:

type
  TStatus = (Deleted, Unchanged, Added , Modified, ChildsModified);

  TObjectStatus = Set of TStatus;

Any idea on how I can identify, save and retrieve it?

Sorry for the long explanation and in advance for your help.

Michael

+3
source share
2 answers

First of all:

Result := TIntegerProperty(FProperties.Objects[Pos]).Value

It is risky because you crash if it is not TIntegerProperty. Use something like:

Pos := FProperties.IndexOf(APropertyName);
if (Pos >= 0) and (FProperties.Objects[Pos] is TIntegerProperty) then
  Result := TIntegerProperty(FProperties.Objects[Pos]).Value
else
  Result := 0;

Further, the status, I do not think you need them:

 - :  - :  - : ChildsModified

, . , .

. ChildsModified , . , .

, - :

type
  TStatus = (stDeleted, stAdded , stModified, stChildsModified);
  TObjectStatus = Set of TStatus;


  TDataPacket = class;
  TProperty = class
  private
    FName   : string;
    FParent : TDataPacket; 
  protected
    procedure NotifyChange(const AStatus: TStatus);
  public
    constructor Create(const AParent: TDataPacket; const AName: string);
    property Name: string read FName;
  end;

  TIntegerProperty = class(TProperty)
  private
    FValue: Integer;
    procedure SetValue(const AValue:integer);
  public
    property Value: Integer read FValue write SetValue;
  end;

  TDataPacket = class
  private
    FProperties: TStringList;
    FStatus : TObjectStatus;
  protected 
    procedure NotifyChange(const AStatus: TStatus);

    function GetProperty(const AName: string): TProperty;
  public
    function GetIntegerValue(const APropertyName: string): integer;
    procedure SetIntegerValue(const APropertyName: string; AValue: integer);
  end;


procedure TProperty.NotifyChange(const AStatus: TStatus);
begin
  FParent.NotifyChange(AStatus);
end;

constructor TProperty.Create(const AParent: TDataPacket; const AName: string);
begin
  Assert(AParent<>nil);
  FName := AName;
  FParent := AParent;
end;

procedure TIntegerProperty.SetValue(const AValue:integer);
begin
  if AValue<>FValue then begin
    FValue := AValue;
    NotifyChange(stChildsModified);
  end;
end;

procedure TDataPacket.NotifyChange(const AStatus: TStatus);
begin
  if AProp=nil then begin
    case AStatus of

  TStatus = (stDeleted, stAdded , stModified, stChildsModified);

  FStatus := FStatus + [AStatus];
end;

function TDataPacket.GetProperty(const AName: string): TProperty;
var
  i : Integer;
begin
  i := FProperties.IndexOf(AName);
  if i>=0 then
    Result := TProperty(FProperties.Objects[i])
  else
    Result := nil;
end;

function TDataPacket.GetIntegerValue(const APropertyName: string): integer;
var
  prop : TProperty;
begin
  prop := GetProperty(APropertyName);
  if (prop<>nil) and (prop is TIntegerProperty) then
    Result := TIntegerProperty(prop).Value
  else
    Result := 0; 
end;

procedure TDataPacket.SetIntegerValue(const APropertyName: string; AValue: integer);
var
  prop : TProperty;
  intprop : TIntegerProperty; 
begin
  prop := GetProperty(APropertyName);
  if (prop<>nil) and not (AProperty is TIntegerProperty) then begin
    // PANIC!
  end else begin
    if prop=nil then begin
      intprop := TIntegerProperty.Create(self, APropertyName);
      intprop.Value := AValue;
      FProperties.AddObject(APropertyName, intprop);
      NotifyChange(stAdded);
    end else begin
      TIntegerProperty(prop).Value := AValue;   
    end;
  end;
end;

.

Property ( ).

+1

, , , , , TIntegerProperty, Integer TObjectStatus.

, TObjectStatus:

type
  TObjectStatusProperty = class(TProperty)
  private
    FValue: TObjectStatus;
  protected
    procedure SetValue(const AValue: TObjectStatus);
  public
    property Value: TObjectStatus read FValue write SetValue;
  end;

:

function TDataPacket.GetObjectStatusValue(
  const APropertyName: string): TObjectStatus;
var
  Pos: integer;
  Prop: TProperty;
begin
  Pos := FProperties.IndexOf(APropertyName);
  if Pos >= 0 then begin
    Prop := FProperties.Objects[Pos] as TProperty;
    Assert(Prop.Name = APropertyName);
    if Prop is TObjectStatusProperty then
      Result := TObjectStatusProperty(Prop).Value
    else
      raise EWrongPropertyType.CreateFmt('Expected %s but got %s',
        [TObjectStatusProperty.ClassName, Prop.ClassName]);
  end else
    Result := [];
end;

procedure TDataPacket.SetObjectStatusValue(
  const APropertyName: string; AValue: TObjectStatus);
var
  Pos: integer;
  Prop: TProperty;
begin
  Pos := FProperties.IndexOf(APropertyName);
  if Pos >= 0 then begin
    Prop := FProperties.Objects[Pos] as TProperty;
    Assert(Prop.Name = APropertyName);
    if Prop is TObjectStatusProperty then
      TObjectStatusProperty(Prop).Value := AValue
    else
      raise EWrongPropertyType.CreateFmt('Expected %s but got %s',
        [TObjectStatusProperty.ClassName, Prop.ClassName]);
  end else begin
    Prop := TObjectStatusProperty.Create(APropertyName);
    TObjectStatusProperty(Prop).Value := AValue;
    FProperties.AddObject(APropertyName, Prop);
  end;
end;

T X Property, , Delphi 2009 Delphi.

+1

Source: https://habr.com/ru/post/1705115/


All Articles