4

UnrealScript总是给我留下深刻的印象,它通过将函数和字段分组/重载到如下块中来对状态(和潜在函数)的内在支持:

state() SomeState
{
    ...
    function void Foo()
    {
        GotoState('SomeOtherState');
    }
    ...
}

这比在每个函数中使用大量 switch 语句要干净得多(这几乎是某种契约设计)。

是否还有其他更通用的编程语言本质上支持与此类似的状态声明(忽略可视化编程语言或 Workflow Foundation 等工具)?

编辑:

UnrealScript 中状态的一些美妙之处在于您可以覆盖子类中的有状态函数,甚至可以定义新的命名状态。我认为这对于实现不同状态的枚举开关(枚举无法扩展)、委托或协同类很麻烦,尤其是在仅支持单继承的 C# 或 Java 等语言中。

4

10 回答 10

3

任何面向对象的编程语言都可以让您轻松创建状态机。但是您可能想看看 QT,它是http://labs.trolltech.com/blogs/2009/01/30/qt-state-machine-framework/。我还没有尝试过。

我更喜欢让我能够创建各种我选择的支持结构的语言,而不是为我提供针对所有不同类型的特殊情况的特殊功能的语言。QT 中所示的 C++ 就是一个很好的例子。

于 2009-06-04T13:22:53.300 回答
3

我不知道,但支持通过元编程轻松编写特定领域语言的语言(例如,Ruby)基本上可以假装。从acts_as_state_machineRails 插件:

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,而不仅仅是状态转换)

于 2009-06-04T13:20:18.377 回答
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 语言,该语言提供了一种在运行时启用/禁用方面的动态方法。

于 2009-06-05T12:46:03.557 回答
2

没有真正使用过 UnrealScript,但您肯定可以用任何支持一流函数/ lambda 的语言实现相同的目标?

于 2009-06-04T13:18:56.757 回答
2

python中有boduch库,可以声明状态……但这不是内在的

于 2009-06-04T13:20:51.557 回答
1

我所知道的对状态和状态机具有内在支持的语言通常分为两类:LexersExpert Systems

词法分析器通常面向文本处理,但通常可以适应其他用途。词法分析器的示例是(f)lexAntlrQuex。我听说过人们使用 lex 进行机器人控制的故事。

专家系统旨在根据一组规则和您呈现的情况做出决策(假设像专家一样)。实现自己的状态处理语言的专家系统的例子是makeClips。make 旨在帮助构建软件,因此如果您对世界的看法可以基于文件日期,那么它的效果最好。Clips 更加灵活,但不像 make 那样天生就可以很好地了解外部操作系统。

于 2009-06-05T13:03:48.653 回答
1

我也一直想知道如何在 C# 中做到这一点,尤其是因为我使用 UnrealEngine 3 作为设计我自己的组件对象模型的基础。(顺便说一句,UDK 是一种很好的原型特性的方法。)除了使用像 egarcia 已经实现的外部方法(事实上,可以通过 LuaInterface 在 .NET 中使用)之外,我提出了两种可能性:

  1. 显式接口实现,每个状态都有一个接口。然后将对象转换为相应的接口(即“状态”)并调用方法;CLR 完成其余的工作。您甚至可以使用泛型方法包装此调用并将接口(“状态”)作为类型参数传递,但这可能是矫枉过正。

  2. 创建一个以状态为键的字典,以委托作为值。以看起来有点 hack-ish 为代价提供更大的灵活性。

就个人而言,从编码的角度来看,我更喜欢方法 1,因为我都是关于强类型的,但方法 2 更容易实现和更新。

附带说明一下,如果您对 egarcia 的 Lua 方法感兴趣并认为 LuaInterface 对您来说太慢,我已经修改了 LuaInterface 以支持 LuaJIT。它使用本地导入,但希望 LuaJIT 的性能能够抵消调度调用。如果您想要来源,请给我留言。

于 2010-07-16T14:58:54.530 回答
1

Lua 还支持带状态的类,前提是您愿意在 Lua 的表上进行编程。

或者,您使用我的库:MindState。我对其进行了设计,使其尽可能地模仿 UnrealScript 的类系统和状态,从常规类继承到可堆叠状态。

于 2010-07-14T13:22:19.520 回答
1

我天真的理解是“类型状态”为面向对象的语言提供了这种功能:

什么是类型状态?

并且可以用任何支持特征的语言轻松实现:

Mixins 与 Traits

不过,我仍在学习所有这些,所以我很想听到一个更有知识的答案。

于 2011-09-16T20:43:41.877 回答
1

Pawn 语言可以:http ://en.wikipedia.org/wiki/Pawn_%28programming_language%29

于 2010-03-29T09:14:56.860 回答