Lazarus

Programming => General => Topic started by: Weitentaaal on February 01, 2023, 02:36:50 pm

Title: Synchronizing certain Data between 2 Objects
Post by: Weitentaaal on February 01, 2023, 02:36:50 pm
Hello,

I'm facing an issue regarding synchronization between 2 Objects. Let's hope I can explain it briefly:

i have two Obects of the Same Type. Thy have some Properties which need to be Synchronized.

Simple Example:

Code: Pascal  [Select][+][-]
  1. MyClass = class
  2. private
  3.    fID: Integer
  4.    fSharedData: String;
  5. public
  6.    property ID: Integer read fID write fID;
  7.    property SharedData: String read fSharedData write fSharedData;
  8. end;
  9.  


i can't simply copy the Objects because i dont want them to end up having the same ID.
But i want to keep some Shared Data synchronized.

Is there any way i can achiev this without writing 200 lines of this:

Code: Pascal  [Select][+][-]
  1.  procedure SyncMyClass(Dest: MyClass);
  2. begin
  3.    Dest.fSharedData:= fSharedData
  4.    //there will be some other Variabels that need to be Syncronized
  5. end;
  6.  

i hope you guys understood my problem and i hope someone could be so kind to help me out.

thanks in advance.
Title: Re: Synchronizing certain Data between 2 Objects
Post by: Zvoni on February 01, 2023, 02:50:16 pm
Use a record for all shared Properties?

Untested!
Code: Pascal  [Select][+][-]
  1. //PMyRecord = ^MyRecord;
  2. MyRecord = Record
  3.     SharedInteger:Integer;
  4.     SharedString:String;
  5.     SharedBoolean:Boolean;
  6. End;
  7.  
  8. MyClass = class
  9. private
  10.    fID: Integer
  11.    fSharedData: MyRecord;
  12. public
  13.    Constructor Create;
  14.    procedure SyncMyClass(Dest: MyClass);
  15.    property ID: Integer read fID write fID;
  16.    property SharedData: String read fSharedData write fSharedData;
  17. end;
  18.  
  19. Constructor MyClass.Create;
  20. Begin
  21.    Inherited;
  22.    fSharedData.SherdInteger:=42;
  23.    fSharedData.SharedString:='Dont panic!';
  24.    fSharedData.SharedBoolean:=False;
  25. End;
  26.  
  27. procedure MyClass.SyncTo(Dest: MyClass);
  28. begin
  29.    Dest.fSharedData:= fSharedData
  30. end;
Title: Re: Synchronizing certain Data between 2 Objects
Post by: Weitentaaal on February 01, 2023, 02:57:09 pm
Quote
Use a record for all shared Properties?

Then i would need to create an array/list of those Records and some refference between Objects and item. Either I am imagining this to be very complicated or I am thinking in the wrong direction.
Title: Re: Synchronizing certain Data between 2 Objects
Post by: bpranoto on February 01, 2023, 03:02:52 pm
How about using class var?
Code: Pascal  [Select][+][-]
  1.   { TMyClass }
  2.  
  3.   TMyClass=class
  4.   private
  5.     class var FSharedData:String;
  6.   public
  7.     constructor Create;
  8.     class property SharedData:String read FSharedData;
  9.   end;
  10.  
  11. { TMyClass }
  12.  
  13. constructor TMyClass.Create;
  14. begin
  15.   Self.FSharedData:='Shared between objects';
  16. end;
  17.  
  18. var
  19.   o1,o2 : TMyClass;
  20. begin
  21.   o1 := TMyClass.Create;
  22.   o2 := TMyClass.Create;
  23.   //
  24.   WriteLn( o1.SharedData);
  25.   WriteLn( o2.SharedData);
  26. end.
  27.  
  28.  
Title: Re: Synchronizing certain Data between 2 Objects
Post by: Zvoni on February 01, 2023, 03:39:17 pm
How about using class var?
GROWL.... That's actually what i tried to remember..
Nice one!

but this snippet shows it IMO better (you set SharedDate in your Constructor)
Code: Pascal  [Select][+][-]
  1. program Project1;
  2. Uses SysUtils, Classes;
  3. Type
  4. TMyClass=class
  5.   private
  6.     class var FSharedData:String;
  7.   public
  8.     class property SharedData:String read FSharedData Write FSharedData;
  9.   end;
  10.  
  11. { TMyClass }
  12.  
  13. var
  14.   o1,o2 : TMyClass;
  15. begin
  16.   o1 := TMyClass.Create;
  17.   o1.SharedData:='Shared between objects';
  18.   o2 := TMyClass.Create;
  19.   //
  20.   WriteLn( o1.SharedData);
  21.   WriteLn( o2.SharedData);
  22.   o1.SharedData:='Written to o1';
  23.   WriteLn( o1.SharedData);
  24.   WriteLn( o2.SharedData);
  25.   o2.SharedData:='Written to o2';
  26.   WriteLn( o1.SharedData);
  27.   WriteLn( o2.SharedData);
  28.   o1.Free;
  29.   o2.Free;
  30. end.
Title: Re: Synchronizing certain Data between 2 Objects
Post by: Weitentaaal on February 01, 2023, 03:59:39 pm
i'm still learning but isn't this going to Share the Value to every instance i create of it ?
i would like to share it pairwise. like this Pair shares this Data and some other Pair shares some other Data.
Title: Re: Synchronizing certain Data between 2 Objects
Post by: Zvoni on February 01, 2023, 04:46:34 pm
i'm still learning but isn't this going to Share the Value to every instance i create of it ?
i would like to share it pairwise. like this Pair shares this Data and some other Pair shares some other Data.
That wasn’t part of the initial problem  :P :P :P

Uff, i think advanced records might help.
I think to remember you can implement an „automatic copy when assigning“
Title: Re: Synchronizing certain Data between 2 Objects
Post by: bpranoto on February 01, 2023, 04:50:32 pm
i'm still learning but isn't this going to Share the Value to every instance i create of it ?
i would like to share it pairwise. like this Pair shares this Data and some other Pair shares some other Data.

In that case you can use composition.

Code: Pascal  [Select][+][-]
  1. program Project1;
  2.  
  3. type
  4.  
  5.   { TMyClass }
  6.  
  7.   TSharedContainer=class
  8.   private
  9.     var FSharedData:String;
  10.   public
  11.     property SharedData:String read FSharedData write FSharedData;
  12.   end;
  13.  
  14.   TMyClass=class
  15.   private
  16.     var FSharedContainer:TSharedContainer;
  17.   public
  18.     property SharedContainer:TSharedContainer read FSharedContainer write FSharedContainer;
  19.   end;
  20.  
  21.  
  22. var
  23.   cta,ctb : TSharedContainer;
  24.   o1,o2,o3,o4 : TMyClass;
  25. begin
  26.   // o1 and o2 shared same container
  27.   cta := TSharedContainer.Create;
  28.   cta.SharedData:='This is container A';
  29.   o1 := TMyClass.Create;o1.SharedContainer:=cta;
  30.   o2 := TMyClass.Create;o2.SharedContainer:=cta;
  31.  
  32.   // o3 and o4 shared same container
  33.   ctb := TSharedContainer.Create;
  34.   ctb.SharedData:='This is container B';
  35.   o3 := TMyClass.Create;o3.SharedContainer:=ctb;
  36.   o4 := TMyClass.Create;o4.SharedContainer:=ctb;
  37.  
  38.   writeln( o1.SharedContainer.SharedData);
  39.   writeln( o2.SharedContainer.SharedData);
  40.   writeln( o3.SharedContainer.SharedData);
  41.   writeln( o4.SharedContainer.SharedData);
  42.  
  43. end.            
  44.  
Title: Re: Synchronizing certain Data between 2 Objects
Post by: Weitentaaal on February 01, 2023, 05:02:43 pm
 thank you guys for your patience and help. i will try your suggestions and Update this Post with the final Solution.
Title: Re: Synchronizing certain Data between 2 Objects
Post by: Zvoni on February 02, 2023, 10:10:28 am
Works.
Code: Pascal  [Select][+][-]
  1. program Project1;
  2. {$modeswitch advancedrecords}
  3.  
  4. Type
  5.  
  6.   { TSharedData }
  7.  
  8.   TSharedData = Record
  9.     SharedInteger:Integer;
  10.     SharedString:String;
  11.     Class Operator Copy(ConstRef aSrc:TSharedData;var tsd:TSharedData);
  12.   end;
  13.  
  14.   { TMyClass }
  15.  
  16.   TMyClass = Class
  17.     Private
  18.       FSharedData:TSharedData;
  19.     Public
  20.       Procedure SyncTo(Dest:TMyClass);
  21.       Property SharedData:TSharedData Read FSharedData;
  22.   end;
  23.  
  24. { TMyClass }
  25.  
  26. procedure TMyClass.SyncTo(Dest: TMyClass);
  27. begin
  28.   Dest.FSharedData:=Self.FSharedData;
  29. end;
  30.  
  31. { TSharedData }
  32.  
  33. class operator TSharedData.Copy(ConstRef aSrc: TSharedData; var tsd: TSharedData
  34.   );
  35. begin
  36.   tsd.SharedInteger:=aSrc.SharedInteger;
  37.   tsd.SharedString:=aSrc.SharedString;
  38. end;
  39.  
  40. Var
  41.   o1,o2:TMyClass;
  42. begin
  43.   o1:=TMyClass.Create;
  44.   o2:=TMyClass.Create;
  45.   o1.FSharedData.SharedInteger:=42;
  46.   o1.FSharedData.SharedString:='Dont Panic!';
  47.  
  48.   o1.SyncTo(o2);
  49.   Writeln(o2.SharedData.SharedInteger);
  50.   Writeln(o2.SharedData.SharedString);
  51.   O1.Free;
  52.   o2.Free;
  53. end.
Title: Re: Synchronizing certain Data between 2 Objects
Post by: Zvoni on February 02, 2023, 10:43:00 am
"Improved" Sample
Code: Pascal  [Select][+][-]
  1. program Project1;
  2. {$modeswitch advancedrecords}
  3.  
  4. Type
  5.  
  6.   { TSharedData }
  7.  
  8.   TSharedData = Record
  9.     SharedInteger:Integer;
  10.     SharedString:String;
  11.     Class Operator Copy(ConstRef aSrc:TSharedData;var tsd:TSharedData);
  12.   end;
  13.   PSharedData=^TSharedData;
  14.  
  15.   { TMyClass }
  16.  
  17.   TMyClass = Class
  18.     Private
  19.       FSharedData:PSharedData;
  20.     Public
  21.       Procedure SyncTo(Dest:TMyClass);
  22.       Property SharedData:PSharedData Read FSharedData;
  23.       //Constructor Create(ASrc:TMyClass);
  24.       //Destructor Destroy;Override;
  25.   end;
  26.  
  27. { TMyClass }
  28.  
  29. procedure TMyClass.SyncTo(Dest: TMyClass);
  30. begin
  31.   Dest.FSharedData:=Self.FSharedData;
  32. end;
  33.  
  34. //constructor TMyClass.Create(ASrc: TMyClass);
  35. //begin
  36. //  ////Inherited(Nil);
  37. //  //If ASrc<>Nil Then
  38. //  //  FSharedData:=ASrc.FSharedData
  39. //  //Else If FSharedData=Nil Then
  40. //  //  New(FSharedData);
  41. //end;
  42. //
  43. //destructor TMyClass.Destroy;
  44. //begin
  45. //  //If FSharedData<>Nil Then
  46. //  //  Dispose(FSharedData);
  47. //  inherited Destroy;
  48. //end;
  49.  
  50. { TSharedData }
  51.  
  52. class operator TSharedData.Copy(ConstRef aSrc: TSharedData; var tsd: TSharedData
  53.   );
  54. begin
  55.   tsd.SharedInteger:=aSrc.SharedInteger;
  56.   tsd.SharedString:=aSrc.SharedString;
  57. end;
  58.  
  59. Var
  60.   o1,o2:TMyClass;
  61.   sd:PSharedData;
  62. begin
  63.   New(sd);
  64.   sd^.SharedInteger:=42;
  65.   sd^.SharedString:='Dont panic!';
  66.  
  67.   o1:=TMyClass.Create;
  68.   o1.FSharedData:=sd;
  69.   o2:=TMyClass.Create;
  70.   o1.SyncTo(o2);
  71.  
  72.   Writeln(o1.SharedData^.SharedInteger);
  73.   Writeln(o1.SharedData^.SharedString);
  74.   Writeln(o2.SharedData^.SharedInteger);
  75.   Writeln(o2.SharedData^.SharedString);
  76.  
  77.   sd^.SharedInteger:=84;
  78.   sd^.SharedString:='Now you can panic!';
  79.  
  80.   Writeln(o1.SharedData^.SharedInteger);
  81.   Writeln(o1.SharedData^.SharedString);
  82.   Writeln(o2.SharedData^.SharedInteger);
  83.   Writeln(o2.SharedData^.SharedString);
  84.  
  85.   Dispose(sd);
  86.  
  87.   O1.Free;
  88.   O2.Free;
  89. end.
Title: Re: Synchronizing certain Data between 2 Objects
Post by: Weitentaaal on February 03, 2023, 08:19:53 am
hello,

i went with the Shared Container instead of the advanced record, because i don't fully understand the Modeswitch yet. not 100% satisfied, but works well.
Thank you !
Title: Re: Synchronizing certain Data between 2 Objects
Post by: bpranoto on February 03, 2023, 09:18:50 am
You're welcome. Object composition is one of OOP techniques which is very useful.
Title: Re: Synchronizing certain Data between 2 Objects
Post by: TRon on February 03, 2023, 09:29:09 am
... instead of the advanced record, because i don't fully understand the Modeswitch yet. not 100% satisfied, but works well.
You can think of advanced (extended) records as records on steroids that allow methods/properties and has a nice side-effect of being to use operators (overloading) or advanced records as being old style pascal object without inheritence/polymorphism.

More can be read here: https://www.freepascal.org/docs-html/current/ref/refch9.html#x119-1430009

It is worth having a look in case you are in need of some record with a bit more intelligence.

TinyPortal © 2005-2018