相比起来,Viewer联邦与transport联邦很相似,都是TAR方式推进时间的,步长都是1.0,lookahead不同,Viewer的lookahead是0.1
程序结构也很相似。 同样,Viewer没有实质性地参与联邦运行。这点与transport联邦不同。
主要的流程都在mainThread函数中:
(1)读取配置数据,产生联邦,加入联邦;
(2)使能时间调节(为了使其他联邦运行得足够慢)和时间受限;
(3)获取各种handles,订阅。Viewer联邦订阅了如下属性和交互:
_rti.subscribeObjectClassAttributesPassively(_BoatClass, _BoatAttributes);
//changing these subscriptions to active causes the Serving.type and state
//attributes to be updated
_rti.subscribeObjectClassAttributes(_ServingClass, _ServingAttributes);
_rti.subscribeObjectClassAttributes(_ChefClass, _ChefAttributes);
_rti.subscribeObjectClassAttributes(_DinerClass, _DinerAttributes);
_rti.subscribeInteractionClass(_SimulationEndsClass);
(4)在第一个同步点ReadyToPopulate完成同步;
(5)在第二个同步点ReadyToRun完成同步;
(6)进入主循环(与transport联邦的主循环完全一样):
//advance time in steps until SimulationEnds received
_targetTime = new LogicalTimeDouble(0.0);
_targetTime.setTo(_logicalTime); //设置要TAR的时间点初始时间为0.0
timeLoop:
while (!_simulationEndsReceived) {
//advance by a step
_targetTime.increaseBy(_advanceInterval); //时间请求按步长进行,每次1.0
_userInterface.setTimeStateAdvancing();
_userInterface.post("This is before TAR: "+_targetTime);
_rti.timeAdvanceRequest(_targetTime); //时间推进请求TAR
//chew through all the events we receive from the RTI
boolean wasTimeAdvanceGrant;
do {
Callback callback = _callbackQueue.dequeue(); //获取外部时间队列中的第一个事件(注意callbackQueue是排序的)
wasTimeAdvanceGrant = callback.dispatch(); //通过调用该事件的dispatch函数来处理事件,并返回是否是time grant的布尔量
if (_simulationEndsReceived) break timeLoop; //如果是SimulationEnds交互则推出外层循环
} while (!wasTimeAdvanceGrant); //直到收到time grant事件