- display_msg and display_error -> debug prefix since in debug header
- debug_warn_err now takes LibError - lib_error.cpp: revise error code -> string (only support liberror now); add function to set errno from LibError - unifont, CFont: parameter made a simple wchar_t from const wchar_t& - mmap now sets errno - Loader and VfsUtil function now return LibError as well - Profile.cpp, ProfileViewer.cpp: fix int/uint/size_t warnings - Renderer.cpp: fix cannot-generate-assignment-operator warning This was SVN commit r3235.
This commit is contained in:
parent
8d3df809bb
commit
6e82e33ccf
@ -30,6 +30,7 @@
|
|||||||
#include "self_test.h"
|
#include "self_test.h"
|
||||||
#include "app_hooks.h"
|
#include "app_hooks.h"
|
||||||
|
|
||||||
|
|
||||||
// needed when writing crashlog
|
// needed when writing crashlog
|
||||||
static const size_t LOG_CHARS = 16384;
|
static const size_t LOG_CHARS = 16384;
|
||||||
wchar_t debug_log[LOG_CHARS];
|
wchar_t debug_log[LOG_CHARS];
|
||||||
@ -436,14 +437,26 @@ const char* debug_get_symbol_string(void* symbol, const char* name, const char*
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// output
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
ErrorReaction display_error(const wchar_t* description, int flags,
|
// translates and displays the given strings in a dialog.
|
||||||
uint skip, void* context, const char* file, int line)
|
// this is typically only used when debug_display_error has failed or
|
||||||
|
// is unavailable because that function is much more capable.
|
||||||
|
// implemented via sys_display_msgw; see documentation there.
|
||||||
|
void debug_display_msgw(const wchar_t* caption, const wchar_t* msg)
|
||||||
|
{
|
||||||
|
sys_display_msgw(ah_translate(caption), ah_translate(msg));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// display the error dialog. shows <description> along with a stack trace.
|
||||||
|
// context and skip are as with debug_dump_stack.
|
||||||
|
// flags: see DisplayErrorFlags. file and line indicate where the error
|
||||||
|
// occurred and are typically passed as __FILE__, __LINE__.
|
||||||
|
ErrorReaction debug_display_error(const wchar_t* description,
|
||||||
|
int flags, uint skip, void* context, const char* file, int line)
|
||||||
{
|
{
|
||||||
if(!file || file[0] == '\0')
|
if(!file || file[0] == '\0')
|
||||||
file = "unknown";
|
file = "unknown";
|
||||||
@ -495,7 +508,7 @@ ErrorReaction display_error(const wchar_t* description, int flags,
|
|||||||
ErrorReaction er = sys_display_error(text, flags);
|
ErrorReaction er = sys_display_error(text, flags);
|
||||||
|
|
||||||
// note: debug_break-ing here to make sure the app doesn't continue
|
// note: debug_break-ing here to make sure the app doesn't continue
|
||||||
// running is no longer necessary. display_error now determines our
|
// running is no longer necessary. debug_display_error now determines our
|
||||||
// window handle and is modal.
|
// window handle and is modal.
|
||||||
|
|
||||||
// handle "break" request unless the caller wants to (doing so here
|
// handle "break" request unless the caller wants to (doing so here
|
||||||
@ -528,8 +541,8 @@ ErrorReaction display_error(const wchar_t* description, int flags,
|
|||||||
|
|
||||||
// notify the user that an assertion failed; displays a stack trace with
|
// notify the user that an assertion failed; displays a stack trace with
|
||||||
// local variables.
|
// local variables.
|
||||||
ErrorReaction debug_assert_failed(const char* file, int line,
|
ErrorReaction debug_assert_failed(const char* expr,
|
||||||
const char* func, const char* expr)
|
const char* file, int line, const char* func)
|
||||||
{
|
{
|
||||||
// for edge cases in some functions, warnings (=asserts) are raised in
|
// for edge cases in some functions, warnings (=asserts) are raised in
|
||||||
// addition to returning an error code. self-tests deliberately trigger
|
// addition to returning an error code. self-tests deliberately trigger
|
||||||
@ -548,12 +561,12 @@ ErrorReaction debug_assert_failed(const char* file, int line,
|
|||||||
uint skip = 1; void* context = 0;
|
uint skip = 1; void* context = 0;
|
||||||
wchar_t buf[400];
|
wchar_t buf[400];
|
||||||
swprintf(buf, ARRAY_SIZE(buf), L"Assertion failed at %hs:%d (%hs): \"%hs\"", base_name, line, func, expr);
|
swprintf(buf, ARRAY_SIZE(buf), L"Assertion failed at %hs:%d (%hs): \"%hs\"", base_name, line, func, expr);
|
||||||
return display_error(buf, DE_ALLOW_SUPPRESS|DE_MANUAL_BREAK, skip, context, base_name, line);
|
return debug_display_error(buf, DE_ALLOW_SUPPRESS|DE_MANUAL_BREAK, skip,context, base_name,line);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ErrorReaction debug_warn_err(int err, const char* file, int line,
|
ErrorReaction debug_warn_err(LibError err,
|
||||||
const char* func)
|
const char* file, int line, const char* func)
|
||||||
{
|
{
|
||||||
// for edge cases in some functions, warnings (=asserts) are raised in
|
// for edge cases in some functions, warnings (=asserts) are raised in
|
||||||
// addition to returning an error code. self-tests deliberately trigger
|
// addition to returning an error code. self-tests deliberately trigger
|
||||||
@ -573,7 +586,7 @@ ErrorReaction debug_warn_err(int err, const char* file, int line,
|
|||||||
wchar_t buf[400];
|
wchar_t buf[400];
|
||||||
char err_buf[200]; error_description_r(err, err_buf, ARRAY_SIZE(err_buf));
|
char err_buf[200]; error_description_r(err, err_buf, ARRAY_SIZE(err_buf));
|
||||||
swprintf(buf, ARRAY_SIZE(buf), L"Function call failed at %hs:%d (%hs): return value was %d (%hs)", base_name, line, func, err, err_buf);
|
swprintf(buf, ARRAY_SIZE(buf), L"Function call failed at %hs:%d (%hs): return value was %d (%hs)", base_name, line, func, err, err_buf);
|
||||||
return display_error(buf, DE_ALLOW_SUPPRESS|DE_MANUAL_BREAK, skip, context, base_name, line);
|
return debug_display_error(buf, DE_ALLOW_SUPPRESS|DE_MANUAL_BREAK, skip,context, base_name,line);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
#define DEBUG_H_INCLUDED
|
#define DEBUG_H_INCLUDED
|
||||||
|
|
||||||
#include "lib.h" // STMT
|
#include "lib.h" // STMT
|
||||||
#include "sysdep/sysdep.h" // ErrorReaction
|
|
||||||
#if OS_WIN
|
#if OS_WIN
|
||||||
# include "sysdep/win/wdbg.h"
|
# include "sysdep/win/wdbg.h"
|
||||||
#else
|
#else
|
||||||
@ -73,7 +72,7 @@ even if debug information is present and assert dialogs are useless.
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
// check heap integrity (independently of mmgr).
|
// check heap integrity (independently of mmgr).
|
||||||
// errors are reported by the CRT or via display_error.
|
// errors are reported by the CRT or via debug_display_error.
|
||||||
extern void debug_heap_check(void);
|
extern void debug_heap_check(void);
|
||||||
|
|
||||||
enum DebugHeapChecks
|
enum DebugHeapChecks
|
||||||
@ -122,7 +121,7 @@ STMT(\
|
|||||||
static unsigned char suppress__ = 0x55;\
|
static unsigned char suppress__ = 0x55;\
|
||||||
if(suppress__ == 0x55 && !(expr))\
|
if(suppress__ == 0x55 && !(expr))\
|
||||||
{\
|
{\
|
||||||
switch(debug_assert_failed(__FILE__, __LINE__, __func__, #expr))\
|
switch(debug_assert_failed(#expr, __FILE__, __LINE__, __func__))\
|
||||||
{\
|
{\
|
||||||
case ER_SUPPRESS:\
|
case ER_SUPPRESS:\
|
||||||
suppress__ = 0xAA;\
|
suppress__ = 0xAA;\
|
||||||
@ -137,9 +136,6 @@ STMT(\
|
|||||||
}\
|
}\
|
||||||
)
|
)
|
||||||
|
|
||||||
// called when an assertion has failed; notifies the user via display_error.
|
|
||||||
extern enum ErrorReaction debug_assert_failed(const char* file, int line,
|
|
||||||
const char* func, const char* assert_expr);
|
|
||||||
|
|
||||||
// show a dialog to make sure unexpected states in the program are noticed.
|
// show a dialog to make sure unexpected states in the program are noticed.
|
||||||
// this is less error-prone than "debug_assert(0 && "text");" and avoids
|
// this is less error-prone than "debug_assert(0 && "text");" and avoids
|
||||||
@ -150,6 +146,9 @@ extern enum ErrorReaction debug_assert_failed(const char* file, int line,
|
|||||||
#define debug_warn(str) debug_assert((str) && 0)
|
#define debug_warn(str) debug_assert((str) && 0)
|
||||||
|
|
||||||
|
|
||||||
|
// if (LibError)err indicates an function failed, display the error dialog.
|
||||||
|
// used by CHECK_ERR et al., which wrap function calls and automatically
|
||||||
|
// warn user and return to caller.
|
||||||
#define DEBUG_WARN_ERR(err)\
|
#define DEBUG_WARN_ERR(err)\
|
||||||
STMT(\
|
STMT(\
|
||||||
static unsigned char suppress__ = 0x55;\
|
static unsigned char suppress__ = 0x55;\
|
||||||
@ -170,8 +169,15 @@ STMT(\
|
|||||||
}\
|
}\
|
||||||
)
|
)
|
||||||
|
|
||||||
extern enum ErrorReaction debug_warn_err(int err, const char* file, int line,
|
|
||||||
const char* func);
|
// called when an assertion has failed; notifies the user via debug_display_error.
|
||||||
|
extern enum ErrorReaction debug_assert_failed(const char* assert_expr,
|
||||||
|
const char* file, int line, const char* func);
|
||||||
|
|
||||||
|
// called when a lib function wrapped in DEBUG_WARN_ERR failed;
|
||||||
|
// notifies the user via debug_display_error.
|
||||||
|
extern enum ErrorReaction debug_warn_err(LibError err,
|
||||||
|
const char* file, int line, const char* func);
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -185,12 +191,61 @@ extern void debug_printf(const char* fmt, ...);
|
|||||||
extern void debug_wprintf(const wchar_t* fmt, ...);
|
extern void debug_wprintf(const wchar_t* fmt, ...);
|
||||||
|
|
||||||
|
|
||||||
extern ErrorReaction display_error(const wchar_t* description, int flags,
|
// translates and displays the given strings in a dialog.
|
||||||
uint skip, void* context, const char* file, int line);
|
// this is typically only used when debug_display_error has failed or
|
||||||
|
// is unavailable because that function is much more capable.
|
||||||
|
// implemented via sys_display_msgw; see documentation there.
|
||||||
|
extern void debug_display_msgw(const wchar_t* caption, const wchar_t* msg);
|
||||||
|
|
||||||
|
|
||||||
|
// choices offered by the shared error dialog
|
||||||
|
enum ErrorReaction
|
||||||
|
{
|
||||||
|
// ignore, continue as if nothing happened.
|
||||||
|
// note: don't start at 0 because that is interpreted as a
|
||||||
|
// DialogBoxParam failure.
|
||||||
|
ER_CONTINUE = 1,
|
||||||
|
|
||||||
|
// ignore and do not report again.
|
||||||
|
// only returned if DE_ALLOW_SUPPRESS was passed.
|
||||||
|
// note: non-persistent; only applicable during this program run.
|
||||||
|
ER_SUPPRESS,
|
||||||
|
|
||||||
|
// trigger breakpoint, i.e. enter debugger.
|
||||||
|
// only returned if DE_MANUAL_BREAK was passed; otherwise,
|
||||||
|
// debug_display_error will trigger a breakpoint itself.
|
||||||
|
ER_BREAK,
|
||||||
|
|
||||||
|
// exit the program immediately.
|
||||||
|
// never returned; debug_display_error exits immediately.
|
||||||
|
ER_EXIT
|
||||||
|
};
|
||||||
|
|
||||||
|
enum DisplayErrorFlags
|
||||||
|
{
|
||||||
|
// allow the suppress button (requires calling via macro that
|
||||||
|
// maintains a 'suppress' bool; see debug_assert)
|
||||||
|
DE_ALLOW_SUPPRESS = 1,
|
||||||
|
|
||||||
|
// disallow the continue button. used e.g. if an exception is fatal.
|
||||||
|
DE_NO_CONTINUE = 2,
|
||||||
|
|
||||||
|
// do not trigger a breakpoint inside debug_display_error; caller
|
||||||
|
// will take care of this if ER_BREAK is returned. this is so that the
|
||||||
|
// debugger can jump directly into the offending function.
|
||||||
|
DE_MANUAL_BREAK = 4
|
||||||
|
};
|
||||||
|
|
||||||
|
// display the error dialog. shows <description> along with a stack trace.
|
||||||
|
// context and skip are as with debug_dump_stack.
|
||||||
|
// flags: see DisplayErrorFlags. file and line indicate where the error
|
||||||
|
// occurred and are typically passed as __FILE__, __LINE__.
|
||||||
|
extern ErrorReaction debug_display_error(const wchar_t* description,
|
||||||
|
int flags, uint skip, void* context, const char* file, int line);
|
||||||
|
|
||||||
// convenience version, in case the advanced parameters aren't needed.
|
// convenience version, in case the advanced parameters aren't needed.
|
||||||
// done this way instead of with default values so that it also works in C.
|
// macro instead of providing overload/default values for C compatibility.
|
||||||
#define DISPLAY_ERROR(text) display_error(text, 0, 0, 0, __FILE__, __LINE__)
|
#define DISPLAY_ERROR(text) debug_display_error(text, 0, 0,0, __FILE__,__LINE__)
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -31,14 +31,6 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// translates the given strings and passes them on to sys_display_msgw
|
|
||||||
// (see documentation there).
|
|
||||||
void display_msgw(const wchar_t* caption, const wchar_t* msg)
|
|
||||||
{
|
|
||||||
sys_display_msgw(ah_translate(caption), ah_translate(msg));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// FNV1-A hash - good for strings.
|
// FNV1-A hash - good for strings.
|
||||||
// if len = 0 (default), treat buf as a C-string;
|
// if len = 0 (default), treat buf as a C-string;
|
||||||
// otherwise, hash <len> bytes of buf.
|
// otherwise, hash <len> bytes of buf.
|
||||||
|
@ -208,10 +208,6 @@ const size_t GiB = 1ul << 30;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// translates the given strings and passes them on to sys_display_msgw
|
|
||||||
// (see documentation there).
|
|
||||||
extern void display_msgw(const wchar_t* caption, const wchar_t* msg);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define BIT(n) (1ul << (n))
|
#define BIT(n) (1ul << (n))
|
||||||
|
@ -11,17 +11,18 @@
|
|||||||
#include <stdlib.h> // abs
|
#include <stdlib.h> // abs
|
||||||
|
|
||||||
|
|
||||||
static const char* lib_error_description(int err)
|
static const char* LibError_description(LibError err)
|
||||||
{
|
{
|
||||||
// not in our range
|
// not in our range
|
||||||
if(!(ERR_MIN <= abs(err) && abs(err) < ERR_MAX))
|
const int ierr = abs((int)err);
|
||||||
|
if(!(ERR_MIN <= ierr && ierr < ERR_MAX))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
switch(err)
|
switch(err)
|
||||||
{
|
{
|
||||||
#define ERR(err, id, str) case id: return str;
|
#define ERR(err, id, str) case id: return str;
|
||||||
#include "lib_errors.h"
|
#include "lib_errors.h"
|
||||||
default: return "Unknown lib error";
|
default: return "Unknown error";
|
||||||
}
|
}
|
||||||
UNREACHABLE;
|
UNREACHABLE;
|
||||||
}
|
}
|
||||||
@ -29,13 +30,12 @@ static const char* lib_error_description(int err)
|
|||||||
|
|
||||||
// generate textual description of an error code.
|
// generate textual description of an error code.
|
||||||
// stores up to <max_chars> in the given buffer.
|
// stores up to <max_chars> in the given buffer.
|
||||||
// <err> can be one of the above error codes, POSIX ENOENT etc., or
|
// if error is unknown/invalid, the string will be something like
|
||||||
// an OS-specific errors. if unknown, the string will be something like
|
|
||||||
// "Unknown error (65536, 0x10000)".
|
// "Unknown error (65536, 0x10000)".
|
||||||
void error_description_r(int err, char* buf, size_t max_chars)
|
void error_description_r(LibError err, char* buf, size_t max_chars)
|
||||||
{
|
{
|
||||||
// lib error
|
// lib error
|
||||||
const char* str = lib_error_description(err);
|
const char* str = LibError_description(err);
|
||||||
if(str)
|
if(str)
|
||||||
{
|
{
|
||||||
// <err> was one of our error codes (chosen so as not to conflict
|
// <err> was one of our error codes (chosen so as not to conflict
|
||||||
@ -44,34 +44,7 @@ void error_description_r(int err, char* buf, size_t max_chars)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Win32 GetLastError and errno both define values in [0,100).
|
|
||||||
// what we'll do is always try the OS-specific translation,
|
|
||||||
// add libc's interpretation if <err> is a valid errno, and
|
|
||||||
// output "Unknown" if none of the above succeeds.
|
|
||||||
const bool should_display_libc_err = (0 <= err && err < sys_nerr);
|
|
||||||
bool have_output = false;
|
|
||||||
|
|
||||||
// OS-specific error
|
|
||||||
if(sys_error_description_r(err, buf, max_chars) == 0) // success
|
|
||||||
{
|
|
||||||
have_output = true;
|
|
||||||
|
|
||||||
// add a separator text before libc description
|
|
||||||
if(should_display_libc_err)
|
|
||||||
strcat_s(buf, max_chars, "; libc err=");
|
|
||||||
}
|
|
||||||
|
|
||||||
// libc error
|
|
||||||
if(should_display_libc_err)
|
|
||||||
{
|
|
||||||
strcat_s(buf, max_chars, strerror(err));
|
|
||||||
// note: we are sure to get meaningful output (not just "unknown")
|
|
||||||
// because err < sys_nerr.
|
|
||||||
have_output = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// fallback
|
// fallback
|
||||||
if(!have_output)
|
|
||||||
snprintf(buf, max_chars, "Unknown error (%d, 0x%X)", err, err);
|
snprintf(buf, max_chars, "Unknown error (%d, 0x%X)", err, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,30 +56,21 @@ LibError LibError_from_errno()
|
|||||||
{
|
{
|
||||||
switch(errno)
|
switch(errno)
|
||||||
{
|
{
|
||||||
case ENOMEM:
|
case ENOMEM: return ERR_NO_MEM;
|
||||||
return ERR_NO_MEM;
|
|
||||||
|
|
||||||
case EINVAL:
|
case EINVAL: return ERR_INVALID_PARAM;
|
||||||
return ERR_INVALID_PARAM;
|
case ENOSYS: return ERR_NOT_IMPLEMENTED;
|
||||||
case ENOSYS:
|
|
||||||
return ERR_NOT_IMPLEMENTED;
|
|
||||||
|
|
||||||
case ENOENT:
|
case ENOENT: return ERR_PATH_NOT_FOUND;
|
||||||
return ERR_PATH_NOT_FOUND;
|
case EACCES: return ERR_FILE_ACCESS;
|
||||||
case EACCES:
|
case EIO: return ERR_IO;
|
||||||
return ERR_FILE_ACCESS;
|
case ENAMETOOLONG: return ERR_PATH_LENGTH;
|
||||||
case EIO:
|
|
||||||
return ERR_IO;
|
|
||||||
case ENAMETOOLONG:
|
|
||||||
return ERR_PATH_LENGTH;
|
|
||||||
|
|
||||||
default:
|
default: return ERR_FAIL;
|
||||||
return ERR_FAIL;
|
|
||||||
}
|
}
|
||||||
UNREACHABLE;
|
UNREACHABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// translate the return value of any POSIX function into LibError.
|
// translate the return value of any POSIX function into LibError.
|
||||||
// ret is typically to -1 to indicate error and 0 on success.
|
// ret is typically to -1 to indicate error and 0 on success.
|
||||||
// you should set errno to 0 before calling the POSIX function to
|
// you should set errno to 0 before calling the POSIX function to
|
||||||
@ -116,3 +80,36 @@ LibError LibError_from_posix(int ret)
|
|||||||
debug_assert(ret == 0 || ret == -1);
|
debug_assert(ret == 0 || ret == -1);
|
||||||
return (ret == 0)? ERR_OK : LibError_from_errno();
|
return (ret == 0)? ERR_OK : LibError_from_errno();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// return the errno.h equivalent of <err>.
|
||||||
|
// does not assign to errno (this simplifies code by allowing direct return)
|
||||||
|
static int return_errno_from_LibError(LibError err)
|
||||||
|
{
|
||||||
|
switch(err)
|
||||||
|
{
|
||||||
|
case ERR_NO_MEM: return ENOMEM;
|
||||||
|
|
||||||
|
case ERR_INVALID_PARAM: return EINVAL;
|
||||||
|
case ERR_NOT_IMPLEMENTED: return ENOSYS;
|
||||||
|
|
||||||
|
case ERR_PATH_NOT_FOUND: return ENOENT;
|
||||||
|
case ERR_FILE_ACCESS: return EACCES;
|
||||||
|
case ERR_IO: return EIO;
|
||||||
|
case ERR_PATH_LENGTH: return ENAMETOOLONG;
|
||||||
|
|
||||||
|
// somewhat of a quandary: the set of errnos in wposix.h doesn't
|
||||||
|
// have an "unknown error". we pick EPERM because we don't expect
|
||||||
|
// that to come up often otherwise.
|
||||||
|
default: return EPERM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// set errno to the equivalent of <err>. used in wposix - underlying
|
||||||
|
// functions return LibError but must be translated to errno at
|
||||||
|
// e.g. the mmap interface level. higher-level code that calls mmap will
|
||||||
|
// in turn convert back to LibError.
|
||||||
|
void LibError_set_errno(LibError err)
|
||||||
|
{
|
||||||
|
errno = return_errno_from_LibError(err);
|
||||||
|
}
|
||||||
|
@ -27,10 +27,9 @@ enum LibError {
|
|||||||
|
|
||||||
// generate textual description of an error code.
|
// generate textual description of an error code.
|
||||||
// stores up to <max_chars> in the given buffer.
|
// stores up to <max_chars> in the given buffer.
|
||||||
// <err> can be one of the above error codes, POSIX ENOENT etc., or
|
// if error is unknown/invalid, the string will be something like
|
||||||
// an OS-specific errors. if unknown, the string will be something like
|
|
||||||
// "Unknown error (65536, 0x10000)".
|
// "Unknown error (65536, 0x10000)".
|
||||||
extern void error_description_r(int err, char* buf, size_t max_chars);
|
extern void error_description_r(LibError err, char* buf, size_t max_chars);
|
||||||
|
|
||||||
|
|
||||||
// return the LibError equivalent of errno, or ERR_FAIL if there's no equal.
|
// return the LibError equivalent of errno, or ERR_FAIL if there's no equal.
|
||||||
@ -43,35 +42,43 @@ extern LibError LibError_from_errno();
|
|||||||
// make sure we do not return any stale errors.
|
// make sure we do not return any stale errors.
|
||||||
extern LibError LibError_from_posix(int ret);
|
extern LibError LibError_from_posix(int ret);
|
||||||
|
|
||||||
|
// set errno to the equivalent of <err>. used in wposix - underlying
|
||||||
|
// functions return LibError but must be translated to errno at
|
||||||
|
// e.g. the mmap interface level. higher-level code that calls mmap will
|
||||||
|
// in turn convert back to LibError.
|
||||||
|
extern void LibError_set_errno(LibError err);
|
||||||
|
|
||||||
|
|
||||||
// be careful here. the given expression (e.g. variable or
|
// be careful here. the given expression (e.g. variable or
|
||||||
// function return value) may be a Handle (=i64), so it needs to be
|
// function return value) may be a Handle (=i64), so it needs to be
|
||||||
// stored and compared as such. (very large but legitimate Handle values
|
// stored and compared as such. (very large but legitimate Handle values
|
||||||
// casted to int can end up negative)
|
// casted to int can end up negative)
|
||||||
// all functions using this return int (instead of i64) for efficiency and
|
// all functions using this return LibError (instead of i64) for
|
||||||
// simplicity. if the input was negative, it is an error code and is
|
// efficiency and simplicity. if the input was negative, it is an
|
||||||
// therefore known to fit; we still mask with UINT_MAX to avoid
|
// error code and is therefore known to fit; we still mask with
|
||||||
// VC cast-to-smaller-type warnings.
|
// UINT_MAX to avoid VC cast-to-smaller-type warnings.
|
||||||
|
|
||||||
// if expression evaluates to a negative i64, warn user and return the number.
|
// if expression evaluates to a negative i64, warn user and return the number.
|
||||||
#if OS_WIN
|
#if OS_WIN
|
||||||
#define CHECK_ERR(expression)\
|
#define CHECK_ERR(expression)\
|
||||||
STMT(\
|
STMT(\
|
||||||
i64 err__ = (i64)(expression);\
|
i64 err64 = (i64)(expression);\
|
||||||
if(err__ < 0)\
|
if(err64 < 0)\
|
||||||
{\
|
{\
|
||||||
DEBUG_WARN_ERR(err__);\
|
LibError err = (LibError)(err64 & UINT_MAX);\
|
||||||
return (LibError)(err__ & UINT_MAX);\
|
DEBUG_WARN_ERR(err);\
|
||||||
|
return err;\
|
||||||
}\
|
}\
|
||||||
)
|
)
|
||||||
#else
|
#else
|
||||||
#define CHECK_ERR(expression)\
|
#define CHECK_ERR(expression)\
|
||||||
STMT(\
|
STMT(\
|
||||||
i64 err__ = (i64)(expression);\
|
i64 err64 = (i64)(expression);\
|
||||||
if(err__ < 0)\
|
if(err64 < 0)\
|
||||||
{\
|
{\
|
||||||
DEBUG_WARN_ERR(err__);\
|
LibError err = (LibError)(err64 & UINT_MAX);\
|
||||||
return (LibError)(err__ & UINT_MAX);\
|
DEBUG_WARN_ERR(err);\
|
||||||
|
return (LibError)(err & UINT_MAX);\
|
||||||
}\
|
}\
|
||||||
)
|
)
|
||||||
#endif
|
#endif
|
||||||
@ -80,9 +87,12 @@ STMT(\
|
|||||||
// (useful for functions that can legitimately fail, e.g. vfs_exists).
|
// (useful for functions that can legitimately fail, e.g. vfs_exists).
|
||||||
#define RETURN_ERR(expression)\
|
#define RETURN_ERR(expression)\
|
||||||
STMT(\
|
STMT(\
|
||||||
i64 err__ = (i64)(expression);\
|
i64 err64 = (i64)(expression);\
|
||||||
if(err__ < 0)\
|
if(err64 < 0)\
|
||||||
return (LibError)(err__ & UINT_MAX);\
|
{\
|
||||||
|
LibError err = (LibError)(err64 & UINT_MAX);\
|
||||||
|
return err;\
|
||||||
|
}\
|
||||||
)
|
)
|
||||||
|
|
||||||
// return an error and warn about it (replaces debug_warn+return)
|
// return an error and warn about it (replaces debug_warn+return)
|
||||||
@ -95,11 +105,12 @@ STMT(\
|
|||||||
// if expression evaluates to a negative i64, warn user and throw the number.
|
// if expression evaluates to a negative i64, warn user and throw the number.
|
||||||
#define THROW_ERR(expression)\
|
#define THROW_ERR(expression)\
|
||||||
STMT(\
|
STMT(\
|
||||||
i64 err__ = (i64)(expression);\
|
i64 err64 = (i64)(expression);\
|
||||||
if(err__ < 0)\
|
if(err64 < 0)\
|
||||||
{\
|
{\
|
||||||
DEBUG_WARN_ERR(err__);\
|
LibError err = (LibError)(err64 & UINT_MAX);\
|
||||||
throw (LibError)(err__ & UINT_MAX);\
|
DEBUG_WARN_ERR(err);\
|
||||||
|
throw err;\
|
||||||
}\
|
}\
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -107,10 +118,11 @@ STMT(\
|
|||||||
// (useful for void functions that must bail and complain)
|
// (useful for void functions that must bail and complain)
|
||||||
#define WARN_ERR_RETURN(expression)\
|
#define WARN_ERR_RETURN(expression)\
|
||||||
STMT(\
|
STMT(\
|
||||||
i64 err__ = (i64)(expression);\
|
i64 err64 = (i64)(expression);\
|
||||||
if(err__ < 0)\
|
if(err64 < 0)\
|
||||||
{\
|
{\
|
||||||
DEBUG_WARN_ERR(err__);\
|
LibError err = (LibError)(err64 & UINT_MAX);\
|
||||||
|
DEBUG_WARN_ERR(err);\
|
||||||
return;\
|
return;\
|
||||||
}\
|
}\
|
||||||
)
|
)
|
||||||
@ -119,9 +131,12 @@ STMT(\
|
|||||||
// (this is similar to debug_assert but also works in release mode)
|
// (this is similar to debug_assert but also works in release mode)
|
||||||
#define WARN_ERR(expression)\
|
#define WARN_ERR(expression)\
|
||||||
STMT(\
|
STMT(\
|
||||||
i64 err__ = (i64)(expression);\
|
i64 err64 = (i64)(expression);\
|
||||||
if(err__ < 0)\
|
if(err64 < 0)\
|
||||||
DEBUG_WARN_ERR(err__);\
|
{\
|
||||||
|
LibError err = (LibError)(err64 & UINT_MAX);\
|
||||||
|
DEBUG_WARN_ERR(err);\
|
||||||
|
}\
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -133,7 +148,7 @@ STMT(\
|
|||||||
{\
|
{\
|
||||||
debug_warn("FYI: WARN_RETURN_IF_FALSE reports that a function failed."\
|
debug_warn("FYI: WARN_RETURN_IF_FALSE reports that a function failed."\
|
||||||
"feel free to ignore or suppress this warning.");\
|
"feel free to ignore or suppress this warning.");\
|
||||||
return -1;\
|
return ERR_FAIL;\
|
||||||
}\
|
}\
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -141,7 +156,7 @@ STMT(\
|
|||||||
#define RETURN_IF_FALSE(ok)\
|
#define RETURN_IF_FALSE(ok)\
|
||||||
STMT(\
|
STMT(\
|
||||||
if(!(ok))\
|
if(!(ok))\
|
||||||
return -1;\
|
return ERR_FAIL;\
|
||||||
)
|
)
|
||||||
|
|
||||||
// if ok evaluates to false or FALSE, warn user.
|
// if ok evaluates to false or FALSE, warn user.
|
||||||
@ -174,6 +189,8 @@ ERR(1, INFO_CB_CONTINUE , "1 (not an error)")
|
|||||||
ERR(2, INFO_CANNOT_HANDLE, "2 (not an error)")
|
ERR(2, INFO_CANNOT_HANDLE, "2 (not an error)")
|
||||||
ERR(3, INFO_NO_REPLACE , "3 (not an error)")
|
ERR(3, INFO_NO_REPLACE , "3 (not an error)")
|
||||||
ERR(4, INFO_SKIPPED , "4 (not an error)")
|
ERR(4, INFO_SKIPPED , "4 (not an error)")
|
||||||
|
//
|
||||||
|
ERR(5, INFO_ALL_COMPLETE, "5 (not an error)")
|
||||||
|
|
||||||
ERR(-100000, ERR_LOGIC, "Logic error in code")
|
ERR(-100000, ERR_LOGIC, "Logic error in code")
|
||||||
ERR(-100060, ERR_TIMED_OUT, "Timed out")
|
ERR(-100060, ERR_TIMED_OUT, "Timed out")
|
||||||
|
@ -27,7 +27,7 @@ typedef std::map<wchar_t, unsigned short> glyphmap_id;
|
|||||||
// Store the size separately, because it's used separately
|
// Store the size separately, because it's used separately
|
||||||
typedef std::map<wchar_t, int> glyphmap_size;
|
typedef std::map<wchar_t, int> glyphmap_size;
|
||||||
|
|
||||||
glyphmap_id* BoundGlyphs = NULL;
|
static glyphmap_id* BoundGlyphs = NULL;
|
||||||
|
|
||||||
struct UniFont
|
struct UniFont
|
||||||
{
|
{
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include "ia32.h"
|
#include "ia32.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// pass "omit frame pointer" setting on to the compiler
|
// pass "omit frame pointer" setting on to the compiler
|
||||||
#if MSC_VERSION
|
#if MSC_VERSION
|
||||||
# if CONFIG_OMIT_FP
|
# if CONFIG_OMIT_FP
|
||||||
@ -129,40 +130,13 @@ extern void* alloca(size_t size);
|
|||||||
|
|
||||||
// raise a message box with the given text or (depending on platform)
|
// raise a message box with the given text or (depending on platform)
|
||||||
// otherwise inform the user.
|
// otherwise inform the user.
|
||||||
|
// called from debug_display_msgw.
|
||||||
extern void sys_display_msg(const char* caption, const char* msg);
|
extern void sys_display_msg(const char* caption, const char* msg);
|
||||||
extern void sys_display_msgw(const wchar_t* caption, const wchar_t* msg);
|
extern void sys_display_msgw(const wchar_t* caption, const wchar_t* msg);
|
||||||
|
|
||||||
// choices offered by the shared error dialog
|
// show the error dialog. flags: see DisplayErrorFlags.
|
||||||
enum ErrorReaction
|
// called from debug_display_error.
|
||||||
{
|
enum ErrorReaction;
|
||||||
// ignore, continue as if nothing happened.
|
|
||||||
ER_CONTINUE = 1,
|
|
||||||
// note: don't start at 0 because that is interpreted as a
|
|
||||||
// DialogBoxParam failure.
|
|
||||||
|
|
||||||
// ignore and do not report again.
|
|
||||||
// only returned if DE_ALLOW_SUPPRESS was passed.
|
|
||||||
ER_SUPPRESS,
|
|
||||||
// note: non-persistent; only applicable during this program run.
|
|
||||||
|
|
||||||
// trigger breakpoint, i.e. enter debugger.
|
|
||||||
// only returned if DE_MANUAL_BREAK was passed; otherwise,
|
|
||||||
// display_error will trigger a breakpoint itself.
|
|
||||||
ER_BREAK,
|
|
||||||
|
|
||||||
// exit the program immediately.
|
|
||||||
// never returned; display_error exits immediately.
|
|
||||||
ER_EXIT
|
|
||||||
};
|
|
||||||
|
|
||||||
enum SysDisplayErrorFlags
|
|
||||||
{
|
|
||||||
DE_ALLOW_SUPPRESS = 1,
|
|
||||||
DE_NO_CONTINUE = 2,
|
|
||||||
DE_MANUAL_BREAK = 4
|
|
||||||
};
|
|
||||||
|
|
||||||
// internal use only (used by display_error)
|
|
||||||
extern ErrorReaction sys_display_error(const wchar_t* text, int flags);
|
extern ErrorReaction sys_display_error(const wchar_t* text, int flags);
|
||||||
|
|
||||||
|
|
||||||
|
@ -102,7 +102,7 @@ void wdbg_set_thread_name(const char* name)
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
// check heap integrity (independently of mmgr).
|
// check heap integrity (independently of mmgr).
|
||||||
// errors are reported by the CRT or via display_error.
|
// errors are reported by the CRT or via debug_display_error.
|
||||||
void debug_heap_check()
|
void debug_heap_check()
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
@ -616,7 +616,7 @@ static const wchar_t* get_exception_locus(const EXCEPTION_POINTERS* ep)
|
|||||||
// no problems with wdbg_exception_filter's "%[^:]" format string.
|
// no problems with wdbg_exception_filter's "%[^:]" format string.
|
||||||
|
|
||||||
// note: keep formatting in sync with wdbg_exception_filter, which
|
// note: keep formatting in sync with wdbg_exception_filter, which
|
||||||
// extracts file/line for use with display_error.
|
// extracts file/line for use with debug_display_error.
|
||||||
static wchar_t locus[256];
|
static wchar_t locus[256];
|
||||||
swprintf(locus, ARRAY_SIZE(locus), L"%hs (%hs:%d)", func_name, file, line);
|
swprintf(locus, ARRAY_SIZE(locus), L"%hs (%hs:%d)", func_name, file, line);
|
||||||
return locus;
|
return locus;
|
||||||
@ -709,7 +709,7 @@ LONG WINAPI wdbg_exception_filter(EXCEPTION_POINTERS* ep)
|
|||||||
int flags = 0;
|
int flags = 0;
|
||||||
if(ep->ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE)
|
if(ep->ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE)
|
||||||
flags = DE_NO_CONTINUE;
|
flags = DE_NO_CONTINUE;
|
||||||
ErrorReaction er = display_error(buf, flags, 1, ep->ContextRecord, file, line);
|
ErrorReaction er = debug_display_error(buf, flags, 1,ep->ContextRecord, file,line);
|
||||||
debug_assert(er > 0);
|
debug_assert(er > 0);
|
||||||
|
|
||||||
wdbg_write_minidump(ep);
|
wdbg_write_minidump(ep);
|
||||||
|
@ -579,8 +579,6 @@ int poll(struct pollfd /* fds */[], int /* nfds */, int /* timeout */)
|
|||||||
//
|
//
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// convert POSIX PROT_* flags to their Win32 PAGE_* enumeration equivalents.
|
// convert POSIX PROT_* flags to their Win32 PAGE_* enumeration equivalents.
|
||||||
// used by mprotect.
|
// used by mprotect.
|
||||||
static DWORD win32_prot(int prot)
|
static DWORD win32_prot(int prot)
|
||||||
@ -637,25 +635,22 @@ static LibError mmap_mem(void* start, size_t len, int prot, int flags, int fd, v
|
|||||||
// see explanation at MAP_NORESERVE definition.
|
// see explanation at MAP_NORESERVE definition.
|
||||||
bool want_commit = (prot != PROT_NONE && !(flags & MAP_NORESERVE));
|
bool want_commit = (prot != PROT_NONE && !(flags & MAP_NORESERVE));
|
||||||
|
|
||||||
|
// decommit a given area (leaves its address space reserved)
|
||||||
if(!want_commit && start != 0 && flags & MAP_FIXED)
|
if(!want_commit && start != 0 && flags & MAP_FIXED)
|
||||||
{
|
{
|
||||||
MEMORY_BASIC_INFORMATION mbi;
|
MEMORY_BASIC_INFORMATION mbi;
|
||||||
BOOL ok = VirtualQuery(start, &mbi, len);
|
WARN_RETURN_IF_FALSE(VirtualQuery(start, &mbi, len));
|
||||||
debug_assert(ok); // todo4
|
if(mbi.State == MEM_COMMIT)
|
||||||
DWORD state = mbi.State;
|
|
||||||
if(state == MEM_COMMIT)
|
|
||||||
{
|
{
|
||||||
ok = VirtualFree(start, len, MEM_DECOMMIT);
|
WARN_IF_FALSE(VirtualFree(start, len, MEM_DECOMMIT));
|
||||||
debug_assert(ok);
|
|
||||||
*pp = 0;
|
*pp = 0;
|
||||||
return ERR_OK;
|
return ERR_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD op = want_commit? MEM_COMMIT : MEM_RESERVE;
|
DWORD flAllocationType = want_commit? MEM_COMMIT : MEM_RESERVE;
|
||||||
|
|
||||||
DWORD flProtect = win32_prot(prot);
|
DWORD flProtect = win32_prot(prot);
|
||||||
void* p = VirtualAlloc(start, len, op, flProtect);
|
void* p = VirtualAlloc(start, len, flAllocationType, flProtect);
|
||||||
if(!p)
|
if(!p)
|
||||||
return ERR_NO_MEM;
|
return ERR_NO_MEM;
|
||||||
*pp = p;
|
*pp = p;
|
||||||
@ -759,6 +754,7 @@ void* mmap(void* start, size_t len, int prot, int flags, int fd, off_t ofs)
|
|||||||
if(err < 0)
|
if(err < 0)
|
||||||
{
|
{
|
||||||
WARN_ERR(err);
|
WARN_ERR(err);
|
||||||
|
LibError_set_errno(err);
|
||||||
return MAP_FAILED;
|
return MAP_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -333,7 +333,7 @@ ErrorReaction sys_display_error(const wchar_t* text, int flags)
|
|||||||
// failed; warn user and make sure we return an ErrorReaction.
|
// failed; warn user and make sure we return an ErrorReaction.
|
||||||
if(ret == 0 || ret == -1)
|
if(ret == 0 || ret == -1)
|
||||||
{
|
{
|
||||||
display_msgw(L"Error", L"Unable to display detailed error dialog.");
|
debug_display_msgw(L"Error", L"Unable to display detailed error dialog.");
|
||||||
return ER_CONTINUE;
|
return ER_CONTINUE;
|
||||||
}
|
}
|
||||||
return (ErrorReaction)ret;
|
return (ErrorReaction)ret;
|
||||||
|
@ -95,18 +95,18 @@ static int ProgressiveLoad()
|
|||||||
{
|
{
|
||||||
wchar_t description[100];
|
wchar_t description[100];
|
||||||
int progress_percent;
|
int progress_percent;
|
||||||
int ret = LDR_ProgressiveLoad(10e-3, description, ARRAY_SIZE(description), &progress_percent);
|
LibError ret = LDR_ProgressiveLoad(10e-3, description, ARRAY_SIZE(description), &progress_percent);
|
||||||
switch(ret)
|
switch(ret)
|
||||||
{
|
{
|
||||||
// no load active => no-op (skip code below)
|
// no load active => no-op (skip code below)
|
||||||
case 0:
|
case ERR_OK:
|
||||||
return 0;
|
return 0;
|
||||||
// current task didn't complete. we only care about this insofar as the
|
// current task didn't complete. we only care about this insofar as the
|
||||||
// load process is therefore not yet finished.
|
// load process is therefore not yet finished.
|
||||||
case ERR_TIMED_OUT:
|
case ERR_TIMED_OUT:
|
||||||
break;
|
break;
|
||||||
// just finished loading
|
// just finished loading
|
||||||
case LDR_ALL_FINISHED:
|
case INFO_ALL_COMPLETE:
|
||||||
g_Game->ReallyStartGame();
|
g_Game->ReallyStartGame();
|
||||||
wcscpy_s(description, ARRAY_SIZE(description), L"Game is starting..");
|
wcscpy_s(description, ARRAY_SIZE(description), L"Game is starting..");
|
||||||
// LDR_ProgressiveLoad returns L""; set to valid text to
|
// LDR_ProgressiveLoad returns L""; set to valid text to
|
||||||
|
@ -64,7 +64,7 @@ int CFont::GetHeight()
|
|||||||
return unifont_height(h);
|
return unifont_height(h);
|
||||||
}
|
}
|
||||||
|
|
||||||
int CFont::GetCharacterWidth(const wchar_t& c)
|
int CFont::GetCharacterWidth(wchar_t c)
|
||||||
{
|
{
|
||||||
return unifont_character_width(h, c);
|
return unifont_character_width(h, c);
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ public:
|
|||||||
void Bind();
|
void Bind();
|
||||||
int GetLineSpacing();
|
int GetLineSpacing();
|
||||||
int GetHeight();
|
int GetHeight();
|
||||||
int GetCharacterWidth(const wchar_t& c);
|
int GetCharacterWidth(wchar_t c);
|
||||||
void CalculateStringSize(const CStrW& string, int& w, int& h);
|
void CalculateStringSize(const CStrW& string, int& w, int& h);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -522,8 +522,7 @@ static void InitVfs(const char* argv0)
|
|||||||
// rationale for data/ being root: untrusted scripts must not be
|
// rationale for data/ being root: untrusted scripts must not be
|
||||||
// allowed to overwrite critical game (or worse, OS) files.
|
// allowed to overwrite critical game (or worse, OS) files.
|
||||||
// the VFS prevents any accesses to files above this directory.
|
// the VFS prevents any accesses to files above this directory.
|
||||||
int err = file_set_root_dir(argv0, "../data");
|
WARN_ERR(file_set_root_dir(argv0, "../data"));
|
||||||
WARN_ERR(err);
|
|
||||||
|
|
||||||
vfs_init();
|
vfs_init();
|
||||||
vfs_mount("", "mods/official", VFS_MOUNT_RECURSIVE|VFS_MOUNT_ARCHIVES|VFS_MOUNT_WATCH);
|
vfs_mount("", "mods/official", VFS_MOUNT_RECURSIVE|VFS_MOUNT_ARCHIVES|VFS_MOUNT_WATCH);
|
||||||
|
@ -84,14 +84,14 @@ struct DurationAdder: public std::binary_function<double, const LoadRequest&, do
|
|||||||
// this routine is provided so we can prevent 2 simultaneous load operations,
|
// this routine is provided so we can prevent 2 simultaneous load operations,
|
||||||
// which is bogus. that can happen by clicking the load button quickly,
|
// which is bogus. that can happen by clicking the load button quickly,
|
||||||
// or issuing via console while already loading.
|
// or issuing via console while already loading.
|
||||||
int LDR_BeginRegistering()
|
LibError LDR_BeginRegistering()
|
||||||
{
|
{
|
||||||
if(state != IDLE)
|
if(state != IDLE)
|
||||||
return -1;
|
return ERR_LOGIC;
|
||||||
|
|
||||||
state = REGISTERING;
|
state = REGISTERING;
|
||||||
load_requests.clear();
|
load_requests.clear();
|
||||||
return 0;
|
return ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -103,7 +103,7 @@ int LDR_BeginRegistering()
|
|||||||
// <estimated_duration_ms>: used to calculate progress, and when checking
|
// <estimated_duration_ms>: used to calculate progress, and when checking
|
||||||
// whether there is enough of the time budget left to process this task
|
// whether there is enough of the time budget left to process this task
|
||||||
// (reduces timeslice overruns, making the main loop more responsive).
|
// (reduces timeslice overruns, making the main loop more responsive).
|
||||||
int LDR_Register(LoadFunc func, void* param, const wchar_t* description,
|
LibError LDR_Register(LoadFunc func, void* param, const wchar_t* description,
|
||||||
int estimated_duration_ms)
|
int estimated_duration_ms)
|
||||||
{
|
{
|
||||||
if(state != REGISTERING)
|
if(state != REGISTERING)
|
||||||
@ -111,21 +111,21 @@ int LDR_Register(LoadFunc func, void* param, const wchar_t* description,
|
|||||||
debug_warn("not called between LDR_(Begin|End)Register - why?!");
|
debug_warn("not called between LDR_(Begin|End)Register - why?!");
|
||||||
// warn here instead of relying on the caller to CHECK_ERR because
|
// warn here instead of relying on the caller to CHECK_ERR because
|
||||||
// there will be lots of call sites spread around.
|
// there will be lots of call sites spread around.
|
||||||
return -1;
|
return ERR_LOGIC;
|
||||||
}
|
}
|
||||||
|
|
||||||
const LoadRequest lr(func, param, description, estimated_duration_ms);
|
const LoadRequest lr(func, param, description, estimated_duration_ms);
|
||||||
load_requests.push_back(lr);
|
load_requests.push_back(lr);
|
||||||
return 0;
|
return ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// call when finished registering tasks; subsequent calls to
|
// call when finished registering tasks; subsequent calls to
|
||||||
// LDR_ProgressiveLoad will then work off the queued entries.
|
// LDR_ProgressiveLoad will then work off the queued entries.
|
||||||
int LDR_EndRegistering()
|
LibError LDR_EndRegistering()
|
||||||
{
|
{
|
||||||
if(state != REGISTERING)
|
if(state != REGISTERING)
|
||||||
return -1;
|
return ERR_LOGIC;
|
||||||
|
|
||||||
if(load_requests.empty())
|
if(load_requests.empty())
|
||||||
debug_warn("no LoadRequests queued");
|
debug_warn("no LoadRequests queued");
|
||||||
@ -134,25 +134,25 @@ int LDR_EndRegistering()
|
|||||||
estimated_duration_tally = 0.0;
|
estimated_duration_tally = 0.0;
|
||||||
task_elapsed_time = 0.0;
|
task_elapsed_time = 0.0;
|
||||||
total_estimated_duration = std::accumulate(load_requests.begin(), load_requests.end(), 0.0, DurationAdder());
|
total_estimated_duration = std::accumulate(load_requests.begin(), load_requests.end(), 0.0, DurationAdder());
|
||||||
return 0;
|
return ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// immediately cancel this load; no further tasks will be processed.
|
// immediately cancel this load; no further tasks will be processed.
|
||||||
// used to abort loading upon user request or failure.
|
// used to abort loading upon user request or failure.
|
||||||
// note: no special notification will be returned by LDR_ProgressiveLoad.
|
// note: no special notification will be returned by LDR_ProgressiveLoad.
|
||||||
int LDR_Cancel()
|
LibError LDR_Cancel()
|
||||||
{
|
{
|
||||||
// note: calling during registering doesn't make sense - that
|
// note: calling during registering doesn't make sense - that
|
||||||
// should be an atomic sequence of begin, register [..], end.
|
// should be an atomic sequence of begin, register [..], end.
|
||||||
if(state != LOADING)
|
if(state != LOADING)
|
||||||
return -1;
|
return ERR_LOGIC;
|
||||||
|
|
||||||
state = IDLE;
|
state = IDLE;
|
||||||
// the queue doesn't need to be emptied now; that'll happen during the
|
// the queue doesn't need to be emptied now; that'll happen during the
|
||||||
// next LDR_StartRegistering. for now, it is sufficient to set the
|
// next LDR_StartRegistering. for now, it is sufficient to set the
|
||||||
// state, so that LDR_ProgressiveLoad is a no-op.
|
// state, so that LDR_ProgressiveLoad is a no-op.
|
||||||
return 0;
|
return ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -186,7 +186,7 @@ static bool HaveTimeForNextTask(double time_left, double time_budget, int estima
|
|||||||
// ("" if finished) and the current progress value.
|
// ("" if finished) and the current progress value.
|
||||||
//
|
//
|
||||||
// return semantics:
|
// return semantics:
|
||||||
// - if the final load task just completed, return LDR_ALL_FINISHED.
|
// - if the final load task just completed, return INFO_ALL_COMPLETE.
|
||||||
// - if loading is in progress but didn't finish, return ERR_TIMED_OUT.
|
// - if loading is in progress but didn't finish, return ERR_TIMED_OUT.
|
||||||
// - if not currently loading (no-op), return 0.
|
// - if not currently loading (no-op), return 0.
|
||||||
// - any other value indicates a failure; the request has been de-queued.
|
// - any other value indicates a failure; the request has been de-queued.
|
||||||
@ -196,10 +196,10 @@ static bool HaveTimeForNextTask(double time_left, double time_budget, int estima
|
|||||||
// persistent, we can't just store a pointer. returning a pointer to
|
// persistent, we can't just store a pointer. returning a pointer to
|
||||||
// our copy of the description doesn't work either, since it's freed when
|
// our copy of the description doesn't work either, since it's freed when
|
||||||
// the request is de-queued. that leaves writing into caller's buffer.
|
// the request is de-queued. that leaves writing into caller's buffer.
|
||||||
int LDR_ProgressiveLoad(double time_budget, wchar_t* description,
|
LibError LDR_ProgressiveLoad(double time_budget, wchar_t* description,
|
||||||
size_t max_chars, int* progress_percent)
|
size_t max_chars, int* progress_percent)
|
||||||
{
|
{
|
||||||
int ret; // single exit; this is returned
|
LibError ret; // single exit; this is returned
|
||||||
double progress = 0.0; // used to set progress_percent
|
double progress = 0.0; // used to set progress_percent
|
||||||
double time_left = time_budget;
|
double time_left = time_budget;
|
||||||
|
|
||||||
@ -217,7 +217,7 @@ int LDR_ProgressiveLoad(double time_budget, wchar_t* description,
|
|||||||
// we're called unconditionally from the main loop, so this isn't
|
// we're called unconditionally from the main loop, so this isn't
|
||||||
// an error; there is just nothing to do.
|
// an error; there is just nothing to do.
|
||||||
if(state != LOADING)
|
if(state != LOADING)
|
||||||
return 0;
|
return ERR_OK;
|
||||||
|
|
||||||
while(!load_requests.empty())
|
while(!load_requests.empty())
|
||||||
{
|
{
|
||||||
@ -232,13 +232,13 @@ int LDR_ProgressiveLoad(double time_budget, wchar_t* description,
|
|||||||
|
|
||||||
// call this task's function and bill elapsed time.
|
// call this task's function and bill elapsed time.
|
||||||
const double t0 = get_time();
|
const double t0 = get_time();
|
||||||
ret = lr.func(lr.param, time_left);
|
int status = lr.func(lr.param, time_left);
|
||||||
const double elapsed_time = get_time() - t0;
|
const double elapsed_time = get_time() - t0;
|
||||||
time_left -= elapsed_time;
|
time_left -= elapsed_time;
|
||||||
task_elapsed_time += elapsed_time;
|
task_elapsed_time += elapsed_time;
|
||||||
|
|
||||||
// either finished entirely, or failed => remove from queue.
|
// either finished entirely, or failed => remove from queue.
|
||||||
if(ret == 0 || ret < 0)
|
if(status <= 0)
|
||||||
{
|
{
|
||||||
debug_printf("LOADER| completed %ls in %g ms; estimate was %g ms\n", lr.description.c_str(), task_elapsed_time*1e3, estimated_duration*1e3);
|
debug_printf("LOADER| completed %ls in %g ms; estimate was %g ms\n", lr.description.c_str(), task_elapsed_time*1e3, estimated_duration*1e3);
|
||||||
task_elapsed_time = 0.0;
|
task_elapsed_time = 0.0;
|
||||||
@ -254,32 +254,37 @@ int LDR_ProgressiveLoad(double time_budget, wchar_t* description,
|
|||||||
// function interrupted itself; add its estimated progress.
|
// function interrupted itself; add its estimated progress.
|
||||||
// note: monotonicity is guaranteed since we never add more than
|
// note: monotonicity is guaranteed since we never add more than
|
||||||
// its estimated_duration_ms.
|
// its estimated_duration_ms.
|
||||||
if(ret > 0)
|
if(status > 0)
|
||||||
{
|
{
|
||||||
ret = MIN(ret, 100); // clamp in case estimate is too high
|
status = MIN(status, 100); // clamp in case estimate is too high
|
||||||
current_estimate += estimated_duration * ret/100.0;
|
current_estimate += estimated_duration * status/100.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
progress = current_estimate / total_estimated_duration;
|
progress = current_estimate / total_estimated_duration;
|
||||||
}
|
}
|
||||||
|
|
||||||
// translate return value
|
// do we need to continue?
|
||||||
// (function interrupted itself; need to return ERR_TIMED_OUT)
|
// .. function interrupted itself, i.e. timed out; abort.
|
||||||
if(ret > 0)
|
if(status > 0)
|
||||||
|
{
|
||||||
ret = ERR_TIMED_OUT;
|
ret = ERR_TIMED_OUT;
|
||||||
|
|
||||||
// failed or timed out => abort immediately; loading will
|
|
||||||
// continue when we're called in the next iteration of the main loop.
|
|
||||||
// rationale: bail immediately instead of remembering the first error
|
|
||||||
// that came up, so that we report can all errors that happen.
|
|
||||||
if(ret != 0)
|
|
||||||
goto done;
|
goto done;
|
||||||
// else: continue and process next queued task.
|
}
|
||||||
|
// .. failed; abort. loading will continue when we're called in
|
||||||
|
// the next iteration of the main loop.
|
||||||
|
// rationale: bail immediately instead of remembering the first
|
||||||
|
// error that came up so we report can all errors that happen.
|
||||||
|
else if(status < 0)
|
||||||
|
{
|
||||||
|
ret = (LibError)status;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
// .. succeeded; continue and process next queued task.
|
||||||
}
|
}
|
||||||
|
|
||||||
// queue is empty, we just finished.
|
// queue is empty, we just finished.
|
||||||
state = IDLE;
|
state = IDLE;
|
||||||
ret = LDR_ALL_FINISHED;
|
ret = INFO_ALL_COMPLETE;
|
||||||
|
|
||||||
|
|
||||||
// set output params (there are several return points above)
|
// set output params (there are several return points above)
|
||||||
@ -302,7 +307,7 @@ done:
|
|||||||
|
|
||||||
// immediately process all queued load requests.
|
// immediately process all queued load requests.
|
||||||
// returns 0 on success or a negative error code.
|
// returns 0 on success or a negative error code.
|
||||||
int LDR_NonprogressiveLoad()
|
LibError LDR_NonprogressiveLoad()
|
||||||
{
|
{
|
||||||
const double time_budget = 100.0;
|
const double time_budget = 100.0;
|
||||||
// large enough so that individual functions won't time out
|
// large enough so that individual functions won't time out
|
||||||
@ -312,15 +317,14 @@ int LDR_NonprogressiveLoad()
|
|||||||
|
|
||||||
for(;;)
|
for(;;)
|
||||||
{
|
{
|
||||||
int ret = LDR_ProgressiveLoad(time_budget, description, ARRAY_SIZE(description), &progress_percent);
|
LibError ret = LDR_ProgressiveLoad(time_budget, description, ARRAY_SIZE(description), &progress_percent);
|
||||||
|
|
||||||
switch(ret)
|
switch(ret)
|
||||||
{
|
{
|
||||||
case 0:
|
case ERR_OK:
|
||||||
debug_warn("No load in progress");
|
debug_warn("No load in progress");
|
||||||
return 0; // success
|
return ERR_OK;
|
||||||
case LDR_ALL_FINISHED:
|
case INFO_ALL_COMPLETE:
|
||||||
return 0; // success
|
return ERR_OK;
|
||||||
case ERR_TIMED_OUT:
|
case ERR_TIMED_OUT:
|
||||||
break; // continue loading
|
break; // continue loading
|
||||||
default:
|
default:
|
||||||
|
@ -87,7 +87,7 @@ registering member functions, which would otherwise be messy.
|
|||||||
// this routine is provided so we can prevent 2 simultaneous load operations,
|
// this routine is provided so we can prevent 2 simultaneous load operations,
|
||||||
// which is bogus. that can happen by clicking the load button quickly,
|
// which is bogus. that can happen by clicking the load button quickly,
|
||||||
// or issuing via console while already loading.
|
// or issuing via console while already loading.
|
||||||
extern int LDR_BeginRegistering();
|
extern LibError LDR_BeginRegistering();
|
||||||
|
|
||||||
|
|
||||||
// callback function of a task; performs the actual work.
|
// callback function of a task; performs the actual work.
|
||||||
@ -111,23 +111,21 @@ typedef int (*LoadFunc)(void* param, double time_left);
|
|||||||
// <estimated_duration_ms>: used to calculate progress, and when checking
|
// <estimated_duration_ms>: used to calculate progress, and when checking
|
||||||
// whether there is enough of the time budget left to process this task
|
// whether there is enough of the time budget left to process this task
|
||||||
// (reduces timeslice overruns, making the main loop more responsive).
|
// (reduces timeslice overruns, making the main loop more responsive).
|
||||||
extern int LDR_Register(LoadFunc func, void* param, const wchar_t* description,
|
extern LibError LDR_Register(LoadFunc func, void* param, const wchar_t* description,
|
||||||
int estimated_duration_ms);
|
int estimated_duration_ms);
|
||||||
|
|
||||||
|
|
||||||
// call when finished registering tasks; subsequent calls to
|
// call when finished registering tasks; subsequent calls to
|
||||||
// LDR_ProgressiveLoad will then work off the queued entries.
|
// LDR_ProgressiveLoad will then work off the queued entries.
|
||||||
extern int LDR_EndRegistering();
|
extern LibError LDR_EndRegistering();
|
||||||
|
|
||||||
|
|
||||||
// immediately cancel this load; no further tasks will be processed.
|
// immediately cancel this load; no further tasks will be processed.
|
||||||
// used to abort loading upon user request or failure.
|
// used to abort loading upon user request or failure.
|
||||||
// note: no special notification will be returned by LDR_ProgressiveLoad.
|
// note: no special notification will be returned by LDR_ProgressiveLoad.
|
||||||
extern int LDR_Cancel();
|
extern LibError LDR_Cancel();
|
||||||
|
|
||||||
|
|
||||||
const int LDR_ALL_FINISHED = 1;
|
|
||||||
|
|
||||||
// process as many of the queued tasks as possible within <time_budget> [s].
|
// process as many of the queued tasks as possible within <time_budget> [s].
|
||||||
// if a task is lengthy, the budget may be exceeded. call from the main loop.
|
// if a task is lengthy, the budget may be exceeded. call from the main loop.
|
||||||
//
|
//
|
||||||
@ -135,7 +133,7 @@ const int LDR_ALL_FINISHED = 1;
|
|||||||
// ("" if finished) and the current progress value.
|
// ("" if finished) and the current progress value.
|
||||||
//
|
//
|
||||||
// return semantics:
|
// return semantics:
|
||||||
// - if the final load task just completed, return LDR_ALL_FINISHED.
|
// - if the final load task just completed, return INFO_ALL_COMPLETE.
|
||||||
// - if loading is in progress but didn't finish, return ERR_TIMED_OUT.
|
// - if loading is in progress but didn't finish, return ERR_TIMED_OUT.
|
||||||
// - if not currently loading (no-op), return 0.
|
// - if not currently loading (no-op), return 0.
|
||||||
// - any other value indicates a failure; the request has been de-queued.
|
// - any other value indicates a failure; the request has been de-queued.
|
||||||
@ -145,12 +143,12 @@ const int LDR_ALL_FINISHED = 1;
|
|||||||
// persistent, we can't just store a pointer. returning a pointer to
|
// persistent, we can't just store a pointer. returning a pointer to
|
||||||
// our copy of the description doesn't work either, since it's freed when
|
// our copy of the description doesn't work either, since it's freed when
|
||||||
// the request is de-queued. that leaves writing into caller's buffer.
|
// the request is de-queued. that leaves writing into caller's buffer.
|
||||||
extern int LDR_ProgressiveLoad(double time_budget, wchar_t* next_description,
|
extern LibError LDR_ProgressiveLoad(double time_budget, wchar_t* next_description,
|
||||||
size_t max_chars, int* progress_percent);
|
size_t max_chars, int* progress_percent);
|
||||||
|
|
||||||
// immediately process all queued load requests.
|
// immediately process all queued load requests.
|
||||||
// returns 0 on success or a negative error code.
|
// returns 0 on success or a negative error code.
|
||||||
extern int LDR_NonprogressiveLoad();
|
extern LibError LDR_NonprogressiveLoad();
|
||||||
|
|
||||||
|
|
||||||
// boilerplate check-if-timed-out and return-progress-percent code.
|
// boilerplate check-if-timed-out and return-progress-percent code.
|
||||||
|
@ -33,12 +33,12 @@ public:
|
|||||||
// Implementation of AbstractProfileTable interface
|
// Implementation of AbstractProfileTable interface
|
||||||
virtual CStr GetName();
|
virtual CStr GetName();
|
||||||
virtual CStr GetTitle();
|
virtual CStr GetTitle();
|
||||||
virtual uint GetNumberRows();
|
virtual size_t GetNumberRows();
|
||||||
virtual const std::vector<ProfileColumn>& GetColumns();
|
virtual const std::vector<ProfileColumn>& GetColumns();
|
||||||
|
|
||||||
virtual CStr GetCellText(uint row, uint col);
|
virtual CStr GetCellText(size_t row, size_t col);
|
||||||
virtual AbstractProfileTable* GetChild(uint row);
|
virtual AbstractProfileTable* GetChild(size_t row);
|
||||||
virtual bool IsHighlightRow(uint row);
|
virtual bool IsHighlightRow(size_t row);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
@ -97,7 +97,7 @@ CStr CProfileNodeTable::GetTitle()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Total number of children
|
// Total number of children
|
||||||
uint CProfileNodeTable::GetNumberRows()
|
size_t CProfileNodeTable::GetNumberRows()
|
||||||
{
|
{
|
||||||
return node->GetChildren()->size() + node->GetScriptChildren()->size() + 1;
|
return node->GetChildren()->size() + node->GetScriptChildren()->size() + 1;
|
||||||
}
|
}
|
||||||
@ -109,11 +109,11 @@ const std::vector<ProfileColumn>& CProfileNodeTable::GetColumns()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Retrieve cell text
|
// Retrieve cell text
|
||||||
CStr CProfileNodeTable::GetCellText(uint row, uint col)
|
CStr CProfileNodeTable::GetCellText(size_t row, size_t col)
|
||||||
{
|
{
|
||||||
CProfileNode* child;
|
CProfileNode* child;
|
||||||
uint nrchildren = node->GetChildren()->size();
|
size_t nrchildren = node->GetChildren()->size();
|
||||||
uint nrscriptchildren = node->GetScriptChildren()->size();
|
size_t nrscriptchildren = node->GetScriptChildren()->size();
|
||||||
char buf[256];
|
char buf[256];
|
||||||
|
|
||||||
if (row < nrchildren)
|
if (row < nrchildren)
|
||||||
@ -177,11 +177,11 @@ CStr CProfileNodeTable::GetCellText(uint row, uint col)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Return a pointer to the child table if the child node is expandable
|
// Return a pointer to the child table if the child node is expandable
|
||||||
AbstractProfileTable* CProfileNodeTable::GetChild(uint row)
|
AbstractProfileTable* CProfileNodeTable::GetChild(size_t row)
|
||||||
{
|
{
|
||||||
CProfileNode* child;
|
CProfileNode* child;
|
||||||
uint nrchildren = node->GetChildren()->size();
|
size_t nrchildren = node->GetChildren()->size();
|
||||||
uint nrscriptchildren = node->GetScriptChildren()->size();
|
size_t nrscriptchildren = node->GetScriptChildren()->size();
|
||||||
|
|
||||||
if (row < nrchildren)
|
if (row < nrchildren)
|
||||||
child = (*node->GetChildren())[row];
|
child = (*node->GetChildren())[row];
|
||||||
@ -197,10 +197,10 @@ AbstractProfileTable* CProfileNodeTable::GetChild(uint row)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Highlight all script nodes
|
// Highlight all script nodes
|
||||||
bool CProfileNodeTable::IsHighlightRow(uint row)
|
bool CProfileNodeTable::IsHighlightRow(size_t row)
|
||||||
{
|
{
|
||||||
uint nrchildren = node->GetChildren()->size();
|
size_t nrchildren = node->GetChildren()->size();
|
||||||
uint nrscriptchildren = node->GetScriptChildren()->size();
|
size_t nrscriptchildren = node->GetScriptChildren()->size();
|
||||||
|
|
||||||
return (row >= nrchildren && row < (nrchildren + nrscriptchildren));
|
return (row >= nrchildren && row < (nrchildren + nrscriptchildren));
|
||||||
}
|
}
|
||||||
|
@ -85,9 +85,9 @@ void CProfileViewerInternals::NavigateTree(int id)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
AbstractProfileTable* table = path[path.size() - 1];
|
AbstractProfileTable* table = path[path.size() - 1];
|
||||||
int numrows = table->GetNumberRows();
|
size_t numrows = table->GetNumberRows();
|
||||||
|
|
||||||
for(int row = 0; row < numrows; ++row)
|
for(size_t row = 0; row < numrows; ++row)
|
||||||
{
|
{
|
||||||
AbstractProfileTable* child = table->GetChild(row);
|
AbstractProfileTable* child = table->GetChild(row);
|
||||||
|
|
||||||
@ -132,17 +132,17 @@ void CProfileViewer::RenderProfile()
|
|||||||
|
|
||||||
AbstractProfileTable* table = m->path[m->path.size() - 1];
|
AbstractProfileTable* table = m->path[m->path.size() - 1];
|
||||||
const std::vector<ProfileColumn>& columns = table->GetColumns();
|
const std::vector<ProfileColumn>& columns = table->GetColumns();
|
||||||
uint numrows = table->GetNumberRows();
|
size_t numrows = table->GetNumberRows();
|
||||||
|
|
||||||
// Render background
|
// Render background
|
||||||
int estimate_height;
|
uint estimate_height;
|
||||||
int estimate_width;
|
uint estimate_width;
|
||||||
|
|
||||||
estimate_width = 50;
|
estimate_width = 50;
|
||||||
for(uint i = 0; i < columns.size(); ++i)
|
for(uint i = 0; i < columns.size(); ++i)
|
||||||
estimate_width += columns[i].width;
|
estimate_width += columns[i].width;
|
||||||
|
|
||||||
estimate_height = 3 + numrows;
|
estimate_height = 3 + (uint)numrows;
|
||||||
if (m->path.size() > 1)
|
if (m->path.size() > 1)
|
||||||
estimate_height += 2;
|
estimate_height += 2;
|
||||||
estimate_height = 20*estimate_height;
|
estimate_height = 20*estimate_height;
|
||||||
|
@ -70,7 +70,7 @@ public:
|
|||||||
*
|
*
|
||||||
* @return Number of rows in this table.
|
* @return Number of rows in this table.
|
||||||
*/
|
*/
|
||||||
virtual uint GetNumberRows() = 0;
|
virtual size_t GetNumberRows() = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GetColumnDescriptions
|
* GetColumnDescriptions
|
||||||
@ -87,7 +87,7 @@ public:
|
|||||||
*
|
*
|
||||||
* @return Text to be displayed in the given cell.
|
* @return Text to be displayed in the given cell.
|
||||||
*/
|
*/
|
||||||
virtual CStr GetCellText(uint row, uint col) = 0;
|
virtual CStr GetCellText(size_t row, size_t col) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GetChild: Return a row's child table if the child is expandable.
|
* GetChild: Return a row's child table if the child is expandable.
|
||||||
@ -97,7 +97,7 @@ public:
|
|||||||
* @return Pointer to the child table if the given row has one.
|
* @return Pointer to the child table if the given row has one.
|
||||||
* Otherwise, return 0.
|
* Otherwise, return 0.
|
||||||
*/
|
*/
|
||||||
virtual AbstractProfileTable* GetChild(uint row) = 0;
|
virtual AbstractProfileTable* GetChild(size_t row) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* IsHighlightRow
|
* IsHighlightRow
|
||||||
@ -106,7 +106,7 @@ public:
|
|||||||
*
|
*
|
||||||
* @return true if the row should be highlighted in a special color.
|
* @return true if the row should be highlighted in a special color.
|
||||||
*/
|
*/
|
||||||
virtual bool IsHighlightRow(uint row) { UNUSED2(row); return false; }
|
virtual bool IsHighlightRow(size_t row) { UNUSED2(row); return false; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ bool VFSUtil::FindFiles (const CStr& dirname, const char* filter, FileList& file
|
|||||||
// also returned.
|
// also returned.
|
||||||
//
|
//
|
||||||
// note: EnumDirEntsCB path and ent are only valid during the callback.
|
// note: EnumDirEntsCB path and ent are only valid during the callback.
|
||||||
int VFSUtil::EnumDirEnts(const CStr start_path, int flags, const char* user_filter,
|
LibError VFSUtil::EnumDirEnts(const CStr start_path, int flags, const char* user_filter,
|
||||||
EnumDirEntsCB cb, void* context)
|
EnumDirEntsCB cb, void* context)
|
||||||
{
|
{
|
||||||
debug_assert((flags & ~(RECURSIVE)) == 0);
|
debug_assert((flags & ~(RECURSIVE)) == 0);
|
||||||
@ -119,5 +119,5 @@ int VFSUtil::EnumDirEnts(const CStr start_path, int flags, const char* user_filt
|
|||||||
}
|
}
|
||||||
while(!dir_queue.empty());
|
while(!dir_queue.empty());
|
||||||
|
|
||||||
return 0;
|
return ERR_OK;
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ enum EnumDirEntsFlags
|
|||||||
// call <cb> for each entry matching <user_filter> (see vfs_next_dirent) in
|
// call <cb> for each entry matching <user_filter> (see vfs_next_dirent) in
|
||||||
// directory <path>; if flags & RECURSIVE, entries in subdirectories are
|
// directory <path>; if flags & RECURSIVE, entries in subdirectories are
|
||||||
// also returned.
|
// also returned.
|
||||||
extern int EnumDirEnts(const CStr path, int flags, const char* filter,
|
extern LibError EnumDirEnts(const CStr path, int flags, const char* filter,
|
||||||
EnumDirEntsCB cb, void* context);
|
EnumDirEntsCB cb, void* context);
|
||||||
|
|
||||||
}; // namespace VFSUtil
|
}; // namespace VFSUtil
|
||||||
|
@ -97,6 +97,9 @@ private:
|
|||||||
// Must be last to count number of rows
|
// Must be last to count number of rows
|
||||||
NumberRows
|
NumberRows
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// no copy ctor because some members are const
|
||||||
|
CRendererStatsTable& operator=(const CRendererStatsTable&);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Construction
|
// Construction
|
||||||
|
Loading…
Reference in New Issue
Block a user