As originally codified:
- The scope is all "reasonably modern" flavors of Unix, X11, and C++.
- Limit language features to those that reliably compile.
- Respect the holy mantra "./configure; make; make install".
- Allow trivial workarounds for platform- and distribution-specific bugs or special requirements.
- Disallow nontrivial workarounds and those that conflict with
correct operation on non-broken platforms.
- Limit hard dependencies on external tools and libraries to those that
are typically pre-installed.
- Maximize orthogonality of settings and switches.
- Support both interactive and non-interactive use.
- Command-line switches should be no more than two characters long.
- Accept no bogus patches.
- Maximize orthogonality of modules.
- Accept no bogus patches.
- Use no unstable tools or libraries.
- If it ain't broke, don't fix it.
- If it damages usability or maintainability, it's considered broke.
- Do not merely deprecate that which deserves to be deleted.
As it happened:
- Within the original scope, no Unix but Linux and no compiler
but GCC gets much testing anymore.
- Scope creep: the workarounds that are included to allow building
the command-line client with Visual Studio are ridiculous.
- Building libxtide for Android required few source code changes but
plenty of autoconf tricks.
- The font settings are context-sensitive.
- I have accepted some bogus patches and made them
work, but no more.
- Font and character set handling has become totally non-orthogonal
because every context is different.
- libXaw3dXft has been unstable (every update breaks the XTide build, but there are no version defines to check).
- The –ns and –nf switches are deprecated but deserve to be deleted.
XTide has a long history of harmonics file woes and has been through
four different file formats trying to solve them.
XTide 1 used a nice, human-readable text format (harmonics.txt)
but it was neither efficient nor extensible. New fields that
were really, really necessary got wedged in as "hot comments,"
initiating a long downhill slide into architectural chaos.
Unwisely, XTide 2 perpetuated the harmonics.txt format but added a
new, extensible XML format for subordinate stations only
(offsets.xml). It was anticipated that one of two things would
eventually happen: either a reasonably functional and stable SQL
database would become standard issue with the average Unix, obviating
the need to avoid that external dependency, or harmonics.txt would go
away and all stations would be done in extensible XML. Neither
one happened. Migration to XML was put off repeatedly because it
would exacerbate the performance bottleneck.
Everybody suffered with the lousy performance until Jan Depner
proposed to implement a binary format (TCD). TCD1 fixed the
performance problem but the extensibility problem persisted. New
fields could be added with just minor changes to libtcd, but then you
needed to recompile the world. Old versions of XTide couldn't
read new harmonics files after fields were added. This had a
major chilling effect on all development that would have required new
TCD2 (a major, incompatible revision) emptied the queue of
incompatible changes but also added a field whose content is
extension fields encoded as text. Adding fields this
way is not as efficient as adding new binary fields, but it avoids the
need to make an incompatible revision over small stuff. The
option to add new binary fields and bump the major rev remains open
should that become necessary.
Unfortunately, as I forget who once observed, "The worst enemy of the
great is the barely good enough." Among the downstream user community,
the obsolete and hopeless .txt and .xml formats refuse to die.
Consensus is that the XTide source code does a miserable job of separating
the user interfaces from the reusable tide-prediction logic. As of
XTide 2.14 the common files have at least been bundled into a library that
can be built upon without making too much of a mess. However, the XML
parser still protrudes into the global namespace, conflicting with any other
lex/yacc type parser that the app might want to link with.
Lots of serious design problems were fixed in refactorings beginning
with version 2.7 (early 2004) and continuing through version
2.9. Remaining minor problems:
- The interface with X11 is still weird, especially bootstrapping.
- The analog tide clock icon caused more problems (with buggy
window managers) than it was worth.
- URLs assigned to prediction pages by the web server should
probably be based on the harmonics file name and the location name
rather than a transient "row ID."
- Constituent inference was patched in via libtcd and maybe could have
been integrated better. In theory, you might want to control it
on a station-by-station basis like preferred units, and it probably
should not require a station reload to turn it on or off.
- Graph and calendar modes are implemented by transient classes.
These are not proper objects, but they are too complicated to be implemented
with methods alone.
- libtcd doesn't let you know whether you are looking at a tide
station or a current station until after you load it.
- The mechanism that XTide 2.13 and later use to get client side fonts for
use in tide graphs is an abomination.
- Calendar mode needs an "extended subset" of the settings that every
other mode uses.
- Application-specific error messages don't belong in libxtide.
- Graph mode is a bottomless source of requests for more settings to
C++ feature footprint
At the time XTide 2 was
developed, the fancier features of C++ such as the Standard Template
Library (STL) and exceptions did not work in a portable fashion among the
commonly available compilers, so their use was avoided.
Similarly, Qt and other free
alternatives to Motif were not widely available, so Athena Widgets
were used. The resulting interface may seem primitive
by today's standards, but it still works.
By the time of the 2.7 refactorings, the STL appeared to be stable
and widely available, so standard templates were introduced where
appropriate to simplify new code. Old code was not STLified
until the Great Cleanup of 2006 (XTide 2.9).
long long int data type was introduced in XTide 2.6 as
part of the changes to handle dates before 1970 and after 2037. Nobody
Streams were expunged from XTide 2.6 after compilers started
deprecating XTide's use of them. In XTide, C++ streams did not
add value versus plain old C I/O, but this is not the case for
bool data type was introduced in XTide 2.9. C++11
extended initializer lists were used in new code in XTide 2.13, but made
optional in XTide 2.13.1 because of continued non-support in Visual Studio
Exceptions are still not used, but should be. The bounds-checking
operation of SafeArray should be replaced with the now-standard at()
A uniform coding convention was imposed in XTide 2.9 (year 2006).
See the file
CodingConventions.txt included in the distribution
tarball. As of 2012, particularly with the issuance of C++11, it has
become problematically obsolete in some areas.
Paths not taken
- There ought to be a way to specify relative dates and times in the
–b and –e fields. Need an applicable standard; ISO 8601
doesn't support it.
- Generate maps for xttpd navigation and general illustration, include in
- Several people have asked for a line in text listings for the current
time, like "2001-03-19 11:50 AM PST 0.10 feet Falling," but it's not clear
what the settings and behaviors should be to handle the "now" event
consistently across all modes. Graphs and clocks have their own ways of
showing the "now," and it would be inappropriate to include "now" in a
- Most tide prediction software generates node factors and equilibrium
arguments monthly or at least does it for the middle of your prediction
interval, but the legacy of SP98 is to do it yearly.
- Doodson style tide prediction as used by Godin/Foreman's IOS package:
- No new Doodson data appear to be forthcoming.
- Most Doodson constituents are approximated fairly well by Congen.
The ones that aren't approximated well are those that are drastically
affected by latitude. To support latitude-dependent constituents, node
factors and equilibrium arguments would have to be generated internally to
XTide, which would be a significant architectural change. [Casement
opined that the latitude-dependent method is bogus anyway because tides are
generated someplace in mid-ocean with a different latitude.]
- If you want IOS, then use IOS.