- Refactored PerfTimer to use less memory.
- Avoid using the PerfTimer in highly called methods DoTimed and RunActivity, instead tracking long ticks manually to reduce overhead and avoid memory allocations.
- Added some helper methods in PerfTimer to output information when a tick takes too long.
- Changed PerfTimer logging to output the time at the start of the line, and no longer truncate output per line.
- Settings.LongTickThreshold changed from TimeSpan to float and renamed to LongTickThresholdMs.
- Made private methods static where possible (runtime can elide checking the object for null).
- Declared attribute classes as sealed (allows reflection on attributes to complete faster).
- Moved some static cctor's into field initializers (static cctor's are slower than static field initializers).
- Made classes static if they contained only static methods (can't create instances of useless objects).
- Use inferable Exts.Lazy and not new Lazy<T>().
- Added required STAThread attribute to CrashDialog.
- Removed unused parameters in private methods.
- Added Serializable attribute to exceptions.
- Added parameter name in calls to ArgumentNullException.
- Use of as operator instead of is + cast.
- Changed (x as Foo).Bar anti-pattern into ((Foo)x).Bar. Results in sensible cast exceptions on error rather than null dereferences.
- Removed unused method in NullShader.
Targeted some methods that generated allocated a lot of memory in the main game loop:
- Actor.Render - Changed LINQ calls into equivalent loops. No allocation for delegates.
- Animation.Render - Returned an array rather than a yield expression. The array uses less memory than the complier generated enumerable.
- FrozenActor and FrozenUnderFog - Materialize the footprint into an array: The enumerable is not-trivial to evaluate is and evaluated many times inside the Tick function. The memory needed is minimal. Changed LINQ into equivalent loops to prevent delegate allocation. Should result in overall much faster calls.
- Widget.GetEventBounds - Changed LINQ calls into equivalent loops.
- MobileInfo.CanEnterCell - Changed LINQ calls into equivalent loops. Don't materialize list of blocking actors every time, instead enumerate them and only when they need to be checked.
- FrozenUnderFog.TickRender - Generate the renderables lazily and also remove a no-op Select call.
Create a single solution platform named x86.
Ensure both Debug and Release configs build to the root for all projects.
Ensure all Release configs generate pdbs.
* Use Pair instead of KeyValuePair
* double -> var
* Butcher XML comments
* Change WinState default to Undefined and use it instead of the new GameOutcome
* Other changes
It was crashing because it tried to seek 8 bytes before the end
of a file that was empty (zero length).
I also added a few more checks and another try/catch to prevent
any more crashes related to damaged files.
List of changes:
* Better and more filters with new layout, for both mods.
* Rename/Delete/Detele all functionality.
* Simplified ReplayMetadata class considerably by introducing a new
GameInformation data object. The new GameInformation class contains
more information than previously available so the new solution is not
compatible with old replays, meaning it can't read old replays.
* Better and cleaner game information gathering in order to be written
at the end of the replay file.
* Revert changes to ReplayConnection, no longer necessary.
* Better exception message on missing sprites and fonts.
* New "SpawnOccupant" class that holds all the information needed by the
MapPreviewWidget to visualize a spawn point. It was using Session.Client
before and it was necessary to separate it to be able to show information
not available at lobby time.
* Fix keyboard focus UI bug when closing a window would not remove focus.
This closes issue #2152. The filters added are:
* Game type (singleplayer / multiplayer)
* Date
* Duration
* Outcome
* Player name
Other changes:
* Added a 'CollapseHiddenChildren' option to the ScrollPanelWidget to
make hidden children take up no space.
* Removed the extension (.rep) from the replay filenames in the
replay browser.
The replay files are just streams all network communication so to
get any info out of them it is necessary to play back the stream
until the wanted information is reached.
This introduces a new metadata block placed at the end of the
replay files and logic to read the new block, or fall back to
playing back the stream for older files.
The replay browser is also updated to use the metadata information
instead of reading the replay stream directly.
This is useful to ignore fast operations that just spam the log.
The class had to be reworked because it couldn't properly handle cases
where all of a node's children where below the threshold.
Also changed DoTimed() and RunActivity() to use PerfTimer.
Check if this instance has been disposed and don't call 'tick'
if it has.
Also remove the finalizer that was broken and wrong anyway.
'runtime' would never become null because it's readonly and
managed resources are freed automatically or may have already
been freed by then.