Recent

Author Topic: [Solved] How to call a class from several units once in OOP  (Read 299 times)

nikel

  • Sr. Member
  • ****
  • Posts: 252
[Solved] How to call a class from several units once in OOP
« on: April 19, 2025, 03:22:01 pm »
Hello, I made a console application which has a config class required by 5 other units. I noticed that the class is called tens of times from functions and classes. I want to obey object oriented programming techniques but don't know how to. Here's the top part of the class.

Code: Pascal  [Select][+][-]
  1. unit Config;
  2.  
  3. {$mode objfpc}
  4. {$m+}
  5. {$TYPEDADDRESS ON}
  6.  
  7. // token 0.1
  8.  
  9. interface
  10.  
  11. uses
  12.   Classes, SysUtils, StrUtils,
  13.   Token, PathsHandler;
  14.  
  15. type
  16.   {TConfig}
  17.   PConfig = ^TConfig;
  18.   TConfig = class
  19.   private
  20.     FDayLongStartTime      : shortstring;
  21.     FDayLongEndTime        : shortstring;
  22.     FDayLongMinBpm         : Byte;
  23.     FDayLongMaxBpm         : Byte;
  24.     FDayLongPath           : string;
  25.     FNightLongStartTime    : shortstring;
  26.     FNightLongEndTime      : shortstring;
  27.     FNightLongMinBpm       : Byte;
  28.     FNightLongMaxBpm       : Byte;
  29.     FNightLongPath         : string;
  30.     FFileType              : shortstring;
  31.     FLastDirectionOfSort   : shortstring;
  32.     FDayLongParams         : shortstring;
  33.     FNightLongParams       : shortstring;
  34.     FBasePath              : string;
  35.     FMinBpm                : Byte;
  36.     FMaxBpm                : Byte;
  37.     FLastPeriod            : shortstring;
  38.  
  39.     FNameOfIndex           : shortstring;
  40.     FConfigFile            : string;
  41.     FDelimiter             : Char;
  42.     FCurrentDir            : string;
  43.     FCurrentPeriod         : shortstring;
  44.     FListOfSort            : TStringList;
  45.     FListOfImport          : TStringList;
  46.   protected
  47.     procedure DoRun;
  48.   public
  49.     constructor Create(TheOwner: TComponent; Cf: string; Dl: Char);
  50.     destructor Destroy;
  51.  
  52.     property DayLongStartTime      : shortstring read FDayLongStartTime write FDayLongStartTime;
  53.     property DayLongEndTime        : shortstring read FDayLongEndTime write FDayLongEndTime;
  54.     property DayLongMinBpm         : Byte read FDayLongMinBpm write FDayLongMinBpm;
  55.     property DayLongMaxBpm         : Byte read FDayLongMaxBpm write FDayLongMaxBpm;
  56.     property DayLongPath           : string read FDayLongPath write FDayLongPath;
  57.     property NightLongStartTime    : shortstring read FNightLongStartTime write FNightLongStartTime;
  58.     property NightLongEndTime      : shortstring read FNightLongEndTime write FNightLongEndTime;
  59.     property NightLongMinBpm       : Byte read FNightLongMinBpm write FNightLongMinBpm;
  60.     property NightLongMaxBpm       : Byte read FNightLongMaxBpm write FNightLongMaxBpm;
  61.     property NightLongPath         : string read FNightLongPath write FNightLongPath;
  62.     property FileType              : shortstring read FFileType write FFileType;
  63.     property LastDirectionOfSort   : shortstring read FLastDirectionOfSort write FLastDirectionOfSort;
  64.     property DayLongParams         : shortstring read FDayLongParams write FDayLongParams;
  65.     property NightLongParams       : shortstring read FNightLongParams write FNightLongParams;
  66.     property BasePath              : string read FBasePath write FBasePath;
  67.     property MinBpm                : Byte read FMinBpm;
  68.     property MaxBpm                : Byte read FMaxBpm;
  69.     property LastPeriod            : shortstring read FLastPeriod write FLastPeriod;
  70.  
  71.     property NameOfIndex: shortstring read FNameOfIndex write FNameOfIndex;
  72.     property ConfigFile: string read FConfigFile write FConfigFile;
  73.     property Delimiter: Char read FDelimiter write FDelimiter;
  74.     property CurrentDir: string read FCurrentDir write FCurrentDir;
  75.     property CurrentPeriod: shortstring read FCurrentPeriod;
  76.     property ListOfSort: TStringList read FListOfSort write FListOfSort;
  77.     procedure WriteConfig(Prop: shortstring; Val: string);
  78.     function ReadConfig(Req: shortstring): string;
  79.     function TrimLeadingZeros(const S: string): string;
  80.     function StrToMinutes(S: string): Integer;
  81.   end;
  82.  
  83. implementation
  84. ...

How can I make it accessible by other units and execute once? I want to execute it once because it reads / saves settings and I don't want to do this multiple times.
« Last Edit: April 19, 2025, 05:09:41 pm by nikel »

dseligo

  • Hero Member
  • *****
  • Posts: 1507
Re: How to call a class from several units once in OOP
« Reply #1 on: April 19, 2025, 03:36:19 pm »
Maybe something like this:
Code: Pascal  [Select][+][-]
  1.     unit Config;
  2.      ...
  3.      
  4.     type
  5.       {TConfig}
  6.       PConfig = ^TConfig;
  7.       TConfig = class
  8.       private
  9. ...
  10.       end;
  11.  
  12. var MyConfig: TConfig;
  13.  
  14.  
  15.     implementation
  16.     ...
  17. initialization
  18.   MyConfig := TConfig.Create;
  19.  
  20. finalization
  21.   MyConfig.Free;
  22.  
  23.  

And now you can use MyConfig in your other units.

cdbc

  • Hero Member
  • *****
  • Posts: 2128
    • http://www.cdbc.dk
Re: How to call a class from several units once in OOP
« Reply #2 on: April 19, 2025, 04:01:25 pm »
Hi
edit dseligo beat me to it...
Simplest solution is to make it a Poorman's 'Singleton', implement it in the implementation section of your unit and access it through a Singleton-function, that returns the same class over and over again, but only creates it once on first use.
On program stop, you free it in the unit's 'finalization' section...
Something like this:
Code: Pascal  [Select][+][-]
  1. unit singleton.config;
  2.  
  3. {$mode ObjFPC}{$H+}
  4. {$m+}
  5. {$TYPEDADDRESS ON}
  6. interface
  7.  
  8. uses
  9.   Classes, SysUtils, StrUtils,
  10.   Token, PathsHandler;
  11.  
  12. type
  13.   {TConfig}
  14.   PConfig = ^TConfig;
  15.   TConfig = class
  16.   private
  17.     FDayLongStartTime      : shortstring;
  18.     FDayLongEndTime        : shortstring;
  19.     FDayLongMinBpm         : Byte;
  20.     FDayLongMaxBpm         : Byte;
  21.     FDayLongPath           : string;
  22.     FNightLongStartTime    : shortstring;
  23.     FNightLongEndTime      : shortstring;
  24.     FNightLongMinBpm       : Byte;
  25.     FNightLongMaxBpm       : Byte;
  26.     FNightLongPath         : string;
  27.     FFileType              : shortstring;
  28.     FLastDirectionOfSort   : shortstring;
  29.     FDayLongParams         : shortstring;
  30.     FNightLongParams       : shortstring;
  31.     FBasePath              : string;
  32.     FMinBpm                : Byte;
  33.     FMaxBpm                : Byte;
  34.     FLastPeriod            : shortstring;
  35.  
  36.     FNameOfIndex           : shortstring;
  37.     FConfigFile            : string;
  38.     FDelimiter             : Char;
  39.     FCurrentDir            : string;
  40.     FCurrentPeriod         : shortstring;
  41.     FListOfSort            : TStringList;
  42.     FListOfImport          : TStringList;
  43.   protected
  44.     procedure DoRun;
  45.   public
  46.     constructor Create(TheOwner: TComponent; Cf: string; Dl: Char);
  47.     destructor Destroy;
  48.  
  49.     property DayLongStartTime      : shortstring read FDayLongStartTime write FDayLongStartTime;
  50.     property DayLongEndTime        : shortstring read FDayLongEndTime write FDayLongEndTime;
  51.     property DayLongMinBpm         : Byte read FDayLongMinBpm write FDayLongMinBpm;
  52.     property DayLongMaxBpm         : Byte read FDayLongMaxBpm write FDayLongMaxBpm;
  53.     property DayLongPath           : string read FDayLongPath write FDayLongPath;
  54.     property NightLongStartTime    : shortstring read FNightLongStartTime write FNightLongStartTime;
  55.     property NightLongEndTime      : shortstring read FNightLongEndTime write FNightLongEndTime;
  56.     property NightLongMinBpm       : Byte read FNightLongMinBpm write FNightLongMinBpm;
  57.     property NightLongMaxBpm       : Byte read FNightLongMaxBpm write FNightLongMaxBpm;
  58.     property NightLongPath         : string read FNightLongPath write FNightLongPath;
  59.     property FileType              : shortstring read FFileType write FFileType;
  60.     property LastDirectionOfSort   : shortstring read FLastDirectionOfSort write FLastDirectionOfSort;
  61.     property DayLongParams         : shortstring read FDayLongParams write FDayLongParams;
  62.     property NightLongParams       : shortstring read FNightLongParams write FNightLongParams;
  63.     property BasePath              : string read FBasePath write FBasePath;
  64.     property MinBpm                : Byte read FMinBpm;
  65.     property MaxBpm                : Byte read FMaxBpm;
  66.     property LastPeriod            : shortstring read FLastPeriod write FLastPeriod;
  67.  
  68.     property NameOfIndex: shortstring read FNameOfIndex write FNameOfIndex;
  69.     property ConfigFile: string read FConfigFile write FConfigFile;
  70.     property Delimiter: Char read FDelimiter write FDelimiter;
  71.     property CurrentDir: string read FCurrentDir write FCurrentDir;
  72.     property CurrentPeriod: shortstring read FCurrentPeriod;
  73.     property ListOfSort: TStringList read FListOfSort write FListOfSort;
  74.     procedure WriteConfig(Prop: shortstring; Val: string);
  75.     function ReadConfig(Req: shortstring): string;
  76.     function TrimLeadingZeros(const S: string): string;
  77.     function StrToMinutes(S: string): Integer;
  78.   end;
  79.  
  80. { Singleton-function provides access to 1 TConfig instance, you need only call
  81.   it once with parameters, after that just call it without 'cause they're all default }
  82. function gConfig(TheOwner: TComponent = nil; Cf: string = ''; Dl: Char = ' '): TConfig;
  83.  
  84. implementation
  85.  
  86. var Singleton: TConfig = nil;
  87.                                                  
  88. function gConfig(TheOwner: TComponent = nil; Cf: string = ''; Dl: Char = ' '): TConfig;
  89. begin
  90.   if not Assigned(Singleton) then Singleton:= TConfig.Create(TheOwner,Cf,Dl);
  91.   Result:= Singleton;
  92. end;
  93.  
  94. finalization
  95.   if Assigned(Singleton) then Singleton.Free;
  96.  
  97. end.
  98.  
On program startup you call the 'gConfig(Self,'Somestring',aChar);' once with parameters, after that you can just use it as/like a variable 'gConfig.CurrentDir:= /home/you/tmp/'... Innit cool  8-)
HTH
Regards Benny
« Last Edit: April 19, 2025, 04:04:56 pm by cdbc »
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 3.6 up until Jan 2024 from then on it's both above &: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 4.99

Thaddy

  • Hero Member
  • *****
  • Posts: 16939
  • Ceterum censeo Trump esse delendam
Re: How to call a class from several units once in OOP
« Reply #3 on: April 19, 2025, 04:19:50 pm »
Code: Pascal  [Select][+][-]
  1.   {TConfig}
  2.   PConfig = ^TConfig;
  3.   TConfig = class
TConfig is already a pointer. don't f*ck up your code by using ppointers....
Such constructs are only relevant for records, not for classes>:D

Then a solution:
Use the initialization section of the class's unit. Instantiate the class and make sure the variable is public.
« Last Edit: April 19, 2025, 04:25:14 pm by Thaddy »
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

nikel

  • Sr. Member
  • ****
  • Posts: 252
Re: How to call a class from several units once in OOP
« Reply #4 on: April 19, 2025, 04:24:46 pm »
Thaddy, thanks for the hint. I was in doubt about it.

Thaddy

  • Hero Member
  • *****
  • Posts: 16939
  • Ceterum censeo Trump esse delendam
Re: How to call a class from several units once in OOP
« Reply #5 on: April 19, 2025, 04:25:46 pm »
I added a solution.
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

nikel

  • Sr. Member
  • ****
  • Posts: 252
Re: How to call a class from several units once in OOP
« Reply #6 on: April 19, 2025, 05:09:22 pm »
dseligo, cdbc, your mysterious code works fine. Thanks a lot. You're all great programmers.

 

TinyPortal © 2005-2018