我正在运行一个分层的Spring状态机,并且-在经过初始转换到状态UP和默认子状态STOPPED之后-希望使用statemachine.getState()
。问题是,它只给我父状态UP,我找不到一种明显的方法来检索父状态和子状态。
机器有状态构造如下:
StateMachineBuilder.Builder<ToolStates, ToolEvents> builder = StateMachineBuilder.builder();
builder.configureStates()
.withStates()
.initial(ToolStates.UP)
.state(ToolStates.UP, new ToolUpEventAction(), null)
.state(ToolStates.DOWN
.and()
.withStates()
.parent(ToolStates.UP)
.initial(ToolStates.STOPPED)
.state(ToolStates.STOPPED,new ToolStoppedEventAction(), null )
.state(ToolStates.IDLE)
.state(ToolStates.PROCESSING,
new ToolBeginProcessingPartAction(),
new ToolDoneProcessingPartAction());
...
builder.build();
ToolStates
和ToolEvents
只是枚举。在客户机类中,在运行上面的构建器代码之后,状态机以statemachine.start();
启动。当我随后调用statemachine.getState().getId();
时,它给出了UP
。在该调用之前没有向状态机发送任何事件。我一直在上下Spring状态机文档和示例。我从调试中知道状态UP
和STOPPED
的入口动作都被调用了,所以我假设它们都是"活动的";并且希望在查询状态机时同时显示这两种状态。是否有一种干净的方式来实现这一点?我想避免将子状态存储在Action类中的某个地方,因为我相信我已经将所有状态管理问题委派给了奇怪的statemmachine,我更愿意学习如何使用它的API来实现这一目的。
希望这是令人尴尬的显而易见的…
欢迎任何建议!
文档描述getStates()
:
https://docs.spring.io/spring-statemachine/docs/current/api/org/springframework/statemachine/state/State.html
java.util.Collection<State<S,E>> getStates()
Gets all possible states this state knows about including itself and substates.
stateMachine.getState().getStates();
总结SMA最有用的建议:事实证明,stateMachine.getState().getStates();
在我的情况下返回了一个包含四个元素的列表:
-
包含
UP
和STOPPED
的StateMachineState
实例 -
三个
ObjectState
实例,包含IDLE
、STOPPED
和PROCESSING
;分别。
这使我暂时采用以下解决方案:
public List<ToolStates> getStates() {
List<ToolStates> result = new ArrayList<>();
Collection<State<ToolStates, ToolEvents>> states = this.stateMachine.getState().getStates();
Iterator<State<ToolStates, ToolEvents>> iter = states.iterator();
while (iter.hasNext()) {
State<ToolStates, ToolEvents> candidate = iter.next();
if (!candidate.isSimple()) {
Collection<ToolStates> ids = candidate.getIds();
Iterator<ToolStates> i = ids.iterator();
while (i.hasNext()) {
result.add(i.next());
}
}
}
return result;
}
这可能会更优雅一些流和过滤,但目前的技巧。不过,我不太喜欢它。这是很多容易出错的逻辑,我必须看看它是否在未来保持-我想知道为什么在Spring statemmachine中没有一个函数给我一个枚举值的列表all当前活动状态,而不是给我所有可能的东西,然后强迫我用外部逻辑来摸索……