Index: ps/trunk/source/ps/Loader.h =================================================================== --- ps/trunk/source/ps/Loader.h +++ ps/trunk/source/ps/Loader.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2009 Wildfire Games. +/* Copyright (C) 2019 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -116,17 +116,17 @@ // != 0, or it's treated as "finished") // - on failure, return a negative error code or 'warning' (see above); // LDR_ProgressiveLoad will abort immediately and return that. -typedef int (*LoadFunc)(void* param, double time_left); +typedef int (*LoadFunc)(std::shared_ptr param, double time_left); // register a task (later processed in FIFO order). // : function that will perform the actual work; see LoadFunc. -// : (optional) parameter/persistent state; must be freed by func. +// : (optional) parameter/persistent state. // : user-visible description of the current task, e.g. // "Loading Textures". // : used to calculate progress, and when checking // whether there is enough of the time budget left to process this task // (reduces timeslice overruns, making the main loop more responsive). -extern void LDR_Register(LoadFunc func, void* param, const wchar_t* description, +extern void LDR_Register(LoadFunc func, std::shared_ptr param, const wchar_t* description, int estimated_duration_ms); Index: ps/trunk/source/ps/Loader.cpp =================================================================== --- ps/trunk/source/ps/Loader.cpp +++ ps/trunk/source/ps/Loader.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2009 Wildfire Games. +/* Copyright (C) 2019 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -62,18 +62,17 @@ // member documentation is in LDR_Register (avoid duplication). LoadFunc func; - void* param; + // MemFun_t instance + std::shared_ptr param; + + // Translatable string shown to the player. CStrW description; - // rationale for storing as CStrW here: - // - needs to be WCS because it's user-visible and will be translated. - // - don't just store a pointer - the caller's string may be volatile. - // - the module interface must work in C, so we get/set as wchar_t*. int estimated_duration_ms; // LDR_Register gets these as parameters; pack everything together. - LoadRequest(LoadFunc func_, void* param_, const wchar_t* desc_, int ms_) + LoadRequest(LoadFunc func_, std::shared_ptr param_, const wchar_t* desc_, int ms_) : func(func_), param(param_), description(desc_), estimated_duration_ms(ms_) { @@ -109,13 +108,13 @@ // register a task (later processed in FIFO order). // : function that will perform the actual work; see LoadFunc. -// : (optional) parameter/persistent state; must be freed by func. +// : (optional) parameter/persistent state. // : user-visible description of the current task, e.g. // "Loading Textures". // : used to calculate progress, and when checking // whether there is enough of the time budget left to process this task // (reduces timeslice overruns, making the main loop more responsive). -void LDR_Register(LoadFunc func, void* param, const wchar_t* description, +void LDR_Register(LoadFunc func, std::shared_ptr param, const wchar_t* description, int estimated_duration_ms) { ENSURE(state == REGISTERING); // must be called between LDR_(Begin|End)Register Index: ps/trunk/source/ps/LoaderThunks.h =================================================================== --- ps/trunk/source/ps/LoaderThunks.h +++ ps/trunk/source/ps/LoaderThunks.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2009 Wildfire Games. +/* Copyright (C) 2019 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -18,15 +18,6 @@ #ifndef INCLUDED_LOADERTHUNKS #define INCLUDED_LOADERTHUNKS -// rationale for allocating MemFun_t dynamically: -// need to store class pointer, function, and argument for each registered -// function; single static storage isn't possible. we don't want to break -// C compat in the Loader.h interface, so we can't have it take care of this. -// that leaves dynamic alloc or reserving some static storage freed when -// load registration begins. the former is slower and requires checking -// the thunked function's return value (because we mustn't free MemFun_t -// if the function times out), but is simpler. - // VC7 warns if T::*func is not aligned to its size (4..16 bytes on IA-32). // this is a bug, since sizeof(void*) would be enough. MS says it won't // be fixed: see http://www.dotnet247.com/247reference/msgs/1/7782.aspx @@ -54,21 +45,16 @@ : this_(this__), func(func_) {} }; -template static int MemFunThunk(void* param, double UNUSED(time_left)) +template static int MemFunThunk(std::shared_ptr param, double UNUSED(time_left)) { - MemFun_t* const mf = (MemFun_t*)param; - int ret = (mf->this_->*mf->func)(); - - if(!ldr_was_interrupted(ret)) - delete mf; - return ret; + MemFun_t* const mf = static_cast*>(param.get()); + return (mf->this_->*mf->func)(); } template void RegMemFun(T* this_, int(T::*func)(void), const wchar_t* description, int estimated_duration_ms) { - void* param = new MemFun_t(this_, func); - LDR_Register(MemFunThunk, param, description, estimated_duration_ms); + LDR_Register(MemFunThunk, std::make_shared>(this_, func), description, estimated_duration_ms); } @@ -86,20 +72,16 @@ : this_(this__), func(func_), arg(arg_) {} }; -template static int MemFun1Thunk(void* param, double UNUSED(time_left)) +template static int MemFun1Thunk(shared_ptr param, double UNUSED(time_left)) { - MemFun1_t* const mf = (MemFun1_t*)param; - int ret = (mf->this_->*mf->func)(mf->arg); - if(!ldr_was_interrupted(ret)) - delete mf; - return ret; + MemFun1_t* const mf = static_cast*>(param.get()); + return (mf->this_->*mf->func)(mf->arg); } template void RegMemFun1(T* this_, int(T::*func)(Arg), Arg arg, const wchar_t* description, int estimated_duration_ms) { - void* param = new MemFun1_t(this_, func, arg); - LDR_Register(MemFun1Thunk, param, description, estimated_duration_ms); + LDR_Register(MemFun1Thunk, std::make_shared >(this_, func, arg), description, estimated_duration_ms); } #endif // INCLUDED_LOADERTHUNKS