1- from typing import TYPE_CHECKING
1+ from typing import TYPE_CHECKING , Callable
22
33from dynamic_stack_decider .abstract_action_element import AbstractActionElement
44from dynamic_stack_decider .abstract_stack_element import AbstractStackElement
5+ from dynamic_stack_decider .tree import AbstractTreeElement , ActionTreeElement
56
67if TYPE_CHECKING :
78 from dynamic_stack_decider .dsd import DSD
@@ -16,21 +17,44 @@ class SequenceElement(AbstractStackElement):
1617 This is not an abstract class to inherit from.
1718 """
1819
19- def __init__ (self , blackboard , dsd : "DSD" , actions : list [AbstractActionElement ]):
20+ def __init__ (
21+ self ,
22+ blackboard ,
23+ dsd : "DSD" ,
24+ actions : list [ActionTreeElement ],
25+ init_function : Callable [[AbstractTreeElement ], AbstractStackElement ],
26+ ):
2027 """
21- :param actions: list of initialized action elements
28+ :param blackboard: Shared blackboard for data exchange and code reuse between elements
29+ :param dsd: The stack decider which has this element on its stack.
30+ :param actions: list of of action tree elements / blueprints for the actions
31+ :param init_function: A function that initializes an action element creating a stack element from a tree element
2232 """
2333 super ().__init__ (blackboard , dsd , dict ())
34+ # Here we store the 'blueprints' of the actions
2435 self .actions = actions
25- self .current_action_index = 0
36+ # We store a reference to the function that initializes the action elements based on the tree
37+ self ._init_function = init_function
38+ # Here we store the actual instances of the active action
39+ # The action is only initialized when it is the current action
40+ assert len (actions ) > 0 , "A sequence element must contain at least one action"
41+ self .current_action : AbstractActionElement = self ._init_function (actions [0 ])
42+ # Where we are in the sequence
43+ self .current_action_index : int = 0
2644
2745 def perform (self , reevaluate = False ):
2846 """
2947 Perform the current action of the sequence. See AbstractStackElement.perform() for more information
3048
3149 :param reevaluate: Ignored for SequenceElements
3250 """
51+ # Log the active element
52+ self .publish_debug_data ("Active Element" , self .current_action .name )
53+ # Pass the perform call to the current action
3354 self .current_action .perform ()
55+ # If the action had debug data, publish it
56+ if self .current_action ._debug_data :
57+ self .publish_debug_data ("Corresponding debug data" , self .current_action ._debug_data )
3458
3559 def pop_one (self ):
3660 """
@@ -39,30 +63,24 @@ def pop_one(self):
3963 assert not self .in_last_element (), (
4064 "It is not possible to pop a single element when" "the last element of the sequence is active"
4165 )
66+ # Increment the index to the next action and initialize it
4267 self .current_action_index += 1
68+ # We initilize the current action here to avoid the problem described in
69+ # https://github.com/bit-bots/dynamic_stack_decider/issues/107
70+ self .current_action = self ._init_function (self .actions [self .current_action_index ])
4371
4472 def in_last_element (self ):
4573 """Returns if the current element is the last element of the sequence"""
4674 return self .current_action_index == len (self .actions ) - 1
4775
48- @property
49- def current_action (self ) -> AbstractActionElement :
50- """
51- Returns the currently executed action of the sequence element
52- """
53- return self .actions [self .current_action_index ]
54-
5576 def repr_dict (self ) -> dict :
5677 """
5778 Represent this stack element as dictionary which is JSON encodable
5879 """
59- self .publish_debug_data ("Active Element" , self .current_action .name )
60- if self .current_action ._debug_data :
61- self .publish_debug_data ("Corresponding debug data" , self .current_action ._debug_data )
6280 data = {
6381 "type" : "sequence" ,
64- "current_action_id " : self .current_action_index ,
65- "content " : [ elem . repr_dict () for elem in self . actions ] ,
82+ "current_action_index " : self .current_action_index ,
83+ "current_action " : self . current_action . repr_dict (),
6684 "debug_data" : self ._debug_data ,
6785 }
6886 self .clear_debug_data ()
0 commit comments