Recent

Author Topic: procedure references with custom argument types  (Read 1556 times)

ardera

  • Newbie
  • Posts: 1
procedure references with custom argument types
« on: February 12, 2018, 08:32:38 pm »
Hello,
I am using Lazarus for a school project and I'm trying to make an EventManager class for it.
I want the Event Listeners to be able to register custom callbacks, so they can do this for example:

Code: Pascal  [Select][+][-]
  1. constructor TSomething.Create(game: TGame);
  2. begin
  3.   game.eventmanager.listen(@self.onPlayerDeath, TPlayerDeathEvent);
  4. end;
  5. procedure TSomething.onPlayerDeath(e: TPlayerDeathEvent);
  6. begin
  7.   // do something
  8. end;
  9.  

normally you'd do something like this in the eventmanager class:
Code: Pascal  [Select][+][-]
  1. type
  2.   TEventClass = class of TEvent;
  3.   TEventCallback = procedure(e: TEvent) of object;
  4.  
  5.   TEventManager = class
  6.     private
  7.       eventclasses: array of TEventClass;
  8.       eventcallbacks: array of array of TEventCallback;
  9.     // etc
  10.   end;
  11.  
When you want to fire an Event, you'd just find the index of an event class and then call all callbacks that are in eventcallbacks[index of the event class].

However, I want the callback procedures to take the specialized Event as an Argument, as you can see in my first code example.
(onPlayerDeath takes TPlayerDeathEvent as an Argument, NOT TEvent!; that is a difference from the definition of TEventCallback)

The first problem, which is a minor one, is that the compiler would probably error when I'd assign @InstanceOfTSomething.onPlayerDeath to let's say eventcallbacks[0][0]; because the arguments of the procedures aren't of the same type. My solution would be let the type TEventCallback equal TMethod, then there'd be no checks. But how do I call a TMethod when I the argument type varies?

What is the best way to achieve this?


Some ideas:
  • somehow using generics
  • using assembly to call the callbacks
  • just disposing the whole concept and using TEvent as an argument type for all callbacks
« Last Edit: February 12, 2018, 08:36:52 pm by ardera »

jamie

  • Hero Member
  • *****
  • Posts: 7662
Re: procedure references with custom argument types
« Reply #1 on: February 12, 2018, 11:20:43 pm »
You need to provide a CMD value and a Command Record.

CMD value would be one of many values pointing to what ever functions you want.
The function can query the Command record which is actually the Parameter record.

You can have a Record type for each cmd format..

This Record will be past in a form of a pointer so you can type case over it the Record you
want..
 
 Of course this Record needs to be filled out prior to sending it...

-- Another option to be thought about ---

If you use the Message Handler in the classes you can define a unique message ID for each function you want.

 You can use SENDMESSAGE as a direct route or PostMessage to que it in order with others waiting.

 when do you messages you start with LM_USER+? for each handler you want.
the receiving class will cycle down through looking for your message you have defined and the method  you
have defined for it.

 Come back for more if this gets you interested.

The only true wisdom is knowing you know nothing

 

TinyPortal © 2005-2018