2014-01-28 35 views
3

我在寫一個原型,它需要兩個代理集和一個命令塊。它需要調用幾個函數,在當前上下文中執行命令塊,然後調用另一個函數。這是我到目前爲止有:在NetLogo擴展中的基元中執行命令塊

class WithContext(pushGraphContext: GraphContext => Unit, popGraphContext: api.World => GraphContext) 
    extends api.DefaultCommand { 
    override def getSyntax = commandSyntax(
    Array(AgentsetType, AgentsetType, CommandBlockType)) 

    def perform(args: Array[Argument], context: Context) { 
    val turtleSet = args(0).getAgentSet.requireTurtleSet 
    val linkSet = args(1).getAgentSet.requireLinkSet 
    val world = linkSet.world 
    val gc = new GraphContext(world, turtleSet, linkSet) 
    val extContext = context.asInstanceOf[ExtensionContext] 
    val nvmContext = extContext.nvmContext 
    pushGraphContext(gc) 
    // execute command block here 
    popGraphContext(world) 
    } 
} 

我看了一些例子所使用nvmContext.runExclusively,但看起來它是專門爲具有一定agentset運行命令塊。我希望當前的代理(可能是觀察者)運行它。我是否應該將nvm.agent包裝在座席中並將其傳遞給nvmContext.runExclusively?如果是這樣,在代理程序集中包裝代理程序的最簡單方法是什麼?如果不是,我該怎麼辦?

回答

2

方法#1

越快 - 丁按理說-髒的方法是使用runExclusiveJob,這表現在(例如)在https://github.com/NetLogo/Sample-Scala-Extension/blob/master/src/SampleScalaExtension.scalacreate-red-turtles命令。

要將當前代理包裝在代理集中,可以使用agent.AgentSetBuilder。 (你也可以通過長度爲1的Array[Agent]ArrayAgentSet建設者之一,但我建議AgentSetBuilder,因爲它是在內部實現細節可能改變的依賴。)

方法2

方法#1的缺點是與創建和設置額外的AgentSetJobContext對象相關的輕微不變的開銷並指導執行。

創建並運行單獨的作業實際上並不是像ifwhile這樣的內置命令如何工作。他們沒有做出新的工作,而是停留在當前的工作中,並通過操作指令指針(nvm.Context.ip)跳轉到指令塊或跳過指令指令塊來使命令塊中的命令運行(或不運行)。

我相信一個擴展命令可以做同樣的事情。我不確定它是否曾經嘗試過,但我看不出有任何理由不起作用。

這樣做會涉及到更多關於NetLogo引擎內部的知識,如https://github.com/NetLogo/NetLogo/wiki/Engine-architecture所述。你可以在例如之後模擬你的基元https://github.com/NetLogo/NetLogo/blob/5.0.x/src/main/org/nlogo/prim/etc/_if.java,包括更改您的實施nvm.CustomAssembled。 (請注意,運行擴展命令的prim._extern將其assemble方法委託給包裝命令自己的assemble方法,所以這應該起作用。)在您的assemble方法中,不要在末尾調用done()來終止作業,而只是允許執行通過。

我可以嘗試構建一個以這種方式工作的示例,但它需要我幾個小時;除非有真正的需求,否則這可能不值得我去做。

+0

它看起來不像'agent.AgentSetBuilder'存在了。也就是說,使用'ArrayAgentSet'的ArrayAgentSet(Class [?extends Agent],Array [Agent],World)'構造函數很容易。 –

+1

噢,對不起,'AgentSetBuilder'是主/無頭的東西。在5.0.x的情況下,是的,你做的是正確的事情。 –