Scala NetLogo 扩展 API:访问全局变量/模型参数

Scala NetLogo Extension API: access globals / model parameters

我正在为我的一个模型构建一个 Scala 扩展。我想尽可能多地使用 Scala。我一直在阅读 API reference.

我想知道是否可以使用扩展 API 访问全局变量。有人做到了吗?

我已经能够设置 breed、turtle 变量,但是,我开始认为(按设计)扩展无法访问全局变量,因为这在本质上使扩展与模型高度耦合。

如果可能的话,请提供 class 其中全局变量可以通过名称引用。

如果不可能,是否有解决方法?我可以创建另一种包含所有全局变量或将全局变量作为参数传递的品种,但是,这些解决方案是最后的手段。

NetLogo 试图将所有事物都视为代理,因此对于全局变量,它们只是 observer 代理的 breeds-own 变量。

可以使用 worldobserver 属性 的扩展 API 访问它们。这可能最容易从 the org.nlogo.agent.World. You can see the observer 属性 那里完成,还有一些用于交互 "observer-owns" 变量的便捷方法。

这里有一个更长的获取和设置全局变量作为扩展的例子:

// 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]]