Hi everyone,
I said I had a few things to propose about gui-indep and here's at least
one of them.
After much sporadic thought on the subject I've decided that Alejandro was
right. We shouldn't have a Communicator class but do everything with
lyxfuncs. Originally I'd agreed we needed lyxfuncs for most of this stuff
but didn't like the idea of having to interpret strings in the gui-to-core
communications. I've been trying to think a decent way to use lyxfuncs
such that we could pass a different parameter for different funcs (eg.
BufferParams for some buffer func, PrinterParams for a printer func) but I
keep ending up needing to do: static_cast<PrinterParam>(void*) which is
very ugly and dangerous. So Alejandro's property string wins out.
Anyway, I'm starting to ramble so I'll try to shorten this a bit. Mostly
this is a repeat of Alejandro's idea with a little extra -- most of which
I'm making up as write this otherwise it'd never get written and I'd never
get around to thinking about it ;-)
Each of the existing members of Communicator become lyxfuncs (or
bufferfuncs or whateverfuncs). The lyxfunc's arguement is a property
string. We should still use parameter structs like BufferParams,
PrinterParams etc. since they are easier to handle. So I suggest adding
one new method and one new constructor to these structs:
/// Constructor: builds from a property string
PrinterParams(string const &);
/// Outputs a minimal(?) property string
string stringify() const;
Thus the interpreting and generation of the string is wrapped in each data
class. So the question that remains is:
How do we define/interpret property strings?
customised LyXLex for strings?
Lars' new regexp stuff which I still haven't looked at?
Given a property string like:
"target=PRINTER p_name=lp1 reverse_order=true count_copies=5"
What do we use to extract:
enum Target{PRINTER, FILE}; Target target;
string p_name;
bool reverse_order;
unsigned int count_copies;
I think a new Lexer that pinches much of LyXLex's code but only works on
strings can probably do this since we can extract bool, string and
int tokens however it means writing a big switch statement for each
constructor and I'm wondering if there's a neater way. Maybe a generic
Lexer (a template?) that given a struct and a table of keyword_items (like
LyXLex uses) could fill in any arbitrary struct. This might work with
RTTI since IIRC RTTI lets us access specific variables by string name at
runtime. Like:
StructType newstruct();
newstruct.rtti("p_name") = "lp1";
Hmmm... maybe I'm in fantasy land...
Then we'd have a kind of generic struct generator class. Very buzzword
compliant :-)
Anyway, even if we just have a simplified Lexer similar to LyXLex we'd
just end up with code like:
PrinterParams::PrinterParams(string const & s)
// all the usual defaults can still be set here.
{
Lexer lex(s, PPLexStructure);
if (!lex.isValid("PrinterParams(string const &)")) {
// isValid checks that the property string
// only contains entries we can use.
// It outputs a message to debugstream if not
// and returns a bool.
abort();
}
while (!lex.done()) {
// only try to set what's in the property string
PPToken current(lex.getNext());
switch (current) {
case P_NAME: p_name = lex.getString();
break;
case REVERSE: reverse_order = lex.getBool();
break;
case TARGET: target = Target(lex.getInt());
....
}
}
Where PPLexStructure is the keyword_item[] and PPToken is the enum
corresponding to the variable names.
So how silly does this idea sound? Have you got a better one?
Allan. (ARRae)
P.S. That's one thing done this weekend, so I'm happy now. And I've
already made a start on the "Transition PR" doc so I might be heading for
a miracle after all! No maybe not, installing SuSE-6.3 last night (most
of last night) cut down the number of hours dramatically. But now I have
3 popular distros all on the same harddrive! Woohoo!