我需要将Action添加到通过API创建的Schedule对象。有文档的接口可以设置除Action之外的几乎所有选项。如何将动作附加到这些对象?
当我尝试以编程方式添加新事件时,从单独的配置文件读取到Schedule对象时,我收到错误,指出Schedule已经初始化,并且我必须构造一个新对象并手动添加其配置。我可以使用可用的Schedule API完成大部分操作。除了Action代码,我可以设置有关Schedule的所有内容。
计划用于流程模型。在Java编辑器中查看模型,我看到我试图通过API在一个看起来像这样的函数中复制的代码:
@Override
@AnyLogicInternalCodegenAPI
public void executeActionOf( EventTimeout _e ) {
if ( _e == _fuelDeliverySchedule_Action_xjal ) {
Schedule<Integer> self = this.fuelDeliverySchedule;
Integer value = fuelDeliverySchedule.getValue();
logger.info("{} received {} pounds of fuel", this.getName(), this.fuelDeliverySchedule.getValue());
this.fuelAvailablePounds += fuelDeliverySchedule.getValue();
;
_fuelDeliverySchedule_Action_xjal.restartTo( fuelDeliverySchedule.getTimeOfNextValue() );
return;
}
super.executeActionOf( _e );
}
也许我可以使用这样的东西来创建我自己的动作函数,但我不确定如何让Scheduled事件使用它。
谢谢, 汤姆
答案 0 :(得分:1)
[编辑(扩展/重写)03.11.2014在更多关于上下文的用户详细信息之后。]
您使用
澄清了上下文当我尝试以编程方式添加&#34;发生的事情&#34;时,请阅读 从单独的配置文件,到Schedule对象,我得到错误 声明附表已经初始化,我必须这样做 构造一个新对象并手动添加其配置。我可以 其中大部分使用可用的Schedule API。我可以设置一切 关于除行动代码之外的时间表。
(您可能希望将其编辑到问题中...一般来说,解释您为什么要尝试做这件事的背景总是很好。)
我想我现在明白了。我假设您的配置文件包含计划详细信息,并且当您说您尝试添加发生的事情时#34; (这是错误的),你的意思是你试图改变日程安排&#39;模式&#39;在Schedule
。所以你的问题是,由于你无法调整预先存在的时间表,你必须以编程方式实例化(创建)自己的,但Schedule
API不允许你设置动作代码(如GUI计划元素所示)。
这是一个相当复杂的解决方案,请耐心等待。我给出了一个简短的&#39; dr&#39; 在深入细节之前总结。
您无法以编程方式对AnyLogic操作进行编码(对于任何元素),因为这相当于
动态创建Java类。解决您的问题需要认识到
计划 GUI 元素同时创建Schedule
实例和 a
超时事件(EventTimeout
)实例以触发操作。因此,您可以自己明确地创建这两个元素(前者是动态的)。诀窍是在替换Schedule
实例时重置超时事件(在新Schedule
的下一个&#39;点'触发)。
[实际上,根据你的措辞,我怀疑这个动作总是一样的,但是,为了一般性,我展示了如果你的配置文件细节可能也想改变动作的性质你如何处理它作为调度模式的那些。]
问题是GUI元素(令人困惑)不仅仅是Schedule
个实例
就它生成的代码而言。有一个(与其名称相同)
GUI元素),它只包含日程表&#39;模式&#39;并且,如在API中,
具有确定何时发生下一个开/关时段(用于开/关时间表)的方法。 (所以
它是一种奇特的日历功能。)但AnyLogic也会生成一个
超时事件实际执行操作;如果你进一步查看代码
生成后,您将看到与下面类似的内容(假设您的GUI计划被调用
fuelSchedule
,添加了Java注释
我):
// Definition of the timeout event
@AnyLogicInternalCodegenAPI
public EventTimeout _fuelSchedule_Action_xjal = new EventTimeout(this);
// First occurrence time of the event as the next schedule on/off change
// time
@Override
@AnyLogicInternalCodegenAPI
public double getFirstOccurrenceTime( EventTimeout _e ) {
if ( _e == _fuelSchedule_Action_xjal ) return fuelSchedule.getTimeOfValue() == time() ? time() : fuelSchedule.getTimeOfNextValue();
return super.getFirstOccurrenceTime( _e );
}
// After your user action code, the event is rescheduled for the next
// schedule on/off change time
_fuelSchedule_Action_xjal.restartTo( fuelSchedule.getTimeOfNextValue() );
即,这会创建一个事件,该事件会在每次调度时触发,并执行GUI计划元素中指定的操作。
因此Schedule
实例上无需更改操作;它实际上与EventTimeout
实例相关。但是,您无法以编程方式在其中更改(或动态创建新的),原因与您无法更改任何 AnyLogic元素的操作相同:
这实际上是以编程方式
创建一个Java类定义,在没有非常专业的情况下是不可能的
Java代码。 (您可以在字符串中创建Java源代码
在其上动态运行Java编译器以生成类。但是,这是非常的
&#39;高级&#39; Java,有很多潜在的陷阱,我肯定不会
建议走那条路。您还必须为用户子类创建源
EventTimeout
的{{1}},因为您不知道AnyLogic的专有EventTimeout
类的正确源代码,并且在任何情况下每个版本都可能会更改。)
但是您不应该:您的配置文件可以包含一组严格的可能操作。 (他们不能是任意Java代码片段,因为他们必须适应模拟。)因此,您可以通过编程方式创建{ {1}} 但是有一个GUI创建的超时事件,你相应地调整(假设这里有一个关闭/开启时间表,并且有 只有一个计划一次活动;显然可以根据您的需要调整这个骨架 我还没有在AnyLogic中对此进行全面测试:
1。有一个AnyLogic变量Schedule
,用于指定当前活动状态
行动。 (为简单起见,我在此处将此视为activeAction
,但使用a更好
Java int
与AnyLogic 7选项列表相同,并且可以
在AnyLogic 6中的原始Java中创建。)
2。在GUI中创建变量,称为enum
,类型为fuelSchedule
,但初始值为Schedule
。在用户控制模式下创建一个单独的超时事件,例如调用null
,操作为:
fuelScheduleTrigger
(处于用户控制模式,此事件尚未触发,最初触发,这就是我们想要的。)
3. 为每个不同的行动方案编写一组功能;让我们说吧
这里只有2个(// Perform the appropriate action (dependent on activeAction)
doAppropriateScheduleAction();
// Set the event to retrigger at the next schedule on/off switch time
fuelScheduleTrigger.restartTo(fuelSchedule.getTimeOfNextValue());
和fuelAction1
)作为示例。码
fuelAction2
as:
doAppropriateScheduleAction
4. 在您的代码中读取配置文件并获取更新的计划信息。
(可能是从循环超时事件或类似事件中运行),请将此替换
if (activeAction == 1) {
fuelAction1();
}
else if (activeAction == 2) {
fuelAction2();
}
带有修改后的计划模式的新实例(正如您所见)
一直在做,适当地设置fuelSchedule
,然后重置超时事件
新的activeAction
时间:
fuelSchedule.getTimeOfValue()
我认为当新的[set up fuelSchedule and activeAction]
// Reset schedule action to match revised schedule
fuelScheduleTrigger.restartTo(fuelSchedule.getTimeOfNextValue());
有下一个&#39;翻转&#39;当时
你搞定了。 (如果你将一个事件重新启动到当前时间,我认为它会在当前时间安排一个事件OK,如果当前时间没有安排其他事件,那么下一个事件就会发生;实际上,如果你正在使用,它肯定会发生在下一个事件中LIFO同步时间调度机制---见my blog post。)
另一种方法是创建一个完整的&#39;使用前面的操作在GUI中安排。您的配置文件读取代码可以替换基础Schedule
实例,然后重置内部 AnyLogic生成的超时事件。但是,这不太可取,因为您依赖于内部命名的AnyLogic事件(在将来的AnyLogic版本中也可能会发生变化,从而破坏您的代码)。
AnyLogic可以通过向获取相关超时事件的Schedule
API添加方法来帮助解决这种情况。例如,Schedule
。那么你就能够正确地#&#39;重启和 getActionTriggeringEventTimeout()
API会更清楚Schedule
始终与触发操作的Schedule
相关联。
当然,AnyLogic还可以通过更改计划来进一步改变计划以允许动态更改计划详细信息(并在内部处理超时事件所需的更新,如果它继续被设计为这样),但这很多更多的工作,可能有更深层次的技术原因,为什么他们希望在计划初始化后修复计划模式。
任何AnyLogic支持人员都在阅读?