<commit_before>/**
 * @file DartLoader.cpp
 */

#include "DartLoader.h"
#include <map>

#include <urdf_parser/urdf_parser.h>
#include <urdf_world/world.h>
#include "urdf_world_parser.h"

#include <iostream>
#include <fstream>
#include "dart/dynamics/Skeleton.h"
#include "dart/dynamics/BodyNode.h"
#include "dart/dynamics/Joint.h"
#include "dart/dynamics/RevoluteJoint.h"
#include "dart/dynamics/PrismaticJoint.h"
#include "dart/dynamics/WeldJoint.h"
#include "dart/dynamics/FreeJoint.h"
#include "dart/dynamics/GenCoord.h"
#include "dart/dynamics/Shape.h"
#include "dart/dynamics/BoxShape.h"
#include "dart/dynamics/EllipsoidShape.h"
#include "dart/dynamics/CylinderShape.h"
#include "dart/dynamics/MeshShape.h"
#include "dart/simulation/World.h"

namespace dart {
namespace utils {

/**
 * @function parseSkeleton
 */
dynamics::Skeleton* DartLoader::parseSkeleton(std::string _urdfFileName) {

    boost::shared_ptr<urdf::ModelInterface> skeletonModelPtr = urdf::parseURDF(readFileToString(_urdfFileName));
    if(!skeletonModelPtr)
        return NULL;

    // Change path to a Unix-style path if given a Windows one
    // Windows can handle Unix-style paths (apparently)
    std::replace(_urdfFileName.begin(), _urdfFileName.end(), '\\' , '/' );
    std::string skelDirectory = _urdfFileName.substr(0, _urdfFileName.rfind("/") + 1);

    return modelInterfaceToSkeleton(skeletonModelPtr.get(), skelDirectory);
}

/**
 * @function parseWorld
 */
simulation::World* DartLoader::parseWorld(std::string _urdfFileName) {

    std::string xmlString = readFileToString(_urdfFileName);

    // Change path to a Unix-style path if given a Windows one
    // Windows can handle Unix-style paths (apparently)
    std::replace(_urdfFileName.begin(), _urdfFileName.end(), '\\' , '/');
    std::string worldDirectory = _urdfFileName.substr(0, _urdfFileName.rfind("/") + 1);

    urdf::World* worldInterface = urdf::parseWorldURDF(xmlString, worldDirectory);
    if(!worldInterface)
        return NULL;

    // Store paths from world to entities
    parseWorldToEntityPaths(xmlString);

    simulation::World* world = new simulation::World();

    for(unsigned int i = 0; i < worldInterface->models.size(); ++i) {
      std::string skeletonDirectory = worldDirectory + mWorld_To_Entity_Paths.find(worldInterface->models[i].model->getName())->second;
      dynamics::Skeleton* skeleton = modelInterfaceToSkeleton(worldInterface->models[i].model.get(), skeletonDirectory);

      if(!skeleton) {
        std::cout << "[ERROR] Robot " << worldInterface->models[i].model->getName() << " was not correctly parsed. World is not loaded. Exiting!" << std::endl;
        return NULL;
      }

      // Initialize position and RPY
      dynamics::Joint* rootJoint = skeleton->getRootBodyNode()->getParentJoint();
      Eigen::Isometry3d transform = toEigen(worldInterface->models[i].origin);

      if(dynamic_cast<dynamics::FreeJoint*>(rootJoint)) {
          Eigen::Vector6d coordinates;
          coordinates << math::logMap(transform.linear()), transform.translation();
          rootJoint->set_q(coordinates);
      }
      else {
          rootJoint->setTransformFromParentBodyNode(transform);
      }

      world->addSkeleton(skeleton);
    }
    return world;
}

/**
 * @function parseWorldToEntityPaths
 */
void DartLoader::parseWorldToEntityPaths(const std::string &_xml_string) {

    TiXmlDocument xml_doc;
    xml_doc.Parse(_xml_string.c_str());

    TiXmlElement *world_xml = xml_doc.FirstChildElement("world");

    if( !world_xml ) {
      return;
    }

    // Get all include filenames
    std::map<std::string, std::string> includedFiles;

    for( TiXmlElement* include_xml = world_xml->FirstChildElement("include");
      include_xml; include_xml = include_xml->NextSiblingElement("include") ) {

      const char *filename = include_xml->Attribute("filename");
      const char *model_name = include_xml->Attribute("model_name");
      std::string string_filename( filename );
      std::string string_filepath = string_filename.substr( 0, string_filename.rfind("/") + 1 );
      std::string string_model_name( model_name );

      includedFiles[string_model_name] = string_filepath;
    }

    // Get all entities
    for( TiXmlElement* entity_xml = world_xml->FirstChildElement("entity");
      entity_xml; entity_xml = entity_xml->NextSiblingElement("entity") ) {

      // Find model and name for entity, if not, error
      const char* entity_model = entity_xml->Attribute("model");
      const char* entity_name = entity_xml->Attribute("name");

      if( entity_name && entity_model ) {
        std::string string_entity_model( entity_model );
        std::string string_entity_name( entity_name );
        // Find the model
        if( includedFiles.find( string_entity_model ) == includedFiles.end() ) {
          std::cout<<"[!] Did not find entity model included. Weird things may happen"<<std::endl;
          return;
        }
        // Add it
        else {
          std::string string_entity_filepath = includedFiles.find( string_entity_model )->second;
          mWorld_To_Entity_Paths[string_entity_name] = string_entity_filepath;
        }
      }
      // If no name or model is defined
      else {
        std::cout<< "[!] Entity was not defined. Weird things will happen" <<std::endl;
      }

    } // for all entities

}

/**
 * @function modelInterfaceToSkeleton
 * @brief Read the ModelInterface and spits out a Skeleton object
 */
dynamics::Skeleton* DartLoader::modelInterfaceToSkeleton(const urdf::ModelInterface* _model, std::string _rootToSkelPath) {

    if( _rootToSkelPath.empty() ) {
        std::cout<< "[DartLoader] Absolute path to skeleton "<<_model->getName()<<" is not set. Probably I will crash!"<<std::endl;
    }

    dynamics::Skeleton* skeleton = new dynamics::Skeleton(_model->getName());
    dynamics::BodyNode* rootNode;
    dynamics::Joint* rootJoint;

    const urdf::Link* root = _model->getRoot().get();
    if(root->name == "world") {
        if(_model->getRoot()->child_links.size() != 1) {
            std::cout<< "[ERROR] Not unique link attached to world." << std::endl;
        }
        else {
            root = root->child_links[0].get();
            rootNode = createDartNode(root, _rootToSkelPath);
            rootJoint = createDartJoint(root->parent_joint.get());
            if(!rootJoint)
                return NULL;
        }
    }
    else {
        rootNode = createDartNode(root, _rootToSkelPath);
        rootJoint = new dynamics::FreeJoint();
        rootJoint->setName("rootJoint");
        rootJoint->setTransformFromParentBodyNode(Eigen::Isometry3d::Identity());
        rootJoint->setTransformFromChildBodyNode(Eigen::Isometry3d::Identity());
    }

    rootNode->setParentJoint(rootJoint);
    skeleton->addBodyNode(rootNode);

    for(unsigned int i = 0; i < root->child_links.size(); i++) {
        createSkeletonRecursive(skeleton, root->child_links[i].get(), rootNode, _rootToSkelPath);
    }

    return skeleton;
}

void DartLoader::createSkeletonRecursive(dynamics::Skeleton* _skel, const urdf::Link* _lk, dynamics::BodyNode* _parentNode, std::string _rootToSkelPath) {
  dynamics::BodyNode* node = createDartNode(_lk, _rootToSkelPath);
  dynamics::Joint* joint = createDartJoint(_lk->parent_joint.get());
  node->setParentJoint(joint);
  _parentNode->addChildBodyNode(node);
  _skel->addBodyNode(node);

  for(unsigned int i = 0; i < _lk->child_links.size(); i++) {
      createSkeletonRecursive(_skel, _lk->child_links[i].get(), node, _rootToSkelPath);
  }
}

/**
 * @function readXml
 */
std::string  DartLoader::readFileToString(std::string _xmlFile) {

  std::string xml_string;
  std::ifstream xml_file(_xmlFile.c_str());

  // Read xml
  while(xml_file.good()) {
    std::string line;
    std::getline(xml_file, line);
    xml_string += (line + "\n");
  }
  xml_file.close();

  return xml_string;
}

/**
 * @function createDartJoint
 */
dynamics::Joint* DartLoader::createDartJoint(const urdf::Joint* _jt)
{
  dynamics::Joint* joint;
  switch(_jt->type) {
  case urdf::Joint::REVOLUTE:
      joint = new dynamics::RevoluteJoint(toEigen(_jt->axis));
      joint->getGenCoord(0)->set_qMin(_jt->limits->lower);
      joint->getGenCoord(0)->set_qMax(_jt->limits->upper);
      break;
  case urdf::Joint::CONTINUOUS:
      joint = new dynamics::RevoluteJoint(toEigen(_jt->axis));
      break;
  case urdf::Joint::PRISMATIC:
      joint = new dynamics::PrismaticJoint(toEigen(_jt->axis));
      joint->getGenCoord(0)->set_qMin(_jt->limits->lower);
      joint->getGenCoord(0)->set_qMax(_jt->limits->upper);
      break;
  case urdf::Joint::FIXED:
      joint = new dynamics::WeldJoint();
      break;
  case urdf::Joint::FLOATING:
      joint = new dynamics::FreeJoint();
      break;
  case urdf::Joint::PLANAR:
      std::cout << "Planar joint not supported." << std::endl;
      assert(false);
      return NULL;
  default:
      std::cout << "Unsupported joint type." << std::endl;
      assert(false);
      return NULL;
  }
  joint->setName(_jt->name);
  joint->setTransformFromParentBodyNode(toEigen(_jt->parent_to_joint_origin_transform));
  joint->setTransformFromChildBodyNode(Eigen::Isometry3d::Identity());
  if(joint->getNumGenCoords() == 1 && _jt->limits) {
    joint->getGenCoord(0)->set_dqMin(-_jt->limits->velocity);
    joint->getGenCoord(0)->set_dqMax(_jt->limits->velocity);
    joint->getGenCoord(0)->set_tauMin(-_jt->limits->effort);
    joint->getGenCoord(0)->set_tauMax(_jt->limits->effort);
  }
  return joint;
}

/**
 * @function createDartNode
 */
dynamics::BodyNode* DartLoader::createDartNode(const urdf::Link* _lk, std::string _rootToSkelPath) {

  dynamics::BodyNode* node = new dynamics::BodyNode(_lk->name);

  // Mesh Loading
  //FIXME: Shouldn't mass and inertia default to 0?
  double mass = 0.1;
  Eigen::Matrix3d inertia = Eigen::MatrixXd::Identity(3,3);
  inertia *= 0.1;

  // Load Inertial information
  if(_lk->inertial) {
      node->setLocalCOM(toEigen(_lk->inertial->origin.position));
      node->setMass(_lk->inertial->mass);
      node->setInertia(_lk->inertial->ixx, _lk->inertial->iyy, _lk->inertial->izz,
                               _lk->inertial->ixy, _lk->inertial->ixz, _lk->inertial->iyz);
  }

  // Set visual information
  for(unsigned int i = 0; i < _lk->visual_array.size(); i++) {
    if(dynamics::Shape* shape = createShape(_lk->visual_array[i].get(), _rootToSkelPath)) {
      node->addVisualizationShape(shape);
    }
  }

  // Set collision information
  for(unsigned int i = 0; i < _lk->collision_array.size(); i++) {
    if(dynamics::Shape* shape = createShape(_lk->collision_array[i].get(), _rootToSkelPath)) {
      node->addCollisionShape(shape);
    }
  }

  return node;
}

void setMaterial(dynamics::Shape* _shape, const urdf::Visual* _viz) {
  if(_viz->material) {
    _shape->setColor(Eigen::Vector3d(_viz->material->color.r, _viz->material->color.g, _viz->material->color.b));
  }
}

void setMaterial(dynamics::Shape* _shape, const urdf::Collision* _col) {
}

/**
 * @function createShape
 */
template <class VisualOrCollision>
dynamics::Shape* DartLoader::createShape(const VisualOrCollision* _vizOrCol, std::string _rootToSkelPath) {
  dynamics::Shape* shape;

  // Sphere
  if(urdf::Sphere* sphere = dynamic_cast<urdf::Sphere*>(_vizOrCol->geometry.get())) {
    shape = new dynamics::EllipsoidShape(2.0 * sphere->radius * Eigen::Vector3d::Ones());
  }

  // Box
  else if(urdf::Box* box = dynamic_cast<urdf::Box*>(_vizOrCol->geometry.get())) {
    shape = new dynamics::BoxShape(Eigen::Vector3d(box->dim.x, box->dim.y, box->dim.z));
  }

  // Cylinder
  else if(urdf::Cylinder* cylinder = dynamic_cast<urdf::Cylinder*>(_vizOrCol->geometry.get())) {
    shape = new dynamics::CylinderShape(cylinder->radius, cylinder->length);
  }

  // Mesh
  else if(urdf::Mesh* mesh = dynamic_cast<urdf::Mesh*>(_vizOrCol->geometry.get())) {
    std::string fullPath = _rootToSkelPath + mesh->filename;
    const aiScene* model = dynamics::MeshShape::loadMesh( fullPath );

    if(!model) {
      std::cout<< "[add_Shape] [ERROR] Not loading model " << fullPath << " (NULL) \n";
      shape = NULL;
    }
    else {
      shape = new dynamics::MeshShape(Eigen::Vector3d(mesh->scale.x, mesh->scale.y, mesh->scale.z), model);
    }
  }

  // Unknown geometry type
  else {
    std::cout << "[add_Shape] No MESH, BOX, CYLINDER OR SPHERE! Not loading this shape." << std::endl;
    return NULL;
  }

  shape->setLocalTransform(toEigen(_vizOrCol->origin));
  setMaterial(shape, _vizOrCol);
  return shape;
}

template dynamics::Shape* DartLoader::createShape<urdf::Visual>(const urdf::Visual* _vizOrCol, std::string _rootToSkelPath);
template dynamics::Shape* DartLoader::createShape<urdf::Collision>(const urdf::Collision* _vizOrCol, std::string _rootToSkelPath);

/**
 * @function pose2Affine3d
 */
Eigen::Isometry3d DartLoader::toEigen(const urdf::Pose& _pose) {
    Eigen::Quaterniond quat;
    _pose.rotation.getQuaternion(quat.x(), quat.y(), quat.z(), quat.w());
    Eigen::Isometry3d transform(quat);
    transform.translation() = Eigen::Vector3d(_pose.position.x, _pose.position.y, _pose.position.z);
    return transform;
}

Eigen::Vector3d DartLoader::toEigen(const urdf::Vector3& _vector) {
    return Eigen::Vector3d(_vector.x, _vector.y, _vector.z);
}

} // namespace utils
} // namespace dart
<commit_msg>Parse joint damping from urdf files<commit_after>/**
 * @file DartLoader.cpp
 */

#include "DartLoader.h"
#include <map>

#include <urdf_parser/urdf_parser.h>
#include <urdf_world/world.h>
#include "urdf_world_parser.h"

#include <iostream>
#include <fstream>
#include "dart/dynamics/Skeleton.h"
#include "dart/dynamics/BodyNode.h"
#include "dart/dynamics/Joint.h"
#include "dart/dynamics/RevoluteJoint.h"
#include "dart/dynamics/PrismaticJoint.h"
#include "dart/dynamics/WeldJoint.h"
#include "dart/dynamics/FreeJoint.h"
#include "dart/dynamics/GenCoord.h"
#include "dart/dynamics/Shape.h"
#include "dart/dynamics/BoxShape.h"
#include "dart/dynamics/EllipsoidShape.h"
#include "dart/dynamics/CylinderShape.h"
#include "dart/dynamics/MeshShape.h"
#include "dart/simulation/World.h"

namespace dart {
namespace utils {

/**
 * @function parseSkeleton
 */
dynamics::Skeleton* DartLoader::parseSkeleton(std::string _urdfFileName) {

    boost::shared_ptr<urdf::ModelInterface> skeletonModelPtr = urdf::parseURDF(readFileToString(_urdfFileName));
    if(!skeletonModelPtr)
        return NULL;

    // Change path to a Unix-style path if given a Windows one
    // Windows can handle Unix-style paths (apparently)
    std::replace(_urdfFileName.begin(), _urdfFileName.end(), '\\' , '/' );
    std::string skelDirectory = _urdfFileName.substr(0, _urdfFileName.rfind("/") + 1);

    return modelInterfaceToSkeleton(skeletonModelPtr.get(), skelDirectory);
}

/**
 * @function parseWorld
 */
simulation::World* DartLoader::parseWorld(std::string _urdfFileName) {

    std::string xmlString = readFileToString(_urdfFileName);

    // Change path to a Unix-style path if given a Windows one
    // Windows can handle Unix-style paths (apparently)
    std::replace(_urdfFileName.begin(), _urdfFileName.end(), '\\' , '/');
    std::string worldDirectory = _urdfFileName.substr(0, _urdfFileName.rfind("/") + 1);

    urdf::World* worldInterface = urdf::parseWorldURDF(xmlString, worldDirectory);
    if(!worldInterface)
        return NULL;

    // Store paths from world to entities
    parseWorldToEntityPaths(xmlString);

    simulation::World* world = new simulation::World();

    for(unsigned int i = 0; i < worldInterface->models.size(); ++i) {
      std::string skeletonDirectory = worldDirectory + mWorld_To_Entity_Paths.find(worldInterface->models[i].model->getName())->second;
      dynamics::Skeleton* skeleton = modelInterfaceToSkeleton(worldInterface->models[i].model.get(), skeletonDirectory);

      if(!skeleton) {
        std::cout << "[ERROR] Robot " << worldInterface->models[i].model->getName() << " was not correctly parsed. World is not loaded. Exiting!" << std::endl;
        return NULL;
      }

      // Initialize position and RPY
      dynamics::Joint* rootJoint = skeleton->getRootBodyNode()->getParentJoint();
      Eigen::Isometry3d transform = toEigen(worldInterface->models[i].origin);

      if(dynamic_cast<dynamics::FreeJoint*>(rootJoint)) {
          Eigen::Vector6d coordinates;
          coordinates << math::logMap(transform.linear()), transform.translation();
          rootJoint->set_q(coordinates);
      }
      else {
          rootJoint->setTransformFromParentBodyNode(transform);
      }

      world->addSkeleton(skeleton);
    }
    return world;
}

/**
 * @function parseWorldToEntityPaths
 */
void DartLoader::parseWorldToEntityPaths(const std::string &_xml_string) {

    TiXmlDocument xml_doc;
    xml_doc.Parse(_xml_string.c_str());

    TiXmlElement *world_xml = xml_doc.FirstChildElement("world");

    if( !world_xml ) {
      return;
    }

    // Get all include filenames
    std::map<std::string, std::string> includedFiles;

    for( TiXmlElement* include_xml = world_xml->FirstChildElement("include");
      include_xml; include_xml = include_xml->NextSiblingElement("include") ) {

      const char *filename = include_xml->Attribute("filename");
      const char *model_name = include_xml->Attribute("model_name");
      std::string string_filename( filename );
      std::string string_filepath = string_filename.substr( 0, string_filename.rfind("/") + 1 );
      std::string string_model_name( model_name );

      includedFiles[string_model_name] = string_filepath;
    }

    // Get all entities
    for( TiXmlElement* entity_xml = world_xml->FirstChildElement("entity");
      entity_xml; entity_xml = entity_xml->NextSiblingElement("entity") ) {

      // Find model and name for entity, if not, error
      const char* entity_model = entity_xml->Attribute("model");
      const char* entity_name = entity_xml->Attribute("name");

      if( entity_name && entity_model ) {
        std::string string_entity_model( entity_model );
        std::string string_entity_name( entity_name );
        // Find the model
        if( includedFiles.find( string_entity_model ) == includedFiles.end() ) {
          std::cout<<"[!] Did not find entity model included. Weird things may happen"<<std::endl;
          return;
        }
        // Add it
        else {
          std::string string_entity_filepath = includedFiles.find( string_entity_model )->second;
          mWorld_To_Entity_Paths[string_entity_name] = string_entity_filepath;
        }
      }
      // If no name or model is defined
      else {
        std::cout<< "[!] Entity was not defined. Weird things will happen" <<std::endl;
      }

    } // for all entities

}

/**
 * @function modelInterfaceToSkeleton
 * @brief Read the ModelInterface and spits out a Skeleton object
 */
dynamics::Skeleton* DartLoader::modelInterfaceToSkeleton(const urdf::ModelInterface* _model, std::string _rootToSkelPath) {

    if( _rootToSkelPath.empty() ) {
        std::cout<< "[DartLoader] Absolute path to skeleton "<<_model->getName()<<" is not set. Probably I will crash!"<<std::endl;
    }

    dynamics::Skeleton* skeleton = new dynamics::Skeleton(_model->getName());
    dynamics::BodyNode* rootNode;
    dynamics::Joint* rootJoint;

    const urdf::Link* root = _model->getRoot().get();
    if(root->name == "world") {
        if(_model->getRoot()->child_links.size() != 1) {
            std::cout<< "[ERROR] Not unique link attached to world." << std::endl;
        }
        else {
            root = root->child_links[0].get();
            rootNode = createDartNode(root, _rootToSkelPath);
            rootJoint = createDartJoint(root->parent_joint.get());
            if(!rootJoint)
                return NULL;
        }
    }
    else {
        rootNode = createDartNode(root, _rootToSkelPath);
        rootJoint = new dynamics::FreeJoint();
        rootJoint->setName("rootJoint");
        rootJoint->setTransformFromParentBodyNode(Eigen::Isometry3d::Identity());
        rootJoint->setTransformFromChildBodyNode(Eigen::Isometry3d::Identity());
    }

    rootNode->setParentJoint(rootJoint);
    skeleton->addBodyNode(rootNode);

    for(unsigned int i = 0; i < root->child_links.size(); i++) {
        createSkeletonRecursive(skeleton, root->child_links[i].get(), rootNode, _rootToSkelPath);
    }

    return skeleton;
}

void DartLoader::createSkeletonRecursive(dynamics::Skeleton* _skel, const urdf::Link* _lk, dynamics::BodyNode* _parentNode, std::string _rootToSkelPath) {
  dynamics::BodyNode* node = createDartNode(_lk, _rootToSkelPath);
  dynamics::Joint* joint = createDartJoint(_lk->parent_joint.get());
  node->setParentJoint(joint);
  _parentNode->addChildBodyNode(node);
  _skel->addBodyNode(node);

  for(unsigned int i = 0; i < _lk->child_links.size(); i++) {
      createSkeletonRecursive(_skel, _lk->child_links[i].get(), node, _rootToSkelPath);
  }
}

/**
 * @function readXml
 */
std::string  DartLoader::readFileToString(std::string _xmlFile) {

  std::string xml_string;
  std::ifstream xml_file(_xmlFile.c_str());

  // Read xml
  while(xml_file.good()) {
    std::string line;
    std::getline(xml_file, line);
    xml_string += (line + "\n");
  }
  xml_file.close();

  return xml_string;
}

/**
 * @function createDartJoint
 */
dynamics::Joint* DartLoader::createDartJoint(const urdf::Joint* _jt)
{
  dynamics::Joint* joint;
  switch(_jt->type) {
  case urdf::Joint::REVOLUTE:
      joint = new dynamics::RevoluteJoint(toEigen(_jt->axis));
      joint->getGenCoord(0)->set_qMin(_jt->limits->lower);
      joint->getGenCoord(0)->set_qMax(_jt->limits->upper);
      joint->setDampingCoefficient(0, _jt->dynamics->damping);
      break;
  case urdf::Joint::CONTINUOUS:
      joint = new dynamics::RevoluteJoint(toEigen(_jt->axis));
      joint->setDampingCoefficient(0, _jt->dynamics->damping);
      break;
  case urdf::Joint::PRISMATIC:
      joint = new dynamics::PrismaticJoint(toEigen(_jt->axis));
      joint->getGenCoord(0)->set_qMin(_jt->limits->lower);
      joint->getGenCoord(0)->set_qMax(_jt->limits->upper);
      joint->setDampingCoefficient(0, _jt->dynamics->damping);
      break;
  case urdf::Joint::FIXED:
      joint = new dynamics::WeldJoint();
      break;
  case urdf::Joint::FLOATING:
      joint = new dynamics::FreeJoint();
      break;
  case urdf::Joint::PLANAR:
      std::cout << "Planar joint not supported." << std::endl;
      assert(false);
      return NULL;
  default:
      std::cout << "Unsupported joint type." << std::endl;
      assert(false);
      return NULL;
  }
  joint->setName(_jt->name);
  joint->setTransformFromParentBodyNode(toEigen(_jt->parent_to_joint_origin_transform));
  joint->setTransformFromChildBodyNode(Eigen::Isometry3d::Identity());
  if(joint->getNumGenCoords() == 1 && _jt->limits) {
    joint->getGenCoord(0)->set_dqMin(-_jt->limits->velocity);
    joint->getGenCoord(0)->set_dqMax(_jt->limits->velocity);
    joint->getGenCoord(0)->set_tauMin(-_jt->limits->effort);
    joint->getGenCoord(0)->set_tauMax(_jt->limits->effort);
  }
  return joint;
}

/**
 * @function createDartNode
 */
dynamics::BodyNode* DartLoader::createDartNode(const urdf::Link* _lk, std::string _rootToSkelPath) {

  dynamics::BodyNode* node = new dynamics::BodyNode(_lk->name);

  // Mesh Loading
  //FIXME: Shouldn't mass and inertia default to 0?
  double mass = 0.1;
  Eigen::Matrix3d inertia = Eigen::MatrixXd::Identity(3,3);
  inertia *= 0.1;

  // Load Inertial information
  if(_lk->inertial) {
      node->setLocalCOM(toEigen(_lk->inertial->origin.position));
      node->setMass(_lk->inertial->mass);
      node->setInertia(_lk->inertial->ixx, _lk->inertial->iyy, _lk->inertial->izz,
                               _lk->inertial->ixy, _lk->inertial->ixz, _lk->inertial->iyz);
  }

  // Set visual information
  for(unsigned int i = 0; i < _lk->visual_array.size(); i++) {
    if(dynamics::Shape* shape = createShape(_lk->visual_array[i].get(), _rootToSkelPath)) {
      node->addVisualizationShape(shape);
    }
  }

  // Set collision information
  for(unsigned int i = 0; i < _lk->collision_array.size(); i++) {
    if(dynamics::Shape* shape = createShape(_lk->collision_array[i].get(), _rootToSkelPath)) {
      node->addCollisionShape(shape);
    }
  }

  return node;
}

void setMaterial(dynamics::Shape* _shape, const urdf::Visual* _viz) {
  if(_viz->material) {
    _shape->setColor(Eigen::Vector3d(_viz->material->color.r, _viz->material->color.g, _viz->material->color.b));
  }
}

void setMaterial(dynamics::Shape* _shape, const urdf::Collision* _col) {
}

/**
 * @function createShape
 */
template <class VisualOrCollision>
dynamics::Shape* DartLoader::createShape(const VisualOrCollision* _vizOrCol, std::string _rootToSkelPath) {
  dynamics::Shape* shape;

  // Sphere
  if(urdf::Sphere* sphere = dynamic_cast<urdf::Sphere*>(_vizOrCol->geometry.get())) {
    shape = new dynamics::EllipsoidShape(2.0 * sphere->radius * Eigen::Vector3d::Ones());
  }

  // Box
  else if(urdf::Box* box = dynamic_cast<urdf::Box*>(_vizOrCol->geometry.get())) {
    shape = new dynamics::BoxShape(Eigen::Vector3d(box->dim.x, box->dim.y, box->dim.z));
  }

  // Cylinder
  else if(urdf::Cylinder* cylinder = dynamic_cast<urdf::Cylinder*>(_vizOrCol->geometry.get())) {
    shape = new dynamics::CylinderShape(cylinder->radius, cylinder->length);
  }

  // Mesh
  else if(urdf::Mesh* mesh = dynamic_cast<urdf::Mesh*>(_vizOrCol->geometry.get())) {
    std::string fullPath = _rootToSkelPath + mesh->filename;
    const aiScene* model = dynamics::MeshShape::loadMesh( fullPath );

    if(!model) {
      std::cout<< "[add_Shape] [ERROR] Not loading model " << fullPath << " (NULL) \n";
      shape = NULL;
    }
    else {
      shape = new dynamics::MeshShape(Eigen::Vector3d(mesh->scale.x, mesh->scale.y, mesh->scale.z), model);
    }
  }

  // Unknown geometry type
  else {
    std::cout << "[add_Shape] No MESH, BOX, CYLINDER OR SPHERE! Not loading this shape." << std::endl;
    return NULL;
  }

  shape->setLocalTransform(toEigen(_vizOrCol->origin));
  setMaterial(shape, _vizOrCol);
  return shape;
}

template dynamics::Shape* DartLoader::createShape<urdf::Visual>(const urdf::Visual* _vizOrCol, std::string _rootToSkelPath);
template dynamics::Shape* DartLoader::createShape<urdf::Collision>(const urdf::Collision* _vizOrCol, std::string _rootToSkelPath);

/**
 * @function pose2Affine3d
 */
Eigen::Isometry3d DartLoader::toEigen(const urdf::Pose& _pose) {
    Eigen::Quaterniond quat;
    _pose.rotation.getQuaternion(quat.x(), quat.y(), quat.z(), quat.w());
    Eigen::Isometry3d transform(quat);
    transform.translation() = Eigen::Vector3d(_pose.position.x, _pose.position.y, _pose.position.z);
    return transform;
}

Eigen::Vector3d DartLoader::toEigen(const urdf::Vector3& _vector) {
    return Eigen::Vector3d(_vector.x, _vector.y, _vector.z);
}

} // namespace utils
} // namespace dart
<|endoftext|>


<commit_before>/*
* Hex Encoder/Decoder
* (C) 1999-2007 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/

#include <botan/hex.h>
#include <botan/parsing.h>
#include <botan/charset.h>
#include <botan/exceptn.h>
#include <algorithm>

namespace Botan {

/*
* Hex_Encoder Constructor
*/
Hex_Encoder::Hex_Encoder(bool breaks, u32bit length, Case c) :
   casing(c), line_length(breaks ? length : 0)
   {
   in.create(64);
   out.create(2*in.size());
   counter = position = 0;
   }

/*
* Hex_Encoder Constructor
*/
Hex_Encoder::Hex_Encoder(Case c) : casing(c), line_length(0)
   {
   in.create(64);
   out.create(2*in.size());
   counter = position = 0;
   }

/*
* Hex Encoding Operation
*/
void Hex_Encoder::encode(byte in, byte out[2], Hex_Encoder::Case casing)
   {
   const byte* BIN_TO_HEX = ((casing == Uppercase) ? BIN_TO_HEX_UPPER :
                                                     BIN_TO_HEX_LOWER);

   out[0] = BIN_TO_HEX[((in >> 4) & 0x0F)];
   out[1] = BIN_TO_HEX[((in     ) & 0x0F)];
   }

/*
* Encode and send a block
*/
void Hex_Encoder::encode_and_send(const byte block[], u32bit length)
   {
   for(u32bit j = 0; j != length; ++j)
      encode(block[j], out + 2*j, casing);

   if(line_length == 0)
      send(out, 2*length);
   else
      {
      u32bit remaining = 2*length, offset = 0;
      while(remaining)
         {
         u32bit sent = std::min(line_length - counter, remaining);
         send(out + offset, sent);
         counter += sent;
         remaining -= sent;
         offset += sent;
         if(counter == line_length)
            {
            send('\n');
            counter = 0;
            }
         }
      }
   }

/*
* Convert some data into hex format
*/
void Hex_Encoder::write(const byte input[], u32bit length)
   {
   in.copy(position, input, length);
   if(position + length >= in.size())
      {
      encode_and_send(in, in.size());
      input += (in.size() - position);
      length -= (in.size() - position);
      while(length >= in.size())
         {
         encode_and_send(input, in.size());
         input += in.size();
         length -= in.size();
         }
      in.copy(input, length);
      position = 0;
      }
   position += length;
   }

/*
* Flush buffers
*/
void Hex_Encoder::end_msg()
   {
   encode_and_send(in, position);
   if(counter && line_length)
      send('\n');
   counter = position = 0;
   }

/*
* Hex_Decoder Constructor
*/
Hex_Decoder::Hex_Decoder(Decoder_Checking c) : checking(c)
   {
   in.create(64);
   out.create(in.size() / 2);
   position = 0;
   }

/*
* Check if a character is a valid hex char
*/
bool Hex_Decoder::is_valid(byte in)
   {
   return (HEX_TO_BIN[in] != 0x80);
   }

/*
* Handle processing an invalid character
*/
void Hex_Decoder::handle_bad_char(byte c)
   {
   if(checking == NONE)
      return;

   if((checking == IGNORE_WS) && Charset::is_space(c))
      return;

   throw Decoding_Error("Hex_Decoder: Invalid hex character: " +
                        to_string(c));
   }

/*
* Hex Decoding Operation
*/
byte Hex_Decoder::decode(const byte hex[2])
   {
   return ((HEX_TO_BIN[hex[0]] << 4) | HEX_TO_BIN[hex[1]]);
   }

/*
* Decode and send a block
*/
void Hex_Decoder::decode_and_send(const byte block[], u32bit length)
   {
   for(u32bit j = 0; j != length / 2; ++j)
      out[j] = decode(block + 2*j);
   send(out, length / 2);
   }

/*
* Convert some data from hex format
*/
void Hex_Decoder::write(const byte input[], u32bit length)
   {
   for(u32bit j = 0; j != length; ++j)
      {
      if(is_valid(input[j]))
         in[position++] = input[j];
      else
         handle_bad_char(input[j]);
      if(position == in.size())
         {
         decode_and_send(in, in.size());
         position = 0;
         }
      }
   }

/*
* Flush buffers
*/
void Hex_Decoder::end_msg()
   {
   decode_and_send(in, position);
   position = 0;
   }

}
<commit_msg>Increase the internal buffer size of the Hex coder/decoder, and put it into a named constant instead of being magic. Move from 64 bytes to 256.<commit_after>/*
* Hex Encoder/Decoder
* (C) 1999-2007 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/

#include <botan/hex.h>
#include <botan/parsing.h>
#include <botan/charset.h>
#include <botan/exceptn.h>
#include <algorithm>

namespace Botan {

const u32bit HEX_CODEC_BUFFER_SIZE = 256;

/*
* Hex_Encoder Constructor
*/
Hex_Encoder::Hex_Encoder(bool breaks, u32bit length, Case c) :
   casing(c), line_length(breaks ? length : 0)
   {
   in.create(HEX_CODEC_BUFFER_SIZE);
   out.create(2*in.size());
   counter = position = 0;
   }

/*
* Hex_Encoder Constructor
*/
Hex_Encoder::Hex_Encoder(Case c) : casing(c), line_length(0)
   {
   in.create(HEX_CODEC_BUFFER_SIZE);
   out.create(2*in.size());
   counter = position = 0;
   }

/*
* Hex Encoding Operation
*/
void Hex_Encoder::encode(byte in, byte out[2], Hex_Encoder::Case casing)
   {
   const byte* BIN_TO_HEX = ((casing == Uppercase) ? BIN_TO_HEX_UPPER :
                                                     BIN_TO_HEX_LOWER);

   out[0] = BIN_TO_HEX[((in >> 4) & 0x0F)];
   out[1] = BIN_TO_HEX[((in     ) & 0x0F)];
   }

/*
* Encode and send a block
*/
void Hex_Encoder::encode_and_send(const byte block[], u32bit length)
   {
   for(u32bit j = 0; j != length; ++j)
      encode(block[j], out + 2*j, casing);

   if(line_length == 0)
      send(out, 2*length);
   else
      {
      u32bit remaining = 2*length, offset = 0;
      while(remaining)
         {
         u32bit sent = std::min(line_length - counter, remaining);
         send(out + offset, sent);
         counter += sent;
         remaining -= sent;
         offset += sent;
         if(counter == line_length)
            {
            send('\n');
            counter = 0;
            }
         }
      }
   }

/*
* Convert some data into hex format
*/
void Hex_Encoder::write(const byte input[], u32bit length)
   {
   in.copy(position, input, length);
   if(position + length >= in.size())
      {
      encode_and_send(in, in.size());
      input += (in.size() - position);
      length -= (in.size() - position);
      while(length >= in.size())
         {
         encode_and_send(input, in.size());
         input += in.size();
         length -= in.size();
         }
      in.copy(input, length);
      position = 0;
      }
   position += length;
   }

/*
* Flush buffers
*/
void Hex_Encoder::end_msg()
   {
   encode_and_send(in, position);
   if(counter && line_length)
      send('\n');
   counter = position = 0;
   }

/*
* Hex_Decoder Constructor
*/
Hex_Decoder::Hex_Decoder(Decoder_Checking c) : checking(c)
   {
   in.create(HEX_CODEC_BUFFER_SIZE);
   out.create(in.size() / 2);
   position = 0;
   }

/*
* Check if a character is a valid hex char
*/
bool Hex_Decoder::is_valid(byte in)
   {
   return (HEX_TO_BIN[in] != 0x80);
   }

/*
* Handle processing an invalid character
*/
void Hex_Decoder::handle_bad_char(byte c)
   {
   if(checking == NONE)
      return;

   if((checking == IGNORE_WS) && Charset::is_space(c))
      return;

   throw Decoding_Error("Hex_Decoder: Invalid hex character: " +
                        to_string(c));
   }

/*
* Hex Decoding Operation
*/
byte Hex_Decoder::decode(const byte hex[2])
   {
   return ((HEX_TO_BIN[hex[0]] << 4) | HEX_TO_BIN[hex[1]]);
   }

/*
* Decode and send a block
*/
void Hex_Decoder::decode_and_send(const byte block[], u32bit length)
   {
   for(u32bit j = 0; j != length / 2; ++j)
      out[j] = decode(block + 2*j);
   send(out, length / 2);
   }

/*
* Convert some data from hex format
*/
void Hex_Decoder::write(const byte input[], u32bit length)
   {
   for(u32bit j = 0; j != length; ++j)
      {
      if(is_valid(input[j]))
         in[position++] = input[j];
      else
         handle_bad_char(input[j]);
      if(position == in.size())
         {
         decode_and_send(in, in.size());
         position = 0;
         }
      }
   }

/*
* Flush buffers
*/
void Hex_Decoder::end_msg()
   {
   decode_and_send(in, position);
   position = 0;
   }

}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2016 Boulanger Guillaume, Chathura Namalgamuwa
 * The file is distributed under the MIT license
 * The license is available in the LICENSE file or at https://github.com/boulangg/phoenix/blob/master/LICENSE
 */

#include "PhysicalAllocator.hpp"

#include <cstddef>
#include <constant.h>
#include <stdio.h>
#include <stdlib.h>
#include "../core/Console.hpp"

using namespace std;

uint64_t PhysicalAllocator::FBT[] = {};
Page* PhysicalAllocator::page_array = nullptr;
uint64_t PhysicalAllocator::nb_physical_pages = 0;

int test_free_block(Page* page_array, uint64_t start, uint64_t end) {
	for (uint64_t i = start; i < end; i++) {
		if (page_array[i].type != PageType::FREE) {
			return 0;
		}
	}
	return 1;
}

void PhysicalAllocator::initAllocator(Page* page_array, uint64_t nb_physical_pages)
{
	PhysicalAllocator::page_array = page_array;
	PhysicalAllocator::nb_physical_pages = nb_physical_pages;
	for (int i=0; i<MAX_ORDER;i++) {
		FBT[i] = 0;
	}

	uint64_t i = 256;
	while (i < nb_physical_pages) {
		uint64_t tmp = i;
		int8_t max_order = 0;
		while (!(tmp & 0x1)) {
			tmp/=2;
			max_order++;
		}
		int8_t order = -1;
		uint64_t start = i;
		uint64_t end = i+1;
		while (order < max_order && test_free_block(page_array, start, end)) {
			order++;
			start = end;
			end += (1 << order);
		}

		if (order >= 0) {
			uint64_t *addr = page_array[i].kernelMappAddr;
			freePagesInternal(addr, order);
			i+=(1 << order);
		} else {
			i++;
		}
	}
}

uint64_t* PhysicalAllocator::fusion(uint64_t* addr, uint8_t order)
{
	uint64_t *buddy = calculAddrBuddy(addr, order);

	uint64_t *prev = &FBT[order];
	uint64_t *curr = (uint64_t*)FBT[order];

	/* Look for buddy bloc inside the free bloc list for the
	 * current order */
	while (curr < buddy && curr != nullptr) {
		// bloc already free
		if (curr == addr) return nullptr;
		prev = curr;
		curr = (uint64_t *) (*curr);
	}

	/* If the buddy is found, we remove the buddy from the free list
	 * and return the lowest address of the two blocs that now form one */
	if (curr == buddy) {
		*prev = *curr;
		if (addr < buddy)
			return addr;
		else
			return buddy;
	}

	/* If we reach the end of the list, we insert the new bloc inside it */
	*prev = (uint64_t)addr;
	*addr = (uint64_t)curr;
	return NULL;
}

uint64_t* PhysicalAllocator::calculAddrBuddy(uint64_t* addr, uint8_t order)
{
	uint64_t buddy = (uint64_t)addr;
	buddy = buddy ^(PAGE_SIZE << order);
	return (uint64_t*)buddy;
}

uint64_t* PhysicalAllocator::allocPagesInternal(uint8_t order)
{
	uint8_t k0 = order;
	/** We look for a bloc big enough to provide the demanded size */
	while (FBT[k0] == 0) {
		k0++;
		/* If we reach the end of the FBT, we can't satisfy the allocation */
		if (k0 > MAX_ORDER)
			return nullptr;
	}
	/* Remove bloc from FBT */
	uint64_t *addr = (uint64_t *)FBT[k0];
	FBT[k0] = *addr;
	/* Fragment bloc until reaching desired size and save buddies in table */
	while (k0>order) {
		uint64_t* addr_buddy = calculAddrBuddy(addr, k0-1);
		k0--;
		FBT[k0]= (uintptr_t)addr_buddy;
		*addr_buddy = 0;
	}

	return addr;
}

Page* PhysicalAllocator::getPageFromAddr(uint64_t* addr) {
	if (addr == nullptr) {
		return nullptr;
	}
	uint64_t index = (uint64_t)addr & ~(KERNEL_START);
	index /= PAGE_SIZE;
	return page_array + index;
}

uint64_t* PhysicalAllocator::getAddrFromPage(Page* page) {
	return page->kernelMappAddr;
}

Page* PhysicalAllocator::allocPage()
{
	return allocPages(0);
}

Page* PhysicalAllocator::allocPages(uint8_t order) {
	uint64_t* addr = allocPagesInternal(order);
	return getPageFromAddr(addr);
}

Page* PhysicalAllocator::allocZeroedPage()
{
	return allocZeroedPages(0);
}

Page* PhysicalAllocator::allocZeroedPages(uint8_t order)
{
	Page* page = allocPages(order);
	uint64_t *addr = getAddrFromPage(page);
	for (uint64_t i=0; i < (uint64_t)(PAGE_SIZE << (order-sizeof(uint64_t))); i++) {
		addr[i] = 0;
	}
	return page;
}

int PhysicalAllocator::freePage(Page* page)
{
	return freePages(page, 0);
}

int PhysicalAllocator::freePages(Page* page, uint8_t order) {
	uint64_t* addr = getAddrFromPage(page);
	return freePagesInternal(addr, order);
}

int PhysicalAllocator::freePagesInternal(uint64_t* addr, uint8_t order)
{
	uint64_t* tmp = addr;
	/* Fusion of blocs when possible */
	while(tmp != NULL) {
		tmp = fusion(tmp, order);
		order++;
	}

	return 0;
}

void PhysicalAllocator::printStats() {
	uint64_t stats[5] = {0, 0, 0, 0, 0};
	for (uint64_t i = 0; i < PhysicalAllocator::nb_physical_pages; ++i) {
		stats[PhysicalAllocator::page_array[i].type] ++;
	}
	char str[512];
	Console::write("Memory (in pages, 4Ko):\n");
	sprintf(str, "  Unavailable: %u\n  Free: %u\n  Allocated: %u\n  Kernel: %u\n  Cache: %u\n", stats[0], stats[1], stats[2], stats[3], stats[4]);
	Console::write(str);
}

<commit_msg>Improvement of PhysicalAllocator<commit_after>/*
 * Copyright (c) 2016 Boulanger Guillaume, Chathura Namalgamuwa
 * The file is distributed under the MIT license
 * The license is available in the LICENSE file or at https://github.com/boulangg/phoenix/blob/master/LICENSE
 */

#include "PhysicalAllocator.hpp"

#include <cstddef>
#include <constant.h>
#include <stdio.h>
#include <stdlib.h>
#include "../core/Console.hpp"

using namespace std;

uint64_t PhysicalAllocator::FBT[] = {};
Page* PhysicalAllocator::page_array = nullptr;
uint64_t PhysicalAllocator::nb_physical_pages = 0;

int test_free_block(Page* page_array, uint64_t start, uint64_t end) {
	for (uint64_t i = start; i < end; i++) {
		if (page_array[i].type != PageType::FREE) {
			return 0;
		}
	}
	return 1;
}

void PhysicalAllocator::initAllocator(Page* page_array, uint64_t nb_physical_pages)
{
	PhysicalAllocator::page_array = page_array;
	PhysicalAllocator::nb_physical_pages = nb_physical_pages;
	for (int i=0; i<MAX_ORDER;i++) {
		FBT[i] = 0;
	}

	uint64_t i = 256;
	while (i < nb_physical_pages) {
		uint64_t tmp = i;
		int8_t max_order = 0;
		while (!(tmp & 0x1)) {
			tmp/=2;
			max_order++;
		}
		int8_t order = -1;
		uint64_t start = i;
		uint64_t end = i+1;
		while (order < max_order && test_free_block(page_array, start, end)) {
			order++;
			start = end;
			end += (1 << order);
		}

		if (order >= 0) {
			uint64_t *addr = page_array[i].kernelMappAddr;
			freePagesInternal(addr, order);
			i+=(1 << order);
		} else {
			i++;
		}
	}
}

uint64_t* PhysicalAllocator::fusion(uint64_t* addr, uint8_t order)
{
	uint64_t *buddy = calculAddrBuddy(addr, order);

	uint64_t *prev = &FBT[order];
	uint64_t *curr = (uint64_t*)FBT[order];

	/* Look for buddy bloc inside the free bloc list for the
	 * current order */
	while (curr < buddy && curr != nullptr) {
		// bloc already free
		if (curr == addr) return nullptr;
		prev = curr;
		curr = (uint64_t *) (*curr);
	}

	/* If the buddy is found, we remove the buddy from the free list
	 * and return the lowest address of the two blocs that now form one */
	if (curr == buddy) {
		*prev = *curr;
		if (addr < buddy)
			return addr;
		else
			return buddy;
	}

	/* If we reach the end of the list, we insert the new bloc inside it */
	*prev = (uint64_t)addr;
	*addr = (uint64_t)curr;
	return NULL;
}

uint64_t* PhysicalAllocator::calculAddrBuddy(uint64_t* addr, uint8_t order)
{
	uint64_t buddy = (uint64_t)addr;
	buddy = buddy ^ (PAGE_SIZE << order);
	return (uint64_t*)buddy;
}

uint64_t* PhysicalAllocator::allocPagesInternal(uint8_t order)
{
	uint8_t k0 = order;
	/** We look for a bloc big enough to provide the demanded size */
	while (FBT[k0] == 0) {
		k0++;
		/* If we reach the end of the FBT, we can't satisfy the allocation */
		if (k0 > MAX_ORDER)
			return nullptr;
	}
	/* Remove bloc from FBT */
	uint64_t *addr = (uint64_t *)FBT[k0];
	FBT[k0] = *addr;
	/* Fragment bloc until reaching desired size and save buddies in table */
	while (k0>order) {
		uint64_t* addr_buddy = calculAddrBuddy(addr, k0-1);
		k0--;
		FBT[k0]= (uintptr_t)addr_buddy;
		*addr_buddy = 0;
	}

	Page* page = getPageFromAddr(addr);
	for (uint64_t i = 0; i < (uint64_t)(1 << order); ++i) {
		page[i].type = PageType::ALLOCATED;
	}

	return addr;
}

Page* PhysicalAllocator::getPageFromAddr(uint64_t* addr) {
	if (addr == nullptr) {
		return nullptr;
	}
	uint64_t index = (uint64_t)addr & ~(KERNEL_START);
	index /= PAGE_SIZE;
	return page_array + index;
}

uint64_t* PhysicalAllocator::getAddrFromPage(Page* page) {
	return page->kernelMappAddr;
}

Page* PhysicalAllocator::allocPage()
{
	return allocPages(0);
}

Page* PhysicalAllocator::allocPages(uint8_t order) {
	uint64_t* addr = allocPagesInternal(order);
	return getPageFromAddr(addr);
}

Page* PhysicalAllocator::allocZeroedPage()
{
	return allocZeroedPages(0);
}

Page* PhysicalAllocator::allocZeroedPages(uint8_t order)
{
	Page* page = allocPages(order);
	uint64_t *addr = getAddrFromPage(page);
	for (uint64_t i=0; i < (uint64_t)(PAGE_SIZE << (order-sizeof(uint64_t))); i++) {
		addr[i] = 0;
	}
	return page;
}

int PhysicalAllocator::freePage(Page* page)
{
	return freePages(page, 0);
}

int PhysicalAllocator::freePages(Page* page, uint8_t order) {
	uint64_t* addr = getAddrFromPage(page);
	return freePagesInternal(addr, order);
}

int PhysicalAllocator::freePagesInternal(uint64_t* addr, uint8_t order)
{
	Page* page = getPageFromAddr(addr);
	for (uint64_t i = 0; i < (uint64_t)(1 << order); ++i) {
		page[i].type = PageType::FREE;
	}

	uint64_t* tmp = addr;
	/* Fusion of blocs when possible */
	while(tmp != NULL) {
		tmp = fusion(tmp, order);
		order++;
	}

	return 0;
}

void PhysicalAllocator::printStats() {
	uint64_t stats[5*2] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
	for (uint64_t i = 0; i < PhysicalAllocator::nb_physical_pages; ++i) {
		stats[PhysicalAllocator::page_array[i].type] ++;
		if (i < 256) {
			stats[PhysicalAllocator::page_array[i].type + 5] ++;
		}
	}
	char str[512];
	Console::write("Memory (low_mem < 1Mo): pages (4Ko)\n");
	sprintf(str, "  Unavailable: %u (low_mem : %u)\n", stats[0], stats[5]);
	Console::write(str);
	sprintf(str, "  Free: %u (low_mem : %u)\n", stats[1], stats[6]);
	Console::write(str);
	sprintf(str, "  Allocated: %u (low_mem : %u)\n", stats[2], stats[7]);
	Console::write(str);
	sprintf(str, "  Kernel: %u (low_mem : %u)\n", stats[3], stats[8]);
	Console::write(str);
	sprintf(str, "  Cache: %u\n", stats[4]);
	Console::write(str);
}

<|endoftext|>


<commit_before>// This file is part of BlueSky
//
// BlueSky is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// BlueSky is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with BlueSky; if not, see <http://www.gnu.org/licenses/>.

#include "bs_common.h"
#include "type_descriptor.h"
#include "bs_kernel.h"
#include "py_bs_exports.h"
#include "py_list_converter.h"
#include "py_pair_converter.h"
#include "py_smart_ptr.h"
//#include <boost/python/python.h>

#include <ostream>
#include <iostream>
#include <sstream>

namespace blue_sky {
using namespace std;

// def(str(self)) impl for plugin_descriptor
BS_HIDDEN_API ostream& operator<<(ostream& os, const plugin_descriptor& pd) {
	os << "{PLUGIN: " << pd.name_ << "; VERSIOM " << pd.version_;
	os << "; INFO: " << pd.short_descr_;
	if(pd.long_descr_.size() > 0)		os << "; LONG INFO: " << pd.long_descr_;
	os << "; NAMESPACE: " << pd.py_namespace_ << '}';
	return os;
}

// def(str(self)) impl for type_descriptor
BS_HIDDEN_API ostream& operator<<(ostream& os, const type_descriptor& td) {
	if(td.is_nil())
		os << "BlueSky Nil type" << endl;
	else {
		os << "{TYPENAME: " << td.stype_;
		os << "; INFO: " << td.short_descr_;
		if(td.long_descr_.size() > 0)
			os << "; LONG INFO: " << td.long_descr_ << '}';
	}
	return os;
}

// def(str(self)) impl for type_info
BS_HIDDEN_API ostream& operator<<(ostream& os, const bs_type_info& ti) {
	os << "BlueSky C++ layer type_info: '" << ti.name() << "' at " << &ti.get() << endl;
	return os;
}

namespace python {
using namespace boost::python;

namespace {
struct type_tuple_traits : public pair_traits< type_tuple > {
	static PyObject* to_python(type const& v) {
		// Make bp::object
		bp::tuple py_tuple = boost::python::make_tuple(v.pd_, v.td_);
		// export it to Python
		return incref(py_tuple.ptr());
	}
};

class bs_refcounter_pyw : public bs_refcounter, public wrapper< bs_refcounter > {
public:
	void dispose() const {
		this->get_override("dispose");
	}

	//void add_ref() const {
	//	if(override f = this->get_override("add_ref"))
	//		f();
	//	else
	//		bs_refcounter::add_ref();
	//}
	//void def_add_ref() const {
	//	bs_refcounter::add_ref();
	//}

	//void del_ref() const {
	//	if(override f = this->get_override("del_ref"))
	//		f();
	//	else
	//		bs_refcounter::del_ref();
	//}
	//void def_del_ref() const {
	//	bs_refcounter::del_ref();
	//}
};

}

// dumb function for testing type_d-tor <-> Py list
typedef std::vector< type_descriptor > type_v;
type_v test_type_v(const type_v& v) {
	using namespace std;
	cout << "Size of type_descriptor list = " << v.size() << endl;
	for(ulong i = 0; i < v.size(); ++i)
		cout << v[i].stype_ << ' ';
	cout << endl;
	return v;
}

// exporting function
void py_bind_common() {
	// bs_type_info binding
	class_< bs_type_info >("type_info")
		.def("before", &bs_type_info::before)
		.def("name", &bs_type_info::name)
		.def("is_nil", &bs_type_info::is_nil)
		.def(self == self)
		.def(self != self)
		.def(self < self)
		.def(self > self)
		.def(self <= self)
		.def(self >= self)
		.def(str(self))
		;

	// register vector of type_info <-> Python list converters
	typedef bspy_converter< list_traits< std::vector< bs_type_info > > > tiv_converter;
	tiv_converter::register_from_py();
	tiv_converter::register_to_py();

	// plugin_descriptor binding
	class_< plugin_descriptor >("plugin_descriptor", no_init)
		.def_readonly("name", &plugin_descriptor::name_)
		.def_readonly("version", &plugin_descriptor::version_)
		.def_readonly("short_descr", &plugin_descriptor::short_descr_)
		.def_readonly("long_descr", &plugin_descriptor::long_descr_)
		.def_readonly("py_namespace", &plugin_descriptor::py_namespace_)
		.def(self < self)
		.def(self == self)
		.def(self != self)
		.def ("__repr__", &plugin_descriptor::get_name)
		.def(str(self))
		;

	// register vector of plugin descriptors <-> Python list converters
	typedef bspy_converter< list_traits< std::vector< plugin_descriptor > > > pdv_converter;
	pdv_converter::register_from_py();
	pdv_converter::register_to_py();

	// type_desccriptor bind
	class_< type_descriptor >("type_descriptor")
		.def(init< const std::string& >())
		.def_readonly("stype", &type_descriptor::stype_)
		.def_readonly("short_descr", &type_descriptor::short_descr_)
		.def_readonly("long_descr", &type_descriptor::long_descr_)
		.def("type", &type_descriptor::type)
		.def("is_nil", &type_descriptor::is_nil)
		.def("is_copyable", &type_descriptor::is_copyable)
		.def("name", &type_descriptor::name)
		.def("parent_td", &type_descriptor::parent_td)
		.def(self == self)
		.def(self != self)
		.def(self < self)
		.def(self < std::string())
		.def(self == std::string())
		.def(self != std::string())
		.def ("__repr__", &type_descriptor::name)
		.def(str(self))
		;

	// register vector of type descriptors <-> Python list converters
	typedef bspy_converter< list_traits< std::vector< type_descriptor > > > tdv_converter;
	tdv_converter::register_from_py();
	tdv_converter::register_to_py();

	// register pair< plugin_descriptor, type_descriptor > <-> Py tuple
	typedef bspy_converter< type_tuple_traits > type_tuple_converter;
	type_tuple_converter::register_from_py();
	type_tuple_converter::register_to_py();

	// register vector of type_tuples <-> Python list converters
	typedef bspy_converter< list_traits< std::vector< type_tuple >, 1 > > ttv_converter;
	ttv_converter::register_from_py();
	ttv_converter::register_to_py();

	//def("test_type_v", &test_type_v);

	class_< bs_refcounter_pyw, boost::noncopyable >("refcounter")
		//.def("add_ref", &bs_refcounter::add_ref, &bs_refcounter_pyw::def_add_ref)
		//.def("del_ref", &bs_refcounter::del_ref, &bs_refcounter_pyw::def_del_ref)
		.def("add_ref", &bs_refcounter::add_ref)
		.def("del_ref", &bs_refcounter::del_ref)
		.add_property("refs", &bs_refcounter::refs)
		.def("dispose", pure_virtual(&bs_refcounter::dispose))
	;
}

}}	// eof namespace blue_sky::python

<commit_msg>Python: export std vector, list and set containers of several types as Python lists<commit_after>// This file is part of BlueSky
//
// BlueSky is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// BlueSky is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with BlueSky; if not, see <http://www.gnu.org/licenses/>.

#include "bs_common.h"
#include "type_descriptor.h"
#include "bs_kernel.h"
#include "py_bs_exports.h"
#include "py_list_converter.h"
#include "py_pair_converter.h"
#include "py_smart_ptr.h"
//#include <boost/python/python.h>

#include <ostream>
#include <iostream>
#include <sstream>

namespace blue_sky {
using namespace std;

// def(str(self)) impl for plugin_descriptor
BS_HIDDEN_API ostream& operator<<(ostream& os, const plugin_descriptor& pd) {
	os << "{PLUGIN: " << pd.name_ << "; VERSIOM " << pd.version_;
	os << "; INFO: " << pd.short_descr_;
	if(pd.long_descr_.size() > 0)		os << "; LONG INFO: " << pd.long_descr_;
	os << "; NAMESPACE: " << pd.py_namespace_ << '}';
	return os;
}

// def(str(self)) impl for type_descriptor
BS_HIDDEN_API ostream& operator<<(ostream& os, const type_descriptor& td) {
	if(td.is_nil())
		os << "BlueSky Nil type" << endl;
	else {
		os << "{TYPENAME: " << td.stype_;
		os << "; INFO: " << td.short_descr_;
		if(td.long_descr_.size() > 0)
			os << "; LONG INFO: " << td.long_descr_ << '}';
	}
	return os;
}

// def(str(self)) impl for type_info
BS_HIDDEN_API ostream& operator<<(ostream& os, const bs_type_info& ti) {
	os << "BlueSky C++ layer type_info: '" << ti.name() << "' at " << &ti.get() << endl;
	return os;
}

namespace python {
using namespace boost::python;

namespace {
struct type_tuple_traits : public pair_traits< type_tuple > {
	static PyObject* to_python(type const& v) {
		// Make bp::object
		bp::tuple py_tuple = boost::python::make_tuple(v.pd_, v.td_);
		// export it to Python
		return incref(py_tuple.ptr());
	}
};

class bs_refcounter_pyw : public bs_refcounter, public wrapper< bs_refcounter > {
public:
	void dispose() const {
		this->get_override("dispose");
	}

	//void add_ref() const {
	//	if(override f = this->get_override("add_ref"))
	//		f();
	//	else
	//		bs_refcounter::add_ref();
	//}
	//void def_add_ref() const {
	//	bs_refcounter::add_ref();
	//}

	//void del_ref() const {
	//	if(override f = this->get_override("del_ref"))
	//		f();
	//	else
	//		bs_refcounter::del_ref();
	//}
	//void def_del_ref() const {
	//	bs_refcounter::del_ref();
	//}
};

template< class T >
struct std_cont_converter {
	typedef bspy_converter< list_traits< std::vector< T > > > v_converter;
	typedef bspy_converter< list_traits< std::list< T >, 1 > > l_converter;
	typedef bspy_converter< list_traits< std::set< T >, 2 > > s_converter;

	static void go() {
		v_converter::register_to_py();
		l_converter::register_to_py();
		s_converter::register_to_py();
		// Python lists goes to C++ in most simple vector form
		v_converter::register_from_py();
	}
};

}

// dumb function for testing type_d-tor <-> Py list
typedef std::vector< type_descriptor > type_v;
type_v test_type_v(const type_v& v) {
	using namespace std;
	cout << "Size of type_descriptor list = " << v.size() << endl;
	for(ulong i = 0; i < v.size(); ++i)
		cout << v[i].stype_ << ' ';
	cout << endl;
	return v;
}

// exporting function
void py_bind_common() {
	// bs_type_info binding
	class_< bs_type_info >("type_info")
		.def("before", &bs_type_info::before)
		.def("name", &bs_type_info::name)
		.def("is_nil", &bs_type_info::is_nil)
		.def(self == self)
		.def(self != self)
		.def(self < self)
		.def(self > self)
		.def(self <= self)
		.def(self >= self)
		.def(str(self))
		;

	// register vector of type_info <-> Python list converters
	typedef bspy_converter< list_traits< std::vector< bs_type_info > > > tiv_converter;
	tiv_converter::register_from_py();
	tiv_converter::register_to_py();

	// plugin_descriptor binding
	class_< plugin_descriptor >("plugin_descriptor", no_init)
		.def_readonly("name", &plugin_descriptor::name_)
		.def_readonly("version", &plugin_descriptor::version_)
		.def_readonly("short_descr", &plugin_descriptor::short_descr_)
		.def_readonly("long_descr", &plugin_descriptor::long_descr_)
		.def_readonly("py_namespace", &plugin_descriptor::py_namespace_)
		.def(self < self)
		.def(self == self)
		.def(self != self)
		.def ("__repr__", &plugin_descriptor::get_name)
		.def(str(self))
		;

	// register vector of plugin descriptors <-> Python list converters
	typedef bspy_converter< list_traits< std::vector< plugin_descriptor > > > pdv_converter;
	pdv_converter::register_from_py();
	pdv_converter::register_to_py();

	// type_desccriptor bind
	class_< type_descriptor >("type_descriptor")
		.def(init< const std::string& >())
		.def_readonly("stype", &type_descriptor::stype_)
		.def_readonly("short_descr", &type_descriptor::short_descr_)
		.def_readonly("long_descr", &type_descriptor::long_descr_)
		.def("type", &type_descriptor::type)
		.def("is_nil", &type_descriptor::is_nil)
		.def("is_copyable", &type_descriptor::is_copyable)
		.def("name", &type_descriptor::name)
		.def("parent_td", &type_descriptor::parent_td)
		.def(self == self)
		.def(self != self)
		.def(self < self)
		.def(self < std::string())
		.def(self == std::string())
		.def(self != std::string())
		.def ("__repr__", &type_descriptor::name)
		.def(str(self))
		;

	// register vector of type descriptors <-> Python list converters
	typedef bspy_converter< list_traits< std::vector< type_descriptor > > > tdv_converter;
	tdv_converter::register_from_py();
	tdv_converter::register_to_py();

	// register pair< plugin_descriptor, type_descriptor > <-> Py tuple
	typedef bspy_converter< type_tuple_traits > type_tuple_converter;
	type_tuple_converter::register_from_py();
	type_tuple_converter::register_to_py();

	// register vector of type_tuples <-> Python list converters
	typedef bspy_converter< list_traits< std::vector< type_tuple >, 1 > > ttv_converter;
	ttv_converter::register_from_py();
	ttv_converter::register_to_py();

	//def("test_type_v", &test_type_v);

	class_< bs_refcounter_pyw, boost::noncopyable >("refcounter")
		//.def("add_ref", &bs_refcounter::add_ref, &bs_refcounter_pyw::def_add_ref)
		//.def("del_ref", &bs_refcounter::del_ref, &bs_refcounter_pyw::def_del_ref)
		.def("add_ref", &bs_refcounter::add_ref)
		.def("del_ref", &bs_refcounter::del_ref)
		.add_property("refs", &bs_refcounter::refs)
		.def("dispose", pure_virtual(&bs_refcounter::dispose))
	;

	// register converters for some C++ containers
	std_cont_converter< int >::go();
	std_cont_converter< unsigned int >::go();
	std_cont_converter< long >::go();
	std_cont_converter< long long >::go();
	std_cont_converter< unsigned long >::go();
	std_cont_converter< unsigned long long >::go();
	std_cont_converter< float >::go();
	std_cont_converter< double >::go();
	std_cont_converter< std::string >::go();
	std_cont_converter< std::wstring >::go();
}

}}	// eof namespace blue_sky::python

<|endoftext|>


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

#include "ostream.h++"

#include <iostream>

namespace skui::css
{
  template<typename... ValueTypes>
  std::ostream& operator<<(std::ostream& os, const std::variant<ValueTypes...>& value)
  {
    std::visit([&os](auto&& v) { os << v; }, value);
    return os;
  }

  std::ostream& operator<<(std::ostream& os, const inherit_t&)
  {
    return os << "inherit";
  }

  std::ostream& operator<<(std::ostream& os, const initial_t&)
  {
    return os << "initial";
  }

  std::ostream& operator<<(std::ostream& os, const color& color)
  {
    core::ostream_format_keeper keeper(os);

    return os << std::hex << std::uint32_t(color);
  }

  std::ostream& operator<<(std::ostream& os, const unit unit)
  {
    switch(unit)
    {
      case unit::mm:
        return os << "mm";
      case unit::cm:
        return os << "cm";
      case unit::in:
        return os << "in";
      case unit::px:
        return os << "px";
      case unit::pt:
        return os << "pt";
      case unit::pc:
        return os << "pc";
      case unit::em:
        return os << "em";
      case unit::ex:
        return os << "ex";
      case unit::ch:
        return os << "ch";
      case unit::rem:
        return os << "rem";
      case unit::vw:
        return os << "vw";
      case unit::vh:
        return os << "vh";
      case unit::vmin:
        return os << "vmin";
      case unit::vmax:
        return os << "vmax";
      case unit::percentage:
        return os << "%";
    }
    return os;
  }

  std::ostream& operator<<(std::ostream& os, const length& length)
  {
    return os << length.value << ' ' << length.unit;
  }

  std::ostream& operator<<(std::ostream& os, const length_with_offset& length_with_offset)
  {
    os << length_with_offset.value;
    if(length_with_offset.offset != length{})
    {
      os << " (offset: " << length_with_offset.offset << ')';
    }
    return os;
  }

  std::ostream& operator<<(std::ostream& os, const position& position)
  {
    return os << "position(" << position.x << ", " << position.y << ")";
  }

  std::ostream& operator<<(std::ostream& os, const skui::css::time& time)
  {
    return os << time.count() << " ms";
  }

  std::ostream& operator<<(std::ostream& os, const steps& steps)
  {
    return os << "steps(" << steps.intervals << ", " << steps.change << ')';
  }

  std::ostream& operator<<(std::ostream& os, const cubic_bezier& cubic_bezier)
  {
    return os << "cubic-bezier(" << cubic_bezier.x1 << ", " << cubic_bezier.y1 << ", "
                                 << cubic_bezier.x2 << ", " << cubic_bezier.y2 << ')';
  }

  std::ostream& operator<<(std::ostream& os, const timing_function& timing_function)
  {
    std::visit([&os](const auto& value) { os << value; }, timing_function);
    return os;
  }

  std::ostream& operator<<(std::ostream& os, const animation_direction& direction)
  {
    switch(direction)
    {
      case animation_direction::normal:
        return os << "normal";
      case animation_direction::reverse:
        return os << "reverse";
      case animation_direction::alternate:
        return os << "alternate";
      case animation_direction::alternate_reverse:
        return os << "alternate-reverse";
    }
    return os;
  }

  std::ostream& operator<<(std::ostream& os, const fill_mode& mode)
  {
    switch(mode)
    {
      case fill_mode::none:
        return os << "none";
      case fill_mode::forwards:
        return os << "forwards";
      case fill_mode::backwards:
        return os << "backwards";
      case fill_mode::both:
        return os << "both";
    }
    return os;
  }

  std::ostream& operator<<(std::ostream& os, const play_state& state)
  {
    switch(state)
    {
      case play_state::running:
        return os << "running";
      case play_state::paused:
        return os << "paused";
    }
    return os;
  }

  std::ostream& operator<<(std::ostream& os, const infinite_t&)
  {
    return os << "infinite";
  }

  std::ostream& operator<<(std::ostream& os, const animation& animation)
  {
    return os << "animation\n{\n"
                 "  name: " << animation.name << ";\n"
                 "  duration: " << /*animation.duration <<*/ ";\n"
                 "  timing-function: " << animation.timing_function << ";\n"
                 "  delay: " << /*animation.delay <<*/ ";\n"
                 "  iteration_count: " << animation.iteration_count << ";\n"
                 "  direction: " << animation.direction << ";\n"
                 "  fill_mode: " << animation.fill_mode << ";\n"
                 "  play_state: " << animation.play_state << ";\n"
                                                             "}";
  }

  std::ostream& operator<<(std::ostream& os,
                           const std::vector<skui::css::color_stop>& colors)
  {
    for(auto it = colors.begin(); it != colors.end(); ++it)
    {
      os << *it;
      if(it+1 != colors.end())
        os << ", ";
    }
    return os;
  }

  std::ostream&operator<<(std::ostream& os, const color_stop& color_stop)
  {
    os << "color-stop(" << color_stop.color;
    if(color_stop.stop)
    {
      os << ", " << *color_stop.stop;
    }
    return os << ")";
  }

  std::ostream& operator<<(std::ostream& os,
                           const linear_gradient& linear_gradient)
  {
    if(linear_gradient.repeating)
      os << "repeating-";

    os << "linear-gradient(to ";
    std::visit([&os](auto&& direction) { os << direction; }, linear_gradient.direction);

    return os << ", " << linear_gradient.colors << ")";
  }
}
<commit_msg>Improve css::position output operator to match predefined positions.<commit_after>/**
 * The MIT License (MIT)
 *
 * Copyright © 2019 Ruben Van Boxem
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 **/

#include "ostream.h++"

#include <iostream>

namespace skui::css
{
  template<typename... ValueTypes>
  std::ostream& operator<<(std::ostream& os, const std::variant<ValueTypes...>& value)
  {
    std::visit([&os](auto&& v) { os << v; }, value);
    return os;
  }

  std::ostream& operator<<(std::ostream& os, const inherit_t&)
  {
    return os << "inherit";
  }

  std::ostream& operator<<(std::ostream& os, const initial_t&)
  {
    return os << "initial";
  }

  std::ostream& operator<<(std::ostream& os, const color& color)
  {
    core::ostream_format_keeper keeper(os);

    return os << std::hex << std::uint32_t(color);
  }

  std::ostream& operator<<(std::ostream& os, const unit unit)
  {
    switch(unit)
    {
      case unit::mm:
        return os << "mm";
      case unit::cm:
        return os << "cm";
      case unit::in:
        return os << "in";
      case unit::px:
        return os << "px";
      case unit::pt:
        return os << "pt";
      case unit::pc:
        return os << "pc";
      case unit::em:
        return os << "em";
      case unit::ex:
        return os << "ex";
      case unit::ch:
        return os << "ch";
      case unit::rem:
        return os << "rem";
      case unit::vw:
        return os << "vw";
      case unit::vh:
        return os << "vh";
      case unit::vmin:
        return os << "vmin";
      case unit::vmax:
        return os << "vmax";
      case unit::percentage:
        return os << "%";
    }
    return os;
  }

  std::ostream& operator<<(std::ostream& os, const length& length)
  {
    return os << length.value << ' ' << length.unit;
  }

  std::ostream& operator<<(std::ostream& os, const length_with_offset& length_with_offset)
  {
    os << length_with_offset.value;
    if(length_with_offset.offset != length{})
    {
      os << " (offset: " << length_with_offset.offset << ')';
    }
    return os;
  }

  std::ostream& operator<<(std::ostream& os, const position& position)
  {
    if(position == top)
      os << "top";
    else if(position == center)
      os << "center";
    else if(position == bottom)
      os << "bottom";
    else if(position == left)
      os << "left";
    else if(position == right)
      os << "right";
    else if(position == top_left)
      os << "top left";
    else if(position == top_right)
      os << "top right";
    else if(position == bottom_left)
      os << "bottom left";
    else if(position == bottom_right)
      os << "bottom right";
    else
      os << "position(" << position.x << ", " << position.y << ")";

    return os;
  }

  std::ostream& operator<<(std::ostream& os, const skui::css::time& time)
  {
    return os << time.count() << " ms";
  }

  std::ostream& operator<<(std::ostream& os, const steps& steps)
  {
    return os << "steps(" << steps.intervals << ", " << steps.change << ')';
  }

  std::ostream& operator<<(std::ostream& os, const cubic_bezier& cubic_bezier)
  {
    return os << "cubic-bezier(" << cubic_bezier.x1 << ", " << cubic_bezier.y1 << ", "
                                 << cubic_bezier.x2 << ", " << cubic_bezier.y2 << ')';
  }

  std::ostream& operator<<(std::ostream& os, const timing_function& timing_function)
  {
    std::visit([&os](const auto& value) { os << value; }, timing_function);
    return os;
  }

  std::ostream& operator<<(std::ostream& os, const animation_direction& direction)
  {
    switch(direction)
    {
      case animation_direction::normal:
        return os << "normal";
      case animation_direction::reverse:
        return os << "reverse";
      case animation_direction::alternate:
        return os << "alternate";
      case animation_direction::alternate_reverse:
        return os << "alternate-reverse";
    }
    return os;
  }

  std::ostream& operator<<(std::ostream& os, const fill_mode& mode)
  {
    switch(mode)
    {
      case fill_mode::none:
        return os << "none";
      case fill_mode::forwards:
        return os << "forwards";
      case fill_mode::backwards:
        return os << "backwards";
      case fill_mode::both:
        return os << "both";
    }
    return os;
  }

  std::ostream& operator<<(std::ostream& os, const play_state& state)
  {
    switch(state)
    {
      case play_state::running:
        return os << "running";
      case play_state::paused:
        return os << "paused";
    }
    return os;
  }

  std::ostream& operator<<(std::ostream& os, const infinite_t&)
  {
    return os << "infinite";
  }

  std::ostream& operator<<(std::ostream& os, const animation& animation)
  {
    return os << "animation\n{\n"
                 "  name: " << animation.name << ";\n"
                 "  duration: " << /*animation.duration <<*/ ";\n"
                 "  timing-function: " << animation.timing_function << ";\n"
                 "  delay: " << /*animation.delay <<*/ ";\n"
                 "  iteration_count: " << animation.iteration_count << ";\n"
                 "  direction: " << animation.direction << ";\n"
                 "  fill_mode: " << animation.fill_mode << ";\n"
                 "  play_state: " << animation.play_state << ";\n"
                                                             "}";
  }

  std::ostream& operator<<(std::ostream& os,
                           const std::vector<skui::css::color_stop>& colors)
  {
    for(auto it = colors.begin(); it != colors.end(); ++it)
    {
      os << *it;
      if(it+1 != colors.end())
        os << ", ";
    }
    return os;
  }

  std::ostream&operator<<(std::ostream& os, const color_stop& color_stop)
  {
    os << "color-stop(" << color_stop.color;
    if(color_stop.stop)
    {
      os << ", " << *color_stop.stop;
    }
    return os << ")";
  }

  std::ostream& operator<<(std::ostream& os,
                           const linear_gradient& linear_gradient)
  {
    if(linear_gradient.repeating)
      os << "repeating-";

    os << "linear-gradient(to ";
    std::visit([&os](auto&& direction) { os << direction; }, linear_gradient.direction);

    return os << ", " << linear_gradient.colors << ")";
  }
}
<|endoftext|>


<commit_before>// Copyright (c) 2011 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 "base/test/test_timeouts.h"

#include "base/command_line.h"
#include "base/logging.h"
#include "base/string_number_conversions.h"
#include "base/test/test_switches.h"

namespace {

// Sets value to the greatest of:
// 1) value's current value.
// 2) min_value.
// 3) the numerical value given by switch_name on the command line.
void InitializeTimeout(const char* switch_name, int min_value, int* value) {
  DCHECK(value);
  if (CommandLine::ForCurrentProcess()->HasSwitch(switch_name)) {
    std::string string_value(
        CommandLine::ForCurrentProcess()->GetSwitchValueASCII(switch_name));
    int timeout;
    base::StringToInt(string_value, &timeout);
    *value = std::max(*value, timeout);
  }
  *value = std::max(*value, min_value);
}

// Sets value to the greatest of:
// 1) value's current value.
// 2) 0
// 3) the numerical value given by switch_name on the command line.
void InitializeTimeout(const char* switch_name, int* value) {
  InitializeTimeout(switch_name, 0, value);
}

}  // namespace

// static
bool TestTimeouts::initialized_ = false;

// The timeout values should increase in the order they appear in this block.
// static
int TestTimeouts::tiny_timeout_ms_ = 100;
int TestTimeouts::action_timeout_ms_ = 2000;
int TestTimeouts::action_max_timeout_ms_ = 29000;
int TestTimeouts::large_test_timeout_ms_ = 3 * 60 * 1000;
int TestTimeouts::huge_test_timeout_ms_ = 10 * 60 * 1000;

// static
int TestTimeouts::live_operation_timeout_ms_ = 45000;

// static
void TestTimeouts::Initialize() {
  if (initialized_) {
    NOTREACHED();
    return;
  }
  initialized_ = true;

  // Note that these timeouts MUST be initialized in the correct order as
  // per the CHECKS below.
  InitializeTimeout(switches::kTestTinyTimeout, &tiny_timeout_ms_);
  InitializeTimeout(switches::kUiTestActionTimeout, tiny_timeout_ms_,
                    &action_timeout_ms_);
  InitializeTimeout(switches::kUiTestActionMaxTimeout, action_timeout_ms_,
                    &action_max_timeout_ms_);
  // TODO(phajdan.jr): Fix callers and remove kTestTerminateTimeout.
  InitializeTimeout(switches::kTestTerminateTimeout, &action_max_timeout_ms_);
  InitializeTimeout(switches::kTestLargeTimeout, action_max_timeout_ms_,
                    &large_test_timeout_ms_);
  InitializeTimeout(switches::kUiTestTimeout, large_test_timeout_ms_,
                    &huge_test_timeout_ms_);

  // The timeout values should be increasing in the right order.
  CHECK(tiny_timeout_ms_ <= action_timeout_ms_);
  CHECK(action_timeout_ms_ <= action_max_timeout_ms_);
  CHECK(action_max_timeout_ms_ <= large_test_timeout_ms_);
  CHECK(large_test_timeout_ms_ <= huge_test_timeout_ms_);

  InitializeTimeout(switches::kLiveOperationTimeout,
                    &live_operation_timeout_ms_);
}
<commit_msg>Increase test timeout by 2 more seconds.<commit_after>// Copyright (c) 2011 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 "base/test/test_timeouts.h"

#include "base/command_line.h"
#include "base/logging.h"
#include "base/string_number_conversions.h"
#include "base/test/test_switches.h"

namespace {

// Sets value to the greatest of:
// 1) value's current value.
// 2) min_value.
// 3) the numerical value given by switch_name on the command line.
void InitializeTimeout(const char* switch_name, int min_value, int* value) {
  DCHECK(value);
  if (CommandLine::ForCurrentProcess()->HasSwitch(switch_name)) {
    std::string string_value(
        CommandLine::ForCurrentProcess()->GetSwitchValueASCII(switch_name));
    int timeout;
    base::StringToInt(string_value, &timeout);
    *value = std::max(*value, timeout);
  }
  *value = std::max(*value, min_value);
}

// Sets value to the greatest of:
// 1) value's current value.
// 2) 0
// 3) the numerical value given by switch_name on the command line.
void InitializeTimeout(const char* switch_name, int* value) {
  InitializeTimeout(switch_name, 0, value);
}

}  // namespace

// static
bool TestTimeouts::initialized_ = false;

// The timeout values should increase in the order they appear in this block.
// static
int TestTimeouts::tiny_timeout_ms_ = 100;
int TestTimeouts::action_timeout_ms_ = 2000;
int TestTimeouts::action_max_timeout_ms_ = 31000;
int TestTimeouts::large_test_timeout_ms_ = 3 * 60 * 1000;
int TestTimeouts::huge_test_timeout_ms_ = 10 * 60 * 1000;

// static
int TestTimeouts::live_operation_timeout_ms_ = 45000;

// static
void TestTimeouts::Initialize() {
  if (initialized_) {
    NOTREACHED();
    return;
  }
  initialized_ = true;

  // Note that these timeouts MUST be initialized in the correct order as
  // per the CHECKS below.
  InitializeTimeout(switches::kTestTinyTimeout, &tiny_timeout_ms_);
  InitializeTimeout(switches::kUiTestActionTimeout, tiny_timeout_ms_,
                    &action_timeout_ms_);
  InitializeTimeout(switches::kUiTestActionMaxTimeout, action_timeout_ms_,
                    &action_max_timeout_ms_);
  // TODO(phajdan.jr): Fix callers and remove kTestTerminateTimeout.
  InitializeTimeout(switches::kTestTerminateTimeout, &action_max_timeout_ms_);
  InitializeTimeout(switches::kTestLargeTimeout, action_max_timeout_ms_,
                    &large_test_timeout_ms_);
  InitializeTimeout(switches::kUiTestTimeout, large_test_timeout_ms_,
                    &huge_test_timeout_ms_);

  // The timeout values should be increasing in the right order.
  CHECK(tiny_timeout_ms_ <= action_timeout_ms_);
  CHECK(action_timeout_ms_ <= action_max_timeout_ms_);
  CHECK(action_max_timeout_ms_ <= large_test_timeout_ms_);
  CHECK(large_test_timeout_ms_ <= huge_test_timeout_ms_);

  InitializeTimeout(switches::kLiveOperationTimeout,
                    &live_operation_timeout_ms_);
}
<|endoftext|>


<commit_before>/*
 * LogData.cpp
 *
 *  Created on: 3 nov. 2014
 *      Author: Briag Le Nabec
 */

#include "LogData.h"

namespace csv {

const unsigned int logPerSecond = 25;

LogData::LogData() {
	nbData = 0;
}

LogData::~LogData() {
	// TODO Auto-generated destructor stub
}

void LogData::PopulateByReadingFile(std::string filename, unsigned int secondPerData) {

	std::ifstream inputStream {filename};
	char c;
	std::vector<std::string> parameterName;
	std::unordered_map<std::string,std::vector<double>> currentData;
	std::string currentName = "";

	while( inputStream.get(c) && c!='\n') {
		if(c == ';') {
			parameterName.push_back(currentName);
			currentName.clear();
		}
		else {
			currentName += c;
		}
	}

	while( inputStream.get(c) && c!='\n') {
	}

	for(auto name : parameterName) {
		std::vector<double> vector;
		data.insert({name, vector});
		currentData.insert({name, vector});

	}
	std::string currentValue = "";
	auto i = 0;
	unsigned int nbRecord = 0;

	while( inputStream.get(c) && c!=EOF) {

		if(c == '\n') {
			i = 0;
			++nbRecord;
			if(nbRecord == secondPerData * logPerSecond) {
				for(auto &pair : currentData) {
					double value = std::accumulate(pair.second.begin(),pair.second.end(),0.0f) / nbRecord;
					data.at(pair.first).push_back(value);
					pair.second.clear();
				}
				nbRecord = 0;
				nbData++;
			}

		}
		else if(c == ';') {

			if(parameterName.at(i) == "LogTime") {
				currentValue.erase(std::remove(currentValue.begin(), currentValue.end(), ':'), currentValue.end());
			}
			if(currentValue == "")
				currentValue = "0";

			std::replace(currentValue.begin(), currentValue.end(),',','.');
			currentData.at(parameterName.at(i)).push_back(std::stod(currentValue));
			currentValue.clear();
			++i;
		}
		else if(c != '\r') { // Windows new-line case '\r\n' instead of '\n'
			currentValue += c;
		}
	}

	if(nbRecord != 0) {
		for(auto &pair : currentData) {
			double value = std::accumulate(pair.second.begin(),pair.second.end(),0.0f) / nbRecord;
			data.at(pair.first).push_back(value);
			pair.second.clear();
		}
		nbRecord = 0;
		nbData++;
	}
}

double LogData::ReadValueFromData(std::string key, unsigned int index) {
	if(index < data.size())
		return data.at(key).at(index);
	return -1;
}

} /* namespace csv */

<commit_msg>correct time calculation<commit_after>/*
 * LogData.cpp
 *
 *  Created on: 3 nov. 2014
 *      Author: Briag Le Nabec
 */

#include "LogData.h"

namespace csv {

const unsigned int logPerSecond = 25;

LogData::LogData() {
	nbData = 0;
}

LogData::~LogData() {
	// TODO Auto-generated destructor stub
}

void LogData::PopulateByReadingFile(std::string filename, unsigned int secondPerData) {

	std::ifstream inputStream {filename};
	char c;
	std::vector<std::string> parameterName;
	std::unordered_map<std::string,std::vector<double>> currentData;
	std::string currentName = "";

	while( inputStream.get(c) && c!='\n') {
		if(c == ';') {
			parameterName.push_back(currentName);
			currentName.clear();
		}
		else {
			currentName += c;
		}
	}

	while( inputStream.get(c) && c!='\n') {
	}

	for(auto name : parameterName) {
		std::vector<double> vector;
		data.insert({name, vector});
		currentData.insert({name, vector});

	}
	std::string currentValue = "";
	auto i = 0;
	unsigned int nbRecord = 0;

	while( inputStream.get(c) && c!=EOF) {

		if(c == '\n') {
			i = 0;
			++nbRecord;
			if(nbRecord == secondPerData * logPerSecond) {
				for(auto &pair : currentData) {
					if(pair.first == "LogTime") {
						data.at(pair.first).push_back(pair.second.at(0));
						pair.second.clear();
					}
					else {
						double value = std::accumulate(pair.second.begin(),pair.second.end(),0.0f) / nbRecord;
						data.at(pair.first).push_back(value);
						pair.second.clear();
					}
				}
				nbRecord = 0;
				nbData++;
			}

		}
		else if(c == ';') {

			if(parameterName.at(i) == "LogTime") {
				currentValue.erase(std::remove(currentValue.begin(), currentValue.end(), ':'), currentValue.end());
			}
			if(currentValue == "")
				currentValue = "0";

			std::replace(currentValue.begin(), currentValue.end(),',','.');
			currentData.at(parameterName.at(i)).push_back(std::stod(currentValue));
			currentValue.clear();
			++i;
		}
		else if(c != '\r') { // Windows new-line case '\r\n' instead of '\n'
			currentValue += c;
		}
	}

	if(nbRecord != 0) {
		for(auto &pair : currentData) {
			if(pair.first == "LogTime") {
				data.at(pair.first).push_back(pair.second.at(0));
				pair.second.clear();
			}
			else {
				double value = std::accumulate(pair.second.begin(),pair.second.end(),0.0f) / nbRecord;
				data.at(pair.first).push_back(value);
				pair.second.clear();
			}
		}
		nbRecord = 0;
		nbData++;
	}
}

double LogData::ReadValueFromData(std::string key, unsigned int index) {
	if(index < data.size())
		return data.at(key).at(index);
	return -1;
}

} /* namespace csv */

<|endoftext|>