Discussion:
Why all the different string types?
Guy Rouillier
2006-03-08 06:04:39 UTC
Permalink
I'm making a change to gCvs that will require me to store a string in
the preferences. I'm baffled trying to figure out what all these
different string types are (I finally gave up and just copied an
existing setting that is specific to qUnix, which uses PCStr.) Let's
see, we have CPStr.cpp, which just to be mean defines PCPStr and PCStr,
but not CPStr at all. That's because CPStr is #define'd in rf/ustr.h to
UPStr. There's UStr, CStr, CString, And some of the code uses std::string.

Then there's all the multistring variants: CMString, CMPString,
CKeyString, CMKeyString. If CKeyString is a multistring, then what is a
CMKeyString?

Are there any suggestions or guidelines on the appropriate uses of these
different string types?
--
Guy Rouillier



Yahoo! Groups Links

<*> To visit your group on the web, go to:
http://groups.yahoo.com/group/cvsgui-dev/

<*> To unsubscribe from this group, send an email to:
cvsgui-dev-***@yahoogroups.com

<*> Your use of Yahoo! Groups is subject to:
http://docs.yahoo.com/info/terms/
kaczoroj
2006-03-09 00:48:19 UTC
Permalink
Guy,

Well, it helps if you use the doxygen-generated class diagram ;) To
store anything you use the classes inheriting from CPersistent.

For the simple string there are two classes with two defines:
#define CPStr UPStr
#define CStr UStr

Then you go to the source and you can see:

/// Up to 255 characters pascal and C string class
class UEXPORT UPStr{...}

/// C string class
class UEXPORT UStr {...}
Post by Guy Rouillier
we have CPStr.cpp, which just to be mean defines PCPStr and PCStr,
but not CPStr at all.
P stands for Persistant. Simply stores the above CPStr and CStr
classes.
Post by Guy Rouillier
There's UStr, CStr, CString, And some of the code uses std::string.
UStr is same as CStr. CString is an MFC classs used on Windows-
specific code. std::string used by me recently as I was trying to see
how would that go if we tried to replace the above string classes with
std::string. Mixed feelings about that one - std::string is by far the
most crappy string class even invented. Unfortunately we can't use
CString (which is superb) so we are stuck with UStr for now. I want to
phase out UPStr (and consquently PCPStr) eventually.
Post by Guy Rouillier
Then there's all the multistring variants: CMString, CMPString,
CKeyString, CMKeyString.
/// CStr specialization of TMString
class CMString : public TMString<CStr> {...}

/// CPStr specialization of TMString
class CMPString : public TMString<CPStr> {..}

Where TMString:
template<class T>
class TMString : public CPersistent

This is a persistent multi-string. It can hold multiple strings and
store them. Very usefull for things like combo boxes.

/// Dictionary specialization of TKeyString ('@')
class CKeyString : public TKeyString<'@'>

/// Multi-key specialization of TKeyString ('x01')
class CMKeyString : public TKeyString<'\x01'>

Where TKeyString
/// Multi-string for storing map (e.g. dictionary)
template <char delimiter>
class TKeyString : public CMString

CMKeyString is just for convienient storage of related dictionaries
together, used to store various keywords in CVSROOT wizard.
Post by Guy Rouillier
Are there any suggestions or guidelines on the appropriate
uses of these different string types?
Well, you can see how the classes are used and keep the same when
making changes - it's not that complicated really.

I would advise to use CStr rather than CPStr.

I am still not sure about the migration to std::string so for now you
can use either one whichever looks more comfortable. Any input on
that? This will require writing and re-writing some tool routines and
since std::string doesn't take NULLs it will cause some crashes until
it's wired properly. But if the general feeling is to go with the
standard we could do that.

I will see if I can organize all that a little bit better but if I do
then it will break gCvs and MacCvs compilation so be prepared for a
little catch-up ;)

Best Regards,
Jerzy








Yahoo! Groups Links

<*> To visit your group on the web, go to:
http://groups.yahoo.com/group/cvsgui-dev/

<*> To unsubscribe from this group, send an email to:
cvsgui-dev-***@yahoogroups.com

<*> Your use of Yahoo! Groups is subject to:
http://docs.yahoo.com/info/terms/
Jens Miltner
2006-03-09 08:47:43 UTC
Permalink
Post by kaczoroj
UStr is same as CStr. CString is an MFC classs used on Windows-
specific code. std::string used by me recently as I was trying to see
how would that go if we tried to replace the above string classes with
std::string. Mixed feelings about that one - std::string is by far the
most crappy string class even invented. Unfortunately we can't use
CString (which is superb) so we are stuck with UStr for now. I want to
phase out UPStr (and consquently PCPStr) eventually.
Can you elaborate a bit on your (apparently bad) experience with
std::string?

Also, we could probably implement the MFC CString class API for the
other platforms and then use that class
(if it's really superior - convince me ;-)
Post by kaczoroj
I would advise to use CStr rather than CPStr.
I am still not sure about the migration to std::string so for now you
can use either one whichever looks more comfortable. Any input on
that? This will require writing and re-writing some tool routines and
since std::string doesn't take NULLs it will cause some crashes until
it's wired properly. But if the general feeling is to go with the
standard we could do that.
I will see if I can organize all that a little bit better but if I do
then it will break gCvs and MacCvs compilation so be prepared for a
little catch-up ;)
Personally, I wouldn't mind playing a little catch up if it reduces
the string class proliferation. I understand Guy's feelings/confusion
about the string classes and IMHO, a good many of them are just
leftovers from older days and/or expose unnecessary implementation
details (like the CPxxx classes, which, IIRC, use Pascal-style
strings for storage). Such implementation details shouldn't surface
in multiple classes but rather in different accessors for a single
string class.

Personally, since std::string is available on all platforms, I'd
suggest either migrating to std::string, or if this requires lots of
conversions due to the way strings need to be passed to the OS,
design a single string class that combines the requirements of all
platforms and has a standardized API (which is one of the things I
like about the STL containers), using OS-provided string classes as
the underlying storage wherever possible...

Just my €.02
</jum>




Yahoo! Groups Links

<*> To visit your group on the web, go to:
http://groups.yahoo.com/group/cvsgui-dev/

<*> To unsubscribe from this group, send an email to:
cvsgui-dev-***@yahoogroups.com

<*> Your use of Yahoo! Groups is subject to:
http://docs.yahoo.com/info/terms/
Guy Rouillier
2006-03-09 19:50:40 UTC
Permalink
kaczoroj wrote:

Jerzy, thank you for taking the time to provide this detailed overview.
I had actually spent some time before sending my original email to
look at these various classes.
Post by kaczoroj
UStr is same as CStr. CString is an MFC classs used on Windows-
specific code. std::string used by me recently as I was trying to see
how would that go if we tried to replace the above string classes with
std::string. Mixed feelings about that one - std::string is by far the
most crappy string class even invented. Unfortunately we can't use
CString (which is superb) so we are stuck with UStr for now. I want to
phase out UPStr (and consquently PCPStr) eventually.
I have Visual Studio and took a quick look at CString. Unfortunately,
it's copyrighted material so we can't just use it. But we could
duplicate it's functionality.
Post by kaczoroj
Post by Guy Rouillier
Are there any suggestions or guidelines on the appropriate
uses of these different string types?
Well, you can see how the classes are used and keep the same when
making changes - it's not that complicated really.
That's what I ended up doing. In CvsPrefs.cpp, I copied an existing
entry inside a qUnix block that used PCStr. In the code that uses this
value, I used UStr. Everything seems to be working.
Post by kaczoroj
I would advise to use CStr rather than CPStr.
I am still not sure about the migration to std::string so for now you
can use either one whichever looks more comfortable. Any input on
that? This will require writing and re-writing some tool routines and
since std::string doesn't take NULLs it will cause some crashes until
it's wired properly. But if the general feeling is to go with the
standard we could do that.
I took a quick look at Persistent.cpp. The major contribution it is
making is to store the instantiated values into a vector so they can be
processed as a group by SaveAll and LoadAll. I don't see why that
behavior has to be built into specialization of native data types. An
alternative would be to create a container object (called CvsPrefs
perhaps ;)) into which things that wish to persist can register
themselves. Instead of having a whole bunch of static CPersistentBool,
CPersistentInt, and PCStr, you can have simple bool, int and strings
that register themselves into the container.

The existing CvsPrefs class can be reorganized to do that. The class
itself could be considerably simplified. Instead of having individual
getters and setters for each preference, there could be a single
SetBoolean, SetInteger and SetString; the first two would just stringize
their argument and call SetString. The first parameter would a string
representing the preference name, and the second the preference value
(and a third a default, if desired, though it might be better to
identify the default when the individual preference is defined to the
container.)

This is the same behavior that is used in Ini files or properties files,
and in an embellished way, the Windows registry. With this approach, we
can then get rid of all these specialized persistent datatypes. Then we
can use or implement whatever string class suits our purposes. I
haven't used std:string much; I do mostly Java programming at work, and
I do remember feeling frustrated at how much functionality was missing
from std::string compared to Java's String class.
Post by kaczoroj
I will see if I can organize all that a little bit better but if I do
then it will break gCvs and MacCvs compilation so be prepared for a
little catch-up ;)
I'd suggest giving some time to perhaps come to a group consensus on
what direction would be preferred.
--
Guy Rouillier



Yahoo! Groups Links

<*> To visit your group on the web, go to:
http://groups.yahoo.com/group/cvsgui-dev/

<*> To unsubscribe from this group, send an email to:
cvsgui-dev-***@yahoogroups.com

<*> Your use of Yahoo! Groups is subject to:
http://docs.yahoo.com/info/terms/
Guy Rouillier
2006-03-27 03:56:43 UTC
Permalink
Post by Guy Rouillier
Jerzy, thank you for taking the time to provide this detailed overview.
I had actually spent some time before sending my original email to
look at these various classes.
Post by kaczoroj
UStr is same as CStr. CString is an MFC classs used on Windows-
specific code. std::string used by me recently as I was trying to see
how would that go if we tried to replace the above string classes with
std::string. Mixed feelings about that one - std::string is by far the
most crappy string class even invented. Unfortunately we can't use
CString (which is superb) so we are stuck with UStr for now. I want to
phase out UPStr (and consquently PCPStr) eventually.
I have Visual Studio and took a quick look at CString. Unfortunately,
it's copyrighted material so we can't just use it. But we could
duplicate it's functionality.
Post by kaczoroj
Post by Guy Rouillier
Are there any suggestions or guidelines on the appropriate
uses of these different string types?
Well, you can see how the classes are used and keep the same when
making changes - it's not that complicated really.
That's what I ended up doing. In CvsPrefs.cpp, I copied an existing
entry inside a qUnix block that used PCStr. In the code that uses this
value, I used UStr. Everything seems to be working.
Post by kaczoroj
I would advise to use CStr rather than CPStr.
I am still not sure about the migration to std::string so for now you
can use either one whichever looks more comfortable. Any input on
that? This will require writing and re-writing some tool routines and
since std::string doesn't take NULLs it will cause some crashes until
it's wired properly. But if the general feeling is to go with the
standard we could do that.
I took a quick look at Persistent.cpp. The major contribution it is
making is to store the instantiated values into a vector so they can be
processed as a group by SaveAll and LoadAll. I don't see why that
behavior has to be built into specialization of native data types. An
alternative would be to create a container object (called CvsPrefs
perhaps ;)) into which things that wish to persist can register
themselves. Instead of having a whole bunch of static CPersistentBool,
CPersistentInt, and PCStr, you can have simple bool, int and strings
that register themselves into the container.
The existing CvsPrefs class can be reorganized to do that. The class
itself could be considerably simplified. Instead of having individual
getters and setters for each preference, there could be a single
SetBoolean, SetInteger and SetString; the first two would just stringize
their argument and call SetString. The first parameter would a string
representing the preference name, and the second the preference value
(and a third a default, if desired, though it might be better to
identify the default when the individual preference is defined to the
container.)
This is the same behavior that is used in Ini files or properties files,
and in an embellished way, the Windows registry. With this approach, we
can then get rid of all these specialized persistent datatypes. Then we
can use or implement whatever string class suits our purposes. I
haven't used std:string much; I do mostly Java programming at work, and
I do remember feeling frustrated at how much functionality was missing
from std::string compared to Java's String class.
Post by kaczoroj
I will see if I can organize all that a little bit better but if I do
then it will break gCvs and MacCvs compilation so be prepared for a
little catch-up ;)
I'd suggest giving some time to perhaps come to a group consensus on
what direction would be preferred.
I've completed the changes I was working on (popup menu customization
and sorting by modTime) so I'm now turning my attention back to stored
settings. I didn't receive any feedback regarding my idea about
removing persistence from the data types and making that a property of
the container, i.e., CvsPrefs. I'd like to try to convert gCvs settings
to a plain text file before we release gCvs 2.0, so I'm going to work on
this next. If there are no objections on the idea, I can come up with
an initial implementation for purposes of discussion. As I said above,
the resulting CvsPrefs should be much simpler since it would only need a
single method to store and retrieve any setting (getString, putString.)
Of course, we'd add some wrappers around those two to make life
easier: getInt, getBoolean, etc.
--
Guy Rouillier



Yahoo! Groups Links

<*> To visit your group on the web, go to:
http://groups.yahoo.com/group/cvsgui-dev/

<*> To unsubscribe from this group, send an email to:
cvsgui-dev-***@yahoogroups.com

<*> Your use of Yahoo! Groups is subject to:
http://docs.yahoo.com/info/terms/
Jens Miltner
2006-03-27 04:34:05 UTC
Permalink
Post by Guy Rouillier
I didn't receive any feedback regarding my idea about
removing persistence from the data types and making that a property of
the container, i.e., CvsPrefs. I'd like to try to convert gCvs settings
to a plain text file before we release gCvs 2.0, so I'm going to work on
this next. If there are no objections on the idea, I can come up with
an initial implementation for purposes of discussion. As I said above,
the resulting CvsPrefs should be much simpler since it would only need a
single method to store and retrieve any setting (getString,
putString.)
Of course, we'd add some wrappers around those two to make life
easier: getInt, getBoolean, etc.
Just some thoughts:

At least for the global settings, MacCvs currently uses the
preference APIs provided by the OS, which has the advantage of
storing the prefs where they belong (among some others). Those APIs
are not string only, i.e. there are native storage APIs for numbers,
booleans, dates, etc. as well, which should be used if possible.

Essentially, when changing the CvsPrefs API, make sure the wrappers
aren't pure wrappers but also allow them to contain the 'real'
implementation for some platform.

Another thing to consider would be to make the sandbox settings
local, i.e. don't use global variables to hold the values: at least
MacCvs allows to open more than one sandbox browser simultaneously
and currently, it's a bit of a hack to switch settings when a window
comes to front (because settings are global in the current
implementation).
I already started some work long ago to make the settings local, i.e.
there would be a settings object that would get passed around and you
could have multiple instances of settings objects, but never
committed the work to the main branch (mainly because there were
other, more important changes and after a while, the modified branch
was completely out of sync). The code still exists on a branch, but
it's probably more work to merge it than to come up with a new
implementation now, especially if you're trying to get rid of the
persistent objects anyway...

</jum>




Yahoo! Groups Links

<*> To visit your group on the web, go to:
http://groups.yahoo.com/group/cvsgui-dev/

<*> To unsubscribe from this group, send an email to:
cvsgui-dev-***@yahoogroups.com

<*> Your use of Yahoo! Groups is subject to:
http://docs.yahoo.com/info/terms/
Guy Rouillier
2006-03-28 03:56:49 UTC
Permalink
Post by Jens Miltner
Another thing to consider would be to make the sandbox settings
local, i.e. don't use global variables to hold the values: at least
MacCvs allows to open more than one sandbox browser simultaneously
and currently, it's a bit of a hack to switch settings when a window
comes to front (because settings are global in the current
implementation).
Jens, thanks for the reply. I don't use the Mac, so please help me
understand what you mean by local sandbox settings. Do these get
persisted or is their lifetime only while the app instance is running?
If they get persisted, what differentiates one set from another? Are
they connected to a specific project, like non-global settings? If so,
could we persist them in the same store that maintains the project settings?

Perhaps what we should do is use the global settings as the default, and
allow the project settings to override. If we do that, I'd like to
break out Admin-Preferences into two separate menu items: Global
settings and Project settings. Having two sets of the same settings in
a single dialog box would get very confusing.

Let's be explicit. In gCvs, on the Preferences dialog is a Globals tab
with the following settings:

Checkout read=only
Use TCP/IP compression
Quiet mode
Dirty files support
Prune empty directories
Supply control when adding files

In WinCvs, I see

File attribute (equivalent to Checkout read-only in gCvs)
CVS Messages (equivalent to Quiet mode in gCvs)
Prune empty directories
Compression level
Encrypt communication
Checkout text files with Unix LF
Disable splash screen
Supply control when adding files
Match path case with Entries case
Logout automatically after N minutes

Are these the ones you are referring to, or are you referring to
everything in the Settings dialog?

Regardless, I still like the idea of having Project setting inherit the
global ones but allow for override. But now having written all this, it
sounds like a better name would be "Default settings" and then "Project
settings".

Some things seem truly global, like path to CVS executable, preferred
external diff program. Why would you want that to vary by project?
Perhaps we need to revisit what is a global and what is per project.
--
Guy Rouillier



Yahoo! Groups Links

<*> To visit your group on the web, go to:
http://groups.yahoo.com/group/cvsgui-dev/

<*> To unsubscribe from this group, send an email to:
cvsgui-dev-***@yahoogroups.com

<*> Your use of Yahoo! Groups is subject to:
http://docs.yahoo.com/info/terms/
Jens Miltner
2006-03-28 07:30:18 UTC
Permalink
Post by Guy Rouillier
Post by Jens Miltner
Another thing to consider would be to make the sandbox settings
local, i.e. don't use global variables to hold the values: at least
MacCvs allows to open more than one sandbox browser simultaneously
and currently, it's a bit of a hack to switch settings when a window
comes to front (because settings are global in the current
implementation).
Jens, thanks for the reply. I don't use the Mac, so please help me
understand what you mean by local sandbox settings. Do these get
persisted or is their lifetime only while the app instance is running?
If they get persisted, what differentiates one set from another? Are
they connected to a specific project, like non-global settings? If so,
could we persist them in the same store that maintains the project settings?
The current implementation already differentiates between "global"
and "project" settings: when constructing a CPersistent, it takes a
kClassPersistent argument, which uses the completely non-intuitive
enum values "kNoClass" and "kAddSettings". Values of type "kNoClass"
are considered global variables and values of type "kAddSettings" are
stored on a per-sandbox basis.

In the Mac implementation, the two classes of settings are also
stored in different locations: the global ones are stored in the
standard system preference location (kind of similar to the Windows
Registry), whereas the per-sandbox settings are stored in text files
in a specific subdirectory of the Mac's Preference folder. Each text
file contains (among other settings) the sandbox path, so the
settings can be identified to be connected to that sandbox...
I'm pretty sure the basic mechanism is the same for the other
platforms, IIRC, even the implementation for the per-sandbox settings
is shared, the only differences are the location where things are
stored and the storage format of the global settings.
Post by Guy Rouillier
Perhaps what we should do is use the global settings as the
default, and
allow the project settings to override. If we do that, I'd like to
break out Admin-Preferences into two separate menu items: Global
settings and Project settings. Having two sets of the same
settings in
a single dialog box would get very confusing.
I think in general, the idea to allow overriding a global setting is
good, however, there are certainly some settings that you would want
to toggle globally, i.e. you don't want to check with each sandbox
whether they have been defined there. You mentioned the cvs
executable, which is a good example of such a setting...

In general, I think the current classification between global and per-
sandbox settings isn't too bad, the only thing missing is a defined
way to specify your default settings and allow to override specific
settings per-sandbox. Right now, you can specify which settings to
use as the starting point when browsing a new sandbox (at least
that's how it works in MacCvs), but once you picked the settings,
this contains all settings, i.e. changing the default settings won't
affect any existing sandbox...
Post by Guy Rouillier
Let's be explicit. In gCvs, on the Preferences dialog is a Globals tab
Checkout read=only
Use TCP/IP compression
Quiet mode
Dirty files support
Prune empty directories
Supply control when adding files
In WinCvs, I see
File attribute (equivalent to Checkout read-only in gCvs)
CVS Messages (equivalent to Quiet mode in gCvs)
Prune empty directories
Compression level
Encrypt communication
Checkout text files with Unix LF
Disable splash screen
Supply control when adding files
Match path case with Entries case
Logout automatically after N minutes
Are these the ones you are referring to, or are you referring to
everything in the Settings dialog?
Regardless, I still like the idea of having Project setting inherit the
global ones but allow for override. But now having written all this, it
sounds like a better name would be "Default settings" and then
"Project
settings".
Some things seem truly global, like path to CVS executable, preferred
external diff program. Why would you want that to vary by project?
Perhaps we need to revisit what is a global and what is per project.
As I mentioned above, the distinction between global and per-project
(or per-sandbox) settings is already there...

The other thing I was referring to were the 'local' settings: In
MacCvs, you can have more than one browser window open, each one
pointing to a different sandbox. However, the current settings
implementation uses global CPersistent instances to access the
settings. This means that theoretically, each of the browsers would
access the very same settings. The current solution in MacCvs is to
switch the settings when bringing another browser window to front,
i.e. store the modified settings of the browser/sandbox being
deactivated and load the settings for the browser becoming the front/
focused window. This is really a big hack, since if there was some
code that would read settings for a background window, this code
would suddenly get the settings for the other sandbox!
In order to solve this problem, I started once to make the
CPersistent values dynamically allocated and create a
CPersistentContainer that would encompass the set of persistent
values that comprise the sandbox settings. Then the browser would
keep a pointer to the CpersistentContainer object and ask this object
for specific settings. Essentially, it's pretty much making the
CvsPrefs class not a singleton, but allocated dynamically where each
instance keeps it's own set of settings (except for the global
settings, which are, of course, shared among all instances, to make
them - well - global ;-)

This involved quite a dose of code changes, since the settings object
needs to be passed around to anything that needs access to the
settings. There were also a couple of places left where I haven't yet
come up with a proper solution - like e.g. the timer code that
automatically logs out after a specified interval. This code is -
most likely - broken anyway on the Mac, since it assumes there is a
single cvs pserver we're connected to, but if you have multiple
browser windows open, chances are you are logged into more than one
server...

Anyway, the main issue here is that switching to a 'local settings'
model requires some major API changes to pass the settings around,
but it would also allow things like 'shoot and forget' style cvs
command handling, i.e. allow to kick off one cvs command and without
having to wait for this command to finish, immediately kick off the
next command. This may even be helpful for single browser
implementations, where you wouldn't have to wait for certain
commands to finish before launching the next command (e.g. update one
subdirectory, commit another one, etc.)

IMHO, the switch to 'local' settings is the more important step over
the switch to overridable settings and/or replacing the CPersistent
model. However, when breaking the APIs anyway, it would certainly be
a good time to adjust the persistent model as well.

Personally, my favorite settings implementation would really look
something like this:

class Settings
{
public:
static Settings* CreateSettingsForPath(const char* sandboxPath);

void Read();
void Write();

bool GetString(const char* key, std::string& value);
void SetString(const char* key, const std::string& value);

bool GetInt(const char* key, int& value);
void SetInt(const char* key, int value);

bool GetBool(const char* key, bool& value);
void SetBool(const char* key, bool value);

// ... more specific accessors could go here

// this one allows to retrieve lists of [sub-]settings - this one
would allow to implement things like persistent string lists
// (e.g. the list of previous CVSROOTs)
bool GetArray(const char* key, std::vector<Settings>& valueArray);
void SetArray(const char* key, const std::vector<Settings>&
valueArray);
};

We'd pass around a settings object and any code needing settings
would ask that settings object for the specific setting values.
The settings class is responsible for reading/writing settings in a
type-safe manner, i.e. it would check for proper values when reading
settings (which would also be platform specific to allow storing the
settings in a platform specific manner - PropertyList files on Mac
OS, perhaps Registry on Windows, ASCII files in ~/.gCvs/Settings/ on
Linux).

Alternatively, the accessor APIs could just return the value itself,
e.g.
std::string GetString(const char* key);
If the settings value is not specified in the project settings, a
default value would be returned. Maybe that's even easier, although
it might be nice to have both APIs (in case you need to check for the
existence of certain settings). The second variant could then just
use the first one internally and provide the default value if the
first one returns false...

just my €.02,
</jum>




Yahoo! Groups Links

<*> To visit your group on the web, go to:
http://groups.yahoo.com/group/cvsgui-dev/

<*> To unsubscribe from this group, send an email to:
cvsgui-dev-***@yahoogroups.com

<*> Your use of Yahoo! Groups is subject to:
http://docs.yahoo.com/info/terms/
Guy Rouillier
2006-03-29 05:51:19 UTC
Permalink
Jens, thanks for the detailed explanation. I'm going to narrow this
post to one particular issue I'm still not clear about.
Post by Jens Miltner
The other thing I was referring to were the 'local' settings: In
MacCvs, you can have more than one browser window open, each one
pointing to a different sandbox. However, the current settings
implementation uses global CPersistent instances to access the
settings. This means that theoretically, each of the browsers would
access the very same settings. The current solution in MacCvs is to
switch the settings when bringing another browser window to front,
i.e. store the modified settings of the browser/sandbox being
deactivated and load the settings for the browser becoming the front/
focused window. This is really a big hack, since if there was some
code that would read settings for a background window, this code
would suddenly get the settings for the other sandbox!
My unfamiliarity with the Mac runtime environment is causing me
confusion. I just fired up one instance of gCvs and set it to one
sandbox. Then I opened up a second gCvs instance and set it to a
different sandbox. I was able to draw graphs for each of those open
instances. Each instance (i.e., process) has it's own gCvsPrefs global
object.

Are you saying that on the Mac, this gCvsPrefs object is shared among
all running instances? So the Mac runtime environment has a shared data
segment for all running instances of a given executable? If so, that's
unique; the only thing like that I've experienced is global data
segments in Windows. In Unix as far as I know, all data is private to a
process unless you specifically allocate shared memory.

Is the app pointer shared between instances in Mac or is that per
instance? If the latter, maybe the most straightforward way to address
this would be to make the CvsPrefs object a member of the app object.
If we want truly global settings that are immediately reflected in all
running instances, we could use a shared memory approach. Though
personally, I don't think I'd like the behavior of a running instance to
change because I changed something in another instance. I think any
changes to truly global settings should only be reflected in the
instance where the change is made, and in all new instances started
after that change. That dispenses with the need for shared memory.
--
Guy Rouillier



Yahoo! Groups Links

<*> To visit your group on the web, go to:
http://groups.yahoo.com/group/cvsgui-dev/

<*> To unsubscribe from this group, send an email to:
cvsgui-dev-***@yahoogroups.com

<*> Your use of Yahoo! Groups is subject to:
http://docs.yahoo.com/info/terms/
kaczoroj
2006-03-27 20:09:33 UTC
Permalink
Guy,

By now I have made up my mind and I am altering the code to use std::
string as we speak. That will eliminate needless implememntations of
string functionality all other again at the price of writing some
utility functions to make the std::string actually usefull ;)

Having that we can see what to do next.
Instead of having individual getters and setters for
each preference, there could be a single SetBoolean,
SetInteger and SetString;
Current persistency implementation is not too bad actually. If we are
going to use the "named" settings storage we will loose type safety.
It is also quire error-prone as you are just one typo away from not
getting what you want. It's also hard to track the changes in the
names etc...

But the most troublesome is that current implementation is deeply
entrenched and works well with the code we have. It would be a huge
task to change that now, not to mention that we need to migrate data
from the old to the new storage format so we would have two systems
operational.

The idea of making settings more "local" so that MDI can be better
supported is probably more realistic.

Best Regards,
Jerzy








Yahoo! Groups Links

<*> To visit your group on the web, go to:
http://groups.yahoo.com/group/cvsgui-dev/

<*> To unsubscribe from this group, send an email to:
cvsgui-dev-***@yahoogroups.com

<*> Your use of Yahoo! Groups is subject to:
http://docs.yahoo.com/info/terms/
Guy Rouillier
2006-03-28 04:57:47 UTC
Permalink
Post by kaczoroj
Guy,
string as we speak. That will eliminate needless implememntations of
string functionality all other again at the price of writing some
utility functions to make the std::string actually usefull ;)
Great! Thanks for taking the lead on that.
Post by kaczoroj
Having that we can see what to do next.
Instead of having individual getters and setters for
each preference, there could be a single SetBoolean,
SetInteger and SetString;
Current persistency implementation is not too bad actually. If we are
going to use the "named" settings storage we will loose type safety.
It is also quire error-prone as you are just one typo away from not
getting what you want. It's also hard to track the changes in the
names etc...
The typo issue is easily resolved. You can have an association between
a list of allowed values (enum, array, whatever) and an associated
character string that gets persisted. For example:

CONSOLE_FONT ==> "P_ConsoleFont"

The API would only take the constant values, something like
setString(CONSOLE_FONT, "courier 10"). The actual names would only be
stored on one place, so tracking changes would be trivial.

I think addressing type safety is doable without too much effort. Once
I get a reply from Jens to help me understand the specific issue he is
addressing, I can think about this a little more clearly. Hmmm, just as
I was about to click the "send" button, I had a late-breaking thought
about type safety. If we come up with a list of allowable types, like
P_TYPE_BOOLEAN, P_TYPE_STRING, P_TYPE_INTEGER, etc, then when a method
like setBoolean(ALWAYS_USE_CVSROOT, true), we could automatically make
sure that ALWAYS_USE_CVSROOT is of type P_TYPE_BOOLEAN.

The current implementation works, but adding a setting shouldn't require
so many changes. Think about Windows INI file handling as an example.
You don't have to declare a separate variable for each individual
setting and then use a separate setter and getter for each one.
Post by kaczoroj
But the most troublesome is that current implementation is deeply
entrenched and works well with the code we have. It would be a huge
task to change that now, not to mention that we need to migrate data
from the old to the new storage format so we would have two systems
operational.
If we are only changing the code implementation, we wouldn't necessarily
have to change the on-disk representation. But your point about having
to change code is valid. I'm not sure it would be any more drastic than
changing our string implementation. Besides, CPersistentBool seems like
a kludge that needs fixing, regardless of the effort.
Post by kaczoroj
The idea of making settings more "local" so that MDI can be better
supported is probably more realistic.
If we are to undertake that, then changing the framework at the same
time might make sense.
--
Guy Rouillier



Yahoo! Groups Links

<*> To visit your group on the web, go to:
http://groups.yahoo.com/group/cvsgui-dev/

<*> To unsubscribe from this group, send an email to:
cvsgui-dev-***@yahoogroups.com

<*> Your use of Yahoo! Groups is subject to:
http://docs.yahoo.com/info/terms/
Oliver Giesen
2006-03-29 07:10:08 UTC
Permalink
Post by Guy Rouillier
My unfamiliarity with the Mac runtime environment is causing me
confusion. I just fired up one instance of gCvs and set it to one
sandbox. Then I opened up a second gCvs instance and set it to a
different sandbox. I was able to draw graphs for each of those open
instances. Each instance (i.e., process) has it's own
gCvsPrefs global object.
This is not about multiple instances. One MacCvsX instance can have multiple independent file view windows (aka "MDI"). Just take a look at the screenshots:
http://cvsgui.sf.net/shots.html#MACCVS

Cheers,

Oliver
---- ------------------
MSN: ***@hotmail.com
ICQ: 18777742 (http://wwp.icq.com/18777742)
Y!: ogiesen


[Non-text portions of this message have been removed]




Yahoo! Groups Links

<*> To visit your group on the web, go to:
http://groups.yahoo.com/group/cvsgui-dev/

<*> To unsubscribe from this group, send an email to:
cvsgui-dev-***@yahoogroups.com

<*> Your use of Yahoo! Groups is subject to:
http://docs.yahoo.com/info/terms/
Jens Miltner
2006-03-29 07:54:10 UTC
Permalink
Post by Oliver Giesen
Post by Guy Rouillier
My unfamiliarity with the Mac runtime environment is causing me
confusion. I just fired up one instance of gCvs and set it to one
sandbox. Then I opened up a second gCvs instance and set it to a
different sandbox. I was able to draw graphs for each of those open
instances. Each instance (i.e., process) has it's own
gCvsPrefs global object.
This is not about multiple instances. One MacCvsX instance can have
multiple independent file view windows (aka "MDI"). Just take a
http://cvsgui.sf.net/shots.html#MACCVS
Yes, it is as Oliver explained. In contrast to Windows and the Linux
workspaces, the Mac OS runtime environment / UI paradigm is such that
usually only a single instance of an application runs and manages
multiple document windows. This also somewhat enforced by the OS /
FileManager (aka "Finder") since double clicking an application to
launch it will first check whether it's already running and make the
running instance front if it's found. Double clicking documents will
also check for the app running and pass the documents to the running
instance and won't launch new instances.

So, essentially, there will always be only one instance of MacCvsX
running at a time, but this instance can handle multiple browser
windows and as such should be able to arbitrate the settings between
the browsers.
And since this (the singleton-app) is such a basic UI paradigm on
Mac OS, we can't just go ahead and launch multiple instances of
MacCvs...

</jum>




Yahoo! Groups Links

<*> To visit your group on the web, go to:
http://groups.yahoo.com/group/cvsgui-dev/

<*> To unsubscribe from this group, send an email to:
cvsgui-dev-***@yahoogroups.com

<*> Your use of Yahoo! Groups is subject to:
http://docs.yahoo.com/info/terms/
Guy Rouillier
2006-03-30 03:50:42 UTC
Permalink
Post by Jens Miltner
So, essentially, there will always be only one instance of MacCvsX
running at a time, but this instance can handle multiple browser
windows and as such should be able to arbitrate the settings between
the browsers.
And since this (the singleton-app) is such a basic UI paradigm on
Mac OS, we can't just go ahead and launch multiple instances of
MacCvs...
Ok, thank you Oliver and Jens for clarifying. Some ideas are starting
to gel:

(1) Persistence should be a characteristic of a (persistence) container,
not of data types. Ideally, we should be able to use simple data types
(int, float, boolean, String) and delegate to the container how to
persist them and retrieve them.

(2) If we use the concept of a generalized persistence container, then
we can have any number of them. We can have one at application (global)
scope, and one for *each* sandbox/instance/project/repository/local
(pick the term you like.) Each container should know how to persist and
populate itself.

(3) Each individual setting that goes into a persistence container is
just a simple data value of a defined data type. It doesn't need to be
identified as being of scope global (kNoClass) or of scope instance
(kAddSettings), nor does it need to be of a specialized persistence data
type like CPersistentBool. It automatically becomes a persistent data
value when it is added to a persistence container, and it becomes a
persistent data value of a particular scope depending on *which*
persistence container you put it in. You can even have a data value of
the exact same name in two or more persistence containers. That would
be the norm, actually, since all sandbox containers would likely have
the same set of data values.

(4) To keep a persistence container generalized, the container itself
should not have to understand that it is "higher" or "lower" in a
persistence hierarchy than any other persistence container. Each should
be self-contained. If a hierarchy exists, that hierarchy should be
established external to the persistence container (perhaps in a
persistence hierarchy tree.) That may be more than is necessary;
perhaps we only have a 2-level hierarchy, local and global.

(5) Which class or classes in the CvsGui class structure should contain
a persistence container is really a different design decision from the
implementation of the persistence container itself. I'm really not
well-versed enough in the entire CvsGui set of classes to make a
well-informed decision there. I notice in AppGlue that all platforms
have an app class; that would seem a logical place for a global
preferences container. Would CCvsSandboxInfo be the correct place for a
sandbox-level persistence container?

After writing all this, persistence containers seem to be just an
in-memory representation for the persistent data values maintained in
the file system. Logical, I suppose, so we might as well take advantage
of all the knowledge that has been accumulated in implementing those.

I'll come up with a straw-man implementation for a persistence container
that we can kick around for ideas.
--
Guy Rouillier



Yahoo! Groups Links

<*> To visit your group on the web, go to:
http://groups.yahoo.com/group/cvsgui-dev/

<*> To unsubscribe from this group, send an email to:
cvsgui-dev-***@yahoogroups.com

<*> Your use of Yahoo! Groups is subject to:
http://docs.yahoo.com/info/terms/
Jens Miltner
2006-03-30 07:33:24 UTC
Permalink
Post by Guy Rouillier
Ok, thank you Oliver and Jens for clarifying. Some ideas are starting
(1) Persistence should be a characteristic of a (persistence)
container,
not of data types. Ideally, we should be able to use simple data types
(int, float, boolean, String) and delegate to the container how to
persist them and retrieve them.
(2) If we use the concept of a generalized persistence container, then
we can have any number of them. We can have one at application (global)
scope, and one for *each* sandbox/instance/project/repository/local
(pick the term you like.) Each container should know how to
persist and
populate itself.
(3) Each individual setting that goes into a persistence container is
just a simple data value of a defined data type. It doesn't need to be
identified as being of scope global (kNoClass) or of scope instance
(kAddSettings), nor does it need to be of a specialized persistence data
type like CPersistentBool. It automatically becomes a persistent data
value when it is added to a persistence container, and it becomes a
persistent data value of a particular scope depending on *which*
persistence container you put it in. You can even have a data
value of
the exact same name in two or more persistence containers. That would
be the norm, actually, since all sandbox containers would likely have
the same set of data values.
(4) To keep a persistence container generalized, the container itself
should not have to understand that it is "higher" or "lower" in a
persistence hierarchy than any other persistence container. Each should
be self-contained. If a hierarchy exists, that hierarchy should be
established external to the persistence container (perhaps in a
persistence hierarchy tree.) That may be more than is necessary;
perhaps we only have a 2-level hierarchy, local and global.
I generally agree with your concept here, although from a 'users'
perspective (i.e. when 'using' the persistence containers), it may be
simpler to have the hierarchy defined intrinsically, so you don't
have to do things like:
if ( sandboxSettings->GetIntegerValue("foo", fooValue) )
globalSettings->GetIntegerValue("foo", fooValue);

If each persistence container could have a fallback persistence
container, it could ask the fallback container if it doesn't find a
value. In our case, the sandbox settings would be constructed with a
pointer to the global settings container, i.e. if a value doesn't
exist in the sandbox settings, the settings container will fallback
to asking the global settings container. Theoretically, even the
global settings container could have a fallback settings container,
which contains hardwired defaults...

Does that make sense to you?

</jum>




Yahoo! Groups Links

<*> To visit your group on the web, go to:
http://groups.yahoo.com/group/cvsgui-dev/

<*> To unsubscribe from this group, send an email to:
cvsgui-dev-***@yahoogroups.com

<*> Your use of Yahoo! Groups is subject to:
http://docs.yahoo.com/info/terms/
Guy Rouillier
2006-03-31 04:43:54 UTC
Permalink
Post by Jens Miltner
I generally agree with your concept here, although from a 'users'
perspective (i.e. when 'using' the persistence containers), it may be
simpler to have the hierarchy defined intrinsically, so you don't
if ( sandboxSettings->GetIntegerValue("foo", fooValue) )
globalSettings->GetIntegerValue("foo", fooValue);
If each persistence container could have a fallback persistence
container, it could ask the fallback container if it doesn't find a
value. In our case, the sandbox settings would be constructed with a
pointer to the global settings container, i.e. if a value doesn't
exist in the sandbox settings, the settings container will fallback
to asking the global settings container. Theoretically, even the
global settings container could have a fallback settings container,
which contains hardwired defaults...
Does that make sense to you?
Yes, after sending my last post, I thought of the same thing. With our
known 2-level hierarchy, usability may be simplified by embedding a
parent pointer. I'll give that a try. Thanks.
--
Guy Rouillier



Yahoo! Groups Links

<*> To visit your group on the web, go to:
http://groups.yahoo.com/group/cvsgui-dev/

<*> To unsubscribe from this group, send an email to:
cvsgui-dev-***@yahoogroups.com

<*> Your use of Yahoo! Groups is subject to:
http://docs.yahoo.com/info/terms/
Loading...