www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Pointers and deleting objects

reply Triften Chmil <Triften_member pathlink.com> writes:
Is there anything I can do with a pointer to make sure the object it points to
hasn't been deleted?

For example:
//We'll assume MyObject has a function/method 'myFunc'
MyObject mo = new MyObject();
MyObject *mop = &mo;
delete(mo);
//What can I check so that this:
mop.myFunc();
//doesn't produce an Access Violation?

i.e.:
if(check something){
mop.myFunc();
}

Thanks much,
Triften Chmil
Sep 25 2005
parent reply Chris Sauls <ibisbasenji gmail.com> writes:
Triften Chmil wrote:
 Is there anything I can do with a pointer to make sure the object it points to
 hasn't been deleted?
 
 For example:
 //We'll assume MyObject has a function/method 'myFunc'
 MyObject mo = new MyObject();
 MyObject *mop = &mo;
 delete(mo);
 //What can I check so that this:
 mop.myFunc();
 //doesn't produce an Access Violation?
 
Simple. Dereference and compare against null. Example: Although I can't help wondering what you need an Object pointer for? (Its an uncommon thing to see in a language like D. At least to me.) -- Chris Sauls
Sep 26 2005
next sibling parent Dejan Lekic <leka entropy.tmok.com> writes:
If pointers are not for language like D, there would be no pointers there...
My opinion on this is - disciplined people, who know how to use pointers,
would find it one of the best features in D.

-- 
...........
Dejan Lekic
  http://dejan.lekic.org
  
Sep 26 2005
prev sibling parent reply Triften Chmil <Triften_member pathlink.com> writes:
In article <dh8co6$qb4$1 digitaldaemon.com>, Chris Sauls says...
Triften Chmil wrote:
 Is there anything I can do with a pointer to make sure the object it points 
 to hasn't been deleted?
 
 For example:
 //We'll assume MyObject has a function/method 'myFunc'
 MyObject mo = new MyObject();
 MyObject *mop = &mo;
 delete(mo);
 //What can I check so that this:
 mop.myFunc();
 //doesn't produce an Access Violation?
 
Simple. Dereference and compare against null. Example: Although I can't help wondering what you need an Object pointer for? (Its an uncommon thing to see in a language like D. At least to me.) -- Chris Sauls
I'm programming a shoot-em-up video game and a weapon that locks-on to an enemy keeps a pointer to that enemy and so can reference the enemy's location to track it. I want to make sure the enemy hasn't been destroyed before I try to lookup its locations. Unless my understanding of programming terms and methods is horribly off, passing a copy of the enemy object wouldn't do, because the location values would change, so you keep a pointer to the enemy object. I suppose you might use someother locating technique (an index in an array) which would basically still be a pointer. If I'm missing some particular aspect of the nature of D, please let me know. (I.E. pointers are evil, or some such.) Thanks again, Triften Chmil
Sep 26 2005
next sibling parent reply J Thomas <jtd514 ameritech.net> writes:
yah: class references are basically pointers in D

MyObject mo = new MyObject();

mo is a pointer, MyObject* is redundant and only really usefull in more 
obscure circumstances




Triften Chmil wrote:
 In article <dh8co6$qb4$1 digitaldaemon.com>, Chris Sauls says...
 
Triften Chmil wrote:

Is there anything I can do with a pointer to make sure the object it points 
to hasn't been deleted?

For example:
//We'll assume MyObject has a function/method 'myFunc'
MyObject mo = new MyObject();
MyObject *mop = &mo;
delete(mo);
//What can I check so that this:
mop.myFunc();
//doesn't produce an Access Violation?
Simple. Dereference and compare against null. Example: Although I can't help wondering what you need an Object pointer for? (Its an uncommon thing to see in a language like D. At least to me.) -- Chris Sauls
I'm programming a shoot-em-up video game and a weapon that locks-on to an enemy keeps a pointer to that enemy and so can reference the enemy's location to track it. I want to make sure the enemy hasn't been destroyed before I try to lookup its locations. Unless my understanding of programming terms and methods is horribly off, passing a copy of the enemy object wouldn't do, because the location values would change, so you keep a pointer to the enemy object. I suppose you might use someother locating technique (an index in an array) which would basically still be a pointer. If I'm missing some particular aspect of the nature of D, please let me know. (I.E. pointers are evil, or some such.) Thanks again, Triften Chmil
Sep 26 2005
parent reply Triften Chmil <Triften_member pathlink.com> writes:
So now I've basically got:

MyObject mo = new MyObject();
MyObject mo2 = mo;
//mo2 is a reference to mo, right?

delete(mo);
//this seems to cause no trouble
int x = mo2.myvar;
mo2.myFunc();

I'd like to be able to check for deletion of the object referenced by mo using
mo2. Is this possible?

In article <dh8qjd$164t$1 digitaldaemon.com>, J Thomas says...
yah: class references are basically pointers in D

MyObject mo = new MyObject();

mo is a pointer, MyObject* is redundant and only really usefull in more 
obscure circumstances




Triften Chmil wrote:
 In article <dh8co6$qb4$1 digitaldaemon.com>, Chris Sauls says...
 
Triften Chmil wrote:

Is there anything I can do with a pointer to make sure the object it points 
to hasn't been deleted?

For example:
//We'll assume MyObject has a function/method 'myFunc'
MyObject mo = new MyObject();
MyObject *mop = &mo;
delete(mo);
//What can I check so that this:
mop.myFunc();
//doesn't produce an Access Violation?
Simple. Dereference and compare against null. Example: Although I can't help wondering what you need an Object pointer for? (Its an uncommon thing to see in a language like D. At least to me.) -- Chris Sauls
I'm programming a shoot-em-up video game and a weapon that locks-on to an enemy keeps a pointer to that enemy and so can reference the enemy's location to track it. I want to make sure the enemy hasn't been destroyed before I try to lookup its locations. Unless my understanding of programming terms and methods is horribly off, passing a copy of the enemy object wouldn't do, because the location values would change, so you keep a pointer to the enemy object. I suppose you might use someother locating technique (an index in an array) which would basically still be a pointer. If I'm missing some particular aspect of the nature of D, please let me know. (I.E. pointers are evil, or some such.) Thanks again, Triften Chmil
Sep 26 2005
parent reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Triften Chmil" <Triften_member pathlink.com> wrote in message 
news:dhaf74$2jkn$1 digitaldaemon.com...
 So now I've basically got:

 MyObject mo = new MyObject();
 MyObject mo2 = mo;
 //mo2 is a reference to mo, right?

 delete(mo);
 //this seems to cause no trouble
 int x = mo2.myvar;
 mo2.myFunc();

 I'd like to be able to check for deletion of the object referenced by mo 
 using
 mo2. Is this possible?
Nope. Unless the GC were to keep a list of pointers to .. uhh, pointers that pointed to the objects, the GC has no way of setting mo2 to any value that says "this is an invalid object" (i.e. null). mo gets set to null as the parameter to delete is actually an inout parameter (hence why you can't use an expression as the parameter to delete). This situation wouldn't really come up that often though. Usually if you're deleting an object, you will get rid of all references to it, as all references to it will then be invalid.
Sep 27 2005
parent reply BCS <BCS_member pathlink.com> writes:
How about rather than delete the object add a Die method that marks it as dead.
Then each time you need to check if an object is still alive, call a
corresponding Alive method and if it isn’t, set the pointer you used to null.
Just a thought. 



In article <dhbveo$l6j$1 digitaldaemon.com>, Jarrett Billingsley says...
"Triften Chmil" <Triften_member pathlink.com> wrote in message 
news:dhaf74$2jkn$1 digitaldaemon.com...
 So now I've basically got:

 MyObject mo = new MyObject();
 MyObject mo2 = mo;
 //mo2 is a reference to mo, right?

 delete(mo);
 //this seems to cause no trouble
 int x = mo2.myvar;
 mo2.myFunc();

 I'd like to be able to check for deletion of the object referenced by mo 
 using
 mo2. Is this possible?
Nope. Unless the GC were to keep a list of pointers to .. uhh, pointers that pointed to the objects, the GC has no way of setting mo2 to any value that says "this is an invalid object" (i.e. null). mo gets set to null as the parameter to delete is actually an inout parameter (hence why you can't use an expression as the parameter to delete). This situation wouldn't really come up that often though. Usually if you're deleting an object, you will get rid of all references to it, as all references to it will then be invalid.
Sep 27 2005
parent reply Triften Chmil <Triften_member pathlink.com> writes:
Yeah, that was going to be my alternative.

So, eventually, all references to the object would be removed and the GC would
come along is scrap it, right?

And if I could clarify something from the message from Jarrett:
Is this:

delete(myOb);

equivalent to this:

myOb = null;

?

In article <dhccqs$1cgf$1 digitaldaemon.com>, BCS says...
How about rather than delete the object add a Die method that marks it as dead.
Then each time you need to check if an object is still alive, call a
corresponding Alive method and if it isn’t, set the pointer you used to null.
Just a thought. 



In article <dhbveo$l6j$1 digitaldaemon.com>, Jarrett Billingsley says...
"Triften Chmil" <Triften_member pathlink.com> wrote in message 
news:dhaf74$2jkn$1 digitaldaemon.com...
 So now I've basically got:

 MyObject mo = new MyObject();
 MyObject mo2 = mo;
 //mo2 is a reference to mo, right?

 delete(mo);
 //this seems to cause no trouble
 int x = mo2.myvar;
 mo2.myFunc();

 I'd like to be able to check for deletion of the object referenced by mo 
 using
 mo2. Is this possible?
Nope. Unless the GC were to keep a list of pointers to .. uhh, pointers that pointed to the objects, the GC has no way of setting mo2 to any value that says "this is an invalid object" (i.e. null). mo gets set to null as the parameter to delete is actually an inout parameter (hence why you can't use an expression as the parameter to delete). This situation wouldn't really come up that often though. Usually if you're deleting an object, you will get rid of all references to it, as all references to it will then be invalid.
Sep 27 2005
parent reply Chris Sauls <ibisbasenji gmail.com> writes:
Triften Chmil wrote:
 Yeah, that was going to be my alternative.
 
 So, eventually, all references to the object would be removed and the GC would
 come along is scrap it, right?
 
 And if I could clarify something from the message from Jarrett:
 Is this:
 
 delete(myOb);
 
 equivalent to this:
 
 myOb = null;
 
 ?
Not strictly. The expression: just clears this particular Object-ref variable. While the expression: notifies the Garbage Collector that the Object ref'd by this variable is ripe for plucking. (Normally it decides this for itself during periodic sweeps for references. An object with no more valid ref's is ripe.) There's no "guarantee" that the GC will deconstruct and delete the object immediately, but its been marked. And in fact, you don't neccessarily need any Die method. Just a basic "if (myOb !is null)" should suffice. If you want to guarantee that the object you wanted deleted is bye-bye then use std.gc.fullCollect() to force the GC's hand: Unless I'm missing something, this should work just fine. -- Chris Sauls
Sep 27 2005
parent reply Triften Chmil <Triften_member pathlink.com> writes:
Actually the issue is that doing this:

MyObject mo = new MyObject();
MyObject mo2 = mo;

delete(mo);

means that mo2 still references the other object and has no idea that the object
has been "deleted". So doing a '!is null' on mo2 is not helpful.

In article <dhdcrg$25gs$1 digitaldaemon.com>, Chris Sauls says...
Triften Chmil wrote:
 Yeah, that was going to be my alternative.
 
 So, eventually, all references to the object would be removed and the GC would
 come along is scrap it, right?
 
 And if I could clarify something from the message from Jarrett:
 Is this:
 
 delete(myOb);
 
 equivalent to this:
 
 myOb = null;
 
 ?
Not strictly. The expression: just clears this particular Object-ref variable. While the expression: notifies the Garbage Collector that the Object ref'd by this variable is ripe for plucking. (Normally it decides this for itself during periodic sweeps for references. An object with no more valid ref's is ripe.) There's no "guarantee" that the GC will deconstruct and delete the object immediately, but its been marked. And in fact, you don't neccessarily need any Die method. Just a basic "if (myOb !is null)" should suffice. If you want to guarantee that the object you wanted deleted is bye-bye then use std.gc.fullCollect() to force the GC's hand: Unless I'm missing something, this should work just fine. -- Chris Sauls
Sep 28 2005
parent reply Chris Sauls <ibisbasenji gmail.com> writes:
Triften Chmil wrote:
 Actually the issue is that doing this:
 
 MyObject mo = new MyObject();
 MyObject mo2 = mo;
 
 delete(mo);
 
 means that mo2 still references the other object and has no idea that the
object
 has been "deleted". So doing a '!is null' on mo2 is not helpful.
 
I just tested this, and sadly you're right. I say sadly primarily because it isn't proper according to the D specs (if I'm reading them right). The 'delete' expression should be immediately marking that object, and all that should be needed for it to be collected is a standard GC sweep, caused either by an allocation request or invoked directly with std.gc.fullCollect(). I'm curious as to why 'delete' is, apparently, not working. -- Chris Sauls
Sep 28 2005
parent reply James Dunne <james.jdunne gmail.com> writes:
Chris Sauls wrote:
 Triften Chmil wrote:
 
 Actually the issue is that doing this:

 MyObject mo = new MyObject();
 MyObject mo2 = mo;

 delete(mo);

 means that mo2 still references the other object and has no idea that 
 the object
 has been "deleted". So doing a '!is null' on mo2 is not helpful.
I just tested this, and sadly you're right. I say sadly primarily because it isn't proper according to the D specs (if I'm reading them right). The 'delete' expression should be immediately marking that object, and all that should be needed for it to be collected is a standard GC sweep, caused either by an allocation request or invoked directly with std.gc.fullCollect(). I'm curious as to why 'delete' is, apparently, not working. -- Chris Sauls
That is not delete's job. Delete's job is to inform the GC that the object is ready for deletion. Such maintenance with making sure that dangling references to that object are cleaned up is solely up to the programmer. Effectively, you've told the garbage collector to collect something which is not 'garbage'. =P
Sep 28 2005
parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Wed, 28 Sep 2005 14:39:22 -0500, James Dunne <james.jdunne gmail.com>  
wrote:
 Chris Sauls wrote:
 Triften Chmil wrote:

 Actually the issue is that doing this:

 MyObject mo = new MyObject();
 MyObject mo2 = mo;

 delete(mo);

 means that mo2 still references the other object and has no idea that  
 the object
 has been "deleted". So doing a '!is null' on mo2 is not helpful.
I just tested this, and sadly you're right. I say sadly primarily because it isn't proper according to the D specs (if I'm reading them right). The 'delete' expression should be immediately marking that object, and all that should be needed for it to be collected is a standard GC sweep, caused either by an allocation request or invoked directly with std.gc.fullCollect(). I'm curious as to why 'delete' is, apparently, not working. -- Chris Sauls
That is not delete's job. Delete's job is to inform the GC that the object is ready for deletion. Such maintenance with making sure that dangling references to that object are cleaned up is solely up to the programmer. Effectively, you've told the garbage collector to collect something which is not 'garbage'. =P
The solution is a reference counted pointer of some sort. However, it cannot work exactly like a C++ one might due to the inability to overload the assignment operator. Instead we can use the constructor, so, where you would say: RefPtr s = new RefPtr(o); RefPtr p; p = s; Instead you have to say: RefPtr s = new RefPtr(o); RefPtr p; p = new RefPtr(s); Essentially replace any/all assignments of RefPtr's with a 'new' statement. Below is an implementation and test program for it. Note I use 'auto' to ensure the reference is deleted at the end of scope. If you cannot do that you _must_ instead call delete manually. Forgetting to do either will introduce the possibility that the destructor for RefPtr is never called, the reference count will be wrong, and the resource will not be free'd. In fact, failing to auto/delete RefPtr will likely mean the destructor for the resource is _never_ called. The garbage collector will still collect the memory at some stage, i.e. when there are no live references to it. My opinion remains that the inability to create a solid reference counting implementation is a weakness in D. I agree that it's 'seldom' required (due to D being garbage collected) but when you need one, you need something solid, reliable and flexible enough to handle the different use cases. The current situation is too easy to break. Destruction is non-deterministic and therefore unreliable. import std.c.windows.windows; import std.random; import std.thread; import std.stdio; class RefPtr { RefPtr parent; Object resource = null; int refs = 0; this(Object res) { resource = res; writefln("ThreadID=(",Thread.getThis().id,") Initial RefPtr for resource=(",resource,")"); increment(); } this(RefPtr rhs) { parent = rhs; parent.increment(); writefln("ThreadID=(",Thread.getThis().id,") Ref=(",parent.refs,") for resource=(",parent.resource,")"); } ~this() { int r; if ((r = decrement()) == 0) { writefln("ThreadID=(",Thread.getThis().id,") release last ref Ref=(",r,")"); if (parent) parent = null; else if (resource) { writefln("ThreadID=(",Thread.getThis().id,") delete resource=(",resource,")"); delete resource; resource = null; } } writefln("ThreadID=(",Thread.getThis().id,") release Ref=(",r,")"); } protected: int increment() { int ret; if (parent) ret = parent.increment(); else { synchronized(this) { ret = ++refs; writefln("ThreadID=(",Thread.getThis().id,") increment to Ref=(",refs,")"); } } return ret; } int decrement() { int ret; if (parent) ret = parent.decrement(); else { synchronized(this) { ret = --refs; writefln("ThreadID=(",Thread.getThis().id,") decrement to Ref=(",refs,")"); } } return ret; } } class Resource { char[] name = "11 was a racehorse"; char[] toString() { return name; } } RefPtr pbob; static this() { pbob = new RefPtr(new Resource()); } static ~this() { delete pbob; } void main() { Thread[] threads; int i; writefln("ThreadID=(",Thread.getThis().id,") is the main thread"); for(i = 0; i < 10; i++) { threads ~= new Thread(&thread_function,null); threads[$-1].start(); } while(true) { i = 0; foreach(Thread t; threads) { if (t.getState() == Thread.TS.TERMINATED) i++; } if (i == 10) break; Sleep(100); } writefln("Main exiting"); } int thread_function(void* isnull) { auto RefPtr p = new RefPtr(pbob); Sleep(1000+rand()%1000); return 0; } Regan
Sep 28 2005
next sibling parent Sean Kelly <sean f4.ca> writes:
In article <opsxt1eskp23k2f5 nrage.netwin.co.nz>, Regan Heath says...
My opinion remains that the inability to create a solid reference counting  
implementation is a weakness in D. I agree that it's 'seldom' required  
(due to D being garbage collected) but when you need one, you need  
something solid, reliable and flexible enough to handle the different use  
cases. The current situation is too easy to break. Destruction is  
non-deterministic and therefore unreliable.
Very much agreed. Cross-scope RAII is awkward to impossible in D, while shared_ptr in C++ TR1 is being sold as a solution for this exact problem. Simply put, GC is a fantastic tool, but it's not a universal solution. And 'auto' simply doesn't make up the difference. Sean
Sep 28 2005
prev sibling parent JT <jtd514 ameritech.net> writes:
Regan Heath wrote:
 
 My opinion remains that the inability to create a solid reference 
 counting  implementation is a weakness in D. I agree that it's 'seldom' 
 required  (due to D being garbage collected) but when you need one, you 
 need  something solid, reliable and flexible enough to handle the 
 different use  cases. The current situation is too easy to break. 
 Destruction is  non-deterministic and therefore unreliable.
 
I completely agree. it can be done but some minor things seem to be a slight more hastle than in C. i was originally hoping D had native reference counted objects to go with it. i think that would be pretty cool.
Sep 28 2005
prev sibling next sibling parent reply Mike Parker <aldacron71 yahoo.com> writes:
Triften Chmil wrote:

 If I'm missing some particular aspect of the nature of D, please let me know.
 (I.E. pointers are evil, or some such.)
You shouldn't need to use pointers with class instances in D as, unlike C++, they are references. The only cases in D where you even need to think about pointers, off the top of my head, are when interfacing with C code, fetching values from associative arrays with the 'in' operator, and in some cases perhaps when working with struct instances as they are not references in D (though most of the time you would want a struct pointer you can use inout parameters instead).
Sep 26 2005
parent Triften Chmil <Triften_member pathlink.com> writes:
Oh, okay. That would explain some the stranger behavior I've been trying to work
around.

Thanks.

In article <dh97rk$1kdn$1 digitaldaemon.com>, Mike Parker says...
Triften Chmil wrote:

 If I'm missing some particular aspect of the nature of D, please let me know.
 (I.E. pointers are evil, or some such.)
You shouldn't need to use pointers with class instances in D as, unlike C++, they are references. The only cases in D where you even need to think about pointers, off the top of my head, are when interfacing with C code, fetching values from associative arrays with the 'in' operator, and in some cases perhaps when working with struct instances as they are not references in D (though most of the time you would want a struct pointer you can use inout parameters instead).
Sep 26 2005
prev sibling next sibling parent David Medlock <noone nowhere.com> writes:
Triften Chmil wrote:
 In article <dh8co6$qb4$1 digitaldaemon.com>, Chris Sauls says...
 
Triften Chmil wrote:

Is there anything I can do with a pointer to make sure the object it points 
to hasn't been deleted?

For example:
//We'll assume MyObject has a function/method 'myFunc'
MyObject mo = new MyObject();
MyObject *mop = &mo;
delete(mo);
//What can I check so that this:
mop.myFunc();
//doesn't produce an Access Violation?
Simple. Dereference and compare against null. Example: Although I can't help wondering what you need an Object pointer for? (Its an uncommon thing to see in a language like D. At least to me.) -- Chris Sauls
I'm programming a shoot-em-up video game and a weapon that locks-on to an enemy keeps a pointer to that enemy and so can reference the enemy's location to track it. I want to make sure the enemy hasn't been destroyed before I try to lookup its locations. Unless my understanding of programming terms and methods is horribly off, passing a copy of the enemy object wouldn't do, because the location values would change, so you keep a pointer to the enemy object. I suppose you might use someother locating technique (an index in an array) which would basically still be a pointer. If I'm missing some particular aspect of the nature of D, please let me know. (I.E. pointers are evil, or some such.) Thanks again, Triften Chmil
Why are you deleting the object? D's garbage collector is fairly good, and I haven't seen signifigant performance issues with it thus far(I do OpenGL coding too). (Sorry if I may not be understanding your intention/approach correctly.) -DavidM
Sep 27 2005
prev sibling parent reply JT <jtd514 ameritech.net> writes:
just FYI heres what Ive done on a commercial game engine for this kind 
of problem. I use a "reference target" and "reference origin" base 
classes. the reference targets simply contain a list of all origins that 
point to them (and the origin class is derived from the target but this 
is an implementation detail thats beside the point) this way your 
objects will  contain a list of referencing objects and it opens your 
framework up to do some pretty fancy yet simple stuff - like sending 
events from a target to all its reference origins when targets die or 
changes state. as for implementation i generally use a small "hook" 
class to manage connections between objects - essentially smart pointers 
that help synchronize these connections. for example i can have in my 
renderer a "multiple hook" of actors and inside my actor i would have a 
"single hook" to a renderer - attach a renderer to an actor and the 
actor is automatically connected to the renderer, etc. anyway Im 
rambling but my point is - Ive found a system like this to be magnitudes 
more flexible than the method you are wishing to employ. fyi

but this is one of the reasons I love D, implementing this kind of 
functionality in D is like a daydream compared to C++, and eek, dare I 
say almost "fun" :D  although I am missing some more complex 
functionality since i dont have a preprocessor but im still working 
around this. (but im hoping to eventually have a metaprogramming system 
to do some of this stuff out of the box)

anyway please let me know how your project goes, and good luck. I really 
like to see people using D for 3d engines because i think it can be used 
to build some amazing technology much easier compared to what we have 
been doing...


Triften Chmil wrote:

 I'm programming a shoot-em-up video game and a weapon that locks-on 
to an enemy
 keeps a pointer to that enemy and so can reference the enemy's 
location to track
 it. I want to make sure the enemy hasn't been destroyed before I try 
to lookup
 its locations.

 Unless my understanding of programming terms and methods is horribly off,
 passing a copy of the enemy object wouldn't do, because the location 
values
 would change, so you keep a pointer to the enemy object. I suppose 
you might use
 someother locating technique (an index in an array) which would 
basically still
 be a pointer.

 If I'm missing some particular aspect of the nature of D, please let 
me know.
 (I.E. pointers are evil, or some such.)

 Thanks again,
 Triften Chmil
Sep 28 2005
parent reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"JT" <jtd514 ameritech.net> wrote in message 
news:dhedg5$3pj$1 digitaldaemon.com...

Hey, it's the (JT)Game .X export plugin guy :)

 just FYI heres what Ive done on a commercial game engine for this kind of 
 problem. I use a "reference target" and "reference origin" base classes. 
 the reference targets simply contain a list of all origins that point to 
 them (and the origin class is derived from the target but this is an 
 implementation detail thats beside the point) this way your objects will 
 contain a list of referencing objects and it opens your framework up to do 
 some pretty fancy yet simple stuff - like sending events from a target to 
 all its reference origins when targets die or changes state. as for 
 implementation i generally use a small "hook" class to manage connections 
 between objects - essentially smart pointers that help synchronize these 
 connections. for example i can have in my renderer a "multiple hook" of 
 actors and inside my actor i would have a "single hook" to a renderer - 
 attach a renderer to an actor and the actor is automatically connected to 
 the renderer, etc. anyway Im rambling but my point is - Ive found a system 
 like this to be magnitudes more flexible than the method you are wishing 
 to employ. fyi

 but this is one of the reasons I love D, implementing this kind of 
 functionality in D is like a daydream compared to C++, and eek, dare I say 
 almost "fun" :D  although I am missing some more complex functionality 
 since i dont have a preprocessor but im still working around this. (but im 
 hoping to eventually have a metaprogramming system to do some of this 
 stuff out of the box)
Just out of curiosity, what about the preprocessor do you miss? Personally, I've not missed the preprocessor one bit. You mention metaprogramming; I'm not sure how a preprocessor would help with that. Then again, I never did much fancy stuff with the preprocessor in C++; it always seemed kind of hackish to me.
 anyway please let me know how your project goes, and good luck. I really 
 like to see people using D for 3d engines because i think it can be used 
 to build some amazing technology much easier compared to what we have been 
 doing...
I hope you've seen nonagon, then! The one thing that irks me about developing with DX9, though, is that I still feel like I'm using C++ when I use it, as there is no way for D to interface with the MDX runtimes. Managed DX in D would be a dream come true. But oh well, checking for error codes isn't _that_ hard.
Sep 28 2005
parent JT <jtd514 ameritech.net> writes:
no thats not me. as for the preprocessor - what i miss is being able to 
construct classes and identifier names programatically. using my 
previous example - the macro: SINGLE_HOOK( cRenderer, Renderer );  could 
construct automatically an actual hook class and access methods called 
"Renderer" (like setRenderer() getRenderer() etc) i dont believe there 
is any way in D to construct identifier names. but again, D is so nice 
you generally never need this.

this is where metaobjects come in. please keep in mind, when I say 
metaprogramming i am not refering to C++ template metaprogramming. the 
template mp was nice but what im refering to is a metaobject protocol 
where the 'compiler metaobjects' are basically exposed to the language 
itself. quite simply, imagine during compile time being handed the 
compiler representation of your program and being given the ability to 
MODIFY anything before being sent to the back-end? this is called 
compile-time metaprogramming. given my previous example I could have the 
compiler itself generate my identifier names, whatever data structures 
and behaviors I need.

my previous example MACRO:

	SINGLE_HOOK( cRenderer, renderer );

could be changed to:

	singlehook cRenderer renderer;

and the 'singlehook' metahandler (most likely written in D) would be 
passed the tree for my program and it would build the code required for 
the feature add it to the tree and pass it back to the compiler for 
completion

of course this is just an example from C++, some of these techniques are 
not necessary in D but you get the idea...

btw if anyone knows how to generate identifier names in D please let me 
know.

I havent looked at nonagen very much but I plan on checking it out. i 
have never used managed direct x so im kind of unfamilar with that. i 
havent gotten into very much graphics programming in D as im still 
focused on building tools and procedures for solid D development in the 
future. but i will definately check out nonagen again...


Jarrett Billingsley wrote:
 "JT" <jtd514 ameritech.net> wrote in message 
 news:dhedg5$3pj$1 digitaldaemon.com...
 
 Hey, it's the (JT)Game .X export plugin guy :)
 
 
just FYI heres what Ive done on a commercial game engine for this kind of 
problem. I use a "reference target" and "reference origin" base classes. 
the reference targets simply contain a list of all origins that point to 
them (and the origin class is derived from the target but this is an 
implementation detail thats beside the point) this way your objects will 
contain a list of referencing objects and it opens your framework up to do 
some pretty fancy yet simple stuff - like sending events from a target to 
all its reference origins when targets die or changes state. as for 
implementation i generally use a small "hook" class to manage connections 
between objects - essentially smart pointers that help synchronize these 
connections. for example i can have in my renderer a "multiple hook" of 
actors and inside my actor i would have a "single hook" to a renderer - 
attach a renderer to an actor and the actor is automatically connected to 
the renderer, etc. anyway Im rambling but my point is - Ive found a system 
like this to be magnitudes more flexible than the method you are wishing 
to employ. fyi

but this is one of the reasons I love D, implementing this kind of 
functionality in D is like a daydream compared to C++, and eek, dare I say 
almost "fun" :D  although I am missing some more complex functionality 
since i dont have a preprocessor but im still working around this. (but im 
hoping to eventually have a metaprogramming system to do some of this 
stuff out of the box)
Just out of curiosity, what about the preprocessor do you miss? Personally, I've not missed the preprocessor one bit. You mention metaprogramming; I'm not sure how a preprocessor would help with that. Then again, I never did much fancy stuff with the preprocessor in C++; it always seemed kind of hackish to me.
anyway please let me know how your project goes, and good luck. I really 
like to see people using D for 3d engines because i think it can be used 
to build some amazing technology much easier compared to what we have been 
doing...
I hope you've seen nonagon, then! The one thing that irks me about developing with DX9, though, is that I still feel like I'm using C++ when I use it, as there is no way for D to interface with the MDX runtimes. Managed DX in D would be a dream come true. But oh well, checking for error codes isn't _that_ hard.
Sep 28 2005