This is the source of information for developers working on WorkBench.
The contents will be enhanced and extended based in feed back sent to dev@pysvn.tigris.org.
Workbench uses two threads.
The foreground thread operates the GUI and only fast operations should be performed in event handlers otherwise the responsiveness of the UI will suffer.
Slow operations are performed on a background thread. The background thread processes work that is added to a work queue.
No GUI operations are allowed to be performed on the background thread. This is because on some platforms the GUI will crash.
An event handler typcially needs to do some work on the foreground thread and some on the background thread.
Arranging to move between threads can involve a lot of code in the event handlers. However Workbench has greatly simplified the coding of event handlers by using using python generators.
The threading and event helper code is in wb_app.py and wb_background_thread.py.
To understand the code you will need to be familier with the __call__()
special
method, how to call a function with arbitary args and keywords and python generators
and the yield keyword.
Any event handler that needs access to the background thread is wrapped via the eventWrapper() function. An example from wb_frame.py:
wx.EVT_MENU( self, wb_ids.id_SP_History, self.app.eventWrapper( self.OnSpHistory ) )
The eventWrapper
function wraps the self.OnSpHistory
function
inside an EventScheduling
object.
Inside the event handler move to the background by:
yield self.app.backgroundProcess
And move to the foreground by:
yield self.app.foregroundProcess
The project_info object has two pysvn client objects, client_fg
for use on the foreground thread and client_bg
for use on the background thread.
You must use the client object that matches the thread the code is running on
otherwise pysvn will raise an exception that the it is already in use.
In this example from wb_subversion_list_handler_common.py
you can see
that the function yields to the background before calling annotate using the client_bg
object.
Then after annotate has completed the function yields to the foreground to do GUI operations,
creating the AnnotateFrame
.
Notice the use of the ok
variable that carries status until the
function is back in the foreground where it can react by calling appropiate GUI operations.
def Cmd_File_Annotate( self, all_rows ): for filename in [self.getFilename( row ) for row in all_rows]: self.app.setProgress( 'Annotating %(count)d', 0 ) self.app.setAction( 'Annotate %s...' % filename ) yield self.app.backgroundProcess ok = False try: annotation = self.project_info.client_bg.annotate( filename ) ok = True except pysvn.ClientError, e: self.app.log_client_error( e ) yield self.app.foregroundProcess if not ok: break h_frame = wb_subversion_annotate.AnnotateFrame( self.app, self.project_info, filename, annotation ) h_frame.Show( True ) self.app.clearProgress() self.app.setAction( 'Ready' )
If you wish to contribute code to WorkBench please keep the style inline with the existing code.
Element | Style | Example |
---|---|---|
module name | Lower case with underscore (_) to seperate words. | wb_app.py |
class | Camel case with initial uppercase letter. | class WbApp |
def | Camel case with initial lowercase letter. | def setAction(): |
variables | Lower case with underscore (_) to seperate words. | current_file = 'a.txt' |
plural variable names | Use the all_ prefix for plural variables, do not
append s , its to easy to confuse singluar with plural. |
all_files = [] |
Compare to None |
Always use is or is not to test a
for None . Use of == can trigger
unexpected calls to __eq__ and __cmp__ class methods. |
if status.entry is None: |
In the Sources
folder run one of the make files to create
the generated source files (wb_version.py and wb_images.py).
Unless you are trying to create binary images of WorkBench use:
make -f wb_common.mak wb_version.py wb_images.py
Now you can run WorkBench using one of the helper scripts.
Platform | Command |
---|---|
Windows | run_wb.cmd |
Unix | wb.sh |
Mac OS X | run_wb.sh |