i m using cocos2d-x V3.4 and i still cannot find a good example on how to use multi threading. i m using pthread as worker thread to do some background processing. from within the pthread,i trigger some custom events (Director::getInstance()->getEventDispatcher()->dispatchEvent(&evt);) to update the UI.things are working fine as long as the triggered events do not add any graphic to the UI (addChild). moving sprites around doesnt look to have any issue. but once the pthread fires an event (EventCustom) that needs to add a ui node (DrawNode in my case), i get a black screen. from what i could find on the web, the pthread is not supposed to fire those events. he just need to fill up a queue of events and schedule pulling those events from the UIThread to render. What i did was having an std::vector as member of a singleton class GameManager. my pthread pushes to that list. and i scheduled a pulling from that list. but my app keep crashing. So i m pretty sure that what i m doing is not the right way.
UI related stuff must be performed on cocos thread otherwise it may lead to undefined behaviour as per my experience.
You can try following steps:
Create a function that will perform required UI related stuff on a particular event
Call the method from your pthread to be performed on cocos thread as follows:
auto scheduler = Director::getInstance()->getScheduler();
scheduler-> performFunctionInCocosThread(CC_CALLBACK_0(YourClass::updateUI, this));
Here updateUI function which is defined in YourClass will be responsible to perform UI related operations.
Related
In one of my projects in GTK3, I am using custom events for communication between threads. One thread is the main OS thread on which the event loop is running. The other one is a non main thread that is doing some internal application specific initialization. The condition is that the first GTK window shall be created, only after the application is initialized. However, I don’t want to delay the main thread entering the event loop for some design related reasons.
Therefore, the main thread enters the event loop as soon as GTK is initialized and the non main thread needs to intimate the main thread when first window can be created. For this intimations I am using custom events in GTK3 (it can be created although I am not sure it is recommended or not).
The code snippet for the non main thread creating custom event is as below -
GdkEvent * createwinevent;
// Create and post custom event to start GTK Window creation
createwinevent = gdk_event_new ((GdkEventType) CREATE_WINDOW);
// CREATE_WINDOW is an enum defined by the application
gdk_event_put (createwinevent);
In the main thread, I am using g_idle_timeout to check the event queue intermittently and handle the custom events.
In GTK4 however, GdkEvents have been made read-only. Can custom events still be created in GTK4 somehow? If not, is there any other mechanism I can use in GTK4 to pass message between threads?
Reading through GTK4 materials could not find anything to support custom events.
Reading from the Migrating from Gtk 3.x to GTK4 (Section Adapt to GdkEvent API changes):
Direct access to GdkEvent structs is no longer possible in GTK 4.
GdkEvent is now a strictly read-only type, and you can no longer
change any of its fields, or construct new events. All event fields
have accessors that you will have to use.
So it think what you are doing is no longer possible in GTK4.
During debugging, I want to see what's awaits my program's event loop.
It's probably flooded, and I want to see by what signals, without (manually) adding specific log-message to every Q_EMIT.
Possible solutions might be watching some internal-qt-data structure that contains the events-queue (Is there such thing? how?)
Or -
Write a log message for every signal emitted (Is that possible?).
Any other ideas?
(QT 4.8 on Windows, using visual studio 2012)
Signals and events are two things that don't have anything to do with each other.
I want to see what's awaits my program's event loop. It's probably flooded.
First of all, let's get the nomenclature straight:
an event queue is where events are stored until delivery;
an event loop is what drains the event queue and delivers events to QObjects,
an event flood happens when, on average, during the delivery of each event there is more than one event added to the queue.
There are two reasons only why an event queue might get flooded:
It takes too long to process some events (e.g. when your code blocks): the drain rate of the queue is lower than the fill rate due to timing.
You're adding more than one event per each event delivered (on average): the fill rate of the queue is higher than the drain rate due to event multiplication - this is completely unrelated to any timing. An apt name for it would be an event storm.
To detect code the blocks for too long, you can use a tool I wrote for another answer.
To know how many events are waiting for any given thread, use the undocumented qGlobalPostedEventsCount(). You add that to the code of the tool linked-to above.
Not sure if this is sufficient for you but you can try installing event filters in between QObjects that implement eventFilter() like this:
class MyWidget : public QWidget
{
QGraphicsView myView;
MyWidget()
{
myView->installEventFilter(this);
// incoming events to myView are shown on the standard output
}
};
You can get more creative with this reading the docs.
The Qt documentation for Events and Filters states:
It is also possible to filter all events for the entire application, by installing an event filter on the QApplication or QCoreApplication object. Such global event filters are called before the object-specific filters. This is very powerful, but it also slows down event delivery of every single event in the entire application.
Therefore, you can create an event filter on the QApplication or QCoreApplication and monitor all events, checking their type.
Alternatively, QCoreApplication uses the virtual notify function to deliver events to objects. Overriding QCoreApplication would allow you to see both the event and QObject to which the event will initially* be delivered.
*Note that events are propagated to parent objects, if the receiving object ignores the event.
If you choose to use notify, be aware of the future direction for this function:
Future direction: This function will not be called for objects that live outside the main thread in Qt 6. Applications that need that functionality should find other solutions for their event inspection needs in the meantime. The change may be extended to the main thread, causing this function to be deprecated.
I have a CListCtrl in my MFC application. The list needs to be updated when I get some notification from the server. Updating list works quite good when there are less notification as operations on the list are less. But in case of heavy load, list control and in turn the application gets freeze.
I am aware of updating UI items in the separate thread in case of bulk updates, but in this case I have the notifications that can come in any order and in any volume, I need to handle in such way that my main thread is not getting blocked.
If anyone faced the issue before please suggest the approach for this case.
You could put all the updates into a queue. Then do a limited number of updates from the queue to the control in the OnIdle function. OnIdle is called when your GUI message queue is empty. It could do up to, say, 20 updates and then return. The main thread would than process any GUI input and when finished with that it would call OnIdle again. In this way you delay and spread out the updates while keeping the GUI alive.
I had a similar situation and resolved it using a Timer. Only when the Timer ticked the ListCtrl could got updated.
Side note: You should do
SetRedraw(FALSE);
before a bulk update
and
SetRedraw(TRUE);
after.
You should not have the control drawing itself at a one-by-one item level, when doing a bulk operation.
Use Thread.I had the same problem and I solved it by just having the loop of adding elements into the clistctrl in thread function. That is,is the POSTMESSAGE() function in the thread should be called as much time as we want to add elements .
MFC Application getting stuck when adding list control elements
Also refer the above link to get some idea
I have made a game that uses a game loop.
Now i am trying to implement a GUI for this game in wxWidgets.
The problem is that when I initialize the GUI the control of the program remains on a GUI loop and doesn't go to the game loop.
So, can i make the GUI run on its own thread?
You can, but leave all code, which interacts with the GUI on the main thread/EDT (Event Dispatch Thread). Concurrent access to GUI elements is not intended by design and will cause problems. Instead, put the game loop into a wxThread and fire appropriate events from there. Those events can then be handled on the EDT to update the GUI or for rendering a frame.
Another solution would be, to invoke single iterations of your game loop on the main thread, using wxTimer.
Note:
Throttle the game loop or coalesce the events if necessary. wxTimer does perfectly support throttling by frequency and coalescing of update events. In a separate thread, you'd need to sleep for the remaining time of the desired cycle/iteration time or wait on a semaphore, triggered by the main thread.
Implement access to share data like the game state with a synchronization object like wxMutex. Preferably, you could instead use std::mutex and std::thread from C++11.
Examples:
http://wiki.wxwidgets.org/Inter-Thread_and_Inter-Process_communication
http://wiki.wxwidgets.org/Making_a_render_loop
I'm working on a Qt app, and at some point I have a class (I name it here "engine") that is governing the program: it has a signal with a timeout which makes the class to draw, and evolve the app logic. Morevoer, it receives events that are caught from a QGraphicsScene.
Each engine "tick", the update() is called on the Scene, updating the drawing according to the app evolution.
Naturally, I want the drawing to be synchronized with the reactions of the events, otherwise, a drawing of some object could be made while the reaction of a event was destroying that same object, causing a SegFault.
I've tried using a queue on the engine such that I would only make the engine to react to those events on a specific place of a update, thus not interfering with the drawing part.
Two problems rised:
I cannot make a copy of a QGraphicsEvent. Apparently the copy operator is private (which I assume is for a good reason anyway).
When the class is processing the events, before the drawing, it can also happen that a new event appears, which can be "bad" because of non-synchronization of it
Taking into account this situation, is there any approach that can solve this situation? Is there any standard procedure in Qt for this? I mean, how do I ensure the drawing is not potentially desynchronized with the events' reactions of the application?