Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/346.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何倒带应用程序状态?_Java_State - Fatal编程技术网

Java 如何倒带应用程序状态?

Java 如何倒带应用程序状态?,java,state,Java,State,我正在开发一个Java桌面飞行模拟。我需要记录驾驶舱中发生的所有飞行员动作,如油门控制、转向、武器部署等,以便我以后可以查看这些事件(或实时流媒体) 我想在事件回放中添加一个可视化回放功能,这样我可以在时间上前后移动时直观地看到驾驶舱。只要我按时间顺序回放事件,回放就没有问题,但是回放有点棘手 如何实现倒带功能?您可以使用的变体,并让每个引导操作实现撤消操作 例如,如果你的飞行员做了向左转向(很简单,我知道)的动作,相反的动作是向右转向 public interface IPilotAction

我正在开发一个Java桌面飞行模拟。我需要记录驾驶舱中发生的所有飞行员动作,如油门控制、转向、武器部署等,以便我以后可以查看这些事件(或实时流媒体)

我想在事件回放中添加一个可视化回放功能,这样我可以在时间上前后移动时直观地看到驾驶舱。只要我按时间顺序回放事件,回放就没有问题,但是回放有点棘手


如何实现倒带功能?

您可以使用的变体,并让每个引导操作实现撤消操作

例如,如果你的飞行员做了向左转向(很简单,我知道)的动作,相反的动作是向右转向

public interface IPilotAction {
    void doAction(CockpitState state);
    void undoAction(CockpitState state);
}

public class ThrottleControl implement IPilotAction {

     private boolean increase;
     private int speedAmount;

     public ThrottleControl(boolean increase, int speedAmount) {
         this.increase = increase;
         this.speedAmount = speedAmount;
     }

     public void doAction(CockpitState state) {
         if (increase) {
            state.speed += speedAmount;
         } else {
            state.speed -= speedAmount;
         }
     }

     public void undoAction(CockpitState state) {
         if (increase {
             state.speed -= speedAmount;
         } else {
             state.speed += speedAmount;
         }
}
我会用修改过的

不同之处在于,我会让Memento对象存储所有试点行动的列表


Memento模式通常用于回滚(undo),但是在您的情况下,我可以看到它也适用。您还需要使先导操作具有可存储状态。

您所寻找的实际上是和模式的混合。每个引导操作都应该是一个可以记录的命令。如果需要,每个记录的命令都有一个记忆体,记录(a)不在命令中,以及(B)无法可靠重建的任何附加状态。“B”很重要,在几乎任何非平凡的领域中都存在这种状态。需要存储它以恢复精确的重建

如果合并这些概念,本质上是在每个命令上附加一个memento,那么将有一系列完整的确定性事件记录

我在一篇文章中更详细地讨论了这个问题。不要害怕根据您的具体需求对设计模式进行实质性调整。:)

重新性能问题:


如果您认为跳转几分钟是一种常见的情况,并且在实现之后您发现这是一个不可行的性能瓶颈,那么我建议在日志机制的同时实现一个偶尔的“快照”。实际上,每隔几分钟保存一次整个应用程序状态,以最大限度地减少需要执行的日志滚动量。然后,您可以从最近保存的状态访问所需的时间范围。这与在动画和媒体中类似。

这不是一个直接的答案,但请查看关于实现撤消的讨论。它们主要是关于文本编辑器的,但同样的原则也应该适用


如果你喜欢不变性,它会有帮助。撤销复杂的变化是困难的。即使是自动化系统也存在性能问题(软件事务内存,STM)。

确保您以模拟的“状态”是功能的方式实施模拟。也就是说,时间的函数

给定时间
T0
的初始状态,您应该能够在时间
Tn
为任何
n
构建模拟帧。例如,初始静止状态和无事件(尚未)可能等于标识函数,因此
Tn==Tn+1

给定时间
Ta
的一些飞行员动作事件,您应该能够为任何
n
构建帧
Ta+n
。因此,您可以将事件视为修改一个函数,该函数将时间值作为参数,并返回该时间的模拟帧

我将把事件的历史实现为表示模拟控制状态的(时间、函数)对。“当前”状态将成为焦点,右边是未来状态列表,左边是过去状态列表。像这样:

([past], present, [future])
每次模拟状态发生变化时,在未来的
中记录一个新的状态函数。然后,运行模拟就变成了从
future
列表中取出函数并将当前时间传递给它们的问题。向后运行它完全相同,只是您将事件从
pass
列表中取出

因此,如果您在时间
Tn
处,并且想要倒回时间
Tn-1
,请查看
过去的
列表,查找
时间
属性小于
n-1
的最新状态。将
n-1
传递到其
函数
属性中,您就拥有了时间
Tn-1
的模拟状态


您可以只存储每个实例的状态。1kb的状态(风速、物体速度+方向/控制输入状态,x 30fps x 20 min~36megs。1kb的状态可让您记录大约16个物体(位置/速度/角速度/方向/和5个控制/效果轴)

这可能对您来说太多了,但它将是最容易实现的。重新创建状态(即时acecss)不需要做任何工作,而且您可以非常轻松地在状态之间进行插值(以便更快/更慢地播放).对于磁盘空间,您可以压缩它,这可以在录制时完成,因此在播放时不会占用内存

节省空间的一种快速方法是对记录文件进行分页,并分别压缩每个文件箱。即每分钟压缩一个压缩流。这样,您只需解压缩当前文件箱,节省大量内存,但这取决于状态数据的压缩程度

录制命令和让类文件实现多个方向的播放需要大量调试工作。减慢/加快播放速度也会增加计算量。而唯一节省的是空间


如果这是额外的,还有其他方法可以节省时间。

这种方法对飞行sim卡的性能可以接受吗?例如,如果我回放事件20分钟,然后决定跳转到时间2分钟,我必须撤消18分钟的事件。可能有数百个事件要撤消。这取决于。你的数据越多撕扯每一个动作,你会得到更大的回应