<commit_before>/* -------------------------------------------------------------------------- *
 *                       OpenSim:  MovingPathPoint.cpp                        *
 * -------------------------------------------------------------------------- *
 * The OpenSim API is a toolkit for musculoskeletal modeling and simulation.  *
 * See http://opensim.stanford.edu and the NOTICE file for more information.  *
 * OpenSim is developed at Stanford University and supported by the US        *
 * National Institutes of Health (U54 GM072970, R24 HD065690) and by DARPA    *
 * through the Warrior Web program.                                           *
 *                                                                            *
 * Copyright (c) 2005-2012 Stanford University and the Authors                *
 * Author(s): Peter Loan                                                      *
 *                                                                            *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may    *
 * not use this file except in compliance with the License. You may obtain a  *
 * copy of the License at http://www.apache.org/licenses/LICENSE-2.0.         *
 *                                                                            *
 * Unless required by applicable law or agreed to in writing, software        *
 * distributed under the License is distributed on an "AS IS" BASIS,          *
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   *
 * See the License for the specific language governing permissions and        *
 * limitations under the License.                                             *
 * -------------------------------------------------------------------------- */

//=============================================================================
// INCLUDES
//=============================================================================
#include <OpenSim/Common/XMLDocument.h>
#include "MovingPathPoint.h"
#include <OpenSim/Common/Function.h>
#include <OpenSim/Common/Constant.h>
#include <OpenSim/Common/MultiplierFunction.h>
#include <OpenSim/Simulation/SimbodyEngine/Coordinate.h>

//=============================================================================
// STATICS
//=============================================================================
using namespace std;
using namespace OpenSim;
using SimTK::Vec3;

//=============================================================================
// CONSTRUCTOR(S) AND DESTRUCTOR
//=============================================================================
//_____________________________________________________________________________
/*
 * Default constructor.
 */
MovingPathPoint::MovingPathPoint() : PathPoint()
{
    constructInfrastructure();
}

//_____________________________________________________________________________
/*
 * Destructor.
 */
MovingPathPoint::~MovingPathPoint()
{
}

//_____________________________________________________________________________
/*
* Connect properties to local pointers.
*/
void MovingPathPoint::constructProperties()
{
    constructProperty_x_location(Constant(0.0));
    constructProperty_y_location(Constant(0.0));
    constructProperty_z_location(Constant(0.0));
}

void MovingPathPoint::constructConnectors()
{
    constructConnector<Coordinate>("x_coordinate");
    constructConnector<Coordinate>("y_coordinate");
    constructConnector<Coordinate>("z_coordinate");
}

bool MovingPathPoint::hasXCoordinate() const
{
    return getConnector<Coordinate>("x_coordinate").isConnected();
}
bool MovingPathPoint::hasYCoordinate() const
{
    return getConnector<Coordinate>("y_coordinate").isConnected();
}
bool MovingPathPoint::hasZCoordinate() const
{
    return getConnector<Coordinate>("z_coordinate").isConnected();
}

const Coordinate& MovingPathPoint::getXCoordinate() const
{
    return _xCoordinate.getRef();
}

const Coordinate& MovingPathPoint::getYCoordinate() const
{
    return _yCoordinate.getRef();
}

const Coordinate& MovingPathPoint::getZCoordinate() const
{
    return _zCoordinate.getRef();
}

void MovingPathPoint::setXCoordinate(const Coordinate& coordinate)
{
    updConnector<Coordinate>("x_coordinate").connect(coordinate);
}
void MovingPathPoint::setYCoordinate(const Coordinate& coordinate)
{
    updConnector<Coordinate>("y_coordinate").connect(coordinate);
}
void MovingPathPoint::setZCoordinate(const Coordinate& coordinate)
{
    updConnector<Coordinate>("z_coordinate").connect(coordinate);
}

void MovingPathPoint::extendConnectToModel(Model& model)
{
    Super::extendConnectToModel(model);
    // Hang on to references to the Coordinates instead of
    // finding the connector each time we need a Coordinate value
    if (getConnector<Coordinate>("x_coordinate").isConnected()) {
        _xCoordinate.reset(&getConnectee<Coordinate>("x_coordinate"));
    }
    if (getConnector<Coordinate>("y_coordinate").isConnected()) {
        _yCoordinate.reset(&getConnectee<Coordinate>("y_coordinate"));
    }
    if (getConnector<Coordinate>("z_coordinate").isConnected()) {
        _zCoordinate.reset(&getConnectee<Coordinate>("z_coordinate"));
    }

    // As OpenSim 3.2 we correct for the Work along a Coordinate due to
    // the generalized force that enforces the "gearing" that moves the point
    // under tension. The work is attributed to a single Coordinate, so
    // we temporarily do not support independent components.
    // TODO: If the coordinates are different then, getdPointdQ() should return a
    // 3x3 of partials or return a Vec3 w.r.t one coordinate at a time, where the
    // specific Coordinate is an argument.
    OPENSIM_THROW_IF(!((_xCoordinate == _yCoordinate) && (_xCoordinate == _zCoordinate)),
        Exception,
        "MovingPathPoint:: Components of the path point location "
        "must depend on the same Coordinate. Condition: "
        "x_coordinate == y_coordinate == z_coordinate  FAILED.");

    // Overwrite any setting of a MovingPathPoint's location property.
    // MovingPathPoint should NOT derive from Station.
    // TODO: We should not have Path specific Points of any kind. They should
    // be "path" Points by virtue of being subcomponents of a GeometryPath.
    // Set it to NaN so it blows up if we attempt to use a MovingPathPoint
    // as a Station.
    set_location(SimTK::Vec3(SimTK::NaN));
}

//_____________________________________________________________________________
/*
 * Override default implementation by Object to intercept and fix the XML node
 * underneath the MovingPathPoint to match the current version.
 */
void MovingPathPoint::updateFromXMLNode(SimTK::Xml::Element& aNode, int versionNumber)
{
    int documentVersion = versionNumber;
    if (documentVersion < 30000) {
        if (Object::getDebugLevel()>=1)
            cout << "Updating MovingPathPoint object to latest format..." << endl;
        XMLDocument::renameChildNode(aNode, "XAttachment", "x_location");
        XMLDocument::renameChildNode(aNode,"YAttachment", "y_location");
        XMLDocument::renameChildNode(aNode,"ZAttachment", "z_location");
    }
    if (documentVersion < 30505) {
        // replace old properties with latest use of Connectors
        SimTK::Xml::element_iterator xCoord = aNode.element_begin("x_coordinate");
        SimTK::Xml::element_iterator yCoord = aNode.element_begin("y_coordinate");
        SimTK::Xml::element_iterator zCoord = aNode.element_begin("z_coordinate");

        std::string xCoord_name(""), yCoord_name(""), zCoord_name("");
        // If default constructed then elements not serialized since they are default
        // values. Check that we have associated elements, then extract their values.
        if (xCoord != aNode.element_end())
            xCoord->getValueAs<std::string>(xCoord_name);
        if (yCoord != aNode.element_end())
            yCoord->getValueAs<std::string>(yCoord_name);
        if (zCoord != aNode.element_end())
            zCoord->getValueAs<std::string>(zCoord_name);
        XMLDocument::addConnector(aNode, "Connector_Coordinate_",
            "x_coordinate", xCoord_name);
        XMLDocument::addConnector(aNode, "Connector_Coordinate_",
            "y_coordinate", yCoord_name);
        XMLDocument::addConnector(aNode, "Connector_Coordinate_",
            "z_coordinate", zCoord_name);
    }

    // Call base class now assuming _node has been corrected for current version
    Super::updateFromXMLNode(aNode, versionNumber);
}

SimTK::Vec3 MovingPathPoint::getLocation(const SimTK::State& s) const
{
    SimTK::Vec3 pInF(0);
    if (!_xCoordinate.empty()) {
        const double xval = SimTK::clamp(_xCoordinate->getRangeMin(),
            _xCoordinate->getValue(s),
            _xCoordinate->getRangeMax());
        pInF[0] = get_x_location().calcValue(SimTK::Vector(1, xval));
    }
    else // assume a Constant
        pInF[0] = get_x_location().calcValue(SimTK::Vector(1, 0.0));

    if (!_yCoordinate.empty()) {
        const double yval = SimTK::clamp(_yCoordinate->getRangeMin(),
            _yCoordinate->getValue(s),
            _yCoordinate->getRangeMax());
        pInF[1] = get_y_location().calcValue(SimTK::Vector(1, yval));
    }
    else // type == Constant
        pInF[1] = get_y_location().calcValue(SimTK::Vector(1, 0.0));

    if (!_zCoordinate.empty()) {
        const double zval = SimTK::clamp(_zCoordinate->getRangeMin(),
            _zCoordinate->getValue(s),
            _zCoordinate->getRangeMax());
        pInF[2] = get_z_location().calcValue(SimTK::Vector(1, zval));
    }
    else // type == Constant
        pInF[2] = get_z_location().calcValue(SimTK::Vector(1, 0.0));

    return pInF;
}

SimTK::Vec3 MovingPathPoint::getVelocity(const SimTK::State& s) const
{
    std::vector<int> derivComponents;
    derivComponents.push_back(0);

    SimTK::Vec3 vInF(0);

    if (!_xCoordinate.empty()){
        //Multiply the partial (derivative of point coordinate w.r.t. gencoord) by genspeed
        vInF[0] = get_x_location().calcDerivative(
            derivComponents, SimTK::Vector(1, _xCoordinate->getValue(s)))*
                _xCoordinate->getSpeedValue(s);
    }
    else
        vInF[0] = 0.0;

    if (!_yCoordinate.empty()){
        //Multiply the partial (derivative of point coordinate w.r.t. gencoord) by genspeed
        vInF[1] = get_y_location().calcDerivative(
            derivComponents, SimTK::Vector(1, _yCoordinate->getValue(s)))*
                _yCoordinate->getSpeedValue(s);
    }
    else
        vInF[1] = 0.0;

    if (!_zCoordinate.empty()){
        //Multiply the partial (derivative of point coordinate w.r.t. gencoord) by genspeed
        vInF[2] = get_z_location().calcDerivative(
            derivComponents, SimTK::Vector(1, _zCoordinate->getValue(s)))*
                _zCoordinate->getSpeedValue(s);
    }
    else
        vInF[2] = 0.0;

    return vInF;
}

//_____________________________________________________________________________
/*
 * Get the velocity of the point in the body's local reference frame.
 */
SimTK::Vec3 MovingPathPoint::getdPointdQ(const SimTK::State& s) const
{
    SimTK::Vec3 dPdq_B(0);

    std::vector<int> derivComponents;
    derivComponents.push_back(0);

    if (!_xCoordinate.empty()){
        //Multiply the partial (derivative of point coordinate w.r.t. gencoord) by genspeed
        dPdq_B[0] = get_x_location().calcDerivative(derivComponents,
            SimTK::Vector(1, _xCoordinate->getValue(s)));
    }
    if (!_yCoordinate.empty()){
        //Multiply the partial (derivative of point coordinate w.r.t. gencoord) by genspeed
        dPdq_B[1] = get_y_location().calcDerivative(derivComponents,
            SimTK::Vector(1, _yCoordinate->getValue(s)));
    }
    if (!_zCoordinate.empty()){
        //Multiply the partial (derivative of point coordinate w.r.t. gencoord) by genspeed
        dPdq_B[2] = get_z_location().calcDerivative(derivComponents,
            SimTK::Vector(1, _zCoordinate->getValue(s)));
    }

    return dPdq_B;
}

void MovingPathPoint::scale(const SimTK::Vec3& aScaleFactors)
{
    if (!_xCoordinate.empty()) {
        // If the function is already a MultiplierFunction, just update its scale factor.
        // Otherwise, make a MultiplierFunction from it and make the muscle point use
        // the new MultiplierFunction.
        MultiplierFunction* mf = dynamic_cast<MultiplierFunction*>(&upd_x_location());
        if (mf) {
            mf->setScale(mf->getScale() * aScaleFactors[0]);
        } else {
            // Make a copy of the original function and delete the original
            // (so its node will be removed from the XML document).
            set_x_location(MultiplierFunction(get_x_location().clone(), aScaleFactors[0]));
        }
    }

    if (!_yCoordinate.empty()) {
        // If the function is already a MultiplierFunction, just update its scale factor.
        // Otherwise, make a MultiplierFunction from it and make the muscle point use
        // the new MultiplierFunction.
        MultiplierFunction* mf = dynamic_cast<MultiplierFunction*>(&upd_y_location());
        if (mf) {
            mf->setScale(mf->getScale() * aScaleFactors[1]);
        } else {
            // Make a copy of the original function and delete the original
            // (so its node will be removed from the XML document).
            set_y_location(MultiplierFunction(get_y_location().clone(), aScaleFactors[1]));
        }
    }

    if (!_zCoordinate.empty()) {
        // If the function is already a MultiplierFunction, just update its scale factor.
        // Otherwise, make a MultiplierFunction from it and make the muscle point use
        // the new MultiplierFunction.
        MultiplierFunction* mf = dynamic_cast<MultiplierFunction*>(&upd_z_location());
        if (mf) {
            mf->setScale(mf->getScale() * aScaleFactors[2]);
        } else {
            set_z_location(MultiplierFunction(get_z_location().clone(), aScaleFactors[2]));
        }
    }

    updateGeometry();
}

SimTK::Vec3 MovingPathPoint::calcLocationInGround(const SimTK::State& s) const
{
    return getParentFrame().getTransformInGround(s)*getLocation(s);
}

SimTK::Vec3 MovingPathPoint::calcVelocityInGround(const SimTK::State& s) const
{
    // compute the local position vector of the station in its reference frame
    // expressed in ground
    const auto& R_GF = getParentFrame().getTransformInGround(s).R();
    const Vec3 r = R_GF*getLocation(s);

    const SimTK::SpatialVec& V_GF = getParentFrame().getVelocityInGround(s);
    const Vec3 v = R_GF*getVelocity(s);

    // The velocity of the station in ground is a function of its frame's
    // linear (vF = V_GF[1]) and angular (omegaF = V_GF[0]) velocity, such that
    // velocity of the station: v = vF + omegaF x r
    return V_GF[1] + V_GF[0] % r + v;
}

SimTK::Vec3 MovingPathPoint::calcAccelerationInGround(const SimTK::State& state) const
{
    //TODO: Enable Exception or Implement the method and add accompanying test.
    //      Exception is disabled because testComponents automatically verifies that
    //      Outputs are functional. My preference is to implement the method
    //OPENSIM_THROW(Exception, "MovingPathPoint::calcAccelerationInGround not implemented.");
    std::cerr << "MovingPathPoint::calcAccelerationInGround() not implemented. "
        << "It returns NaN" << std::endl;
    return Vec3(SimTK::NaN);
}
<commit_msg>Clarify comments and procudeure for calcVelocityInGround<commit_after>/* -------------------------------------------------------------------------- *
 *                       OpenSim:  MovingPathPoint.cpp                        *
 * -------------------------------------------------------------------------- *
 * The OpenSim API is a toolkit for musculoskeletal modeling and simulation.  *
 * See http://opensim.stanford.edu and the NOTICE file for more information.  *
 * OpenSim is developed at Stanford University and supported by the US        *
 * National Institutes of Health (U54 GM072970, R24 HD065690) and by DARPA    *
 * through the Warrior Web program.                                           *
 *                                                                            *
 * Copyright (c) 2005-2012 Stanford University and the Authors                *
 * Author(s): Peter Loan                                                      *
 *                                                                            *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may    *
 * not use this file except in compliance with the License. You may obtain a  *
 * copy of the License at http://www.apache.org/licenses/LICENSE-2.0.         *
 *                                                                            *
 * Unless required by applicable law or agreed to in writing, software        *
 * distributed under the License is distributed on an "AS IS" BASIS,          *
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   *
 * See the License for the specific language governing permissions and        *
 * limitations under the License.                                             *
 * -------------------------------------------------------------------------- */

//=============================================================================
// INCLUDES
//=============================================================================
#include <OpenSim/Common/XMLDocument.h>
#include "MovingPathPoint.h"
#include <OpenSim/Common/Function.h>
#include <OpenSim/Common/Constant.h>
#include <OpenSim/Common/MultiplierFunction.h>
#include <OpenSim/Simulation/SimbodyEngine/Coordinate.h>

//=============================================================================
// STATICS
//=============================================================================
using namespace std;
using namespace OpenSim;
using SimTK::Vec3;

//=============================================================================
// CONSTRUCTOR(S) AND DESTRUCTOR
//=============================================================================
//_____________________________________________________________________________
/*
 * Default constructor.
 */
MovingPathPoint::MovingPathPoint() : PathPoint()
{
    constructInfrastructure();
}

//_____________________________________________________________________________
/*
 * Destructor.
 */
MovingPathPoint::~MovingPathPoint()
{
}

//_____________________________________________________________________________
/*
* Connect properties to local pointers.
*/
void MovingPathPoint::constructProperties()
{
    constructProperty_x_location(Constant(0.0));
    constructProperty_y_location(Constant(0.0));
    constructProperty_z_location(Constant(0.0));
}

void MovingPathPoint::constructConnectors()
{
    constructConnector<Coordinate>("x_coordinate");
    constructConnector<Coordinate>("y_coordinate");
    constructConnector<Coordinate>("z_coordinate");
}

bool MovingPathPoint::hasXCoordinate() const
{
    return getConnector<Coordinate>("x_coordinate").isConnected();
}
bool MovingPathPoint::hasYCoordinate() const
{
    return getConnector<Coordinate>("y_coordinate").isConnected();
}
bool MovingPathPoint::hasZCoordinate() const
{
    return getConnector<Coordinate>("z_coordinate").isConnected();
}

const Coordinate& MovingPathPoint::getXCoordinate() const
{
    return _xCoordinate.getRef();
}

const Coordinate& MovingPathPoint::getYCoordinate() const
{
    return _yCoordinate.getRef();
}

const Coordinate& MovingPathPoint::getZCoordinate() const
{
    return _zCoordinate.getRef();
}

void MovingPathPoint::setXCoordinate(const Coordinate& coordinate)
{
    updConnector<Coordinate>("x_coordinate").connect(coordinate);
}
void MovingPathPoint::setYCoordinate(const Coordinate& coordinate)
{
    updConnector<Coordinate>("y_coordinate").connect(coordinate);
}
void MovingPathPoint::setZCoordinate(const Coordinate& coordinate)
{
    updConnector<Coordinate>("z_coordinate").connect(coordinate);
}

void MovingPathPoint::extendConnectToModel(Model& model)
{
    Super::extendConnectToModel(model);
    // Hang on to references to the Coordinates instead of
    // finding the connector each time we need a Coordinate value
    if (getConnector<Coordinate>("x_coordinate").isConnected()) {
        _xCoordinate.reset(&getConnectee<Coordinate>("x_coordinate"));
    }
    if (getConnector<Coordinate>("y_coordinate").isConnected()) {
        _yCoordinate.reset(&getConnectee<Coordinate>("y_coordinate"));
    }
    if (getConnector<Coordinate>("z_coordinate").isConnected()) {
        _zCoordinate.reset(&getConnectee<Coordinate>("z_coordinate"));
    }

    // As OpenSim 3.2 we correct for the Work along a Coordinate due to
    // the generalized force that enforces the "gearing" that moves the point
    // under tension. The work is attributed to a single Coordinate, so
    // we temporarily do not support independent components.
    // TODO: If the coordinates are different then, getdPointdQ() should return a
    // 3x3 of partials or return a Vec3 w.r.t one coordinate at a time, where the
    // specific Coordinate is an argument.
    OPENSIM_THROW_IF(!((_xCoordinate == _yCoordinate) && (_xCoordinate == _zCoordinate)),
        Exception,
        "MovingPathPoint:: Components of the path point location "
        "must depend on the same Coordinate. Condition: "
        "x_coordinate == y_coordinate == z_coordinate  FAILED.");

    // Overwrite any setting of a MovingPathPoint's location property.
    // MovingPathPoint should NOT derive from Station.
    // TODO: We should not have Path specific Points of any kind. They should
    // be "path" Points by virtue of being subcomponents of a GeometryPath.
    // Set it to NaN so it blows up if we attempt to use a MovingPathPoint
    // as a Station.
    set_location(SimTK::Vec3(SimTK::NaN));
}

//_____________________________________________________________________________
/*
 * Override default implementation by Object to intercept and fix the XML node
 * underneath the MovingPathPoint to match the current version.
 */
void MovingPathPoint::updateFromXMLNode(SimTK::Xml::Element& aNode, int versionNumber)
{
    int documentVersion = versionNumber;
    if (documentVersion < 30000) {
        if (Object::getDebugLevel()>=1)
            cout << "Updating MovingPathPoint object to latest format..." << endl;
        XMLDocument::renameChildNode(aNode, "XAttachment", "x_location");
        XMLDocument::renameChildNode(aNode,"YAttachment", "y_location");
        XMLDocument::renameChildNode(aNode,"ZAttachment", "z_location");
    }
    if (documentVersion < 30505) {
        // replace old properties with latest use of Connectors
        SimTK::Xml::element_iterator xCoord = aNode.element_begin("x_coordinate");
        SimTK::Xml::element_iterator yCoord = aNode.element_begin("y_coordinate");
        SimTK::Xml::element_iterator zCoord = aNode.element_begin("z_coordinate");

        std::string xCoord_name(""), yCoord_name(""), zCoord_name("");
        // If default constructed then elements not serialized since they are default
        // values. Check that we have associated elements, then extract their values.
        if (xCoord != aNode.element_end())
            xCoord->getValueAs<std::string>(xCoord_name);
        if (yCoord != aNode.element_end())
            yCoord->getValueAs<std::string>(yCoord_name);
        if (zCoord != aNode.element_end())
            zCoord->getValueAs<std::string>(zCoord_name);
        XMLDocument::addConnector(aNode, "Connector_Coordinate_",
            "x_coordinate", xCoord_name);
        XMLDocument::addConnector(aNode, "Connector_Coordinate_",
            "y_coordinate", yCoord_name);
        XMLDocument::addConnector(aNode, "Connector_Coordinate_",
            "z_coordinate", zCoord_name);
    }

    // Call base class now assuming _node has been corrected for current version
    Super::updateFromXMLNode(aNode, versionNumber);
}

SimTK::Vec3 MovingPathPoint::getLocation(const SimTK::State& s) const
{
    SimTK::Vec3 pInF(0);
    if (!_xCoordinate.empty()) {
        const double xval = SimTK::clamp(_xCoordinate->getRangeMin(),
            _xCoordinate->getValue(s),
            _xCoordinate->getRangeMax());
        pInF[0] = get_x_location().calcValue(SimTK::Vector(1, xval));
    }
    else // assume a Constant
        pInF[0] = get_x_location().calcValue(SimTK::Vector(1, 0.0));

    if (!_yCoordinate.empty()) {
        const double yval = SimTK::clamp(_yCoordinate->getRangeMin(),
            _yCoordinate->getValue(s),
            _yCoordinate->getRangeMax());
        pInF[1] = get_y_location().calcValue(SimTK::Vector(1, yval));
    }
    else // type == Constant
        pInF[1] = get_y_location().calcValue(SimTK::Vector(1, 0.0));

    if (!_zCoordinate.empty()) {
        const double zval = SimTK::clamp(_zCoordinate->getRangeMin(),
            _zCoordinate->getValue(s),
            _zCoordinate->getRangeMax());
        pInF[2] = get_z_location().calcValue(SimTK::Vector(1, zval));
    }
    else // type == Constant
        pInF[2] = get_z_location().calcValue(SimTK::Vector(1, 0.0));

    return pInF;
}

SimTK::Vec3 MovingPathPoint::getVelocity(const SimTK::State& s) const
{
    std::vector<int> derivComponents;
    derivComponents.push_back(0);

    SimTK::Vec3 vInF(0);

    if (!_xCoordinate.empty()){
        //Multiply the partial (derivative of point coordinate w.r.t. gencoord) by genspeed
        vInF[0] = get_x_location().calcDerivative(
            derivComponents, SimTK::Vector(1, _xCoordinate->getValue(s)))*
                _xCoordinate->getSpeedValue(s);
    }
    else
        vInF[0] = 0.0;

    if (!_yCoordinate.empty()){
        //Multiply the partial (derivative of point coordinate w.r.t. gencoord) by genspeed
        vInF[1] = get_y_location().calcDerivative(
            derivComponents, SimTK::Vector(1, _yCoordinate->getValue(s)))*
                _yCoordinate->getSpeedValue(s);
    }
    else
        vInF[1] = 0.0;

    if (!_zCoordinate.empty()){
        //Multiply the partial (derivative of point coordinate w.r.t. gencoord) by genspeed
        vInF[2] = get_z_location().calcDerivative(
            derivComponents, SimTK::Vector(1, _zCoordinate->getValue(s)))*
                _zCoordinate->getSpeedValue(s);
    }
    else
        vInF[2] = 0.0;

    return vInF;
}

//_____________________________________________________________________________
/*
 * Get the velocity of the point in the body's local reference frame.
 */
SimTK::Vec3 MovingPathPoint::getdPointdQ(const SimTK::State& s) const
{
    SimTK::Vec3 dPdq_B(0);

    std::vector<int> derivComponents;
    derivComponents.push_back(0);

    if (!_xCoordinate.empty()){
        //Multiply the partial (derivative of point coordinate w.r.t. gencoord) by genspeed
        dPdq_B[0] = get_x_location().calcDerivative(derivComponents,
            SimTK::Vector(1, _xCoordinate->getValue(s)));
    }
    if (!_yCoordinate.empty()){
        //Multiply the partial (derivative of point coordinate w.r.t. gencoord) by genspeed
        dPdq_B[1] = get_y_location().calcDerivative(derivComponents,
            SimTK::Vector(1, _yCoordinate->getValue(s)));
    }
    if (!_zCoordinate.empty()){
        //Multiply the partial (derivative of point coordinate w.r.t. gencoord) by genspeed
        dPdq_B[2] = get_z_location().calcDerivative(derivComponents,
            SimTK::Vector(1, _zCoordinate->getValue(s)));
    }

    return dPdq_B;
}

void MovingPathPoint::scale(const SimTK::Vec3& aScaleFactors)
{
    if (!_xCoordinate.empty()) {
        // If the function is already a MultiplierFunction, just update its scale factor.
        // Otherwise, make a MultiplierFunction from it and make the muscle point use
        // the new MultiplierFunction.
        MultiplierFunction* mf = dynamic_cast<MultiplierFunction*>(&upd_x_location());
        if (mf) {
            mf->setScale(mf->getScale() * aScaleFactors[0]);
        } else {
            // Make a copy of the original function and delete the original
            // (so its node will be removed from the XML document).
            set_x_location(MultiplierFunction(get_x_location().clone(), aScaleFactors[0]));
        }
    }

    if (!_yCoordinate.empty()) {
        // If the function is already a MultiplierFunction, just update its scale factor.
        // Otherwise, make a MultiplierFunction from it and make the muscle point use
        // the new MultiplierFunction.
        MultiplierFunction* mf = dynamic_cast<MultiplierFunction*>(&upd_y_location());
        if (mf) {
            mf->setScale(mf->getScale() * aScaleFactors[1]);
        } else {
            // Make a copy of the original function and delete the original
            // (so its node will be removed from the XML document).
            set_y_location(MultiplierFunction(get_y_location().clone(), aScaleFactors[1]));
        }
    }

    if (!_zCoordinate.empty()) {
        // If the function is already a MultiplierFunction, just update its scale factor.
        // Otherwise, make a MultiplierFunction from it and make the muscle point use
        // the new MultiplierFunction.
        MultiplierFunction* mf = dynamic_cast<MultiplierFunction*>(&upd_z_location());
        if (mf) {
            mf->setScale(mf->getScale() * aScaleFactors[2]);
        } else {
            set_z_location(MultiplierFunction(get_z_location().clone(), aScaleFactors[2]));
        }
    }

    updateGeometry();
}

SimTK::Vec3 MovingPathPoint::calcLocationInGround(const SimTK::State& s) const
{
    return getParentFrame().getTransformInGround(s)*getLocation(s);
}

SimTK::Vec3 MovingPathPoint::calcVelocityInGround(const SimTK::State& s) const
{
    // compute the local position vector, r, of the moving point in its
    // parent reference frame, F, expressed in Ground, G.
    const auto& R_GF = getParentFrame().getTransformInGround(s).R();
    const Vec3 r = R_GF*getLocation(s);

    // express the local velocity of the moving point in Ground
    const Vec3 v = R_GF*getVelocity(s);

    // get the velocity of the parent frame, F,  in Ground, G.
    const SimTK::SpatialVec& V_GF = getParentFrame().getVelocityInGround(s);

    // The velocity of the moving point in Ground is a combination of its parent
    // frame's linear (v_GF = V_GF[1]) and angular (omega_GF = V_GF[0]) velocity,
    // and its local velocity in F, such that:
    // v_GP = v_GF + omega_GF x r_FP_G + v_FP_G
    return V_GF[1] + V_GF[0] % r + v;
}

SimTK::Vec3 MovingPathPoint::calcAccelerationInGround(const SimTK::State& state) const
{
    //TODO: Enable Exception or Implement the method and add accompanying test.
    //      Exception is disabled because testComponents automatically verifies that
    //      Outputs are functional. My preference is to implement the method
    //OPENSIM_THROW(Exception, "MovingPathPoint::calcAccelerationInGround not implemented.");
    std::cerr << "MovingPathPoint::calcAccelerationInGround() not implemented. "
        << "It returns NaN" << std::endl;
    return Vec3(SimTK::NaN);
}
<|endoftext|>


<commit_before>// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/chromeos/drive/file_system/move_operation.h"

#include "chrome/browser/chromeos/drive/file_system/copy_operation.h"
#include "chrome/browser/chromeos/drive/file_system/operation_test_base.h"
#include "chrome/browser/drive/fake_drive_service.h"
#include "google_apis/drive/test_util.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace drive {
namespace file_system {

class MoveOperationTest : public OperationTestBase {
 protected:
  virtual void SetUp() OVERRIDE {
   OperationTestBase::SetUp();
   operation_.reset(new MoveOperation(blocking_task_runner(),
                                      observer(),
                                      metadata()));
   copy_operation_.reset(new CopyOperation(blocking_task_runner(),
                                           observer(),
                                           scheduler(),
                                           metadata(),
                                           cache(),
                                           fake_service(),
                                           temp_dir()));
  }

  scoped_ptr<MoveOperation> operation_;
  scoped_ptr<CopyOperation> copy_operation_;
};

TEST_F(MoveOperationTest, MoveFileInSameDirectory) {
  const base::FilePath src_path(
      FILE_PATH_LITERAL("drive/root/Directory 1/SubDirectory File 1.txt"));
  const base::FilePath dest_path(
      FILE_PATH_LITERAL("drive/root/Directory 1/Test.log"));

  ResourceEntry src_entry, dest_entry;
  ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(src_path, &src_entry));
  ASSERT_EQ(FILE_ERROR_NOT_FOUND,
            GetLocalResourceEntry(dest_path, &dest_entry));

  FileError error = FILE_ERROR_FAILED;
  operation_->Move(src_path,
                   dest_path,
                   false,
                   google_apis::test_util::CreateCopyResultCallback(&error));
  test_util::RunBlockingPoolTask();
  EXPECT_EQ(FILE_ERROR_OK, error);

  EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(dest_path, &dest_entry));
  EXPECT_EQ(src_entry.local_id(), dest_entry.local_id());
  EXPECT_EQ(ResourceEntry::DIRTY, dest_entry.metadata_edit_state());
  EXPECT_EQ(FILE_ERROR_NOT_FOUND, GetLocalResourceEntry(src_path, &src_entry));

  EXPECT_EQ(1U, observer()->get_changed_paths().size());
  EXPECT_TRUE(observer()->get_changed_paths().count(src_path.DirName()));
}

TEST_F(MoveOperationTest, MoveFileFromRootToSubDirectory) {
  base::FilePath src_path(FILE_PATH_LITERAL("drive/root/File 1.txt"));
  base::FilePath dest_path(
      FILE_PATH_LITERAL("drive/root/Directory 1/Test.log"));

  ResourceEntry src_entry, dest_entry;
  ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(src_path, &src_entry));
  ASSERT_EQ(FILE_ERROR_NOT_FOUND,
            GetLocalResourceEntry(dest_path, &dest_entry));

  FileError error = FILE_ERROR_FAILED;
  operation_->Move(src_path,
                   dest_path,
                   false,
                   google_apis::test_util::CreateCopyResultCallback(&error));
  test_util::RunBlockingPoolTask();
  EXPECT_EQ(FILE_ERROR_OK, error);

  EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(dest_path, &dest_entry));
  EXPECT_EQ(src_entry.local_id(), dest_entry.local_id());
  EXPECT_EQ(ResourceEntry::DIRTY, dest_entry.metadata_edit_state());
  EXPECT_EQ(FILE_ERROR_NOT_FOUND, GetLocalResourceEntry(src_path, &src_entry));

  EXPECT_EQ(2U, observer()->get_changed_paths().size());
  EXPECT_TRUE(observer()->get_changed_paths().count(src_path.DirName()));
  EXPECT_TRUE(observer()->get_changed_paths().count(dest_path.DirName()));
}

TEST_F(MoveOperationTest, MoveFileBetweenSubDirectoriesRenameWithTitle) {
  base::FilePath src_path(
      FILE_PATH_LITERAL("drive/root/Directory 1/SubDirectory File 1.txt"));
  base::FilePath dest_path(FILE_PATH_LITERAL(
      "drive/root/Directory 1/Sub Directory Folder/"
      "SubDirectory File 1 (1).txt"));

  ResourceEntry src_entry, dest_entry;
  ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(src_path, &src_entry));
  ASSERT_EQ(FILE_ERROR_NOT_FOUND,
            GetLocalResourceEntry(dest_path, &dest_entry));

  FileError error = FILE_ERROR_FAILED;
  // Copy the src file into the same directory. This will make inconsistency
  // between title and path of the copied file.
  copy_operation_->Copy(
      src_path,
      src_path,
      false,
      google_apis::test_util::CreateCopyResultCallback(&error));
  test_util::RunBlockingPoolTask();
  EXPECT_EQ(FILE_ERROR_OK, error);
  base::FilePath copied_path(
      FILE_PATH_LITERAL("drive/root/Directory 1/SubDirectory File 1 (1).txt"));
  ResourceEntry copied_entry;
  ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(copied_path, &copied_entry));
  ASSERT_EQ("SubDirectory File 1.txt", copied_entry.title());

  // Move the copied file.
  operation_->Move(copied_path,
                   dest_path,
                   false,
                   google_apis::test_util::CreateCopyResultCallback(&error));
  test_util::RunBlockingPoolTask();
  EXPECT_EQ(FILE_ERROR_OK, error);

  EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(dest_path, &dest_entry));
  EXPECT_EQ("SubDirectory File 1 (1).txt", dest_entry.title());
  EXPECT_EQ(copied_entry.local_id(), dest_entry.local_id());
  EXPECT_EQ(ResourceEntry::DIRTY, dest_entry.metadata_edit_state());
  EXPECT_EQ(FILE_ERROR_NOT_FOUND,
            GetLocalResourceEntry(copied_path, &copied_entry));

  EXPECT_EQ(2U, observer()->get_changed_paths().size());
  EXPECT_TRUE(observer()->get_changed_paths().count(copied_path.DirName()));
  EXPECT_TRUE(observer()->get_changed_paths().count(dest_path.DirName()));
}

TEST_F(MoveOperationTest, MoveNotExistingFile) {
  base::FilePath src_path(FILE_PATH_LITERAL("drive/root/Dummy file.txt"));
  base::FilePath dest_path(FILE_PATH_LITERAL("drive/root/Test.log"));

  FileError error = FILE_ERROR_OK;
  operation_->Move(src_path,
                   dest_path,
                   false,
                   google_apis::test_util::CreateCopyResultCallback(&error));
  test_util::RunBlockingPoolTask();
  EXPECT_EQ(FILE_ERROR_NOT_FOUND, error);

  ResourceEntry entry;
  EXPECT_EQ(FILE_ERROR_NOT_FOUND, GetLocalResourceEntry(src_path, &entry));
  EXPECT_EQ(FILE_ERROR_NOT_FOUND, GetLocalResourceEntry(dest_path, &entry));
}

TEST_F(MoveOperationTest, MoveFileToNonExistingDirectory) {
  base::FilePath src_path(FILE_PATH_LITERAL("drive/root/File 1.txt"));
  base::FilePath dest_path(FILE_PATH_LITERAL("drive/root/Dummy/Test.log"));

  FileError error = FILE_ERROR_OK;
  operation_->Move(src_path,
                   dest_path,
                   false,
                   google_apis::test_util::CreateCopyResultCallback(&error));
  test_util::RunBlockingPoolTask();
  EXPECT_EQ(FILE_ERROR_NOT_FOUND, error);

  ResourceEntry entry;
  EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(src_path, &entry));
  EXPECT_EQ(FILE_ERROR_NOT_FOUND, GetLocalResourceEntry(dest_path, &entry));
}

// Test the case where the parent of |dest_file_path| is a existing file,
// not a directory.
TEST_F(MoveOperationTest, MoveFileToInvalidPath) {
  base::FilePath src_path(FILE_PATH_LITERAL("drive/root/File 1.txt"));
  base::FilePath dest_path(
      FILE_PATH_LITERAL("drive/root/Duplicate Name.txt/Test.log"));

  FileError error = FILE_ERROR_OK;
  operation_->Move(src_path,
                   dest_path,
                   false,
                   google_apis::test_util::CreateCopyResultCallback(&error));
  test_util::RunBlockingPoolTask();
  EXPECT_EQ(FILE_ERROR_NOT_A_DIRECTORY, error);

  ResourceEntry entry;
  EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(src_path, &entry));
  EXPECT_EQ(FILE_ERROR_NOT_FOUND, GetLocalResourceEntry(dest_path, &entry));
}

TEST_F(MoveOperationTest, PreserveLastModified) {
  const base::FilePath src_path(
      FILE_PATH_LITERAL("drive/root/Directory 1/SubDirectory File 1.txt"));
  const base::FilePath dest_path(
      FILE_PATH_LITERAL("drive/root/Directory 1/Test.log"));

  ResourceEntry src_entry, dest_entry;
  ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(src_path, &src_entry));
  ASSERT_EQ(FILE_ERROR_NOT_FOUND,
            GetLocalResourceEntry(dest_path, &dest_entry));

  FileError error = FILE_ERROR_FAILED;
  operation_->Move(src_path,
                   dest_path,
                   true,  // Preserve last modified.
                   google_apis::test_util::CreateCopyResultCallback(&error));
  test_util::RunBlockingPoolTask();
  EXPECT_EQ(FILE_ERROR_OK, error);

  EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(dest_path, &dest_entry));
  EXPECT_EQ(src_entry.local_id(), dest_entry.local_id());
  EXPECT_EQ(src_entry.file_info().last_modified(),
            dest_entry.file_info().last_modified());
  EXPECT_EQ(ResourceEntry::DIRTY, dest_entry.metadata_edit_state());
  EXPECT_EQ(FILE_ERROR_NOT_FOUND,
            GetLocalResourceEntry(src_path, &src_entry));
}

}  // namespace file_system
}  // namespace drive
<commit_msg>drive: Check OperationObserver::OnEntryUpdatedByOperation is called by MoveOperation in tests<commit_after>// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/chromeos/drive/file_system/move_operation.h"

#include "chrome/browser/chromeos/drive/file_system/copy_operation.h"
#include "chrome/browser/chromeos/drive/file_system/operation_test_base.h"
#include "chrome/browser/drive/fake_drive_service.h"
#include "google_apis/drive/test_util.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace drive {
namespace file_system {

class MoveOperationTest : public OperationTestBase {
 protected:
  virtual void SetUp() OVERRIDE {
   OperationTestBase::SetUp();
   operation_.reset(new MoveOperation(blocking_task_runner(),
                                      observer(),
                                      metadata()));
   copy_operation_.reset(new CopyOperation(blocking_task_runner(),
                                           observer(),
                                           scheduler(),
                                           metadata(),
                                           cache(),
                                           fake_service(),
                                           temp_dir()));
  }

  scoped_ptr<MoveOperation> operation_;
  scoped_ptr<CopyOperation> copy_operation_;
};

TEST_F(MoveOperationTest, MoveFileInSameDirectory) {
  const base::FilePath src_path(
      FILE_PATH_LITERAL("drive/root/Directory 1/SubDirectory File 1.txt"));
  const base::FilePath dest_path(
      FILE_PATH_LITERAL("drive/root/Directory 1/Test.log"));

  ResourceEntry src_entry, dest_entry;
  ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(src_path, &src_entry));
  ASSERT_EQ(FILE_ERROR_NOT_FOUND,
            GetLocalResourceEntry(dest_path, &dest_entry));

  FileError error = FILE_ERROR_FAILED;
  operation_->Move(src_path,
                   dest_path,
                   false,
                   google_apis::test_util::CreateCopyResultCallback(&error));
  test_util::RunBlockingPoolTask();
  EXPECT_EQ(FILE_ERROR_OK, error);

  EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(dest_path, &dest_entry));
  EXPECT_EQ(src_entry.local_id(), dest_entry.local_id());
  EXPECT_EQ(ResourceEntry::DIRTY, dest_entry.metadata_edit_state());
  EXPECT_EQ(FILE_ERROR_NOT_FOUND, GetLocalResourceEntry(src_path, &src_entry));

  EXPECT_EQ(1U, observer()->get_changed_paths().size());
  EXPECT_TRUE(observer()->get_changed_paths().count(src_path.DirName()));

  EXPECT_EQ(1U, observer()->updated_local_ids().size());
  EXPECT_TRUE(observer()->updated_local_ids().count(src_entry.local_id()));
}

TEST_F(MoveOperationTest, MoveFileFromRootToSubDirectory) {
  base::FilePath src_path(FILE_PATH_LITERAL("drive/root/File 1.txt"));
  base::FilePath dest_path(
      FILE_PATH_LITERAL("drive/root/Directory 1/Test.log"));

  ResourceEntry src_entry, dest_entry;
  ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(src_path, &src_entry));
  ASSERT_EQ(FILE_ERROR_NOT_FOUND,
            GetLocalResourceEntry(dest_path, &dest_entry));

  FileError error = FILE_ERROR_FAILED;
  operation_->Move(src_path,
                   dest_path,
                   false,
                   google_apis::test_util::CreateCopyResultCallback(&error));
  test_util::RunBlockingPoolTask();
  EXPECT_EQ(FILE_ERROR_OK, error);

  EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(dest_path, &dest_entry));
  EXPECT_EQ(src_entry.local_id(), dest_entry.local_id());
  EXPECT_EQ(ResourceEntry::DIRTY, dest_entry.metadata_edit_state());
  EXPECT_EQ(FILE_ERROR_NOT_FOUND, GetLocalResourceEntry(src_path, &src_entry));

  EXPECT_EQ(2U, observer()->get_changed_paths().size());
  EXPECT_TRUE(observer()->get_changed_paths().count(src_path.DirName()));
  EXPECT_TRUE(observer()->get_changed_paths().count(dest_path.DirName()));

  EXPECT_EQ(1U, observer()->updated_local_ids().size());
  EXPECT_TRUE(observer()->updated_local_ids().count(src_entry.local_id()));
}

TEST_F(MoveOperationTest, MoveFileBetweenSubDirectoriesRenameWithTitle) {
  base::FilePath src_path(
      FILE_PATH_LITERAL("drive/root/Directory 1/SubDirectory File 1.txt"));
  base::FilePath dest_path(FILE_PATH_LITERAL(
      "drive/root/Directory 1/Sub Directory Folder/"
      "SubDirectory File 1 (1).txt"));

  ResourceEntry src_entry, dest_entry;
  ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(src_path, &src_entry));
  ASSERT_EQ(FILE_ERROR_NOT_FOUND,
            GetLocalResourceEntry(dest_path, &dest_entry));

  FileError error = FILE_ERROR_FAILED;
  // Copy the src file into the same directory. This will make inconsistency
  // between title and path of the copied file.
  copy_operation_->Copy(
      src_path,
      src_path,
      false,
      google_apis::test_util::CreateCopyResultCallback(&error));
  test_util::RunBlockingPoolTask();
  EXPECT_EQ(FILE_ERROR_OK, error);
  base::FilePath copied_path(
      FILE_PATH_LITERAL("drive/root/Directory 1/SubDirectory File 1 (1).txt"));
  ResourceEntry copied_entry;
  ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(copied_path, &copied_entry));
  ASSERT_EQ("SubDirectory File 1.txt", copied_entry.title());

  // Move the copied file.
  operation_->Move(copied_path,
                   dest_path,
                   false,
                   google_apis::test_util::CreateCopyResultCallback(&error));
  test_util::RunBlockingPoolTask();
  EXPECT_EQ(FILE_ERROR_OK, error);

  EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(dest_path, &dest_entry));
  EXPECT_EQ("SubDirectory File 1 (1).txt", dest_entry.title());
  EXPECT_EQ(copied_entry.local_id(), dest_entry.local_id());
  EXPECT_EQ(ResourceEntry::DIRTY, dest_entry.metadata_edit_state());
  EXPECT_EQ(FILE_ERROR_NOT_FOUND,
            GetLocalResourceEntry(copied_path, &copied_entry));

  EXPECT_EQ(2U, observer()->get_changed_paths().size());
  EXPECT_TRUE(observer()->get_changed_paths().count(copied_path.DirName()));
  EXPECT_TRUE(observer()->get_changed_paths().count(dest_path.DirName()));

  EXPECT_EQ(1U, observer()->updated_local_ids().size());
  EXPECT_TRUE(observer()->updated_local_ids().count(copied_entry.local_id()));
}

TEST_F(MoveOperationTest, MoveNotExistingFile) {
  base::FilePath src_path(FILE_PATH_LITERAL("drive/root/Dummy file.txt"));
  base::FilePath dest_path(FILE_PATH_LITERAL("drive/root/Test.log"));

  FileError error = FILE_ERROR_OK;
  operation_->Move(src_path,
                   dest_path,
                   false,
                   google_apis::test_util::CreateCopyResultCallback(&error));
  test_util::RunBlockingPoolTask();
  EXPECT_EQ(FILE_ERROR_NOT_FOUND, error);

  ResourceEntry entry;
  EXPECT_EQ(FILE_ERROR_NOT_FOUND, GetLocalResourceEntry(src_path, &entry));
  EXPECT_EQ(FILE_ERROR_NOT_FOUND, GetLocalResourceEntry(dest_path, &entry));
}

TEST_F(MoveOperationTest, MoveFileToNonExistingDirectory) {
  base::FilePath src_path(FILE_PATH_LITERAL("drive/root/File 1.txt"));
  base::FilePath dest_path(FILE_PATH_LITERAL("drive/root/Dummy/Test.log"));

  FileError error = FILE_ERROR_OK;
  operation_->Move(src_path,
                   dest_path,
                   false,
                   google_apis::test_util::CreateCopyResultCallback(&error));
  test_util::RunBlockingPoolTask();
  EXPECT_EQ(FILE_ERROR_NOT_FOUND, error);

  ResourceEntry entry;
  EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(src_path, &entry));
  EXPECT_EQ(FILE_ERROR_NOT_FOUND, GetLocalResourceEntry(dest_path, &entry));
}

// Test the case where the parent of |dest_file_path| is a existing file,
// not a directory.
TEST_F(MoveOperationTest, MoveFileToInvalidPath) {
  base::FilePath src_path(FILE_PATH_LITERAL("drive/root/File 1.txt"));
  base::FilePath dest_path(
      FILE_PATH_LITERAL("drive/root/Duplicate Name.txt/Test.log"));

  FileError error = FILE_ERROR_OK;
  operation_->Move(src_path,
                   dest_path,
                   false,
                   google_apis::test_util::CreateCopyResultCallback(&error));
  test_util::RunBlockingPoolTask();
  EXPECT_EQ(FILE_ERROR_NOT_A_DIRECTORY, error);

  ResourceEntry entry;
  EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(src_path, &entry));
  EXPECT_EQ(FILE_ERROR_NOT_FOUND, GetLocalResourceEntry(dest_path, &entry));
}

TEST_F(MoveOperationTest, PreserveLastModified) {
  const base::FilePath src_path(
      FILE_PATH_LITERAL("drive/root/Directory 1/SubDirectory File 1.txt"));
  const base::FilePath dest_path(
      FILE_PATH_LITERAL("drive/root/Directory 1/Test.log"));

  ResourceEntry src_entry, dest_entry;
  ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(src_path, &src_entry));
  ASSERT_EQ(FILE_ERROR_NOT_FOUND,
            GetLocalResourceEntry(dest_path, &dest_entry));

  FileError error = FILE_ERROR_FAILED;
  operation_->Move(src_path,
                   dest_path,
                   true,  // Preserve last modified.
                   google_apis::test_util::CreateCopyResultCallback(&error));
  test_util::RunBlockingPoolTask();
  EXPECT_EQ(FILE_ERROR_OK, error);

  EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(dest_path, &dest_entry));
  EXPECT_EQ(src_entry.local_id(), dest_entry.local_id());
  EXPECT_EQ(src_entry.file_info().last_modified(),
            dest_entry.file_info().last_modified());
  EXPECT_EQ(ResourceEntry::DIRTY, dest_entry.metadata_edit_state());
  EXPECT_EQ(FILE_ERROR_NOT_FOUND,
            GetLocalResourceEntry(src_path, &src_entry));
}

}  // namespace file_system
}  // namespace drive
<|endoftext|>


<commit_before>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/component_updater/flash_component_installer.h"

#include <string.h>

#include "base/base_paths.h"
#include "base/bind.h"
#include "base/compiler_specific.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/logging.h"
#include "base/path_service.h"
#include "base/string_split.h"
#include "base/string_util.h"
#include "base/stringprintf.h"
#include "base/values.h"
#include "base/version.h"
#include "build/build_config.h"
#include "chrome/browser/component_updater/component_updater_service.h"
#include "chrome/browser/component_updater/pepper_flash_field_trial.h"
#include "chrome/browser/plugin_prefs.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/installer/util/browser_distribution.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/plugin_service.h"
#include "content/public/common/pepper_plugin_info.h"
#include "ppapi/c/private/ppb_pdf.h"
#include "webkit/plugins/plugin_constants.h"
#include "webkit/plugins/ppapi/plugin_module.h"

using content::BrowserThread;
using content::PluginService;

namespace {

// CRX hash. The extension id is: mimojjlkmoijpicakmndhoigimigcmbb.
const uint8 sha2_hash[] = {0xc8, 0xce, 0x99, 0xba, 0xce, 0x89, 0xf8, 0x20,
                           0xac, 0xd3, 0x7e, 0x86, 0x8c, 0x86, 0x2c, 0x11,
                           0xb9, 0x40, 0xc5, 0x55, 0xaf, 0x08, 0x63, 0x70,
                           0x54, 0xf9, 0x56, 0xd3, 0xe7, 0x88, 0xba, 0x8c};

// File name of the Pepper Flash component manifest on different platforms.
const char kPepperFlashManifestName[] = "Flapper";

// Name of the Pepper Flash OS in the component manifest.
const char kPepperFlashOperatingSystem[] =
#if defined(OS_MACOSX)
    "mac";
#elif defined(OS_WIN)
    "win";
#else  // OS_LINUX, etc. TODO(viettrungluu): Separate out Chrome OS and Android?
    "linux";
#endif

// Name of the Pepper Flash architecture in the component manifest.
const char kPepperFlashArch[] =
#if defined(ARCH_CPU_X86)
    "ia32";
#elif defined(ARCH_CPU_X86_64)
    "x64";
#else  // TODO(viettrungluu): Support an ARM check?
    "???";
#endif

// The Pepper Flash plugins are in a directory with this name.
const FilePath::CharType kPepperFlashBaseDirectory[] =
    FILE_PATH_LITERAL("PepperFlash");

// If we don't have a Pepper Flash component, this is the version we claim.
const char kNullVersion[] = "0.0.0.0";

// True if Pepper Flash should be enabled by default. Aura builds for any OS
// and part of Windows canary have it enabled by default.
bool IsPepperFlashEnabledByDefault() {
#if defined(USE_AURA)
  return true;
#elif !defined(OS_WIN)
  return false;
#else
  if (!PepperFlashFieldTrial::InEnableByDefaultGroup())
    return false;

  BrowserDistribution* dist = BrowserDistribution::GetDistribution();
  if (!dist)
    return false;
  string16 channel;
  if (!dist->GetChromeChannel(&channel))
    return false;
  return (channel == L"canary");
#endif
}

// The base directory on Windows looks like:
// <profile>\AppData\Local\Google\Chrome\User Data\PepperFlash\.
FilePath GetPepperFlashBaseDirectory() {
  FilePath result;
  PathService::Get(chrome::DIR_USER_DATA, &result);
  return result.Append(kPepperFlashBaseDirectory);
}

// Pepper Flash plugins have the version encoded in the path itself
// so we need to enumerate the directories to find the full path.
// On success it returns something like:
// <profile>\AppData\Local\Google\Chrome\User Data\PepperFlash\10.3.44.555\.
bool GetLatestPepperFlashDirectory(FilePath* result, Version* latest) {
  *result = GetPepperFlashBaseDirectory();
  bool found = false;
  file_util::FileEnumerator
      file_enumerator(*result, false, file_util::FileEnumerator::DIRECTORIES);
  for (FilePath path = file_enumerator.Next(); !path.value().empty();
       path = file_enumerator.Next()) {
    Version version(path.BaseName().MaybeAsASCII());
    if (!version.IsValid())
      continue;
    if (version.CompareTo(*latest) > 0) {
      *latest = version;
      *result = path;
      found = true;
    }
  }
  return found;
}

// Returns true if the Pepper |interface_name| is implemented  by this browser.
// It does not check if the interface is proxied.
bool SupportsPepperInterface(const char* interface_name) {
  static webkit::ppapi::PluginModule::GetInterfaceFunc get_itf =
      webkit::ppapi::PluginModule::GetLocalGetInterfaceFunc();
  if (get_itf(interface_name))
    return true;
  // It might be that flapper is using as a temporary hack the PDF interface
  // so we need to check for that as well. TODO(cpu): make this more sane.
  return (strcmp(interface_name, PPB_PDF_INTERFACE) == 0);
}

bool MakePepperFlashPluginInfo(const FilePath& flash_path,
                               const Version& flash_version,
                               bool out_of_process,
                               content::PepperPluginInfo* plugin_info) {
  if (!flash_version.IsValid())
    return false;
  const std::vector<uint16> ver_nums = flash_version.components();
  if (ver_nums.size() < 3)
    return false;

  plugin_info->is_internal = false;
  plugin_info->is_out_of_process = out_of_process;
  plugin_info->path = flash_path;
  plugin_info->name = kFlashPluginName;

  // The description is like "Shockwave Flash 10.2 r154".
  plugin_info->description = StringPrintf("%s %d.%d r%d",
      kFlashPluginName, ver_nums[0], ver_nums[1], ver_nums[2]);

  plugin_info->version = flash_version.GetString();

  webkit::WebPluginMimeType swf_mime_type(kFlashPluginSwfMimeType,
                                          kFlashPluginSwfExtension,
                                          kFlashPluginName);
  plugin_info->mime_types.push_back(swf_mime_type);
  webkit::WebPluginMimeType spl_mime_type(kFlashPluginSplMimeType,
                                          kFlashPluginSplExtension,
                                          kFlashPluginName);
  plugin_info->mime_types.push_back(spl_mime_type);
  return true;
}

// If it is a |fresh_install| we enable or disable it by default in some
// configurations. See IsPepperFlashEnabledByDefault() for more information.
void RegisterPepperFlashWithChrome(const FilePath& path,
                                   const Version& version,
                                   bool fresh_install) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  content::PepperPluginInfo plugin_info;
  if (!MakePepperFlashPluginInfo(path, version, true, &plugin_info))
    return;
  bool enable_by_default = IsPepperFlashEnabledByDefault();
  if (fresh_install)
    PluginPrefs::EnablePluginGlobally(enable_by_default, plugin_info.path);

  bool add_to_front = enable_by_default;
  PluginService::GetInstance()->RegisterInternalPlugin(
      plugin_info.ToWebPluginInfo(), add_to_front);
  PluginService::GetInstance()->RefreshPlugins();
}

// Returns true if this browser implements one of the interfaces given in
// |interface_string|, which is a '|'-separated string of interface names.
bool CheckPepperFlashInterfaceString(const std::string& interface_string) {
  std::vector<std::string> interface_names;
  base::SplitString(interface_string, '|', &interface_names);
  for (size_t i = 0; i < interface_names.size(); i++) {
    if (SupportsPepperInterface(interface_names[i].c_str()))
      return true;
  }
  return false;
}

// Returns true if this browser implements all the interfaces that Flash
// specifies in its component installer manifest.
bool CheckPepperFlashInterfaces(base::DictionaryValue* manifest) {
  base::ListValue* interface_list = NULL;

  // We don't *require* an interface list, apparently.
  if (!manifest->GetList("x-ppapi-required-interfaces", &interface_list))
    return true;

  for (size_t i = 0; i < interface_list->GetSize(); i++) {
    std::string interface_string;
    if (!interface_list->GetString(i, &interface_string))
      return false;
    if (!CheckPepperFlashInterfaceString(interface_string))
      return false;
  }

  return true;
}

}  // namespace

class PepperFlashComponentInstaller : public ComponentInstaller {
 public:
  explicit PepperFlashComponentInstaller(const Version& version);

  virtual ~PepperFlashComponentInstaller() {}

  virtual void OnUpdateError(int error) OVERRIDE;

  virtual bool Install(base::DictionaryValue* manifest,
                       const FilePath& unpack_path) OVERRIDE;

 private:
  Version current_version_;
};

PepperFlashComponentInstaller::PepperFlashComponentInstaller(
    const Version& version) : current_version_(version) {
  DCHECK(version.IsValid());
}

void PepperFlashComponentInstaller::OnUpdateError(int error) {
  NOTREACHED() << "Pepper Flash update error: " << error;
}

bool PepperFlashComponentInstaller::Install(base::DictionaryValue* manifest,
                                            const FilePath& unpack_path) {
  Version version;
  if (!CheckPepperFlashManifest(manifest, &version))
    return false;
  if (current_version_.CompareTo(version) > 0)
    return false;
  if (!file_util::PathExists(unpack_path.Append(
          chrome::kPepperFlashPluginFilename)))
    return false;
  // Passed the basic tests. Time to install it.
  FilePath path =
      GetPepperFlashBaseDirectory().AppendASCII(version.GetString());
  if (file_util::PathExists(path))
    return false;
  if (!file_util::Move(unpack_path, path))
    return false;
  // Installation is done. Now tell the rest of chrome. Both the path service
  // and to the plugin service.
  current_version_ = version;
  PathService::Override(chrome::DIR_PEPPER_FLASH_PLUGIN, path);
  path = path.Append(chrome::kPepperFlashPluginFilename);
  BrowserThread::PostTask(
      BrowserThread::UI, FROM_HERE,
      base::Bind(&RegisterPepperFlashWithChrome, path, version, true));
  return true;
}

bool CheckPepperFlashManifest(base::DictionaryValue* manifest,
                              Version* version_out) {
  std::string name;
  manifest->GetStringASCII("name", &name);
  // TODO(viettrungluu): Support WinFlapper for now, while we change the format
  // of the manifest. (Should be safe to remove checks for "WinFlapper" in, say,
  // Nov. 2011.)  crbug.com/98458
  if (name != kPepperFlashManifestName && name != "WinFlapper")
    return false;

  std::string proposed_version;
  manifest->GetStringASCII("version", &proposed_version);
  Version version(proposed_version.c_str());
  if (!version.IsValid())
    return false;

  if (!CheckPepperFlashInterfaces(manifest))
    return false;

  // TODO(viettrungluu): See above TODO.
  if (name == "WinFlapper") {
    *version_out = version;
    return true;
  }

  std::string os;
  manifest->GetStringASCII("x-ppapi-os", &os);
  if (os != kPepperFlashOperatingSystem)
    return false;

  std::string arch;
  manifest->GetStringASCII("x-ppapi-arch", &arch);
  if (arch != kPepperFlashArch)
    return false;

  *version_out = version;
  return true;
}

namespace {

void FinishPepperFlashUpdateRegistration(ComponentUpdateService* cus,
                                         const Version& version) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  CrxComponent pepflash;
  pepflash.name = "pepper_flash";
  pepflash.installer = new PepperFlashComponentInstaller(version);
  pepflash.version = version;
  pepflash.pk_hash.assign(sha2_hash, &sha2_hash[sizeof(sha2_hash)]);
  if (cus->RegisterComponent(pepflash) != ComponentUpdateService::kOk) {
    NOTREACHED() << "Pepper Flash component registration failed.";
  }
}

void StartPepperFlashUpdateRegistration(ComponentUpdateService* cus) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
  FilePath path = GetPepperFlashBaseDirectory();
  if (!file_util::PathExists(path)) {
    if (!file_util::CreateDirectory(path)) {
      NOTREACHED() << "Could not create Pepper Flash directory.";
      return;
    }
  }

  Version version(kNullVersion);
  if (GetLatestPepperFlashDirectory(&path, &version)) {
    path = path.Append(chrome::kPepperFlashPluginFilename);
    if (file_util::PathExists(path)) {
      BrowserThread::PostTask(
          BrowserThread::UI, FROM_HERE,
          base::Bind(&RegisterPepperFlashWithChrome, path, version, false));
    } else {
      version = Version(kNullVersion);
    }
  }

  BrowserThread::PostTask(
      BrowserThread::UI, FROM_HERE,
      base::Bind(&FinishPepperFlashUpdateRegistration, cus, version));
}

}  // namespace

void RegisterPepperFlashComponent(ComponentUpdateService* cus) {
#if defined(GOOGLE_CHROME_BUILD)
  BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
                          base::Bind(&StartPepperFlashUpdateRegistration, cus));
#endif
}
<commit_msg>Remove old versions of Pepper Flash on users' machines. Everytime a new WinFlapper is downloaded, the older ones will be removed the next time Chrome is launched.<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/component_updater/flash_component_installer.h"

#include <string.h>

#include <vector>

#include "base/base_paths.h"
#include "base/bind.h"
#include "base/compiler_specific.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/logging.h"
#include "base/path_service.h"
#include "base/string_split.h"
#include "base/string_util.h"
#include "base/stringprintf.h"
#include "base/values.h"
#include "base/version.h"
#include "build/build_config.h"
#include "chrome/browser/component_updater/component_updater_service.h"
#include "chrome/browser/component_updater/pepper_flash_field_trial.h"
#include "chrome/browser/plugin_prefs.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/installer/util/browser_distribution.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/plugin_service.h"
#include "content/public/common/pepper_plugin_info.h"
#include "ppapi/c/private/ppb_pdf.h"
#include "webkit/plugins/plugin_constants.h"
#include "webkit/plugins/ppapi/plugin_module.h"

using content::BrowserThread;
using content::PluginService;

namespace {

// CRX hash. The extension id is: mimojjlkmoijpicakmndhoigimigcmbb.
const uint8 sha2_hash[] = {0xc8, 0xce, 0x99, 0xba, 0xce, 0x89, 0xf8, 0x20,
                           0xac, 0xd3, 0x7e, 0x86, 0x8c, 0x86, 0x2c, 0x11,
                           0xb9, 0x40, 0xc5, 0x55, 0xaf, 0x08, 0x63, 0x70,
                           0x54, 0xf9, 0x56, 0xd3, 0xe7, 0x88, 0xba, 0x8c};

// File name of the Pepper Flash component manifest on different platforms.
const char kPepperFlashManifestName[] = "Flapper";

// Name of the Pepper Flash OS in the component manifest.
const char kPepperFlashOperatingSystem[] =
#if defined(OS_MACOSX)
    "mac";
#elif defined(OS_WIN)
    "win";
#else  // OS_LINUX, etc. TODO(viettrungluu): Separate out Chrome OS and Android?
    "linux";
#endif

// Name of the Pepper Flash architecture in the component manifest.
const char kPepperFlashArch[] =
#if defined(ARCH_CPU_X86)
    "ia32";
#elif defined(ARCH_CPU_X86_64)
    "x64";
#else  // TODO(viettrungluu): Support an ARM check?
    "???";
#endif

// The Pepper Flash plugins are in a directory with this name.
const FilePath::CharType kPepperFlashBaseDirectory[] =
    FILE_PATH_LITERAL("PepperFlash");

// If we don't have a Pepper Flash component, this is the version we claim.
const char kNullVersion[] = "0.0.0.0";

// True if Pepper Flash should be enabled by default. Aura builds for any OS
// and part of Windows canary have it enabled by default.
bool IsPepperFlashEnabledByDefault() {
#if defined(USE_AURA)
  return true;
#elif !defined(OS_WIN)
  return false;
#else
  if (!PepperFlashFieldTrial::InEnableByDefaultGroup())
    return false;

  BrowserDistribution* dist = BrowserDistribution::GetDistribution();
  if (!dist)
    return false;
  string16 channel;
  if (!dist->GetChromeChannel(&channel))
    return false;
  return (channel == L"canary");
#endif
}

// The base directory on Windows looks like:
// <profile>\AppData\Local\Google\Chrome\User Data\PepperFlash\.
FilePath GetPepperFlashBaseDirectory() {
  FilePath result;
  PathService::Get(chrome::DIR_USER_DATA, &result);
  return result.Append(kPepperFlashBaseDirectory);
}

// Pepper Flash plugins have the version encoded in the path itself
// so we need to enumerate the directories to find the full path.
// On success, |latest_dir| returns something like:
// <profile>\AppData\Local\Google\Chrome\User Data\PepperFlash\10.3.44.555\.
// |latest_version| returns the corresponding version number. |older_dirs|
// returns directories of all older versions.
bool GetPepperFlashDirectory(FilePath* latest_dir,
                             Version* latest_version,
                             std::vector<FilePath>* older_dirs) {
  FilePath base_dir = GetPepperFlashBaseDirectory();
  bool found = false;
  file_util::FileEnumerator
      file_enumerator(base_dir, false, file_util::FileEnumerator::DIRECTORIES);
  for (FilePath path = file_enumerator.Next(); !path.value().empty();
       path = file_enumerator.Next()) {
    Version version(path.BaseName().MaybeAsASCII());
    if (!version.IsValid())
      continue;
    if (found) {
      if (version.CompareTo(*latest_version) > 0) {
        older_dirs->push_back(*latest_dir);
        *latest_dir = path;
        *latest_version = version;
      } else {
        older_dirs->push_back(path);
      }
    } else {
      *latest_dir = path;
      *latest_version = version;
      found = true;
    }
  }
  return found;
}

// Returns true if the Pepper |interface_name| is implemented  by this browser.
// It does not check if the interface is proxied.
bool SupportsPepperInterface(const char* interface_name) {
  static webkit::ppapi::PluginModule::GetInterfaceFunc get_itf =
      webkit::ppapi::PluginModule::GetLocalGetInterfaceFunc();
  if (get_itf(interface_name))
    return true;
  // It might be that flapper is using as a temporary hack the PDF interface
  // so we need to check for that as well. TODO(cpu): make this more sane.
  return (strcmp(interface_name, PPB_PDF_INTERFACE) == 0);
}

bool MakePepperFlashPluginInfo(const FilePath& flash_path,
                               const Version& flash_version,
                               bool out_of_process,
                               content::PepperPluginInfo* plugin_info) {
  if (!flash_version.IsValid())
    return false;
  const std::vector<uint16> ver_nums = flash_version.components();
  if (ver_nums.size() < 3)
    return false;

  plugin_info->is_internal = false;
  plugin_info->is_out_of_process = out_of_process;
  plugin_info->path = flash_path;
  plugin_info->name = kFlashPluginName;

  // The description is like "Shockwave Flash 10.2 r154".
  plugin_info->description = StringPrintf("%s %d.%d r%d",
      kFlashPluginName, ver_nums[0], ver_nums[1], ver_nums[2]);

  plugin_info->version = flash_version.GetString();

  webkit::WebPluginMimeType swf_mime_type(kFlashPluginSwfMimeType,
                                          kFlashPluginSwfExtension,
                                          kFlashPluginName);
  plugin_info->mime_types.push_back(swf_mime_type);
  webkit::WebPluginMimeType spl_mime_type(kFlashPluginSplMimeType,
                                          kFlashPluginSplExtension,
                                          kFlashPluginName);
  plugin_info->mime_types.push_back(spl_mime_type);
  return true;
}

// If it is a |fresh_install| we enable or disable it by default in some
// configurations. See IsPepperFlashEnabledByDefault() for more information.
void RegisterPepperFlashWithChrome(const FilePath& path,
                                   const Version& version,
                                   bool fresh_install) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  content::PepperPluginInfo plugin_info;
  if (!MakePepperFlashPluginInfo(path, version, true, &plugin_info))
    return;
  bool enable_by_default = IsPepperFlashEnabledByDefault();
  if (fresh_install)
    PluginPrefs::EnablePluginGlobally(enable_by_default, plugin_info.path);

  bool add_to_front = enable_by_default;
  PluginService::GetInstance()->RegisterInternalPlugin(
      plugin_info.ToWebPluginInfo(), add_to_front);
  PluginService::GetInstance()->RefreshPlugins();
}

// Returns true if this browser implements one of the interfaces given in
// |interface_string|, which is a '|'-separated string of interface names.
bool CheckPepperFlashInterfaceString(const std::string& interface_string) {
  std::vector<std::string> interface_names;
  base::SplitString(interface_string, '|', &interface_names);
  for (size_t i = 0; i < interface_names.size(); i++) {
    if (SupportsPepperInterface(interface_names[i].c_str()))
      return true;
  }
  return false;
}

// Returns true if this browser implements all the interfaces that Flash
// specifies in its component installer manifest.
bool CheckPepperFlashInterfaces(base::DictionaryValue* manifest) {
  base::ListValue* interface_list = NULL;

  // We don't *require* an interface list, apparently.
  if (!manifest->GetList("x-ppapi-required-interfaces", &interface_list))
    return true;

  for (size_t i = 0; i < interface_list->GetSize(); i++) {
    std::string interface_string;
    if (!interface_list->GetString(i, &interface_string))
      return false;
    if (!CheckPepperFlashInterfaceString(interface_string))
      return false;
  }

  return true;
}

}  // namespace

class PepperFlashComponentInstaller : public ComponentInstaller {
 public:
  explicit PepperFlashComponentInstaller(const Version& version);

  virtual ~PepperFlashComponentInstaller() {}

  virtual void OnUpdateError(int error) OVERRIDE;

  virtual bool Install(base::DictionaryValue* manifest,
                       const FilePath& unpack_path) OVERRIDE;

 private:
  Version current_version_;
};

PepperFlashComponentInstaller::PepperFlashComponentInstaller(
    const Version& version) : current_version_(version) {
  DCHECK(version.IsValid());
}

void PepperFlashComponentInstaller::OnUpdateError(int error) {
  NOTREACHED() << "Pepper Flash update error: " << error;
}

bool PepperFlashComponentInstaller::Install(base::DictionaryValue* manifest,
                                            const FilePath& unpack_path) {
  Version version;
  if (!CheckPepperFlashManifest(manifest, &version))
    return false;
  if (current_version_.CompareTo(version) > 0)
    return false;
  if (!file_util::PathExists(unpack_path.Append(
          chrome::kPepperFlashPluginFilename)))
    return false;
  // Passed the basic tests. Time to install it.
  FilePath path =
      GetPepperFlashBaseDirectory().AppendASCII(version.GetString());
  if (file_util::PathExists(path))
    return false;
  if (!file_util::Move(unpack_path, path))
    return false;
  // Installation is done. Now tell the rest of chrome. Both the path service
  // and to the plugin service.
  current_version_ = version;
  PathService::Override(chrome::DIR_PEPPER_FLASH_PLUGIN, path);
  path = path.Append(chrome::kPepperFlashPluginFilename);
  BrowserThread::PostTask(
      BrowserThread::UI, FROM_HERE,
      base::Bind(&RegisterPepperFlashWithChrome, path, version, true));
  return true;
}

bool CheckPepperFlashManifest(base::DictionaryValue* manifest,
                              Version* version_out) {
  std::string name;
  manifest->GetStringASCII("name", &name);
  // TODO(viettrungluu): Support WinFlapper for now, while we change the format
  // of the manifest. (Should be safe to remove checks for "WinFlapper" in, say,
  // Nov. 2011.)  crbug.com/98458
  if (name != kPepperFlashManifestName && name != "WinFlapper")
    return false;

  std::string proposed_version;
  manifest->GetStringASCII("version", &proposed_version);
  Version version(proposed_version.c_str());
  if (!version.IsValid())
    return false;

  if (!CheckPepperFlashInterfaces(manifest))
    return false;

  // TODO(viettrungluu): See above TODO.
  if (name == "WinFlapper") {
    *version_out = version;
    return true;
  }

  std::string os;
  manifest->GetStringASCII("x-ppapi-os", &os);
  if (os != kPepperFlashOperatingSystem)
    return false;

  std::string arch;
  manifest->GetStringASCII("x-ppapi-arch", &arch);
  if (arch != kPepperFlashArch)
    return false;

  *version_out = version;
  return true;
}

namespace {

void FinishPepperFlashUpdateRegistration(ComponentUpdateService* cus,
                                         const Version& version) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  CrxComponent pepflash;
  pepflash.name = "pepper_flash";
  pepflash.installer = new PepperFlashComponentInstaller(version);
  pepflash.version = version;
  pepflash.pk_hash.assign(sha2_hash, &sha2_hash[sizeof(sha2_hash)]);
  if (cus->RegisterComponent(pepflash) != ComponentUpdateService::kOk) {
    NOTREACHED() << "Pepper Flash component registration failed.";
  }
}

void StartPepperFlashUpdateRegistration(ComponentUpdateService* cus) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
  FilePath path = GetPepperFlashBaseDirectory();
  if (!file_util::PathExists(path)) {
    if (!file_util::CreateDirectory(path)) {
      NOTREACHED() << "Could not create Pepper Flash directory.";
      return;
    }
  }

  Version version(kNullVersion);
  std::vector<FilePath> older_dirs;
  if (GetPepperFlashDirectory(&path, &version, &older_dirs)) {
    path = path.Append(chrome::kPepperFlashPluginFilename);
    if (file_util::PathExists(path)) {
      BrowserThread::PostTask(
          BrowserThread::UI, FROM_HERE,
          base::Bind(&RegisterPepperFlashWithChrome, path, version, false));
    } else {
      version = Version(kNullVersion);
    }
  }

  BrowserThread::PostTask(
      BrowserThread::UI, FROM_HERE,
      base::Bind(&FinishPepperFlashUpdateRegistration, cus, version));

  // Remove older versions of Pepper Flash.
  for (std::vector<FilePath>::iterator iter = older_dirs.begin();
       iter != older_dirs.end(); ++iter) {
    file_util::Delete(*iter, true);
  }
}

}  // namespace

void RegisterPepperFlashComponent(ComponentUpdateService* cus) {
#if defined(GOOGLE_CHROME_BUILD)
  BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
                          base::Bind(&StartPepperFlashUpdateRegistration, cus));
#endif
}
<|endoftext|>


<commit_before>/*
 * PassConfig.cpp
 *
 *  Created on: Dec 4, 2009
 *      Author: Philip Rogers
 */

#include <boost/foreach.hpp>
#include "PassConfig.hpp"

using namespace std;
using namespace Packet;

PassConfig::PassConfig() : weight(0.0) { }

PassConfig::PassConfig(const PassConfig& c)
: weight(c.weight){
	// copy over the states
	for (int i=0; i<c.length(); ++i)
		passStateVector.push_back(c.getPassState(i));
}

PassConfig::~PassConfig() {
	passStateVector.clear();
}

void PassConfig::addPassState(const PassState& passState){
	passStateVector.push_back(passState);
}

PassState PassConfig::getPassState(int idx) const {
	assert(idx < (int)passStateVector.size()); // pass state index must exist
	return passStateVector.at(idx);
}

int PassConfig::length() const{
	return passStateVector.size();
}

void PassConfig::setWeight(double w){
	weight = w;
}

ostream& operator<<(ostream& out, const PassConfig &config){
	out << "config weight(" << config.weight << "):" << endl;
	for(int i=0; i<(int)config.passStateVector.size(); i++){
		out << "\t state(" << i << "):" << config.passStateVector.at(i) << endl;
	}
	return out;
}

bool operator<(const PassConfig& lhs, const PassConfig& rhs){
	return (lhs.weight < rhs.weight);
}

Packet::LogFrame::DebugCircle drawCircle(const Geometry2d::Point& center, float radius, int r, int g, int b) {
	Packet::LogFrame::DebugCircle circle;
	circle.center = center;
	circle.radius(radius);
	circle.color[0] = r;
	circle.color[1] = g;
	circle.color[2] = b;
	return circle;
}

Packet::LogFrame::DebugLine drawLine(const Geometry2d::Point& pt1, const Geometry2d::Point& pt2, int r, int g, int b) {
	Packet::LogFrame::DebugLine line;
	line.pt[0] = pt1;
	line.pt[1] = pt2;
	line.color[0] = r;
	line.color[1] = g;
	line.color[2] = b;
	return line;
}

void PassConfig::drawConfig(SystemState* sysState, int r, int g, int b) const {
	// parameters for drawing
	float ball_radius = 0.05;
	float pos_radius = 0.1;

	// draw the path of the ball and the robot trajectories
	int stateNum = 0;
	PassState prevState;
	BOOST_FOREACH(PassState state, passStateVector) {
//		switch (state.stateType) {
//		case PassState::INTERMEDIATE:
//			// if in first state, draw the robot and ball positions
//			// if in the last state, draw the ball
//			break;
//		case PassState::KICKPASS:
//			break;
//		case PassState::RECEIVEPASS:
//			break;
//		case PassState::KICKGOAL:
//			break;
//		}

		// draw the ball
		sysState->debugCircles.push_back(drawCircle(state.ballPos, ball_radius, r,g,b));

		// draw robots
		sysState->debugCircles.push_back(drawCircle(state.robot1Pos, pos_radius, r,g,b));
		sysState->debugCircles.push_back(drawCircle(state.robot2Pos, pos_radius, r,g,b));

		if(stateNum > 0){
			sysState->debugLines.push_back(drawLine(prevState.ballPos, state.ballPos, r,g,b));
			sysState->debugLines.push_back(drawLine(prevState.robot1Pos, state.robot1Pos, r,g,b));
			sysState->debugLines.push_back(drawLine(prevState.robot2Pos, state.robot2Pos, r,g,b));
		}
		prevState = state;
		stateNum++;
	}
}
<commit_msg>New render code for PassConfigs<commit_after>/*
 * PassConfig.cpp
 *
 *  Created on: Dec 4, 2009
 *      Author: Philip Rogers
 */

#include <boost/foreach.hpp>
#include "PassConfig.hpp"

using namespace std;
using namespace Packet;

PassConfig::PassConfig() : weight(0.0) { }

PassConfig::PassConfig(const PassConfig& c)
: weight(c.weight){
	// copy over the states
	for (int i=0; i<c.length(); ++i)
		passStateVector.push_back(c.getPassState(i));
}

PassConfig::~PassConfig() {
	passStateVector.clear();
}

void PassConfig::addPassState(const PassState& passState){
	passStateVector.push_back(passState);
}

PassState PassConfig::getPassState(int idx) const {
	assert(idx < (int)passStateVector.size()); // pass state index must exist
	return passStateVector.at(idx);
}

int PassConfig::length() const{
	return passStateVector.size();
}

void PassConfig::setWeight(double w){
	weight = w;
}

ostream& operator<<(ostream& out, const PassConfig &config){
	out << "config weight(" << config.weight << "):" << endl;
	for(int i=0; i<(int)config.passStateVector.size(); i++){
		out << "\t state(" << i << "):" << config.passStateVector.at(i) << endl;
	}
	return out;
}

bool operator<(const PassConfig& lhs, const PassConfig& rhs){
	return (lhs.weight < rhs.weight);
}

Packet::LogFrame::DebugCircle drawCircle(const Geometry2d::Point& center, float radius, int r, int g, int b) {
	Packet::LogFrame::DebugCircle circle;
	circle.center = center;
	circle.radius(radius);
	circle.color[0] = r;
	circle.color[1] = g;
	circle.color[2] = b;
	return circle;
}

Packet::LogFrame::DebugLine drawLine(const Geometry2d::Point& pt1, const Geometry2d::Point& pt2, int r, int g, int b) {
	Packet::LogFrame::DebugLine line;
	line.pt[0] = pt1;
	line.pt[1] = pt2;
	line.color[0] = r;
	line.color[1] = g;
	line.color[2] = b;
	return line;
}

void PassConfig::drawConfig(SystemState* sysState, int r, int g, int b) const {
	// parameters for drawing
	float ball_radius = 0.05;
	float pos_radius = 0.1;

	// Hardcoded printing, assuming
	// Intermediate (init), KickPass, ReceivePass, KickGoal, Intermediate (ball in goal)
	if (passStateVector.size() != 5)
		throw invalid_argument("Incorrect size of passConfig - hardcoded for 5");

	// pull out the states
	const PassState start    = passStateVector[0],
					kickPass = passStateVector[1],
					recPass  = passStateVector[2],
					kickGoal = passStateVector[3],
					end      = passStateVector[4];

	// render initial positions
	sysState->debugCircles.push_back(drawCircle(start.robot1Pos, pos_radius, r,g,b));
	sysState->debugCircles.push_back(drawCircle(start.robot2Pos, pos_radius, r,g,b));

	// render kickPass states
	sysState->debugCircles.push_back(drawCircle(kickPass.robot1Pos, pos_radius, r,g,b));
	sysState->debugLines.push_back(drawLine(start.robot1Pos, kickPass.robot1Pos, r,g,b));
	sysState->debugCircles.push_back(drawCircle(kickPass.ballPos, ball_radius, r,g,b));

	// render recPass state
	sysState->debugCircles.push_back(drawCircle(recPass.robot2Pos, pos_radius, r,g,b));
	sysState->debugLines.push_back(drawLine(kickPass.ballPos, recPass.ballPos, r,g,b));
	sysState->debugLines.push_back(drawLine(kickPass.robot2Pos, recPass.robot2Pos, r,g,b));
	sysState->debugCircles.push_back(drawCircle(recPass.ballPos, ball_radius, r,g,b));

	// render kickGoal state
	sysState->debugCircles.push_back(drawCircle(kickGoal.robot2Pos, pos_radius, r,g,b));
	sysState->debugCircles.push_back(drawCircle(kickGoal.ballPos, ball_radius, r,g,b));
	sysState->debugLines.push_back(drawLine(kickGoal.ballPos, end.ballPos, r,g,b));
	sysState->debugLines.push_back(drawLine(recPass.robot2Pos, kickGoal.robot2Pos, r,g,b));

	// render final ball position
	sysState->debugCircles.push_back(drawCircle(end.ballPos, ball_radius, r,g,b));

	// Code to do arbitrary paths while printing excess information
//	// draw the path of the ball and the robot trajectories
//	int stateNum = 0;
//	PassState prevState;
//	BOOST_FOREACH(PassState state, passStateVector) {
//
//		// draw the ball
//		sysState->debugCircles.push_back(drawCircle(state.ballPos, ball_radius, r,g,b));
//
//		// draw robots
//		sysState->debugCircles.push_back(drawCircle(state.robot1Pos, pos_radius, r,g,b));
//		sysState->debugCircles.push_back(drawCircle(state.robot2Pos, pos_radius, r,g,b));
//
//		if(stateNum > 0){
//			sysState->debugLines.push_back(drawLine(prevState.ballPos, state.ballPos, r,g,b));
//			sysState->debugLines.push_back(drawLine(prevState.robot1Pos, state.robot1Pos, r,g,b));
//			sysState->debugLines.push_back(drawLine(prevState.robot2Pos, state.robot2Pos, r,g,b));
//		}
//		prevState = state;
//		stateNum++;
//	}
}
<|endoftext|>


<commit_before>// main.cpp - Copyright 2013-2015 Will Cassella, All Rights Reserved

#include <GLFW/glfw3.h>
#include <Core/Console.h>
#include <Core/Math/Vec2.h>
#include <GLRender/GLRender.h>
#include <ExampleGame/FPSCamera.h>
#include <ExampleGame/Ghost.h>

//Define context parameters
int32 window_width = 1280;
int32 window_height = 720;

//Function Prototypes
GLFWwindow* InitGLFW();
void eventLoop(GLFWwindow* window, Scene& scene);
void cleanUp(GLFWwindow* window);

struct
{
	//////////////////
	///   Fields   ///
public:

	Vec2 Position;

	///////////////////
	///   Methods   ///
public:

	void UpdatePosition(GLFWwindow* window)
	{
		double x;
		double y;

		glfwGetCursorPos(window, &x, &y);

		Position.X = (float)x - window_width / 2;
		Position.Y = (float)y - window_height / 2;
	}
	void SetPosition(GLFWwindow* window, float x, float y)
	{
		glfwSetCursorPos(window, x + window_width / 2, y + window_height / 2);
		Position.X = x;
		Position.X = y;
	}

} Cursor;

int main(int32 /*argc*/, char** /*argv*/)
{
	Console::WriteLine("Initializing subsystems...");

	// Initialize GLFW and get a window
	GLFWwindow* window = InitGLFW();

	// Make an openGL context in window
	glfwMakeContextCurrent(window);
	InitRenderer(window_width, window_height);

	///////////////////////////////
	///   Setting up a simple   ///
	///          scene          ///

	auto scene = New<Scene>();

	//auto& sponza = test.Spawn<Prop>();
	//sponza.MeshComponent.Mesh = "data/sponza.dat";
	//sponza.MeshComponent.Mesh->SetMaterial(String("data/Sponza.mat"));

	scene->Spawn<Ghost>();
	//gun.MeshComponent.Mesh = "data/battle_rifle.dat";
	//gun.MeshComponent.Mesh->SetMaterial(String("data/Gun.mat"));

	scene->Spawn<FPSCamera>();
	//test.Cameras.Add(&cam);

	//Execute the main event loop
	eventLoop(window, *scene);

	//Cleanup the engine
	cleanUp(window);

	// Shut down the application
	Application::BeginShutdown();
}

GLFWwindow* InitGLFW()
{
	//Initialize GLFW
	if (!glfwInit())
	{
		Console::WriteLine("GLFW Initialization failure");
		exit(EXIT_FAILURE);
	}

	// Make the window invisible
	glfwWindowHint(GLFW_VISIBLE, false);

	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 1);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);

	GLFWwindow* window = glfwCreateWindow(window_width, window_height, "Willow Engine", NULL, NULL);

	//make sure the window was initialized properly
	if (!window)
	{
		Console::WriteLine("Window failed to initialize properly");
		glfwTerminate();
		exit(EXIT_FAILURE);
	}

	// figure out the center of the screen
	int screen_height = 1080;
	int screen_width = 1920;

	int posx = (screen_width - window_width)/2;
	int posy = (screen_height - window_height)/2;

	//move the window to the center of the screen
	glfwSetWindowPos(window, posx, posy);

	//Make the window visible
	glfwShowWindow(window);

	// Make the cursor invisible
	glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
	// Move the cursor to the center of the screen
	glfwSetCursorPos(window, window_width/2, window_height/2);

	return window;
}

void eventLoop(GLFWwindow* window, Scene& scene)
{
	Console::WriteLine("Entering event loop...");

	double previous = glfwGetTime();
	double lastTime = previous;
	double lag = 0.0;
	uint32 numFrames = 0;
	uint32 numUpdates = 0;
	bool exit = false;

	// Begin the event loop
	while (!glfwWindowShouldClose(window) && !exit)
	{
		double currentTime = glfwGetTime();
		lag += currentTime - previous;
		previous = currentTime;
		numFrames++;

		if (currentTime - lastTime >= 1.0)
		{
			Console::WriteLine("@ ms/frame = @ fps", 1000.0 / numFrames, numFrames);
			Console::WriteLine("@ updates/second", numUpdates);
			numFrames = 0;
			numUpdates = 0;
			lastTime = currentTime;
		}

		// Poll input events
		glfwPollEvents();

		Cursor.UpdatePosition(window);

		while (lag >= scene.TimeStep)
		{
			Vec2 moveAccum;

			// Dispatch events
			if (glfwGetKey(window, GLFW_KEY_W))
			{
				moveAccum.Y += 1;
			}
			if (glfwGetKey(window, GLFW_KEY_S))
			{
				moveAccum.Y -= 1;
			}
			if (glfwGetKey(window, GLFW_KEY_D))
			{
				moveAccum.X += 1;
			}
			if (glfwGetKey(window, GLFW_KEY_A))
			{
				moveAccum.X -= 1;
			}
			if (glfwGetKey(window, GLFW_KEY_SPACE))
			{
				scene.Events.DispatchEvent("Poof");
			}
			if (glfwGetKey(window, GLFW_KEY_ESCAPE))
			{
				exit = true;
			}
			if (glfwGetKey(window, GLFW_KEY_Q))
			{
				scene.Events.DispatchEvent("Spin", 0.5f);
			}

			if (moveAccum != Vec2(0, 0))
			{
				scene.Events.DispatchEvent("Move", moveAccum.Normalize());
			}

			scene.Events.DispatchEvent("Look", Vec2(Cursor.Position.X / 100, Cursor.Position.Y / 100));
			Cursor.SetPosition(window, 0, 0);

			// Update the scene
			scene.Update();

			lag -= scene.TimeStep;
			numUpdates++;
		}

		//render the frame
		RenderScene(scene);
		glfwSwapBuffers(window);

		// Free memory
		Application::GetMemoryManager().Sweep();
	}

	Console::WriteLine("Leaving event loop...");
}

void cleanUp(GLFWwindow* window)
{
	Console::WriteLine("Shutting down...");

	//Delete the window (along with the context)
	glfwDestroyWindow(window);

	//Quit GLFW
	glfwTerminate();
}
<commit_msg>- Fixed memory leak. But actually this time.<commit_after>// main.cpp - Copyright 2013-2015 Will Cassella, All Rights Reserved

#include <GLFW/glfw3.h>
#include <Core/Console.h>
#include <Core/Math/Vec2.h>
#include <GLRender/GLRender.h>
#include <ExampleGame/FPSCamera.h>
#include <ExampleGame/Ghost.h>

//Define context parameters
int32 window_width = 1280;
int32 window_height = 720;

//Function Prototypes
GLFWwindow* InitGLFW();
void eventLoop(GLFWwindow* window, Scene& scene);
void cleanUp(GLFWwindow* window);

struct
{
	//////////////////
	///   Fields   ///
public:

	Vec2 Position;

	///////////////////
	///   Methods   ///
public:

	void UpdatePosition(GLFWwindow* window)
	{
		double x;
		double y;

		glfwGetCursorPos(window, &x, &y);

		Position.X = (float)x - window_width / 2;
		Position.Y = (float)y - window_height / 2;
	}
	void SetPosition(GLFWwindow* window, float x, float y)
	{
		glfwSetCursorPos(window, x + window_width / 2, y + window_height / 2);
		Position.X = x;
		Position.X = y;
	}

} Cursor;

int main(int32 /*argc*/, char** /*argv*/)
{
	Console::WriteLine("Initializing subsystems...");

	// Initialize GLFW and get a window
	GLFWwindow* window = InitGLFW();

	// Make an openGL context in window
	glfwMakeContextCurrent(window);
	InitRenderer(window_width, window_height);

	///////////////////////////////
	///   Setting up a simple   ///
	///          scene          ///

	auto scene = New<Scene>();

	//auto& sponza = test.Spawn<Prop>();
	//sponza.MeshComponent.Mesh = "data/sponza.dat";
	//sponza.MeshComponent.Mesh->SetMaterial(String("data/Sponza.mat"));

	scene->Spawn<Ghost>();
	//gun.MeshComponent.Mesh = "data/battle_rifle.dat";
	//gun.MeshComponent.Mesh->SetMaterial(String("data/Gun.mat"));

	scene->Spawn<FPSCamera>();
	//test.Cameras.Add(&cam);

	//Execute the main event loop
	eventLoop(window, *scene);

	// Destroy the scene
	scene = nullptr;

	//Cleanup the engine
	cleanUp(window);

	// Shut down the application
	Application::BeginShutdown();
}

GLFWwindow* InitGLFW()
{
	//Initialize GLFW
	if (!glfwInit())
	{
		Console::WriteLine("GLFW Initialization failure");
		exit(EXIT_FAILURE);
	}

	// Make the window invisible
	glfwWindowHint(GLFW_VISIBLE, false);

	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 1);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);

	GLFWwindow* window = glfwCreateWindow(window_width, window_height, "Willow Engine", NULL, NULL);

	//make sure the window was initialized properly
	if (!window)
	{
		Console::WriteLine("Window failed to initialize properly");
		glfwTerminate();
		exit(EXIT_FAILURE);
	}

	// figure out the center of the screen
	int screen_height = 1080;
	int screen_width = 1920;

	int posx = (screen_width - window_width)/2;
	int posy = (screen_height - window_height)/2;

	//move the window to the center of the screen
	glfwSetWindowPos(window, posx, posy);

	//Make the window visible
	glfwShowWindow(window);

	// Make the cursor invisible
	glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
	// Move the cursor to the center of the screen
	glfwSetCursorPos(window, window_width/2, window_height/2);

	return window;
}

void eventLoop(GLFWwindow* window, Scene& scene)
{
	Console::WriteLine("Entering event loop...");

	double previous = glfwGetTime();
	double lastTime = previous;
	double lag = 0.0;
	uint32 numFrames = 0;
	uint32 numUpdates = 0;
	bool exit = false;

	// Begin the event loop
	while (!glfwWindowShouldClose(window) && !exit)
	{
		double currentTime = glfwGetTime();
		lag += currentTime - previous;
		previous = currentTime;
		numFrames++;

		if (currentTime - lastTime >= 1.0)
		{
			Console::WriteLine("@ ms/frame = @ fps", 1000.0 / numFrames, numFrames);
			Console::WriteLine("@ updates/second", numUpdates);
			numFrames = 0;
			numUpdates = 0;
			lastTime = currentTime;
		}

		// Poll input events
		glfwPollEvents();

		Cursor.UpdatePosition(window);

		while (lag >= scene.TimeStep)
		{
			Vec2 moveAccum;

			// Dispatch events
			if (glfwGetKey(window, GLFW_KEY_W))
			{
				moveAccum.Y += 1;
			}
			if (glfwGetKey(window, GLFW_KEY_S))
			{
				moveAccum.Y -= 1;
			}
			if (glfwGetKey(window, GLFW_KEY_D))
			{
				moveAccum.X += 1;
			}
			if (glfwGetKey(window, GLFW_KEY_A))
			{
				moveAccum.X -= 1;
			}
			if (glfwGetKey(window, GLFW_KEY_SPACE))
			{
				scene.Events.DispatchEvent("Poof");
			}
			if (glfwGetKey(window, GLFW_KEY_ESCAPE))
			{
				exit = true;
			}
			if (glfwGetKey(window, GLFW_KEY_Q))
			{
				scene.Events.DispatchEvent("Spin", 0.5f);
			}

			if (moveAccum != Vec2(0, 0))
			{
				scene.Events.DispatchEvent("Move", moveAccum.Normalize());
			}

			scene.Events.DispatchEvent("Look", Vec2(Cursor.Position.X / 100, Cursor.Position.Y / 100));
			Cursor.SetPosition(window, 0, 0);

			// Update the scene
			scene.Update();

			lag -= scene.TimeStep;
			numUpdates++;
		}

		//render the frame
		RenderScene(scene);
		glfwSwapBuffers(window);

		// Free memory
		Application::GetMemoryManager().Sweep();
	}

	Console::WriteLine("Leaving event loop...");
}

void cleanUp(GLFWwindow* window)
{
	Console::WriteLine("Shutting down...");

	//Delete the window (along with the context)
	glfwDestroyWindow(window);

	//Quit GLFW
	glfwTerminate();
}
<|endoftext|>


<commit_before>/*
    Copyright (c) 2010 Bertjan Broeksema <broeksema@kde.org>

    This library is free software; you can redistribute it and/or modify it
    under the terms of the GNU Library General Public License as published by
    the Free Software Foundation; either version 2 of the License, or (at your
    option) any later version.

    This library 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 Library General Public
    License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to the
    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
*/
#include "agentpluginloader.h"

#include "libs/xdgbasedirs_p.h"
#include "shared/akdebug.h"

using namespace Akonadi;

AgentPluginLoader::~AgentPluginLoader()
{
  QHash<QString, QPluginLoader*>::iterator it = m_pluginLoaders.begin();
  while ( it != m_pluginLoaders.end() ) {
    it.value()->unload();
    ++it;
  }

  qDeleteAll( m_pluginLoaders );
}

QPluginLoader *AgentPluginLoader::load( const QString &pluginName )
{
  const QString pluginFile = XdgBaseDirs::findPluginFile( pluginName );
  if ( pluginFile.isEmpty() ) {
    akError() << Q_FUNC_INFO << "plugin file not found!";
    return 0;
  }

  if ( m_pluginLoaders.contains( pluginFile ) ) {
    return m_pluginLoaders.value( pluginFile );
  } else {
    QPluginLoader *loader = new QPluginLoader( pluginFile );
    if ( !loader->load() ) {
      akError() << Q_FUNC_INFO << "Failed to load agent: " << loader->errorString();
      return 0;
    }
    m_pluginLoaders.insert( pluginFile, loader );
    return loader;
  }
}
<commit_msg>Slightly more helpfull debug output<commit_after>/*
    Copyright (c) 2010 Bertjan Broeksema <broeksema@kde.org>

    This library is free software; you can redistribute it and/or modify it
    under the terms of the GNU Library General Public License as published by
    the Free Software Foundation; either version 2 of the License, or (at your
    option) any later version.

    This library 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 Library General Public
    License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to the
    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
*/
#include "agentpluginloader.h"

#include "libs/xdgbasedirs_p.h"
#include "shared/akdebug.h"

using namespace Akonadi;

AgentPluginLoader::~AgentPluginLoader()
{
  QHash<QString, QPluginLoader*>::iterator it = m_pluginLoaders.begin();
  while ( it != m_pluginLoaders.end() ) {
    it.value()->unload();
    ++it;
  }

  qDeleteAll( m_pluginLoaders );
}

QPluginLoader *AgentPluginLoader::load( const QString &pluginName )
{
  const QString pluginFile = XdgBaseDirs::findPluginFile( pluginName );
  if ( pluginFile.isEmpty() ) {
    akError() << Q_FUNC_INFO << "plugin file:" << pluginName << "not found!";
    return 0;
  }

  if ( m_pluginLoaders.contains( pluginFile ) ) {
    return m_pluginLoaders.value( pluginFile );
  } else {
    QPluginLoader *loader = new QPluginLoader( pluginFile );
    if ( !loader->load() ) {
      akError() << Q_FUNC_INFO << "Failed to load agent: " << loader->errorString();
      return 0;
    }
    m_pluginLoaders.insert( pluginFile, loader );
    return loader;
  }
}
<|endoftext|>