1Slideshow module design & coding manifest 2========================================= 3 4Coding style: 5------------- 6 7 - modified BSD style: 8 if( !test ) 9 { 10 function( arg1, 11 arg2, 12 arg3 ); 13 } 14 15 - members are always named maSomething 16 17 - no tabs, indent four spaces 18 19 - Class names (and type names in general) are UpperCamelCase, method 20 names lowerCamelCase 21 22 - all file names are lowercase, header files end in hxx, source files 23 in cxx; one header per class, only one linkable class per cxx. 24 25 - header guards follow this scheme: INCLUDED_SLIDESHOW_<CLASSNAME>_HXX 26 27 - module-external headers, and system headers are included like this: 28 #include <module/header.hxx> or #include <boost/shared_ptr.hpp>. 29 module-internal headers are included like this: 30 #include "header.hxx" 31 No external header guards are used in cxx files 32 33 34Design 35------ 36 37 - currently, the slideshow module is basically 38 single-threaded. Therefore, the XSlideShow interface must be called 39 from the _main thread_ (this precondition is asserted). Other 40 listener interfaces, which we could not impose this limitation upon 41 (XSlideShowView's XMouseMotionListener, XMouseListener, 42 XPaintListener and XModifyListener) will queue the events, and 43 process them in the main thread. Therefore, XSlideShow::update() 44 needs to be called frequently from the slideshow client. 45 46 This design is necessitated by the fact that at least one XCanvas 47 implementation (vclcanvas) must be called from the main thread 48 only. Once the UNO threading framework is integrated, this can be 49 changed. 50 51 As of now, SlideView, SlideShowImpl, EventMultiplexerListener and 52 DummyRenderer are exposed to calls from the outside world; of 53 those, SlideView and EventMultiplexerListener serialize the calls 54 by enqueuing events, SlideShowImpl imposes the hard constraint of 55 being called from the main thread, and DummyRenderer is content 56 with a simple object mutex. As a side effect, the global EventQueue 57 must be thread-safe (as one of the few internal objects having an 58 object mutex) 59 60 - wherever possible, abstract interfaces and shared_ptr are used. 61 * exception: global objects like EventQueue, 62 and tightly collaborating classes, like Slide/LayerManager/Layer 63 64 - since shared_ptr can lead to circular references (resulting in 65 memory leaks), some care needs to be taken to avoid those. Where 66 circular references are inevitable, or can happen by accident, 67 classes implement the Disposable interface. The owner of the object 68 then calls dispose() on its owned objects. 69 Another way of avoiding circular references are weak_ptr, which are 70 used in a few places. 71 One of those places are the ViewEventHandlers, which are held weak 72 on the EventMultiplexer. Otherwise, every class in need of view 73 events would have to delegate listening to a dedicated child 74 object, or burden their clients with the Disposable interface. 75 76 - Pattern: Separate Listener 77 To avoid circular shared_ptr references, classes in need to 78 register a listener at EventMultiplexer often implement the 79 corresponding listener interface in a separate object. This object 80 is held via shared_ptr by the original class, and normally 81 registered at the EventMultiplexer (and thus held by shared_ptr 82 there, too). The separate listener object in turn holds the 83 original object by plain reference. This is safe, if the original 84 object removes the listener from the EventMultiplexer, before or 85 within the destructor. 86 87 88Testing 89======= 90 91Before merging changes to HEAD, besides making sure the usual QA has 92been done, also run the unit and integration tests in the 93slideshow/test directory. Issuing a "dmake test" should run the unit 94tests, and generate a "demoshow" binary, that should also be run and 95checked to work properly. 96