|
View:
New views
11 Messages
—
Rating Filter:
Alert me
|
|
|
Tool-Tip timing problemThis is some strange behavior which bugs me right now. I'm using tool
tips in my app. Now I have a special loop running like this: while( app->runWhileEvents() == TRUE ){ windowMain->OnFrameUpdate(); } This is since I have to do periodic updating of the screen. Now if this is in place tool tips do no more show up or only after hovering for over 5 seconds over a control. How is the tool tip implemented? What could mess up the timing? -- Yours sincerely Plüss Roland ------------------------------------------------------------------------------ _______________________________________________ Foxgui-users mailing list Foxgui-users@... https://lists.sourceforge.net/lists/listinfo/foxgui-users |
|
|
Re: Tool-Tip timing problemOn Thursday 26 March 2009, Roland Plüss wrote:
> This is some strange behavior which bugs me right now. I'm using tool > tips in my app. Now I have a special loop running like this: > > while( app->runWhileEvents() == TRUE ){ > windowMain->OnFrameUpdate(); > } > > This is since I have to do periodic updating of the screen. Now if this > is in place tool tips do no more show up or only after hovering for over > 5 seconds over a control. How is the tool tip implemented? What could > mess up the timing? The FXToolTip is done using "on idle" processing, i.e. its done just before the main thread would otherwise fall asleep in the select() system call. The "on idle" processing kicks in when there are no events, and no timers; however, since you're using runWhileEvents() the event loop returns instead of calling idle processing. My suggestion: put the onFrameUpdate() into a idle processing callback [basically, call app->addChore() to run it each time you need it to run]. This way, you could use a normal event loop, and the system will perform your OnFrameUpdate() as part of the regular chore processing. Note:- if OnFrameUpdate() takes a very long time, the regular chores may be a bit less frequently executed. But at least they'll still run. [If OnFrameUpdate() takes a very long time, you could also try to kick it off from a timer; this allows you some more control over how frequently this function is called....]. Hope this helps, - Jeroen ------------------------------------------------------------------------------ _______________________________________________ Foxgui-users mailing list Foxgui-users@... https://lists.sourceforge.net/lists/listinfo/foxgui-users |
|
|
tooltips stop popping up during FXList updatesIs there a way to get tooltips to appear in a FXList that is loading
with setItem/insertItem? ------------------------------------------------------------------------------ _______________________________________________ Foxgui-users mailing list Foxgui-users@... https://lists.sourceforge.net/lists/listinfo/foxgui-users |
|
|
Re: tooltips stop popping up during FXList updatesOn Tuesday 31 March 2009, Jason Heblack wrote:
> Is there a way to get tooltips to appear in a FXList that is loading > with setItem/insertItem? If a FXToolTip has been created, it should automatically show the full title of the text of each item if you hover the mouse over that item. The tooltip system however also sends a SEL_QUERY_TIP to the target of the FXList widget; if you intercept this, you can supply a custom tip, as follows: FXMAPFUNC(SEL_QUERY_TIP,MyTarget::ID_LIST,MyTarget::onQueryTip) and then: // We were asked about tip text long MyTarget::onQueryTip(FXObject* sender,FXSelector,void* ptr){ FXString tip="TipTopTip"; sender->handle(this,FXSEL(SEL_COMMAND,ID_SETSTRINGVALUE),(void*)&tip); return 1; } This would show "TipTopTip" anywhere in the list. You can use getCursorPosition() and getItemAt(x,y) to display an item-dependent custom tooltip. Hope this helps, - Jeroen ------------------------------------------------------------------------------ _______________________________________________ Foxgui-users mailing list Foxgui-users@... https://lists.sourceforge.net/lists/listinfo/foxgui-users |
|
|
Re: tooltips stop popping up during FXList updatesThe example here shows a case of broken tooltips. There is only one
widget here that would be affected by tooltips. Is this example fixable by changing a base class? Steps to reproduce: 1. run the attached cpp file or run from copying and pasting 2. hover mouse over list items Actual results: Tooltips appear quickly but then immediately disappear when an item is either put into the list or an existing list item text is reset. Expected results: The tooltips would remain until the mouse pointer leaves a list item. #include <fx.h> class ListItemModel { public: FXString m_text, *m_tip; ListItemModel(FXString text, FXString *tip) { m_text = text; m_tip = tip; } }; class GUIList : public FX::FXList { FXDECLARE(GUIList) public: GUIList() { } GUIList(FXComposite *p, FXObject* tgt, FXSelector sel, FXuint opts, FXint x, FXint y, FXint w, FXint h); long onQueryTip(FXObject* sender, FXSelector sel, void* ptr); }; GUIList::GUIList(FXComposite *p, FXObject* tgt, FXSelector sel, FXuint opts, FXint x, FXint y, FXint w, FXint h) : FXList(p, tgt, sel, opts, x, y, w, h) { ; } FXDEFMAP(GUIList) GUIListMap[] = { FXMAPFUNC(SEL_QUERY_TIP, 0, GUIList::onQueryTip) }; FXIMPLEMENT(GUIList, FXList, GUIListMap, ARRAYNUMBER(GUIListMap)) class Window : public FX::FXMainWindow { FXDECLARE(Window) protected: Window() { ; } public: static GUIList *s_list; static FXColor s_black; enum { ID_SET = FXMainWindow::ID_LAST, ID_INSERT }; Window(FXApp* a); long set(FXObject* obj, FXSelector sel, void* ptr); long insert(FXObject* obj, FXSelector sel, void* ptr); virtual ~Window() { ; } virtual void create() { FXMainWindow::create(); show(PLACEMENT_SCREEN); } }; FXDEFMAP(Window) WindowMap[] = { FXMAPFUNC(SEL_IO_READ, Window::ID_SET, Window::set), FXMAPFUNC(SEL_IO_READ, Window::ID_INSERT, Window::insert) }; FXIMPLEMENT(Window, FX::FXMainWindow, WindowMap, ARRAYNUMBER(WindowMap)) Window::Window(FXApp* a) : FXMainWindow(a, "example", NULL, NULL, DECOR_TITLE | DECOR_MINIMIZE | DECOR_CLOSE | LAYOUT_FILL_X | LAYOUT_FILL_Y | LAYOUT_FIX_WIDTH, 0, 0, 800, 600) { s_list = new GUIList(this, this, ID_SET, FX::LIST_BROWSESELECT | LAYOUT_FILL_Y | LAYOUT_FIX_WIDTH, 0, 0, 200, 0); s_list->setScrollStyle(VSCROLLER_ALWAYS | HSCROLLER_NEVER); s_list->verticalScrollBar()->setHiliteColor(s_black); s_list->appendItem("test", NULL, new FXString("test")); s_list->appendItem("test", NULL, new FXString("test")); s_list->appendItem("test", NULL, new FXString("test")); s_list->appendItem("test", NULL, new FXString("test")); s_list->appendItem("test", NULL, new FXString("test")); s_list->appendItem("test", NULL, new FXString("test")); s_list->appendItem("test", NULL, new FXString("test")); s_list->appendItem("test", NULL, new FXString("test")); s_list->appendItem("test", NULL, new FXString("test")); s_list->appendItem("test", NULL, new FXString("test")); s_list->appendItem("test", NULL, new FXString("test")); s_list->appendItem("test", NULL, new FXString("test")); s_list->appendItem("test", NULL, new FXString("test")); s_list->appendItem("test", NULL, new FXString("test")); s_list->appendItem("test", NULL, new FXString("test")); s_list->appendItem("test", NULL, new FXString("test")); s_list->appendItem("test", NULL, new FXString("test")); s_list->appendItem("test", NULL, new FXString("test")); s_list->appendItem("test", NULL, new FXString("test")); s_list->appendItem("test", NULL, new FXString("test")); new FXToolTip(getApp(), TOOLTIP_PERMANENT); } long Window::set(FXObject* obj, FXSelector sel, void* ptr) { FXString *text = *((FXString**) ptr); s_list->setItemText((s_list->getNumItems() - 1), *text); delete text; return 1; } long Window::insert(FXObject* obj, FXSelector sel, void* ptr) { ListItemModel *model = *((ListItemModel**) ptr); s_list->insertItem((s_list->getNumItems()), model->m_text, NULL, model->m_tip); delete model; return 1; } Window *g_window; FXColor Window::s_black = FXRGB(0, 0, 0); GUIList* Window::s_list = NULL; long GUIList::onQueryTip(FXObject* sender, FXSelector sel, void* ptr) { FXint idx = g_window->s_list->getCursorItem(); if (idx < 0) return 0; FXString *tip = ((FXString *) g_window->s_list->getItemData(idx)); sender->handle(this, FXSEL(SEL_COMMAND, ID_SETSTRINGVALUE), (void*) tip); return 1; } class Worker : public FX::FXThread { public: Worker() { ; } FXint run(); }; FXint Worker::run() { FXMessageChannel load(g_window->getApp()); FXString *string; ListItemModel *model; for (FXint i = 1; i <= 100; i++) { string = new FXString(FXString("setItem - ") + FXString(FXString::value(i) + " of 100")); load.message(g_window, FXSEL(SEL_IO_READ, Window::ID_SET), &string, sizeof (*string)); FXThread::sleep(100000000); } for (FXint i = 1; i <= 10000; i++) { model = new ListItemModel(FXString(FXString::value(i) + " of 1000"), new FXString(FXString::value(FX::FXThread::time()) + FXString(" nanoseconds since Epoch "))); load.message(g_window, FXSEL(SEL_IO_READ, Window::ID_INSERT), &model, sizeof (*model)); model = 0; FXThread::sleep(100000000); } } int main(int argc, char *argv[]) { FXApp application("example", "example"); application.init(argc, argv); g_window = new Window(&application); application.create(); application.setToolTipPause(0); (new Worker)->start(); return application.run(); } [example.cpp] #include <fx.h> class ListItemModel { public: FXString m_text, *m_tip; ListItemModel(FXString text, FXString *tip) { m_text = text; m_tip = tip; } }; class GUIList : public FX::FXList { FXDECLARE(GUIList) public: GUIList() { } GUIList(FXComposite *p, FXObject* tgt, FXSelector sel, FXuint opts, FXint x, FXint y, FXint w, FXint h); long onQueryTip(FXObject* sender, FXSelector sel, void* ptr); }; GUIList::GUIList(FXComposite *p, FXObject* tgt, FXSelector sel, FXuint opts, FXint x, FXint y, FXint w, FXint h) : FXList(p, tgt, sel, opts, x, y, w, h) { ; } FXDEFMAP(GUIList) GUIListMap[] = { FXMAPFUNC(SEL_QUERY_TIP, 0, GUIList::onQueryTip) }; FXIMPLEMENT(GUIList, FXList, GUIListMap, ARRAYNUMBER(GUIListMap)) class Window : public FX::FXMainWindow { FXDECLARE(Window) protected: Window() { ; } public: static GUIList *s_list; static FXColor s_black; enum { ID_SET = FXMainWindow::ID_LAST, ID_INSERT }; Window(FXApp* a); long set(FXObject* obj, FXSelector sel, void* ptr); long insert(FXObject* obj, FXSelector sel, void* ptr); virtual ~Window() { ; } virtual void create() { FXMainWindow::create(); show(PLACEMENT_SCREEN); } }; FXDEFMAP(Window) WindowMap[] = { FXMAPFUNC(SEL_IO_READ, Window::ID_SET, Window::set), FXMAPFUNC(SEL_IO_READ, Window::ID_INSERT, Window::insert) }; FXIMPLEMENT(Window, FX::FXMainWindow, WindowMap, ARRAYNUMBER(WindowMap)) Window::Window(FXApp* a) : FXMainWindow(a, "example", NULL, NULL, DECOR_TITLE | DECOR_MINIMIZE | DECOR_CLOSE | LAYOUT_FILL_X | LAYOUT_FILL_Y | LAYOUT_FIX_WIDTH, 0, 0, 800, 600) { s_list = new GUIList(this, this, ID_SET, FX::LIST_BROWSESELECT | LAYOUT_FILL_Y | LAYOUT_FIX_WIDTH, 0, 0, 200, 0); s_list->setScrollStyle(VSCROLLER_ALWAYS | HSCROLLER_NEVER); s_list->verticalScrollBar()->setHiliteColor(s_black); s_list->appendItem("test", NULL, new FXString("test")); s_list->appendItem("test", NULL, new FXString("test")); s_list->appendItem("test", NULL, new FXString("test")); s_list->appendItem("test", NULL, new FXString("test")); s_list->appendItem("test", NULL, new FXString("test")); s_list->appendItem("test", NULL, new FXString("test")); s_list->appendItem("test", NULL, new FXString("test")); s_list->appendItem("test", NULL, new FXString("test")); s_list->appendItem("test", NULL, new FXString("test")); s_list->appendItem("test", NULL, new FXString("test")); s_list->appendItem("test", NULL, new FXString("test")); s_list->appendItem("test", NULL, new FXString("test")); s_list->appendItem("test", NULL, new FXString("test")); s_list->appendItem("test", NULL, new FXString("test")); s_list->appendItem("test", NULL, new FXString("test")); s_list->appendItem("test", NULL, new FXString("test")); s_list->appendItem("test", NULL, new FXString("test")); s_list->appendItem("test", NULL, new FXString("test")); s_list->appendItem("test", NULL, new FXString("test")); s_list->appendItem("test", NULL, new FXString("test")); new FXToolTip(getApp(), TOOLTIP_PERMANENT); } long Window::set(FXObject* obj, FXSelector sel, void* ptr) { FXString *text = *((FXString**) ptr); s_list->setItemText((s_list->getNumItems() - 1), *text); delete text; return 1; } long Window::insert(FXObject* obj, FXSelector sel, void* ptr) { ListItemModel *model = *((ListItemModel**) ptr); s_list->insertItem((s_list->getNumItems()), model->m_text, NULL, model->m_tip); delete model; return 1; } Window *g_window; FXColor Window::s_black = FXRGB(0, 0, 0); GUIList* Window::s_list = NULL; long GUIList::onQueryTip(FXObject* sender, FXSelector sel, void* ptr) { FXint idx = g_window->s_list->getCursorItem(); if (idx < 0) return 0; FXString *tip = ((FXString *) g_window->s_list->getItemData(idx)); sender->handle(this, FXSEL(SEL_COMMAND, ID_SETSTRINGVALUE), (void*) tip); return 1; } class Worker : public FX::FXThread { public: Worker() { ; } FXint run(); }; FXint Worker::run() { FXMessageChannel load(g_window->getApp()); FXString *string; ListItemModel *model; for (FXint i = 1; i <= 100; i++) { string = new FXString(FXString("setItem - ") + FXString(FXString::value(i) + " of 100")); load.message(g_window, FXSEL(SEL_IO_READ, Window::ID_SET), &string, sizeof (*string)); FXThread::sleep(100000000); } for (FXint i = 1; i <= 10000; i++) { model = new ListItemModel(FXString(FXString::value(i) + " of 1000"), new FXString(FXString::value(FX::FXThread::time()) + FXString(" nanoseconds since Epoch "))); load.message(g_window, FXSEL(SEL_IO_READ, Window::ID_INSERT), &model, sizeof (*model)); model = 0; FXThread::sleep(100000000); } } int main(int argc, char *argv[]) { FXApp application("example", "example"); application.init(argc, argv); g_window = new Window(&application); application.create(); application.setToolTipPause(0); (new Worker)->start(); return application.run(); } ------------------------------------------------------------------------------ _______________________________________________ Foxgui-users mailing list Foxgui-users@... https://lists.sourceforge.net/lists/listinfo/foxgui-users |
|
|
Re: tooltips stop popping up during FXList updatesOn Wednesday 01 April 2009, Jason Heblack wrote:
> The example here shows a case of broken tooltips. There is only one > widget here that would be affected by tooltips. Is this example fixable > by changing a base class? > > Steps to reproduce: > 1. run the attached cpp file or run from copying and pasting > 2. hover mouse over list items > > Actual results: > Tooltips appear quickly but then immediately disappear when an item is > either put into the list or an existing list item text is reset. > > Expected results: > The tooltips would remain until the mouse pointer leaves a list item. > > > #include <fx.h> > > class ListItemModel { > public: > FXString m_text, *m_tip; > > ListItemModel(FXString text, FXString *tip) { > m_text = text; > m_tip = tip; > } > }; > > class GUIList : public FX::FXList { > > FXDECLARE(GUIList) > public: > GUIList() { > } > GUIList(FXComposite *p, FXObject* tgt, FXSelector sel, FXuint opts, > FXint x, FXint y, FXint w, FXint h); > long onQueryTip(FXObject* sender, FXSelector sel, void* ptr); > }; > > GUIList::GUIList(FXComposite *p, FXObject* tgt, FXSelector sel, FXuint > opts, FXint x, FXint y, FXint w, FXint h) : FXList(p, tgt, sel, opts, x, > y, w, h) { > ; > } > FXDEFMAP(GUIList) GUIListMap[] = { > FXMAPFUNC(SEL_QUERY_TIP, 0, GUIList::onQueryTip) > }; > > FXIMPLEMENT(GUIList, FXList, GUIListMap, ARRAYNUMBER(GUIListMap)) > > class Window : public FX::FXMainWindow { > > FXDECLARE(Window) > protected: > Window() { > ; > } > public: > static GUIList *s_list; > static FXColor s_black; > > enum { > ID_SET = FXMainWindow::ID_LAST, > ID_INSERT > }; > Window(FXApp* a); > long set(FXObject* obj, FXSelector sel, void* ptr); > long insert(FXObject* obj, FXSelector sel, void* ptr); > > virtual ~Window() { > ; > } > > virtual void create() { > FXMainWindow::create(); > show(PLACEMENT_SCREEN); > } > }; > > FXDEFMAP(Window) WindowMap[] = { > FXMAPFUNC(SEL_IO_READ, Window::ID_SET, Window::set), > FXMAPFUNC(SEL_IO_READ, Window::ID_INSERT, Window::insert) > }; > > FXIMPLEMENT(Window, FX::FXMainWindow, WindowMap, ARRAYNUMBER(WindowMap)) > > Window::Window(FXApp* a) : FXMainWindow(a, "example", NULL, NULL, > DECOR_TITLE | DECOR_MINIMIZE | DECOR_CLOSE | LAYOUT_FILL_X | > LAYOUT_FILL_Y | LAYOUT_FIX_WIDTH, 0, 0, 800, 600) { > s_list = new GUIList(this, this, ID_SET, FX::LIST_BROWSESELECT | > LAYOUT_FILL_Y | LAYOUT_FIX_WIDTH, 0, 0, 200, 0); > s_list->setScrollStyle(VSCROLLER_ALWAYS | HSCROLLER_NEVER); > s_list->verticalScrollBar()->setHiliteColor(s_black); > s_list->appendItem("test", NULL, new FXString("test")); > s_list->appendItem("test", NULL, new FXString("test")); > s_list->appendItem("test", NULL, new FXString("test")); > s_list->appendItem("test", NULL, new FXString("test")); > s_list->appendItem("test", NULL, new FXString("test")); > s_list->appendItem("test", NULL, new FXString("test")); > s_list->appendItem("test", NULL, new FXString("test")); > s_list->appendItem("test", NULL, new FXString("test")); > s_list->appendItem("test", NULL, new FXString("test")); > s_list->appendItem("test", NULL, new FXString("test")); > s_list->appendItem("test", NULL, new FXString("test")); > s_list->appendItem("test", NULL, new FXString("test")); > s_list->appendItem("test", NULL, new FXString("test")); > s_list->appendItem("test", NULL, new FXString("test")); > s_list->appendItem("test", NULL, new FXString("test")); > s_list->appendItem("test", NULL, new FXString("test")); > s_list->appendItem("test", NULL, new FXString("test")); > s_list->appendItem("test", NULL, new FXString("test")); > s_list->appendItem("test", NULL, new FXString("test")); > s_list->appendItem("test", NULL, new FXString("test")); > new FXToolTip(getApp(), TOOLTIP_PERMANENT); > } > > long Window::set(FXObject* obj, FXSelector sel, void* ptr) { > FXString *text = *((FXString**) ptr); > s_list->setItemText((s_list->getNumItems() - 1), *text); > delete text; > return 1; > } > > long Window::insert(FXObject* obj, FXSelector sel, void* ptr) { > ListItemModel *model = *((ListItemModel**) ptr); > s_list->insertItem((s_list->getNumItems()), model->m_text, NULL, > model->m_tip); > delete model; > return 1; > } > > Window *g_window; > FXColor Window::s_black = FXRGB(0, 0, 0); > GUIList* Window::s_list = NULL; > > long GUIList::onQueryTip(FXObject* sender, FXSelector sel, void* ptr) { > FXint idx = g_window->s_list->getCursorItem(); > if (idx < 0) > return 0; > FXString *tip = ((FXString *) g_window->s_list->getItemData(idx)); > sender->handle(this, FXSEL(SEL_COMMAND, ID_SETSTRINGVALUE), (void*) > tip); > return 1; > } > > class Worker : public FX::FXThread { > public: > > Worker() { > ; > } > FXint run(); > }; > > FXint Worker::run() { > FXMessageChannel load(g_window->getApp()); > FXString *string; > ListItemModel *model; > for (FXint i = 1; i <= 100; i++) { > string = new FXString(FXString("setItem - ") + > FXString(FXString::value(i) + " of 100")); > load.message(g_window, FXSEL(SEL_IO_READ, Window::ID_SET), > &string, sizeof (*string)); > FXThread::sleep(100000000); > } > for (FXint i = 1; i <= 10000; i++) { > model = new ListItemModel(FXString(FXString::value(i) + " of > 1000"), new FXString(FXString::value(FX::FXThread::time()) + FXString(" > nanoseconds since Epoch "))); > load.message(g_window, FXSEL(SEL_IO_READ, Window::ID_INSERT), > &model, sizeof (*model)); > model = 0; > FXThread::sleep(100000000); > } > } > > int main(int argc, char *argv[]) { > FXApp application("example", "example"); > application.init(argc, argv); > g_window = new Window(&application); > application.create(); > application.setToolTipPause(0); > (new Worker)->start(); > return application.run(); > } I think I found your problem. When you add new items into the FXList, the cursor-item is reset to -1 in the subsequent recalc(). It needs to do that because when an item is added we recompute the content size and possibly scroll the list, and as a result no longer know which item is under the cursor. I believe the getCursorItem() is, by the way, quite a useless function [I think I've used it only once in all of my FOX applications], and moreover its not reliable. Instead, I'm computing the tooltip based on getCursorPosition() and getItemAt() directly, at the time that the tooltip is posted. This simplifies the code and at the same time makes stuff more reliable in your case. To make custom tooltips easier, perhaps its not a bad idea to have an overloadable virtual inside FXListItem; this way subclassed FXLists can easily provide custom tooltips. The current SEL_QUERY_TIP will still be there as well, of course. Regards, - Jeroen P.S. Looking at your code, a small suggestion: more the initialization of FXMessageChannel outside of Worker::run() since the thread operates asynchronously with the main GUI thread. FXMessageChannel calls FXApp::addInput() which should not be called from another thread; this might cause stuff to be left in inconsistent state, or possibly even crash things. ------------------------------------------------------------------------------ _______________________________________________ Foxgui-users mailing list Foxgui-users@... https://lists.sourceforge.net/lists/listinfo/foxgui-users |
|
|
mouse pointer has to move in the FXList before the chores are seenThe example shows a case of broken chores. The mouse has to be moved to
get the chores to load items into the list. Steps to reproduce: 1. run the attached cpp file (UTF-8) 2. run mouse pointer over the FXList Actual results: The FXList is filled with list items when the mouse is moved over the list. If the mouse pointer is not moved over the FXList then nothing happens. Expected results: The FXList would be filled with items without having to move the mouse. [example.cpp] #include <fx.h> class Window : public FX::FXMainWindow { FXDECLARE(Window) protected: Window() { ; } public: FXList *m_list; enum { ID_CHORE = FXMainWindow::ID_LAST }; Window(FXApp* a); long chore(FXObject* obj, FXSelector sel, void* ptr); virtual ~Window() { ; } virtual void create() { FXMainWindow::create(); show(PLACEMENT_SCREEN); } }; FXDEFMAP(Window) WindowMap[] = { FXMAPFUNC(SEL_CHORE, Window::ID_CHORE, Window::chore) }; FXIMPLEMENT(Window, FX::FXMainWindow, WindowMap, ARRAYNUMBER(WindowMap)) Window::Window(FXApp* a) : FXMainWindow(a, "example", NULL, NULL, DECOR_TITLE | DECOR_MINIMIZE | DECOR_CLOSE | LAYOUT_FILL_X | LAYOUT_FILL_Y | LAYOUT_FIX_WIDTH, 0, 0, 800, 600) { m_list = new FXList(this, this, ID_CHORE, FX::LIST_BROWSESELECT | LAYOUT_FILL_Y | LAYOUT_FIX_WIDTH, 0, 0, 200, 0); m_list->setScrollStyle(VSCROLLER_ALWAYS | HSCROLLER_NEVER); } long Window::chore(FXObject* obj, FXSelector sel, void* ptr) { FXString *string = *((FXString**) ptr); m_list->insertItem((m_list->getNumItems()), *string); return 1; } Window *g_window; class Worker : public FX::FXThread { public: Worker() { ; } FXint run(); }; FXint Worker::run() { FXString *string; for (FXint i = 1; i <= 10000; i++) { string = new FXString(FXString::value(i) + " of 1000"); while (g_window->getApp()->hasChore(g_window, Window::ID_CHORE)) { FXThread::yield(); } g_window->getApp()->addChore(g_window, Window::ID_CHORE,&string); FXThread::sleep(100000000); } } int main(int argc, char *argv[]) { FXApp application("example", "example"); application.init(argc, argv); g_window = new Window(&application); application.create(); application.setToolTipPause(0); (new Worker)->start(); return application.run(); } ------------------------------------------------------------------------------ _______________________________________________ Foxgui-users mailing list Foxgui-users@... https://lists.sourceforge.net/lists/listinfo/foxgui-users |
|
|
Re: mouse pointer has to move in the FXList before the chores are seenOn Thursday 02 April 2009, Jason Heblack wrote:
> The example shows a case of broken chores. The mouse has to be moved to > get the chores to load items into the list. > > Steps to reproduce: > 1. run the attached cpp file (UTF-8) > 2. run mouse pointer over the FXList > > Actual results: > The FXList is filled with list items when the mouse is moved over the > list. If the mouse pointer is not moved over the FXList then nothing > happens. > > Expected results: > The FXList would be filled with items without having to move the mouse. Yes, This is a "works as designed" thing. To invoke things from the worker thread to be executed in the main GUI thread, you will need to use FXMessageChannel. EVENT SOURCES ============= When the main GUI thread falls asleep in select(), it only wakes up when external events happen that it is set up to watch. These events can be: GUI events from the X11 server or GDI, sockets and pipes you've added via addInput(), or signals added with addSignal(). If none of these events are raised, the select() expires and we execute any timers that are due. Its important to realize that the main GUI thread will NOT be woken up by any other means except those mentioned above! MESSAGE CHANNEL IS AN EVENT SOURCE ================================== FXMessageChannel is a convenience class which [behind the scenes] calls addInput() so that an event source is registered with FXApp. We use this to communicate between a worker thread and the GUI thread; it allows us to send a message from a worker thread, with the handler executing in the context of the main GUI thread. FXMessageChannel was created as a separate object, so as to not burden single-threaded applications with the need to have an extra event source (in this case, a pipe) around all the time. CHORES ====== Chores are only executed just before select() would be called, i.e. we have run out of events to process and are about to block. This makes chores pretty cheap because they are only executed when nothing else would be going on anyway, at least in our own application. BOTH GUI AND WORKER THREAD CAN MANIPULATE DATA ============================================== FOX API's are NOT thread safe (there are simply too many of them), but it has facilities to allow worker threads and GUI to safely manipulate common data. One of these is appMutex, accessible via app->mutex(). This mutex is locked whenever the main GUI thread is executing ANY handler, and only released while the GUI thread is sleeping. This allows worker threads to SAFELY manipulate data structures which are also manipulated by GUI messages, PROVIDED the worker thread first acquires the appMutex. Of course, you can [and should] perform more fine-grained locking if possible so as to not block the GUI thread for extended periods of time. ======================================================================== Now, in your case, the correct way to set a chore from a worker thread is to use FXMessageChannel. The worker thread uses the FXMessageChannel::message() API to cause a message to be passed from the worker to the main GUI thread. The main GUI thread will be woken up, and dispatch to the proper handler, which can then either set the chore you want or [perhaps better] invoke the desired function directly. Your previous version earlier this week was actually more correct.... A bit lengthy, but I hope it helps, - Jeroen ------------------------------------------------------------------------------ _______________________________________________ Foxgui-users mailing list Foxgui-users@... https://lists.sourceforge.net/lists/listinfo/foxgui-users |
|
|
deserialization optimization in the main gui threadThe code below from main gui thread (fox-1.7.17) measures the
deserialization time for an aggregate object. If there are more worker threads in the background then the total time found is greater. Why would the amount of worker threads in the background influence the time measured in the main gui thread? When the worker threads are around, the total time is about 500ms. When the workers have exited, the total time is about 50ms or about 10 times less. FXlong start,end; FXfloat total; start=FX::FXThread::time(); fileIn.open(*s_stored[s_selected], FX::FXStreamLoad); fileIn >> s_active[s_selected]; fileIn.close(); end=FX::FXThread::time(); total=(end-start)/1000000; cout << "milliseconds: " << total << endl; There is also always free memory reported as being available. At the start it is about 84432 free. At the end it is about 16636 free. Is round robin scheduling being applied to the main gui thread in addition to the workers? The workers policy were all set to round robin. Inside the deserialization load methods, all that is being loaded are bools, ints, and strings or an image or an object that has those members. store >> m_url; store >> m_selected; m_image = new FXJPGImage(getApp(), NULL); m_image->loadPixels(store); ------------------------------------------------------------------------------ This SF.net email is sponsored by: High Quality Requirements in a Collaborative Environment. Download a free trial of Rational Requirements Composer Now! http://p.sf.net/sfu/www-ibm-com _______________________________________________ Foxgui-users mailing list Foxgui-users@... https://lists.sourceforge.net/lists/listinfo/foxgui-users |
|
|
Re: deserialization optimization in the main gui threadOn Tuesday 07 April 2009, Jason Heblack wrote:
> The code below from main gui thread (fox-1.7.17) measures the > deserialization time for an aggregate object. If there are more worker > threads in the background then the total time found is greater. Why > would the amount of worker threads in the background influence the time > measured in the main gui thread? When the worker threads are around, the > total time is about 500ms. When the workers have exited, the total time > is about 50ms or about 10 times less. > > FXlong start,end; > FXfloat total; > start=FX::FXThread::time(); > fileIn.open(*s_stored[s_selected], FX::FXStreamLoad); > fileIn >> s_active[s_selected]; > fileIn.close(); > end=FX::FXThread::time(); > total=(end-start)/1000000; > cout << "milliseconds: " << total << endl; > > There is also always free memory reported as being available. At the > start it is about 84432 free. At the end it is about 16636 free. > > Is round robin scheduling being applied to the main gui thread in > addition to the workers? The workers policy were all set to round robin. > > Inside the deserialization load methods, all that is being loaded are > bools, ints, and strings or an image or an object that has those > members. > > store >> m_url; > store >> m_selected; > m_image = new FXJPGImage(getApp(), NULL); > m_image->loadPixels(store); Silly question: do you run this on a multi-core box? OK, assuming you answer the above in the affirmative, of course; otherwise it'd be too easy ;-) My suspicion is cache-thrashing, where the other threads cause cachelines to be evicted and thus main memory gets hit more often than otherwise would be the case. You probably need to test this hypothesis with some cache-profiling tool... - Jeroen -- +----------------------------------------------------------------------------+ | Copyright (C) 20:50 04/ 7/2009 Jeroen van der Zijp. All Rights Reserved. | +----------------------------------------------------------------------------+ ------------------------------------------------------------------------------ This SF.net email is sponsored by: High Quality Requirements in a Collaborative Environment. Download a free trial of Rational Requirements Composer Now! http://p.sf.net/sfu/www-ibm-com _______________________________________________ Foxgui-users mailing list Foxgui-users@... https://lists.sourceforge.net/lists/listinfo/foxgui-users |
|
|
Re: deserialization optimization in the main gui thread>Silly question: do you run this on a multi-core box? > >OK, assuming you answer the above in the affirmative, of course; otherwise >it'd be too easy ;-) > >My suspicion is cache-thrashing, where the other threads cause cachelines >to be evicted and thus main memory gets hit more often than otherwise would >be the case. > >You probably need to test this hypothesis with some cache-profiling tool... > > > - Jeroen Jeroen, No. I use ccache and distcc on abandoned single-cpu computers taken from a successful business during an upgrade. I had bought an AMD 800mz single CPU for 4K one time except each of these free computers is faster than that. SunStudio12.1 is slower than distcc for single CPUs though. Jason -- +----------------------------------------------------------------------------+ | Copyright (C) 20:50 04/ 7/2009 Jeroen van der Zijp. All Rights Reserved. | +----------------------------------------------------------------------------+ ------------------------------------------------------------------------------ This SF.net email is sponsored by: High Quality Requirements in a Collaborative Environment. Download a free trial of Rational Requirements Composer Now! http://p.sf.net/sfu/www-ibm-com _______________________________________________ Foxgui-users mailing list Foxgui-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/foxgui-users |
| Free embeddable forum powered by Nabble | Forum Help |