From: John "West" McKenna Received: (from john@localhost) by mermaid.ucc.gu.uwa.edu.au (8.8.8/8.8.8/Debian/GNU) id WAA26194 for dgd@list.imaginary.com; Mon, 10 Jan 2000 22:45:32 +0800 Message-Id: <200001101445.WAA26194@mermaid.ucc.gu.uwa.edu.au> Subject: [DGD]upgrading To: dgd@list.imaginary.com Date: Mon, 10 Jan 2000 22:45:31 +0800 (WST) X-Mailer: ELM [version 2.4ME+ PL39 (25)] MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Reply-To: dgd@list.imaginary.com Sender: dgd-admin@list.imaginary.com List-Id: A discussion list for everything pertaining to DGD. Errors-To: dgd-admin@list.imaginary.com X-BeenThere: dgd@list.imaginary.com X-Mailman-Version: 1.0b6 There's been a bit of talk about upgrading objects, and there's always been people wanting code for it. So... This is how I'm doing upgrading of objects. Like Dworkin's kernel lib, I distinguish between classes and objects. Actually, I make a three-way distinction: 1) libs: Anything with /lib/ in its path can be inherited. It cannot be cloned. No other objects can be inherited. create() is not called, and the blueprint should not be used. 2) clones: Anything with /obj/ in its path can be cloned. No other objects can be cloned. create() is called on the clones, but not the blueprint. The blueprint should not be used. 3) singles: All other objects have create() called on the blueprint. 2 and 3 together are called 'objects'. If you're foolish enough to have *both* /lib/ and /obj/ in your path, you're treated as a lib. There is also mention of 'physical' objects. These are clones that have some 'real' existence in the MUD universe (including players). Any clone that wants a real existence inherits /kernel/lib/physical, which defines (among many other things) the function is_physical() to simply return 1. The code below is NOT the best way of doing things. In particular, I'm not at all happy with the way that I'm including the auto object in the inheritence table. There's a bug in there somewhere too - it fails in interesting ways if there was a compilation error. Hopefully having some code will provoke a little discussion, and maybe even a little code... /* The auto object */ int is_clone() { return (sscanf(object_name(this_object()), "%*s#")); } void _create() { /* create() gets called for clones of objects in a .../obj/... directory, and for blueprints of objects that are not in a .../obj/... or .../lib/... directory, but not for anything else. In particular, inherited objects and the blueprints of clones don't get create() called. */ string name; name=object_name(this_object()); /* It can only be a clone if it was in a .../obj/... directory, so no need to explicitly check for that */ if (sscanf(name, "%*s#")) { this_object()->create(); } else { if (!sscanf(name, "%*s/lib/") && !sscanf(name, "%*s/obj/")) { this_object()->create(); } } } object compile_object(string name) { object o; o=::compile_object(name); /* Make sure create() gets called */ call_other(o, "???"); return o; } object clone_object(object obj) { if (sscanf(object_name(obj), "%*s/lib/")) { DRIVER->message("Illegal clone: "+mixed_to_string(this_object())+ " attempting to clone "+mixed_to_string(obj)); return nil; } if (!sscanf(object_name(obj), "%*s/obj/")) { DRIVER->message("Illegal clone: "+mixed_to_string(this_object())+ " attempting to clone "+mixed_to_string(obj)); return nil; } return ::clone_object(obj); } /* The driver object */ mapping inheritence; mapping upgrading; mapping last_upgraded; int reboot_time; string *upgraded_clones; void initialize() { /* ... */ reboot_time=time(); } object inherit_program(string from, string path, int priv) { if (!sscanf(path, "%*s/lib/")) { message("Illegal inherit: "+from+" attempting to inherit "+path); return nil; } else { if (!inheritence) { inheritence=([ ]); } if (!inheritence[path]) { inheritence[path]=({ }); } if (!inheritence[AUTO]) { inheritence[AUTO]=({ }); } /* !!! This is really ugly. There must be a better way of doing this. But we're not told when someone inherits AUTO. So we just add it whenever any object gets mentioned (because if the object exists, it inherits AUTO). */ inheritence[AUTO]=(inheritence[AUTO]-({ from }))+({ from }); inheritence[AUTO]=(inheritence[AUTO]-({ path }))+({ path }); inheritence[path]=(inheritence[path]-({ from }))+({ from }); return load(path); } } static string *_upgrade(string path) { string *inherited_by; object obj; string *done; int i; done=({ }); if (inheritence) { obj=find_object(path); inherited_by=inheritence[path]; if (!upgrading[path]) { upgrading[path]=1; if (inherited_by) { /* It's a lib - destruct it and upgrade everything that inherits it */ last_upgraded[path]=time(); destruct_object(obj); done+=({path}); for (i=0;ilast_upgrade) { done+=_upgrade(path); } } inherited_by=inheritence[path]; if (inherited_by) { for (i=0;iis_clone() && obj->is_physical()) { old_location=obj->query_property(UNIV_PROP_PARENT); obj->move(nil); } obj->upgraded(); if (obj->is_clone() && obj->is_physical()) { obj->move(old_location); } } }