Domanda

Non penso che tale supporto esista nelle lingue attuali.Penso che quello che voglio fare potrebbe essere risolto da un "motore di flusso di lavoro".Ma il problema che ho con i flussi di lavoro è che generalmente sono:

  1. Dichiarativo/verboso e trovo che lo stile imperativo sia molto più conciso
  2. Pesante, avrò un sacco di piccole macchine statali semplici ma diverse

Ho indagato serializzazione degli iteratori in C# ma questo non mi porta esattamente dove voglio essere.Attualmente sto cercando di mettere insieme un DSL in Boh ma non sono sicuro di riuscire a ottenere un comportamento simile a una coroutine in Boo e anche a serializzarlo.

Esempio

Ecco un esempio immaginario limitato di ciò che mi piacerebbe fare.Il problema principale è che in qualsiasi momento di una routine potrebbe essere necessario ottenere l'input dell'utente.Il tempo tra gli input potrebbe essere molto lungo, pertanto lo stato del servizio dovrà essere serializzato su disco.

    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)

Aggiornamento

Ho un "motore" funzionante in CPython.Si appoggia al supporto iteratore/rendimento in Python.Quindi il codice assomiglia a questo:

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

Dove rollDice può essere interrotto.con alcune azioni dell'utente. CPython tuttavia non serializza gli iteratori.

Poiché l'intero stato del gioco può essere definito come una sequenza di comandi, serializzo lo stato del gioco fino al punto in cui inizia una coroutine e poi l'elenco rimanente di comandi.Quindi per salvare/ripristinare appare così:

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

Indagini attuali

Lo trovo ancora insoddisfacente.Poiché finisco per dover utilizzare "rendimento" su quasi tutti i metodi.Preferirei non dover decorare specificatamente un metodo.Inoltre fallisce abbastanza nella serializzazione.

Attualmente sto studiando un percorso funzionale, poiché i linguaggi funzionali sembrano avere un supporto migliore per la creazione di metaprogrammazione/DSL.Attualmente sto guardando

Spero che con strutture di metaprogrammazione sufficientemente potenti potrò automatizzare il meccanismo di archiviazione dello stato.Inoltre, se seguo il percorso F#, sono abbastanza sicuro di poter ricorrere al "tecnica"/(hack) Ero solito serializzare gli iteratori.

È stato utile?

Soluzione

È strano che tu lo chieda oggi, e più tardi ne ho letto Continuazioni in mono.Sembra il genere di cose che stai cercando.In particolare si fa riferimento a Microthreading in Second Life, inclusa questa descrizione:

Secondlife ha richiesto che il codice fosse sospeso in qualsiasi momento e che il suo intero stato fosse serializzabile in un formato adatto per l'archiviazione in un database.Lo stato serializzato potrebbe quindi essere ripristinato in un momento diverso nel tempo o su un computer diverso (ad esempio mentre si sposta da nodo a nodo).

A meno che tu non abbia capito male, questa potrebbe essere una buona strada da esplorare.

Altri suggerimenti

Ho trovato il miglior supporto per la serializzazione coroutine sembra essere a Lua tramite il Plutone biblioteca.

Ci provo Mono 2.6, ma non è riuscito a far funzionare le coroutine.Ho quindi sperimentato per un po' Python/IronPython, ma mancava il supporto per la serializzazione.

Ora con Lua dovrò farlo interfaccia tramite P/Invoke da .NET a Lua che si rivela una sfida per lavorare sia su Linux che su Windows, ma alla fine se sto cercando un linguaggio di scripting per supportare un gioco, probabilmente è meglio usare quello che è già comunemente scelto.

Aggiornamento

Alla fine ho abbandonato Lua per il momento.Ero troppo impantanato nelle questioni di integrazione.Sono tornato a Python.sto usando espressioni di rendimento di Python per le mie coroutine e risolvendo il problema pickle non supporta i generatori.

Nel mio caso, lo stato del programma non ha sempre coroutine attive, il che significa che a volte posso mettere in salamoia lo stato.Altrimenti memorizzo l'ultimo stato di pickle e una "cronologia di riproduzione" delle azioni successive.Quindi ripristinare lo stato significa semplicemente deselezionare l'ultimo stato e riprodurre qualsiasi azione.

Potresti dare un'occhiata al flusso di lavoro di Windows:

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

È pensato per essere utilizzato in questo modo, con la possibilità di rendere persistente un flusso di lavoro se è presente inattività, nonché la possibilità di riavviarlo.

Anche se tecnicamente non è il supporto linguistico, dovrebbe portare a termine il lavoro.

Stai cercando continuazioni?

In qualsiasi linguaggio che supporti le chiusure, è possibile scrivere programmi in stile passaggio di continuazione e implementare manualmente call/cc.

call/cc essendo call-with-current-continuation.

L'ultima versione di Java include Rhino, un interprete javascript con supporto per continuazioni serializzabili.C'è anche Plutone+Lua, su cui sto indagando adesso.

Mi piacerebbe sapere quale percorso hai intrapreso, poiché le continuazioni serializzabili sono importanti per il http://weaverengine.com progetto.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top