<commit_before>/*
 * opencog/server/DimensionalEmbedding.cc
 *
 * Copyright (C) 2010 by Singularity Institute for Artificial Intelligence
 * All Rights Reserved
 *
 * Written by David Crane <dncrane@gmail.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Free Software Foundation and including the exceptions
 * at http://opencog.org/wiki/Licenses
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, write to:
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
#include "DimensionalEmbedding.h"
#include <opencog/server/CogServer.h>
#include <opencog/util/Logger.h>
#include <string>
#include <numeric>
#include <opencog/guile/SchemePrimitive.h>

using namespace opencog;

void DimensionalEmbedding::init(CogServer* cogServer){
    this->cogServer=cogServer;
    this->as=cogServer->getAtomSpace();

    define_scheme_primitive("embedSpace",
                            &DimensionalEmbedding::embedSimLinks,
                            this);
    define_scheme_primitive("logEmbedding",
                            &DimensionalEmbedding::logSimEmbedding,
                            this);

}

void DimensionalEmbedding::embedSimLinks() {
    embedAtomSpace(SIMILARITY_LINK);
}
void DimensionalEmbedding::logSimEmbedding() {
    logAtomEmbedding(SIMILARITY_LINK);
}
// Uses a slightly modified version of dijkstra's algorithm
double DimensionalEmbedding::findHighestWeightPath(const Handle& startHandle,
                                                   const Handle& targetHandle,
                                                   const Type& linkType)
{
    if(startHandle == targetHandle) return 1;
    typedef std::map<Handle, double> NodeMap;
    NodeMap nodeMap;
    nodeMap[startHandle]=1;

    HandleSet visitedNodes;
    visitedNodes.add(startHandle);
    while(!nodeMap.empty()) {
        std::pair<Handle, double> bestNode = std::make_pair(startHandle, -1);

        //set bestNode to the node in nodeMap with the highest weight
        for(NodeMap::iterator it=nodeMap.begin(); it!=nodeMap.end(); ++it){
            if(it->second > bestNode.second) bestNode=(*it);
        }
        //Look at all of the links connected to the bestNode
        HandleSeq newLinks = as->getIncoming(bestNode.first);
        for(HandleSeq::iterator it=newLinks.begin(); it!=newLinks.end(); ++it){
            //ignore links that aren't of type linkType
            if(as->getType(*it)!=linkType) continue;

            HandleSeq newNodes = as->getOutgoing(*it);
            //update all of the nodes' weights.
            for(HandleSeq::iterator it2=newNodes.begin();
                it2!=newNodes.end(); ++it2){
                //if the node has been visited, don't do anything
                if(visitedNodes.contains(*it2)) continue;

                const TruthValue& linkTV = as->getTV(*it);
                nodeMap[*it2]=
                    bestNode.second*(linkTV.getMean()*linkTV.getConfidence());
                visitedNodes.add(*it2);
                //Check whether we've reached the targetHandle
                if ((*it2)==targetHandle) return nodeMap[*it2];
            }

        }
        nodeMap.erase(bestNode.first);
    }
    return 0; //no path found, return 0
}

void DimensionalEmbedding::addPivot(const Handle& h, const Type& linkType){
    pivotsMap[linkType].push_back(h);

    //update atomEmbedding for this linkType to include this pivot in its
    //embedding vector for each node.
    HandleSeq nodes;
    as->getHandleSet(std::back_inserter(nodes), NODE, true);
    for(HandleSeq::iterator it=nodes.begin(); it!=nodes.end(); ++it){
        std::vector<double>& embedVector=atomMaps[linkType][*it];
        embedVector.push_back
            (findHighestWeightPath(*it, h, linkType));
    }
}

void DimensionalEmbedding::embedAtomSpace(const Type& linkType){
    HandleSeq nodes;
    as->getHandleSet(std::back_inserter(nodes), NODE, true);

    PivotSeq& pivots = pivotsMap[linkType];
    Handle bestChoice = nodes.back();
    while((pivots.size() < numDimensions) && (!nodes.empty())){
        addPivot(bestChoice, linkType);
        //logger().info("Pivot %d picked", pivots.size());
        nodes.erase(std::find(nodes.begin(), nodes.end(), bestChoice));

        bestChoice = nodes[0];
        double bestChoiceWeight = 1;
        for(HandleSeq::iterator it=nodes.begin(); it!=nodes.end(); ++it){
            //calculate the nearness to pivots by multiplying the highest
            //weight paths from the node to each pivot.
            std::vector<double>& embedVector=atomMaps[linkType][*it];
            double testChoiceWeight =
                std::accumulate(embedVector.begin(),
                                embedVector.end(),
                                double(1),
                                std::multiplies<double>());
            //pick the node with the lowest testChoiceWeight
            //(farthest from the pivots)
            if(testChoiceWeight < bestChoiceWeight){
                bestChoice = *it;
                bestChoiceWeight = testChoiceWeight;
            }
        }
    }
    //logger().info("Embedding done");
}

void DimensionalEmbedding::addNode(const Handle& h, const Type& linkType){
    PivotSeq& pivots=pivotsMap[linkType];
    std::vector<double> embeddingVector;
    //The i'th entry of the handle's embeddingVector is the value of the
    //highest weight path between the handle and the i'th pivot.
    for(PivotSeq::iterator it=pivots.begin(); it!=pivots.end(); ++it){
        embeddingVector.push_back(findHighestWeightPath(h, *it, linkType));
    }
    atomMaps[linkType][h]=embeddingVector;
}

void DimensionalEmbedding::clearEmbedding(const Type& linkType){
    atomMaps.erase(linkType);
    pivotsMap.erase(linkType);
}

void DimensionalEmbedding::logAtomEmbedding(const Type& linkType){
    AtomEmbedding atomEmbedding=atomMaps[linkType];
    PivotSeq pivots = pivotsMap[linkType];

    std::ostringstream oss;

    oss << "PIVOTS:" << std::endl;
    for(PivotSeq::const_iterator it=pivots.begin(); it!=pivots.end(); ++it){
        Atom* atom = TLB::getAtom(*it);
        oss << atom->toShortString() << std::endl;
    }
    oss << "Node Embeddings:" << std::endl;
    AtomEmbedding::const_iterator it;
    for(it=atomEmbedding.begin(); it!=atomEmbedding.end(); ++it){
        Atom* atom = TLB::getAtom(it->first);
        oss << atom->toShortString() << " : (";
        std::vector<double> embedVector = it->second;
        for(std::vector<double>::const_iterator it2=embedVector.begin();
            it2!=embedVector.end();
            ++it2){
            oss << *it2 << " ";
        }
        oss << ")" << std::endl;
    }
    logger().info(oss.str());
    return;
}
<commit_msg>fixed problem when repeatedly embedding (now clears old embedding before starting anew)<commit_after>/*
 * opencog/server/DimensionalEmbedding.cc
 *
 * Copyright (C) 2010 by Singularity Institute for Artificial Intelligence
 * All Rights Reserved
 *
 * Written by David Crane <dncrane@gmail.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Free Software Foundation and including the exceptions
 * at http://opencog.org/wiki/Licenses
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, write to:
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
#include "DimensionalEmbedding.h"
#include <opencog/server/CogServer.h>
#include <opencog/util/Logger.h>
#include <string>
#include <numeric>
#include <opencog/guile/SchemePrimitive.h>

using namespace opencog;

void DimensionalEmbedding::init(CogServer* cogServer){
    this->cogServer=cogServer;
    this->as=cogServer->getAtomSpace();

    define_scheme_primitive("embedSpace",
                            &DimensionalEmbedding::embedSimLinks,
                            this);
    define_scheme_primitive("logEmbedding",
                            &DimensionalEmbedding::logSimEmbedding,
                            this);

}

void DimensionalEmbedding::embedSimLinks() {
    embedAtomSpace(SIMILARITY_LINK);
}
void DimensionalEmbedding::logSimEmbedding() {
    logAtomEmbedding(SIMILARITY_LINK);
}
// Uses a slightly modified version of dijkstra's algorithm
double DimensionalEmbedding::findHighestWeightPath(const Handle& startHandle,
                                                   const Handle& targetHandle,
                                                   const Type& linkType)
{
    if(startHandle == targetHandle) return 1;
    typedef std::map<Handle, double> NodeMap;
    NodeMap nodeMap;
    nodeMap[startHandle]=1;

    HandleSet visitedNodes;
    visitedNodes.add(startHandle);
    while(!nodeMap.empty()) {
        std::pair<Handle, double> bestNode = std::make_pair(startHandle, -1);

        //set bestNode to the node in nodeMap with the highest weight
        for(NodeMap::iterator it=nodeMap.begin(); it!=nodeMap.end(); ++it){
            if(it->second > bestNode.second) bestNode=(*it);
        }
        //Look at all of the links connected to the bestNode
        HandleSeq newLinks = as->getIncoming(bestNode.first);
        for(HandleSeq::iterator it=newLinks.begin(); it!=newLinks.end(); ++it){
            //ignore links that aren't of type linkType
            if(as->getType(*it)!=linkType) continue;

            HandleSeq newNodes = as->getOutgoing(*it);
            //update all of the nodes' weights.
            for(HandleSeq::iterator it2=newNodes.begin();
                it2!=newNodes.end(); ++it2){
                //if the node has been visited, don't do anything
                if(visitedNodes.contains(*it2)) continue;

                const TruthValue& linkTV = as->getTV(*it);
                nodeMap[*it2]=
                    bestNode.second*(linkTV.getMean()*linkTV.getConfidence());
                visitedNodes.add(*it2);
                //Check whether we've reached the targetHandle
                if ((*it2)==targetHandle) return nodeMap[*it2];
            }

        }
        nodeMap.erase(bestNode.first);
    }
    return 0; //no path found, return 0
}

void DimensionalEmbedding::addPivot(const Handle& h, const Type& linkType){
    pivotsMap[linkType].push_back(h);

    //update atomEmbedding for this linkType to include this pivot in its
    //embedding vector for each node.
    HandleSeq nodes;
    as->getHandleSet(std::back_inserter(nodes), NODE, true);
    for(HandleSeq::iterator it=nodes.begin(); it!=nodes.end(); ++it){
        std::vector<double>& embedVector=atomMaps[linkType][*it];
        embedVector.push_back
            (findHighestWeightPath(*it, h, linkType));
    }
}

void DimensionalEmbedding::embedAtomSpace(const Type& linkType){
    clearEmbedding(linkType);
    HandleSeq nodes;
    as->getHandleSet(std::back_inserter(nodes), NODE, true);

    PivotSeq& pivots = pivotsMap[linkType];
    Handle bestChoice = nodes.back();
    while((pivots.size() < numDimensions) && (!nodes.empty())){
        addPivot(bestChoice, linkType);
        //logger().info("Pivot %d picked", pivots.size());
        nodes.erase(std::find(nodes.begin(), nodes.end(), bestChoice));

        bestChoice = nodes[0];
        double bestChoiceWeight = 1;
        for(HandleSeq::iterator it=nodes.begin(); it!=nodes.end(); ++it){
            //calculate the nearness to pivots by multiplying the highest
            //weight paths from the node to each pivot.
            std::vector<double>& embedVector=atomMaps[linkType][*it];
            double testChoiceWeight =
                std::accumulate(embedVector.begin(),
                                embedVector.end(),
                                double(1),
                                std::multiplies<double>());
            //pick the node with the lowest testChoiceWeight
            //(farthest from the pivots)
            if(testChoiceWeight < bestChoiceWeight){
                bestChoice = *it;
                bestChoiceWeight = testChoiceWeight;
            }
        }
    }
    //logger().info("Embedding done");
}

void DimensionalEmbedding::addNode(const Handle& h, const Type& linkType){
    PivotSeq& pivots=pivotsMap[linkType];
    std::vector<double> embeddingVector;
    //The i'th entry of the handle's embeddingVector is the value of the
    //highest weight path between the handle and the i'th pivot.
    for(PivotSeq::iterator it=pivots.begin(); it!=pivots.end(); ++it){
        embeddingVector.push_back(findHighestWeightPath(h, *it, linkType));
    }
    atomMaps[linkType][h]=embeddingVector;
}

void DimensionalEmbedding::clearEmbedding(const Type& linkType){
    atomMaps.erase(linkType);
    pivotsMap.erase(linkType);
}

void DimensionalEmbedding::logAtomEmbedding(const Type& linkType){
    AtomEmbedding atomEmbedding=atomMaps[linkType];
    PivotSeq pivots = pivotsMap[linkType];

    std::ostringstream oss;

    oss << "PIVOTS:" << std::endl;
    for(PivotSeq::const_iterator it=pivots.begin(); it!=pivots.end(); ++it){
        Atom* atom = TLB::getAtom(*it);
        oss << atom->toShortString() << std::endl;
    }
    oss << "Node Embeddings:" << std::endl;
    AtomEmbedding::const_iterator it;
    for(it=atomEmbedding.begin(); it!=atomEmbedding.end(); ++it){
        Atom* atom = TLB::getAtom(it->first);
        oss << atom->toShortString() << " : (";
        std::vector<double> embedVector = it->second;
        for(std::vector<double>::const_iterator it2=embedVector.begin();
            it2!=embedVector.end();
            ++it2){
            oss << *it2 << " ";
        }
        oss << ")" << std::endl;
    }
    logger().info(oss.str());
    return;
}
<|endoftext|>


<commit_before>#include "Police.h"
#include "Zombie.h"
#include "PlayScene.h"

CPolice::CPolice(void)
{
//	enemyList = &(CPlayScene::GetInstance()->GetZombieList());
}

CPolice::~CPolice(void)
{
}

void CPolice::Render()
{
	NNObject::Render();
}

void CPolice::Update( float dTime )
{
	CCharacter::Update(dTime);
}

void CPolice::initStatus( PoliceInfo *policeInfo, int police_type_idx )
{
	m_HealthPoint = policeInfo[police_type_idx].HealthPoint;
	m_FullHP = m_HealthPoint/100;
	m_MovingSpeed = policeInfo[police_type_idx].MovingSpeed;
	m_AttackRange = policeInfo[police_type_idx].AttackRange;
	m_SplashAttackRange = policeInfo[police_type_idx].SplashRange;
	m_AttackPower = policeInfo[police_type_idx].AttackPower;
	m_DefensivePower = policeInfo[police_type_idx].DefensivePower;
	m_AttackSpeed = policeInfo[police_type_idx].AttackSpeed;
	m_SplashAttack = policeInfo[police_type_idx].IsSplash;
	m_Identity = policeInfo[police_type_idx].identity;
	m_policeType = policeInfo[police_type_idx].policeType;
	m_spritePath = CCharacter::string2wstring(policeInfo[police_type_idx].SpritePath.c_str());
	m_typeName = policeInfo[police_type_idx].TypeName;
}

<commit_msg>police체력 수정<commit_after>#include "Police.h"
#include "Zombie.h"
#include "PlayScene.h"

CPolice::CPolice(void)
{
//	enemyList = &(CPlayScene::GetInstance()->GetZombieList());
}

CPolice::~CPolice(void)
{
}

void CPolice::Render()
{
	NNObject::Render();
}

void CPolice::Update( float dTime )
{
	CCharacter::Update(dTime);
}

void CPolice::initStatus( PoliceInfo *policeInfo, int police_type_idx )
{
	m_HealthPoint = policeInfo[police_type_idx].HealthPoint;
	m_FullHP = m_HealthPoint;
	m_MovingSpeed = policeInfo[police_type_idx].MovingSpeed;
	m_AttackRange = policeInfo[police_type_idx].AttackRange;
	m_SplashAttackRange = policeInfo[police_type_idx].SplashRange;
	m_AttackPower = policeInfo[police_type_idx].AttackPower;
	m_DefensivePower = policeInfo[police_type_idx].DefensivePower;
	m_AttackSpeed = policeInfo[police_type_idx].AttackSpeed;
	m_SplashAttack = policeInfo[police_type_idx].IsSplash;
	m_Identity = policeInfo[police_type_idx].identity;
	m_policeType = policeInfo[police_type_idx].policeType;
	m_spritePath = CCharacter::string2wstring(policeInfo[police_type_idx].SpritePath.c_str());
	m_typeName = policeInfo[police_type_idx].TypeName;
}

<|endoftext|>


<commit_before>// SimmModelVisibleIterator.cpp
// Authors: Kenny Smith
/* Copyright (c) 2005, Stanford University, Kenny Smith
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject
 * to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#include "SimmModelVisibleIterator.h"
#include <OpenSim/Tools/Property.h>
#include <OpenSim/Tools/Object.h>
#include <OpenSim/Tools/VisibleObject.h>

#include "SimmModel.h"

using namespace OpenSim;
/* -------------------------------------------------------------------------
	SimmModelVisibleIterator::SimmModelVisibleIterator
---------------------------------------------------------------------------- */
SimmModelVisibleIterator::SimmModelVisibleIterator(SimmModel& model, Object* traversalRoot) :
	_model(model),
	_traversalRoot(traversalRoot),
	_traversalStarted(false),
	_traversalFinished(false)
{
	if (traversalRoot==0)
		_traversalRoot=&_model;
} // SimmModelVisibleIterator::SimmModelVisibleIterator

/* -------------------------------------------------------------------------
	SimmModelVisibleIterator::~SimmModelVisibleIterator
---------------------------------------------------------------------------- */
SimmModelVisibleIterator::~SimmModelVisibleIterator()
{
} // SimmModelVisibleIterator::~SimmModelVisibleIterator

/* -------------------------------------------------------------------------
	SimmModelVisibleIterator::getNextVisible - this routine cycles through visible objects
	in the model returning them in arbitrary order.
---------------------------------------------------------------------------- */
ArrayPtrs<VisibleObject>* SimmModelVisibleIterator::getVisibleObjects(Object* traversalRoot)
{
	if (traversalRoot == 0)
		traversalRoot = &_model;

	ArrayPtrs<VisibleObject>* collectVisibleObjects = new ArrayPtrs<VisibleObject>;
	collectVisibleObjects->setMemoryOwner(false);

	// Get properties of to pobject
	// if Object is an instance of a visible object then return it, otherwise go down the properties
	VisibleObject* vis;
	if(vis = dynamic_cast<VisibleObject*> (traversalRoot)){
		collectVisibleObjects->append(vis);
		return collectVisibleObjects;
	}
	PropertySet& rootProps = traversalRoot->getPropertySet();
	for(int i=0; i < rootProps.getSize(); i++){
		Property* nextProp = rootProps.get(i);
		switch(nextProp->getType()){
			case Property::PropertyType::Obj:
				{	// Recur
					Object& propObj = nextProp->getValueObj();
					collectVisibleObjects->append(*getVisibleObjects(&propObj));
					break;
				}
			case Property::PropertyType::ObjArray:
				{
					ArrayPtrs<Object>& propObjArray = nextProp->getValueObjArray();
					for(int j=0; j< propObjArray.getSize(); j++){
						collectVisibleObjects->append(*getVisibleObjects(propObjArray.get(j)));
					}
					break;
				}
			default:
				break;
		}
	}
	return collectVisibleObjects;
}
<commit_msg><commit_after>// SimmModelVisibleIterator.cpp
// Authors: Kenny Smith
/* Copyright (c) 2005, Stanford University, Kenny Smith
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject
 * to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#include "SimmModelVisibleIterator.h"
#include <OpenSim/Tools/Property.h>
#include <OpenSim/Tools/Object.h>
#include <OpenSim/Tools/VisibleObject.h>

#include "SimmModel.h"

using namespace OpenSim;
/* -------------------------------------------------------------------------
	SimmModelVisibleIterator::SimmModelVisibleIterator
---------------------------------------------------------------------------- */
SimmModelVisibleIterator::SimmModelVisibleIterator(SimmModel& model) :
	_model(model),
	_traversalRoot(model),
	_traversalStarted(false),
	_traversalFinished(false)
{
} // SimmModelVisibleIterator::SimmModelVisibleIterator

/* -------------------------------------------------------------------------
	SimmModelVisibleIterator::~SimmModelVisibleIterator
---------------------------------------------------------------------------- */
SimmModelVisibleIterator::~SimmModelVisibleIterator()
{
} // SimmModelVisibleIterator::~SimmModelVisibleIterator

/* -------------------------------------------------------------------------
	SimmModelVisibleIterator::getNextVisible - this routine cycles through visible objects
	in the model returning them in arbitrary order.
---------------------------------------------------------------------------- */
ArrayPtrs<VisibleObject>* SimmModelVisibleIterator::getVisibleObjects(Object* traversalRoot)
{
	if (traversalRoot == 0)
		traversalRoot = &_model;

	ArrayPtrs<VisibleObject>* collectVisibleObjects = new ArrayPtrs<VisibleObject>;
	collectVisibleObjects->setMemoryOwner(false);

	// Get properties of to pobject
	// if Object is an instance of a visible object then return it, otherwise go down the properties
	VisibleObject* vis;
	if(vis = dynamic_cast<VisibleObject*> (traversalRoot)){
		collectVisibleObjects->append(vis);
		return collectVisibleObjects;
	}
	PropertySet& rootProps = traversalRoot->getPropertySet();
	for(int i=0; i < rootProps.getSize(); i++){
		Property* nextProp = rootProps.get(i);
		switch(nextProp->getType()){
			case Property::PropertyType::Obj:
				{	// Recur
					Object& propObj = nextProp->getValueObj();
					collectVisibleObjects->append(*getVisibleObjects(&propObj));
					break;
				}
			case Property::PropertyType::ObjArray:
				{
					ArrayPtrs<Object>& propObjArray = nextProp->getValueObjArray();
					for(int j=0; j< propObjArray.getSize(); j++){
						collectVisibleObjects->append(*getVisibleObjects(propObjArray.get(j)));
					}
					break;
				}
			default:
				break;
		}
	}
	return collectVisibleObjects;
}
<|endoftext|>


<commit_before>/***********************************************************************************************************************
**
** Copyright (c) 2011, 2014 ETH Zurich
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
** following conditions are met:
**
**    * Redistributions of source code must retain the above copyright notice, this list of conditions and the following
**      disclaimer.
**    * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
**      following disclaimer in the documentation and/or other materials provided with the distribution.
**    * Neither the name of the ETH Zurich nor the names of its contributors may be used to endorse or promote products
**      derived from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
** INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
***********************************************************************************************************************/

#include "JavaCompiler.h"

#include "ModelBase/src/model/TreeManager.h"
#include "ModelBase/src/nodes/Node.h"

#include "VisualizationBase/src/items/Item.h"
#include "VisualizationBase/src/overlays/BoxOverlay.h"
#include "VisualizationBase/src/overlays/OverlayAccessor.h"

#include "JavaExport/src/exporter/JavaExporter.h"

#include "../CommandLineCompiler.h"
#include "../CompilerOutputParser.h"

namespace OODebug {

void JavaCompiler::compileTree(Model::TreeManager* manager, const QString& pathToProjectContainerDirectory)
{
	CommandLineCompiler compiler("javac", &CompilerOutputParser::parseJavacErrorFormat);
	auto nodeItemMap = Visualization::Item::nodeItemsMap();

	std::shared_ptr<Export::TextToNodeMap> map;
	std::shared_ptr<Export::SourceDir> dir;

	auto exportErrors = JavaExport::JavaExporter::exportTree(manager, pathToProjectContainerDirectory, map, dir);
	// First handle export errors.
	for (auto& error : exportErrors)
	{
		auto node = error.node();
		auto it = nodeItemMap.find(node);
		while (it != nodeItemMap.end() && it.key() == node)
		{
			visualizeMessage(it.value(), node, error.message());
			++it;
		}
	}

	for (auto file : dir->recursiveFiles())
	{
		Q_ASSERT(file);
		auto feedback = compiler.compileFile(pathToProjectContainerDirectory + QDir::separator() + file->path());
		for (auto& message : feedback.messages())
		{
			// In the map we don't have the pathToProjectContainerDirectory prefix
			auto fileName = message->getFileName().remove(pathToProjectContainerDirectory + QDir::separator());
			// lines and columns -1 because javac begins at 1 and TextToNodeMap at 0
			Model::Node* node = nullptr;
			if (auto rootMsg = message->getRootMessage())
				node = map->node(fileName, rootMsg->getLineNumber() - 1, rootMsg->getColumnNumber() - 1);
			else
				node = map->node(fileName, message->getLineNumber() - 1, message->getColumnNumber() - 1);
			Q_ASSERT(node);

			auto it = nodeItemMap.find(node);
			while (it != nodeItemMap.end() && it.key() == node)
			{
				// TODO for notes which have a rootMessage add a link to the message location.
				visualizeMessage(it.value(), node, message->getMessage());
				++it;
			}
		}
	}
}

void JavaCompiler::visualizeMessage(Visualization::Item* item, Model::Node* node, const QString& message)
{
	static const QString overlayGroupName("CompilerMessages");

	auto scene = item->scene();
	auto overlayGroup = scene->overlayGroup(overlayGroupName);

	if (!overlayGroup) overlayGroup = scene->addOverlayGroup(overlayGroupName);

	overlayGroup->addOverlay(makeOverlay( new Visualization::BoxOverlay(item,
		[node, message](Visualization::BoxOverlay *){
		return message;
	})));
}

} /* namespace OODebug */
<commit_msg>Compile to a build dir instead of the source dir<commit_after>/***********************************************************************************************************************
**
** Copyright (c) 2011, 2014 ETH Zurich
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
** following conditions are met:
**
**    * Redistributions of source code must retain the above copyright notice, this list of conditions and the following
**      disclaimer.
**    * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
**      following disclaimer in the documentation and/or other materials provided with the distribution.
**    * Neither the name of the ETH Zurich nor the names of its contributors may be used to endorse or promote products
**      derived from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
** INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
***********************************************************************************************************************/

#include "JavaCompiler.h"

#include "ModelBase/src/model/TreeManager.h"
#include "ModelBase/src/nodes/Node.h"

#include "VisualizationBase/src/items/Item.h"
#include "VisualizationBase/src/overlays/BoxOverlay.h"
#include "VisualizationBase/src/overlays/OverlayAccessor.h"

#include "JavaExport/src/exporter/JavaExporter.h"

#include "../CommandLineCompiler.h"
#include "../CompilerOutputParser.h"

namespace OODebug {

void JavaCompiler::compileTree(Model::TreeManager* manager, const QString& pathToProjectContainerDirectory)
{
	auto nodeItemMap = Visualization::Item::nodeItemsMap();

	std::shared_ptr<Export::TextToNodeMap> map;
	std::shared_ptr<Export::SourceDir> dir;

	auto exportErrors = JavaExport::JavaExporter::exportTree(manager, pathToProjectContainerDirectory, map, dir);
	// First handle export errors.
	for (auto& error : exportErrors)
	{
		auto node = error.node();
		auto it = nodeItemMap.find(node);
		while (it != nodeItemMap.end() && it.key() == node)
		{
			visualizeMessage(it.value(), node, error.message());
			++it;
		}
	}

	static const QString buildFolder("build");
	QDir buildDir(pathToProjectContainerDirectory + QDir::separator() + buildFolder);
	if (!buildDir.exists())
	{
		QDir projectDir(pathToProjectContainerDirectory);
		Q_ASSERT(projectDir.exists());
		Q_ASSERT(projectDir.mkdir(buildFolder));
	}
	const QStringList buildFolderArgs = {"-d", pathToProjectContainerDirectory + QDir::separator() + buildFolder};
	CommandLineCompiler compiler("javac", &CompilerOutputParser::parseJavacErrorFormat);

	for (auto file : dir->recursiveFiles())
	{
		Q_ASSERT(file);
		auto feedback = compiler.compileFile(pathToProjectContainerDirectory + QDir::separator() + file->path(),
														 buildFolderArgs);
		for (auto& message : feedback.messages())
		{
			// In the map we don't have the pathToProjectContainerDirectory prefix
			auto fileName = message->getFileName().remove(pathToProjectContainerDirectory + QDir::separator());
			// lines and columns -1 because javac begins at 1 and TextToNodeMap at 0
			Model::Node* node = nullptr;
			if (auto rootMsg = message->getRootMessage())
				node = map->node(fileName, rootMsg->getLineNumber() - 1, rootMsg->getColumnNumber() - 1);
			else
				node = map->node(fileName, message->getLineNumber() - 1, message->getColumnNumber() - 1);
			Q_ASSERT(node);

			auto it = nodeItemMap.find(node);
			while (it != nodeItemMap.end() && it.key() == node)
			{
				// TODO for notes which have a rootMessage add a link to the message location.
				visualizeMessage(it.value(), node, message->getMessage());
				++it;
			}
		}
	}
}

void JavaCompiler::visualizeMessage(Visualization::Item* item, Model::Node* node, const QString& message)
{
	static const QString overlayGroupName("CompilerMessages");

	auto scene = item->scene();
	auto overlayGroup = scene->overlayGroup(overlayGroupName);

	if (!overlayGroup) overlayGroup = scene->addOverlayGroup(overlayGroupName);

	overlayGroup->addOverlay(makeOverlay( new Visualization::BoxOverlay(item,
		[node, message](Visualization::BoxOverlay *){
		return message;
	})));
}

} /* namespace OODebug */
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2007-2013 Frank Mertens.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version
 * 2 of the License, or (at your option) any later version.
 */

#include <fkit/stdio.h>
#include <fkit/Pattern.h>
#include <fkit/File.h>
#include <fkit/Process.h>
#include <fkit/ProcessFactory.h>
#include "BuildPlan.h"
#include "GnuToolChain.h"

namespace fmake
{

GnuToolChain::GnuToolChain(String execPath)
	: ToolChain(execPath, queryMachine(execPath))
{}

String GnuToolChain::queryMachine(String execPath)
{
	return Process::start(machineCommand(execPath), Process::ForwardOutput)->lineOut()->readLine();
}

String GnuToolChain::machineCommand(String execPath)
{
	return execPath + " -dumpmachine";
}

String GnuToolChain::machineCommand() const
{
	return machineCommand(execPath());
}

int GnuToolChain::defaultSpeedOptimizationLevel() const
{
	return 2;
}

int GnuToolChain::defaultSizeOptimizationLevel() const
{
	return 1;
}

String GnuToolChain::analyseCommand(BuildPlan *plan, String source) const
{
	Format args;
	args << execPath();
	appendCompileOptions(args, plan);
	args << "-MM" << "-MG" << source;
	return args->join(" ");
}

Ref<Job> GnuToolChain::createAnalyseJob(BuildPlan *plan, String source)
{
	return Job::create(analyseCommand(plan, source));
}

Ref<Module> GnuToolChain::finishAnalyseJob(BuildPlan *plan, Job *job)
{
	Ref<StringList> parts = job->outputText()->split(Pattern("[:\\\\\n\r ]{1,}"));
	return Module::create(job->command(), plan->modulePath(parts->pop(0)), parts, true);
}

Ref<Job> GnuToolChain::createCompileJob(BuildPlan *plan, Module *module)
{
	Format args;
	args << execPath();
	appendCompileOptions(args, plan);
	args << "-c" << "-o" << module->modulePath();
	args << module->sourcePath();
	String command = args->join(" ");
	return Job::create(command);
}

Ref<Job> GnuToolChain::createLinkJob(BuildPlan *plan, Module *module)
{
	Format args;
	args << execPath();
	if (plan->options() & BuildPlan::Static) args << "-static";
	args << "-pthread";
	args << "-o" << module->toolName();
	args << module->modulePath();
	appendLinkOptions(args, plan);
	String command = args->join(" ");
	return Job::create(command);
}

Ref<Job> GnuToolChain::createTestJob(BuildPlan *plan, Module *module)
{
	return Job::create(module->toolName());
}

String GnuToolChain::linkName(BuildPlan *plan) const
{
	String name;
	if (plan->options() & BuildPlan::Library)
		name = "lib" + plan->name() + ".so." + plan->version();
	else
		name = plan->name();
	return name;
}

bool GnuToolChain::link(BuildPlan *plan)
{
	String name = plan->name();
	String version = plan->version();
	int options = plan->options();
	ModuleList *modules = plan->modules();

	Format args;

	args << execPath();
	if (options & BuildPlan::Static) args << "-static";
	if ((options & BuildPlan::Library) && !(options & BuildPlan::Static)) args << "-shared";
	args << "-pthread";

	if (options & BuildPlan::Library) {
		Ref<StringList> versions = version->split(".");
		args << "-Wl,-soname,lib" + name + ".so." + versions->at(0);
	}

	args << "-o" << linkName(plan);

	for (int i = 0; i < modules->size(); ++i)
		args << modules->at(i)->modulePath();

	appendLinkOptions(args, plan);

	String command = args->join(" ");

	if (!plan->shell()->run(command))
		return false;

	if ((options & BuildPlan::Library) && !(options & BuildPlan::Static))
		createLibrarySymlinks(plan, linkName(plan));

	return true;
}

bool GnuToolChain::linkTest(BuildPlan *plan, String linkPath, StringList *linkTest) const
{
	Ref<File> src = File::temp();
	src->unlinkWhenDone();
	src->write("int main() { return 0; }\n");
	src->close();
	Format args;
	args << execPath() << src->path() << "-L" + linkPath;
	for (int i = 0; i < linkTest->size(); ++i) args << "-l" + linkTest->at(i);
	args << "-o" + src->path() + "_";

	String command = args->join(" ");
	return plan->shell()->run(command);
}

bool GnuToolChain::install(BuildPlan *plan)
{
	String product = linkName(plan);
	int options = plan->options();
	String installPath = plan->installPath(
		((options & BuildPlan::Library) ? "lib/" : "bin/") + product
	);
	if (!plan->shell()->install(product, installPath)) return false;
	if ((options & BuildPlan::Library) && !(options & BuildPlan::Static))
		createLibrarySymlinks(plan, installPath);
	return true;
}

bool GnuToolChain::install(BuildPlan *plan, Module *module)
{
	String product = module->toolName();
	return plan->shell()->install(product, plan->installPath("bin/" + product));
}

bool GnuToolChain::uninstall(BuildPlan *plan)
{
	String product = linkName(plan);
	int options = plan->options();
	String installPath = plan->installPath(
		((options & BuildPlan::Library) ? "lib/" : "bin/") + product
	);
	if (!plan->shell()->unlink(installPath)) return false;
	if ((options & BuildPlan::Library) && !(options & BuildPlan::Static))
		cleanLibrarySymlinks(plan, installPath);
	return false;
}

bool GnuToolChain::uninstall(BuildPlan *plan, Module *module)
{
	return plan->shell()->unlink(plan->installPath("bin/" + module->toolName()));
}

void GnuToolChain::clean(BuildPlan *plan)
{
	for (int i = 0; i < plan->modules()->size(); ++i) {
		plan->shell()->unlink(plan->modules()->at(i)->modulePath());
		if (plan->options() & BuildPlan::Tools)
			plan->shell()->unlink(plan->modules()->at(i)->toolName());
	}

	String product = linkName(plan);
	plan->shell()->unlink(product);

	if ((plan->options() & BuildPlan::Library) && !(plan->options() & BuildPlan::Static))
		cleanLibrarySymlinks(plan, product);
}

void GnuToolChain::appendCompileOptions(Format args, BuildPlan *plan)
{
	// args << "-std=c++0x";
	if (plan->options() & BuildPlan::Debug) args << "-g";
	if (plan->options() & BuildPlan::Release) args << "-DNDEBUG";
	if (plan->options() & BuildPlan::OptimizeSpeed) args << String(Format("-O") << plan->speedOptimizationLevel());
	if (plan->options() & BuildPlan::OptimizeSize) args << "-Os";
	if (plan->options() & BuildPlan::OptimizeDebug) args << "-Og";
	if (plan->options() & BuildPlan::Static) args << "-static";
	if (plan->options() & BuildPlan::Library) args << "-fPIC";
	else args << "-fPIE";
	args << "-Wall" << "-pthread";
	if (plan->customCompileFlags()) {
		for (int i = 0; i < plan->customCompileFlags()->size(); ++i)
			args << plan->customCompileFlags()->at(i);
	}
	for (int i = 0; i < plan->includePaths()->size(); ++i)
		args << "-I" + plan->includePaths()->at(i);
}

void GnuToolChain::appendLinkOptions(Format args, BuildPlan *plan)
{
	if (plan->customLinkFlags()) {
		for (int i = 0; i < plan->customLinkFlags()->size(); ++i)
			args << plan->customLinkFlags()->at(i);
	}

	StringList *libraryPaths = plan->libraryPaths();
	StringList *libraries = plan->libraries();

	for (int i = 0; i < libraryPaths->size(); ++i)
		args << "-L" + libraryPaths->at(i);

	for (int i = 0; i < libraries->size(); ++i)
		args << "-l" + libraries->at(i);

	if (libraryPaths->size() > 0) {
		Ref<StringList> rpaths = StringList::create();
		for (int i = 0; i < libraryPaths->size(); ++i)
			*rpaths << "-rpath=" + libraryPaths->at(i)->absolutePath();
		args << "-Wl,--enable-new-dtags," + rpaths->join(",");
	}
}

void GnuToolChain::createLibrarySymlinks(BuildPlan *plan, String libPath)
{
	cleanLibrarySymlinks(plan, libPath);

	Ref<StringList> parts = libPath->split('.');
	while (parts->popBack() != "so")
		plan->shell()->symlink(libPath, parts->join("."));
}

void GnuToolChain::cleanLibrarySymlinks(BuildPlan *plan, String libPath)
{
	Ref<StringList> parts = libPath->split('.');
	while (parts->popBack() != "so")
		plan->shell()->unlink(parts->join("."));
}

} // namespace fmake
<commit_msg>Improved speed of tool chain instantiation by using env MACHTYPE.<commit_after>/*
 * Copyright (C) 2007-2013 Frank Mertens.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version
 * 2 of the License, or (at your option) any later version.
 */

#include <fkit/stdio.h>
#include <fkit/Pattern.h>
#include <fkit/File.h>
#include <fkit/Process.h>
#include <fkit/ProcessFactory.h>
#include "BuildPlan.h"
#include "GnuToolChain.h"

namespace fmake
{

GnuToolChain::GnuToolChain(String execPath)
	: ToolChain(execPath, queryMachine(execPath))
{}

String GnuToolChain::queryMachine(String execPath)
{
	String machType = Process::env("MACHTYPE");
	if (machType != "") return machType;
	return Process::start(machineCommand(execPath), Process::ForwardOutput)->lineOut()->readLine();
}

String GnuToolChain::machineCommand(String execPath)
{
	return execPath + " -dumpmachine";
}

String GnuToolChain::machineCommand() const
{
	return machineCommand(execPath());
}

int GnuToolChain::defaultSpeedOptimizationLevel() const
{
	return 2;
}

int GnuToolChain::defaultSizeOptimizationLevel() const
{
	return 1;
}

String GnuToolChain::analyseCommand(BuildPlan *plan, String source) const
{
	Format args;
	args << execPath();
	appendCompileOptions(args, plan);
	args << "-MM" << "-MG" << source;
	return args->join(" ");
}

Ref<Job> GnuToolChain::createAnalyseJob(BuildPlan *plan, String source)
{
	return Job::create(analyseCommand(plan, source));
}

Ref<Module> GnuToolChain::finishAnalyseJob(BuildPlan *plan, Job *job)
{
	Ref<StringList> parts = job->outputText()->split(Pattern("[:\\\\\n\r ]{1,}"));
	return Module::create(job->command(), plan->modulePath(parts->pop(0)), parts, true);
}

Ref<Job> GnuToolChain::createCompileJob(BuildPlan *plan, Module *module)
{
	Format args;
	args << execPath();
	appendCompileOptions(args, plan);
	args << "-c" << "-o" << module->modulePath();
	args << module->sourcePath();
	String command = args->join(" ");
	return Job::create(command);
}

Ref<Job> GnuToolChain::createLinkJob(BuildPlan *plan, Module *module)
{
	Format args;
	args << execPath();
	if (plan->options() & BuildPlan::Static) args << "-static";
	args << "-pthread";
	args << "-o" << module->toolName();
	args << module->modulePath();
	appendLinkOptions(args, plan);
	String command = args->join(" ");
	return Job::create(command);
}

Ref<Job> GnuToolChain::createTestJob(BuildPlan *plan, Module *module)
{
	return Job::create(module->toolName());
}

String GnuToolChain::linkName(BuildPlan *plan) const
{
	String name;
	if (plan->options() & BuildPlan::Library)
		name = "lib" + plan->name() + ".so." + plan->version();
	else
		name = plan->name();
	return name;
}

bool GnuToolChain::link(BuildPlan *plan)
{
	String name = plan->name();
	String version = plan->version();
	int options = plan->options();
	ModuleList *modules = plan->modules();

	Format args;

	args << execPath();
	if (options & BuildPlan::Static) args << "-static";
	if ((options & BuildPlan::Library) && !(options & BuildPlan::Static)) args << "-shared";
	args << "-pthread";

	if (options & BuildPlan::Library) {
		Ref<StringList> versions = version->split(".");
		args << "-Wl,-soname,lib" + name + ".so." + versions->at(0);
	}

	args << "-o" << linkName(plan);

	for (int i = 0; i < modules->size(); ++i)
		args << modules->at(i)->modulePath();

	appendLinkOptions(args, plan);

	String command = args->join(" ");

	if (!plan->shell()->run(command))
		return false;

	if ((options & BuildPlan::Library) && !(options & BuildPlan::Static))
		createLibrarySymlinks(plan, linkName(plan));

	return true;
}

bool GnuToolChain::linkTest(BuildPlan *plan, String linkPath, StringList *linkTest) const
{
	Ref<File> src = File::temp();
	src->unlinkWhenDone();
	src->write("int main() { return 0; }\n");
	src->close();
	Format args;
	args << execPath() << src->path() << "-L" + linkPath;
	for (int i = 0; i < linkTest->size(); ++i) args << "-l" + linkTest->at(i);
	args << "-o" + src->path() + "_";

	String command = args->join(" ");
	return plan->shell()->run(command);
}

bool GnuToolChain::install(BuildPlan *plan)
{
	String product = linkName(plan);
	int options = plan->options();
	String installPath = plan->installPath(
		((options & BuildPlan::Library) ? "lib/" : "bin/") + product
	);
	if (!plan->shell()->install(product, installPath)) return false;
	if ((options & BuildPlan::Library) && !(options & BuildPlan::Static))
		createLibrarySymlinks(plan, installPath);
	return true;
}

bool GnuToolChain::install(BuildPlan *plan, Module *module)
{
	String product = module->toolName();
	return plan->shell()->install(product, plan->installPath("bin/" + product));
}

bool GnuToolChain::uninstall(BuildPlan *plan)
{
	String product = linkName(plan);
	int options = plan->options();
	String installPath = plan->installPath(
		((options & BuildPlan::Library) ? "lib/" : "bin/") + product
	);
	if (!plan->shell()->unlink(installPath)) return false;
	if ((options & BuildPlan::Library) && !(options & BuildPlan::Static))
		cleanLibrarySymlinks(plan, installPath);
	return false;
}

bool GnuToolChain::uninstall(BuildPlan *plan, Module *module)
{
	return plan->shell()->unlink(plan->installPath("bin/" + module->toolName()));
}

void GnuToolChain::clean(BuildPlan *plan)
{
	for (int i = 0; i < plan->modules()->size(); ++i) {
		plan->shell()->unlink(plan->modules()->at(i)->modulePath());
		if (plan->options() & BuildPlan::Tools)
			plan->shell()->unlink(plan->modules()->at(i)->toolName());
	}

	String product = linkName(plan);
	plan->shell()->unlink(product);

	if ((plan->options() & BuildPlan::Library) && !(plan->options() & BuildPlan::Static))
		cleanLibrarySymlinks(plan, product);
}

void GnuToolChain::appendCompileOptions(Format args, BuildPlan *plan)
{
	// args << "-std=c++0x";
	if (plan->options() & BuildPlan::Debug) args << "-g";
	if (plan->options() & BuildPlan::Release) args << "-DNDEBUG";
	if (plan->options() & BuildPlan::OptimizeSpeed) args << String(Format("-O") << plan->speedOptimizationLevel());
	if (plan->options() & BuildPlan::OptimizeSize) args << "-Os";
	if (plan->options() & BuildPlan::OptimizeDebug) args << "-Og";
	if (plan->options() & BuildPlan::Static) args << "-static";
	if (plan->options() & BuildPlan::Library) args << "-fPIC";
	else args << "-fPIE";
	args << "-Wall" << "-pthread";
	if (plan->customCompileFlags()) {
		for (int i = 0; i < plan->customCompileFlags()->size(); ++i)
			args << plan->customCompileFlags()->at(i);
	}
	for (int i = 0; i < plan->includePaths()->size(); ++i)
		args << "-I" + plan->includePaths()->at(i);
}

void GnuToolChain::appendLinkOptions(Format args, BuildPlan *plan)
{
	if (plan->customLinkFlags()) {
		for (int i = 0; i < plan->customLinkFlags()->size(); ++i)
			args << plan->customLinkFlags()->at(i);
	}

	StringList *libraryPaths = plan->libraryPaths();
	StringList *libraries = plan->libraries();

	for (int i = 0; i < libraryPaths->size(); ++i)
		args << "-L" + libraryPaths->at(i);

	for (int i = 0; i < libraries->size(); ++i)
		args << "-l" + libraries->at(i);

	if (libraryPaths->size() > 0) {
		Ref<StringList> rpaths = StringList::create();
		for (int i = 0; i < libraryPaths->size(); ++i)
			*rpaths << "-rpath=" + libraryPaths->at(i)->absolutePath();
		args << "-Wl,--enable-new-dtags," + rpaths->join(",");
	}
}

void GnuToolChain::createLibrarySymlinks(BuildPlan *plan, String libPath)
{
	cleanLibrarySymlinks(plan, libPath);

	Ref<StringList> parts = libPath->split('.');
	while (parts->popBack() != "so")
		plan->shell()->symlink(libPath, parts->join("."));
}

void GnuToolChain::cleanLibrarySymlinks(BuildPlan *plan, String libPath)
{
	Ref<StringList> parts = libPath->split('.');
	while (parts->popBack() != "so")
		plan->shell()->unlink(parts->join("."));
}

} // namespace fmake
<|endoftext|>


<commit_before>/**

Electron library for communicating with SDI-12 slaves over RS232/485.

Adapted for Electron Robyn Hannah NRI Electronics June 2016
Currently Copyright NRI Electronics 2016. Can be used for evaluation purposes.

*/
/*
*/

/* _____PROJECT INCLUDES_____________________________________________________ */
#include "SDI12Master.h"
#include "Serial4/Serial4.h"	// for some reason this has to be in this file, not xxxx.h file
#include "Serial5/Serial5.h"

#undef SPARK_SERIAL2 		// #define once Spark Serial2 is implemented

/* _____GLOBAL VARIABLES_____________________________________________________ */
USARTSerial SDISerial = Serial1; 	///< Pointer to Serial1 class object

/* _____PUBLIC FUNCTIONS_____________________________________________________ */
/**
Constructor.

Creates class object using given serial port , SDI-12 slave defaults to ID  0.

@ingroup setup
*/
SDI12Master::SDI12Master(char _port)
{
	serialPort = _port;
	slaveID = 0;
}
/*
Destructor
*/
SDI12Master::~SDI12Master()
{
	Serial.println("the end has come");
}

// sets a print out debug mode
void SDI12Master::setDebug(bool _debug)
{
	debugMode = _debug;
}

/**
Initialize class object.

Sets up the serial port using 1200, E,7,1 which is SDI-12 standard

*/
void SDI12Master::begin(char _serialPort)
{
	txBufferIndex = 0;
	txBufferLength = 0;
	rxBufferIndex = 0;
	rxBufferLength = 0;

	switch(serialPort){
		case 1:
			SDISerial = Serial1;
			pinMode(TX,OUTPUT);
			digitalWrite(TX,HIGH);		// output is inverted, will put low on SDI-12 line
			break;
		/*    case 2:
				SDISerial = Serial2;
				break;	// to use Serial 2 would need to #include "Serial2/Serial2.h" at top*/
		case 4:
			SDISerial = Serial4;
			pinMode(C3,OUTPUT);
			digitalWrite(C3,HIGH);		// output is inverted, will put low on SDI-12 line
			break;
		case 5:
			SDISerial = Serial5;
			pinMode(C1,OUTPUT);
			digitalWrite(C1,HIGH);		// output is inverted, will put low on SDI-12 line
			break;
		default:
			SDISerial = Serial1;		// Default to Serial1 for Electron
			pinMode(TX,OUTPUT);
			digitalWrite(TX,HIGH);		// output is inverted, will put low on SDI-12 line
			break;
	}
	pinMode(txEnablePin,OUTPUT);
	digitalWrite(txEnablePin,txEnableState);
	pinMode(rxEnablePin,OUTPUT);
	digitalWrite(rxEnablePin,rxDisableState);
	pinMode(biasPin,OUTPUT);
	digitalWrite(biasPin,HIGH);
	SDISerial.begin(1200,SERIAL_7E1);	// SERIAL_7E1 not implemented in firmware yet, goes to 8N1 with cluge
}

/**
Set idle time callback function (cooperative multitasking).

This function gets called in the idle time between transmission of data
and response from slave. Do not call functions that read from the serial
buffer that is used by SDI12Master. Use of i2c/TWI, 1-Wire, other
serial ports, etc. is permitted within callback function.

@see SDI12Master::ModbusMasterTransaction()
*/
void SDI12Master::idle(void (*idle)())
{
	_idle = idle;
}

/* Function turns bytes - 8 bits -  in a string into a 7 bit data and even parity setting in the msb
		Assumes the msb of c is not set, ie 7 bit data already, if it is set then the routine
		is pointless as it is trying to convert 7 bit characters for transmission by 8N1
		Routine also assumes the string is null terminated     */
void SDI12Master::to7E1(char* ptrC)
{
	char lookup[8] = {0,1,1,0,1,0,0,1};
	char p;
	if(debugMode)Serial.println("Changing the string to 7E1");
	while(*ptrC){
		p = (*ptrC ^ (*ptrC>>4)) & 0x0f;
		if(lookup[p&0x07] ^ (p>>3)){
			*ptrC = *ptrC | 0x80;		// set parity
		}
		ptrC++;
	}
}

/* Reverse of the above, it is taking in characters which are 7E1 and converting them to 7 bit
		characters in the string, can optionally check for parity errors on the characters
		using the msb of the character as the E parity bit*/
bool SDI12Master::from7E1(char* ptrC)
{
	char lookup[8] = {0,1,1,0,1,0,0,1};
	char p,C;
	bool result = false;
	if(debugMode)Serial.println("Translating back to characters from 7E1");
	while(*ptrC){
		C = *ptrC & 0x7f;		// clear parity
		// find out if parity should have been set on the character
		p = (C ^ (C>>4)) & 0x0f;
		if(lookup[p&0x07] ^ (p>>3)){
			if((*ptrC & 0x80)==0x80)result = true;
		}
		else{
			if((*ptrC & 0x80)== 0x00)result = true;
		}
		*ptrC = C;
		ptrC++;
	}
	return result;	// returns false if there was an error on the string
}

/*
Send a command to the SDI-12 sensor bus
char sdi_cmd(char* _sCmd)
The _sCmd string must be zero terminated and must be the complete command
	ie slaveID|Function|!
	return is a char* to the rxBuffer containing the immediate response
	If the command is a start measurement M then the function parses the response to
	obtain the time before the measurement will be available (milliseconds) and the number of sensors
	that will be read. These are sent to the public variables int availTime; and char sensorCount;
	Returns a result of sdiSuccess (0) if all OK else sdiFail (1) or sdiTimeout (2)
*/
char SDI12Master::sdi_cmd(char* _sCmd)
{
	char index,cnt,i;
	char* ptr;
	char* xptr;
	float fvalue[5];
	/* need to create a buffer which is really 7E1 characters, Electron can only
		handle 8N1 at present */
	strcpy(&txBuffer[0],_sCmd);
	if(txBuffer[0] == '?')slaveID = '?';
	else slaveID = txBuffer[0] - 0x30;	 // obviously only works for addresses 0 -> 9
	if(SERIAL_7E1 == SERIAL_8N1){
		// someday there will be a SERIAL_7E1 available, till then cluge it
		to7E1(&txBuffer[0]);
	}
	char result = sdiSuccess;
	sdi_break();	// send break
	sdi_transmit(&txBuffer[0]);
	digitalWrite(rxEnablePin,rxEnableState);
	digitalWrite(txEnablePin,txDisableState);
	result = sdi_receive();
	if(debugMode)Serial.printlnf("Received string %s : Parity %i",&rxBuffer[0],result);
	_sCmd++;
	switch(*_sCmd){
		case 'M':
			if(result == sdiSuccess){
				// just check that the aM! bit was not included
				if(xptr = strstr(&rxBuffer[0],"M!")){
					xptr = xptr + 2;
				}
				else{
					xptr = strchr(&rxBuffer[0],(slaveID+0x30));
				}
				sensorCount = *(xptr+4) - 0x30;
				if((sensorCount < 1) || (sensorCount > 9))result = sdiReplyError;
				*(xptr+4) = 0;
				xptr++;
				availTime = atoi(xptr);
				*(xptr+3) = sensorCount + 0x30;	// restore for posterity
			}
			break;
		case 'D':
			if(result == sdiSuccess){
				cnt = 0;
				_sCmd++;
				index = (*_sCmd - 0x30); 	// 0, 1 etc
				ptr = &rxBuffer[0];
                while(*ptr){
                    while((*ptr != '+') && (*ptr != '-') && (*ptr != 0))ptr++;		// go to first sign character
					if((*ptr=='+') || (*ptr=='-')){
						fvalue[cnt] = atof(ptr);
						cnt++;
						ptr++;	// go look for the next sign
					}
				}
				index = index * cnt;	// starting point on the results table
				for(i=0;i<cnt;i++)sensorReadings[index+i] = fvalue[i];
				sensorsRead = cnt;
			}
			break;
		case 'I':
			// Send identification, result in rxBuffer
			break;
		case '!':
			if(slaveID == '?'){
				// this is an address query
				if(result == sdiSuccess){
					slaveID = rxBuffer[0] - 0x30;	// available to read
				}
			}
			else{
				// acknowledge active, result is in result
			}
			break;

	}
	return result;
}

/*
Wake request. Function puts a break on the SDI-12 line for the duration of the delay
*/
void SDI12Master::sdi_wake(int delay)
{
	unsigned long timeStart;
	SDISerial.end();
	digitalWrite(rxEnablePin,rxDisableState);
	digitalWrite(txEnablePin,txEnableState);
	digitalWrite(biasPin,HIGH);
	timeStart = millis();
	switch(serialPort){
		case 1:
			pinMode(TX,OUTPUT);
			digitalWrite(TX,LOW);
			break;
		case 4:
			pinMode(C3,OUTPUT);
			digitalWrite(C3,LOW);
			break;
		case 5:
			pinMode(C1,OUTPUT);
			digitalWrite(C1,LOW);
			break;
		default:
			pinMode(TX,OUTPUT);
			digitalWrite(TX,LOW);
			break;
	}
	while(millis() < timeStart + delay);
	SDISerial.begin(1200,SERIAL_7E1);	// re enable Serial
}

/*
Sleep state request. Function puts both rx and tx into disabled state and drops the bias pin to LOW
 void sdi_sleep(void);
*/
void SDI12Master::sdi_sleep(void)
{
	if(txEnableState == HIGH)digitalWrite(txEnablePin,LOW);
	else digitalWrite(txEnablePin,HIGH);
	if(rxEnableState == HIGH)digitalWrite(rxEnablePin,LOW);
	else digitalWrite(rxEnablePin,HIGH);
	digitalWrite(biasPin,LOW);;
}

/* _____PRIVATE FUNCTIONS____________________________________________________ */
/*

/* Function puts a break on the SDI-12 data line
		Disables the serial port to do so, does not re enable
*/
void SDI12Master::sdi_break(void)
{
	unsigned long timeStart;
	SDISerial.end();
	if(debugMode)Serial.println("Sending a break signal");
	digitalWrite(rxEnablePin,rxDisableState);
	digitalWrite(txEnablePin,txEnableState);
	digitalWrite(biasPin,HIGH);
	timeStart = millis();
	switch(serialPort){
		case 1:
			pinMode(TX,OUTPUT);
			digitalWrite(TX,LOW);
			break;
		case 4:
			pinMode(C3,OUTPUT);
			digitalWrite(C3,LOW);
			break;
		case 5:
			pinMode(C1,OUTPUT);
			digitalWrite(C1,LOW);
			break;
		default:
			pinMode(TX,OUTPUT);
			digitalWrite(TX,LOW);
			break;
	}
	while(millis() < timeStart + breakTimeMin);
	SDISerial.begin(1200,SERIAL_7E1);	// re enable Serial
	SDISerial.flush();
}

/* Function puts a mark on the SDI-12 data line, assumes the break function has disabled Serial
		and all is OK to lower the signal on the TX line
		have determined that the serial line goes to mark state when I begin the serial above
		otherwise there is a glitch after my mark and the begin which upsets things.
		Finding that it is 8 bits plus parity which is odd, not 7 plus parity
		Currently this is not called because the SDISerial.begin sequence in the break routine
		takes approximately 10 mSec to come good, this is about the mark time required
*/
void SDI12Master::sdi_mark()
{
	unsigned long timeStart;
	timeStart = millis();
	switch(serialPort){
		case 1:
			pinMode(TX,OUTPUT);
			digitalWrite(TX,HIGH);
			break;
		case 4:
			pinMode(C3,OUTPUT);
			digitalWrite(C3,HIGH);
			break;
		case 5:
			pinMode(C1,OUTPUT);
			digitalWrite(C1,HIGH);
			break;
		default:
			pinMode(TX,OUTPUT);
			digitalWrite(TX,HIGH);
			break;
	}
	while(millis() < timeStart + markTimeMin);
	SDISerial.begin(1200,SERIAL_7E1);	// re enable Serial
	SDISerial.flush();
	while(SDISerial.available()){
		// I am not positive that the flush really clears the receive buffer so do it anyway
		SDISerial.read();
	}

}
void SDI12Master::sdi_transmit(char* ptr)
{
	int bytesW;
	if(debugMode)Serial.printlnf("Transmitting %s", ptr);
	while(*ptr != 0){
		bytesW = SDISerial.write(*ptr);
		SDISerial.flush();		// does not work properly but does wait for the current character to leave
		//if(debugMode)Serial.printlnf("Byte written %i %x",bytesW,*ptr);
		ptr++;
	}
	delay(delayAfterTransmit);
	//digitalWrite(rxEnablePin,rxEnableState);
	//digitalWrite(txEnablePin,txDisableState);
}
char SDI12Master::sdi_receive(void)
{
	/* This will timeout after maxSensorResponseTime if a response has not happened
		and after maxTotalResponseTime even if it is still receiving data	*/
	unsigned long timeStart;
	char read;
	bool resEnd = false;
	bool resStart = false;
	int cnt = 0;

	//digitalWrite(rxEnablePin,rxEnableState);
	//digitalWrite(txEnablePin,txDisableState);
	rxBuffer[0] = 0;
	//slaveID = (txBuffer[0]&0x7f)-0x30;
	timeStart = millis();
	//digitalWrite(rxEnablePin,rxEnableState);
	//digitalWrite(txEnablePin,txDisableState);
	if(debugMode)Serial.printlnf("Receiving characters - expecting from %x",slaveID);
	if(slaveID == '?'){
		resStart = true;
		rxBufferIndex = 0;
		rxBufferLength = 0;
	}
	while (!resEnd && (millis() < (timeStart + maxTotalResponseTime))){
		if (SDISerial.available()){
			read = SDISerial.read();
			//if(debugMode)Serial.write(read);
			if(((read&0x7f-0x30) == slaveID)  && !resStart){
				// response starts with slave ID or the case of address query it is '?'
				resStart = true;
				rxBufferIndex = 0;
				rxBufferLength = 0;
			}
			if(resStart && (rxBufferIndex < sizeBuffer)){
				rxBuffer[rxBufferIndex] = read;
				//if(debugMode)Serial.write(read);
				rxBufferIndex++;
				rxBuffer[rxBufferIndex] = 0;
			}
			if(SERIAL_7E1 == SERIAL_8N1){
				if((read == 0x0a) && (rxBuffer[rxBufferIndex-2] == 0x8d)){
					// 0x0a,0x8d will be the 8N1 equivalent of the 7E1 version of '\n' and '\r'
					resEnd = true;
				}
			}
			else{
				if((read == '\n') && (rxBuffer[rxBufferIndex-2] == '\r')){
					resEnd = true;
				}
			}
		}
	}
	if(resEnd){
		if(SERIAL_7E1 == SERIAL_8N1){
			/* Until SERIAL_7E1 is in firmware we need to do a cluge
					we did get a response, need to translate this back to 7 bit characters and check parity*/
			if(from7E1(&rxBuffer[0])){
				return sdiSuccess;
			}
			else return sdiParityError;
		}
		else{
			return sdiSuccess;	// there does not seem to be any parity checks available in firmware?
		}
	}
	else return sdiTimeout;
}
<commit_msg>Delete SDI12Master.cpp<commit_after><|endoftext|>


<commit_before><commit_msg>remove run number from argument list<commit_after><|endoftext|>


<commit_before>#include "FlowControllerFactory.hpp"
#include "FlowControllerImpl.hpp"

#include <fastdds/dds/log/Log.hpp>

namespace eprosima {
namespace fastdds {
namespace rtps {

const char* const pure_sync_flow_controller_name = "PureSyncFlowController";
const char* const sync_flow_controller_name = "SyncFlowController";
const char* const async_flow_controller_name = "AsyncFlowController";
#ifdef FASTDDS_STATISTICS
const char* const async_statistics_flow_controller_name = "AsyncStatisticsFlowController";
#endif // ifndef FASTDDS_STATISTICS

void FlowControllerFactory::init(
        fastrtps::rtps::RTPSParticipantImpl* participant)
{
    participant_ = participant;
    // Create default flow controllers.

    // PureSyncFlowController -> used by volatile besteffort writers.
    flow_controllers_.insert(std::make_pair<std::string, std::unique_ptr<FlowController>>(
                pure_sync_flow_controller_name,
                std::unique_ptr<FlowController>(
                    new FlowControllerImpl<FlowControllerPureSyncPublishMode,
                    FlowControllerFifoSchedule>(participant_, nullptr))));
    // SyncFlowController -> used by rest of besteffort writers.
    flow_controllers_.insert(std::make_pair<std::string, std::unique_ptr<FlowController>>(
                sync_flow_controller_name,
                std::unique_ptr<FlowController>(
                    new FlowControllerImpl<FlowControllerSyncPublishMode,
                    FlowControllerFifoSchedule>(participant_, nullptr))));
    // AsyncFlowController
    flow_controllers_.insert(std::make_pair<std::string, std::unique_ptr<FlowController>>(
                async_flow_controller_name,
                std::unique_ptr<FlowController>(
                    new FlowControllerImpl<FlowControllerAsyncPublishMode,
                    FlowControllerFifoSchedule>(participant_, nullptr))));

#ifdef FASTDDS_STATISTICS
    flow_controllers_.insert({async_statistics_flow_controller_name,
                              std::unique_ptr<FlowController>(
                                  new FlowControllerImpl<FlowControllerAsyncPublishMode,
                                  FlowControllerFifoSchedule>(participant_, nullptr))});
#endif // ifndef FASTDDS_STATISTICS
}

void FlowControllerFactory::register_flow_controller (
        const FlowControllerDescriptor& flow_controller_descr)
{
    if (flow_controllers_.end() != flow_controllers_.find(flow_controller_descr.name))
    {
        logError(RTPS_PARTICIPANT,
                "Error registering FlowController " << flow_controller_descr.name << ". Already registered");
        return;
    }

    if (0 < flow_controller_descr.max_bytes_per_period)
    {
        switch (flow_controller_descr.scheduler)
        {
            case FlowControllerSchedulerPolicy::FIFO:
                flow_controllers_.insert({flow_controller_descr.name,
                                          std::unique_ptr<FlowController>(
                                              new FlowControllerImpl<FlowControllerLimitedAsyncPublishMode,
                                              FlowControllerFifoSchedule>(participant_, &flow_controller_descr))});
                break;
            case FlowControllerSchedulerPolicy::ROUND_ROBIN:
                flow_controllers_.insert({flow_controller_descr.name,
                                          std::unique_ptr<FlowController>(
                                              new FlowControllerImpl<FlowControllerLimitedAsyncPublishMode,
                                              FlowControllerRoundRobinSchedule>(participant_,
                                              &flow_controller_descr))});
                break;
            case FlowControllerSchedulerPolicy::HIGH_PRIORITY:
                flow_controllers_.insert({flow_controller_descr.name,
                                          std::unique_ptr<FlowController>(
                                              new FlowControllerImpl<FlowControllerLimitedAsyncPublishMode,
                                              FlowControllerHighPrioritySchedule>(participant_,
                                              &flow_controller_descr))});
                break;
            case FlowControllerSchedulerPolicy::PRIORITY_WITH_RESERVATION:
                flow_controllers_.insert({flow_controller_descr.name,
                                          std::unique_ptr<FlowController>(
                                              new FlowControllerImpl<FlowControllerLimitedAsyncPublishMode,
                                              FlowControllerPriorityWithReservationSchedule>(participant_,
                                              &flow_controller_descr))});
                break;
            default:
                assert(false);
        }
    }
    else
    {
        switch (flow_controller_descr.scheduler)
        {
            case FlowControllerSchedulerPolicy::FIFO:
                flow_controllers_.insert({flow_controller_descr.name,
                                          std::unique_ptr<FlowController>(
                                              new FlowControllerImpl<FlowControllerAsyncPublishMode,
                                              FlowControllerFifoSchedule>(participant_, &flow_controller_descr))});
                break;
            case FlowControllerSchedulerPolicy::ROUND_ROBIN:
                flow_controllers_.insert({flow_controller_descr.name,
                                          std::unique_ptr<FlowController>(
                                              new FlowControllerImpl<FlowControllerAsyncPublishMode,
                                              FlowControllerRoundRobinSchedule>(participant_,
                                              &flow_controller_descr))});
                break;
            case FlowControllerSchedulerPolicy::HIGH_PRIORITY:
                flow_controllers_.insert({flow_controller_descr.name,
                                          std::unique_ptr<FlowController>(
                                              new FlowControllerImpl<FlowControllerAsyncPublishMode,
                                              FlowControllerHighPrioritySchedule>(participant_,
                                              &flow_controller_descr))});
                break;
            case FlowControllerSchedulerPolicy::PRIORITY_WITH_RESERVATION:
                flow_controllers_.insert({flow_controller_descr.name,
                                          std::unique_ptr<FlowController>(
                                              new FlowControllerImpl<FlowControllerAsyncPublishMode,
                                              FlowControllerPriorityWithReservationSchedule>(participant_,
                                              &flow_controller_descr))});
                break;
            default:
                assert(false);
        }
    }
}

/*!
 * Get a FlowController given its name.
 *
 * @param flow_controller_name Name of the interested FlowController.
 * @return Pointer to the FlowController. nullptr if no registered FlowController with that name.
 */
FlowController* FlowControllerFactory::retrieve_flow_controller(
        const std::string& flow_controller_name,
        const fastrtps::rtps::WriterAttributes& writer_attributes)
{
    FlowController* returned_flow = nullptr;

    // Detect it has to be returned a default flow_controller.
    if (0 == flow_controller_name.compare(FASTDDS_FLOW_CONTROLLER_DEFAULT))
    {
        if (fastrtps::rtps::SYNCHRONOUS_WRITER == writer_attributes.mode)
        {
            if (fastrtps::rtps::BEST_EFFORT == writer_attributes.endpoint.reliabilityKind)
            {
                returned_flow = flow_controllers_[pure_sync_flow_controller_name].get();
            }
            else
            {
                returned_flow = flow_controllers_[sync_flow_controller_name].get();
            }
        }
        else
        {
            returned_flow = flow_controllers_[async_flow_controller_name].get();
        }
    }
#ifdef FASTDDS_STATISTICS
    else if (0 == flow_controller_name.compare(FASTDDS_STATISTICS_FLOW_CONTROLLER_DEFAULT))
    {
        assert(fastrtps::rtps::ASYNCHRONOUS_WRITER == writer_attributes.mode);
        returned_flow = flow_controllers_[async_statistics_flow_controller_name].get();
    }
#endif // ifdef FASTDDS_STATISTICS
    else
    {
        auto it = flow_controllers_.find(flow_controller_name);

        if (flow_controllers_.end() != it)
        {
            returned_flow = it->second.get();
        }
    }

    if (nullptr != returned_flow)
    {
        returned_flow->init();
    }
    else
    {
        logError(RTPS_PARTICIPANT,
                "Cannot find FlowController " << flow_controller_name << ".");
    }

    return returned_flow;
}

} // namespace rtps
} // namespace fastdds
} // namespace eprosima
<commit_msg>Fix build on old compilers when FASTDDS_STATISTICS is define (#2929)<commit_after>#include "FlowControllerFactory.hpp"
#include "FlowControllerImpl.hpp"

#include <fastdds/dds/log/Log.hpp>

namespace eprosima {
namespace fastdds {
namespace rtps {

const char* const pure_sync_flow_controller_name = "PureSyncFlowController";
const char* const sync_flow_controller_name = "SyncFlowController";
const char* const async_flow_controller_name = "AsyncFlowController";
#ifdef FASTDDS_STATISTICS
const char* const async_statistics_flow_controller_name = "AsyncStatisticsFlowController";
#endif // ifndef FASTDDS_STATISTICS

void FlowControllerFactory::init(
        fastrtps::rtps::RTPSParticipantImpl* participant)
{
    participant_ = participant;
    // Create default flow controllers.

    // PureSyncFlowController -> used by volatile besteffort writers.
    flow_controllers_.insert(std::make_pair<std::string, std::unique_ptr<FlowController>>(
                pure_sync_flow_controller_name,
                std::unique_ptr<FlowController>(
                    new FlowControllerImpl<FlowControllerPureSyncPublishMode,
                    FlowControllerFifoSchedule>(participant_, nullptr))));
    // SyncFlowController -> used by rest of besteffort writers.
    flow_controllers_.insert(std::make_pair<std::string, std::unique_ptr<FlowController>>(
                sync_flow_controller_name,
                std::unique_ptr<FlowController>(
                    new FlowControllerImpl<FlowControllerSyncPublishMode,
                    FlowControllerFifoSchedule>(participant_, nullptr))));
    // AsyncFlowController
    flow_controllers_.insert(std::make_pair<std::string, std::unique_ptr<FlowController>>(
                async_flow_controller_name,
                std::unique_ptr<FlowController>(
                    new FlowControllerImpl<FlowControllerAsyncPublishMode,
                    FlowControllerFifoSchedule>(participant_, nullptr))));

#ifdef FASTDDS_STATISTICS
    flow_controllers_.insert(std::make_pair<std::string, std::unique_ptr<FlowController>>(
                async_statistics_flow_controller_name,
                std::unique_ptr<FlowController>(
                    new FlowControllerImpl<FlowControllerAsyncPublishMode,
                    FlowControllerFifoSchedule>(participant_, nullptr))));
#endif // ifndef FASTDDS_STATISTICS
}

void FlowControllerFactory::register_flow_controller (
        const FlowControllerDescriptor& flow_controller_descr)
{
    if (flow_controllers_.end() != flow_controllers_.find(flow_controller_descr.name))
    {
        logError(RTPS_PARTICIPANT,
                "Error registering FlowController " << flow_controller_descr.name << ". Already registered");
        return;
    }

    if (0 < flow_controller_descr.max_bytes_per_period)
    {
        switch (flow_controller_descr.scheduler)
        {
            case FlowControllerSchedulerPolicy::FIFO:
                flow_controllers_.insert({flow_controller_descr.name,
                                          std::unique_ptr<FlowController>(
                                              new FlowControllerImpl<FlowControllerLimitedAsyncPublishMode,
                                              FlowControllerFifoSchedule>(participant_, &flow_controller_descr))});
                break;
            case FlowControllerSchedulerPolicy::ROUND_ROBIN:
                flow_controllers_.insert({flow_controller_descr.name,
                                          std::unique_ptr<FlowController>(
                                              new FlowControllerImpl<FlowControllerLimitedAsyncPublishMode,
                                              FlowControllerRoundRobinSchedule>(participant_,
                                              &flow_controller_descr))});
                break;
            case FlowControllerSchedulerPolicy::HIGH_PRIORITY:
                flow_controllers_.insert({flow_controller_descr.name,
                                          std::unique_ptr<FlowController>(
                                              new FlowControllerImpl<FlowControllerLimitedAsyncPublishMode,
                                              FlowControllerHighPrioritySchedule>(participant_,
                                              &flow_controller_descr))});
                break;
            case FlowControllerSchedulerPolicy::PRIORITY_WITH_RESERVATION:
                flow_controllers_.insert({flow_controller_descr.name,
                                          std::unique_ptr<FlowController>(
                                              new FlowControllerImpl<FlowControllerLimitedAsyncPublishMode,
                                              FlowControllerPriorityWithReservationSchedule>(participant_,
                                              &flow_controller_descr))});
                break;
            default:
                assert(false);
        }
    }
    else
    {
        switch (flow_controller_descr.scheduler)
        {
            case FlowControllerSchedulerPolicy::FIFO:
                flow_controllers_.insert({flow_controller_descr.name,
                                          std::unique_ptr<FlowController>(
                                              new FlowControllerImpl<FlowControllerAsyncPublishMode,
                                              FlowControllerFifoSchedule>(participant_, &flow_controller_descr))});
                break;
            case FlowControllerSchedulerPolicy::ROUND_ROBIN:
                flow_controllers_.insert({flow_controller_descr.name,
                                          std::unique_ptr<FlowController>(
                                              new FlowControllerImpl<FlowControllerAsyncPublishMode,
                                              FlowControllerRoundRobinSchedule>(participant_,
                                              &flow_controller_descr))});
                break;
            case FlowControllerSchedulerPolicy::HIGH_PRIORITY:
                flow_controllers_.insert({flow_controller_descr.name,
                                          std::unique_ptr<FlowController>(
                                              new FlowControllerImpl<FlowControllerAsyncPublishMode,
                                              FlowControllerHighPrioritySchedule>(participant_,
                                              &flow_controller_descr))});
                break;
            case FlowControllerSchedulerPolicy::PRIORITY_WITH_RESERVATION:
                flow_controllers_.insert({flow_controller_descr.name,
                                          std::unique_ptr<FlowController>(
                                              new FlowControllerImpl<FlowControllerAsyncPublishMode,
                                              FlowControllerPriorityWithReservationSchedule>(participant_,
                                              &flow_controller_descr))});
                break;
            default:
                assert(false);
        }
    }
}

/*!
 * Get a FlowController given its name.
 *
 * @param flow_controller_name Name of the interested FlowController.
 * @return Pointer to the FlowController. nullptr if no registered FlowController with that name.
 */
FlowController* FlowControllerFactory::retrieve_flow_controller(
        const std::string& flow_controller_name,
        const fastrtps::rtps::WriterAttributes& writer_attributes)
{
    FlowController* returned_flow = nullptr;

    // Detect it has to be returned a default flow_controller.
    if (0 == flow_controller_name.compare(FASTDDS_FLOW_CONTROLLER_DEFAULT))
    {
        if (fastrtps::rtps::SYNCHRONOUS_WRITER == writer_attributes.mode)
        {
            if (fastrtps::rtps::BEST_EFFORT == writer_attributes.endpoint.reliabilityKind)
            {
                returned_flow = flow_controllers_[pure_sync_flow_controller_name].get();
            }
            else
            {
                returned_flow = flow_controllers_[sync_flow_controller_name].get();
            }
        }
        else
        {
            returned_flow = flow_controllers_[async_flow_controller_name].get();
        }
    }
#ifdef FASTDDS_STATISTICS
    else if (0 == flow_controller_name.compare(FASTDDS_STATISTICS_FLOW_CONTROLLER_DEFAULT))
    {
        assert(fastrtps::rtps::ASYNCHRONOUS_WRITER == writer_attributes.mode);
        returned_flow = flow_controllers_[async_statistics_flow_controller_name].get();
    }
#endif // ifdef FASTDDS_STATISTICS
    else
    {
        auto it = flow_controllers_.find(flow_controller_name);

        if (flow_controllers_.end() != it)
        {
            returned_flow = it->second.get();
        }
    }

    if (nullptr != returned_flow)
    {
        returned_flow->init();
    }
    else
    {
        logError(RTPS_PARTICIPANT,
                "Cannot find FlowController " << flow_controller_name << ".");
    }

    return returned_flow;
}

} // namespace rtps
} // namespace fastdds
} // namespace eprosima
<|endoftext|>


<commit_before>#include "sensorflare.h"
//Structure to keep in EEPROM memory the value of uotput pins
struct dataStruct
{
    int digitalPin[8];
    struct pwmPin{
        int pin;
        int value;
    };
    pwmPin pwmoutput[8];
};

union {
    dataStruct outputData;
    char eeArray[sizeof(outputData)];
} EEPROMData;

char stringvalue[40];
// Constructor
//Constructor of Digital Output controler elements
SensorFlare::DigitalOut::DigitalOut(int _number)
{
    number = _number;
    state = LOW;
}
//Constructor of PWM Output controler elements
SensorFlare::PWMOut::PWMOut(int _number)
{
    number = _number;

}
//Constructor of Variable publish element by defult PUBLIC
SensorFlare::VarPublish::VarPublish(String _name)
{
    name = _name;
    lastTime=0UL;
    property="PUBLIC";
}
//Constructor of Variable publish element by choose between PUBLIC and PRIVATE
SensorFlare::VarPublish::VarPublish(String _name,String _property)
{
    name = _name;
    lastTime=0UL;
    property=_property;
}

// Initializers that should be called in the `setup()` function

//Initizalize the pin as output and the last value received
void SensorFlare::DigitalOut::begin()
{
    pinMode(number, OUTPUT);
    Spark.function("digital",controlPin);
    //Initialize the output with the last receive value from SensorFlare
    readEEPROM();
    digitalWrite(number,EEPROMData.outputData.digitalPin[number]);

}
//Initizalize the pin as PWM output and the last value received
void SensorFlare::PWMOut::begin()
{
    pinMode(number, OUTPUT);
    Spark.function("pwm",controlPWM);
    //Initialize the output with the last receive value from SensorFlare
    readEEPROM();
    analogWrite(number,EEPROMData.outputData.digitalPin[number]);
    for (int i=0;i<8;i++){
        if (EEPROMData.outputData.pwmoutput[i].pin==number)
        {
            analogWrite(number,EEPROMData.outputData.pwmoutput[i].value);
            value=EEPROMData.outputData.pwmoutput[i].value;
        }
    }

}
// Main API functions that the library provides
// typically called in `loop()`
//Method that publish the variable (int) _val every _period time
int SensorFlare::VarPublish::Publish(int _val, int _periode)
{
     var_int=_val;
     periode=_periode*1000;
     unsigned long now = millis();
    if (property=="PRIVATE"){
        if (now-lastTime>periode) {
        lastTime = now;
        sprintf(stringvalue,"%u",var_int);
        Spark.publish(name,stringvalue,60,PRIVATE);
       }
       return 0;
    }
    else if (property=="PUBLIC"){
        if (now-lastTime>periode) {
        lastTime = now;
        sprintf(stringvalue,"%u",var_int);
        Spark.publish(name,stringvalue);
       }
       return 1;
    }
    else{
        return -1;//Return -1 if the variable could be publish because a mistake on the property
    }
}

//Method that publish the variable (float) _val every _period time
int SensorFlare::VarPublish::Publish(float _val, int _periode)
{
     var_float=_val;
     periode=_periode*1000;
     unsigned long now = millis();
    if (property=="PRIVATE"){
        if (now-lastTime>periode) {
        lastTime = now;
        sprintf(stringvalue,"%f",var_float);
        Spark.publish(name,stringvalue,60,PRIVATE);
       }
       return 0;
    }
    else if (property=="PUBLIC"){
        if (now-lastTime>periode) {
        lastTime = now;
        sprintf(stringvalue,"%f",var_float);
        Spark.publish(name,stringvalue);
       }
       return 1;
    }
    else{
        return -1;
    }
}

//Function for open/close pin
//The structure of the receive command is pin:state where state is on or off
int controlPin(String command) {
    int index=command.indexOf(":");
     String pinout=command.substring(0,index);
     String state=command.substring(index+1);
     int pin=pinout.toInt();

    if (state=="on") {
        digitalWrite(pin,HIGH);
        EEPROMData.outputData.digitalPin[pin]=1;
        writeEEPROM();
        return 1;
    }
    else if (state=="off") {
        digitalWrite(pin,LOW);
        EEPROMData.outputData.digitalPin[pin]=0;
        writeEEPROM();
        return 0;
    }
    else {
        //EEPROMData.eevar.state[pin]=-1;
        return -1;//return -1 if the command received has not the correct structure
    }

}

//Function that control the specific brightness of the led conected to specific pwmpin.
//the structure of the command is pwmpin:brightness
int controlPWM(String command) {
     int index=command.indexOf(":");
     String pwmpin=command.substring(0,index);
     String val=command.substring(index+1);
     int pin=pwmpin.toInt();
     int value=val.toInt();
    if (value<256&&value>=0){
        analogWrite(pin,value);
        if (pin==10){
            EEPROMData.outputData.pwmoutput[2].pin=pin;
            EEPROMData.outputData.pwmoutput[2].value=value;
         }
        else if (pin==11){
            EEPROMData.outputData.pwmoutput[3].pin=pin;
            EEPROMData.outputData.pwmoutput[3].value=value;
        }
        else if (pin>13&&pin<18){
            EEPROMData.outputData.pwmoutput[pin-10].pin=pin;
            EEPROMData.outputData.pwmoutput[pin-10].value=value;
        }
        else if (pin<2){
            EEPROMData.outputData.pwmoutput[pin].pin=pin;
            EEPROMData.outputData.pwmoutput[pin].value=value;
        }
        writeEEPROM();
        return value;
    }
    else{
        return -1;// return -1 if the pin sended on the command is not the PWM output ones
    }
}

//function to read from the EEPROM
void readEEPROM(void) {
    for (int i=0; i<sizeof(dataStruct); i++) {
        EEPROMData.eeArray[i] = EEPROM.read(i);
    }
}
//function to write on the EEPROM
void writeEEPROM(void) {
    for (int i=0; i<sizeof(dataStruct); i++) {
        EEPROM.write(i, EEPROMData.eeArray[i]);
    }
}
<commit_msg>Update sensorflare.cpp<commit_after>/*"name": "sensorflare",
Author: "LPFraile <lidiapf0@gmail.com>",
License: "BSD",
Version: "0.0.1",
Description: "Include your Particle Core on Sensorflare"
File: source file
*/
#include "sensorflare.h"
//Structure to keep in EEPROM memory the value of uotput pins
struct dataStruct
{
    int digitalPin[8];
    struct pwmPin{
        int pin;
        int value;
    };
    pwmPin pwmoutput[8];
};

union {
    dataStruct outputData;
    char eeArray[sizeof(outputData)];
} EEPROMData;

char stringvalue[40];
// Constructor
//Constructor of Digital Output controler elements
SensorFlare::DigitalOut::DigitalOut(int _number)
{
    number = _number;
    state = LOW;
}
//Constructor of PWM Output controler elements
SensorFlare::PWMOut::PWMOut(int _number)
{
    number = _number;

}
//Constructor of Variable publish element by defult PUBLIC
SensorFlare::VarPublish::VarPublish(String _name)
{
    name = _name;
    lastTime=0UL;
    property="PUBLIC";
}
//Constructor of Variable publish element by choose between PUBLIC and PRIVATE
SensorFlare::VarPublish::VarPublish(String _name,String _property)
{
    name = _name;
    lastTime=0UL;
    property=_property;
}

// Initializers that should be called in the `setup()` function

//Initizalize the pin as output and the last value received
void SensorFlare::DigitalOut::begin()
{
    pinMode(number, OUTPUT);
    Spark.function("digital",controlPin);
    //Initialize the output with the last receive value from SensorFlare
    readEEPROM();
    digitalWrite(number,EEPROMData.outputData.digitalPin[number]);

}
//Initizalize the pin as PWM output and the last value received
void SensorFlare::PWMOut::begin()
{
    pinMode(number, OUTPUT);
    Spark.function("pwm",controlPWM);
    //Initialize the output with the last receive value from SensorFlare
    readEEPROM();
    analogWrite(number,EEPROMData.outputData.digitalPin[number]);
    for (int i=0;i<8;i++){
        if (EEPROMData.outputData.pwmoutput[i].pin==number)
        {
            analogWrite(number,EEPROMData.outputData.pwmoutput[i].value);
            value=EEPROMData.outputData.pwmoutput[i].value;
        }
    }

}
// Main API functions that the library provides
// typically called in `loop()`
//Method that publish the variable (int) _val every _period time
int SensorFlare::VarPublish::Publish(int _val, int _periode)
{
     var_int=_val;
     periode=_periode*1000;
     unsigned long now = millis();
    if (property=="PRIVATE"){
        if (now-lastTime>periode) {
        lastTime = now;
        sprintf(stringvalue,"%u",var_int);
        Spark.publish(name,stringvalue,60,PRIVATE);
       }
       return 0;
    }
    else if (property=="PUBLIC"){
        if (now-lastTime>periode) {
        lastTime = now;
        sprintf(stringvalue,"%u",var_int);
        Spark.publish(name,stringvalue);
       }
       return 1;
    }
    else{
        return -1;//Return -1 if the variable could be publish because a mistake on the property
    }
}

//Method that publish the variable (float) _val every _period time
int SensorFlare::VarPublish::Publish(float _val, int _periode)
{
     var_float=_val;
     periode=_periode*1000;
     unsigned long now = millis();
    if (property=="PRIVATE"){
        if (now-lastTime>periode) {
        lastTime = now;
        sprintf(stringvalue,"%f",var_float);
        Spark.publish(name,stringvalue,60,PRIVATE);
       }
       return 0;
    }
    else if (property=="PUBLIC"){
        if (now-lastTime>periode) {
        lastTime = now;
        sprintf(stringvalue,"%f",var_float);
        Spark.publish(name,stringvalue);
       }
       return 1;
    }
    else{
        return -1;
    }
}

//Function for open/close pin
//The structure of the receive command is pin:state where state is on or off
int controlPin(String command) {
    int index=command.indexOf(":");
     String pinout=command.substring(0,index);
     String state=command.substring(index+1);
     int pin=pinout.toInt();

    if (state=="on") {
        digitalWrite(pin,HIGH);
        EEPROMData.outputData.digitalPin[pin]=1;
        writeEEPROM();
        return 1;
    }
    else if (state=="off") {
        digitalWrite(pin,LOW);
        EEPROMData.outputData.digitalPin[pin]=0;
        writeEEPROM();
        return 0;
    }
    else {
        //EEPROMData.eevar.state[pin]=-1;
        return -1;//return -1 if the command received has not the correct structure
    }

}

//Function that control the specific brightness of the led conected to specific pwmpin.
//the structure of the command is pwmpin:brightness
int controlPWM(String command) {
     int index=command.indexOf(":");
     String pwmpin=command.substring(0,index);
     String val=command.substring(index+1);
     int pin=pwmpin.toInt();
     int value=val.toInt();
    if (value<256&&value>=0){
        analogWrite(pin,value);
        if (pin==10){
            EEPROMData.outputData.pwmoutput[2].pin=pin;
            EEPROMData.outputData.pwmoutput[2].value=value;
         }
        else if (pin==11){
            EEPROMData.outputData.pwmoutput[3].pin=pin;
            EEPROMData.outputData.pwmoutput[3].value=value;
        }
        else if (pin>13&&pin<18){
            EEPROMData.outputData.pwmoutput[pin-10].pin=pin;
            EEPROMData.outputData.pwmoutput[pin-10].value=value;
        }
        else if (pin<2){
            EEPROMData.outputData.pwmoutput[pin].pin=pin;
            EEPROMData.outputData.pwmoutput[pin].value=value;
        }
        writeEEPROM();
        return value;
    }
    else{
        return -1;// return -1 if the pin sended on the command is not the PWM output ones
    }
}

//function to read from the EEPROM
void readEEPROM(void) {
    for (int i=0; i<sizeof(dataStruct); i++) {
        EEPROMData.eeArray[i] = EEPROM.read(i);
    }
}
//function to write on the EEPROM
void writeEEPROM(void) {
    for (int i=0; i<sizeof(dataStruct); i++) {
        EEPROM.write(i, EEPROMData.eeArray[i]);
    }
}
<|endoftext|>