// bank_sync.cpp — see bank_sync.h. Pure; standard library only. #include "core/instrument/map/bank_sync.h" #include #include #include "core/wire/wire.h" namespace reasampler::instrument::map { std::int64_t parseBankGeneration(const std::string& raw) { // Whole-string, non-negative decimal parse, no exceptions/locale surprises (core/wire's // guarded accumulate). Leading sign, non-digit, empty, or int64 overflow -> absent (0). std::int64_t value = 0; if (!wire::parseUnsignedDecimal(raw, value)) return kBankGenerationAbsent; return value; } std::string formatBankGeneration(std::int64_t generation) { return std::to_string(generation); } bool bankGenerationChanged(std::int64_t seen, std::int64_t current) { return current != seen; } AssignConsumeDecision consumeDecision(const std::optional& request, std::int64_t lastConsumed, bool resolves, bool isFocusedTarget) { AssignConsumeDecision d; d.consumedGeneration = lastConsumed; // default: nothing changes // Rule 1: no request, or not newer than what we already consumed. if (!request) return d; if (request->generation <= lastConsumed) return d; // Rule 2: new but not our target -> don't advance the marker, stay eligible. if (!isFocusedTarget) return d; // New and our target: consumed-as-seen either way. d.consumedGeneration = request->generation; // Rule 3: unresolvable -> drop silently, marker already advanced above. if (!resolves) return d; // Rule 4: new, target, resolvable -> apply. d.apply = true; d.bankId = request->bankId; d.sampleId = request->sampleId; return d; } } // namespace reasampler::instrument::map