Allow callers of LiStartConnection() to omit passing callbacks they don't need

This commit is contained in:
Cameron Gutman 2015-05-13 21:51:33 -05:00
parent b74b54be53
commit 6b0f1aecc5
5 changed files with 156 additions and 40 deletions

View File

@ -3,7 +3,7 @@
static int stage = STAGE_NONE;
static CONNECTION_LISTENER_CALLBACKS listenerCallbacks;
static CONNECTION_LISTENER_CALLBACKS originalCallbacks;
static ConnListenerConnectionTerminated originalTerminationCallback;
// This is used for debug prints so it's not declared static
PLATFORM_CALLBACKS platformCallbacks;
@ -101,26 +101,6 @@ void LiStopConnection(void) {
LC_ASSERT(stage == STAGE_NONE);
}
static void ClInternalStageStarting(int stage)
{
originalCallbacks.stageStarting(stage);
}
static void ClInternalStageComplete(int stage)
{
originalCallbacks.stageComplete(stage);
}
static void ClInternalStageFailed(int stage, long errorCode)
{
originalCallbacks.stageFailed(stage, errorCode);
}
static void ClInternalConnectionStarted(void)
{
originalCallbacks.connectionStarted();
}
static void ClInternalConnectionTerminated(long errorCode)
{
// Avoid recursion and issuing multiple callbacks
@ -129,17 +109,7 @@ static void ClInternalConnectionTerminated(long errorCode)
}
alreadyTerminated = 1;
originalCallbacks.connectionTerminated(errorCode);
}
void ClInternalDisplayMessage(char* message)
{
originalCallbacks.displayMessage(message);
}
void ClInternalDisplayTransientMessage(char* message)
{
originalCallbacks.displayTransientMessage(message);
originalTerminationCallback(errorCode);
}
void LiCompleteThreadStart(void)
@ -155,16 +125,15 @@ int LiStartConnection(IP_ADDRESS host, PSTREAM_CONFIGURATION streamConfig, PCONN
serverMajorVersion = _serverMajorVersion;
memcpy(&originalCallbacks, clCallbacks, sizeof(originalCallbacks));
// Replace missing callbacks with placeholders
fixupMissingCallbacks(&drCallbacks, &arCallbacks, &clCallbacks, &plCallbacks);
memcpy(&platformCallbacks, plCallbacks, sizeof(platformCallbacks));
listenerCallbacks.stageStarting = ClInternalStageStarting;
listenerCallbacks.stageComplete = ClInternalStageComplete;
listenerCallbacks.stageFailed = ClInternalStageFailed;
listenerCallbacks.connectionStarted = ClInternalConnectionStarted;
// Hook the termination callback so we can avoid issuing a termination callback
// after LiStopConnection() is called
originalTerminationCallback = clCallbacks->connectionTerminated;
memcpy(&listenerCallbacks, clCallbacks, sizeof(listenerCallbacks));
listenerCallbacks.connectionTerminated = ClInternalConnectionTerminated;
listenerCallbacks.displayMessage = ClInternalDisplayMessage;
listenerCallbacks.displayTransientMessage = ClInternalDisplayTransientMessage;
alreadyTerminated = 0;

View File

@ -0,0 +1,140 @@
#include "Limelight-internal.h"
static void fakeDrSetup(int width, int height, int redrawRate, void* context, int drFlags) {}
static void fakeDrStart(void) {}
static void fakeDrStop(void) {}
static void fakeDrRelease(void) {}
static int fakeDrSubmitDecodeUnit(PDECODE_UNIT decodeUnit) { return DR_OK; }
static DECODER_RENDERER_CALLBACKS fakeDrCallbacks = {
.setup = fakeDrSetup,
.start = fakeDrStart,
.stop = fakeDrStop,
.release = fakeDrRelease,
.submitDecodeUnit = fakeDrSubmitDecodeUnit,
};
static void fakeArInit(void) {}
static void fakeArStart(void) {}
static void fakeArStop(void) {}
static void fakeArRelease(void) {}
static void fakeArDecodeAndPlaySample(char* sampleData, int sampleLength) {}
AUDIO_RENDERER_CALLBACKS fakeArCallbacks = {
.init = fakeArInit,
.start = fakeArStart,
.stop = fakeArStop,
.release = fakeArRelease,
.decodeAndPlaySample = fakeArDecodeAndPlaySample,
};
static void fakeClStageStarting(int stage) {}
static void fakeClStageComplete(int stage) {}
static void fakeClStageFailed(int stage, long errorCode) {}
static void fakeClConnectionStarted(void) {}
static void fakeClConnectionTerminated(long errorCode) {}
static void fakeClDisplayMessage(char* message) {}
static void fakeClDisplayTransientMessage(char* message) {}
static CONNECTION_LISTENER_CALLBACKS fakeClCallbacks = {
.stageStarting = fakeClStageStarting,
.stageComplete = fakeClStageComplete,
.stageFailed = fakeClStageFailed,
.connectionStarted = fakeClConnectionStarted,
.connectionTerminated = fakeClConnectionTerminated,
.displayMessage = fakeClDisplayMessage,
.displayTransientMessage = fakeClDisplayTransientMessage,
};
static void fakePlThreadStart(void) {}
static void fakePlDebugPrint(char* string) {}
static PLATFORM_CALLBACKS fakePlCallbacks = {
.threadStart = fakePlThreadStart,
.debugPrint = fakePlDebugPrint,
};
void fixupMissingCallbacks(PDECODER_RENDERER_CALLBACKS *drCallbacks, PAUDIO_RENDERER_CALLBACKS *arCallbacks,
PCONNECTION_LISTENER_CALLBACKS *clCallbacks, PPLATFORM_CALLBACKS *plCallbacks)
{
if (*drCallbacks == NULL) {
*drCallbacks = &fakeDrCallbacks;
}
else {
if ((*drCallbacks)->setup == NULL) {
(*drCallbacks)->setup = fakeDrSetup;
}
if ((*drCallbacks)->start == NULL) {
(*drCallbacks)->start = fakeDrStart;
}
if ((*drCallbacks)->stop == NULL) {
(*drCallbacks)->stop = fakeDrStop;
}
if ((*drCallbacks)->release == NULL) {
(*drCallbacks)->release = fakeDrRelease;
}
if ((*drCallbacks)->submitDecodeUnit == NULL) {
(*drCallbacks)->submitDecodeUnit = fakeDrSubmitDecodeUnit;
}
}
if (*arCallbacks == NULL) {
*arCallbacks = &fakeArCallbacks;
}
else {
if ((*arCallbacks)->init == NULL) {
(*arCallbacks)->init = fakeArInit;
}
if ((*arCallbacks)->start == NULL) {
(*arCallbacks)->start = fakeArStart;
}
if ((*arCallbacks)->stop == NULL) {
(*arCallbacks)->stop = fakeArStop;
}
if ((*arCallbacks)->release == NULL) {
(*arCallbacks)->release = fakeArRelease;
}
if ((*arCallbacks)->decodeAndPlaySample == NULL) {
(*arCallbacks)->decodeAndPlaySample = fakeArDecodeAndPlaySample;
}
}
if (*clCallbacks == NULL) {
*clCallbacks = &fakeClCallbacks;
}
else {
if ((*clCallbacks)->stageStarting == NULL) {
(*clCallbacks)->stageStarting = fakeClStageStarting;
}
if ((*clCallbacks)->stageComplete == NULL) {
(*clCallbacks)->stageComplete = fakeClStageComplete;
}
if ((*clCallbacks)->stageFailed == NULL) {
(*clCallbacks)->stageFailed = fakeClStageFailed;
}
if ((*clCallbacks)->connectionStarted == NULL) {
(*clCallbacks)->connectionStarted = fakeClConnectionStarted;
}
if ((*clCallbacks)->connectionTerminated == NULL) {
(*clCallbacks)->connectionTerminated = fakeClConnectionTerminated;
}
if ((*clCallbacks)->displayMessage == NULL) {
(*clCallbacks)->displayMessage = fakeClDisplayMessage;
}
if ((*clCallbacks)->displayTransientMessage == NULL) {
(*clCallbacks)->displayTransientMessage = fakeClDisplayTransientMessage;
}
}
if (*plCallbacks == NULL) {
*plCallbacks = &fakePlCallbacks;
}
else {
if ((*plCallbacks)->threadStart == NULL) {
(*plCallbacks)->threadStart = fakePlThreadStart;
}
if ((*plCallbacks)->debugPrint == NULL) {
(*plCallbacks)->debugPrint = fakePlDebugPrint;
}
}
}

View File

@ -8,6 +8,9 @@
extern int serverMajorVersion;
void fixupMissingCallbacks(PDECODER_RENDERER_CALLBACKS *drCallbacks, PAUDIO_RENDERER_CALLBACKS *arCallbacks,
PCONNECTION_LISTENER_CALLBACKS *clCallbacks, PPLATFORM_CALLBACKS *plCallbacks);
char* getSdpPayloadForStreamConfig(PSTREAM_CONFIGURATION streamConfig, struct in_addr targetAddress,
int rtspClientVersion, int *length);

View File

@ -135,6 +135,7 @@
<ClCompile Include="ByteBuffer.c" />
<ClCompile Include="Connection.c" />
<ClCompile Include="ControlStream.c" />
<ClCompile Include="FakeCallbacks.c" />
<ClCompile Include="InputStream.c" />
<ClCompile Include="LinkedBlockingQueue.c" />
<ClCompile Include="OpenAES\oaes_base64.c" />

View File

@ -63,6 +63,9 @@
<ClCompile Include="OpenAES\oaes_lib.c">
<Filter>Source Files\OpenAES</Filter>
</ClCompile>
<ClCompile Include="FakeCallbacks.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="ByteBuffer.h">