7

そのようなサポートは現在の言語には存在しないと思います。私がやりたいことは「ワークフローエンジン」で解決できると思います。しかし、私がワークフローで抱えている問題は、一般的に次のとおりです。

  1. 宣言型/冗長性と私は命令型のスタイルがはるかに簡潔だと思います
  2. ヘビー級、私はたくさんのシンプルで多様な小さなステートマシンを持っています

C#でイテレーターをシリアル化することを調査しましたが、それでは目的の場所に正確に到達できません。現在、 BooでDSLを作成することを検討していますが、コルーチンのような動作をBooに取り込み、シリアル化できるかどうかはわかりません。

これが私がやりたいことの限られた架空の例です。主な問題は、ルーチンのどの時点でも、ユーザー入力を取得する必要があるかもしれないということです。入力間の時間が非常に長くなる可能性があるため、サービスの状態をディスクにシリアル化する必要があります。

    def RunMachine(user)
      var lever = user.ChooseLever()
      lever.Pull()
      var device = CreateDevice(user)
      machine.Add(device)
      machine.Run()

   def CreateDevice(user)
      var color = user.ChooseColor()
      var shape = user.ChooseShape()
      return Device(color, shape)

アップデート

私はCPythonで動作する「エンジン」を持っています。Pythonでのイテレータ/yieldサポートに便乗します。したがって、コードは次のようになります。

def escape(self, you):        
    roll = yield self.game.rollDice(you)
    if roll < 5:
        self.caughtAction(you)                  

どこrollDiceで中断することができます。いくつかのユーザーアクションで。ただし、 CPythonはイテレータをシリアル化しません。

ゲームの状態全体を一連のコマンドとして定義できるため、コルーチンが開始された時点までゲームの状態をシリアル化し、次に残りのコマンドのリストをシリアル化します。したがって、保存/復元するには次のようになります。

def dumpGameState(game):
    if gameState.partialState:
        return pickle.dumps({ 'partialState': game.partialState, 'partialInputs': game.partialInputs })

    return pickle.dumps(game)

def loadGameState(data):
    state = pickle.loads(data)

    if state.__class__ is Game:
        return state

    r = pickle.loads(state['partialState'])

    for input in state['partialInputs']:
        game.execute(**input)   
    return game

現在の調査

私はまだこれが不十分だと思っています。結局、ほとんどすべてのメソッドで「yield」を使用する必要があります。メソッドを特別に装飾する必要はありません。また、シリアル化ではかなり失敗します。

関数型言語はメタプログラミング/DSL作成をよりよくサポートしているように見えるので、現在私は関数型ルートに行くことを調査しています。現在見ている

十分に強力なメタプログラミング機能があれば、状態ストレージメカニズムを自動化できることを期待しています。また、F#ルートを使用すると、イテレータのシリアル化に使用した「テクニック」/(ハック)に頼ることができると確信しています。

4

5 に答える 5

7

今日これを聞いて、後でモノの継続について読んだのはおかしいです。あなたが求めているようなもののように見えます。特に、SecondLifeのマイクロスレッディングへの参照があります。これには次の説明が含まれます。

SecondLifeでは、コードを任意の時点で一時停止し、その状態全体をデータベースへの保存に適した形式にシリアル化できるようにする必要がありました。シリアル化された状態は、別の時点または別のコンピューター(たとえば、ノードからノードへの移動中)で復元できます。

私があなたを誤解していない限り、これは探索するのに良い道かもしれません。

于 2009-04-09T18:25:44.833 に答える
4

コルーチンをシリアル化するための最良のサポートは、冥王星ライブラリを介してLuaにあるようです。

私はMono2.6を試してみましたが、コルーチンを機能させることができませんでした。その後、しばらくの間Python / IronPythonを試してみましたが、シリアル化のサポートが不足していました。

今度はLuaを使用して、.NETからLuaへのP / Invokeを介してインターフェイスする必要があります。これは、LinuxとWindowsの両方で動作するための課題であることがわかりますが、最終的には、ゲームをサポートするスクリプト言語を探している場合は、おそらくすでに一般的に選択されているものを使用するのが最善です。

アップデート

とりあえずLuaを捨ててしまいました。私は統合の問題で行き詰まりすぎていました。Pythonに戻りました。コルーチンにPythonのyield式を使用しており、 pickleがジェネレーターをサポートしていないという問題を回避しています。

私の場合、プログラムの状態に常にアクティブなコルーチンがあるとは限りません。つまり、状態をピクルスにすることができる場合があります。それ以外の場合は、最後のピクルス状態と、それ以降のアクションの「再生履歴」を保存します。次に、状態を復元すると、最後の状態の選択が解除され、アクションが再生されます。

于 2010-03-01T19:15:00.240 に答える
1

Windowsワークフローを確認することをお勧めします。

http://msdn.microsoft.com/en-us/netframework/aa663328.aspx

これは、このような方法で使用することを目的としており、ワークフローが非アクティブの場合にワークフローを永続化する機能と、ワークフローを再開する機能を備えています。

技術的には言語サポートではありませんが、仕事を終わらせる必要があります。

于 2009-04-09T15:10:37.497 に答える
1

継続をお探しですか?

クロージャをサポートする任意の言語で、継続渡しスタイルでプログラムを記述し、手動でcall/ccを実装することができます。

call/ccであることcall-with-current-continuation

于 2009-04-09T15:38:15.207 に答える
0

最新バージョンのJavaには、シリアル化可能な継続をサポートするjavascriptインタープリターであるRhinoが含まれています。現在調査中のPluto+Luaもあります。

http://weaverengine.comプロジェクトではシリアル化可能な継続が重要であるため、最終的にどのような道をたどったかについてお聞きしたいと思います。

于 2011-09-04T12:51:07.583 に答える