Пример #1
0
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;
}
Пример #2
0
/*
 * 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;
    }
}