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」が表示されます (開始状態または S2 から) 状態 S1 に移動して同じメソッドを呼び出すと、「foo quux」が表示されます. ただし、S2 で状態スタックに S1 をプッシュすると、foo() bar() を呼び出すと、「foo quux」ではなく「foo bar」が表示されます。

とにかく、元の質問に戻ります。UnrealScript で提供されるのと同じ状態機能を取得する 1 つの方法は、実行時にアスペクトを動的に有効/無効にする方法を提供する AOP 言語を採用することです。

于 2009-06-05T12:46:03.557 に答える
2

UnrealScript を実際に使用したわけではありませんが、ファーストクラスの関数 / ラムダをサポートするどの言語でも同じことを確実に実現できますか?

于 2009-06-04T13:18:56.757 に答える
2

状態を宣言できるようにするPythonのboduchライブラリがあります...しかし、これは組み込みではありません

于 2009-06-04T13:20:51.557 に答える
1

私の素朴な理解は、「タイプ状態」がオブジェクト指向言語にこの種の機能を提供するということです。

typestateとは何ですか?

特性をサポートする任意の言語で簡単に実装できます。

MixinsとTraits

しかし、私はまだこれらすべてについて学んでいるので、もっと知識のある答えを聞きたいです。

于 2011-09-16T20:43:41.877 に答える
1

Lua は、Lua のテーブル上でプログラミングする意思がある場合、状態を持つクラスもサポートします。

または、私のライブラリMindStateを使用します。通常のクラスの継承からスタック可能な状態まで、UnrealScript のクラス システムと状態を可能な限り模倣するように設計しました。

于 2010-07-14T13:22:19.520 に答える
1

私が知っている、ステートとステート マシンを本質的にサポートする言語は、通常、レクサーエキスパート システムの 2 つのクラスに分類されます。

レクサーは通常、テキスト処理を対象としていますが、多くの場合、他の用途に適応させることができます。レクサーの例は(f)lexAntlrQuexです。ロボット制御に lex を使っている人の話を聞いたことがあります。

エキスパート システムは、一連のルールとそれらに提示された状況に基づいて (おそらくエキスパートのように) 決定を下すように設計されています。独自の状態処理言語を実装するエキスパート システムの例は、makeClipsです。make はソフトウェアのビルドを支援するように設計されているため、世界観がファイルの日付に基づいている場合に最も効果的です。Clips ははるかに柔軟ですが、make のように外部 OS を本質的によく把握していません。

于 2009-06-05T13:03:48.653 に答える
1

Pawn 言語: http://en.wikipedia.org/wiki/Pawn_%28programming_language%29

于 2010-03-29T09:14:56.860 に答える
1

C# でこれを行う方法についても考えていました。これは、独自のコンポーネント オブジェクト モデルを設計するための基礎として UnrealEngine 3 を使用しているためです。(ちなみに、UDK は機能のプロトタイプを作成するための優れた方法です。) egarcia が実装した (実際には、LuaInterface を介して .NET で使用できる) ような外部アプローチを使用する以外に、2 つの可能性を思いつきました。

  1. 各状態のインターフェイスを使用した明示的なインターフェイスの実装。次に、オブジェクトを対応するインターフェイス (つまり、「状態」) にキャストし、メソッドを呼び出します。残りは CLR が行います。この呼び出しをジェネリック メソッドでラップして、インターフェイス (「状態」) を型パラメーターとして渡すこともできますが、これはやり過ぎかもしれません。

  2. デリゲートを値として状態をキーとする辞書を作成します。ハックのように見えるという代償を払って、より大きな柔軟性を提供します。

個人的には、コーディングの観点からは方法 1 を好みます。なぜなら、私は厳密な型がすべてだからです。ただし、方法 2 の方が実装と更新が簡単です。

余談ですが、egarcia の Lua アプローチに興味があり、LuaInterface が遅すぎると思われる場合は、LuaJIT をサポートするように LuaInterface を変更しました。ネイティブ インポートを使用しますが、うまくいけば、LuaJIT のパフォーマンスがディスパッチ コールを相殺します。ソースが必要な場合は、私に連絡してください。

于 2010-07-16T14:58:54.530 に答える