Friday, March 22, 2013

"new fuse" progress

I really was liking this new fuse system, but the fact that using it seemed to limit even a small game to one UNDO was killing me. As far as I could tell, the problem was my call to "runevents" after an UNDO and other xverb commands. It just was taking up too much memory.

I decided just now that I'd code my own version of "runevents" that I'd run in such cases. I call it... fake_runevents!

The new "NEW_FUSE" code:
#ifclear NO_FUSES

#ifset NEW_FUSE
property fuse_length alias e_to

replace fuse
{
    type fuse
    size 0
    timer
    {
        if self.fuse_length
            return (self.fuse_length - counter)
        else
            return 0
    }
    fuse_length 0
    in_scope 0
    tick
    {
        local a
        a = self.timer
        if a <= 0
            self.fuse_length = 0
#ifset DEBUG
        if debug_flags & D_FUSES
        {
            print "[Running fuse "; number self; ":  timer = ";
            print number a; "]"
        }
#endif

        if a = 0
            Deactivate(self)
        return a
    }
}

property timer_start alias fuse_length
property fake_event alias s_to

replace daemon
{
    type daemon
    size 0
    in_scope 0
    timer
    {
        if self.timer_start
        {
            return (counter - self.timer_start)
        }
        else
            return 0
    }
}

object fuse_bucket
{}

routine fake_runevents
{
    local i
    for i in fuse_bucket
    {
!        if i.type = fuse
!        {
            run i.fake_event
!        }
    }
}
#endif  ! NEW_FUSE

!\
Activate - added a warning for when it is called before the player global has been set.
\!
replace Activate(a, set)                ! <set> is for fuses only
{
    local err
    if not player
        {
        Font(BOLD_ON)
        print "[WARNING:  The player global must be set before
        daemon (object "; number a;") can be activated.]"
        err = true
        }
#ifset NEW_FUSE
    move a to fuse_bucket
#endif
    a.in_scope = player
    a is active
    if a.type = fuse and not err
    {
        if set
#ifclear NEW_FUSE
            a.timer = set
#else
            a.fuse_length = (counter + set)
#endif

        run a.activate_event
    }
    elseif a.type = daemon and not err
    {
#ifclear NEW_FUSE
        if set and not a.#timer
#else
        if set and not a.#timer_start
#endif
        {
            Font(BOLD_ON)
            print "[WARNING:  Attempt to set nonexistent timer
                property on daemon (object "; number a; ")]"
            err = true
        }
        else
#ifclear NEW_FUSE
            a.timer = set
#else
            a.timer_start = (counter - set)
#endif
        run a.activate_event
    }
    elseif not err
    {
        Font(BOLD_ON)
        print "[WARNING:  Attempt to activate non-fuse/\
        daemon (object "; number a; ")]"
        err = true
    }

#ifset DEBUG
    if debug_flags & D_FUSES and not err
    {
        print "[Activating "; a.name; " "; number a;
        if a.type = fuse
            print " (timer = "; number a.timer; ")";
        print "]"
    }
#endif
    if err
        {
        Font(BOLD_OFF)
        "\npress a key to continue..."
        HiddenPause
        }
    return (not err)
}

replace Deactivate(a)
{
    local err

    remove a
    a.in_scope = 0
    a is not active

    if a.type ~= fuse and a.type ~= daemon
    {
        print "[WARNING:  Attempt to deactivate non-fuse/\
            daemon (object "; number a; ")]"
        err = true
    }
    else
    {
        run a.deactivate_event
    }

#ifset DEBUG
    if debug_flags & D_FUSES and not err
    {
        print "[Deactivating "; a.name; " "; number a; "]"
    }
#endif

    return (not err)
}
#endif ! ifclear NO_FUSES
So, you copy your "event in <fuse or daemon>" code to the fuse's fake_event property. Of course, like the old "new fuse" stuff, whether or not your code properly prints stuff will be based on whether your code uses the new counter-based timing effectively.

Anyhow, my guess is that "runevents" uses a fair amount of memory since it's doing a lot of FindObject-y stuff behind the scenes, and this method of helping Hugo find the fuses and daemons quicker seems to help my test game out a good amount.

1 comment:

  1. This comment has been removed by a blog administrator.

    ReplyDelete