Externs and GC
Monkey Forums/Monkey Programming/Externs and GC
| ||
Mark, I've externed some C++ code that takes an Object pointer and stores it. Monkey proceeds to GC the object, then my pointer is invalid. Is there anything I can do about this short of keeping a reference in Monkey? |
| ||
tryclass Whatever : public Object { public: Array<short> data; Whatever() { } ~Whatever() { } void mark(); }; void Whatever::mark(){ Object::mark(); gc_mark(data); } |
| ||
That's a pretty cool way of doing it, but unfortunately this can be ANY object, not just an externed one. If it's the only way, I may need to add a restriction that the code only works with classes extending the externed one, but it really limits what I want to do. Also, I need to make sure that this is (at least somewhat) target-agnostic. Somehow I feel C/C++ targets are going to be the only ones supported. Edit: I think I've worked out a way to do it using reference counting. Basically I'll have a Map<Object,Int> where the key is the Object to be retained and the value is the number of references. I should be able to keep track of this fairly easy. |
| ||
Hi, > Is there anything I can do about this short of keeping a reference in Monkey? Currently, all objects must be ultimately reachable from a Monkey global var - if not, they'll be collected. Mojo handles this by storing singleton driver objects such as graphics/audio drivers in Monkey globals in the appropriate modules. Then, the mark methods of these driver objects mark any internal 'globals' that need to be kept alive. For example, the mark method of the audio driver marks any sounds currently assigned to channels. I'll have a look at adding something a bit sexier here, eg: a C++ add_root function that allows you to add non-monkey global vars. |
| ||
Perhaps also weak reference functionality like in Java?Global obj:SomeClass Global wr:WeakReference<SomeClass> Function Main:Int() ' create an object and a weak reference to it obj = New SomeClass wr = New WeakReference<SomeClass>(obj) ' at this point, wr.ref = obj ' clear the global object obj = Null ' gc occurs somewhere, the reference from wr.ref is ignored ' if obj was collected, set wr.ref to Null, but leave the instance of WeakReference End Class WeakReference<T> Private Field ref:T Public Method New(ref:T) Self.ref = ref End Method Ref:T() Property Return ref End End Alternatively you could add it as part of the syntax. Global obj:SomeClass Global wr:SomeClass Weak ..... obj = New SomeClass wr = obj obj = Null ' obj gets collected, wr is set to Null |
| ||
So basically I made a reference counter class that I'm calling from C++. Whenever I store a pointer to an Object, I retain. When the pointer is deleted, I release. |