Recent

Author Topic: [Solved] Passing the address of a method to another class.  (Read 3640 times)

dbannon

  • Hero Member
  • *****
  • Posts: 3797
    • tomboy-ng, a rewrite of the classic Tomboy
[Solved] Passing the address of a method to another class.
« on: November 04, 2017, 12:45:25 pm »
I'd like to pass the address of a method to another class so that it can call that method when it needs to. (Reason is the second class does not have any GUI aspect, its tidy to allow the upper level class to ask the user a question.)  Here is a simplified version of what I want to do, it won't compile in either Delphi or ObjFPC mode. However, if instead of the ClassA method, I make a standalone function, that works OK in Delphi mode. I cannot use a standalone function as I need access to the ClassA's data.

Code: Pascal  [Select][+][-]
  1. program test;
  2. {$mode objfpc}{$H+}
  3.  
  4. type  TProceedFunction = function() : boolean;
  5.  
  6. type TClassA = class
  7.         function Proceed : boolean;
  8.         procedure DoIt;
  9. end;
  10.  
  11. type TClassB = class
  12.         ProceedFunction : TProceedFunction;
  13.         procedure CallTheFunction;
  14. end;
  15.  
  16. function TClassA.Proceed : boolean;
  17. begin
  18.         writeln('Wow, we called Proceed');
  19.         Result := True;
  20. end;
  21.  
  22. procedure TClassA.DoIt;
  23. var
  24.         ClassB : TClassB;
  25. begin
  26.         ClassB := TClassB.Create;
  27.         ClassB.ProceedFunction := @Proceed;
  28.         ClassB.CallTheFunction;
  29.         ClassB.Free;
  30. end;
  31.  
  32. procedure TClassB.CallTheFunction;
  33. begin
  34.         ProceedFunction;
  35. end;
  36.  
  37. var
  38.         ClassA : TClassA;
  39.  
  40. begin
  41.         ClassA := TClassA.Create;
  42.         ClassA.DoIt;
  43.         ClassA.free;
  44. end.
 

Sorry ! I made it as short as I could !  Any suggestions how I can tell ClassB what function to call when it needs a bit of reassurance ?
« Last Edit: November 05, 2017, 03:31:34 am by dbannon »
Lazarus 3, Linux (and reluctantly Win10/11, OSX Monterey)
My Project - https://github.com/tomboy-notes/tomboy-ng and my github - https://github.com/davidbannon

Thaddy

  • Hero Member
  • *****
  • Posts: 19125
  • Glad to be alive.
Re: Passing the address of a method to another class.
« Reply #1 on: November 04, 2017, 12:54:43 pm »
Use an TNotfyevent  property in class a and handle that if it is called with class b as sender.
« Last Edit: November 04, 2017, 12:56:30 pm by Thaddy »
objects are fine constructs. You can even initialize them with constructors.

Leledumbo

  • Hero Member
  • *****
  • Posts: 8836
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: Passing the address of a method to another class.
« Reply #2 on: November 04, 2017, 03:27:51 pm »
Code: Pascal  [Select][+][-]
  1. type  TProceedFunction = function() : boolean of object;
  2.  

Thaddy

  • Hero Member
  • *****
  • Posts: 19125
  • Glad to be alive.
Re: Passing the address of a method to another class.
« Reply #3 on: November 04, 2017, 03:53:32 pm »
Code: Pascal  [Select][+][-]
  1. type  TProceedFunction = function() : boolean of object;
  2.  

No. if he wants to access the data easily (and OOP) it should be at least:
Code: Pascal  [Select][+][-]
  1. type  TProceedFunction = function(sender:Tobject) : boolean of object;
  2. // and check the event like:
  3.   if sender is classB then with
  4.     sender as classB do....// access published properties and methods
  5.  

Because the sender has the data...
« Last Edit: November 04, 2017, 04:08:58 pm by Thaddy »
objects are fine constructs. You can even initialize them with constructors.

jamie

  • Hero Member
  • *****
  • Posts: 7695
Re: Passing the address of a method to another class.
« Reply #4 on: November 04, 2017, 10:31:40 pm »
Why can't a field member of that ClassA be inside of classB?

That way you gan access to the whole class instant and you don't need to create an
instant of it inside ClassB, just set it via a property.
 
 If the idea is to access different visual effects by resetting this, you can create a
base class with the common method in it to be called, that way various different classes of the
same base can be assigned to this field property in ClassB.

 This almost sounds like Home work but I could be wrong ;)

The only true wisdom is knowing you know nothing

dbannon

  • Hero Member
  • *****
  • Posts: 3797
    • tomboy-ng, a rewrite of the classic Tomboy
Re: Passing the address of a method to another class.
« Reply #5 on: November 05, 2017, 02:24:23 am »
This forum really does deliver !
I don't see how I can use TNotifyEven to pass up my needed parameters but Leledumbo's model works in my test file.
That trick would not compile in my real app, so I assumed it was a Delphi only thing and did not try it in my test file. Sigh ... It does, of course, work in my test file so I'm going to have to find out whats happening.

Thanks Folks !
Quote
This almost sounds like Home work but I could be wrong
Yep, you are wrong ! The other end altogether. Its a retirement project !  After a long career using opensource I thought it time I put some back. Not far away from making a song and dance about it.
David
Lazarus 3, Linux (and reluctantly Win10/11, OSX Monterey)
My Project - https://github.com/tomboy-notes/tomboy-ng and my github - https://github.com/davidbannon

schuler

  • Sr. Member
  • ****
  • Posts: 336
Re: Passing the address of a method to another class.
« Reply #6 on: November 05, 2017, 02:33:46 am »
I would not say that it's a retirement project. I would say that it's a "self funded" project. It markets better.

I would like to bring attention to the "of object". Also, have a look at the "Assigned" function.

dbannon

  • Hero Member
  • *****
  • Posts: 3797
    • tomboy-ng, a rewrite of the classic Tomboy
Re: Passing the address of a method to another class.
« Reply #7 on: November 05, 2017, 03:30:55 am »
OK, the "of object" works in my main app now too. My issue was that I was running that unit in Delphi mode (because I was too lazy to deref a bunch of pointers to records).

Just to be clear, in my example code, ClassA must be in objfpc mode, not delphi mode. It does not matter which mode ClassB is compiled under. And thats where I define the type with its rather strange "of object" qualifier.
I say strange because its not an object, its a class and the qualifier appears to apply to the return value not the function! ;D

But I'm happy, its all working.  Thanks Thaddy, Leledumbo,  jamie and schuler !

When I first suggested 'we' move our project over to Pascal I was met with stunned silence. I was willing to contribute but it turned out I've done it all (with massive help from the lazarus community). I have already proved FPC/Lazarus is a better cross platform solution than the ungodly mixture of GTK+, Mono, C# that we have been using. And its fun to work with!

David
Lazarus 3, Linux (and reluctantly Win10/11, OSX Monterey)
My Project - https://github.com/tomboy-notes/tomboy-ng and my github - https://github.com/davidbannon

 

TinyPortal © 2005-2018