EPawnActionAbortState::Type UPawnAction::Abort(EAIForceParam::Type ShouldForce) { // if already aborting, and this request is not Forced, just skip it if (AbortState != EPawnActionAbortState::NotBeingAborted && ShouldForce != EAIForceParam::Force) { if (AbortState == EPawnActionAbortState::NeverStarted) { UE_VLOG(GetPawn(), LogPawnAction, Log, TEXT("%s> Discarding Abort request since the action has never been started yet"), *GetName()); } else { UE_VLOG(GetPawn(), LogPawnAction, Log, TEXT("%s> Discarding Abort request due to action being already in abort state"), *GetName()); } return AbortState; } const bool bForce = ShouldForce == EAIForceParam::Force; EPawnActionAbortState::Type Result = EPawnActionAbortState::NotBeingAborted; EPawnActionAbortState::Type ChildResult = EPawnActionAbortState::AbortDone; if (ChildAction != NULL) { ChildResult = ChildAction->Abort(ShouldForce); if (ChildResult == EPawnActionAbortState::NotBeingAborted) { UE_VLOG(GetPawn(), LogPawnAction, Error, TEXT("%s> ChildAction %s failed to carry out proper abortion! Things might get ugly..") , *GetName(), *ChildAction->GetName()); // fake proper result and hope for the best! ChildResult = EPawnActionAbortState::AbortDone; } } if (bForce) { Result = PerformAbort(ShouldForce); if (Result != EPawnActionAbortState::AbortDone) { UE_VLOG(GetPawn(), LogPawnAction, Error, TEXT("%s> failed to force-abort! Things might get ugly..") , *GetName()); // fake proper result and hope for the best! Result = EPawnActionAbortState::AbortDone; } } else { switch (ChildResult) { case EPawnActionAbortState::MarkPendingAbort: // this means child is awaiting its abort, so should parent case EPawnActionAbortState::LatentAbortInProgress: // this means child is performing time-consuming abort. Parent should wait Result = EPawnActionAbortState::MarkPendingAbort; break; case EPawnActionAbortState::AbortDone: Result = IsPaused() ? EPawnActionAbortState::MarkPendingAbort : PerformAbort(ShouldForce); break; default: UE_VLOG(GetPawn(), LogPawnAction, Error, TEXT("%s> Unhandled Abort State!") , *GetName()); Result = EPawnActionAbortState::AbortDone; break; } } SetAbortState(Result); return Result; }
/* * Process the given USB control command, storing the result in replyBuf * and returning the number of output bytes. Returns -1 if command is * invalid. All control processing has to happen until completion (no * delayed execution) and it may not take additional input from the host * (data direction set as host to device). * * The replyBuf is 8 bytes long. */ int8_t usbHandleControl(uint8_t cmd, uint8_t *replyBuf) { DEBUGF(DBG_INFO, "cmd %d (%d)\n", cmd, cmd - XUM1541_IOCTL); switch (cmd) { case XUM1541_ENTER_BOOTLOADER: enterBootLoader(); return 0; case XUM1541_ECHO: replyBuf[0] = cmd; return 1; case XUM1541_INIT: savedNibWritePtr = savedNibWrites; board_set_status(STATUS_ACTIVE); // First time: init IO pins and probe for IEC or IEEE devices if (cmds == NULL) cmds = cbm_init(); // If we still don't have a bus, something is really wrong. if (cmds == NULL) return -1; replyBuf[0] = XUM1541_VERSION; replyBuf[1] = XUM1541_CAPABILITIES; replyBuf[2] = currState; /* * Our previous transaction was interrupted in the middle, say by * the user pressing ^C. Reset the IEC bus and then enter the * stalled state. The host will clear the stall and continue * their new transaction. */ if (cmdSeqInProgress) { replyBuf[2] |= XUM1541_DOING_RESET; cmdSeqInProgress = XUM1541_DOING_RESET; cmds->cbm_reset(false); SetAbortState(); } cmdSeqInProgress |= XUM1541_CMD_IN_PROGRESS; /* * We wait in main() until at least one device is present on the * IEC bus. Notify the user if they requested a command before * that has been detected. */ if (!device_running) replyBuf[2] |= XUM1541_NO_DEVICE; return 8; case XUM1541_SHUTDOWN: cmdSeqInProgress = 0; board_set_status(STATUS_READY); return 0; case XUM1541_RESET: // Only do reset if we didn't just reset in INIT (above). if ((cmdSeqInProgress & XUM1541_DOING_RESET) == 0) cmds->cbm_reset(false); return 0; #ifdef TAPE_SUPPORT case XUM1541_TAP_BREAK: cmds->cbm_reset(false); return 0; #endif // TAPE_SUPPORT default: DEBUGF(DBG_ERROR, "ERR: control cmd %d not impl\n", cmd); return -1; } }