|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
IntroductionBack when I was a structural engineer in the 80s and 90s, we had a mantra: "If it can't be drawn, it can't be built". As a result we were taught to sketch all our ideas out on paper until we could demonstrate an idea's viability. Now that i'm older (and debatebly wiser) and am no longer a practising structural engineer, I nevertheless continue to sketch my ideas because I've found that old mantra is right on the nose, although now i'm a software engineer I would probably say: "If I can't draw it, it's probably because I don't fully understand it". What prompted this article was one of those fortunate moments when you call on a collegue to help you out in a given situation (as fraught with danger as asking a collegue for help is) and you actually learn something useful. In this case I was struggling to untangle some logic that relied on 3 or 4 relatively unrelated variables in order to implement some specific business rules for my current employer. So I called in a collegue and asked him to let me explain the logic to him so that he might help me untangle it. To assist me I drew a picture, and then another, and then another, before finally giving up and bringing up the relevant source code (what a cop out!). This at least allowed me to explain the complexity of the problem, and it was at that point that Ed (my collegue) said, "This needs a state diagram". To which I said, "Sounds good to me. Off you go then". So as I explained, Ed drew the state diagram and within 10 minutes we had it all sorted out and found another logical bug to boot. Then I said, "That's the fundamental problem with high level logic that relies for its input on the result of source code residing in a variety of different source files, its just about impossible to comment (or something equally succinct!). "What would be great would be a way of putting diagrams like this in the code". And then it all fell into place. ASCII art (if that's what it can be called) has been around for ever and a day, and whilst it has been developed into UML diagrams I was unable to find freeware Windows tools that would maintain such diagrams in an easy and quick manner. Presenting CodePlotterCodePlotter is a graphical tool for creating and maintaining generic 'box-connection' diagrams in your code. By 'generic' I mean that CodePlotter can be used to express a range of organisational structures, such as:
The boxes can be labelled and the diagrams can also have a multi-line title. However, CodePlotter is definitely not a UML modelling tool (although it can be used to express similar diagrams). If you think of it as such then you may be disappointed by this initial implementation. Then again you might not, but instead engage with me on a merry rollercoaster ride of new features and bug fixes. Installing CodePlotter is as easy as...
Using CodePlotterThe following simple tutorial will create you two linked boxes, after which it's really just more of the same.
Then simply drag the boxes around to see the connections zig and zag as new paths are generated. Two things to be aware of:
Inside CodePlotterCodePlotter comprises 3 main elements:
Of these only the first really warrants close attention since the other two are either not fully implemented or fairly trivial in their complexity. The TextDiagram EngineThis is a fairly grand title for the component that has the following basic functions:
The last of these was the most straightforward since, given a valid model, it is entirely deterministic. The only slightly tricky bit was ensuring that the output format precisely matched the required input format. The parsing of the model was also fairly simple (in hindsight) once I realised that supporting multiple box styles with only subtle differences (rect, roundrect and round) made it extremely difficult to figure out with any great degree of certainty a given arrangement of characters. ie. once I reduced the problem domain to a single box style with connectors having only simple start and end characters, things got alot simpler. The connection path finding, however, was definitely both the most fun and the most painful part of the design (and its not over yet either). Indeed, until Ed suggested that I require the user to specify the side of the source box from which a given connection was to start, I struggled to figure out what approach to take. (ps. I know that path finding is a well worn problem domain, but most of the fun of these articles is doing it yourself so that you know exactly how it is behaving and why) Once the start side is specified, I first thought out a simple set of rules that might be used to get from A to B, taking into account that the initial direction might be in one of four possible directions relative to the target. These are the following rules I came up with:
And that, with a certain degree of tweaking, is about it. SurprisesWhen I started this project I approached it from the perspective that all I had to do was find the magical set of rules that covered all eventualities and it would be done. And, in a sense I still believe that. However, what I definitely was not expecting was to see the simple set of rules outlined above actually fix a problem that I had not anticipated, and I'm still not exactly clear how it occurred even after debugging it. What I observed was the path doubling back on itself to find an alternative route after it hit a dead-end. The surprising thing was not so much that it doubled back, given I had specifically added backtracking as a means of achieving this goal; what was surprising was that it seemed to do so via some other means - definitely creepy! Further Work
CopyrightThe code is supplied here for you to use and abuse without restriction, except that you may not modify it and pass it off as your own. History
|
||||||||||||||||||||||