Major Update:

- Implement consistent Function addition to application
  - Use TYPE_XXX constants to declare function type
  - Use NewXXXX() methods to call constructor correctly
  - Add FunctionType list (with constructor) to Application
  - Create Function by comparison to FunctionType list
- Simplify LoadConfig() and Init() methods for functions
  - Combine methods into Init() method
  - Pass relevant data member to Init() method
  - Remove all CDataMember references on functions
- ApplicationCore:
  - Split ReadParam() method from LoadConfig() method
  - Split main configuration into separate files:
    - config/ - main config file, general application settings
    - definition/ - application definition, e.g. function blocks
  - Definition and Address List files specified in config file
  - Load address file in address/ branch
  - Made DataTree & JSONparser private
  - Made Config, Definition & Address branches public
  - Removed unnecessary branch references
  - Improved event logging
- DataTreeCore:
  - Allow GetChFirstChild & GetChElement to create parent branches
    with correct type, ie. Object/Array
  - Remove unnecessary Create param from GetXxx functions
  - Bug fix: Print empty objects/arrays correct, ie. empty brackets
  - Bug fix: Adding element at specific index
  - Bug fix: Error when get/create string value with "null"
- FunctionCore:
  - Type param now set as constant via constructor
  - Create empty Handles & Channels objects if none in Config
- SelectableCore:
  - Add Queue length parameter to handles for UNIX and TCP sockets
- DeviceCore:
  - Bug fix: missing Process() method
This commit is contained in:
Charl Wentzel
2018-11-24 13:35:23 +02:00
parent 7434334280
commit a972fb9101
15 changed files with 518 additions and 469 deletions

View File

@@ -20,8 +20,14 @@ extern CApplication * Application;
//---------------------------------------------------------------------------
// Function Constructor
//CFunctionCore * NewFunctionCore( const char * Name ) {
// return new CFunctionCore( Name, "Function" );
//}
//---------------------------------------------------------------------------
// Life cycle
CFunctionCore::CFunctionCore( const char * pName, const char * pType )
CFunctionCore::CFunctionCore( const char * pName, const char * pType ) : Type( pType )
{
// Set name
if (pName) {
@@ -32,25 +38,8 @@ CFunctionCore::CFunctionCore( const char * pName, const char * pType )
Name = NULL;
}
// Set Type
if (pType) {
Type = (char*)malloc( strlen(pType)+1 );
strcpy( Type, pType );
}
else {
Type = NULL;
}
// Channels
FirstChannel = NULL;
// List
Application->AddFunction( this );
// Data Tree
DataTree = Application->DataTree;
ConfigMember = NULL;
LinkConfigMember = NULL;
FirstChannel = NULL;
// Logging
Log = Application->Log;
@@ -107,20 +96,25 @@ CFunctionCore::~CFunctionCore()
// Destroy Name
if (Name) free( Name );
if (Type) free( Type );
}
//---------------------------------------------------------------------------
bool CFunctionCore::LoadConfigData()
bool CFunctionCore::Init( CDataMember * FunctionConfig )
{
CDataMember * TempMember;
// Load configuration
CDataMember * ItemConfig;
CDataMember * ChannelConfig;
EDebugLevel pLogLevel;
int pLogOutput;
char * TempStr;
// Validate
if (!FunctionConfig )
return false;
// Get debug level
pLogLevel = dlNone;
TempStr = (char*)ConfigMember->GetChStr( "Log/Level", "Medium", true );
TempStr = (char*)FunctionConfig->GetChStr( "Log/Level", "Medium", true );
if (TempStr)
{
if (!strcasecmp( TempStr, "Low" ))
@@ -133,66 +127,63 @@ bool CFunctionCore::LoadConfigData()
// Set debug output
pLogOutput = 0;
if ((TempMember = ConfigMember->GetChild( "Log/Output", true )))
ItemConfig = FunctionConfig->GetChild( "Log/Output[0]", true ); // Create first element if not exist
while (ItemConfig)
{
TempMember = TempMember->GetFirstChild();
while (TempMember)
if ((TempStr = (char*)ItemConfig->GetStr( "Normal" ))) // Set default value "Normal" if not set
{
if ((TempStr = (char*)TempMember->GetStr()))
{
if (!strcasecmp( TempStr, "Normal"))
pLogOutput |= OUT_NORMAL;
else if (!strcasecmp( TempStr, "Bin"))
pLogOutput |= OUT_BIN;
else if (!strcasecmp( TempStr, "Hex"))
pLogOutput |= OUT_HEX;
else if (!strcasecmp( TempStr, "Count"))
pLogOutput |= OUT_COUNT;
else if (!strcasecmp( TempStr, "AsIs"))
pLogOutput |= OUT_ASIS;
else if (!strcasecmp( TempStr, "CRLF"))
pLogOutput |= OUT_CRLF;
}
// Next
TempMember = TempMember->GetNextPeer();
if (!strcasecmp( TempStr, "Normal")) // Normal ASCII -> Unless "AsIs", print special chars as "."
pLogOutput |= OUT_NORMAL;
else if (!strcasecmp( TempStr, "Bin")) // Print as Binary value ('1' and '0')
pLogOutput |= OUT_BIN;
else if (!strcasecmp( TempStr, "Hex")) // Print as Hexadecimal value (0-9,A-F)
pLogOutput |= OUT_HEX;
else if (!strcasecmp( TempStr, "Count")) // Print number of characters
pLogOutput |= OUT_COUNT;
else if (!strcasecmp( TempStr, "AsIs")) // Use with "Normal" -> Do not print special chars as "."
pLogOutput |= OUT_ASIS;
else if (!strcasecmp( TempStr, "CRLF")) // Add \r\n at end of line if not present
pLogOutput |= OUT_CRLF;
else
pLogOutput |= OUT_NORMAL;
}
ItemConfig = ItemConfig->GetNextPeer();
}
// Set Logging
SetLogParam( pLogLevel, pLogOutput );
// Load Channels
TempMember = ConfigMember->GetChFirstChild( "Channels" );
while (TempMember)
ChannelConfig = FunctionConfig->GetChFirstChild( "Channels", true );
while (ChannelConfig)
{
if (TempMember->GetName()) {
AddChannel( TempMember->GetName(),
TempMember->GetChBool( "InputEnabled", true, true ),
TempMember->GetChBool( "OutputEnabled", false, true ));
if (ChannelConfig->GetName()) {
AddChannel( ChannelConfig->GetName(),
ChannelConfig->GetChBool( "InputEnabled", true, true ),
ChannelConfig->GetChBool( "OutputEnabled", false, true ));
}
// Next
TempMember = TempMember->GetNextPeer();
ChannelConfig = ChannelConfig->GetNextPeer();
}
return true;
}
//---------------------------------------------------------------------------
bool CFunctionCore::LoadChannelLinkData()
bool CFunctionCore::InitChannelLinks( CDataMember * LinkConfig )
{
TChannel * Channel;
CDataMember * ChannelMember;
CDataMember * FunctionMember;
// Validate
if (!LinkConfig)
return false;
// Process each Channel
ChannelMember = LinkConfigMember->GetFirstChild();
ChannelMember = LinkConfig->GetFirstChild();
while (ChannelMember)
{
if ((Channel = GetChannel( ChannelMember->GetName() )))
{
FunctionMember = ChannelMember->GetFirstChild();
FunctionMember = ChannelMember->GetElement( 0 );
while (FunctionMember)
{
// Get Parameters
@@ -200,11 +191,9 @@ bool CFunctionCore::LoadChannelLinkData()
FunctionMember->GetChStr( "Function" ),
FunctionMember->GetChStr( "Channel" ),
FunctionMember->GetChBool( "Bidirectional" ) );
// Next
FunctionMember = FunctionMember->GetNextPeer();
}
}
// Next
ChannelMember = ChannelMember->GetNextPeer();
}
@@ -212,69 +201,6 @@ bool CFunctionCore::LoadChannelLinkData()
}
//---------------------------------------------------------------------------
bool CFunctionCore::Init()
{
// Report status
if (Log) Log->Message( LogLevel, dlLow, "%s: Function '%s' - Initialised", ProcessName, Name );
return true;
}
//---------------------------------------------------------------------------
bool CFunctionCore::InitConfig( const char * pConfigPath )
{
// Validate
if (!DataTree || !(ConfigMember = DataTree->GetChild( pConfigPath, true )))
return false;
// Load configuration
LoadConfigData();
Init();
return true;
}
//---------------------------------------------------------------------------
bool CFunctionCore::InitConfig( CDataMember * pBaseMember )
{
// Validate
if (!DataTree || !(ConfigMember = pBaseMember ))
return false;
// Load configuration
LoadConfigData();
Init();
return true;
}
//---------------------------------------------------------------------------
bool CFunctionCore::InitChannelLinks( const char * pLinkConfigPath )
{
// Validate
if (!DataTree || !(LinkConfigMember = DataTree->GetChild( pLinkConfigPath, true )))
return false;
// Load configuration
LoadChannelLinkData();
return true;
}
//---------------------------------------------------------------------------
bool CFunctionCore::InitChannelLinks( CDataMember *pLinkConfigMember )
{
// Validate
if (!DataTree || !(LinkConfigMember = pLinkConfigMember))
return false;
// Load configuration
LoadChannelLinkData();
return true;
}
//---------------------------------------------------------------------------
bool CFunctionCore::SetLogParam( EDebugLevel pDebugLevel, int pOutputDisplay )
{
// Output