写 GUI 的时候为了维护界面的状态一直用 OOP ,但是开发的很慢,也容易出 Bug ,然后就用状态机来实现,感觉还不错,有这么用的小伙伴吗?
const FSM = function () {
this.states = [];
this.current = undefined;
this.enabled = true;
};
FSM.prototype.add = function (name, enter, leave, ...event_foo_pairs) {
let state = {
__name__: name,
enter: enter,
leave: leave
};
event_foo_pairs.forEach(pairs => state[pairs[0]] = pairs[1]);
this.states.push(state);
this.states.length === 1 && this.go(name);
};
FSM.prototype.go = function (name, ...var_args) {
const prev = this.states.filter(i => i.__name__ === this.current)
const can_leave = prev.map(i => i.leave()).reduce((p, n) => p && n, true);
if (can_leave) {
const next = this.states.filter(i => i.__name__ === name);
next.length === 0 && console.error('No such next jump: ', name);
this.current = name;
const ret = next.map(i => i.enter.apply(this, var_args)).reduce((p, n) => p && n, true);
return ret;
} else {
console.warn('Can\'t leave state: ', this.current);
console.warn(new Error().stack);
return false;
}
};
FSM.prototype.fire = function (event, ...var_args) {
return this.states.filter(i => i.__name__ === this.current && i.hasOwnProperty(event)).map(s => s[event]).map(i => i.apply(this, var_args));
};
1
shunia 2016-03-11 12:36:38 +08:00
把这个问题说的学渣能明白一点,其实就是一个 State 控件(可以支持视图,也可以虚拟的),根据提供的状态进行跳转.
是这个意思吗? |
2
yksoft1 2016-03-11 12:44:10 +08:00
Windows 的消息循环里面一般不就是一个有限状态机么
|
3
twl007 2016-03-11 12:49:21 +08:00
OOP 只是编程范式吧 - - 状态机是数学模型吧? 用 OOP 也能实现状态机啊 - - ||||
|
4
mko0okmko0 2016-03-11 13:48:22 +08:00
状态机不是基本吗 XD
好吧其实是一个门槛,恭喜你迈过去 |
5
murmur 2016-03-11 14:02:23 +08:00
最基本的状态机不就是正则表达式么。。另外维护状态什么,好像新的 redux 就是搞这个的
|
6
jiongxiaobu 2016-03-11 14:55:58 +08:00
react ?
|
7
bdbai 2016-03-11 18:29:20 +08:00 via iPhone
给楼主的思想点个赞。推荐 React 和 Redux 。
|
8
glogo 2016-03-11 19:33:22 +08:00
这个思路不错!不过其实维护对象的状态是不是就是在状态机里转哪.....
|
9
quix 2016-03-11 20:26:19 +08:00
当年的 flex 不就是支持 state 么。 但有时候有多种状态, 一大堆 fsm 也不方便
|
11
march1993 OP @mko0okmko0 求高级玩法
|
17
mrsatangel 2016-03-11 23:13:14 +08:00
想当年在单片机上就有 qpc 状态机+emwin GUI 。用状态机表示目录层级没问题,框架一大复杂度急剧增加,维护状态机本身的开销比较大。另外呢 FSM 本身不足以作为一种 paradigm 和 OOP 比较
|
18
mko0okmko0 2016-03-12 01:01:30 +08:00
|
19
noli 2016-03-12 01:21:01 +08:00
JS 不是 GUI 的好工具。模拟 OOP 本身就挺费力的。
看看 OC 或者 C# 你才可以感受到为什么 OOP 在 GUI 领域是特别好的工具。 |
20
zhuangzhuang1988 2016-03-12 19:52:50 +08:00
状态机? 可以看这个。。。 https://book.douban.com/subject/6886605/ 在最后有关于状态机 UI 编程。。
代码大概这样 let rec drawingLoop(clr, from) = async { let! move = Async.AwaitEvent(form.MouseMove) #1 if (move.Button &&& MouseButtons.Left) = MouseButtons.Left then drawRectangle(clr, from, (move.X, move.Y)) #2 return! drawingLoop(clr, from) #2 else return (move.X, move.Y) } #3 let waitingLoop() = async { while true do #4 let! down = Async.AwaitEvent(form.MouseDown) let downPos = (down.X, down.Y) if (down.Button &&& MouseButtons.Left) = MouseButtons.Left then let! upPos = drawingLoop(Color.IndianRed, downPos) #5 do printfn "Drawn rectanlge (%A, %A)" downPos upPos } #A Wait for the next mouse action #2 Refresh rectangle and continue in the 'Drawing' state #3 Return end location to the 'Waiting' state #4 Repeat after drawing finishes #5 Transition to the 'Drawing' state |
22
march1993 OP @zhuangzhuang1988 666666
|