Skip to content

Ten-Trillion-Triangles/TSync

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

TSync

TSync is a comprehensive multithreading library for Unreal Engine that provides Blueprint and C++ support for asynchronous task execution, thread management, and synchronization primitives.

Features

  • Blueprint Multithreading: Execute background tasks directly from Blueprints without C++ knowledge
  • Raw Thread Management: Create and manage custom FRunnable threads with interface-based communication
  • Mutex Support: Thread-safe synchronization with named mutexes accessible from Blueprints
  • Game Thread Locks: Convenient locking mechanisms for game thread operations
  • Async Task System: Predefined async task types with delegate-based completion callbacks
  • Interface-Based Architecture: Clean communication between threads using UE interfaces
  • Automatic Thread Cleanup: Built-in garbage collection for completed threads
  • RAII Scope Locking: Automatic mutex management with scope-based unlocking

Architecture

TSync consists of several key components:

Core Classes

  • AAsyncTaskManager: Main actor that manages all threading operations
  • UMutexWrapper: Blueprint-safe wrapper around FCriticalSection
  • FRawThread: Custom FRunnable implementation for background thread execution
  • UBpAsyncNode: Blueprint async action node for background task execution
  • UAsyncFunctionLibrary: Static utility functions for accessing the task manager

Interface System

  • IRawThreadInterface: Interface for objects that can execute threaded operations
    • ExecuteThreaded(): Called on background thread to perform work
    • OnThreadFinished(): Called on game thread when work completes
    • OnThreadExit(): Notifies thread manager of thread completion

Building

Prerequisites

  • Unreal Engine 4.25+ or Unreal Engine 5.x
  • Visual Studio 2019+ (Windows) or Xcode (macOS) or GCC/Clang (Linux)
  • C++17 compatible compiler

Installation

  1. Plugin Installation:

    # Copy TSync folder to your project's Plugins directory
    cp -r TSync /path/to/YourProject/Plugins/
  2. Enable in Project:

    • Open your Unreal Engine project
    • Go to Edit → Plugins
    • Find "TSync" under "Other" category
    • Enable the plugin
    • Restart the editor when prompted
  3. Add Module Dependency (for C++ projects):

    // In YourProject.Build.cs
    PublicDependencyModuleNames.AddRange(new string[] {
        "Core",
        "CoreUObject", 
        "Engine",
        "TSync"  // Add this line
    });

Building from Source

# Generate project files
./GenerateProjectFiles.sh  # Linux/Mac
# or
GenerateProjectFiles.bat   # Windows

# Build the project
# This will automatically build TSync as a dependency

Usage

Blueprint Usage

1. Basic Async Task Execution

  1. Place AsyncTaskManager in Level:

    • Drag AsyncTaskManager actor into your level
    • Or spawn it dynamically in Blueprint
  2. Get Task Manager Reference:

    // In Blueprint: Call "Get Async Task Manager" function
  3. Execute Async Task:

    // In Blueprint:
    // 1. Call "Execute Task" on AsyncTaskManager
    // 2. Set Task Type (enum)
    // 3. Set Requester (self reference)
    // 4. Bind to "On Task Complete" delegate

2. Background Task Node

// In Blueprint:
// 1. Right-click → Add Node → "Run Background Task"
// 2. Connect execution to "Task" output pin (runs on background thread)
// 3. Connect completion logic to "Game Thread Task" output pin (runs on game thread)

3. Mutex Operations

// Lock a mutex
AsyncTaskManager → Lock("MyMutexName")

// Unlock a mutex  
AsyncTaskManager → Unlock("MyMutexName")

// Scope lock (automatically unlocks when object is destroyed)
ScopedMutex = AsyncTaskManager → Scope Lock()

// Game thread locks (for simple game thread synchronization)
AsyncTaskManager → Game Thread Lock("MyLock")
AsyncTaskManager → Game Thread Unlock("MyLock")
bool IsLocked = AsyncTaskManager → Is Game Thread Locked("MyLock")

4. Raw Thread Creation

// In Blueprint:
// AsyncTaskManager → Start Raw Thread
// - Thread Name: "MyWorkerThread"
// - Target: Object implementing IRawThreadInterface
// - Reference Object: Optional data object
// - Command: String command for the target
// - Options: Array of string parameters
// - Auto Stop Thread: true (automatically cleanup when done)

C++ Usage

1. Implementing Thread Interface

// MyThreadWorker.h
UCLASS()
class MYGAME_API UMyThreadWorker : public UObject, public IRawThreadInterface
{
    GENERATED_BODY()

public:
    // Implement the interface
    virtual void ExecuteThreaded_Implementation(UObject* ReferenceObject, 
        const FString& Command, const TArray<FString>& Options) override;
    
    virtual void OnThreadFinished_Implementation(UObject* ReferenceObject,
        const FString& Command, const TArray<FString>& Params) override;
};

// MyThreadWorker.cpp
void UMyThreadWorker::ExecuteThreaded_Implementation(UObject* ReferenceObject, 
    const FString& Command, const TArray<FString>& Options)
{
    // This runs on background thread
    // Perform heavy computation here
    
    // When done, call OnThreadFinished on game thread
    AsyncTask(ENamedThreads::GameThread, [this, ReferenceObject, Command]()
    {
        TArray<FString> Results = {"Result1", "Result2"};
        OnThreadFinished_Implementation(ReferenceObject, Command, Results);
    });
}

void UMyThreadWorker::OnThreadFinished_Implementation(UObject* ReferenceObject,
    const FString& Command, const TArray<FString>& Params)
{
    // This runs on game thread
    // Update UI, game state, etc.
}

2. Starting Threads from C++

// Get the task manager
AAsyncTaskManager* TaskManager = UAsyncFunctionLibrary::GetAsyncTaskManager();

// Create worker object
UMyThreadWorker* Worker = NewObject<UMyThreadWorker>();

// Start thread
TaskManager->StartRawThread(
    TEXT("MyWorkerThread"),
    Worker,                    // Target object
    nullptr,                   // Reference object (optional)
    TEXT("ProcessData"),       // Command
    {TEXT("Param1"), TEXT("Param2")}, // Options
    true                       // Auto stop
);

3. Mutex Usage in C++

// Get task manager
AAsyncTaskManager* TaskManager = UAsyncFunctionLibrary::GetAsyncTaskManager();

// Lock/unlock manually
TaskManager->Lock(TEXT("MyMutex"));
// ... critical section code ...
TaskManager->Unlock(TEXT("MyMutex"));

// Scope lock (RAII)
UMutexWrapper* ScopedLock = TaskManager->ScopeLock();
// Automatically unlocks when ScopedLock goes out of scope

API Reference

AAsyncTaskManager

Function Description
ExecuteTask(EAsyncTaskBp, UObject*) Execute predefined async task
StartRawThread(...) Create custom background thread
Lock(FString) Lock named mutex
Unlock(FString) Unlock named mutex
ScopeLock() Create RAII scoped mutex
GameThreadLock(FString) Simple game thread lock
GameThreadUnlock(FString) Unlock game thread lock
IsGameThreadLocked(FString) Check if game thread lock is active
SetThreadPriority(int32) Set default thread priority
KillThread(FString) Manually terminate thread

Thread Priorities

Priority Value Description
Any Background Task 0 Low priority background work
Any High Priority Task 1 High priority background work
Any Background Thread 2 Background thread pool
Any High Priority Thread 3 High priority thread pool

Examples

File Processing Example

// Blueprint: Process large file in background
// 1. Get AsyncTaskManager reference
// 2. Call StartRawThread with FileProcessor target
// 3. FileProcessor reads file on background thread
// 4. Results returned via OnThreadFinished callback
// 5. Update UI on game thread

Network Request Example

// C++: Async HTTP request
class UHttpWorker : public UObject, public IRawThreadInterface
{
    virtual void ExecuteThreaded_Implementation(UObject* ReferenceObject, 
        const FString& Command, const TArray<FString>& Options) override
    {
        // Perform HTTP request on background thread
        FString Response = MakeHttpRequest(Options[0]);
        
        // Return to game thread
        AsyncTask(ENamedThreads::GameThread, [this, Response]()
        {
            OnThreadFinished_Implementation(nullptr, TEXT("HttpComplete"), {Response});
        });
    }
};

About

A Multithreading Library for Unreal Engine Blueprints

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors