* This means it outputs natively/properly to stdout/stderr and its output can be
redirected with pipes.
* It does mean we need to be very careful whenever it's run internally to not
pop up a command window, which happens by default.
* This allows us to add rich text support much more easily into other itemviews
like RDTableView.
* We set it up for debug messages so that resource links in debug messages can
be linked.
* The GUIInvoke object takes a QObject, and uses QPointer to check that
it hasn't been deleted when the callback fires. This prevents delayed
callbacks from executing after the object has been deleted and
crashing.
* In most cases the pointer is just 'this'.
* For unsigned integers this notices UINT16/32/64_MAX and displays as
a text string for easier consumption.
* Also for numbers over a given threshold we display them as hex instead
of decimal.
* We enforce a naming scheme more strongly - types, member functions,
and enum values must be UpperCaseCamel, and member variables must be
lowerCaseCamel. No underscores allowed.
* eventId not eventID or EID, and Id preferred to ID in general. Also
for resourceId.
* Removed some lingering hungarian m_Foo naming.
* Some pipeline state structs that are almost identical between the
different APIs are pulled out into common structs. Where something
doesn't make sense (e.g. viewport enable for vulkan) it will just be
set to a sensible default (in that case always true).
* Changed scissors to be x/y & width/height instead of sometimes
left/top/right/bottom
* Abbreviations are discouraged, e.g. operation not op, function not
func.
* This is a *very* light-touch analytics system that will track the
simplest and most anonymous statistics that can be useful in
determining which features are most used or perhaps underused, and
where it's best to direct development attention.
* It is entirely implemented in the UI layer, no analytics-gathering
code exists in the library that's injected into programs, and of
course no capture data (screenshots, resource contents, shaders, etc
etc) is transmitted.
* Once it's turned on, it will apply to both development and release
builds. It tracks stats over a month, and then at the beginning of a
new month it sends the previous data.
* When the user first starts up a build with analytics if there's no
previous analytics database then they are informed of the new code and
asked to approve it. They have the option of selecting to manually
verify any sent reports, or just opt-ing out entirely.
* We remove the now unneeded name fields in buffer/texture descriptions
and some of the pipeline state structs.
* A single function will give the human-readable name for a resource id.
This will look up a custom set of renames, on top of the names from
the resource descriptions.
* Note that while this is public and uses std::string, because it's a
template with specialisations in a .inl the string never crosses a
module boundary - each including module has its own implementation.
* This will be used as part of the upcoming serialisation refactor.
* Some POD structs are still given ToStr implementations as we haven't
yet switched over the serialisation system to expect all structs to
have serialise functions.
To quote the Qt documentation for QFileDialog::setNameFilters:
> Note that the filter *.* is not portable, because the historical
> assumption that the file extension determines the file type is not
> consistent on every operating system. It is possible to have a file
> with no dot in its name (for example, Makefile). In a native Windows
> file dialog, *.* will match such files, while in other types of file
> dialogs it may not. So it is better to use * if you mean to select
> any file.
Admittedly, one of these usages is Windows-only and we are using the
native file dialog there, but we might as well be consistent.
Instead of manually specifying the default extension, just grab the
first one from each filter. We can only specify one at a time, so
update it whenever the selected filter changes.
In most of these cases, the open file dialog won't even display a file
without the proper extension, so this helps ensure the user doesn't
accidentally misplace their files. The one exception is *.rdc, which
could be found without the extension, but could not be opened.