add notify method to NotifierReg#418
Conversation
|
有點好玩 但是不知道要在什麼情境下使用 /usr/include/c++/15.1.1/bits/stl_vector.h:1370: std::vector<_Tp, _Alloc>::reference std::vector<_Tp, _Alloc>::back() [with _Tp = rime::Segment; _Alloc = std
|
|
用来通知插件外的组件有事件更新,最常用其实是update_notifier predict组件在更新的context之后update_notifier通知其他组件更新才能不按键都可以弹出 看来这样还是太简单了😂 -- 补充 这个是我在librime-predict的框架上做了个librime-predict-leveldb,但是那样是cpp实现,就想看看librime-lua加点api是不是可能lua实现来点灵活性(要调整可能简单点 |
如果要觸發 update_notifier 可以用 context::refresh_nonconfirmed_composition() prediict 以前看過 ,,太繞了 ,幾個 status 在notify 中轉來轉去 |
|
似乎是可以 |
predict-leveldb commit 了? |
fxliang/librime-predict-leveldb
似乎还是有差别,那个接口是依赖了composition非空和composition_.back().status < Segment::kSelected还是有一点点不一样 |
|
更新了下,这个问题应该解决了 |
diff --git a/src/types.cc b/src/types.cc
index 8a2db84..c62c9bf 100644
--- a/src/types.cc
+++ b/src/types.cc
@@ -1464,6 +1464,9 @@ static int raw_connect(lua_State *L) {
return 1;
}
+template<typename T, typename ... I>
+static void notify(T& t, I... i) { t(i...); }
+
namespace ConnectionReg {
using T = boost::signals2::connection;
@@ -1494,6 +1497,7 @@ namespace NotifierReg {
static const luaL_Reg methods[] = {
{ "connect", raw_connect<T, Context *>},
+ { "notify", WRAP((notify<T, Context*>))},
{ NULL, NULL },
};
@@ -1515,6 +1519,7 @@ namespace OptionUpdateNotifierReg {
static const luaL_Reg methods[] = {
{ "connect", raw_connect<T, Context *, const string&>},
+ { "notify", WRAP((notify<T, Context*, const string&>))},
{ NULL, NULL },
};
@@ -1536,6 +1541,7 @@ namespace PropertyUpdateNotifierReg {
static const luaL_Reg methods[] = {
{ "connect", raw_connect<T, Context *, const string&>},
+ { "notify", WRAP((notify<T, Context*, const string&>))},
{ NULL, NULL },
};
@@ -1557,6 +1563,7 @@ namespace KeyEventNotifierReg {
static const luaL_Reg methods[] = {
{ "connect", raw_connect<T, Context *, const KeyEvent&>},
+ { "notify", WRAP((notify<T, Context*, const KeyEvent&>))},
{ NULL, NULL },
};
|
|
是否需要引入,讨论有结果吗?目前状态是可能会引起崩溃? |
|
如果是在回调里去调对应的notifier又没条件跳过,是会崩,死循环 |
還有 使用 select_notifier:notify() 一定要檢查 not composition:empty() |
add notify for other Notifiers
递归触发的事加了几行,应该解了。select_notifier的额外处理还要再想想 |
在 notify() 檢查 select_notifier 和 空 segments 是可行的 template<typename T, typename C, typename ... I>
static void notify(T& t, C c, I... i) {
if (reinterpret_cast<void*>(&t) == reinterpret_cast<void*>(&c->select_notifier()) && c->composition().empty()) {
LOG(ERROR) << "notify of select error error : segments is empty";
return;
}
t(c, i...);
}
}沒有 segmnt 有segment |
|
我準備在 context 中加入 xxxx_notify() +class StopSlotException : public std::runtime_error {
+ public:
+ using std::runtime_error::runtime_error;
+};
+
class RIME_DLL Context {
public:
using Notifier = signal<void(Context* ctx)>;
@@ -81,6 +85,32 @@ class RIME_DLL Context {
// options and properties starting with '_' are local to schema;
// others are session scoped.
void ClearTransientOptions();
+ template <typename T, typename... I>
+ void notify(T& t, I&&... i) {
+ try {
+ t(i...);
+ } catch (const StopSlotException& e) {
+ LOG(INFO) << "stop slot " << e.what();
+ }
+ };
+ void commit_notify() { notify(commit_notifier_, this); };
+ void select_notify() {
+ if (this->composition().empty())
+ return;
+ notify(select_notifier_, this);
+ }
+ void update_notify() { notify(update_notifier_, this); };
+ void delete_notify() { notify(delete_notifier_, this); };
+ void abort_notify() { notify(abort_notifier_, this); };
+ void option_update_notify(const string& option) {
+ notify(option_update_notifier_, this, option);
+ };
+ void property_update_notify(const string& property) {
+ notify(property_update_notifier_, this, property);
+ };
+ void unhandled_key_notify(const rime::KeyEvent& key_event) {
+ notify(unhandled_key_notifier_, this, key_event);
+ };librime-lua raw_connect template<typename T, typename ... I>
static int raw_connect(lua_State *L) {
Lua *lua = Lua::from_state(L);
T & t = LuaType<T &>::todata(L, 1);
an<LuaObj> o = LuaObj::todata(L, 2);
auto f = [lua, o](I... i) {
auto r = lua->void_call<an<LuaObj>, Context *>(o, i...);
if (!r.ok()) {
auto e = r.get_err();
if ( e.e.find("::STOP_SLOT::") != string::npos) { // <---------
throw rime::StopSlotException(e.e);
}
LOG(ERROR) << "Context::Notifier error(" << e.status << "): " << e.e;
}
};--- lua script
function init(env)
env.commit_notify = env.engine.context.commit_notifier:connect(
function(ctx)
-- .......
error("::STOP_SLOT:: stop commit")
end, 0) -- 0 是group 把這傳播function 排在 Engine::OnCommit() 前,就會中止後面的 OnCommit() 呼叫
end
|
那你得说服佛振😀 |
|
很難 ,先送 PR吧 |


No description provided.