Owning bundle that assembles a list of ILayoutSourceFactory instances into a single CompositeLayoutSource.
More...
#include <phosphor-layout-api/include/PhosphorLayoutApi/LayoutSourceBundle.h>
Public Member Functions | |
| LayoutSourceBundle () | |
| ~LayoutSourceBundle () | |
| LayoutSourceBundle (const LayoutSourceBundle &)=delete | |
| LayoutSourceBundle & | operator= (const LayoutSourceBundle &)=delete |
| LayoutSourceBundle (LayoutSourceBundle &&) noexcept | |
| LayoutSourceBundle & | operator= (LayoutSourceBundle &&) noexcept |
| void | addFactory (std::unique_ptr< ILayoutSourceFactory > factory) |
| Register a factory. | |
| void | build () |
| Materialise sources from every registered factory and wire the composite. | |
| void | buildFromRegistered (const FactoryContext &ctx) |
Auto-discovery convenience: drain every provider registered via LayoutSourceProviderRegistrar (in priority order, ties broken by registration order), invoke each builder with ctx, add any non-null factories returned, and call build(). | |
| CompositeLayoutSource * | composite () const |
| The unified composite over every registered source. | |
| ILayoutSource * | source (const QString &name) const |
Borrowed access to the source produced by the factory whose name() matches name. | |
Owning bundle that assembles a list of ILayoutSourceFactory instances into a single CompositeLayoutSource.
Primary entry point: buildFromRegistered(ctx). Composition roots (daemon, editor, settings, future plugin hosts) populate a FactoryContext with the registries they own and let the bundle pick up every provider that self-registered at static-init time via LayoutSourceProviderRegistrar. Adding a new family — e.g. the planned scrolling engine — is purely a new provider library; no edits to this bundle or to composition roots (assuming the engine reuses an existing ctx service).
Escape hatch: addFactory for tests or custom compositions that want to pre-register a fixture-specific source alongside (or in place of) the auto-discovered set. The two sets are stitched into the same composite — pre-registered factories come first, then auto-discovered providers in priority order.
Lifetime contract for consumers: the bundle owns every source and the composite. Callers may hold a borrowed pointer to composite() (or to any source via source()) for as long as the bundle is alive. Resetting or destroying the bundle while observers still hold raw pointers is a use-after-free — disconnect signals, drop QML bindings, and cancel pending D-Bus calls before teardown.
| PhosphorLayout::LayoutSourceBundle::LayoutSourceBundle | ( | ) |
| PhosphorLayout::LayoutSourceBundle::~LayoutSourceBundle | ( | ) |
|
delete |
|
noexcept |
| void PhosphorLayout::LayoutSourceBundle::addFactory | ( | std::unique_ptr< ILayoutSourceFactory > | factory | ) |
Register a factory.
Order is significant — the composite iterates sources in registration order, which determines id-namespace precedence for collisions (in practice each provider library uses a distinct id prefix, so collisions are only theoretical).
May only be called before build() or buildFromRegistered(); registering after either call is a programmer error and triggers a Q_ASSERT in debug builds. The single-shot gate is per-bundle — move-assign a fresh bundle to start a new registration cycle.
| void PhosphorLayout::LayoutSourceBundle::build | ( | ) |
Materialise sources from every registered factory and wire the composite.
Single-shot: calling build() after a successful build triggers a Q_ASSERT in debug builds and is a no-op in release. Each factory's create() is invoked exactly once. Matches the lifecycle discipline on addFactory and buildFromRegistered — any second-call into a built bundle is a programmer error. Duplicate factory names are detected here and logged at qWarning so consumer-side source(name) lookups don't silently target the wrong source.
| void PhosphorLayout::LayoutSourceBundle::buildFromRegistered | ( | const FactoryContext & | ctx | ) |
Auto-discovery convenience: drain every provider registered via LayoutSourceProviderRegistrar (in priority order, ties broken by registration order), invoke each builder with ctx, add any non-null factories returned, and call build().
Production composition roots (daemon, editor, settings) call this once after populating ctx with the registries they own. Builders that return nullptr (because ctx doesn't surface the engine's required service) are silently skipped — that's the "this composition root doesn't host this engine" signal.
Coexists with addFactory: callers may pre-register custom factories (typically tests with a fixture-specific source) before calling buildFromRegistered, and both sets will be stitched into the same composite.
Single-shot per bundle: calling buildFromRegistered a second time triggers a Q_ASSERT in debug builds and is a no-op in release. The bundle has no in-place reset — a caller that needs a rebuild (e.g. a future runtime plugin loader wanting to pick up newly-dlopen'd providers) must move-assign a fresh instance and re-wire every borrowed-pointer consumer that held composite() or source(name). This is why the @todo(plugin-compositor) marker in LayoutSourceProviderRegistry.h flags a redesign as the path forward for dynamic plugin loading rather than an incremental API addition.
Exception contract: provider builder lambdas and factory create() calls MUST NOT throw. The bundle performs no rollback on partial failure — a thrown builder leaves m_factories partially populated with already-consumed entries and m_composite null, and the single-shot gate then prevents any retry. Every in-tree builder is a trivial make_unique around a factory that stores a borrowed pointer, so this is currently impossible; any future builder that wants fallible construction needs to return nullptr (the documented "not hosted" signal) rather than throw.
|
inline |
The unified composite over every registered source.
Null until build() has been called.
|
delete |
|
noexcept |
| ILayoutSource * PhosphorLayout::LayoutSourceBundle::source | ( | const QString & | name | ) | const |
Borrowed access to the source produced by the factory whose name() matches name.
Returns null when no such factory has been registered or when build() has not run yet.
Names are unique within a bundle: build() enforces first-registration-wins and skips any duplicate-name factory (see the warning in LayoutSourceBundle::build). Callers may therefore treat the returned pointer as the single source for name — no "first match" disclaimer is needed.
Primary use case is the autotile-style fast path: composition roots that want to reuse a long-lived source's preview cache across calls hand the named pointer to consumers (see LayoutAdaptor::setAutotileLayoutSource etc.). The composite() pointer is the canonical ILayoutSource for every other call site — only reach for source(name) when a specific provider's cache discipline materially differs from the composite's.