<commit_before>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit (ITK)
  Module:    itkImageToImageAffineMeanSquaresGradientDescentRegistrationTest.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 2000 National Library of Medicine
All rights reserved.

See COPYRIGHT.txt for copyright details.

=========================================================================*/
#include "itkPhysicalImage.h"
#include "itkSimpleImageRegionIterator.h"
#include "itkImageToImageAffineMeanSquaresGradientDescentRegistration.h"

/**
 *  This test uses two 2D-Gaussians (standard deviation RegionSize/2)
 *  One is shifted by 7,3 pixels from the other.
 *  therefore the solution of the registration is |-7 -3|
 *  This test uses LevenbergMarquart Optimizer but
 *  conjugate gradient optimizer tolerances are also defined
 *  in the itkImageToImageAffineMeanSquaresGradientDescentRegistration.txx file
 *  (you need to change the type of the optimizer in the header file
 *  ie itkImageToImageAffineMeanSquaresGradientDescentRegistration.h)
 */

int main()
{

  /*Allocate Images*/
  typedef itk::PhysicalImage<unsigned char,2>           ReferenceType;
  typedef itk::PhysicalImage<unsigned char,2>           TargetType;

  typedef itk::ImageToImageAffineMeanSquaresGradientDescentRegistration<ReferenceType,TargetType> RegistrationType;

  ReferenceType::SizeType size = {{100,100}};
  ReferenceType::IndexType index = {{0,0}};
  ReferenceType::RegionType region;
  region.SetSize( size );
  region.SetIndex( index );

  ReferenceType::Pointer imgReference = ReferenceType::New();
  imgReference->SetLargestPossibleRegion( region );
  imgReference->SetBufferedRegion( region );
  imgReference->SetRequestedRegion( region );
  imgReference->Allocate();

  TargetType::Pointer imgTarget = TargetType::New();
  imgTarget->SetLargestPossibleRegion( region );
  imgTarget->SetBufferedRegion( region );
  imgTarget->SetRequestedRegion( region );
  imgTarget->Allocate();

  /* Fill images with a 2D gaussian*/
  typedef  itk::SimpleImageRegionIterator<ReferenceType> ReferenceIteratorType;

  typedef  itk::SimpleImageRegionIterator<TargetType> TargetIteratorType;

  itk::Point<double,2> center;
  center[0] = (double)region.GetSize()[0]/2.0;
  center[1] = (double)region.GetSize()[1]/2.0;

  const double s = (double)region.GetSize()[0]/2.0;

  itk::Point<double,2>  p;
  itk::Vector<double,2> d;

  /* Set the displacement */
  itk::Vector<double,2> displacement;
  displacement[0] = 7;
  displacement[1] = 3;

  ReferenceIteratorType ri(imgReference,region);
  TargetIteratorType ti(imgTarget,region);
  ri.Begin();
  while(!ri.IsAtEnd())
  {
    p[0] = ri.GetIndex()[0];
    p[1] = ri.GetIndex()[1];
    d = p-center;
    d += displacement;
    const double x = d[0];
    const double y = d[1];
    ri.Set( 200.0 * exp( - ( x*x + y*y )/(s*s) ) );
    ++ri;
  }

  ti.Begin();
  while(!ti.IsAtEnd())
  {
    p[0] = ti.GetIndex()[0];
    p[1] = ti.GetIndex()[1];
    d = p-center;
    const double x = d[0];
    const double y = d[1];
    ti.Set( 200.0 * exp( - ( x*x + y*y )/(s*s) ) );
    ++ti;
  }

  RegistrationType::Pointer registrationMethod = RegistrationType::New();

  registrationMethod->SetReference(imgReference);
  registrationMethod->SetTarget(imgTarget);
  registrationMethod->SetTranslationScale( 1e4 );

  registrationMethod->GetOptimizer()->SetLearningRate(0.01);
  registrationMethod->GetOptimizer()->SetNumberOfIterations(20);

  registrationMethod->StartRegistration();

  // get the results
  RegistrationType::ParametersType solution =
    registrationMethod->GetOptimizer()->GetCurrentPosition();

  std::cout << "Solution is: " << solution << std::endl;

  //
  // check results to see if it is within range
  //
  bool pass = true;
  double trueParameters[6] = { 1, 0, 0, 1, -7, -3 };
  for( unsigned int j = 0; j < 4; j++ )
    {
    if( vnl_math_abs( solution[j] - trueParameters[j] ) > 0.02 )
      pass = false;
    }
  for( unsigned int j = 4; j < 6; j++ )
    {
    if( vnl_math_abs( solution[j] - trueParameters[j] ) > 1.0 )
      pass = false;
    }

  if( !pass )
    {
    std::cout << "Test failed." << std::endl;
    return EXIT_FAILURE;
    }

  std::cout << "Test passed." << std::endl;
  return EXIT_SUCCESS;

}
<commit_msg>ERR: More iterations added. Test corrected for translation scale<commit_after>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit (ITK)
  Module:    itkImageToImageAffineMeanSquaresGradientDescentRegistrationTest.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 2000 National Library of Medicine
All rights reserved.

See COPYRIGHT.txt for copyright details.

=========================================================================*/
#include "itkPhysicalImage.h"
#include "itkSimpleImageRegionIterator.h"
#include "itkImageToImageAffineMeanSquaresGradientDescentRegistration.h"

/**
 *  This test uses two 2D-Gaussians (standard deviation RegionSize/2)
 *  One is shifted by 7,3 pixels from the other.
 *  therefore the solution of the registration is |-7 -3|
 *  This test uses LevenbergMarquart Optimizer but
 *  conjugate gradient optimizer tolerances are also defined
 *  in the itkImageToImageAffineMeanSquaresGradientDescentRegistration.txx file
 *  (you need to change the type of the optimizer in the header file
 *  ie itkImageToImageAffineMeanSquaresGradientDescentRegistration.h)
 */

int main()
{

  /*Allocate Images*/
  typedef itk::PhysicalImage<unsigned char,2>           ReferenceType;
  typedef itk::PhysicalImage<unsigned char,2>           TargetType;

  typedef itk::ImageToImageAffineMeanSquaresGradientDescentRegistration<ReferenceType,TargetType> RegistrationType;

  ReferenceType::SizeType size = {{100,100}};
  ReferenceType::IndexType index = {{0,0}};
  ReferenceType::RegionType region;
  region.SetSize( size );
  region.SetIndex( index );

  ReferenceType::Pointer imgReference = ReferenceType::New();
  imgReference->SetLargestPossibleRegion( region );
  imgReference->SetBufferedRegion( region );
  imgReference->SetRequestedRegion( region );
  imgReference->Allocate();

  TargetType::Pointer imgTarget = TargetType::New();
  imgTarget->SetLargestPossibleRegion( region );
  imgTarget->SetBufferedRegion( region );
  imgTarget->SetRequestedRegion( region );
  imgTarget->Allocate();

  /* Fill images with a 2D gaussian*/
  typedef  itk::SimpleImageRegionIterator<ReferenceType> ReferenceIteratorType;

  typedef  itk::SimpleImageRegionIterator<TargetType> TargetIteratorType;

  itk::Point<double,2> center;
  center[0] = (double)region.GetSize()[0]/2.0;
  center[1] = (double)region.GetSize()[1]/2.0;

  const double s = (double)region.GetSize()[0]/2.0;

  itk::Point<double,2>  p;
  itk::Vector<double,2> d;

  /* Set the displacement */
  itk::Vector<double,2> displacement;
  displacement[0] = 7;
  displacement[1] = 3;

  ReferenceIteratorType ri(imgReference,region);
  TargetIteratorType ti(imgTarget,region);
  ri.Begin();
  while(!ri.IsAtEnd())
  {
    p[0] = ri.GetIndex()[0];
    p[1] = ri.GetIndex()[1];
    d = p-center;
    d += displacement;
    const double x = d[0];
    const double y = d[1];
    ri.Set( 200.0 * exp( - ( x*x + y*y )/(s*s) ) );
    ++ri;
  }

  ti.Begin();
  while(!ti.IsAtEnd())
  {
    p[0] = ti.GetIndex()[0];
    p[1] = ti.GetIndex()[1];
    d = p-center;
    const double x = d[0];
    const double y = d[1];
    ti.Set( 200.0 * exp( - ( x*x + y*y )/(s*s) ) );
    ++ti;
  }

  RegistrationType::Pointer registrationMethod = RegistrationType::New();

  const double translationScale = 1e4;

  registrationMethod->SetReference(imgReference);
  registrationMethod->SetTarget(imgTarget);
  registrationMethod->SetTranslationScale( translationScale );

  registrationMethod->GetOptimizer()->SetLearningRate(0.01);
  registrationMethod->GetOptimizer()->SetNumberOfIterations(50);

  registrationMethod->StartRegistration();

  // get the results
  RegistrationType::ParametersType solution =
    registrationMethod->GetOptimizer()->GetCurrentPosition();

  std::cout << "Solution is: " << solution << std::endl;

  //
  // check results to see if it is within range
  //
  bool pass = true;
  double trueParameters[6] = { 1, 0, 0, 1, -7, -3 };
  for( unsigned int j = 0; j < 4; j++ )
    {
    if( vnl_math_abs( solution[j] - trueParameters[j] ) > 0.02 )
      pass = false;
    }
  for( unsigned int j = 4; j < 6; j++ )
    {
    if( vnl_math_abs( solution[j] * translationScale - trueParameters[j] ) > 1.0 )
      pass = false;
    }

  if( !pass )
    {
    std::cout << "Test failed." << std::endl;
    return EXIT_FAILURE;
    }

  std::cout << "Test passed." << std::endl;
  return EXIT_SUCCESS;

}
<|endoftext|>


<commit_before><commit_msg>Fix refracted objects drawing order (#2577)<commit_after><|endoftext|>


<commit_before>#include "Synchronizer.h"

#include "Connector.h"

using namespace ru::org::codingteam::styx;

Synchronizer::Synchronizer()
	: _state(SynchronizerState::NotConnected)
{
}

void Synchronizer::dispatchConnected(Connector &connector, WsaSocket &socket)
{
	_state = SynchronizerState::Handshake;
	connector.sendLogin(socket);
}

void Synchronizer::dispatchMessage(Connector &connector, WsaSocket &socket, const Message &message)
{
	switch (_state)
	{
	case SynchronizerState::Hashing:
		// TODO: Check current contact and message contact, invalidate some chunks if needed.
		break;
	case SynchronizerState::Messaging:
		connector.sendMessage(socket, message);
		break;
	}
}

void Synchronizer::dispatchMessage(Connector &connector, WsaSocket &socket, const LoginResult &message)
{
	if (!message.logged())
	{
		throw std::exception("Cannot log in");
	}

	switch (_state)
	{
	case SynchronizerState::Handshake:
		_state = SynchronizerState::Hashing;
		hashingStep(connector, socket);
		break;
	default:
		throw std::exception("Invalid synchronizer state");
	}
}

void Synchronizer::hashingStep(Connector &connector, WsaSocket &socket)
{
	// TODO: do single hashing step.
}<commit_msg>Add logging.<commit_after>#include "Synchronizer.h"

#include <boost/log/trivial.hpp>

#include "Connector.h"

using namespace ru::org::codingteam::styx;

Synchronizer::Synchronizer()
	: _state(SynchronizerState::NotConnected)
{
}

void Synchronizer::dispatchConnected(Connector &connector, WsaSocket &socket)
{
	_state = SynchronizerState::Handshake;
	connector.sendLogin(socket);
}

void Synchronizer::dispatchMessage(Connector &connector, WsaSocket &socket, const Message &message)
{
	switch (_state)
	{
	case SynchronizerState::Hashing:
		// TODO: Check current contact and message contact, invalidate some chunks if needed.
		break;
	case SynchronizerState::Messaging:
		connector.sendMessage(socket, message);
		break;
	}
}

void Synchronizer::dispatchMessage(Connector &connector, WsaSocket &socket, const LoginResult &message)
{
	if (!message.logged())
	{
		throw std::exception("Cannot log in");
	}

	switch (_state)
	{
	case SynchronizerState::Handshake:
		_state = SynchronizerState::Hashing;
		BOOST_LOG_TRIVIAL(info) << "Successfully logged in";
		hashingStep(connector, socket);
		break;
	default:
		throw std::exception("Invalid synchronizer state");
	}
}

void Synchronizer::hashingStep(Connector &connector, WsaSocket &socket)
{
	// TODO: do single hashing step.
}<|endoftext|>


<commit_before>#include <ncurses.h>

#include "../../../src/configuration.hh"
#include "../../../src/concat_c.hh"
#include "../../../src/contents.hh"
#include "../../../src/key_aliases.hh"
#include "../../../src/show_message.hh"
#include "../../vick-move/src/move.hh"

namespace vick {
namespace insert_mode {

struct insert_c : public change {
    const std::string track;
    const move_t y, x;
    insert_c(const std::string& track, move_t y, move_t x)
        : track(track)
        , y(y)
        , x(x)
    {
    }
    virtual bool is_overriding() override { return true; }
    virtual void undo(contents& contents) override
    {
        contents.cont[y] = contents.cont[y].substr(0, x) +
                           contents.cont[y].substr(x + track.size());
        contents.y = y;
        contents.x = x;
        if (contents.x && contents.x >= contents.cont[y].size())
            contents.x = contents.cont[y].size() - 1;
    }
    virtual void redo(contents& contents) override
    {
        contents.cont[y] =
            contents.cont[y].substr(0, x) + track + contents.cont[y].substr(x);
        contents.y = y;
        contents.x = x + track.size();
        if (contents.x >= contents.cont[y].size())
            contents.x = contents.cont[y].size() - 1;
    }
    virtual std::shared_ptr<change>
    regenerate(const contents& contents) const override
    {
        return std::make_shared<insert_c>(track, contents.y, contents.x);
    }
};

struct newline_c : public change {
    const std::string first, second;
    const int y;
    newline_c(const contents& contents)
        : first(contents.cont[contents.y].substr(0, contents.x))
        , second(contents.cont[contents.y].substr(contents.x))
        , y(contents.y)
    {
    }
    virtual bool is_overriding() { return true; }
    virtual void undo(contents& contents)
    {
        contents.cont[y] = first + second;
        contents.cont.erase(contents.cont.begin() + y + 1);
        contents.y = y;
        contents.x = first.size();
    }
    virtual void redo(contents& contents)
    {
        contents.cont[y] = first;
        contents.cont.insert(contents.cont.begin() + y + 1, second);
        contents.y = y + 1;
        contents.x = 0;
    }
    virtual std::shared_ptr<change> regenerate(const contents& contents) const
    {
        return std::make_shared<newline_c>(contents);
    }
};

boost::optional<std::shared_ptr<change> >
enter_insert_mode(contents& contents, boost::optional<int> pref)
{
    std::string track;
    auto x = contents.x;
    char ch;
    show_message("--INSERT--");
    contents.is_inserting = true;
    if (get_contents().refresh) {
        print_contents(get_contents());
        show_message("--INSERT--");
    }
    while ((ch = getch()) != QUIT_KEY) {
        if (ch == '\n') {
            std::vector<std::shared_ptr<change> > changes;
            changes.reserve(3);
            if (track.size())
                changes.push_back(
                    std::make_shared<insert_c>(track, contents.y, x));
            changes.push_back(std::make_shared<newline_c>(contents));
            changes.back()->redo(contents);
            auto recursed = enter_insert_mode(contents, pref);
            if (recursed) changes.push_back(recursed.get());
            return boost::optional<std::shared_ptr<change> >(
                std::make_shared<concat_c>(changes));
        }
        if (contents.x >= contents.cont[contents.y].size()) {
            contents.cont[contents.y].push_back(ch);
            contents.x = contents.cont[contents.y].size();
            track += ch;
        }
        else {
            contents.cont[contents.y].insert(contents.x, 1, ch);
            contents.x++;
            track += ch;
        }
        if (get_contents().refresh) {
            print_contents(get_contents());
            show_message("--INSERT--");
        }
    }
    contents.is_inserting = false;
    showing_message = false;
    return boost::optional<std::shared_ptr<change> >(
        std::make_shared<insert_c>(track, contents.y, x));
}

struct replace_c : public change {
    const std::string o, n;
    const move_t y, x;
    replace_c(const std::string& o, const std::string& n, move_t y, move_t x)
        : o(o)
        , n(n)
        , y(y)
        , x(x)
    {
    }
    virtual bool is_overriding() override { return true; }
    virtual void undo(contents& contents) override
    {
        contents.cont[y] = contents.cont[y].substr(0, x) + o +
                           contents.cont[y].substr(x + o.size());
    }
    virtual void redo(contents& contents) override
    {
        contents.cont[y] = contents.cont[y].substr(0, x) + n +
                           contents.cont[y].substr(x + n.size());
    }
    virtual std::shared_ptr<change>
    regenerate(const contents& contents) const override
    {
        return std::make_shared<replace_c>(
            contents.cont[contents.y].substr(contents.x, n.size()), n,
            contents.y, contents.x);
    }
};

boost::optional<std::shared_ptr<change> >
enter_replace_mode(contents& contents, boost::optional<int> pref)
{
    std::string o, n;
    auto x = contents.x;
    char ch;
    show_message("--INSERT (REPLACE)--");
    contents.is_inserting = true;
    if (get_contents().refresh) {
        print_contents(get_contents());
        show_message("--INSERT (REPLACE)--");
    }
    while ((ch = getch()) != QUIT_KEY) {
        if (ch == '\n') {
            o = contents.cont[contents.y][contents.x];
            std::vector<std::shared_ptr<change> > changes;
            changes.reserve(3);
            if (o.size())
                changes.push_back(
                    std::make_shared<replace_c>(o, n, contents.y, x));
            changes.push_back(std::make_shared<newline_c>(contents));
            changes.back()->redo(contents);
            auto recursed = enter_replace_mode(contents, pref);
            if (recursed) changes.push_back(recursed.get());
            return boost::optional<std::shared_ptr<change> >(
                std::make_shared<concat_c>(changes));
        }
        if (contents.x >= contents.cont[contents.y].size()) {
            contents.cont[contents.y].push_back(ch);
            contents.x = contents.cont[contents.y].size();
            n += ch;
        }
        else {
            o += contents.cont[contents.y][contents.x];
            n += ch;
            contents.cont[contents.y][contents.x] = ch;
            contents.x++;
        }
        if (get_contents().refresh) {
            print_contents(get_contents());
            show_message("--INSERT (REPLACE)--");
        }
    }
    contents.is_inserting = false;
    showing_message = false;
    return boost::optional<std::shared_ptr<change> >(
        std::make_shared<replace_c>(o, n, contents.y, x));
}

struct append_c : public change {
    const std::string track;
    const move_t y, x;
    append_c(const std::string& track, move_t y, move_t x)
        : track(track)
        , y(y)
        , x(x)
    {
    }
    virtual bool is_overriding() override { return true; }
    virtual void undo(contents& contents) override
    {
        contents.cont[y] = contents.cont[y].substr(0, x) +
                           contents.cont[y].substr(x + track.size());
        contents.y = y;
        contents.x = x;
        if (contents.x && contents.x >= contents.cont[y].size())
            contents.x = contents.cont[y].size() - 1;
    }
    virtual void redo(contents& contents) override
    {
        contents.cont[y] =
            contents.cont[y].substr(0, x) + track + contents.cont[y].substr(x);
        contents.y = y;
        contents.x = x + track.size();
        if (contents.x >= contents.cont[y].size())
            contents.x = contents.cont[y].size() - 1;
    }
    virtual std::shared_ptr<change>
    regenerate(const contents& contents) const override
    {
        return std::make_shared<append_c>(track, contents.y, contents.x + 1);
    }
};

boost::optional<std::shared_ptr<change> >
enter_append_mode(contents& contents, boost::optional<int> pref)
{
    if (contents.cont[contents.y].size() == 0)
        return enter_insert_mode(contents, pref);
    contents.x++;
    std::string track;
    auto x = contents.x;
    char ch;
    show_message("--INSERT--");
    contents.is_inserting = true;
    if (get_contents().refresh) {
        print_contents(get_contents());
        show_message("--INSERT--");
    }
    while ((ch = getch()) != QUIT_KEY) {
        if (ch == '\n') {
            std::vector<std::shared_ptr<change> > changes;
            changes.reserve(3);
            if (track.size())
                changes.push_back(
                    std::make_shared<insert_c>(track, contents.y, x));
            changes.push_back(std::make_shared<newline_c>(contents));
            changes.back()->redo(contents);
            auto recursed = enter_insert_mode(contents, pref);
            if (recursed) changes.push_back(recursed.get());
            return boost::optional<std::shared_ptr<change> >(
                std::make_shared<concat_c>(changes));
        }
        if (contents.x >= contents.cont[contents.y].size()) {
            contents.cont[contents.y].push_back(ch);
            contents.x = contents.cont[contents.y].size();
            track += ch;
        }
        else {
            contents.cont[contents.y].insert(contents.x, 1, ch);
            contents.x++;
            track += ch;
        }
        if (get_contents().refresh) {
            print_contents(get_contents());
            show_message("--INSERT--");
        }
    }
    contents.is_inserting = false;
    showing_message = false;
    return boost::optional<std::shared_ptr<change> >(
        std::make_shared<append_c>(track, contents.y, x));
}

}
}
<commit_msg>Remove miscellanious space at end of line<commit_after>#include <ncurses.h>

#include "../../../src/configuration.hh"
#include "../../../src/concat_c.hh"
#include "../../../src/contents.hh"
#include "../../../src/key_aliases.hh"
#include "../../../src/show_message.hh"
#include "../../vick-move/src/move.hh"

namespace vick {
namespace insert_mode {

struct insert_c : public change {
    const std::string track;
    const move_t y, x;
    insert_c(const std::string& track, move_t y, move_t x)
        : track(track)
        , y(y)
        , x(x)
    {
    }
    virtual bool is_overriding() override { return true; }
    virtual void undo(contents& contents) override
    {
        contents.cont[y] = contents.cont[y].substr(0, x) +
                           contents.cont[y].substr(x + track.size());
        contents.y = y;
        contents.x = x;
        if (contents.x && contents.x >= contents.cont[y].size())
            contents.x = contents.cont[y].size() - 1;
    }
    virtual void redo(contents& contents) override
    {
        contents.cont[y] =
            contents.cont[y].substr(0, x) + track + contents.cont[y].substr(x);
        contents.y = y;
        contents.x = x + track.size();
        if (contents.x >= contents.cont[y].size())
            contents.x = contents.cont[y].size() - 1;
    }
    virtual std::shared_ptr<change>
    regenerate(const contents& contents) const override
    {
        return std::make_shared<insert_c>(track, contents.y, contents.x);
    }
};

struct newline_c : public change {
    const std::string first, second;
    const int y;
    newline_c(const contents& contents)
        : first(contents.cont[contents.y].substr(0, contents.x))
        , second(contents.cont[contents.y].substr(contents.x))
        , y(contents.y)
    {
    }
    virtual bool is_overriding() { return true; }
    virtual void undo(contents& contents)
    {
        contents.cont[y] = first + second;
        contents.cont.erase(contents.cont.begin() + y + 1);
        contents.y = y;
        contents.x = first.size();
    }
    virtual void redo(contents& contents)
    {
        contents.cont[y] = first;
        contents.cont.insert(contents.cont.begin() + y + 1, second);
        contents.y = y + 1;
        contents.x = 0;
    }
    virtual std::shared_ptr<change> regenerate(const contents& contents) const
    {
        return std::make_shared<newline_c>(contents);
    }
};

boost::optional<std::shared_ptr<change> >
enter_insert_mode(contents& contents, boost::optional<int> pref)
{
    std::string track;
    auto x = contents.x;
    char ch;
    show_message("--INSERT--");
    contents.is_inserting = true;
    if (get_contents().refresh) {
        print_contents(get_contents());
        show_message("--INSERT--");
    }
    while ((ch = getch()) != QUIT_KEY) {
        if (ch == '\n') {
            std::vector<std::shared_ptr<change> > changes;
            changes.reserve(3);
            if (track.size())
                changes.push_back(
                    std::make_shared<insert_c>(track, contents.y, x));
            changes.push_back(std::make_shared<newline_c>(contents));
            changes.back()->redo(contents);
            auto recursed = enter_insert_mode(contents, pref);
            if (recursed) changes.push_back(recursed.get());
            return boost::optional<std::shared_ptr<change> >(
                std::make_shared<concat_c>(changes));
        }
        if (contents.x >= contents.cont[contents.y].size()) {
            contents.cont[contents.y].push_back(ch);
            contents.x = contents.cont[contents.y].size();
            track += ch;
        }
        else {
            contents.cont[contents.y].insert(contents.x, 1, ch);
            contents.x++;
            track += ch;
        }
        if (get_contents().refresh) {
            print_contents(get_contents());
            show_message("--INSERT--");
        }
    }
    contents.is_inserting = false;
    showing_message = false;
    return boost::optional<std::shared_ptr<change> >(
        std::make_shared<insert_c>(track, contents.y, x));
}

struct replace_c : public change {
    const std::string o, n;
    const move_t y, x;
    replace_c(const std::string& o, const std::string& n, move_t y, move_t x)
        : o(o)
        , n(n)
        , y(y)
        , x(x)
    {
    }
    virtual bool is_overriding() override { return true; }
    virtual void undo(contents& contents) override
    {
        contents.cont[y] = contents.cont[y].substr(0, x) + o +
                           contents.cont[y].substr(x + o.size());
    }
    virtual void redo(contents& contents) override
    {
        contents.cont[y] = contents.cont[y].substr(0, x) + n +
                           contents.cont[y].substr(x + n.size());
    }
    virtual std::shared_ptr<change>
    regenerate(const contents& contents) const override
    {
        return std::make_shared<replace_c>(
            contents.cont[contents.y].substr(contents.x, n.size()), n,
            contents.y, contents.x);
    }
};

boost::optional<std::shared_ptr<change> >
enter_replace_mode(contents& contents, boost::optional<int> pref)
{
    std::string o, n;
    auto x = contents.x;
    char ch;
    show_message("--INSERT (REPLACE)--");
    contents.is_inserting = true;
    if (get_contents().refresh) {
        print_contents(get_contents());
        show_message("--INSERT (REPLACE)--");
    }
    while ((ch = getch()) != QUIT_KEY) {
        if (ch == '\n') {
            o = contents.cont[contents.y][contents.x];
            std::vector<std::shared_ptr<change> > changes;
            changes.reserve(3);
            if (o.size())
                changes.push_back(
                    std::make_shared<replace_c>(o, n, contents.y, x));
            changes.push_back(std::make_shared<newline_c>(contents));
            changes.back()->redo(contents);
            auto recursed = enter_replace_mode(contents, pref);
            if (recursed) changes.push_back(recursed.get());
            return boost::optional<std::shared_ptr<change> >(
                std::make_shared<concat_c>(changes));
        }
        if (contents.x >= contents.cont[contents.y].size()) {
            contents.cont[contents.y].push_back(ch);
            contents.x = contents.cont[contents.y].size();
            n += ch;
        }
        else {
            o += contents.cont[contents.y][contents.x];
            n += ch;
            contents.cont[contents.y][contents.x] = ch;
            contents.x++;
        }
        if (get_contents().refresh) {
            print_contents(get_contents());
            show_message("--INSERT (REPLACE)--");
        }
    }
    contents.is_inserting = false;
    showing_message = false;
    return boost::optional<std::shared_ptr<change> >(
        std::make_shared<replace_c>(o, n, contents.y, x));
}

struct append_c : public change {
    const std::string track;
    const move_t y, x;
    append_c(const std::string& track, move_t y, move_t x)
        : track(track)
        , y(y)
        , x(x)
    {
    }
    virtual bool is_overriding() override { return true; }
    virtual void undo(contents& contents) override
    {
        contents.cont[y] = contents.cont[y].substr(0, x) +
                           contents.cont[y].substr(x + track.size());
        contents.y = y;
        contents.x = x;
        if (contents.x && contents.x >= contents.cont[y].size())
            contents.x = contents.cont[y].size() - 1;
    }
    virtual void redo(contents& contents) override
    {
        contents.cont[y] =
            contents.cont[y].substr(0, x) + track + contents.cont[y].substr(x);
        contents.y = y;
        contents.x = x + track.size();
        if (contents.x >= contents.cont[y].size())
            contents.x = contents.cont[y].size() - 1;
    }
    virtual std::shared_ptr<change>
    regenerate(const contents& contents) const override
    {
        return std::make_shared<append_c>(track, contents.y, contents.x + 1);
    }
};

boost::optional<std::shared_ptr<change> >
enter_append_mode(contents& contents, boost::optional<int> pref)
{
    if (contents.cont[contents.y].size() == 0)
        return enter_insert_mode(contents, pref);
    contents.x++;
    std::string track;
    auto x = contents.x;
    char ch;
    show_message("--INSERT--");
    contents.is_inserting = true;
    if (get_contents().refresh) {
        print_contents(get_contents());
        show_message("--INSERT--");
    }
    while ((ch = getch()) != QUIT_KEY) {
        if (ch == '\n') {
            std::vector<std::shared_ptr<change> > changes;
            changes.reserve(3);
            if (track.size())
                changes.push_back(
                    std::make_shared<insert_c>(track, contents.y, x));
            changes.push_back(std::make_shared<newline_c>(contents));
            changes.back()->redo(contents);
            auto recursed = enter_insert_mode(contents, pref);
            if (recursed) changes.push_back(recursed.get());
            return boost::optional<std::shared_ptr<change> >(
                std::make_shared<concat_c>(changes));
        }
        if (contents.x >= contents.cont[contents.y].size()) {
            contents.cont[contents.y].push_back(ch);
            contents.x = contents.cont[contents.y].size();
            track += ch;
        }
        else {
            contents.cont[contents.y].insert(contents.x, 1, ch);
            contents.x++;
            track += ch;
        }
        if (get_contents().refresh) {
            print_contents(get_contents());
            show_message("--INSERT--");
        }
    }
    contents.is_inserting = false;
    showing_message = false;
    return boost::optional<std::shared_ptr<change> >(
        std::make_shared<append_c>(track, contents.y, x));
}

}
}
<|endoftext|>


<commit_before>////////////////////////////////////////////////////////////////////////////
//
// Copyright 2016 Realm Inc.
//
// 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.
//
////////////////////////////////////////////////////////////////////////////

#include "global_notifier.hpp"

#include "admin_realm.hpp"

#include "impl/realm_coordinator.hpp"
#include "impl/transact_log_handler.hpp"
#include "object_schema.hpp"
#include "object_store.hpp"
#include "results.hpp"
#include "util/event_loop_dispatcher.hpp"
#include "util/event_loop_signal.hpp"

#include "sync/sync_manager.hpp"
#include "sync/sync_user.hpp"
#include "sync/sync_session.hpp"

#include <realm/lang_bind_helper.hpp>
#include <realm/util/file.hpp>
#include <realm/util/scope_exit.hpp>

#include <json.hpp>

#include <condition_variable>
#include <mutex>
#include <queue>
#include <stdexcept>
#include <unordered_map>
#include <utility>
#include <vector>

using namespace realm;
using namespace realm::_impl;

namespace realm {
static void to_json(nlohmann::json& j, VersionID v)
{
    j = {{"version", v.version}, {"index", v.index}};
}
static void from_json(nlohmann::json const& j, VersionID& v)
{
    v.version = j["version"];
    v.index = j["index"];
}

namespace sync {
static void to_json(nlohmann::json& j, ObjectID id)
{
    j = id.to_string();
}
static void from_json(nlohmann::json const& j, ObjectID& v)
{
    std::string str = j;
    v = ObjectID::from_string(str);
}
}
}

class GlobalNotifier::Impl final : public AdminRealmListener {
public:
    Impl(std::unique_ptr<Callback>,
         std::string local_root_dir, SyncConfig sync_config_template);

    util::Optional<ChangeNotification> next_changed_realm();
    void release_version(sync::ObjectID id, VersionID old_version, VersionID new_version);

public:
    void register_realm(sync::ObjectID, StringData virtual_path) override;
    void unregister_realm(sync::ObjectID, StringData) override;
    void error(std::exception_ptr err) override { m_target->error(err); }
    void download_complete() override { m_target->download_complete(); }

    const std::unique_ptr<util::Logger> m_logger;
    const std::unique_ptr<Callback> m_target;

    std::mutex m_work_queue_mutex;
    struct RealmToCalculate {
        sync::ObjectID realm_id;
        std::string virtual_path;
        std::shared_ptr<_impl::RealmCoordinator> coordinator;
        std::unique_ptr<Replication> history;
        std::unique_ptr<SharedGroup> shared_group;
        std::queue<VersionID> versions;
        bool pending_deletion = false;

        // constructor to make GCC 4.9 happy
        RealmToCalculate(sync::ObjectID realm_id, std::string virtual_path)
        : realm_id(realm_id)
        , virtual_path(std::move(virtual_path))
        {
        }
    };
    std::queue<RealmToCalculate*> m_work_queue;
    std::unordered_map<sync::ObjectID, RealmToCalculate> m_realms;

    struct SignalCallback {
        std::weak_ptr<Impl> notifier;
        void operator()()
        {
            if (auto alive = notifier.lock()) {
                GlobalNotifier notifier(alive);
                alive->m_target->realm_changed(&notifier);
            }
        }
    };

    std::shared_ptr<util::EventLoopSignal<SignalCallback>> m_signal;
};

GlobalNotifier::Impl::Impl(std::unique_ptr<Callback> async_target,
                           std::string local_root_dir, SyncConfig sync_config_template)
: AdminRealmListener(local_root_dir, std::move(sync_config_template))
, m_logger(SyncManager::shared().make_logger())
, m_target(std::move(async_target))
{
}

void GlobalNotifier::Impl::register_realm(sync::ObjectID id, StringData path) {
    auto info = &m_realms.emplace(id, RealmToCalculate{id, path}).first->second;
    m_realms.emplace(id, RealmToCalculate{id, path});

    auto strid = id.to_string();
    if (!m_target->realm_available(strid, path)) {
        m_logger->trace("Global notifier: not watching %1", path);
        return;
    }
    if (info->coordinator) {
        m_logger->trace("Global notifier: already watching %1", path);
        return;
    }

    m_logger->trace("Global notifier: watching %1", path);
    auto config = get_config(path, strid);
    info->coordinator = _impl::RealmCoordinator::get_coordinator(config);

    std::weak_ptr<Impl> weak_self = std::static_pointer_cast<Impl>(shared_from_this());
    info->coordinator->set_transaction_callback([=, weak_self = std::move(weak_self)](VersionID old_version, VersionID new_version) {
        auto self = weak_self.lock();
        if (!self)
            return;

        std::lock_guard<std::mutex> l(m_work_queue_mutex);
        if (info->shared_group) {
            m_logger->trace("Global notifier: sync transaction on (%1): Realm already open", info->virtual_path);
        }
        else {
            m_logger->trace("Global notifier: sync transaction on (%1): opening Realm", info->virtual_path);
            std::unique_ptr<Group> read_only_group;
            auto config = info->coordinator->get_config();
            config.force_sync_history = true; // FIXME: needed?
            config.schema = util::none;
            Realm::open_with_config(config, info->history, info->shared_group, read_only_group, nullptr);
            info->shared_group->begin_read(old_version);
        }
        info->versions.push(new_version);
        if (info->versions.size() == 1) {
            m_logger->trace("Global notifier: Signaling main thread");
            m_work_queue.push(info);
            m_signal->notify();
        }
    });
}

void GlobalNotifier::Impl::unregister_realm(sync::ObjectID id, StringData path) {
    auto realm = m_realms.find(id);
    if (realm == m_realms.end()) {
        m_logger->trace("Global notifier: unwatched Realm at (%1) was deleted", path);
        return;
    }

    std::lock_guard<std::mutex> l(m_work_queue_mutex);
    // Otherwise we need to defer closing the Realm until we're done with our current work.
    m_logger->trace("Global notifier: enqueuing deletion of Realm at (%1)", path);
    if (realm->second.coordinator)
        realm->second.coordinator->set_transaction_callback(nullptr);
    realm->second.pending_deletion = true;

    if (realm->second.versions.empty()) {
        m_work_queue.push(&realm->second);
        m_signal->notify();
    }
}

void GlobalNotifier::Impl::release_version(sync::ObjectID id, VersionID old_version, VersionID new_version)
{
    std::lock_guard<std::mutex> l(m_work_queue_mutex);

    auto it = m_realms.find(id);
    REALM_ASSERT(it != m_realms.end());
    auto& info = it->second;

    if (info.pending_deletion && old_version == VersionID()) {
        m_logger->trace("Global notifier: completing pending deletion of (%1)", info.virtual_path);
        if (info.coordinator) {
            std::string path = info.coordinator->get_config().path;
            m_realms.erase(it);
            if (File::exists(path)) {
              File::remove(path);
            }
        }
        else {
            m_realms.erase(it);
        }
    }
    else {
        auto& sg = info.shared_group;
        REALM_ASSERT(sg->get_version_of_current_transaction() == old_version);

        REALM_ASSERT(!info.versions.empty() && info.versions.front() == new_version);
        info.versions.pop();

        if (info.versions.empty()) {
            info.shared_group = nullptr;
            info.history = nullptr;
            m_logger->trace("Global notifier: release version on (%1): no pending versions", info.virtual_path);

            if (info.pending_deletion) {
                m_logger->trace("Global notifier: enqueuing deletion notification for (%1)", info.virtual_path);
                m_work_queue.push(&info);
            }
        }
        else {
            LangBindHelper::advance_read(*sg, new_version);
            m_work_queue.push(&info);
            m_logger->trace("Global notifier: release version on (%1): enqueuing next version", info.virtual_path);
        }
    }

    if (!m_work_queue.empty()) {
        m_logger->trace("Global notifier: Signaling main thread");
        m_signal->notify();
    }
}

GlobalNotifier::GlobalNotifier(std::unique_ptr<Callback> async_target,
                               std::string local_root_dir, SyncConfig sync_config_template)
: m_impl(std::make_shared<GlobalNotifier::Impl>(std::move(async_target),
                                                std::move(local_root_dir),
                                                std::move(sync_config_template)))
{
    std::weak_ptr<GlobalNotifier::Impl> weak_impl = m_impl;
    m_impl->m_signal = std::make_shared<util::EventLoopSignal<Impl::SignalCallback>>(Impl::SignalCallback{weak_impl});
}

void GlobalNotifier::start()
{
    m_impl->m_logger->trace("Global notifier: start()");
    m_impl->start();
}

GlobalNotifier::~GlobalNotifier() = default;

util::Optional<GlobalNotifier::ChangeNotification> GlobalNotifier::next_changed_realm()
{
    std::lock_guard<std::mutex> l(m_impl->m_work_queue_mutex);
    if (m_impl->m_work_queue.empty()) {
        m_impl->m_logger->trace("Global notifier: next_changed_realm(): no realms pending");
        return util::none;
    }

    auto next = m_impl->m_work_queue.front();
    m_impl->m_work_queue.pop();
    m_impl->m_logger->trace("Global notifier: notifying for realm at %1", next->virtual_path);

    if (next->versions.empty() && next->pending_deletion) {
        return ChangeNotification(m_impl, next->virtual_path, next->realm_id);
    }

    auto old_version = next->shared_group->get_version_of_current_transaction();
    return ChangeNotification(m_impl, next->virtual_path, next->realm_id,
                              next->coordinator->get_config(),
                              old_version, next->versions.front());
}

GlobalNotifier::Callback& GlobalNotifier::target()
{
    return *m_impl->m_target;
}

GlobalNotifier::ChangeNotification::ChangeNotification(std::shared_ptr<GlobalNotifier::Impl> notifier,
                                                       std::string virtual_path,
                                                       sync::ObjectID realm_id,
                                                       Realm::Config config,
                                                       VersionID old_version,
                                                       VersionID new_version)
: realm_path(std::move(virtual_path))
, type(Type::Change)
, m_realm_id(realm_id)
, m_config(std::move(config))
, m_old_version(old_version)
, m_new_version(new_version)
, m_notifier(std::move(notifier))
{
}

GlobalNotifier::ChangeNotification::ChangeNotification(std::shared_ptr<GlobalNotifier::Impl> notifier,
                                                       std::string virtual_path,
                                                       sync::ObjectID realm_id)
: realm_path(std::move(virtual_path))
, type(Type::Delete)
, m_realm_id(realm_id)
, m_notifier(std::move(notifier))
{
}

GlobalNotifier::ChangeNotification::~ChangeNotification()
{
    if (m_notifier)
        m_notifier->release_version(m_realm_id, m_old_version, m_new_version);
    if (m_old_realm)
        m_old_realm->close();
    if (m_new_realm)
        m_new_realm->close();
}

std::string GlobalNotifier::ChangeNotification::serialize() const
{
    nlohmann::json ret;
    ret["virtual_path"] = realm_path;
    ret["realm_id"] = m_realm_id;
    if (type == Type::Change) {
        ret["path"] = m_config.path;
        ret["old_version"] = m_old_version;
        ret["new_version"] = m_new_version;
        ret["is_change"] = true;
    }
    return ret.dump();
}

GlobalNotifier::ChangeNotification::ChangeNotification(std::string const& serialized)
{
    auto parsed = nlohmann::json::parse(serialized);
    realm_path = parsed["virtual_path"];
    m_realm_id = parsed["realm_id"];

    if (!parsed["is_change"].is_null()) {
        type = Type::Change;
        m_old_version = parsed["old_version"];
        m_new_version = parsed["new_version"];

        m_config.path = parsed["path"];
        m_config.force_sync_history = true;
        m_config.schema_mode = SchemaMode::Additive;
        m_config.cache = false;
        m_config.automatic_change_notifications = false;
    }
    else {
        type = Type::Delete;
    }
}

SharedRealm GlobalNotifier::ChangeNotification::get_old_realm() const
{
    if (const_cast<VersionID&>(m_old_version) == VersionID{})
        return nullptr;
    if (m_old_realm)
        return m_old_realm;

    m_old_realm = Realm::get_shared_realm(m_config);
    Realm::Internal::begin_read(*m_old_realm, m_old_version);
    return m_old_realm;
}

SharedRealm GlobalNotifier::ChangeNotification::get_new_realm() const
{
    if (m_new_realm)
        return m_new_realm;
    m_new_realm = Realm::get_shared_realm(m_config);
    Realm::Internal::begin_read(*m_new_realm, m_new_version);
    return m_new_realm;
}

std::unordered_map<std::string, CollectionChangeSet> const& GlobalNotifier::ChangeNotification::get_changes() const
{
    if (m_have_calculated_changes)
        return m_changes;

    Realm::Config config;
    config.path = m_config.path;
    config.cache = false;
    config.force_sync_history = true;
    config.automatic_change_notifications = false;

    auto realm = Realm::get_shared_realm(config);

    auto& sg = Realm::Internal::get_shared_group(*realm);
    Realm::Internal::begin_read(*realm, m_old_version);
    Group const& g = realm->read_group();

    _impl::TransactionChangeInfo info;
    info.track_all = true;
    _impl::transaction::advance(*sg, info, m_new_version);

    m_changes.reserve(info.tables.size());
    for (size_t i = 0; i < info.tables.size(); ++i) {
        auto& change = info.tables[i];
        if (!change.empty()) {
            auto name = ObjectStore::object_type_for_table_name(g.get_table_name(i));
            if (name) {
                m_changes[name] = std::move(change).finalize();
            }
        }
    }

    m_have_calculated_changes = true;
    return m_changes;
}

GlobalNotifier::Callback::~Callback() = default;
<commit_msg>fix removing of file<commit_after>////////////////////////////////////////////////////////////////////////////
//
// Copyright 2016 Realm Inc.
//
// 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.
//
////////////////////////////////////////////////////////////////////////////

#include "global_notifier.hpp"

#include "admin_realm.hpp"

#include "impl/realm_coordinator.hpp"
#include "impl/transact_log_handler.hpp"
#include "object_schema.hpp"
#include "object_store.hpp"
#include "results.hpp"
#include "util/event_loop_dispatcher.hpp"
#include "util/event_loop_signal.hpp"

#include "sync/sync_manager.hpp"
#include "sync/sync_user.hpp"
#include "sync/sync_session.hpp"

#include <realm/lang_bind_helper.hpp>
#include <realm/util/file.hpp>
#include <realm/util/scope_exit.hpp>

#include <json.hpp>

#include <condition_variable>
#include <mutex>
#include <queue>
#include <stdexcept>
#include <unordered_map>
#include <utility>
#include <vector>

using namespace realm;
using namespace realm::_impl;

namespace realm {
static void to_json(nlohmann::json& j, VersionID v)
{
    j = {{"version", v.version}, {"index", v.index}};
}
static void from_json(nlohmann::json const& j, VersionID& v)
{
    v.version = j["version"];
    v.index = j["index"];
}

namespace sync {
static void to_json(nlohmann::json& j, ObjectID id)
{
    j = id.to_string();
}
static void from_json(nlohmann::json const& j, ObjectID& v)
{
    std::string str = j;
    v = ObjectID::from_string(str);
}
}
}

class GlobalNotifier::Impl final : public AdminRealmListener {
public:
    Impl(std::unique_ptr<Callback>,
         std::string local_root_dir, SyncConfig sync_config_template);

    util::Optional<ChangeNotification> next_changed_realm();
    void release_version(sync::ObjectID id, VersionID old_version, VersionID new_version);

public:
    void register_realm(sync::ObjectID, StringData virtual_path) override;
    void unregister_realm(sync::ObjectID, StringData) override;
    void error(std::exception_ptr err) override { m_target->error(err); }
    void download_complete() override { m_target->download_complete(); }

    const std::unique_ptr<util::Logger> m_logger;
    const std::unique_ptr<Callback> m_target;

    std::mutex m_work_queue_mutex;
    struct RealmToCalculate {
        sync::ObjectID realm_id;
        std::string virtual_path;
        std::shared_ptr<_impl::RealmCoordinator> coordinator;
        std::unique_ptr<Replication> history;
        std::unique_ptr<SharedGroup> shared_group;
        std::queue<VersionID> versions;
        bool pending_deletion = false;

        // constructor to make GCC 4.9 happy
        RealmToCalculate(sync::ObjectID realm_id, std::string virtual_path)
        : realm_id(realm_id)
        , virtual_path(std::move(virtual_path))
        {
        }
    };
    std::queue<RealmToCalculate*> m_work_queue;
    std::unordered_map<sync::ObjectID, RealmToCalculate> m_realms;

    struct SignalCallback {
        std::weak_ptr<Impl> notifier;
        void operator()()
        {
            if (auto alive = notifier.lock()) {
                GlobalNotifier notifier(alive);
                alive->m_target->realm_changed(&notifier);
            }
        }
    };

    std::shared_ptr<util::EventLoopSignal<SignalCallback>> m_signal;
};

GlobalNotifier::Impl::Impl(std::unique_ptr<Callback> async_target,
                           std::string local_root_dir, SyncConfig sync_config_template)
: AdminRealmListener(local_root_dir, std::move(sync_config_template))
, m_logger(SyncManager::shared().make_logger())
, m_target(std::move(async_target))
{
}

void GlobalNotifier::Impl::register_realm(sync::ObjectID id, StringData path) {
    auto info = &m_realms.emplace(id, RealmToCalculate{id, path}).first->second;
    m_realms.emplace(id, RealmToCalculate{id, path});

    auto strid = id.to_string();
    if (!m_target->realm_available(strid, path)) {
        m_logger->trace("Global notifier: not watching %1", path);
        return;
    }
    if (info->coordinator) {
        m_logger->trace("Global notifier: already watching %1", path);
        return;
    }

    m_logger->trace("Global notifier: watching %1", path);
    auto config = get_config(path, strid);
    info->coordinator = _impl::RealmCoordinator::get_coordinator(config);

    std::weak_ptr<Impl> weak_self = std::static_pointer_cast<Impl>(shared_from_this());
    info->coordinator->set_transaction_callback([=, weak_self = std::move(weak_self)](VersionID old_version, VersionID new_version) {
        auto self = weak_self.lock();
        if (!self)
            return;

        std::lock_guard<std::mutex> l(m_work_queue_mutex);
        if (info->shared_group) {
            m_logger->trace("Global notifier: sync transaction on (%1): Realm already open", info->virtual_path);
        }
        else {
            m_logger->trace("Global notifier: sync transaction on (%1): opening Realm", info->virtual_path);
            std::unique_ptr<Group> read_only_group;
            auto config = info->coordinator->get_config();
            config.force_sync_history = true; // FIXME: needed?
            config.schema = util::none;
            Realm::open_with_config(config, info->history, info->shared_group, read_only_group, nullptr);
            info->shared_group->begin_read(old_version);
        }
        info->versions.push(new_version);
        if (info->versions.size() == 1) {
            m_logger->trace("Global notifier: Signaling main thread");
            m_work_queue.push(info);
            m_signal->notify();
        }
    });
}

void GlobalNotifier::Impl::unregister_realm(sync::ObjectID id, StringData path) {
    auto realm = m_realms.find(id);
    if (realm == m_realms.end()) {
        m_logger->trace("Global notifier: unwatched Realm at (%1) was deleted", path);
        return;
    }

    std::lock_guard<std::mutex> l(m_work_queue_mutex);
    // Otherwise we need to defer closing the Realm until we're done with our current work.
    m_logger->trace("Global notifier: enqueuing deletion of Realm at (%1)", path);
    if (realm->second.coordinator)
        realm->second.coordinator->set_transaction_callback(nullptr);
    realm->second.pending_deletion = true;

    if (realm->second.versions.empty()) {
        m_work_queue.push(&realm->second);
        m_signal->notify();
    }
}

void GlobalNotifier::Impl::release_version(sync::ObjectID id, VersionID old_version, VersionID new_version)
{
    std::lock_guard<std::mutex> l(m_work_queue_mutex);

    auto it = m_realms.find(id);
    REALM_ASSERT(it != m_realms.end());
    auto& info = it->second;

    if (info.pending_deletion && old_version == VersionID()) {
        m_logger->trace("Global notifier: completing pending deletion of (%1)", info.virtual_path);
        if (info.coordinator) {
            std::string path = info.coordinator->get_config().path;
            m_realms.erase(it);
            File::try_remove(path);
        }
        else {
            m_realms.erase(it);
        }
    }
    else {
        auto& sg = info.shared_group;
        REALM_ASSERT(sg->get_version_of_current_transaction() == old_version);

        REALM_ASSERT(!info.versions.empty() && info.versions.front() == new_version);
        info.versions.pop();

        if (info.versions.empty()) {
            info.shared_group = nullptr;
            info.history = nullptr;
            m_logger->trace("Global notifier: release version on (%1): no pending versions", info.virtual_path);

            if (info.pending_deletion) {
                m_logger->trace("Global notifier: enqueuing deletion notification for (%1)", info.virtual_path);
                m_work_queue.push(&info);
            }
        }
        else {
            LangBindHelper::advance_read(*sg, new_version);
            m_work_queue.push(&info);
            m_logger->trace("Global notifier: release version on (%1): enqueuing next version", info.virtual_path);
        }
    }

    if (!m_work_queue.empty()) {
        m_logger->trace("Global notifier: Signaling main thread");
        m_signal->notify();
    }
}

GlobalNotifier::GlobalNotifier(std::unique_ptr<Callback> async_target,
                               std::string local_root_dir, SyncConfig sync_config_template)
: m_impl(std::make_shared<GlobalNotifier::Impl>(std::move(async_target),
                                                std::move(local_root_dir),
                                                std::move(sync_config_template)))
{
    std::weak_ptr<GlobalNotifier::Impl> weak_impl = m_impl;
    m_impl->m_signal = std::make_shared<util::EventLoopSignal<Impl::SignalCallback>>(Impl::SignalCallback{weak_impl});
}

void GlobalNotifier::start()
{
    m_impl->m_logger->trace("Global notifier: start()");
    m_impl->start();
}

GlobalNotifier::~GlobalNotifier() = default;

util::Optional<GlobalNotifier::ChangeNotification> GlobalNotifier::next_changed_realm()
{
    std::lock_guard<std::mutex> l(m_impl->m_work_queue_mutex);
    if (m_impl->m_work_queue.empty()) {
        m_impl->m_logger->trace("Global notifier: next_changed_realm(): no realms pending");
        return util::none;
    }

    auto next = m_impl->m_work_queue.front();
    m_impl->m_work_queue.pop();
    m_impl->m_logger->trace("Global notifier: notifying for realm at %1", next->virtual_path);

    if (next->versions.empty() && next->pending_deletion) {
        return ChangeNotification(m_impl, next->virtual_path, next->realm_id);
    }

    auto old_version = next->shared_group->get_version_of_current_transaction();
    return ChangeNotification(m_impl, next->virtual_path, next->realm_id,
                              next->coordinator->get_config(),
                              old_version, next->versions.front());
}

GlobalNotifier::Callback& GlobalNotifier::target()
{
    return *m_impl->m_target;
}

GlobalNotifier::ChangeNotification::ChangeNotification(std::shared_ptr<GlobalNotifier::Impl> notifier,
                                                       std::string virtual_path,
                                                       sync::ObjectID realm_id,
                                                       Realm::Config config,
                                                       VersionID old_version,
                                                       VersionID new_version)
: realm_path(std::move(virtual_path))
, type(Type::Change)
, m_realm_id(realm_id)
, m_config(std::move(config))
, m_old_version(old_version)
, m_new_version(new_version)
, m_notifier(std::move(notifier))
{
}

GlobalNotifier::ChangeNotification::ChangeNotification(std::shared_ptr<GlobalNotifier::Impl> notifier,
                                                       std::string virtual_path,
                                                       sync::ObjectID realm_id)
: realm_path(std::move(virtual_path))
, type(Type::Delete)
, m_realm_id(realm_id)
, m_notifier(std::move(notifier))
{
}

GlobalNotifier::ChangeNotification::~ChangeNotification()
{
    if (m_notifier)
        m_notifier->release_version(m_realm_id, m_old_version, m_new_version);
    if (m_old_realm)
        m_old_realm->close();
    if (m_new_realm)
        m_new_realm->close();
}

std::string GlobalNotifier::ChangeNotification::serialize() const
{
    nlohmann::json ret;
    ret["virtual_path"] = realm_path;
    ret["realm_id"] = m_realm_id;
    if (type == Type::Change) {
        ret["path"] = m_config.path;
        ret["old_version"] = m_old_version;
        ret["new_version"] = m_new_version;
        ret["is_change"] = true;
    }
    return ret.dump();
}

GlobalNotifier::ChangeNotification::ChangeNotification(std::string const& serialized)
{
    auto parsed = nlohmann::json::parse(serialized);
    realm_path = parsed["virtual_path"];
    m_realm_id = parsed["realm_id"];

    if (!parsed["is_change"].is_null()) {
        type = Type::Change;
        m_old_version = parsed["old_version"];
        m_new_version = parsed["new_version"];

        m_config.path = parsed["path"];
        m_config.force_sync_history = true;
        m_config.schema_mode = SchemaMode::Additive;
        m_config.cache = false;
        m_config.automatic_change_notifications = false;
    }
    else {
        type = Type::Delete;
    }
}

SharedRealm GlobalNotifier::ChangeNotification::get_old_realm() const
{
    if (const_cast<VersionID&>(m_old_version) == VersionID{})
        return nullptr;
    if (m_old_realm)
        return m_old_realm;

    m_old_realm = Realm::get_shared_realm(m_config);
    Realm::Internal::begin_read(*m_old_realm, m_old_version);
    return m_old_realm;
}

SharedRealm GlobalNotifier::ChangeNotification::get_new_realm() const
{
    if (m_new_realm)
        return m_new_realm;
    m_new_realm = Realm::get_shared_realm(m_config);
    Realm::Internal::begin_read(*m_new_realm, m_new_version);
    return m_new_realm;
}

std::unordered_map<std::string, CollectionChangeSet> const& GlobalNotifier::ChangeNotification::get_changes() const
{
    if (m_have_calculated_changes)
        return m_changes;

    Realm::Config config;
    config.path = m_config.path;
    config.cache = false;
    config.force_sync_history = true;
    config.automatic_change_notifications = false;

    auto realm = Realm::get_shared_realm(config);

    auto& sg = Realm::Internal::get_shared_group(*realm);
    Realm::Internal::begin_read(*realm, m_old_version);
    Group const& g = realm->read_group();

    _impl::TransactionChangeInfo info;
    info.track_all = true;
    _impl::transaction::advance(*sg, info, m_new_version);

    m_changes.reserve(info.tables.size());
    for (size_t i = 0; i < info.tables.size(); ++i) {
        auto& change = info.tables[i];
        if (!change.empty()) {
            auto name = ObjectStore::object_type_for_table_name(g.get_table_name(i));
            if (name) {
                m_changes[name] = std::move(change).finalize();
            }
        }
    }

    m_have_calculated_changes = true;
    return m_changes;
}

GlobalNotifier::Callback::~Callback() = default;
<|endoftext|>


<commit_before>/***
Copyright 2017 Yaohai XU

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.
***/

/**
    FastLSH
    StdThreadComputer.cpp
    Purpose: This is the source file for StdThread computing functions

    @author Peter Yaohai XU
    @version 1.0 4/07/17
*/

#include <cmath>
#include <thread>
#include <algorithm>
#include <iostream>
#include "../../include/otherClasses/Computer.h"

vector2D ComputerStdThread::computeHash(vector2D dataset, size_t pointNum){
    vector2D hashMatrix;
    //pre-allocate memory space
    for (int i = 0; i < pointNum; ++i) {
        vector1D vL(ph.L,0);
        hashMatrix.push_back(vL);
    }

    // a implementation of nested loop to stdthread
    const size_t nthreads = std::thread::hardware_concurrency();
    const size_t outloop = pointNum;
    const size_t inloop = ph.L;
    const size_t nloop = outloop*inloop;

    // vector of threads
    std::vector<std::thread> threads(nthreads);
    for(int t = 0;t<nthreads;t++)
    {
        threads[t] = std::thread(std::bind(
                [&](const int bi, const int ei, const int t)
                {
                    // loop over all items
                    for(int i = bi;i<ei;i++)
                    {
                        // inner loop
                        {
                            int n = i/inloop; //retrive outer loop index
                            int l = i%inloop; //retrive inner loop index
                            // (optional) make output critical
                            double hashFinalValue = 0;
                            //loop through the inner of a hash function group
                            for (int k = 0; k < ph.K; ++k) {
                                double dTemp = 0;
                                //loop through all the dimensions
                                for (int d = 0; d < ph.D; ++d) {
                                    //vector(math) multiply to make projection
                                    dTemp += dataset[n][d]*ph.randomLine[l][k][d];
                                }
                                //assign hashvalue into bucket
                                double hashvalue = floor(dTemp/ph.W);
                                //merge hash group results **see documentation
                                hashFinalValue = hashvalue*ph.randomVector[k] + hashFinalValue;
                            }
                            hashMatrix[n][l] = hashFinalValue;

                        }
                    }
                    //allocate different index to threads
                },t*nloop/nthreads,(t+1)==nthreads?nloop:(t+1)*nloop/nthreads,t));
    }

    //lambda to start threads
    std::for_each(threads.begin(),threads.end(),[](std::thread& x){x.join();});

    return hashMatrix;
}

vector2D ComputerStdThreadNormal::computeCollision(vector2D hMatrixN, vector2D hMatrixQ){
    //pre-allocate memory space
    vector2D collisionMatrix;
    for (int i = 0; i < ph.Q ; ++i) {
        vector1D singleLine(ph.N, 0);
        collisionMatrix.push_back(singleLine);
    }

    // a implementation of nested loop to stdthread
    const size_t nthreads = std::thread::hardware_concurrency();
    const size_t outloop = ph.Q;
    const size_t inloop = ph.N;
    const size_t nloop = outloop*inloop;
    std::vector<std::thread> threads(nthreads);
    for(int t = 0;t<nthreads;t++)
    {
        threads[t] = std::thread(std::bind(
                [&](const int bi, const int ei, const int t)
                {
                    // loop over all items
                    for(int i = bi;i<ei;i++)
                    {
                        // inner loop
                        {
                            int q = i/inloop;
                            int n = i%inloop;
                            for (int hash_id = 0; hash_id < ph.L; ++hash_id) {
                                //cast to int for comparision, reduce double compare risk
                                if (hMatrixN[n][hash_id] == hMatrixQ[q][hash_id])
                                    collisionMatrix[q][n]++;
                            }

                        }
                    }
                    //allocate different index to threads
                },t*nloop/nthreads,(t+1)==nthreads?nloop:(t+1)*nloop/nthreads,t));
    }
    //lambda to start threads
    std::for_each(threads.begin(),threads.end(),[](std::thread& x){x.join();});
    return collisionMatrix;
}

vector2D ComputerStdThreadNormal::computeCandidate(vector2D collisionMatrix){
    //pre-allocate memory space
    vector2D candidateSet;
    for (int i = 0; i < ph.Q; ++i) {
        vector1D temp(0,0);
        candidateSet.push_back(temp);
    }

    // a implementation of nested loop to stdthread
    const size_t nthreads = std::thread::hardware_concurrency();
    const size_t nloop = ph.Q;
    std::vector<std::thread> threads(nthreads);

    for(int t = 0;t<nthreads;t++)
    {
        threads[t] = std::thread(std::bind(
                [&](const int bi, const int ei, const int t)
                {
                    // loop over all items
                    for(int i = bi;i<ei;i++)
                    {
                        vector1D candidates;
                        for (int j = 0; j < ph.N; ++j) {
                            if(collisionMatrix[i][j]>=ph.T)
                                candidates.push_back((double &&) j);
                        }
                        candidateSet[i] = candidates;
                    }
                    //allocate different index to threads
                },t*nloop/nthreads,(t+1)==nthreads?nloop:(t+1)*nloop/nthreads,t));
    }
    //lambda to start threads
    std::for_each(threads.begin(),threads.end(),[](std::thread& x){x.join();});
    return candidateSet;
}

//by quick mode, it means get candidateset directly, skip the collision table
vector2D ComputerStdThreadQuick::computeCandidate(vector2D hMatrixN, vector2D hMatrixQ){
    vector2D candidateSet;
    //Prepare set to store candidates
    for (int i = 0; i < ph.Q; ++i) {
        vector1D temp(0,0);
        candidateSet.push_back(temp);
    }

    // a implementation of nested loop to stdthread
    const size_t nthreads = std::thread::hardware_concurrency();
    const size_t nloop = ph.Q;
    std::vector<std::thread> threads(nthreads);

    for(int t = 0;t<nthreads;t++)
    {
        threads[t] = std::thread(std::bind(
                [&](const int bi, const int ei, const int t)
                {
                    // loop over all items
                    for(int i = bi;i<ei;i++)
                    {
                        vector1D singleRow(0, 0);
                        for (int n = 0; n <ph.N ; ++n){
                            int colliNum = 0;
                            for (int hash_id = 0; hash_id < ph.L; ++hash_id) {
                                if (hMatrixN[n][hash_id] == hMatrixQ[i][hash_id]) {
                                    colliNum++;
                                    if(colliNum>=ph.T){
                                        singleRow.push_back((double &&) n);
                                        break;
                                    }
                                }
                            }
                        }
                        candidateSet[i] = singleRow;
                    }
                    //allocate different index to threads
                },t*nloop/nthreads,(t+1)==nthreads?nloop:(t+1)*nloop/nthreads,t));
    }
    //lambda to start threads
    std::for_each(threads.begin(),threads.end(),[](std::thread& x){x.join();});
    return candidateSet;
}

void ComputerStdThread::printThreadMode(){
    std::cout<< "Pthread";
}
void ComputerStdThreadNormal::printComputeMode(){
    std::cout<< "Normal";
}
void ComputerStdThreadQuick::printComputeMode(){
    std::cout<< "Quick";
}

<commit_msg>Fix: error: ‘bind’ is not a member of ‘std’<commit_after>/***
Copyright 2017 Yaohai XU

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.
***/

/**
    FastLSH
    StdThreadComputer.cpp
    Purpose: This is the source file for StdThread computing functions

    @author Peter Yaohai XU
    @version 1.0 4/07/17
*/

#include <cmath>
#include <thread>
#include <algorithm>
#include <iostream>
#include <functional>
#include "../../include/otherClasses/Computer.h"

vector2D ComputerStdThread::computeHash(vector2D dataset, size_t pointNum){
    vector2D hashMatrix;
    //pre-allocate memory space
    for (int i = 0; i < pointNum; ++i) {
        vector1D vL(ph.L,0);
        hashMatrix.push_back(vL);
    }

    // a implementation of nested loop to stdthread
    const size_t nthreads = std::thread::hardware_concurrency();
    const size_t outloop = pointNum;
    const size_t inloop = ph.L;
    const size_t nloop = outloop*inloop;

    // vector of threads
    std::vector<std::thread> threads(nthreads);
    for(int t = 0;t<nthreads;t++)
    {
        threads[t] = std::thread(std::bind(
                [&](const int bi, const int ei, const int t)
                {
                    // loop over all items
                    for(int i = bi;i<ei;i++)
                    {
                        // inner loop
                        {
                            int n = i/inloop; //retrive outer loop index
                            int l = i%inloop; //retrive inner loop index
                            // (optional) make output critical
                            double hashFinalValue = 0;
                            //loop through the inner of a hash function group
                            for (int k = 0; k < ph.K; ++k) {
                                double dTemp = 0;
                                //loop through all the dimensions
                                for (int d = 0; d < ph.D; ++d) {
                                    //vector(math) multiply to make projection
                                    dTemp += dataset[n][d]*ph.randomLine[l][k][d];
                                }
                                //assign hashvalue into bucket
                                double hashvalue = floor(dTemp/ph.W);
                                //merge hash group results **see documentation
                                hashFinalValue = hashvalue*ph.randomVector[k] + hashFinalValue;
                            }
                            hashMatrix[n][l] = hashFinalValue;

                        }
                    }
                    //allocate different index to threads
                },t*nloop/nthreads,(t+1)==nthreads?nloop:(t+1)*nloop/nthreads,t));
    }

    //lambda to start threads
    std::for_each(threads.begin(),threads.end(),[](std::thread& x){x.join();});

    return hashMatrix;
}

vector2D ComputerStdThreadNormal::computeCollision(vector2D hMatrixN, vector2D hMatrixQ){
    //pre-allocate memory space
    vector2D collisionMatrix;
    for (int i = 0; i < ph.Q ; ++i) {
        vector1D singleLine(ph.N, 0);
        collisionMatrix.push_back(singleLine);
    }

    // a implementation of nested loop to stdthread
    const size_t nthreads = std::thread::hardware_concurrency();
    const size_t outloop = ph.Q;
    const size_t inloop = ph.N;
    const size_t nloop = outloop*inloop;
    std::vector<std::thread> threads(nthreads);
    for(int t = 0;t<nthreads;t++)
    {
        threads[t] = std::thread(std::bind(
                [&](const int bi, const int ei, const int t)
                {
                    // loop over all items
                    for(int i = bi;i<ei;i++)
                    {
                        // inner loop
                        {
                            int q = i/inloop;
                            int n = i%inloop;
                            for (int hash_id = 0; hash_id < ph.L; ++hash_id) {
                                //cast to int for comparision, reduce double compare risk
                                if (hMatrixN[n][hash_id] == hMatrixQ[q][hash_id])
                                    collisionMatrix[q][n]++;
                            }

                        }
                    }
                    //allocate different index to threads
                },t*nloop/nthreads,(t+1)==nthreads?nloop:(t+1)*nloop/nthreads,t));
    }
    //lambda to start threads
    std::for_each(threads.begin(),threads.end(),[](std::thread& x){x.join();});
    return collisionMatrix;
}

vector2D ComputerStdThreadNormal::computeCandidate(vector2D collisionMatrix){
    //pre-allocate memory space
    vector2D candidateSet;
    for (int i = 0; i < ph.Q; ++i) {
        vector1D temp(0,0);
        candidateSet.push_back(temp);
    }

    // a implementation of nested loop to stdthread
    const size_t nthreads = std::thread::hardware_concurrency();
    const size_t nloop = ph.Q;
    std::vector<std::thread> threads(nthreads);

    for(int t = 0;t<nthreads;t++)
    {
        threads[t] = std::thread(std::bind(
                [&](const int bi, const int ei, const int t)
                {
                    // loop over all items
                    for(int i = bi;i<ei;i++)
                    {
                        vector1D candidates;
                        for (int j = 0; j < ph.N; ++j) {
                            if(collisionMatrix[i][j]>=ph.T)
                                candidates.push_back((double &&) j);
                        }
                        candidateSet[i] = candidates;
                    }
                    //allocate different index to threads
                },t*nloop/nthreads,(t+1)==nthreads?nloop:(t+1)*nloop/nthreads,t));
    }
    //lambda to start threads
    std::for_each(threads.begin(),threads.end(),[](std::thread& x){x.join();});
    return candidateSet;
}

//by quick mode, it means get candidateset directly, skip the collision table
vector2D ComputerStdThreadQuick::computeCandidate(vector2D hMatrixN, vector2D hMatrixQ){
    vector2D candidateSet;
    //Prepare set to store candidates
    for (int i = 0; i < ph.Q; ++i) {
        vector1D temp(0,0);
        candidateSet.push_back(temp);
    }

    // a implementation of nested loop to stdthread
    const size_t nthreads = std::thread::hardware_concurrency();
    const size_t nloop = ph.Q;
    std::vector<std::thread> threads(nthreads);

    for(int t = 0;t<nthreads;t++)
    {
        threads[t] = std::thread(std::bind(
                [&](const int bi, const int ei, const int t)
                {
                    // loop over all items
                    for(int i = bi;i<ei;i++)
                    {
                        vector1D singleRow(0, 0);
                        for (int n = 0; n <ph.N ; ++n){
                            int colliNum = 0;
                            for (int hash_id = 0; hash_id < ph.L; ++hash_id) {
                                if (hMatrixN[n][hash_id] == hMatrixQ[i][hash_id]) {
                                    colliNum++;
                                    if(colliNum>=ph.T){
                                        singleRow.push_back((double &&) n);
                                        break;
                                    }
                                }
                            }
                        }
                        candidateSet[i] = singleRow;
                    }
                    //allocate different index to threads
                },t*nloop/nthreads,(t+1)==nthreads?nloop:(t+1)*nloop/nthreads,t));
    }
    //lambda to start threads
    std::for_each(threads.begin(),threads.end(),[](std::thread& x){x.join();});
    return candidateSet;
}

void ComputerStdThread::printThreadMode(){
    std::cout<< "Pthread";
}
void ComputerStdThreadNormal::printComputeMode(){
    std::cout<< "Normal";
}
void ComputerStdThreadQuick::printComputeMode(){
    std::cout<< "Quick";
}

<|endoftext|>


<commit_before>#include <fstream>
#include "riemann_solver.h"

using namespace std;

void Solve(Discrete_Records &result, Status &s1, Status &s2);
void PrintResult(Discrete_Records &result);

int main(int argc, int argv) {

	Status s1, s2;
	Discrete_Records result;

	s1.pressure = 1.0;
	s1.density = 1.0;
	s1.velocity = 0.0;

	s2.pressure = 0.1;
	s2.density = 0.125;
	s2.velocity = 0.0;

	result.records = new Status[201];
	result.time = 0.14;
	result.size = 201;
	result.dx = 2.0 / (201 - 1);

	Solve(result, s1, s2);

	PrintResult(result);

	delete[] result.records;

	return 0;
}

void Solve(Discrete_Records &result,Status &s1, Status &s2) {
	Riemann_Solver solver(s1,s2);
	solver.Solver();
	solver.Get_Result(result);
}

void PrintResult(Discrete_Records &result) {

	ofstream file("output.dat");

	file << "VARIABLES = \"X\", \"Pressure\", \"Density\", \"Velocity\"" << '\n';
	file << "ZONE I=201, DATAPACKING=BLOCK" << '\n';

	file.precision(10);
	file.setf(ios::fixed, ios::floatfield);

	for (int i = 0; i < result.size; i++)
	{
		file << i * result.dx - 1.0 << '\t';
	}
	file << '\n';
	for (int i = 0; i < result.size; i++)
	{
		file << result.records[i].pressure << '\t';
	}
	file << '\n';
	for (int i = 0; i < result.size; i++)
	{
		file << result.records[i].density << '\t';
	}
	file << '\n';
	for (int i = 0; i < result.size; i++)
	{
		file << result.records[i].velocity << '\t';
	}
	file << endl;
}<commit_msg>a few mistake corrected<commit_after>#include <fstream>
#include "riemann_solver.h"

using namespace std;

void Solve(Discrete_Records &result, Status &s1, Status &s2);
void PrintResult(Discrete_Records &result);

int main(int argc, char **argv) {

	Status s1, s2;
	Discrete_Records result;

	s1.pressure = 1.0;
	s1.density = 1.0;
	s1.velocity = 0.0;

	s2.pressure = 0.1;
	s2.density = 0.125;
	s2.velocity = 0.0;

	result.records = new Status[201];
	result.time = 0.14;
	result.size = 201;
	result.dx = 2.0 / (201 - 1);

	Solve(result, s1, s2);

	PrintResult(result);

	delete[] result.records;

	return 0;
}

void Solve(Discrete_Records &result,Status &s1, Status &s2) {
	Riemann_Solver solver(s1,s2);
	solver.Solver();
	solver.Get_Result(result);
}

void PrintResult(Discrete_Records &result) {

	ofstream file("output.dat");

	file << "VARIABLES = \"X\", \"Pressure\", \"Density\", \"Velocity\"" << '\n';
	file << "ZONE I=201, DATAPACKING=BLOCK" << '\n';

	file.precision(10);
	file.setf(ios::fixed, ios::floatfield);

	for (int i = 0; i < result.size; i++)
	{
		file << i * result.dx - 1.0 << '\t';
	}
	file << '\n';
	for (int i = 0; i < result.size; i++)
	{
		file << result.records[i].pressure << '\t';
	}
	file << '\n';
	for (int i = 0; i < result.size; i++)
	{
		file << result.records[i].density << '\t';
	}
	file << '\n';
	for (int i = 0; i < result.size; i++)
	{
		file << result.records[i].velocity << '\t';
	}
	file << endl;
}
<|endoftext|>


<commit_before>/*******************************************************************************
* Copyright 2016 ROBOTIS CO., LTD.
*
* 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.
*******************************************************************************/

/* Authors: Hye-Jong KIM */

#ifndef OMMATH_HPP_
#define OMMATH_HPP_

#include "../../include/open_manipulator/OMDebug.hpp"

#include <Eigen.h>        // Calls main Eigen matrix class library
#include <Eigen/LU>       // Calls inverse, determinant, LU decomp., etc.

#include <math.h>

#define DEG2RAD (M_PI / 180.0)
#define RAD2DEG (180.0 / M_PI)

#define ZERO_VECTOR     Eigen::Vector3f::Zero()
#define IDENTITY_MATRIX Eigen::Matrix3f::Identity(3,3)

class OMMath
{
 public:
  OMMath(){}
  ~OMMath(){}

  float sign(float number)
  {
    if (number >= 0.0)
    {
      return 1.0;
    }
    else
    {
      return -1.0;
    }
  }

  Eigen::Vector3f makeEigenVector3(float v1, float v2, float v3)
  {
    Eigen::Vector3f temp;
    temp << v1, v2, v3;
    return temp;
  }

  Eigen::Matrix3f makeEigenMatrix3(float m11, float m12, float m13, float m21, float m22, float m23, float m31, float m32, float m33)
  {
    Eigen::Matrix3f temp;
    temp << m11, m12, m13, m21, m22, m23, m31, m32, m33;
    return temp;
  }

  Eigen::Matrix3f makeRotationMatrix(float roll, float pitch, float yaw)
  {
    Eigen::Matrix3f rotation_matrix;
    Eigen::Matrix3f roll_matrix;
    Eigen::Matrix3f pitch_matrix;
    Eigen::Matrix3f yaw_matrix;

    roll_matrix  << 1.000,  0.000,     0.000,
                    0.000,  cos(roll), sin(roll),
                    0.000, -sin(roll), cos(roll);

    pitch_matrix << cos(pitch),  0.000, sin(pitch),
                    0.000,       1.000, 0.000,
                    -sin(pitch), 0.000, cos(pitch);

    yaw_matrix   << cos(yaw), -sin(yaw), 0.000,
                    sin(yaw), cos(yaw),  0.000,
                    0.000,    0.000,     1.000;

    rotation_matrix = roll_matrix * pitch_matrix * yaw_matrix;

    return rotation_matrix;
  }

  Eigen::Matrix3f makeRotationMatrix(Eigen::Vector3f rotation_vector)
  {
    Eigen::Matrix3f rotation_matrix;
    rotation_matrix = makeRotationMatrix(rotation_vector(0), rotation_vector(1), rotation_vector(2));
    return rotation_matrix;
  }

  Eigen::Vector3f makeRotationVector(Eigen::Matrix3f rotation_matrix)
  {
    Eigen::Matrix3f R = rotation_matrix;
    Eigen::Vector3f l = Eigen::Vector3f::Zero();
    Eigen::Vector3f rotation_vector = Eigen::Vector3f::Zero();

    float theta = 0.0;
    float diag  = 0.0;
    bool diagonal_matrix = true;

    l << R(2,1) - R(1,2),
         R(0,2) - R(2,0),
         R(1,0) - R(0,1);
    theta = atan2(l.norm(), R(0,0) + R(1,1) + R(2,2) - 1);
    diag  = R(0,0) + R(1,1) + R(2,2);

    for (int8_t i = 0; i < 3; i++)
    {
      for (int8_t j = 0; j < 3; j++)
      {
        if (i != j)
        {
          if (R(i, j) != 0)
          {
            diagonal_matrix = false;
          }
        }
      }
    }
    if (R == Eigen::Matrix3f::Identity())
    {
      rotation_vector = Eigen::Vector3f::Zero();
    }
    else if (diagonal_matrix == true)
    {
      rotation_vector << R(0,0) + 1, R(1,1) + 1, R(2,2) + 1;
      rotation_vector = rotation_vector * M_PI_2;
    }
    else
    {
      rotation_vector = theta * (l / l.norm());
    }
    return rotation_vector;
  }

  Eigen::Matrix3f skewSymmetricMatrix(Eigen::Vector3f v)
  {
    Eigen::Matrix3f skew_symmetric_matrix = Eigen::Matrix3f::Zero();

    skew_symmetric_matrix <<    0,  -v(2),  v(1),
                            v(2),      0, -v(0),
                            -v(1),   v(0),     0;

    return skew_symmetric_matrix;
  }

  Eigen::Matrix3f rodriguesRotationMatrix(Eigen::Vector3f axis, float angle)
  {
    Eigen::Matrix3f skew_symmetric_matrix = Eigen::Matrix3f::Zero();
    Eigen::Matrix3f rotation_matrix = Eigen::Matrix3f::Zero();
    Eigen::Matrix3f Identity_matrix = Eigen::Matrix3f::Identity();

    skew_symmetric_matrix = skewSymmetricMatrix(axis);
    rotation_matrix = Identity_matrix +
                      skew_symmetric_matrix * sin(angle) +
                      skew_symmetric_matrix * skew_symmetric_matrix * (1 - cos(angle));

    return rotation_matrix;
  }

  Eigen::Vector3f differentialPosition(Eigen::Vector3f desired_position, Eigen::Vector3f present_position)
  {
    Eigen::Vector3f differential_position;
    differential_position = desired_position - present_position;

    return differential_position;
  }

  Eigen::Vector3f differentialOrientation(Eigen::Matrix3f desired_orientation, Eigen::Matrix3f present_orientation)
  {
    Eigen::Vector3f differential_orientation;
    differential_orientation = present_orientation * makeRotationVector(present_orientation.transpose() * desired_orientation);

    return differential_orientation;
  }

  Eigen::VectorXf differentialPose(Eigen::Vector3f desired_position, Eigen::Vector3f present_position, Eigen::Matrix3f desired_orientation, Eigen::Matrix3f present_orientation)
  {
    Eigen::Vector3f differential_position;
    Eigen::Vector3f differential_orientation;
    Eigen::VectorXf  differential_pose(6);

    differential_position = differentialPosition(desired_position, present_position);
    differential_orientation = differentialOrientation(desired_orientation, present_orientation);
    differential_pose << differential_position(0),
                         differential_position(1),
                         differential_position(2),
                         differential_orientation(0),
                         differential_orientation(1),
                         differential_orientation(2);
    return differential_pose;
  }
};

#endif // OMMATH_HPP_
<commit_msg>fix makerotation vec,matrix function<commit_after>/*******************************************************************************
* Copyright 2016 ROBOTIS CO., LTD.
*
* 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.
*******************************************************************************/

/* Authors: Hye-Jong KIM */

#ifndef OMMATH_HPP_
#define OMMATH_HPP_

#include "../../include/open_manipulator/OMDebug.hpp"

#include <Eigen.h>        // Calls main Eigen matrix class library
#include <Eigen/LU>       // Calls inverse, determinant, LU decomp., etc.

#include <math.h>

#define DEG2RAD (M_PI / 180.0)
#define RAD2DEG (180.0 / M_PI)

#define ZERO_VECTOR     Eigen::Vector3f::Zero()
#define IDENTITY_MATRIX Eigen::Matrix3f::Identity(3,3)

class OMMath
{
 public:
  OMMath(){}
  ~OMMath(){}

  float sign(float number)
  {
    if (number >= 0.0)
    {
      return 1.0;
    }
    else
    {
      return -1.0;
    }
  }

  Eigen::Vector3f makeEigenVector3(float v1, float v2, float v3)
  {
    Eigen::Vector3f temp;
    temp << v1, v2, v3;
    return temp;
  }

  Eigen::Matrix3f makeEigenMatrix3(float m11, float m12, float m13, float m21, float m22, float m23, float m31, float m32, float m33)
  {
    Eigen::Matrix3f temp;
    temp << m11, m12, m13, m21, m22, m23, m31, m32, m33;
    return temp;
  }

  Eigen::Vector3f matrixLogarithm(Eigen::Matrix3f rotation_matrix)
  {
    Eigen::Matrix3f R = rotation_matrix;
    Eigen::Vector3f l = Eigen::Vector3f::Zero();
    Eigen::Vector3f rotation_vector = Eigen::Vector3f::Zero();

    float theta = 0.0;
    float diag  = 0.0;
    bool diagonal_matrix = true;

    l << R(2,1) - R(1,2),
         R(0,2) - R(2,0),
         R(1,0) - R(0,1);
    theta = atan2(l.norm(), R(0,0) + R(1,1) + R(2,2) - 1);
    diag  = R(0,0) + R(1,1) + R(2,2);

    for (int8_t i = 0; i < 3; i++)
    {
      for (int8_t j = 0; j < 3; j++)
      {
        if (i != j)
        {
          if (R(i, j) != 0)
          {
            diagonal_matrix = false;
          }
        }
      }
    }
    if (R == Eigen::Matrix3f::Identity())
    {
      rotation_vector = Eigen::Vector3f::Zero();
    }
    else if (diagonal_matrix == true)
    {
      rotation_vector << R(0,0) + 1, R(1,1) + 1, R(2,2) + 1;
      rotation_vector = rotation_vector * M_PI_2;
    }
    else
    {
      rotation_vector = theta * (l / l.norm());
    }
    return rotation_vector;
  }

  Eigen::Matrix3f skewSymmetricMatrix(Eigen::Vector3f v)
  {
    Eigen::Matrix3f skew_symmetric_matrix = Eigen::Matrix3f::Zero();

    skew_symmetric_matrix <<    0,  -v(2),  v(1),
                            v(2),      0, -v(0),
                            -v(1),   v(0),     0;

    return skew_symmetric_matrix;
  }

  Eigen::Matrix3f rodriguesRotationMatrix(Eigen::Vector3f axis, float angle)
  {
    Eigen::Matrix3f skew_symmetric_matrix = Eigen::Matrix3f::Zero();
    Eigen::Matrix3f rotation_matrix = Eigen::Matrix3f::Zero();
    Eigen::Matrix3f Identity_matrix = Eigen::Matrix3f::Identity();

    skew_symmetric_matrix = skewSymmetricMatrix(axis);
    rotation_matrix = Identity_matrix +
                      skew_symmetric_matrix * sin(angle) +
                      skew_symmetric_matrix * skew_symmetric_matrix * (1 - cos(angle));

    return rotation_matrix;
  }

  Eigen::Matrix3f makeRotationMatrix(Eigen::Vector3f rotation_vector)
  {
    Eigen::Matrix3f rotation_matrix;
    Eigen::Vector3f axis;
    float angle;

    angle = rotation_vector.norm();
    axis(0) = rotation_vector(0) / angle;
    axis(1) = rotation_vector(1) / angle;
    axis(2) = rotation_vector(2) / angle;

    rotation_matrix = rodriguesRotationMatrix(axis, angle);
    return rotation_matrix;
  }

  Eigen::Vector3f makeRotationVector(Eigen::Matrix3f rotation_matrix)
  {
    return matrixLogarithm(rotation_matrix);
  }

  Eigen::Vector3f differentialPosition(Eigen::Vector3f desired_position, Eigen::Vector3f present_position)
  {
    Eigen::Vector3f differential_position;
    differential_position = desired_position - present_position;

    return differential_position;
  }

  Eigen::Vector3f differentialOrientation(Eigen::Matrix3f desired_orientation, Eigen::Matrix3f present_orientation)
  {
    Eigen::Vector3f differential_orientation;
    differential_orientation = present_orientation * makeRotationVector(present_orientation.transpose() * desired_orientation);

    return differential_orientation;
  }

  Eigen::VectorXf differentialPose(Eigen::Vector3f desired_position, Eigen::Vector3f present_position, Eigen::Matrix3f desired_orientation, Eigen::Matrix3f present_orientation)
  {
    Eigen::Vector3f differential_position;
    Eigen::Vector3f differential_orientation;
    Eigen::VectorXf  differential_pose(6);

    differential_position = differentialPosition(desired_position, present_position);
    differential_orientation = differentialOrientation(desired_orientation, present_orientation);
    differential_pose << differential_position(0),
                         differential_position(1),
                         differential_position(2),
                         differential_orientation(0),
                         differential_orientation(1),
                         differential_orientation(2);
    return differential_pose;
  }
};

#endif // OMMATH_HPP_
<|endoftext|>


<commit_before>#include <osre/App/AppBase.h>
#include <osre/Properties/Settings.h>
#include <osre/Common/Logger.h>
#include <osre/Scene/GeometryBuilder.h>
#include <osre/Scene/Stage.h>
#include <osre/Scene/Node.h>
#include <osre/RenderBackend/RenderCommon.h>

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>

using namespace OSRE;
using namespace OSRE::RenderBackend;

// to identify local log entries
static const String Tag    = "HelloWorld";

glm::mat4 P = glm::mat4( 1 );
glm::mat4 M = glm::mat4( 1 );
glm::mat4 V = glm::mat4( 1 );

class HelloWorldApp : public App::AppBase {
    Scene::Stage *m_stage;
    TransformMatrixBlock m_transformMatrix;

public:
    HelloWorldApp( int argc, char *argv[] )
    : AppBase( argc, argv )
    , m_stage( nullptr ) {

    }

    virtual ~HelloWorldApp() {

    }

protected:
    virtual bool onCreate( Properties::Settings *config = nullptr ) {
        AppBase::getConfig()->setString( Properties::Settings::WindowsTitle, "HelloWorld!" );

        if( !AppBase::onCreate( config ) ) {
            return false;
        }

        m_stage = AppBase::createStage( "HelloWorld" );
        Scene::Node *geoNode = m_stage->addNode( "geo", nullptr );
        Scene::GeometryBuilder myBuilder;
        RenderBackend::Geometry *geo = myBuilder.createTriangle();
        if( nullptr != geo ) {
			m_transformMatrix.m_model = glm::rotate(m_transformMatrix.m_model, 0.0f, glm::vec3(1, 1, 0));

			Parameter *parameter = Parameter::create("MVP", PT_Mat4);
			::memcpy(parameter->m_data.m_data, glm::value_ptr(m_transformMatrix.m_projection*m_transformMatrix.m_view*m_transformMatrix.m_model), sizeof(glm::mat4));

			geo->m_parameter = parameter;
			geo->m_numParameter++;

			geoNode->addGeometry(geo);
		}

        return true;
    }

    virtual void onUpdate()  {
        m_stage->update();
    }
};

int main( int argc, char *argv[] )  {
    HelloWorldApp myApp( argc, argv );
    if( !myApp.create() ) {
        osre_error(Tag, "Cannot create application instance." );
        return 1;
    }

    // handle events until application will be terminated
    while( myApp.handleEvents() ) {

        // update application data
        myApp.update();

        // request next frame rendering
        myApp.requestNextFrame();
    }
    myApp.destroy();

    return 0;
}
<commit_msg>Sample: remove unused code.<commit_after>#include <osre/App/AppBase.h>
#include <osre/Properties/Settings.h>
#include <osre/Common/Logger.h>
#include <osre/Scene/GeometryBuilder.h>
#include <osre/Scene/Stage.h>
#include <osre/Scene/Node.h>
#include <osre/RenderBackend/RenderCommon.h>

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>

using namespace OSRE;
using namespace OSRE::RenderBackend;

// to identify local log entries
static const String Tag    = "HelloWorld";

class HelloWorldApp : public App::AppBase {
    Scene::Stage *m_stage;
    TransformMatrixBlock m_transformMatrix;

public:
    HelloWorldApp( int argc, char *argv[] )
    : AppBase( argc, argv )
    , m_stage( nullptr ) {

    }

    virtual ~HelloWorldApp() {

    }

protected:
    virtual bool onCreate( Properties::Settings *config = nullptr ) {
        AppBase::getConfig()->setString( Properties::Settings::WindowsTitle, "HelloWorld!" );

        if( !AppBase::onCreate( config ) ) {
            return false;
        }

        m_stage = AppBase::createStage( "HelloWorld" );
        Scene::Node *geoNode = m_stage->addNode( "geo", nullptr );
        Scene::GeometryBuilder myBuilder;
        RenderBackend::Geometry *geo = myBuilder.createTriangle();
        if( nullptr != geo ) {
			m_transformMatrix.m_model = glm::rotate(m_transformMatrix.m_model, 0.0f, glm::vec3(1, 1, 0));

			Parameter *parameter = Parameter::create("MVP", PT_Mat4);
			::memcpy(parameter->m_data.m_data, glm::value_ptr(m_transformMatrix.m_projection*m_transformMatrix.m_view*m_transformMatrix.m_model), sizeof(glm::mat4));

			geo->m_parameter = parameter;
			geo->m_numParameter++;

			geoNode->addGeometry(geo);
		}

        return true;
    }

    virtual void onUpdate()  {
        m_stage->update();
    }
};

int main( int argc, char *argv[] )  {
    HelloWorldApp myApp( argc, argv );
    if( !myApp.create() ) {
        osre_error(Tag, "Cannot create application instance." );
        return 1;
    }

    // handle events until application will be terminated
    while( myApp.handleEvents() ) {

        // update application data
        myApp.update();

        // request next frame rendering
        myApp.requestNextFrame();
    }
    myApp.destroy();

    return 0;
}
<|endoftext|>