cwIo.h/cpp : Added optional synchronous callbacks for all sub-systems.
The UI is now automatically cleared in io::stop().
This commit is contained in:
parent
277323d1f8
commit
f0e6a56a60
64
cwIo.cpp
64
cwIo.cpp
@ -167,14 +167,14 @@ namespace cw
|
|||||||
|
|
||||||
|
|
||||||
// All callbacks to the application occur through this function
|
// All callbacks to the application occur through this function
|
||||||
rc_t _ioCallback( io_t* p, bool asyncFl, const msg_t* m )
|
rc_t _ioCallback( io_t* p, bool asyncFl, const msg_t* m, rc_t* app_rc_ref=nullptr )
|
||||||
{
|
{
|
||||||
rc_t rc = kOkRC;
|
rc_t rc = kOkRC;
|
||||||
rc_t rc_app = kOkRC;
|
|
||||||
bool unlockFl = false;
|
bool unlockFl = false;
|
||||||
|
bool isSynchronousFl = !asyncFl;
|
||||||
|
|
||||||
// if this is not an async callback then lock the mutex
|
// if this is a synchronous callback then lock the mutex
|
||||||
if( !asyncFl )
|
if( isSynchronousFl )
|
||||||
{
|
{
|
||||||
switch(rc = mutex::lock(p->cbMutexH,p->cbMutexTimeOutMs))
|
switch(rc = mutex::lock(p->cbMutexH,p->cbMutexTimeOutMs))
|
||||||
{
|
{
|
||||||
@ -194,8 +194,11 @@ namespace cw
|
|||||||
|
|
||||||
// make the callback to the client
|
// make the callback to the client
|
||||||
if( rc == kOkRC )
|
if( rc == kOkRC )
|
||||||
rc_app = p->cbFunc( p->cbArg, m );
|
{
|
||||||
|
rc_t app_rc = p->cbFunc( p->cbArg, m );
|
||||||
|
if( app_rc_ref != nullptr )
|
||||||
|
*app_rc_ref = app_rc;
|
||||||
|
}
|
||||||
|
|
||||||
// if the mutex is locked
|
// if the mutex is locked
|
||||||
if( unlockFl )
|
if( unlockFl )
|
||||||
@ -205,8 +208,8 @@ namespace cw
|
|||||||
rc = cwLogError(rc,"io mutex callback mutex unlock failed.");
|
rc = cwLogError(rc,"io mutex callback mutex unlock failed.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc_app;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc_t _ioParse( io_t* p, const object_t* cfg )
|
rc_t _ioParse( io_t* p, const object_t* cfg )
|
||||||
@ -235,6 +238,7 @@ namespace cw
|
|||||||
//
|
//
|
||||||
bool _threadFunc( void* arg )
|
bool _threadFunc( void* arg )
|
||||||
{
|
{
|
||||||
|
rc_t rc = kOkRC;
|
||||||
thread_t* t = (thread_t*)arg;
|
thread_t* t = (thread_t*)arg;
|
||||||
thread_msg_t tm = { .id=t->id, .arg=t->arg };
|
thread_msg_t tm = { .id=t->id, .arg=t->arg };
|
||||||
msg_t m;
|
msg_t m;
|
||||||
@ -242,7 +246,8 @@ namespace cw
|
|||||||
m.tid = kThreadTId;
|
m.tid = kThreadTId;
|
||||||
m.u.thread = &tm;
|
m.u.thread = &tm;
|
||||||
|
|
||||||
_ioCallback( t->p, t->asyncFl, &m );
|
if((rc = _ioCallback( t->p, t->asyncFl, &m )) != kOkRC )
|
||||||
|
cwLogError(rc,"Thread app callback failed.");
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -270,13 +275,16 @@ namespace cw
|
|||||||
|
|
||||||
if( t->startedFl && !t->deletedFl )
|
if( t->startedFl && !t->deletedFl )
|
||||||
{
|
{
|
||||||
|
rc_t rc = kOkRC;
|
||||||
msg_t m;
|
msg_t m;
|
||||||
timer_msg_t tm;
|
timer_msg_t tm;
|
||||||
|
|
||||||
tm.id = t->id;
|
tm.id = t->id;
|
||||||
m.tid = kTimerTId;
|
m.tid = kTimerTId;
|
||||||
m.u.timer = &tm;
|
m.u.timer = &tm;
|
||||||
_ioCallback( t->io, t->asyncFl, &m );
|
|
||||||
|
if((rc = _ioCallback( t->io, t->asyncFl, &m )) != kOkRC )
|
||||||
|
cwLogError(rc,"Timer app callback failed.");
|
||||||
}
|
}
|
||||||
|
|
||||||
return !t->deletedFl;
|
return !t->deletedFl;
|
||||||
@ -365,7 +373,8 @@ namespace cw
|
|||||||
if( serialCfgIdx > p->serialN )
|
if( serialCfgIdx > p->serialN )
|
||||||
cwLogError(kAssertFailRC,"The serial cfg index %i is out of range %i in serial port callback.", serialCfgIdx, p->serialN );
|
cwLogError(kAssertFailRC,"The serial cfg index %i is out of range %i in serial port callback.", serialCfgIdx, p->serialN );
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
rc_t rc = kOkRC;
|
||||||
const serialPort_t* sp = p->serialA + serialCfgIdx;
|
const serialPort_t* sp = p->serialA + serialCfgIdx;
|
||||||
msg_t m;
|
msg_t m;
|
||||||
serial_msg_t sm;
|
serial_msg_t sm;
|
||||||
@ -377,7 +386,8 @@ namespace cw
|
|||||||
m.tid = kSerialTId;
|
m.tid = kSerialTId;
|
||||||
m.u.serial = &sm;
|
m.u.serial = &sm;
|
||||||
|
|
||||||
_ioCallback( p, sp->asyncFl, &m );
|
if((rc = _ioCallback( p, sp->asyncFl, &m )) != kOkRC )
|
||||||
|
cwLogError(rc,"Serial port app callback failed.");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -558,13 +568,15 @@ namespace cw
|
|||||||
midi_msg_t mm;
|
midi_msg_t mm;
|
||||||
const midi::packet_t* pkt = pktArray + i;
|
const midi::packet_t* pkt = pktArray + i;
|
||||||
io_t* p = reinterpret_cast<io_t*>(pkt->cbDataPtr);
|
io_t* p = reinterpret_cast<io_t*>(pkt->cbDataPtr);
|
||||||
|
rc_t rc = kOkRC;
|
||||||
|
|
||||||
|
|
||||||
mm.pkt = pkt;
|
mm.pkt = pkt;
|
||||||
m.tid = kMidiTId;
|
m.tid = kMidiTId;
|
||||||
m.u.midi = &mm;
|
m.u.midi = &mm;
|
||||||
|
|
||||||
_ioCallback( p, p->midiAsyncFl, &m );
|
if((rc = _ioCallback( p, p->midiAsyncFl, &m )) !=kOkRC )
|
||||||
|
cwLogError(rc,"MIDI app callback failed.");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
for(unsigned j=0; j<pkt->msgCnt; ++j)
|
for(unsigned j=0; j<pkt->msgCnt; ++j)
|
||||||
@ -652,7 +664,10 @@ namespace cw
|
|||||||
m.tid = kSockTId;
|
m.tid = kSockTId;
|
||||||
m.u.sock = &sm;
|
m.u.sock = &sm;
|
||||||
|
|
||||||
_ioCallback( p, p->sockA[ sockArray_index ].asyncFl, &m );
|
rc_t rc;
|
||||||
|
|
||||||
|
if((rc = _ioCallback( p, p->sockA[ sockArray_index ].asyncFl, &m )) != kOkRC )
|
||||||
|
cwLogError(rc,"Socket app callback failed.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -937,6 +952,7 @@ namespace cw
|
|||||||
rc_t rc = kOkRC;
|
rc_t rc = kOkRC;
|
||||||
if( agd != nullptr && ag != nullptr && cwIsFlag(agd->flags,kMeterFl))
|
if( agd != nullptr && ag != nullptr && cwIsFlag(agd->flags,kMeterFl))
|
||||||
{
|
{
|
||||||
|
rc_t app_rc = kOkRC;
|
||||||
msg_t m;
|
msg_t m;
|
||||||
m.tid = kAudioMeterTId;
|
m.tid = kAudioMeterTId;
|
||||||
m.u.audioGroupDev = agd;
|
m.u.audioGroupDev = agd;
|
||||||
@ -945,8 +961,10 @@ namespace cw
|
|||||||
audio::buf::meter(p->audioBufH, agd->devIdx, audioBufFlags, agd->meterA, agd->chCnt );
|
audio::buf::meter(p->audioBufH, agd->devIdx, audioBufFlags, agd->meterA, agd->chCnt );
|
||||||
|
|
||||||
// callback the application with the current meter values
|
// callback the application with the current meter values
|
||||||
rc = _ioCallback( p, ag->asyncFl, &m);
|
if((rc = _ioCallback( p, ag->asyncFl, &m, &app_rc )) != kOkRC )
|
||||||
|
cwLogError(rc,"Audio meter app callback failed.");
|
||||||
|
|
||||||
|
rc = app_rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
@ -1055,7 +1073,8 @@ namespace cw
|
|||||||
_audioGroupProcSampleBufs( ag->p, ag, kAudioGroupGetBuf, true );
|
_audioGroupProcSampleBufs( ag->p, ag, kAudioGroupGetBuf, true );
|
||||||
_audioGroupProcSampleBufs( ag->p, ag, kAudioGroupGetBuf, false );
|
_audioGroupProcSampleBufs( ag->p, ag, kAudioGroupGetBuf, false );
|
||||||
|
|
||||||
_ioCallback( ag->p, ag->asyncFl, &msg);
|
if((rc = _ioCallback( ag->p, ag->asyncFl, &msg)) != kOkRC )
|
||||||
|
cwLogError(rc,"Audio app callback failed %i.",ag->asyncFl);
|
||||||
|
|
||||||
_audioGroupProcSampleBufs( ag->p, ag, kAudioGroupAdvBuf, true );
|
_audioGroupProcSampleBufs( ag->p, ag, kAudioGroupAdvBuf, true );
|
||||||
_audioGroupProcSampleBufs( ag->p, ag, kAudioGroupAdvBuf, false );
|
_audioGroupProcSampleBufs( ag->p, ag, kAudioGroupAdvBuf, false );
|
||||||
@ -1344,6 +1363,7 @@ namespace cw
|
|||||||
{
|
{
|
||||||
if(( rc = node->getv(
|
if(( rc = node->getv(
|
||||||
"enableFl", p->audioGroupA[i].enableFl,
|
"enableFl", p->audioGroupA[i].enableFl,
|
||||||
|
"asyncFl", p->audioGroupA[i].asyncFl,
|
||||||
"label", p->audioGroupA[i].msg.label,
|
"label", p->audioGroupA[i].msg.label,
|
||||||
"id", p->audioGroupA[i].msg.userId,
|
"id", p->audioGroupA[i].msg.userId,
|
||||||
"srate", p->audioGroupA[i].msg.srate,
|
"srate", p->audioGroupA[i].msg.srate,
|
||||||
@ -1687,11 +1707,16 @@ namespace cw
|
|||||||
{
|
{
|
||||||
io_t* p = (io_t*)cbArg;
|
io_t* p = (io_t*)cbArg;
|
||||||
msg_t r;
|
msg_t r;
|
||||||
|
rc_t rc = kOkRC;
|
||||||
|
rc_t app_rc = kOkRC;
|
||||||
|
|
||||||
r.tid = kUiTId;
|
r.tid = kUiTId;
|
||||||
r.u.ui = { .opId=opId, .wsSessId=wsSessId, .parentAppId=parentAppId, .uuId=uuId, .appId=appId, .chanId=chanId, .value=v };
|
r.u.ui = { .opId=opId, .wsSessId=wsSessId, .parentAppId=parentAppId, .uuId=uuId, .appId=appId, .chanId=chanId, .value=v };
|
||||||
|
|
||||||
return _ioCallback( p, p->uiAsyncFl, &r );
|
if((rc = _ioCallback( p, p->uiAsyncFl, &r, &app_rc )) != kOkRC )
|
||||||
|
cwLogError(rc,"UI app callback failed.");
|
||||||
|
|
||||||
|
return app_rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc_t _uiConfig( io_t* p, const object_t* c, const ui::appIdMap_t* mapA, unsigned mapN )
|
rc_t _uiConfig( io_t* p, const object_t* c, const ui::appIdMap_t* mapA, unsigned mapN )
|
||||||
@ -1957,7 +1982,12 @@ cw::rc_t cw::io::stop( handle_t h )
|
|||||||
io_t* p = _handleToPtr(h);
|
io_t* p = _handleToPtr(h);
|
||||||
p->quitFl.store(true);
|
p->quitFl.store(true);
|
||||||
|
|
||||||
|
// stop the audio devices
|
||||||
_audioDeviceStartStop(p,false);
|
_audioDeviceStartStop(p,false);
|
||||||
|
|
||||||
|
// clear the UI
|
||||||
|
if( p->wsUiH.isValid() )
|
||||||
|
uiDestroyElement(h,ui::kRootUuId);
|
||||||
|
|
||||||
return kOkRC;
|
return kOkRC;
|
||||||
}
|
}
|
||||||
|
4
cwIo.h
4
cwIo.h
@ -27,7 +27,7 @@ namespace cw
|
|||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
kThreadTId,
|
kThreadTId,
|
||||||
kTimerTId,
|
kTimerTId,
|
||||||
kSerialTId,
|
kSerialTId,
|
||||||
kMidiTId,
|
kMidiTId,
|
||||||
@ -36,7 +36,7 @@ namespace cw
|
|||||||
kSockTId,
|
kSockTId,
|
||||||
kWebSockTId,
|
kWebSockTId,
|
||||||
kUiTId,
|
kUiTId,
|
||||||
kExecTId
|
kExecTId // callback from io::exec() which is inside the application main loop thread
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct thread_msg_str
|
typedef struct thread_msg_str
|
||||||
|
Loading…
Reference in New Issue
Block a user