and one or more buffers where old messages are replaced (using buffer:setmsg()).
Does setmsg replace the latest/newest or the oldest msg in the buffer?
(from the example on GitHub I would say the latest/newest)
buffer and displays a volume meter. Old volume values are not needed in this use
This is really a great example. I would include it in the documentation. This completely justify the concept of "listener" for multiple buffers, because buffers can be fed in different ways by writers. Plus what you mention in your reply: the possibility to abort operations on a specific buffer to interrupt the corresponding worker/writer while others continue undisturbed.
world you have buffer referencing objects. The Blocking/NonBlocking flag is
stored in the buffer referencing object and is evaluated and considered if you
Thank you for confirming. If possible, I would write a guide for dummies (like me) in which you simplify the concept. As an example: instead of "buffer referencing object" one can write "handle" (as for files in C) or "reference".
So the guide for dummies could say: "the 'blocking' flag is associated with the handle, not with the buffer. Handles to the same buffer will have their own flag to modify the behavior of the invoked method".
The functions mtmsg.abort() / buffer:abort() / listener:abort() can be used to
interrupt/cancel operations from other threads. These methods are setting an
Now it's clear, thank you very much.
That raises a question: after I issue an 'abort' operation, is it possible to remove all the messages from the buffer so that the listener/reader will never process them when I resume regular operation by setting abort to false?
referencing this listener behind the scene. So the underlying listener object
can only be destructed if the last buffer is destructed.
Thank you for clarifying. It seems correct given the fact that one cannot have multiple listeners listening to the same buffer, right? I realized this only re-reading the documentation.
I incorrectly assumed that not only a given listener can have multiple buffers, but also a given buffer can have multiple listeners. If that were the case, then one should have the buffer keep a reference to the listener so that the listener can be destructed after all referenced buffers, and one should have the listener keep a reference to the buffers so that a buffer can be destructed only if all attached listener are destructed. The latter is not possible in current implementation, a given buffer can be attached to only one listener, therefore you do not need to have the listener store the reference to the buffer (I little bit convoluted, but I hope my reasoning is clear).
I'm going to rethink the current solution since I now have the impression that
this could be improved (but I'm not sure). Again thank you for your feedback!
I think the existing implementation is good! Keeping things simple is good.
If I look at buffers as if they were queues/lists, I would want some method to put a message in front of the others that may already be present (this could be useful for 'urgent' messages with some higher priority - but one could use independent buffers for that). Also, removing messages already added could be useful.
by intention does not serialize tables. There are several libraries that can
I totally agree. What I meant: this is worth mentioning in the documentation. So that if one asks himself how to send a table, the answer is "serialize it" or just write a constructor in a string and send the string.
incrementally build up a larger message without locking. Then if the message is
Do you mean instead of sending a tuple of arguments, build a tuple one element at a time?
(especially because of the efficiency gain in lock time)
Will it be easy to manage the situation where multiple writers are building a long message in the same buffer, simultaneously?
==== now for mtstates
- mtstates.newstate() always returns a state referencing object to a *new* state
even if there is already a state with the same name. So it's valid to have more
:
- mtstates.singleton() returns a state referencing object to a new state if the
state by this name does not exist and returns a state referencing object to an
existing state if the state by this name does exist.
:
some code in a larger framework or whatsoever where you cannot (or do not want
to) control the setup of everything and your code runs in different threads but
you want to have shared data/state you could use mtstates.singleton() from these
This is really clear. Thank you very much. I hope you can add this to the documentation on GitHub. I think this could really help.
is constructed by the invocation of mtstates.singleton() with the name "foo".
Then within this singleton state mtstates.singleton() is invoked with the name
Let me double check to see if I understand correctly: one can use singleton to be sure to own a reference and be sure the state is not garbage collected.
The thing to avoid is to call singleton twice with the same name from the same thread, right?
But it should be safe to call singleton once from each thread, right?
(I hope I got it right, otherwise I may be missing something important - I am new to Lua and I am not sure I fully grasp what a "state" is, for now I am thinking it is something that holds the global environment... but I am sure there is more - I am sorry if I am missing something important here)
mtstates.interrupt() is easier whereas mtint provides more functionality.
Thank you very much. This could be added to the documentation so that future readers/users (as me) can benefit from this notes.