digitalmars.D.announce - ANN: WeakObjectReference - class to hold weak references
- Myron Alexander (10/10) Jun 23 2007 Hello.
- Myron Alexander (13/13) Jun 23 2007 Hello.
- Myron Alexander (4/7) Jun 23 2007 I have attached the fixed version.
- Extrawurst (3/14) Jun 23 2007 i would attach the fixed version for the lazy guys who dont recognize
- Robert Fraser (5/149) Jun 24 2007 Awesome! If you have the time, do you think you could do a Tango version...
Hello. I recently had a need for weak references and, with the help of Bill Baxter, who pointed me in the right direction, I created the attached class. Its using the apache license so have fun. If you want to add it to Tango, or Phobos and need the license changed, just drop me a note. Best regards, Myron. dprogramming...myron...alexander...com replace the first ... with , remove the second, and replace the third with ".".
Jun 23 2007
Hello. There is a bug in the version. I just noticed it now. When I rewrote the test code into a class, I accidentally left out the check on the malloc return. I have to go somewhere now so I'll fix it later. After: weakObjRef = cast(T**)stdlib.malloc (p.sizeof); just add: if (null == weakObjRef) { _d_OutOfMemory (); } and then import std.outofmemory. Sorry, Myron.
Jun 23 2007
Myron Alexander wrote:There is a bug in the version. I just noticed it now. When I rewrote the test code into a class, I accidentally left out the check on the malloc return. I have to go somewhere now so I'll fix it later.I have attached the fixed version. Regards, Myron.
Jun 23 2007
i would attach the fixed version for the lazy guys who dont recognize the post with the fix ;) Myron Alexander schrieb:Hello. I recently had a need for weak references and, with the help of Bill Baxter, who pointed me in the right direction, I created the attached class. Its using the apache license so have fun. If you want to add it to Tango, or Phobos and need the license changed, just drop me a note. Best regards, Myron. dprogramming...myron...alexander...com replace the first ... with , remove the second, and replace the third with ".".
Jun 23 2007
Awesome! If you have the time, do you think you could do a Tango version too? I think Tango doesn't have object.notifyRegister() though... Thanks, Best of wishes, Fraser Myron Alexander Wrote:Hello. I recently had a need for weak references and, with the help of Bill Baxter, who pointed me in the right direction, I created the attached class. Its using the apache license so have fun. If you want to add it to Tango, or Phobos and need the license changed, just drop me a note. Best regards, Myron. dprogramming...myron...alexander...com replace the first ... with , remove the second, and replace the third with ".". /+ Create a WeakReference to an Object such that the GC will not be prevented from collecting the referenced object. Copyright 2007 Myron Alexander Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +/ import std.stdio; import std.string : str = toString; import stdlib = std.c.stdlib; class WeakObjectReference(T : Object) { this (T obj) { /* Get a pointer to the object referenced. The pointer is necessary as * I do not what type to declare a pointer to a reference (ie T*->T). * I tried T*T but that doesn't work. The T** implementation works but * out of curiosity, it would be nice to know if something like T*T could * be done. */ T* p = cast(T*)obj; /* Allocate a non-gc region of memory to store the pointer to the object. * The type is T** as it is: memptr -> T* -> obj. */ weakObjRef = cast(T**)stdlib.malloc (p.sizeof); debug { writefln ("%s", weakObjRef); writefln ("%s", p); writefln ("%s", &obj); } /* Set memptr->T* = address of obj reference. */ *weakObjRef = p; /* Request that the GC call the unhook delegate when the referenced object * is collected. The unhook delegate removes the pointer to the object. * This is very important otherwise we would maintain a pointer to a * non-existant object. */ obj.notifyRegister (&unhook); } ~this () { debug { writefln ("Destructing weak reference ..."); } /* Remove the object destruction notification delegate as we will no * longer maintain a link to that object. */ if (*weakObjRef != null) { debug { writefln ("... Unhooked ..."); } (cast(T)(*weakObjRef)).notifyUnRegister(&unhook); *weakObjRef = null; } /* Free the non-gc memory allocated in the constructor. */ stdlib.free (weakObjRef); debug { writefln ("... Done"); } } T get () { debug { writefln ("Getting pointer: %s", /*weakObjRef == null ? "NULL" :*/ *weakObjRef); } return cast(T)(*weakObjRef); } private void unhook (Object obj) { debug { writefln ("Unhook object"); } *weakObjRef = null; } private T** weakObjRef; } class AnException : Exception { this (string msg) { super (msg); } } void main () { AnException x = new AnException ("Boom"); writefln ("%s", &x); writefln ("%s", cast (AnException*)x); AnException *xp = cast (AnException*)(x); writefln ("EX0: %s", (cast(AnException)xp).toString); auto w = new WeakObjectReference!(AnException) (x); //xp = w.get (); AnException y = w.get (); if (y !is null) { //AnException xx = cast(AnException)xp; writefln ("EX1: %s", y.toString()); } delete x; y = w.get (); if (y !is null) { writefln ("EX2: %s", y.toString()); } else { writefln ("EX2: y is null"); } }
Jun 24 2007