C++0x: Running code in GUI thread from worker threads.

January 29, 2011

Filed under: How-to,HTMLayout,Sciter,Source code — Andrew @ 11:53 pm

One of topics in design of multi-threading GUI applications is to choose method of calling GUI code from so called worker threads – threads that do some work in background. At some point they need to report results to the GUI. But GUI is a shareable resource so some form of synchronization is required. One approach is to use some global lock/mutex and capture it each time when any thread need to access tree of GUI objects.

Another method is to enqueue update tasks to the GUI thread. GUI thread will execute them when it can. This approach does not require synchronization code to be spread across whole application. The whole system will work faster and probability of deadlocks/synchronization issues is almost zero in this case.

The only problem: for each action that you need to do in GUI thread you will need to create separate task/object for deferred execution (or to use some other mechanism like marshalling in COM).

With new features of C++0x we can accomplish this with almost zero overhead. In particular we will need lambdas.

Here is how our code of worker thread function may look like:

void worker_thread()
{
  dom::element some_el = ...;
  string html_to_set = ...;
  int result;
  ...
  auto gui_code_block = [some_el,html_to_set,&result] ()
  { // executed in GUI thread
    if(some.children() > 10)
      some.set_html(html_to_set);
    result = 20; // report some result if needed.
  };
  gui_exec(gui_code_block);
  ...
  if( result == 20 ) ...;
  ...
}

As you see here I am declaring inline code block that will be
executed in GUI thread while the rest of the function body will run in its own thread.

The key point here is the gui_exec() function that may look like as:

void gui_exec( std::function<void()> gui_block )
{
  event evt;
  PostMessage(hwnd, WM_NULL, WPARAM(&evt),LPARAM(&gui_block));
  evt.wait(); // suspend worker thread until GUI will execute the block.
}

It posts the message to the GUI with address of synchronization object and
address of our GUI code block (function in fact). It is simple as you see.

And the last piece – we need message handler in GUI thread that will actually execute that code block. The best place for it is inside so called “GUI message pump” – Get/DispatchMessage loop that exist in any GUI application:

typedef std::function<void(void)> gui_block;

while (GetMessage(&msg, NULL, 0, 0))
{
    if( msg.message == WM_NULL )
    {
      gui_block* pf = reinterpret_cast<gui_block*>(msg.lParam);
      event* pe = reinterpret_cast<event*>(msg.wParam);
      (*pf)();  // execute the block
      pe->signal(); // signal that we've done with it
                        // this will resume execution of worker thread.
    }
    else
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
}

And that is it.

The only note: I am using WM_NULL message here but in reality you should use some other not that popular message for it. RegisterWindowMessage() will help to get that message number.

C++, how to change class of object in runtime.

August 12, 2010

Filed under: How-to,Source code — Andrew @ 4:06 pm

There is a nice feature in TIScript that allows to change class of already instantiated object.
Let’s say we have two classes:

class MyWidget : Behavior { ... }
class MyWidgetReadonly : Behavior { ... }

that handle user interaction with some widget on the screen. This widget can operate in two distinct modes: normal and read-only.
These modes share the same widget state but have substantially different behavioral characteristic. So it makes sense to split these two sets of methods into two classes to avoid pollution of our code by the crowd of if(readonly) ... else ....
When needed we can switch class of the object like this:

var widget = new MyWidget();
....
if( needReadOnlyMode )
  widget.prototype = MyWidgetReadonly; // changing class of the object.
...

Pretty much all dynamic languages allow to do such things. E.g. in Python you can modify obj.__bases__.

Surprisingly you can do the same in C++ too and without any “hack”. We can use so called placement new operator to do the trick. Here is how.

Let’s define our class hierarchy as this:

class MyWidget
{
public:
  int data;  // state variables here
  virtual void on_mouse() { printf("normal on_mouse, data=%d\n",data); }
  virtual void on_key() { printf("normal on_key\n"); }
};
class MyWidgetReadOnly: public MyWidget
{
  // no data at all here, sic!
  virtual void on_mouse() { printf("read-only on_mouse, data=%d\n",data); }
  virtual void on_key() { printf("read-only on_key\n"); }
};

And we will switch class of our object using this helper template function:

// turn_to(A* obj) changes class of the object
// that means it just replaces VTBL of the object by VTBL of another class.
// NOTE: these two classes has to be ABI compatible!
template <typename TO_T, typename FROM_T>
  inline void turn_to(FROM_T* p)
  {
    assert( sizeof(FROM_T) == sizeof(TO_T));
    ::new(p) TO_T(); // use of placement new
  }

Note: This will work if our class has default constructor that does not initialize any member variables.

Let’s try this small sample ( test.cpp ):

#include <new>
#include <assert.h>
// turn_to(A* obj) changes class of the object
// that means it just replaces VTBL of the object by VTBL of another class.
// NOTE: these two classes has to be ABI compatible!
template <typename TO_T, typename FROM_T>
  inline void turn_to(FROM_T* p)
  {
    assert( sizeof(FROM_T) == sizeof(TO_T));
    ::new(p) TO_T(); // use of placement new
  }

class MyWidget
{
public:
  int data;  // state variables here
  virtual void on_mouse() { printf("normal on_mouse, data=%d\n",data); }
  virtual void on_key() { printf("normal on_key\n"); }
};
class MyWidgetReadOnly: public MyWidget
{
  // no data at all here, sic!
  virtual void on_mouse() { printf("read-only on_mouse, data=%d\n",data); }
  virtual void on_key() { printf("read-only on_key\n"); }
};

int main(int argc, char* argv[])
{
  MyWidget *w = new MyWidget();
  w->data = 123;
  w->on_mouse();
  turn_to<MyWidgetReadOnly>(w); // turning the instance to MyWidgetReadOnly class.
  w->on_mouse();
	return 0;
}

After compiling and running it we should see in console output like this:

normal on_mouse, data=123
read-only on_mouse, data=123

So it works – we are able to transform existing instance of some class to the instance of other class.

DISCLAIMER:

Be warned that this is a Jedi Sword feature. Use it responsibly, only if you know why you need it. And what are the consequences. Even mentioning of this approach in some software development companies (that usually are on the Dark Side) may damage your reputation.

[how-to] Add entry to Windows Explorer context “New” menu.

April 5, 2010

Filed under: How-to — Andrew @ 6:53 pm

Pretty frequently I am creating .htm and .tis files. For example for testing purposes.
Usually such files use common template like html/head/body elements, etc.

Here is the add-html-template.reg file that adds “New HTML Document” into context menu of Windows Explorer. So to create HTML file it is enough to right-click in some folder and select “New/New HTML Document” menu item.

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\.htm\ShellNew]
"FileName"="C:\\utils\\template.htm"

Copy block of text above into, say, file named add-html-template.reg and double-click on it to run. Registry Editor will ask permission to update registry. “Ok” on that and reboot Windows (or restart Windows Explorer). Done.

Last note: path after “FileName” – it should contain real path of the template.