mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2025-04-28 13:59:48 +00:00
Added a message bus system
This commit is contained in:
parent
50a03e6c9d
commit
548d1eef26
@ -25,6 +25,7 @@ builder.Services.AddMudServices(config =>
|
|||||||
});
|
});
|
||||||
|
|
||||||
builder.Services.AddMudMarkdownServices();
|
builder.Services.AddMudMarkdownServices();
|
||||||
|
builder.Services.AddSingleton(MessageBus.INSTANCE);
|
||||||
builder.Services.AddSingleton<Rust>();
|
builder.Services.AddSingleton<Rust>();
|
||||||
builder.Services.AddMudMarkdownClipboardService<MarkdownClipboardService>();
|
builder.Services.AddMudMarkdownClipboardService<MarkdownClipboardService>();
|
||||||
builder.Services.AddSingleton<SettingsManager>();
|
builder.Services.AddSingleton<SettingsManager>();
|
||||||
|
13
app/MindWork AI Studio/Tools/Event.cs
Normal file
13
app/MindWork AI Studio/Tools/Event.cs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
namespace AIStudio.Tools;
|
||||||
|
|
||||||
|
public enum Event
|
||||||
|
{
|
||||||
|
NONE,
|
||||||
|
|
||||||
|
// Common events:
|
||||||
|
STATE_HAS_CHANGED,
|
||||||
|
|
||||||
|
// Update events:
|
||||||
|
USER_SEARCH_FOR_UPDATE,
|
||||||
|
UPDATE_AVAILABLE,
|
||||||
|
}
|
8
app/MindWork AI Studio/Tools/IMessageBusReceiver.cs
Normal file
8
app/MindWork AI Studio/Tools/IMessageBusReceiver.cs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
using Microsoft.AspNetCore.Components;
|
||||||
|
|
||||||
|
namespace AIStudio.Tools;
|
||||||
|
|
||||||
|
public interface IMessageBusReceiver
|
||||||
|
{
|
||||||
|
public Task ProcessMessage<T>(ComponentBase? sendingComponent, Event triggeredEvent, T? data);
|
||||||
|
}
|
44
app/MindWork AI Studio/Tools/MSGComponentBase.cs
Normal file
44
app/MindWork AI Studio/Tools/MSGComponentBase.cs
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
using Microsoft.AspNetCore.Components;
|
||||||
|
|
||||||
|
namespace AIStudio.Tools;
|
||||||
|
|
||||||
|
public abstract class MSGComponentBase : ComponentBase, IDisposable, IMessageBusReceiver
|
||||||
|
{
|
||||||
|
[Inject]
|
||||||
|
protected MessageBus MessageBus { get; init; } = null!;
|
||||||
|
|
||||||
|
#region Overrides of ComponentBase
|
||||||
|
|
||||||
|
protected override void OnInitialized()
|
||||||
|
{
|
||||||
|
this.MessageBus.RegisterComponent(this);
|
||||||
|
base.OnInitialized();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Implementation of IMessageBusReceiver
|
||||||
|
|
||||||
|
public abstract Task ProcessMessage<T>(ComponentBase? sendingComponent, Event triggeredEvent, T? data);
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Implementation of IDisposable
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
this.MessageBus.Unregister(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
protected async Task SendMessage<T>(Event triggeredEvent, T? data = default)
|
||||||
|
{
|
||||||
|
await this.MessageBus.SendMessage(this, triggeredEvent, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void ApplyFilters(ComponentBase[] components, Event[] events)
|
||||||
|
{
|
||||||
|
this.MessageBus.ApplyFilters(this, components, events);
|
||||||
|
}
|
||||||
|
}
|
66
app/MindWork AI Studio/Tools/MessageBus.cs
Normal file
66
app/MindWork AI Studio/Tools/MessageBus.cs
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
using System.Collections.Concurrent;
|
||||||
|
|
||||||
|
using Microsoft.AspNetCore.Components;
|
||||||
|
|
||||||
|
namespace AIStudio.Tools;
|
||||||
|
|
||||||
|
public sealed class MessageBus
|
||||||
|
{
|
||||||
|
public static readonly MessageBus INSTANCE = new();
|
||||||
|
|
||||||
|
private readonly ConcurrentDictionary<IMessageBusReceiver, ComponentBase[]> componentFilters = new();
|
||||||
|
private readonly ConcurrentDictionary<IMessageBusReceiver, Event[]> componentEvents = new();
|
||||||
|
private readonly ConcurrentQueue<Message> messageQueue = new();
|
||||||
|
private readonly SemaphoreSlim sendingSemaphore = new(1, 1);
|
||||||
|
|
||||||
|
private MessageBus()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ApplyFilters(IMessageBusReceiver receiver, ComponentBase[] components, Event[] events)
|
||||||
|
{
|
||||||
|
this.componentFilters[receiver] = components;
|
||||||
|
this.componentEvents[receiver] = events;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RegisterComponent(IMessageBusReceiver receiver)
|
||||||
|
{
|
||||||
|
this.componentFilters.TryAdd(receiver, []);
|
||||||
|
this.componentEvents.TryAdd(receiver, []);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Unregister(IMessageBusReceiver receiver)
|
||||||
|
{
|
||||||
|
this.componentFilters.TryRemove(receiver, out _);
|
||||||
|
this.componentEvents.TryRemove(receiver, out _);
|
||||||
|
}
|
||||||
|
|
||||||
|
private record class Message(ComponentBase? SendingComponent, Event TriggeredEvent, object? Data);
|
||||||
|
|
||||||
|
public async Task SendMessage<T>(ComponentBase? sendingComponent, Event triggeredEvent, T? data = default)
|
||||||
|
{
|
||||||
|
this.messageQueue.Enqueue(new Message(sendingComponent, triggeredEvent, data));
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await this.sendingSemaphore.WaitAsync();
|
||||||
|
while (this.messageQueue.TryDequeue(out var message))
|
||||||
|
{
|
||||||
|
foreach (var (receiver, componentFilter) in this.componentFilters)
|
||||||
|
{
|
||||||
|
if (componentFilter.Length > 0 && sendingComponent is not null && !componentFilter.Contains(sendingComponent))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var eventFilter = this.componentEvents[receiver];
|
||||||
|
if (eventFilter.Length == 0 || eventFilter.Contains(triggeredEvent))
|
||||||
|
// We don't await the task here because we don't want to block the message bus:
|
||||||
|
_ = receiver.ProcessMessage(message.SendingComponent, message.TriggeredEvent, message.Data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
this.sendingSemaphore.Release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
16
app/MindWork AI Studio/Tools/MessageBusExtensions.cs
Normal file
16
app/MindWork AI Studio/Tools/MessageBusExtensions.cs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
using Microsoft.AspNetCore.Components;
|
||||||
|
|
||||||
|
namespace AIStudio.Tools;
|
||||||
|
|
||||||
|
public static class MessageBusExtensions
|
||||||
|
{
|
||||||
|
public static async Task SendMessage<T>(this ComponentBase component, Event triggeredEvent, T? data = default)
|
||||||
|
{
|
||||||
|
await MessageBus.INSTANCE.SendMessage(component, triggeredEvent, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ApplyFilters(this IMessageBusReceiver component, ComponentBase[] components, Event[] events)
|
||||||
|
{
|
||||||
|
MessageBus.INSTANCE.ApplyFilters(component, components, events);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user