Important Update:
- FunctionCore
- So not set Function JSON "config" param to empty object by default
- Change TChannelLink to reference Channel direct
- Add Input/Output to TChannelLink
- Replace LinkChannel() Bidirectional param with Input/Output param
- Update JSON config as well
- Implement Channel "Ready" state and events
- Remove Input/OutputEnabled parameters and related methods
- Remove from JSON config as well
- Update AddChannel() method accordingly
- Add Ref param to struct TChannel
- SelectableCore:
- Convert inline ChangeState() to non-inline method
- Move ChangeState() to last step in open/close methods
- Add Channels in Not Ready state
- Change Channel state when Handle state changed
- DeviceCore:
- Add Channels in Ready state
- FileCore:
- Add Channel in Not Ready state
This commit is contained in:
162
FunctionCore.cpp
162
FunctionCore.cpp
@@ -54,12 +54,8 @@ CFunctionCore::~CFunctionCore()
|
||||
free( FirstChannel->Ref );
|
||||
}
|
||||
|
||||
// Destroy Linked Outputs
|
||||
// Destroy Linked Channels
|
||||
while (FirstChannel->FirstLink) {
|
||||
if (FirstChannel->FirstLink->Name) {
|
||||
free( FirstChannel->FirstLink->Name );
|
||||
free( FirstChannel->FirstLink->Ref );
|
||||
}
|
||||
NextLinkedChannel = FirstChannel->FirstLink->Next;
|
||||
delete FirstChannel->FirstLink;
|
||||
FirstChannel->FirstLink = NextLinkedChannel;
|
||||
@@ -103,13 +99,8 @@ bool CFunctionCore::Init( CDataMember * FunctionConfig )
|
||||
|
||||
// Load Channels
|
||||
ChannelConfig = FunctionConfig->GetChFirstChild( "Channels", true );
|
||||
while (ChannelConfig)
|
||||
{
|
||||
if (ChannelConfig->GetName()) {
|
||||
AddChannel( ChannelConfig->GetName(),
|
||||
ChannelConfig->GetChBool( "InputEnabled", true, true ),
|
||||
ChannelConfig->GetChBool( "OutputEnabled", false, true ));
|
||||
}
|
||||
while (ChannelConfig) {
|
||||
AddChannel( ChannelConfig->GetName(), false );
|
||||
ChannelConfig = ChannelConfig->GetNextPeer();
|
||||
}
|
||||
|
||||
@@ -118,7 +109,6 @@ bool CFunctionCore::Init( CDataMember * FunctionConfig )
|
||||
ConfigName = (char*)FunctionConfig->GetChStr( "Config" );
|
||||
Config = Application->Config->GetChild( ConfigName, true );
|
||||
}
|
||||
if (Config->isNull()) Config->SetObject();
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -145,9 +135,10 @@ bool CFunctionCore::InitChannelLinks( CDataMember * LinkConfig )
|
||||
{
|
||||
// Get Parameters
|
||||
LinkChannel( Channel->Name,
|
||||
FunctionMember->GetChStr( "Function" ),
|
||||
FunctionMember->GetChStr( "Channel" ),
|
||||
FunctionMember->GetChBool( "Bidirectional" ) );
|
||||
FunctionMember->GetChStr( "Function", NULL, true ),
|
||||
FunctionMember->GetChStr( "Channel", NULL, true ),
|
||||
FunctionMember->GetChBool( "Input", false, true ),
|
||||
FunctionMember->GetChBool( "Output", false, true ) );
|
||||
FunctionMember = FunctionMember->GetNextPeer();
|
||||
}
|
||||
}
|
||||
@@ -175,7 +166,7 @@ bool CFunctionCore::SetLogLevel( EDebugLevel pDebugLevel )
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
TChannel * CFunctionCore::AddChannel( const char * ChannelName, const bool pInputEnable, const bool pOutputEnable )
|
||||
TChannel * CFunctionCore::AddChannel( const char * ChannelName, bool Ready )
|
||||
{
|
||||
TChannel ** Channel = NULL;
|
||||
|
||||
@@ -197,63 +188,106 @@ TChannel * CFunctionCore::AddChannel( const char * ChannelName, const bool pInpu
|
||||
|
||||
// Set Name
|
||||
(*Channel)->Name = strdup( ChannelName );
|
||||
(*Channel)->Ref = (char*)malloc( strlen(Name)+strlen(ChannelName)+2 );
|
||||
sprintf( (*Channel)->Ref, "%s/%s", Name, ChannelName );
|
||||
(*Channel)->Ready = Ready;
|
||||
|
||||
// Log Event
|
||||
if (Log) Log->Message( LogLevel, dlLow, "%s/%s: Channel '%s' - Created",
|
||||
ProcessName, Name, ChannelName );
|
||||
if (Log) Log->Message( LogLevel, dlLow, "%s/%s: Channel '%s' - Created, Ref:'%s', Ready:%s",
|
||||
ProcessName, Name, ChannelName, (*Channel)->Ref, (((*Channel)->Ready)? "Yes" : "No") );
|
||||
}
|
||||
|
||||
// Set parameters
|
||||
(*Channel)->InputEnabled = pInputEnable;
|
||||
(*Channel)->OutputEnabled = pOutputEnable;
|
||||
|
||||
return *Channel;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// Automated Data Input/Output
|
||||
bool CFunctionCore::LinkChannel( const char * ChannelName, const char * LinkFunctionName, const char * LinkChannelName, bool Bidirectional )
|
||||
bool CFunctionCore::SetChannelState( TChannel * Channel, const bool Ready )
|
||||
{
|
||||
TChannel * OutChannel = NULL;
|
||||
CFunctionCore * InFunction = NULL;
|
||||
TChannel * InChannel = NULL;
|
||||
TChannelLink * LinkChannel;
|
||||
|
||||
// Validate
|
||||
if (!Channel)
|
||||
return false;
|
||||
|
||||
// Update state
|
||||
Channel->Ready = Ready;
|
||||
if (Log) Log->Message( LogLevel, dlLow, "%s/%s: Update Channel '%s' - Ready:%s",
|
||||
ProcessName, Name, Channel->Name, ((Ready)? "Yes" : "No") );
|
||||
|
||||
// Update linked channels
|
||||
LinkChannel = Channel->FirstLink;
|
||||
while (LinkChannel) {
|
||||
LinkChannel->Function->ChannelStateEvent( LinkChannel->Channel, Channel->Ref, Ready );
|
||||
LinkChannel = LinkChannel->Next;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool CFunctionCore::ChannelStateEvent( TChannel * Channel, const char * SourceRef, const bool Ready )
|
||||
{
|
||||
TChannelLink * LinkChannel;
|
||||
|
||||
if (!Channel)
|
||||
return false;
|
||||
if (!(LinkChannel = GetLinkChannel( Channel, SourceRef )))
|
||||
return false;
|
||||
|
||||
if (Log) Log->Message( LogLevel, dlLow, "%s/%s: Update Link Channel '%s'-->'%s' - Ready:%s",
|
||||
ProcessName, Name, Channel->Name, LinkChannel->Channel->Ref, ((Ready)? "Yes" : "No") );
|
||||
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// Automated Data Input/Output
|
||||
bool CFunctionCore::LinkChannel( const char * ChannelName, const char * LinkFunctionName, const char * LinkChannelName, bool Input, bool Output )
|
||||
{
|
||||
TChannel * Channel = NULL;
|
||||
CFunctionCore * LinkFunction = NULL;
|
||||
TChannel * LinkChannel = NULL;
|
||||
TChannelLink ** LinkedChannel = NULL;
|
||||
|
||||
// Check if Channels & Function exist
|
||||
if (!(OutChannel = GetChannel( ChannelName )) ||
|
||||
!(InFunction = Application->GetFunction( LinkFunctionName )) ||
|
||||
!(InChannel = InFunction->GetChannel( LinkChannelName )) ) {
|
||||
if (!(Channel = GetChannel( ChannelName )) ||
|
||||
!(LinkFunction = Application->GetFunction( LinkFunctionName )) ||
|
||||
!(LinkChannel = LinkFunction->GetChannel( LinkChannelName )) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if linked Channel exists
|
||||
LinkedChannel = &(OutChannel->FirstLink);
|
||||
while (*LinkedChannel && (((*LinkedChannel)->Function != InFunction) || strcmp( (*LinkedChannel)->Name, LinkChannelName ) )) {
|
||||
LinkedChannel = &(Channel->FirstLink);
|
||||
while (*LinkedChannel && ((*LinkedChannel)->Channel == LinkChannel))
|
||||
LinkedChannel = &((*LinkedChannel)->Next);
|
||||
}
|
||||
|
||||
// Create if not found
|
||||
if (!*LinkedChannel)
|
||||
{
|
||||
// Create
|
||||
*LinkedChannel = new TChannelLink;
|
||||
|
||||
// Set Parameters
|
||||
(*LinkedChannel)->Function = InFunction;
|
||||
(*LinkedChannel)->Name = strdup( LinkChannelName );
|
||||
sprintf( (*LinkedChannel)->Ref, "%s/%s", LinkFunctionName, LinkChannelName );
|
||||
// Set Parameters
|
||||
(*LinkedChannel)->Function = LinkFunction;
|
||||
(*LinkedChannel)->Channel = LinkChannel;
|
||||
(*LinkedChannel)->Input = Input;
|
||||
(*LinkedChannel)->Output = Output;
|
||||
|
||||
// Log Event
|
||||
if (Log) Log->Message( LogLevel, dlLow, "%s/%s: Output Linked - '%s/%s' --> '%s/%s'",
|
||||
ProcessName, Name, Name, ChannelName, LinkFunctionName, LinkChannelName );
|
||||
}
|
||||
// Log Event
|
||||
if (Log) Log->Message( LogLevel, dlLow, "%s/%s: Forward Channel Linked - '%s'-->'%s' - In:%s, Out:%s",
|
||||
ProcessName, Name, Channel->Ref, (*LinkedChannel)->Channel->Ref, ((Input)? "Yes" : "No"), ((Output)? "Yes" : "No") );
|
||||
|
||||
// Link return direction as well
|
||||
if (Bidirectional) {
|
||||
return InFunction->LinkChannel( LinkChannelName, Name, ChannelName, false );
|
||||
}
|
||||
// Find Linked channel on remote function
|
||||
LinkedChannel = &(LinkChannel->FirstLink);
|
||||
while (*LinkedChannel && ((*LinkedChannel)->Channel == Channel))
|
||||
LinkedChannel = &((*LinkedChannel)->Next);
|
||||
if (!*LinkedChannel)
|
||||
*LinkedChannel = new TChannelLink;
|
||||
|
||||
// Set Parameters
|
||||
(*LinkedChannel)->Function = this;
|
||||
(*LinkedChannel)->Channel = Channel;
|
||||
(*LinkedChannel)->Input = Output;
|
||||
(*LinkedChannel)->Output = Input;
|
||||
|
||||
// Log Event
|
||||
if (Log) Log->Message( LogLevel, dlLow, "%s/%s: Reverse Channel Linked - '%s'-->'%s' - In:%s, Out:%s",
|
||||
ProcessName, Name, LinkChannel->Ref, (*LinkedChannel)->Channel->Ref, ((Output)? "Yes" : "No"), ((Input)? "Yes" : "No") );
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
@@ -274,9 +308,8 @@ int CFunctionCore::Input( const char * ChannelName, const char * SourceRef, cons
|
||||
ProcessName, Name, ((SourceRef && *SourceRef)? SourceRef : "(Any)"), ChannelName );
|
||||
return 0;
|
||||
}
|
||||
else if (!Channel->InputEnabled) {
|
||||
// Channel disabled
|
||||
if (Log) Log->Message( LogLevel, dlHigh, "%s/%s: Channel '%s'-'%s' - Input rejected, Channel input disabled",
|
||||
else if (!Channel->Ready) {
|
||||
if (Log) Log->Message( LogLevel, dlHigh, "%s/%s: Channel '%s'->'%s' - Input rejected, Channel not Ready",
|
||||
ProcessName, Name, ((SourceRef && *SourceRef)? SourceRef : "(Any)"), ChannelName );
|
||||
return 0;
|
||||
}
|
||||
@@ -316,7 +349,7 @@ int CFunctionCore::Output( const char * ChannelName, const char * TargetRef, con
|
||||
|
||||
int CFunctionCore::Output( const TChannel * Channel, const char * TargetRef, const bool SourceRef, const char * Data, int Len, int OutputFormat )
|
||||
{
|
||||
TChannelLink * OutChannel = NULL;
|
||||
TChannelLink * LinkChannel = NULL;
|
||||
int TempLen = 0;
|
||||
int OutLen = 0;
|
||||
|
||||
@@ -325,27 +358,20 @@ int CFunctionCore::Output( const TChannel * Channel, const char * TargetRef, con
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Check if enabled
|
||||
if (!Channel->OutputEnabled) {
|
||||
if (Log) Log->Message( LogLevel, dlHigh, "%s/%s: Channel '%s' - Output rejected, Channel output disabled",
|
||||
ProcessName, Name, Channel->Name, ((TargetRef && *TargetRef)? TargetRef : "(All)") );
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Log event
|
||||
if (Log) Log->Output( LogLevel, dlHigh, ((!OutputFormat)? LogOutput : OutputFormat), Data, Len, "%s/%s: Channel '%s' - OUT:",
|
||||
if (Log) Log->Output( LogLevel, dlHigh, ((!OutputFormat)? LogOutput : OutputFormat), Data, Len, "%s/%s: Channel '%s'->'%s' - OUT:",
|
||||
ProcessName, Name, Channel->Name, ((TargetRef && *TargetRef)? TargetRef : "(All)") );
|
||||
|
||||
// Pass output to all linked inputs
|
||||
if (Len == -1)
|
||||
Len = strlen( Data );
|
||||
OutChannel = Channel->FirstLink;
|
||||
while (OutChannel) {
|
||||
if (!TargetRef || !*TargetRef || !strcasecmp( TargetRef, OutChannel->Ref )) {
|
||||
TempLen = OutChannel->Function->Input( OutChannel->Name, ((SourceRef)? Channel->Ref : NULL), Data, Len );
|
||||
LinkChannel = Channel->FirstLink;
|
||||
while (LinkChannel) {
|
||||
if (!TargetRef || !*TargetRef || !strcasecmp( TargetRef, LinkChannel->Channel->Ref )) {
|
||||
TempLen = LinkChannel->Function->Input( LinkChannel->Channel->Name, ((SourceRef)? Channel->Ref : NULL), Data, Len );
|
||||
OutLen = (TempLen > OutLen)? TempLen : OutLen;
|
||||
}
|
||||
OutChannel = OutChannel->Next;
|
||||
LinkChannel = LinkChannel->Next;
|
||||
}
|
||||
|
||||
// Return processed bytes
|
||||
|
||||
Reference in New Issue
Block a user