On Thu, 29 Jun 2000, Patrick Dughi wrote: > Basically, a pair of set/accessor functions for each character part, > based on idnum lookup? Sounds a bit annoying. In non-OO languages that don't support exception-handling? Very annoying. In OO languages that do support exception-handling? Probably not that much better. Compare the following in C, /* * C: get_char_gender() looks up the pointer through some means * and returns it gender -- or -1 if we have an error. */ byte sex = get_char_gender (cid); if (sex == -1) return; sprintf (buf, "It's a %s.\r\n", HIMHER (sex)); send_to_char (buf, to); // C++: A CharacterID class is at work, here. It has a private(?) // function named character() inside of it that fetches the // character pointer. If it fails to fetch the pointer, it // throws a BadCharacter exception. All of its accessors use // the character() function, so they all throw. try { to.writeLine ("It's a %s.", HIMHER (cid.gender())); } catch (BadCharacter* bc) { delete bc; // ? return; } In this minimal example, the C code seems much better. However, the exception handling mechanism permits us to only handle an error once, not every time it might occur: try { for (int hits = 0; hits < numHits; hits++) { . . // Calculate the damage amount . fighting ().character ()->damage (this, amount); } } catch (BadCharacter* cd) { fighting (NOBODY); writeLine ("Congratulations, you won!"); } It's still really ugly, but imagine having to write a pointer-free version of act() using the C mechanism demonstrated above. The error checking in each case...break block would be more than enough to drive me completely mad. OTOH, both versions could get away with, struct character_data *ch = get_char_by_id (cid); . . . if the code is guaranteed to not invalidate the pointer at any time during the scope of 'ch'. > Perl-like hash tables? In my Python code I use the builtin dictionary type and a unique string identifier for each object. The id is then stored, rather than references to another object, and when it's needed we do (pseudo-codish), cd = character.charDictionary # Alias class EarlyDetectionSystem(Object): def tripped(self, tripped): # Setup as ON_ENTER listener. if cd.has_key(self.owner): owner = cd[self.owner] report_to = owner else: report_to[:] = everyone[:] report_to.remove(tripped) report_to.message( \ tripped.name + " tripped the EDS at " + \ tripped.location.name + "!") # expire after N uses self.uses = self.uses - 1 if self.uses < 1: self.fromloc() del self # end tripped # end EarlyDetectionSystem Objects and instances have different ids. Basically, we define a factory function that creates a new object instance. It takes its "prototypes" unique id and munges it. So if the id was, "eds," the first instance would be, "eds__instance_0," the second instance, "eds__instance_1," etc. > I'll see if I can't write a general way using a sort of named lookup > thing... get_value(chidnum,"gender"); or something.. That will require (potentially excessive) casting. byte sex = *((int *) get_value(chidnum, "gender")); and will potentially be slow, depending upon how you implement the lookup for data elements within the character. At that point, it'd almost be better to use a complete generic attribute system stored on the character. The lookup wouldn't be that much more expensive and the flexibility of not having a type system for your wajas (world whatcha-ma-jiggers; i.e., an item, room, character, whatever) could be interesting (but allow nothing that couldn't be faked and be just as playable as far as the player is concerned). As an aside, Microsoft's C# (which, surprisingly, they actually submitted to the ECMA standards board) language provides property get/set methods that aid in rapid application development (e.g., "code evolution") that could find interesting applications, here: public class CharacterId { private long _cid; public string Name { get { // as in, writeLine (cid.Name); Character obj = FindPointer (_cid); if (obj == null) throw new Exception ("Bad character."); return obj.Name; } set { // as in, cid.Name = ""; Character obj = FindPointer (_cid); if (obj == null) throw new Exception ("Bad character."); obj.Name = value; } } . . . } In this case, you would treat CharacterId precisely as you would the Character class. The underlying, invisible property code would handle the differences in a user-transparent manner. (This is both a good and bad thing.) -dak : Please cite your quotations properly. This makes it much easier to keep track of the thread if you miss a post, etc. +------------------------------------------------------------+ | Ensure that you have read the CircleMUD Mailing List FAQ: | | http://qsilver.queensu.ca/~fletchra/Circle/list-faq.html | +------------------------------------------------------------+
This archive was generated by hypermail 2b30 : 04/10/01 PDT