Giter Site home page Giter Site logo

mihairobertcr / unitaskpubsub Goto Github PK

View Code? Open in Web Editor NEW

This project forked from hadashia/unitaskpubsub

0.0 0.0 0.0 55 KB

UniTask & IUniTaskAsyncEnumerable baseed pub/sub messaging. this is like the UniTask version of UniRx.MessageBroker.

License: MIT License

C# 100.00%

unitaskpubsub's Introduction

UniTaskPubSub

UniTask & IUniTaskAsyncEnumerable based pub/sub messaging. This is like the UniTask version of UniRx.MessageBroker.

Pub/Sub (Publish/Subscribe) pattern

In the Pub/Sub messaging model, the sender who creates and sends a message is called the publisher. The party receiving the message is called the subscriber.

  • Makes the sender and receiver loosely coupled, rather than the object directly calling the method.
  • It is possible to create multiple processes for a single message. In other words, the number of subscribers to a publisher is 1:N.

UniTask

UniTask is a library that brings fast and powerful async/await to the Unity world.

UniTaskPubSub uses UniTask and allows async/await for processing pub/sub messages.

Pub/Sub & Game archtecture

In game development, one event in the game often affects many factors and many objects. This is one of the reasons why game development is so complex. It is useful to make the sender and receiver loosely coupled by a Pub/sub messaging system.

Installation

Requirements

Install via UPM (using Git URL)

  1. Navigate to your project's Packages folder and open the manifest.json file.
  2. Add this line below the "dependencies": { line
    • "jp.hadashikick.unitaskpubsub": "https://github.com/hadashiA/UniTaskPubSub.git?path=Assets/UniTaskPubSub#0.10.0",
  3. UPM should now install the package.

Install manually (using .unitypackage)

  1. Download the .unitypackage from releases page.
  2. Open UniTaskPubSub.x.x.x.unitypackage

Usage

UniTask based pub/sub

struct FooMessage
{
    public int Id;
}
var messageBus = new AsyncMessageBus();

// Subscriber

messageBus.Subscribe<FooMessage>(async msg =>
{
    await DoSomething1Async(msg.Id);
});

messageBus.Subscribe<FooMessage>(async msg =>
{
    await DoSomething2Async(msg.Id);
});


// Publisher

// Await for all subscribers.
await messageBus.PublishAsync(new FooMessage { Id = 1 });

// After PublishAsync awaited, DoSomething1Async and DoSomething2Async have been completed.

You can also use AsyncMessageBus.Default instance, instead of new AsyncMessageBus().

Fire & forget

When using Publish(), do not wait for Subscriber.

messageBus.Publish(new FooMessage { Id = 1 });

CancellationToken

PublishAsync and Publish can be passed a cancellationToken. This can be used to cancel the process registered in the Subscriber.

messageBus.Subscribe<FooMessage>(async (msg, cancellationToken) =>
{
    // ...
    cancellationToken.ThrowIfCancellationRequested();
    // ...
});

await messageBus.PublishAsync(new FooMessage(), cancellationToken);

Subscription

Subscribe returns IDisposable. Disposing of this will unsubscribe.

var subscription = messageBus.Subscribe<FooMessage>(...);
subscription.Dispose();

The AddTo extension to UniTask is useful.

messageBus.Subscribe<FooMessage>(...)
    .AddTo(cancellationToken);

Filter

AsyncMessageBus can insert any preprocessing or postprocessing into publish. This feature is called a filter.

Filters can be used to do the following in one step

  • Insert logging.
  • Ignore certain messages
  • etc..

Examples:

// Add filter type
class LoggingFilter : IAsyncPublishFilter
{
    public async UniTask PublishFilterAsync<T>(
        T msg,
        CancellationToken cancellation,
        Func<T, CancellationToken, UniTask> next)
    {
        UnityEngine.Debug.Log($"Publish {msg.GetType()}");
        await next(msg, cancellation); // Processing all subscribers.
        UnityEngine.Debug.Log($"Invoked {msg.GetType()}");
    }
}

class IgnoreFilter : IAsyncPublishFilter
{
    public async UniTask PublishFilterAsync<T>(
        T msg,
        CancellationToken cancellation,
        Func<T, CancellationToken, UniTask> next)
    {
        if (msg is FooMessage foo)
        {
            if (msg.SomeCondition) 
            {
                UnityEngine.Debug.LogWarning($"Ignore {msg}")
                return;
            }
        }
        await next(msg, cancellation); // Processing all subscribers.
    }
}
// Create filter inserted MessageBus
var messageBus = new AsyncMessageBus(new IAsyncPublishFilter[]
{
    new LoggingFilter(),
    new IgnoreFilter(),
});

IUniTaskAsyncEnumerable based pub/sub

Required UniTask.Linq

AsyncEnumerableMessageBus can subscribe to a message as an async stream.

AsyncEnumerableMessageBus.Receive<TMessage> returns IUniTaskAsyncEnumerable. You can take full advantage of LINQ operations and Subscribe functions for IUniTaskAsyncEnumerable.

struct FooMessage
{
    public int Id;
}
using UniTaskPubSub;

var messageBus = new AsyncEnumerableMessageBus();

messageBus.Receive<FooMessage>()
    .Where(msg => msg.Id > 1)
    .Take(2)
    .Subscribe(async foo => 
    {
        await LoadAsync(foo.Id);
        await ...
        await ...        
    });
    
//     
    
messageBus.Publish(new FooMessage { Id = 1 });
messageBus.Publish(new FooMessage { Id = 2 });
messageBus.Publish(new FooMessage { Id = 3 });

You can also use AsyncEnumerableMessageBus.Default instance, instead of new AsyncEnumerableMessageBus().

In Unity 2020.2+ + C# 8, you can also use await foreach.

await foreach (var foo in messageBus.Receive<FooMessage>())
{
    // Do something
}

Author

@hadashiA

License

MIT

unitaskpubsub's People

Contributors

hadashia avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.