50ButtonsEach / fliclib-linux-dist

114 stars 19 forks source link

Integration into main-loop application #19

Open chhitz opened 8 years ago

chhitz commented 8 years ago

Looking at the (completely undocumented) header files and sample code ones comes to the conclusion that the blocking Client::run() method has to called for the library to function.

I'd like to integrate Flic buttons into an existing main-loop based application. For this a blocking run() method is not ideal as I would need an extra thread to run it.

For this kine of applications, I suggest adding a poll() method to the Client class. A call to poll() would dispatch the ready handlers/callbacks without blocking. I could then call this method in the existing main-loop without an additional thread.

fabianbergmark commented 8 years ago

This might be a good idea. However, I don't see the problem with requiring users to create a separate thread. Are you using this on a very constrained platform?

chhitz commented 8 years ago

I'm looking at this from more of a design side. Using the same main-loop for the whole application makes lock and mutexes unnecessary which simplifies development (and debugging).

Am I assuming right that all the callbacks are executed in the context of the thread that executes run()?

fabianbergmark commented 8 years ago

The run method is simply a loop around a blocking network read to receive events from the daemon. Do you mean you want the poll method to do a non-blocking read, and if a case a event was received dispatch that? Or do you want the read-loop to be run in an internal thread, and poll to dispatch any received events. I think the first alternative might be dangerous as running poll to seldom would cause a buildup. The gain with the second alternative is only the simplicity of a single threaded application. If more people think this is a good idea I will implement it.

Emill commented 8 years ago

Maybe it would be nice if the socket fd was exposed so one could select on it. And then a non-blocking function "handleEvents" or something that can be called if the fd has data.

2016-02-07 14:57 GMT+01:00 Fabian Bergmark notifications@github.com:

The run method is simply a loop around a blocking network read to receive events from the daemon. Do you mean you want the poll method to do a non-blocking read, and if a case a event was received dispatch that? Or do you want the read-loop to be run in an internal thread, and poll to dispatch any received events. I think the first alternative might be dangerous as running poll to seldom would cause a buildup. The gain with the second alternative is only the simplicity of a single threaded application. If more people think this is a good idea I will implement it.

— Reply to this email directly or view it on GitHub https://github.com/50ButtonsEach/fliclib-linux-dist/issues/19#issuecomment-181020249 .

chhitz commented 8 years ago

A third option would be to implement the connection to the daemon also in a non-blocking, asynchronous way (for example using Asio).

fabianbergmark commented 8 years ago

Keep in mind that the solutions have to be compatible with SWIG, so working with sockets directly sounds scary. If the only concern is on which thread the event callbacks are executed, using a single mutex to get the same single-threaded flow isn't to much of a hassle in my opinion, but I do agree that the blocking run function isn't very pretty.

NikolasE commented 8 years ago

I also would like to have a non-blocking function. With this, it would be easier to integrate into other systems that wait for other (e.g. TCP-based) connections.

fabianbergmark commented 8 years ago

But a providing a non-blocking poll function that you could call in a select loop would affect delay if you don't use a very low timeout. I could expose the socket as an integer value but would that be usable from Java/Python?