text:
#include "completeness_checker.hpp"

#include "../contrib/tinydir.h" // for tinydir_next

#include "../db/storage.hpp"
#include "../instance/instance.hpp"
#include "../io/jsonreader.hpp"
#include "../util/autotuneconfig.hpp"

#include "../db/db_objects-odb-sqlite.hxx"
#include "../db/db_objects-odb.hxx"

/*
 * Headers to get solvers
 */
#include "../manager/solvers.hpp"
#include "solver_headers.hpp"

#include "../baselines/earlyscheduler.hpp"
#include "../util/randomizer.hpp"
#include "../util/solverconfig.hpp"

#include <boost/hana.hpp>
#include <boost/hana/assert.hpp>
#include <boost/hana/core/to.hpp>
#include <boost/hana/equal.hpp>
#include <boost/hana/tuple.hpp>
#include <boost/hana/type.hpp>
namespace hana = boost::hana;

CompletenessChecker::CompletenessChecker(bool autotune_mode_in)
    : autotune_mode(autotune_mode_in), l("CCHECKER")
{}

void
CompletenessChecker::run(int argc, const char ** argv)
{
	if (!this->autotune_mode) {
		Configuration & cfg = *Configuration::get();
		cfg.parse_cmdline(argc, argv);

		this->storage_path = cfg.get_storage_path();
		this->config_file = cfg.get_algo_config_file();
		this->instance_dir = cfg.get_instance_dir();

		this->generate_scfgs_tcpspsuite();
	} else {
		AutotuneConfig & acfg = *AutotuneConfig::get();
		acfg.parse_cmdline(argc, argv);
		Configuration & cfg = *Configuration::get();

		this->storage_path = cfg.get_storage_path();
		this->instance_dir = cfg.get_instance_dir();

		this->generate_scfgs_autotune();
	}
	this->read_instances();

	this->check();
}

void
CompletenessChecker::generate_scfgs_tcpspsuite()
{
	Configuration & cfg = *Configuration::get();
	cfg.read_solver_config(this->config_file);
	this->scfgs = cfg.solver_configs();
}

void
CompletenessChecker::generate_scfgs_autotune()
{
	AutotuneConfig & acfg = *AutotuneConfig::get();
	do {
		this->scfgs.push_back(acfg.generateConfig());
	} while (acfg.nextConfig());
}

void
CompletenessChecker::check()
{
	Storage storage(this->storage_path);

	/*
	 * Read all the instances
	 */
	std::vector<std::pair<std::shared_ptr<Instance>, std::string>>
	    parsed_instances;
	for (std::string instance_fname : this->instances) {
		JsonReader reader(instance_fname);
		std::shared_ptr<Instance> instance{reader.parse()};
		parsed_instances.push_back({instance, instance_fname});
	}

	for (const SolverConfig & scfg : this->scfgs) {
		/*
		 * See what we have for this solver config
		 */
		using ResultId = std::pair<std::string, std::string>;
		std::set<ResultId> computed_results;
		auto results_for_scfg = storage.get_results_for_config(scfg);
		for (auto result : results_for_scfg) {
			computed_results.insert({result->instance, result->algorithm});
		}

		for (auto & instance_pair : parsed_instances) {
			std::shared_ptr<Instance> instance = instance_pair.first;

			constexpr unsigned int max_N = solvers::get_free_N<void>() - 1;
			// get the set of registered solvers
			auto registered_solvers = solvers::registry_hook<max_N>{}();

			hana::for_each(registered_solvers, [&](auto solver_cls) {
				if (scfg.match(decltype(solver_cls)::type::get_id())) {
					// Found a combination of solver, solver-config and instance!
					ResultId required_result = {instance->get_id(),
					                            decltype(solver_cls)::type::get_id()};
					if (computed_results.find(required_result) ==
					    computed_results.end()) {
						BOOST_LOG(l.w()) << "--- Found a missing result:";
						BOOST_LOG(l.w()) << "       Instance ID:  " << instance->get_id();
						BOOST_LOG(l.w()) << "       Algorithm:    "
						                 << decltype(solver_cls)::type::get_id();
						BOOST_LOG(l.w()) << "       Config:    ";
						for (const auto & cfg_kv : scfg.get_kvs()) {
							std::stringstream buf;
							buf << cfg_kv.second;
							BOOST_LOG(l.w())
							    << "            " << cfg_kv.first << "\t: " << buf.str();
						}
					}
				}
			});
		}
	}
}

void
CompletenessChecker::read_instances()
{
	tinydir_dir dir;
	std::vector<std::string> directories;
	directories.push_back(this->instance_dir);

	while (!directories.empty()) {
		std::string directory = directories.back();
		directories.pop_back();

		tinydir_open(&dir, directory.c_str());

		while (dir.has_next) {
			tinydir_file file;
			tinydir_readfile(&dir, &file);

			std::string filename(file.path);

			if (filename.substr(filename.size() - 1, 1) == ".") {
				tinydir_next(&dir);
				continue;
			}

			if (file.is_dir) {
				directories.push_back(filename);
			} else {
				std::string extension = filename.substr(filename.size() - 5, 5);
				if (extension.compare(".json") == 0) {
					this->instances.push_back(filename);
					BOOST_LOG(l.i()) << "Instance found: " << filename;
				}
			}

			tinydir_next(&dir);
		}
	}
}

int
main(int argc, const char ** argv)
{
	std::vector<std::string> remaining_args;

	enum class MODE
	{
		UNDECIDED,
		AUTOTUNE,
		TCPSPSUITE
	};

	MODE m{MODE::UNDECIDED};

	for (int i = 0; i < argc; ++i) {
		std::string arg = argv[i];

		if (arg == "tcpspsuite") {
			m = MODE::TCPSPSUITE;
		} else if (arg == "autotune") {
			m = MODE::AUTOTUNE;
		} else {
			remaining_args.push_back(arg);
		}
	}

	const char ** remaining_argv =
	    (const char **)malloc(sizeof(const char *) * remaining_args.size());

	for (unsigned int i = 0; i < remaining_args.size(); ++i) {
		remaining_argv[i] = remaining_args[i].c_str();
	}

	bool autotune_mode = (m == MODE::AUTOTUNE);
	CompletenessChecker checker(autotune_mode);
	checker.run((int)remaining_args.size(), remaining_argv);

	return 0;
}

ext: cpp

max_stars_repo_name: kit-algo/TCPSPSuite

max_issues_repo_name: kit-algo/TCPSPSuite

max_forks_repo_name: kit-algo/TCPSPSuite


text:
/*
  Copyright (c) 2015, Matthew H. Reilly (kb1vc)
  All rights reserved.

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

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

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

#include <iostream>
#include <stdlib.h>
#include <unistd.h>
#include <boost/format.hpp>
#include <string>
#include <list>
#include <uhd/usrp/multi_usrp.hpp>
#include <vector>
#include <string>
#include <boost/foreach.hpp>
#include <boost/format.hpp>

#include <uhd/utils/safe_main.hpp>
#include <uhd/version.hpp>
#include <uhd/device.hpp>
#include <uhd/types/ranges.hpp>
#include <uhd/property_tree.hpp>
#include <boost/algorithm/string.hpp> //for split
#include <uhd/usrp/dboard_id.hpp>
#include <uhd/usrp/mboard_eeprom.hpp>
#include <uhd/usrp/dboard_eeprom.hpp>

std::string getMbName(uhd::usrp::multi_usrp::sptr usrp)
{
  uhd::property_tree::sptr tree = usrp->get_device()->get_tree();
  std::string mbname = tree->list("/mboards").at(0);
  return tree->access<std::string>("/mboards/" + mbname + "/name").get();
}

void dumpProps(uhd::usrp::multi_usrp::sptr usrp)
{
  uhd::property_tree::sptr tree = usrp->get_device()->get_tree();
  std::string mbname = tree->list("/mboards").at(0);

  uhd::usrp::mboard_eeprom_t eeprom = tree->access<uhd::usrp::mboard_eeprom_t>("/mboards/" + mbname + "/eeprom").get();
  BOOST_FOREACH(const std::string & key, eeprom.keys()) {
    if( eeprom[key].empty() ) {
      std::cerr << boost::format("Empty key [%s]\n") % key;
    }
    else {
      std::cerr << boost::format(" eeprom[%s] = [%s]\n") % key % eeprom[key];
    }
  }

  std::cerr << boost::format("went the direct route = [%s]\n")
    % tree->access<uhd::usrp::mboard_eeprom_t>("/mboards/" + mbname + "/eeprom").get()["ip-addr"];
}

int main(int argc, char ** argv)
{
  if(argc < 2) {
    std::cerr << "Usage:  IntN_FreqTable  dev-arg-string" << std::endl;
    exit(-1);
  }

  std::string devaddr(argv[1]);
  uhd::device_addr_t rad(devaddr);

  uhd::usrp::multi_usrp::sptr usrp;
  // make the device.
  usrp = uhd::usrp::multi_usrp::make(rad);

  // now do the RX front end LO experiment.
  uhd::freq_range_t rx_rf_freq_range, tx_rf_freq_range; ///< property of the device -- what is the min/maximum RX frequency?
  rx_rf_freq_range = usrp->get_rx_freq_range();
  tx_rf_freq_range = usrp->get_tx_freq_range();

  uhd::tune_result_t tunres_int;

  // Now sweep from min to max freq, and find the steps along the way.
  double ff_incr = 1.0e6; // start with a small step...
  double r_st, r_en, target;

  // now look through the range
  for(int i = 0; i < 2; i++) {
    r_st = (i == 0) ? rx_rf_freq_range.start() : tx_rf_freq_range.start();;
    r_en = (i == 0) ? rx_rf_freq_range.stop() : tx_rf_freq_range.stop();;

    // first find the first setting.
    uhd::tune_request_t treq(r_st);
    treq.args = uhd::device_addr_t("mode_n=integer");
    tunres_int = (i == 0) ? usrp->set_rx_freq(treq) : usrp->set_tx_freq(treq);
    target = tunres_int.actual_rf_freq;

    for(double ff = target + ff_incr;
	ff < r_en;
	ff += ff_incr) {
      uhd::tune_request_t treq(ff);
      treq.rf_freq = ff;
      treq.rf_freq_policy = uhd::tune_request_t::POLICY_MANUAL;
      treq.args = uhd::device_addr_t("mode_n=integer");
      tunres_int = (i == 0) ? usrp->set_rx_freq(treq) : usrp->set_tx_freq(treq);

      std::string mode = (i == 0) ? "RX" : "TX";

      std::cerr << boost::format("%s Range Check RF_actual %lf DDC = %lf target = %lf requested RF = %lf ddc = %lf\n")
	% mode
	% (1e-6 * tunres_int.actual_rf_freq)
	% (1e-6 * tunres_int.actual_dsp_freq)
	% (1e-6 * ff)
	% (1e-6 * treq.rf_freq)
	% (1e-6 * treq.dsp_freq);

      if(target != tunres_int.actual_rf_freq) {
	// we found a new one...
	r_st = tunres_int.actual_rf_freq;
	target = r_st;
      }
    }
  }

}

ext: cxx


text:
/*
 * Manager.cpp
 *
 *  Created on: 23 Oct 2015
 *      Author: hieu
 */
#include <boost/foreach.hpp>
#include <cstdlib>
#include <vector>
#include <sstream>
#include "../System.h"
#include "../TranslationModel/PhraseTable.h"
#include "Manager.h"
#include "InputPath.h"
#include "Hypothesis.h"
#include "TargetPhraseImpl.h"
#include "ActiveChart.h"
#include "Sentence.h"

#include "nbest/KBestExtractor.h"

using namespace std;

namespace Moses2
{

namespace SCFG
{

Manager::Manager(System &sys, const TranslationTask &task,
                 const std::string &inputStr, long translationId)
  :ManagerBase(sys, task, inputStr, translationId)
{

}

Manager::~Manager()
{

}

void Manager::Decode()
{
  // init pools etc
  //cerr << "START InitPools()" << endl;
  InitPools();
  //cerr << "START ParseInput()" << endl;

  FactorCollection &vocab = system.GetVocab();
  m_input = Sentence::CreateFromString(GetPool(), vocab, system, m_inputStr,
                                       m_translationId);

  const SCFG::Sentence &sentence = static_cast<const SCFG::Sentence&>(GetInput());

  size_t inputSize = sentence.GetSize();
  //cerr << "inputSize=" << inputSize << endl;

  m_inputPaths.Init(sentence, *this);
  //cerr << "CREATED m_inputPaths" << endl;

  m_stacks.Init(*this, inputSize);
  //cerr << "CREATED m_stacks" << endl;

  for (int startPos = inputSize - 1; startPos >= 0; --startPos) {
    //cerr << endl << "startPos=" << startPos << endl;
    SCFG::InputPath &initPath = *m_inputPaths.GetMatrix().GetValue(startPos, 0);

    //cerr << "BEFORE InitActiveChart=" << initPath.Debug(system) << endl;
    InitActiveChart(initPath);
    //cerr << "AFTER InitActiveChart=" << initPath.Debug(system) << endl;

    int maxPhraseSize = inputSize - startPos + 1;
    for (int phraseSize = 1; phraseSize < maxPhraseSize; ++phraseSize) {
      //cerr << endl << "phraseSize=" << phraseSize << endl;

      SCFG::InputPath &path = *m_inputPaths.GetMatrix().GetValue(startPos, phraseSize);

      Stack &stack = m_stacks.GetStack(startPos, phraseSize);

      //cerr << "BEFORE LOOKUP path=" << path.Debug(system) << endl;
      Lookup(path);
      //cerr << "AFTER LOOKUP path="  << path.Debug(system) << endl;
      Decode(path, stack);
      //cerr << "AFTER DECODE path=" << path.Debug(system) << endl;

      LookupUnary(path);
      //cerr << "AFTER LookupUnary path=" << path.Debug(system) << endl;

      //cerr << "#rules=" << path.GetNumRules() << endl;
    }
  }

  /*
  const Stack *stack;
  stack = &m_stacks.GetStack(0, 5);
  cerr << "stack 0,12:" << stack->Debug(system) << endl;
  */
  //m_stacks.OutputStacks();
}

void Manager::InitActiveChart(SCFG::InputPath &path)
{
  size_t numPt = system.mappings.size();
  //cerr << "numPt=" << numPt << endl;

  for (size_t i = 0; i < numPt; ++i) {
    const PhraseTable &pt = *system.mappings[i];
    //cerr << "START InitActiveChart" << endl;
    pt.InitActiveChart(GetPool(), *this, path);
    //cerr << "FINISHED InitActiveChart" << endl;
  }
}

void Manager::Lookup(SCFG::InputPath &path)
{
  size_t numPt = system.mappings.size();
  //cerr << "numPt=" << numPt << endl;

  for (size_t i = 0; i < numPt; ++i) {
    const PhraseTable &pt = *system.mappings[i];
    size_t maxChartSpan = system.maxChartSpans[i];
    pt.Lookup(GetPool(), *this, maxChartSpan, m_stacks, path);
  }

  /*
  size_t tpsNum = path.targetPhrases.GetSize();
  if (tpsNum) {
    cerr << tpsNum << " " << path << endl;
  }
  */
}

void Manager::LookupUnary(SCFG::InputPath &path)
{
  size_t numPt = system.mappings.size();
  //cerr << "numPt=" << numPt << endl;

  for (size_t i = 0; i < numPt; ++i) {
    const PhraseTable &pt = *system.mappings[i];
    pt.LookupUnary(GetPool(), *this, m_stacks, path);
  }

  /*
  size_t tpsNum = path.targetPhrases.GetSize();
  if (tpsNum) {
    cerr << tpsNum << " " << path << endl;
  }
  */
}

///////////////////////////////////////////////////////////////
// CUBE-PRUNING
///////////////////////////////////////////////////////////////
void Manager::Decode(SCFG::InputPath &path, Stack &stack)
{
  // clear cube pruning data
  //std::vector<QueueItem*> &container = Container(m_queue);
  //container.clear();
  Recycler<HypothesisBase*> &hypoRecycler = GetHypoRecycle();
  while (!m_queue.empty()) {
    QueueItem *item = m_queue.top();
    m_queue.pop();
    // recycle unused hypos from queue
    Hypothesis *hypo = item->hypo;
    hypoRecycler.Recycle(hypo);

    // recycle queue item
    m_queueItemRecycler.push_back(item);
  }

  m_seenPositions.clear();

  // init queue
  BOOST_FOREACH(const InputPath::Coll::value_type &valPair, path.targetPhrases) {
    const SymbolBind &symbolBind = valPair.first;
    const SCFG::TargetPhrases &tps = *valPair.second;

    CreateQueue(path, symbolBind, tps);
  }

  // MAIN LOOP
  size_t pops = 0;
  while (!m_queue.empty() && pops < system.options.cube.pop_limit) {
    //cerr << "pops=" << pops << endl;
    QueueItem *item = m_queue.top();
    m_queue.pop();

    // add hypo to stack
    Hypothesis *hypo = item->hypo;

    //cerr << "hypo=" << *hypo << " " << endl;
    stack.Add(hypo, GetHypoRecycle(), arcLists);
    //cerr << "Added " << *hypo << " " << endl;

    item->CreateNext(GetSystemPool(), GetPool(), *this, m_queue, m_seenPositions, path);
    //cerr << "Created next " << endl;
    m_queueItemRecycler.push_back(item);

    ++pops;
  }

}

void Manager::CreateQueue(
  const SCFG::InputPath &path,
  const SymbolBind &symbolBind,
  const SCFG::TargetPhrases &tps)
{
  MemPool &pool = GetPool();

  SeenPosition *seenItem = new (pool.Allocate<SeenPosition>()) SeenPosition(pool, symbolBind, tps, symbolBind.numNT);
  bool unseen = m_seenPositions.Add(seenItem);
  assert(unseen);

  QueueItem *item = QueueItem::Create(GetPool(), *this);
  item->Init(GetPool(), symbolBind, tps, seenItem->hypoIndColl);
  for (size_t i = 0; i < symbolBind.coll.size(); ++i) {
    const SymbolBindElement &ele = symbolBind.coll[i];
    if (ele.hypos) {
      const Moses2::Hypotheses *hypos = ele.hypos;
      item->AddHypos(*hypos);
    }
  }

  item->CreateHypo(GetSystemPool(), *this, path, symbolBind);

  //cerr << "hypo=" << item->hypo->Debug(system) << endl;

  m_queue.push(item);
}

///////////////////////////////////////////////////////////////
// NON CUBE-PRUNING
///////////////////////////////////////////////////////////////
/*
void Manager::Decode(SCFG::InputPath &path, Stack &stack)
{
  //cerr << "path=" << path << endl;

  boost::unordered_map<SCFG::SymbolBind, SCFG::TargetPhrases*>::const_iterator iterOuter;
  for (iterOuter = path.targetPhrases->begin(); iterOuter != path.targetPhrases->end(); ++iterOuter) {
    const SCFG::SymbolBind &symbolBind = iterOuter->first;

    const SCFG::TargetPhrases &tps = *iterOuter->second;
    //cerr << "symbolBind=" << symbolBind << " tps=" << tps.GetSize() << endl;

    SCFG::TargetPhrases::const_iterator iter;
    for (iter = tps.begin(); iter != tps.end(); ++iter) {
      const SCFG::TargetPhraseImpl &tp = **iter;
      //cerr << "tp=" << tp << endl;
      ExpandHypo(path, symbolBind, tp, stack);
    }
  }
}
*/

void Manager::ExpandHypo(
  const SCFG::InputPath &path,
  const SCFG::SymbolBind &symbolBind,
  const SCFG::TargetPhraseImpl &tp,
  Stack &stack)
{
  Recycler<HypothesisBase*> &hypoRecycler = GetHypoRecycle();

  std::vector<const SymbolBindElement*> ntEles = symbolBind.GetNTElements();
  Vector<size_t> prevHyposIndices(GetPool(), symbolBind.numNT);
  assert(ntEles.size() == symbolBind.numNT);
  //cerr << "ntEles:" << ntEles.size() << endl;

  size_t ind = 0;
  while (IncrPrevHypoIndices(prevHyposIndices, ind, ntEles)) {
    SCFG::Hypothesis *hypo = SCFG::Hypothesis::Create(GetSystemPool(), *this);
    hypo->Init(*this, path, symbolBind, tp, prevHyposIndices);
    hypo->EvaluateWhenApplied();

    stack.Add(hypo, hypoRecycler, arcLists);

    ++ind;
  }
}

bool Manager::IncrPrevHypoIndices(
  Vector<size_t> &prevHyposIndices,
  size_t ind,
  const std::vector<const SymbolBindElement*> ntEles)
{
  if (ntEles.size() == 0) {
    // no nt. Do the 1st
    return ind ? false : true;
  }

  size_t numHypos = 0;

  //cerr << "IncrPrevHypoIndices:" << ind << " " << ntEles.size() << " ";
  for (size_t i = 0; i < ntEles.size() - 1; ++i) {
    const SymbolBindElement &ele = *ntEles[i];
    const Hypotheses &hypos = *ele.hypos;
    numHypos = hypos.size();

    std::div_t divRet = std::div((int)ind, (int)numHypos);
    ind = divRet.quot;

    size_t hypoInd = divRet.rem;
    prevHyposIndices[i] = hypoInd;
    //cerr << "(" << i << "," << ind << "," << numHypos << "," << hypoInd << ")";
  }

  // last
  prevHyposIndices.back() = ind;

  // check if last is over limit
  const SymbolBindElement &ele = *ntEles.back();
  const Hypotheses &hypos = *ele.hypos;
  numHypos = hypos.size();

  //cerr << "(" << (ntEles.size() - 1) << "," << ind << "," << numHypos << ","  << ind << ")";
  //cerr << endl;

  if (ind >= numHypos) {
    return false;
  } else {
    return true;
  }
}

std::string Manager::OutputBest() const
{
  string out;
  const Stack &lastStack = m_stacks.GetLastStack();
  const SCFG::Hypothesis *bestHypo = lastStack.GetBestHypo();

  if (bestHypo) {
    //cerr << "BEST TRANSLATION: " << bestHypo << bestHypo->Debug(system) << endl;
    //cerr << " " << out.str() << endl;
    stringstream outStrm;
    Moses2::FixPrecision(outStrm);

    bestHypo->OutputToStream(outStrm);

    out = outStrm.str();
    out = out.substr(4, out.size() - 10);

    if (system.options.output.ReportHypoScore) {
      out = SPrint(bestHypo->GetScores().GetTotalScore()) + " " + out;
    }
  } else {
    if (system.options.output.ReportHypoScore) {
      out = "0 ";
    }

    //cerr << "NO TRANSLATION " << GetTranslationId() << endl;
  }

  return out;
}

std::string Manager::OutputNBest()
{
  stringstream out;
  //Moses2::FixPrecision(out);

  arcLists.Sort();
  //cerr << "arcs=" << arcLists.Debug(system) << endl;

  KBestExtractor extractor(*this);
  extractor.OutputToStream(out);

  return out.str();
}

std::string Manager::OutputTransOpt()
{
  const Stack &lastStack = m_stacks.GetLastStack();
  const SCFG::Hypothesis *bestHypo = lastStack.GetBestHypo();

  if (bestHypo) {
    stringstream outStrm;
    bestHypo->OutputTransOpt(outStrm);
    return outStrm.str();
  } else {
    return "";
  }
}

} // namespace
}


text:
///////////////////////////////////////////////////////////////////////////////
// BSD 3-Clause License
//
// Copyright (C) 2018-2020, LAAS-CNRS, University of Edinburgh
// Copyright note valid unless otherwise stated in individual files.
// All rights reserved.
///////////////////////////////////////////////////////////////////////////////

#ifndef BINDINGS_PYTHON_CROCODDYL_UTILS_MAP_CONVERTER_HPP_
#define BINDINGS_PYTHON_CROCODDYL_UTILS_MAP_CONVERTER_HPP_

#include <Eigen/Dense>
#include <map>
#include <boost/python/stl_iterator.hpp>
#include <boost/python/to_python_converter.hpp>

namespace crocoddyl {
namespace python {

namespace bp = boost::python;

/// @note Registers converter from a provided type to the python
///       iterable type to the.
template <class K, class V, bool NoProxy = true>
struct map_to_dict {
  static PyObject* convert(const std::map<K, V>& map) {
    bp::dict* dict = new boost::python::dict();
    typename std::map<K, V>::const_iterator it;
    for (it = map.begin(); it != map.end(); ++it) {
      if (NoProxy) {
        dict->setdefault(it->first, boost::ref(it->second));
      } else {
        dict->setdefault(it->first, it->second);
      }
    }
    return dict->ptr();
  }
  static PyTypeObject const* get_pytype() { return &PyDict_Type; }
};

/// Conversion from dict to map solution proposed in
/// https://stackoverflow.com/questions/6116345/boostpython-possible-to-automatically-convert-from-dict-stdmap
/// This template encapsulates the conversion machinery.
template <typename key_t, typename val_t>
struct dict_to_map {
  /// The type of the map we convert the Python dict into
  typedef std::map<key_t, val_t> map_t;

  dict_to_map& from_python() {
    boost::python::converter::registry::push_back(&dict_to_map::convertible, &dict_to_map::construct,
                                                  boost::python::type_id<map_t>());
    // Support chaining.
    return *this;
  }

  /// Check if conversion is possible
  static void* convertible(PyObject* object) { return PyObject_GetIter(object) ? object : NULL; }

  /// Perform the conversion
  static void construct(PyObject* objptr, boost::python::converter::rvalue_from_python_stage1_data* data) {
    // convert the PyObject pointed to by `objptr` to a boost::python::dict
    boost::python::handle<> objhandle(boost::python::borrowed(objptr));  // "smart ptr"
    boost::python::dict d(objhandle);

    // get a pointer to memory into which we construct the map
    // this is provided by the Python runtime
    void* storage =
        reinterpret_cast<boost::python::converter::rvalue_from_python_storage<map_t>*>(data)->storage.bytes;

    // placement-new allocate the result
    new (storage) map_t();

    // iterate over the dictionary `d`, fill up the map `m`
    map_t& m(*(static_cast<map_t*>(storage)));
    boost::python::list keys(d.keys());
    int keycount(static_cast<int>(boost::python::len(keys)));
    for (int i = 0; i < keycount; ++i) {
      // get the key
      boost::python::object keyobj(keys[i]);
      boost::python::extract<key_t> keyproxy(keyobj);
      if (!keyproxy.check()) {
        PyErr_SetString(PyExc_KeyError, "Bad key type");
        boost::python::throw_error_already_set();
      }
      key_t key = keyproxy();

      // get the corresponding value
      boost::python::object valobj(d[keyobj]);
      boost::python::extract<val_t> valproxy(valobj);
      if (!valproxy.check()) {
        PyErr_SetString(PyExc_ValueError, "Bad value type");
        boost::python::throw_error_already_set();
      }
      val_t val = valproxy();
      m[key] = val;
    }

    // remember the location for later
    data->convertible = storage;
  }
};

}  // namespace python
}  // namespace crocoddyl

#endif  // BINDINGS_PYTHON_CROCODDYL_UTILS_MAP_CONVERTER_HPP_

ext: hpp

max_stars_repo_name: paLeziart/crocoddyl

max_issues_repo_name: paLeziart/crocoddyl

max_forks_repo_name: paLeziart/crocoddyl


text:
// copyright (c) 2009-2010 satoshi nakamoto
// copyright (c) 2009-2014 the moorecoin core developers
// distributed under the mit software license, see the accompanying
// file copying or http://www.opensource.org/licenses/mit-license.php.

#include "wallet/walletdb.h"

#include "base58.h"
#include "consensus/validation.h"
#include "main.h"
#include "protocol.h"
#include "serialize.h"
#include "sync.h"
#include "util.h"
#include "utiltime.h"
#include "wallet/wallet.h"

#include <boost/filesystem.hpp>
#include <boost/foreach.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/thread.hpp>

using namespace std;

static uint64_t naccountingentrynumber = 0;

//
// cwalletdb
//

bool cwalletdb::writename(const string& straddress, const string& strname)
{
    nwalletdbupdated++;
    return write(make_pair(string("name"), straddress), strname);
}

bool cwalletdb::erasename(const string& straddress)
{
    // this should only be used for sending addresses, never for receiving addresses,
    // receiving addresses must always have an address book entry if they're not change return.
    nwalletdbupdated++;
    return erase(make_pair(string("name"), straddress));
}

bool cwalletdb::writepurpose(const string& straddress, const string& strpurpose)
{
    nwalletdbupdated++;
    return write(make_pair(string("purpose"), straddress), strpurpose);
}

bool cwalletdb::erasepurpose(const string& strpurpose)
{
    nwalletdbupdated++;
    return erase(make_pair(string("purpose"), strpurpose));
}

bool cwalletdb::writetx(uint256 hash, const cwallettx& wtx)
{
    nwalletdbupdated++;
    return write(std::make_pair(std::string("tx"), hash), wtx);
}

bool cwalletdb::erasetx(uint256 hash)
{
    nwalletdbupdated++;
    return erase(std::make_pair(std::string("tx"), hash));
}

bool cwalletdb::writekey(const cpubkey& vchpubkey, const cprivkey& vchprivkey, const ckeymetadata& keymeta)
{
    nwalletdbupdated++;

    if (!write(std::make_pair(std::string("keymeta"), vchpubkey),
               keymeta, false))
        return false;

    // hash pubkey/privkey to accelerate wallet load
    std::vector<unsigned char> vchkey;
    vchkey.reserve(vchpubkey.size() + vchprivkey.size());
    vchkey.insert(vchkey.end(), vchpubkey.begin(), vchpubkey.end());
    vchkey.insert(vchkey.end(), vchprivkey.begin(), vchprivkey.end());

    return write(std::make_pair(std::string("key"), vchpubkey), std::make_pair(vchprivkey, hash(vchkey.begin(), vchkey.end())), false);
}

bool cwalletdb::writecryptedkey(const cpubkey& vchpubkey,
                                const std::vector<unsigned char>& vchcryptedsecret,
                                const ckeymetadata &keymeta)
{
    const bool feraseunencryptedkey = true;
    nwalletdbupdated++;

    if (!write(std::make_pair(std::string("keymeta"), vchpubkey),
            keymeta))
        return false;

    if (!write(std::make_pair(std::string("ckey"), vchpubkey), vchcryptedsecret, false))
        return false;
    if (feraseunencryptedkey)
    {
        erase(std::make_pair(std::string("key"), vchpubkey));
        erase(std::make_pair(std::string("wkey"), vchpubkey));
    }
    return true;
}

bool cwalletdb::writemasterkey(unsigned int nid, const cmasterkey& kmasterkey)
{
    nwalletdbupdated++;
    return write(std::make_pair(std::string("mkey"), nid), kmasterkey, true);
}

bool cwalletdb::writecscript(const uint160& hash, const cscript& redeemscript)
{
    nwalletdbupdated++;
    return write(std::make_pair(std::string("cscript"), hash), redeemscript, false);
}

bool cwalletdb::writewatchonly(const cscript &dest)
{
    nwalletdbupdated++;
    return write(std::make_pair(std::string("watchs"), dest), '1');
}

bool cwalletdb::erasewatchonly(const cscript &dest)
{
    nwalletdbupdated++;
    return erase(std::make_pair(std::string("watchs"), dest));
}

bool cwalletdb::writebestblock(const cblocklocator& locator)
{
    nwalletdbupdated++;
    return write(std::string("bestblock"), locator);
}

bool cwalletdb::readbestblock(cblocklocator& locator)
{
    return read(std::string("bestblock"), locator);
}

bool cwalletdb::writeorderposnext(int64_t norderposnext)
{
    nwalletdbupdated++;
    return write(std::string("orderposnext"), norderposnext);
}

bool cwalletdb::writedefaultkey(const cpubkey& vchpubkey)
{
    nwalletdbupdated++;
    return write(std::string("defaultkey"), vchpubkey);
}

bool cwalletdb::readpool(int64_t npool, ckeypool& keypool)
{
    return read(std::make_pair(std::string("pool"), npool), keypool);
}

bool cwalletdb::writepool(int64_t npool, const ckeypool& keypool)
{
    nwalletdbupdated++;
    return write(std::make_pair(std::string("pool"), npool), keypool);
}

bool cwalletdb::erasepool(int64_t npool)
{
    nwalletdbupdated++;
    return erase(std::make_pair(std::string("pool"), npool));
}

bool cwalletdb::writeminversion(int nversion)
{
    return write(std::string("minversion"), nversion);
}

bool cwalletdb::readaccount(const string& straccount, caccount& account)
{
    account.setnull();
    return read(make_pair(string("acc"), straccount), account);
}

bool cwalletdb::writeaccount(const string& straccount, const caccount& account)
{
    return write(make_pair(string("acc"), straccount), account);
}

bool cwalletdb::writeaccountingentry(const uint64_t naccentrynum, const caccountingentry& acentry)
{
    return write(std::make_pair(std::string("acentry"), std::make_pair(acentry.straccount, naccentrynum)), acentry);
}

bool cwalletdb::writeaccountingentry(const caccountingentry& acentry)
{
    return writeaccountingentry(++naccountingentrynumber, acentry);
}

camount cwalletdb::getaccountcreditdebit(const string& straccount)
{
    list<caccountingentry> entries;
    listaccountcreditdebit(straccount, entries);

    camount ncreditdebit = 0;
    boost_foreach (const caccountingentry& entry, entries)
        ncreditdebit += entry.ncreditdebit;

    return ncreditdebit;
}

void cwalletdb::listaccountcreditdebit(const string& straccount, list<caccountingentry>& entries)
{
    bool fallaccounts = (straccount == "*");

    dbc* pcursor = getcursor();
    if (!pcursor)
        throw runtime_error("cwalletdb::listaccountcreditdebit(): cannot create db cursor");
    unsigned int fflags = db_set_range;
    while (true)
    {
        // read next record
        cdatastream sskey(ser_disk, client_version);
        if (fflags == db_set_range)
            sskey << std::make_pair(std::string("acentry"), std::make_pair((fallaccounts ? string("") : straccount), uint64_t(0)));
        cdatastream ssvalue(ser_disk, client_version);
        int ret = readatcursor(pcursor, sskey, ssvalue, fflags);
        fflags = db_next;
        if (ret == db_notfound)
            break;
        else if (ret != 0)
        {
            pcursor->close();
            throw runtime_error("cwalletdb::listaccountcreditdebit(): error scanning db");
        }

        // unserialize
        string strtype;
        sskey >> strtype;
        if (strtype != "acentry")
            break;
        caccountingentry acentry;
        sskey >> acentry.straccount;
        if (!fallaccounts && acentry.straccount != straccount)
            break;

        ssvalue >> acentry;
        sskey >> acentry.nentryno;
        entries.push_back(acentry);
    }

    pcursor->close();
}

dberrors cwalletdb::reordertransactions(cwallet* pwallet)
{
    lock(pwallet->cs_wallet);
    // old wallets didn't have any defined order for transactions
    // probably a bad idea to change the output of this

    // first: get all cwallettx and caccountingentry into a sorted-by-time multimap.
    typedef pair<cwallettx*, caccountingentry*> txpair;
    typedef multimap<int64_t, txpair > txitems;
    txitems txbytime;

    for (map<uint256, cwallettx>::iterator it = pwallet->mapwallet.begin(); it != pwallet->mapwallet.end(); ++it)
    {
        cwallettx* wtx = &((*it).second);
        txbytime.insert(make_pair(wtx->ntimereceived, txpair(wtx, (caccountingentry*)0)));
    }
    list<caccountingentry> acentries;
    listaccountcreditdebit("", acentries);
    boost_foreach(caccountingentry& entry, acentries)
    {
        txbytime.insert(make_pair(entry.ntime, txpair((cwallettx*)0, &entry)));
    }

    int64_t& norderposnext = pwallet->norderposnext;
    norderposnext = 0;
    std::vector<int64_t> norderposoffsets;
    for (txitems::iterator it = txbytime.begin(); it != txbytime.end(); ++it)
    {
        cwallettx *const pwtx = (*it).second.first;
        caccountingentry *const pacentry = (*it).second.second;
        int64_t& norderpos = (pwtx != 0) ? pwtx->norderpos : pacentry->norderpos;

        if (norderpos == -1)
        {
            norderpos = norderposnext++;
            norderposoffsets.push_back(norderpos);

            if (pwtx)
            {
                if (!writetx(pwtx->gethash(), *pwtx))
                    return db_load_fail;
            }
            else
                if (!writeaccountingentry(pacentry->nentryno, *pacentry))
                    return db_load_fail;
        }
        else
        {
            int64_t norderposoff = 0;
            boost_foreach(const int64_t& noffsetstart, norderposoffsets)
            {
                if (norderpos >= noffsetstart)
                    ++norderposoff;
            }
            norderpos += norderposoff;
            norderposnext = std::max(norderposnext, norderpos + 1);

            if (!norderposoff)
                continue;

            // since we're changing the order, write it back
            if (pwtx)
            {
                if (!writetx(pwtx->gethash(), *pwtx))
                    return db_load_fail;
            }
            else
                if (!writeaccountingentry(pacentry->nentryno, *pacentry))
                    return db_load_fail;
        }
    }
    writeorderposnext(norderposnext);

    return db_load_ok;
}

class cwalletscanstate {
public:
    unsigned int nkeys;
    unsigned int nckeys;
    unsigned int nkeymeta;
    bool fisencrypted;
    bool fanyunordered;
    int nfileversion;
    vector<uint256> vwalletupgrade;

    cwalletscanstate() {
        nkeys = nckeys = nkeymeta = 0;
        fisencrypted = false;
        fanyunordered = false;
        nfileversion = 0;
    }
};

bool
readkeyvalue(cwallet* pwallet, cdatastream& sskey, cdatastream& ssvalue,
             cwalletscanstate &wss, string& strtype, string& strerr)
{
    try {
        // unserialize
        // taking advantage of the fact that pair serialization
        // is just the two items serialized one after the other
        sskey >> strtype;
        if (strtype == "name")
        {
            string straddress;
            sskey >> straddress;
            ssvalue >> pwallet->mapaddressbook[cmoorecoinaddress(straddress).get()].name;
        }
        else if (strtype == "purpose")
        {
            string straddress;
            sskey >> straddress;
            ssvalue >> pwallet->mapaddressbook[cmoorecoinaddress(straddress).get()].purpose;
        }
        else if (strtype == "tx")
        {
            uint256 hash;
            sskey >> hash;
            cwallettx wtx;
            ssvalue >> wtx;
            cvalidationstate state;
            if (!(checktransaction(wtx, state) && (wtx.gethash() == hash) && state.isvalid()))
                return false;

            // undo serialize changes in 31600
            if (31404 <= wtx.ftimereceivedistxtime && wtx.ftimereceivedistxtime <= 31703)
            {
                if (!ssvalue.empty())
                {
                    char ftmp;
                    char funused;
                    ssvalue >> ftmp >> funused >> wtx.strfromaccount;
                    strerr = strprintf("loadwallet() upgrading tx ver=%d %d '%s' %s",
                                       wtx.ftimereceivedistxtime, ftmp, wtx.strfromaccount, hash.tostring());
                    wtx.ftimereceivedistxtime = ftmp;
                }
                else
                {
                    strerr = strprintf("loadwallet() repairing tx ver=%d %s", wtx.ftimereceivedistxtime, hash.tostring());
                    wtx.ftimereceivedistxtime = 0;
                }
                wss.vwalletupgrade.push_back(hash);
            }

            if (wtx.norderpos == -1)
                wss.fanyunordered = true;

            pwallet->addtowallet(wtx, true, null);
        }
        else if (strtype == "acentry")
        {
            string straccount;
            sskey >> straccount;
            uint64_t nnumber;
            sskey >> nnumber;
            if (nnumber > naccountingentrynumber)
                naccountingentrynumber = nnumber;

            if (!wss.fanyunordered)
            {
                caccountingentry acentry;
                ssvalue >> acentry;
                if (acentry.norderpos == -1)
                    wss.fanyunordered = true;
            }
        }
        else if (strtype == "watchs")
        {
            cscript script;
            sskey >> script;
            char fyes;
            ssvalue >> fyes;
            if (fyes == '1')
                pwallet->loadwatchonly(script);

            // watch-only addresses have no birthday information for now,
            // so set the wallet birthday to the beginning of time.
            pwallet->ntimefirstkey = 1;
        }
        else if (strtype == "key" || strtype == "wkey")
        {
            cpubkey vchpubkey;
            sskey >> vchpubkey;
            if (!vchpubkey.isvalid())
            {
                strerr = "error reading wallet database: cpubkey corrupt";
                return false;
            }
            ckey key;
            cprivkey pkey;
            uint256 hash;

            if (strtype == "key")
            {
                wss.nkeys++;
                ssvalue >> pkey;
            } else {
                cwalletkey wkey;
                ssvalue >> wkey;
                pkey = wkey.vchprivkey;
            }

            // old wallets store keys as "key" [pubkey] => [privkey]
            // ... which was slow for wallets with lots of keys, because the public key is re-derived from the private key
            // using ec operations as a checksum.
            // newer wallets store keys as "key"[pubkey] => [privkey][hash(pubkey,privkey)], which is much faster while
            // remaining backwards-compatible.
            try
            {
                ssvalue >> hash;
            }
            catch (...) {}

            bool fskipcheck = false;

            if (!hash.isnull())
            {
                // hash pubkey/privkey to accelerate wallet load
                std::vector<unsigned char> vchkey;
                vchkey.reserve(vchpubkey.size() + pkey.size());
                vchkey.insert(vchkey.end(), vchpubkey.begin(), vchpubkey.end());
                vchkey.insert(vchkey.end(), pkey.begin(), pkey.end());

                if (hash(vchkey.begin(), vchkey.end()) != hash)
                {
                    strerr = "error reading wallet database: cpubkey/cprivkey corrupt";
                    return false;
                }

                fskipcheck = true;
            }

            if (!key.load(pkey, vchpubkey, fskipcheck))
            {
                strerr = "error reading wallet database: cprivkey corrupt";
                return false;
            }
            if (!pwallet->loadkey(key, vchpubkey))
            {
                strerr = "error reading wallet database: loadkey failed";
                return false;
            }
        }
        else if (strtype == "mkey")
        {
            unsigned int nid;
            sskey >> nid;
            cmasterkey kmasterkey;
            ssvalue >> kmasterkey;
            if(pwallet->mapmasterkeys.count(nid) != 0)
            {
                strerr = strprintf("error reading wallet database: duplicate cmasterkey id %u", nid);
                return false;
            }
            pwallet->mapmasterkeys[nid] = kmasterkey;
            if (pwallet->nmasterkeymaxid < nid)
                pwallet->nmasterkeymaxid = nid;
        }
        else if (strtype == "ckey")
        {
            vector<unsigned char> vchpubkey;
            sskey >> vchpubkey;
            vector<unsigned char> vchprivkey;
            ssvalue >> vchprivkey;
            wss.nckeys++;

            if (!pwallet->loadcryptedkey(vchpubkey, vchprivkey))
            {
                strerr = "error reading wallet database: loadcryptedkey failed";
                return false;
            }
            wss.fisencrypted = true;
        }
        else if (strtype == "keymeta")
        {
            cpubkey vchpubkey;
            sskey >> vchpubkey;
            ckeymetadata keymeta;
            ssvalue >> keymeta;
            wss.nkeymeta++;

            pwallet->loadkeymetadata(vchpubkey, keymeta);

            // find earliest key creation time, as wallet birthday
            if (!pwallet->ntimefirstkey ||
                (keymeta.ncreatetime < pwallet->ntimefirstkey))
                pwallet->ntimefirstkey = keymeta.ncreatetime;
        }
        else if (strtype == "defaultkey")
        {
            ssvalue >> pwallet->vchdefaultkey;
        }
        else if (strtype == "pool")
        {
            int64_t nindex;
            sskey >> nindex;
            ckeypool keypool;
            ssvalue >> keypool;
            pwallet->setkeypool.insert(nindex);

            // if no metadata exists yet, create a default with the pool key's
            // creation time. note that this may be overwritten by actually
            // stored metadata for that key later, which is fine.
            ckeyid keyid = keypool.vchpubkey.getid();
            if (pwallet->mapkeymetadata.count(keyid) == 0)
                pwallet->mapkeymetadata[keyid] = ckeymetadata(keypool.ntime);
        }
        else if (strtype == "version")
        {
            ssvalue >> wss.nfileversion;
            if (wss.nfileversion == 10300)
                wss.nfileversion = 300;
        }
        else if (strtype == "cscript")
        {
            uint160 hash;
            sskey >> hash;
            cscript script;
            ssvalue >> script;
            if (!pwallet->loadcscript(script))
            {
                strerr = "error reading wallet database: loadcscript failed";
                return false;
            }
        }
        else if (strtype == "orderposnext")
        {
            ssvalue >> pwallet->norderposnext;
        }
        else if (strtype == "destdata")
        {
            std::string straddress, strkey, strvalue;
            sskey >> straddress;
            sskey >> strkey;
            ssvalue >> strvalue;
            if (!pwallet->loaddestdata(cmoorecoinaddress(straddress).get(), strkey, strvalue))
            {
                strerr = "error reading wallet database: loaddestdata failed";
                return false;
            }
        }
    } catch (...)
    {
        return false;
    }
    return true;
}

static bool iskeytype(string strtype)
{
    return (strtype== "key" || strtype == "wkey" ||
            strtype == "mkey" || strtype == "ckey");
}

dberrors cwalletdb::loadwallet(cwallet* pwallet)
{
    pwallet->vchdefaultkey = cpubkey();
    cwalletscanstate wss;
    bool fnoncriticalerrors = false;
    dberrors result = db_load_ok;

    try {
        lock(pwallet->cs_wallet);
        int nminversion = 0;
        if (read((string)"minversion", nminversion))
        {
            if (nminversion > client_version)
                return db_too_new;
            pwallet->loadminversion(nminversion);
        }

        // get cursor
        dbc* pcursor = getcursor();
        if (!pcursor)
        {
            logprintf("error getting wallet database cursor\n");
            return db_corrupt;
        }

        while (true)
        {
            // read next record
            cdatastream sskey(ser_disk, client_version);
            cdatastream ssvalue(ser_disk, client_version);
            int ret = readatcursor(pcursor, sskey, ssvalue);
            if (ret == db_notfound)
                break;
            else if (ret != 0)
            {
                logprintf("error reading next record from wallet database\n");
                return db_corrupt;
            }

            // try to be tolerant of single corrupt records:
            string strtype, strerr;
            if (!readkeyvalue(pwallet, sskey, ssvalue, wss, strtype, strerr))
            {
                // losing keys is considered a catastrophic error, anything else
                // we assume the user can live with:
                if (iskeytype(strtype))
                    result = db_corrupt;
                else
                {
                    // leave other errors alone, if we try to fix them we might make things worse.
                    fnoncriticalerrors = true; // ... but do warn the user there is something wrong.
                    if (strtype == "tx")
                        // rescan if there is a bad transaction record:
                        softsetboolarg("-rescan", true);
                }
            }
            if (!strerr.empty())
                logprintf("%s\n", strerr);
        }
        pcursor->close();
    }
    catch (const boost::thread_interrupted&) {
        throw;
    }
    catch (...) {
        result = db_corrupt;
    }

    if (fnoncriticalerrors && result == db_load_ok)
        result = db_noncritical_error;

    // any wallet corruption at all: skip any rewriting or
    // upgrading, we don't want to make it worse.
    if (result != db_load_ok)
        return result;

    logprintf("nfileversion = %d\n", wss.nfileversion);

    logprintf("keys: %u plaintext, %u encrypted, %u w/ metadata, %u total\n",
           wss.nkeys, wss.nckeys, wss.nkeymeta, wss.nkeys + wss.nckeys);

    // ntimefirstkey is only reliable if all keys have metadata
    if ((wss.nkeys + wss.nckeys) != wss.nkeymeta)
        pwallet->ntimefirstkey = 1; // 0 would be considered 'no value'

    boost_foreach(uint256 hash, wss.vwalletupgrade)
        writetx(hash, pwallet->mapwallet[hash]);

    // rewrite encrypted wallets of versions 0.4.0 and 0.5.0rc:
    if (wss.fisencrypted && (wss.nfileversion == 40000 || wss.nfileversion == 50000))
        return db_need_rewrite;

    if (wss.nfileversion < client_version) // update
        writeversion(client_version);

    if (wss.fanyunordered)
        result = reordertransactions(pwallet);

    return result;
}

dberrors cwalletdb::findwallettx(cwallet* pwallet, vector<uint256>& vtxhash, vector<cwallettx>& vwtx)
{
    pwallet->vchdefaultkey = cpubkey();
    bool fnoncriticalerrors = false;
    dberrors result = db_load_ok;

    try {
        lock(pwallet->cs_wallet);
        int nminversion = 0;
        if (read((string)"minversion", nminversion))
        {
            if (nminversion > client_version)
                return db_too_new;
            pwallet->loadminversion(nminversion);
        }

        // get cursor
        dbc* pcursor = getcursor();
        if (!pcursor)
        {
            logprintf("error getting wallet database cursor\n");
            return db_corrupt;
        }

        while (true)
        {
            // read next record
            cdatastream sskey(ser_disk, client_version);
            cdatastream ssvalue(ser_disk, client_version);
            int ret = readatcursor(pcursor, sskey, ssvalue);
            if (ret == db_notfound)
                break;
            else if (ret != 0)
            {
                logprintf("error reading next record from wallet database\n");
                return db_corrupt;
            }

            string strtype;
            sskey >> strtype;
            if (strtype == "tx") {
                uint256 hash;
                sskey >> hash;

                cwallettx wtx;
                ssvalue >> wtx;

                vtxhash.push_back(hash);
                vwtx.push_back(wtx);
            }
        }
        pcursor->close();
    }
    catch (const boost::thread_interrupted&) {
        throw;
    }
    catch (...) {
        result = db_corrupt;
    }

    if (fnoncriticalerrors && result == db_load_ok)
        result = db_noncritical_error;

    return result;
}

dberrors cwalletdb::zapwallettx(cwallet* pwallet, vector<cwallettx>& vwtx)
{
    // build list of wallet txs
    vector<uint256> vtxhash;
    dberrors err = findwallettx(pwallet, vtxhash, vwtx);
    if (err != db_load_ok)
        return err;

    // erase each wallet tx
    boost_foreach (uint256& hash, vtxhash) {
        if (!erasetx(hash))
            return db_corrupt;
    }

    return db_load_ok;
}

void threadflushwalletdb(const string& strfile)
{
    // make this thread recognisable as the wallet flushing thread
    renamethread("moorecoin-wallet");

    static bool fonethread;
    if (fonethread)
        return;
    fonethread = true;
    if (!getboolarg("-flushwallet", true))
        return;

    unsigned int nlastseen = nwalletdbupdated;
    unsigned int nlastflushed = nwalletdbupdated;
    int64_t nlastwalletupdate = gettime();
    while (true)
    {
        millisleep(500);

        if (nlastseen != nwalletdbupdated)
        {
            nlastseen = nwalletdbupdated;
            nlastwalletupdate = gettime();
        }

        if (nlastflushed != nwalletdbupdated && gettime() - nlastwalletupdate >= 2)
        {
            try_lock(bitdb.cs_db,lockdb);
            if (lockdb)
            {
                // don't do this if any databases are in use
                int nrefcount = 0;
                map<string, int>::iterator mi = bitdb.mapfileusecount.begin();
                while (mi != bitdb.mapfileusecount.end())
                {
                    nrefcount += (*mi).second;
                    mi++;
                }

                if (nrefcount == 0)
                {
                    boost::this_thread::interruption_point();
                    map<string, int>::iterator mi = bitdb.mapfileusecount.find(strfile);
                    if (mi != bitdb.mapfileusecount.end())
                    {
                        logprint("db", "flushing wallet.dat\n");
                        nlastflushed = nwalletdbupdated;
                        int64_t nstart = gettimemillis();

                        // flush wallet.dat so it's self contained
                        bitdb.closedb(strfile);
                        bitdb.checkpointlsn(strfile);

                        bitdb.mapfileusecount.erase(mi++);
                        logprint("db", "flushed wallet.dat %dms\n", gettimemillis() - nstart);
                    }
                }
            }
        }
    }
}

bool backupwallet(const cwallet& wallet, const string& strdest)
{
    if (!wallet.ffilebacked)
        return false;
    while (true)
    {
        {
            lock(bitdb.cs_db);
            if (!bitdb.mapfileusecount.count(wallet.strwalletfile) || bitdb.mapfileusecount[wallet.strwalletfile] == 0)
            {
                // flush log data to the dat file
                bitdb.closedb(wallet.strwalletfile);
                bitdb.checkpointlsn(wallet.strwalletfile);
                bitdb.mapfileusecount.erase(wallet.strwalletfile);

                // copy wallet.dat
                boost::filesystem::path pathsrc = getdatadir() / wallet.strwalletfile;
                boost::filesystem::path pathdest(strdest);
                if (boost::filesystem::is_directory(pathdest))
                    pathdest /= wallet.strwalletfile;

                try {
#if boost_version >= 104000
                    boost::filesystem::copy_file(pathsrc, pathdest, boost::filesystem::copy_option::overwrite_if_exists);
#else
                    boost::filesystem::copy_file(pathsrc, pathdest);
#endif
                    logprintf("copied wallet.dat to %s\n", pathdest.string());
                    return true;
                } catch (const boost::filesystem::filesystem_error& e) {
                    logprintf("error copying wallet.dat to %s - %s\n", pathdest.string(), e.what());
                    return false;
                }
            }
        }
        millisleep(100);
    }
    return false;
}

//
// try to (very carefully!) recover wallet.dat if there is a problem.
//
bool cwalletdb::recover(cdbenv& dbenv, const std::string& filename, bool fonlykeys)
{
    // recovery procedure:
    // move wallet.dat to wallet.timestamp.bak
    // call salvage with faggressive=true to
    // get as much data as possible.
    // rewrite salvaged data to wallet.dat
    // set -rescan so any missing transactions will be
    // found.
    int64_t now = gettime();
    std::string newfilename = strprintf("wallet.%d.bak", now);

    int result = dbenv.dbenv->dbrename(null, filename.c_str(), null,
                                       newfilename.c_str(), db_auto_commit);
    if (result == 0)
        logprintf("renamed %s to %s\n", filename, newfilename);
    else
    {
        logprintf("failed to rename %s to %s\n", filename, newfilename);
        return false;
    }

    std::vector<cdbenv::keyvalpair> salvageddata;
    bool fsuccess = dbenv.salvage(newfilename, true, salvageddata);
    if (salvageddata.empty())
    {
        logprintf("salvage(aggressive) found no records in %s.\n", newfilename);
        return false;
    }
    logprintf("salvage(aggressive) found %u records\n", salvageddata.size());

    boost::scoped_ptr<db> pdbcopy(new db(dbenv.dbenv, 0));
    int ret = pdbcopy->open(null,               // txn pointer
                            filename.c_str(),   // filename
                            "main",             // logical db name
                            db_btree,           // database type
                            db_create,          // flags
                            0);
    if (ret > 0)
    {
        logprintf("cannot create database file %s\n", filename);
        return false;
    }
    cwallet dummywallet;
    cwalletscanstate wss;

    dbtxn* ptxn = dbenv.txnbegin();
    boost_foreach(cdbenv::keyvalpair& row, salvageddata)
    {
        if (fonlykeys)
        {
            cdatastream sskey(row.first, ser_disk, client_version);
            cdatastream ssvalue(row.second, ser_disk, client_version);
            string strtype, strerr;
            bool freadok = readkeyvalue(&dummywallet, sskey, ssvalue,
                                        wss, strtype, strerr);
            if (!iskeytype(strtype))
                continue;
            if (!freadok)
            {
                logprintf("warning: cwalletdb::recover skipping %s: %s\n", strtype, strerr);
                continue;
            }
        }
        dbt datkey(&row.first[0], row.first.size());
        dbt datvalue(&row.second[0], row.second.size());
        int ret2 = pdbcopy->put(ptxn, &datkey, &datvalue, db_nooverwrite);
        if (ret2 > 0)
            fsuccess = false;
    }
    ptxn->commit(0);
    pdbcopy->close(0);

    return fsuccess;
}

bool cwalletdb::recover(cdbenv& dbenv, const std::string& filename)
{
    return cwalletdb::recover(dbenv, filename, false);
}

bool cwalletdb::writedestdata(const std::string &address, const std::string &key, const std::string &value)
{
    nwalletdbupdated++;
    return write(std::make_pair(std::string("destdata"), std::make_pair(address, key)), value);
}

bool cwalletdb::erasedestdata(const std::string &address, const std::string &key)
{
    nwalletdbupdated++;
    return erase(std::make_pair(std::string("destdata"), std::make_pair(address, key)));
}

max_stars_repo_name: moorecoin/MooreCoinMiningAlgorithm

max_issues_repo_name: moorecoin/MooreCoinMiningAlgorithm

max_forks_repo_name: moorecoin/MooreCoinMiningAlgorithm


text:
#include "VisionMPC_interface.h"
#include "../convexMPC/common_types.h"
#include "VisionSolverMPC.h"
#include <Eigen/Dense>
#include <pthread.h>
#include <stdio.h>
#include <string.h>

#define V_NUM_LEGS 4

vision_mpc_problem_setup v_problem_config;
vision_mpc_update_data_t v_update;

pthread_mutex_t vision_problem_cfg_mt;
pthread_mutex_t vision_mpc_update_mt;
pthread_t vision_mpc_solve_thread;

u8 v_first_run = 1;

void vision_initialize_mpc()
{
  //printf("Initializing MPC!\n");
  if(pthread_mutex_init(&vision_problem_cfg_mt,NULL)!=0)
    printf("[MPC ERROR] Failed to initialize problem configuration mutex.\n");

  if(pthread_mutex_init(&vision_mpc_update_mt,NULL)!=0)
    printf("[MPC ERROR] Failed to initialize update data mutex.\n");
}

void vision_setup_problem(double dt, int horizon, double mu, double f_max)
{
  if(v_first_run) {
    v_first_run = false;
    vision_initialize_mpc();
  }

  //pthread_mutex_lock(&problem_cfg_mt);

  v_problem_config.horizon = horizon;
  v_problem_config.f_max = f_max;
  v_problem_config.mu = mu;
  v_problem_config.dt = dt;

  //pthread_mutex_unlock(&problem_cfg_mt);
  vision_resize_qp_mats(horizon);
}

//inline to motivate gcc to unroll the loop in here.
inline void vision_mpf_to_flt(flt* dst, mfp* src, s32 n_items) {
  for(s32 i = 0; i < n_items; i++)
    *dst++ = *src++;
}

inline void vision_mint_to_u8(u8* dst, mint* src, s32 n_items) {
  for(s32 i = 0; i < n_items; i++)
    *dst++ = *src++;
}

int vision_has_solved = 0;

//safely copies problem data and starts the solver
void vision_update_problem_data(double* p, double* v, double* q, double* w, double* r, double yaw, double* weights, double* state_trajectory, double alpha, int* gait)
{
  vision_mpf_to_flt(v_update.p,p,3);
  vision_mpf_to_flt(v_update.v,v,3);
  vision_mpf_to_flt(v_update.q,q,4);
  vision_mpf_to_flt(v_update.w,w,3);
  vision_mpf_to_flt(v_update.r,r,12);
  v_update.yaw = yaw;
  vision_mpf_to_flt(v_update.weights,weights,12);
  //this is safe, the solver isn't running, and v_update_problem_data and setup_problem
  //are called from the same thread
  vision_mpf_to_flt(v_update.traj,state_trajectory,12*v_problem_config.horizon);
  v_update.alpha = alpha;
  vision_mint_to_u8(v_update.gait,gait,4*v_problem_config.horizon);

  vision_solve_mpc(&v_update, &v_problem_config);
  vision_has_solved = 1;
}

void vision_update_problem_data_floats(float* p, float* v, float* q, float* w,
                                float* r, float yaw, float* weights,
                                float* state_trajectory, float alpha, int* gait)
{
  v_update.alpha = alpha;
  v_update.yaw = yaw;
  vision_mint_to_u8(v_update.gait,gait,4*v_problem_config.horizon);
  memcpy((void*)v_update.p,(void*)p,sizeof(float)*3);
  memcpy((void*)v_update.v,(void*)v,sizeof(float)*3);
  memcpy((void*)v_update.q,(void*)q,sizeof(float)*4);
  memcpy((void*)v_update.w,(void*)w,sizeof(float)*3);
  memcpy((void*)v_update.r,(void*)r,sizeof(float)*12);
  memcpy((void*)v_update.weights,(void*)weights,sizeof(float)*12);
  memcpy((void*)v_update.traj,(void*)state_trajectory, sizeof(float) * 12 * v_problem_config.horizon);
  vision_solve_mpc(&v_update, &v_problem_config);
  vision_has_solved = 1;

}

double vision_get_solution(int index)
{
  if(!vision_has_solved) return 0.f;
  mfp* qs = vision_get_q_soln();
  return qs[index];
}

max_stars_repo_name: zbwu/Cheetah-Software

max_issues_repo_name: zbwu/Cheetah-Software

max_forks_repo_name: zbwu/Cheetah-Software


text: #include <boost/wave/preprocessing_hooks.hpp>

max_stars_repo_name: miathedev/BoostForArduino

max_issues_repo_name: miathedev/BoostForArduino

max_forks_repo_name: miathedev/BoostForArduino


text:
//此源码被清华学神尹成大魔王专业翻译分析并修改
//尹成QQ77025077
//尹成微信18510341407
//尹成所在QQ群721929980
//尹成邮箱 yinc13@mails.tsinghua.edu.cn
//尹成毕业于清华大学,微软区块链领域全球最有价值专家
//https://mvp.microsoft.com/zh-cn/PublicProfile/4033620
//————————————————————————————————————————————————————————————————————————————————————————————————————————————————
/*
    此文件是Rippled的一部分：https://github.com/ripple/rippled
    版权所有（c）2012，2013 Ripple Labs Inc.

    使用、复制、修改和/或分发本软件的权限
    特此授予免费或不收费的目的，前提是
    版权声明和本许可声明出现在所有副本中。

    本软件按“原样”提供，作者不作任何保证。
    关于本软件，包括
    适销性和适用性。在任何情况下，作者都不对
    任何特殊、直接、间接或后果性损害或任何损害
    因使用、数据或利润损失而导致的任何情况，无论是在
    合同行为、疏忽或其他侵权行为
    或与本软件的使用或性能有关。
**/

//==============================================================

#include <ripple/app/paths/Credit.h>
#include <ripple/app/paths/impl/AmountSpec.h>
#include <ripple/app/paths/impl/Steps.h>
#include <ripple/app/paths/impl/StepChecks.h>
#include <ripple/basics/Log.h>
#include <ripple/ledger/PaymentSandbox.h>
#include <ripple/protocol/IOUAmount.h>
#include <ripple/protocol/Quality.h>
#include <ripple/protocol/XRPAmount.h>

#include <boost/container/flat_set.hpp>

#include <numeric>
#include <sstream>

namespace ripple {

template <class TDerived>
class XRPEndpointStep : public StepImp<
    XRPAmount, XRPAmount, XRPEndpointStep<TDerived>>
{
private:
    AccountID acc_;
    bool const isLast_;
    beast::Journal j_;

//因为此步骤始终是链中的端点
//（第一步或最后一步）使用相同的缓存
//对于cachedin和cachedout，将只使用一个
    boost::optional<XRPAmount> cache_;

    boost::optional<EitherAmount>
    cached () const
    {
        if (!cache_)
            return boost::none;
        return EitherAmount (*cache_);
    }

public:
    XRPEndpointStep (
        StrandContext const& ctx,
        AccountID const& acc)
            : acc_(acc)
            , isLast_(ctx.isLast)
            , j_ (ctx.j) {}

    AccountID const& acc () const
    {
        return acc_;
    }

    boost::optional<std::pair<AccountID,AccountID>>
    directStepAccts () const override
    {
        if (isLast_)
            return std::make_pair(xrpAccount(), acc_);
        return std::make_pair(acc_, xrpAccount());
    }

    boost::optional<EitherAmount>
    cachedIn () const override
    {
        return cached ();
    }

    boost::optional<EitherAmount>
    cachedOut () const override
    {
        return cached ();
    }

    boost::optional<Quality>
    qualityUpperBound(ReadView const& v, bool& redeems) const override;

    std::pair<XRPAmount, XRPAmount>
    revImp (
        PaymentSandbox& sb,
        ApplyView& afView,
        boost::container::flat_set<uint256>& ofrsToRm,
        XRPAmount const& out);

    std::pair<XRPAmount, XRPAmount>
    fwdImp (
        PaymentSandbox& sb,
        ApplyView& afView,
        boost::container::flat_set<uint256>& ofrsToRm,
        XRPAmount const& in);

    std::pair<bool, EitherAmount>
    validFwd (
        PaymentSandbox& sb,
        ApplyView& afView,
        EitherAmount const& in) override;

//检查是否存在错误和违反冻结约束的情况。
    TER check (StrandContext const& ctx) const;

protected:
    XRPAmount
    xrpLiquidImpl (ReadView& sb, std::int32_t reserveReduction) const
    {
        return ripple::xrpLiquid (sb, acc_, reserveReduction, j_);
    }

    std::string logStringImpl (char const* name) const
    {
        std::ostringstream ostr;
        ostr <<
            name << ": " <<
            "\nAcc: " << acc_;
        return ostr.str ();
    }

private:
    template <class P>
    friend bool operator==(
        XRPEndpointStep<P> const& lhs,
        XRPEndpointStep<P> const& rhs);

    friend bool operator!=(
        XRPEndpointStep const& lhs,
        XRPEndpointStep const& rhs)
    {
        return ! (lhs == rhs);
    }

    bool equal (Step const& rhs) const override
    {
        if (auto ds = dynamic_cast<XRPEndpointStep const*> (&rhs))
        {
            return *this == *ds;
        }
        return false;
    }
};

//————————————————————————————————————————————————————————————————————————————————————————————————————————————————

//在两种不同的情况下，流动用于转移资金：
//付款，以及
//o提供交叉路口。
//在这两种情况下，处理资金的规则几乎是，但不是
//完全一样。

//付款xrpendpointstep类（不提供交叉）。
class XRPEndpointPaymentStep : public XRPEndpointStep<XRPEndpointPaymentStep>
{
public:
    explicit XRPEndpointPaymentStep() = default;

    using XRPEndpointStep<XRPEndpointPaymentStep>::XRPEndpointStep;

    XRPAmount
    xrpLiquid (ReadView& sb) const
    {
        return xrpLiquidImpl (sb, 0);;
    }

    std::string logString () const override
    {
        return logStringImpl ("XRPEndpointPaymentStep");
    }
};

//提供交叉xrpendpointstep类（不是付款）。
class XRPEndpointOfferCrossingStep :
    public XRPEndpointStep<XRPEndpointOfferCrossingStep>
{
private:

//出于历史原因，允许报价交叉进一步挖掘
//存入xrp储备，而不是普通支付。（我相信这是
//因为信任行是在删除xrp之后创建的。）
//返回应减少的准备金。
//
//请注意，只有当信托额度没有
//当前存在。
    static std::int32_t computeReserveReduction (
        StrandContext const& ctx, AccountID const& acc)
    {
        if (ctx.isFirst &&
            !ctx.view.read (keylet::line (acc, ctx.strandDeliver)))
                return -1;
        return 0;
    }

public:
    XRPEndpointOfferCrossingStep (
        StrandContext const& ctx, AccountID const& acc)
    : XRPEndpointStep<XRPEndpointOfferCrossingStep> (ctx, acc)
    , reserveReduction_ (computeReserveReduction (ctx, acc))
    {
    }

    XRPAmount
    xrpLiquid (ReadView& sb) const
    {
        return xrpLiquidImpl (sb, reserveReduction_);
    }

    std::string logString () const override
    {
        return logStringImpl ("XRPEndpointOfferCrossingStep");
    }

private:
    std::int32_t const reserveReduction_;
};

//————————————————————————————————————————————————————————————————————————————————————————————————————————————————

template <class TDerived>
inline bool operator==(XRPEndpointStep<TDerived> const& lhs,
    XRPEndpointStep<TDerived> const& rhs)
{
    return lhs.acc_ == rhs.acc_ && lhs.isLast_ == rhs.isLast_;
}

template <class TDerived>
boost::optional<Quality>
XRPEndpointStep<TDerived>::qualityUpperBound(
    ReadView const& v, bool& redeems) const
{
    redeems = this->redeems(v, true);
    return Quality{STAmount::uRateOne};
}

template <class TDerived>
std::pair<XRPAmount, XRPAmount>
XRPEndpointStep<TDerived>::revImp (
    PaymentSandbox& sb,
    ApplyView& afView,
    boost::container::flat_set<uint256>& ofrsToRm,
    XRPAmount const& out)
{
    auto const balance = static_cast<TDerived const*>(this)->xrpLiquid (sb);

    auto const result = isLast_ ? out : std::min (balance, out);

    auto& sender = isLast_ ? xrpAccount() : acc_;
    auto& receiver = isLast_ ? acc_ : xrpAccount();
    auto ter   = accountSend (sb, sender, receiver, toSTAmount (result), j_);
    if (ter != tesSUCCESS)
        return {XRPAmount{beast::zero}, XRPAmount{beast::zero}};

    cache_.emplace (result);
    return {result, result};
}

template <class TDerived>
std::pair<XRPAmount, XRPAmount>
XRPEndpointStep<TDerived>::fwdImp (
    PaymentSandbox& sb,
    ApplyView& afView,
    boost::container::flat_set<uint256>& ofrsToRm,
    XRPAmount const& in)
{
    assert (cache_);
    auto const balance = static_cast<TDerived const*>(this)->xrpLiquid (sb);

    auto const result = isLast_ ? in : std::min (balance, in);

    auto& sender = isLast_ ? xrpAccount() : acc_;
    auto& receiver = isLast_ ? acc_ : xrpAccount();
    auto ter   = accountSend (sb, sender, receiver, toSTAmount (result), j_);
    if (ter != tesSUCCESS)
        return {XRPAmount{beast::zero}, XRPAmount{beast::zero}};

    cache_.emplace (result);
    return {result, result};
}

template <class TDerived>
std::pair<bool, EitherAmount>
XRPEndpointStep<TDerived>::validFwd (
    PaymentSandbox& sb,
    ApplyView& afView,
    EitherAmount const& in)
{
    if (!cache_)
    {
        JLOG (j_.error()) << "Expected valid cache in validFwd";
        return {false, EitherAmount (XRPAmount (beast::zero))};
    }

    assert (in.native);

    auto const& xrpIn = in.xrp;
    auto const balance = static_cast<TDerived const*>(this)->xrpLiquid (sb);

    if (!isLast_ && balance < xrpIn)
    {
        JLOG (j_.error()) << "XRPEndpointStep: Strand re-execute check failed."
            << " Insufficient balance: " << to_string (balance)
            << " Requested: " << to_string (xrpIn);
        return {false, EitherAmount (balance)};
    }

    if (xrpIn != *cache_)
    {
        JLOG (j_.error()) << "XRPEndpointStep: Strand re-execute check failed."
            << " ExpectedIn: " << to_string (*cache_)
            << " CachedIn: " << to_string (xrpIn);
    }
    return {true, in};
}

template <class TDerived>
TER
XRPEndpointStep<TDerived>::check (StrandContext const& ctx) const
{
    if (!acc_)
    {
        JLOG (j_.debug()) << "XRPEndpointStep: specified bad account.";
        return temBAD_PATH;
    }

    auto sleAcc = ctx.view.read (keylet::account (acc_));
    if (!sleAcc)
    {
        JLOG (j_.warn()) << "XRPEndpointStep: can't send or receive XRP from "
                             "non-existent account: "
                          << acc_;
        return terNO_ACCOUNT;
    }

    if (!ctx.isFirst && !ctx.isLast)
    {
        return temBAD_PATH;
    }

    auto& src = isLast_ ? xrpAccount () : acc_;
    auto& dst = isLast_ ? acc_ : xrpAccount();
    auto ter = checkFreeze (ctx.view, src, dst, xrpCurrency ());
    if (ter != tesSUCCESS)
        return ter;

    return tesSUCCESS;
}

//————————————————————————————————————————————————————————————————————————————————————————————————————————————————

namespace test
{
//测试所需
bool xrpEndpointStepEqual (Step const& step, AccountID const& acc)
{
    if (auto xs =
        dynamic_cast<XRPEndpointStep<XRPEndpointPaymentStep> const*> (&step))
    {
        return xs->acc () == acc;
    }
    return false;
}
}

//————————————————————————————————————————————————————————————————————————————————————————————————————————————————

std::pair<TER, std::unique_ptr<Step>>
make_XRPEndpointStep (
    StrandContext const& ctx,
    AccountID const& acc)
{
    TER ter = tefINTERNAL;
    std::unique_ptr<Step> r;
    if (ctx.offerCrossing)
    {
        auto offerCrossingStep =
            std::make_unique<XRPEndpointOfferCrossingStep> (ctx, acc);
        ter = offerCrossingStep->check (ctx);
        r = std::move (offerCrossingStep);
    }
else //付款
    {
        auto paymentStep =
            std::make_unique<XRPEndpointPaymentStep> (ctx, acc);
        ter = paymentStep->check (ctx);
        r = std::move (paymentStep);
    }
    if (ter != tesSUCCESS)
        return {ter, nullptr};

    return {tesSUCCESS, std::move (r)};
}

} //涟漪

max_stars_repo_name: yinchengtsinghua/RippleCPPChinese

max_issues_repo_name: yinchengtsinghua/RippleCPPChinese

max_forks_repo_name: yinchengtsinghua/RippleCPPChinese


text:
// ROS includes.
#include "ros/ros.h"
#include "ros/time.h"
#include <message_filters/subscriber.h>
#include <message_filters/synchronizer.h>
#include <message_filters/sync_policies/approximate_time.h>

#include <image_transport/image_transport.h>
#include <image_transport/subscriber_filter.h>
#include <sensor_msgs/CameraInfo.h>

#include <string.h>
#include <boost/thread.hpp>

#include <iostream>
#include <fstream>

#include <cv_bridge/cv_bridge.h>

#include "Matrix.h"
#include "Vector.h"
#include "Camera.h"
#include "pointcloud.h"
#include "Globals.h"
#include "groundplaneestimator.h"
#include "ConfigFile.h"

#include "rwth_perception_people_msgs/GroundPlane.h"

using namespace std;
using namespace sensor_msgs;
using namespace message_filters;

ros::Publisher pub_ground_plane;

cv::Mat img_depth_;
cv_bridge::CvImagePtr cv_depth_ptr;	// cv_bridge for depth image

GroundPlaneEstimator GPEstimator;

void ReadConfigFile(string path_config_file)
{

    ConfigFile config(path_config_file);

    /////////////////////////////////GP Estimator/////////////////////////
    Globals::nrInter_ransac = config.read<int>("nrInter_ransac");
    Globals::numberOfPoints_reconAsObstacle = config.read<int>("numberOfPoints_reconAsObstacle");
}

void callback(const ImageConstPtr &depth,  const CameraInfoConstPtr &info)
{

    // Get depth
    cv_depth_ptr = cv_bridge::toCvCopy(depth);
    img_depth_ = cv_depth_ptr->image;
    Matrix<double> matrix_depth(info->width, info->height);

    for (int r = 0;r < 480;r++){
        for (int c = 0;c < 640;c++) {
            matrix_depth(c, r) = img_depth_.at<float>(r,c);
        }
    }

    // Generate base camera
    Matrix<double> R = Eye<double>(3);
    Vector<double> t(3, 0.0);
    Vector<double> GP(0.0, 0.99, 0.0, 1.8); // just some placeholders which will be replaced after GP Estimation
    Matrix<double> K(3,3, (double*)&info->K[0]);

    Camera camera(K,R,t,GP);
    PointCloud point_cloud(camera, matrix_depth);

    GP = GPEstimator.ComputeGroundPlane(point_cloud);

    // Generate Ground Plane Message
    rwth_perception_people_msgs::GroundPlane ground_plane_msg;
    ground_plane_msg.header = depth->header;
    ground_plane_msg.d = GP(3);
    ground_plane_msg.n.push_back(GP(0));
    ground_plane_msg.n.push_back(GP(1));
    ground_plane_msg.n.push_back(GP(2));

    pub_ground_plane.publish(ground_plane_msg);

}

// Connection callback that unsubscribes from the tracker if no one is subscribed.
void connectCallback(message_filters::Subscriber<CameraInfo> &sub_cam,
                     image_transport::SubscriberFilter &sub_depth,
                     image_transport::ImageTransport &it){
    if(!pub_ground_plane.getNumSubscribers()) {
        ROS_DEBUG("Ground Plane estimated: No subscribers. Unsubscribing.");
        sub_cam.unsubscribe();
        sub_depth.unsubscribe();
    } else {
        ROS_DEBUG("Ground Plane estimated: New subscribers. Subscribing.");
        sub_cam.subscribe();
        sub_depth.subscribe(it,sub_depth.getTopic().c_str(),1);
    }
}

int main(int argc, char **argv)
{
    // Set up ROS.
    ros::init(argc, argv, "ground_plane");
    ros::NodeHandle n;

    // Declare variables that can be modified by launch file or command line.
    int queue_size;
    string cam_ns;
    string pub_topic_gp;
    string config_file;

    // Initialize node parameters from launch file or command line.
    // Use a private node handle so that multiple instances of the node can be run simultaneously
    // while using different parameters.
    ros::NodeHandle private_node_handle_("~");
    private_node_handle_.param("queue_size", queue_size, int(5));
    private_node_handle_.param("config_file", config_file, string(""));

    private_node_handle_.param("camera_namespace", cam_ns, string("/head_xtion"));
    string topic_depth_image = cam_ns + "/depth/image";
    string topic_camera_info = cam_ns + "/rgb/camera_info";

    if(strcmp(config_file.c_str(),"") == 0) {
        ROS_ERROR("No config file specified.");
        ROS_ERROR("Run with: rosrun rwth_ground_plane ground_plane _config_file:=/path/to/config");
        exit(0);
    }

    ROS_DEBUG("ground_plane: Queue size for synchronisation is set to: %i", queue_size);

    // Image transport handle
    image_transport::ImageTransport it(private_node_handle_);

    // Create a subscriber.
    // Set queue size to 1 because generating a queue here will only pile up images and delay the output by the amount of queued images
    image_transport::SubscriberFilter subscriber_depth;
    subscriber_depth.subscribe(it, topic_depth_image.c_str(), 1); subscriber_depth.unsubscribe();
    message_filters::Subscriber<CameraInfo> subscriber_camera_info(n, topic_camera_info.c_str(), 1); subscriber_camera_info.unsubscribe();

    ros::SubscriberStatusCallback con_cb = boost::bind(&connectCallback,
                                                       boost::ref(subscriber_camera_info),
                                                       boost::ref(subscriber_depth),
                                                       boost::ref(it));

    //The real queue size for synchronisation is set here.
    sync_policies::ApproximateTime<Image, CameraInfo> MySyncPolicy(queue_size);
    MySyncPolicy.setAgePenalty(1000); //set high age penalty to publish older data faster even if it might not be correctly synchronized.

    ReadConfigFile(config_file);

    const sync_policies::ApproximateTime<Image, CameraInfo> MyConstSyncPolicy = MySyncPolicy;

    Synchronizer< sync_policies::ApproximateTime<Image, CameraInfo> > sync(MyConstSyncPolicy,
                                                                                subscriber_depth, subscriber_camera_info);

    sync.registerCallback(boost::bind(&callback, _1, _2));

    // Create a topic publisher
    private_node_handle_.param("ground_plane", pub_topic_gp, string("/ground_plane"));
    pub_ground_plane = n.advertise<rwth_perception_people_msgs::GroundPlane>(pub_topic_gp.c_str(), 10, con_cb, con_cb);

    ros::spin();

    return 0;
}

max_stars_repo_name: CodeToPoem/HumanAwareRobotNavigation


text:
/*
  An example of how to register two 2d images using Horn-Schunk optical flow
*/

// Gadgetron includes
#include "cuDemonsSolver.h"
#include "cuNDArray.h"
#include "hoNDArray_fileio.h"
#include "parameterparser.h"
#include "cuCGHSOFSolver.h"
// Std includes
#include <iostream>
#include <cuLinearResampleOperator.h>
#include <boost/program_options.hpp>
#include "cuNDArray_fileio.h"
#include "vector_td_io.h"

using namespace Gadgetron;
using namespace std;

// Define desired precision

namespace po = boost::program_options;
int main(int argc, char** argv)
{

  //
  // Parse command line
  //

  string moving_filename,fixed_filename,vfield_filename;
  float alpha, sigma_diff,sigma_fluid,sigma_int,sigma_vdiff;
  int iterations,levels,device;
  vector_td<float,3> phys_dims;
  bool composite,exponential;
  po::options_description desc("Allowed options");
  desc.add_options()
          ("help", "produce help message")
          ("moving,m", po::value<string>(&moving_filename), "Moving image")
          ("fixed,f", po::value<string>(&fixed_filename), "Fixed image")
          ("output,o", po::value<string>(&vfield_filename)->default_value("deformation_field.real"), "Output filename")
          ("alpha,a",po::value<float>(&alpha)->default_value(0.5),"Maximum step length per iteration")
          ("sigma_diff",po::value<float>(&sigma_diff)->default_value(1),"Diffusion sigma for regularization")
          ("sigma_fluid",po::value<float>(&sigma_fluid)->default_value(0),"Fluid sigma for regularization")
          ("sigma_int",po::value<float>(&sigma_int)->default_value(0),"Intensity sigma for regularization (bilateral)")
          ("iterations,i",po::value<int>(&iterations)->default_value(30),"Number of iterations to use")
          ("levels",po::value<int>(&levels)->default_value(1),"Number of multiresolution levels to use")
          ("sigma_vdiff",po::value<float>(&sigma_vdiff)->default_value(0),"Vector field difference sigma for regularization (bilateral)")
          ("composite",po::value<bool>(&composite)->default_value(true),"Do proper vector composition when adding vector fields")
          ("exponential",po::value<bool>(&exponential)->default_value(true),"Use exponential calculations (ensures invertible field)")
          ("device",po::value<int>(&device)->default_value(0),"Cuda device to use")
          ("physical_dims",po::value<vector_td<float,3>>(&phys_dims)->default_value(vector_td<float,3>(1,1,1)),"Physical dimension in mm")
          ("NGF",po::value<float>(),"Strength of normalized gradient field")
          ;

  po::variables_map vm;
  po::store(po::parse_command_line(argc, argv, desc), vm);
  po::notify(vm);

  if (vm.count("help")) {
    cout << desc << "\n";
    return 1;
  }

  std::cout << "Command line options:" << std::endl;
  for (po::variables_map::iterator it = vm.begin(); it != vm.end(); ++it){
    boost::any a = it->second.value();
    std::cout << it->first << ": ";
    if (a.type() == typeid(std::string)) std::cout << it->second.as<std::string>();
    else if (a.type() == typeid(int)) std::cout << it->second.as<int>();
    else if (a.type() == typeid(unsigned int)) std::cout << it->second.as<unsigned int>();
    else if (a.type() == typeid(float)) std::cout << it->second.as<float>();
    else if (a.type() == typeid(vector_td<float,3>)) std::cout << it->second.as<vector_td<float,3> >();
    else if (a.type() == typeid(vector_td<int,3>)) std::cout << it->second.as<vector_td<int,3> >();
    else if (a.type() == typeid(vector_td<unsigned int,3>)) std::cout << it->second.as<vector_td<unsigned int,3> >();
    else std::cout << "Unknown type" << std::endl;
    std::cout << std::endl;
  }

  cudaSetDevice(device);
  cudaDeviceReset();

  // Load sample data from disk
  //

  boost::shared_ptr< hoNDArray<float> > host_fixed =
    read_nd_array<float>(fixed_filename.c_str());

  boost::shared_ptr< hoNDArray<float> > host_moving =
    read_nd_array<float>(moving_filename.c_str());

  if( !host_fixed.get() || !host_moving.get() ){
    cout << endl << "One of the input images is not found. Quitting!\n" << endl;
    return 1;
  }

  unsigned int num_fixed_dims = host_fixed->get_number_of_dimensions();
  unsigned int num_moving_dims = host_moving->get_number_of_dimensions();

  if( !(num_fixed_dims == 2 || num_fixed_dims == 3)  ){
    cout << endl << "The fixed image is not two- or three-dimensional. Quitting!\n" << endl;
    return 1;
  }

  if( !(num_moving_dims == 2 || num_moving_dims == 3)  ){
    cout << endl << "The moving image is not two- or three-dimensional. Quitting!\n" << endl;
    return 1;
  }

  // Upload host data to device
  //

  cuNDArray<float> fixed_image(host_fixed.get());
  cuNDArray<float> moving_image(host_moving.get());

  floatd3 sigma_diff_v = floatd3(sigma_diff);
  sigma_diff_v /= phys_dims;

  // Use bilinear interpolation for resampling
  //

  // Setup solver
  //

  cuDemonsSolver<float,3> HS;

  HS.set_iterations( iterations);

  HS.set_alpha(alpha);

  HS.set_sigmaDiff(sigma_diff_v);
  HS.set_sigmaFluid(sigma_fluid);
  HS.set_sigmaInt(sigma_int);
  HS.set_sigmaVDiff(sigma_vdiff);
  HS.set_compositive(composite);
  HS.set_exponential(exponential);
  if (vm.count("NGF")){
    HS.use_normalized_gradient_field(vm["NGF"].as<float>());
  }

//  HS.use_normalized_gradient_field(0.01);

  // Run registration
  //

  cuNDArray<float> result = HS.multi_level_reg( &fixed_image, &moving_image,levels );

  auto deformed_moving = deform_image( &moving_image, result );

  // All done, write out the result
  //

  write_nd_array<float>(&result,vfield_filename.c_str() );

  auto host_result = deformed_moving.to_host();
  write_nd_array<float>(host_result.get(), "def_moving.real" );

  auto jac = Jacobian(&result);
  jac -= 1.0f;

  write_nd_array<float>(&jac, "jacobian.real" );

  return 0;
}

max_stars_repo_name: ahsanjav/gt-tomography

max_issues_repo_name: ahsanjav/gt-tomography

max_forks_repo_name: ahsanjav/gt-tomography


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

#include <mapviz_plugins/grid_plugin.h>

// C++ standard libraries
#include <cstdio>
#include <vector>

#include <boost/lexical_cast.hpp>

// QT libraries
#include <QGLWidget>
#include <QPalette>

#include <mapviz/select_frame_dialog.h>

// Declare plugin
#include <pluginlib/class_list_macros.h>
PLUGINLIB_DECLARE_CLASS(
    mapviz_plugins,
    grid,
    mapviz_plugins::GridPlugin,
    mapviz::MapvizPlugin)

namespace mapviz_plugins
{
  GridPlugin::GridPlugin() :
    config_widget_(new QWidget()),
    alpha_(1.0),
    top_left_(0, 0, 0),
    size_(1),
    rows_(1),
    columns_(1),
    transformed_(false)
  {
    ui_.setupUi(config_widget_);

    ui_.color->setColor(Qt::red);

    // Set background white
    QPalette p(config_widget_->palette());
    p.setColor(QPalette::Background, Qt::white);
    config_widget_->setPalette(p);

    // Set status text red
    QPalette p3(ui_.status->palette());
    p3.setColor(QPalette::Text, Qt::red);
    ui_.status->setPalette(p3);

    QObject::connect(ui_.select_frame, SIGNAL(clicked()), this, SLOT(SelectFrame()));
    QObject::connect(ui_.frame, SIGNAL(textEdited(const QString&)), this, SLOT(FrameEdited()));
    QObject::connect(ui_.alpha, SIGNAL(valueChanged(double)), this, SLOT(SetAlpha(double)));
    QObject::connect(ui_.x, SIGNAL(valueChanged(double)), this, SLOT(SetX(double)));
    QObject::connect(ui_.y, SIGNAL(valueChanged(double)), this, SLOT(SetY(double)));
    QObject::connect(ui_.size, SIGNAL(valueChanged(double)), this, SLOT(SetSize(double)));
    QObject::connect(ui_.rows, SIGNAL(valueChanged(int)), this, SLOT(SetRows(int)));
    QObject::connect(ui_.columns, SIGNAL(valueChanged(int)), this, SLOT(SetColumns(int)));
    connect(ui_.color, SIGNAL(colorEdited(const QColor &)), this, SLOT(DrawIcon()));
  }

  GridPlugin::~GridPlugin()
  {
    Shutdown();
  }

  void GridPlugin::Shutdown()
  {
  }

  void GridPlugin::DrawIcon()
  {
    if (icon_)
    {
      QPixmap icon(16, 16);
      icon.fill(Qt::transparent);

      QPainter painter(&icon);
      painter.setRenderHint(QPainter::Antialiasing, true);

      QPen pen(QColor(ui_.color->color()));

      pen.setWidth(2);
      pen.setCapStyle(Qt::SquareCap);
      painter.setPen(pen);

      painter.drawLine(2, 2, 14, 2);
      painter.drawLine(2, 2, 2, 14);
      painter.drawLine(14, 2, 14, 14);
      painter.drawLine(2, 14, 14, 14);
      painter.drawLine(8, 2, 8, 14);
      painter.drawLine(2, 8, 14, 8);

      icon_->SetPixmap(icon);
    }
  }

  void GridPlugin::SetAlpha(double alpha)
  {
    alpha_ = alpha;
  }

  void GridPlugin::SetX(double x)
  {
    top_left_.setX(x);

    RecalculateGrid();
  }

  void GridPlugin::SetY(double y)
  {
    top_left_.setY(y);

    RecalculateGrid();
  }

  void GridPlugin::SetSize(double size)
  {
    size_ = size;

    RecalculateGrid();
  }

  void GridPlugin::SetRows(int rows)
  {
    rows_ = rows;

    RecalculateGrid();
  }

  void GridPlugin::SetColumns(int columns)
  {
    columns_ = columns;

    RecalculateGrid();
  }

  void GridPlugin::SelectFrame()
  {
    std::string frame = mapviz::SelectFrameDialog::selectFrame(tf_);
    if (!frame.empty())
    {
      ui_.frame->setText(QString::fromStdString(frame));
      FrameEdited();
    }
  }

  void GridPlugin::FrameEdited()
  {
    source_frame_ = ui_.frame->text().toStdString();

    initialized_ = true;

    RecalculateGrid();
  }

  void GridPlugin::PrintError(const std::string& message)
  {
    if (message == ui_.status->text().toStdString())
    {
      return;
    }

    ROS_ERROR("Error: %s", message.c_str());
    QPalette p(ui_.status->palette());
    p.setColor(QPalette::Text, Qt::red);
    ui_.status->setPalette(p);
    ui_.status->setText(message.c_str());
  }

  void GridPlugin::PrintInfo(const std::string& message)
  {
    if (message == ui_.status->text().toStdString())
    {
      return;
    }

    ROS_INFO("%s", message.c_str());
    QPalette p(ui_.status->palette());
    p.setColor(QPalette::Text, Qt::green);
    ui_.status->setPalette(p);
    ui_.status->setText(message.c_str());
  }

  void GridPlugin::PrintWarning(const std::string& message)
  {
    if (message == ui_.status->text().toStdString())
    {
      return;
    }

    ROS_WARN("%s", message.c_str());
    QPalette p(ui_.status->palette());
    p.setColor(QPalette::Text, Qt::darkYellow);
    ui_.status->setPalette(p);
    ui_.status->setText(message.c_str());
  }

  QWidget* GridPlugin::GetConfigWidget(QWidget* parent)
  {
    config_widget_->setParent(parent);

    return config_widget_;
  }

  bool GridPlugin::Initialize(QGLWidget* canvas)
  {
    canvas_ = canvas;

    DrawIcon();

    return true;
  }

  void GridPlugin::Draw(double x, double y, double scale)
  {
    if (transformed_)
    {
      QColor color = ui_.color->color();

      glLineWidth(3);
      glColor4d(color.redF(), color.greenF(), color.blueF(), alpha_);
      glBegin(GL_LINES);

        std::list<tf::Point>::iterator transformed_left_it = transformed_left_points_.begin();
        std::list<tf::Point>::iterator transformed_right_it = transformed_right_points_.begin();
        for (; transformed_left_it != transformed_left_points_.end(); ++transformed_left_it)
        {
          glVertex2d(transformed_left_it->getX(), transformed_left_it->getY());
          glVertex2d(transformed_right_it->getX(), transformed_right_it->getY());

          ++transformed_right_it;
        }

        std::list<tf::Point>::iterator transformed_top_it = transformed_top_points_.begin();
        std::list<tf::Point>::iterator transformed_bottom_it = transformed_bottom_points_.begin();
        for (; transformed_top_it != transformed_top_points_.end(); ++transformed_top_it)
        {
          glVertex2d(transformed_top_it->getX(), transformed_top_it->getY());
          glVertex2d(transformed_bottom_it->getX(), transformed_bottom_it->getY());

          ++transformed_bottom_it;
        }

      glEnd();

      PrintInfo("OK");
    }
  }

  void GridPlugin::RecalculateGrid()
  {
    transformed_ = false;

    left_points_.clear();
    right_points_.clear();
    top_points_.clear();
    bottom_points_.clear();

    transformed_left_points_.clear();
    transformed_right_points_.clear();
    transformed_top_points_.clear();
    transformed_bottom_points_.clear();

    // Set top and bottom
    for (int c = 0; c <= columns_; c++)
    {
      tf::Point top_point(top_left_.getX() + c * size_, top_left_.getY(), 0);
      top_points_.push_back(top_point);
      transformed_top_points_.push_back(transform_ * top_point);

      tf::Point bottom_point(top_left_.getX() + c * size_, top_left_.getY() + size_ * rows_, 0);
      bottom_points_.push_back(bottom_point);
      transformed_bottom_points_.push_back(transform_ * bottom_point);
    }

    // Set left and right
    for (int r = 0; r <= rows_; r++)
    {
      tf::Point left_point(top_left_.getX(), top_left_.getY() + r * size_, 0);
      left_points_.push_back(left_point);
      transformed_left_points_.push_back(transform_ * left_point);

      tf::Point right_point(top_left_.getX() + size_ * columns_, top_left_.getY() + r * size_, 0);
      right_points_.push_back(right_point);
      transformed_right_points_.push_back(transform_ * right_point);
    }
  }

  void GridPlugin::Transform()
  {
    transformed_ = false;

    if (GetTransform(ros::Time(), transform_))
    {
      Transform(left_points_, transformed_left_points_);
      Transform(right_points_, transformed_right_points_);
      Transform(top_points_, transformed_top_points_);
      Transform(bottom_points_, transformed_bottom_points_);

      transformed_ = true;
    }
  }

  void GridPlugin::Transform(std::list<tf::Point>& src, std::list<tf::Point>& dst)
  {
    std::list<tf::Point>::iterator points_it = src.begin();
    std::list<tf::Point>::iterator transformed_it = dst.begin();
    for (; points_it != src.end() && transformed_it != dst.end(); ++points_it)
    {
      (*transformed_it) = transform_ * (*points_it);

      ++transformed_it;
    }
  }

  void GridPlugin::LoadConfig(const YAML::Node& node, const std::string& path)
  {
    if (node["color"])
    {
      std::string color;
      node["color"] >> color;
      ui_.color->setColor(QColor(color.c_str()));
    }

    if (node["frame"])
    {
      std::string frame;
      node["frame"] >> frame;
      ui_.frame->setText(QString::fromStdString(frame));
    }

    if (node["x"])
    {
      float x = 0;
      node["x"] >> x;
      ui_.x->setValue(x);
    }

    if (node["y"])
    {
      float y = 0;
      node["y"] >> y;
      ui_.y->setValue(y);
    }

    if (node["alpha"])
    {
      node["alpha"] >> alpha_;
      ui_.alpha->setValue(alpha_);
    }

    if (node["size"])
    {
      node["size"] >> size_;
      ui_.size->setValue(size_);
    }

    if (node["rows"])
    {
      node["rows"] >> rows_;
      ui_.rows->setValue(rows_);
    }

    if (node["columns"])
    {
      node["columns"] >> columns_;
      ui_.columns->setValue(columns_);
    }

    FrameEdited();
  }

  void GridPlugin::SaveConfig(YAML::Emitter& emitter, const std::string& path)
  {
    emitter << YAML::Key << "color" << YAML::Value << ui_.color->color().name().toStdString();

    emitter << YAML::Key << "alpha" << YAML::Value << alpha_;

    std::string frame = ui_.frame->text().toStdString();
    emitter << YAML::Key << "frame" << YAML::Value << frame;

    emitter << YAML::Key << "x" << YAML::Value << top_left_.getX();
    emitter << YAML::Key << "y" << YAML::Value << top_left_.getY();
    emitter << YAML::Key << "size" << YAML::Value << size_;
    emitter << YAML::Key << "rows" << YAML::Value << rows_;
    emitter << YAML::Key << "columns" << YAML::Value << columns_;
  }
}

max_stars_repo_name: matt-attack/mapviz

max_issues_repo_name: matt-attack/mapviz

max_forks_repo_name: matt-attack/mapviz