Developer forums (C::B DEVELOPMENT STRICTLY!) > Plugins development

Help on wxWidgets multi threading management

<< < (2/2)

jmccay:
My experience with threads is limited, but you can not rule out that wxWidgets is trying to get a lock too--somewhere deep inside the dark recesses of the code.  Whereas you be able to get away with this for short code segments which take a very, very small amount of time, I would recommend against it.  You are putting to much coupling (connection) between the GUI and the search code.  The two should be more separated.  There should be a clean line between the two.  This allows you to make changes to either side of the code (GUI or worker) without effecting the unchanged side code.  It should also make the threading issues easier.  As suggested before, using events is the best way to communicate between the two.
jmccay

dje:
Hi all !

The ThreadSearch plugin main idea is to be able to continue viewing/editing code during a text search (being blocked for 5 minutes is boring and I experienced that too many times). That's why I started this plugin.

I chose to use this graphical control for 3 reasons :
- quite the same strategy as in the 'Search in files'
- allows being consistent with C::B standard search options (case, whole words, beginning of words, reg ex...)
- all is managed by the control, you just have to provide informations and you don't reinvent the wheel.

Nevertheless, I agree that mixing gui calls in the worker thread may be surprising if reasons are not know.
I'll may have a look at Scintilla code to see if it is possible to extract search algorythm quite easily.

But I am very frustrated not understanding why this code does not work.

Concerning the proposed doors :
I tried Door one but I can't find the exit  :(
I am not a fan of door 2 because this plugin looses part of its interest and may be more unpleasant to user.
The third looks the good one but requires more efforts... I'll probably choose this one but I have to improve my knowledge about wxScintilla and wxString possibilities.

Dje

Pecan:
You can still use most of the routines in wxScintilla, but without the gui stuff.

Scintilla isn't all that big. I've extracted a number of usefull non-gui routines from it. The sample in ...\src\sdk\wxscintilla\samples\test\ is very useful.

It shows the separation of utilility routines from gui, and someone has already provided a .cbp that you can modify for your environment.

All the find routine's "word boundaries" are built into the non-gui find routines. You dont need a gui to use them.

If you see a routine you need that calls gui, either rip out the calls or (as I've done) write a fake routine to capture it and return a success notice.

wxscintilla.h in the .../src/includes is a nice reference to paste up on the wall (just joking).

But honestly, door 3 isn't going to be as hard as you think. Just move the hidden control to the main thread and call the wxscintilla utility routines on a buffer from the background thread.

As TheDragon :) says, it'll fly... I'm looking forward to your success.

Pecan:
You might want to have a look at the wyoEditor.

It looks like it uses a background thread to do FindInFiles. And it's wxScintilla based.

http://wyoguide.sourceforge.net/index.php?page=editor.html
wyoGuide: A guide, a tutorial for developing well-designed cross-platform applications

eranif:
Hi dje!,

I recently developed a search thread that supports the following:
- match case
- match whole word
- regular expression
- file extensions
- events and easy interface with the main thread

Source code (5 sources + 1 sample):
http://www.eistware.com/st/SearchThread.zip

The code was built and tested on windows using VS20005, so no makefile is provided, but you should be able to complie and run it
easily.

A brief usage:

--- Code: ---#include "search_thread.h"

// to use the search thread, we first need to start it ..

//----------------------------------------------------------
// Initialisation
//----------------------------------------------------------
// The search thread is singleton object so there is ohly one instance of it.
SearchThreadST::Get()->Start();

//--------------------------------------------------------------
// Starting new search
//--------------------------------------------------------------
// to perform a search, we create a SearchData object
// and set it with information provided by the user
SearchData data;
data.SetFindString(wxT("something_to_search")); // the find string
data.SetMatchCase(true); // is search case sensetive?
data.SetMatchWholeWord(true); // match whole word?, see also: SetWordChars() function
data.SetRootDir(true); // our search will start here
data.SetRegularExpression(false); // use regular expression?
data.SetExtensions(wxT("*.cpp;*.h;*.hpp;*.hxx")); // look at these file types

SearchThreadST::Get()->SetNotifyWindow( this ); // all events will be fired to 'this'
SearchThreadST::Get()->PerformSearch( data ); // do the search

//-----------------------------------------------------------------------
// Stopping running search
//-----------------------------------------------------------------------
SearchThreadST::Get()->StopSearch();

//------------------------------------------------------------------------
// process results:
//------------------------------------------------------------------------
// SearchThread fires three events:
// wxEVT_SEARCH_THREAD_MATCHFOUND - a match was found
// wxEVT_SEARCH_THREAD_SEARCHEND - search ended
// wxEVT_SEARCH_THREAD_SEARCHCANCELED - search cancelled by user
 
 
// in your code, you need to define 3 event handlers:
// Note: that the events will be sent to the NotifyWindow set earlier
//---------------------------------------------------------------------
EVT_COMMAND(wxID_ANY, wxEVT_SEARCH_THREAD_MATCHFOUND, Frame::OnSearchThread)
EVT_COMMAND(wxID_ANY, wxEVT_SEARCH_THREAD_SEARCHCANCELED, Frame::OnSearchThread)
EVT_COMMAND(wxID_ANY, wxEVT_SEARCH_THREAD_SEARCHEND, Frame::OnSearchThread)

// and the handler ...
void Frame::OnSearchThread(wxCommandEvent &event)
{
if( event.GetEventType() == wxEVT_SEARCH_THREAD_MATCHFOUND)
{
// wxEVT_SEARCH_THREAD_MATCHFOUND returns a SearchResultList
// which is defined as:
// typedef std::list<SearchResult> SearchResultList;
// see SearchResult for more details.
SearchResultList *res = (SearchResultList*)event.GetClientData();
SearchResultList::iterator iter = res->begin();

wxString msg;
for(; iter != res->end(); iter++){
msg.Append((*iter).GetMessage() + wxT("\n"));
}

m_debugWin->AppendText(msg);
delete res;
}
else if(event.GetEventType() == wxEVT_SEARCH_THREAD_SEARCHCANCELED)
{
// wxEVT_SEARCH_THREAD_SEARCHCANCELED sets a cancell message in the GetString() method of the
// the event and nothing more
m_debugWin->AppendText(event.GetString() + wxT("\n"));
}
else if(event.GetEventType() == wxEVT_SEARCH_THREAD_SEARCHEND)
{
// When search ended, a summary object is sent to user:
// The summary contains the number of files scanned and number of total matches found
// a GetMessage() is provided that formats a nice suammry string
SearchSummary *summary = (SearchSummary*)event.GetClientData();
m_debugWin->AppendText(summary->GetMessage() + wxT("\n"));
delete summary;
}
}

//--------------------------------------------------------------
// Clean up
//--------------------------------------------------------------

// before shutdown, it is recommended to stop the SearchThread and free
// its resources:
SearchThreadST::Get()->Stop();
SearchThreadST::Free();


--- End code ---

You can use it as is, or just for reference,

HTH,
Eran

Navigation

[0] Message Index

[*] Previous page

Go to full version