Host Ownership of Shared Values
In the previous chapter:
audiodeckbecame the host.audio_encodewas embedded inside it.- The UI was unified.
- Only
audiodeckwas enabled.
However, one important thing has not changed yet.
audio_encode is still storing its shared values in fallback storage.
Current State
Right now, shared values for audio_encode live in:
context.scene.qa_shared
So even though:
audiodeckcontrols the panelaudio_encoderenders inside it
The data is still owned by generated fallback storage.
audiodeckcontrols the UI, but not the data.
Why This Matters
Suppose audiodeck already defines its own property group:
class AudioDeckProps(bpy.types.PropertyGroup):
audio_path: bpy.props.StringProperty(
name="Audio Path",
subtype="FILE_PATH"
)
And suppose it is registered as:
bpy.types.Scene.audiodeck_props = bpy.props.PointerProperty(
type=AudioDeckProps
)
Now we have two places storing the same concept:
context.scene.audiodeck_props.audio_path
context.scene.qa_shared.project__audio_path
Two values. One meaning.
That duplication is unnecessary.
If audiodeck is the host, it should own the data.
The Mechanism: HostAPI
When audio_encode reads or draws a shared value, it does not directly access storage.
Instead, it calls:
host_api.get(...)
host_api.draw(...)
Until now, we were relying on the default fallback host.
Now we will provide our own.
Step 1 – Implement a Minimal HostAPI in audiodeck
Open:
audiodeck/__init__.py
Add the following class:
class AudioDeckHostAPI:
def get(self, context, key, fallback_prop):
if key == "project.audio_path":
return context.scene.audiodeck_props.audio_path
# fallback for unknown keys
return getattr(context.scene.qa_shared, fallback_prop)
def draw(self, layout, context, key, fallback_prop, label=None):
if key == "project.audio_path":
layout.prop(
context.scene.audiodeck_props,
"audio_path",
text=label
)
else:
layout.prop(
context.scene.qa_shared,
fallback_prop,
text=label
)
This class does two things:
- Routes
"project.audio_path"intoaudiodeck_props. - Falls back to generated storage for all other shared keys.
The plugin does not change. Only the host’s routing logic changes.
Step 2 – Inject the HostAPI
Modify the registration of audio_encode inside audiodeck.register():
audio_encode_ops.register(
mode="plugin",
host_api=AudioDeckHostAPI()
)
That is the entire ownership transfer.
What Changed?
Before:
audio_encode
└── qa_shared
After:
audio_encode
└── HostAPI
└── audiodeck_props
Now:
audio_encodereads fromaudiodeckstorage.audio_encodedrawsaudiodeckproperties.- Fallback storage remains available for other shared keys.
What Did NOT Change
audio_encodetool scriptaudio_encodeshared decoratoraudio_encodeoperator logicaudio_encodebuild process
Only audiodeck changed.
The plugin remains generated, reusable, and composable.
What You Have Now
At this point:
- UI ownership belongs to
audiodeck. - Data ownership belongs to
audiodeck. audio_encoderemains independent and reusable.- The relationship is defined entirely through the HostAPI contract.
In the next chapter, we will make this routing scalable — so you do not have to write if key == ... for every shared value.