parameters - 使用参数和源块创建代理
问题描述
我用几个参数创建了自己的流程图块。其中两个属于“代理”类型,在 Main 中我选择了相应的代理。我的块所做的是,它根据进入块的代理创建新代理(有点像批处理块)。
到目前为止,我能够验证传入代理以确保在 Main 中选择了正确的代理类型。现在我想用一个源块和注入函数创建另一个代理。但是我的问题来了。我想根据所选参数(类型代理)动态创建代理。显然,仅将参数的名称放在新的代理字段中是行不通的(它确实有效,但仅适用于第一个代理 - 之后我收到一个错误,因为创建了同一个代理)。我知道通常我必须使用“ new Agent() ”之类的东西来创建新的代理,但我找不到参数值和代理类型之间的链接。
我的问题是,我尝试使我的块尽可能可定制,这意味着我想在未来的项目中再次使用这个块,而不需要更改代码(或至少更改太多)。每个项目都会有不同的代理、变量、名称、参数等。
编辑:添加截图
解决方案
有两种方法可以实现这一点:通过 Java 反射和使用 java.util.function.Supplier。请注意,这两种方法的缺点是,由于事先不知道生成的代理的类型,因此代码将新实体称为代理,但它实际上创建了正确类型的代理,可以使用“instanceof”进行检查或投。
下面提供了这两个版本。在接下来的 2 小时内,可以在此处找到示例 .alp。在此示例中,有 2 个代理Main和ProgrammaticAgent。
现在谈谈创作的方法。
- 通过 Java 反射
这是两者中最不可取的方法。在示例主代理中,代码位于“直接创建”按钮的操作属性中。代码如下,更详细的描述请阅读评论。
// This is the name of the class that needs to be created
// as a string. It can be passed as a parameter.
// NOTE: you need the whole name including package name
// (in this case 'testprogcreation.' but you'll have your own)
String classNameValue = "testprogcreation.ProgrammaticAgent";
try {
// get a handle on the Class of that agent
Class agentClass = Class.forName(classNameValue);
// find the Constructor
Constructor c = agentClass.getDeclaredConstructor(
com.anylogic.engine.Engine.class,
com.anylogic.engine.Agent.class,
com.anylogic.engine.AgentList.class);
// Create the agent. Now, because we don't know the type
// at compile time it has to be declared as 'Agent' here
// but in actuality it is of type specified in 'classNameValue' above
Agent agent =
(Agent)c.newInstance(getEngine(), this, getDefaultPopulation());
// add to default population
((AgentLinkedHashSet<Agent>)getDefaultPopulation())._add(agent);
// set up parameters by name
agent.setParameter("parameterOne", 5.0, false);
agent.setParameter("parameterTwo", "some value", false);
agent.markParametersAreSet(); // <- mark that parameters are set
// tell AnyLogic that agent is created and started
agent.create();
agent.start();
// now you can do whatever with the agent, in this case send it
// via 'enter' into some process
enter.take(agent);
} catch (Exception e) {
e.printStackTrace();
error("Could not instantiate %s, see Console for full error", classNameValue);
}
- 通过功能供应商
这是一个更整洁的方法。这里将创建新代理的块有一个名为agentSupplier的动态参数(见图),类型为java.util.function.Supplier并agentSupplier.get()
在需要代理的新实例时调用。
然后向该供应商提供对“add_”方法的引用,该方法由 AnyLogic 在创建代理群体对象时自动生成。在这种情况下,总体称为“programmaticAgents”,因此该方法称为“add_programmaticAgents(...”)。
请注意,在上图中,默认值字段中的代码实际上会在封闭代理中更改,以反映正确的自动创建方法。
推荐阅读
- java - 如何在 dockerized Spring Boot 应用程序中启用 https(找不到 PKCS12)
- ruby-on-rails - 无法检测到 rake 任务,NameError: undefined local variable or method 'config' for main:Object
- input - sas数据集中具有相同名称的不同变量
- ios - ios Objective-c架构arm64的重复符号
- asp.net-mvc - 交换部署槽时如何刷新 Azure 应用服务缓存
- java - 如何在回收器适配器中初始化侦听器?
- function - 函数到 Lambda 转换
- javascript - 如何将对象作为数据类型传递给 sequilize 中的数据模型?
- javascript - 如何更新地图键?
- sql - SQL插入到哪里