UnrealScript总是给我留下深刻的印象,它通过将函数和字段分组/重载到以下块来对状态(和潜在函数)进行内在支持:
state() SomeState
{
...
function void Foo()
{
GotoState('SomeOtherState');
}
...
}
这比在每个函数中使用大量switch-statements(它几乎是某种design by contract)要清晰得多。
还有其他更通用的编程语言本质上支持与此类似的状态声明(忽略可视化编程语言或Workflow Foundation等工具)吗?
编辑:
UnrealScript中的一些状态之美是你可以在子类中覆盖有状态函数,甚至可以定义新的命名状态。我认为这对于enum-switch(枚举不能扩展),委托或实现不同状态的共同类很麻烦,特别是在只支持单继承的C#或Java等语言中。
答案 0 :(得分:3)
我所知道的,但支持通过元编程(例如Ruby)轻松编写特定领域语言的语言基本上可以假装。来自Rails的acts_as_state_machine
插件:
class Nonprofit < ActiveRecord::Base
acts_as_state_machine :initial => :created, :column => 'status'
# These are all of the states for the existing system.
state :submitted
state :processing
state :nonprofit_reviewing
state :accepted
event :accept do
transitions :from => :processing, :to => :accepted
transitions :from => :nonprofit_reviewing, :to => :accepted
end
event :receive do
transitions :from => :submitted, :to => :processing
end
# either a CTP or nonprofit user edits the entry, requiring a review
event :send_for_review do
transitions :from => :processing, :to => :nonprofit_reviewing
transitions :from => :nonprofit_reviewing, :to => :processing
transitions :from => :accepted, :to => :nonprofit_reviewing
end
end
(您还可以在event
块中包含任意代码,而不仅仅是状态转换)
答案 1 :(得分:3)
任何面向对象的编程语言都可以让您轻松创建状态机。但你可能想看看QT,它是http://labs.trolltech.com/blogs/2009/01/30/qt-state-machine-framework/。我没试过。
我优先选择语言,使我能够创建各种支持结构的语言,为我提供适用于各种特殊情况的特殊功能。 QT中显示的C ++就是一个很好的例子。
答案 2 :(得分:2)
没有真正使用过UnrealScript,但你可以在任何支持一流函数/ lambda的语言中实现同样的目标吗?
答案 3 :(得分:2)
python中的boduch库可以声明状态......但这不是内在的
答案 4 :(得分:2)
我所知道的没有编程语言提供相同的功能,在UnrealScript中有“状态”。 UnrealScript中的状态与普通状态机不同。它们更像是可以放置在对象上的图层。拦截方法调用并可以访问对象内部状态的图层。
从UnrealEngine3开始,您还可以堆叠状态,因此具有多个活动层。 例如:
function bar()
{
// print quux
}
state S1
{
function foo()
{
// print foo
}
}
state S2
{
function foo()
{
// print bar
}
function bar()
{
// print bar
}
}
现在当你进入状态S2并调用foo()和bar()时,你会看到“bar bar” 当你进入状态S1(从开始状态或S2)并调用相同的方法时,你会看到“foo quux”。 但是,当您在S2中并在状态堆栈上按S1时,当您调用foo()bar()而不是“foo quux”时,您将看到“foo bar”。
无论如何,你回到最初的问题。获得与UnrealScript相同的状态功能的一种方法是采用AOP语言,该语言提供动态的方法来在运行时启用/禁用方面。
答案 5 :(得分:1)
我所知道的对状态和状态机具有内在支持的语言通常分为两类: Lexers 和专家系统。
Lexers 通常面向文本处理,但通常可以适应其他用途。词典的示例包括(f)lex,Antlr,Quex。我听说过使用lex进行机器人控制的人的故事。
专家系统旨在根据一组规则和您提供的情况做出决策(应该像专家一样)。实现自己的状态处理语言的专家系统的示例是make和Clips。 make旨在帮助构建软件,因此如果您的世界视图可以基于文件日期,那么它最有效。剪辑更加灵活,但并不像make那样天生就能很好地了解外部操作系统。
答案 6 :(得分:1)
答案 7 :(得分:1)
Lua还支持有州的课程,前提是你愿意在Lua的桌子上编程。
或者,您使用我的库:MindState。我设计它是为了模仿UnrealScript的类系统,并尽可能地说明,从常规类继承到可堆叠状态。
答案 8 :(得分:1)
我一直想知道如何在C#中做到这一点,尤其是因为我使用UnrealEngine 3作为设计我自己的组件 - 对象模型的基础。 (顺便说一句,UDK是一种很好的原型功能。)除了使用像egarcia这样的外部方法(事实上,它可以通过LuaInterface在.NET中使用),我提出了两种可能性:
显式接口实现,每个状态都有一个接口。然后,您将对象转换为相应的接口(即“状态”)并调用该方法; CLR完成其余的工作。您甚至可以使用泛型方法包装此调用,并将接口(“state”)作为类型参数传递,但这可能是过度的。
创建一个由状态键入的字典,并将委托作为值。提供更大的灵活性,代价是看起来很糟糕。
就个人而言,我从编码的角度来看更喜欢方法1,因为我只关注强类型,但方法二更容易实现和更新。
另外,如果你对egarcia的Lua方法感兴趣并且认为LuaInterface对你来说太慢了,我已经修改了LuaInterface以支持LuaJIT。它使用本机导入,但希望LuaJIT的性能将抵消调度调用。如果你想要消息来源,请给我留言。
答案 9 :(得分:1)
我天真的理解是'type state'为面向对象的语言提供了这种功能:
可以用任何支持特征的语言轻松实现:
我仍然在学习所有这些,所以我很乐意听到更有见识的答案。