Recent

Author Topic: New component - properties are integer instead of single  (Read 2936 times)

bobby100

  • Sr. Member
  • ****
  • Posts: 260
    • Malzilla
New component - properties are integer instead of single
« on: June 17, 2024, 06:44:15 pm »
I have created two components:
- a graphic component
- a component just with properties, so that I can have more of the first component sharing the same settings (like sharing the same theme/appearance)

A lot of the published properties from the Theme component are of the type single (decimal point numbers).
After installing the component, the half of the properties are OK, the 2nd half are reduced to integer.
The problem is not just in Object Inspector, but also at reading these properties from other components.
Code: Pascal  [Select][+][-]
  1. property BLCD_FrameColor: TColor read FFrameColor write SetFrameColor default clBtnFace;
  2.     property BLCD_BoardColor: TColor read FBoardColor write SetBoardColor default clBlack;
  3.     property BLCD_DotColorOn: TColor read FDotColorOn write SetDotColorOn default clSkyBlue;
  4.     property BLCD_ColorScheme: TColorScheme read FColorScheme write SetColorScheme default csCustom;
  5.     property BLCD_FrameAltitude: integer read FFrameAltitude write SetFrameAltitude default 2;
  6.     property BLCD_FrameHeight: integer read FFrameHeight write SetFrameHeight default 8;
  7.     property BLCD_FrameSize: integer read FFrameSize write SetFrameSize default 8;
  8.     property BLCD_FrameStyle: TFrameStyle read FFrameStyle write SetFrameStyle default fsFlat;
  9.     property BLCD_DotShape: TDotShape read FDotShape write SetDotShape default stSquare;
  10.     property BLCD_DotSize: integer read FDotSize write SetDotSize default 4;
  11.     property BLCD_DotsSpace: integer read FDotsSpace write SetDotsSpace default 1;
  12.     property BLCD_DotBlend: boolean read FDotBlend write SetDotBlend default False;
  13.     property BLCD_DotBlendOperation: TBlendOperation read FDotBlendOperation write SetDotBlendOperation default boGlow;
  14.     property BLCD_DotBlur: boolean read FDotBlur write SetDotBlur default False;
  15.     property BLCD_DotBlurRadius: single read FDotBlurRadius write SetDotBlurRadius default 0.8;
  16.     property BLCD_BoardShadow: TBoardShadow read FBoardShadow write SetBoardShadow default bsFrame;
  17.     property COM_LightSourceIntensity: single read FLightSourceIntensity write SetLightSourceIntensity default 500;
  18.     property COM_LightSourceDistanceTerm: single read FLightSourceDistanceTerm write SetLightSourceDistanceTerm default 150;
  19.     property COM_LightSourceDistanceFactor: single read FLightSourceDistanceFactor write SetLightSourceDistanceFactor default 1.0;
  20.     property COM_LightDestFactor: single read FLightDestFactor write SetLightDestFactor default 1.0;
  21.     property COM_LightColor: TColor read FLightColor write SetLightColor default clWhite;
  22.     property COM_SpecularFactor: single read FSpecularFactor write SetSpecularFactor default 0.6;
  23.     property COM_SpecularIndex: single read FSpecularIndex write SetSpecularIndex default 10;
  24.     property COM_AmbientFactor: single read FAmbientFactor write SetAmbientFactor default 0.3;
  25.     property COM_DiffusionFactor: single read FDiffusionFactor write SetDiffusionFactor default 0.9;
  26.     property COM_NegativeDiffusionFactor: single read FNegativeDiffusionFactor write SetNegativeDiffusionFactor default 0.1;
  27.     property COM_DiffuseSaturation: boolean read FDiffuseSaturation write SetDiffuseSaturation default False;
  28.     property COM_LightPositionX: integer read FLightPositionX write SetLightPositionX default -100;
  29.     property COM_LightPositionY: integer read FLightPositionY write SetLightPositionY default -100;
  30.     property COM_LightPositionZ: integer read FLightPositionZ write SetLightPositionZ default 100;

All the properties with BLCD_ in name are OK, all the properties with COM_ in name are reduced to integer and the value is always zero (shows in Object Inspector without decimals).
It helped once when I changed the properties names (it was C_, now is COM_), but today returned to the old problem. Is underscore in properties name a problem?

Problem exists in debug and release mode.

Using Lazarus 2.2.6 with FPC 3.2.2 on Windows 10.

Thaddy

  • Hero Member
  • *****
  • Posts: 16187
  • Censorship about opinions does not belong here.
Re: New component - properties are integer instead of single
« Reply #1 on: June 17, 2024, 10:16:32 pm »
It looks like it and if that is the case that is a bug since underscores are part of the allowed character set. Anyway, best to get rid of the underscores and if it is the cause, file a bug report. Your code will look nicer too...
Then again, the working part of your code has also underscores and that should be fine.
Maybe  COM is not a good naming unless it refers to COM interfaces. Make it COMO or something.
« Last Edit: June 17, 2024, 10:21:40 pm by Thaddy »
If I smell bad code it usually is bad code and that includes my own code.

bobby100

  • Sr. Member
  • ****
  • Posts: 260
    • Malzilla
Re: New component - properties are integer instead of single
« Reply #2 on: June 17, 2024, 11:18:15 pm »
It seems that the problem goes far beyond the property names.
I've installed Lazarus 3.4 - the problem remains, but there is even more - not even the IDE works like it should anymore. It gets into infinite loops etc. If I delete the Theme component from the form, everything is fine with the IDE.

I am doing something very, very wrong. I'll try tomorrow to post simplified code here.


bobby100

  • Sr. Member
  • ****
  • Posts: 260
    • Malzilla
Re: New component - properties are integer instead of single
« Reply #3 on: June 18, 2024, 07:31:05 pm »
Here is the code. It shouldn't have external dependencies.

So, TBLCDDisplay is a graphic component, TBComponentTheme contains the colors etc. settings.
The idea is that more than one TBLCDDisplays can have centralized appearance settings. The further plan is to have more different components using the same theme.

As soon as I assign the TBComponentTheme to the TBLCDDisplay - everything stops responding. I have somewhere a loop between the components that I am not aware of.
All the variables in TBComponentTheme were in the public section, but I have had a loss of values. This would be the original problem in this thread (integers instead of single).
I've moved the variables into a separate class (TPersistent), and it seems that values aren't lost now, but I still have the loop. After clicking the button in the test app - it doesn't even finish drawing the TBLCDDisplay.

Could someone help me here?


alpine

  • Hero Member
  • *****
  • Posts: 1302
Re: New component - properties are integer instead of single
« Reply #5 on: June 20, 2024, 06:09:14 pm »
TBLCDDisplay.Paint() --> Prepare() --> ApplyTheme() --> Invalidate (-->Paint)

Also in ApplyTheme you don't have begin/end block according to the indentation.
"I'm sorry Dave, I'm afraid I can't do that."
—HAL 9000

bobby100

  • Sr. Member
  • ****
  • Posts: 260
    • Malzilla
Re: New component - properties are integer instead of single
« Reply #6 on: June 20, 2024, 06:48:35 pm »
alpine, you are my hero - thank you very, very much!

That incomplete begin/end block is from trying to get this working - added code, didn't help - delete code etc. Somehow deleted more than needed there.
I wonder why the compiler didn't throw an error there...

alpine

  • Hero Member
  • *****
  • Posts: 1302
Re: New component - properties are integer instead of single
« Reply #7 on: June 20, 2024, 06:57:28 pm »
No problem.

What about the original problem with the properties. Is it resolved now?
"I'm sorry Dave, I'm afraid I can't do that."
—HAL 9000

bobby100

  • Sr. Member
  • ****
  • Posts: 260
    • Malzilla
Re: New component - properties are integer instead of single
« Reply #8 on: June 20, 2024, 07:26:34 pm »
Yes, it is.
I don't know what exactly helped. The biggest change was to move all the internal variables into a TPersistent class (the variables containing theme settings).
At some step, I saw that the variables are losing the values mid into applying the theme (a couple of values are applied OK, the rest was causing problems like division by zero). The debugger was complaining about not finding the values in memory (or something like that, I didn't take a note of the message). It seems like the variables are de-reffered somehow (pointers being null-ed?). That could be the exact problem of the properties in object inspector too - if the variables are not found in memory, the object inspector couldn't render it right. I came to thoughts that somehow my class instance gets exchanged by the raw class structure (no instance created).
It should not be the case. I am using TBComponentTheme as a palette component in Lazarus. After dropping such component on the form - the Create should be called by the form.
At the point with TBComponentTheme component dropped onto the form - the Object Inspector was already showing wrong values.
After assigning the TBComponentTheme to a LCDDisplay component - the IDE would not render completely, my form would not render completely etc.

So, the single significant change was moving the variables (theme-related) inside the TBComponentTheme into a separate TPersistent class (TThemeSet), create an instance of it in TBComponentTheme.Create, and work with the instance.

alpine

  • Hero Member
  • *****
  • Posts: 1302
Re: New component - properties are integer instead of single
« Reply #9 on: June 20, 2024, 07:45:33 pm »
I'm just speculating, but - is it possible that the total mess created by the paint loop to give you the impression that persistency is broken while it isn't? After all installing it into the IDE will broke it's loop too.
 Edit: Just loading the project, placing a breakpoint and pressing F9 a few times was enough to catch the loop by examining the stack window. I'm on Linux and there wasn't any big troubles (hang-ups or something) with the IDE. I suspect on Win it will behave differently because of the toolkit.
« Last Edit: June 20, 2024, 07:51:54 pm by alpine »
"I'm sorry Dave, I'm afraid I can't do that."
—HAL 9000

bobby100

  • Sr. Member
  • ****
  • Posts: 260
    • Malzilla
Re: New component - properties are integer instead of single
« Reply #10 on: June 20, 2024, 08:27:07 pm »
The loop you resolved came latter. I've moved code around between the procedures because I was thinking that the LCDDisplay is accessing variables from BComponentTheme before variables got initialized, and that's how I probably caused the loop.
Before moving the variables into TPersistent, in most of the cases, the program got bugging at SetFrameStyle in TBComponentTheme. The value to be set was one with the "could not be found in memory" problem. My biggest problem at that moment was, that I didn't even call any Set procedures at all. Call stack didn't help at all here - I couldn't find what was calling my SetFrameStyle.
The code was simply running wild (tested with Lazarus 2.2.6 and 3.4 on Windows 10, installers from sourceforge).

alpine

  • Hero Member
  • *****
  • Posts: 1302
Re: New component - properties are integer instead of single
« Reply #11 on: June 20, 2024, 08:38:34 pm »
Quote
Before moving the variables into TPersistent,
I'm a bit confused - in order to put something in a form it must be a TComponent (i.e. TPersistent), which should do the persistency stuff. How did you do it before?
"I'm sorry Dave, I'm afraid I can't do that."
—HAL 9000

bobby100

  • Sr. Member
  • ****
  • Posts: 260
    • Malzilla
Re: New component - properties are integer instead of single
« Reply #12 on: June 20, 2024, 09:31:37 pm »
So, before:

Code: Pascal  [Select][+][-]
  1. TBComponentsTheme = class(TComponent)
  2. private
  3.   FParameter1: integer;
  4.   FParameter2: single;
  5. .
  6. .
  7.   procedure SetParameter1(AValue: integer);
  8.   procedure SetParameter2(AValue: single);
  9.  
  10. published
  11.   property Parameter1: integer read FParameter1 write SetParameter1;
  12.   property Parameter2: single read FParameter2 write SetParameter2;
  13.  
  14. etc.
and that didn't work well (situation at the beginning of this topic).

Now:
Code: Pascal  [Select][+][-]
  1. TBComponentsThemeSet = class(TPersistent)
  2. public
  3.   FParameter1: integer;
  4.   FParameter2: single;
  5. end;
  6.  
  7. TBComponentTheme = class(TComponent)
  8. private
  9.   FThemeSet: TBComponentsThemeSet;
  10.   function GetParameter1: integer;
  11.   function GetParameter2: single;
  12.   procedure SetParameter1(AValue: integer);
  13.   procedure SetParameter2(AValue: single);
  14. published
  15.   property Parameter1: integer read GetParameter1 write SetParameter1;
  16.   property Parameter2: single read GetParameter2 write SetParameter2;
  17. .
  18. .
  19. .
  20.  
  21. implementation
  22.  
  23. constructor TBComponentTheme (AOwner: TComponent);
  24. begin
  25.   inherited Create (AOwner: TComponent);
  26.   FThemeSet := TBComponentsThemeSet.Create;
  27. end;
  28.  
  29. destructor TBComponentTheme.Destroy;
  30. begin
  31.   FreeAndNil(FThemeSet);
  32.   inherited Destroy;
  33. end;
  34.  
  35. procedure TBComponentTheme.SetParameter1(AValue: integer);
  36. begin
  37.   FThemeSet.FParameter1 := AValue;
  38. end;
  39.  
  40. function TBComponentTheme.GetParameter1: integer;
  41. begin
  42.   Result := FThemeSet.FParameter1;
  43. end;
  44.  
This is how it is now, and it works.

Code is cropped to just the necessary to show the basic idea.

alpine

  • Hero Member
  • *****
  • Posts: 1302
Re: New component - properties are integer instead of single
« Reply #13 on: June 21, 2024, 10:17:55 am »
Still not clear for me. The actual difference is that you have added property accessors GetParameterX into the TBComponentTheme. IMO the TBComponentsThemeSet not relevant at all, even less it's predecessor TPersistent.

Have you tried just to replace read FParameterX (private field) with read GetParameterX (accessor) wich simply returns FParameterX? Without using the TBComponentsThemeSet.
"I'm sorry Dave, I'm afraid I can't do that."
—HAL 9000

bobby100

  • Sr. Member
  • ****
  • Posts: 260
    • Malzilla
Re: New component - properties are integer instead of single
« Reply #14 on: June 21, 2024, 01:06:45 pm »
Didn't try with getter-functions before I moved the variables into a separate class, e.g. until it really went necessary.
What I did try, but without anything being better, was to move the variables between the sections (private, protected, public).
I've also tried direct set access in Properties
Code: [Select]
  property ParameterX read FParameterX write FParameterX;, but that didn't bring any good.

 

TinyPortal © 2005-2018