Reflection / Invoke

BlitzMax Forums/BlitzMax Programming/Reflection / Invoke

GrimGary(Posted 2016) [#1]
The setup I'm trying to do is that I have several different types of objects. Whether it's a custom GUI control or a character on screen. They all have a display method. What I wanted to do was put them into a list, iterate through them and invoke their display methods. There aren't too many of these objects overall (each handles a subset of displaying), so I wasn't worried about reflection speed.

However, the display methods don't have any parameters to pass through and the invoke example doesn't really show how to handle this. I've tried no parameter, a string, an object, and so on. But how do I handle not having to pass on arguments in the invoke method?


Silver_Knee(Posted 2016) [#2]
Invoke has two parameters: obj:Object and args:Object[]. Obj is the Object that you want to invoke the method on and args are the arguments. It is an array so 0 arguments is an empty array, like new Object[0] or since this is BlitzMax you can also use Null as empty array.

Maybe the SendMessage method of every object is another way to solve your issue without reflection


GrimGary(Posted 2016) [#3]
Yeah, null solved the issue. Thank you.

And thank you for the alternative suggestion. I'll try that see if its a better fit.


Derron(Posted 2016) [#4]
Instead of Reflection, rely on extending a base class (vanilla does not allow for interfaces, which would enable a similar approach like "mixins")

Type TRenderableEntity
  Method Draw() abstract
End Type

Type TMyGuiObject extends TRenderableEntity
  Method Draw()
    'draw this gui
  End Method
End Type

Type TPlayerFigure extends TRenderableEntity
  Method Draw()
    'draw this little stickman
  End Method
End Type

For local entity:TRenderableEntity = EachIn ToRenderList
  entity.Draw() 'does not matter whether GUI or playerfigure..
Next

Of course it is then up to you to order the renderlist accordingly (with custom "compare()"-functions and eg. "zIndex"-field-properties).


bye
Ron


GrimGary(Posted 2016) [#5]
Hot damn. Forgot about abstraction totally. I think that may have been what I was looking for in the first place. [head smack].

The GUI elements are already extended from a main gui object, so this fits even better.

Thank you =)


grable(Posted 2016) [#6]
Alternatively, if the objects do not have a common base type and/or you are worried about the speed of using reflection.
You could cache the function pointer of each method in addition to its instance and call them directly.

This only works though if the method prototypes are the same.



Derron(Posted 2016) [#7]
Also make sure that you remove the "cached function pointer" when releasing (/removing) an instance.


With Brucey's BMX-NG you would be able to use interfaces - which allows to keep GUI and other screen entities separate. You then would have an interface for "drawables" and each object which allows to get drawn, implements this interface.
Of course for "simple" objects, the "abstract-approach" would do.

Abstract would not be needed at all - eg. I sometimes use a simple "DrawRect(area.x, area.y, area.w, area.h)" in the default Draw() if no Draw()-method-override took place, kind of "visual debugging".


bye
Ron