Skip to content

Replace 'do_activity' attribute with 'activity' in State class #12

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion stateforward/elements/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
A base class for complex states that may contain other states (regions).

### State
A simple or composite state within the state machine that can perform `entry`, `exit`, and `do_activity` behaviors. It may also contain `completion`, `deferred` events, and a reference to a `submachine`.
A simple or composite state within the state machine that can perform `entry`, `exit`, and `activity` behaviors. It may also contain `completion`, `deferred` events, and a reference to a `submachine`.

### Region
Represents a 'container' for states inside composite states or state machines. Maintains a `subvertex` collection for the vertices it encloses and references its `initial` state.
Expand Down
6 changes: 3 additions & 3 deletions stateforward/elements/elements.py
Original file line number Diff line number Diff line change
Expand Up @@ -600,14 +600,14 @@ class State(Vertex, CompositeState):
"""
State is a Vertex that is also a CompositeState.

It can define behaviors for entry and exit, as well as an ongoing do_activity behavior. The State can also
It can define behaviors for entry and exit, as well as an ongoing activity behavior. The State can also
have a completion event, which indicates that the internal behavior and activities are complete, and potentially
deferred events. States can also act as submachine states containing an entire StateMachine.

Attributes:
entry (Behavior): The behavior that is executed when entering the state.
exit (Behavior): The behavior that is executed when exiting the state.
do_activity (Behavior): The behavior that is executed while the state machine is in this state.
activity (Behavior): The behavior that is executed while the state machine is in this state.
completion (CompletionEvent): An event that is triggered when the state has completed its activity.
deferred (Collection[Event]): Events that are not handled in the state but are deferred to the state machine
for handling at a later time.
Expand All @@ -617,7 +617,7 @@ class State(Vertex, CompositeState):

entry: "Behavior" = None
exit: "Behavior" = None
do_activity: "Behavior" = None
activity: "Behavior" = None
completion: CompletionEvent = None
deferred: model.Collection[Event] = None
submachine: "StateMachine" = None
Expand Down
8 changes: 4 additions & 4 deletions stateforward/elements/functional.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,22 +210,22 @@ def simple_state(
exit: Union[
type[elements.Behavior], Callable[[elements.Behavior, elements.Event], None]
] = None,
do_activity: Union[
activity: Union[
type[elements.Behavior], Callable[[elements.Behavior, elements.Event], None]
] = None,
):
if not model.element.is_subtype(entry, elements.Behavior):
entry = behavior(entry)
if not model.element.is_subtype(exit, elements.Behavior):
exit = behavior(exit)
if not model.element.is_subtype(do_activity, elements.Behavior):
do_activity = behavior(do_activity)
if not model.element.is_subtype(activity, elements.Behavior):
activity = behavior(activity)
return model.element.new(
name,
(elements.State,),
entry=entry,
exit=exit,
do_activity=do_activity,
activity=activity,
)


Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from stateforward.elements import StateMachine


# TODO implement a compiler for the state machine
class StateMachineCompiler:
@classmethod
def compile(cls, state_machine: StateMachine):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,9 @@ async def run(self) -> None:
await self.terminate()

async def step(self) -> None:
pass
for future in self.stack.values():
if exception := future.exception() is not None:
raise exception

def is_active(self, *elements: model.Element) -> bool:
return all(element in self.stack for element in elements)
Expand All @@ -110,9 +112,12 @@ def push(
return typing.cast(Future, future)

def pop(self, element: model.Element, *, result: typing.Any = NULL):
future = self.stack.pop(element, Null())
if result is not NULL and not future.done():
future.set_result(result)
future = self.stack.pop(element, NULL)
if future.done():
if future.exception() is not None:
raise future.result()
elif result is not NULL:
future.set_result(result)
return typing.cast(Future, future)

def terminate(self):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,6 @@ async def exec_transition_exit(self, transition: elements.Transition):
async def exec_vertex_entry(
self, vertex: elements.Vertex, event: elements.Event, kind: elements.EntryKind
):
# self.log.debug(f"entering vertex {model.qualified_name_of(vertex)}")
self.push(vertex)
if isinstance(vertex, elements.State):
await self.exec_state_entry(vertex, event, kind)
Expand All @@ -176,7 +175,7 @@ async def exec_vertex_entry(
async def exec_final_state_entry(
self, final_state: elements.FinalState, event: elements.Event
):
await self.terminate()
raise NotImplementedError()

async def exec_event_exit(self, event: elements.Event):
self.pop(event)
Expand Down Expand Up @@ -204,10 +203,10 @@ def exec_time_event_entry(self, event: elements.TimeEvent):

async def exec_completion_event_wait(self, event: elements.CompletionEvent):
source: elements.State = model.owner_of(event)
future = self.stack.get(source.do_activity)
future = self.stack.get(source.activity)
event.value = await future
activities = tuple(
self.stack.get(typing.cast(elements.State, state).do_activity)
self.stack.get(typing.cast(elements.State, state).activity)
for state in self.stack
if model.element.is_subtype(state, elements.State)
and model.element.is_descendant_of(source, state)
Expand All @@ -224,16 +223,6 @@ def exec_completion_event_entry(self, event: elements.CompletionEvent):
)
return task

async def exec_call_event_wait(self, event: elements.CallEvent):
await event.results
self.push(event)

def exec_call_event_entry(self, event: elements.CallEvent):
qualified_name = model.qualified_name_of(event)
return asyncio.create_task(
self.exec_call_event_wait(event), name=qualified_name
)

def exec_event_entry(self, event: elements.Event):
qualified_name = model.qualified_name_of(event)
self.log.debug(f"entering event {qualified_name}")
Expand All @@ -243,9 +232,6 @@ def exec_event_entry(self, event: elements.Event):
elif isinstance(event, elements.CompletionEvent):
return self.exec_completion_event_entry(event)

# elif isinstance(event, elements.CallEvent):
# return self.exec_call_event_entry(event)

elif isinstance(event, elements.ChangeEvent):
return self.exec_change_event_entry(event)

Expand All @@ -271,15 +257,13 @@ async def exec_state_entry(
self.log.debug(f"entering state {qualified_name}")
if state.entry is not None:
await self.exec_behavior(state.entry, event)
if state.do_activity is not None:
if state.activity is not None:
self.push(
state.do_activity,
self.loop.create_task(self.exec_behavior(state.do_activity, event)),
state.activity,
self.loop.create_task(self.exec_behavior(state.activity, event)),
)
if state.submachine is not None:
return
# await self.enter_state_machine(state.submachine, event, kind)
# else:
await asyncio.gather(
*(
self.exec_region_entry(region, event, kind)
Expand Down Expand Up @@ -344,10 +328,10 @@ async def exec_state_exit(self, state: elements.State, event: elements.Event):
for region in state.regions or []
)
)
if state.do_activity is not None:
do_activity = self.pop(state.do_activity)
if not do_activity.done():
do_activity.cancel()
if state.activity is not None:
activity = self.pop(state.activity)
if not activity.done():
activity.cancel()
if state.exit is not None:
await self.exec_behavior(state.exit, event)
self.log.debug(f'leaving state "{qualified_name}"')
Expand Down
Empty file.

This file was deleted.

Loading