Re: perplexing error
B Razen <odbrazen-/[email protected]>
| Newsgroups | gmane.comp.games.mud.client.lyntin |
|---|---|
| Message-ID | <[email protected]> |
--- will <[email protected]> wrote: > On Tue, 21 Oct 2003, B Razen wrote: > > > > Reloading modules definitely throws off the line numbering, but > > as far as I can tell that seems to be a python thing. If I make > > more than trivial changes I do a shutdown/restart so things > > line up again. > > It's a Python thing but probably aggravated by how we're reloading > modules. I had done some fixes to the load_cmd and thought I had fixed > it, but it sounds like you're still having issues. Oops, I should have mentioned I'm still running 3.x > > While we're on the subject, does anyone have a way to calculate > > dependencies and reload them in the right order? I have a custom reload > > command that has a hand-built list, but I have to update it every time > > I add a module or change an import. The problem is that modules can > > end up passing around objects from common classes that were redefined. > > This happens even though I expire all old instances, the class that > > inherits from the old version is still around and can create new > > instances that derive from 'old' classes. > > > > I have 150+ classes spread over 20 modules, so getting the right > > reload order is a bit of a pain. > > That's pretty intense. I've been keeping my modules self-contained, so > I've never bumped into this problem. I'm not sure what to tell you, but > it sounds like you're going to have to make your modules more intelligent > about things. Maybe you should write a #dumpload command that goes > through all the modules and forces them to clean themselves up (destroying > all references to everything, unregistering with hooks, so on so forth) > and then reloads them all in a specific order. > > We could probably use some adjustments to the load_cmd and the unload_cmd > that would either help this situation or fix it for you (assuming you're > using the unload function to clean up the module). > I don't actually use much of the lyntin framework outside of the connection negotiation & session management. So my problems are more akin to trying to reload all the base lyntin modules while the app is running. I'll cook up a longer post if people are interested, but the basic framework is just some objects I hang off of the lyntin session. The basic lyntin hooks (from/to mud & cron) are pushed through these objects & regexp matching etc happens there. This wrapper makes writing in a full blown python application style easy, at the expense of making tintin/zmud/tf style scripting hard. For instance I have 0 actions, 0 gags, and just a few aliases. There is a relationship between players & muds for data, some kinds of data (maps, items, mobs) are persisted for the mud and some are presisted only for a particular player of that mud (raw logging, kill history). Classes & races are dealt with by subclassing Player. sess. player. # the current player for this session, inherits from player.Player spellq # handles 'busy' actions that are limited by combat rounds vitals # keeps track of this players hps/stats/whatever mud # the current mud, inherits mud.Mud interf. # my interface class where all hooks are added catch # all catcher.Catcher text matching/filtering/muffling use this cron # all wall-clock timed events use this bump # all combat-round timed events use this write. # points to writable file-like objects mud # writes to mud socket log # writes to the current log ui # writes to the tk UI manager. # mini-version of interf, used for combat modes push # eg push(HealManager()), push(FindKillManager()) pop # opposite of push, managers usually pop themselves when 'done' set # clear the stack & set a new manager This all gets setup whenever the connect_hook is triggered, and torn down whenever the death_hook is triggered. When I reload modules manually I call the teardown/setup manually to put me back in a clean state. The whole thing is callback driven, almost all the work is done through CatchQueues which are an accumulation of Catcher objects that look like # example from Player.spellq setup class Engaged(catcher.Catcher): start = re.compile("^\s*You're already engaged this round") expects = 1 # we only want this one line of input def parse(self, lines): pass # nothing to parse, we only care it happened eng_ob = Engaged(listen=1) # listen forever eng_ob.add_callback(sess.player.spellq.already_engaged) sess.interf.catch.add(eng_ob) Most Cacther instances catch multi-line input and are one-shot as opposed to listeners. The cron & bump classes just call a function every X bumps. So to have a func called every hour it looks like sess.interf.cron.add(my_hourly_func, 60*60) To save your char every 10 combat rounds def save_closure(): sess.interf.write.mud('save\n') sess.interf.bump.add(save_closure, 10) # about 20 seconds All the session objects just watch for things and keep state, the information is pulled together in the sess.manager which have names like 'InFight', 'InOut', 'Healup', 'Goto'. They look at the state of the world and decide if they need to do something. So instead of trigger style 'if you see this => do that' you end up with small situational managers that are called when the state of the world changes (player vitals, location, etc) 'what does my world look like? => do something|nothing' this post is already longer than I inteded, so I'll stop. -Razen __________________________________ Do you Yahoo!? The New Yahoo! Shopping - with improved product search http://shopping.yahoo.com ------------------------------------------------------- This SF.net email is sponsored by OSDN developer relations Here's your chance to show off your extensive product knowledge We want to know what you know. Tell us and you have a chance to win $100 http://www.zoomerang.com/survey.zgi?HRPT1X3RYQNC5V4MLNSV3E54