< All Topics

Cancel Current Operation

Overview

The Cancel current operation function allows you to interrupt and stop ongoing archive operations, providing users with responsive control over long-running zip/unzip processes. This function is essential for maintaining good user experience in applications that handle large files or multiple archive operations.

Function Description

Cancel Current Operation

  • Node Name: Cancel current operation
  • Category: Archive Manager
  • Type: Synchronous (immediate operation)

Immediately cancels any currently running archive operation (zip or unzip). This function works with both synchronous and asynchronous operations, allowing users to abort processes that are taking too long or are no longer needed.

Blueprint Usage

Parameters

ParameterTypeDescription
NoneThis function takes no input parameters
OutputTypeDescription
Return ValueBooleantrue if operation was cancelled, false if no operation was running

Blueprint Setup Examples

Basic Cancellation Setup

  1. Start Archive Operation: Begin any async archive operation
  2. Setup Cancel Trigger: Connect user input (button press, key input) to cancel function
  3. Handle Cancellation: Process the cancellation result
  4. Update UI: Show cancellation feedback to user

Mouse Button Cancellation

Left Mouse Button (Pressed)
    ↓
Cancel current operation
    ↓
Branch: Return Value
    ↓ (True)
Print String: "Operation cancelled successfully"
    ↓ (False)
Print String: "No operation to cancel"

Keyboard Cancellation (ESC Key)

Escape Key (Pressed)
    ↓
Cancel current operation
    ↓
Branch: Was Cancelled?
    ↓ (True)
Print String: "Zipping cancelled"
Hide Progress Bar
Update Cancel Button State
    ↓ (False)
Print String: "No active operation"

UI Button Cancellation

Cancel Button (On Clicked)
    ↓
Cancel current operation
    ↓
Branch: Success?
    ↓ (True)
Set Button Text: "Cancelled"
Set Button Enabled: False
Hide Progress Widget
    ↓ (False)
Print String: "Nothing to cancel"

Complete Async Operation with Cancellation

Event BeginPlay
    ↓
Start Zip Files Async
    ↓
Show Progress Bar
    ↓
Enable Cancel Button

// Separate event chain
Cancel Button (On Clicked)
    ↓
Cancel current operation
    ↓
Branch: Cancelled?
    ↓ (True)
Hide Progress Bar
Print String: "Archive operation cancelled by user"
Reset UI State

C++ Usage

Basic Cancellation

#include "ArchiveManagerBPLibrary.h"

// Cancel any running archive operation
bool bWasCancelled = UArchiveManagerBPLibrary::CancelCurrentOperation();

if (bWasCancelled)
{
    UE_LOG(LogTemp, Log, TEXT("Archive operation cancelled successfully"));
    
    // Update UI to reflect cancellation
    UpdateUIForCancellation();
}
else
{
    UE_LOG(LogTemp, Warning, TEXT("No archive operation was running to cancel"));
}

Advanced Cancellation Manager

UCLASS()
class YOURGAME_API UArchiveCancellationManager : public UObject
{
    GENERATED_BODY()

public:
    UFUNCTION(BlueprintCallable)
    bool RequestCancellation();
    
    UFUNCTION(BlueprintCallable)
    void SetupCancellationControls();
    
    UFUNCTION(BlueprintCallable)
    bool IsOperationCancellable() const;

private:
    bool bOperationInProgress = false;
    bool bCancellationRequested = false;
    
    UFUNCTION()
    void OnArchiveOperationStarted();
    
    UFUNCTION()
    void OnArchiveOperationCompleted(bool bSuccess);
};

bool UArchiveCancellationManager::RequestCancellation()
{
    if (!bOperationInProgress)
    {
        UE_LOG(LogTemp, Warning, TEXT("No operation in progress to cancel"));
        return false;
    }
    
    bCancellationRequested = true;
    bool bCancelled = UArchiveManagerBPLibrary::CancelCurrentOperation();
    
    if (bCancelled)
    {
        UE_LOG(LogTemp, Log, TEXT("Cancellation request processed successfully"));
        bOperationInProgress = false;
        
        // Notify UI
        OnCancellationProcessed.Broadcast();
    }
    else
    {
        UE_LOG(LogTemp, Error, TEXT("Failed to cancel operation"));
        bCancellationRequested = false;
    }
    
    return bCancelled;
}

void UArchiveCancellationManager::SetupCancellationControls()
{
    // Bind ESC key for cancellation
    if (APlayerController* PC = GetWorld()->GetFirstPlayerController())
    {
        PC->InputComponent->BindKey(EKeys::Escape, IE_Pressed, this, 
                                  FName("RequestCancellation"));
    }
}

bool UArchiveCancellationManager::IsOperationCancellable() const
{
    return bOperationInProgress && !bCancellationRequested;
}

Cancellation with Progress Tracking

UCLASS()
class YOURGAME_API UProgressiveCancellationSystem : public UObject
{
    GENERATED_BODY()

public:
    UFUNCTION(BlueprintCallable)
    void StartArchiveWithCancellation(const TArray& Files, const FString& OutputPath);
    
    UFUNCTION(BlueprintCallable)
    void CancelWithConfirmation();

private:
    FTimerHandle ProgressTimer;
    bool bOperationActive = false;
    float CurrentProgress = 0.0f;
    
    UFUNCTION()
    void UpdateProgress();
    
    UFUNCTION()
    void OnZipProgress(float Progress);
    
    UFUNCTION()
    void OnZipComplete(bool bSuccess);
    
    UFUNCTION()
    void ConfirmCancellation();
};

void UProgressiveCancellationSystem::StartArchiveWithCancellation(
    const TArray& Files, 
    const FString& OutputPath)
{
    if (bOperationActive)
    {
        UE_LOG(LogTemp, Warning, TEXT("Operation already in progress"));
        return;
    }
    
    bOperationActive = true;
    CurrentProgress = 0.0f;
    
    // Setup progress callback
    FZipProgressDelegate ProgressDelegate;
    ProgressDelegate.BindDynamic(this, &UProgressiveCancellationSystem::OnZipProgress);
    
    // Setup completion callback
    FZipFilesDelegate CompletionDelegate;
    CompletionDelegate.BindDynamic(this, &UProgressiveCancellationSystem::OnZipComplete);
    
    // Start async operation
    bool bStarted = UArchiveManagerBPLibrary::ZipFilesAsync(
        Files, 
        OutputPath, 
        false, 
        CompletionDelegate,
        ProgressDelegate,
        nullptr // Cancellation token
    );
    
    if (bStarted)
    {
        // Start progress monitoring
        GetWorld()->GetTimerManager().SetTimer(ProgressTimer, this, 
            &UProgressiveCancellationSystem::UpdateProgress, 0.1f, true);
            
        UE_LOG(LogTemp, Log, TEXT("Archive operation started with cancellation support"));
    }
    else
    {
        bOperationActive = false;
        UE_LOG(LogTemp, Error, TEXT("Failed to start archive operation"));
    }
}

void UProgressiveCancellationSystem::CancelWithConfirmation()
{
    if (!bOperationActive)
    {
        UE_LOG(LogTemp, Warning, TEXT("No operation to cancel"));
        return;
    }
    
    // Show confirmation dialog in real implementation
    // For now, directly cancel
    ConfirmCancellation();
}

void UProgressiveCancellationSystem::ConfirmCancellation()
{
    bool bCancelled = UArchiveManagerBPLibrary::CancelCurrentOperation();
    
    if (bCancelled)
    {
        GetWorld()->GetTimerManager().ClearTimer(ProgressTimer);
        bOperationActive = false;
        
        UE_LOG(LogTemp, Log, TEXT("Operation cancelled at %.1f%% progress"), 
               CurrentProgress * 100.0f);
        
        // Notify UI of cancellation
        OnOperationCancelled.Broadcast(CurrentProgress);
    }
}

void UProgressiveCancellationSystem::OnZipProgress(float Progress)
{
    CurrentProgress = Progress;
    
    // Update UI progress
    OnProgressUpdated.Broadcast(Progress);
}

void UProgressiveCancellationSystem::OnZipComplete(bool bSuccess)
{
    GetWorld()->GetTimerManager().ClearTimer(ProgressTimer);
    bOperationActive = false;
    
    if (bSuccess)
    {
        UE_LOG(LogTemp, Log, TEXT("Archive operation completed successfully"));
        OnOperationCompleted.Broadcast(true);
    }
    else
    {
        // Check if it was cancelled or failed
        FString ErrorMessage = UArchiveManagerBPLibrary::GetLastArchiveError();
        if (ErrorMessage.Contains(TEXT("cancelled")) || ErrorMessage.Contains(TEXT("aborted")))
        {
            UE_LOG(LogTemp, Log, TEXT("Operation was cancelled"));
            OnOperationCancelled.Broadcast(CurrentProgress);
        }
        else
        {
            UE_LOG(LogTemp, Error, TEXT("Operation failed: %s"), *ErrorMessage);
            OnOperationCompleted.Broadcast(false);
        }
    }
}

Multi-Operation Cancellation System

UCLASS()
class YOURGAME_API UMultiOperationCanceller : public UObject
{
    GENERATED_BODY()

public:
    UFUNCTION(BlueprintCallable)
    FString StartOperation(const FString& OperationType);
    
    UFUNCTION(BlueprintCallable)
    bool CancelOperation(const FString& OperationId);
    
    UFUNCTION(BlueprintCallable)
    bool CancelAllOperations();
    
    UFUNCTION(BlueprintCallable)
    TArray GetActiveOperations() const;

private:
    struct FActiveOperation
    {
        FString Id;
        FString Type;
        FDateTime StartTime;
        bool bCancellable;
    };
    
    TMap ActiveOperations;
    
    FString GenerateOperationId();
    void CleanupOperation(const FString& OperationId);
};

FString UMultiOperationCanceller::StartOperation(const FString& OperationType)
{
    FString OperationId = GenerateOperationId();
    
    FActiveOperation NewOp;
    NewOp.Id = OperationId;
    NewOp.Type = OperationType;
    NewOp.StartTime = FDateTime::Now();
    NewOp.bCancellable = true;
    
    ActiveOperations.Add(OperationId, NewOp);
    
    UE_LOG(LogTemp, Log, TEXT("Started %s operation with ID: %s"), 
           *OperationType, *OperationId);
    
    return OperationId;
}

bool UMultiOperationCanceller::CancelOperation(const FString& OperationId)
{
    if (!ActiveOperations.Contains(OperationId))
    {
        UE_LOG(LogTemp, Warning, TEXT("Operation %s not found or already completed"), 
               *OperationId);
        return false;
    }
    
    const FActiveOperation& Op = ActiveOperations[OperationId];
    if (!Op.bCancellable)
    {
        UE_LOG(LogTemp, Warning, TEXT("Operation %s is not cancellable at this time"), 
               *OperationId);
        return false;
    }
    
    bool bCancelled = UArchiveManagerBPLibrary::CancelCurrentOperation();
    
    if (bCancelled)
    {
        UE_LOG(LogTemp, Log, TEXT("Cancelled %s operation %s"), 
               *Op.Type, *OperationId);
        CleanupOperation(OperationId);
    }
    
    return bCancelled;
}

bool UMultiOperationCanceller::CancelAllOperations()
{
    if (ActiveOperations.Num() == 0)
    {
        UE_LOG(LogTemp, Log, TEXT("No operations to cancel"));
        return true;
    }
    
    bool bAllCancelled = true;
    TArray OperationsToCancel;
    
    // Collect cancellable operations
    for (const auto& Pair : ActiveOperations)
    {
        if (Pair.Value.bCancellable)
        {
            OperationsToCancel.Add(Pair.Key);
        }
    }
    
    // Cancel each operation
    for (const FString& OpId : OperationsToCancel)
    {
        if (!CancelOperation(OpId))
        {
            bAllCancelled = false;
        }
    }
    
    UE_LOG(LogTemp, Log, TEXT("Cancelled %d/%d operations"), 
           OperationsToCancel.Num() - (bAllCancelled ? 0 : 1), 
           OperationsToCancel.Num());
    
    return bAllCancelled;
}

Cancellation Scenarios

User-Initiated Cancellation

  • Button Press: Cancel button in progress dialog
  • Keyboard Shortcut: ESC key or Ctrl+C
  • Mouse Click: Click outside progress area
  • Menu Action: Stop operation from menu

System-Initiated Cancellation

  • Timeout: Operation takes too long
  • Resource Limits: Memory or disk space exhaustion
  • Application Shutdown: Clean shutdown sequence
  • Error Conditions: Unrecoverable errors

Context-Sensitive Cancellation

  • File Size: Only allow cancellation for large operations
  • Progress Stage: Disable cancellation during critical phases
  • Operation Type: Different rules for zip vs unzip
  • User Permissions: Admin-only cancellation for system operations

Best Practices

User Experience Guidelines

  • Clear feedback: Always inform user when cancellation succeeds
  • Immediate response: Cancel function should respond quickly
  • Confirmation dialogs: Ask for confirmation on long operations
  • Progress indication: Show how much work will be lost
  • Alternative actions: Offer pause instead of cancel when possible

Implementation Guidelines

  • Check operation state: Verify operation is running before cancelling
  • Handle gracefully: Clean up resources after cancellation
  • Update UI immediately: Disable progress indicators
  • Log cancellations: Record for debugging and analytics
  • Test thoroughly: Verify cancellation works at all stages

Error Handling

  • No operation running: Handle gracefully without errors
  • Cancellation fails: Retry or force termination
  • Partial completion: Handle partially created files
  • Resource cleanup: Ensure no leaked handles or memory

Integration Examples

Progress Dialog with Cancellation

Start Archive Operation
    ↓
Create Progress Widget
    ↓
Show Modal Dialog
    ↓
Bind Cancel Button Event
    ↓
Update Progress Bar (Timer)

// Cancel button event
Cancel Button Clicked
    ↓
Show Confirmation Dialog: "Cancel operation?"
    ↓ (Yes)
Cancel current operation
    ↓
Close Progress Dialog
    ↓
Print String: "Operation cancelled"

Timeout-Based Cancellation

Start Archive Operation
    ↓
Set Timer: 60 seconds (Timeout)
    ↓
Start Progress Monitoring

// Timeout event
Timeout Timer Expired
    ↓
Cancel current operation
    ↓
Print String: "Operation timed out and was cancelled"
    ↓
Show Error Dialog: "Operation took too long"

Smart Cancellation System

Custom Event: Smart Cancel
    ↓
Branch: Operation Progress > 90%?
    ↓ (True)
Show Dialog: "Almost done, wait or cancel?"
    ↓ Wait Button: Continue operation
    ↓ Cancel Button: Cancel current operation
    ↓ (False)
Cancel current operation immediately

Platform Considerations

Desktop Platforms

  • Keyboard shortcuts: ESC, Ctrl+C support
  • System integration: Task manager compatibility
  • Multi-threading: Thread-safe cancellation
  • File system: Handle locked files gracefully

Mobile Platforms

  • Touch interface: Large, accessible cancel buttons
  • Background apps: Handle app suspension during operations
  • Battery optimization: Cancel to save power
  • Storage limits: Cancel when space is low

Console Platforms

  • Controller input: Map to appropriate buttons
  • System notifications: Integrate with platform UI
  • Memory constraints: Auto-cancel on memory pressure
  • Certification requirements: Follow platform guidelines

Common Issues and Solutions

IMPORTANT!!! If you want to call out input nodes make sure to do this in level blueprint or pawn controller blueprint. Input actions will not work in other blueprints.

Cancellation Doesn’t Work

  • Issue: Cancel function returns false
  • Cause: No operation running or operation already completed
  • Solution: Check operation state before calling cancel

Partial Files Created

  • Issue: Incomplete archive files left after cancellation
  • Cause: Cancellation occurred during file write
  • Solution: Implement cleanup to remove partial files

UI Not Updating

  • Issue: Progress bar continues after cancellation
  • Cause: UI update callbacks not properly handled
  • Solution: Clear timers and update UI state immediately

Memory Leaks

  • Issue: Memory usage doesn’t decrease after cancellation
  • Cause: Resources not properly cleaned up
  • Solution: Implement proper resource management in callbacks

Testing Cancellation

Test Scenarios

  • Early cancellation: Cancel immediately after starting
  • Mid-operation: Cancel during active processing
  • Late cancellation: Cancel near completion
  • Multiple operations: Cancel with several operations queued
  • Resource pressure: Cancel under low memory/storage

Validation Points

  • Return value accuracy: Verify true/false responses
  • Resource cleanup: Check for memory/handle leaks
  • File system state: Verify no corrupt files remain
  • UI consistency: Ensure UI reflects cancellation state
  • Error messages: Confirm appropriate error reporting
Table of Contents