<commit_before>/*
    open source routing machine
    Copyright (C) Dennis Luxen, 2010

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.

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 the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
or see http://www.gnu.org/licenses/agpl.txt.
 */

//g++ createHierarchy.cpp -fopenmp -Wno-deprecated -o createHierarchy -O3 -march=native -DNDEBUG -I/usr/include/libxml2 -lstxxl

#define VERBOSE(x) x
#define VERBOSE2(x)

#ifdef NDEBUG
#undef VERBOSE
#undef VERBOSE2
#endif

#include <boost/foreach.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/ini_parser.hpp>

#include <fstream>
#include <istream>
#include <iostream>
#include <cstring>
#include <string>
#include <vector>

#include "Algorithms/CRC32.h"
#include "Util/OpenMPReplacement.h"
#include "typedefs.h"
#include "Contractor/Contractor.h"
#include "Contractor/ContractionCleanup.h"
#include "Contractor/EdgeBasedGraphFactory.h"
#include "DataStructures/BinaryHeap.h"
#include "DataStructures/ExtractorStructs.h"
#include "DataStructures/NNGrid.h"
#include "Util/BaseConfiguration.h"
#include "Util/InputFileUtil.h"
#include "Util/GraphLoader.h"
#include "Util/OpenMPReplacement.h"

using namespace std;

typedef DynamicGraph<EdgeData>::InputEdge InputEdge;
typedef StaticGraph<EdgeData>::InputEdge StaticEdge;
typedef BaseConfiguration ContractorConfiguration;

std::vector<NodeInfo> internalToExternaleNodeMapping;
std::vector<_Restriction> inputRestrictions;
std::vector<NodeID> bollardNodes;
std::vector<NodeID> trafficLightNodes;

int main (int argc, char *argv[]) {
    if(argc < 3) {
        ERR("usage: " << std::endl << argv[0] << " <osrm-data> <osrm-restrictions>");
    }

    double startupTime = get_timestamp();
    unsigned numberOfThreads = omp_get_num_procs();
    std::string SRTM_ROOT;
    if(testDataFile("contractor.ini")) {
        ContractorConfiguration contractorConfig("contractor.ini");
        if(atoi(contractorConfig.GetParameter("Threads").c_str()) != 0 && (unsigned)atoi(contractorConfig.GetParameter("Threads").c_str()) <= numberOfThreads)
            numberOfThreads = (unsigned)atoi( contractorConfig.GetParameter("Threads").c_str() );
        if(0 < contractorConfig.GetParameter("SRTM").size() )
            SRTM_ROOT = contractorConfig.GetParameter("SRTM");
    }
    if(0 != SRTM_ROOT.size())
        INFO("Loading SRTM from/to " << SRTM_ROOT);
    omp_set_num_threads(numberOfThreads);

    INFO("Using restrictions from file: " << argv[2]);
    std::ifstream restrictionsInstream(argv[2], ios::binary);
    if(!restrictionsInstream.good()) {
        ERR("Could not access <osrm-restrictions> files");
    }
    _Restriction restriction;
    unsigned usableRestrictionsCounter(0);
    restrictionsInstream.read((char*)&usableRestrictionsCounter, sizeof(unsigned));
    for(unsigned i = 0; i < usableRestrictionsCounter; ++i) {
        restrictionsInstream.read((char *)&(restriction), sizeof(_Restriction));
        inputRestrictions.push_back(restriction);
    }
    restrictionsInstream.close();

    ifstream in;
    in.open (argv[1], ifstream::in | ifstream::binary);
    if (!in.is_open()) {
        ERR("Cannot open " << argv[1]);
    }

    char nodeOut[1024];    		strcpy(nodeOut, argv[1]);    		strcat(nodeOut, ".nodes");
    char edgeOut[1024];    		strcpy(edgeOut, argv[1]);    		strcat(edgeOut, ".hsgr");
    char ramIndexOut[1024];    	strcpy(ramIndexOut, argv[1]);    	strcat(ramIndexOut, ".ramIndex");
    char fileIndexOut[1024];    strcpy(fileIndexOut, argv[1]);    	strcat(fileIndexOut, ".fileIndex");
    char levelInfoOut[1024];    strcpy(levelInfoOut, argv[1]);    	strcat(levelInfoOut, ".levels");

    std::vector<ImportEdge> edgeList;
    NodeID nodeBasedNodeNumber = readBinaryOSRMGraphFromStream(in, edgeList, bollardNodes, trafficLightNodes, &internalToExternaleNodeMapping, inputRestrictions);
    in.close();
    INFO("Loaded " << inputRestrictions.size() << " restrictions, " << bollardNodes.size() << " bollard nodes, " << trafficLightNodes.size() << " traffic lights");

    if(!testDataFile("speedprofile.ini")) {
        ERR("Need speedprofile.ini to apply traffic signal penalty");
    }
    boost::property_tree::ptree speedProfile;
    boost::property_tree::ini_parser::read_ini("speedprofile.ini", speedProfile);
    EdgeBasedGraphFactory * edgeBasedGraphFactory = new EdgeBasedGraphFactory (nodeBasedNodeNumber, edgeList, bollardNodes, trafficLightNodes, inputRestrictions, internalToExternaleNodeMapping, speedProfile, SRTM_ROOT);
    edgeList.clear();
    std::vector<ImportEdge>().swap(edgeList);

    edgeBasedGraphFactory->Run();
    NodeID edgeBasedNodeNumber = edgeBasedGraphFactory->GetNumberOfNodes();
    std::vector<EdgeBasedEdge> edgeBasedEdgeList;
    edgeBasedGraphFactory->GetEdgeBasedEdges(edgeBasedEdgeList);

    std::vector<EdgeBasedGraphFactory::EdgeBasedNode> nodeBasedEdgeList;
    edgeBasedGraphFactory->GetEdgeBasedNodes(nodeBasedEdgeList);
    DELETE(edgeBasedGraphFactory);
    double expansionHasFinishedTime = get_timestamp() - startupTime;

    WritableGrid * writeableGrid = new WritableGrid();
    INFO("building grid ...");
    writeableGrid->ConstructGrid(nodeBasedEdgeList, ramIndexOut, fileIndexOut);
    DELETE( writeableGrid );
    CRC32 crc32;
    unsigned crc32OfNodeBasedEdgeList = crc32((char *)&(nodeBasedEdgeList[0]), nodeBasedEdgeList.size()*sizeof(EdgeBasedGraphFactory::EdgeBasedNode));
//    INFO("CRC32 of data is " << crc32OfNodeBasedEdgeList);

    nodeBasedEdgeList.clear();
    std::vector<EdgeBasedGraphFactory::EdgeBasedNode>().swap(nodeBasedEdgeList);

    INFO("writing node map ...");
    std::ofstream mapOutFile(nodeOut, ios::binary);
    mapOutFile.write((char *)&(internalToExternaleNodeMapping[0]), internalToExternaleNodeMapping.size()*sizeof(NodeInfo));
    mapOutFile.close();

    std::vector<NodeInfo>().swap(internalToExternaleNodeMapping);
    inputRestrictions.clear();
    std::vector<_Restriction>().swap(inputRestrictions);

//    unsigned crc32OfNodeBasedEdgeList = crc32((char*)&edgeBasedEdgeList[0], edgeBasedEdgeList.size());
//    INFO("CRC32 of data is " << crc32OfNodeBasedEdgeList);

    INFO("initializing contractor");
    Contractor* contractor = new Contractor( edgeBasedNodeNumber, edgeBasedEdgeList );
    double contractionStartedTimestamp(get_timestamp());
    contractor->Run();
    INFO("Contraction took " << get_timestamp() - contractionStartedTimestamp << " sec");

    std::vector< ContractionCleanup::Edge > contractedEdges;
    contractor->GetEdges( contractedEdges );
    delete contractor;

    ContractionCleanup * cleanup = new ContractionCleanup(edgeBasedNodeNumber, contractedEdges);
    contractedEdges.clear();
    std::vector<ContractionCleanup::Edge>().swap(contractedEdges);
    cleanup->Run();

    std::vector< InputEdge> cleanedEdgeList;
    cleanup->GetData(cleanedEdgeList);
    DELETE( cleanup );

    INFO("Building Node Array");
    sort(cleanedEdgeList.begin(), cleanedEdgeList.end());
    unsigned numberOfNodes = 0;
    unsigned numberOfEdges = cleanedEdgeList.size();
    INFO("Serializing compacted graph");
    ofstream edgeOutFile(edgeOut, ios::binary);

    BOOST_FOREACH(InputEdge & edge, cleanedEdgeList) {
        if(edge.source > numberOfNodes) {
            numberOfNodes = edge.source;
        }
        if(edge.target > numberOfNodes) {
            numberOfNodes = edge.target;
        }
    }
    numberOfNodes+=1;

    std::vector< StaticGraph<EdgeData>::_StrNode > _nodes;
    _nodes.resize( numberOfNodes + 1 );

    StaticGraph<EdgeData>::EdgeIterator edge = 0;
    StaticGraph<EdgeData>::EdgeIterator position = 0;
    for ( StaticGraph<EdgeData>::NodeIterator node = 0; node <= numberOfNodes; ++node ) {
        StaticGraph<EdgeData>::EdgeIterator lastEdge = edge;
        while ( edge < numberOfEdges && cleanedEdgeList[edge].source == node )
            ++edge;
        _nodes[node].firstEdge = position; //=edge
        position += edge - lastEdge; //remove
    }
    //Serialize numberOfNodes, nodes
    edgeOutFile.write((char*) &crc32OfNodeBasedEdgeList, sizeof(unsigned));
    edgeOutFile.write((char*) &numberOfNodes, sizeof(unsigned));
    edgeOutFile.write((char*) &_nodes[0], sizeof(StaticGraph<EdgeData>::_StrNode)*(numberOfNodes+1));

    //Serialize number of Edges
    edgeOutFile.write((char*) &position, sizeof(unsigned));

    edge = 0;
    int usedEdgeCounter = 0;
    StaticGraph<EdgeData>::_StrEdge currentEdge;
    for ( StaticGraph<EdgeData>::NodeIterator node = 0; node < numberOfNodes; ++node ) {
        for ( StaticGraph<EdgeData>::EdgeIterator i = _nodes[node].firstEdge, e = _nodes[node+1].firstEdge; i != e; ++i ) {

            currentEdge.target = cleanedEdgeList[edge].target;
            currentEdge.data = cleanedEdgeList[edge].data;
            if(currentEdge.data.distance <= 0) {
                INFO("Edge: " << i << ",source: " << cleanedEdgeList[edge].source << ", target: " << cleanedEdgeList[edge].target << ", dist: " << currentEdge.data.distance);
                ERR("Failed at edges of node " << node << " of " << numberOfNodes);
            }
            //Serialize edges
            edgeOutFile.write((char*) &currentEdge, sizeof(StaticGraph<EdgeData>::_StrEdge));
            ++edge;
            ++usedEdgeCounter;
        }
    }
    double endTime = (get_timestamp() - startupTime);
    INFO("Expansion  : " << (nodeBasedNodeNumber/expansionHasFinishedTime) << " nodes/sec and "<< (edgeBasedNodeNumber/expansionHasFinishedTime) << " edges/sec");
    INFO("Contraction: " << (edgeBasedNodeNumber/expansionHasFinishedTime) << " nodes/sec and "<< usedEdgeCounter/endTime << " edges/sec");

    edgeOutFile.close();
    cleanedEdgeList.clear();
    _nodes.clear();
    INFO("finished preprocessing");
    return 0;
}
<commit_msg>Fixes segfault where route over node with highest ID could not be unpacked.<commit_after>/*
    open source routing machine
    Copyright (C) Dennis Luxen, 2010

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.

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 the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
or see http://www.gnu.org/licenses/agpl.txt.
 */

//g++ createHierarchy.cpp -fopenmp -Wno-deprecated -o createHierarchy -O3 -march=native -DNDEBUG -I/usr/include/libxml2 -lstxxl

#define VERBOSE(x) x
#define VERBOSE2(x)

#ifdef NDEBUG
#undef VERBOSE
#undef VERBOSE2
#endif

#include <boost/foreach.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/ini_parser.hpp>

#include <fstream>
#include <istream>
#include <iostream>
#include <cstring>
#include <string>
#include <vector>

#include "Algorithms/CRC32.h"
#include "Util/OpenMPReplacement.h"
#include "typedefs.h"
#include "Contractor/Contractor.h"
#include "Contractor/ContractionCleanup.h"
#include "Contractor/EdgeBasedGraphFactory.h"
#include "DataStructures/BinaryHeap.h"
#include "DataStructures/ExtractorStructs.h"
#include "DataStructures/NNGrid.h"
#include "Util/BaseConfiguration.h"
#include "Util/InputFileUtil.h"
#include "Util/GraphLoader.h"
#include "Util/OpenMPReplacement.h"

using namespace std;

typedef DynamicGraph<EdgeData>::InputEdge InputEdge;
typedef StaticGraph<EdgeData>::InputEdge StaticEdge;
typedef BaseConfiguration ContractorConfiguration;

std::vector<NodeInfo> internalToExternaleNodeMapping;
std::vector<_Restriction> inputRestrictions;
std::vector<NodeID> bollardNodes;
std::vector<NodeID> trafficLightNodes;

int main (int argc, char *argv[]) {
    if(argc < 3) {
        ERR("usage: " << std::endl << argv[0] << " <osrm-data> <osrm-restrictions>");
    }

    double startupTime = get_timestamp();
    unsigned numberOfThreads = omp_get_num_procs();
    std::string SRTM_ROOT;
    if(testDataFile("contractor.ini")) {
        ContractorConfiguration contractorConfig("contractor.ini");
        if(atoi(contractorConfig.GetParameter("Threads").c_str()) != 0 && (unsigned)atoi(contractorConfig.GetParameter("Threads").c_str()) <= numberOfThreads)
            numberOfThreads = (unsigned)atoi( contractorConfig.GetParameter("Threads").c_str() );
        if(0 < contractorConfig.GetParameter("SRTM").size() )
            SRTM_ROOT = contractorConfig.GetParameter("SRTM");
    }
    if(0 != SRTM_ROOT.size())
        INFO("Loading SRTM from/to " << SRTM_ROOT);
    omp_set_num_threads(numberOfThreads);

    INFO("Using restrictions from file: " << argv[2]);
    std::ifstream restrictionsInstream(argv[2], ios::binary);
    if(!restrictionsInstream.good()) {
        ERR("Could not access <osrm-restrictions> files");
    }
    _Restriction restriction;
    unsigned usableRestrictionsCounter(0);
    restrictionsInstream.read((char*)&usableRestrictionsCounter, sizeof(unsigned));
    for(unsigned i = 0; i < usableRestrictionsCounter; ++i) {
        restrictionsInstream.read((char *)&(restriction), sizeof(_Restriction));
        inputRestrictions.push_back(restriction);
    }
    restrictionsInstream.close();

    ifstream in;
    in.open (argv[1], ifstream::in | ifstream::binary);
    if (!in.is_open()) {
        ERR("Cannot open " << argv[1]);
    }

    char nodeOut[1024];    		strcpy(nodeOut, argv[1]);    		strcat(nodeOut, ".nodes");
    char edgeOut[1024];    		strcpy(edgeOut, argv[1]);    		strcat(edgeOut, ".hsgr");
    char ramIndexOut[1024];    	strcpy(ramIndexOut, argv[1]);    	strcat(ramIndexOut, ".ramIndex");
    char fileIndexOut[1024];    strcpy(fileIndexOut, argv[1]);    	strcat(fileIndexOut, ".fileIndex");
    char levelInfoOut[1024];    strcpy(levelInfoOut, argv[1]);    	strcat(levelInfoOut, ".levels");

    std::vector<ImportEdge> edgeList;
    NodeID nodeBasedNodeNumber = readBinaryOSRMGraphFromStream(in, edgeList, bollardNodes, trafficLightNodes, &internalToExternaleNodeMapping, inputRestrictions);
    in.close();
    INFO("Loaded " << inputRestrictions.size() << " restrictions, " << bollardNodes.size() << " bollard nodes, " << trafficLightNodes.size() << " traffic lights");

    if(!testDataFile("speedprofile.ini")) {
        ERR("Need speedprofile.ini to apply traffic signal penalty");
    }
    boost::property_tree::ptree speedProfile;
    boost::property_tree::ini_parser::read_ini("speedprofile.ini", speedProfile);
    EdgeBasedGraphFactory * edgeBasedGraphFactory = new EdgeBasedGraphFactory (nodeBasedNodeNumber, edgeList, bollardNodes, trafficLightNodes, inputRestrictions, internalToExternaleNodeMapping, speedProfile, SRTM_ROOT);
    edgeList.clear();
    std::vector<ImportEdge>().swap(edgeList);

    edgeBasedGraphFactory->Run();
    NodeID edgeBasedNodeNumber = edgeBasedGraphFactory->GetNumberOfNodes();
    std::vector<EdgeBasedEdge> edgeBasedEdgeList;
    edgeBasedGraphFactory->GetEdgeBasedEdges(edgeBasedEdgeList);

    std::vector<EdgeBasedGraphFactory::EdgeBasedNode> nodeBasedEdgeList;
    edgeBasedGraphFactory->GetEdgeBasedNodes(nodeBasedEdgeList);
    DELETE(edgeBasedGraphFactory);
    double expansionHasFinishedTime = get_timestamp() - startupTime;

    WritableGrid * writeableGrid = new WritableGrid();
    INFO("building grid ...");
    writeableGrid->ConstructGrid(nodeBasedEdgeList, ramIndexOut, fileIndexOut);
    DELETE( writeableGrid );
    CRC32 crc32;
    unsigned crc32OfNodeBasedEdgeList = crc32((char *)&(nodeBasedEdgeList[0]), nodeBasedEdgeList.size()*sizeof(EdgeBasedGraphFactory::EdgeBasedNode));
//    INFO("CRC32 of data is " << crc32OfNodeBasedEdgeList);

    nodeBasedEdgeList.clear();
    std::vector<EdgeBasedGraphFactory::EdgeBasedNode>().swap(nodeBasedEdgeList);

    INFO("writing node map ...");
    std::ofstream mapOutFile(nodeOut, ios::binary);
    mapOutFile.write((char *)&(internalToExternaleNodeMapping[0]), internalToExternaleNodeMapping.size()*sizeof(NodeInfo));
    mapOutFile.close();

    std::vector<NodeInfo>().swap(internalToExternaleNodeMapping);
    inputRestrictions.clear();
    std::vector<_Restriction>().swap(inputRestrictions);

//    unsigned crc32OfNodeBasedEdgeList = crc32((char*)&edgeBasedEdgeList[0], edgeBasedEdgeList.size());
//    INFO("CRC32 of data is " << crc32OfNodeBasedEdgeList);

    INFO("initializing contractor");
    Contractor* contractor = new Contractor( edgeBasedNodeNumber, edgeBasedEdgeList );
    double contractionStartedTimestamp(get_timestamp());
    contractor->Run();
    INFO("Contraction took " << get_timestamp() - contractionStartedTimestamp << " sec");

    std::vector< ContractionCleanup::Edge > contractedEdges;
    contractor->GetEdges( contractedEdges );
    delete contractor;

    ContractionCleanup * cleanup = new ContractionCleanup(edgeBasedNodeNumber, contractedEdges);
    contractedEdges.clear();
    std::vector<ContractionCleanup::Edge>().swap(contractedEdges);
    cleanup->Run();

    std::vector< InputEdge> cleanedEdgeList;
    cleanup->GetData(cleanedEdgeList);
    DELETE( cleanup );

    INFO("Building Node Array");
    sort(cleanedEdgeList.begin(), cleanedEdgeList.end());
    unsigned numberOfNodes = 0;
    unsigned numberOfEdges = cleanedEdgeList.size();
    INFO("Serializing compacted graph");
    ofstream edgeOutFile(edgeOut, ios::binary);

    BOOST_FOREACH(InputEdge & edge, cleanedEdgeList) {
        if(edge.source > numberOfNodes) {
            numberOfNodes = edge.source;
        }
        if(edge.target > numberOfNodes) {
            numberOfNodes = edge.target;
        }
    }
    numberOfNodes+=1;

    std::vector< StaticGraph<EdgeData>::_StrNode > _nodes;
    _nodes.resize( numberOfNodes + 1 );

    StaticGraph<EdgeData>::EdgeIterator edge = 0;
    StaticGraph<EdgeData>::EdgeIterator position = 0;
    for ( StaticGraph<EdgeData>::NodeIterator node = 0; node <= numberOfNodes; ++node ) {
        StaticGraph<EdgeData>::EdgeIterator lastEdge = edge;
        while ( edge < numberOfEdges && cleanedEdgeList[edge].source == node )
            ++edge;
        _nodes[node].firstEdge = position; //=edge
        position += edge - lastEdge; //remove
    }
    ++numberOfNodes;
    //Serialize numberOfNodes, nodes
    edgeOutFile.write((char*) &crc32OfNodeBasedEdgeList, sizeof(unsigned));
    edgeOutFile.write((char*) &numberOfNodes, sizeof(unsigned));
    edgeOutFile.write((char*) &_nodes[0], sizeof(StaticGraph<EdgeData>::_StrNode)*(numberOfNodes));
    //Serialize number of Edges
    edgeOutFile.write((char*) &position, sizeof(unsigned));
    --numberOfNodes;
    edge = 0;
    int usedEdgeCounter = 0;
    StaticGraph<EdgeData>::_StrEdge currentEdge;
    for ( StaticGraph<EdgeData>::NodeIterator node = 0; node < numberOfNodes; ++node ) {
        for ( StaticGraph<EdgeData>::EdgeIterator i = _nodes[node].firstEdge, e = _nodes[node+1].firstEdge; i != e; ++i ) {
            assert(node != cleanedEdgeList[edge].target);
            currentEdge.target = cleanedEdgeList[edge].target;
            currentEdge.data = cleanedEdgeList[edge].data;
            if(currentEdge.data.distance <= 0) {
                INFO("Edge: " << i << ",source: " << cleanedEdgeList[edge].source << ", target: " << cleanedEdgeList[edge].target << ", dist: " << currentEdge.data.distance);
                ERR("Failed at edges of node " << node << " of " << numberOfNodes);
            }
            //Serialize edges
            edgeOutFile.write((char*) &currentEdge, sizeof(StaticGraph<EdgeData>::_StrEdge));
            ++edge;
            ++usedEdgeCounter;
        }
    }
    double endTime = (get_timestamp() - startupTime);
    INFO("Expansion  : " << (nodeBasedNodeNumber/expansionHasFinishedTime) << " nodes/sec and "<< (edgeBasedNodeNumber/expansionHasFinishedTime) << " edges/sec");
    INFO("Contraction: " << (edgeBasedNodeNumber/expansionHasFinishedTime) << " nodes/sec and "<< usedEdgeCounter/endTime << " edges/sec");

    edgeOutFile.close();
    cleanedEdgeList.clear();
    _nodes.clear();
    INFO("finished preprocessing");
    return 0;
}
<|endoftext|>


<commit_before>/* Copyright (c) 1996-2004, Adaptec Corporation
 * 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 Adaptec Corporation 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 OWNER 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.
 */

/****************************************************************************
*
* Created:  12/20/00
*
*****************************************************************************
*
* File Name:            setscfg.cpp
* Module:
* Contributors:         Edrick Estrada
* Description:
* Version Control:
*
* $Revision$
* $NoKeywords: $
* $Log$
* Revision 1.1.1.1  2004-04-29 10:20:14  bap
* Imported upstream version 0.0.4.
*
*****************************************************************************/

/*** INCLUDES ***/
#include "setscfg.hpp"
/*** CONSTANTS ***/
/*** TYPES ***/
/*** STATIC DATA ***/
/*** EXTERNAL DATA ***/
/*** MACROS ***/
/*** PROTOTYPES ***/
/*** FUNCTIONS ***/

setscfg::setscfg ()
{
   ENTER("setscfg::setscfg (");
   EXIT();
}

setscfg::~setscfg()
{
   ENTER( "setscfg::~setscfg()" );
   EXIT();
}

/*******************************************************
Main exe loop
*******************************************************/
Command::Dpt_Error setscfg::execute(String_List **output)
{
	ENTER("Command::Dpt_Error setscfg::execute(String_List **output)");

	Dpt_Error err;

	Init_Engine();

	String_List *out;
	*output = out = new String_List();

	engine->Reset();
    if (engine->Send( MSG_RAID_HW_ENABLE ) == MSG_RTN_COMPLETED){

		out->add_Item("System Configuration set.");
		out->add_Item("\n");
	}
   return (err);
}

Command &setscfg::Clone() const
{
        ENTER("Command &setscfg::Clone() const");
        EXIT();
        return(*new setscfg(*this));
}<commit_msg>file should end in newline (raidutil/setscfg.cpp)<commit_after>/* Copyright (c) 1996-2004, Adaptec Corporation
 * 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 Adaptec Corporation 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 OWNER 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.
 */

/****************************************************************************
*
* Created:  12/20/00
*
*****************************************************************************
*
* File Name:            setscfg.cpp
* Module:
* Contributors:         Edrick Estrada
* Description:
* Version Control:
*
* $Revision$
* $NoKeywords: $
* $Log$
* Revision 1.1.1.1  2004-04-29 10:20:14  bap
* Imported upstream version 0.0.4.
*
*****************************************************************************/

/*** INCLUDES ***/
#include "setscfg.hpp"
/*** CONSTANTS ***/
/*** TYPES ***/
/*** STATIC DATA ***/
/*** EXTERNAL DATA ***/
/*** MACROS ***/
/*** PROTOTYPES ***/
/*** FUNCTIONS ***/

setscfg::setscfg ()
{
   ENTER("setscfg::setscfg (");
   EXIT();
}

setscfg::~setscfg()
{
   ENTER( "setscfg::~setscfg()" );
   EXIT();
}

/*******************************************************
Main exe loop
*******************************************************/
Command::Dpt_Error setscfg::execute(String_List **output)
{
	ENTER("Command::Dpt_Error setscfg::execute(String_List **output)");

	Dpt_Error err;

	Init_Engine();

	String_List *out;
	*output = out = new String_List();

	engine->Reset();
    if (engine->Send( MSG_RAID_HW_ENABLE ) == MSG_RTN_COMPLETED){

		out->add_Item("System Configuration set.");
		out->add_Item("\n");
	}
   return (err);
}

Command &setscfg::Clone() const
{
        ENTER("Command &setscfg::Clone() const");
        EXIT();
        return(*new setscfg(*this));
}
<|endoftext|>


<commit_before>#ifndef STAN__ERROR_HANDLING__SCALAR__DOM_ERR_HPP
#define STAN__ERROR_HANDLING__SCALAR__DOM_ERR_HPP

#include <typeinfo>
#ifdef BOOST_MSVC
#  pragma warning(push) // Quiet warnings in boost/format.hpp
#  pragma warning(disable: 4996) // _SCL_SECURE_NO_DEPRECATE
#  pragma warning(disable: 4512) // assignment operator could not be generated.
// And warnings in error handling:
#  pragma warning(disable: 4702) // unreachable code
// Note that this only occurs when the compiler can deduce code is unreachable,
// for example when policy macros are used to ignore errors rather than throw.
#endif
#include <boost/format.hpp>

#include <string>
#include <sstream>
#include <stdexcept>

namespace stan {
  namespace error_handling {

    /**
     * Throw a domain error with a consistently formatted message.
     *
     * This is an abstraction for all Stan functions to use when throwing
     * domain errors. This will allow us to change the behavior for all
     * functions at once. (We've already changed behavior mulitple times up
     * to Stan v2.5.0.)
     *
     * The message is:
     * "<function>(<typeid(T)>.name()>): <name> <msg1><y><msg2>"
     *
     * @tparam T Type of variable
     * @param function Name of the function
     * @param name Name of the variable
     * @param y Variable
     * @param msg1 Message to print before the variable
     * @param msg2 Message to print after the variable
     */
    template <typename T>
    inline void dom_err(const std::string& function,
                        const std::string& name,
                        const T& y,
                        const std::string& msg1,
                        const std::string& msg2) {
      std::ostringstream message;

      message << function << "(" << typeid(T).name() << "): "
              << name << " "
              << msg1
              << y
              << msg2;

      throw std::domain_error(message.str());
    }

    /**
     * Throw a domain error with a consistently formatted message.
     *
     * This is an abstraction for all Stan functions to use when throwing
     * domain errors. This will allow us to change the behavior for all
     * functions at once. (We've already changed behavior mulitple times up
     * to Stan v2.5.0.)
     *
     * The message is:
     * "<function>(<typeid(T)>.name()>): <name> <msg1><y>"
     *
     * @tparam T Type of variable
     * @param function Name of the function
     * @param name Name of the variable
     * @param y Variable
     * @param msg1 Message to print before the variable
     */
    template <typename T>
    inline void dom_err(const std::string& function,
                        const std::string& name,
                        const T& y,
                        const std::string& msg1) {
      dom_err(function, name, y, msg1, "");
    }

  }
}
#endif
<commit_msg>removed include to boost format<commit_after>#ifndef STAN__ERROR_HANDLING__SCALAR__DOM_ERR_HPP
#define STAN__ERROR_HANDLING__SCALAR__DOM_ERR_HPP

#include <string>
#include <sstream>
#include <stdexcept>

namespace stan {
  namespace error_handling {

    /**
     * Throw a domain error with a consistently formatted message.
     *
     * This is an abstraction for all Stan functions to use when throwing
     * domain errors. This will allow us to change the behavior for all
     * functions at once. (We've already changed behavior mulitple times up
     * to Stan v2.5.0.)
     *
     * The message is:
     * "<function>(<typeid(T)>.name()>): <name> <msg1><y><msg2>"
     *
     * @tparam T Type of variable
     * @param function Name of the function
     * @param name Name of the variable
     * @param y Variable
     * @param msg1 Message to print before the variable
     * @param msg2 Message to print after the variable
     */
    template <typename T>
    inline void dom_err(const std::string& function,
                        const std::string& name,
                        const T& y,
                        const std::string& msg1,
                        const std::string& msg2) {
      std::ostringstream message;

      message << function << "(" << typeid(T).name() << "): "
              << name << " "
              << msg1
              << y
              << msg2;

      throw std::domain_error(message.str());
    }

    /**
     * Throw a domain error with a consistently formatted message.
     *
     * This is an abstraction for all Stan functions to use when throwing
     * domain errors. This will allow us to change the behavior for all
     * functions at once. (We've already changed behavior mulitple times up
     * to Stan v2.5.0.)
     *
     * The message is:
     * "<function>(<typeid(T)>.name()>): <name> <msg1><y>"
     *
     * @tparam T Type of variable
     * @param function Name of the function
     * @param name Name of the variable
     * @param y Variable
     * @param msg1 Message to print before the variable
     */
    template <typename T>
    inline void dom_err(const std::string& function,
                        const std::string& name,
                        const T& y,
                        const std::string& msg1) {
      dom_err(function, name, y, msg1, "");
    }

  }
}
#endif
<|endoftext|>


<commit_before>#include <iostream>
#include <seqan/find.h>

using namespace seqan;
using namespace std;
///This program uses the algorithm @Spec.WildShiftAnd@ to perform a wildcard search.
int main()
{
	String<char> hayst = "If you must cross a course cross cow across a crowded cow crossing, "
						 "cross the cross coarse cow across the crowded cow crossing carefully.";
	String<char> ndl = "cr?o[uw]";
///The pattern matches e.g. "cow", "crow", and "cou", but not "cros".
	Finder<String<char> > finder(hayst);
	Pattern<String<char>, WildShiftAnd> pattern(ndl);

	while (find(finder, pattern))
	{
		cout << position(finder) << "\n";
	}
	return 0;
}

<commit_msg><commit_after>///A tutorial about the use of wildcard find algorithms.
#include <iostream>
#include <seqan/find.h>

using namespace seqan;

///This program uses the algorithm @Spec.WildShiftAnd@ to perform a wildcard search.
int main()
{
	String<char> hayst = "If you must cross a course cross cow across a crowded cow crossing, "
						 "cross the cross coarse cow across the crowded cow crossing carefully.";
	String<char> ndl = "cr?o[uw]";
///The pattern matches e.g. "cow", "crow", and "cou", but not "cros".
	Finder<String<char> > finder(hayst);
	Pattern<String<char>, WildShiftAnd> pattern(ndl);

	while (find(finder, pattern)) {
		::std::cout << position(finder) << "\n";
	}
	return 0;
}

<|endoftext|>


<commit_before>#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include <sauce/sauce>

using ::testing::Sequence;
using ::testing::Return;

namespace sauce {
namespace test {

class Chasis {};
class CoupChasis:
  public Chasis {};

class Engine {};
class HybridEngine:
  public Engine {};

class Vehicle {};
class Herbie:
  public Vehicle {
public:
  SAUCE_SHARED_PTR<Chasis> chasis;
  SAUCE_SHARED_PTR<Engine> engine;

  Herbie():
    chasis(),
    engine() {}

  Herbie(SAUCE_SHARED_PTR<Chasis> chasis, SAUCE_SHARED_PTR<Engine> engine):
    chasis(chasis),
    engine(engine) {}
};

// Our mock for the new and delete operations.
//
// Gmock doesn't create templated mocks, so we roll our own specializations
// and delegate to mocked methods instead.
//
// Usually an allocator is specified by type alone: an instance is not passed.
// This is explicitly protected in the standard (requiring allocator instances
// to be exchangable and so essentially stateless.)
//
// It also prevents us from using per-instance state, which is the way gmock
// likes to do things.  To work around this, the mocked allocator state is
// kept in a common, static field (whose type is this class.)  This is the
// actual gmock, the AllocateWith (and friends) below are just
// helper types that exploit it.
class MockAllocation {
public:

  template<class C>
  C * allocate(size_t);

  template<class C>
  void deallocate(C *, size_t);

  MOCK_METHOD1(allocateCoupChasis, CoupChasis * (size_t));
  MOCK_METHOD1(allocateHybridEngine, HybridEngine * (size_t));
  MOCK_METHOD1(allocateHerbie, Herbie * (size_t));

  MOCK_METHOD2(deallocateCoupChasis, void(CoupChasis *, size_t));
  MOCK_METHOD2(deallocateHybridEngine, void(HybridEngine *, size_t));
  MOCK_METHOD2(deallocateHerbie, void(Herbie *, size_t));

};

template<>
CoupChasis * MockAllocation::allocate<CoupChasis>(size_t size) {
  return allocateCoupChasis(size);
}

template<>
HybridEngine * MockAllocation::allocate<HybridEngine>(size_t size) {
  return allocateHybridEngine(size);
}

template<>
Herbie * MockAllocation::allocate<Herbie>(size_t size) {
  return allocateHerbie(size);
}

template<>
void MockAllocation::deallocate<CoupChasis>(CoupChasis * coupChasis, size_t size) {
  deallocateCoupChasis(coupChasis, size);
}

template<>
void MockAllocation::deallocate<HybridEngine>(HybridEngine * hybridEngine, size_t size) {
  deallocateHybridEngine(hybridEngine, size);
}

template<>
void MockAllocation::deallocate<Herbie>(Herbie * herbie, size_t size) {
  deallocateHerbie(herbie, size);
}

template<typename Backing>
class AllocateWith {
public:

  // typedef Backing Backing_;
  typedef MockAllocation Backing_;

  /**
   * The untemplated allocator base class.
   *
   * It holds the shared, static pointer to a backing instance.
   */
  class Base {
  protected:
    static Backing_ * backing;
  public:
    static void setBacking(Backing_ & b) {
      backing = &b;
    }
  };

  template<class C>
  class Allocator:
    public Base {
  public:

    typedef size_t    size_type;
    typedef ptrdiff_t difference_type;
    typedef C *       pointer;
    typedef C const * const_pointer;
    typedef C &       reference;
    typedef C const & const_reference;
    typedef C         value_type;

    template<typename D>
    class rebind {
    public:
      typedef Allocator<D> other;
    };

    Allocator() {
    }

    Allocator(Allocator const & a) {
    }

    template<typename D> Allocator(Allocator<D> const &) {
    }

    C * allocate(size_t size) {
      Backing_ * b = Base::backing;
      return b->allocate<C>(size);
    }

    void deallocate(C * c, size_t size) {
      Backing_ * b = Base::backing;
      b->deallocate<C>(c, size);
    }

  };

};

// Our mock for the construct and destroy operations.
//
// Gmock doesn't create templated mocks, so we roll our own specializations
// and delegate to mocked methods instead.
class MockInitializer {
public:

  template<class C>
  void construct(C *);

  template<class C, typename A1, typename A2>
  void construct(C *, A1, A2);

  template<class C>
  void destroy(C *);

  MOCK_METHOD1(newCoupChasis, void(CoupChasis *));
  MOCK_METHOD1(newHybridEngine, void(HybridEngine *));
  MOCK_METHOD3(newHerbie, void(Herbie *, SAUCE_SHARED_PTR<Chasis>, SAUCE_SHARED_PTR<Engine> ));

  MOCK_METHOD1(deleteCoupChasis, void(CoupChasis *));
  MOCK_METHOD1(deleteHybridEngine, void(HybridEngine *));
  MOCK_METHOD1(deleteHerbie, void(Herbie *));

};

template<>
void MockInitializer::construct<CoupChasis>(CoupChasis * coupChasis) {
  newCoupChasis(coupChasis);
}

template<>
void MockInitializer::construct<HybridEngine>(HybridEngine * hybridEngine) {
  newHybridEngine(hybridEngine);
}

template<>
void MockInitializer::construct<Herbie>(Herbie * herbie,
                                        SAUCE_SHARED_PTR<Chasis> chasis,
                                        SAUCE_SHARED_PTR<Engine> engine) {
  newHerbie(herbie, chasis, engine);
}

template<>
void MockInitializer::destroy<CoupChasis>(CoupChasis * coupChasis) {
  deleteCoupChasis(coupChasis);
}

template<>
void MockInitializer::destroy<HybridEngine>(HybridEngine * hybridEngine) {
  deleteHybridEngine(hybridEngine);
}

template<>
void MockInitializer::destroy<Herbie>(Herbie * herbie) {
  deleteHerbie(herbie);
}

class MyModule {
public:

  template<typename Injector>
  static ::sauce::internal::bindings::New<Injector, Chasis,
                                          AllocateWith<MockAllocation>::Allocator<CoupChasis>,
                                          CoupChasis,
                                          CoupChasis()> * bindings(
    Chasis) {
    return 0;
  }

  template<typename Injector>
  static ::sauce::internal::bindings::New<Injector, Engine,
                                          AllocateWith<MockAllocation>::Allocator<HybridEngine>,
                                          HybridEngine,
                                          HybridEngine()> * bindings(Engine) {
    return 0;
  }

  template<typename Injector>
  static ::sauce::internal::bindings::New<Injector, Vehicle,
                                          AllocateWith<MockAllocation>::Allocator<Herbie>, Herbie,
                                          Herbie(Chasis, Engine)> * bindings(
    Vehicle) {
    return 0;
  }

};

template<>
MockAllocation * AllocateWith<MockAllocation>::Base::backing = NULL;

class SauceTest:
  public ::testing::Test {
public:

  ::sauce::Injector<MyModule, MockInitializer> injector;
  MockAllocation allocator;
  MockInitializer & initializer;

  // SauceTest is a friend of Injector
  SauceTest():
    injector(),
    allocator(),
    initializer(injector.initializer) {
    AllocateWith<MockAllocation>::Base::setBacking(allocator);
  }

};

TEST_F(SauceTest, shouldProvideAndDisposeADependency) {
  CoupChasis expected;

  // Allocate and construct.  Have the mock allocator return the coup chasis above.
  EXPECT_CALL(allocator, allocateCoupChasis(1)).WillOnce(Return(&expected));
  EXPECT_CALL(initializer, newCoupChasis(&expected));

  // Destroy and deallocate
  EXPECT_CALL(initializer, deleteCoupChasis(&expected));
  EXPECT_CALL(allocator, deallocateCoupChasis(&expected, 1));

  // Ask for a Chasis
  SAUCE_SHARED_PTR<Chasis> actual = injector.provide<Chasis>();
  ASSERT_EQ(&expected, actual.get());
}

// Argument matcher for smart pointers based on backing address.
MATCHER_P(SmartPointerTo, address, "") {
  return arg.get() == address;
}

TEST_F(SauceTest, shouldProvideAndDisposeOfDependenciesTransitively) {
  CoupChasis chasis;
  HybridEngine engine;
  Herbie vehicle;

  // We don't care about the relative ordering between chasis and engine:
  // only about how they stand relative to the vehicle.
  Sequence injectedChasis, injectedEngine;

  // Allocate and construct the chasis
  EXPECT_CALL(allocator, allocateCoupChasis(1)).
  InSequence(injectedChasis).
  WillOnce(Return(&chasis));
  EXPECT_CALL(initializer, newCoupChasis(&chasis)).
  InSequence(injectedChasis);

  // Allocate and construct the engine
  EXPECT_CALL(allocator, allocateHybridEngine(1)).
  InSequence(injectedEngine).
  WillOnce(Return(&engine));
  EXPECT_CALL(initializer, newHybridEngine(&engine)).
  InSequence(injectedEngine);

  // Allocate and construct the vehicle itself, injecting the two dependencies
  EXPECT_CALL(allocator, allocateHerbie(1)).
  InSequence(injectedChasis, injectedEngine).
  WillOnce(Return(&vehicle));
  EXPECT_CALL(initializer, newHerbie(&vehicle, SmartPointerTo(&chasis), SmartPointerTo(&engine))).
  InSequence(injectedChasis, injectedEngine);

  // Destroy and deallocate the engine
  EXPECT_CALL(initializer, deleteHybridEngine(&engine)).
  InSequence(injectedEngine);
  EXPECT_CALL(allocator, deallocateHybridEngine(&engine, 1)).
  InSequence(injectedEngine);

  // Destroy and deallocate the chasis
  EXPECT_CALL(initializer, deleteCoupChasis(&chasis)).
  InSequence(injectedChasis);
  EXPECT_CALL(allocator, deallocateCoupChasis(&chasis, 1)).
  InSequence(injectedChasis);

  // Destroy and deallocate the vehicle
  // Should destroying the vehicle after its dependencies be an issue?  This
  // is simply the order that falls out of smart pointer deletion..
  EXPECT_CALL(initializer, deleteHerbie(&vehicle)).
  InSequence(injectedChasis, injectedEngine);
  EXPECT_CALL(allocator, deallocateHerbie(&vehicle, 1)).
  InSequence(injectedChasis, injectedEngine);

  // And request a Vehicle, show it's our local, and let it fall out of scope
  SAUCE_SHARED_PTR<Vehicle> actual = injector.provide<Vehicle>();
  ASSERT_EQ(&vehicle, actual.get());
}

}
}<commit_msg>There we go.<commit_after>#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include <sauce/sauce>

using ::testing::Sequence;
using ::testing::Return;

namespace sauce {
namespace test {

class Chasis {};
class CoupChasis:
  public Chasis {};

class Engine {};
class HybridEngine:
  public Engine {};

class Vehicle {};
class Herbie:
  public Vehicle {
public:
  SAUCE_SHARED_PTR<Chasis> chasis;
  SAUCE_SHARED_PTR<Engine> engine;

  Herbie():
    chasis(),
    engine() {}

  Herbie(SAUCE_SHARED_PTR<Chasis> chasis, SAUCE_SHARED_PTR<Engine> engine):
    chasis(chasis),
    engine(engine) {}
};

// Our mock for the new and delete operations.
//
// Gmock doesn't create templated mocks, so we roll our own specializations
// and delegate to mocked methods instead.
//
// Usually an allocator is specified by type alone: an instance is not passed.
// This is explicitly protected in the standard (requiring allocator instances
// to be exchangable and so essentially stateless.)
//
// It also prevents us from using per-instance state, which is the way gmock
// likes to do things.  To work around this, the mocked allocator state is
// kept in a common, static field (whose type is this class.)  This is the
// actual gmock, the AllocateWith (and friends) below are just
// helper types that exploit it.
class MockAllocation {
public:

  template<class C>
  C * allocate(size_t);

  template<class C>
  void deallocate(C *, size_t);

  MOCK_METHOD1(allocateCoupChasis, CoupChasis * (size_t));
  MOCK_METHOD1(allocateHybridEngine, HybridEngine * (size_t));
  MOCK_METHOD1(allocateHerbie, Herbie * (size_t));

  MOCK_METHOD2(deallocateCoupChasis, void(CoupChasis *, size_t));
  MOCK_METHOD2(deallocateHybridEngine, void(HybridEngine *, size_t));
  MOCK_METHOD2(deallocateHerbie, void(Herbie *, size_t));

};

template<>
CoupChasis * MockAllocation::allocate<CoupChasis>(size_t size) {
  return allocateCoupChasis(size);
}

template<>
HybridEngine * MockAllocation::allocate<HybridEngine>(size_t size) {
  return allocateHybridEngine(size);
}

template<>
Herbie * MockAllocation::allocate<Herbie>(size_t size) {
  return allocateHerbie(size);
}

template<>
void MockAllocation::deallocate<CoupChasis>(CoupChasis * coupChasis, size_t size) {
  deallocateCoupChasis(coupChasis, size);
}

template<>
void MockAllocation::deallocate<HybridEngine>(HybridEngine * hybridEngine, size_t size) {
  deallocateHybridEngine(hybridEngine, size);
}

template<>
void MockAllocation::deallocate<Herbie>(Herbie * herbie, size_t size) {
  deallocateHerbie(herbie, size);
}

template<typename Backing>
class AllocateWith {
public:

  typedef Backing Backing_;

  /**
   * The untemplated allocator base class.
   *
   * It holds the shared, static pointer to a backing instance.
   */
  class Base {
  protected:
    static Backing_ * backing;
  public:
    static void setBacking(Backing_ & b) {
      backing = &b;
    }
  };

  template<class C>
  class Allocator:
    public Base {
  public:

    typedef size_t    size_type;
    typedef ptrdiff_t difference_type;
    typedef C *       pointer;
    typedef C const * const_pointer;
    typedef C &       reference;
    typedef C const & const_reference;
    typedef C         value_type;

    template<typename D>
    class rebind {
    public:
      typedef Allocator<D> other;
    };

    Allocator() {
    }

    Allocator(Allocator const & a) {
    }

    template<typename D> Allocator(Allocator<D> const &) {
    }

    C * allocate(size_t size) {
      Backing_ * b = Base::backing;
      return b->template allocate<C>(size);
    }

    void deallocate(C * c, size_t size) {
      Backing_ * b = Base::backing;
      b->template deallocate<C>(c, size);
    }

  };

};

// Our mock for the construct and destroy operations.
//
// Gmock doesn't create templated mocks, so we roll our own specializations
// and delegate to mocked methods instead.
class MockInitializer {
public:

  template<class C>
  void construct(C *);

  template<class C, typename A1, typename A2>
  void construct(C *, A1, A2);

  template<class C>
  void destroy(C *);

  MOCK_METHOD1(newCoupChasis, void(CoupChasis *));
  MOCK_METHOD1(newHybridEngine, void(HybridEngine *));
  MOCK_METHOD3(newHerbie, void(Herbie *, SAUCE_SHARED_PTR<Chasis>, SAUCE_SHARED_PTR<Engine> ));

  MOCK_METHOD1(deleteCoupChasis, void(CoupChasis *));
  MOCK_METHOD1(deleteHybridEngine, void(HybridEngine *));
  MOCK_METHOD1(deleteHerbie, void(Herbie *));

};

template<>
void MockInitializer::construct<CoupChasis>(CoupChasis * coupChasis) {
  newCoupChasis(coupChasis);
}

template<>
void MockInitializer::construct<HybridEngine>(HybridEngine * hybridEngine) {
  newHybridEngine(hybridEngine);
}

template<>
void MockInitializer::construct<Herbie>(Herbie * herbie,
                                        SAUCE_SHARED_PTR<Chasis> chasis,
                                        SAUCE_SHARED_PTR<Engine> engine) {
  newHerbie(herbie, chasis, engine);
}

template<>
void MockInitializer::destroy<CoupChasis>(CoupChasis * coupChasis) {
  deleteCoupChasis(coupChasis);
}

template<>
void MockInitializer::destroy<HybridEngine>(HybridEngine * hybridEngine) {
  deleteHybridEngine(hybridEngine);
}

template<>
void MockInitializer::destroy<Herbie>(Herbie * herbie) {
  deleteHerbie(herbie);
}

class MyModule {
public:

  template<typename Injector>
  static ::sauce::internal::bindings::New<Injector, Chasis,
                                          AllocateWith<MockAllocation>::Allocator<CoupChasis>,
                                          CoupChasis,
                                          CoupChasis()> * bindings(
    Chasis) {
    return 0;
  }

  template<typename Injector>
  static ::sauce::internal::bindings::New<Injector, Engine,
                                          AllocateWith<MockAllocation>::Allocator<HybridEngine>,
                                          HybridEngine,
                                          HybridEngine()> * bindings(Engine) {
    return 0;
  }

  template<typename Injector>
  static ::sauce::internal::bindings::New<Injector, Vehicle,
                                          AllocateWith<MockAllocation>::Allocator<Herbie>, Herbie,
                                          Herbie(Chasis, Engine)> * bindings(
    Vehicle) {
    return 0;
  }

};

template<>
MockAllocation * AllocateWith<MockAllocation>::Base::backing = NULL;

class SauceTest:
  public ::testing::Test {
public:

  ::sauce::Injector<MyModule, MockInitializer> injector;
  MockAllocation allocator;
  MockInitializer & initializer;

  // SauceTest is a friend of Injector
  SauceTest():
    injector(),
    allocator(),
    initializer(injector.initializer) {
    AllocateWith<MockAllocation>::Base::setBacking(allocator);
  }

};

TEST_F(SauceTest, shouldProvideAndDisposeADependency) {
  CoupChasis expected;

  // Allocate and construct.  Have the mock allocator return the coup chasis above.
  EXPECT_CALL(allocator, allocateCoupChasis(1)).WillOnce(Return(&expected));
  EXPECT_CALL(initializer, newCoupChasis(&expected));

  // Destroy and deallocate
  EXPECT_CALL(initializer, deleteCoupChasis(&expected));
  EXPECT_CALL(allocator, deallocateCoupChasis(&expected, 1));

  // Ask for a Chasis
  SAUCE_SHARED_PTR<Chasis> actual = injector.provide<Chasis>();
  ASSERT_EQ(&expected, actual.get());
}

// Argument matcher for smart pointers based on backing address.
MATCHER_P(SmartPointerTo, address, "") {
  return arg.get() == address;
}

TEST_F(SauceTest, shouldProvideAndDisposeOfDependenciesTransitively) {
  CoupChasis chasis;
  HybridEngine engine;
  Herbie vehicle;

  // We don't care about the relative ordering between chasis and engine:
  // only about how they stand relative to the vehicle.
  Sequence injectedChasis, injectedEngine;

  // Allocate and construct the chasis
  EXPECT_CALL(allocator, allocateCoupChasis(1)).
  InSequence(injectedChasis).
  WillOnce(Return(&chasis));
  EXPECT_CALL(initializer, newCoupChasis(&chasis)).
  InSequence(injectedChasis);

  // Allocate and construct the engine
  EXPECT_CALL(allocator, allocateHybridEngine(1)).
  InSequence(injectedEngine).
  WillOnce(Return(&engine));
  EXPECT_CALL(initializer, newHybridEngine(&engine)).
  InSequence(injectedEngine);

  // Allocate and construct the vehicle itself, injecting the two dependencies
  EXPECT_CALL(allocator, allocateHerbie(1)).
  InSequence(injectedChasis, injectedEngine).
  WillOnce(Return(&vehicle));
  EXPECT_CALL(initializer, newHerbie(&vehicle, SmartPointerTo(&chasis), SmartPointerTo(&engine))).
  InSequence(injectedChasis, injectedEngine);

  // Destroy and deallocate the engine
  EXPECT_CALL(initializer, deleteHybridEngine(&engine)).
  InSequence(injectedEngine);
  EXPECT_CALL(allocator, deallocateHybridEngine(&engine, 1)).
  InSequence(injectedEngine);

  // Destroy and deallocate the chasis
  EXPECT_CALL(initializer, deleteCoupChasis(&chasis)).
  InSequence(injectedChasis);
  EXPECT_CALL(allocator, deallocateCoupChasis(&chasis, 1)).
  InSequence(injectedChasis);

  // Destroy and deallocate the vehicle
  // Should destroying the vehicle after its dependencies be an issue?  This
  // is simply the order that falls out of smart pointer deletion..
  EXPECT_CALL(initializer, deleteHerbie(&vehicle)).
  InSequence(injectedChasis, injectedEngine);
  EXPECT_CALL(allocator, deallocateHerbie(&vehicle, 1)).
  InSequence(injectedChasis, injectedEngine);

  // And request a Vehicle, show it's our local, and let it fall out of scope
  SAUCE_SHARED_PTR<Vehicle> actual = injector.provide<Vehicle>();
  ASSERT_EQ(&vehicle, actual.get());
}

}
}<|endoftext|>


<commit_before>//=======================================================================
// Copyright (c) 2014-2017 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#include "test.hpp"
#include "bias_test.hpp"

// Tests for merge

TEMPLATE_TEST_CASE_2("merge/0", "[merge]", T, float, double) {
    etl::fast_matrix<T, 2, 2> a0({1, 2, 3, 2});
    etl::fast_matrix<T, 2, 2> a1({2, 3, 2, 6});
    etl::fast_matrix<T, 2, 2> a2({3, 2, 6, 0});
    etl::fast_matrix<T, 6, 2> c;

    merge(c, a0, 0);
    merge(c, a1, 1);
    merge(c, a2, 2);

    REQUIRE_EQUALS(c(0, 0), T(1));
    REQUIRE_EQUALS(c(0, 1), T(2));
    REQUIRE_EQUALS(c(1, 0), T(3));
    REQUIRE_EQUALS(c(1, 1), T(2));
    REQUIRE_EQUALS(c(2, 0), T(2));
    REQUIRE_EQUALS(c(2, 1), T(3));
    REQUIRE_EQUALS(c(3, 0), T(2));
    REQUIRE_EQUALS(c(3, 1), T(6));
    REQUIRE_EQUALS(c(4, 0), T(3));
    REQUIRE_EQUALS(c(4, 1), T(2));
    REQUIRE_EQUALS(c(5, 0), T(6));
    REQUIRE_EQUALS(c(5, 1), T(0));
}

TEMPLATE_TEST_CASE_2("batch_merge/0", "[batch_merge]", T, float, double) {
    etl::fast_matrix<T, 2, 2, 2> a0({1, 2, 3, 2, 0, 1, 4, 5});
    etl::fast_matrix<T, 2, 2, 2> a1({2, 3, 2, 6, -1, -2, -3, -4});
    etl::fast_matrix<T, 2, 2, 2> a2({3, 2, 6, 0, 1, 2, 3, 4});
    etl::fast_matrix<T, 2, 6, 2> c;

    batch_merge(c, a0, 0);
    batch_merge(c, a1, 1);
    batch_merge(c, a2, 2);

    REQUIRE_EQUALS(c(0, 0, 0), T(1));
    REQUIRE_EQUALS(c(0, 0, 1), T(2));
    REQUIRE_EQUALS(c(0, 1, 0), T(3));
    REQUIRE_EQUALS(c(0, 1, 1), T(2));
    REQUIRE_EQUALS(c(0, 2, 0), T(2));
    REQUIRE_EQUALS(c(0, 2, 1), T(3));
    REQUIRE_EQUALS(c(0, 3, 0), T(2));
    REQUIRE_EQUALS(c(0, 3, 1), T(6));
    REQUIRE_EQUALS(c(0, 4, 0), T(3));
    REQUIRE_EQUALS(c(0, 4, 1), T(2));
    REQUIRE_EQUALS(c(0, 5, 0), T(6));
    REQUIRE_EQUALS(c(0, 5, 1), T(0));

    REQUIRE_EQUALS(c(1, 0, 0), T(0));
    REQUIRE_EQUALS(c(1, 0, 1), T(1));
    REQUIRE_EQUALS(c(1, 1, 0), T(4));
    REQUIRE_EQUALS(c(1, 1, 1), T(5));
    REQUIRE_EQUALS(c(1, 2, 0), T(-1));
    REQUIRE_EQUALS(c(1, 2, 1), T(-2));
    REQUIRE_EQUALS(c(1, 3, 0), T(-3));
    REQUIRE_EQUALS(c(1, 3, 1), T(-4));
    REQUIRE_EQUALS(c(1, 4, 0), T(1));
    REQUIRE_EQUALS(c(1, 4, 1), T(2));
    REQUIRE_EQUALS(c(1, 5, 0), T(3));
    REQUIRE_EQUALS(c(1, 5, 1), T(4));
}
<commit_msg>New tests<commit_after>//=======================================================================
// Copyright (c) 2014-2017 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#include "test.hpp"
#include "bias_test.hpp"

// Tests for merge

TEMPLATE_TEST_CASE_2("merge/0", "[merge]", T, float, double) {
    etl::fast_matrix<T, 2, 2> a0({1, 2, 3, 2});
    etl::fast_matrix<T, 2, 2> a1({2, 3, 2, 6});
    etl::fast_matrix<T, 2, 2> a2({3, 2, 6, 0});
    etl::fast_matrix<T, 6, 2> c;

    merge(c, a0, 0);
    merge(c, a1, 1);
    merge(c, a2, 2);

    REQUIRE_EQUALS(c(0, 0), T(1));
    REQUIRE_EQUALS(c(0, 1), T(2));
    REQUIRE_EQUALS(c(1, 0), T(3));
    REQUIRE_EQUALS(c(1, 1), T(2));
    REQUIRE_EQUALS(c(2, 0), T(2));
    REQUIRE_EQUALS(c(2, 1), T(3));
    REQUIRE_EQUALS(c(3, 0), T(2));
    REQUIRE_EQUALS(c(3, 1), T(6));
    REQUIRE_EQUALS(c(4, 0), T(3));
    REQUIRE_EQUALS(c(4, 1), T(2));
    REQUIRE_EQUALS(c(5, 0), T(6));
    REQUIRE_EQUALS(c(5, 1), T(0));
}

TEMPLATE_TEST_CASE_2("batch_merge/0", "[batch_merge]", T, float, double) {
    etl::fast_matrix<T, 2, 2, 2> a0({1, 2, 3, 2, 0, 1, 4, 5});
    etl::fast_matrix<T, 2, 2, 2> a1({2, 3, 2, 6, -1, -2, -3, -4});
    etl::fast_matrix<T, 2, 2, 2> a2({3, 2, 6, 0, 1, 2, 3, 4});
    etl::fast_matrix<T, 2, 6, 2> c;

    batch_merge(c, a0, 0);
    batch_merge(c, a1, 1);
    batch_merge(c, a2, 2);

    REQUIRE_EQUALS(c(0, 0, 0), T(1));
    REQUIRE_EQUALS(c(0, 0, 1), T(2));
    REQUIRE_EQUALS(c(0, 1, 0), T(3));
    REQUIRE_EQUALS(c(0, 1, 1), T(2));
    REQUIRE_EQUALS(c(0, 2, 0), T(2));
    REQUIRE_EQUALS(c(0, 2, 1), T(3));
    REQUIRE_EQUALS(c(0, 3, 0), T(2));
    REQUIRE_EQUALS(c(0, 3, 1), T(6));
    REQUIRE_EQUALS(c(0, 4, 0), T(3));
    REQUIRE_EQUALS(c(0, 4, 1), T(2));
    REQUIRE_EQUALS(c(0, 5, 0), T(6));
    REQUIRE_EQUALS(c(0, 5, 1), T(0));

    REQUIRE_EQUALS(c(1, 0, 0), T(0));
    REQUIRE_EQUALS(c(1, 0, 1), T(1));
    REQUIRE_EQUALS(c(1, 1, 0), T(4));
    REQUIRE_EQUALS(c(1, 1, 1), T(5));
    REQUIRE_EQUALS(c(1, 2, 0), T(-1));
    REQUIRE_EQUALS(c(1, 2, 1), T(-2));
    REQUIRE_EQUALS(c(1, 3, 0), T(-3));
    REQUIRE_EQUALS(c(1, 3, 1), T(-4));
    REQUIRE_EQUALS(c(1, 4, 0), T(1));
    REQUIRE_EQUALS(c(1, 4, 1), T(2));
    REQUIRE_EQUALS(c(1, 5, 0), T(3));
    REQUIRE_EQUALS(c(1, 5, 1), T(4));
}

// Tests for dispatch

TEMPLATE_TEST_CASE_2("dispatch/0", "[dispatch]", T, float, double) {
    etl::fast_matrix<T, 2, 2> sa0({1, 2, 3, 2});
    etl::fast_matrix<T, 2, 2> sa1({2, 3, 2, 6});
    etl::fast_matrix<T, 2, 2> sa2({3, 2, 6, 0});
    etl::fast_matrix<T, 2, 2> a0;
    etl::fast_matrix<T, 2, 2> a1;
    etl::fast_matrix<T, 2, 2> a2;

    etl::fast_matrix<T, 6, 2> c;

    merge(c, sa0, 0);
    merge(c, sa1, 1);
    merge(c, sa2, 2);

    dispatch(a0, c, 0);
    dispatch(a1, c, 1);
    dispatch(a2, c, 2);

    for(size_t i = 0; i < 4; ++i){
        REQUIRE_EQUALS(a0[i], sa0[i]);
        REQUIRE_EQUALS(a1[i], sa1[i]);
        REQUIRE_EQUALS(a2[i], sa2[i]);
    }
}

TEMPLATE_TEST_CASE_2("batch_dispatch/0", "[batch_dispatch]", T, float, double) {
    etl::fast_matrix<T, 2, 2, 2> sa0({1, 2, 3, 2, 0, 1, 4, 5});
    etl::fast_matrix<T, 2, 2, 2> sa1({2, 3, 2, 6, -1, -2, -3, -4});
    etl::fast_matrix<T, 2, 2, 2> sa2({3, 2, 6, 0, 1, 2, 3, 4});
    etl::fast_matrix<T, 2, 2, 2> a0;
    etl::fast_matrix<T, 2, 2, 2> a1;
    etl::fast_matrix<T, 2, 2, 2> a2;

    etl::fast_matrix<T, 2, 6, 2> c;

    batch_merge(c, sa0, 0);
    batch_merge(c, sa1, 1);
    batch_merge(c, sa2, 2);

    batch_dispatch(a0, c, 0);
    batch_dispatch(a1, c, 1);
    batch_dispatch(a2, c, 2);

    for(size_t i = 0; i < 8; ++i){
        REQUIRE_EQUALS(a0[i], sa0[i]);
        REQUIRE_EQUALS(a1[i], sa1[i]);
        REQUIRE_EQUALS(a2[i], sa2[i]);
    }
}
<|endoftext|>


<commit_before>#include "MoveDummy.h"
#include "ObjectDummy.h"
#include "BodyDummy.h"
#include "ShapeCapsule.h"

#include "Utils.h"
#include "Engine.h"
#include "Physics.h"
#include "Game.h"
#include "World.h"

#define MOVE_DUMMY_IFPS			(1.0f/100.0f)
#define MOVE_DUMMY_CLAMP           89.9f
#define MOVE_DUMMY_COLLISIONS		1

using namespace MathLib;

CMoveDummy::CMoveDummy()		//캯
{
	m_pObject = new CObjectDummy();		//һʵ
	m_pDummy = new CBodyDummy();
	m_pShape = new CShapeCapsule(0.5f, 1.0f);

	SetCollisionMask(1);
	Clear();
}

CMoveDummy::~CMoveDummy()
{
	m_pDummy->SetObject(NULL);
	SAFE_DELETE(m_pObject);
	SAFE_DELETE(m_pDummy);
}

void CMoveDummy::SetCollision(int c)
{
	m_nCollision = c;
}

int CMoveDummy::GetCollision() const
{
	return m_nCollision;
}

void CMoveDummy::SetCollisionMask(int m)
{
	m_pShape->SetCollisionMask(m);
}

int CMoveDummy::GetCollisionMask() const
{
	return m_nCollisionMask;
}

void CMoveDummy::SetGround(int g)
{
	m_nGround = g;
}

int CMoveDummy::GetGround() const
{
	return m_nGround;
}

void CMoveDummy::SetCeiling(int c)
{
	m_nCeiling = c;
}

int CMoveDummy::GetCeiling() const
{
	return m_nCeiling;
}

void CMoveDummy::SetPosition(const MathLib::vec3& p)
{
	m_vPosition = p;
}

const MathLib::vec3& CMoveDummy::GetPosition() const
{
	return m_vPosition;
}

void CMoveDummy::SetCollisionRadius(float radius)
{
	if (!Compare(m_pShape->GetRadius(), radius))
	{
		m_pDummy->SetPreserveTransform(Mat4(Translate(m_vUp * (radius - m_pShape->GetRadius()))) * m_pDummy->GetTransform());
		m_pShape->SetRadius(radius);
	}

	Update_Bounds();
}

float CMoveDummy::GetCollisionRadius() const
{
	return m_pShape->GetRadius();
}

void CMoveDummy::SetCollisionHeight(float height)
{
	if (!Compare(m_pShape->GetHeight(), height))
	{
		m_pDummy->SetPreserveTransform(Mat4(Translate(m_vUp * (height - m_pShape->GetHeight()) * 0.5f)) * m_pDummy->GetTransform());
		m_pShape->SetHeight(height);
	}

	Update_Bounds();
}
float CMoveDummy::GetCollisionHeight() const
{
	return m_pShape->GetHeight();
}

void CMoveDummy::SetUp(const MathLib::vec3& u)
{
	m_vUp = u;
}

const MathLib::vec3& CMoveDummy::GetUp() const
{
	return m_vUp;
}
void CMoveDummy::SetEnabled(int e)
{
	m_nEnabled = e;
}

float CMoveDummy::GetCollisionHeight() const
{
	return m_pShape->GetHeight();
}
void CMoveDummy::SetUp(const MathLib::vec3& u)
{
	m_vUp = u;
}

const MathLib::vec3& CMoveDummy::GetUp() const
{
	return m_vUp;
}
void CMoveDummy::SetEnabled(int e)
{
	m_nEnabled = e;
}

int CMoveDummy::GetEnabled() const
{
	return m_nEnabled;
}

void CMoveDummy::SetVelocity(const MathLib::vec3& v)
{
	m_vVelocity = v;
}

const MathLib::vec3& CMoveDummy::GetVelocity() const
{
	return m_vVelocity;
}

void CMoveDummy::SetMaxVelocity(float v)
{
	m_fMaxVelocity = v;
}
float CMoveDummy::GetMaxVelocity() const
{
	return m_fMaxVelocity;
}

void CMoveDummy::SetAcceleration(float a)
{
	m_fAcceleration = a;
}
float CMoveDummy::GetAcceleration() const
{
	return m_fAcceleration;
}
float CMoveDummy::GetMaxThrough() const
{
	return m_fMaxThrough;
}
void CMoveDummy::Clear()
{
	SetVelocity(vec3_zero);
	SetMaxVelocity(2.5f);
	SetAcceleration(15.0f);
	SetCollision(1);
	SetCollisionMask(1);
	SetGround(0);
	SetCeiling(0);
	SetPosition(vec3_zero);
	SetUp(vec3(0.0f, 0.0f, 1.0f));
	SetEnabled(1);
	m_pDummy->SetEnabled(1);
	m_pObject->SetBody(NULL);
	m_pObject->SetBody(m_pDummy);

	m_pShape->SetBody(NULL);
	m_pShape->SetBody(m_pDummy);
	m_pShape->SetExclusionMask(2);

	m_pObject->SetWorldTransform(Get_Body_Transform());

}
<commit_msg>Signed-off-by: mrlitong <litongtongxue@gmail.com><commit_after>#include "MoveDummy.h"
#include "ObjectDummy.h"
#include "BodyDummy.h"
#include "ShapeCapsule.h"

#include "Utils.h"
#include "Engine.h"
#include "Physics.h"
#include "Game.h"
#include "World.h"

#define MOVE_DUMMY_IFPS			(1.0f/100.0f)
#define MOVE_DUMMY_CLAMP           89.9f
#define MOVE_DUMMY_COLLISIONS		1

using namespace MathLib;

CMoveDummy::CMoveDummy()		//캯
{
	m_pObject = new CObjectDummy();		//һʵ
	m_pDummy = new CBodyDummy();
	m_pShape = new CShapeCapsule(0.5f, 1.0f);

	SetCollisionMask(1);
	Clear();
}

CMoveDummy::~CMoveDummy()
{
	m_pDummy->SetObject(NULL);
	SAFE_DELETE(m_pObject);
	SAFE_DELETE(m_pDummy);
}

void CMoveDummy::SetCollision(int c)
{
	m_nCollision = c;
}

int CMoveDummy::GetCollision() const
{
	return m_nCollision;
}

void CMoveDummy::SetCollisionMask(int m)
{
	m_pShape->SetCollisionMask(m);
}

int CMoveDummy::GetCollisionMask() const
{
	return m_nCollisionMask;
}

void CMoveDummy::SetGround(int g)
{
	m_nGround = g;
}

int CMoveDummy::GetGround() const
{
	return m_nGround;
}

void CMoveDummy::SetCeiling(int c)
{
	m_nCeiling = c;
}

int CMoveDummy::GetCeiling() const
{
	return m_nCeiling;
}

void CMoveDummy::SetPosition(const MathLib::vec3& p)
{
	m_vPosition = p;
}

const MathLib::vec3& CMoveDummy::GetPosition() const
{
	return m_vPosition;
}

void CMoveDummy::SetCollisionRadius(float radius)
{
	if (!Compare(m_pShape->GetRadius(), radius))
	{
		m_pDummy->SetPreserveTransform(Mat4(Translate(m_vUp * (radius - m_pShape->GetRadius()))) * m_pDummy->GetTransform());
		m_pShape->SetRadius(radius);
	}

	Update_Bounds();
}

float CMoveDummy::GetCollisionRadius() const
{
	return m_pShape->GetRadius();
}

void CMoveDummy::SetCollisionHeight(float height)
{
	if (!Compare(m_pShape->GetHeight(), height))
	{
		m_pDummy->SetPreserveTransform(Mat4(Translate(m_vUp * (height - m_pShape->GetHeight()) * 0.5f)) * m_pDummy->GetTransform());
		m_pShape->SetHeight(height);
	}

	Update_Bounds();
}
float CMoveDummy::GetCollisionHeight() const
{
	return m_pShape->GetHeight();
}

void CMoveDummy::SetUp(const MathLib::vec3& u)
{
	m_vUp = u;
}

const MathLib::vec3& CMoveDummy::GetUp() const
{
	return m_vUp;
}
void CMoveDummy::SetEnabled(int e)
{
	m_nEnabled = e;
}

float CMoveDummy::GetCollisionHeight() const
{
	return m_pShape->GetHeight();
}
void CMoveDummy::SetUp(const MathLib::vec3& u)
{
	m_vUp = u;
}

const MathLib::vec3& CMoveDummy::GetUp() const
{
	return m_vUp;
}
void CMoveDummy::SetEnabled(int e)
{
	m_nEnabled = e;
}

int CMoveDummy::GetEnabled() const
{
	return m_nEnabled;
}

void CMoveDummy::SetVelocity(const MathLib::vec3& v)
{
	m_vVelocity = v;
}

const MathLib::vec3& CMoveDummy::GetVelocity() const
{
	return m_vVelocity;
}

void CMoveDummy::SetMaxVelocity(float v)
{
	m_fMaxVelocity = v;
}
float CMoveDummy::GetMaxVelocity() const
{
	return m_fMaxVelocity;
}

void CMoveDummy::SetAcceleration(float a)
{
	m_fAcceleration = a;
}
float CMoveDummy::GetAcceleration() const
{
	return m_fAcceleration;
}
float CMoveDummy::GetMaxThrough() const
{
	return m_fMaxThrough;
}
void CMoveDummy::Clear()
{
	SetVelocity(vec3_zero);
	SetMaxVelocity(2.5f);
	SetAcceleration(15.0f);
	SetCollision(1);
	SetCollisionMask(1);
	SetGround(0);
	SetCeiling(0);
	SetPosition(vec3_zero);
	SetUp(vec3(0.0f, 0.0f, 1.0f));
	SetEnabled(1);
	m_pDummy->SetEnabled(1);
	m_pObject->SetBody(NULL);
	m_pObject->SetBody(m_pDummy);

	m_pShape->SetBody(NULL);
	m_pShape->SetBody(m_pDummy);
	m_pShape->SetExclusionMask(2);

	m_pObject->SetWorldTransform(Get_Body_Transform());

	SetCollisionRadius(0.5f);
	SetCollisionHeight(1.0f);

}
<|endoftext|>


<commit_before>#include <iostream>
#include <cmath>
#include <list>
#include <fstream>
#include <vector>
#include "gnuplot_i.hpp"

#define GNUPLOT_PATH "C:/gnuplot/bin"
#define M_PI 3.1415926

using namespace std;

double start, stop;

double M = 5.974e24;
double G = 6.67e-11;
double h = 3; //wielkosc kroku calkowania
const int table_size = 30000;

double x[table_size];
double y[table_size];
double vx[table_size];
double vy[table_size];

//http://scicomp.stackexchange.com/questions/12854/simulate-motion-of-the-kepler-orbit-using-runge-kutta-4-method-in-c

double func1(double y1, double y2, double y3, double y4){
    return y2;
}

double func2(double y1,double y2, double y3, double y4 ){
    double r = sqrt(y1*y1+y3*y3);
    return -G*M*y1/(r*r*r);
}

double func3(double y1, double y2,double y3, double y4 ){
    return y4;
}

double func4(double y1, double y2, double y3, double y4){
    double r = sqrt(y1*y1+y3*y3);
    return -G*M*y3/(r*r*r);
}

void RungeKutta(double *y1, double *y2, double *y3, double *y4 ){

    for(int i=0; i<table_size-1; i++){
        double k11=h*func1(y1[i],y2[i], y3[i],  y4[i]);
        double k21=h*func2(y1[i],y2[i], y3[i],  y4[i]);
        double k31=h*func3(y1[i],y2[i], y3[i],  y4[i]);
        double k41=h*func4(y1[i],y2[i], y3[i],  y4[i]);

        double k12=h*func1(0.5*k11+y1[i], 0.5*k21+y2[i], 0.5*k31+y3[i], 0.5*k41+y4[i]);
        double k22=h*func2(0.5*k11+y1[i], 0.5*k21+y2[i], 0.5*k31+y3[i], 0.5*k41+y4[i]);
        double k32=h*func3(0.5*k11+y1[i], 0.5*k21+y2[i], 0.5*k31+y3[i], 0.5*k41+y4[i]);
        double k42=h*func4(0.5*k11+y1[i], 0.5*k21+y2[i], 0.5*k31+y3[i], 0.5*k41+y4[i]);

        double k13=h*func1(0.5*k12+y1[i], 0.5*k22+y2[i], 0.5*k32+y3[i], 0.5*k42+y4[i]);
        double k23=h*func2(0.5*k12+y1[i], 0.5*k22+y2[i], 0.5*k32+y3[i], 0.5*k42+y4[i]);
        double k33=h*func3(0.5*k12+y1[i], 0.5*k22+y2[i], 0.5*k32+y3[i], 0.5*k42+y4[i]);
        double k43=h*func4(0.5*k12+y1[i], 0.5*k22+y2[i], 0.5*k32+y3[i], 0.5*k42+y4[i]);

        double k14=h*func1(k13+y1[i], k23+y2[i], k33+y3[i], k43+y4[i]);
        double k24=h*func2(k13+y1[i], k23+y2[i], k33+y3[i], k43+y4[i]);
        double k34=h*func3(k13+y1[i], k23+y2[i], k33+y3[i], k43+y4[i]);
        double k44=h*func4(k13+y1[i], k23+y2[i], k33+y3[i], k43+y4[i]);

        y1[i+1] = y1[i] + (k11+2*k12+2*k13+k14)/6;
        y2[i+1] = y2[i] + (k21+2*k22+2*k23+k24)/6;
        y3[i+1] = y3[i] + (k31+2*k32+2*k33+k34)/6;
        y4[i+1] = y4[i] + (k41+2*k42+2*k43+k44)/6;
    }

}

double min(double *tab){
    double mini = tab[0];
    for (int i=1; i< table_size; i++){
        if (tab[i] < mini) mini = tab[i];
    }

    return mini;
}

double max(double *tab){
    double maxi = tab[0];
    for (int i=1; i< table_size; i++){
        if (tab[i] > maxi) maxi = tab[i];
    }

    return maxi;
}

void wybierzFunk(){
    cout << "Wybierz przypadek [1-3]: \n> ";
    int wybor;

    cin >> wybor;
    x[0] = 6.578e6;
    y[0] = 0;
    vx[0] = 0;
    switch(wybor){
    case 1:
        vy[0] = 7900;
        break;
    case 2:
        vy[0] = 9000;
        break;
    case 3:
        vy[0] = 11200;
        break;
    default:
        throw string("Example not found");
    }
}

int main()
{
    Gnuplot::set_GNUPlotPath( GNUPLOT_PATH );

    try{
        wybierzFunk();
    } catch (string s){
        cout << s << endl;
        return 0;
    }

    RungeKutta(x,vx,y,vy);

    start = 0;
    stop = table_size-1;

    Gnuplot X_plot;
    Gnuplot Y_plot;
    Gnuplot Vx_plot;
    Gnuplot Vy_plot;
    Gnuplot XY_plot;

    {
        X_plot.set_title( "X" );
        X_plot.set_xlabel( "X" );
        X_plot.set_ylabel( "Y" );

        X_plot.set_grid();
        X_plot.set_xrange( start , stop ) ;
        X_plot.set_yrange(min(x),max(x));
        X_plot.set_style( "lines" );
        vector<double> poz;
        vector<double> pion;
        for(int i=0; i<table_size; i++){
            poz.push_back(i);
            pion.push_back(x[i]);
        }

        X_plot.plot_xy( poz, pion, "Wykres funkcji." );
    }

    {
        Y_plot.set_title( "Y" );
        Y_plot.set_xlabel( "X" );
        Y_plot.set_ylabel( "Y" );

        Y_plot.set_grid();
        Y_plot.set_xrange( start , stop ) ;
        Y_plot.set_yrange(min(y),max(y));
        Y_plot.set_style( "lines" );
        vector<double> poz;
        vector<double> pion;
        for(int i=0; i<table_size; i++){
            poz.push_back(i);
            pion.push_back(y[i]);
        }

        Y_plot.plot_xy( poz, pion, "Wykres funkcji." );
    }

    {
        Vx_plot.set_title( "Vx" );
        Vx_plot.set_xlabel( "X" );
        Vx_plot.set_ylabel( "Y" );

        Vx_plot.set_grid();
        Vx_plot.set_xrange( start , stop ) ;
        Vx_plot.set_yrange(min(vx),max(vx));
        Vx_plot.set_style( "lines" );
        vector<double> poz;
        vector<double> pion;
        for(int i=0; i<table_size; i++){
            poz.push_back(i);
            pion.push_back(vx[i]);
        }

        Vx_plot.plot_xy( poz, pion, "Wykres funkcji." );
    }

    {
        Vy_plot.set_title( "Vy" );
        Vy_plot.set_xlabel( "X" );
        Vy_plot.set_ylabel( "Y" );

        Vy_plot.set_grid();
        Vy_plot.set_xrange( start , stop ) ;
        Vy_plot.set_yrange(min(vy),max(vy));
        Vy_plot.set_style( "lines" );
        vector<double> poz;
        vector<double> pion;
        for(int i=0; i<table_size; i++){
            poz.push_back(i);
            pion.push_back(vy[i]);
        }

        Vy_plot.plot_xy( poz, pion, "Wykres funkcji." );
    }

    {
        XY_plot.set_title( "XY" );
        XY_plot.set_xlabel( "X" );
        XY_plot.set_ylabel( "Y" );

        XY_plot.set_grid();
        XY_plot.set_xrange( min(x)*1.1 , max(x)*1.1 ) ;
        XY_plot.set_yrange(min(y)*1.1,max(y)*1.1);
        XY_plot.set_style( "lines" );
        vector<double> poz;
        vector<double> pion;
        for(int i=0; i<table_size; i++){
            poz.push_back(x[i]);
            pion.push_back(y[i]);
        }

        XY_plot.plot_xy( poz, pion, "Wykres funkcji." );

        XY_plot.set_style( "points" );
        vector<double> poz0 {x[0]};
        vector<double> pion0{y[0]};
        XY_plot.plot_xy( poz0, pion0, "Pocztek ruchu." );

        vector<double> zero {0};
        XY_plot.plot_xy( zero, zero, "Punkt zerowy." );
    }

    getchar();
    getchar();

    return 0;
}

<commit_msg>Dalsze czyszczenie kodu.<commit_after>#include <iostream>
#include <cmath>
#include <list>
#include <fstream>
#include <vector>
#include "gnuplot_i.hpp"

#define GNUPLOT_PATH "C:/gnuplot/bin"

using namespace std;

double start, stop;

double M = 5.974e24;
double G = 6.67e-11;
double h = 3; //wielkosc kroku calkowania
const int table_size = 30000;

double x[table_size];
double y[table_size];
double vx[table_size];
double vy[table_size];

//http://scicomp.stackexchange.com/questions/12854/simulate-motion-of-the-kepler-orbit-using-runge-kutta-4-method-in-c

double func1(double y2){
    return y2;
}

double func2(double y1, double y3 ){
    double r = sqrt(y1*y1+y3*y3);
    return -G*M*y1/(r*r*r);
}

double func3(double y4 ){
    return y4;
}

double func4(double y1, double y3){
    double r = sqrt(y1*y1+y3*y3);
    return -G*M*y3/(r*r*r);
}

void RungeKutta(double *y1, double *y2, double *y3, double *y4 ){

    for(int i=0; i<table_size-1; i++){
        double k11=h*func1(y2[i]);
        double k21=h*func2(y1[i], y3[i]);
        double k31=h*func3(y4[i]);
        double k41=h*func4(y1[i], y3[i]);

        double k12=h*func1(0.5*k21+y2[i]);
        double k22=h*func2(0.5*k11+y1[i], 0.5*k31+y3[i]);
        double k32=h*func3( 0.5*k41+y4[i]);
        double k42=h*func4(0.5*k11+y1[i], 0.5*k31+y3[i]);

        double k13=h*func1(0.5*k22+y2[i]);
        double k23=h*func2(0.5*k12+y1[i], 0.5*k32+y3[i]);
        double k33=h*func3(0.5*k42+y4[i]);
        double k43=h*func4(0.5*k12+y1[i], 0.5*k32+y3[i]);

        double k14=h*func1(k23+y2[i]);
        double k24=h*func2(k13+y1[i], k33+y3[i]);
        double k34=h*func3(k43+y4[i]);
        double k44=h*func4(k13+y1[i], k33+y3[i]);

        y1[i+1] = y1[i] + (k11+2*k12+2*k13+k14)/6;
        y2[i+1] = y2[i] + (k21+2*k22+2*k23+k24)/6;
        y3[i+1] = y3[i] + (k31+2*k32+2*k33+k34)/6;
        y4[i+1] = y4[i] + (k41+2*k42+2*k43+k44)/6;
    }

}

double min(double *tab){
    double mini = tab[0];
    for (int i=1; i< table_size; i++){
        if (tab[i] < mini) mini = tab[i];
    }

    return mini;
}

double max(double *tab){
    double maxi = tab[0];
    for (int i=1; i< table_size; i++){
        if (tab[i] > maxi) maxi = tab[i];
    }

    return maxi;
}

void wybierzFunk(){
    cout << "Wybierz przypadek [1-3]: \n> ";
    int wybor;

    cin >> wybor;
    x[0] = 6.578e6;
    y[0] = 0;
    vx[0] = 0;
    switch(wybor){
    case 1:
        vy[0] = 7900;
        break;
    case 2:
        vy[0] = 9000;
        break;
    case 3:
        vy[0] = 11200;
        break;
    default:
        throw string("Example not found");
    }
}

int main()
{
    Gnuplot::set_GNUPlotPath( GNUPLOT_PATH );

    try{
        wybierzFunk();
    } catch (string s){
        cout << s << endl;
        return 0;
    }

    RungeKutta(x,vx,y,vy);

    start = 0;
    stop = table_size-1;

    Gnuplot X_plot;
    Gnuplot Y_plot;
    Gnuplot Vx_plot;
    Gnuplot Vy_plot;
    Gnuplot XY_plot;

    {
        X_plot.set_title( "X" );
        X_plot.set_xlabel( "X" );
        X_plot.set_ylabel( "Y" );

        X_plot.set_grid();
        X_plot.set_xrange( start , stop ) ;
        X_plot.set_yrange(min(x),max(x));
        X_plot.set_style( "lines" );
        vector<double> poz;
        vector<double> pion;
        for(int i=0; i<table_size; i++){
            poz.push_back(i);
            pion.push_back(x[i]);
        }

        X_plot.plot_xy( poz, pion, "Wykres funkcji." );
    }

    {
        Y_plot.set_title( "Y" );
        Y_plot.set_xlabel( "X" );
        Y_plot.set_ylabel( "Y" );

        Y_plot.set_grid();
        Y_plot.set_xrange( start , stop ) ;
        Y_plot.set_yrange(min(y),max(y));
        Y_plot.set_style( "lines" );
        vector<double> poz;
        vector<double> pion;
        for(int i=0; i<table_size; i++){
            poz.push_back(i);
            pion.push_back(y[i]);
        }

        Y_plot.plot_xy( poz, pion, "Wykres funkcji." );
    }

    {
        Vx_plot.set_title( "Vx" );
        Vx_plot.set_xlabel( "X" );
        Vx_plot.set_ylabel( "Y" );

        Vx_plot.set_grid();
        Vx_plot.set_xrange( start , stop ) ;
        Vx_plot.set_yrange(min(vx),max(vx));
        Vx_plot.set_style( "lines" );
        vector<double> poz;
        vector<double> pion;
        for(int i=0; i<table_size; i++){
            poz.push_back(i);
            pion.push_back(vx[i]);
        }

        Vx_plot.plot_xy( poz, pion, "Wykres funkcji." );
    }

    {
        Vy_plot.set_title( "Vy" );
        Vy_plot.set_xlabel( "X" );
        Vy_plot.set_ylabel( "Y" );

        Vy_plot.set_grid();
        Vy_plot.set_xrange( start , stop ) ;
        Vy_plot.set_yrange(min(vy),max(vy));
        Vy_plot.set_style( "lines" );
        vector<double> poz;
        vector<double> pion;
        for(int i=0; i<table_size; i++){
            poz.push_back(i);
            pion.push_back(vy[i]);
        }

        Vy_plot.plot_xy( poz, pion, "Wykres funkcji." );
    }

    {
        XY_plot.set_title( "XY" );
        XY_plot.set_xlabel( "X" );
        XY_plot.set_ylabel( "Y" );

        XY_plot.set_grid();
        XY_plot.set_xrange( min(x)*1.1 , max(x)*1.1 ) ;
        XY_plot.set_yrange(min(y)*1.1,max(y)*1.1);
        XY_plot.set_style( "lines" );
        vector<double> poz;
        vector<double> pion;
        for(int i=0; i<table_size; i++){
            poz.push_back(x[i]);
            pion.push_back(y[i]);
        }

        XY_plot.plot_xy( poz, pion, "Wykres funkcji." );

        XY_plot.set_style( "points" );
        vector<double> poz0 {x[0]};
        vector<double> pion0{y[0]};
        XY_plot.plot_xy( poz0, pion0, "Pocztek ruchu." );

        vector<double> zero {0};
        XY_plot.plot_xy( zero, zero, "Punkt zerowy." );
    }

    getchar();
    getchar();

    return 0;
}

<|endoftext|>


<commit_before>/*
 * Copyright (c) 2012. The Regents of the University of California. All rights reserved.
 * Licensed pursuant to the terms and conditions available for viewing at:
 * http://opensource.org/licenses/BSD-3-Clause
 *
 * File: imagecache.cpp
 * Author: Jonathan Ventura
 * Last Modified: 12.2.2012
 */

#include <ImageCache/imagecache.h>
#include <PatchTracker/ssd.h>

#include <cvd/vision.h>
#include <cvd/image_convert.h>
#include <cvd/convolution.h>
#include <cvd/image_io.h>

#include <TooN/TooN.h>

namespace vrlt
{
    using namespace std;
    using namespace TooN;
    using namespace CVD;

    ImageCache::ImageCache()
    : matchThreshold( 30 * 30 * 80 * 45 ), maxCacheSize( 1 ), ssd_calc( ImageRef(80,45) ), next_to_try( 0 )
    {

    }

    void ImageCache::makeSmallByteImage( Camera *camera )
    {
        camera->small_byte_image = halfSample( halfSample( halfSample( halfSample( camera->image ) ) ) );
    }

    void ImageCache::prepareSmallImage( Camera *camera )
    {
        camera->small_byte_image = halfSample( camera->small_byte_image );

        camera->small_image.resize( camera->small_byte_image.size() );
        convert_image( camera->small_byte_image, camera->small_image );

        convolveGaussian( camera->small_image, 2.5 );
        removeMean( camera->small_image );
        normalize( camera->small_image );
    }

    bool ImageCache::test( Camera *camera )
    {
        Sophus::SE3d inv_pose = camera->node->globalPose().inverse();

        for ( int i = 0; i < cache.size(); i++ )
        {
            Sophus::SE3d rel_pose = cache[i]->node->globalPose() * inv_pose;
            double dist = norm( rel_pose.get_translation() );
            if ( dist < 0.1 ) {
                double angle = norm( rel_pose.get_rotation().ln() ) * 180. / M_PI;
                if ( angle < 45. ) return false;
            }
        }
        return true;
    }

    void ImageCache::add( Camera *camera )
    {
        if ( cache.size() >= maxCacheSize )
        {
            cache.erase( cache.begin() );
        }
        cache.push_back( camera );
        next_to_try = cache.size() - 1;
    }

    void ImageCache::addCopy( Camera *camera )
    {
        Camera *mycamera = new Camera;
        mycamera->name = camera->name;
        mycamera->calibration = camera->calibration;
        mycamera->image = camera->image;
        Node *mynode = new Node;
        mynode->name = camera->node->name;
        mycamera->node = mynode;
        mynode->camera = mycamera;
        mynode->pose = camera->node->pose;

        makeSmallByteImage( mycamera );
        prepareSmallImage( mycamera );
        this->add( mycamera );
    }

    void ImageCache::getNext( Camera *query )
    {
        if ( cache.empty() ) return;
        Camera *camera = cache[next_to_try];
        query->node->pose = camera->node->pose;
    }

    void ImageCache::moveNext()
    {
        next_to_try--;
        if ( next_to_try < 0 ) next_to_try = cache.size() - 1;
    }

    bool ImageCache::search( Camera *query )
    {
        makeSmallByteImage( query );
        prepareSmallImage( query );

        float bestCorr = -1.f;
        bestCamera = NULL;

        for ( int i = 0; i < cache.size(); i++ )
        {
            Camera *camera = cache[i];

            float corr = getCorr( camera->small_image, query->small_image );
            if ( corr > bestCorr )
            {
                bestCorr = corr;
                bestCamera = camera;
            }
        }

        if ( bestCamera == NULL ) return false;

        query->node->pose = bestCamera->node->pose;
        return true;
    }
}<commit_msg>converted ImageCache<commit_after>/*
 * Copyright (c) 2012. The Regents of the University of California. All rights reserved.
 * Licensed pursuant to the terms and conditions available for viewing at:
 * http://opensource.org/licenses/BSD-3-Clause
 *
 * File: imagecache.cpp
 * Author: Jonathan Ventura
 * Last Modified: 12.2.2012
 */

#include <ImageCache/imagecache.h>
#include <PatchTracker/ssd.h>

#include <opencv2/imgproc.hpp>

#include <Eigen/Core>

namespace vrlt
{

    ImageCache::ImageCache()
    : matchThreshold( 30 * 30 * 80 * 45 ), maxCacheSize( 1 ), next_to_try( 0 ), ssd_calc( cv::Size(80,45) )
    {

    }

    void ImageCache::makeSmallByteImage( Camera *camera )
    {
        cv::Mat img1;
        cv::Mat img2;
        cv::Mat img3;
        cv::pyrDown( camera->image, img1 );
        cv::pyrDown( img1, img2 );
        cv::pyrDown( img2, img3 );
        cv::pyrDown( img3, camera->small_byte_image );
    }

    void ImageCache::prepareSmallImage( Camera *camera )
    {
        cv::Mat img5;
        cv::pyrDown( camera->small_byte_image, img5 );
        camera->small_byte_image = img5;

        camera->small_byte_image.convertTo( camera->small_image, CV_32FC1 );

        cv::GaussianBlur( camera->small_image, camera->small_image, cv::Size(7,7), 2.5 );
        cv::subtract( camera->small_image, cv::mean(camera->small_image), camera->small_image );
        cv::divide( camera->small_image, cv::norm(camera->small_image), camera->small_image );
    }

    bool ImageCache::test( Camera *camera )
    {
        Sophus::SE3d inv_pose = camera->node->globalPose().inverse();

        for ( int i = 0; i < cache.size(); i++ )
        {
            Sophus::SE3d rel_pose = cache[i]->node->globalPose() * inv_pose;
            double dist = rel_pose.translation().norm();
            if ( dist < 0.1 ) {
                double angle = rel_pose.so3().log().norm() * 180. / M_PI;
                if ( angle < 45. ) return false;
            }
        }
        return true;
    }

    void ImageCache::add( Camera *camera )
    {
        if ( cache.size() >= maxCacheSize )
        {
            cache.erase( cache.begin() );
        }
        cache.push_back( camera );
        next_to_try = cache.size() - 1;
    }

    void ImageCache::addCopy( Camera *camera )
    {
        Camera *mycamera = new Camera;
        mycamera->name = camera->name;
        mycamera->calibration = camera->calibration;
        mycamera->image = camera->image;
        Node *mynode = new Node;
        mynode->name = camera->node->name;
        mycamera->node = mynode;
        mynode->camera = mycamera;
        mynode->pose = camera->node->pose;

        makeSmallByteImage( mycamera );
        prepareSmallImage( mycamera );
        this->add( mycamera );
    }

    void ImageCache::getNext( Camera *query )
    {
        if ( cache.empty() ) return;
        Camera *camera = cache[next_to_try];
        query->node->pose = camera->node->pose;
    }

    void ImageCache::moveNext()
    {
        next_to_try--;
        if ( next_to_try < 0 ) next_to_try = cache.size() - 1;
    }

    bool ImageCache::search( Camera *query )
    {
        makeSmallByteImage( query );
        prepareSmallImage( query );

        float bestCorr = -1.f;
        bestCamera = NULL;

        for ( int i = 0; i < cache.size(); i++ )
        {
            Camera *camera = cache[i];

            float corr = getCorr( camera->small_image, query->small_image );
            if ( corr > bestCorr )
            {
                bestCorr = corr;
                bestCamera = camera;
            }
        }

        if ( bestCamera == NULL ) return false;

        query->node->pose = bestCamera->node->pose;
        return true;
    }
}<|endoftext|>