All Projects → viniciusfbb → ipub-messaging

viniciusfbb / ipub-messaging

Licence: MIT license
Messaging system for communication between classes / layers in delphi

Programming Languages

pascal
1382 projects

Projects that are alternatives of or similar to ipub-messaging

FMX.MaterialIconsFont
Material Design Icons 3.0.1
Stars: ✭ 20 (-56.52%)
Mutual labels:  firemonkey, fmx
skia4delphi
Skia4Delphi is a cross-platform 2D graphics API for Delphi platforms based on Google's Skia Graphics Library. It provides a comprehensive 2D API that can be used across mobile, server and desktop models to render images.
Stars: ✭ 486 (+956.52%)
Mutual labels:  firemonkey, fmx
FMXPong
Pong 3D with Delphi and Firemonkey (Windows, Mac OS, Android, IOS)
Stars: ✭ 25 (-45.65%)
Mutual labels:  firemonkey, fmx
OldCEF4Delphi
OldCEF4Delphi is an open source project to embed Chromium-based browsers in applications made with Delphi.
Stars: ✭ 55 (+19.57%)
Mutual labels:  firemonkey, fmx
PUSHTestFCM
[FireMonkey] Push test project
Stars: ✭ 17 (-63.04%)
Mutual labels:  firemonkey, fmx
FMX.FontAwesome
[FireMonkey] FontAwesome
Stars: ✭ 21 (-54.35%)
Mutual labels:  firemonkey, fmx
RADStudio-DemoKit
A collection of demos around 10.4 Sydney updated for 10.4.2.
Stars: ✭ 39 (-15.22%)
Mutual labels:  firemonkey, fmx
TeeGrid-VCL-FMX-Samples
Grid control for Delphi and C++ (VCL and FMX)
Stars: ✭ 132 (+186.96%)
Mutual labels:  firemonkey, fmx
FireMonkeyInstagramApp
Sample Instagram UI design project made with Embarcadero Delphi 10.1 Berlin.
Stars: ✭ 23 (-50%)
Mutual labels:  firemonkey, fmx
GBE3D
Suite de composants 3D pour Delphi Firemonkey
Stars: ✭ 18 (-60.87%)
Mutual labels:  firemonkey, fmx
WebView4Delphi
WebView4Delphi is an open source project created by Salvador Díaz Fau to embed Chromium-based browsers in applications made with Delphi or Lazarus/FPC for Windows.
Stars: ✭ 157 (+241.3%)
Mutual labels:  firemonkey, fmx
Occa
JIT Compilation for Multiple Architectures: C++, OpenMP, CUDA, HIP, OpenCL, Metal
Stars: ✭ 230 (+400%)
Mutual labels:  multithreading
Nebula
Nebula is an open-source and free-to-use modern C++ game engine.
Stars: ✭ 224 (+386.96%)
Mutual labels:  multithreading
tfprof
Profiling Taskflow Programs through Visualization
Stars: ✭ 36 (-21.74%)
Mutual labels:  multithreading
S3sync
Really fast sync tool for S3
Stars: ✭ 224 (+386.96%)
Mutual labels:  multithreading
GroundGrowing
Open Source Unity3d Planetary Terrain Editor Extension with incremental background updates via multithreading
Stars: ✭ 66 (+43.48%)
Mutual labels:  multithreading
Simplenetwork
simple TCP server / client C++ linux socket
Stars: ✭ 225 (+389.13%)
Mutual labels:  multithreading
Java Interview Questions
1000+ Java Interview Questions
Stars: ✭ 212 (+360.87%)
Mutual labels:  multithreading
Px sched
Single Header C++11 Task Scheduler
Stars: ✭ 182 (+295.65%)
Mutual labels:  multithreading
Thread
type safe multi-threading made easier
Stars: ✭ 34 (-26.09%)
Mutual labels:  multithreading

iPub Messaging

Thread safe, asynchronous and simplistic messaging system for communication between classes / layers in delphi created by the iPub team.

The problem

Delphi has its own messaging system (System.Messaging.pas) that works well but is totally synchronous and thread unsafe. In multithreaded systems we always need to communicate with other classes, sometimes synchronously, sometimes asynchronously, sometimes synchronizing with the mainthread (in the case of the UI), and doing this without a message system (communicating directly) makes the code large and complex, prone to many bugs.

The solution

An ideal messaging system would be a thread safe system that would allow a class to subscribe and then unsubscribe to listen to a particular message over this time, and this listener class that will receiving the message is who will inform how the sender will invoke it's method: on the same thread (posting), on the main thread (main), on another thread (async) and on a thread other than main (background). This is the basis of our messaging system, the usage is similar to another existing system, the Delphi Event Bus (DEB).

Advantages over similar (DEB)

  • Performance: faster in all operations (subscribe, unsubscribe, post), in addition to 10x faster initialization
  • Efficiency: consumes half the memory
  • Minor code: lower generated binary and faster compilation

See the comparison in an environment with 1000 objects:

Subscribe Post Unsubscribe
iPub 1.6368 ms 0.1215 ms 1.7666 ms
DEB 9.8832 ms 2.0293 ms 4.0022 ms

Using

Interface message

ILogOutMessage = interface
  ['{CA101646-B801-433D-B31A-ADF7F31AC59E}']
  // here you can put any data
end;

Listening to a message

First, you must subscribe your class to listen to messages, then all public methods that have the [Subscribe] attribute will be subscribed.

TForm1 = class(TForm)
  procedure FormCreate(Sender: TObject);
  procedure FormDestroy(Sender: TObject);
private
  { Private declarations }
public
  { Public declarations }
  [Subscribe(TipMessagingThread.Main)]
  procedure OnLogout(const AMessage: ILogOutMessage);
end;

...

procedure TForm1.FormCreate(Sender: TObject);
begin
  GMessaging.Subscribe(Self);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  GMessaging.Unsubscribe(Self);
end;

procedure TForm1.OnLogout(const AMessage: ILogOutMessage);
begin
  Showmessage('Log out!');
end;

You can also declare the method in protected part, but to do this you need to add {$RTTI EXPLICIT METHODS([vcProtected, vcPublic, vcPublished])} before the class.

Sending a message

var
  LMessage: ILogOutMessage
begin
  LMessage := TLogOutMessage.Create;
  GMessaging.Post(LMessage);

Other message types

In the previous examples we have shown an interface message, but there are altogether 3 type of messages:

Identity Parameter
name (explicit) string
guid of parameter interface (implicit) interface
guid of parameter interface (implicit) + name (explicit) interface

To receive messages with name identity, just declare the name in method attribute:

  [Subscribe('Name', TipMessagingThread.Main)]

To send messages with name identity, just inform it in the Post call:

  GMessaging.Post('Name', LMessage);

Note: The explicit name is case-insensitive.

Thread invoke kind

In [Subscribe] attribute, you can determine how the method receiving a message will be executed:

Kind Description
TipMessagingThread.Posting The default, the subscriber method will be invoked in the same posting thread where Post was called
TipMessagingThread.Main The subscriber method will be invoked in the main thread
TipMessagingThread.Async The subscriber method will be invoked asynchronously in a new anonnymous thread other than the posting thread
TipMessagingThread.Background If the posting thread is the main thread, the subscriber method will be invoked asynchronously in a new anonnymous thread, other than the posting thread. If the posting thread is not the main thread, the subscriber method will be invoked synchronously in the same posting thread

Manually subscribe a method at run time

Although the use of the [Subscribe] attribute to subscribe a method is very practical, it is limited because you have to define the name of the message before compilation, in design time, and sometimes it is really useful to define the name of the messages in runtime. An example, a message for a product that has been changed 'product_105346_changed', that name of that message I can only define at run time, so we added the option to subscribe / unsubscribe a method to listen to a message manually:

  GMessaging.SubscribeMethod<string>('product_105346_changed', Self.OnProductChanged, TipMessagingThread.Posting);
  GMessaging.UnsubscribeMethod<string>('product_105346_changed', Self.OnProductChanged);

These two manual methods are independent of the Subscribe / Unsubscribe methods. You can merge the same class with subscribed methods automatically using the [Subscribe] attribute and calling Subscribe / Unsubscribe, and at the same time in this class having methods that you added manually using SubscribeMethod / UnsubscribeMethod.

Another benefit of manually enrolling methods is that they do not restrict to public methods only (although this problem can be solved using the RTTI EXPLICIT METHODS directive).

Considerations

The idea of the system is just to forward messages, notices, containing or not information, so keep in mind that it is not advisable to place large codes or codes with stops (waitfor) within the subscribed methods to listen to messages, as this would directly affect the performance of the system, even in asynchronous modes.

Another consideration is just a reminder of the correct way to use Delphi's TTask. Never use TTask to execute methods with stops (events, semaphores, ...), it was not made for that, its goal is to perform continuous and simpler tasks, if your task is more complex the correct thing is to use a TThread. We are warning you about this, because our system uses delphi's TTask to increase performance mainly in more complex environments in addition to saving resources, and if you use TTask incorrectly in your codes you can cause your application to freeze when sending a message.

License

The iPub Messaging is licensed under MIT, and the license file is included in this folder.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].