Tooled Composite Tooled Composite Design Pattern Design Pattern Presentation by Andy Bulka CTO Austhink Software [email protected]
Jun 25, 2015
Tooled Composite Tooled Composite Design PatternDesign Pattern
Presentation by
Andy BulkaCTO Austhink Software
What is this about?What is this about?
Ever wanted to create a "direct Ever wanted to create a "direct manipulation" program where you select manipulation" program where you select various tools and manipulate stuff on a various tools and manipulate stuff on a workspace? Like MS paint etc. These workspace? Like MS paint etc. These sorts of applications are quite difficult to sorts of applications are quite difficult to build due to the many possible build due to the many possible combinations of behavior that is combinations of behavior that is needed. Every tool must know what to needed. Every tool must know what to do with each type of object. How do we do with each type of object. How do we manage this sort of complexity?manage this sort of complexity?
By GOF authorBy GOF authorJohn VlissidesJohn Vlissides
http://www.research.ibm.com/designpatterns/pubs/ph-sep99.pdf
The ProblemThe Problem
““direct manipulation” direct manipulation” metaphor.metaphor.
How do you represent shapes? How do you represent tools? How do tools and shapes interact? How do you enhance the editor with
new shapes and tools?
Representing shapesRepresenting shapes
COMPOSITE – design pattern
Representing “Tools”
usually a palette of tools editor’s behavior changes with the
current tool E.g. when drawing tool is active we create shapes;
E.g. when the selection tool is active we select shapes
Representing “Tools”
STATE – design pattern
How tools and shapes How tools and shapes interactinteract
How a tool interacts with each shape is usually different
m x n possible interactions between m tools and n shapes.
How do we manage and organise this complexity?
VisitorVisitor
VisitorVisitor
Shapes don’t have tool knowledge – Shapes don’t have tool knowledge – tools do all the work. Shapes just tools do all the work. Shapes just implement implement AcceptVisitor(v)AcceptVisitor(v) and then and then do a v.VisitShape() or v.VisitEdge() or do a v.VisitShape() or v.VisitEdge() or whatever they themselves are.whatever they themselves are.
Each tool has a Each tool has a VisitShape VisitShape VisitEdge VisitEdge VisitShapeRhEdgeZone VisitShapeRhEdgeZonemethod method that gets triggered in this that gets triggered in this way.way.
Example SequenceExample Sequence
Start in Hover ToolStart in Hover Tool All mouseMove events go to Hover All mouseMove events go to Hover
tooltool As hover over shapes/edges you ask As hover over shapes/edges you ask
what is under me and change what is under me and change cursor. You “visit” the shape and cursor. You “visit” the shape and change cursor accordinglychange cursor accordingly
ToolHover--------------
VisitShape() cursor = HAND
VisitEdge() cursor = ARROW
Example Sequence Example Sequence continuedcontinued
User Left ClicksUser Left Clicks HoverTool.OnLeftClick sees that you HoverTool.OnLeftClick sees that you
are over a resize zone shape, so are over a resize zone shape, so switches to the Resize toolswitches to the Resize tool Zones (e.g. resize zone) within shapes are also Zones (e.g. resize zone) within shapes are also ‘shapes’‘shapes’
Resize tool.OnMouseMove resizes the Resize tool.OnMouseMove resizes the shape you are on. Repeatedly (as shape you are on. Repeatedly (as MouseMove events arrive).MouseMove events arrive).
Resize tool.OnMouseUp switches back Resize tool.OnMouseUp switches back to the hover tool.to the hover tool.
RTTI as RTTI as alternative to Visitoralternative to Visitor
Have each tool use RTTI (runtime type info) to Have each tool use RTTI (runtime type info) to see what the type of the shape is and do see what the type of the shape is and do something.something.
Thus instead of each tool with numerous Thus instead of each tool with numerous VisitSOMETHING() method, just have a single VisitSOMETHING() method, just have a single Visit() method with an Visit() method with an if if statement based on rtti statement based on rtti inside.inside.
ToolHover--------------
Visit() if target == Shape // use of RTTI
… else if target == Edge …..
ToolHover--------------
VisitShape() …VisitEdge() ...
RTTI as RTTI as alternative to Visitoralternative to Visitor
When visitor was invented double When visitor was invented double dispatch was the only way to get dispatch was the only way to get around the lack of RTTI in C++around the lack of RTTI in C++
RTTI approach is simpler than RTTI approach is simpler than visitorvisitor
Easier to reuse and specialise tools Easier to reuse and specialise tools since don’t have to modify visitor since don’t have to modify visitor class every time add new shape – class every time add new shape – just subclass a tool and use RTTI just subclass a tool and use RTTI
EventsEvents
Funnel all Funnel all events events through to through to the the current current tooltool..
Each tool has Each tool has custom custom handling for handling for all the gui all the gui events e.g. events e.g. mouseDown, mouseDown, mouseClick, mouseClick, mouseMove mouseMove etc.etc.
Classic STATE pattern, passing through method invocations to the current state object
Tooled Composite Tooled Composite patternpattern
Rewire events as you swap tools
SwapTool(tool)
Event HandlingEvent Handling
MouseUp might trigger exiting a MouseUp might trigger exiting a tool and reverting to another tool tool and reverting to another tool e.g. back to Hover.e.g. back to Hover.
State pattern – each state knows State pattern – each state knows when to switch to another state – OR when to switch to another state – OR – outer class e.g. canvas knows– outer class e.g. canvas knows
State State Pattern Pattern
– – switchiswitchi
ng ng statestate
Notice calls to “SetTool”
Prototype PatternPrototype Pattern
Use for creation toolUse for creation tool Create a copy of an instance of an Create a copy of an instance of an
objectobject Could create a new instance rather Could create a new instance rather
than prototype – depends on how than prototype – depends on how complex the prototypical object iscomplex the prototypical object is
Command PatternCommand Pattern
Hook in command manager for Hook in command manager for undo/redoundo/redo
We use tool to generate a command We use tool to generate a command and then run the command, which and then run the command, which redoes the gui action, except redoes the gui action, except through “official channels” through “official channels”
Final PatternFinal Pattern
ReflectionsReflections
Classic approach -> visitor.Classic approach -> visitor.Practical approachPractical approach -> use RTTI (or -> use RTTI (or equivalent e.g. have each shape return a equivalent e.g. have each shape return a shapeType enum) for better shapeType enum) for better comprehensibility.comprehensibility.
Classic approach -> 3D table of possibilities, Classic approach -> 3D table of possibilities, with events, shapes, tools on each axis.with events, shapes, tools on each axis.Practical approachPractical approach -> table too sparse and -> table too sparse and complex, so just code for the cases you complex, so just code for the cases you want.want.
ReflectionsReflections Classic approach -> some blend of Classic approach -> some blend of
visitShape() / visitEdge() etc methods and visitShape() / visitEdge() etc methods and mouse event methods, within each toolmouse event methods, within each toolPractical approachPractical approach -> Skip most of the -> Skip most of the visit methods and do the logic in the visit methods and do the logic in the mouse handling methods. Generalise the mouse handling methods. Generalise the mouse handling into one event mouse handling into one event (mouseAction) and use if statements to (mouseAction) and use if statements to catch the situations of interest. You know catch the situations of interest. You know what the current shape is by having a what the current shape is by having a pointer to it (set up for you by the tool or pointer to it (set up for you by the tool or something).something).