Files
redAcore/FunctionCore.cpp
Charl Wentzel b7ed169730 Major Update & Bug fixes:
- FileCore:
  - Replace dlNone -> dlLow
  - Remove temporary code used by CBaslerCamera
- Function Core:
  - Add method SetDebugLevel()
  - Remove global parameter BaseMember;
- JSONparse:
  - Print Bool parameters as true/false, not 1/0
- SelectCore:
  - Add method SetDebugLevel()
- SignalCore:
  - Replace dlNone -> dlLow
2017-07-09 16:31:47 +02:00

326 lines
9.7 KiB
C++

/*
* FunctionCore.cpp
*
* Created on: 18 May 2016
* Author: wentzelc
*/
// redA Libraries
#include "FunctionCore.h"
#include "TimingCore.h"
#include "LogCore.h"
// Standard C/C++ Libraries
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//---------------------------------------------------------------------------
extern char * ProcessName;
//---------------------------------------------------------------------------
// Life cycle
CFunctionCore::CFunctionCore( const char * FunctionName, CLogCore * pLog, EDebugLevel pDebugLevel, int pOuputDisplay )
{
// Set name
if (FunctionName) {
Name = (char*)malloc( strlen(FunctionName)+1 );
strcpy( Name, FunctionName );
}
else {
Name = NULL;
}
// Data Tree
DataTree = NULL;
// Channels
FirstChannel = NULL;
// Output
Log = pLog;
OutputDisplay = pOuputDisplay;
DebugLevel = pDebugLevel;
// Report status
if (Log) Log->Message( DebugLevel, dlLow, "%s: Function '%s' - Created", ProcessName, FunctionName );
}
//---------------------------------------------------------------------------
CFunctionCore::~CFunctionCore()
{
TChannel * NextChannel = NULL;
TChannelLink * NextLinkedChannel = NULL;
// Destroy Channels
while (FirstChannel)
{
// 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;
free( FirstChannel->FirstInput );
FirstChannel->FirstInput = NextLinkedChannel;
}
// Destroy Linked Outputs
while (FirstChannel->FirstOutput) {
if (FirstChannel->FirstOutput->Name) {
free( FirstChannel->FirstOutput->Name );
}
NextLinkedChannel = FirstChannel->FirstOutput->Next;
free( FirstChannel->FirstOutput );
FirstChannel->FirstOutput = NextLinkedChannel;
}
// Destroy Channel
NextChannel = FirstChannel->Next;
free( FirstChannel );
FirstChannel = NextChannel;
}
// Report status
if (Log) Log->Message( DebugLevel, dlLow, "%s: Function '%s' - Destroyed", ProcessName, Name );
// Destroy Name
if (Name) {
free( Name );
}
}
//---------------------------------------------------------------------------
bool CFunctionCore::LoadConfig( CDataTree * pDataTree, const char * pBasePath )
{
TDataMember * BaseMember;
// Validate
if (!(DataTree = pDataTree) ||
!(BaseMember = DataTree->GetMember( NULL, pBasePath, true )))
return false;
return true;
}
//---------------------------------------------------------------------------
bool CFunctionCore::SetDebugLevel( EDebugLevel pDebugLevel )
{
DebugLevel = pDebugLevel;
return true;
}
//---------------------------------------------------------------------------
TChannel * CFunctionCore::AddChannel( const char * ChannelName, const bool pInputEnable, const bool pOutputEnable )
{
TChannel ** Channel = NULL;
// Validate
if (!ChannelName) {
return NULL;
}
// Check if exists
Channel = &FirstChannel;
while (*Channel && strcmp( ChannelName, (*Channel)->Name )) {
Channel = &((*Channel)->Next);
}
// Create if not exist
if (!*Channel) {
// Create
*Channel = (TChannel*)malloc( sizeof(TChannel) );
memset( *Channel, 0, sizeof(TChannel) );
// Set Name
(*Channel)->Name = (char*)malloc( strlen(ChannelName)+1 );
strcpy( (*Channel)->Name, ChannelName );
// Log Event
if (Log) Log->Message( DebugLevel, dlLow, "%s: Channel '%s' - Created", Name, ChannelName );
}
// Set parameters
(*Channel)->InputEnabled = pInputEnable;
(*Channel)->OutputEnabled = pOutputEnable;
return *Channel;
}
//---------------------------------------------------------------------------
// Automated Data Input/Output
bool CFunctionCore::LinkInputChannel( const char * ChannelName, CFunctionCore * OutFunction, const char * OutChannelName, bool Bidirectional )
{
TChannel * Channel = NULL;
TChannelLink ** LinkedChannel = NULL;
// Get Channel
if (!OutFunction || !OutFunction || !(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 = (TChannelLink*)malloc( sizeof(TChannelLink) );
memset( *LinkedChannel, 0, sizeof( TChannelLink ));
// Set Parameters
(*LinkedChannel)->Function = OutFunction;
(*LinkedChannel)->Name = (char*)malloc( strlen(OutChannelName)+1 );
strcpy( (*LinkedChannel)->Name, OutChannelName );
// Log Event
if (Log) Log->Message( DebugLevel, dlLow, "%s: Input Linked - '%s'/'%s' <-- '%s'/'%s'", Name, Name, ChannelName, OutFunction->GetName(), OutChannelName );
}
// Link Return direction as well
if (Bidirectional) {
return OutFunction->LinkInputChannel( OutChannelName, this, ChannelName, false );
}
return true;
}
//---------------------------------------------------------------------------
bool CFunctionCore::LinkOutputChannel( const char * ChannelName, CFunctionCore * InFunction, const char * InChannelName, bool Bidirectional )
{
TChannel * Channel = NULL;
TChannelLink ** LinkedChannel = NULL;
// Get Channel
if (!InFunction || !InChannelName || !(Channel = GetChannel( ChannelName ))) {
return false;
}
// Check if linked Channel exists
LinkedChannel = &(Channel->FirstOutput);
while (*LinkedChannel && (((*LinkedChannel)->Function != InFunction) || strcmp( (*LinkedChannel)->Name, InChannelName ) )) {
LinkedChannel = &((*LinkedChannel)->Next);
}
// Create if not found
if (!*LinkedChannel)
{
// Create
*LinkedChannel = (TChannelLink*)malloc( sizeof(TChannelLink) );
memset( *LinkedChannel, 0, sizeof( TChannelLink ));
// Set Parameters
(*LinkedChannel)->Function = InFunction;
(*LinkedChannel)->Name = (char*)malloc( strlen(InChannelName)+1 );
strcpy( (*LinkedChannel)->Name, InChannelName );
// Log Event
if (Log) Log->Message( DebugLevel, dlLow, "%s: Output Linked - '%s'/'%s' --> '%s'/'%s'", Name, Name, ChannelName, InFunction->GetName(), InChannelName );
}
// Link return direction as well
if (Bidirectional) {
return InFunction->LinkOutputChannel( InChannelName, this, ChannelName, false );
}
return true;
}
//---------------------------------------------------------------------------
// Manual Data Input/Output
int CFunctionCore::Input( const char * ChannelName, const char * Data, int MaxLen )
{
TChannel * Channel = NULL;
// Validate
if (!ChannelName || !Data) {
return 0;
}
// Get Channel
if (!(Channel = GetChannel( ChannelName ))) {
// Channel not found
if (Log) Log->Message( DebugLevel, dlHigh, "%s: Channel '%s' - Input rejected, Channel not found", Name, ChannelName );
return 0;
}
else if (!Channel->InputEnabled) {
// Channel disabled
if (Log) Log->Message( DebugLevel, dlHigh, "%s: Channel '%s' - Input rejected, Channel input disabled", Name, ChannelName );
return 0;
}
else {
// Return processed bytes
if (MaxLen == -1) {
MaxLen = strlen( Data );
}
if (Log) Log->Output( DebugLevel, dlHigh, OutputDisplay, Data, MaxLen, "%s: Channel '%s' - IN:", Name, ChannelName );
return MaxLen;
}
}
//---------------------------------------------------------------------------
int CFunctionCore::Output( const char * ChannelName, const char * Data, int Len )
{
TChannel * Channel = NULL;
// Validate
if (!ChannelName) {
return 0;
}
// Get Channel
if (!(Channel = GetChannel( ChannelName ))) {
if (Log) Log->Message( DebugLevel, dlHigh, "%s: Channel '%s' - Output rejected, Channel not found", Name, ChannelName );
return 0;
}
else {
// Return processed bytes
return Output( Channel, Data, Len );
}
}
//---------------------------------------------------------------------------
int CFunctionCore::Output( const TChannel * Channel, const char * Data, int Len )
{
TChannelLink * OutChannel = NULL;
// Validate
if (!Channel || !Data) {
return 0;
}
// Check if enabled
if (!Channel->OutputEnabled) {
if (Log) Log->Message( DebugLevel, dlHigh, "%s: Channel '%s' - Output rejected, Channel output disabled", Name, Channel->Name );
return 0;
}
// Log event
if (Log) Log->Output( DebugLevel, dlHigh, OutputDisplay, Data, Len, "%s: Channel '%s' - OUT:", Name, Channel->Name );
// Pass output to all linked inputs
if (Len == -1) {
Len = strlen( Data );
}
OutChannel = Channel->FirstOutput;
while (OutChannel) {
OutChannel->Function->Input( OutChannel->Name, Data, Len );
OutChannel = OutChannel->Next;
}
// Return processed bytes
return Len;
}
//---------------------------------------------------------------------------