StimBuff: Make virtual so we can dynamic_cast in getOrCreateStimBuff

This commit is contained in:
2025-11-16 02:23:53 -04:00
parent addd2e275d
commit c5ed453bb4
6 changed files with 162 additions and 12 deletions
+61 -2
View File
@@ -30,6 +30,8 @@ static SmoThreadingModelDesc smoThreadingModelDesc;
// Local collection of stimulus producers
static std::vector<std::shared_ptr<StimulusProducer>> attachedStimulusProducers;
static bool isSupportedQualeIfaceApi(const std::string& qualeIfaceApi);
// Check if a StimulusProducer matches the requested stim feature
static bool isProducerForStimFeature(
const std::shared_ptr<StimulusProducer>& stimProducer,
@@ -192,6 +194,17 @@ private:
return false;
}
// Check for duplicate qualeIfaceApi
const std::string& qualeIfaceApi = context->spec->qualeIfaceApi;
if (context->stimProducer->hasBufferWithQualeIfaceApi(qualeIfaceApi))
{
std::cerr << __func__ << ": Buffer with qualeIfaceApi '"
<< qualeIfaceApi << "' already exists for this producer. "
"Each producer can only have one buffer per qualeIfaceApi."
<< std::endl;
return false;
}
// Parse histbuffMs
int histbuffMs = parseHistbuffMs(context->spec);
@@ -203,7 +216,7 @@ private:
std::cerr << __func__ << ": Failed to create StimBuffer: "
<< e.what() << ". Producer is committed, DeviceReattacher will retry."
<< std::endl;
// Return false so DeviceReattacher can retry later
// Return false so caller can handle error callback
return false;
}
@@ -604,6 +617,13 @@ static const StimBuffApiDesc livoxGen1ApiDesc = {
}
};
static bool isSupportedQualeIfaceApi(const std::string& qualeIfaceApi)
{
// Check if this is a supported (implemented) qualeIfaceApi
return qualeIfaceApi == "mesh" || qualeIfaceApi == "pcloudIntensity" ||
qualeIfaceApi == "pcloudAmbience";
}
// Callback function implementations
extern "C" int livoxGen1_initializeInd(void)
{
@@ -713,6 +733,29 @@ extern "C" void livoxGen1_attachDeviceReq(
"not available");
}
// Validate qualeIfaceApi
const std::string& qualeIfaceApi = desc->qualeIfaceApi;
if (qualeIfaceApi == "gyro" || qualeIfaceApi == "accel")
{
// These are for ImuStimulusProducer (not yet implemented)
std::cerr << __func__ << ": qualeIfaceApi '" << qualeIfaceApi
<< "' requires ImuStimulusProducer which is not yet implemented"
<< std::endl;
cb.callbackFn(false, desc);
return;
}
if (!isSupportedQualeIfaceApi(qualeIfaceApi))
{
// Unknown qualeIfaceApi
std::cerr << __func__ << ": Unsupported qualeIfaceApi '"
<< qualeIfaceApi << "' for LivoxGen1. "
"Supported values: mesh, pcloudIntensity, pcloudAmbience"
<< std::endl;
cb.callbackFn(false, desc);
return;
}
auto request = std::make_shared<AttachDeviceReq>(desc, cb);
// Case 1: Check if StimBuffer already exists
@@ -740,7 +783,23 @@ extern "C" void livoxGen1_attachDeviceReq(
}
else
{
// StimProducer exists, StimBuffer doesn't
/** EXPLANATION:
* StimProducer exists, StimBuffer doesn't (DASpec doesn't match)
* Check if producer already has a buffer with the requested
* qualeIfaceApi but different DASpec - this is not allowed.
*/
if (stimProducer->hasBufferWithQualeIfaceApi(desc->qualeIfaceApi))
{
std::cerr << __func__ << ": Producer already has a buffer with "
"qualeIfaceApi '" << desc->qualeIfaceApi
<< "' but with a different DeviceAttachmentSpec. "
"A single LivoxGen1 device cannot support multiple DASpecs "
"with the same qualeIfaceApi." << std::endl;
cb.callbackFn(false, desc);
return;
}
request->stimProducer = stimProducer;
// Ensure StimBuffer is attached and enable pcloud data if needed
request->attachDeviceReq4_doCreateStimBuff_maybeDirectlyCalled(
@@ -106,6 +106,40 @@ void produceStimFrameAck(void)
{
}
std::shared_ptr<StimulusBuffer>
PcloudStimulusProducer::getAttachedStimulusBuffer(
const std::shared_ptr<device::DeviceAttachmentSpec>& spec) const
{
// Call base class implementation
auto buffer = StimulusProducer::getAttachedStimulusBuffer(spec);
if (!buffer)
{
return nullptr;
}
// Optionally validate/upcast the buffer type matches expected type
// based on qualeIfaceApi (for type safety)
const std::string& qualeIfaceApi = spec->qualeIfaceApi;
if (qualeIfaceApi == "mesh")
{
if (std::dynamic_pointer_cast<MeshStimulusBuffer>(buffer))
{ return buffer; }
}
else if (qualeIfaceApi == "pcloudIntensity")
{
if (std::dynamic_pointer_cast<PcloudIntensityStimulusBuffer>(buffer))
{ return buffer; }
}
else if (qualeIfaceApi == "pcloudAmbience")
{
if (std::dynamic_pointer_cast<PcloudAmbienceStimulusBuffer>(buffer))
{ return buffer; }
}
// Type mismatch - return nullptr
return nullptr;
}
std::shared_ptr<StimulusBuffer>
PcloudStimulusProducer::getOrCreateAttachedStimulusBuffer(
const std::shared_ptr<device::DeviceAttachmentSpec>& deviceAttachmentSpec,
@@ -117,15 +151,43 @@ PcloudStimulusProducer::getOrCreateAttachedStimulusBuffer(
if (existingBuffer)
{ return existingBuffer; }
// Create new MeshStimulusBuffer (for now, always use XYZ type)
auto buffer = std::make_shared<MeshStimulusBuffer>(
*this, deviceAttachmentSpec, histbuffMs, openClInputConstraints);
// Parse qualeIfaceApi to determine buffer type
const std::string& qualeIfaceApi = deviceAttachmentSpec->qualeIfaceApi;
// Add to collection
attachedStimulusBuffers.push_back(buffer);
// Update specialized member
meshStimulusBuffer = buffer;
return buffer;
if (qualeIfaceApi == "mesh")
{
auto meshBuffer = std::make_shared<MeshStimulusBuffer>(
*this, deviceAttachmentSpec, histbuffMs, openClInputConstraints);
meshStimulusBuffer = meshBuffer;
attachedStimulusBuffers.push_back(meshBuffer);
return meshBuffer;
}
else if (qualeIfaceApi == "pcloudIntensity")
{
auto intensityBuffer = std::make_shared<PcloudIntensityStimulusBuffer>(
*this, deviceAttachmentSpec, histbuffMs, openClInputConstraints);
intensityStimulusBuffer = intensityBuffer;
attachedStimulusBuffers.push_back(intensityBuffer);
return intensityBuffer;
}
else if (qualeIfaceApi == "pcloudAmbience")
{
auto ambienceBuffer = std::make_shared<PcloudAmbienceStimulusBuffer>(
*this, deviceAttachmentSpec, histbuffMs, openClInputConstraints);
ambienceStimulusBuffer = ambienceBuffer;
attachedStimulusBuffers.push_back(ambienceBuffer);
return ambienceBuffer;
}
else
{
throw std::runtime_error(
"Unsupported qualeIfaceApi: '" + qualeIfaceApi + "' for "
"PcloudStimulusProducer. "
"Supported values: mesh, pcloudIntensity, pcloudAmbience");
}
}
void PcloudStimulusProducer::stimFrameProductionTimesliceInd()
@@ -67,6 +67,10 @@ public:
&deviceAttachmentSpec,
int histbuffMs) override;
std::shared_ptr<StimulusBuffer> getAttachedStimulusBuffer(
const std::shared_ptr<device::DeviceAttachmentSpec>& spec)
const override;
protected:
void stimFrameProductionTimesliceInd() override;