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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.