Important Update:

- FunctionCore/SelectableCore/FileCore/DeviceCore:
  - Remove InputChannels
    - Only OutputChannels -> LinkedChannels
    - Remove PullInput/Output() methods
    - Remove StoredOutput
  - Add References to channels and linked channels
    - Send SourceRef with output
    - Receive TargetRef with input
    - Filter output channels based on TargetRef
This commit is contained in:
Charl Wentzel
2019-06-04 18:35:23 +02:00
parent 7459763eb6
commit fa6825b72a
7 changed files with 84 additions and 232 deletions

View File

@@ -51,26 +51,18 @@ CFunctionCore::~CFunctionCore()
// Destroy Parameters
if (FirstChannel->Name) {
free( FirstChannel->Name );
}
// Destroy Linked Inputs
while (FirstChannel->FirstInput) {
if (FirstChannel->FirstInput->Name) {
free( FirstChannel->FirstInput->Name );
}
NextLinkedChannel = FirstChannel->FirstInput->Next;
delete FirstChannel->FirstInput;
FirstChannel->FirstInput = NextLinkedChannel;
free( FirstChannel->Ref );
}
// Destroy Linked Outputs
while (FirstChannel->FirstOutput) {
if (FirstChannel->FirstOutput->Name) {
free( FirstChannel->FirstOutput->Name );
while (FirstChannel->FirstLink) {
if (FirstChannel->FirstLink->Name) {
free( FirstChannel->FirstLink->Name );
free( FirstChannel->FirstLink->Ref );
}
NextLinkedChannel = FirstChannel->FirstOutput->Next;
delete FirstChannel->FirstOutput;
FirstChannel->FirstOutput = NextLinkedChannel;
NextLinkedChannel = FirstChannel->FirstLink->Next;
delete FirstChannel->FirstLink;
FirstChannel->FirstLink = NextLinkedChannel;
}
// Destroy Channel
@@ -152,7 +144,7 @@ bool CFunctionCore::InitChannelLinks( CDataMember * LinkConfig )
while (FunctionMember)
{
// Get Parameters
LinkOutputChannel( Channel->Name,
LinkChannel( Channel->Name,
FunctionMember->GetChStr( "Function" ),
FunctionMember->GetChStr( "Channel" ),
FunctionMember->GetChBool( "Bidirectional" ) );
@@ -205,6 +197,7 @@ TChannel * CFunctionCore::AddChannel( const char * ChannelName, const bool pInpu
// Set Name
(*Channel)->Name = strdup( ChannelName );
sprintf( (*Channel)->Ref, "%s/%s", Name, ChannelName );
// Log Event
if (Log) Log->Message( LogLevel, dlLow, "%s/%s: Channel '%s' - Created",
@@ -220,48 +213,7 @@ TChannel * CFunctionCore::AddChannel( const char * ChannelName, const bool pInpu
//---------------------------------------------------------------------------
// Automated Data Input/Output
bool CFunctionCore::LinkInputChannel( const char * ChannelName, const char * OutFunctionName, const char * OutChannelName, bool Bidirectional )
{
CFunctionCore * OutFunction = NULL;
TChannel * Channel = NULL;
TChannelLink ** LinkedChannel = NULL;
// Get Channel
if (!(OutFunction = Application->GetFunction( OutFunctionName )) || !(Channel = GetChannel( ChannelName ))) {
return false;
}
// Check if linked Channel exists
LinkedChannel = &(Channel->FirstInput);
while (*LinkedChannel && (((*LinkedChannel)->Function != OutFunction) || strcmp( (*LinkedChannel)->Name, OutChannelName ) )) {
LinkedChannel = &((*LinkedChannel)->Next);
}
// Create if not found
if (!*LinkedChannel)
{
// Create
*LinkedChannel = new TChannelLink;
// Set Parameters
(*LinkedChannel)->Function = OutFunction;
(*LinkedChannel)->Name = strdup( OutChannelName );
// Log Event
if (Log) Log->Message( LogLevel, dlLow, "%s/%s: Input Linked - '%s'/'%s' <-- '%s'/'%s'",
ProcessName, Name, Name, ChannelName, OutFunction->GetName(), OutChannelName );
}
// Link Return direction as well
if (Bidirectional) {
return OutFunction->LinkInputChannel( OutChannelName, Name, ChannelName, false );
}
return true;
}
//---------------------------------------------------------------------------
bool CFunctionCore::LinkOutputChannel( const char * ChannelName, const char * InFunctionName, const char * InChannelName, bool Bidirectional )
bool CFunctionCore::LinkChannel( const char * ChannelName, const char * LinkFunctionName, const char * LinkChannelName, bool Bidirectional )
{
TChannel * OutChannel = NULL;
CFunctionCore * InFunction = NULL;
@@ -270,14 +222,14 @@ bool CFunctionCore::LinkOutputChannel( const char * ChannelName, const char * In
// Check if Channels & Function exist
if (!(OutChannel = GetChannel( ChannelName )) ||
!(InFunction = Application->GetFunction( InFunctionName )) ||
!(InChannel = InFunction->GetChannel( InChannelName )) ) {
!(InFunction = Application->GetFunction( LinkFunctionName )) ||
!(InChannel = InFunction->GetChannel( LinkChannelName )) ) {
return false;
}
// Check if linked Channel exists
LinkedChannel = &(OutChannel->FirstOutput);
while (*LinkedChannel && (((*LinkedChannel)->Function != InFunction) || strcmp( (*LinkedChannel)->Name, InChannelName ) )) {
LinkedChannel = &(OutChannel->FirstLink);
while (*LinkedChannel && (((*LinkedChannel)->Function != InFunction) || strcmp( (*LinkedChannel)->Name, LinkChannelName ) )) {
LinkedChannel = &((*LinkedChannel)->Next);
}
@@ -289,80 +241,80 @@ bool CFunctionCore::LinkOutputChannel( const char * ChannelName, const char * In
// Set Parameters
(*LinkedChannel)->Function = InFunction;
(*LinkedChannel)->Name = strdup( InChannelName );
(*LinkedChannel)->Name = strdup( LinkChannelName );
sprintf( (*LinkedChannel)->Ref, "%s/%s", LinkFunctionName, LinkChannelName );
// Log Event
if (Log) Log->Message( LogLevel, dlLow, "%s/%s: Output Linked - '%s'/'%s' --> '%s'/'%s'",
ProcessName, Name, Name, ChannelName, InFunction->GetName(), InChannelName );
if (Log) Log->Message( LogLevel, dlLow, "%s/%s: Output Linked - '%s/%s' --> '%s/%s'",
ProcessName, Name, Name, ChannelName, LinkFunctionName, LinkChannelName );
}
// Link return direction as well
if (Bidirectional) {
return InFunction->LinkOutputChannel( InChannelName, Name, ChannelName, false );
return InFunction->LinkChannel( LinkChannelName, Name, ChannelName, false );
}
return true;
}
//---------------------------------------------------------------------------
// Manual Data Input/Output
int CFunctionCore::Input( const char * ChannelName, const char * Data, int Len )
int CFunctionCore::Input( const char * ChannelName, const char * SourceRef, const char * Data, int Len )
{
TChannel * Channel = NULL;
TChannel * Channel = NULL;
// Validate
if (!ChannelName || !Data) {
if (!ChannelName || !*ChannelName || !Data) {
return 0;
}
// Get Channel
if (!(Channel = GetChannel( ChannelName ))) {
// Channel not found
if (Log) Log->Message( LogLevel, dlHigh, "%s/%s: Channel '%s' - Input rejected, Channel not found",
ProcessName, Name, ChannelName );
if (Log) Log->Message( LogLevel, dlHigh, "%s/%s: Channel '%s'->'%s' - Input rejected, Channel not found",
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' - Input rejected, Channel input disabled",
ProcessName, Name, ChannelName );
if (Log) Log->Message( LogLevel, dlHigh, "%s/%s: Channel '%s'-'%s' - Input rejected, Channel input disabled",
ProcessName, Name, ((SourceRef && *SourceRef)? SourceRef : "(Any)"), ChannelName );
return 0;
}
else {
// Return processed bytes
if (Len == -1) {
Len = strlen( Data );
}
if (Log) Log->Output( LogLevel, dlHigh, LogOutput, Data, Len, "%s/%s: Channel '%s' - IN:",
ProcessName, Name, ChannelName );
return Len;
// Return processed bytes
if (Len == -1) {
Len = strlen( Data );
}
if (Log) Log->Output( LogLevel, dlHigh, LogOutput, Data, Len, "%s/%s: Channel '%s'->'%s' - IN:",
ProcessName, Name, ((SourceRef && *SourceRef)? SourceRef : "(Any)"), ChannelName );
return Len;
}
//---------------------------------------------------------------------------
int CFunctionCore::Output( const char * ChannelName, const char * Data, int Len )
int CFunctionCore::Output( const char * ChannelName, const char * TargetRef, const bool SourceRef, const char * Data, int Len )
{
TChannel * Channel = NULL;
// Validate
if (!ChannelName) {
if (!ChannelName || !*ChannelName) {
return 0;
}
// Get Channel
if (!(Channel = GetChannel( ChannelName ))) {
if (Log) Log->Message( LogLevel, dlHigh, "%s/%s: Channel '%s' - Output rejected, Channel not found",
ProcessName, Name, ChannelName );
if (Log) Log->Message( LogLevel, dlHigh, "%s/%s: Channel '%s'->'%s' - Output rejected, Output Channel not found",
ProcessName, Name, ChannelName, ((TargetRef && *TargetRef)? TargetRef : "(All)") );
return 0;
}
else {
// Return processed bytes
return Output( Channel, Data, Len );
return Output( Channel, TargetRef, SourceRef, Data, Len );
}
}
//---------------------------------------------------------------------------
int CFunctionCore::Output( const TChannel * Channel, const char * Data, int Len, int OutputFormat )
int CFunctionCore::Output( const TChannel * Channel, const char * TargetRef, const bool SourceRef, const char * Data, int Len, int OutputFormat )
{
TChannelLink * OutChannel = NULL;
int TempLen = 0;
@@ -376,22 +328,23 @@ int CFunctionCore::Output( const TChannel * Channel, const char * Data, int Len,
// 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 );
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:",
ProcessName, Name, Channel->Name );
ProcessName, Name, Channel->Name, ((TargetRef && *TargetRef)? TargetRef : "(All)") );
// Pass output to all linked inputs
if (Len == -1) {
if (Len == -1)
Len = strlen( Data );
}
OutChannel = Channel->FirstOutput;
OutChannel = Channel->FirstLink;
while (OutChannel) {
TempLen = OutChannel->Function->Input( OutChannel->Name, Data, Len );
OutLen = (TempLen > OutLen)? TempLen : OutLen;
if (!TargetRef || !*TargetRef || !strcasecmp( TargetRef, OutChannel->Ref )) {
TempLen = OutChannel->Function->Input( OutChannel->Name, ((SourceRef)? Channel->Ref : NULL), Data, Len );
OutLen = (TempLen > OutLen)? TempLen : OutLen;
}
OutChannel = OutChannel->Next;
}
@@ -399,97 +352,3 @@ int CFunctionCore::Output( const TChannel * Channel, const char * Data, int Len,
return OutLen;
}
//---------------------------------------------------------------------------
bool CFunctionCore::PullInput( const char * ChannelName )
{
TChannel * Channel = NULL;
// Validate
if (!ChannelName) {
return false;
}
// Get Channel
if (!(Channel = GetChannel( ChannelName ))) {
// Channel not found
if (Log) Log->Message( LogLevel, dlHigh, "%s/%s: Channel '%s' - Input failed, Channel not found",
ProcessName, Name, ChannelName );
return false;
}
else {
// Return success
return PullInput( Channel );
}
}
//---------------------------------------------------------------------------
bool CFunctionCore::PullInput( TChannel * Channel )
{
TChannelLink * InChannel = NULL;
char ** Data = NULL;
int * Len = NULL;
// Validate
if (!Channel) {
return false;
}
// Check if enabled
if (!Channel->InputEnabled) {
if (Log) Log->Message( LogLevel, dlHigh, "%s/%s: Channel '%s' - Input failed, Channel input disabled",
ProcessName, Name, Channel->Name );
return false;
}
// Pass output to all linked inputs
InChannel = Channel->FirstInput;
while (InChannel)
{
// Pull Output from Channel
if (InChannel->Function->PullOutput( InChannel->Name, Data, Len ))
{
// Use input
Input( Channel->Name, *Data, ((*Len)? *Len : -1) );
}
InChannel = InChannel->Next;
}
// Return success
return Len;
}
//---------------------------------------------------------------------------
bool CFunctionCore::PullOutput( const char * ChannelName, char ** Data, int * Len )
{
TChannel * Channel = NULL;
int TempLen = 0;
// Validate
if (!ChannelName || !Data) {
return 0;
}
// Get Channel
if (!(Channel = GetChannel( ChannelName ))) {
// Channel not found
if (Log) Log->Message( LogLevel, dlHigh, "%s/%s: Channel '%s' - Output failed, Channel not found",
ProcessName, Name, ChannelName );
return 0;
}
else if (!Channel->InputEnabled) {
// Channel disabled
if (Log) Log->Message( LogLevel, dlHigh, "%s/%s: Channel '%s' - Output failed, Channel output disabled",
ProcessName, Name, ChannelName );
return 0;
}
else {
// Return processed bytes
*Data = StoredOutput;
TempLen = (*Data)? strlen(*Data) : 0;
if (Len) *Len = TempLen;
if (Log) Log->Output( LogLevel, dlHigh, LogOutput, ((*Data)? *Data : "(NULL)"), TempLen, "%s/%s: Channel '%s' - IN:",
ProcessName, Name, ChannelName );
return Len;
}
}
//---------------------------------------------------------------------------