Reflection / Invoke
BlitzMax Forums/BlitzMax Programming/Reflection / Invoke
| ||
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? |
| ||
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 |
| ||
Yeah, null solved the issue. Thank you. And thank you for the alternative suggestion. I'll try that see if its a better fit. |
| ||
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 |
| ||
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 =) |
| ||
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. |
| ||
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 |