Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions docs/spec/core/bridge.md
Original file line number Diff line number Diff line change
Expand Up @@ -869,6 +869,17 @@ static-init time. The `inline` keyword lets the definition in this header be
included and instantiated across many translation units without an ODR/link
violation; the registration itself runs from the macro's static initializer.

`BRIDGE_REGISTER_ACTION_SOURCE(M, A)` — the `.cpp`-side half of
`BRIDGE_REGISTER_ACTION` decomposed into a header-only declaration
(`BRIDGE_DECLARE_ACTION`) plus a registration call, for a model header whose
per-TU registration cost is worth moving out (see
[registry.md, "Moving a registrar out of the
header"](registry.md#moving-a-registrar-out-of-the-header)) — emits
exactly the same two initializers as (b) above, so it carries the identical
`#include <morph/core/bridge.hpp>` requirement: the translation unit calling
`BRIDGE_REGISTER_ACTION_SOURCE` must include this header, or the link fails
on the same unresolved `registerActionExecutorOnce<M, A>` symbol.

## `MemberPointerTraits`

Declared as `morph::bridge::detail::MemberPointerTraits`.
Expand Down
197 changes: 197 additions & 0 deletions docs/spec/core/registry.md

Large diffs are not rendered by default.

43 changes: 26 additions & 17 deletions examples/kanban/include/kanban/models/board_model.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -543,23 +543,32 @@ class BoardModel {

} // namespace kanban

BRIDGE_REGISTER_MODEL(kanban::BoardModel, "BoardModel")
BRIDGE_REGISTER_ACTION(kanban::BoardModel, kanban::OpenBoard, "OpenBoard", ::morph::model::Loggable::No)
BRIDGE_REGISTER_ACTION(kanban::BoardModel, kanban::GetBoardState, "GetBoardState", ::morph::model::Loggable::No)
BRIDGE_REGISTER_ACTION(kanban::BoardModel, kanban::CreateColumn, "CreateColumn")
BRIDGE_REGISTER_ACTION(kanban::BoardModel, kanban::CreateSwimlane, "CreateSwimlane")
BRIDGE_REGISTER_ACTION(kanban::BoardModel, kanban::CreateTask, "CreateTask")
BRIDGE_REGISTER_ACTION(kanban::BoardModel, kanban::AddComment, "AddComment")
BRIDGE_REGISTER_ACTION(kanban::BoardModel, kanban::MoveTaskPosition, "MoveTaskPosition")
BRIDGE_REGISTER_ACTION(kanban::BoardModel, kanban::GetEventsSince, "GetEventsSince", ::morph::model::Loggable::No)
BRIDGE_REGISTER_ACTION(kanban::BoardModel, kanban::GetActivity, "GetActivity", ::morph::model::Loggable::No)
BRIDGE_REGISTER_ACTION(kanban::BoardModel, kanban::CreateRule, "CreateRule")
BRIDGE_REGISTER_ACTION(kanban::BoardModel, kanban::GetRules, "GetRules", ::morph::model::Loggable::No)
BRIDGE_REGISTER_ACTION(kanban::BoardModel, kanban::DeleteRule, "DeleteRule")
BRIDGE_REGISTER_ACTION(kanban::BoardModel, kanban::ApplyTagMutation, "ApplyTagMutation")
BRIDGE_REGISTER_ACTION(kanban::BoardModel, kanban::AddAttachment, "AddAttachment")
BRIDGE_REGISTER_ACTION(kanban::BoardModel, kanban::GetAttachments, "GetAttachments", ::morph::model::Loggable::No)
BRIDGE_REGISTER_ACTION(kanban::BoardModel, kanban::RemoveAttachment, "RemoveAttachment")
// Declared, not registered: this header is reached by ~20 translation units
// (test files, the QML/GUI bridge, app.cpp), and BRIDGE_REGISTER_MODEL/
// BRIDGE_REGISTER_ACTION's registrar initialiser would instantiate this
// model's action codecs, buildActionDescription<A>, and forms::schemaJson<A>
// again in every one of them -- a measured double-digit CPU-second cost per
// TU, for codecs the overwhelming majority of those TUs never call (see
// docs/spec/core/registry.md, "Moving a registrar out of the header"). The
// actual registration happens once, in board_model.cpp, via
// BRIDGE_REGISTER_MODEL_SOURCE/BRIDGE_REGISTER_ACTION_SOURCE.
BRIDGE_DECLARE_MODEL(kanban::BoardModel, "BoardModel")
BRIDGE_DECLARE_ACTION(kanban::BoardModel, kanban::OpenBoard, "OpenBoard", ::morph::model::Loggable::No)
BRIDGE_DECLARE_ACTION(kanban::BoardModel, kanban::GetBoardState, "GetBoardState", ::morph::model::Loggable::No)
BRIDGE_DECLARE_ACTION(kanban::BoardModel, kanban::CreateColumn, "CreateColumn")
BRIDGE_DECLARE_ACTION(kanban::BoardModel, kanban::CreateSwimlane, "CreateSwimlane")
BRIDGE_DECLARE_ACTION(kanban::BoardModel, kanban::CreateTask, "CreateTask")
BRIDGE_DECLARE_ACTION(kanban::BoardModel, kanban::AddComment, "AddComment")
BRIDGE_DECLARE_ACTION(kanban::BoardModel, kanban::MoveTaskPosition, "MoveTaskPosition")
BRIDGE_DECLARE_ACTION(kanban::BoardModel, kanban::GetEventsSince, "GetEventsSince", ::morph::model::Loggable::No)
BRIDGE_DECLARE_ACTION(kanban::BoardModel, kanban::GetActivity, "GetActivity", ::morph::model::Loggable::No)
BRIDGE_DECLARE_ACTION(kanban::BoardModel, kanban::CreateRule, "CreateRule")
BRIDGE_DECLARE_ACTION(kanban::BoardModel, kanban::GetRules, "GetRules", ::morph::model::Loggable::No)
BRIDGE_DECLARE_ACTION(kanban::BoardModel, kanban::DeleteRule, "DeleteRule")
BRIDGE_DECLARE_ACTION(kanban::BoardModel, kanban::ApplyTagMutation, "ApplyTagMutation")
BRIDGE_DECLARE_ACTION(kanban::BoardModel, kanban::AddAttachment, "AddAttachment")
BRIDGE_DECLARE_ACTION(kanban::BoardModel, kanban::GetAttachments, "GetAttachments", ::morph::model::Loggable::No)
BRIDGE_DECLARE_ACTION(kanban::BoardModel, kanban::RemoveAttachment, "RemoveAttachment")

// `BoardModel` is keyed on the project the board belongs to, and `OpenBoard`
// is the action that names it. `BRIDGE_MODEL_KEY` deduces the key *type* from
Expand Down
24 changes: 24 additions & 0 deletions examples/kanban/src/models/board_model.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1474,3 +1474,27 @@ GetActivityResult BoardModel::execute(const GetActivity& /*action*/) {
}

} // namespace kanban

// The actual registration board_model.hpp's BRIDGE_DECLARE_MODEL/
// BRIDGE_DECLARE_ACTION calls defer to this one translation unit -- see the
// comment above those calls, and docs/spec/core/registry.md, "Moving a
// registrar out of the header". A model header reached by many translation
// units (kanban's tests, the QML/GUI bridge, app.cpp) pays for this once,
// here, instead of once per including TU.
BRIDGE_REGISTER_MODEL_SOURCE(kanban::BoardModel)
BRIDGE_REGISTER_ACTION_SOURCE(kanban::BoardModel, kanban::OpenBoard)
BRIDGE_REGISTER_ACTION_SOURCE(kanban::BoardModel, kanban::GetBoardState)
BRIDGE_REGISTER_ACTION_SOURCE(kanban::BoardModel, kanban::CreateColumn)
BRIDGE_REGISTER_ACTION_SOURCE(kanban::BoardModel, kanban::CreateSwimlane)
BRIDGE_REGISTER_ACTION_SOURCE(kanban::BoardModel, kanban::CreateTask)
BRIDGE_REGISTER_ACTION_SOURCE(kanban::BoardModel, kanban::AddComment)
BRIDGE_REGISTER_ACTION_SOURCE(kanban::BoardModel, kanban::MoveTaskPosition)
BRIDGE_REGISTER_ACTION_SOURCE(kanban::BoardModel, kanban::GetEventsSince)
BRIDGE_REGISTER_ACTION_SOURCE(kanban::BoardModel, kanban::GetActivity)
BRIDGE_REGISTER_ACTION_SOURCE(kanban::BoardModel, kanban::CreateRule)
BRIDGE_REGISTER_ACTION_SOURCE(kanban::BoardModel, kanban::GetRules)
BRIDGE_REGISTER_ACTION_SOURCE(kanban::BoardModel, kanban::DeleteRule)
BRIDGE_REGISTER_ACTION_SOURCE(kanban::BoardModel, kanban::ApplyTagMutation)
BRIDGE_REGISTER_ACTION_SOURCE(kanban::BoardModel, kanban::AddAttachment)
BRIDGE_REGISTER_ACTION_SOURCE(kanban::BoardModel, kanban::GetAttachments)
BRIDGE_REGISTER_ACTION_SOURCE(kanban::BoardModel, kanban::RemoveAttachment)
Loading
Loading