SPKnot, KnotHolderEntity, and KnotHolder
Dear Inkscape-devel,
Can someone explain to me the relationships between SPKnot, KnotHolderEntity, and KnotHolder? The code seems a bit confusing to me in terms of how they are related to each other.
What I have collected so far: SPKnot is a like a UI element. It has properties like style and color and signals when events are triggered. KnotHolderEntity is like the manager of SPKnot, allocating and storing pointer to SPKnot to allow SPKnot object to outlive the scope of the entity. It also manages connections between signals that SPKnot emits and receivers for those signals. KnotHolder aggregates KnotHolderEntity, with a few functions that iterate through the list of these entities to do certain things like handling events and knot update by calling methods that have been implemented in SPKnot already.
My questions are: Why is SPKnot named with the SP prefix? From SPObject documentation, all SPObject is supposed to be representable as a node in SVG. There is no notion of “knot” in SVG 2 as far as I know, and the class didn't even inherit SPObject. In terms of Model-View-Controller design pattern, I see SPKnot as the Model and KnotHolderEntity as the Controller, handling the Model creation and events handling. But instead, event handling resides partly in SPKnot itself and partly in KnotHolder, which confuses me in terms of the design of these classes. Is the main purpose of KnotHolder really just for aggregating KnotHolderEntity in a list? I might be missing something, but I don’t see why we can’t move handler methods all into KnotHolderEntity, following MVP pattern. Knot events are handled individually after all. What are these PatternKnotHolderEntityXY / Angle / Scale? They seem to do something specific to patterns but instead of seeing their implementations in their own classes, I see declarations and methods about them implemented in KnotHolder and KnotHolderEntity instead. Can we factor these out somewhere, like how LPETangentToCurve defines their own KnotHolderEntities in their own source file?
Overall, I’m skeptical most about the implementation of KnotHolder. It can be much simpler — just an aggregator of KnotHolderEntities. Right now, it seems to have unrelated functionalities that obscure the purpose of the class.
I’d love any additional documentation about this if anyone can point me to it. I don’t see much on the generated Doxygen doc and in the source files. Thank you.
Regards, _______________________ Papoj "Hua" Thamjaroenporn papoj@...3117... mailto:papoj@...3117...
2015-11-12 21:45 GMT+01:00 Papoj Thamjaroenporn <pt2277@...3110...>:
Why is SPKnot named with the SP prefix? From SPObject documentation, all SPObject is supposed to be representable as a node in SVG. There is no notion of “knot” in SVG 2 as far as I know, and the class didn't even inherit SPObject.
It's because SPKnot is not an SPObject. It's purely an UI element. and does not exist at the document level. SP is a prefix for "Sodipodi", the former name of Inkscape, and it was used for all GObject classes, not just those inherited from SPObject.
In terms of Model-View-Controller design pattern, I see SPKnot as the Model and KnotHolderEntity as the Controller, handling the Model creation and events handling. But instead, event handling resides partly in SPKnot itself and partly in KnotHolder, which confuses me in terms of the design of these classes.
SPKnot and SPKnotHolderEntity exist only because back when the original Sodipodi code was written, creating a derived class in GObject involved writing tons of boilerplate. That's why each type of knot is not a distinct class, but a generic instance of SPKnot that differs only by what signal handlers it has attached. You can see PathManipulator and the Inkscape::UI::Node hierarchy for my more modern take on this, which uses virtual functions instead of signals. I wanted to eventually port everything to this new pattern, but my master's thesis was about a completely different area of code.
Unfortunately, there are several things in Inkscape which are similarly poorly designed. There are also at least a few cases where people who added new features did not fully understand the existing, reasonably good design due to documentation deficiencies and coded around it, resulting in huge kludges - it's the main reason why our dev cycles take so long.
Best regards, Krzysztof
participants (2)
-
Krzysztof Kosiński
-
Papoj Thamjaroenporn