<commit_before>/*-----------------------------------------------------------------------------
 This source file is part of Hopsan NG

 Copyright (c) 2011 
    <NAME>, <NAME>, <NAME>, <NAME>,
    <NAME>, <NAME>, <NAME>, <NAME>

 This file is provided "as is", with no guarantee or warranty for the
 functionality or reliability of the contents. All contents in this file is
 the original work of the copyright holders at the Division of Fluid and
 Mechatronic Systems (Flumes) at Linköping University. Modifying, using or
 redistributing any part of this file is prohibited without explicit
 permission from the copyright holders.
-----------------------------------------------------------------------------*/

//!
//! @file   Port.cc
//! @author <NAME> <<EMAIL>>
//! @date   2010-01-16
//!
//! @brief Contains Port base class as well as Sub classes
//!
//$Id$

#include "Port.h"
#include <iostream>
#include <sstream>
#include <cassert>
#include <math.h>
#include "HopsanEssentials.h"
#include "Component.h"
#include "ComponentSystem.h"
#include "CoreUtilities/HopsanCoreMessageHandler.h"

using namespace std;
using namespace hopsan;

//! Port base class constructor
Port::Port(string node_type, string portname, Component *portOwner, Port *pParentPort)
{
    mPortType = UNDEFINEDPORT;
    mPortName = portname;
    mNodeType = node_type;
    mpComponent = portOwner;
    mpParentPort = pParentPort; //Only used by subports in multiports
    mConnectionRequired = true;
    mConnectedPorts.clear();
    mpNode = 0;
    mpStartNode = 0;
}


//Destructor
Port::~Port()
{
    if (mpStartNode != 0)
    {
        //! Remove the mapping to eventual system parameters to avoid cowboy-writing in memory after deleted port.
        //! dataNames and dataUnits are here just to decide the number of elements in the start node.
        std::vector<std::string> dataNames, dataUnits;
        mpStartNode->getDataNamesAndUnits(dataNames, dataUnits);
        for(int i = 0; i < dataNames.size(); ++i)
        {
            getComponent()->getSystemParent()->getSystemParameters().unMapParameter(mpStartNode->getDataPtr(i));
        }
    }
}



//! Returns the type of node that can be connected to this port
const string Port::getNodeType()
{
    return mNodeType;
}


//! Returns the parent component
Component* Port::getComponent()
{
    if(mpParentPort)
        return mpParentPort->getComponent();
    else
        return mpComponent;
}


//! Returns a pointer to the connected node
Node* Port::getNodePtr(const size_t /*portIdx*/)
{
    return mpNode;
}

//! Adds a subport to a multiport
Port* Port::addSubPort()
{
    assert("This should only be implemented and called from multiports" == 0);
    return 0;
}

//! REmoves a subport from multiport
void Port::removeSubPort(Port* /*ptr*/)
{
    assert("This should only be implemented and called from multiports" == 0);
}


//! @brief Load start values by copying the start values from the port to the node
void Port::loadStartValues()
{
    if((isConnected()) && mpStartNode)
    {
        this->mpStartNode->copyNodeVariables(mpNode);
    }
}


//! @brief Load start values to the start value container from the node (last values from simulation)
void Port::loadStartValuesFromSimulation()
{
    if((isConnected()) && mpStartNode)
    {
        this->mpNode->copyNodeVariables(mpStartNode);
    }
}


//! Reads a value from the connected node
//! @param [in] idx The data id of the data to read
//! @return The data value
double Port::readNode(const size_t idx, const size_t /*portIdx*/)
{
    //! @todo ummm??, if this is a readport node and it is not connected then noone will ever read
    //! @todo maybe use dummy nodes with 0 in for not connected ports
    /*if((this->getPortType() == Port::READPORT) && (!this->isConnected()))      //Signal nodes don't have to be connected
    {
        return 0;
    }*/
    //return mpNode->getData(idx);
    //cout << "readNode: " << mpNode << endl;
    return mpNode->mDataVector[idx];//Test for speed up
}


//! Writes a value to the connected node
//! @param [in] idx The data id of the data to write
//! @param [in] value The value of the data to read
void Port::writeNode(const size_t &idx, const double &value, const size_t /*portIdx*/)
{
    //! @todo ummm??, if this is a writeport and it is not connected then noone will ever write. Should the check may be done?
    /*if((this->getPortType() == Port::WRITEPORT) && (!this->isConnected()))     //Signal nodes don't have to be connected
    {
        return;
    }*/
    mpNode->mDataVector[idx] = value;//Test for speed up
    //mpNode->setData(idx, value);
}


double *Port::getNodeDataPtr(const size_t idx, const size_t /*portIdx*/)
{
    return mpNode->getDataPtr(idx);
}<commit_msg>Added error handling for readNode and writeNode functions. They will be slightly slower, but they are not intended to be optimized anyway.<commit_after>/*-----------------------------------------------------------------------------
 This source file is part of Hopsan NG

 Copyright (c) 2011 
    <NAME>, <NAME>, <NAME>, <NAME>,
    <NAME>, <NAME>, <NAME>, <NAME>

 This file is provided "as is", with no guarantee or warranty for the
 functionality or reliability of the contents. All contents in this file is
 the original work of the copyright holders at the Division of Fluid and
 Mechatronic Systems (Flumes) at Linköping University. Modifying, using or
 redistributing any part of this file is prohibited without explicit
 permission from the copyright holders.
-----------------------------------------------------------------------------*/

//!
//! @file   Port.cc
//! @author <NAME> <<EMAIL>.se>
//! @date   2010-01-16
//!
//! @brief Contains Port base class as well as Sub classes
//!
//$Id$

#include "Port.h"
#include <iostream>
#include <sstream>
#include <cassert>
#include <math.h>
#include "HopsanEssentials.h"
#include "Component.h"
#include "ComponentSystem.h"
#include "CoreUtilities/HopsanCoreMessageHandler.h"

using namespace std;
using namespace hopsan;

//! Port base class constructor
Port::Port(string node_type, string portname, Component *portOwner, Port *pParentPort)
{
    mPortType = UNDEFINEDPORT;
    mPortName = portname;
    mNodeType = node_type;
    mpComponent = portOwner;
    mpParentPort = pParentPort; //Only used by subports in multiports
    mConnectionRequired = true;
    mConnectedPorts.clear();
    mpNode = 0;
    mpStartNode = 0;
}


//Destructor
Port::~Port()
{
    if (mpStartNode != 0)
    {
        //! Remove the mapping to eventual system parameters to avoid cowboy-writing in memory after deleted port.
        //! dataNames and dataUnits are here just to decide the number of elements in the start node.
        std::vector<std::string> dataNames, dataUnits;
        mpStartNode->getDataNamesAndUnits(dataNames, dataUnits);
        for(int i = 0; i < dataNames.size(); ++i)
        {
            getComponent()->getSystemParent()->getSystemParameters().unMapParameter(mpStartNode->getDataPtr(i));
        }
    }
}



//! Returns the type of node that can be connected to this port
const string Port::getNodeType()
{
    return mNodeType;
}


//! Returns the parent component
Component* Port::getComponent()
{
    if(mpParentPort)
        return mpParentPort->getComponent();
    else
        return mpComponent;
}


//! Returns a pointer to the connected node
Node* Port::getNodePtr(const size_t /*portIdx*/)
{
    return mpNode;
}

//! Adds a subport to a multiport
Port* Port::addSubPort()
{
    assert("This should only be implemented and called from multiports" == 0);
    return 0;
}

//! REmoves a subport from multiport
void Port::removeSubPort(Port* /*ptr*/)
{
    assert("This should only be implemented and called from multiports" == 0);
}


//! @brief Load start values by copying the start values from the port to the node
void Port::loadStartValues()
{
    if((isConnected()) && mpStartNode)
    {
        this->mpStartNode->copyNodeVariables(mpNode);
    }
}


//! @brief Load start values to the start value container from the node (last values from simulation)
void Port::loadStartValuesFromSimulation()
{
    if((isConnected()) && mpStartNode)
    {
        this->mpNode->copyNodeVariables(mpStartNode);
    }
}


//! Reads a value from the connected node
//! @param [in] idx The data id of the data to read
//! @return The data value
double Port::readNode(const size_t idx, const size_t /*portIdx*/)
{
    //! @note This if-statement will slow simulation down, but if optimization is desired readNode and writeNode shall not be used anyway.
    if(mIsConnected)
    {
        std::stringstream ss;
        ss << "Attempted to call readNode() for non-connected port \"" << this->getPortName() << "\".";
        mpComponent->addErrorMessage(ss.str());
        mpComponent->getSystemParent()->stop();     //Read attempt from non-connected port; abort simulation and give error message
        return 0;
    }
    else
    {
        return mpNode->mDataVector[idx];
    }
}


//! Writes a value to the connected node
//! @param [in] idx The data id of the data to write
//! @param [in] value The value of the data to read
void Port::writeNode(const size_t &idx, const double &value, const size_t /*portIdx*/)
{
    //! @note This if-statement will slow simulation down, but if optimization is desired readNode and writeNode shall not be used anyway.
    if(mIsConnected)
    {
        mpNode->mDataVector[idx] = value;       //Write to node if there is a node to write to
    }
}


double *Port::getNodeDataPtr(const size_t idx, const size_t /*portIdx*/)
{
    return mpNode->getDataPtr(idx);
}
{'fraction_non_alphanumeric': 0.14334790755777638, 'fraction_numerical': 0.004268165729752238, 'mean_word_length': 2.958384837247631, 'pattern_counts': {'":': 0, '<': 49, '<?xml version=': 0, '>': 69, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3278952', 'n_tokens_mistral': 2827, 'n_tokens_neox': 2724, 'n_words': 1007}