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

时间:2019-02-05 22:50:52

标签: scala api netlogo

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

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

我已经能够设置品种,乌龟变量,但是,我开始认为(通过设计)扩展不能访问全局变量,因为这本质上将扩展与模型耦合在一起。

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

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

1 个答案:

答案 0 :(得分:2)

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

可以从observer的{​​{1}}属性使用扩展API访问它们。这很容易从the org.nlogo.agent.World完成。您可以在此处看到the observer属性,以及一些与“观察者拥有”变量进行交互的便捷方法。

以下是获取和设置全局变量作为扩展的更长示例:

world

如果将它们作为// 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