Monday, November 22, 2010

Singleton Hidden and Some Implications

Some factories were exposed to user as singleton instances. This had two fold implications: first of them is: you did not know without diving in NaroCAD codebase what you can do and what you can't. Also from plugin writers, it was needed to keep a strict namespace to them (root one) to make easier at level of codebase to not interfer with all kind of factories that are used (here was about Options intems and FunctionFactory, where you register your custom functions.
Also they were singletons, which at one level it is an antipattern. Even they are sigletons, they are likely better to be exposed to this interface, as you can query a plugin. This also solves the possibility when NaroCAD APIs will change and you will make assumptions about code without being so.
The last implication is that for now there is just one class to you to register your plugins. From there you will get an ActionsGraph instance and you're good to go. Want to extend the Options's dialog with one OptionsItem? Get from actionsGraph your OptionsSetupInput and take the factory instance that is contained. The same for functions.
This will reduce once more coupling and problems around code. Another area that was shown, it was just that code was fragile on File->New that was not verifying that the file loaded is consistent, so breakage of it, will make future (1.5.4) version to crash. The unit test was done to verify consistency, but also the attribute saving/loading was also "fixed" (will throw exceptions so programmer will know if you will save invalid data that you have to do something!). So, if you will try the TwoPointLine plugin you will likely see some slight changes, but this refactor will mean a more stable NaroCAD and for developper view a more "complaining" unit test suite.
Another small change is that plugins will just need to add an attribute (NaroRegister) and you're ready to go, with less conventions and easier to organize your code.
So, as a conclusion, plugins will be easier to write and less problematic.
Update: one crash that was fixed regarding plugins was to register your plugin, write something to a file that depends on plugin and second time, load the file but don't load the plugin. It ws hard to fix because when a file is loaded it simply fill in memory objects and broke the internal model. By throwing an exception and "try-catching it", will let the data tree broken. So I fixed the code in two ways: try to not crash areas like TreeView using wrong data, and when loading wrong data file, will catch the exception and revert to a previous state (before loading the file).

No comments: