view systems/scriptingsystem.py @ 157:79d6b17b80a3

Implemented simple script system.
author KarstenBock@gmx.net
date Sat, 12 Nov 2011 16:27:39 +0100
parents e856b604b650
children 1b66e1ce226b
line wrap: on
line source

#   This program is free software: you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation, either version 3 of the License, or
#   (at your option) any later version.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program.  If not, see <http://www.gnu.org/licenses/>.

from parpg.bGrease import System
from collections import deque

class Script(object):
    """Script object"""

    def __init__(self, condition, actions, commands):
        """Constructor"""
        assert(isinstance(actions, deque))
        self.condition = condition
        self.actions = actions
        self.commands = commands
        self.running = False
        self.finished = False
        self.time = 0
        self.wait = 0
        self.cur_action = None

    def update(self, time):
        """Advance the script"""
        if not self.running:
            return
        if self.cur_action and not self.cur_action.executed:
            return
        self.time += time
        if self.wait <= self.time:
            self.time = 0		    
            try:
                action = self.actions.popleft()
                self.cur_action = action[0]
                self.wait = action[1]
                if len(action) >= 3:
                    vals = action[3:] if len(action) > 3 else ()
                    command = action[2]
                    self.commands[command](*vals, action=self.cur_action)
                else:
                    self.cur_action.execute()
            except IndexError:
                self.finished = True
                self.running = False


class ScriptingSystem(System):
    """
    System responsible for managing scripts attached to entities to define 
    their behavior.
    """

    def __init__(self, funcs):
        """Constructor"""
        self.funcs = funcs
        self.vals = {}
        self.scripts = []

    def step(self, dt):
        """Execute a time step for the system. Must be defined
        by all system classes.

        :param dt: Time since last step invocation
        :type dt: float
        """
        for script in self.scripts:
            assert(isinstance(script, Script))
            if script.finished:
                self.scripts.remove(script)
            elif script.running:
                script.update(dt)
            elif eval(script.condition, self.funcs, self.vals):
                script.running = True