Recent

Author Topic: Using callback functions  (Read 1086 times)

geraldholdsworth

  • Full Member
  • ***
  • Posts: 195
Using callback functions
« on: April 18, 2021, 01:13:16 pm »
Hi all,

I have set up a call back function for my class, so that the calling code can get some feedback on the progress of operations. This works fine, if the calling code actually sets the property, but crashes if it is not set.

I have:
Code: Pascal  [Select][+][-]
  1. TProgressProc = procedure(Fupdate: Integer) of Object;
in the private section in the definition of the class.
Then:
Code: Pascal  [Select][+][-]
  1. FProgress    : TProgressProc;
as a private variable.
Then I have:
Code: Pascal  [Select][+][-]
  1. property ProgressIndicator: TProgressProc write FProgress;
in the published section of the class.
Finally, the class code calls the function:
Code: Pascal  [Select][+][-]
  1. procedure TSpriteFile.UpdateProgress(Fupdate: Integer);
  2. begin
  3.  if Assigned(FProgress) then FProgress(Fupdate);
  4. end;
(defined in the private section of the class definition).
If I remove the 'of Object' from the definition, I get told that the property cannot be published. I've also set FProgress to nil in the Create method of the class, but this has no effect, but it doesn't like:
Code: Pascal  [Select][+][-]
  1. if FProgress<>nil then FProgress(FUpdate);
For what it's worth, this is version 2.0.12 on High Sierra.

Cheers,

Gerald.

PascalDragon

  • Hero Member
  • *****
  • Posts: 5446
  • Compiler Developer
Re: Using callback functions
« Reply #1 on: April 18, 2021, 01:25:10 pm »
I've also set FProgress to nil in the Create method of the class, but this has no effect, but it doesn't like:
Code: Pascal  [Select][+][-]
  1. if FProgress<>nil then FProgress(FUpdate);

What is the exact error you're getting?

Note: it's not necessary to explicitely set variables of a class instance to Nil/0, cause that's the default value for class members directly before Create is called.

geraldholdsworth

  • Full Member
  • ***
  • Posts: 195
Re: Using callback functions
« Reply #2 on: April 18, 2021, 01:46:57 pm »
What is the exact error you're getting?
Sorry, should've mentioned that. It's EXC_BAD_ACCESS - so it is still calling the function despite nothing being defined.

Setting the FProgress to nil at Create time was just an attempt to get it working.

cdbc

  • Hero Member
  • *****
  • Posts: 1026
    • http://www.cdbc.dk
Re: Using callback functions
« Reply #3 on: April 18, 2021, 02:06:02 pm »
Hi
Have you tried to move 'property ProgressIndicator' to the public section? I don't know, but can have something to do with TPersistent et.al ???? Just my 2 cents  ::)
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 2.2.6 up until Jan 2024 from then on it's: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 3.0

geraldholdsworth

  • Full Member
  • ***
  • Posts: 195
Re: Using callback functions
« Reply #4 on: April 18, 2021, 02:14:54 pm »
Just tried that - same result.
Also tried moving the TProcessProc outside the class definition, to before it - same result.

In case it's something else, seemingly unrelated, the entire source code is here.
« Last Edit: April 18, 2021, 02:20:30 pm by geraldholdsworth »

jamie

  • Hero Member
  • *****
  • Posts: 6091
Re: Using callback functions
« Reply #5 on: April 18, 2021, 02:39:36 pm »
I started looking at that file but there is just too much to look at …


I can say this however, while in the OnCreate Event of the object the only item that is valid is the SELF, in other words, the returning object, the result that is, is not yet valid.

 So If you are setting the Call back pointer via a Timer  or something on that order with a wild value of an instance the Assign test will pass because it knows no better but it does not mean it's valid..

 I can't say if this is what you are doing but this is what you can try and that is at the start up before calling any constructors, not while inside a constructor you should be ensuring any returning instance is set to nil.

 If you have instances living outside a class in global space, on the heap, in some array etc, these most likely have wild values in them and they need to be cleared before any of this stuff gets running...

 Also while in the app if you unhook them, they should be NILLED out so that the Assign will work properly …

This is just my assumptions because I've seen code like this before in Delphi which is where I've been spending a lot of time lately and I am sure its no different in fpc in this respect.
The only true wisdom is knowing you know nothing

geraldholdsworth

  • Full Member
  • ***
  • Posts: 195
Re: Using callback functions
« Reply #6 on: April 18, 2021, 03:00:29 pm »
Thank you Jamie - that got me thinking. So, in the calling code, I added a line setting the property ProgressIndicator to nil. The UpdateProgress procedure then correctly did not call the function, as it was not defined. However, I still got the same error, but this time when I freed the class. It took me a while, but I then realised I was creating the instance wrong.
I had:
Code: Pascal  [Select][+][-]
  1. sp.Create
(where sp is of type TSpriteFile, the class) where it should have been:
Code: Pascal  [Select][+][-]
  1. sp:=TSpriteFile.Create
Definitely a "D'OH!" moment!!!

jamie

  • Hero Member
  • *****
  • Posts: 6091
Re: Using callback functions
« Reply #7 on: April 18, 2021, 03:06:19 pm »
ok, well I never would of expected you to do something like that   :'(
The only true wisdom is knowing you know nothing

 

TinyPortal © 2005-2018