[Lumiera] PROC BACKEND GUI LUMIERA Application Structure proposal
Ichthyostega
prg at ichthyostega.de
Sun Nov 9 03:47:32 CET 2008
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
> Ichthyostega 2008-11-06 19:28:13 wrote on the wiki:
>> From reading the above text, this proposal seems to capture that.
>> But I am somewhat unsure if the purpose of this proposal isn't
>> rather to load just a micro kernel and the pull up components
>> according to configuration. Because I wouldn't accept such an
>> architecture, and I clearly stated so right at the beginning of our
>> project. I accepted a very flexible and language neutral plugin
>> system on the condition the core remains in control, stays
>> reasonable monolithic and componentization doesn't handicap us in
>> creating an architecture based on abstractions and exploiting the
>> proven design patterns.
...I should add here that this is the summary of a detailed argument
from last year. Basically I am just saying "YAGNI", to employ the term
of the XP folks.
>> Another point is, you need not write a main, because there is
>> already one. Please have a look at it, especially with regards to
>> the global initialisation.
...
Christian Thaeter schrieb:
> Well I already wrote a main too now :) I remember that you had one
> and that joel has one too. This has to be sorted out.
Probably everyone of us needs some things to be triggered from main().
To reiterate. We had the design proposal about GlobalInitialisation,
followed by some discussion. This was last spring, IIRC. Resulting
from this discussion, I built the "lifecycle" functionality into
lumiera::Appconfig. C wrapper prototypes are at the bottom of
appconfig.hpp (and probably need to be put into a separate header;
Btw. the function lumiera_Appconfig_get is now of course superseded
by the new config system)
The core idea is that subsystems in need of initialisation register
a callback into a given "lifecycle hook", instead of having lots
of "initialize this and pull up that" spaghetti code in the main.
Besides the existing Lumiera main.cpp, this system is used by
my test class runner(s). I'll quote the main from there,
because this one is fairly complete:
- ---test/components/mainsuite.cpp-------------
using lumiera::Appconfig;
using lumiera::ON_GLOBAL_INIT;
using lumiera::ON_GLOBAL_SHUTDOWN;
int main (int argc, const char* argv[])
{
util::Cmdline args (argc,argv);
test::TestOption optparser (args);
test::Suite suite (optparser.getTestgroup());
Appconfig::lifecycle(ON_GLOBAL_INIT);
if (optparser.getDescribe())
suite.describe();
else
suite.run (args);
Appconfig::lifecycle(ON_GLOBAL_SHUTDOWN);
return 0;
}
Some notes and explanations:
* because it's a combined C/C++ Application, main must be compiled g++
* there is a ON_BASIC_INIT hook which is executed in the static
initialisation phase; for example NOBUG_INIT is being triggered from
there. Static initialisation code is dangerous and should be limited
to what is really necessary, i.e. any service which must be
guaranteed to be available ON_GLOBAL_INIT
* even ON_GLOBAL_INIT each subsystem should just initialize itself,
but not rely on any other subsystem to be available
* from within the session manager, I'll trigger similar hooks called
ON_SESSION_INIT and ON_SESSION_CLOSE. Probably this is the best
point for the subsystems to go into operation mode
* in the mentioned discussion, we stated that we can cut the dtor calls
for production builds to improve the shutdown time. Thus, anything
which needs to be properly closed should run ON_GLOBAL_SHUTDOWN.
* we haven't defined anything regarding emergency exit yet.
Obviously, we could define another hook ON_EMERGENCY_EXIT
> As you see, you see nothing :). Basically this just initializes the
> system, and currently loading all available plugins at start .....
> Then there is the TODO ("video editing") which is what we have to
> fill with our intented way. This is left very open yet and indeed it
> could be used as microkernel which just pulls up components, but I
> think we rather agree to jump into some controled environment there
> to pull things in a very well defined manner up
Yes. Currently we are writing an Application which always does two or
three very predictable things. In all cases it will pull up a session
in Proc. Optionally, it may trigger a script runner and/or start up
the GUI. Thus I think, exactly this should be stated directly within
main. I believe, code should not only be correct, but also clearly
state what it does at the right abstraction level. Because we are
in main, anything here should express "the big picture".
For example, the missing snippet for the real main() could be:
if (optparser.isOpenSession())
Session::current.load(optparser.getSessionFile());
else
Session::current.reset()
if (optparser.isRunScript())
// call whatever is needed to run the script...
if (optparser.isUseGUI())
// call whatever is needed to pull up the GUI, passing on cmdline
> About program options: I was thinking about stuffing them into the
> config system somehow (--foo-bar=baz becomes "option.foo.bar = baz"
> ?), nothing decided yet but that would make them available to the
> rest of the application in a convinient way.
No problem. boost::program_options (and probably any other serious
library) allows to parse and remove known options and leave the rest of
the remaining commandline intact. I use this for the test class runner
where the rest of the commandline can be examined within the individual
test class(es). In a similar fashion, the GUI toolkit probably wants
to see the commandline for dealing with any toolkit options. We
could pass the rest of the commandline to the config system
which would extract any matching options
> Think about that program options may need to be accessible from
> anywhere including plugins which are written in some languages which
> have no bindings yet. The config system will provide a 'interface'
> for accessing it from anywhere.
Getting option handling correct within a componentized system can be
challenging. That's why I am asking: do we really really need to give
any plugin access to the commandline?
Wouldn't it be sufficient for the plugins to load configuration
from the config system and get any remaining setup directly as call
parameters (i.e. based on data found in the serialized session)?
Because, if we want plugins to participate in the options parsing,
we need the plugins to register their options, in order to detect
clashes and to produce a complete options summary help message.
Certainly doable (did it several times). But certainly nothing
we should do just because we think it /might/ be useful for
some future things we can not foresee yet
Hermann
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
iD8DBQFJFk9EZbZrB6HelLIRAg/FAJ4ifJaUyjJoVd1DICoIvhtKgm0oVwCfZN9q
IDYUeN2GWp/woAC3vjtVGqo=
=HnKy
-----END PGP SIGNATURE-----
More information about the Lumiera
mailing list