添加语言包改变事件注册及通知

This commit is contained in:
gb 2023-01-19 15:44:47 +08:00
parent 507d7538bd
commit 55b7297367
1 changed files with 65 additions and 3 deletions

View File

@ -15,6 +15,7 @@
#include <map> #include <map>
#include <algorithm> #include <algorithm>
#include <locale.h> #include <locale.h>
#include <thread>
namespace util namespace util
{ {
@ -142,7 +143,18 @@ class lang_mgr
return std::find(code_pages.begin(), code_pages.end(), cp) != code_pages.end(); return std::find(code_pages.begin(), code_pages.end(), cp) != code_pages.end();
} }
}MAPSTR; }MAPSTR;
typedef struct _chg_notify
{
void(*notify)(int code_page, void* param);
void* param;
bool operator==(void(*ntfy)(int code_page, void* param))
{
return notify == ntfy;
}
}CHGNOTIFY;
std::vector<CHGNOTIFY> notify_;
volatile bool in_changing_;
std::vector<MAPSTR> code_pages_; std::vector<MAPSTR> code_pages_;
LANATTR **all_; LANATTR **all_;
uint32_t os_cp_; uint32_t os_cp_;
@ -286,6 +298,11 @@ class lang_mgr
return ret; return ret;
} }
void notify_changed(void)
{
for (auto& v : notify_)
v.notify(cur_cp_, v.param);
}
#if defined(_WIN32) || defined(_WIN64) #if defined(_WIN32) || defined(_WIN64)
static std::string u2a(const wchar_t* u, UINT cp = CP_ACP) static std::string u2a(const wchar_t* u, UINT cp = CP_ACP)
@ -447,7 +464,7 @@ class lang_mgr
#endif #endif
} }
lang_mgr() : os_cp_(lang_mgr::get_os_code_page()), cur_cp_(-1), cur_lang_(""), all_(nullptr) lang_mgr() : os_cp_(lang_mgr::get_os_code_page()), cur_cp_(-1), cur_lang_(""), all_(nullptr), in_changing_(true)
{ {
std::string path(get_module_path()); std::string path(get_module_path());
size_t pos = path.rfind(PATH_SEPERATOR[0]); size_t pos = path.rfind(PATH_SEPERATOR[0]);
@ -482,6 +499,7 @@ class lang_mgr
str += v.name.length() + 2; str += v.name.length() + 2;
st++; st++;
} }
in_changing_ = false;
} }
~lang_mgr() ~lang_mgr()
{ {
@ -520,7 +538,7 @@ public:
if (*locale >= '0' && *locale <= '9') if (*locale >= '0' && *locale <= '9')
cp = atoi(locale); cp = atoi(locale);
} }
end = (char *)";"; *end = ';';
} }
return cp; return cp;
@ -557,12 +575,30 @@ public:
if (it == code_pages_.end()) if (it == code_pages_.end())
return ENOENT; return ENOENT;
load_language_pak(it->file.c_str(), false); std::string f(it->file);
in_changing_ = true;
std::this_thread::sleep_for(std::chrono::milliseconds(50));
cp = cur_cp_;
load_language_pak(f.c_str(), false);
in_changing_ = false;
if (cp != cur_cp_)
notify_changed();
return 0; return 0;
} }
const char* get_string(uint32_t id, int* err) const char* get_string(uint32_t id, int* err)
{ {
int cnt = 0;
while (in_changing_)
{
std::this_thread::sleep_for(std::chrono::milliseconds(10));
if (cnt++ > 100)
return "";
}
if (map_off_[id].size()) if (map_off_[id].size())
{ {
if (err) if (err)
@ -582,6 +618,28 @@ public:
{ {
return code_pages_.size(); return code_pages_.size();
} }
void register_language_changed_notify(void(*lan_changed)(int code_page, void* param), bool reg, void* param = nullptr)
{
std::vector<CHGNOTIFY>::iterator it = std::find(notify_.begin(), notify_.end(), lan_changed);
if (it == notify_.end())
{
if (reg)
{
CHGNOTIFY c;
c.notify = lan_changed;
c.param = param;
notify_.push_back(c);
}
}
else
{
if (reg)
it->param = param;
else
notify_.erase(it);
}
}
}; };
lang_mgr* lang_mgr::inst_ = nullptr; lang_mgr* lang_mgr::inst_ = nullptr;
@ -610,4 +668,8 @@ extern "C"
{ {
return lang_mgr::instance()->get_string(id, err); return lang_mgr::instance()->get_string(id, err);
} }
void register_language_changed_notify(void(*lan_changed)(int code_page, void* param), bool reg, void* param)
{
lang_mgr::instance()->register_language_changed_notify(lan_changed, reg, param);
}
} }