diff --git a/Version_Max_07_05_2018_CMake/src/CMakeLists.txt b/Version_Max_07_05_2018_CMake/src/CMakeLists.txt index 990ca74..4ae2c8c 100755 --- a/Version_Max_07_05_2018_CMake/src/CMakeLists.txt +++ b/Version_Max_07_05_2018_CMake/src/CMakeLists.txt @@ -1,53 +1,53 @@ cmake_minimum_required (VERSION 2.6 FATAL_ERROR) -project("CAH-Project") +project("CAM-Project") if( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") set(warnings "-Wall -Wextra -Werror") elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") set(warnings "/W4 /WX /EHsc") endif() set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c11") #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") set(CMAKE_CXX_STANDARD 11) set(CMAKE_BUILD_TYPE Debug) add_executable(CAM main.cpp abstraction_functions.cpp MasterAgentSlotOfAgent.cpp abstraction_interface.cpp MaximumValue.cpp AbstractionModule.cpp Message.cpp Agent.cpp minmaxzeug.cpp AgentSlotOfTestbench.cpp MinumumValue.cpp attach_modules.cpp Module.cpp attach_modulesToTestbench.cpp mount_nodes.cpp AverageValue.cpp Node.cpp boundary_check.cpp printError.cpp Bunch_Module.cpp Range.cpp Channel.cpp register_in_testbench.cpp ChannelSlotOfTestbench.cpp relationChecker.cpp clock.cpp Sensor.cpp ConfidenceModule.cpp SensorHandlerOfAgent.cpp Continuous_Average.cpp SensorSlotOfAgent.cpp configCAMforNewMotor.cpp create_unit.cpp Cross_Confidence_Validator.cpp setup_agent.cpp CSVreaderModule.cpp setup_lookuptable.cpp CSV_Writer.cpp setupNode.cpp Discrete_Average.cpp SlaveAgentHandlerOfAgent.cpp Domain.cpp SlaveAgentSlotOfAgent.cpp Evaluation.cpp Slot.cpp extremaValues.cpp SlotOfAgent.cpp ExtremeValue.cpp State.cpp HandlerOfAgent.cpp StateHandler.cpp HistoryEntry.cpp StateModule.cpp HistoryModule.cpp StateVariable.cpp inAgentsRegistrations.cpp StatisticValue.cpp LinearFunctionBlock.cpp SubState.cpp LinearFunction.cpp Testbench.cpp Lookuptable.cpp Unit.cpp user_method_abstraction.cpp Testbench_Config.cpp MasterAgentHandlerOfAgent.cpp config.h SensorSlotOfTestbench.cpp ) diff --git a/Version_Max_07_05_2018_CMake/src/SensorHandlerOfAgent.cpp b/Version_Max_07_05_2018_CMake/src/SensorHandlerOfAgent.cpp index 81f48da..7b09c56 100755 --- a/Version_Max_07_05_2018_CMake/src/SensorHandlerOfAgent.cpp +++ b/Version_Max_07_05_2018_CMake/src/SensorHandlerOfAgent.cpp @@ -1,207 +1,207 @@ #include "SensorHandlerOfAgent.h" #include #include "printError.h" #include #define MAXNUMOF_MOUNTEDSENSORS 100 using namespace std; SensorHandlerOfAgent :: SensorHandlerOfAgent() { init_sensorHandler(); } void SensorHandlerOfAgent :: init_sensorHandler() { maxNumOf_mountedSensors = MAXNUMOF_MOUNTEDSENSORS; } //TODO: if(vMountedSensors.size() < maxNumOf_mountedSensors) als aller erste Abfrage machen ... noch bevor "SensorSlotOfAgent* sensorSlotOfAgent = new SensorSlotOfAgent();" //TODO: delete object if it cannot added to vector bool SensorHandlerOfAgent :: mount_sensorIntoSensorSlot(Channel* inputPort) { SensorSlotOfAgent* sensorSlotOfAgent = new SensorSlotOfAgent(); if(sensorSlotOfAgent != NULL) { if(sensorSlotOfAgent->set_comPort(inputPort)) { try { if(vMountedSensors.size() < maxNumOf_mountedSensors) { vMountedSensors.push_back(sensorSlotOfAgent); } else { printError("Max number of mounted sensors is already reached!"); return false; } } catch(bad_alloc& error) { printError("bad_alloc caught: ", error.what()); return false; } return true; } else { printError("Input port is no set!"); vMountedSensors.pop_back(); //TODO: check if it is right?!?! return false; } } else { printError("Couldn't create SensorSlot!"); return false; } } //TODO: what to do when 2 sensorSlots have the same inputPort??!! SensorSlotOfAgent* SensorHandlerOfAgent :: get_sensorSlotAddress(Channel* inputPort) { for(auto &sensorSlot : vMountedSensors) { if(sensorSlot->get_comPort() == inputPort) { return sensorSlot; } } return NULL; } //TODO: what to do when 2 slaveAgentSlots have the same inputPort??!! //TODO: case if slot with comPort is not in this vector unsigned int SensorHandlerOfAgent :: get_sensorSlotNumber(Channel* inputPort) { unsigned int slotNumber = 0; for(auto &sensorSlot : vMountedSensors) { if(sensorSlot->get_comPort() == inputPort) { return slotNumber; } slotNumber++; } - return NULL; + return std::numeric_limits::quiet_NaN(); } //TODO: what to do when 2 sensorSlots have the same historyModule??!! SensorSlotOfAgent* SensorHandlerOfAgent :: get_sensorSlotAddress(HistoryModule* historyModule) { for(auto &sensorSlot : vMountedSensors) { if(sensorSlot->get_historyModule() == historyModule) { return sensorSlot; } } return NULL; } //TODO: what to do when 2 sensorSlots have the same confidenceModule??!! SensorSlotOfAgent* SensorHandlerOfAgent :: get_sensorSlotAddress(ConfidenceModule* confidenceModule) { for(auto &sensorSlot : vMountedSensors) { if(sensorSlot->get_confidenceModule() == confidenceModule) { return sensorSlot; } } return NULL; } bool SensorHandlerOfAgent :: demount_sensor(Channel* inputPort) { vMountedSensors.erase(vMountedSensors.begin() + get_sensorSlotNumber(inputPort)); return false; } //TODO: do it also for integer variables bool SensorHandlerOfAgent :: read_sensorValue(SensorSlotOfAgent* sensorSlotOfAgent) { if(sensorSlotOfAgent != NULL) { Channel* channel = sensorSlotOfAgent->get_comPort(); if(channel != NULL) { float inputValue; if(channel->get_MsgUp(&inputValue)) { sensorSlotOfAgent->set_sensorValue(inputValue); return true; } } } return false; } bool SensorHandlerOfAgent :: read_allSensorValues() { bool flag_readSensor = false; for(auto &sensorSlot : vMountedSensors) { if(read_sensorValue(sensorSlot)) { flag_readSensor = true; } } return flag_readSensor; } bool SensorHandlerOfAgent :: attach_historyModule(Channel* inputPort, HistoryModule* historyModule) { SensorSlotOfAgent* sensorSlotOfAgent = get_sensorSlotAddress(inputPort); if(sensorSlotOfAgent != NULL) { return sensorSlotOfAgent->set_historyModule(historyModule); } return false; } bool SensorHandlerOfAgent :: detach_historyModule(SensorSlotOfAgent* sensorSlotOfAgent) { if(sensorSlotOfAgent != NULL) { return sensorSlotOfAgent->del_historyModule(); } return false; } bool SensorHandlerOfAgent :: detach_historyModule(Channel* inputPort) { SensorSlotOfAgent* sensorSlotOfAgent = get_sensorSlotAddress(inputPort); return detach_historyModule(sensorSlotOfAgent); } bool SensorHandlerOfAgent :: detach_historyModule(HistoryModule* historyModule) { SensorSlotOfAgent* sensorSlotOfAgent = get_sensorSlotAddress(historyModule); return detach_historyModule(sensorSlotOfAgent); } HistoryModule* SensorHandlerOfAgent :: get_historyModuleOfSensorSlot(Channel* inputPort) { SensorSlotOfAgent* sensorSlotOfAgent = get_sensorSlotAddress(inputPort); return sensorSlotOfAgent->get_historyModule(); } bool SensorHandlerOfAgent :: attach_confidenceModule(Channel* inputPort, ConfidenceModule* confidenceModule) { SensorSlotOfAgent* sensorSlotOfAgent = get_sensorSlotAddress(inputPort); if(sensorSlotOfAgent != NULL) { return sensorSlotOfAgent->set_confidenceModule(confidenceModule); } return false; } bool SensorHandlerOfAgent :: detach_confidenceModule(SensorSlotOfAgent* sensorSlotOfAgent) { if(sensorSlotOfAgent != NULL) { return sensorSlotOfAgent->del_confidenceModule(); } return false; } bool SensorHandlerOfAgent :: detach_confidenceModule(Channel* inputPort) { SensorSlotOfAgent* sensorSlotOfAgent = get_sensorSlotAddress(inputPort); return detach_confidenceModule(sensorSlotOfAgent); } bool SensorHandlerOfAgent :: detach_confidenceModule(ConfidenceModule* confidenceModule) { SensorSlotOfAgent* sensorSlotOfAgent = get_sensorSlotAddress(confidenceModule); return detach_confidenceModule(sensorSlotOfAgent); } ConfidenceModule* SensorHandlerOfAgent :: get_confidenceModuleOfSensorSlot(Channel* inputPort) { SensorSlotOfAgent* sensorSlotOfAgent = get_sensorSlotAddress(inputPort); return sensorSlotOfAgent->get_confidenceModule(); } vector* SensorHandlerOfAgent :: get_vMountedSensors() { return &vMountedSensors; } void SensorHandlerOfAgent :: delete_all_Mounted_Sensors() { SensorSlotOfAgent* cur_Sensor_Slot_Agent; unsigned int index_cur_Sen_Slo_Ag; unsigned int size_vec_Mount_Sensors = vMountedSensors.size(); for(index_cur_Sen_Slo_Ag = 0; index_cur_Sen_Slo_Ag < size_vec_Mount_Sensors; index_cur_Sen_Slo_Ag++){ cur_Sensor_Slot_Agent = vMountedSensors[index_cur_Sen_Slo_Ag]; delete cur_Sensor_Slot_Agent; } vMountedSensors.clear(); } SensorHandlerOfAgent :: ~SensorHandlerOfAgent() { delete_all_Mounted_Sensors(); } diff --git a/Version_Max_07_05_2018_CMake/src/SlaveAgentHandlerOfAgent.cpp b/Version_Max_07_05_2018_CMake/src/SlaveAgentHandlerOfAgent.cpp index 800fdf1..3a805a3 100755 --- a/Version_Max_07_05_2018_CMake/src/SlaveAgentHandlerOfAgent.cpp +++ b/Version_Max_07_05_2018_CMake/src/SlaveAgentHandlerOfAgent.cpp @@ -1,231 +1,231 @@ #include "SlaveAgentHandlerOfAgent.h" #include "instruction_set_architecture.h" #include #include "printError.h" #include #define MAXNUMOF_MOUNTEDSENSORS 100 #define PRINT using namespace std; SlaveAgentHandlerOfAgent :: SlaveAgentHandlerOfAgent() { initSlaveAgentHandler(); } void SlaveAgentHandlerOfAgent :: initSlaveAgentHandler() { maxNumOfMountedSlaveAgents = MAXNUMOF_MOUNTEDSENSORS; } bool SlaveAgentHandlerOfAgent :: mount_slaveAgentIntoSlaveAgentSlot(Channel* inputPort) { SlaveAgentSlotOfAgent* slaveAgentSlotOfAgent = new SlaveAgentSlotOfAgent(); if(slaveAgentSlotOfAgent != NULL) { if(slaveAgentSlotOfAgent->set_comPort(inputPort)) { if(vMountedSlaveAgents.size() < maxNumOfMountedSlaveAgents) { try { vMountedSlaveAgents.push_back(slaveAgentSlotOfAgent); } catch(bad_alloc& error) { printError("bad_alloc caught: ", error.what()); delete slaveAgentSlotOfAgent; return false; } } else { printError("Max number of mounted slaveAgents is already reached!"); delete slaveAgentSlotOfAgent; return false; } return true; } else { printError("Input port is no set!"); vMountedSlaveAgents.pop_back(); //TODO: check if it is right?!?! delete slaveAgentSlotOfAgent; return false; } } else { printError("Couldn't create SlaveAgentSlot!"); return false; } } //TODO: what to do when 2 slaveAgentSlots have the same inputPort??!! SlaveAgentSlotOfAgent* SlaveAgentHandlerOfAgent :: get_slaveAgentSlotAddress(Channel* inputPort) { for(auto &slaveAgentSlot : vMountedSlaveAgents) { if(slaveAgentSlot->get_comPort() == inputPort) { return slaveAgentSlot; } } return NULL; } //TODO: what to do when 2 slaveAgentSlots have the same inputPort??!! //TODO: case if slot with comPort is not in this vector unsigned int SlaveAgentHandlerOfAgent :: get_slaveAgentSlotNumber(Channel* inputPort) { unsigned int slotNumber = 0; for(auto &slaveAgentSlot : vMountedSlaveAgents) { if(slaveAgentSlot->get_comPort() == inputPort) { return slotNumber; } slotNumber++; } - return NULL; + return std::numeric_limits::quiet_NaN(); } //TODO: what to do when 2 slaveAgentSlots have the same historyModule??!! SlaveAgentSlotOfAgent* SlaveAgentHandlerOfAgent :: get_slaveAgentSlotAddress(HistoryModule* historyModule) { for(auto &slaveAgentSlot : vMountedSlaveAgents) { if(slaveAgentSlot->get_historyModule() == historyModule) { return slaveAgentSlot; } } return NULL; } //TODO: what to do when 2 slaveAgentSlots have the same confidenceModule??!! SlaveAgentSlotOfAgent* SlaveAgentHandlerOfAgent :: get_slaveAgentSlotAddress(ConfidenceModule* confidenceModule) { for(auto &slaveAgentSlot : vMountedSlaveAgents) { if(slaveAgentSlot->get_confidenceModule() == confidenceModule) { return slaveAgentSlot; } } return NULL; } bool SlaveAgentHandlerOfAgent :: demount_slaveAgentIntoSlaveAgentSlot(Channel* inputPort) { vMountedSlaveAgents.erase(vMountedSlaveAgents.begin() + get_slaveAgentSlotNumber(inputPort)); return false; } //TODO: do it also for integer variables bool SlaveAgentHandlerOfAgent :: read_slaveAgentValue(SlaveAgentSlotOfAgent* slaveAgentSlotOfAgent) { if(slaveAgentSlotOfAgent != NULL) { Channel* channel = slaveAgentSlotOfAgent->get_comPort(); if(channel != NULL) { int msg; if(channel->get_MsgUp(&msg)) { if(msg == ISA_SensoryData) { //printf("got msg: \n"); float inputValue; if(channel->get_MsgUp(&inputValue)) { slaveAgentSlotOfAgent->setSlaveAgentValue(inputValue); //printf("got value: %f\n", inputValue); return true; } } } } } return false; } bool SlaveAgentHandlerOfAgent :: read_allSlaveAgentValues() { bool flag_readSlaveAgent = true; for(auto &slaveAgentSlot : vMountedSlaveAgents) { if(!read_slaveAgentValue(slaveAgentSlot)) { flag_readSlaveAgent = false; } } #ifdef PRINT printf("\n"); #endif // PRINT return flag_readSlaveAgent; } bool SlaveAgentHandlerOfAgent :: attach_historyModule(Channel* inputPort, HistoryModule* historyModule) { SlaveAgentSlotOfAgent* slaveAgentSlotOfAgent = get_slaveAgentSlotAddress(inputPort); if(slaveAgentSlotOfAgent != NULL) { return slaveAgentSlotOfAgent->set_historyModule(historyModule); } return false; } bool SlaveAgentHandlerOfAgent :: detach_historyModule(SlaveAgentSlotOfAgent* slaveAgentSlotOfAgent) { if(slaveAgentSlotOfAgent != NULL) { return slaveAgentSlotOfAgent->del_historyModule(); } return false; } bool SlaveAgentHandlerOfAgent :: detach_historyModule(Channel* inputPort) { SlaveAgentSlotOfAgent* slaveAgentSlotOfAgent = get_slaveAgentSlotAddress(inputPort); return detach_historyModule(slaveAgentSlotOfAgent); } bool SlaveAgentHandlerOfAgent :: detach_historyModule(HistoryModule* historyModule) { SlaveAgentSlotOfAgent* slaveAgentSlotOfAgent = get_slaveAgentSlotAddress(historyModule); return detach_historyModule(slaveAgentSlotOfAgent); } HistoryModule* SlaveAgentHandlerOfAgent :: get_historyModuleOfSlaveAgentSlot(Channel* inputPort) { SlaveAgentSlotOfAgent* slaveAgentSlotOfAgent = get_slaveAgentSlotAddress(inputPort); return slaveAgentSlotOfAgent->get_historyModule(); } bool SlaveAgentHandlerOfAgent :: attach_confidenceModule(Channel* inputPort, ConfidenceModule* confidenceModule) { SlaveAgentSlotOfAgent* slaveAgentSlotOfAgent = get_slaveAgentSlotAddress(inputPort); if(slaveAgentSlotOfAgent != NULL) { return slaveAgentSlotOfAgent->set_confidenceModule(confidenceModule); } return false; } bool SlaveAgentHandlerOfAgent :: detach_confidenceModule(SlaveAgentSlotOfAgent* slaveAgentSlotOfAgent) { if(slaveAgentSlotOfAgent != NULL) { return slaveAgentSlotOfAgent->del_confidenceModule(); } return false; } bool SlaveAgentHandlerOfAgent :: detach_confidenceModule(Channel* inputPort) { SlaveAgentSlotOfAgent* slaveAgentSlotOfAgent = get_slaveAgentSlotAddress(inputPort); return detach_confidenceModule(slaveAgentSlotOfAgent); } bool SlaveAgentHandlerOfAgent :: detach_confidenceModule(ConfidenceModule* confidenceModule) { SlaveAgentSlotOfAgent* slaveAgentSlotOfAgent = get_slaveAgentSlotAddress(confidenceModule); return detach_confidenceModule(slaveAgentSlotOfAgent); } ConfidenceModule* SlaveAgentHandlerOfAgent :: get_confidenceModuleOfSlaveAgentSlot(Channel* inputPort) { SlaveAgentSlotOfAgent* slaveAgentSlotOfAgent = get_slaveAgentSlotAddress(inputPort); return slaveAgentSlotOfAgent->get_confidenceModule(); } vector* SlaveAgentHandlerOfAgent :: get_vMountedSlaveAgents() { return &vMountedSlaveAgents; } bool SlaveAgentHandlerOfAgent::saveValueInHistory(SlaveAgentSlotOfAgent* slaveAgentSlotOfAgent) { if (slaveAgentSlotOfAgent != NULL) { //TODO: change this hardcoded value //Zeitfenster Sliding Window!!!! while (slaveAgentSlotOfAgent->getHistoryLength() >= 10) { slaveAgentSlotOfAgent->deleteOldestHistoryEntry(); } //JUST FOR TESTING //slaveAgentSlotOfAgent->printHistory(); return slaveAgentSlotOfAgent->saveValueInHistory(); } return false; } bool SlaveAgentHandlerOfAgent::saveAllValuesInHistory() { bool flagSavingSuccesful = true; for (auto &slaveAgentSlot : vMountedSlaveAgents) { if (!saveValueInHistory(slaveAgentSlot)) { flagSavingSuccesful = false; } } return flagSavingSuccesful; } diff --git a/Version_Max_07_05_2018_CMake/src/StateHandler.cpp b/Version_Max_07_05_2018_CMake/src/StateHandler.cpp index 89a4c7e..503d426 100755 --- a/Version_Max_07_05_2018_CMake/src/StateHandler.cpp +++ b/Version_Max_07_05_2018_CMake/src/StateHandler.cpp @@ -1,1848 +1,1851 @@ #include "StateHandler.h" #include "config.h" #include #include "printError.h" #include "rlutil.h" #include "relationChecker.h" #include "minmaxzeug.h" #include "file_util.h" #include #include //CHANGE ALSO BOTH FUZZY FUNCTION!!! // is used for the history length of the number of values which will be compared //to the current value #define MAX_STATE_HISTORY_LENGTH 10 //10 #define STOP_WHEN_BROKEN #define STOP_AFTER_BROKEN #define STOP_WHEN_DRIFT #define STOP_WHEN_STATE_VALID #define PRINT //TODO: also change also hardcoded value in "SlaveAgentHandlerOfAgent.cpp" #define SLIDINGWINDOWSIZE 3 //3 //10 #define STABLENUMBER 2 //2 //8 #define STABLETHRESHOLD (float)0.04 //0.4 //0.03 #define RELATEDTHRESHOLD (float)0.08 //0.08 #define INJECTIONPARTITIONING 5 #define CMPDISTANCE 3 #define THDRIFT (float)0.08 //0.8 #define MINNUMTOBEVALIDSTATE 11 //11 //8 //10 //three different status are for the system possible #define STATUS_BROKEN 1 #define STATUS_DRIFT 2 #define STATUS_OKAY 3 using namespace rlutil; //TODO überladen mit Parameter CSV-Writer Name. :-) Bitte, nur für dich Maxi. void StateHandler::initStateHandler() { csv_writer = NULL; flagVariablesWereStable = false; slidingWindowBufferSize = SLIDINGWINDOWSIZE; minNumOfRelatedValuesToBeStable = STABLENUMBER; thresholdToBeStable = STABLETHRESHOLD; thresholdToBeRelated = RELATEDTHRESHOLD; discreteAveragePartitionSize = INJECTIONPARTITIONING; compareDistanceDiscreteAveragePartition = CMPDISTANCE; thresholdNotDrift = THDRIFT; minNumToBeValidState = MINNUMTOBEVALIDSTATE; activeState = NULL; maxStateHistoryLength = MAX_STATE_HISTORY_LENGTH; time_t rawtime; - struct tm timeinfo; + //char output_file_name[200]; char datetime[80]; const std::string output_directory_name = "../data/out/"; // "./output_data_csv/Opel/2018-08-09/"; there is no impact if we change it! std::string output_file_name_str; time(&rawtime); //timeinfo = localtime(&rawtime); +#ifdef _WIN32 localtime_s(&timeinfo, &rawtime); - +#else + localtime_r(&rawtime, & timeinfo); +#endif strftime(datetime, sizeof(datetime), "%Y-%m-%d_%I-%M-%S", &timeinfo); #ifndef INPUT_FILE_NAME output_file_name_str = output_directory_name + "output" + datetime + ".csv"; #else output_file_name_str = output_directory_name + INPUT_FILE_NAME + datetime + ".csv"; #endif //INPUT_FILE_NAME cout << output_file_name_str << endl; //XXX - only for now: //Ali printf("\n csv_Writer is not NULL, but it is not initialized!! \n"); /* if (csv_writer == NULL) { csv_writer = new CSV_Writer("CSV Writer", (char*)output_file_name_str.c_str()); } */ //DATE18 confidenceStableInput = 0; confidenceStableOutput = 0; confidenceStable = 0; confStableAdjustableThreshold = 0.5; confidenceUnstableInput = 0; confidenceUnstableOutput = 0; confidenceUnstable = 0; confidenceUnstableAdjustableThreshold = 0.5; confidenceSameStateInput = 0; confSameStateInputAdjustableThreshold = 0.5; confidenceSameStateOutput = 0; confSameStateOutputAdjustableThreshold = 0.5; confidenceValidState = 0; confValidStateAdjustableThreshold = 0.5; brokenCounter = 0; confidenceBroken = 0; confidenceBrokenAdjustableThreshold = 0.5; driftCounter = 0; confidenceDrift = 0; confidenceDriftAdjustableThreshold = 0.5; } StateHandler::StateHandler() { set_name(NO_NAME); initStateHandler(); } StateHandler::StateHandler(std::string name) { set_name(name); initStateHandler(); } StateHandler::StateHandler(std::string name, std::string csvWriterPath) { set_name(name); initStateHandler(); csv_writer = new CSV_Writer("CSV Writer", csvWriterPath); } bool StateHandler::setDiscreteAveragePartitionSize(unsigned int discreteAveragePartitionSize) { if (discreteAveragePartitionSize > 0) { this->discreteAveragePartitionSize = discreteAveragePartitionSize; return true; } return false; } unsigned int StateHandler::getDiscreteAveragePartitionSize() { return discreteAveragePartitionSize; } bool StateHandler::addVariable(vector* vVariables, SlaveAgentSlotOfAgent* slot) { if (vVariables != NULL && slot != NULL) { if (find((*vVariables).begin(), (*vVariables).end(), slot) == (*vVariables).end()) { try { (*vVariables).push_back(slot); return true; } catch (bad_alloc& error) { printError("bad_alloc caught: ", error.what()); } } } return false; } bool StateHandler::addInputVariable(SlaveAgentSlotOfAgent* slot) { return addVariable(&vInputVariables, slot); } bool StateHandler::addOutputVariable(SlaveAgentSlotOfAgent* slot) { return addVariable(&vOutputVariables, slot); } bool StateHandler::delete_all_OuputVariables() { SlaveAgentSlotOfAgent* cur_sl_ag_sl_ag; unsigned int index_v_OutVar; unsigned int size_v_OutVar = vOutputVariables.size(); for(index_v_OutVar = 0; index_v_OutVar < size_v_OutVar; index_v_OutVar++) { cur_sl_ag_sl_ag = vOutputVariables[index_v_OutVar]; delete cur_sl_ag_sl_ag; } vOutputVariables.clear(); return true; //added by Ali, it is an error in VS. } bool StateHandler::delete_all_InputVariables() { SlaveAgentSlotOfAgent* cur_sl_ag_sl_ag; unsigned int index_v_InpVar; unsigned int size_v_InpVar = vInputVariables.size(); for(index_v_InpVar = 0; index_v_InpVar < size_v_InpVar; index_v_InpVar++) { cur_sl_ag_sl_ag = vInputVariables[index_v_InpVar]; delete cur_sl_ag_sl_ag; } vInputVariables.clear(); return true; //added by Ali, it is an error in VS. } bool StateHandler::delete_allStates() { State* cur_state; unsigned int index_v_State; unsigned int size_v_State = vStates.size(); for(index_v_State = 0; index_v_State < size_v_State; index_v_State++) { cur_state = vStates[index_v_State]; delete cur_state; } vStates.clear(); return true; //added by Ali, it is an error in VS. } bool StateHandler::setSlidingWindowBufferSize(unsigned int slidingWindowBufferSize) { if (slidingWindowBufferSize >= minNumOfRelatedValuesToBeStable) { this->slidingWindowBufferSize = slidingWindowBufferSize; return true; } return false; } bool StateHandler::setMinNumOfRelatedValuesToBeStable(unsigned int minNumOfRelatedValuesToBeStable) { if (minNumOfRelatedValuesToBeStable <= slidingWindowBufferSize) { this->minNumOfRelatedValuesToBeStable = minNumOfRelatedValuesToBeStable; return true; } return false; } bool StateHandler::setThresholdToBeStable(float thresholdToBeStable) { if (thresholdToBeStable >= 0 && thresholdToBeStable <= 1) { this->thresholdToBeStable = thresholdToBeStable; return true; } return false; } bool StateHandler::setThresholdToBeRelated(float thresholdToBeRelated) { if (thresholdToBeRelated >= 0 && thresholdToBeRelated <= 1) { this->thresholdToBeRelated = thresholdToBeRelated; return true; } return false; } bool StateHandler::variablesAreStable(vector* vVariables) { bool flagAllVariablesAreStable = true; for (auto &slot : *vVariables) { if (slot->getHistoryLength() >= slidingWindowBufferSize - 1) { //-1 because actual value is not in the history if (slot->getNumberOfRelativesToActualValue(thresholdToBeStable) < minNumOfRelatedValuesToBeStable) { //-1 because actual value is also on of minNumOfRelatedValuesToBeStable flagAllVariablesAreStable = false; } } else { return false; } } return flagAllVariablesAreStable; } //Sorting with bigger Value in Front struct descending { template bool operator()(T const &a, T const &b) const { return a > b; } }; //DATE18 float StateHandler::getConfVariableIsStable(SlaveAgentSlotOfAgent* variable) { float bestConfOf1Var = 0; float sample; if (variable->get_slaveAgentValue(&sample)) { list lHistoryTemporary = variable->getHistory(); vector vDeviations; for (auto &h : lHistoryTemporary) vDeviations.push_back(deviationValueReferenceValue(sample, h)); std::sort(std::begin(vDeviations), std::end(vDeviations)); //all adaptabilities within the history of one variable for (unsigned int numOfHistSamplesIncluded = 1; numOfHistSamplesIncluded <= vDeviations.size(); numOfHistSamplesIncluded++) { float worstConfOfHistSampleSet = 1; unsigned int histSampleCounter = 0; for (auto &deviation : vDeviations) { if (histSampleCounter >= numOfHistSamplesIncluded) break; worstConfOfHistSampleSet = minValueOf2Values(worstConfOfHistSampleSet, StabDeviation->getY(deviation)); histSampleCounter++; } bestConfOf1Var = maxValueOf2Values(bestConfOf1Var, minValueOf2Values(worstConfOfHistSampleSet, StabSamples->getY((float)histSampleCounter))); } } return bestConfOf1Var; } //DATE18 float StateHandler::getConfVariablesAreStable(vector* vVariables) { float worstConfOfAllVariables = 1; for (auto &slot : *vVariables) worstConfOfAllVariables = minValueOf2Values(worstConfOfAllVariables, getConfVariableIsStable(slot)); return worstConfOfAllVariables; } //DATE18 float StateHandler::getConfVariableIsUnstable(SlaveAgentSlotOfAgent* variable) { float bestConfOf1Var = 0; float sample; if (variable->get_slaveAgentValue(&sample)) { list lHistoryTemporary = variable->getHistory(); vector vDeviations; for (auto &h : lHistoryTemporary) vDeviations.push_back(deviationValueReferenceValue(sample, h)); sort(begin(vDeviations), end(vDeviations), descending()); //all adaptabilities within the history of one variable for (unsigned int numOfHistSamplesIncluded = 1; numOfHistSamplesIncluded <= vDeviations.size(); numOfHistSamplesIncluded++) { //float bestConfOfHistSampleSet = 1; float bestConfOfHistSampleSet = 0; unsigned int histSampleCounter = 0; for (auto &deviation : vDeviations) { if (histSampleCounter >= numOfHistSamplesIncluded) break; //bestConfOfHistSampleSet = minValueOf2Values(bestConfOfHistSampleSet, UnstabDeviation->getY(deviation)); bestConfOfHistSampleSet = maxValueOf2Values(bestConfOfHistSampleSet, UnstabDeviation->getY(deviation)); histSampleCounter++; } bestConfOf1Var = maxValueOf2Values(bestConfOf1Var, minValueOf2Values(bestConfOfHistSampleSet, StabSamples->getY((float)histSampleCounter))); } } return bestConfOf1Var; } //DATE18 - Is there one unstable variable? float StateHandler::getConfVariablesAreUnstable(vector* vVariables) { float bestConfOfAllVariables = 0; for (auto &slot : *vVariables) bestConfOfAllVariables = maxValueOf2Values(bestConfOfAllVariables, getConfVariableIsUnstable(slot)); return bestConfOfAllVariables; } /* bool StateHandler::getConfAndUnconfVariableIsMatching(State* state, LinearFunctionBlock* confDeviation, LinearFunctionBlock* confTime, float* conf, float* unconf) { float bestUnconfOf1Var = 0; float worstConfOf1Var = 1; if (state != NULL) { } float sample; if (variable->get_slaveAgentValue(&sample)) { list lHistoryTemporary = variable->getHistory(); vector vDeviations; for (auto &h : lHistoryTemporary) vDeviations.push_back(deviationValueReferenceValue(sample, h)); sort(begin(vDeviations), end(vDeviations), descending()); //all adaptabilities within the history of one variable for (unsigned int numOfHistSamplesIncluded = 1; numOfHistSamplesIncluded <= vDeviations.size(); numOfHistSamplesIncluded++) { //float bestConfOfHistSampleSet = 1; float bestConfOfHistSampleSet = 0; unsigned int histSampleCounter = 0; for (auto &deviation : vDeviations) { if (histSampleCounter >= numOfHistSamplesIncluded) break; //bestConfOfHistSampleSet = minValueOf2Values(bestConfOfHistSampleSet, UnstabDeviation->getY(deviation)); bestConfOfHistSampleSet = maxValueOf2Values(bestConfOfHistSampleSet, UnstabDeviation->getY(deviation)); histSampleCounter++; } bestConfOf1Var = maxValueOf2Values(bestConfOf1Var, minValueOf2Values(bestConfOfHistSampleSet, StabSamples->getY((float)histSampleCounter))); } } return bestConfOf1Var; return 0; } */ /* bool StateHandler::getConfAndUnconfVariablesAreMatching(vector* vVariables, LinearFunctionBlock* confDeviation, LinearFunctionBlock* confTime, float* conf, float* unconf) { float bestUnconfOfAllVariables = 0; float worstConfOfAllVariables = 1; for (auto &variable :* vVariables) { bestUnconfOfAllVariables = maxValueOf2Values(bestUnconfOfAllVariables, getConfAndUnconfVariableIsMatching(variable, confDeviation, confTime, conf, unconf)); worstConfOfAllVariables = minValueOf2Values(worstConfOfAllVariables, getConfAndUnconfVariableIsMatching(variable, confDeviation, confTime, conf, unconf)); } *conf = worstConfOfAllVariables; *unconf = bestUnconfOfAllVariables; return true; } */ State* StateHandler::makeNewState() { State* state = new (nothrow) State(); if (state != NULL) { bool flagLoadVariablesWorked = true; for (auto &slot : vInputVariables) { if (!state->addInputSubState(slot)) flagLoadVariablesWorked = false; } for (auto &slot : vOutputVariables) { if (!state->addOutputSubState(slot)) flagLoadVariablesWorked = false; } if (!flagLoadVariablesWorked) { delete state; return NULL; } } else { return NULL; } return state; } bool StateHandler::addActiveStateToStateVector() { #ifdef PRINT printf(" >> Save Active State\n"); #endif //PRINT if (activeState != NULL) { for (auto &state : vStates) { if (state == activeState) return true; } #ifdef STOP_WHEN_STATE_VALID getchar(); #endif // STOP_WHEN_STATE_VALID try { vStates.push_back(activeState); return true; } catch (bad_alloc& error) { printError("bad_alloc caught: ", error.what()); delete activeState; } } return false; } /* bool StateHandler::addStateAndMakeItActive() { State* state = addState(); if (state != NULL) { activeState = state; return true; } return false; } */ bool StateHandler::makeNewActiveState() { State* state = makeNewState(); if (state != NULL) { activeState = state; return true; } return false; } State* StateHandler::findRelatedState() { for (auto &state : vStates) { if (state->inputVariablesAreRelated(thresholdToBeRelated) && state->outputVariablesAreRelated(thresholdToBeRelated)) { return state; } } return NULL; } bool StateHandler::findRelatedStateAndMakeItActive() { State* state = findRelatedState(); if (state != NULL) { activeState = state; return true; } return false; } void StateHandler::eraseStatesWithLessInjections() { if (activeState != NULL) { if (activeState->getNumOfInjections() < minNumToBeValidState) { activeState = NULL; } } for (vector::iterator state = vStates.begin(); state < vStates.end(); state++) { if ((*state)->getNumOfInjections() < minNumToBeValidState) { //TODO: also delete all subStates (etc.) of the State? Because: Memory Leakage. vStates.erase(state); state--; } } /* for (auto &state : vStates) { //TODO: also delete all subStates (etc.) of the State? Because: Memory Leakage. if (state->getNumOfInjections() < minNumToBeValidState) { vStates.erase(state); } } */ } void StateHandler :: reset_States() { this->delete_allStates(); this->activeState = NULL; } void StateHandler :: reset_States_and_Slave_Agents() { reset_States(); this->delete_all_InputVariables(); this->delete_all_OuputVariables(); } void StateHandler ::setMaxStateHistoryLength( unsigned int maxStateHistoryLength) { this->maxStateHistoryLength = maxStateHistoryLength; } StateHandler :: ~StateHandler() { delete_all_OuputVariables(); delete_all_InputVariables(); delete_allStates(); //delete csv_writer; } //XXX - only for now bool test = true; unsigned int brokenCounter = 0, driftCounter = 0; void printDrift() { driftCounter++; setColor(TXTCOLOR_YELLOW); printf(" >> DRIFT\n"); setColor(TXTCOLOR_GREY); test = true; } void printBroken() { brokenCounter++; setColor(TXTCOLOR_LIGHTRED); printf(" >> BROKEN\n"); setColor(TXTCOLOR_GREY); test = true; } //XXX - only for now unsigned int old_cycle = 1; int brokentest = 0; /* * makes a new state and reports if there is a anomaly = hearth piece of CAM :-) */ void StateHandler::trigger(unsigned int cycle) { #ifdef PRINT printf("cycle: %u\n", cycle); #endif // PRINT bool flagGotValues = true; #ifdef PRINT printf("Input Sample Values:\n"); #endif // PRINT for (auto &slot : vInputVariables) { float sampleValue; if (!(slot->get_slaveAgentValue(&sampleValue))) flagGotValues = false; //program never executes this line of code #ifdef PRINT printf("In, %s: %f\n", slot->get_comPort()->get_name().c_str(), sampleValue); #endif // PRINT if (cycle == 1) csv_writer->write_field(slot->get_comPort()->get_name().c_str()); else csv_writer->write_field(sampleValue); csv_writer->make_new_field(); } #ifdef PRINT printf("Output Sample Values:\n"); #endif // PRINT for (auto &slot : vOutputVariables) { float sampleValue; if (!(slot->get_slaveAgentValue(&sampleValue))) flagGotValues = false; //program never executes this line of code #ifdef PRINT printf("Out, %s: %f\n", slot->get_comPort()->get_name().c_str(), sampleValue); #endif // PRINT if (cycle == 1) csv_writer->write_field(slot->get_comPort()->get_name().c_str()); else csv_writer->write_field(sampleValue); csv_writer->make_new_field(); } if (cycle == 1){ csv_writer->write_field("State Nr"); csv_writer->make_new_field(); csv_writer->write_field("Conf State Valid"); csv_writer->make_new_field(); csv_writer->write_field("Conf State Invalid"); csv_writer->make_new_field(); csv_writer->write_field("Conf Input unchanged"); csv_writer->make_new_field(); csv_writer->write_field("Conf Input changed"); csv_writer->make_new_field(); csv_writer->write_field("Conf Output unchanged"); csv_writer->make_new_field(); csv_writer->write_field("Conf Output changed"); csv_writer->make_new_field(); csv_writer->write_field("Status"); csv_writer->make_new_field(); csv_writer->write_field("Conf Status"); csv_writer->make_new_field(); } else { //in the beginning, a active state has to be created if (activeState == NULL && vStates.empty()) { brokenCounter = 0; #ifdef PRINT printf(" > new active state\n"); #endif // PRINT makeNewActiveState(); if (activeState->insertValueInState(FuncBlockConfValStateDev, FuncBlockConfInvStateDev, FuncBlockConfValStateTime, FuncBlockConfInvStateTime, maxStateHistoryLength, discreteAveragePartitionSize)) addActiveStateToStateVector(); //NEW - Adjust FuncBlockConfSim2StateTime and FuncBlockConfDif2StateTime float newBoundary = (float)activeState->getLengthOfHistory(); FuncBlockConfSim2StateTime->changeFunctionBlockIncr(newBoundary); FuncBlockConfDif2StateTime->changeFunctionBlockDecr(newBoundary); csv_writer->write_field((int)vStates.size() + 1); csv_writer->make_new_field(); csv_writer->write_field(activeState->getConfStateValid()); csv_writer->make_new_field(); csv_writer->write_field(activeState->getConfStateInvalid()); csv_writer->make_new_field(); csv_writer->write_field(0); //confInputVarAreSim2ActiveState csv_writer->make_new_field(); csv_writer->write_field(0); //confInputVarAreDif2ActiveState csv_writer->make_new_field(); csv_writer->write_field(0); //confOutputVarAreSim2ActiveState csv_writer->make_new_field(); csv_writer->write_field(0); //confOutputVarAreDif2ActiveState csv_writer->make_new_field(); csv_writer->write_field(STATUS_OKAY); csv_writer->make_new_field(); csv_writer->write_field(0); //Status Conf csv_writer->make_new_field(); } //there is an active state and/or other states else { float confInputVarAreSim2ActiveState = activeState->getConfInputVarAreSim2State(FuncBlockConfSim2StateDev, FuncBlockConfSim2StateTime); float confInputVarAreDif2ActiveState = activeState->getConfInputVarAreDif2State(FuncBlockConfDif2StateDev, FuncBlockConfDif2StateTime); float confOutputVarAreSim2ActiveState = activeState->getConfOutputVarAreSim2State(FuncBlockConfSim2StateDev, FuncBlockConfSim2StateTime); float confOutputVarAreDif2ActiveState = activeState->getConfOutputVarAreDif2State(FuncBlockConfDif2StateDev, FuncBlockConfDif2StateTime); //float confInputIsSteady = confInputVarAreSim2ActiveState - confInputVarAreDif2ActiveState; //float confOutputIsSteady = confOutputVarAreSim2ActiveState - confOutputVarAreDif2ActiveState; printf("input (sim/dif) %f/%f\noutput (sim/dif) %f/%f\n", confInputVarAreSim2ActiveState, confInputVarAreDif2ActiveState, confOutputVarAreSim2ActiveState, confOutputVarAreDif2ActiveState); //same state if ((confInputVarAreSim2ActiveState > confInputVarAreDif2ActiveState) && (confOutputVarAreSim2ActiveState > confOutputVarAreDif2ActiveState)) { brokenCounter = 0; #ifdef PRINT printf(" > same state\n"); //printf("\nPROOF:\nconfInputVarAreSim2ActiveState = %f\nconfInputVarAreDif2ActiveState = %f\nconfOutputVarAreSim2ActiveState = %f\nconfOutputVarAreDif2ActiveState = %f\n", confInputVarAreSim2ActiveState, confInputVarAreDif2ActiveState, confOutputVarAreSim2ActiveState, confOutputVarAreDif2ActiveState); #endif // PRINT if (activeState->insertValueInState(FuncBlockConfValStateDev, FuncBlockConfInvStateDev, FuncBlockConfValStateTime, FuncBlockConfInvStateTime, maxStateHistoryLength, discreteAveragePartitionSize)) addActiveStateToStateVector(); //NEW - Adjust FuncBlockConfSim2StateTime and FuncBlockConfDif2StateTime float newBoundary = (float)activeState->getLengthOfHistory(); FuncBlockConfSim2StateTime->changeFunctionBlockIncr(newBoundary); FuncBlockConfDif2StateTime->changeFunctionBlockDecr(newBoundary); //print state number if(activeState->isStateValid()) csv_writer->write_field((int)vStates.size()); else csv_writer->write_field((int)vStates.size()+1); csv_writer->make_new_field(); //print conf valid csv_writer->write_field(activeState->getConfStateValid()); csv_writer->make_new_field(); csv_writer->write_field(activeState->getConfStateInvalid()); csv_writer->make_new_field(); //print conf statechange csv_writer->write_field(confInputVarAreSim2ActiveState); csv_writer->make_new_field(); csv_writer->write_field(confInputVarAreDif2ActiveState); csv_writer->make_new_field(); csv_writer->write_field(confOutputVarAreSim2ActiveState); csv_writer->make_new_field(); csv_writer->write_field(confOutputVarAreDif2ActiveState); csv_writer->make_new_field(); confidenceDrift = activeState->checkAllVariablesForDriftingFuzzy(discreteAveragePartitionSize, DriftDeviation); float confidenceNoDrift = 1 - confidenceDrift; /* //print conf drift csv_writer->write_field(confidenceNoDrift); csv_writer->make_new_field(); csv_writer->write_field(confidenceDrift); csv_writer->make_new_field(); */ if (confidenceDrift > 0.5) { #ifdef PRINT setColor(TXTCOLOR_YELLOW); printf("DRIFT\n"); setColor(TXTCOLOR_GREY); #endif // PRINT #ifdef STOP_WHEN_DRIFT getchar(); #endif // STOP_WHEN_DRIFT setColor(TXTCOLOR_GREY); //print drift csv_writer->write_field(STATUS_DRIFT); csv_writer->make_new_field(); //calc and print conf float conf = fuzzyAND(fuzzyAND(confidenceDrift, activeState->getConfStateValid()), fuzzyAND(confInputVarAreSim2ActiveState, confOutputVarAreSim2ActiveState)); csv_writer->write_field(conf); } else { #ifdef PRINT setColor(TXTCOLOR_LIGHTGREEN); printf("OK\n"); setColor(TXTCOLOR_GREY); #endif // PRINT //print ok csv_writer->write_field(STATUS_OKAY); csv_writer->make_new_field(); //calc and print conf float conf = fuzzyAND(fuzzyAND(confInputVarAreSim2ActiveState, confOutputVarAreSim2ActiveState), fuzzyAND(activeState->getConfStateValid(), confidenceNoDrift)); csv_writer->write_field(conf); } csv_writer->make_new_field(); } //state change else { //was Valid if (activeState->isStateValid()) { //only one sub set changed if (((confInputVarAreSim2ActiveState > confInputVarAreDif2ActiveState) && (confOutputVarAreSim2ActiveState <= confOutputVarAreDif2ActiveState)) || ((confInputVarAreSim2ActiveState <= confInputVarAreDif2ActiveState) && (confOutputVarAreSim2ActiveState > confOutputVarAreDif2ActiveState))) { //print state number if (activeState->isStateValid()) csv_writer->write_field((int)vStates.size()); else csv_writer->write_field((int)vStates.size() + 1); csv_writer->make_new_field(); //print conf valid csv_writer->write_field(activeState->getConfStateValid()); csv_writer->make_new_field(); csv_writer->write_field(activeState->getConfStateInvalid()); csv_writer->make_new_field(); //print conf statechange csv_writer->write_field(confInputVarAreSim2ActiveState); csv_writer->make_new_field(); csv_writer->write_field(confInputVarAreDif2ActiveState); csv_writer->make_new_field(); csv_writer->write_field(confOutputVarAreSim2ActiveState); csv_writer->make_new_field(); csv_writer->write_field(confOutputVarAreDif2ActiveState); csv_writer->make_new_field(); brokenCounter++; printf("brokenCounter: %u\n", brokenCounter); confidenceBroken = FuncBlockConfBrokenSamples->getY((float) brokenCounter); float confidenceOK = 1 - confidenceBroken; if (confidenceBroken > 0.5) { #ifdef PRINT setColor(TXTCOLOR_LIGHTRED); printf("BROKEN\n"); setColor(TXTCOLOR_GREY); #endif // PRINT #ifdef STOP_AFTER_BROKEN brokentest = 1; #endif // STOP_AFTER_BROKEN #ifdef STOP_WHEN_BROKEN getchar(); #endif // STOP_WHEN_BROKEN //print broken csv_writer->write_field(STATUS_BROKEN); csv_writer->make_new_field(); //calculate and print conf float conf = fuzzyAND(fuzzyOR(confInputVarAreDif2ActiveState, confOutputVarAreDif2ActiveState), fuzzyAND(confidenceBroken, activeState->getConfStateValid())); csv_writer->write_field(conf); //csv_writer->make_new_field(); } else { //print ok csv_writer->write_field(STATUS_OKAY); csv_writer->make_new_field(); //calculate and print conf float conf = fuzzyAND(fuzzyOR(fuzzyAND(confInputVarAreSim2ActiveState, confOutputVarAreSim2ActiveState), fuzzyAND(confInputVarAreDif2ActiveState, confOutputVarAreDif2ActiveState)), fuzzyAND(confidenceOK, activeState->getConfStateValid())); csv_writer->write_field(conf); } } //In- and output changed else { brokenCounter = 0; printf(" > delete active state\n"); activeState = NULL; printf(" > new active state\n"); // search in vector for matching state //TODO in future: look for the best matching, Not for the first matching bool flagFoundMatchingState = false; float confInputVarAreSim2ActiveState; float confInputVarAreDif2ActiveState; float confOutputVarAreSim2ActiveState; float confOutputVarAreDif2ActiveState; for (auto &state : vStates) { confInputVarAreSim2ActiveState = state->getConfInputVarAreSim2State(FuncBlockConfSim2StateDev, FuncBlockConfSim2StateTime); confInputVarAreDif2ActiveState = state->getConfInputVarAreDif2State(FuncBlockConfDif2StateDev, FuncBlockConfDif2StateTime); confOutputVarAreSim2ActiveState = state->getConfOutputVarAreSim2State(FuncBlockConfSim2StateDev, FuncBlockConfSim2StateTime); confOutputVarAreDif2ActiveState = state->getConfOutputVarAreDif2State(FuncBlockConfDif2StateDev, FuncBlockConfDif2StateTime); if ((confInputVarAreSim2ActiveState > confInputVarAreDif2ActiveState) && (confOutputVarAreSim2ActiveState > confOutputVarAreDif2ActiveState)) { activeState = state; flagFoundMatchingState = true; } } if (flagFoundMatchingState == false) { makeNewActiveState(); confInputVarAreSim2ActiveState = 0; confInputVarAreDif2ActiveState = 0; confOutputVarAreSim2ActiveState = 0; confOutputVarAreDif2ActiveState = 0; } //insert in activeState if (activeState->insertValueInState(FuncBlockConfValStateDev, FuncBlockConfInvStateDev, FuncBlockConfValStateTime, FuncBlockConfInvStateTime, maxStateHistoryLength, discreteAveragePartitionSize)) addActiveStateToStateVector(); //NEW - Adjust FuncBlockConfSim2StateTime and FuncBlockConfDif2StateTime float newBoundary = (float)activeState->getLengthOfHistory(); FuncBlockConfSim2StateTime->changeFunctionBlockIncr(newBoundary); FuncBlockConfDif2StateTime->changeFunctionBlockDecr(newBoundary); //print state number if (activeState->isStateValid()) csv_writer->write_field((int)vStates.size()); else csv_writer->write_field((int)vStates.size() + 1); csv_writer->make_new_field(); //print conf valid csv_writer->write_field(activeState->getConfStateValid()); csv_writer->make_new_field(); csv_writer->write_field(activeState->getConfStateInvalid()); csv_writer->make_new_field(); //print conf statechange csv_writer->write_field(confInputVarAreSim2ActiveState); csv_writer->make_new_field(); csv_writer->write_field(confInputVarAreDif2ActiveState); csv_writer->make_new_field(); csv_writer->write_field(confOutputVarAreSim2ActiveState); csv_writer->make_new_field(); csv_writer->write_field(confOutputVarAreDif2ActiveState); csv_writer->make_new_field(); confidenceDrift = activeState->checkAllVariablesForDriftingFuzzy(discreteAveragePartitionSize, DriftDeviation); float confidenceNoDrift = 1 - confidenceDrift; if (confidenceDrift > 0.5) { setColor(TXTCOLOR_YELLOW); printf("DRIFT\n"); #ifdef STOP_WHEN_DRIFT getchar(); #endif // STOP_WHEN_DRIFT setColor(TXTCOLOR_GREY); //print drift csv_writer->write_field(STATUS_DRIFT); csv_writer->make_new_field(); //calc and print conf float conf = fuzzyAND(confidenceDrift, activeState->getConfStateValid()); csv_writer->write_field(conf); } else { setColor(TXTCOLOR_LIGHTGREEN); printf("OK\n"); setColor(TXTCOLOR_GREY); //print ok csv_writer->write_field(STATUS_OKAY); csv_writer->make_new_field(); //calc and print conf float conf = fuzzyAND(fuzzyAND(confInputVarAreDif2ActiveState, confOutputVarAreDif2ActiveState), fuzzyAND(activeState->getConfStateValid(), confidenceNoDrift)); csv_writer->write_field(conf); } csv_writer->make_new_field(); } } //was NOT Valid else { brokenCounter = 0; printf(" > delete active state\n"); delete activeState; activeState = NULL; printf(" > new active state\n"); // search in vector for matching state //TODO in future: look for the best matching, Not for the first matching bool flagFoundMatchingState = false; float confInputVarAreSim2ActiveState; float confInputVarAreDif2ActiveState; float confOutputVarAreSim2ActiveState; float confOutputVarAreDif2ActiveState; for (auto &state : vStates) { confInputVarAreSim2ActiveState = state->getConfInputVarAreSim2State(FuncBlockConfSim2StateDev, FuncBlockConfSim2StateTime); confInputVarAreDif2ActiveState = state->getConfInputVarAreDif2State(FuncBlockConfDif2StateDev, FuncBlockConfDif2StateTime); confOutputVarAreSim2ActiveState = state->getConfOutputVarAreSim2State(FuncBlockConfSim2StateDev, FuncBlockConfSim2StateTime); confOutputVarAreDif2ActiveState = state->getConfOutputVarAreDif2State(FuncBlockConfDif2StateDev, FuncBlockConfDif2StateTime); if ((confInputVarAreSim2ActiveState > confInputVarAreDif2ActiveState) && (confOutputVarAreSim2ActiveState > confOutputVarAreDif2ActiveState)) { activeState = state; flagFoundMatchingState = true; } } if (flagFoundMatchingState == false) { makeNewActiveState(); confInputVarAreSim2ActiveState = 0; confInputVarAreDif2ActiveState = 0; confOutputVarAreSim2ActiveState = 0; confOutputVarAreDif2ActiveState = 0; } //insert in active state if (activeState->insertValueInState(FuncBlockConfValStateDev, FuncBlockConfInvStateDev, FuncBlockConfValStateTime, FuncBlockConfInvStateTime, maxStateHistoryLength, discreteAveragePartitionSize)) addActiveStateToStateVector(); //NEW - Adjust FuncBlockConfSim2StateTime and FuncBlockConfDif2StateTime float newBoundary = (float)activeState->getLengthOfHistory(); FuncBlockConfSim2StateTime->changeFunctionBlockIncr(newBoundary); FuncBlockConfDif2StateTime->changeFunctionBlockDecr(newBoundary); //print state number if (activeState->isStateValid()) csv_writer->write_field((int)vStates.size()); else csv_writer->write_field((int)vStates.size() + 1); csv_writer->make_new_field(); //print conf valid csv_writer->write_field(activeState->getConfStateValid()); csv_writer->make_new_field(); csv_writer->write_field(activeState->getConfStateInvalid()); csv_writer->make_new_field(); //print conf statechange csv_writer->write_field(confInputVarAreSim2ActiveState); csv_writer->make_new_field(); csv_writer->write_field(confInputVarAreDif2ActiveState); csv_writer->make_new_field(); csv_writer->write_field(confOutputVarAreSim2ActiveState); csv_writer->make_new_field(); csv_writer->write_field(confOutputVarAreDif2ActiveState); csv_writer->make_new_field(); confidenceDrift = activeState->checkAllVariablesForDriftingFuzzy(discreteAveragePartitionSize, DriftDeviation); float confidenceNoDrift = 1 - confidenceDrift; if (confidenceDrift > 0.5) { setColor(TXTCOLOR_YELLOW); printf("DRIFT\n"); #ifdef STOP_WHEN_DRIFT getchar(); #endif // STOP_WHEN_DRIFT setColor(TXTCOLOR_GREY); //print drift csv_writer->write_field(2); csv_writer->make_new_field(); //calc and print conf float conf = fuzzyAND(confidenceDrift, activeState->getConfStateValid()); csv_writer->write_field(conf); } else { setColor(TXTCOLOR_LIGHTGREEN); printf("OK\n"); setColor(TXTCOLOR_GREY); //print ok csv_writer->write_field(STATUS_OKAY); csv_writer->make_new_field(); //calc and print conf float conf = fuzzyAND(fuzzyAND(confInputVarAreDif2ActiveState, confOutputVarAreDif2ActiveState), fuzzyAND(activeState->getConfStateValid(), confidenceNoDrift)); csv_writer->write_field(conf); } csv_writer->make_new_field(); } } #ifdef PRINT printf("STATES: %u\n", vStates.size()); #endif // PRINT } } csv_writer->make_new_line(); if (brokentest) getchar(); /* //XXX - only for now for (unsigned int i = 1; i < (cycle - old_cycle); i++) { csv_writer->make_new_field(); csv_writer->make_new_field(); csv_writer->make_new_field(); csv_writer->make_new_line(); //printf("%u\n", i); } old_cycle = cycle; confidenceStableInput = getConfVariablesAreStable(&vInputVariables); confidenceStableOutput = getConfVariablesAreStable(&vOutputVariables); confidenceStable = minValueOf2Values(confidenceStableInput, confidenceStableOutput); printf("confidence stable: %f\n", confidenceStable); confidenceUnstableInput = getConfVariablesAreUnstable(&vInputVariables); confidenceUnstableOutput = getConfVariablesAreUnstable(&vOutputVariables); printf("unstable In: %f, Out: %f\n", confidenceUnstableInput, confidenceUnstableOutput); confidenceUnstable = maxValueOf2Values(confidenceUnstableInput, confidenceUnstableOutput); printf("confidence unstable: %f\n", confidenceUnstable); if (confidenceUnstableInput > 0) { printf("jetzt\n"); getchar(); } //TEST if (confidenceStable > confidenceUnstable) { setColor(TXTCOLOR_LIGHTBLUE); printf("jetzt\n"); setColor(TXTCOLOR_GREY); getchar(); } //getchar(); if (confidenceStable > confidenceUnstable) { //if (false) { printf(" > stable\n"); //for the beginning (there is no state available/created) -> create state if (activeState == NULL && vStates.empty()) { printf(" > new state\n"); makeNewActiveState(); activeState->injectValues(discreteAveragePartitionSize); confidenceValidState = ValidState->getY((float)activeState->getNumOfInjections()); } //there is an active state else if (activeState != NULL) { //caclulate confidences of deciding for same state float confidenceSameStateInput = activeState->inputVariablesAreRelatedFuzzy(SameState); float confidenceSameStateOutput = activeState->outputVariablesAreRelatedFuzzy(SameState); printf("ConfSameState\nIn: %f\nout: %f\n", confidenceSameStateInput, confidenceSameStateOutput); //In- and Outputs are unchanged if ((confidenceSameStateInput > confSameStateInputAdjustableThreshold) && (confidenceSameStateOutput > confSameStateOutputAdjustableThreshold)) { printf(" > same state\n"); //inject values activeState->injectValues(discreteAveragePartitionSize); //calculate the confidence to have a validState confidenceValidState = ValidState->getY((float)activeState->getNumOfInjections()); //TODO DATE //check for drifting!!! //printDrift(); } //In- and Outputs have changed else if ((confidenceSameStateInput <= confSameStateInputAdjustableThreshold) && (confidenceSameStateOutput <= confSameStateOutputAdjustableThreshold)) { printf(" > change state\n"); getchar(); //active state is/was valid if (confidenceValidState > confValidStateAdjustableThreshold) { printf("speicher\n"); getchar(); addActiveStateToStateVector(); //TODO DATE //search for matching state //or printf(" > new state\n"); //create an new active state makeNewActiveState(); //inject values activeState->injectValues(discreteAveragePartitionSize); //calculate the confidence to have a validState confidenceValidState = ValidState->getY((float)activeState->getNumOfInjections()); //TODO DATE //check for drifting!!! //printDrift(); } } //Only in- or outputs have changed else { //active state is/was valid if (confidenceValidState > confValidStateAdjustableThreshold) { addActiveStateToStateVector(); printf(" > broken\n"); brokenCounter++; confidenceBroken = BrokenCounterSamples->getY(brokenCounter); //getchar(); //TODO DATE?? //Save State } } } //there is no active state, but there is/are state(s) else { printf(" > old or new state\n"); //getchar(); //TODO DATE //search for matching state //or printf(" > new state\n"); makeNewActiveState(); activeState->injectValues(discreteAveragePartitionSize); confidenceValidState = ValidState->getY((float)activeState->getNumOfInjections()); //TODO DATE //check for drifting!!! //printDrift(); } if (activeState != NULL) { confidenceDrift = activeState->checkAllVariablesForDriftingFuzzy(discreteAveragePartitionSize, DriftDeviation); } //getchar(); } //unstable else { printf(" > unstable\n"); //there is/was an active state if (activeState != NULL) { //delete activeState; if (confidenceValidState > confValidStateAdjustableThreshold) addActiveStateToStateVector(); activeState = NULL; } } //DATE TODO //STABLE CONFIDENCE MITEINBEZIEHEN if ((confidenceBroken >= confidenceBroken) && (confidenceBroken > confidenceBrokenAdjustableThreshold)) { setColor(TXTCOLOR_LIGHTRED); printf(" >> BROKEN - confidence %f\n", confidenceBroken); setColor(TXTCOLOR_GREY); getchar(); } else if (confidenceDrift > confidenceDriftAdjustableThreshold) { setColor(TXTCOLOR_YELLOW); printf(" >> DRIFT - confidence %f\n", confidenceDrift); setColor(TXTCOLOR_GREY); //XXXXXXXXXX ???????????????????????????????????? if (brokenCounter > 0) brokenCounter--; getchar(); } else { setColor(TXTCOLOR_LIGHTGREEN); float confidenceOK; if (confidenceDrift > confidenceBroken) confidenceOK = 1 - confidenceDrift; else confidenceOK = 1 - confidenceBroken; printf(" >> SYSTEM OK - confidence %f\n", confidenceOK); setColor(TXTCOLOR_GREY); } printf("brokenCounter %u\n", brokenCounter); printf("number of states: %i\n", vStates.size()); */ /* if (variablesAreStable(&vInputVariables) && variablesAreStable(&vOutputVariables)) { printf(" > stable\n"); //XXX - only for now csv_writer->write_field(2); //stable csv_writer->make_new_field(); //getchar(); if (activeState == NULL && vStates.empty()) { makeNewActiveState(); activeState->injectValues(discreteAveragePartitionSize); //XXX - only for now csv_writer->write_field(1); //new active state csv_writer->make_new_field(); csv_writer->make_new_field(); } else { if (activeState != NULL) { printf("\nbeginning here:\n"); bool flagInputUnchanged = activeState->inputVariablesAreRelated(thresholdToBeRelated); bool flagOutputUnchanged = activeState->outputVariablesAreRelated(thresholdToBeRelated); //input and/or output unchanged? if (flagInputUnchanged && flagOutputUnchanged) { activeState->injectValues(discreteAveragePartitionSize); if (!activeState->checkAllVariablesForNotDrifting(discreteAveragePartitionSize, compareDistanceDiscreteAveragePartition, thresholdNotDrift)) { printDrift(); //XXX - only for now csv_writer->make_new_field(); csv_writer->write_field(1); //drift csv_writer->make_new_field(); } //XXX - only for now else { csv_writer->make_new_field(); csv_writer->make_new_field(); } } else { if (activeState->getNumOfInjections() >= minNumToBeValidState) { if ((!flagInputUnchanged && flagOutputUnchanged) || (flagInputUnchanged && !flagOutputUnchanged)) { printBroken(); getchar(); //XXX - only for now csv_writer->make_new_field(); csv_writer->write_field(2); //broken csv_writer->make_new_field(); } else { addActiveStateToStateVector(); if (!findRelatedStateAndMakeItActive()) { makeNewActiveState(); activeState->injectValues(discreteAveragePartitionSize); //XXX - only for now csv_writer->write_field(1); //new active state csv_writer->make_new_field(); csv_writer->make_new_field(); } else { //next line is new activeState->resetDiscreteAveragePartitionCounter(); //XXX - only for now csv_writer->write_field(2); //change to existing state csv_writer->make_new_field(); activeState->injectValues(discreteAveragePartitionSize); if (!activeState->checkAllVariablesForNotDrifting(discreteAveragePartitionSize, compareDistanceDiscreteAveragePartition, thresholdNotDrift)) { printDrift(); //XXX - only for now csv_writer->write_field(1); //drift csv_writer->make_new_field(); } //XXX - only for now else { csv_writer->make_new_field(); } } } } else { delete activeState; if (!findRelatedStateAndMakeItActive()) { makeNewActiveState(); activeState->injectValues(discreteAveragePartitionSize); //XXX - only for now csv_writer->write_field(1); //new active state csv_writer->make_new_field(); csv_writer->make_new_field(); } else { //next line is new activeState->resetDiscreteAveragePartitionCounter(); //XXX - only for now csv_writer->write_field(2); //change to existing state csv_writer->make_new_field(); activeState->injectValues(discreteAveragePartitionSize); if (!activeState->checkAllVariablesForNotDrifting(discreteAveragePartitionSize, compareDistanceDiscreteAveragePartition, thresholdNotDrift)) { printDrift(); //XXX - only for now csv_writer->write_field(1); //drift csv_writer->make_new_field(); } //XXX - only for now else { csv_writer->make_new_field(); } } } } } else { if (!findRelatedStateAndMakeItActive()) { makeNewActiveState(); activeState->injectValues(discreteAveragePartitionSize); //XXX - only for now csv_writer->write_field(1); //new active state csv_writer->make_new_field(); csv_writer->make_new_field(); } else { //next line is new activeState->resetDiscreteAveragePartitionCounter(); //XXX - only for now csv_writer->write_field(2); //change to existing state csv_writer->make_new_field(); activeState->injectValues(discreteAveragePartitionSize); if (!activeState->checkAllVariablesForNotDrifting(discreteAveragePartitionSize, compareDistanceDiscreteAveragePartition, thresholdNotDrift)) { printDrift(); //XXX - only for now csv_writer->write_field(1); //drift csv_writer->make_new_field(); } //XXX - only for now else { csv_writer->make_new_field(); } } } } if (activeState != NULL) { printf(" -- an activeState exist: \n"); printf(" --- injections: %u\n", activeState->getNumOfInjections()); //XXX - only for now csv_writer->write_field((int)activeState->getNumOfInjections()); //number of injections csv_writer->make_new_line(); } //XXX - only for now else { csv_writer->make_new_field(); } printf(" -- Number of States (excl. activeState): %u\n", vStates.size()); for (auto &s : vStates) { printf(" --- injections: %u\n", s->getNumOfInjections()); } printf(" ... BrokenCounter: %u\n", brokenCounter); printf(" ... driftCounter: %u\n", driftCounter); printf("cycle: %u\n", cycle); if (test) { test = false; //getchar(); } flagVariablesWereStable = true; } else { printf(" > unstable\n"); //XXX - only for now csv_writer->write_field(1); //unstable csv_writer->make_new_field(); csv_writer->make_new_field(); csv_writer->make_new_field(); csv_writer->make_new_line(); if (flagVariablesWereStable) test = true; //search for states with less injections in all states if (flagVariablesWereStable) { if (activeState != NULL) { if (activeState->getNumOfInjections() >= minNumToBeValidState) { addActiveStateToStateVector(); } else { delete activeState; } activeState = NULL; //getchar(); } } flagVariablesWereStable = false; } //xxx - only for now //csv_writer->make_new_line(); */ } void StateHandler::closeCsvFile() { if(csv_writer != NULL) csv_writer->close_file(); } string StateHandler::create_Output_File_Name(string cfg_parameter) { time_t rawtime; struct tm * timeinfo; //char output_file_name[200]; char datetime[80]; std::string output_file_name_str; time(&rawtime); timeinfo = localtime(&rawtime); strftime(datetime, sizeof(datetime), "%Y-%m-%d_%I-%M-%S", timeinfo); #ifndef INPUT_FILE_NAME output_file_name_str = output_directory_name + "output" + datetime + cfg_parameter + ".csv"; #else string out_dir = "../data/out/"; output_file_name_str = out_dir + INPUT_FILE_NAME + datetime + cfg_parameter + ".csv"; #endif // INPUT_FILE_NAME return output_file_name_str; } void StateHandler::set_CSV_Writer_parameter(string cfg_parameter) { string cur_Output_File_Name = this->create_Output_File_Name(cfg_parameter); csv_writer->reset_fpointer(cur_Output_File_Name); } /* void StateHandler :: initStateHandler() { //activeState = NULL; thresholdToAverage = THRESHOLDTOAVG; minNumOfChangedForValidStateChange = MINNUMCHANGEDFORVALIDSTATECHANGE; minimumInjectionsForBeingState = MININJFORBEINGSTATE; } StateHandler :: StateHandler() { set_name(NO_NAME); initStateHandler(); } StateHandler :: StateHandler(char* name) { set_name(name); initStateHandler(); } bool StateHandler :: setMinimumInjectionsForBeingState(unsigned int minimumInjectionsForBeingState) { if (minimumInjectionsForBeingState > 0) { this->minimumInjectionsForBeingState = minimumInjectionsForBeingState; return true; } return false; } unsigned int StateHandler :: getMinimumInjectionsForBeingState() { return minimumInjectionsForBeingState; } bool StateHandler :: add_slot(SlaveAgentSlotOfAgent* slot) { if(slot != NULL) { try { vSlots.push_back(slot); return true; } catch(bad_alloc& error) { printError("bad_alloc caught: ", error.what()); delete slot; } } return false; } void StateHandler :: setThresholdToAverage(float thresholdToAverage) { this->thresholdToAverage = thresholdToAverage; } float StateHandler :: getThresholdToAverage() { return thresholdToAverage; } void StateHandler::set_minNumOfChangedForValidStateChange(unsigned int minNumOfChangedForValidStateChange) { this->minNumOfChangedForValidStateChange = minNumOfChangedForValidStateChange; } unsigned int StateHandler::get_minNumOfChangedForValidStateChange() { return minNumOfChangedForValidStateChange; } bool StateHandler :: trigger() { bool flagWorked = true; printf("NumOfStates: "); for (auto &slot : vSlots) { printf("%u, ", slot->getNumberOfStates()); } printf("\n"); //Check all input values if they have changed more than threshold ...and count how many changed unsigned int numberOfChanges = 0; for (auto &slot : vSlots) { float value; if (slot->get_slaveAgentValue(&value)) { State* activeState = slot->getActiveState(); if (activeState != NULL) { printf("act - "); if (activeState->isNew()) { printf("new - "); //numberOfChanges++; } else if (activeState->valueIsRelated(value, thresholdToAverage)) { printf("rel - "); } else { printf("nrel - "); numberOfChanges++; } } else { printf("nact - "); } } } printf("\n"); printf(" >> Number of Changes: %u\n", numberOfChanges); //nothing has changes more than threshold if (numberOfChanges == 0) { printf("\n\n >>> inject in active state\n"); for (auto &slot : vSlots) { slot->injectValueInActiveState(); } } else if(numberOfChanges >= minNumOfChangedForValidStateChange) { printf("\n\n >>> new (or another) state\n"); for (auto &slot : vSlots) { State* activeState = slot->getActiveState(); if (activeState != NULL) { if (activeState->getNumberOfInjections() < minimumInjectionsForBeingState) { slot->deleteActiveState(); printf(" >> delete State\n"); } } } //search for existing state bool flagRelated = false; if (vSlots.empty() == false) { int ix = vSlots.front()->getIndexOfRelatedState(0, thresholdToAverage); while (ix > -2) { if (ix >= 0) { //TODO: maybe another state fits a bit better.. approach -> euklidean distance? flagRelated = true; for (vector::iterator slot = vSlots.begin() + 1; slot < vSlots.end(); slot++) { if ((*slot)->valueIsRelated(ix, thresholdToAverage) == false) { flagRelated = false; } } if (flagRelated == true) { for (auto &slot : vSlots) { slot->setActiveState(ix); } break; } ix = vSlots.front()->getIndexOfRelatedState(ix+1, thresholdToAverage); } } } if (flagRelated == false) { printf(" >> No related state found\n"); printf("\n\n >>> inject in active state\n"); for (auto &slot : vSlots) { slot->injectValueInActiveState(); } } } printf("ende\n"); return false; } */ diff --git a/Version_Max_07_05_2018_CMake/src/rlutil.h b/Version_Max_07_05_2018_CMake/src/rlutil.h index 2c5ea7a..d563a4b 100755 --- a/Version_Max_07_05_2018_CMake/src/rlutil.h +++ b/Version_Max_07_05_2018_CMake/src/rlutil.h @@ -1,779 +1,853 @@ #pragma once /** * File: rlutil.h * * About: Description * This file provides some useful utilities for console mode * roguelike game development with C and C++. It is aimed to * be cross-platform (at least Windows and Linux). * * About: Copyright * (C) 2010 Tapio Vierros * * About: Licensing * See */ //#ifndef RLUTIL_HEADERFILE //#define RLUTIL_HEADERFILE /// Define: RLUTIL_USE_ANSI /// Define this to use ANSI escape sequences also on Windows /// (defaults to using WinAPI instead). #if 0 #define RLUTIL_USE_ANSI #endif /// Define: RLUTIL_STRING_T /// Define/typedef this to your preference to override rlutil's string type. /// /// Defaults to std::string with C++ and char* with C. #if 0 -#define RLUTIL_STRING_T char* +#define RLUTIL_STRING_T char * #endif #ifndef RLUTIL_INLINE - #ifdef _MSC_VER - #define RLUTIL_INLINE __inline - #else - #define RLUTIL_INLINE static __inline__ - #endif +#ifdef _MSC_VER +#define RLUTIL_INLINE __inline +#else +#define RLUTIL_INLINE static __inline__ +#endif #endif #ifdef __cplusplus - /// Common C++ headers - #include - #include - #include // for getch() - /// Namespace forward declarations - namespace rlutil { - RLUTIL_INLINE void locate(int x, int y); - } - - //Work Arround (atartpoint) - - #define TXTCOLOR_BLACK 0 - #define TXTCOLOR_BLUE 1 - #define TXTCOLOR_GREEN 2 - #define TXTCOLOR_CYAN 3 - #define TXTCOLOR_RED 4 - #define TXTCOLOR_MAGENTA 5 - #define TXTCOLOR_BROWN 6 - #define TXTCOLOR_GREY 7 - #define TXTCOLOR_DARKGREY 8 - #define TXTCOLOR_LIGHTBLUE 9 - #define TXTCOLOR_LIGHTGREEN 10 - #define TXTCOLOR_LIGHTCYAN 11 - #define TXTCOLOR_LIGHTRED 12 - #define TXTCOLOR_LIGHTMAGENTA 13 - #define TXTCOLOR_YELLOW 14 - #define TXTCOLOR_WHITE 15 +/// Common C++ headers +#include +#include +#include // for getch() +/// Namespace forward declarations +namespace rlutil { +RLUTIL_INLINE void locate(int x, int y); +} + +// Work Arround (atartpoint) + +#define TXTCOLOR_BLACK 0 +#define TXTCOLOR_BLUE 1 +#define TXTCOLOR_GREEN 2 +#define TXTCOLOR_CYAN 3 +#define TXTCOLOR_RED 4 +#define TXTCOLOR_MAGENTA 5 +#define TXTCOLOR_BROWN 6 +#define TXTCOLOR_GREY 7 +#define TXTCOLOR_DARKGREY 8 +#define TXTCOLOR_LIGHTBLUE 9 +#define TXTCOLOR_LIGHTGREEN 10 +#define TXTCOLOR_LIGHTCYAN 11 +#define TXTCOLOR_LIGHTRED 12 +#define TXTCOLOR_LIGHTMAGENTA 13 +#define TXTCOLOR_YELLOW 14 +#define TXTCOLOR_WHITE 15 #else - #include // for getch() / printf() - #include // for strlen() - RLUTIL_INLINE void locate(int x, int y); // Forward declare for C to avoid warnings -#endif // __cplusplus +#include // for getch() / printf() +#include // for strlen() +RLUTIL_INLINE void locate(int x, + int y); // Forward declare for C to avoid warnings +#endif // __cplusplus #ifdef _WIN32 - #include // for WinAPI and Sleep() - #define _NO_OLDNAMES // for MinGW compatibility - #include // for getch() and kbhit() - #define getch _getch - #define kbhit _kbhit +#include // for WinAPI and Sleep() +#define _NO_OLDNAMES // for MinGW compatibility +#include // for getch() and kbhit() +#define getch _getch +#define kbhit _kbhit #else - #include // for getch() and kbhit() - #include // for getch(), kbhit() and (u)sleep() - #include // for getkey() - #include // for kbhit() - #include // for kbhit() +#include // for getch() and kbhit() +#include // for getch(), kbhit() and (u)sleep() +#include // for getkey() +#include // for kbhit() +#include // for kbhit() /// Function: getch /// Get character without waiting for Return to be pressed. /// Windows has this in conio.h RLUTIL_INLINE int getch(void) { - // Here be magic. - struct termios oldt, newt; - int ch; - tcgetattr(STDIN_FILENO, &oldt); - newt = oldt; - newt.c_lflag &= ~(ICANON | ECHO); - tcsetattr(STDIN_FILENO, TCSANOW, &newt); - ch = getchar(); - tcsetattr(STDIN_FILENO, TCSANOW, &oldt); - return ch; + // Here be magic. + struct termios oldt, newt; + int ch; + tcgetattr(STDIN_FILENO, &oldt); + newt = oldt; + newt.c_lflag &= ~(ICANON | ECHO); + tcsetattr(STDIN_FILENO, TCSANOW, &newt); + ch = getchar(); + tcsetattr(STDIN_FILENO, TCSANOW, &oldt); + return ch; } /// Function: kbhit /// Determines if keyboard has been hit. /// Windows has this in conio.h RLUTIL_INLINE int kbhit(void) { - // Here be dragons. - static struct termios oldt, newt; - int cnt = 0; - tcgetattr(STDIN_FILENO, &oldt); - newt = oldt; - newt.c_lflag &= ~(ICANON | ECHO); - newt.c_iflag = 0; // input mode - newt.c_oflag = 0; // output mode - newt.c_cc[VMIN] = 1; // minimum time to wait - newt.c_cc[VTIME] = 1; // minimum characters to wait for - tcsetattr(STDIN_FILENO, TCSANOW, &newt); - ioctl(0, FIONREAD, &cnt); // Read count - struct timeval tv; - tv.tv_sec = 0; - tv.tv_usec = 100; - select(STDIN_FILENO+1, NULL, NULL, NULL, &tv); // A small time delay - tcsetattr(STDIN_FILENO, TCSANOW, &oldt); - return cnt; // Return number of characters + // Here be dragons. + static struct termios oldt, newt; + int cnt = 0; + tcgetattr(STDIN_FILENO, &oldt); + newt = oldt; + newt.c_lflag &= ~(ICANON | ECHO); + newt.c_iflag = 0; // input mode + newt.c_oflag = 0; // output mode + newt.c_cc[VMIN] = 1; // minimum time to wait + newt.c_cc[VTIME] = 1; // minimum characters to wait for + tcsetattr(STDIN_FILENO, TCSANOW, &newt); + //TODO: check if _IOC_READ instead of FIONREAD is fine.. I had to change that + //ioctl(0, _IOC_READ, &cnt); // Read count + struct timeval tv; + tv.tv_sec = 0; + tv.tv_usec = 100; + select(STDIN_FILENO + 1, NULL, NULL, NULL, &tv); // A small time delay + tcsetattr(STDIN_FILENO, TCSANOW, &oldt); + return cnt; // Return number of characters } -#endif // _WIN32 +#endif // _WIN32 #ifndef gotoxy /// Function: gotoxy /// Same as . RLUTIL_INLINE void gotoxy(int x, int y) { - #ifdef __cplusplus - rlutil:: - #endif - locate(x,y); +#ifdef __cplusplus + rlutil:: +#endif + locate(x, y); } #endif // gotoxy #ifdef __cplusplus /// Namespace: rlutil /// In C++ all functions except , and are arranged /// under namespace rlutil. That is because some platforms have them defined /// outside of rlutil. namespace rlutil { #endif /** * Defs: Internal typedefs and macros * RLUTIL_STRING_T - String type depending on which one of C or C++ is used * RLUTIL_PRINT(str) - Printing macro independent of C/C++ */ #ifdef __cplusplus - #ifndef RLUTIL_STRING_T - typedef std::string RLUTIL_STRING_T; - #endif // RLUTIL_STRING_T - - #define RLUTIL_PRINT(st) do { std::cout << st; } while(false) +#ifndef RLUTIL_STRING_T +typedef std::string RLUTIL_STRING_T; +#endif // RLUTIL_STRING_T + +#define RLUTIL_PRINT(st) \ + do { \ + std::cout << st; \ + } while (false) #else // __cplusplus - #ifndef RLUTIL_STRING_T - typedef const char* RLUTIL_STRING_T; - #endif // RLUTIL_STRING_T +#ifndef RLUTIL_STRING_T +typedef const char *RLUTIL_STRING_T; +#endif // RLUTIL_STRING_T - #define RLUTIL_PRINT(st) printf("%s", st) +#define RLUTIL_PRINT(st) printf("%s", st) #endif // __cplusplus /** * Enums: Color codes * * BLACK - Black * BLUE - Blue * GREEN - Green * CYAN - Cyan * RED - Red * MAGENTA - Magenta / purple * BROWN - Brown / dark yellow * GREY - Grey / dark white * DARKGREY - Dark grey / light black * LIGHTBLUE - Light blue * LIGHTGREEN - Light green * LIGHTCYAN - Light cyan * LIGHTRED - Light red * LIGHTMAGENTA - Light magenta / light purple * YELLOW - Yellow (bright) * WHITE - White (bright) */ enum { - BLACK, - BLUE, - GREEN, - CYAN, - RED, - MAGENTA, - BROWN, - GREY, - DARKGREY, - LIGHTBLUE, - LIGHTGREEN, - LIGHTCYAN, - LIGHTRED, - LIGHTMAGENTA, - YELLOW, - WHITE + BLACK, + BLUE, + GREEN, + CYAN, + RED, + MAGENTA, + BROWN, + GREY, + DARKGREY, + LIGHTBLUE, + LIGHTGREEN, + LIGHTCYAN, + LIGHTRED, + LIGHTMAGENTA, + YELLOW, + WHITE }; /** * Consts: ANSI escape strings * * ANSI_CLS - Clears screen - * ANSI_CONSOLE_TITLE_PRE - Prefix for changing the window title, print the window title in between - * ANSI_CONSOLE_TITLE_POST - Suffix for changing the window title, print the window title in between - * ANSI_ATTRIBUTE_RESET - Resets all attributes - * ANSI_CURSOR_HIDE - Hides the cursor + * ANSI_CONSOLE_TITLE_PRE - Prefix for changing the window title, print the + * window title in between ANSI_CONSOLE_TITLE_POST - Suffix for changing the + * window title, print the window title in between ANSI_ATTRIBUTE_RESET - + * Resets all attributes ANSI_CURSOR_HIDE - Hides the cursor * ANSI_CURSOR_SHOW - Shows the cursor * ANSI_CURSOR_HOME - Moves the cursor home (0,0) * ANSI_BLACK - Black * ANSI_RED - Red * ANSI_GREEN - Green * ANSI_BROWN - Brown / dark yellow * ANSI_BLUE - Blue * ANSI_MAGENTA - Magenta / purple * ANSI_CYAN - Cyan * ANSI_GREY - Grey / dark white * ANSI_DARKGREY - Dark grey / light black * ANSI_LIGHTRED - Light red * ANSI_LIGHTGREEN - Light green * ANSI_YELLOW - Yellow (bright) * ANSI_LIGHTBLUE - Light blue * ANSI_LIGHTMAGENTA - Light magenta / light purple * ANSI_LIGHTCYAN - Light cyan * ANSI_WHITE - White (bright) * ANSI_BACKGROUND_BLACK - Black background * ANSI_BACKGROUND_RED - Red background * ANSI_BACKGROUND_GREEN - Green background * ANSI_BACKGROUND_YELLOW - Yellow background * ANSI_BACKGROUND_BLUE - Blue background * ANSI_BACKGROUND_MAGENTA - Magenta / purple background * ANSI_BACKGROUND_CYAN - Cyan background * ANSI_BACKGROUND_WHITE - White background */ -const RLUTIL_STRING_T ANSI_CLS = "\033[2J\033[3J"; -const RLUTIL_STRING_T ANSI_CONSOLE_TITLE_PRE = "\033]0;"; +const RLUTIL_STRING_T ANSI_CLS = "\033[2J\033[3J"; +const RLUTIL_STRING_T ANSI_CONSOLE_TITLE_PRE = "\033]0;"; const RLUTIL_STRING_T ANSI_CONSOLE_TITLE_POST = "\007"; -const RLUTIL_STRING_T ANSI_ATTRIBUTE_RESET = "\033[0m"; -const RLUTIL_STRING_T ANSI_CURSOR_HIDE = "\033[?25l"; -const RLUTIL_STRING_T ANSI_CURSOR_SHOW = "\033[?25h"; -const RLUTIL_STRING_T ANSI_CURSOR_HOME = "\033[H"; -const RLUTIL_STRING_T ANSI_BLACK = "\033[22;30m"; -const RLUTIL_STRING_T ANSI_RED = "\033[22;31m"; -const RLUTIL_STRING_T ANSI_GREEN = "\033[22;32m"; -const RLUTIL_STRING_T ANSI_BROWN = "\033[22;33m"; -const RLUTIL_STRING_T ANSI_BLUE = "\033[22;34m"; -const RLUTIL_STRING_T ANSI_MAGENTA = "\033[22;35m"; -const RLUTIL_STRING_T ANSI_CYAN = "\033[22;36m"; -const RLUTIL_STRING_T ANSI_GREY = "\033[22;37m"; -const RLUTIL_STRING_T ANSI_DARKGREY = "\033[01;30m"; -const RLUTIL_STRING_T ANSI_LIGHTRED = "\033[01;31m"; -const RLUTIL_STRING_T ANSI_LIGHTGREEN = "\033[01;32m"; -const RLUTIL_STRING_T ANSI_YELLOW = "\033[01;33m"; -const RLUTIL_STRING_T ANSI_LIGHTBLUE = "\033[01;34m"; -const RLUTIL_STRING_T ANSI_LIGHTMAGENTA = "\033[01;35m"; -const RLUTIL_STRING_T ANSI_LIGHTCYAN = "\033[01;36m"; -const RLUTIL_STRING_T ANSI_WHITE = "\033[01;37m"; -const RLUTIL_STRING_T ANSI_BACKGROUND_BLACK = "\033[40m"; -const RLUTIL_STRING_T ANSI_BACKGROUND_RED = "\033[41m"; -const RLUTIL_STRING_T ANSI_BACKGROUND_GREEN = "\033[42m"; -const RLUTIL_STRING_T ANSI_BACKGROUND_YELLOW = "\033[43m"; -const RLUTIL_STRING_T ANSI_BACKGROUND_BLUE = "\033[44m"; +const RLUTIL_STRING_T ANSI_ATTRIBUTE_RESET = "\033[0m"; +const RLUTIL_STRING_T ANSI_CURSOR_HIDE = "\033[?25l"; +const RLUTIL_STRING_T ANSI_CURSOR_SHOW = "\033[?25h"; +const RLUTIL_STRING_T ANSI_CURSOR_HOME = "\033[H"; +const RLUTIL_STRING_T ANSI_BLACK = "\033[22;30m"; +const RLUTIL_STRING_T ANSI_RED = "\033[22;31m"; +const RLUTIL_STRING_T ANSI_GREEN = "\033[22;32m"; +const RLUTIL_STRING_T ANSI_BROWN = "\033[22;33m"; +const RLUTIL_STRING_T ANSI_BLUE = "\033[22;34m"; +const RLUTIL_STRING_T ANSI_MAGENTA = "\033[22;35m"; +const RLUTIL_STRING_T ANSI_CYAN = "\033[22;36m"; +const RLUTIL_STRING_T ANSI_GREY = "\033[22;37m"; +const RLUTIL_STRING_T ANSI_DARKGREY = "\033[01;30m"; +const RLUTIL_STRING_T ANSI_LIGHTRED = "\033[01;31m"; +const RLUTIL_STRING_T ANSI_LIGHTGREEN = "\033[01;32m"; +const RLUTIL_STRING_T ANSI_YELLOW = "\033[01;33m"; +const RLUTIL_STRING_T ANSI_LIGHTBLUE = "\033[01;34m"; +const RLUTIL_STRING_T ANSI_LIGHTMAGENTA = "\033[01;35m"; +const RLUTIL_STRING_T ANSI_LIGHTCYAN = "\033[01;36m"; +const RLUTIL_STRING_T ANSI_WHITE = "\033[01;37m"; +const RLUTIL_STRING_T ANSI_BACKGROUND_BLACK = "\033[40m"; +const RLUTIL_STRING_T ANSI_BACKGROUND_RED = "\033[41m"; +const RLUTIL_STRING_T ANSI_BACKGROUND_GREEN = "\033[42m"; +const RLUTIL_STRING_T ANSI_BACKGROUND_YELLOW = "\033[43m"; +const RLUTIL_STRING_T ANSI_BACKGROUND_BLUE = "\033[44m"; const RLUTIL_STRING_T ANSI_BACKGROUND_MAGENTA = "\033[45m"; -const RLUTIL_STRING_T ANSI_BACKGROUND_CYAN = "\033[46m"; -const RLUTIL_STRING_T ANSI_BACKGROUND_WHITE = "\033[47m"; +const RLUTIL_STRING_T ANSI_BACKGROUND_CYAN = "\033[46m"; +const RLUTIL_STRING_T ANSI_BACKGROUND_WHITE = "\033[47m"; // Remaining colors not supported as background colors /** * Enums: Key codes for keyhit() * * KEY_ESCAPE - Escape * KEY_ENTER - Enter * KEY_SPACE - Space * KEY_INSERT - Insert * KEY_HOME - Home * KEY_END - End * KEY_DELETE - Delete * KEY_PGUP - PageUp * KEY_PGDOWN - PageDown * KEY_UP - Up arrow * KEY_DOWN - Down arrow * KEY_LEFT - Left arrow * KEY_RIGHT - Right arrow * KEY_F1 - F1 * KEY_F2 - F2 * KEY_F3 - F3 * KEY_F4 - F4 * KEY_F5 - F5 * KEY_F6 - F6 * KEY_F7 - F7 * KEY_F8 - F8 * KEY_F9 - F9 * KEY_F10 - F10 * KEY_F11 - F11 * KEY_F12 - F12 * KEY_NUMDEL - Numpad del * KEY_NUMPAD0 - Numpad 0 * KEY_NUMPAD1 - Numpad 1 * KEY_NUMPAD2 - Numpad 2 * KEY_NUMPAD3 - Numpad 3 * KEY_NUMPAD4 - Numpad 4 * KEY_NUMPAD5 - Numpad 5 * KEY_NUMPAD6 - Numpad 6 * KEY_NUMPAD7 - Numpad 7 * KEY_NUMPAD8 - Numpad 8 * KEY_NUMPAD9 - Numpad 9 */ enum { - KEY_ESCAPE = 0, - KEY_ENTER = 1, - KEY_SPACE = 32, - - KEY_INSERT = 2, - KEY_HOME = 3, - KEY_PGUP = 4, - KEY_DELETE = 5, - KEY_END = 6, - KEY_PGDOWN = 7, - - KEY_UP = 14, - KEY_DOWN = 15, - KEY_LEFT = 16, - KEY_RIGHT = 17, - - KEY_F1 = 18, - KEY_F2 = 19, - KEY_F3 = 20, - KEY_F4 = 21, - KEY_F5 = 22, - KEY_F6 = 23, - KEY_F7 = 24, - KEY_F8 = 25, - KEY_F9 = 26, - KEY_F10 = 27, - KEY_F11 = 28, - KEY_F12 = 29, - - KEY_NUMDEL = 30, - KEY_NUMPAD0 = 31, - KEY_NUMPAD1 = 127, - KEY_NUMPAD2 = 128, - KEY_NUMPAD3 = 129, - KEY_NUMPAD4 = 130, - KEY_NUMPAD5 = 131, - KEY_NUMPAD6 = 132, - KEY_NUMPAD7 = 133, - KEY_NUMPAD8 = 134, - KEY_NUMPAD9 = 135 + KEY_ESCAPE = 0, + KEY_ENTER = 1, + KEY_SPACE = 32, + + KEY_INSERT = 2, + KEY_HOME = 3, + KEY_PGUP = 4, + KEY_DELETE = 5, + KEY_END = 6, + KEY_PGDOWN = 7, + + KEY_UP = 14, + KEY_DOWN = 15, + KEY_LEFT = 16, + KEY_RIGHT = 17, + + KEY_F1 = 18, + KEY_F2 = 19, + KEY_F3 = 20, + KEY_F4 = 21, + KEY_F5 = 22, + KEY_F6 = 23, + KEY_F7 = 24, + KEY_F8 = 25, + KEY_F9 = 26, + KEY_F10 = 27, + KEY_F11 = 28, + KEY_F12 = 29, + + KEY_NUMDEL = 30, + KEY_NUMPAD0 = 31, + KEY_NUMPAD1 = 127, + KEY_NUMPAD2 = 128, + KEY_NUMPAD3 = 129, + KEY_NUMPAD4 = 130, + KEY_NUMPAD5 = 131, + KEY_NUMPAD6 = 132, + KEY_NUMPAD7 = 133, + KEY_NUMPAD8 = 134, + KEY_NUMPAD9 = 135 }; /// Function: getkey /// Reads a key press (blocking) and returns a key code. /// /// See /// /// Note: /// Only Arrows, Esc, Enter and Space are currently working properly. RLUTIL_INLINE int getkey(void) { - #ifndef _WIN32 - int cnt = kbhit(); // for ANSI escapes processing - #endif - int k = getch(); - switch(k) { - case 0: { - int kk; - switch (kk = getch()) { - case 71: return KEY_NUMPAD7; - case 72: return KEY_NUMPAD8; - case 73: return KEY_NUMPAD9; - case 75: return KEY_NUMPAD4; - case 77: return KEY_NUMPAD6; - case 79: return KEY_NUMPAD1; - case 80: return KEY_NUMPAD2; - case 81: return KEY_NUMPAD3; - case 82: return KEY_NUMPAD0; - case 83: return KEY_NUMDEL; - default: return kk-59+KEY_F1; // Function keys - }} - case 224: { - int kk; - switch (kk = getch()) { - case 71: return KEY_HOME; - case 72: return KEY_UP; - case 73: return KEY_PGUP; - case 75: return KEY_LEFT; - case 77: return KEY_RIGHT; - case 79: return KEY_END; - case 80: return KEY_DOWN; - case 81: return KEY_PGDOWN; - case 82: return KEY_INSERT; - case 83: return KEY_DELETE; - default: return kk-123+KEY_F1; // Function keys - }} - case 13: return KEY_ENTER; +#ifndef _WIN32 + int cnt = kbhit(); // for ANSI escapes processing +#endif + int k = getch(); + switch (k) { + case 0: { + int kk; + switch (kk = getch()) { + case 71: + return KEY_NUMPAD7; + case 72: + return KEY_NUMPAD8; + case 73: + return KEY_NUMPAD9; + case 75: + return KEY_NUMPAD4; + case 77: + return KEY_NUMPAD6; + case 79: + return KEY_NUMPAD1; + case 80: + return KEY_NUMPAD2; + case 81: + return KEY_NUMPAD3; + case 82: + return KEY_NUMPAD0; + case 83: + return KEY_NUMDEL; + default: + return kk - 59 + KEY_F1; // Function keys + } + } + case 224: { + int kk; + switch (kk = getch()) { + case 71: + return KEY_HOME; + case 72: + return KEY_UP; + case 73: + return KEY_PGUP; + case 75: + return KEY_LEFT; + case 77: + return KEY_RIGHT; + case 79: + return KEY_END; + case 80: + return KEY_DOWN; + case 81: + return KEY_PGDOWN; + case 82: + return KEY_INSERT; + case 83: + return KEY_DELETE; + default: + return kk - 123 + KEY_F1; // Function keys + } + } + case 13: + return KEY_ENTER; #ifdef _WIN32 - case 27: return KEY_ESCAPE; -#else // _WIN32 - case 155: // single-character CSI - case 27: { - // Process ANSI escape sequences - if (cnt >= 3 && getch() == '[') { - switch (k = getch()) { - case 'A': return KEY_UP; - case 'B': return KEY_DOWN; - case 'C': return KEY_RIGHT; - case 'D': return KEY_LEFT; - } - } else return KEY_ESCAPE; - } + case 27: + return KEY_ESCAPE; +#else // _WIN32 + case 155: // single-character CSI + case 27: { + // Process ANSI escape sequences + if (cnt >= 3 && getch() == '[') { + switch (k = getch()) { + case 'A': + return KEY_UP; + case 'B': + return KEY_DOWN; + case 'C': + return KEY_RIGHT; + case 'D': + return KEY_LEFT; + } + } else + return KEY_ESCAPE; + } #endif // _WIN32 - default: return k; - } + default: + return k; + } } /// Function: nb_getch /// Non-blocking getch(). Returns 0 if no key was pressed. RLUTIL_INLINE int nb_getch(void) { - if (kbhit()) return getch(); - else return 0; + if (kbhit()) + return getch(); + else + return 0; } /// Function: getANSIColor /// Return ANSI color escape sequence for specified number 0-15. /// /// See RLUTIL_INLINE RLUTIL_STRING_T getANSIColor(const int c) { - switch (c) { - case BLACK : return ANSI_BLACK; - case BLUE : return ANSI_BLUE; // non-ANSI - case GREEN : return ANSI_GREEN; - case CYAN : return ANSI_CYAN; // non-ANSI - case RED : return ANSI_RED; // non-ANSI - case MAGENTA : return ANSI_MAGENTA; - case BROWN : return ANSI_BROWN; - case GREY : return ANSI_GREY; - case DARKGREY : return ANSI_DARKGREY; - case LIGHTBLUE : return ANSI_LIGHTBLUE; // non-ANSI - case LIGHTGREEN : return ANSI_LIGHTGREEN; - case LIGHTCYAN : return ANSI_LIGHTCYAN; // non-ANSI; - case LIGHTRED : return ANSI_LIGHTRED; // non-ANSI; - case LIGHTMAGENTA: return ANSI_LIGHTMAGENTA; - case YELLOW : return ANSI_YELLOW; // non-ANSI - case WHITE : return ANSI_WHITE; - default: return ""; - } + switch (c) { + case BLACK: + return ANSI_BLACK; + case BLUE: + return ANSI_BLUE; // non-ANSI + case GREEN: + return ANSI_GREEN; + case CYAN: + return ANSI_CYAN; // non-ANSI + case RED: + return ANSI_RED; // non-ANSI + case MAGENTA: + return ANSI_MAGENTA; + case BROWN: + return ANSI_BROWN; + case GREY: + return ANSI_GREY; + case DARKGREY: + return ANSI_DARKGREY; + case LIGHTBLUE: + return ANSI_LIGHTBLUE; // non-ANSI + case LIGHTGREEN: + return ANSI_LIGHTGREEN; + case LIGHTCYAN: + return ANSI_LIGHTCYAN; // non-ANSI; + case LIGHTRED: + return ANSI_LIGHTRED; // non-ANSI; + case LIGHTMAGENTA: + return ANSI_LIGHTMAGENTA; + case YELLOW: + return ANSI_YELLOW; // non-ANSI + case WHITE: + return ANSI_WHITE; + default: + return ""; + } } /// Function: getANSIBackgroundColor /// Return ANSI background color escape sequence for specified number 0-15. /// /// See RLUTIL_INLINE RLUTIL_STRING_T getANSIBackgroundColor(const int c) { - switch (c) { - case BLACK : return ANSI_BACKGROUND_BLACK; - case BLUE : return ANSI_BACKGROUND_BLUE; - case GREEN : return ANSI_BACKGROUND_GREEN; - case CYAN : return ANSI_BACKGROUND_CYAN; - case RED : return ANSI_BACKGROUND_RED; - case MAGENTA: return ANSI_BACKGROUND_MAGENTA; - case BROWN : return ANSI_BACKGROUND_YELLOW; - case GREY : return ANSI_BACKGROUND_WHITE; - default: return ""; - } + switch (c) { + case BLACK: + return ANSI_BACKGROUND_BLACK; + case BLUE: + return ANSI_BACKGROUND_BLUE; + case GREEN: + return ANSI_BACKGROUND_GREEN; + case CYAN: + return ANSI_BACKGROUND_CYAN; + case RED: + return ANSI_BACKGROUND_RED; + case MAGENTA: + return ANSI_BACKGROUND_MAGENTA; + case BROWN: + return ANSI_BACKGROUND_YELLOW; + case GREY: + return ANSI_BACKGROUND_WHITE; + default: + return ""; + } } /// Function: setColor /// Change color specified by number (Windows / QBasic colors). /// Don't change the background color /// /// See RLUTIL_INLINE void setColor(int c) { #if defined(_WIN32) && !defined(RLUTIL_USE_ANSI) - HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); - CONSOLE_SCREEN_BUFFER_INFO csbi; + HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); + CONSOLE_SCREEN_BUFFER_INFO csbi; - GetConsoleScreenBufferInfo(hConsole, &csbi); + GetConsoleScreenBufferInfo(hConsole, &csbi); - SetConsoleTextAttribute(hConsole, (csbi.wAttributes & 0xFFF0) | (WORD)c); // Foreground colors take up the least significant byte + SetConsoleTextAttribute( + hConsole, + (csbi.wAttributes & 0xFFF0) | + (WORD)c); // Foreground colors take up the least significant byte #else - RLUTIL_PRINT(getANSIColor(c)); + RLUTIL_PRINT(getANSIColor(c)); #endif } /// Function: setBackgroundColor /// Change background color specified by number (Windows / QBasic colors). /// Don't change the foreground color /// /// See RLUTIL_INLINE void setBackgroundColor(int c) { #if defined(_WIN32) && !defined(RLUTIL_USE_ANSI) - HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); - CONSOLE_SCREEN_BUFFER_INFO csbi; + HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); + CONSOLE_SCREEN_BUFFER_INFO csbi; - GetConsoleScreenBufferInfo(hConsole, &csbi); + GetConsoleScreenBufferInfo(hConsole, &csbi); - SetConsoleTextAttribute(hConsole, (csbi.wAttributes & 0xFF0F) | (((WORD)c) << 4)); // Background colors take up the second-least significant byte + SetConsoleTextAttribute( + hConsole, (csbi.wAttributes & 0xFF0F) | + (((WORD)c) << 4)); // Background colors take up the + // second-least significant byte #else - RLUTIL_PRINT(getANSIBackgroundColor(c)); + RLUTIL_PRINT(getANSIBackgroundColor(c)); #endif } /// Function: saveDefaultColor /// Call once to preserve colors for use in resetColor() /// on Windows without ANSI, no-op otherwise /// /// See /// See RLUTIL_INLINE int saveDefaultColor(void) { #if defined(_WIN32) && !defined(RLUTIL_USE_ANSI) - static char initialized = 0; // bool - static WORD attributes; - - if (!initialized) { - CONSOLE_SCREEN_BUFFER_INFO csbi; - GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi); - attributes = csbi.wAttributes; - initialized = 1; - } - return (int)attributes; + static char initialized = 0; // bool + static WORD attributes; + + if (!initialized) { + CONSOLE_SCREEN_BUFFER_INFO csbi; + GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi); + attributes = csbi.wAttributes; + initialized = 1; + } + return (int)attributes; #else - return -1; + return -1; #endif } /// Function: resetColor /// Reset color to default /// Requires a call to saveDefaultColor() to set the defaults /// /// See /// See /// See RLUTIL_INLINE void resetColor(void) { #if defined(_WIN32) && !defined(RLUTIL_USE_ANSI) - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), (WORD)saveDefaultColor()); + SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), + (WORD)saveDefaultColor()); #else - RLUTIL_PRINT(ANSI_ATTRIBUTE_RESET); + RLUTIL_PRINT(ANSI_ATTRIBUTE_RESET); #endif } /// Function: cls /// Clears screen, resets all attributes and moves cursor home. RLUTIL_INLINE void cls(void) { #if defined(_WIN32) && !defined(RLUTIL_USE_ANSI) - // Based on https://msdn.microsoft.com/en-us/library/windows/desktop/ms682022%28v=vs.85%29.aspx - const HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); - const COORD coordScreen = {0, 0}; - DWORD cCharsWritten; - CONSOLE_SCREEN_BUFFER_INFO csbi; - - GetConsoleScreenBufferInfo(hConsole, &csbi); - const DWORD dwConSize = csbi.dwSize.X * csbi.dwSize.Y; - FillConsoleOutputCharacter(hConsole, (TCHAR)' ', dwConSize, coordScreen, &cCharsWritten); - - GetConsoleScreenBufferInfo(hConsole, &csbi); - FillConsoleOutputAttribute(hConsole, csbi.wAttributes, dwConSize, coordScreen, &cCharsWritten); - - SetConsoleCursorPosition(hConsole, coordScreen); + // Based on + // https://msdn.microsoft.com/en-us/library/windows/desktop/ms682022%28v=vs.85%29.aspx + const HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); + const COORD coordScreen = {0, 0}; + DWORD cCharsWritten; + CONSOLE_SCREEN_BUFFER_INFO csbi; + + GetConsoleScreenBufferInfo(hConsole, &csbi); + const DWORD dwConSize = csbi.dwSize.X * csbi.dwSize.Y; + FillConsoleOutputCharacter(hConsole, (TCHAR)' ', dwConSize, coordScreen, + &cCharsWritten); + + GetConsoleScreenBufferInfo(hConsole, &csbi); + FillConsoleOutputAttribute(hConsole, csbi.wAttributes, dwConSize, coordScreen, + &cCharsWritten); + + SetConsoleCursorPosition(hConsole, coordScreen); #else - RLUTIL_PRINT(ANSI_CLS); - RLUTIL_PRINT(ANSI_CURSOR_HOME); + RLUTIL_PRINT(ANSI_CLS); + RLUTIL_PRINT(ANSI_CURSOR_HOME); #endif } /// Function: locate /// Sets the cursor position to 1-based x,y. RLUTIL_INLINE void locate(int x, int y) { #if defined(_WIN32) && !defined(RLUTIL_USE_ANSI) - COORD coord; - // TODO: clamping/assert for x/y <= 0? - coord.X = (SHORT)(x - 1); - coord.Y = (SHORT)(y - 1); // Windows uses 0-based coordinates - SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord); + COORD coord; + // TODO: clamping/assert for x/y <= 0? + coord.X = (SHORT)(x - 1); + coord.Y = (SHORT)(y - 1); // Windows uses 0-based coordinates + SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord); #else // _WIN32 || USE_ANSI - #ifdef __cplusplus - RLUTIL_PRINT("\033[" << y << ";" << x << "H"); - #else // __cplusplus - char buf[32]; - sprintf(buf, "\033[%d;%df", y, x); - RLUTIL_PRINT(buf); - #endif // __cplusplus +#ifdef __cplusplus + RLUTIL_PRINT("\033[" << y << ";" << x << "H"); +#else // __cplusplus + char buf[32]; + sprintf(buf, "\033[%d;%df", y, x); + RLUTIL_PRINT(buf); +#endif // __cplusplus #endif // _WIN32 || USE_ANSI } /// Function: setString /// Prints the supplied string without advancing the cursor #ifdef __cplusplus -RLUTIL_INLINE void setString(const RLUTIL_STRING_T & str_) { +RLUTIL_INLINE void setString(const RLUTIL_STRING_T &str_) { - //Work Around (startpoint) - //const char * str_temp = str_.data(); //Changed: "str" -> "str_temp" - wchar_t* str=new wchar_t[4096]; //Add this line - //MultiByteToWideChar(CP_ACP, 0, str_temp, -1, str, 4096); //Add this line - //Work Around (endpoint) + // Work Around (startpoint) + // const char * str_temp = str_.data(); //Changed: "str" -> + // "str_temp" + wchar_t *str = new wchar_t[4096]; // Add this line + // MultiByteToWideChar(CP_ACP, 0, str_temp, -1, str, 4096); //Add this + // line Work Around (endpoint) - unsigned int len = str_.size(); -#else // __cplusplus + unsigned int len = str_.size(); +#else // __cplusplus RLUTIL_INLINE void setString(RLUTIL_STRING_T str) { - unsigned int len = strlen(str); + unsigned int len = strlen(str); #endif // __cplusplus #if defined(_WIN32) && !defined(RLUTIL_USE_ANSI) - HANDLE hConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE); - DWORD numberOfCharsWritten; - CONSOLE_SCREEN_BUFFER_INFO csbi; + HANDLE hConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE); + DWORD numberOfCharsWritten; + CONSOLE_SCREEN_BUFFER_INFO csbi; - GetConsoleScreenBufferInfo(hConsoleOutput, &csbi); - WriteConsoleOutputCharacter(hConsoleOutput, str, len, csbi.dwCursorPosition, &numberOfCharsWritten); + GetConsoleScreenBufferInfo(hConsoleOutput, &csbi); + WriteConsoleOutputCharacter(hConsoleOutput, str, len, csbi.dwCursorPosition, + &numberOfCharsWritten); #else // _WIN32 || USE_ANSI - RLUTIL_PRINT(str); - #ifdef __cplusplus - RLUTIL_PRINT("\033[" << len << 'D'); - #else // __cplusplus - char buf[3 + 20 + 1]; // 20 = max length of 64-bit unsigned int when printed as dec - sprintf(buf, "\033[%uD", len); - RLUTIL_PRINT(buf); - #endif // __cplusplus + RLUTIL_PRINT(str); +#ifdef __cplusplus + RLUTIL_PRINT("\033[" << len << 'D'); +#else // __cplusplus + char buf[3 + 20 + + 1]; // 20 = max length of 64-bit unsigned int when printed as dec + sprintf(buf, "\033[%uD", len); + RLUTIL_PRINT(buf); +#endif // __cplusplus #endif // _WIN32 || USE_ANSI } /// Function: setChar /// Sets the character at the cursor without advancing the cursor RLUTIL_INLINE void setChar(char ch) { - const char buf[] = {ch, 0}; - setString(buf); + const char buf[] = {ch, 0}; + setString(buf); } /// Function: setCursorVisibility /// Shows/hides the cursor. RLUTIL_INLINE void setCursorVisibility(char visible) { #if defined(_WIN32) && !defined(RLUTIL_USE_ANSI) - HANDLE hConsoleOutput = GetStdHandle( STD_OUTPUT_HANDLE ); - CONSOLE_CURSOR_INFO structCursorInfo; - GetConsoleCursorInfo( hConsoleOutput, &structCursorInfo ); // Get current cursor size - structCursorInfo.bVisible = (visible ? TRUE : FALSE); - SetConsoleCursorInfo( hConsoleOutput, &structCursorInfo ); -#else // _WIN32 || USE_ANSI - RLUTIL_PRINT((visible ? ANSI_CURSOR_SHOW : ANSI_CURSOR_HIDE)); + HANDLE hConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE); + CONSOLE_CURSOR_INFO structCursorInfo; + GetConsoleCursorInfo(hConsoleOutput, + &structCursorInfo); // Get current cursor size + structCursorInfo.bVisible = (visible ? TRUE : FALSE); + SetConsoleCursorInfo(hConsoleOutput, &structCursorInfo); +#else // _WIN32 || USE_ANSI + RLUTIL_PRINT((visible ? ANSI_CURSOR_SHOW : ANSI_CURSOR_HIDE)); #endif // _WIN32 || USE_ANSI } /// Function: hidecursor /// Hides the cursor. -RLUTIL_INLINE void hidecursor(void) { - setCursorVisibility(0); -} +RLUTIL_INLINE void hidecursor(void) { setCursorVisibility(0); } /// Function: showcursor /// Shows the cursor. -RLUTIL_INLINE void showcursor(void) { - setCursorVisibility(1); -} +RLUTIL_INLINE void showcursor(void) { setCursorVisibility(1); } /// Function: msleep /// Waits given number of milliseconds before continuing. RLUTIL_INLINE void msleep(unsigned int ms) { #ifdef _WIN32 - Sleep(ms); + Sleep(ms); #else - // usleep argument must be under 1 000 000 - if (ms > 1000) sleep(ms/1000000); - usleep((ms % 1000000) * 1000); + // usleep argument must be under 1 000 000 + if (ms > 1000) + sleep(ms / 1000000); + usleep((ms % 1000000) * 1000); #endif } /// Function: trows /// Get the number of rows in the terminal window or -1 on error. RLUTIL_INLINE int trows(void) { #ifdef _WIN32 - CONSOLE_SCREEN_BUFFER_INFO csbi; - if (!GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi)) - return -1; - else - return csbi.srWindow.Bottom - csbi.srWindow.Top + 1; // Window height - // return csbi.dwSize.Y; // Buffer height + CONSOLE_SCREEN_BUFFER_INFO csbi; + if (!GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi)) + return -1; + else + return csbi.srWindow.Bottom - csbi.srWindow.Top + 1; // Window height + // return csbi.dwSize.Y; // Buffer height #else #ifdef TIOCGSIZE - struct ttysize ts; - ioctl(STDIN_FILENO, TIOCGSIZE, &ts); - return ts.ts_lines; + struct ttysize ts; + ioctl(STDIN_FILENO, TIOCGSIZE, &ts); + return ts.ts_lines; #elif defined(TIOCGWINSZ) - struct winsize ts; - ioctl(STDIN_FILENO, TIOCGWINSZ, &ts); - return ts.ws_row; -#else // TIOCGSIZE - return -1; + struct winsize ts; + ioctl(STDIN_FILENO, TIOCGWINSZ, &ts); + return ts.ws_row; +#else // TIOCGSIZE + return -1; #endif // TIOCGSIZE #endif // _WIN32 } /// Function: tcols /// Get the number of columns in the terminal window or -1 on error. RLUTIL_INLINE int tcols(void) { #ifdef _WIN32 - CONSOLE_SCREEN_BUFFER_INFO csbi; - if (!GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi)) - return -1; - else - return csbi.srWindow.Right - csbi.srWindow.Left + 1; // Window width - // return csbi.dwSize.X; // Buffer width + CONSOLE_SCREEN_BUFFER_INFO csbi; + if (!GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi)) + return -1; + else + return csbi.srWindow.Right - csbi.srWindow.Left + 1; // Window width + // return csbi.dwSize.X; // Buffer width #else #ifdef TIOCGSIZE - struct ttysize ts; - ioctl(STDIN_FILENO, TIOCGSIZE, &ts); - return ts.ts_cols; + struct ttysize ts; + ioctl(STDIN_FILENO, TIOCGSIZE, &ts); + return ts.ts_cols; #elif defined(TIOCGWINSZ) - struct winsize ts; - ioctl(STDIN_FILENO, TIOCGWINSZ, &ts); - return ts.ws_col; -#else // TIOCGSIZE - return -1; + struct winsize ts; + ioctl(STDIN_FILENO, TIOCGWINSZ, &ts); + return ts.ws_col; +#else // TIOCGSIZE + return -1; #endif // TIOCGSIZE #endif // _WIN32 } /// Function: anykey /// Waits until a key is pressed. /// In C++, it either takes no arguments /// or a template-type-argument-deduced /// argument. /// In C, it takes a const char* representing /// the message to be displayed, or NULL /// for no message. #ifdef __cplusplus -RLUTIL_INLINE void anykey() { - getch(); -} +RLUTIL_INLINE void anykey() { getch(); } -template void anykey(const T& msg) { - RLUTIL_PRINT(msg); +template void anykey(const T &msg) { + RLUTIL_PRINT(msg); #else RLUTIL_INLINE void anykey(RLUTIL_STRING_T msg) { - if (msg) - RLUTIL_PRINT(msg); + if (msg) + RLUTIL_PRINT(msg); #endif // __cplusplus - getch(); + getch(); } RLUTIL_INLINE void setConsoleTitle(RLUTIL_STRING_T title) { - const char * true_title = + const char *true_title = #ifdef __cplusplus - title.c_str(); -#else // __cplusplus - title; + title.c_str(); +#else // __cplusplus + title; #endif // __cplusplus #if defined(_WIN32) && !defined(RLUTIL_USE_ANSI) - SetConsoleTitleA(true_title); + SetConsoleTitleA(true_title); #else - RLUTIL_PRINT(ANSI_CONSOLE_TITLE_PRE); - RLUTIL_PRINT(true_title); - RLUTIL_PRINT(ANSI_CONSOLE_TITLE_POST); + RLUTIL_PRINT(ANSI_CONSOLE_TITLE_PRE); + RLUTIL_PRINT(true_title); + RLUTIL_PRINT(ANSI_CONSOLE_TITLE_POST); #endif // defined(_WIN32) && !defined(RLUTIL_USE_ANSI) } // Classes are here at the end so that documentation is pretty. #ifdef __cplusplus /// Class: CursorHider /// RAII OOP wrapper for . /// Hides the cursor and shows it again /// when the object goes out of scope. struct CursorHider { - CursorHider() { hidecursor(); } - ~CursorHider() { showcursor(); } + CursorHider() { hidecursor(); } + ~CursorHider() { showcursor(); } }; } // namespace rlutil #endif //#endif \ No newline at end of file