Specifically, this enables -Wswitch=error on GCC/Clang and its MSVC
equivalent; the exact way it is handled varies slightly, but what
they all have in common is that in a switch statement over an
enumeration, any enumerand that is not explicitly (via case:) or
implicitly (via default:) handled in the switch triggers an error.
Moreover, we also change the switch statements in three ways:
* Switch statements that ought to be extended every time a new
enumerand is added (e.g. Entity::DrawOrGetDistance(), are changed
to explicitly list every single enumerand, and not have a
default: branch.
Note that the assertions are kept because it is legal for
a enumeration to have a value unlike any of its defined
enumerands, and we can e.g. read garbage from a file, or
an uninitialized variable. This requires some rearranging if
a default: branch is undesired.
* Switch statements that ought to only ever see a few select
enumerands, are changed to always assert in the default: branch.
* Switch statements that do something meaningful for a few
enumerands, and ignore everything else, are changed to do nothing
in a default: branch, under the assumption that changing them
every time an enumerand is added or removed would just result
in noise and catch no bugs.
This commit also removes the {Request,Entity,Constraint}::UNKNOWN and
Entity::DATUM_POINT enumerands, as those were just fancy names for
zeroes. They mess up switch exhaustiveness checks and most of the time
were not the best way to implement what they did anyway.
This follows the previous commit. Unlike it, though, a small change
to control flow is made to separate the command and pending operation
enumerations.
Specifically, take the old code that looks like this:
class Foo {
enum { X = 1, Y = 2 };
int kind;
}
... foo.kind = Foo::X; ...
and convert it to this:
class Foo {
enum class Kind : uint32_t { X = 1, Y = 2 };
Kind kind;
}
... foo.kind = Foo::Kind::X;
(In some cases the enumeration would not be in the class namespace,
such as when it is generally useful.)
The benefits are as follows:
* The type of the field gives a clear indication of intent, both
to humans and tools (such as binding generators).
* The compiler is able to automatically warn when a switch is not
exhaustive; but this is currently suppressed by the
default: ssassert(false, ...)
idiom.
* Integers and plain enums are weakly type checked: they implicitly
convert into each other. This can hide bugs where type conversion
is performed but not intended. Enum classes are strongly type
checked.
* Plain enums pollute parent namespaces; enum classes do not.
Almost every defined enum we have already has a kind of ad-hoc
namespacing via `NAMESPACE_`, which is now explicit.
* Plain enums do not have a well-defined ABI size, which is
important for bindings. Enum classes can have it, if specified.
We specify the base type for all enums as uint32_t, which is
a safe choice and allows us to not change the numeric values
of any variants.
This commit introduces absolutely no functional change to the code,
just renaming and change of types. It handles almost all cases,
except GraphicsWindow::pending.operation, which needs minor
functional change.
This will allow us in future to accept `const T &` anywhere it's
necessary to reduce the amount of copying.
This commit is quite conservative: it does not attempt very hard to
refactor code that performs incidental mutation. In particular
dogd and caches are not marked with the `mutable` keyword.
dogd will be eliminated later, opening up more opportunities to
add const qualifiers.
This commit also doesn't introduce any uses of the newly added const
qualifers. This will be done later.
This includes explanation and context for non-obvious cases and
shortens debug cycles when just-in-time debugging is not available
(like on Linux) by immediately printing description of the assert
as well as symbolized backtrace.
This helps to ensure that a base class that changes underneath us
would not leave any overridden functions hanging.
This already highlighted some questionable use of GTKMM's API,
which were also fixed in this commit.
This is a high-SNR warning that's enabled by default on MSVC and
it has highlighted some bugs in glhelper.cpp (that are also fixed
in this commit).
Unfortunately GCC does not have an equivalent for that warning,
and -Wconversion is very noisy.
MSVC 2013 keeps having aggravating bugs where its unique_ptr
implementation wants to use deleted functions.
In this case the worst that could happen is one copy per entity
once during initialization (which should in principle be elided
anyway because a return value is a prvalue... no idea if MSVC does
actually do that).
This commit integrates the vector font in the resource system, so
that cross-compilation would be easier and a custom font could be
used without recompilation.
The font handling code was carefully written to lazily load glyphs;
as possible; in practice this means that startup is less than 15ms
slower after this commit, most of it spent in inflate().
This also reduces executable size and makes compilation of
glhelper.cpp much faster.
This commit integrates the bitmap font in the resource system, so
that cross-compilation would be easier.
The font handling code was carefully written to do glyph parsing
lazily; in practice this means that after this commit, startup
is less than 25ms slower, most of it spent in inflate().
This should also result in faster rendering, since there is no
rampant plane switching anymore; instead, all characters that are
actually used are stashed into same one texture.
This commit integrates icons in the resource system so that they
can be loaded (or reloaded, without restarting) in @2x mode, which
will be added in a future commit. png2c is no longer necessary.
png2c used to perform the following transformation:
if(r + g + b < 11) r = g = b = 11;
This is now achieved by switching the icons to RGBA mode and adding
alpha channel with the following imagemagick invocation, which is
equivalent to the transformation above:
for i in *.png; do
convert -fuzz 4% -channel rgba -matte \
-fill "rgba(255,255,255,0)" -opaque black \
$i $i
done
The Debian package solvespace now includes /usr/share/solvespace;
this should be split out into solvespace-data later.
Without resources, it makes no sense anymore to keep these in
separate subdirectories: unixutil* is shared between Cocoa
and GTK ports, and gloffscreen* should be shared between all ports
(but it's still platform-specific).
Currently, icons, fonts, etc are converted to C structures at compile
time and are hardcoded to the binary. This presents several problems:
* Cross-compilation is complicated. Right now, it is necessary
to be able to run executables for the target platform; this
happens to work with wine-binfmt installed, but is rather ugly.
* Icons can only have one resolution. On OS X, modern software is
expected to take advantage of high-DPI ("Retina") screens and
use so-called @2x assets when ran in high-DPI mode.
* Localization is complicated. Win32 and OS X provide built-in
support for loading the resource appropriate for the user's
locale.
* Embedding strings can only be done as raw strings, using C++'s
R"(...)" literals. This precludes embedding sizable strings,
e.g. JavaScript libraries as used in Three.js export, and makes
git history less useful. Not embedding the libraries means we
have to rely on external CDNs, which requires an Internet
connection and adds a glaring point of failure.
* Linux distribution guidelines are violated. All architecture-
independent data, especially large data such as fonts, is
expected to be in /usr/share, not in the binary.
* Customization is impossible without recompilation. Minor
modifications like adding a few missing vector font characters
or adjusting localization require a complete development
environment, which is unreasonable to expect from users of
a mechanical CAD.
As such, this commit adds a resource system that bundles (and
sometimes builds) resources with the executable. Where they go is
platform-dependent:
* on Win32: into resources of the executable, which allows us to
keep distributing one file;
* on OS X: into the app bundle;
* on other *nix: into /usr/share/solvespace/ or ../res/ (relative
to the executable path), the latter allowing us to run freshly
built executables without installation.
It also subsides the platform-specific resources that are in src/.
The resource system is not yet used for anything; this will be added
in later commits.
A previous attempt to fix this was done in 0128b8679. However, it was
not rigorous. The added offset was dependent on font size and it
introduced an error into edit control positioning. Further, it is
irrelevant to non-workplanes.
After this commit, the workplane drawing code adds a fixed offset
instead. Also, the "tab" is enlarged to not overlap with #XY etc.
Without this, if we have e.g.:
* a/x.slvs
* a/y.slvs importing a/x.slvs
and copy a/ to b/, then loading b/y.slvs would load a/x.slvs, which
is rather surprising.
Before this commit, e.g. a 120° angle could be exported as its
supplementary 60° angle but it would still say 120° in the label.
After this commit, the right angle is selected in DXF-based software.
Similarly, it roundtrips through SolveSpace correctly.