Reference functions
Monkey Forums/Monkey Programming/Reference functions
| ||
Is it possible to reference a function in Monkey? Like having a function as a parameter of another function? Something like: [monkeycode] Function Test:Void(myFunc:Int(param1:Int, param2:Int)) myFunc(1, 2) End [/monkeycode] You could do this in BlitzMax, if I remember correctly. |
| ||
The reason I ask is that I am trying to use Singletons like you do in C++, like so:// Singleton.h template <class T> class Singleton { public: static T& instance() { static T _instance; return _instance; } private: Singleton(); ~Singleton(); Singleton(Singleton const&); Singleton& operator=(Singleton const&); }; // MyClass.h #include "Singleton.h" class MyClass { public: int member; } #define sMyClass Singleton<MyClass>.instance() // main.cpp #include "MyClass.h" int main() { sMyClass.member = 5; return 0; } My attempt to implement the simpleton class in Monkey worked fine: [monkeycode] ' Singleton.monkey Strict Class Singleton<T> Function instance:T() If (_instance) Return _instance _instance = New T Return _instance End Method New() End Method Global _instance:T End [/monkeycode] Now all that's left is the #define part, but we don't have that preprocessor directive in Monkey, so first I tried Alias. Turns out Alias doesn't work like that. Next I thought I'd reference the instance function instead. Something like: [monkeycode] ' MyClass.monkey Strict Import Singleton Class MyClass Field member:Int End Global sMyClass:MyClass() = Singleton<MyClass>.instance [/monkeycode] [monkeycode] ' main.monkey Strict Import MyClass Function Main:Int() sMyClass().member = 5; End [/monkeycode] |
| ||
It is simpler than that! import myClass [monkeycode] Function Main:Int() MyClass.member = 5; End [/monkeycode] ------------ myClass.monkey ----------- [monkeycode] Global MyClass:MyClassSingleton = new MyClassSingleton Class MyClassSingleton Field member:Int End [/monkeycode] --------------------------------------- That class will ONLY be created IF you mention that class anywhere in your code seen from the initial Main:Int() file + imports. Meaning that if you have 500 Globals like that in one file and you only mention one, only that one will ever be translated and instaciated. In my oppinion it is not the exact same as a Singleton, but to me it is better in most cases. |
| ||
That's true Tibit, thanks for that! Will go that route for this project. However, function pointers, or function references would be very much appreciated for other purposes. I hope Mark implements it in a future update. |
| ||
You can get references to functions using reflection: [monkeycode] Import reflection Function PrintSomething() Print("Hello World") End Function DoFunction(func:FunctionInfo) func.Invoke([]) End Function Main() Local func:FunctionInfo = GetFunction("PrintSomething",[]) DoFunction(func) End [/monkeycode] You can also get at methods and functions within classes, and anything else! There's a nice little write-up in the documentation for the reflection module, or you can check out my videos on reflection if you want to find out more. There's a lot you can do with it :) |
| ||
invaderJim, are reflection safe to use performance wise for non-debug stuff? I'm still thinking about reflection from C#, and I fear that. And on the subject of function references, or having functions as objects. There is a lot of cool things that can be done with that and certainly something that I'd like. Maybe reflection is the solution there? I strongly recommend Jim's videos btw, they are great! |
| ||
Yeah reflection is a nice workaround and if I ever need to reference functions I will be sure to use it :) But reflection is slow. That is the downside of it. Thanks for sharing though! If it is not implemented this is the only way to do it! :) |
| ||
It's certainly slower than a direct reference, yeah, but I wouldn't discount it completely. It really just depends on what you're doing. If I ever get worried about performance, I just wrap my functions in classes and reference them that way. |
| ||
Haha, never thought of referencing them by wrapping them in classes. Good idea! :) |
| ||
[monkeycode] Interface Callback Method Execute:Void (args:Object[]) End Class SampleFunction Implements Callback Method Execute:Void (args:Object[]) 'Your function code here End End [/monkeycode] Only drawback is you have to create the class. |