fix(instrument_drop_win): make performInstrumentDrop all-or-nothing
On chunk-write failure, call TrackFX_Delete(track, fxIndex) to remove the just-added empty FX instance before returning false. Signature verified at reaper_plugin_functions.h:7236. Update the header comment from "leaves at most the added FX" to the new all-or-nothing contract.
This commit is contained in:
@@ -15,6 +15,7 @@
|
|||||||
#define REAPERAPI_MINIMAL
|
#define REAPERAPI_MINIMAL
|
||||||
#define REAPERAPI_WANT_GetThingFromPoint
|
#define REAPERAPI_WANT_GetThingFromPoint
|
||||||
#define REAPERAPI_WANT_TrackFX_AddByName
|
#define REAPERAPI_WANT_TrackFX_AddByName
|
||||||
|
#define REAPERAPI_WANT_TrackFX_Delete
|
||||||
#define REAPERAPI_WANT_TrackFX_SetNamedConfigParm
|
#define REAPERAPI_WANT_TrackFX_SetNamedConfigParm
|
||||||
#define REAPERAPI_WANT_Undo_BeginBlock2
|
#define REAPERAPI_WANT_Undo_BeginBlock2
|
||||||
#define REAPERAPI_WANT_Undo_EndBlock2
|
#define REAPERAPI_WANT_Undo_EndBlock2
|
||||||
@@ -73,6 +74,12 @@ bool performInstrumentDrop(MediaTrack* track, const std::string& chunkBase64) {
|
|||||||
// (instrument_drop::buildInstrumentDropChunk -> sample_map::serializeComponentState),
|
// (instrument_drop::buildInstrumentDropChunk -> sample_map::serializeComponentState),
|
||||||
// so these bytes are exactly what ReaSampler 9000's setState accepts.
|
// so these bytes are exactly what ReaSampler 9000's setState accepts.
|
||||||
ok = TrackFX_SetNamedConfigParm(track, fxIndex, "vst_chunk", chunkBase64.c_str());
|
ok = TrackFX_SetNamedConfigParm(track, fxIndex, "vst_chunk", chunkBase64.c_str());
|
||||||
|
if (!ok) {
|
||||||
|
// All-or-nothing: if the chunk write fails, remove the empty FX instance we just
|
||||||
|
// added so the track is left exactly as it was. TrackFX_Delete signature (verified
|
||||||
|
// in reaper_plugin_functions.h:7236): bool TrackFX_Delete(MediaTrack*, int fx).
|
||||||
|
TrackFX_Delete(track, fxIndex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The undo label reflects the placement-of-the-player framing (not a capture, not an insert).
|
// The undo label reflects the placement-of-the-player framing (not a capture, not an insert).
|
||||||
|
|||||||
@@ -47,10 +47,11 @@ FxDropTarget resolveFxDropTarget(int screenX, int screenY);
|
|||||||
// (the instrument_drop::buildInstrumentDropChunk output) as its component state so it plays
|
// (the instrument_drop::buildInstrumentDropChunk output) as its component state so it plays
|
||||||
// the dragged capture. `chunkBase64` is the base64 vst_chunk. Wraps the add + inject in one
|
// the dragged capture. `chunkBase64` is the base64 vst_chunk. Wraps the add + inject in one
|
||||||
// REAPER undo block (mirrors the bank-verb undo discipline). Returns true on success (the FX
|
// REAPER undo block (mirrors the bank-verb undo discipline). Returns true on success (the FX
|
||||||
// was added and the chunk written), false on any failure (add returned -1, or the chunk write
|
// was added and the chunk written), false on any failure. All-or-nothing: if the chunk write
|
||||||
// was rejected). A false return leaves at most the added FX (no partial-state confusion — the
|
// fails after a successful add, the freshly-added FX instance is removed via TrackFX_Delete
|
||||||
// caller surfaces nothing; a failed add is visible by nothing happening). NEVER inserts a
|
// before returning false, leaving the track exactly as it was (no orphaned empty-state FX).
|
||||||
// timeline item; the ONLY mutations are the FX instance + its state, both undoable.
|
// NEVER inserts a timeline item; the ONLY mutations are the FX instance + its state, both
|
||||||
|
// undoable.
|
||||||
bool performInstrumentDrop(MediaTrack* track, const std::string& chunkBase64);
|
bool performInstrumentDrop(MediaTrack* track, const std::string& chunkBase64);
|
||||||
|
|
||||||
} // namespace reasampler
|
} // namespace reasampler
|
||||||
|
|||||||
Reference in New Issue
Block a user