mirror of https://github.com/OpenRCT2/OpenRCT2.git
Refactor memory handling in Changelog.cpp
This commit is contained in:
parent
ba5bc415c7
commit
badb90ba20
|
@ -14,16 +14,17 @@
|
|||
*****************************************************************************/
|
||||
#pragma endregion
|
||||
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
#include <openrct2/Context.h>
|
||||
#include <openrct2/OpenRCT2.h>
|
||||
#include <openrct2/core/Math.hpp>
|
||||
#include <openrct2/core/Memory.hpp>
|
||||
#include <openrct2-ui/windows/Window.h>
|
||||
|
||||
#include <openrct2-ui/interface/Widget.h>
|
||||
#include <openrct2/core/String.hpp>
|
||||
#include <openrct2/localisation/Localisation.h>
|
||||
#include <openrct2/platform/platform.h>
|
||||
#include <openrct2/util/Util.h>
|
||||
#include <openrct2-ui/windows/Window.h>
|
||||
#include <openrct2-ui/interface/Widget.h>
|
||||
|
||||
enum {
|
||||
WIDX_BACKGROUND,
|
||||
|
@ -89,10 +90,8 @@ static rct_window_event_list window_changelog_events = {
|
|||
static bool window_changelog_read_file();
|
||||
static void window_changelog_dispose_file();
|
||||
|
||||
static char *_changelogText = nullptr;
|
||||
static size_t _changelogTextSize = 0;
|
||||
static char **_changelogLines = nullptr;
|
||||
static sint32 _changelogNumLines = 0;
|
||||
static std::string _changelogText;
|
||||
static std::vector<const char *> _changelogLines;
|
||||
static sint32 _changelogLongestLineWidth = 0;
|
||||
|
||||
rct_window * window_changelog_open()
|
||||
|
@ -164,7 +163,7 @@ static void window_changelog_resize(rct_window *w)
|
|||
static void window_changelog_scrollgetsize(rct_window *w, sint32 scrollIndex, sint32 *width, sint32 *height)
|
||||
{
|
||||
*width = _changelogLongestLineWidth + 4;
|
||||
*height = _changelogNumLines * 11;
|
||||
*height = (sint32)(_changelogLines.size() * 11);
|
||||
}
|
||||
|
||||
static void window_changelog_invalidate(rct_window *w)
|
||||
|
@ -192,73 +191,76 @@ static void window_changelog_scrollpaint(rct_window *w, rct_drawpixelinfo *dpi,
|
|||
|
||||
sint32 x = 3;
|
||||
sint32 y = 3;
|
||||
for (sint32 i = 0; i < _changelogNumLines; i++) {
|
||||
gfx_draw_string(dpi, _changelogLines[i], w->colours[0], x, y);
|
||||
for (auto line : _changelogLines)
|
||||
{
|
||||
gfx_draw_string(dpi, (char *)line, w->colours[0], x, y);
|
||||
y += 11;
|
||||
}
|
||||
}
|
||||
|
||||
static bool window_changelog_read_file()
|
||||
static std::string GetChangelogText()
|
||||
{
|
||||
window_changelog_dispose_file();
|
||||
utf8 path[MAX_PATH];
|
||||
platform_get_changelog_path(path, sizeof(path));
|
||||
if (!readentirefile(path, (void**)&_changelogText, &_changelogTextSize)) {
|
||||
|
||||
#if defined(_WIN32) && !defined(__MINGW32__)
|
||||
auto pathW = String::ToUtf16(path);
|
||||
auto fs = std::ifstream(pathW, std::ios::out | std::ios::app);
|
||||
#else
|
||||
auto fs = std::ifstream(path, std::ios::out | std::ios::app);
|
||||
#endif
|
||||
return std::string((std::istreambuf_iterator<char>(fs)), std::istreambuf_iterator<char>());
|
||||
}
|
||||
|
||||
static bool window_changelog_read_file()
|
||||
{
|
||||
try
|
||||
{
|
||||
_changelogText = GetChangelogText();
|
||||
}
|
||||
catch (const std::bad_alloc &)
|
||||
{
|
||||
log_error("Unable to allocate memory for changelog.txt");
|
||||
return false;
|
||||
}
|
||||
catch (const std::exception &)
|
||||
{
|
||||
log_error("Unable to read changelog.txt");
|
||||
return false;
|
||||
}
|
||||
void* new_memory = realloc(_changelogText, _changelogTextSize + 1);
|
||||
if (new_memory == nullptr) {
|
||||
log_error("Failed to reallocate memory for changelog text");
|
||||
return false;
|
||||
}
|
||||
_changelogText = (char*)new_memory;
|
||||
_changelogText[_changelogTextSize++] = 0;
|
||||
|
||||
char *start = _changelogText;
|
||||
if (_changelogTextSize >= 3 && utf8_is_bom(_changelogText))
|
||||
auto * start = _changelogText.data();
|
||||
if (_changelogText.size() >= 3 && utf8_is_bom(start))
|
||||
{
|
||||
start += 3;
|
||||
}
|
||||
|
||||
sint32 changelogLinesCapacity = 8;
|
||||
_changelogLines = Memory::Allocate<utf8*>(changelogLinesCapacity * sizeof(char*));
|
||||
_changelogLines[0] = start;
|
||||
_changelogNumLines = 1;
|
||||
|
||||
char *ch = start;
|
||||
while (*ch != 0) {
|
||||
_changelogLines.clear();
|
||||
_changelogLines.push_back(start);
|
||||
auto ch = start;
|
||||
while (*ch != '\0')
|
||||
{
|
||||
uint8 c = *ch;
|
||||
if (c == '\n') {
|
||||
if (c == '\n')
|
||||
{
|
||||
*ch++ = 0;
|
||||
_changelogNumLines++;
|
||||
if (_changelogNumLines > changelogLinesCapacity) {
|
||||
changelogLinesCapacity *= 2;
|
||||
new_memory = realloc(_changelogLines, changelogLinesCapacity * sizeof(char*));
|
||||
if (new_memory == nullptr) {
|
||||
log_error("Failed to reallocate memory for change log lines");
|
||||
return false;
|
||||
}
|
||||
_changelogLines = (char**)new_memory;
|
||||
}
|
||||
_changelogLines[_changelogNumLines - 1] = ch;
|
||||
} else if (c < 32 || c > 122) {
|
||||
// A character that won't be drawn or change state.
|
||||
_changelogLines.push_back(ch);
|
||||
}
|
||||
else if (utf8_is_format_code(c))
|
||||
{
|
||||
*ch++ = FORMAT_OUTLINE_OFF;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
ch++;
|
||||
}
|
||||
}
|
||||
|
||||
new_memory = realloc(_changelogLines, _changelogNumLines * sizeof(char*));
|
||||
if (new_memory == nullptr) {
|
||||
log_error("Failed to reallocate memory for change log lines");
|
||||
return false;
|
||||
}
|
||||
_changelogLines = (char**)new_memory;
|
||||
|
||||
gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM;
|
||||
_changelogLongestLineWidth = 0;
|
||||
for (sint32 i = 0; i < _changelogNumLines; i++) {
|
||||
sint32 width = gfx_get_string_width(_changelogLines[i]);
|
||||
for (auto line : _changelogLines)
|
||||
{
|
||||
auto width = gfx_get_string_width(line);
|
||||
_changelogLongestLineWidth = Math::Max(width, _changelogLongestLineWidth);
|
||||
}
|
||||
return true;
|
||||
|
@ -266,8 +268,7 @@ static bool window_changelog_read_file()
|
|||
|
||||
static void window_changelog_dispose_file()
|
||||
{
|
||||
SafeFree(_changelogText);
|
||||
SafeFree(_changelogLines);
|
||||
_changelogTextSize = 0;
|
||||
_changelogNumLines = 0;
|
||||
_changelogText = std::string();
|
||||
_changelogLines.clear();
|
||||
_changelogLines.shrink_to_fit();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue