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? |
| ||
try
class 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
EndAlternatively 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. |