Giter Club home page Giter Club logo

delphi-event-bus's People

Contributors

chomps1 avatar edwinyzh avatar jypdwhite avatar kevind7 avatar spinettaro avatar swiftexpat avatar viniciusfbb avatar wxinix avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

delphi-event-bus's Issues

Crashes galore on theme change

My app uses DEB heavily, pulling data from multiple industrial devices and posting to channels for events to operate on the data. This includes the app's main form, which displays an overview of the devices so it's processing dozens of posted events per second, and other forms that may be displayed at the same time with different views of the data.. If the user changes the program's theme, subsequent Posts to any form with registered events all throw an exception - I assume this is because of the underlying window re-creation during the theme change breaks something DEB depends on.

It would seem that a global Active property for the event engine, that suspended all events when False (i.e. Posts would be swallowed and discarded rather than processed) may work around this sort of situation, and would be a great addition. As of now, individually unregister/re-registering each form/frame that's handling events around the theme change is a huge effort, and forcing the user to not see their theme change request until the app is re-started is pretty unfriendly.

Or if you have a better suggestion, I'd love to hear it. Thanks!

Steve

The project's headed to the wrong direction, unfortunately...

I've been using DEB for many years and I LOVE it!

However, I must say, after the way of defining an event changed from TObject to interface, it's no longer as handy as before.
With the old TObject-based events, it's very easier to define an event - just define a class.
But with the latest version, for every single event/message, you have to define both:

  • the interface
  • and the implementation class for that interface.
    And this is only a message!

So I have been sticking to the old TObject-based events and I'm more than happy with it ;)

[Bug] Memory leaks in the TEventBus.Post() method.

The cloned LEvent local variable is not freed.

My partial (read only handling the freeing when in main-thread mode):

      for LSubscription in LSubscriptions do
      begin
        LEvent := CloneEvent(AEvent);
        PostToSubscription(LSubscription, LEvent, LIsMainThread);

        // edwin: fix memory leaks
        if AEventOwner and (LSubscription.SubscriberMethod.ThreadMode in [Posting, Main]) then
          LEvent.Free;
        // edwin end.
      end;

But my code doesn't free the LEvent var when in async mode...

DEB on Android

Firemonkey project is working well on Windows platform but will fail on Android.

Is there any chance for getting support of mobile platforms by DEB?

REQUEST: Set Context on registration

A useful feature will be to allow the Context to be defined on registration (RegisterSubscriberForEvents and RegisterSubscriberForChannels) if set and override the attribute especially when using MDI forms that get events for specific MDI form.

Remove dependency on DUnitX.Utils

Thats a rather large sand obscure dependency for the little bit of code you rely on. Can you maybe implement the required yourself and move away from needing DUnitX altogether?

Any plan to support XE4?

Thread-safe event broadcasting - this is a great concept, I don't know how do you achieve that without using Windows handle ( I assume you don't, since it supports FMX).

Most important - do you have a plan to support XE4?

TList inside posted event objects empties on Delphi 11 Alexandria

if posted event object contains a TList, that TList arrive empty to subscribers.

I make a simple application to demostrate that
TestDEBIssue.zip

Place a breakpoint on frmMain, on line 62
Evalueting AEvent.List result this

On Delphi 10.4 Sydney
(((('test', False, 20), nil, nil, nil), 1, $850538, $32F9310, nil, nil), Pointer($863C4C) as {System.Generics.Defaults}IComparer<frmMain.TTestObject>, (nil,nil), 1)

On Delphi 11.0 Alexandria
((nil, nil, nil, nil), 1, $7C4004, $30E4AA0, nil, nil, Pointer($7D7D58) as {System.Generics.Defaults}IComparer<frmMain.TTestObject>, (nil,nil))

As you can see, on Alexandria the TList part arrive filled with nils

Error Undeclared TEventBusFactory

Hi Guys,

I try use but error [dcc32 Error] EventBus.pas(272): E2003 Undeclared identifier: 'TEventBusFactory'

Show in unit Eventub

function GlobalEventBus: IEventBus;
begin
Result := TEventBusFactory.GlobalEventBus;
end;

The error is on my project because i do a pompile from your samples and no show errors

About thread mode

Can you provide a ThreadMode:
The subscriber method will be invoked in the thread the RegisterSubscriberForEvent be called.
or
Alternatively, when calling RegisterSubscriberForEvent, we can specify the thread the subscriber method will be invoked

Create Groups of Observers

Hi,
at the moment, the Event Bus creates a global (default) event bus to manage the the communication. This means that every time a message is being post, all the subscribers receive it and react on it.

May I suggest to create something like groups of subscribers?

They can be registered like this:
TEventBus.GetDefault.RegisterSubscriber('Group 1', self);

and send messages like this:
TEventBus.GetDefault.post('Group 1', LEvent);

An observer can be, also, subscribed like this:
[Subscribe ('Group 1')]
procedure OnEvent(AEvent: TAnyTypeOfEvent);
begin
// manage the event
end;

Before I try to do it myself, I wanted to check with you if this is something that you would be interested in bringing into your project.

Thanks

This doesn't seem to be fixed, even with the latest commit as of Aug 18, 2020. When TEventMM = mmManual or mmManualAndFreeMainEvent, LEvent is NEVER properly free-ed, and will result in memory leak!

This doesn't seem to be fixed, even with the latest commit as of Aug 18, 2020. When TEventMM = mmManual or mmManualAndFreeMainEvent, LEvent is NEVER properly free-ed, and will result in memory leak!

The test cases do not cover mmManual and mmManualAndFreeMainEvent

Originally posted by @wxinix in #10 (comment)

Threading issues with asynchronous messaging to inactive subscription

There are threading issues in asynchronous messaging with inactive subscription.

Namely code in Post methods checks whether subscription is active before invoking subscription method

TEventBus.Post

for LSubscription in LSubscriptions do begin
  if (LSubscription.Context <> AChannel) or (not LSubscription.Active) then Continue;
  PostToChannel(LSubscription, AMessage, LIsMainThread);

for LSubscription in LSubscriptions do begin
  if not LSubscription.Active then Continue;
  PostToSubscription(LSubscription, AEvent, LIsMainThread);

But, depending on threading mode PostToChannel and PostToSubscription methods can invoke subscription method asynchronously with TThread.Queue or TTask.Run or TThread.CreateAnonymousThread

During that time subscription can get inactive and that can cause crashes by calling subscription method on dead object.

[Question] MVVM and DEB

Hi,
I hope this is the right place to ask a question. Feel free to remove this false "issue".
I used the deb protocol some years ago in java with a small "single" page application. I think it is an elegant solution to an hard architectural problem.
I built an MVVM structure in Delphi with your deb pattern library.
How would you solve this (the problem is simplified):
Assumption: One ViewModel (called vmA) with three Views and One ViewModel (called vmB) with 2 views.
The [Subscribe(...)] is positioned in a "master view" class of the framework and the five views inherits from it.
The master view subscribe to "viewmodel.topic" an avent called "OnViewModelCalling".
The ViewModels calls the post() to the "viewmodel.topic".
How can I be notified who is the "Sender" ViewModel of the event? I mean vmA or vmB?
Do I add these infos in the event object or are there any other solutions?

One solutions without object sender I am thinking:
One "topic" per "sender" (viewmodel.topic.vmA and viewmodel.topic.vmB). But I have to move the [Subscribe(...)] to children and the responsibility of MVVM comunication system is passed to the concrete class. I don't like this.

Thanks
Eddy

Some questions

I started testing the DEB code and I have a few doubts:

  1. In the examples (e.g. weather station) in the event handling methods, event objects are not released, there is a continuous memory leakage.

  2. Why aren't cloned event objects released by the event bus? The bus could do this when the event handling method is returned.

  3. I don't know why there are two identical methods:

function TEventBus.GenerateThreadProc(ASubscription: TSubscription;
  AEvent: TObject): TThreadProcedure;
start
  Result := procedure
    start
      if ASubscription.Active then
      start
        ASubscription.SubscriberMethod.Method.Invoke(ASubscription.Subscriber,
          [AEvent]);
      end;
    end;
end;

function TEventBus.GenerateTProc(ASubscription: TSubscription;
  AEvent: TObject): TProc;
start
  Result := procedure
    start
      if ASubscription.Active then
      start
        ASubscription.SubscriberMethod.Method.Invoke(ASubscription.Subscriber,
          [AEvent]);
      end;
    end;
end;

A little bug in Unregister ?

I believe there is a small bug in the Unregister mechanism:
if it takes a Unregister, all those who have made a subscription for that class of events are removed.

I think the problem is the 290-292 lines of the unit EventBus.pas, where instead of:

 if (LSubscription.Subscriber.Equals (ASubscriber)) then
    LSubscription.Active: = false;
 LSubscriptions.Delete (I);

put it:

 if (LSubscription.Subscriber.Equals (ASubscriber)) then
 begin
   LSubscription.Active: = false;
   LSubscriptions.Delete (I);
 end;

But it is better if you look at the code...

Congratulations for the good work.

Memory leak

TEventBus.Post makes a clone of the event, and this clone is never freed. This causes a build up of event objects in memory.

Help with memory leak reporting

Add the following to EventBus.pas which will decrement the interface counter on finalization (if set) and release allocated memory. This specifically helps in situations where your using a memory manager which reports memory leaks on shutdown.

finalization
  FGlobalEventBus := nil;
end.

lock in eventbus class is a class var

Given the possibility to create multiple event bus instances and the non existence of any other class vars I think the lock should be instance wise and not the same lock for possibly multiple instances.

Cloned Event leaks

Hi,

the cloned event in Post is not freed. I have corrected that.

How do I push on github?

infinite loop in TRTTIUtils.Clone

Hello Daniele,

So I've just started integrating delphi-event-bus into my program.
The first issue I'm experiencing is that, TEventBus.Post will be in a dead-loop in line 162, which calls TRTTIUtils.Clone, which in turn loop infinitely in line 827:

if Field.GetValue(cloned).IsEmpty then
        begin
          targetObject := TRTTIUtils.Clone(sourceObject); // infinite loop here...

I guess it must has something to do with my event definition:

  // Base event about a TWoDoc
  TBaseDocEvent = class(TBaseAppEvent)
  private
    FDoc: TWoDoc;
  public
    property Doc: TWoDoc read FDoc write FDoc;
  end;

Where TWoDoc has properties like

   property ParentDoc: TWoDoc read FDoc write FDoc;
   property NextSibling: TWoDoc read FDoc write FDoc;
   // and so on...

I wish you can shed some light on the issue, thanks.

user defined type for TSubscriberMethod

It would be very usefull if Context type in TSubscriberMethod can be defined by developer , something like this

//EventBus.Develoer //new unit
const
TSubscriberContextDefault = ''; //could change to TSubscriberContextDefault = 0
type
TSubscriberContextType = string; //could change to TSubscriberContextType = integer; or even flat to carry two part

//EventBus.Subscribers unit
type
TSubscriberMethod = class(TObject)
private
FEventType: TClass;
FThreadMode: TThreadMode;
FMethod: TRttiMethod;
FContext: TSubscriberContextType;
...

it needed to change some lines in other units

my (and some friends) implementation of events is based on integer and a long list of integer constants and methods that could use this perfect event bus implementation

thank you.

Deadlock when posting events synchronized in background

Dear Danielle.
I try to process as much as possible in background. The event bus is perfect for simplifying my code. I'm using some additional libraries for some reason, and I get synchronized (Delphi-) events from those libraries. I would like to post some of the processing into background, but unfortunately the eventbus post gets into deadlock. I prepared a simplified test for reproduction. As a workaround I removed the critical section from your code in post routine, because I can't see any disadvantage. But maybe you can explain, what you wanted to avoid by using the critical section in the post routine?!
EventBusTest.zip
Kind regards,
Detlef Schweng.

'Access violation' in TDuckTypedList.CanBeWrappedAsList (line 169)

Hi,

Do you have any idea why the following error might happen? It seems happens when duplicating the event object. Currently I workaround it using the TObjectClone class (shown at the end), but I really want my copy of delphi-event-bus to be fully in sync with the official repository, otherwise it's really a pain when committing changes.

error details:

compiled with      : Delphi XE4
madExcept version  : 4.0.19
callstack crc      : $e81d85aa, $52a6acdb, $8ac0e71b
exception number   : 1
exception class    : EAccessViolation
exception message  : Access violation at address 00C6882F in module 'Program1.exe'. Read of address 00000000.

main thread ($3850):
00c6882f +02b Program1.exe DuckListU         169  +1 TDuckTypedList.CanBeWrappedAsList
00d4ba7c +220 Program1.exe RTTIUtilsU        589 +31 TRTTIUtils.CopyObject
00d4c39f +377 Program1.exe RTTIUtilsU        833 +59 TRTTIUtils.Clone
00d4c351 +329 Program1.exe RTTIUtilsU        827 +53 TRTTIUtils.Clone
00e5b203 +00f Program1.exe EventBus           89  +8 TEventBus.CloneEvent
00e5bc8a +0e6 Program1.exe EventBus          204 +20 TEventBus.Post
0102510f +067 Program1.exe WorkSpaceForm     757  +3 TfrmWorkSpace.TryOpenMostRencelyProject$237291$ActRec.$1$Body
00929d3a +08e Program1.exe OtlTaskControl   4220  +7 TOmniMessageExec.OnMessage
00926969 +1c1 Program1.exe OtlTaskControl   3170 +18 TOmniTaskControl.ForwardTaskMessage
0040fc8a +012 Program1.exe System          34138 +12 @IntfCast
00929707 +03b Program1.exe OtlTaskControl   4114  +1 TOmniTaskControlEventMonitor.ForwardTaskMessage
0092b837 +07f Program1.exe OtlEventMonitor   330  +6 ProcessMessages
0092ba49 +0a1 Program1.exe OtlEventMonitor   363  +7 TOmniEventMonitor.WndProc
007f562f +07f Program1.exe DSiWin32         6175 +15 DSiClassWndProc
762e7885 +00a USER32.dll                                   DispatchMessageW
006a2143 +0f3 Program1.exe Vcl.Forms       10288 +23 TApplication.ProcessMessage
006a2186 +00a Program1.exe Vcl.Forms       10318  +1 TApplication.HandleMessage
006a24c1 +0c9 Program1.exe Vcl.Forms       10456 +26 TApplication.Run
010df31a +0f2 Program1.exe Program1    150 +44 initialization
76cc343b +010 kernel32.dll                                 BaseThreadInitThunk

My workaround (I got TObjectClone from the Internet but forgot the source :p):

class function TObjectClone.From<T>(Source: T): T;
var
  Context: TRttiContext;
  IsComponent, LookOutForNameProp: Boolean;
  RttiType: TRttiType;
  Method: TRttiMethod;
  MinVisibility: TMemberVisibility;
  Params: TArray<TRttiParameter>;
  Prop: TRttiProperty;
  SourceAsPointer, ResultAsPointer: Pointer;
begin
  RttiType := Context.GetType(Source.ClassType);
  //find a suitable constructor, though treat components specially
  IsComponent := (Source is TComponent);
  for Method in RttiType.GetMethods do
    if Method.IsConstructor then
    begin
      Params := Method.GetParameters;
      if Params = nil then Break;
      if (Length(Params) = 1) and IsComponent and
         (Params[0].ParamType is TRttiInstanceType) and
         SameText(Method.Name, 'Create') then Break;
    end;
  if Params = nil then
    Result := Method.Invoke(Source.ClassType, []).AsType<T>
  else
    Result := Method.Invoke(Source.ClassType, [TComponent(Source).Owner]).AsType<T>;
  try
    //many VCL control properties require the Parent property to be set first
    if Source is TControl then TControl(Result).Parent := TControl(Source).Parent;
    //loop through the props, copying values across for ones that are read/write
    Move(Source, SourceAsPointer, SizeOf(Pointer));
    Move(Result, ResultAsPointer, SizeOf(Pointer));
    LookOutForNameProp := IsComponent and (TComponent(Source).Owner <> nil);
    if IsComponent then
      MinVisibility := mvPublished //an alternative is to build an exception list
    else
      MinVisibility := mvPublic;
    for Prop in RttiType.GetProperties do
      if (Prop.Visibility >= MinVisibility) and Prop.IsReadable and Prop.IsWritable then
        if LookOutForNameProp and (Prop.Name = 'Name') and
          (Prop.PropertyType is TRttiStringType) then
          LookOutForNameProp := False
        else
          Prop.SetValue(ResultAsPointer, Prop.GetValue(SourceAsPointer));
  except
    Result.Free;
    raise;
  end;
end;

Can not Post the class

Can not Post the following class:

TOnNotifyDocEvent = class
private
FData: TDictionary<string, TValue>;
public
constructor Create;
destructor Destroy;override;
property Data: TDictionary<string, TValue> read FData;
end;

constructor TOnInfoNotifyDocDataLoadCompleteEvent.Create;
begin
FData:= TDictionary<string, TValue>.Create;
end;

[idea] Tiny.Rtti is 500+ faster than the system RTTI

Hello,

I recently discovered Tiny.RTTI, according to its just-commited benchmark demo program, as shown on the repository's github page, it's 500+ faster than System.Rtti! I tried to recreate the

I've no idea why it's that faster, maybe people as knowledgeable as @sglienke can tell us something :)

And since DEB invokes the subscribing methods using System.Rtti, so it might be a candidate for improving the performance.

Exception error while using Spring4D Dependency injection and multiple UnRegister.

Hi,

I'm using Delphi Tokyo, latest version. I'm using Spring4D container and declaring an IEventBus (not using the built in singleton) as a singleton.

In one part of my code I call twice the method to UnRegister the current object.

E.g.

if not Assigned(fEventBus) then Exit; // shouldnt be needed but, hey just in case

If fEventBus.IsRegistered(Self) then
fEventBus.UnRegister(Self);

Calling this twice will cause an exception. The exception happens while attempting to Acquire the critical section via FCS. It seems that the finalization section was already called and the FCS critical section is now nil, causing the issue.

In general Finalization sections mixed with Dependency containers will cause trouble. I will suggest an implementation that completely skips the use of that methodology if the developer is not using the built in singleton.

Thank you for your great work with this, it is extremely useful. It will be great if you wrap it into a component so its easier to share and it can be exposed via Delphinus or GetIt.

UPDATE:
I did a quick test changing the Critical sections with a TMonitor (new versions are faster than TCriticalSections due to use of Spinlocks) and it did the trick. Another option could be to put the critical section inside of the object and only use the global one when creating the GetDefault singleton.

Background / Async tasks deadlock

Deb uses TTaskRun, which submits to a shared threadpool. When multiple events are fired quickly, the app deadlocks and does not recover. I have fixed this by creating a threadpool for DEB and modifying the run to use that threadpool.
Before:
TTask.Run(LProc);
After:
TTask.Run(LProc, FDebThreadPool);

Pull request for fix is: #74
If anyone has an example of using TThreadPoolStats to check the health of that thread pool before the task runs it would be great to see to ensure the pool is healthy enough not to deadlock later.

Request/Reply pattern

The Delphi-Event-Bus library works great for pub/sub pattern. Is that possible to use the library for request/reply pattern?

Minor improvement of subscriber registration

Please add the parameter ARaiseExcIfEmpty : Boolean to the RegisterSubscriber() method to pass it on to the FindSubscriberMethods() method.
At the moment, in the RegisterSubscriber() method, when calling the FindSubscriberMethods() method, this parameter is hardcoded to True, it should not be so, see:

procedure TEventBus.RegisterSubscriber<T>(ASubscriber: TObject); <== please add ARaiseExcIfEmpty param
var
  LSubscriberClass: TClass;
  LSubscriberMethods: TArray<TSubscriberMethod>;
  LSubscriberMethod: TSubscriberMethod;
begin
  FMultiReadExclWriteSync.BeginWrite;

  try
    LSubscriberClass := ASubscriber.ClassType;
    LSubscriberMethods := TSubscribersFinder.FindSubscriberMethods<T>(LSubscriberClass, True); <==== HARDCODED
    for LSubscriberMethod in LSubscriberMethods do Subscribe<T>(ASubscriber, LSubscriberMethod);
  finally
    FMultiReadExclWriteSync.EndWrite;
  end;
end;

I have a problem with this because I have a base class that supports caching and I want to call RegisterSubscriberForEvents() in this base class (not to do this in many inherited classes). But because not every descendant cache class uses events, I get an EObjectHasNoSubscriberMethods exception in runtime.

And of course a change is necessary in these two methods

procedure TEventBus.RegisterSubscriberForChannels(ASubscriber: TObject); <== ARaiseExcIfEmpty param
begin
  RegisterSubscriber<ChannelAttribute>(ASubscriber);
end;

procedure TEventBus.RegisterSubscriberForEvents(ASubscriber: TObject); <== ARaiseExcIfEmpty param
begin
  RegisterSubscriber<SubscribeAttribute>(ASubscriber);
end;

Question: Explanation/Examples for TThreadMode Subscriptions

Hi Folks,

I'm just starting to use delphi-event-bus and I'd like to have some more information on the subscription types, like typical use cases and when to use which subscription method.
I assume, but I'm not 100% sure:

  • TThreadMode.Posting is the default when no type is given in the subscribe attribute
  • TThreadMode.Main should be used, when the consumed event results in an ui update
  • If an event is produced and consumed in the UI, Posting is equvalent to Main

What about the others?

Error invoking subscriber method. Subscriber class: <something> . Original exception: EInvalidCast: Invalid class typecast

Hi,
I use a MQTTClient and onReceive I post a event for a lot of subscriber on my code.

procedure TDMMain.riempiDatiMqtt(ADevice, APayLoad : string);
var
  LEvent: IMQTTReceiveEvent;
begin
  try
      LEvent := GetMQTTReceiveEvent;
      LEvent.SN := ADevice;
      LEvent.Payload := APayLoad;
      ToCodeSite('LEvent',LEvent.SN + ' ' + LEvent.Payload);
      try
        GlobalEventBus.Post(LEvent);
      except
        on e : exception do
        begin
          ToCodeSite('GlobalEventBus.Post(LEvent) except: ', e.Message);
        end;
      end;
  except
    on e: Exception do
    begin
      ToCodeSite('RiempiDatiMqtt except: ', e.Message);
    end;
  end;
end;

Rarely, the GlobalEventBus.Post method raises a typecast error like subject with different type of Subscriber class. like TAniindicator, TStyledEdit, TEdit, and more.

Can you help me?

RAD Studio 12 shows a deprecation warning for DisposeOf

[dcc32 Warnung] EventBus.Helpers.pas(215): W1000 Symbol 'DisposeOf' ist veraltet: 'Use Free instead'

class destructor TInterfaceHelper.Destroy;
begin
  FInterfaceTypes.DisposeOf;
end;

Any good reason why DisposeOf should still be used?

[Question]

Hello,
There four event-handler invocation mode:
TThreadMode = (Posting, Main, Async, Background);

I use only the default (Posting) mode and Main mode (ensure the code to be run in the UI thread if it needs to access any UI controls).

But I don't quite understand the rest of the modes, care to explain a little :)

[Suggestion] - Return value from posting an event to the same thread

Is it reasonable to make the TEventBus.Post method be able to return a value (can be any type of value, a TObject or TValue? not sure)?

The idea is like the `SendMessage' winapi.

It's very necessary, in case we use an event to represent an action (a concept borrowed from Redux action.

That being said, I want to achieve an application architecture, where:

  • the modification of the model is centralized in a single module (which will subscribe events from other modules - including, but not limited to the UI),

  • and the other modules will not modify the model directly, but only post through the EventBus "action events" to describe what they desire the model to change.

And it must come in handy if the event posting would be able to return values when posting to the same thread.

Not sure if I have described it clearly, but I mainly have inspired by Redux Framework.

I hope this makes sense.

And this stackoverflow question might help understanding my suggestion: React.js - flux vs global event bus

Hang on splash screen

Hi,
I created a new app, included EventBus and then ran it on an Android device and it started regularly.
Right after I added System.Messaging, I run and 8 times out of 10 it doesn't start and stays on the splash screen.
BR

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.