Gwyddion3 will break both binary and source compatibility to fix or replace misdesigned features and allow to solve issues that would have to be solved by dirty hacks otherwise. (The older of you may remeber the very same sentence introducing Gwyddion2 plan.)
Some potential big changes are in essence additions or extensions that do not break compatibility and can be implemented during 2.x. These are not listed here.
Get rid of redundant libraries: libgwydraw is a natural part of libgwydgets, libgwymodule a part of libgwyapp (which should be separated from the app itself directory-wise); libgwyddion and libgwyprocess could be also merged, but they make sense separate too.
The funamental problem with serialization (and even more with deserialization) is that failures are not run-time. Instead of passing an error with GError it fails hard, a malformed file can make Gwyddion abort. We could introduce an alternative (de)serialization API, but mixing objects using both APIs in one (de)serialization action would evidently not work well.
While changing it, serialization should be possible ot perform to an arbitrary seekable stream (e.g. directly to the file) and should not require allocation of an output buffer for the whole file in memory.
Sort the stuff by type: Channels are under /data, 0th channel stuff under /data/0, etc.; graphs are under /graph, 0th graph stuff under /graph/0, etc. This removed lots of the brain damaged logic of data-browser and allows to perform much more operations generically whithout caring much about particular item types.
We have too many things that are lists of smaller parts, with these parts occasionally being added, removed or shuffled around – and we want other things to be notified when they do. We also often visualize these lists as GtkTreeViews or GtkComboBoxes. For instance:
Ideally these things would be GtkTreeModels. However, they are often quite simple (value-like serializables), in addition each of them implementing GtkTreeModel would mean considerable code duplication. It looks like a good idea to devise a simplier generic array/list interface that would permit the creation of an adaptor class which would in turn implement all the dull GtkTreeModel bits.
While GwyDataField with a regular grid serves quite well for 2D data representation – among other reasons because general point-value sets in higher dimensions are so hard to deal with that people avoid producing them unless necessary – the situation is quite different in 1D. We need a general – possibly ordered – (coordinate, value) set object because in 1D arbitrary coordinate sets are common.
Originally graphs were not something we expected to operate on further much. Nevertheless, they are first class objects now. GwyGraphCurveModel has the right data representation (except one would pack (coordinate, value) to achieve better memory locality), but they carry too much presentational information (and lack some value information such as units that are associated only with a GwyGraphModel as a whole) to be useful for general 1D data representation.
Some module functions – layers, tools – provide object-like interfaces (independently on whether they are technically implemented as classes or not), while others – namely data processing and graph functions – provide procedure-like interfaces (again, independently on whether they are technically implemented as classes or not). Procedural interfaces should be easily callable by other modules and pywgy scripts.
The main architectural obstacle is the impossibility to call a module function with a given set of parameters. Modules should probably explicitly register a set of parameters they want to use from settings, so that the application can handle the parameters generically. Upon call they will be given a particular parameter set, perhaps GwyContainer too, but possibly wth some wrapper API. The calling interface can be something like
module_function(ParameterSet paramset[, const gchar *name]);
and the current container, graph, whatever is obtained via app functions. This precludes using the functions on non-current objects. For that a “snapshot” holding the complete set of information obtainable from gwy_app_data_browser_get_current() would have to be created and passed for each invocation (with some fallback to the actual current object if unspecified).
In the case all modules are objects, the interface can be: create
instance, set parameters (or set some parameter save/load mechanism), call
module_func->run(data),
destroy instance.
Provide a consistent interface to “slow” functions, or a general background-processing interface. It should be able to use multiple worker threads behind the scene – at least interface-wise, implementation can be then done later.
Remove static mutable data or add proper locking or document what cannot be accessed safely from multiple threads (this mainly involves some object initialization magic that is not completely safe even on GObject side at the time of writing this). Also add locking to idle/timeout functions used in widgets.
All object types should be construable with g_object_new(…) (they may have obligatory construction properties, of course). At present many data-like objects can be properly created only with new() functions with mandatory parameters – for instance DataField, DataLine, DataWindow, … This causes difficulties for bindings and makes subclassing essentially impossible.
Where feasible, the construction properties should be made optional, i.e. changeable during object life time. However, in some cases the value of this flexibility does not justify the costs of the much more complex implementation.
Provide scrollable/zoomable data windows as graphics editors and other apps do? It's a lot of work and I don't really miss them. However, zoom in is sometimes handy and it is not possible on large scans.
The direct mangling of GdkGLConfig makes it very hard to compile an app that uses GtkGLExt itself with gwyddion libs that are compiled without GtkGLExt support. We should use an indirection such as GwyGdkGLConfig that would be defined to GdkGLConfig or void.
Stop defining standard math functions (albeit apparently missing on the platform) in a header others may include involuntaritly, i.e. gwyconfig.h. Define inline functions such as gwy_math_fallback_cbrt() in gwymathfallback.h and macros cbrt → gwy_math_fallback_cbrt() if cbrt() is not provided, but do not include gwymathfallback.h by any other header. Only those who want these replacements will then include it – explicitly.
Remove ROUND macro (superseded by GWY_ROUND).
Obviously misdesigned to resemble GwyNLFitPreset. When the central function gwy_cdline_fit() has 1/3 of parameters ignored because they make no sense something is wrong.
The underscorized-lowercase GwyCDLine names should be gwy_cd_line_foo(), not gwy_cdline_foo() – it causes problems with bindings. Incidentally, GwyNLFitPreset has the same problem, the underscorized name should be gwy_nl_fit_preset (the same for GwyNLFitter).
Also, 3D functions should not have 3D as a word, this can also cause problems with bindings. Renaming Gwy3DSetup will require some workarounds as it's serialized in containers. Maybe this can be solved by some proxy object with the new serialization interface.
Use Cairo for drawing, this will finally solve all the image/graph export problems and hacks, not speaking about easy PostScript export; as of Gwyddion-2.0, Cairo is not ready though. Gtk+ 2.10 also brings some printing support that can be expected to be usable at the time of Gwyddion 3.0 release.
By the time we can expect Gwyddion-3.0, most processors are likely to be multicore. We should not waste the computing potential.
I have a fairly good idea what to do about this, it can be even introduced during 2.x, have to dump brain here (Yeti).
Namely to construct menus and toolbox(es); it might be possible to do this partially in 2.x, but might not make sense. Or maybe screw GtkAction, the current GtkAction and GtkUIManager implementations are far from being meaningfully subclassable.
Recent GLib provides some things we implemented manually: memory mapped files, i18n macros. Use them. Also convert things to use GSlice where appropriate.
Remove the grain quantity interface parts that duplicate GwyGrainValue – namely the generic metadata functions introduced in 2.7.