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

/**
   \file pp2d.cpp

   Interactive trials with CHOMP for point vehicles moving
   holonomously in the plane.  There is a fixed start and goal
   configuration, and you can drag a circular obstacle around to see
   how the CHOMP algorithm reacts to that.  Some of the computations
   involve guesswork, for instance how best to compute velocities, so
   a simple first-order scheme has been used.  This appears to produce
   some unwanted drift of waypoints from the start configuration to
   the end configuration.  Parameters could also be tuned a bit
   better.  Other than that, it works pretty nicely.
*/

#include "gfx.hpp"
#include <iostream>
#include <vector>
#include <Eigen/Dense>
#include <stdlib.h>
#include <sys/time.h>
#include <err.h>
#include "chomp.hpp"

typedef Eigen::VectorXd Vector;
typedef Eigen::MatrixXd Matrix;
typedef Eigen::Isometry3d Transform;

using namespace std;

//////////////////////////////////////////////////
// trajectory etc

static size_t const cdim (2);	// dimension of config space
static size_t const nq (20);	// number of q stacked into xi
static size_t const obs_dim (3);	// x,y,R
Vector xi;			// the trajectory (q_1, q_2, ...q_n)
Vector qs;			// the start config a.k.a. q_0
Vector qe;			// the end config a.k.a. q_(n+1)
Matrix obs;     //A matrix containning all obstavles, each column is (x,y,R) of the obstacle

void add_obs(double px,double py, double radius){
  //conservativeResize is used. It's a costy operation, but hopefully will not
  // be done to often.
  obs.conservativeResize(obs_dim,obs.cols()+1);
  obs.block(0,obs.cols()-1,obs_dim,1)<<px,py,radius;
}
enum { PAUSE, STEP, RUN } state;

static size_t grabbed (-1);
static Vector grab_offset (3);

//////////////////////////////////////////////////
// robot (one per waypoint)

class Robot
{
public:
  EIGEN_MAKE_ALIGNED_OPERATOR_NEW

  Robot ()
    : position_ (Vector::Zero(2))
  {
  }

  void update (Vector const & position)
  {
    if (position.size() != 2) {
      errx (EXIT_FAILURE, "Robot::update(): position has %zu DOF (but needs 2)",
	    (size_t) position.size());
    }
    position_ = position;

  }

  void draw () const
  {
    // translucent disk for base
    gfx::set_pen (1.0, 0.7, 0.7, 0.7, 0.5);
    gfx::fill_arc (position_[0], position_[1], radius_, 0.0, 2.0 * M_PI);

    // thick circle outline for base
    gfx::set_pen (3.0, 0.2, 0.2, 0.2, 1.0);
    gfx::draw_arc (position_[0], position_[1], radius_, 0.0, 2.0 * M_PI);

  }

  static double const radius_;

  Vector position_;

};

double const Robot::radius_ (0.5);

Robot rstart;
Robot rend;
vector <Robot> robots;

//////////////////////////////////////////////////

static void update_robots ()
{
  rstart.update (qs);
  rend.update (qe);
  if (nq != robots.size()) {
    robots.resize (nq);
  }
  for (size_t ii (0); ii < nq; ++ii) {
    robots[ii].update (xi.block (ii * cdim, 0, cdim, 1));
  }

}

static void cb_step ()
{
  state = STEP;
}

static void cb_run ()
{ /*
  if (RUN == state) {
    state = PAUSE;
  }
  else {
    state = RUN;
  } */
}

static void cb_jumble ()
{ /*
  for (size_t ii (0); ii < xidim; ++ii) {
    xi[ii] = double (rand()) / (0.1 * numeric_limits<int>::max()) - 5.0;
  }
  update_robots();
  */
}

static void cb_idle ()
{

  if (state == PAUSE) return;
  // end of "the" CHOMP iteration
  //////////////////////////////////////////////////

  chomp::run_chomp(qs,qe,xi,obs);
  update_robots ();

}

static void cb_draw ()
{
  //////////////////////////////////////////////////
  // set bounds

  Vector bmin (qs);
  Vector bmax (qs);
  for (size_t ii (0); ii < 2; ++ii) {
    if (qe[ii] < bmin[ii]) {
      bmin[ii] = qe[ii];
    }
    if (qe[ii] > bmax[ii]) {
      bmax[ii] = qe[ii];
    }
    for (size_t jj (0); jj < nq; ++jj) {
      if (xi[ii + cdim * jj] < bmin[ii]) {
	bmin[ii] = xi[ii + cdim * jj];
      }
      if (xi[ii + cdim * jj] > bmax[ii]) {
	bmax[ii] = xi[ii + cdim * jj];
      }
    }
  }

  gfx::set_view (bmin[0] - 2.0, bmin[1] - 2.0, bmax[0] + 2.0, bmax[1] + 2.0);

  //////////////////////////////////////////////////
  // robots

  rstart.draw();
  for (size_t ii (0); ii < robots.size(); ++ii) {
    robots[ii].draw();
  }
  rend.draw();

  //////////////////////////////////////////////////
  // trj

  gfx::set_pen (1.0, 0.2, 0.2, 0.2, 1.0);
  gfx::draw_line (qs[0], qs[1], xi[0], xi[1]);
  for (size_t ii (1); ii < nq; ++ii) {
    gfx::draw_line (xi[(ii-1) * cdim], xi[(ii-1) * cdim + 1], xi[ii * cdim], xi[ii * cdim + 1]);
  }
  gfx::draw_line (xi[(nq-1) * cdim], xi[(nq-1) * cdim + 1], qe[0], qe[1]);

  gfx::set_pen (5.0, 0.8, 0.2, 0.2, 1.0);
  gfx::draw_point (qs[0], qs[1]);
  gfx::set_pen (5.0, 0.5, 0.5, 0.5, 1.0);
  for (size_t ii (0); ii < nq; ++ii) {
    gfx::draw_point (xi[ii * cdim], xi[ii * cdim + 1]);
  }
  gfx::set_pen (5.0, 0.2, 0.8, 0.2, 1.0);
  gfx::draw_point (qe[0], qe[1]);

  //////////////////////////////////////////////////
  // handles
  for (size_t ii = 0; ii< obs.cols(); ++ii) {
    gfx::set_pen (1.0, 0.0, 0.0, 1.0, 0.2);
    gfx::fill_arc (obs(0,ii), obs(1,ii), obs(2,ii), 0.0, 2.0 * M_PI);
  }

}

static void cb_mouse (double px, double py, int flags)
{
if ((flags & gfx::MOUSE_RELEASE) && (flags & gfx::MOUSE_B3)) {
  //add new obstacle at that location
  add_obs (px, py, 2.0);
}

  else if (flags & gfx::MOUSE_PRESS) {
    for (size_t ii=0; ii<obs.cols() ; ++ii) {
      Vector offset (obs.block(0,ii,2,1));
      offset[0] -= px;
      offset[1] -= py;
      if (offset.norm() <= obs(2,ii)) {
      grab_offset = offset;
      grabbed = ii;
      state=RUN;
      break;
      }
    }
  }
  else if (flags & gfx::MOUSE_DRAG) {
    if (-1 != grabbed) {
      obs(0,grabbed) = px+grab_offset(0);
      obs(1,grabbed) = py+grab_offset(1);
    }
  }
  else if (flags & gfx::MOUSE_RELEASE) {
    grabbed = -1;
    state = PAUSE;
  }

}

int main()
{
  /*

  update_robots();

  gfx::add_button ("jumble", cb_jumble);
  gfx::add_button ("step", cb_step);
  gfx::add_button ("run", cb_run);
  gfx::main ("chomp", cb_idle, cb_draw, cb_mouse);
*/

  qs.resize (cdim);
  qs << -5.0, -5.0;
  qe.resize (cdim);
  qe << 7.0, 7.0;
  add_obs (3.0, 0.0, 2.0);
  add_obs (0.0, 3.0, 2.0);

  chomp::run_chomp(qs,qe,xi,obs);
  update_robots ();
  state = PAUSE;
  gfx::main ("chomp", cb_idle, cb_draw, cb_mouse);
}
<commit_msg>fix typos<commit_after>/* Trials with CHOMP.
 *
 * Copyright (C) 2014 Roland Philippsen. All rights reserved.
 *
 * BSD license:
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the copyright holder nor the names of
 *    contributors to this software may be used to endorse or promote
 *    products derived from this software without specific prior written
 *    permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT
 * HOLDER OR THE CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/**
   \file pp2d.cpp

   Interactive trials with CHOMP for point vehicles moving
   holonomously in the plane.  There is a fixed start and goal
   configuration, and you can drag a circular obstacle around to see
   how the CHOMP algorithm reacts to that.  Some of the computations
   involve guesswork, for instance how best to compute velocities, so
   a simple first-order scheme has been used.  This appears to produce
   some unwanted drift of waypoints from the start configuration to
   the end configuration.  Parameters could also be tuned a bit
   better.  Other than that, it works pretty nicely.
*/

#include "gfx.hpp"
#include <iostream>
#include <vector>
#include <Eigen/Dense>
#include <stdlib.h>
#include <sys/time.h>
#include <err.h>
#include "chomp.hpp"

typedef Eigen::VectorXd Vector;
typedef Eigen::MatrixXd Matrix;
typedef Eigen::Isometry3d Transform;

using namespace std;

//////////////////////////////////////////////////
// trajectory etc

static size_t const cdim (2);	// dimension of config space
static size_t const nq (20);	// number of q stacked into xi
static size_t const obs_dim (3);	// x,y,R
Vector xi;			// the trajectory (q_1, q_2, ...q_n)
Vector qs;			// the start config a.k.a. q_0
Vector qe;			// the end config a.k.a. q_(n+1)
Matrix obs;     //A matrix containning all obstavles, each column is (x,y,R) of the obstacle

void add_obs(double px,double py, double radius){
  //conservativeResize is used. It's a costy operation, but hopefully will not
  // be done too often.
  obs.conservativeResize(obs_dim,obs.cols()+1);
  obs.block(0,obs.cols()-1,obs_dim,1)<<px,py,radius;
}
enum { PAUSE, STEP, RUN } state;

static size_t grabbed (-1);
static Vector grab_offset (3);

//////////////////////////////////////////////////
// robot (one per waypoint)

class Robot
{
public:
  EIGEN_MAKE_ALIGNED_OPERATOR_NEW

  Robot ()
    : position_ (Vector::Zero(2))
  {
  }

  void update (Vector const & position)
  {
    if (position.size() != 2) {
      errx (EXIT_FAILURE, "Robot::update(): position has %zu DOF (but needs 2)",
	    (size_t) position.size());
    }
    position_ = position;

  }

  void draw () const
  {
    // translucent disk for base
    gfx::set_pen (1.0, 0.7, 0.7, 0.7, 0.5);
    gfx::fill_arc (position_[0], position_[1], radius_, 0.0, 2.0 * M_PI);

    // thick circle outline for base
    gfx::set_pen (3.0, 0.2, 0.2, 0.2, 1.0);
    gfx::draw_arc (position_[0], position_[1], radius_, 0.0, 2.0 * M_PI);

  }

  static double const radius_;

  Vector position_;

};

double const Robot::radius_ (0.5);

Robot rstart;
Robot rend;
vector <Robot> robots;

//////////////////////////////////////////////////

static void update_robots ()
{
  rstart.update (qs);
  rend.update (qe);
  if (nq != robots.size()) {
    robots.resize (nq);
  }
  for (size_t ii (0); ii < nq; ++ii) {
    robots[ii].update (xi.block (ii * cdim, 0, cdim, 1));
  }

}

static void cb_step ()
{
  state = STEP;
}

static void cb_run ()
{ /*
  if (RUN == state) {
    state = PAUSE;
  }
  else {
    state = RUN;
  } */
}

static void cb_jumble ()
{ /*
  for (size_t ii (0); ii < xidim; ++ii) {
    xi[ii] = double (rand()) / (0.1 * numeric_limits<int>::max()) - 5.0;
  }
  update_robots();
  */
}

static void cb_idle ()
{

  if (state == PAUSE) return;
  // end of "the" CHOMP iteration
  //////////////////////////////////////////////////

  chomp::run_chomp(qs,qe,xi,obs);
  update_robots ();

}

static void cb_draw ()
{
  //////////////////////////////////////////////////
  // set bounds

  Vector bmin (qs);
  Vector bmax (qs);
  for (size_t ii (0); ii < 2; ++ii) {
    if (qe[ii] < bmin[ii]) {
      bmin[ii] = qe[ii];
    }
    if (qe[ii] > bmax[ii]) {
      bmax[ii] = qe[ii];
    }
    for (size_t jj (0); jj < nq; ++jj) {
      if (xi[ii + cdim * jj] < bmin[ii]) {
	bmin[ii] = xi[ii + cdim * jj];
      }
      if (xi[ii + cdim * jj] > bmax[ii]) {
	bmax[ii] = xi[ii + cdim * jj];
      }
    }
  }

  gfx::set_view (bmin[0] - 2.0, bmin[1] - 2.0, bmax[0] + 2.0, bmax[1] + 2.0);

  //////////////////////////////////////////////////
  // robots

  rstart.draw();
  for (size_t ii (0); ii < robots.size(); ++ii) {
    robots[ii].draw();
  }
  rend.draw();

  //////////////////////////////////////////////////
  // trj

  gfx::set_pen (1.0, 0.2, 0.2, 0.2, 1.0);
  gfx::draw_line (qs[0], qs[1], xi[0], xi[1]);
  for (size_t ii (1); ii < nq; ++ii) {
    gfx::draw_line (xi[(ii-1) * cdim], xi[(ii-1) * cdim + 1], xi[ii * cdim], xi[ii * cdim + 1]);
  }
  gfx::draw_line (xi[(nq-1) * cdim], xi[(nq-1) * cdim + 1], qe[0], qe[1]);

  gfx::set_pen (5.0, 0.8, 0.2, 0.2, 1.0);
  gfx::draw_point (qs[0], qs[1]);
  gfx::set_pen (5.0, 0.5, 0.5, 0.5, 1.0);
  for (size_t ii (0); ii < nq; ++ii) {
    gfx::draw_point (xi[ii * cdim], xi[ii * cdim + 1]);
  }
  gfx::set_pen (5.0, 0.2, 0.8, 0.2, 1.0);
  gfx::draw_point (qe[0], qe[1]);

  //////////////////////////////////////////////////
  // handles
  for (size_t ii = 0; ii< obs.cols(); ++ii) {
    gfx::set_pen (1.0, 0.0, 0.0, 1.0, 0.2);
    gfx::fill_arc (obs(0,ii), obs(1,ii), obs(2,ii), 0.0, 2.0 * M_PI);
  }

}

static void cb_mouse (double px, double py, int flags)
{
if ((flags & gfx::MOUSE_RELEASE) && (flags & gfx::MOUSE_B3)) {
  //add new obstacle at that location
  add_obs (px, py, 2.0);
}

  else if (flags & gfx::MOUSE_PRESS) {
    for (size_t ii=0; ii<obs.cols() ; ++ii) {
      Vector offset (obs.block(0,ii,2,1));
      offset[0] -= px;
      offset[1] -= py;
      if (offset.norm() <= obs(2,ii)) {
      grab_offset = offset;
      grabbed = ii;
      state=RUN;
      break;
      }
    }
  }
  else if (flags & gfx::MOUSE_DRAG) {
    if (-1 != grabbed) {
      obs(0,grabbed) = px+grab_offset(0);
      obs(1,grabbed) = py+grab_offset(1);
    }
  }
  else if (flags & gfx::MOUSE_RELEASE) {
    grabbed = -1;
    state = PAUSE;
  }

}

int main()
{
  /*

  update_robots();

  gfx::add_button ("jumble", cb_jumble);
  gfx::add_button ("step", cb_step);
  gfx::add_button ("run", cb_run);
  gfx::main ("chomp", cb_idle, cb_draw, cb_mouse);
*/

  qs.resize (cdim);
  qs << -5.0, -5.0;
  qe.resize (cdim);
  qe << 7.0, 7.0;
  add_obs (3.0, 0.0, 2.0);
  add_obs (0.0, 3.0, 2.0);

  chomp::run_chomp(qs,qe,xi,obs);
  update_robots ();
  state = PAUSE;
  gfx::main ("chomp", cb_idle, cb_draw, cb_mouse);
}
<|endoftext|>


<commit_before>

//#if ETH_JSONRPC && 1

#include <boost/test/unit_test.hpp>
#include <libdevcore/Log.h>
#include <libdevcore/CommonIO.h>
#include <libdevcore/CommonJS.h>
#include <libwebthree/WebThree.h>
#include <libethrpc/EthStubServer.h>
#include <jsonrpc/connectors/httpserver.h>
#include <jsonrpc/connectors/httpclient.h>
#include "JsonSpiritHeaders.h"
#include "ethstubclient.h"

using namespace std;
using namespace dev;
using namespace dev::eth;
namespace js = json_spirit;

namespace jsonrpc_tests {

string name = "Ethereum(++) tests";
string dbPath;
dev::WebThreeDirect web3(name, dbPath);

KeyPair us;
auto_ptr<EthStubServer> jsonrpcServer;
auto_ptr<EthStubClient> jsonrpcClient;

struct JsonrpcFixture  {
    JsonrpcFixture()
    {
        cnote << "setup jsonrpc";

        web3.setIdealPeerCount(5);

        us = KeyPair::create();
        jsonrpcServer = auto_ptr<EthStubServer>(new EthStubServer(new jsonrpc::HttpServer(8080), web3));
        jsonrpcServer->setKeys({us});
        jsonrpcServer->StartListening();

        jsonrpcClient = auto_ptr<EthStubClient>(new EthStubClient(new jsonrpc::HttpClient("http://localhost:8080")));
    }
    ~JsonrpcFixture()
    {
        cnote << "teardown jsonrpc";
    }
};

BOOST_GLOBAL_FIXTURE(JsonrpcFixture)

BOOST_AUTO_TEST_CASE(jsonrpc_balanceAt)
{

}

BOOST_AUTO_TEST_CASE(jsonrpc_block)
{
}

BOOST_AUTO_TEST_CASE(jsonrpc_call)
{
}

BOOST_AUTO_TEST_CASE(jsonrpc_coinbase)
{
    cnote << "Testing jsonrpc coinbase...";
    string coinbase = jsonrpcClient->coinbase();
    BOOST_CHECK_EQUAL(jsToAddress(coinbase), web3.ethereum()->address());
}

BOOST_AUTO_TEST_CASE(jsonrpc_countAt)
{
}

BOOST_AUTO_TEST_CASE(jsonrpc_defaultBlock)
{
    cnote << "Testing jsonrpc defaultBlock...";
    int defaultBlock = jsonrpcClient->defaultBlock();
    BOOST_CHECK_EQUAL(defaultBlock, web3.ethereum()->getDefault());
}

BOOST_AUTO_TEST_CASE(jsonrpc_fromAscii)
{
}

BOOST_AUTO_TEST_CASE(jsonrpc_fromFixed)
{
}

BOOST_AUTO_TEST_CASE(jsonrpc_gasPrice)
{
    cnote << "Testing jsonrpc gasPrice...";
    string gasPrice = jsonrpcClient->gasPrice();
    BOOST_CHECK_EQUAL(gasPrice, toJS(10 * dev::eth::szabo));
}

BOOST_AUTO_TEST_CASE(jsonrpc_isListening)
{
    //TODO
    cnote << "Testing jsonrpc isListening...";
}

BOOST_AUTO_TEST_CASE(jsonrpc_isMining)
{
    cnote << "Testing jsonrpc isMining...";

    web3.ethereum()->startMining();
    bool miningOn = jsonrpcClient->isMining();
    BOOST_CHECK_EQUAL(miningOn, web3.ethereum()->isMining());

    web3.ethereum()->stopMining();
    bool miningOff = jsonrpcClient->isMining();
    BOOST_CHECK_EQUAL(miningOff, web3.ethereum()->isMining());
}

BOOST_AUTO_TEST_CASE(jsonrpc_key)
{
    cnote << "Testing jsonrpc key...";
    Json::Value key = jsonrpcClient->key();
    BOOST_CHECK_EQUAL(key.isString(), true);
    BOOST_CHECK_EQUAL(jsToSecret(key.asString()), us.secret());
}

BOOST_AUTO_TEST_CASE(jsonrpc_keys)
{
    cnote << "Testing jsonrpc keys...";
    Json::Value keys = jsonrpcClient->keys();
    BOOST_CHECK_EQUAL(keys.isArray(), true);
    BOOST_CHECK_EQUAL(keys.size(),  1);
    BOOST_CHECK_EQUAL(jsToSecret(keys[0u].asString()) , us.secret());
}

BOOST_AUTO_TEST_CASE(jsonrpc_lll)
{
}

BOOST_AUTO_TEST_CASE(jsonrpc_messages)
{
}

BOOST_AUTO_TEST_CASE(jsonrpc_number)
{
    cnote << "Testing jsonrpc number...";
    int number = jsonrpcClient->number();
    BOOST_CHECK_EQUAL(number, web3.ethereum()->number() + 1);
}

BOOST_AUTO_TEST_CASE(jsonrpc_peerCount)
{
    cnote << "Testing jsonrpc peerCount...";
    //TODO
}

BOOST_AUTO_TEST_CASE(jsonrpc_secretToAddress)
{
    cnote << "Testing jsonrpc secretToAddress...";
    string address = jsonrpcClient->secretToAddress(toJS(us.secret()));
    BOOST_CHECK_EQUAL(jsToAddress(address), us.address());
}

BOOST_AUTO_TEST_CASE(jsonrpc_setListening)
{
    cnote << "Testing jsonrpc setListening...";
    //TODO
}

BOOST_AUTO_TEST_CASE(jsonrpc_setMining)
{
    cnote << "Testing jsonrpc setMining...";

    jsonrpcClient->setMining(true);
    BOOST_CHECK_EQUAL(web3.ethereum()->isMining(), true);

    jsonrpcClient->setMining(false);
    BOOST_CHECK_EQUAL(web3.ethereum()->isMining(), false);
}

BOOST_AUTO_TEST_CASE(jsonrpc_sha3)
{
    cnote << "Testing jsonrpc sha3...";
    string testString = "1234567890987654";
    string sha3 = jsonrpcClient->sha3(testString);
    BOOST_CHECK_EQUAL(jsToFixed<32>(sha3), dev::eth::sha3(jsToBytes(testString)));
}

BOOST_AUTO_TEST_CASE(jsonrpc_stateAt)
{

}

BOOST_AUTO_TEST_CASE(jsonrpc_toAscii)
{
    cnote << "Testing jsonrpc toAscii...";
    string testString = "1234567890987654";
    string ascii = jsonrpcClient->toAscii(testString);
    BOOST_CHECK_EQUAL(jsToBinary(testString), ascii);
    BOOST_CHECK_EQUAL(testString, jsFromBinary(ascii));     // failing!
}

BOOST_AUTO_TEST_CASE(jsonrpc_toDecimal)
{
    cnote << "Testing jsonrpc toDecimal...";
    string testString = "1234567890987654";
    string decimal = jsonrpcClient->toDecimal(testString);
    BOOST_CHECK_EQUAL(jsToDecimal(testString), decimal);
}

BOOST_AUTO_TEST_CASE(jsonrpc_toFixed)
{
    cnote << "Testing jsonrpc toFixed...";
    double testValue = 123567;
    string fixed = jsonrpcClient->toFixed(testValue);
    BOOST_CHECK_EQUAL(jsToFixed(testValue), fixed);
    BOOST_CHECK_EQUAL(testValue, jsFromFixed(fixed));
}

BOOST_AUTO_TEST_CASE(jsonrpc_transact)
{
}

BOOST_AUTO_TEST_CASE(jsonrpc_transaction)
{
}

BOOST_AUTO_TEST_CASE(jsonrpc_uncle)
{
}

BOOST_AUTO_TEST_CASE(jsonrpc_watch)
{
}

}

//#endif

<commit_msg>jsonrpc tests<commit_after>

//#if ETH_JSONRPC && 1

#include <boost/test/unit_test.hpp>
#include <libdevcore/Log.h>
#include <libdevcore/CommonIO.h>
#include <libdevcore/CommonJS.h>
#include <libwebthree/WebThree.h>
#include <libethrpc/EthStubServer.h>
#include <jsonrpc/connectors/httpserver.h>
#include <jsonrpc/connectors/httpclient.h>
#include "JsonSpiritHeaders.h"
#include "TestHelper.h"
#include "ethstubclient.h"

using namespace std;
using namespace dev;
using namespace dev::eth;
namespace js = json_spirit;

namespace jsonrpc_tests {

string name = "Ethereum(++) tests";
string dbPath;
dev::WebThreeDirect web3(name, dbPath, true);

std::vector<dev::KeyPair> keys = {KeyPair::create()};

auto_ptr<EthStubServer> jsonrpcServer;
auto_ptr<EthStubClient> jsonrpcClient;

struct JsonrpcFixture  {
    JsonrpcFixture()
    {
        cnote << "setup jsonrpc";

        web3.setIdealPeerCount(5);
        web3.ethereum()->setForceMining(true);
        jsonrpcServer = auto_ptr<EthStubServer>(new EthStubServer(new jsonrpc::HttpServer(8080), web3));
        jsonrpcServer->setKeys(keys);
        jsonrpcServer->StartListening();

        jsonrpcClient = auto_ptr<EthStubClient>(new EthStubClient(new jsonrpc::HttpClient("http://localhost:8080")));
    }
    ~JsonrpcFixture()
    {
        cnote << "teardown jsonrpc";
    }
};

BOOST_GLOBAL_FIXTURE(JsonrpcFixture)

BOOST_AUTO_TEST_CASE(jsonrpc_balanceAt)
{
    cnote << "Testing jsonrpc balanceAt...";
    dev::KeyPair pair = keys[0];
//    string balance = jsonrpcClient->balanceAt(toJS(pair.address()));

}

BOOST_AUTO_TEST_CASE(jsonrpc_block)
{
}

BOOST_AUTO_TEST_CASE(jsonrpc_call)
{
}

BOOST_AUTO_TEST_CASE(jsonrpc_coinbase)
{
    cnote << "Testing jsonrpc coinbase...";
    string coinbase = jsonrpcClient->coinbase();
    BOOST_CHECK_EQUAL(jsToAddress(coinbase), web3.ethereum()->address());
}

BOOST_AUTO_TEST_CASE(jsonrpc_countAt)
{
}

BOOST_AUTO_TEST_CASE(jsonrpc_defaultBlock)
{
    cnote << "Testing jsonrpc defaultBlock...";
    int defaultBlock = jsonrpcClient->defaultBlock();
    BOOST_CHECK_EQUAL(defaultBlock, web3.ethereum()->getDefault());
}

BOOST_AUTO_TEST_CASE(jsonrpc_fromAscii)
{
}

BOOST_AUTO_TEST_CASE(jsonrpc_fromFixed)
{
}

BOOST_AUTO_TEST_CASE(jsonrpc_gasPrice)
{
    cnote << "Testing jsonrpc gasPrice...";
    string gasPrice = jsonrpcClient->gasPrice();
    BOOST_CHECK_EQUAL(gasPrice, toJS(10 * dev::eth::szabo));
}

BOOST_AUTO_TEST_CASE(jsonrpc_isListening)
{
    //TODO
    cnote << "Testing jsonrpc isListening...";
}

BOOST_AUTO_TEST_CASE(jsonrpc_isMining)
{
    cnote << "Testing jsonrpc isMining...";

    web3.ethereum()->startMining();
    bool miningOn = jsonrpcClient->isMining();
    BOOST_CHECK_EQUAL(miningOn, web3.ethereum()->isMining());

    web3.ethereum()->stopMining();
    bool miningOff = jsonrpcClient->isMining();
    BOOST_CHECK_EQUAL(miningOff, web3.ethereum()->isMining());
}

BOOST_AUTO_TEST_CASE(jsonrpc_key)
{
    cnote << "Testing jsonrpc key...";
    string key = jsonrpcClient->key();
    BOOST_CHECK_EQUAL(jsToSecret(key), keys[0].secret());
}

BOOST_AUTO_TEST_CASE(jsonrpc_keys)
{
    cnote << "Testing jsonrpc keys...";
    Json::Value k = jsonrpcClient->keys();
    BOOST_CHECK_EQUAL(k.isArray(), true);
    BOOST_CHECK_EQUAL(k.size(),  keys.size());
    for (unsigned i = 0; i < k.size(); i++)
        BOOST_CHECK_EQUAL(jsToSecret(k[i].asString()) , keys[i].secret());
}

BOOST_AUTO_TEST_CASE(jsonrpc_lll)
{
}

BOOST_AUTO_TEST_CASE(jsonrpc_messages)
{
}

BOOST_AUTO_TEST_CASE(jsonrpc_number)
{
    cnote << "Testing jsonrpc number...";
    int number = jsonrpcClient->number();
    BOOST_CHECK_EQUAL(number, web3.ethereum()->number() + 1);
}

BOOST_AUTO_TEST_CASE(jsonrpc_number2)
{
    cnote << "Testing jsonrpc number2...";
    int number = jsonrpcClient->number();
    BOOST_CHECK_EQUAL(number, web3.ethereum()->number() + 1);
    dev::eth::mine(*(web3.ethereum()), 1);
    int numberAfter = jsonrpcClient->number();
    BOOST_CHECK_EQUAL(number + 1, numberAfter);
    BOOST_CHECK_EQUAL(numberAfter, web3.ethereum()->number() + 1);
}

BOOST_AUTO_TEST_CASE(jsonrpc_peerCount)
{
    cnote << "Testing jsonrpc peerCount...";
    //TODO
}

BOOST_AUTO_TEST_CASE(jsonrpc_secretToAddress)
{
    cnote << "Testing jsonrpc secretToAddress...";
    dev::KeyPair pair = dev::KeyPair::create();
    string address = jsonrpcClient->secretToAddress(toJS(pair.secret()));
    BOOST_CHECK_EQUAL(jsToAddress(address), pair.address());
}

BOOST_AUTO_TEST_CASE(jsonrpc_setListening)
{
    cnote << "Testing jsonrpc setListening...";
    //TODO
}

BOOST_AUTO_TEST_CASE(jsonrpc_setMining)
{
    cnote << "Testing jsonrpc setMining...";

    jsonrpcClient->setMining(true);
    BOOST_CHECK_EQUAL(web3.ethereum()->isMining(), true);

    jsonrpcClient->setMining(false);
    BOOST_CHECK_EQUAL(web3.ethereum()->isMining(), false);
}

BOOST_AUTO_TEST_CASE(jsonrpc_sha3)
{
    cnote << "Testing jsonrpc sha3...";
    string testString = "1234567890987654";
    string sha3 = jsonrpcClient->sha3(testString);
    BOOST_CHECK_EQUAL(jsToFixed<32>(sha3), dev::eth::sha3(jsToBytes(testString)));
}

BOOST_AUTO_TEST_CASE(jsonrpc_stateAt)
{

}

BOOST_AUTO_TEST_CASE(jsonrpc_toAscii)
{
    cnote << "Testing jsonrpc toAscii...";
    string testString = "1234567890987654";
    string ascii = jsonrpcClient->toAscii(testString);
    BOOST_CHECK_EQUAL(jsToBinary(testString), ascii);
    BOOST_CHECK_EQUAL(testString, jsFromBinary(ascii));     // failing!
}

BOOST_AUTO_TEST_CASE(jsonrpc_toDecimal)
{
    cnote << "Testing jsonrpc toDecimal...";
    string testString = "1234567890987654";
    string decimal = jsonrpcClient->toDecimal(testString);
    BOOST_CHECK_EQUAL(jsToDecimal(testString), decimal);
}

BOOST_AUTO_TEST_CASE(jsonrpc_toFixed)
{
    cnote << "Testing jsonrpc toFixed...";
    double testValue = 123567;
    string fixed = jsonrpcClient->toFixed(testValue);
    BOOST_CHECK_EQUAL(jsToFixed(testValue), fixed);
    BOOST_CHECK_EQUAL(testValue, jsFromFixed(fixed));
}

BOOST_AUTO_TEST_CASE(jsonrpc_transact)
{
}

BOOST_AUTO_TEST_CASE(jsonrpc_transaction)
{
}

BOOST_AUTO_TEST_CASE(jsonrpc_uncle)
{
}

BOOST_AUTO_TEST_CASE(jsonrpc_watch)
{

}

}

//#endif

<|endoftext|>


<commit_before>// ======================================================================== //
// Copyright 2009-2017 Intel Corporation                                    //
//                                                                          //
// 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.                                           //
// ======================================================================== //

#undef NDEBUG

// sg
#include "SceneGraph.h"
#include "sg/common/Texture2D.h"
#include "sg/geometry/TriangleMesh.h"

#define TINYOBJLOADER_IMPLEMENTATION  // define this in only *one* .cc
#include "../3rdParty/tiny_obj_loader.h"

#include <cstring>
#include <sstream>

namespace ospray {
  namespace sg {

    std::shared_ptr<Texture2D> loadTexture(const FileName &fullPath,
                                           const bool preferLinear = false)
    {
      std::shared_ptr<Texture2D> tex = Texture2D::load(fullPath, preferLinear);
      if (!tex)
        std::cout << "could not load texture " << fullPath.str() << " !\n";

      return tex;
    }

    void addTextureIfNeeded(Material &node,
                            const std::string &type,
                            const FileName &texName,
                            const FileName &containingPath,
                            bool preferLinear = false)
    {
      if (!texName.str().empty()) {
        auto tex = loadTexture(containingPath + texName, preferLinear);
        if (tex) {
          tex->setName(type);
          node.setChild(type, tex);
        }
      }
    }

    static inline float parseFloatString(std::string valueString)
    {
      std::stringstream valueStream(valueString);

      float value;
      valueStream >> value;

      return value;
    }

    static inline vec3f parseVec3fString(std::string valueString)
    {
      std::stringstream valueStream(valueString);

      vec3f value;
      valueStream >> value.x >> value.y >> value.z;

      return value;
    }

    static inline void parseParameterString(std::string typeAndValueString,
                                            std::string &paramType,
                                            ospcommon::utility::Any &paramValue)
    {
      std::stringstream typeAndValueStream(typeAndValueString);
      std::string paramValueString;
      getline(typeAndValueStream, paramValueString);

      std::vector<float> floats;
      std::stringstream valueStream(typeAndValueString);
      float val;
      while (valueStream >> val)
        floats.push_back(val);
      if (floats.size() == 1)
        paramType = "float";
      else if (floats.size() == 2)
        paramType = "vec2f";
      else if (floats.size() == 3)
        paramType = "vec3f";

      if (paramType == "float") {
        paramValue = parseFloatString(paramValueString);
      } else if (paramType == "vec3f") {
        paramValue = parseVec3fString(paramValueString);
      } else {
        // Unknown type.
        paramValue = typeAndValueString;
      }
    }

    static inline std::vector<std::shared_ptr<Material>> createSgMaterials(
        std::vector<tinyobj::material_t> &mats, const FileName &containingPath)
    {
      std::vector<std::shared_ptr<Material>> sgMaterials;

      for (auto &mat : mats) {
        auto matNodePtr = createNode(mat.name, "Material")->nodeAs<Material>();
        auto &matNode   = *matNodePtr;

        for (auto &param : mat.unknown_parameter) {
          if (param.first == "type") {
            matNode["type"] = param.second;
            std::cout << "Creating material node of type " << param.second
                      << std::endl;
          } else {
            std::string paramType;
            ospcommon::utility::Any paramValue;
            parseParameterString(param.second, paramType, paramValue);
            try {
              matNode.createChildWithValue(param.first, paramType, paramValue);
            } catch (const std::runtime_error &) {
              // NOTE(jda) - silently move on if parsed node type doesn't exist
            }
          }
        }

        matNode["d"]  = mat.dissolve;
        matNode["Ka"] = vec3f(mat.ambient[0], mat.ambient[1], mat.ambient[2]);
        matNode["Kd"] = vec3f(mat.diffuse[0], mat.diffuse[1], mat.diffuse[2]);
        matNode["Ks"] =
            vec3f(mat.specular[0], mat.specular[1], mat.specular[2]);

        addTextureIfNeeded(
            matNode, "map_Ka", mat.ambient_texname, containingPath);
        addTextureIfNeeded(
            matNode, "map_Kd", mat.diffuse_texname, containingPath);
        addTextureIfNeeded(
            matNode, "map_Ks", mat.specular_texname, containingPath);
        addTextureIfNeeded(matNode,
                           "map_Ns",
                           mat.specular_highlight_texname,
                           containingPath,
                           true);
        addTextureIfNeeded(
            matNode, "map_bump", mat.bump_texname, containingPath);
        addTextureIfNeeded(
            matNode, "map_d", mat.alpha_texname, containingPath, true);
        sgMaterials.push_back(matNodePtr);
      }

      return sgMaterials;
    }

    void importOBJ(const std::shared_ptr<Node> &world, const FileName &fileName)
    {
      tinyobj::attrib_t attrib;
      std::vector<tinyobj::shape_t> shapes;
      std::vector<tinyobj::material_t> materials;

      std::string err;
      auto containingPath = fileName.path().str() + '/';
      bool ret            = tinyobj::LoadObj(&attrib,
                                  &shapes,
                                  &materials,
                                  &err,
                                  fileName.c_str(),
                                  containingPath.c_str());

      if (!err.empty())
        std::cerr << "#ospsg: obj parsing warning(s)...\n" << err << std::endl;

      if (!ret) {
        std::cerr << "#ospsg: FATAL error parsing obj file, no geometry added"
                  << " to the scene!" << std::endl;
        return;
      }

      auto sgMaterials = createSgMaterials(materials, containingPath);

      std::string base_name = fileName.name() + '_';
      int shapeId           = 0;

      for (auto &shape : shapes) {
        for (int numVertsInFace : shape.mesh.num_face_vertices) {
          if (numVertsInFace != 3) {
            std::cerr << "Warning: more thant 3 verts in face!";
            PRINT(numVertsInFace);
          }
        }

        auto name = base_name + std::to_string(shapeId++) + '_' + shape.name;
        auto mesh = createNode(name, "TriangleMesh")->nodeAs<TriangleMesh>();

        auto v = createNode("vertex", "DataVector3f")->nodeAs<DataVector3f>();
        auto numSrcIndices = shape.mesh.indices.size();
        v->v.reserve(numSrcIndices);

        auto vi = createNode("index", "DataVector3i")->nodeAs<DataVector3i>();
        vi->v.reserve(numSrcIndices / 3);

        auto vn = createNode("normal", "DataVector3f")->nodeAs<DataVector3f>();
        vn->v.reserve(numSrcIndices);

        auto vt =
            createNode("texcoord", "DataVector2f")->nodeAs<DataVector2f>();
        vt->v.reserve(numSrcIndices);

        for (int i = 0; i < shape.mesh.indices.size(); i += 3) {
          auto idx0 = shape.mesh.indices[i + 0];
          auto idx1 = shape.mesh.indices[i + 1];
          auto idx2 = shape.mesh.indices[i + 2];

          auto prim = vec3i(i + 0, i + 1, i + 2);
          vi->push_back(prim);

          v->push_back(vec3f(attrib.vertices[idx0.vertex_index * 3 + 0],
                             attrib.vertices[idx0.vertex_index * 3 + 1],
                             attrib.vertices[idx0.vertex_index * 3 + 2]));
          v->push_back(vec3f(attrib.vertices[idx1.vertex_index * 3 + 0],
                             attrib.vertices[idx1.vertex_index * 3 + 1],
                             attrib.vertices[idx1.vertex_index * 3 + 2]));
          v->push_back(vec3f(attrib.vertices[idx2.vertex_index * 3 + 0],
                             attrib.vertices[idx2.vertex_index * 3 + 1],
                             attrib.vertices[idx2.vertex_index * 3 + 2]));

          if (!attrib.normals.empty()) {
            vn->push_back(vec3f(attrib.normals[idx0.normal_index * 3 + 0],
                                attrib.normals[idx0.normal_index * 3 + 1],
                                attrib.normals[idx0.normal_index * 3 + 2]));
            vn->push_back(vec3f(attrib.normals[idx1.normal_index * 3 + 0],
                                attrib.normals[idx1.normal_index * 3 + 1],
                                attrib.normals[idx1.normal_index * 3 + 2]));
            vn->push_back(vec3f(attrib.normals[idx2.normal_index * 3 + 0],
                                attrib.normals[idx2.normal_index * 3 + 1],
                                attrib.normals[idx2.normal_index * 3 + 2]));
          }

          if (!attrib.texcoords.empty()) {
            vt->push_back(vec2f(attrib.texcoords[idx0.texcoord_index * 2 + 0],
                                attrib.texcoords[idx0.texcoord_index * 2 + 1]));
            vt->push_back(vec2f(attrib.texcoords[idx1.texcoord_index * 2 + 0],
                                attrib.texcoords[idx1.texcoord_index * 2 + 1]));
            vt->push_back(vec2f(attrib.texcoords[idx2.texcoord_index * 2 + 0],
                                attrib.texcoords[idx2.texcoord_index * 2 + 1]));
          }
        }

        mesh->add(v);
        mesh->add(vi);
        if (!vn->empty())
          mesh->add(vn);
        if (!vt->empty())
          mesh->add(vt);

        auto matIdx = shape.mesh.material_ids[0];
        if (!sgMaterials.empty()) {
          if (matIdx >= 0)
            mesh->setChild("material", sgMaterials[matIdx]);
          else
            mesh->setChild("material", sgMaterials[0]);
          mesh->child("material").setParent(mesh);
        }

        auto model = createNode(name + "_model", "Model");
        model->add(mesh);

        auto instance = createNode(name + "_instance", "Instance");
        instance->setChild("model", model);
        model->setParent(instance);

        world->add(instance);
      }
    }

  }  // ::ospray::sg
}  // ::ospray
<commit_msg>Fix OBJ importer<commit_after>// ======================================================================== //
// Copyright 2009-2017 Intel Corporation                                    //
//                                                                          //
// 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.                                           //
// ======================================================================== //

#undef NDEBUG

// sg
#include "SceneGraph.h"
#include "sg/common/Texture2D.h"
#include "sg/geometry/TriangleMesh.h"

#define TINYOBJLOADER_IMPLEMENTATION  // define this in only *one* .cc
#include "../3rdParty/tiny_obj_loader.h"

#include <cstring>
#include <sstream>

namespace ospray {
  namespace sg {

    std::shared_ptr<Texture2D> loadTexture(const FileName &fullPath,
                                           const bool preferLinear = false)
    {
      std::shared_ptr<Texture2D> tex = Texture2D::load(fullPath, preferLinear);
      if (!tex)
        std::cout << "could not load texture " << fullPath.str() << " !\n";

      return tex;
    }

    void addTextureIfNeeded(Material &node,
                            const std::string &type,
                            const FileName &texName,
                            const FileName &containingPath,
                            bool preferLinear = false)
    {
      if (!texName.str().empty()) {
        auto tex = loadTexture(containingPath + texName, preferLinear);
        if (tex) {
          tex->setName(type);
          node.setChild(type, tex);
        }
      }
    }

    static inline float parseFloatString(std::string valueString)
    {
      std::stringstream valueStream(valueString);

      float value;
      valueStream >> value;

      return value;
    }

    static inline vec3f parseVec3fString(std::string valueString)
    {
      std::stringstream valueStream(valueString);

      vec3f value;
      valueStream >> value.x >> value.y >> value.z;

      return value;
    }

    static inline void parseParameterString(std::string typeAndValueString,
                                            std::string &paramType,
                                            ospcommon::utility::Any &paramValue)
    {
      std::stringstream typeAndValueStream(typeAndValueString);
      std::string paramValueString;
      getline(typeAndValueStream, paramValueString);

      std::vector<float> floats;
      std::stringstream valueStream(typeAndValueString);
      float val;
      while (valueStream >> val)
        floats.push_back(val);
      if (floats.size() == 1)
        paramType = "float";
      else if (floats.size() == 2)
        paramType = "vec2f";
      else if (floats.size() == 3)
        paramType = "vec3f";

      if (paramType == "float") {
        paramValue = parseFloatString(paramValueString);
      } else if (paramType == "vec3f") {
        paramValue = parseVec3fString(paramValueString);
      } else {
        // Unknown type.
        paramValue = typeAndValueString;
      }
    }

    static inline std::vector<std::shared_ptr<Material>> createSgMaterials(
        std::vector<tinyobj::material_t> &mats, const FileName &containingPath)
    {
      std::vector<std::shared_ptr<Material>> sgMaterials;

      for (auto &mat : mats) {
        auto matNodePtr = createNode(mat.name, "Material")->nodeAs<Material>();
        auto &matNode   = *matNodePtr;

        for (auto &param : mat.unknown_parameter) {
          if (param.first == "type") {
            matNode["type"] = param.second;
            std::cout << "Creating material node of type " << param.second
                      << std::endl;
          } else {
            std::string paramType;
            ospcommon::utility::Any paramValue;
            parseParameterString(param.second, paramType, paramValue);
            try {
              matNode.createChildWithValue(param.first, paramType, paramValue);
            } catch (const std::runtime_error &) {
              // NOTE(jda) - silently move on if parsed node type doesn't exist
            }
          }
        }

        matNode["d"]  = mat.dissolve;
        matNode["Ka"] = vec3f(mat.ambient[0], mat.ambient[1], mat.ambient[2]);
        matNode["Kd"] = vec3f(mat.diffuse[0], mat.diffuse[1], mat.diffuse[2]);
        matNode["Ks"] =
            vec3f(mat.specular[0], mat.specular[1], mat.specular[2]);

        addTextureIfNeeded(
            matNode, "map_Ka", mat.ambient_texname, containingPath);
        addTextureIfNeeded(
            matNode, "map_Kd", mat.diffuse_texname, containingPath);
        addTextureIfNeeded(
            matNode, "map_Ks", mat.specular_texname, containingPath);
        addTextureIfNeeded(matNode,
                           "map_Ns",
                           mat.specular_highlight_texname,
                           containingPath,
                           true);
        addTextureIfNeeded(
            matNode, "map_bump", mat.bump_texname, containingPath);
        addTextureIfNeeded(
            matNode, "map_d", mat.alpha_texname, containingPath, true);
        sgMaterials.push_back(matNodePtr);
      }

      return sgMaterials;
    }

    void importOBJ(const std::shared_ptr<Node> &world, const FileName &fileName)
    {
      tinyobj::attrib_t attrib;
      std::vector<tinyobj::shape_t> shapes;
      std::vector<tinyobj::material_t> materials;

      std::string err;
      auto containingPath = fileName.path().str() + '/';
      bool ret            = tinyobj::LoadObj(&attrib,
                                  &shapes,
                                  &materials,
                                  &err,
                                  fileName.c_str(),
                                  containingPath.c_str());

      if (!err.empty())
        std::cerr << "#ospsg: obj parsing warning(s)...\n" << err << std::endl;

      if (!ret) {
        std::cerr << "#ospsg: FATAL error parsing obj file, no geometry added"
                  << " to the scene!" << std::endl;
        return;
      }

      auto sgMaterials = createSgMaterials(materials, containingPath);

      std::string base_name = fileName.name() + '_';
      int shapeId           = 0;

      for (auto &shape : shapes) {
        for (int numVertsInFace : shape.mesh.num_face_vertices) {
          if (numVertsInFace != 3) {
            std::cerr << "Warning: more thant 3 verts in face!";
            PRINT(numVertsInFace);
          }
        }

        auto name = base_name + std::to_string(shapeId++) + '_' + shape.name;
        auto mesh = createNode(name, "TriangleMesh")->nodeAs<TriangleMesh>();

        auto v = createNode("vertex", "DataVector3f")->nodeAs<DataVector3f>();
        auto numSrcIndices = shape.mesh.indices.size();
        v->v.reserve(numSrcIndices);

        auto vi = createNode("index", "DataVector3i")->nodeAs<DataVector3i>();
        vi->v.reserve(numSrcIndices / 3);

        auto vn = createNode("normal", "DataVector3f")->nodeAs<DataVector3f>();
        vn->v.reserve(numSrcIndices);

        auto vt =
            createNode("texcoord", "DataVector2f")->nodeAs<DataVector2f>();
        vt->v.reserve(numSrcIndices);

        for (int i = 0; i < shape.mesh.indices.size(); i += 3) {
          auto idx0 = shape.mesh.indices[i + 0];
          auto idx1 = shape.mesh.indices[i + 1];
          auto idx2 = shape.mesh.indices[i + 2];

          auto prim = vec3i(i + 0, i + 1, i + 2);
          vi->push_back(prim);

          v->push_back(vec3f(attrib.vertices[idx0.vertex_index * 3 + 0],
                             attrib.vertices[idx0.vertex_index * 3 + 1],
                             attrib.vertices[idx0.vertex_index * 3 + 2]));
          v->push_back(vec3f(attrib.vertices[idx1.vertex_index * 3 + 0],
                             attrib.vertices[idx1.vertex_index * 3 + 1],
                             attrib.vertices[idx1.vertex_index * 3 + 2]));
          v->push_back(vec3f(attrib.vertices[idx2.vertex_index * 3 + 0],
                             attrib.vertices[idx2.vertex_index * 3 + 1],
                             attrib.vertices[idx2.vertex_index * 3 + 2]));

          // TODO create missing normals&texcoords if only some faces have them
          if (!attrib.normals.empty() && idx0.normal_index != -1) {
            vn->push_back(vec3f(attrib.normals[idx0.normal_index * 3 + 0],
                                attrib.normals[idx0.normal_index * 3 + 1],
                                attrib.normals[idx0.normal_index * 3 + 2]));
            vn->push_back(vec3f(attrib.normals[idx1.normal_index * 3 + 0],
                                attrib.normals[idx1.normal_index * 3 + 1],
                                attrib.normals[idx1.normal_index * 3 + 2]));
            vn->push_back(vec3f(attrib.normals[idx2.normal_index * 3 + 0],
                                attrib.normals[idx2.normal_index * 3 + 1],
                                attrib.normals[idx2.normal_index * 3 + 2]));
          }

          if (!attrib.texcoords.empty() && idx0.texcoord_index != -1) {
            vt->push_back(vec2f(attrib.texcoords[idx0.texcoord_index * 2 + 0],
                                attrib.texcoords[idx0.texcoord_index * 2 + 1]));
            vt->push_back(vec2f(attrib.texcoords[idx1.texcoord_index * 2 + 0],
                                attrib.texcoords[idx1.texcoord_index * 2 + 1]));
            vt->push_back(vec2f(attrib.texcoords[idx2.texcoord_index * 2 + 0],
                                attrib.texcoords[idx2.texcoord_index * 2 + 1]));
          }
        }

        mesh->add(v);
        mesh->add(vi);
        if (!vn->empty())
          mesh->add(vn);
        if (!vt->empty())
          mesh->add(vt);

        auto matIdx = shape.mesh.material_ids[0];
        if (!sgMaterials.empty()) {
          if (matIdx >= 0)
            mesh->setChild("material", sgMaterials[matIdx]);
          else
            mesh->setChild("material", sgMaterials[0]);
          mesh->child("material").setParent(mesh);
        }

        auto model = createNode(name + "_model", "Model");
        model->add(mesh);

        auto instance = createNode(name + "_instance", "Instance");
        instance->setChild("model", model);
        model->setParent(instance);

        world->add(instance);
      }
    }

  }  // ::ospray::sg
}  // ::ospray
<|endoftext|>


<commit_before>/*
   Copyright (c) 2013, Sean Kasun
   All rights reserved.

   Redistribution and use in source and binary forms, with or without
   modification, are permitted provided that the following conditions are met:

 * Redistributions of source code must retain the above copyright notice, this
 list of conditions and the following disclaimer.

 * Redistributions in binary form must reproduce the above copyright notice,
 this list of conditions and the following disclaimer in the documentation
 and/or other materials provided with the distribution.

 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "chunkloader.h"
#include "chunkcache.h"
#include "chunk.h"

ChunkLoader::ChunkLoader(QString path,int x,int z,QCache<ChunkID,Chunk> &cache,QMutex &mutex) : path(path),x(x),z(z),cache(cache),mutex(mutex)
{
}
ChunkLoader::~ChunkLoader()
{
}

void ChunkLoader::run()
{
	int rx=x>>5;
	int rz=z>>5;

	QFile f(path+"/region/r."+QString::number(rx)+"."+QString::number(rz)+".mca");
	if (!f.open(QIODevice::ReadOnly)) //no chunks in this region
	{
		emit loaded(x,z);
		return;
	}
	//map header into memory
	uchar *header=f.map(0,4096);
	int offset=4*((x&31)+(z&31)*32);
	int coffset=(header[offset]<<16)|(header[offset+1]<<8)|header[offset+2];
	int numSectors=header[offset+3];
	f.unmap(header);

	if (coffset==0) // no chunk
	{
		f.close();
		emit loaded(x,z);
		return;
	}

	uchar *raw=f.map(coffset*4096,numSectors*4096);
	NBT nbt(raw);
	ChunkID id(x,z);
	mutex.lock();
	Chunk *chunk=cache[id];
	if (chunk)
		chunk->load(nbt);
	mutex.unlock();
	f.unmap(raw);
	f.close();

	emit loaded(x,z);
}
<commit_msg>Fixed crashes with malformed MCA files.<commit_after>/*
   Copyright (c) 2013, Sean Kasun
   All rights reserved.

   Redistribution and use in source and binary forms, with or without
   modification, are permitted provided that the following conditions are met:

 * Redistributions of source code must retain the above copyright notice, this
 list of conditions and the following disclaimer.

 * Redistributions in binary form must reproduce the above copyright notice,
 this list of conditions and the following disclaimer in the documentation
 and/or other materials provided with the distribution.

 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "chunkloader.h"
#include "chunkcache.h"
#include "chunk.h"

ChunkLoader::ChunkLoader(QString path,int x,int z,QCache<ChunkID,Chunk> &cache,QMutex &mutex) : path(path),x(x),z(z),cache(cache),mutex(mutex)
{
}
ChunkLoader::~ChunkLoader()
{
}

void ChunkLoader::run()
{
	int rx=x>>5;
	int rz=z>>5;

	QFile f(path+"/region/r."+QString::number(rx)+"."+QString::number(rz)+".mca");
	if (!f.open(QIODevice::ReadOnly)) //no chunks in this region
	{
		emit loaded(x,z);
		return;
	}
	//map header into memory
	uchar *header=f.map(0,4096);
	int offset=4*((x&31)+(z&31)*32);
	int coffset=(header[offset]<<16)|(header[offset+1]<<8)|header[offset+2];
	int numSectors=header[offset+3];
	f.unmap(header);

	if (coffset==0) // no chunk
	{
		f.close();
		emit loaded(x,z);
		return;
	}

	uchar *raw=f.map(coffset*4096,numSectors*4096);
	if (raw == NULL)
	{
		f.close();
		emit loaded(x, z);
		return;
	}
	NBT nbt(raw);
	ChunkID id(x,z);
	mutex.lock();
	Chunk *chunk=cache[id];
	if (chunk)
		chunk->load(nbt);
	mutex.unlock();
	f.unmap(raw);
	f.close();

	emit loaded(x,z);
}
<|endoftext|>


<commit_before>#include "QXmppRemoteMethod.h"
#include "QXmppClient.h"
#include "QXmppUtils.h"
#include "QXmppConfiguration.h"

#include <QEventLoop>
#include <QTimer>
#include <qdebug.h>

QXmppRemoteMethod::QXmppRemoteMethod(const QString &jid, const QString &method, const QVariantList &args, QXmppClient *client) :
        QObject(client), m_client(client)
{
    m_payload.setTo( jid );
    m_payload.setFrom( client->getConfiguration().jid() );
    m_payload.setInterface( method.section('.', 0, 0 ) );
    m_payload.setMethod( method.section('.', 1) );
    m_payload.setArguments( args );
}

QXmppRemoteMethodResult QXmppRemoteMethod::call( )
{
    QEventLoop loop(this);
    connect( this, SIGNAL(callDone()), &loop, SLOT(quit()));
    QTimer::singleShot(30000,&loop, SLOT(quit())); // Timeout incase the other end hangs...

    m_client->sendPacket( m_payload );

    loop.exec( QEventLoop::ExcludeUserInputEvents | QEventLoop::WaitForMoreEvents );
    return m_result;
}

void QXmppRemoteMethod::gotError( const QXmppRpcErrorIq &iq )
{
    if ( iq.id() == m_payload.id() )
    {
        m_result.hasError = true;
        m_result.errorMessage = iq.error().text();
        m_result.code = iq.error().type();
        emit callDone();
    }
}

void QXmppRemoteMethod::gotResult( const QXmppRpcResponseIq &iq )
{
    if ( iq.id() == m_payload.id() )
    {
        m_result.hasError = false;
        m_result.result = iq.values();
        emit callDone();
    }
}
<commit_msg>only expect a single reply value<commit_after>#include "QXmppRemoteMethod.h"
#include "QXmppClient.h"
#include "QXmppUtils.h"
#include "QXmppConfiguration.h"

#include <QEventLoop>
#include <QTimer>
#include <qdebug.h>

QXmppRemoteMethod::QXmppRemoteMethod(const QString &jid, const QString &method, const QVariantList &args, QXmppClient *client) :
        QObject(client), m_client(client)
{
    m_payload.setTo( jid );
    m_payload.setFrom( client->getConfiguration().jid() );
    m_payload.setInterface( method.section('.', 0, 0 ) );
    m_payload.setMethod( method.section('.', 1) );
    m_payload.setArguments( args );
}

QXmppRemoteMethodResult QXmppRemoteMethod::call( )
{
    QEventLoop loop(this);
    connect( this, SIGNAL(callDone()), &loop, SLOT(quit()));
    QTimer::singleShot(30000,&loop, SLOT(quit())); // Timeout incase the other end hangs...

    m_client->sendPacket( m_payload );

    loop.exec( QEventLoop::ExcludeUserInputEvents | QEventLoop::WaitForMoreEvents );
    return m_result;
}

void QXmppRemoteMethod::gotError( const QXmppRpcErrorIq &iq )
{
    if ( iq.id() == m_payload.id() )
    {
        m_result.hasError = true;
        m_result.errorMessage = iq.error().text();
        m_result.code = iq.error().type();
        emit callDone();
    }
}

void QXmppRemoteMethod::gotResult( const QXmppRpcResponseIq &iq )
{
    if ( iq.id() == m_payload.id() )
    {
        m_result.hasError = false;
        // FIXME: we don't handle multiple responses
        m_result.result = iq.values().first();
        emit callDone();
    }
}
<|endoftext|>


<commit_before>//
// texture.cpp
// Copyright (c) 2015 Adam Ransom
//

#include <OpenGL/gl3.h>
#include "texture.h"
#include "exception.h"

namespace BarelyGL {
Texture::Texture(const int width, const int height, GLenum format, const void* pixels)
  : width_(width)
  , height_(height)
  , format_(format)
{
  generate();
  bind();
  set_data(pixels);
  set_parameters();
  unbind();
}

void Texture::bind() const
{
  glBindTexture(GL_TEXTURE_2D, id_);
}

/*
 * Uploads the image data to graphics card
 */
void Texture::set_data(const void* data)
{
  glTexImage2D(GL_TEXTURE_2D,    // target of the texture
               0,                // mipmap level
               format_,          // internal color format
               width_,           // width of texture
               height_,          // height of texture
               0,                // border (must be 0)
               format_,          // format of texture being uploaded
               GL_UNSIGNED_BYTE, // type of pixel data being uploaded
               data              // pixel data
              );
}

void Texture::unbind() const
{
  glBindTexture(GL_TEXTURE_2D, 0);
}

void Texture::destroy()
{
  if (id_ != 0)
  {
    glDeleteTextures(1, &id_);
  }
}

//
// =============================
//        Private Methods
// =============================
//

void Texture::generate()
{
  glGenTextures(1, &id_);

  if (id_ == 0) throw Exception("Could not generate texture");
}

/*
 * Sets the texture paramaters. This makes sure the texture doesn't wrap and
 * uses a linear filter for resizing
 */
void Texture::set_parameters()
{
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
}

Texture::~Texture()
{
  destroy();
}
} // end of namespace BarelyGL
<commit_msg>internal and upload formats should be separate<commit_after>//
// texture.cpp
// Copyright (c) 2015 Adam Ransom
//

#include <OpenGL/gl3.h>
#include "texture.h"
#include "exception.h"

namespace BarelyGL {
Texture::Texture(const int width, const int height, GLenum format, const void* pixels)
  : width_(width)
  , height_(height)
  , format_(format)
{
  generate();
  bind();
  set_data(pixels);
  set_parameters();
  unbind();
}

void Texture::bind() const
{
  glBindTexture(GL_TEXTURE_2D, id_);
}

/*
 * Uploads the image data to graphics card
 */
void Texture::set_data(const void* data)
{
  glTexImage2D(GL_TEXTURE_2D,    // target of the texture
               0,                // mipmap level
               GL_RGBA8,         // internal color format
               width_,           // width of texture
               height_,          // height of texture
               0,                // border (must be 0)
               format_,          // format of texture being uploaded
               GL_UNSIGNED_BYTE, // type of pixel data being uploaded
               data              // pixel data
              );
}

void Texture::unbind() const
{
  glBindTexture(GL_TEXTURE_2D, 0);
}

void Texture::destroy()
{
  if (id_ != 0)
  {
    glDeleteTextures(1, &id_);
  }
}

//
// =============================
//        Private Methods
// =============================
//

void Texture::generate()
{
  glGenTextures(1, &id_);

  if (id_ == 0) throw Exception("Could not generate texture");
}

/*
 * Sets the texture paramaters. This makes sure the texture doesn't wrap and
 * uses a linear filter for resizing
 */
void Texture::set_parameters()
{
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
}

Texture::~Texture()
{
  destroy();
}
} // end of namespace BarelyGL
<|endoftext|>


<commit_before>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2014.  All rights reserved
 */
#ifndef _Stroika_Foundation_Memory_SharedPtr_inl_
#define _Stroika_Foundation_Memory_SharedPtr_inl_   1

/*
 ********************************************************************************
 ***************************** Implementation Details ***************************
 ********************************************************************************
 */
#include    "BlockAllocated.h"

#include    "../Execution/Exceptions.h"

namespace   Stroika {
    namespace   Foundation {
        namespace   Memory {

            /*
             ********************************************************************************
             ************ Private_::ReferenceCounterContainerType_ **************************
             ********************************************************************************
             */
            inline  Private_::ReferenceCounterContainerType_::ReferenceCounterContainerType_ ()
                : fCount (0)
                , fDeleteCounter_ (true)
            {
            }
            inline  Private_::ReferenceCounterContainerType_::ReferenceCounterContainerType_ (bool deleteCounter)
                : fCount (0)
                , fDeleteCounter_ (deleteCounter)
            {
            }

            namespace   Private_ {
                template    <typename   T>
                class   Envelope_ {
                private:
                    T*                              fPtr_;
                    ReferenceCounterContainerType_* fCountHolder_;
                public:
                    Envelope_ (T* ptr, ReferenceCounterContainerType_* countHolder )
                        : fPtr_ (ptr)
                        , fCountHolder_ (countHolder)
                    {
                        Require ((fPtr_ == nullptr) == (fCountHolder_ == nullptr));
                    }
                    template    <typename T2>
                    inline  Envelope_ (Envelope_<T2>&& from) noexcept
                :
                    fPtr_ (from.GetPtr ())
                    , fCountHolder_ (from.fCountHolder_)
                    {
                        from.fPtr_ = nullptr;
                        from.fCountHolder_ = nullptr;
                    }
                    template    <typename T2>
                    inline  Envelope_ (const Envelope_<T2>& from) noexcept
                :
                    fPtr_ (from.GetPtr ())
                    , fCountHolder_ (from.fCountHolder_)
                    {
                    }
                    template <typename T2>
                    inline  Envelope_ (const Envelope_<T2>& from, T* newP) noexcept
                :
                    fPtr_ (newP)
                    , fCountHolder_ (from.fCountHolder_)
                    {
                        // reason for this is for dynamic cast. We allow replacing the P with a newP, but the
                        // actual ptr cannot change, and this assert check automatically converts pointers to
                        // a common base pointer type
                        Require (newP == from.GetPtr ());
                    }
                    inline  T*      GetPtr () const noexcept
                    {
                        return fPtr_;
                    }
                    inline  void    SetPtr (T* p) noexcept {
                        fPtr_ = p;
                    }
                    inline  SharedPtrBase::ReferenceCountType CurrentRefCount () const noexcept
                    {
                        return fCountHolder_ == nullptr ? 0 : fCountHolder_->fCount.load ();
                    }
                    inline  void    Increment () noexcept {
                        RequireNotNull (fCountHolder_);
                        fCountHolder_->fCount++;
                    }
                    inline  bool    Decrement () noexcept {
                        Require (CurrentRefCount () > 0);
                        if (--fCountHolder_->fCount == 0)
                        {
                            return true;
                        }
                        return false;
                    }
                    inline  void    DoDeleteCounter () noexcept {
                        RequireNotNull (fCountHolder_);
                        if (fCountHolder_->fDeleteCounter_)
                        {
                            ManuallyBlockAllocated<ReferenceCounterContainerType_>::Delete (fCountHolder_);
                        }
                        fCountHolder_ = nullptr;
                    }

                private:
                    template    <typename T2>
                    friend  class   Envelope_;
                };
            }

            /*
             ********************************************************************************
             ********************************** SharedPtr<T> ********************************
             ********************************************************************************
             */
            template    <typename T>
            inline  SharedPtr<T>::SharedPtr () noexcept
:
            fEnvelope_ (nullptr, nullptr)
            {
            }
            template    <typename T>
            inline  SharedPtr<T>::SharedPtr (nullptr_t) noexcept
:
            fEnvelope_ (nullptr, nullptr)
            {
            }
            template    <typename T>
            inline  SharedPtr<T>::SharedPtr (T* from)
                : fEnvelope_ (mkEnvelope_ (from))
            {
                Assert (fEnvelope_.GetPtr () == from);
                if (from != nullptr) {
                    // NB: the fEnvelope_.CurrentRefCount () USUALLY == 0, but not necessarily, if the refcount is stored
                    // in the 'from' - (see SharedPtrBase) - in which case the refcount might already be larger.
                    fEnvelope_.Increment ();
                }
            }
            template    <typename T>
            inline  SharedPtr<T>::SharedPtr (const Envelope_& from) noexcept
:
            fEnvelope_ (from)
            {
                if (fEnvelope_.GetPtr () != nullptr) {
                    fEnvelope_.Increment ();
                }
            }
            template    <typename T>
            inline  SharedPtr<T>::SharedPtr (const SharedPtr<T>& from) noexcept
:
            fEnvelope_ (from.fEnvelope_)
            {
                if (fEnvelope_.GetPtr () != nullptr) {
                    fEnvelope_.Increment ();
                }
            }
            template    <typename T>
            inline  SharedPtr<T>::SharedPtr (SharedPtr<T>&& from) noexcept
:
            fEnvelope_ (move (from.fEnvelope_))
            {
                // no need to increment refcount here because the entire envelope moved from from to this, and so total counts same
            }
            template    <typename T>
            template    <typename T2>
            SharedPtr<T>::SharedPtr (const SharedPtr<T2>& from) noexcept
:
            fEnvelope_ (from.fEnvelope_)
            {
                if (fEnvelope_.GetPtr () != nullptr) {
                    fEnvelope_.Increment ();
                }
            }
            template    <typename T>
            template    <typename T2>
            typename SharedPtr<T>::Envelope_    SharedPtr<T>::mkEnvelope_ (T2* from, typename enable_if<is_convertible<T2*, Private_::ReferenceCounterContainerType_*>::value >::type*)
            {
                if (from == nullptr) {
                    return  Envelope_ (nullptr, nullptr);
                }
                else {
                    from->fPtr_ = from;
                    //Assert (from == fromCnt);
                    return  Envelope_ (from, from);
                }
            }
            template    <typename T>
            template    <typename T2>
            typename SharedPtr<T>::Envelope_    SharedPtr<T>::mkEnvelope_ (T2* from, typename enable_if < !is_convertible<T2*, Private_::ReferenceCounterContainerType_*>::value >::type*)
            {
                return  Envelope_ (from, from == nullptr ? nullptr : ManuallyBlockAllocated<Private_::ReferenceCounterContainerType_>::New ());
            }
            template    <typename T>
            inline  SharedPtr<T>& SharedPtr<T>::operator= (const SharedPtr<T>& rhs) noexcept {
                if (rhs.fEnvelope_.GetPtr () != fEnvelope_.GetPtr ())
                {
                    if (fEnvelope_.GetPtr () != nullptr) {
                        if (fEnvelope_.Decrement ()) {
                            fEnvelope_.DoDeleteCounter ();
                            delete fEnvelope_.GetPtr ();
                            fEnvelope_.SetPtr (nullptr);
                        }
                    }
                    fEnvelope_ = rhs.fEnvelope_;
                    if (fEnvelope_.GetPtr () != nullptr) {
                        Assert (fEnvelope_.CurrentRefCount () > 0);
                        fEnvelope_.Increment ();
                    }
                }
                return *this;
            }
            template    <typename T>
            inline  SharedPtr<T>::~SharedPtr ()
            {
                if (fEnvelope_.GetPtr () != nullptr) {
                    if (fEnvelope_.Decrement ()) {
                        fEnvelope_.DoDeleteCounter ();
                        delete fEnvelope_.GetPtr ();
                    }
                }
            }
            template    <typename T>
            inline  bool    SharedPtr<T>::IsNull () const noexcept
            {
                return fEnvelope_.GetPtr () == nullptr;
            }
            template    <typename T>
            inline  T&  SharedPtr<T>::GetRep () const noexcept
            {
                RequireNotNull (fEnvelope_.GetPtr ());
                Assert (fEnvelope_.CurrentRefCount () > 0);
                return *fEnvelope_.GetPtr ();
            }
            template    <typename T>
            inline  T* SharedPtr<T>::operator-> () const noexcept
            {
                return &GetRep ();
            }
            template    <typename T>
            inline  T& SharedPtr<T>::operator* () const noexcept
            {
                return GetRep ();
            }
            template    <typename T>
            inline  SharedPtr<T>::operator T* () const noexcept
            {
                return fEnvelope_.GetPtr ();
            }
            template    <typename T>
            inline  T*  SharedPtr<T>::get () const noexcept
            {
                return fEnvelope_.GetPtr ();
            }
            template    <typename T>
            inline  void    SharedPtr<T>::release () noexcept {
                *this = SharedPtr<T> (nullptr);
            }
            template    <typename T>
            inline  void    SharedPtr<T>::clear () noexcept {
                release ();
            }
            template    <typename T>
            inline  void    SharedPtr<T>::reset (T* p)
            {
                if (fEnvelope_.GetPtr () != p) {
                    *this = SharedPtr<T> (p);
                }
            }
            template    <typename T>
            template    <typename T2>
            inline  SharedPtr<T2> SharedPtr<T>::Dynamic_Cast () const  noexcept
            {
                return SharedPtr<T2> (typename SharedPtr<T2>::Envelope_ (fEnvelope_, dynamic_cast<T2*> (get ())));
            }
            template    <typename T>
            inline  typename SharedPtr<T>::ReferenceCountType   SharedPtr<T>::CurrentRefCount () const noexcept
            {
                return fEnvelope_.CurrentRefCount ();
            }
            template    <typename T>
            inline  typename SharedPtr<T>::ReferenceCountType   SharedPtr<T>::use_count () const noexcept
            {
                return fEnvelope_.CurrentRefCount ();
            }
            template    <typename T>
            inline  bool    SharedPtr<T>::IsUnique () const noexcept
            {
                return fEnvelope_.CurrentRefCount () == 1;
            }
            template    <typename T>
            inline  bool    SharedPtr<T>::unique () const noexcept
            {
                // respect the stl-ish names
                return IsUnique ();
            }
            template    <typename T>
            inline  bool    SharedPtr<T>::operator< (const SharedPtr<T>& rhs) const noexcept
            {
                // not technically legal to compare pointers this way, but its is legal to convert to int, and then compare, and
                // this does the same thing...
                //      -- LGP 2009-01-11
                return fEnvelope_.GetPtr () < rhs.fEnvelope_.GetPtr ();
            }
            template    <typename T>
            inline  bool    SharedPtr<T>::operator<= (const SharedPtr<T>& rhs) const noexcept
            {
                // not technically legal to compare pointers this way, but its is legal to convert to int, and then compare, and
                // this does the same thing...
                //      -- LGP 2009-01-11
                return fEnvelope_.GetPtr () <= rhs.fEnvelope_.GetPtr ();
            }
            template    <typename T>
            inline  bool    SharedPtr<T>::operator> (const SharedPtr<T>& rhs) const noexcept
            {
                // not technically legal to compare pointers this way, but its is legal to convert to int, and then compare, and
                // this does the same thing...
                //      -- LGP 2009-01-11
                return fEnvelope_.GetPtr () > rhs.fEnvelope_.GetPtr ();
            }
            template    <typename T>
            inline  bool    SharedPtr<T>::operator>= (const SharedPtr<T>& rhs) const noexcept
            {
                // not technically legal to compare pointers this way, but its is legal to convert to int, and then compare, and
                // this does the same thing...
                //      -- LGP 2009-01-11
                return fEnvelope_.GetPtr () >= rhs.fEnvelope_.GetPtr ();
            }
            template    <typename T>
            inline  bool    SharedPtr<T>::operator== (const SharedPtr<T>& rhs) const noexcept
            {
                return fEnvelope_.GetPtr () == rhs.fEnvelope_.GetPtr ();
            }
            template    <typename T>
            inline  bool    SharedPtr<T>::operator!= (const SharedPtr<T>& rhs) const noexcept
            {
                return fEnvelope_.GetPtr () != rhs.fEnvelope_.GetPtr ();
            }

            /*
             ********************************************************************************
             ************************* enable_shared_from_this<T> ***************************
             ********************************************************************************
             */
            template    <typename   T>
            inline  enable_shared_from_this<T>::enable_shared_from_this ()
                : ReferenceCounterContainerType_ (false)
#if     qDebug
                // only initialized for assertion in shared_from_this()
                , fPtr_ (nullptr)
#endif
            {
            }
            template    <typename   T>
            inline  SharedPtr<T> enable_shared_from_this<T>::shared_from_this ()
            {
                /*
                 * The Constructor for SharedPtr<T> expects a T*. However, we don't have a T*. But recall,
                 * the ONLY legal way to use this enable_shared_from_this is:
                 *
                 *       struct  TTT : Memory::enable_shared_from_this<TTT> {
                 *           string x;
                 *           ....
                 *       };
                 *
                 *   and so if we have a legal pointer to enable_shared_from_this<T>, then it MUST also be castable to a pointer to T*!!!
                 */
                AssertNotNull (fPtr_);
                return (SharedPtr<T> (typename SharedPtr<T>::Envelope_ (fPtr_, this)));
            }

        }

        namespace   Execution {
            template    <typename T>
            inline  void    ThrowIfNull (const Memory::SharedPtr<T>& p)
            {
                if (p.get () == nullptr) {
                    Execution::DoThrow (bad_alloc (), "ThrowIfNull (SharedPtr<T> ()) - throwing bad_alloc ()");
                }
            }
        }

    }
}
namespace std {
    template    <class TO_TYPE_T,   class FROM_TYPE_T>
    inline  Stroika::Foundation::Memory::SharedPtr<TO_TYPE_T>   dynamic_pointer_cast (const Stroika::Foundation::Memory::SharedPtr<FROM_TYPE_T>& sp) noexcept {
        return sp.template Dynamic_Cast<TO_TYPE_T> ();
    }
}
#endif  /*_Stroika_Foundation_Memory_SharedPtr_inl_*/
<commit_msg>tweak SharedPtr<T>::release ()<commit_after>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2014.  All rights reserved
 */
#ifndef _Stroika_Foundation_Memory_SharedPtr_inl_
#define _Stroika_Foundation_Memory_SharedPtr_inl_   1

/*
 ********************************************************************************
 ***************************** Implementation Details ***************************
 ********************************************************************************
 */
#include    "BlockAllocated.h"

#include    "../Execution/Exceptions.h"

namespace   Stroika {
    namespace   Foundation {
        namespace   Memory {

            /*
             ********************************************************************************
             ************ Private_::ReferenceCounterContainerType_ **************************
             ********************************************************************************
             */
            inline  Private_::ReferenceCounterContainerType_::ReferenceCounterContainerType_ ()
                : fCount (0)
                , fDeleteCounter_ (true)
            {
            }
            inline  Private_::ReferenceCounterContainerType_::ReferenceCounterContainerType_ (bool deleteCounter)
                : fCount (0)
                , fDeleteCounter_ (deleteCounter)
            {
            }

            namespace   Private_ {
                template    <typename   T>
                class   Envelope_ {
                private:
                    T*                              fPtr_;
                    ReferenceCounterContainerType_* fCountHolder_;
                public:
                    Envelope_ (T* ptr, ReferenceCounterContainerType_* countHolder )
                        : fPtr_ (ptr)
                        , fCountHolder_ (countHolder)
                    {
                        Require ((fPtr_ == nullptr) == (fCountHolder_ == nullptr));
                    }
                    template    <typename T2>
                    inline  Envelope_ (Envelope_<T2>&& from) noexcept
                :
                    fPtr_ (from.GetPtr ())
                    , fCountHolder_ (from.fCountHolder_)
                    {
                        from.fPtr_ = nullptr;
                        from.fCountHolder_ = nullptr;
                    }
                    template    <typename T2>
                    inline  Envelope_ (const Envelope_<T2>& from) noexcept
                :
                    fPtr_ (from.GetPtr ())
                    , fCountHolder_ (from.fCountHolder_)
                    {
                    }
                    template <typename T2>
                    inline  Envelope_ (const Envelope_<T2>& from, T* newP) noexcept
                :
                    fPtr_ (newP)
                    , fCountHolder_ (from.fCountHolder_)
                    {
                        // reason for this is for dynamic cast. We allow replacing the P with a newP, but the
                        // actual ptr cannot change, and this assert check automatically converts pointers to
                        // a common base pointer type
                        Require (newP == from.GetPtr ());
                    }
                    inline  T*      GetPtr () const noexcept
                    {
                        return fPtr_;
                    }
                    inline  void    SetPtr (T* p) noexcept {
                        fPtr_ = p;
                    }
                    inline  SharedPtrBase::ReferenceCountType CurrentRefCount () const noexcept
                    {
                        return fCountHolder_ == nullptr ? 0 : fCountHolder_->fCount.load ();
                    }
                    inline  void    Increment () noexcept {
                        RequireNotNull (fCountHolder_);
                        fCountHolder_->fCount++;
                    }
                    inline  bool    Decrement () noexcept {
                        Require (CurrentRefCount () > 0);
                        if (--fCountHolder_->fCount == 0)
                        {
                            return true;
                        }
                        return false;
                    }
                    inline  void    DoDeleteCounter () noexcept {
                        RequireNotNull (fCountHolder_);
                        if (fCountHolder_->fDeleteCounter_)
                        {
                            ManuallyBlockAllocated<ReferenceCounterContainerType_>::Delete (fCountHolder_);
                        }
                        fCountHolder_ = nullptr;
                    }

                private:
                    template    <typename T2>
                    friend  class   Envelope_;
                };
            }

            /*
             ********************************************************************************
             ********************************** SharedPtr<T> ********************************
             ********************************************************************************
             */
            template    <typename T>
            inline  SharedPtr<T>::SharedPtr () noexcept
:
            fEnvelope_ (nullptr, nullptr)
            {
            }
            template    <typename T>
            inline  SharedPtr<T>::SharedPtr (nullptr_t) noexcept
:
            fEnvelope_ (nullptr, nullptr)
            {
            }
            template    <typename T>
            inline  SharedPtr<T>::SharedPtr (T* from)
                : fEnvelope_ (mkEnvelope_ (from))
            {
                Assert (fEnvelope_.GetPtr () == from);
                if (from != nullptr) {
                    // NB: the fEnvelope_.CurrentRefCount () USUALLY == 0, but not necessarily, if the refcount is stored
                    // in the 'from' - (see SharedPtrBase) - in which case the refcount might already be larger.
                    fEnvelope_.Increment ();
                }
            }
            template    <typename T>
            inline  SharedPtr<T>::SharedPtr (const Envelope_& from) noexcept
:
            fEnvelope_ (from)
            {
                if (fEnvelope_.GetPtr () != nullptr) {
                    fEnvelope_.Increment ();
                }
            }
            template    <typename T>
            inline  SharedPtr<T>::SharedPtr (const SharedPtr<T>& from) noexcept
:
            fEnvelope_ (from.fEnvelope_)
            {
                if (fEnvelope_.GetPtr () != nullptr) {
                    fEnvelope_.Increment ();
                }
            }
            template    <typename T>
            inline  SharedPtr<T>::SharedPtr (SharedPtr<T>&& from) noexcept
:
            fEnvelope_ (move (from.fEnvelope_))
            {
                // no need to increment refcount here because the entire envelope moved from from to this, and so total counts same
            }
            template    <typename T>
            template    <typename T2>
            SharedPtr<T>::SharedPtr (const SharedPtr<T2>& from) noexcept
:
            fEnvelope_ (from.fEnvelope_)
            {
                if (fEnvelope_.GetPtr () != nullptr) {
                    fEnvelope_.Increment ();
                }
            }
            template    <typename T>
            template    <typename T2>
            typename SharedPtr<T>::Envelope_    SharedPtr<T>::mkEnvelope_ (T2* from, typename enable_if<is_convertible<T2*, Private_::ReferenceCounterContainerType_*>::value >::type*)
            {
                if (from == nullptr) {
                    return  Envelope_ (nullptr, nullptr);
                }
                else {
                    from->fPtr_ = from;
                    //Assert (from == fromCnt);
                    return  Envelope_ (from, from);
                }
            }
            template    <typename T>
            template    <typename T2>
            typename SharedPtr<T>::Envelope_    SharedPtr<T>::mkEnvelope_ (T2* from, typename enable_if < !is_convertible<T2*, Private_::ReferenceCounterContainerType_*>::value >::type*)
            {
                return  Envelope_ (from, from == nullptr ? nullptr : ManuallyBlockAllocated<Private_::ReferenceCounterContainerType_>::New ());
            }
            template    <typename T>
            inline  SharedPtr<T>& SharedPtr<T>::operator= (const SharedPtr<T>& rhs) noexcept {
                if (rhs.fEnvelope_.GetPtr () != fEnvelope_.GetPtr ())
                {
                    if (fEnvelope_.GetPtr () != nullptr) {
                        if (fEnvelope_.Decrement ()) {
                            fEnvelope_.DoDeleteCounter ();
                            delete fEnvelope_.GetPtr ();
                            fEnvelope_.SetPtr (nullptr);
                        }
                    }
                    fEnvelope_ = rhs.fEnvelope_;
                    if (fEnvelope_.GetPtr () != nullptr) {
                        Assert (fEnvelope_.CurrentRefCount () > 0);
                        fEnvelope_.Increment ();
                    }
                }
                return *this;
            }
            template    <typename T>
            inline  SharedPtr<T>::~SharedPtr ()
            {
                if (fEnvelope_.GetPtr () != nullptr) {
                    if (fEnvelope_.Decrement ()) {
                        fEnvelope_.DoDeleteCounter ();
                        delete fEnvelope_.GetPtr ();
                    }
                }
            }
            template    <typename T>
            inline  bool    SharedPtr<T>::IsNull () const noexcept
            {
                return fEnvelope_.GetPtr () == nullptr;
            }
            template    <typename T>
            inline  T&  SharedPtr<T>::GetRep () const noexcept
            {
                RequireNotNull (fEnvelope_.GetPtr ());
                Assert (fEnvelope_.CurrentRefCount () > 0);
                return *fEnvelope_.GetPtr ();
            }
            template    <typename T>
            inline  T* SharedPtr<T>::operator-> () const noexcept
            {
                return &GetRep ();
            }
            template    <typename T>
            inline  T& SharedPtr<T>::operator* () const noexcept
            {
                return GetRep ();
            }
            template    <typename T>
            inline  SharedPtr<T>::operator T* () const noexcept
            {
                return fEnvelope_.GetPtr ();
            }
            template    <typename T>
            inline  T*  SharedPtr<T>::get () const noexcept
            {
                return fEnvelope_.GetPtr ();
            }
            template    <typename T>
            inline  void    SharedPtr<T>::release () noexcept {
                if (fEnvelope_.GetPtr () != nullptr)
                {
                    if (fEnvelope_.Decrement ()) {
                        fEnvelope_.DoDeleteCounter ();
                        delete fEnvelope_.GetPtr ();
                        fEnvelope_.SetPtr (nullptr);
                    }
                }
            }
            template    <typename T>
            inline  void    SharedPtr<T>::clear () noexcept {
                release ();
            }
            template    <typename T>
            inline  void    SharedPtr<T>::reset (T* p)
            {
                if (fEnvelope_.GetPtr () != p) {
                    *this = SharedPtr<T> (p);
                }
            }
            template    <typename T>
            template    <typename T2>
            inline  SharedPtr<T2> SharedPtr<T>::Dynamic_Cast () const  noexcept
            {
                return SharedPtr<T2> (typename SharedPtr<T2>::Envelope_ (fEnvelope_, dynamic_cast<T2*> (get ())));
            }
            template    <typename T>
            inline  typename SharedPtr<T>::ReferenceCountType   SharedPtr<T>::CurrentRefCount () const noexcept
            {
                return fEnvelope_.CurrentRefCount ();
            }
            template    <typename T>
            inline  typename SharedPtr<T>::ReferenceCountType   SharedPtr<T>::use_count () const noexcept
            {
                return fEnvelope_.CurrentRefCount ();
            }
            template    <typename T>
            inline  bool    SharedPtr<T>::IsUnique () const noexcept
            {
                return fEnvelope_.CurrentRefCount () == 1;
            }
            template    <typename T>
            inline  bool    SharedPtr<T>::unique () const noexcept
            {
                // respect the stl-ish names
                return IsUnique ();
            }
            template    <typename T>
            inline  bool    SharedPtr<T>::operator< (const SharedPtr<T>& rhs) const noexcept
            {
                // not technically legal to compare pointers this way, but its is legal to convert to int, and then compare, and
                // this does the same thing...
                //      -- LGP 2009-01-11
                return fEnvelope_.GetPtr () < rhs.fEnvelope_.GetPtr ();
            }
            template    <typename T>
            inline  bool    SharedPtr<T>::operator<= (const SharedPtr<T>& rhs) const noexcept
            {
                // not technically legal to compare pointers this way, but its is legal to convert to int, and then compare, and
                // this does the same thing...
                //      -- LGP 2009-01-11
                return fEnvelope_.GetPtr () <= rhs.fEnvelope_.GetPtr ();
            }
            template    <typename T>
            inline  bool    SharedPtr<T>::operator> (const SharedPtr<T>& rhs) const noexcept
            {
                // not technically legal to compare pointers this way, but its is legal to convert to int, and then compare, and
                // this does the same thing...
                //      -- LGP 2009-01-11
                return fEnvelope_.GetPtr () > rhs.fEnvelope_.GetPtr ();
            }
            template    <typename T>
            inline  bool    SharedPtr<T>::operator>= (const SharedPtr<T>& rhs) const noexcept
            {
                // not technically legal to compare pointers this way, but its is legal to convert to int, and then compare, and
                // this does the same thing...
                //      -- LGP 2009-01-11
                return fEnvelope_.GetPtr () >= rhs.fEnvelope_.GetPtr ();
            }
            template    <typename T>
            inline  bool    SharedPtr<T>::operator== (const SharedPtr<T>& rhs) const noexcept
            {
                return fEnvelope_.GetPtr () == rhs.fEnvelope_.GetPtr ();
            }
            template    <typename T>
            inline  bool    SharedPtr<T>::operator!= (const SharedPtr<T>& rhs) const noexcept
            {
                return fEnvelope_.GetPtr () != rhs.fEnvelope_.GetPtr ();
            }

            /*
             ********************************************************************************
             ************************* enable_shared_from_this<T> ***************************
             ********************************************************************************
             */
            template    <typename   T>
            inline  enable_shared_from_this<T>::enable_shared_from_this ()
                : ReferenceCounterContainerType_ (false)
#if     qDebug
                // only initialized for assertion in shared_from_this()
                , fPtr_ (nullptr)
#endif
            {
            }
            template    <typename   T>
            inline  SharedPtr<T> enable_shared_from_this<T>::shared_from_this ()
            {
                /*
                 * The Constructor for SharedPtr<T> expects a T*. However, we don't have a T*. But recall,
                 * the ONLY legal way to use this enable_shared_from_this is:
                 *
                 *       struct  TTT : Memory::enable_shared_from_this<TTT> {
                 *           string x;
                 *           ....
                 *       };
                 *
                 *   and so if we have a legal pointer to enable_shared_from_this<T>, then it MUST also be castable to a pointer to T*!!!
                 */
                AssertNotNull (fPtr_);
                return (SharedPtr<T> (typename SharedPtr<T>::Envelope_ (fPtr_, this)));
            }

        }

        namespace   Execution {
            template    <typename T>
            inline  void    ThrowIfNull (const Memory::SharedPtr<T>& p)
            {
                if (p.get () == nullptr) {
                    Execution::DoThrow (bad_alloc (), "ThrowIfNull (SharedPtr<T> ()) - throwing bad_alloc ()");
                }
            }
        }

    }
}
namespace std {
    template    <class TO_TYPE_T,   class FROM_TYPE_T>
    inline  Stroika::Foundation::Memory::SharedPtr<TO_TYPE_T>   dynamic_pointer_cast (const Stroika::Foundation::Memory::SharedPtr<FROM_TYPE_T>& sp) noexcept {
        return sp.template Dynamic_Cast<TO_TYPE_T> ();
    }
}
#endif  /*_Stroika_Foundation_Memory_SharedPtr_inl_*/
<|endoftext|>