private boolean isReplay() { boolean isReplay = false; if (recordAndReplayCurrentStatus.getStatus() == RecordAndReplayStatus.REPLAY_FINISHED || recordAndReplayCurrentStatus.getStatus() == RecordAndReplayStatus.REPLAYING) { isReplay = true; if (recordAndReplayUtils.isShutdownRequested()) { recordAndReplayCurrentStatus.setStatus(RecordAndReplayStatus.NOT_ACTIVATED); recordAndReplayUtils.reset(); } } return isReplay; }
@Override public boolean step() { //Activate record when the preparations are ready if (recordAndReplayCurrentStatus.getStatus() == RecordAndReplayStatus.PREPARING_RECORD) { recordAndReplayCurrentStatus.setStatus(RecordAndReplayStatus.RECORDING); } //Activate the replay when the preparations are ready if (recordAndReplayCurrentStatus.getStatus() == RecordAndReplayStatus.PREPARING_REPLAY) { recordAndReplaySerializer.deserializeRecordAndReplayData(); recordAndReplayCurrentStatus.setStatus(RecordAndReplayStatus.REPLAYING); } return true; }
private void saveRecordingData() { if (recordAndReplayCurrentStatus.getStatus() == RecordAndReplayStatus.RECORDING) { if (recordAndReplayUtils.isShutdownRequested()) { recordAndReplaySerializer.serializeRecordAndReplayData(); recordAndReplayCurrentStatus.setStatus(RecordAndReplayStatus.NOT_ACTIVATED); recordAndReplayUtils.reset(); } else { String recordingPath = PathManager.getInstance().getRecordingPath(recordAndReplayUtils.getGameTitle()).toString(); recordAndReplaySerializer.serializeRecordedEvents(recordingPath); } } }
/** * Processes recorded events for a certain amount of time and only if the timestamp is right. */ private void processRecordedEvents() { if (recordAndReplayCurrentStatus.getStatus() == RecordAndReplayStatus.REPLAYING && !this.areRecordedEventsLoaded) { initialiseReplayData(); } //If replay is ready, process some recorded events if the time is right. if (recordAndReplayCurrentStatus.getStatus() == RecordAndReplayStatus.REPLAYING) { processRecordedEventsBatch(1); if (this.recordedEvents.isEmpty()) { if (recordAndReplayUtils.getFileCount() <= recordAndReplayUtils.getFileAmount()) { //Get next recorded events file loadNextRecordedEventFile(); } else { finishReplay(); } } } }
/** * Serialize RecordedEvents. * @param recordingPath path where the data should be saved. */ public void serializeRecordedEvents(String recordingPath) { String filepath = recordingPath + EVENT_DIR + recordAndReplayUtils.getFileCount() + JSON; recordAndReplayUtils.setFileAmount(recordAndReplayUtils.getFileAmount() + 1); recordAndReplayUtils.setFileCount(recordAndReplayUtils.getFileCount() + 1); recordedEventSerializer.serializeRecordedEvents(recordedEventStore.popEvents(), filepath); logger.info("RecordedEvents Serialization completed!"); }
/** * Calls the 'process' method if the replay is activated and the event is of a type selected to be replayed. * This way, events of the types that are recorded and replayed are ignored during a replay. This is what makes * the player have no control over the character during a replay. * @param entity the entity which the event was sent against. * @param event the event being sent. */ @Override public void send(EntityRef entity, Event event) { if (recordAndReplayCurrentStatus.getStatus() != RecordAndReplayStatus.REPLAYING || !isSelectedToReplayEvent(event)) { originalSend(entity, event); } }
/** * Deserialize RecordedEvents. * @param recordingPath path where the data was saved. */ void deserializeRecordedEvents(String recordingPath) { String filepath = recordingPath + EVENT_DIR + recordAndReplayUtils.getFileCount() + JSON; recordAndReplayUtils.setFileCount(recordAndReplayUtils.getFileCount() + 1); recordedEventStore.setEvents(recordedEventSerializer.deserializeRecordedEvents(filepath)); logger.info("RecordedEvents Deserialization completed!"); }
private void loadNextRecordedEventFile() { String recordingPath = PathManager.getInstance().getRecordingPath(recordAndReplayUtils.getGameTitle()).toString(); recordAndReplaySerializer.deserializeRecordedEvents(recordingPath); fillRecordedEvents(); }
private void sendStandardEvent(EntityRef entity, Event event, List<EventSystemReplayImpl.EventHandlerInfo> selectedHandlers) { for (EventSystemReplayImpl.EventHandlerInfo handler : selectedHandlers) { // Check isValid at each stage in case components were removed. if (handler.isValidFor(entity)) { handler.invoke(entity, event); } } }
@Override public <T extends Event> void registerEventReceiver(EventReceiver<T> eventReceiver, Class<T> eventClass, int priority, Class<? extends Component>... componentTypes) { EventSystemReplayImpl.EventHandlerInfo info = new EventSystemReplayImpl.ReceiverEventHandlerInfo<>(eventReceiver, priority, componentTypes); addEventHandler(eventClass, info, Arrays.asList(componentTypes)); }
@Override public boolean exists() { updateRealEntityRef(); return this.realEntityRef.exists(); }
@Override public int compare(EventSystemReplayImpl.EventHandlerInfo o1, EventSystemReplayImpl.EventHandlerInfo o2) { return o2.getPriority() - o1.getPriority(); } }
public RecordAndReplaySerializer(EntityManager manager, RecordedEventStore store, RecordAndReplayUtils recordAndReplayUtils, CharacterStateEventPositionMap characterStateEventPositionMap, DirectionAndOriginPosRecorderList directionAndOriginPosRecorderList, ModuleEnvironment moduleEnvironment) { this.entityManager = manager; this.recordedEventStore = store; this.recordAndReplayUtils = recordAndReplayUtils; this.characterStateEventPositionMap = characterStateEventPositionMap; this.directionAndOriginPosRecorderList = directionAndOriginPosRecorderList; this.recordedEventSerializer = new RecordedEventSerializer(entityManager, moduleEnvironment); }
@Override public <T extends Event> void registerEventReceiver(EventReceiver<T> eventReceiver, Class<T> eventClass, Class<? extends Component>... componentTypes) { registerEventReceiver(eventReceiver, eventClass, EventPriority.PRIORITY_NORMAL, componentTypes); }
/** * EventCatcher constructor that receives a list of event classes it is supposed to record, and the RecordedEventStore that * will store said event classes. * @param selectedClassesToRecord A list of classes that should be recorded and sent to the RecordedEventStore. * @param recordedEventStore The Store that will save the events selected to be recorded. */ public EventCatcher(List<Class<?>> selectedClassesToRecord, RecordedEventStore recordedEventStore) { this.selectedClassesToRecord = selectedClassesToRecord; this.eventCopier = new EventCopier(); this.recordedEventStore = recordedEventStore; }
/** * Calls the 'process' method if the replay is activated and the event is of a type selected to be replayed. * This way, events of the types that are recorded and replayed are ignored during a replay. This is what makes * the player have no control over the character during a replay. * @param entity the entity which the event was sent against. * @param event the event being sent. * @param component the component sent along with the event. */ @Override public void send(EntityRef entity, Event event, Component component) { if (recordAndReplayCurrentStatus.getStatus() != RecordAndReplayStatus.REPLAYING || !isSelectedToReplayEvent(event)) { originalSend(entity, event, component); } }
@Override public void destroy() { updateRealEntityRef(); this.realEntityRef.destroy(); }
@Override public boolean isPersistent() { updateRealEntityRef(); return this.realEntityRef.isPersistent(); }
@Override public boolean isAlwaysRelevant() { updateRealEntityRef(); return this.realEntityRef.isAlwaysRelevant(); }