===================================================================== Reasoning and sanity (or lack of) behind the object based system. ===================================================================== Nick 'Zaf' Clifford . Feb 2003 ===================================================================== ============ Introduction ============ This code, though single-threaded acts like a multithreaded code-base. The reason for this is due to the function callbacks. All functions must be reentrant[1]. At first I thought I could handle this with standard techniques, and not need to worry about too much. However as the M3 Milestone approached, testing should there were common cases where execution would end up in the wrong places. A common example is give below. Example: The server object holds a pointer to the Me user object. When the server is disconnected, it goes through each of its user objects and deletes them. At this point the Me user object is deleted, however the server object has requested that when the Me object is deleted, it gets called, so the servers server_me_deleted() function is called, and it then decides to delete itself, since the Me object has gone. Which of course isn't good, because even if it does unwind its stack, you'll end up back at the beginning, in the server_destroy function with a dead/hanging pointer. Although this example can be solved by better code checks, there are many more instances like this throughout the code, most of them can't be solved as easily. ============ The solution ============ The object based system I've devised, looks very much like C++, and should give even the most insane coder, strong urges to look to C++ for a better solution to this task. I have looked to C++, and every time I do, I don't like what I see. So, to summerize: * YES! This can be done in C++. * YES it IS what C++ was designed to solve * NO! I will not do this in C++. If you wish to rewrite the code base to use C++, you may feel free. This is the GPL, you can do what you like. IF you do attempt to do the port to C++, I would be very interested in hearing about it. And if you do get a significant portition of the base system done in C++, I *WILL* look at your work, and strongly consider making the switch. I have nothing against C++, I've just never been able to find it sutiable for my liking. The strongest part of C++ IMHO is templates, and they are done as a hack! ========== The system ========== Say goodbye to pointers, atleast, for most things. The object system uses handles (in a similar way the Win32 system does). (No I'm not a Win32 programmer, though I was once). When you wish to refer to an object, you will receive a HANDLE. This is what you pass to all functions that deal with this object. You should *NOT* derefence the HANDLE to the actual pointer (using the object functions) unless the HANDLE belongs to an object in your module that you created. This way, if an object is deleted, the hash lookup for the HANDLE will fail. You *MUST* expect every single function you pass a HANDLE to to fail. You must NEVER assume that it will succeed. Even if the previous call, one line up succeeds, you MUST check to make sure that this call succeeds too. ============= The Interface ============= See src/obj.h for now. Sorry ========= Footnotes ========= [1] Reentrant code is code that is/can be called twice in one stack. eg A() calls B() which calls A() again which calls C(). A() is a reentrant function. Hopefully it support this.