SDK 1.0.0-pre.2 migration
Use EpicTuner 0.8.3 or later. This is a source-helper and host-diagnostics update; C ABI 1.1, service table layouts and existing numeric constants are unchanged.
Dropdown selection: properties and events are different domains
ET_UI_SELECTED was always an event type, not a property. It has the same
numeric value as the unrelated ET_UI_UNITS property. Renumbering it would break
existing event handlers. Prefer the explicit names added in this SDK:
- Set a dropdown's index with
ET_UI_SELECTED_INDEX(alias ofET_UI_VALUE). - Receive selection events as
ET_UI_EVENT_SELECTED(legacyET_UI_SELECTED). - Both the selected property and event value use
ET_VALUE_F64: a zero-based index, not the option text.-1is the no-selection property value.
panel.add(ET_UI_SELECT, "model").text(ET_UI_OPTIONS, "").selectedIndex(-1);
// After a Make selection, update options and index together in one atomic patch:
ui.patch(e.panel, {Ui::text("model", ET_UI_OPTIONS, "Model A\nModel B"),
Ui::selectedIndex("model", 0)}, e.revision, e.origin, &completion);
Do not place ET_UI_SELECTED in a property array or a patch. The host now reports
the node, offending property and correction instead of a generic type error.
Empty options render an empty, disabled control. Populate options and choose an
index in the same patch. When replacing a short list, reset its old index too.
For a single option, set index 0 to autoselect it. Programmatic selection does
not generate a user selection event: update dependent controls and the preview
in the same plugin logic instead of waiting for a callback.
Several patches from one event
Before host 0.8.3, the first successful patch advanced the panel revision and
subsequent calls using that event's revision failed with ET_ERROR_CONFLICT.
This affected every property, including a status update followed by options.
Host 0.8.3 queues synchronous patch calls made inside the same UI event callback,
for the event's panel, revision and origin. It applies them in call order, using
each successful completion's revision for the next call. A failed call cancels
its remaining dependent calls. Intervening user edits still cause a conflict;
they are never silently overwritten. Every call keeps its own completion.
Host 0.8.4 extends this to calls using the SDK's default origin 0, including
a status/render call before the options call. Use 0.8.4 or later for that pattern.
Prefer one atomic patch for mutually dependent options, indexes and previews.
Separate status/render patches may precede it. Calls made later from timers or
completion callbacks must use a fresh revision (the successful patch completion
returns it as ET_VALUE_U64). Do not reuse a saved event revision indefinitely.
Patch errors and startup failures
Patches remain atomic: partial application would leave dependent controls
inconsistent. ET_OK means queued. A completion supplies the actual result and
detail; copy or log that borrowed string inside the callback. Rejections are
also visible in Tools > Plugins diagnostics without a completion callback.
The host reports named service failures and immediate UI validation failures when
startup fails. For plugin-specific operations, use
return context.check(result, "Load base tune database") to attach the step name.
An asynchronous definition failure must be handled in its completion; returning
from start() cannot synchronously report a later host reply. Keep the callback
owner alive and return ET_OK when the definition has been queued successfully.
Empty table previews
Plugin-owned calibration tables use tab-separated cells and newline-separated
rows, with ET_UI_COLUMNS matching the row width (12 for a 2-row, 12-column table).
Set a range covering every finite value. ET_UI_VALUE contains the edited/current
dataset and takes precedence over initial ET_UI_DATA. For refreshed previews,
patch ET_UI_VALUE; otherwise a previous edited value can hide new initial data.
Keep ET_UI_TARGET empty for plugin-owned data. A rejected atomic patch changes
neither the dropdowns nor the preview. Inspect the completion before assuming the
renderer failed. The client now displays an explicit message for empty previews.
See the control/event tables, the first-plugin tutorial, and the cascading-select example for a complete Make → Model → Tune flow.