Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/tutorius/linear_creator.py
blob: 91b11f49618417b09185fdc609ed7fd9a9c7a15f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# Copyright (C) 2009, Tutorius.org
# Greatly influenced by sugar/activity/namingalert.py
#
# 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 2 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, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

from sugar.tutorius.core import *
from sugar.tutorius.actions import *
from sugar.tutorius.filters import *

from copy import deepcopy

class LinearCreator(object):
    """
    This class is used to create a FSM from a linear sequence of orders. The
    orders themselves are meant to be either an action or a transition.
    """
    
    def __init__(self):
        self.fsm = FiniteStateMachine("Sample Tutorial")
        self.current_actions = []
        self.nb_state = 0
        self.state_name = "INIT"
    
    def set_name(self, name):
        """
        Sets the name of the generated FSM.
        """
        self.fsm.name = name
        
    def action(self, action):
        """
        Adds an action to execute in the current state.
        """
        self.current_actions.append(action)
        
    def event(self, event_filter):
        """
        Adds a transition to another state. When executing this, all the actions
        previously called will be bundled in a single state, with the exit
        condition of this state being the transition just added.
        
        Whatever the name of the next state you inserted in the event, it will
        be replaced to point to the next event in the line.
        """
        if len(self.current_actions) != 0:
            # Set the next state name - there is no way the caller should have
            # to deal with that.
            next_state_name = "State %d" % (self.nb_state+1)
            event_filter.set_next_state(next_state_name)
            state = State(self.state_name, action_list=self.current_actions,
                event_filter_list=[event_filter])
            self.state_name = next_state_name

            self.nb_state += 1
            self.fsm.add_state(state)
            
            # Clear the actions from the list
            self.current_actions = []
        
    def generate_fsm(self):
        """
        Returns a finite state machine corresponding to the sequence of calls 
        that were made from this point on.
        """
        # Copy the whole FSM that was generated yet
        new_fsm = deepcopy(self.fsm)
        
        # Generate the final state
        state = None
        if len(self.current_actions) != 0:
            state = State("State" + str(self.nb_state), action_list=self.current_actions)
            # Don't increment the nb_state here - we would break the linearity
            # because we might generate more stuff with this creator later.
            # Since we rely on linearity for continuity when generating the 
            # next state's name on an event filter, we cannot increment here.
        else:
            state = State("State" + str(self.nb_state))
        
        # Insert the state in the copy of the FSM
        new_fsm.add_state(state)
        
        return new_fsm