Files
msime-windows/engine/core/session.cpp
T
fanlusky a7779d2b05 refactor(engine): 将 engine 从 submodule 内嵌为仓内一等组件
`vendor/MetasequoiaImeEngine` submodule 改为 `engine/` 目录,导入的是
product-lock.json 原本钉住的提交 c810d201,逐文件核对过 blob,因此这是一次
搬迁而不是引擎升级。引擎自己的嵌套 submodule(googlepinyinime-rev、utfcpp、
miniaudio)按各自 gitlink 一并展开,来源与提交见 engine/UPSTREAM.md。

Windows 专门化裁掉了不属于本产品的部分:whisper.cpp 与本地推理 provider、
macOS 示例宿主、整个 dictionary/ 建库流水线、上游 CI 与 release-please 配置。
词库仍按 product-lock.json 在构建时取发布产物。

引擎不再进 product-lock.json:没有 gitlink 就没有可比对的东西,锁里写一个上游
commit 等于宣称这棵树仍等于上游,而第一个 Windows 专门化改动落地时这句话就假了。
verify-contracts / verify-checkout 随之移除,verify-published 保留。

CI 与工具链:引擎源码并入根 scripts/format.sh(删掉引擎自己的那份,避免两套排除
列表分叉);引擎 voice.yml 里的 silero_vad.onnx 摘要校验移到本仓 lock job;
engine-bump-triage 工作流与其测试删除;gitsubmodule 的 dependabot 频率由 daily
改为 monthly。

README、README.en、AGENTS.md、CONTRIBUTING、docs/product-release.md 及各子目录
文档同步说明新的位置与边界。
2026-09-12 03:40:48 +08:00

193 lines
6.6 KiB
C++

#include "../include/metasequoia/session.h"
#include "input_session.h"
#include "nine_key_session.h"
#include <stdexcept>
namespace metasequoia
{
class Session::Impl
{
public:
explicit Impl(const SessionOptions &options)
: session(options.scheme, options.shuangpin_profile, options.paths),
nine_key(options.paths, options.learning, options.frequency, options.fuzzy_pinyin)
{
session.set_quanpin_autocorrect_types(options.autocorrect_types);
session.set_fuzzy_pinyin_options(options.fuzzy_pinyin);
session.set_quanpin_helpcode_enabled(options.helpcode);
session.set_shuangpin_helpcode_enabled(options.helpcode);
if (!session.set_helpcode_schema(options.helpcode_schema) ||
!session.set_frequency_adjustment(options.frequency) || !session.set_english_input_options(options.english))
throw std::invalid_argument("Invalid session options");
session.set_local_mode_options(options.local_modes);
session.set_mixed_expressive_options(options.expressive);
session.set_wubi_input_options(options.wubi);
session.enable_fixed_positions();
}
InputSession session;
NineKeySession nine_key;
bool nine_key_enabled = false;
};
Session::Session(SessionOptions options)
{
options.paths.validate();
impl_ = std::make_unique<Impl>(options);
impl_->session.set_chinese_punctuation_enabled(options.chinese_punctuation);
impl_->session.set_candidate_learning_enabled(options.learning);
}
Session::~Session() = default;
void Session::set_nine_key_enabled(bool enabled)
{
impl_->nine_key.command(Command::Cancel);
impl_->nine_key_enabled = enabled;
}
KeyResult Session::choose_nine_key_spelling(std::size_t index)
{
return impl_->nine_key.choose_spelling(index);
}
KeyResult Session::character(char value, bool shift_only)
{
if (impl_->nine_key_enabled && impl_->session.scheme() == SchemeType::Quanpin &&
impl_->session.local_input_mode() == LocalInputMode::None && !impl_->session.dedicated_english_mode() &&
impl_->session.preedit().empty() && value >= '2' && value <= '9')
return impl_->nine_key.character(value);
if (impl_->nine_key.active())
return {};
return impl_->session.handle_character(value, shift_only);
}
KeyResult Session::command(Command value)
{
if (impl_->nine_key.active())
return impl_->nine_key.command(value);
return impl_->session.handle_command(value);
}
KeyResult Session::candidate_key(char value)
{
if (impl_->nine_key.active())
return value >= '1' && value <= '9' ? impl_->nine_key.select(value - '1') : KeyResult{};
return impl_->session.handle_candidate_key(value);
}
KeyResult Session::punctuation(char value)
{
if (impl_->nine_key.active())
{
auto result = impl_->session.handle_punctuation(value);
if (!result.handled)
return result;
const auto composition = impl_->nine_key.finish(0);
result.commit = composition.commit.value_or("") + result.commit.value_or("");
return result;
}
return impl_->session.handle_punctuation(value);
}
void Session::set_chinese_punctuation_enabled(bool enabled)
{
impl_->session.set_chinese_punctuation_enabled(enabled);
}
KeyResult Session::select(std::size_t index)
{
if (impl_->nine_key.active())
return impl_->nine_key.select(index);
return impl_->session.select_candidate(index);
}
KeyResult Session::select_edge(std::size_t index, CandidateEdge edge)
{
if (impl_->nine_key.active())
return {};
return impl_->session.select_candidate_edge(index, edge);
}
KeyResult Session::pin(std::size_t index)
{
if (impl_->nine_key.active())
return impl_->nine_key.pin(index);
return impl_->session.pin_candidate(index);
}
KeyResult Session::remove(std::size_t index)
{
if (impl_->nine_key.active())
return impl_->nine_key.remove(index);
return impl_->session.remove_candidate(index);
}
KeyResult Session::fix_position(std::size_t index, int position)
{
if (position < 1 || position > 5)
return {};
if (impl_->nine_key.active())
return impl_->nine_key.set_position(index, position);
return impl_->session.set_candidate_position(index, position);
}
KeyResult Session::clear_position(std::size_t index)
{
if (impl_->nine_key.active())
return impl_->nine_key.set_position(index, 0);
return impl_->session.set_candidate_position(index, 0);
}
KeyResult Session::finish()
{
return finish(0);
}
KeyResult Session::finish(std::size_t first_index)
{
if (impl_->nine_key.active())
return impl_->nine_key.finish(first_index);
return impl_->session.finish_composition(first_index);
}
void Session::switch_scheme(SchemeType scheme)
{
impl_->nine_key.command(Command::Cancel);
impl_->session.switch_scheme(scheme);
}
bool Session::is_supported_helpcode_schema(const std::string &schema)
{
return InputSession::is_supported_helpcode_schema(schema);
}
bool Session::set_helpcode_schema(const std::string &schema)
{
return impl_->session.set_helpcode_schema(schema);
}
void Session::set_helpcode_enabled(bool enabled)
{
impl_->session.set_quanpin_helpcode_enabled(enabled);
impl_->session.set_shuangpin_helpcode_enabled(enabled);
}
void Session::set_dedicated_english(bool enabled)
{
impl_->nine_key.command(Command::Cancel);
impl_->session.set_dedicated_english_mode(enabled);
}
void Session::set_wubi_mixed_pinyin(bool enabled)
{
impl_->session.set_wubi_input_options(WubiInputOptions{enabled});
}
SessionSnapshot Session::snapshot() const
{
if (impl_->nine_key.active())
return impl_->nine_key.snapshot();
const auto &session = impl_->session;
SessionSnapshot view{session.scheme(),
session.local_input_mode(),
session.preedit(),
session.raw_segmentation(),
session.normalized_segmentation(),
session.candidates(),
session.dedicated_english_mode(),
session.editing_text(),
session.caret_position()};
view.answered_by_pinyin_fallback = session.answered_by_pinyin_fallback();
return view;
}
std::optional<OnlineQuery> Session::online_query() const
{
if (impl_->nine_key.active())
return std::nullopt;
return impl_->session.online_query();
}
bool Session::apply_online_candidate(const OnlineQuery &query, std::string candidate, CandidateSource source)
{
if (impl_->nine_key.active())
return false;
return impl_->session.apply_online_candidate(query, std::move(candidate), source);
}
} // namespace metasequoia