我建立一个Scala的延长我的车型之一。我想利用斯卡拉尽可能。我一直在阅读的API reference。
我想知道是否有可能访问使用扩展API全局变量。已经有人实现这一点?
我已经能够设置品种,龟变量,但是,我开始觉得(设计)的扩展不能因为这本质上与模型的扩展高度夫妇访问全局变量。
如果有可能的话,请提供在全局可以通过名称引用的类。
如果这是不可能,有没有解决办法?我可以创建一个包含所有全局或传递全局变量作为参数,然而,这些解决方案是最后度假村的另一个品种。
的NetLogo试图把一切作为一个代理,所以对于全局变量,这些都是单纯的为了breeds-own
代理observer
变量。
他们可以使用从observer
的world
财产的扩展API进行访问。这可能是从the org.nlogo.agent.World
最容易完成的。你可以看到the observer
物业那里,以及用于交互的“观察者拥有”变量几个方便的方法。
这里是获取和设置全局作为扩展的一个长一点的示例:
// will return a list of lists with global names and values
object GetGlobals extends api.Reporter {
override def getSyntax = reporterSyntax(ret = ListType)
def report(args: Array[api.Argument], context: api.Context): AnyRef = {
import org.nlogo.agent.World
import org.nlogo.api.ScalaConversions.toLogoList
val world = context.world.asInstanceOf[World]
val globals = world.observer.variables
val results = (0 until globals.length).map( (i) => {
val globalName = world.observerOwnsNameAt(i)
val globalValue = world.observer.getVariable(i)
Seq( globalName, globalValue ).toLogoList
})
results.toLogoList
}
}
// expects a list of lists with global names and values to set
object SetGlobals extends api.Command {
override def getSyntax = commandSyntax(right = List(ListType))
def perform(args: Array[api.Argument], context: api.Context) {
import org.nlogo.agent.World
import org.nlogo.core.LogoList
val world = context.world.asInstanceOf[World]
val newGlobals = args(0).getList
newGlobals.foreach( (newGlobalAny) => {
val newGlobal = newGlobalAny.asInstanceOf[LogoList]
val globalName = newGlobal(0).asInstanceOf[String]
val newValue = newGlobal(1)
world.setObserverVariableByName( globalName, newValue )
})
}
}
如果你到一个扩展为get-globals
和set-globals
添加这些到一个扩展名为sample-scala
,你可以使用它们像这样:
extensions [ sample-scala ]
globals [ g1 g2 g3 ]
to test
show sample-scala:get-globals
sample-scala:set-globals [ [ "g1" 10 ] [ "g2" "hello" ] [ "g3" nobody ] ]
show sample-scala:get-globals
end
你会看到这样的输出:
observer> test
observer: [["G1" 0] ["G2" 0] ["G3" 0]]
observer: [["G1" 10] ["G2" "hello"] ["G3" nobody]]