<commit_before>#include <cmath>
#include <util/Logger.h>
#include <util/geometry.hpp>
#include "OpenGl.h"
#include "RotateView.h"

namespace sg_gui {

static logger::LogChannel rotateviewlog("rotateviewlog", "[RotateView] ");

RotateView::RotateView() :
	_x(0.0),
	_y(1.0),
	_z(0.0),
	_w(0.0),
	_prevX(0.0),
	_prevY(1.0),
	_prevZ(0.0),
	_prevW(0.0),
	_buttonDown(0, 0),
	_dragging(false),
	_highlight(false) {}

bool
RotateView::filterDown(DrawBase& /*signal*/) {

	updateContentSize();

	util::point<float,3> min    = _contentSize.min();
	util::point<float,3> max    = _contentSize.max();
	util::point<float,3> center = _contentSize.center();

	glMatrixMode(GL_MODELVIEW);

	glPushMatrix();

	// put a light
	float lightX = -100;
	float lightY = -100;
	float lightZ = -100;
	GLfloat lightpos[] = {lightX, lightY, lightZ, 0.0};
	glEnable(GL_LIGHT1);
	glLightfv(GL_LIGHT1, GL_POSITION, lightpos);
	GLfloat ambient[] = {0.5, 0.5, 0.5, 1.0};
	glLightfv(GL_LIGHT1, GL_AMBIENT, ambient);
	GLfloat specular[] = {0.3, 0.3, 0.3, 1.0};
	glLightfv(GL_LIGHT1, GL_SPECULAR, specular);
	GLfloat diffuse[] = {0.5, 0.5, 0.5, 1.0};
	glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse);

	// perform the rotation
	glTranslated(center.x(),  center.y(), center.z());
	glRotated(_w/M_PI*180.0, _x, _y, _z);
	glTranslated(-center.x(), -center.y(), -center.z());

	glColor4f((_highlight ? 0.88 : 0.1), 0.2, 0.05, 0.5);

	// draw box around content
	glLineWidth(1.0);
	glEnable(GL_LINE_SMOOTH);

	glBegin(GL_LINES);
	glVertex3f(min.x(), min.y(), min.z());
	glVertex3f(min.x(), min.y(), max.z());

	glVertex3f(min.x(), min.y(), max.z());
	glVertex3f(min.x(), max.y(), max.z());

	glVertex3f(min.x(), max.y(), max.z());
	glVertex3f(min.x(), max.y(), min.z());

	glVertex3f(min.x(), max.y(), min.z());
	glVertex3f(min.x(), min.y(), min.z());

	glVertex3f(max.x(), min.y(), min.z());
	glVertex3f(max.x(), min.y(), max.z());

	glVertex3f(max.x(), min.y(), max.z());
	glVertex3f(max.x(), max.y(), max.z());

	glVertex3f(max.x(), max.y(), max.z());
	glVertex3f(max.x(), max.y(), min.z());

	glVertex3f(max.x(), max.y(), min.z());
	glVertex3f(max.x(), min.y(), min.z());

	glVertex3f(min.x(), min.y(), min.z());
	glVertex3f(max.x(), min.y(), min.z());

	glVertex3f(min.x(), min.y(), max.z());
	glVertex3f(max.x(), min.y(), max.z());

	glVertex3f(min.x(), max.y(), max.z());
	glVertex3f(max.x(), max.y(), max.z());

	glVertex3f(min.x(), max.y(), min.z());
	glVertex3f(max.x(), max.y(), min.z());
	glEnd();

	glEnable(GL_LIGHTING);
	glEnable(GL_COLOR_MATERIAL);

	return true;
}

void
RotateView::unfilterDown(DrawBase& /*signal*/) {

	glDisable(GL_LIGHT1);
	glPopMatrix();
}

bool
RotateView::filterDown(QuerySize& signal) {

	LOG_ALL(rotateviewlog) << "got size query..." << std::endl;

	updateContentSize();

	LOG_ALL(rotateviewlog) << "content size is " << _contentSize << std::endl;

	// bounding box of all possible rotations around center
	float maxSideLength = std::max(_contentSize.width(), std::max(_contentSize.height(), _contentSize.depth()));
	util::point<float,3> center = _contentSize.center();

	util::box<float,3> size(
			center - util::point<float,3>(maxSideLength/2, maxSideLength/2, maxSideLength/2),
			center + util::point<float,3>(maxSideLength/2, maxSideLength/2, maxSideLength/2));

	LOG_ALL(rotateviewlog) << "max rotated content size is " << size << std::endl;

	signal.setSize(size);

	return false;
}

void
RotateView::unfilterDown(QuerySize& draw) {}

bool
RotateView::filterDown(PointerSignal& signal) {

	// rotate ray position around content center
	signal.ray.position() = util::rotate3d(
			util::ray<float,3>(
					_contentSize.center(),
					util::point<float,3>(_x, _y, _z)),
			-_w,
			signal.ray.position());

	// rotate ray direction around (0,0,0)
	signal.ray.direction() = util::rotate3d(
			util::ray<float,3>(
					util::point<float,3>( 0,  0,  0),
					util::point<float,3>(_x, _y, _z)),
			-_w,
			signal.ray.direction());

	std::cout << "transformed ray " << signal.ray << std::endl;

	return true;
}

void
RotateView::unfilterDown(PointerSignal& signal) {

	// inversely rotate ray position around content center
	signal.ray.position() = util::rotate3d(
			util::ray<float,3>(
					_contentSize.center(),
					util::point<float,3>(_x, _y, _z)),
			_w,
			signal.ray.position());

	// inversely rotate ray direction around (0,0,0)
	signal.ray.direction() = util::rotate3d(
			util::ray<float,3>(
					util::point<float,3>( 0,  0,  0),
					util::point<float,3>(_x, _y, _z)),
			_w,
			signal.ray.direction());
}

void
RotateView::onSignal(MouseDown& signal) {

	util::point<float,2> position = signal.ray.position().project<2>();

	LOG_ALL(rotateviewlog) << "mouse button " << signal.button << " down, position is " << position << std::endl;

	if (signal.button == buttons::Left && _contentSize.contains(position)) {

		LOG_ALL(rotateviewlog) << "it's the left mouse button -- start dragging mode" << std::endl;

		_dragging = true;
		_buttonDown = position;

		_prevX = _x;
		_prevY = _y;
		_prevZ = _z;
		_prevW = _w;
	}
}

void
RotateView::onSignal(MouseMove& signal) {

	LOG_ALL(rotateviewlog) << "the mouse is moved" << std::endl;

	if (!signal.modifiers & buttons::LeftDown) {

		bool wasHighlighted = _highlight;

		_highlight = _contentSize.contains(signal.ray.position().project<2>());

		if (wasHighlighted != _highlight)
			send<ContentChanged>();
	}

	if (!_dragging)
		return;

	LOG_ALL(rotateviewlog) << "I am in dragging mode" << std::endl;

	// mouse is dragged
	if (signal.modifiers & buttons::LeftDown) {

		LOG_ALL(rotateviewlog) << "left button is still pressed" << std::endl;

		util::point<float,2> moved = signal.ray.position().project<2>() - _buttonDown;

		// scale movement with inverse size of content
		moved.x() /= _contentSize.width();
		moved.y() /= _contentSize.height();

		// change the current rotation according to mouse movement
		rotate(moved);

		send<ContentChanged>();

	} else {

		LOG_ALL(rotateviewlog) << "left button released -- stop dragging" << std::endl;

		_dragging = false;
	}
}

void
RotateView::onInnerSignal(ContentChanged&) {

	_contentSize = util::box<float,3>();
	updateContentSize();
}

void
RotateView::updateContentSize() {

	LOG_ALL(rotateviewlog) << "updating content size..." << std::endl;

	if (!_contentSize.isZero())
		return;

	QuerySize query;
	sendInner(query);
	_contentSize = query.getSize();
}

void
RotateView::rotate(const util::point<float,2>& moved) {

	LOG_ALL(rotateviewlog) << "current rotation: " << _w << ", (" << _x << ", " << _y << ", " << _z << ")" << std::endl;

	LOG_ALL(rotateviewlog) << "moved by: " << moved << std::endl;

	// previous rotation to quaternion
	float qx, qy, qz, qw;

	qx = _prevX*sin(_prevW/2.0);
	qy = _prevY*sin(_prevW/2.0);
	qz = _prevZ*sin(_prevW/2.0);
	qw =        cos(_prevW/2.0);

	// difference rotation as angle-axis
	float dx, dy, dz, dw;

	// ensure numerical stability
	float dnorm = sqrt(moved.y()*moved.y() + moved.x()*moved.x());
	if (dnorm <= 0.0001)
		return;

	dx =  moved.y()/dnorm;
	dy = -moved.x()/dnorm;
	dz = 0.0;
	dw = dnorm*M_PI;

	LOG_ALL(rotateviewlog) << "add rotation: " << dw << ", (" << dx << ", " << dy << ", " << dz << ")" << std::endl;

	// difference rotation to quaternion
	float qdx, qdy, qdz, qdw;

	qdx = dx*sin(dw/2.0);
	qdy = dy*sin(dw/2.0);
	qdz = dz*sin(dw/2.0);
	qdw =    cos(dw/2.0);

	// composition of both quaternions
	float cx, cy, cz, cw;

	cw = (qdw*qw - qdx*qx - qdy*qy - qdz*qz);
	cx = (qdw*qx + qdx*qw + qdy*qz - qdz*qy);
	cy = (qdw*qy - qdx*qz + qdy*qw + qdz*qx);
	cz = (qdw*qz + qdx*qy - qdy*qx + qdz*qw);

	LOG_ALL(rotateviewlog) << "result quaternion: " << cw << ", (" << cx << ", " << cy << ", " << cz << ")" << std::endl;

	// back to axis-angle rotation
	_w = 2*acos(cw);
	_x = cx/sin(_w/2.0);
	_y = cy/sin(_w/2.0);
	_z = cz/sin(_w/2.0);

	// normalize rotation vector
	float norm = sqrt(_x*_x + _y*_y + _z*_z);
	_x = _x/norm;
	_y = _y/norm;
	_z = _z/norm;

	LOG_ALL(rotateviewlog) << "new rotation: " << _w << ", (" << _x << ", " << _y << ", " << _z << ")" << std::endl;
}

} // namespace sg_gui
<commit_msg>fixed bounding box computation in RotateView<commit_after>#include <cmath>
#include <util/Logger.h>
#include <util/geometry.hpp>
#include "OpenGl.h"
#include "RotateView.h"

namespace sg_gui {

static logger::LogChannel rotateviewlog("rotateviewlog", "[RotateView] ");

RotateView::RotateView() :
	_x(0.0),
	_y(1.0),
	_z(0.0),
	_w(0.0),
	_prevX(0.0),
	_prevY(1.0),
	_prevZ(0.0),
	_prevW(0.0),
	_buttonDown(0, 0),
	_dragging(false),
	_highlight(false) {}

bool
RotateView::filterDown(DrawBase& /*signal*/) {

	updateContentSize();

	util::point<float,3> min    = _contentSize.min();
	util::point<float,3> max    = _contentSize.max();
	util::point<float,3> center = _contentSize.center();

	glMatrixMode(GL_MODELVIEW);

	glPushMatrix();

	// put a light
	float lightX = -100;
	float lightY = -100;
	float lightZ = -100;
	GLfloat lightpos[] = {lightX, lightY, lightZ, 0.0};
	glEnable(GL_LIGHT1);
	glLightfv(GL_LIGHT1, GL_POSITION, lightpos);
	GLfloat ambient[] = {0.5, 0.5, 0.5, 1.0};
	glLightfv(GL_LIGHT1, GL_AMBIENT, ambient);
	GLfloat specular[] = {0.3, 0.3, 0.3, 1.0};
	glLightfv(GL_LIGHT1, GL_SPECULAR, specular);
	GLfloat diffuse[] = {0.5, 0.5, 0.5, 1.0};
	glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse);

	// perform the rotation
	glTranslated(center.x(),  center.y(), center.z());
	glRotated(_w/M_PI*180.0, _x, _y, _z);
	glTranslated(-center.x(), -center.y(), -center.z());

	glColor4f((_highlight ? 0.88 : 0.1), 0.2, 0.05, 0.5);

	// draw box around content
	glLineWidth(1.0);
	glEnable(GL_LINE_SMOOTH);

	glBegin(GL_LINES);
	glVertex3f(min.x(), min.y(), min.z());
	glVertex3f(min.x(), min.y(), max.z());

	glVertex3f(min.x(), min.y(), max.z());
	glVertex3f(min.x(), max.y(), max.z());

	glVertex3f(min.x(), max.y(), max.z());
	glVertex3f(min.x(), max.y(), min.z());

	glVertex3f(min.x(), max.y(), min.z());
	glVertex3f(min.x(), min.y(), min.z());

	glVertex3f(max.x(), min.y(), min.z());
	glVertex3f(max.x(), min.y(), max.z());

	glVertex3f(max.x(), min.y(), max.z());
	glVertex3f(max.x(), max.y(), max.z());

	glVertex3f(max.x(), max.y(), max.z());
	glVertex3f(max.x(), max.y(), min.z());

	glVertex3f(max.x(), max.y(), min.z());
	glVertex3f(max.x(), min.y(), min.z());

	glVertex3f(min.x(), min.y(), min.z());
	glVertex3f(max.x(), min.y(), min.z());

	glVertex3f(min.x(), min.y(), max.z());
	glVertex3f(max.x(), min.y(), max.z());

	glVertex3f(min.x(), max.y(), max.z());
	glVertex3f(max.x(), max.y(), max.z());

	glVertex3f(min.x(), max.y(), min.z());
	glVertex3f(max.x(), max.y(), min.z());
	glEnd();

	glEnable(GL_LIGHTING);
	glEnable(GL_COLOR_MATERIAL);

	return true;
}

void
RotateView::unfilterDown(DrawBase& /*signal*/) {

	glDisable(GL_LIGHT1);
	glPopMatrix();
}

bool
RotateView::filterDown(QuerySize& signal) {

	LOG_ALL(rotateviewlog) << "got size query..." << std::endl;

	updateContentSize();

	LOG_ALL(rotateviewlog) << "content size is " << _contentSize << std::endl;

	// bounding box of all possible rotations around center
	float maxDiameter = util::length(_contentSize.max() - _contentSize.min());
	util::point<float,3> center = _contentSize.center();

	util::box<float,3> size(
			center - util::point<float,3>(maxDiameter/2, maxDiameter/2, maxDiameter/2),
			center + util::point<float,3>(maxDiameter/2, maxDiameter/2, maxDiameter/2));

	LOG_ALL(rotateviewlog) << "max rotated content size is " << size << std::endl;

	signal.setSize(size);

	return false;
}

void
RotateView::unfilterDown(QuerySize& draw) {}

bool
RotateView::filterDown(PointerSignal& signal) {

	// rotate ray position around content center
	signal.ray.position() = util::rotate3d(
			util::ray<float,3>(
					_contentSize.center(),
					util::point<float,3>(_x, _y, _z)),
			-_w,
			signal.ray.position());

	// rotate ray direction around (0,0,0)
	signal.ray.direction() = util::rotate3d(
			util::ray<float,3>(
					util::point<float,3>( 0,  0,  0),
					util::point<float,3>(_x, _y, _z)),
			-_w,
			signal.ray.direction());

	std::cout << "transformed ray " << signal.ray << std::endl;

	return true;
}

void
RotateView::unfilterDown(PointerSignal& signal) {

	// inversely rotate ray position around content center
	signal.ray.position() = util::rotate3d(
			util::ray<float,3>(
					_contentSize.center(),
					util::point<float,3>(_x, _y, _z)),
			_w,
			signal.ray.position());

	// inversely rotate ray direction around (0,0,0)
	signal.ray.direction() = util::rotate3d(
			util::ray<float,3>(
					util::point<float,3>( 0,  0,  0),
					util::point<float,3>(_x, _y, _z)),
			_w,
			signal.ray.direction());
}

void
RotateView::onSignal(MouseDown& signal) {

	util::point<float,2> position = signal.ray.position().project<2>();

	LOG_ALL(rotateviewlog) << "mouse button " << signal.button << " down, position is " << position << std::endl;

	if (signal.button == buttons::Left && _contentSize.contains(position)) {

		LOG_ALL(rotateviewlog) << "it's the left mouse button -- start dragging mode" << std::endl;

		_dragging = true;
		_buttonDown = position;

		_prevX = _x;
		_prevY = _y;
		_prevZ = _z;
		_prevW = _w;
	}
}

void
RotateView::onSignal(MouseMove& signal) {

	LOG_ALL(rotateviewlog) << "the mouse is moved" << std::endl;

	if (!signal.modifiers & buttons::LeftDown) {

		bool wasHighlighted = _highlight;

		_highlight = _contentSize.contains(signal.ray.position().project<2>());

		if (wasHighlighted != _highlight)
			send<ContentChanged>();
	}

	if (!_dragging)
		return;

	LOG_ALL(rotateviewlog) << "I am in dragging mode" << std::endl;

	// mouse is dragged
	if (signal.modifiers & buttons::LeftDown) {

		LOG_ALL(rotateviewlog) << "left button is still pressed" << std::endl;

		util::point<float,2> moved = signal.ray.position().project<2>() - _buttonDown;

		// scale movement with inverse size of content
		moved.x() /= _contentSize.width();
		moved.y() /= _contentSize.height();

		// change the current rotation according to mouse movement
		rotate(moved);

		send<ContentChanged>();

	} else {

		LOG_ALL(rotateviewlog) << "left button released -- stop dragging" << std::endl;

		_dragging = false;
	}
}

void
RotateView::onInnerSignal(ContentChanged&) {

	_contentSize = util::box<float,3>();
	updateContentSize();
}

void
RotateView::updateContentSize() {

	LOG_ALL(rotateviewlog) << "updating content size..." << std::endl;

	if (!_contentSize.isZero())
		return;

	QuerySize query;
	sendInner(query);
	_contentSize = query.getSize();
}

void
RotateView::rotate(const util::point<float,2>& moved) {

	LOG_ALL(rotateviewlog) << "current rotation: " << _w << ", (" << _x << ", " << _y << ", " << _z << ")" << std::endl;

	LOG_ALL(rotateviewlog) << "moved by: " << moved << std::endl;

	// previous rotation to quaternion
	float qx, qy, qz, qw;

	qx = _prevX*sin(_prevW/2.0);
	qy = _prevY*sin(_prevW/2.0);
	qz = _prevZ*sin(_prevW/2.0);
	qw =        cos(_prevW/2.0);

	// difference rotation as angle-axis
	float dx, dy, dz, dw;

	// ensure numerical stability
	float dnorm = sqrt(moved.y()*moved.y() + moved.x()*moved.x());
	if (dnorm <= 0.0001)
		return;

	dx =  moved.y()/dnorm;
	dy = -moved.x()/dnorm;
	dz = 0.0;
	dw = dnorm*M_PI;

	LOG_ALL(rotateviewlog) << "add rotation: " << dw << ", (" << dx << ", " << dy << ", " << dz << ")" << std::endl;

	// difference rotation to quaternion
	float qdx, qdy, qdz, qdw;

	qdx = dx*sin(dw/2.0);
	qdy = dy*sin(dw/2.0);
	qdz = dz*sin(dw/2.0);
	qdw =    cos(dw/2.0);

	// composition of both quaternions
	float cx, cy, cz, cw;

	cw = (qdw*qw - qdx*qx - qdy*qy - qdz*qz);
	cx = (qdw*qx + qdx*qw + qdy*qz - qdz*qy);
	cy = (qdw*qy - qdx*qz + qdy*qw + qdz*qx);
	cz = (qdw*qz + qdx*qy - qdy*qx + qdz*qw);

	LOG_ALL(rotateviewlog) << "result quaternion: " << cw << ", (" << cx << ", " << cy << ", " << cz << ")" << std::endl;

	// back to axis-angle rotation
	_w = 2*acos(cw);
	_x = cx/sin(_w/2.0);
	_y = cy/sin(_w/2.0);
	_z = cz/sin(_w/2.0);

	// normalize rotation vector
	float norm = sqrt(_x*_x + _y*_y + _z*_z);
	_x = _x/norm;
	_y = _y/norm;
	_z = _z/norm;

	LOG_ALL(rotateviewlog) << "new rotation: " << _w << ", (" << _x << ", " << _y << ", " << _z << ")" << std::endl;
}

} // namespace sg_gui
<|endoftext|>


<commit_before>// Copyright 2010-2013 RethinkDB, all rights reserved.
#ifndef RDB_PROTOCOL_DATUM_HPP_
#define RDB_PROTOCOL_DATUM_HPP_

#include <map>
#include <memory>
#include <set>
#include <string>
#include <utility>
#include <vector>

#include "btree/keys.hpp"
#include "containers/archive/archive.hpp"
#include "containers/counted.hpp"
#include "containers/scoped.hpp"
#include "http/json.hpp"
#include "rdb_protocol/error.hpp"

class Datum;

RDB_DECLARE_SERIALIZABLE(Datum);

namespace ql {
class datum_stream_t;
class env_t;
class val_t;

namespace pseudo {
class datum_cmp_t;
void time_to_str_key(const datum_t &d, std::string *str_out);
void sanitize_time(datum_t *time);
} // namespace pseudo

// These let us write e.g. `foo(NOTHROW) instead of `foo(false/*nothrow*/)`.
// They should be passed to functions that have multiple behaviors (like `el` or
// `add` below).

// NOTHROW: Return NULL
// THROW: Throw an error
enum throw_bool_t { NOTHROW = 0, THROW = 1};

// NOCLOBBER: Don't overwrite existing values.
// CLOBBER: Overwrite existing values.
enum clobber_bool_t { NOCLOBBER = 0, CLOBBER = 1};

// A `datum_t` is basically a JSON value, although we may extend it later.
class datum_t : public slow_atomic_countable_t<datum_t> {
public:
    // This ordering is important, because we use it to sort objects of
    // disparate type.  It should be alphabetical.
    enum type_t { UNINITIALIZED = 0, R_ARRAY = 1, R_BOOL = 2, R_NULL = 3,
                  R_NUM = 4, R_OBJECT = 5, R_STR = 6 };
    explicit datum_t(type_t _type);

    // These allow you to construct a datum from the type of value it
    // represents.  We have some gotchya-constructors to scare away implicit
    // conversions.
    explicit datum_t(bool) = delete;
    explicit datum_t(int) = delete;
    explicit datum_t(float) = delete;
    // Need to explicitly ask to construct a bool.
    datum_t(type_t _type, bool _bool);
    explicit datum_t(double _num);
    explicit datum_t(std::string &&str);
    explicit datum_t(const char *cstr);
    explicit datum_t(std::vector<counted_t<const datum_t> > &&_array);
    explicit datum_t(std::map<std::string, counted_t<const datum_t> > &&object);

    // These construct a datum from an equivalent representation.
    datum_t();
    explicit datum_t(const Datum *d);
    void init_from_pb(const Datum *d);
    explicit datum_t(cJSON *json);
    explicit datum_t(const scoped_cJSON_t &json);

    ~datum_t();

    void write_to_protobuf(Datum *out) const;

    type_t get_type() const;
    bool is_ptype() const;
    bool is_ptype(const std::string &reql_type) const;
    std::string get_reql_type() const;
    std::string get_type_name() const;
    std::string print() const;
    static const size_t trunc_len = 300;
    std::string trunc_print() const;
    std::string print_primary() const;
    std::string print_secondary(const store_key_t &key) const;
    /* An inverse to print_secondary. Returns the primary key. */
    static std::string unprint_secondary(const std::string &secondary_and_primary);
    static std::string extract_secondary(const std::string &secondary_and_primary);
    store_key_t truncated_secondary() const;
    void check_type(type_t desired, const char *msg = NULL) const;
    void type_error(const std::string &msg) const NORETURN;

    bool as_bool() const;
    double as_num() const;
    int64_t as_int() const;
    const std::string &as_str() const;

    // Use of `size` and `el` is preferred to `as_array` when possible.
    const std::vector<counted_t<const datum_t> > &as_array() const;
    size_t size() const;
    // Access an element of an array.
    counted_t<const datum_t> get(size_t index, throw_bool_t throw_bool = THROW) const;
    // Use of `get` is preferred to `as_object` when possible.
    const std::map<std::string, counted_t<const datum_t> > &as_object() const;

    // Access an element of an object.
    counted_t<const datum_t> get(const std::string &key,
                                 throw_bool_t throw_bool = THROW) const;
    counted_t<const datum_t> merge(counted_t<const datum_t> rhs) const;
    // RSI: Rename this typedef.
    typedef counted_t<const datum_t> (*merge_resoluter_t)(const std::string &key,
                                                          counted_t<const datum_t> l,
                                                          counted_t<const datum_t> r);
    counted_t<const datum_t> merge(counted_t<const datum_t> rhs,
                                   merge_resoluter_t f) const;

    cJSON *as_json_raw() const;
    scoped_cJSON_t as_json() const;
    counted_t<datum_stream_t> as_datum_stream(
            const protob_t<const Backtrace> &backtrace) const;

    // These behave as expected and defined in RQL.  Theoretically, two data of
    // the same type should compare the same way their printed representations
    // would compare lexicographcally, while dispareate types are compared
    // alphabetically by type name.
    int cmp(const datum_t &rhs) const;
    bool operator==(const datum_t &rhs) const;
    bool operator!=(const datum_t &rhs) const;

    bool operator<(const datum_t &rhs) const;
    bool operator<=(const datum_t &rhs) const;
    bool operator>(const datum_t &rhs) const;
    bool operator>=(const datum_t &rhs) const;

    void runtime_fail(base_exc_t::type_t exc_type,
                      const char *test, const char *file, int line,
                      std::string msg) const NORETURN;

    static size_t max_trunc_size();
    /* Note key_is_truncated returns true if the key is of max size. This gives
     * a false positive if the sum sizes of the keys is exactly the maximum but
     * not over at all. This means that a key of exactly max_trunc_size counts
     * as truncated by this function. Unfortunately there isn't a general way
     * to tell if keys of max_trunc_size were exactly that size or longer and
     * thus truncated. */
    static bool key_is_truncated(const store_key_t &key);

    void rcheck_is_ptype(const std::string s = "") const;

private:
    friend class datum_ptr_t;
    friend void pseudo::sanitize_time(datum_t *time);
    void add(counted_t<const datum_t> val); // add to an array
    // change an element of an array
    void change(size_t index, counted_t<const datum_t> val);
    void insert(size_t index, counted_t<const datum_t> val); // insert into an array
    void erase(size_t index); // erase from an array
    void erase_range(size_t start, size_t end); // erase a range from an array
    void splice(size_t index, counted_t<const datum_t> values);
    MUST_USE bool add(const std::string &key, counted_t<const datum_t> val,
                      clobber_bool_t clobber_bool = NOCLOBBER); // add to an object
    // Returns true if key was in object.
    MUST_USE bool delete_field(const std::string &key);

    void init_empty();
    void init_str();
    void init_array();
    void init_object();
    void init_json(cJSON *json);

    void check_str_validity(const std::string &str);

    friend void pseudo::time_to_str_key(const datum_t &d, std::string *str_out);
    void pt_to_str_key(std::string *str_out) const;
    void num_to_str_key(std::string *str_out) const;
    void str_to_str_key(std::string *str_out) const;
    void bool_to_str_key(std::string *str_out) const;
    void array_to_str_key(std::string *str_out) const;

    int pseudo_cmp(const datum_t &rhs) const;
    static const std::set<std::string> _allowed_pts;
    void maybe_sanitize_ptype(const std::set<std::string> &allowed_pts = _allowed_pts);

    type_t type;
    union {
        bool r_bool;
        double r_num;
        // TODO: Make this a char vector
        std::string *r_str;
        std::vector<counted_t<const datum_t> > *r_array;
        std::map<std::string, counted_t<const datum_t> > *r_object;
    };

public:
    static const char* const reql_type_string;

private:
    DISABLE_COPYING(datum_t);
};

size_t serialized_size(const counted_t<const datum_t> &datum);

write_message_t &operator<<(write_message_t &wm, const counted_t<const datum_t> &datum);
archive_result_t deserialize(read_stream_t *s, counted_t<const datum_t> *datum);

write_message_t &operator<<(write_message_t &wm, const empty_ok_t<const counted_t<const datum_t> > &datum);
archive_result_t deserialize(read_stream_t *s, empty_ok_ref_t<counted_t<const datum_t> > datum);

// Converts a double to int, but returns false if it's not an integer orout of range.
bool number_as_integer(double d, int64_t *i_out);

// Converts a double to int, calling number_as_integer and throwing if it fails.
int64_t checked_convert_to_int(const rcheckable_t *target, double d);

// If you need to do mutable operations to a `datum_t`, use one of these (it's
// basically a `scoped_ptr_t` that can access private methods on `datum_t` and
// checks for pseudotype validity when you turn it into a `counted_t<const
// datum_t>`).
class datum_ptr_t {
public:
    template<class... Args>
    explicit datum_ptr_t(Args... args) : ptr_(make_scoped<datum_t>(std::forward<Args>(args)...)) { }
    counted_t<const datum_t> to_counted(
            const std::set<std::string> &allowed_ptypes = std::set<std::string>()) {
        ptr()->maybe_sanitize_ptype(allowed_ptypes);
        return counted_t<const datum_t>(ptr_.release());
    }
    const datum_t *operator->() const { return const_ptr(); }
    void add(counted_t<const datum_t> val) { ptr()->add(val); }
    void change(size_t i, counted_t<const datum_t> val) { ptr()->change(i, val); }
    void insert(size_t i, counted_t<const datum_t> val) { ptr()->insert(i, val); }
    void erase(size_t i) { ptr()->erase(i); }
    void erase_range(size_t start, size_t end) { ptr()->erase_range(start, end); }
    void splice(size_t index, counted_t<const datum_t> values) {
        ptr()->splice(index, values);
    }
    MUST_USE bool add(const std::string &key, counted_t<const datum_t> val,
                      clobber_bool_t clobber_bool = NOCLOBBER) {
        return ptr()->add(key, val, clobber_bool);
    }
    MUST_USE bool delete_field(const std::string &key) {
        return ptr()->delete_field(key);
    }

private:
    datum_t *ptr() {
        r_sanity_check(ptr_.has());
        return ptr_.get();
    }
    const datum_t *const_ptr() const {
        r_sanity_check(ptr_.has());
        return ptr_.get();
    }

    scoped_ptr_t<datum_t> ptr_;
    DISABLE_COPYING(datum_ptr_t);
};

// This is like a `wire_datum_t` but for gmr.  We need it because gmr allows
// non-strings as keys, while the data model we pinched from JSON doesn't.  See
// README.md for more info.
class wire_datum_map_t {
public:
    wire_datum_map_t() : state(COMPILED) { }
    bool has(counted_t<const datum_t> key);
    counted_t<const datum_t> get(counted_t<const datum_t> key);
    void set(counted_t<const datum_t> key, counted_t<const datum_t> val);

    void compile();
    void finalize();

    counted_t<const datum_t> to_arr() const;
private:
    struct datum_value_compare_t {
        bool operator()(counted_t<const datum_t> a, counted_t<const datum_t> b) const {
            return *a < *b;
        }
    };

    std::map<counted_t<const datum_t>,
             counted_t<const datum_t>,
             datum_value_compare_t> map;
    std::vector<std::pair<Datum, Datum> > map_pb;

public:
    friend class write_message_t;
    void rdb_serialize(write_message_t &msg /* NOLINT */) const;
    friend class archive_deserializer_t;
    archive_result_t rdb_deserialize(read_stream_t *s);

private:
    enum { SERIALIZABLE, COMPILED } state;
};

namespace pseudo {
class datum_cmp_t {
public:
    virtual int operator()(const datum_t &x, const datum_t &y) const = 0;
    virtual ~datum_cmp_t() { }
};
} // namespace pseudo

} // namespace ql
#endif // RDB_PROTOCOL_DATUM_HPP_
<commit_msg>Fixed typo in comment in datum.hpp.<commit_after>// Copyright 2010-2013 RethinkDB, all rights reserved.
#ifndef RDB_PROTOCOL_DATUM_HPP_
#define RDB_PROTOCOL_DATUM_HPP_

#include <map>
#include <memory>
#include <set>
#include <string>
#include <utility>
#include <vector>

#include "btree/keys.hpp"
#include "containers/archive/archive.hpp"
#include "containers/counted.hpp"
#include "containers/scoped.hpp"
#include "http/json.hpp"
#include "rdb_protocol/error.hpp"

class Datum;

RDB_DECLARE_SERIALIZABLE(Datum);

namespace ql {
class datum_stream_t;
class env_t;
class val_t;

namespace pseudo {
class datum_cmp_t;
void time_to_str_key(const datum_t &d, std::string *str_out);
void sanitize_time(datum_t *time);
} // namespace pseudo

// These let us write e.g. `foo(NOTHROW) instead of `foo(false/*nothrow*/)`.
// They should be passed to functions that have multiple behaviors (like `el` or
// `add` below).

// NOTHROW: Return NULL
// THROW: Throw an error
enum throw_bool_t { NOTHROW = 0, THROW = 1};

// NOCLOBBER: Don't overwrite existing values.
// CLOBBER: Overwrite existing values.
enum clobber_bool_t { NOCLOBBER = 0, CLOBBER = 1};

// A `datum_t` is basically a JSON value, although we may extend it later.
class datum_t : public slow_atomic_countable_t<datum_t> {
public:
    // This ordering is important, because we use it to sort objects of
    // disparate type.  It should be alphabetical.
    enum type_t { UNINITIALIZED = 0, R_ARRAY = 1, R_BOOL = 2, R_NULL = 3,
                  R_NUM = 4, R_OBJECT = 5, R_STR = 6 };
    explicit datum_t(type_t _type);

    // These allow you to construct a datum from the type of value it
    // represents.  We have some gotchya-constructors to scare away implicit
    // conversions.
    explicit datum_t(bool) = delete;
    explicit datum_t(int) = delete;
    explicit datum_t(float) = delete;
    // Need to explicitly ask to construct a bool.
    datum_t(type_t _type, bool _bool);
    explicit datum_t(double _num);
    explicit datum_t(std::string &&str);
    explicit datum_t(const char *cstr);
    explicit datum_t(std::vector<counted_t<const datum_t> > &&_array);
    explicit datum_t(std::map<std::string, counted_t<const datum_t> > &&object);

    // These construct a datum from an equivalent representation.
    datum_t();
    explicit datum_t(const Datum *d);
    void init_from_pb(const Datum *d);
    explicit datum_t(cJSON *json);
    explicit datum_t(const scoped_cJSON_t &json);

    ~datum_t();

    void write_to_protobuf(Datum *out) const;

    type_t get_type() const;
    bool is_ptype() const;
    bool is_ptype(const std::string &reql_type) const;
    std::string get_reql_type() const;
    std::string get_type_name() const;
    std::string print() const;
    static const size_t trunc_len = 300;
    std::string trunc_print() const;
    std::string print_primary() const;
    std::string print_secondary(const store_key_t &key) const;
    /* An inverse to print_secondary. Returns the primary key. */
    static std::string unprint_secondary(const std::string &secondary_and_primary);
    static std::string extract_secondary(const std::string &secondary_and_primary);
    store_key_t truncated_secondary() const;
    void check_type(type_t desired, const char *msg = NULL) const;
    void type_error(const std::string &msg) const NORETURN;

    bool as_bool() const;
    double as_num() const;
    int64_t as_int() const;
    const std::string &as_str() const;

    // Use of `size` and `el` is preferred to `as_array` when possible.
    const std::vector<counted_t<const datum_t> > &as_array() const;
    size_t size() const;
    // Access an element of an array.
    counted_t<const datum_t> get(size_t index, throw_bool_t throw_bool = THROW) const;
    // Use of `get` is preferred to `as_object` when possible.
    const std::map<std::string, counted_t<const datum_t> > &as_object() const;

    // Access an element of an object.
    counted_t<const datum_t> get(const std::string &key,
                                 throw_bool_t throw_bool = THROW) const;
    counted_t<const datum_t> merge(counted_t<const datum_t> rhs) const;
    // RSI: Rename this typedef.
    typedef counted_t<const datum_t> (*merge_resoluter_t)(const std::string &key,
                                                          counted_t<const datum_t> l,
                                                          counted_t<const datum_t> r);
    counted_t<const datum_t> merge(counted_t<const datum_t> rhs,
                                   merge_resoluter_t f) const;

    cJSON *as_json_raw() const;
    scoped_cJSON_t as_json() const;
    counted_t<datum_stream_t> as_datum_stream(
            const protob_t<const Backtrace> &backtrace) const;

    // These behave as expected and defined in RQL.  Theoretically, two data of
    // the same type should compare the same way their printed representations
    // would compare lexicographcally, while dispareate types are compared
    // alphabetically by type name.
    int cmp(const datum_t &rhs) const;
    bool operator==(const datum_t &rhs) const;
    bool operator!=(const datum_t &rhs) const;

    bool operator<(const datum_t &rhs) const;
    bool operator<=(const datum_t &rhs) const;
    bool operator>(const datum_t &rhs) const;
    bool operator>=(const datum_t &rhs) const;

    void runtime_fail(base_exc_t::type_t exc_type,
                      const char *test, const char *file, int line,
                      std::string msg) const NORETURN;

    static size_t max_trunc_size();
    /* Note key_is_truncated returns true if the key is of max size. This gives
     * a false positive if the sum sizes of the keys is exactly the maximum but
     * not over at all. This means that a key of exactly max_trunc_size counts
     * as truncated by this function. Unfortunately there isn't a general way
     * to tell if keys of max_trunc_size were exactly that size or longer and
     * thus truncated. */
    static bool key_is_truncated(const store_key_t &key);

    void rcheck_is_ptype(const std::string s = "") const;

private:
    friend class datum_ptr_t;
    friend void pseudo::sanitize_time(datum_t *time);
    void add(counted_t<const datum_t> val); // add to an array
    // change an element of an array
    void change(size_t index, counted_t<const datum_t> val);
    void insert(size_t index, counted_t<const datum_t> val); // insert into an array
    void erase(size_t index); // erase from an array
    void erase_range(size_t start, size_t end); // erase a range from an array
    void splice(size_t index, counted_t<const datum_t> values);
    MUST_USE bool add(const std::string &key, counted_t<const datum_t> val,
                      clobber_bool_t clobber_bool = NOCLOBBER); // add to an object
    // Returns true if key was in object.
    MUST_USE bool delete_field(const std::string &key);

    void init_empty();
    void init_str();
    void init_array();
    void init_object();
    void init_json(cJSON *json);

    void check_str_validity(const std::string &str);

    friend void pseudo::time_to_str_key(const datum_t &d, std::string *str_out);
    void pt_to_str_key(std::string *str_out) const;
    void num_to_str_key(std::string *str_out) const;
    void str_to_str_key(std::string *str_out) const;
    void bool_to_str_key(std::string *str_out) const;
    void array_to_str_key(std::string *str_out) const;

    int pseudo_cmp(const datum_t &rhs) const;
    static const std::set<std::string> _allowed_pts;
    void maybe_sanitize_ptype(const std::set<std::string> &allowed_pts = _allowed_pts);

    type_t type;
    union {
        bool r_bool;
        double r_num;
        // TODO: Make this a char vector
        std::string *r_str;
        std::vector<counted_t<const datum_t> > *r_array;
        std::map<std::string, counted_t<const datum_t> > *r_object;
    };

public:
    static const char* const reql_type_string;

private:
    DISABLE_COPYING(datum_t);
};

size_t serialized_size(const counted_t<const datum_t> &datum);

write_message_t &operator<<(write_message_t &wm, const counted_t<const datum_t> &datum);
archive_result_t deserialize(read_stream_t *s, counted_t<const datum_t> *datum);

write_message_t &operator<<(write_message_t &wm, const empty_ok_t<const counted_t<const datum_t> > &datum);
archive_result_t deserialize(read_stream_t *s, empty_ok_ref_t<counted_t<const datum_t> > datum);

// Converts a double to int, but returns false if it's not an integer or out of range.
bool number_as_integer(double d, int64_t *i_out);

// Converts a double to int, calling number_as_integer and throwing if it fails.
int64_t checked_convert_to_int(const rcheckable_t *target, double d);

// If you need to do mutable operations to a `datum_t`, use one of these (it's
// basically a `scoped_ptr_t` that can access private methods on `datum_t` and
// checks for pseudotype validity when you turn it into a `counted_t<const
// datum_t>`).
class datum_ptr_t {
public:
    template<class... Args>
    explicit datum_ptr_t(Args... args) : ptr_(make_scoped<datum_t>(std::forward<Args>(args)...)) { }
    counted_t<const datum_t> to_counted(
            const std::set<std::string> &allowed_ptypes = std::set<std::string>()) {
        ptr()->maybe_sanitize_ptype(allowed_ptypes);
        return counted_t<const datum_t>(ptr_.release());
    }
    const datum_t *operator->() const { return const_ptr(); }
    void add(counted_t<const datum_t> val) { ptr()->add(val); }
    void change(size_t i, counted_t<const datum_t> val) { ptr()->change(i, val); }
    void insert(size_t i, counted_t<const datum_t> val) { ptr()->insert(i, val); }
    void erase(size_t i) { ptr()->erase(i); }
    void erase_range(size_t start, size_t end) { ptr()->erase_range(start, end); }
    void splice(size_t index, counted_t<const datum_t> values) {
        ptr()->splice(index, values);
    }
    MUST_USE bool add(const std::string &key, counted_t<const datum_t> val,
                      clobber_bool_t clobber_bool = NOCLOBBER) {
        return ptr()->add(key, val, clobber_bool);
    }
    MUST_USE bool delete_field(const std::string &key) {
        return ptr()->delete_field(key);
    }

private:
    datum_t *ptr() {
        r_sanity_check(ptr_.has());
        return ptr_.get();
    }
    const datum_t *const_ptr() const {
        r_sanity_check(ptr_.has());
        return ptr_.get();
    }

    scoped_ptr_t<datum_t> ptr_;
    DISABLE_COPYING(datum_ptr_t);
};

// This is like a `wire_datum_t` but for gmr.  We need it because gmr allows
// non-strings as keys, while the data model we pinched from JSON doesn't.  See
// README.md for more info.
class wire_datum_map_t {
public:
    wire_datum_map_t() : state(COMPILED) { }
    bool has(counted_t<const datum_t> key);
    counted_t<const datum_t> get(counted_t<const datum_t> key);
    void set(counted_t<const datum_t> key, counted_t<const datum_t> val);

    void compile();
    void finalize();

    counted_t<const datum_t> to_arr() const;
private:
    struct datum_value_compare_t {
        bool operator()(counted_t<const datum_t> a, counted_t<const datum_t> b) const {
            return *a < *b;
        }
    };

    std::map<counted_t<const datum_t>,
             counted_t<const datum_t>,
             datum_value_compare_t> map;
    std::vector<std::pair<Datum, Datum> > map_pb;

public:
    friend class write_message_t;
    void rdb_serialize(write_message_t &msg /* NOLINT */) const;
    friend class archive_deserializer_t;
    archive_result_t rdb_deserialize(read_stream_t *s);

private:
    enum { SERIALIZABLE, COMPILED } state;
};

namespace pseudo {
class datum_cmp_t {
public:
    virtual int operator()(const datum_t &x, const datum_t &y) const = 0;
    virtual ~datum_cmp_t() { }
};
} // namespace pseudo

} // namespace ql
#endif // RDB_PROTOCOL_DATUM_HPP_
<|endoftext|>


<commit_before>// RedPacketList.cpp : ʵļ
//

#include "stdafx.h"
#include "DacrsUI.h"
#include "RedPacketList.h"
#include "afxdialogex.h"

// CRedPacketList Ի

IMPLEMENT_DYNAMIC(CRedPacketList, CDialogEx)

CRedPacketList::CRedPacketList(CWnd* pParent /*=NULL*/)
	: CDialogEx(CRedPacketList::IDD, pParent)
{

}

CRedPacketList::~CRedPacketList()
{
}

void CRedPacketList::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_LIST2, m_listCtrl);
}

BEGIN_MESSAGE_MAP(CRedPacketList, CDialogEx)
END_MESSAGE_MAP()

// CRedPacketList Ϣ

void CRedPacketList::ShowTxDetail(CString txhash)
{
	CString strCommand,strShowData;
	strCommand.Format(_T("%s %s"),_T("gettxdetail") ,txhash );
	CSoyPayHelp::getInstance()->SendRpc(strCommand,strShowData);

	if (strShowData == _T(""))
	{
		return ;
	}
	Json::Reader reader;
	Json::Value root;
	if (!reader.parse(strShowData.GetString(), root))
		return ;
	int npos = strShowData.Find("confirmHeight");
	int confirHeight = 1440;
	if ( npos >= 0 ) { //
		confirHeight += root["confirmHeight"].asInt() ;    //ױȷϵĸ߶
	}

	vector<unsigned char>vHash;
	CSoyPayHelp::getInstance()->revert((char*)&confirHeight);

	char key[4];
	memset(key,0,4);

	memcpy(key,&confirHeight,sizeof(confirHeight));
	vHash.assign(key,key+sizeof(key));
	string strKeyHex = CSoyPayHelp::getInstance()->HexStr(vHash);

	vHash =CSoyPayHelp::getInstance()->ParseHex(txhash.GetString());
	reverse(vHash.begin(),vHash.end());
	string SendHash = CSoyPayHelp::getInstance()->HexStr(vHash);

	CString keyValue;
	keyValue.Format(_T("%s%s"),strKeyHex.c_str(),SendHash.c_str());
	strCommand.Format(_T("%s %s %s"),_T("getscriptdata") ,theApp.m_redPacketScriptid,keyValue );
	CSoyPayHelp::getInstance()->SendRpc(strCommand,strShowData);

	if (strShowData == _T("") || strShowData.Find("value") < 0)
		return ;

	if (!reader.parse(strShowData.GetString(), root))
		return ;;

	CString nValue = root["value"].asCString();
	uistruct::RED_DATA redPacket;
	memset(&redPacket , 0 , sizeof(uistruct::RED_DATA));
	std::vector<unsigned char> vTemp = CSoyPayHelp::getInstance()->ParseHex(nValue.GetString());
	memcpy(&redPacket, &vTemp[0], sizeof(uistruct::RED_DATA));

	CString showdata = _T(""); //= _T(" ַ                             \r\n\r\n");
	m_listCtrl.DeleteAllItems();
	 if (redPacket.dbdata.type == 3 && !redPacket.dbdata.fover)
	{
		//showdata.Format(_T("δ"));
		::MessageBox( this->GetSafeHwnd() ,_T("δ"), _T("ʾ") , MB_ICONINFORMATION ) ;
	}else{
		for (int i =0;i <redPacket.dbdata.takennum;i++)
		{
			int nSubIdx = 0;
			uistruct::USER_INFO userinfo = redPacket.userinfo[i];
			std::vector<unsigned char> vSendid;
			vSendid.assign(userinfo.regid,userinfo.regid+sizeof(userinfo.regid));
			string regid  =CSoyPayHelp::getInstance()->GetNotFullRegID(vSendid);
			double money = (userinfo.amount*1.0)/COIN;
			//showdata.AppendFormat(_T(" %s                       %.8f\r\n\r\n"),regid.c_str(),money);
			showdata.Format(_T("%d"),i);
			m_listCtrl.InsertItem(i, showdata);					//

			showdata.Format(_T("%s"),regid.c_str());
			m_listCtrl.SetItemText(i , ++nSubIdx , showdata );  //

			strShowData.Format(_T("%.8f"), money);
			m_listCtrl.SetItemText(i , ++nSubIdx , strShowData );  //hash

		}
	 }

	//GetDlgItem(IDC_EDIT_TXDETAIL)->SetWindowText(showdata);
}
BOOL CRedPacketList::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	struct LISTCol {
		CString		name ;
		UINT		size ;
	} listcol[3]  = {
		{"",          70},
		{"˻ID",          85},
		{"" ,      150}
	};

	for( int i = 0 ; i < 3 ; i++  ) {
		m_listCtrl.InsertColumn(i,listcol[i].name,LVCFMT_CENTER,listcol[i].size);
	}
	m_listCtrl.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_HEADERDRAGDROP );// |LVS_SINGLESEL  );
	// TODO:  ڴӶĳʼ
	ShowTxDetail(theApp.m_strAddress);
	return TRUE;  // return TRUE unless you set the focus to a control
	// 쳣: OCX ҳӦ FALSE
}
<commit_msg>修改接龙红包未抢完之前不显示列表<commit_after>// RedPacketList.cpp : ʵļ
//

#include "stdafx.h"
#include "DacrsUI.h"
#include "RedPacketList.h"
#include "afxdialogex.h"

// CRedPacketList Ի

IMPLEMENT_DYNAMIC(CRedPacketList, CDialogEx)

CRedPacketList::CRedPacketList(CWnd* pParent /*=NULL*/)
	: CDialogEx(CRedPacketList::IDD, pParent)
{

}

CRedPacketList::~CRedPacketList()
{
}

void CRedPacketList::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_LIST2, m_listCtrl);
}

BEGIN_MESSAGE_MAP(CRedPacketList, CDialogEx)
END_MESSAGE_MAP()

// CRedPacketList Ϣ

void CRedPacketList::ShowTxDetail(CString txhash)
{
	CString strCommand,strShowData;
	strCommand.Format(_T("%s %s"),_T("gettxdetail") ,txhash );
	CSoyPayHelp::getInstance()->SendRpc(strCommand,strShowData);

	if (strShowData == _T(""))
	{
		return ;
	}
	Json::Reader reader;
	Json::Value root;
	if (!reader.parse(strShowData.GetString(), root))
		return ;
	int npos = strShowData.Find("confirmHeight");
	int confirHeight = 1440;
	if ( npos >= 0 ) { //
		confirHeight += root["confirmHeight"].asInt() ;    //ױȷϵĸ߶
	}

	vector<unsigned char>vHash;
	CSoyPayHelp::getInstance()->revert((char*)&confirHeight);

	char key[4];
	memset(key,0,4);

	memcpy(key,&confirHeight,sizeof(confirHeight));
	vHash.assign(key,key+sizeof(key));
	string strKeyHex = CSoyPayHelp::getInstance()->HexStr(vHash);

	vHash =CSoyPayHelp::getInstance()->ParseHex(txhash.GetString());
	reverse(vHash.begin(),vHash.end());
	string SendHash = CSoyPayHelp::getInstance()->HexStr(vHash);

	CString keyValue;
	keyValue.Format(_T("%s%s"),strKeyHex.c_str(),SendHash.c_str());
	strCommand.Format(_T("%s %s %s"),_T("getscriptdata") ,theApp.m_redPacketScriptid,keyValue );
	CSoyPayHelp::getInstance()->SendRpc(strCommand,strShowData);

	if (strShowData == _T("") || strShowData.Find("value") < 0)
		return ;

	if (!reader.parse(strShowData.GetString(), root))
		return ;;

	CString nValue = root["value"].asCString();
	uistruct::RED_DATA redPacket;
	memset(&redPacket , 0 , sizeof(uistruct::RED_DATA));
	std::vector<unsigned char> vTemp = CSoyPayHelp::getInstance()->ParseHex(nValue.GetString());
	memcpy(&redPacket, &vTemp[0], sizeof(uistruct::RED_DATA));

	CString showdata = _T(""); //= _T(" ַ                             \r\n\r\n");
	m_listCtrl.DeleteAllItems();
	 if (redPacket.dbdata.type == 3 && !redPacket.dbdata.fover)
	{
		//showdata.Format(_T("δ"));
		::MessageBox( this->GetSafeHwnd() ,_T("δ"), _T("ʾ") , MB_ICONINFORMATION );
		CDialog::OnOK();
	}else{
		for (int i =0;i <redPacket.dbdata.takennum;i++)
		{
			int nSubIdx = 0;
			uistruct::USER_INFO userinfo = redPacket.userinfo[i];
			std::vector<unsigned char> vSendid;
			vSendid.assign(userinfo.regid,userinfo.regid+sizeof(userinfo.regid));
			string regid  =CSoyPayHelp::getInstance()->GetNotFullRegID(vSendid);
			double money = (userinfo.amount*1.0)/COIN;
			//showdata.AppendFormat(_T(" %s                       %.8f\r\n\r\n"),regid.c_str(),money);
			showdata.Format(_T("%d"),i);
			m_listCtrl.InsertItem(i, showdata);					//

			showdata.Format(_T("%s"),regid.c_str());
			m_listCtrl.SetItemText(i , ++nSubIdx , showdata );  //

			strShowData.Format(_T("%.8f"), money);
			m_listCtrl.SetItemText(i , ++nSubIdx , strShowData );  //hash

		}
	 }

	//GetDlgItem(IDC_EDIT_TXDETAIL)->SetWindowText(showdata);
}
BOOL CRedPacketList::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	struct LISTCol {
		CString		name ;
		UINT		size ;
	} listcol[3]  = {
		{"",          70},
		{"˻ID",          85},
		{"" ,      150}
	};

	for( int i = 0 ; i < 3 ; i++  ) {
		m_listCtrl.InsertColumn(i,listcol[i].name,LVCFMT_CENTER,listcol[i].size);
	}
	m_listCtrl.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_HEADERDRAGDROP );// |LVS_SINGLESEL  );
	// TODO:  ڴӶĳʼ
	ShowTxDetail(theApp.m_strAddress);
	return TRUE;  // return TRUE unless you set the focus to a control
	// 쳣: OCX ҳӦ FALSE
}
<|endoftext|>


<commit_before>//=====================================================================//
/*!	@file
	@brief	R8C I2C メイン @n
			for EEPROM 24FC1025
	@author	平松邦仁 (hira@rvf-rc45.net)
*/
//=====================================================================//
#include "main.hpp"
#include <cstring>
#include "system.hpp"
#include "clock.hpp"
#include "common/command.hpp"
#include "common/format.hpp"

static void wait_(uint16_t n)
{
	while(n > 0) {
		asm("nop");
		--n;
	}
}

static timer_b timer_b_;
static uart0 uart0_;
static utils::command<64> command_;
static i2c_io i2c_io_;
static eeprom eeprom_(i2c_io_);

extern "C" {
	void sci_putch(char ch) {
		uart0_.putch(ch);
	}

	char sci_getch(void) {
		return uart0_.getch();
	}

	uint16_t sci_length() {
		return uart0_.length();
	}

	void sci_puts(const char* str) {
		uart0_.puts(str);
	}
}

extern "C" {
	const void* variable_vectors_[] __attribute__ ((section (".vvec"))) = {
		(void*)brk_inst_,   nullptr,	// (0)
		(void*)null_task_,  nullptr,	// (1) flash_ready
		(void*)null_task_,  nullptr,	// (2)
		(void*)null_task_,  nullptr,	// (3)

		(void*)null_task_,  nullptr,	// (4) コンパレーターB1
		(void*)null_task_,  nullptr,	// (5) コンパレーターB3
		(void*)null_task_,  nullptr,	// (6)
		(void*)null_task_,  nullptr,	// (7) タイマＲＣ

		(void*)null_task_,  nullptr,	// (8)
		(void*)null_task_,  nullptr,	// (9)
		(void*)null_task_,  nullptr,	// (10)
		(void*)null_task_,  nullptr,	// (11)

		(void*)null_task_,  nullptr,	// (12)
		(void*)null_task_,  nullptr,	// (13) キー入力
		(void*)null_task_,  nullptr,	// (14) A/D 変換
		(void*)null_task_,  nullptr,	// (15)

		(void*)null_task_,  nullptr,	// (16)
		(void*)uart0_.send_task, nullptr,   // (17) UART0 送信
		(void*)uart0_.recv_task, nullptr,   // (18) UART0 受信
		(void*)null_task_,  nullptr,	// (19)

		(void*)null_task_,  nullptr,	// (20)
		(void*)null_task_,  nullptr,	// (21) /INT2
		(void*)null_task_,  nullptr,	// (22) タイマＲＪ２
		(void*)null_task_,  nullptr,	// (23) 周期タイマ

		(void*)timer_b_.itask,  nullptr,	// (24) タイマＲＢ２
		(void*)null_task_,  nullptr,	// (25) /INT1
		(void*)null_task_,  nullptr,	// (26) /INT3
		(void*)null_task_,  nullptr,	// (27)

		(void*)null_task_,  nullptr,	// (28)
		(void*)null_task_,  nullptr,	// (29) /INT0
		(void*)null_task_,  nullptr,	// (30)
		(void*)null_task_,  nullptr,	// (31)
	};
}

static bool check_key_word_(uint8_t idx, const char* key)
{
	char buff[12];
	if(command_.get_word(idx, sizeof(buff), buff)) {
		if(strcmp(buff, key) == 0) {
			return true;
		}
	}
	return false;
}

static bool get_value_(const char* text, uint32_t& val) {
	val = 0;
	char ch;
	while((ch = *text++) != 0) {
		if(ch >= '0' && ch <= '9') {
			ch -= '0';
		} else if(ch >= 'A' && ch <= 'F') {
			ch -= 'A' + 10;
		} else if(ch >= 'a' && ch <= 'f') {
			ch -= 'a' + 10;
		} else {
			return false;
		}
		val <<= 4;
		val |= ch;
	}
	return true;
}

static void dump_(uint32_t adr, const uint8_t* src, uint8_t len) {
	utils::format("%05X:") % adr;
	for(uint8_t i = 0; i < len; ++i) {
		utils::format(" %02X") % static_cast<uint32_t>(src[i]);
	}
}

 __attribute__ ((section (".exttext")))
int main(int argc, char *argv[])
{
	using namespace device;

// クロック関係レジスタ・プロテクト解除
	PRCR.PRC0 = 1;

// 高速オンチップオシレーターへ切り替え(20MHz)
// ※ F_CLK を設定する事（Makefile内）
	OCOCR.HOCOE = 1;
	wait_(1000);
	SCKCR.HSCKSEL = 1;
	CKSTPR.SCKSEL = 1;

	// タイマーＢ初期化
	{
		uint8_t ir_level = 2;
		timer_b_.start_timer(60, ir_level);
	}

	// UART の設定 (P1_4: TXD0[out], P1_5: RXD0[in])
	// ※シリアルライターでは、RXD 端子は、P1_6 となっているので注意！
	{
		utils::PORT_MAP(utils::port_map::P14::TXD0);
		utils::PORT_MAP(utils::port_map::P15::RXD0);
		uint8_t ir_level = 1;
		uart0_.start(19200, ir_level);
	}

	// I2C クラスの初期化
	{
		i2c_io_.init();
	}

	// EEPROM（24FC1025）を開始
	{
		// 2 バイトアドレス、ページサイズ128バイト
		uint8_t device_select = 0;
		eeprom_.start(device_select, true, 128);
	}

	sci_puts("Start R8C EEPROM monitor\n");
	command_.set_prompt("# ");

	// LED シグナル用ポートを出力
	PD1.B0 = 1;

	uint8_t cnt = 0;
	while(1) {
		timer_b_.sync();

		if(cnt >= 20) {
			cnt = 0;
		}
		if(cnt < 10) P1.B0 = 1;
		else P1.B0 = 0;
		++cnt;

		// コマンド入力と、コマンド解析
		if(command_.service()) {
			uint8_t cmdn = command_.get_words();
			bool err = true;
			if(cmdn == 1) {
				if(check_key_word_(0, "help")) {
					sci_puts("read xxxx\n");
					sci_puts("write yyyy aa bb cc ...\n");
					err = false;
				}
			} else if(cmdn == 2) {
				if(check_key_word_(0, "read")) {
					char buff[9];
					if(command_.get_word(1, sizeof(buff), buff)) {
						uint32_t adr;
						if(get_value_(buff, adr)) {
							uint8_t tmp[8];
							if(eeprom_.read(adr, tmp, 8)) {
								dump_(adr, tmp, 8);
							} else {
								sci_puts("Stall eeprom read...\n");
							}
							err = false;
						}
					}
				}
			} else if(cmdn >= 3 && cmdn <= 10) {
				if(check_key_word_(0, "write")) {
					char buff[9];
					if(command_.get_word(1, sizeof(buff), buff)) {
						uint32_t adr;
						if(get_value_(buff, adr)) {
							cmdn -= 2;
							uint8_t tmp[8];
							bool f = true;
							for(uint8_t i = 0; i < cmdn; ++i) {
								if(command_.get_word(2 + i, sizeof(buff), buff)) {
									uint32_t data;
									if(get_value_(buff, data)) {
										tmp[i] = data;
									} else {
										f = false;
										break;
									}
								} else {
									f = false;
									break;
								}
							}
							if(f) {
								if(!eeprom_.write(adr, tmp, cmdn)) {
									sci_puts("Stall eeprom write...\n");
								}
								err = false;
							}
						}
					}
				}
			}
			if(cmdn > 0 && err) {
				sci_puts("Command error: ");
				sci_puts(command_.get_command());
				sci_putch('\n');
			}
		}
	}
}
<commit_msg>update eeprom type<commit_after>//=====================================================================//
/*!	@file
	@brief	R8C I2C メイン @n
			for EEPROM 24FC1025
	@author	平松邦仁 (hira@rvf-rc45.net)
*/
//=====================================================================//
#include "main.hpp"
#include <cstring>
#include "system.hpp"
#include "clock.hpp"
#include "common/command.hpp"
#include "common/format.hpp"

static void wait_(uint16_t n)
{
	while(n > 0) {
		asm("nop");
		--n;
	}
}

static timer_b timer_b_;
static uart0 uart0_;
static utils::command<64> command_;
static i2c_io i2c_io_;
static eeprom eeprom_(i2c_io_);

extern "C" {
	void sci_putch(char ch) {
		uart0_.putch(ch);
	}

	char sci_getch(void) {
		return uart0_.getch();
	}

	uint16_t sci_length() {
		return uart0_.length();
	}

	void sci_puts(const char* str) {
		uart0_.puts(str);
	}
}

extern "C" {
	const void* variable_vectors_[] __attribute__ ((section (".vvec"))) = {
		(void*)brk_inst_,   nullptr,	// (0)
		(void*)null_task_,  nullptr,	// (1) flash_ready
		(void*)null_task_,  nullptr,	// (2)
		(void*)null_task_,  nullptr,	// (3)

		(void*)null_task_,  nullptr,	// (4) コンパレーターB1
		(void*)null_task_,  nullptr,	// (5) コンパレーターB3
		(void*)null_task_,  nullptr,	// (6)
		(void*)null_task_,  nullptr,	// (7) タイマＲＣ

		(void*)null_task_,  nullptr,	// (8)
		(void*)null_task_,  nullptr,	// (9)
		(void*)null_task_,  nullptr,	// (10)
		(void*)null_task_,  nullptr,	// (11)

		(void*)null_task_,  nullptr,	// (12)
		(void*)null_task_,  nullptr,	// (13) キー入力
		(void*)null_task_,  nullptr,	// (14) A/D 変換
		(void*)null_task_,  nullptr,	// (15)

		(void*)null_task_,  nullptr,	// (16)
		(void*)uart0_.send_task, nullptr,   // (17) UART0 送信
		(void*)uart0_.recv_task, nullptr,   // (18) UART0 受信
		(void*)null_task_,  nullptr,	// (19)

		(void*)null_task_,  nullptr,	// (20)
		(void*)null_task_,  nullptr,	// (21) /INT2
		(void*)null_task_,  nullptr,	// (22) タイマＲＪ２
		(void*)null_task_,  nullptr,	// (23) 周期タイマ

		(void*)timer_b_.itask,  nullptr,	// (24) タイマＲＢ２
		(void*)null_task_,  nullptr,	// (25) /INT1
		(void*)null_task_,  nullptr,	// (26) /INT3
		(void*)null_task_,  nullptr,	// (27)

		(void*)null_task_,  nullptr,	// (28)
		(void*)null_task_,  nullptr,	// (29) /INT0
		(void*)null_task_,  nullptr,	// (30)
		(void*)null_task_,  nullptr,	// (31)
	};
}

static bool check_key_word_(uint8_t idx, const char* key)
{
	char buff[12];
	if(command_.get_word(idx, sizeof(buff), buff)) {
		if(strcmp(buff, key) == 0) {
			return true;
		}
	}
	return false;
}

static bool get_value_(const char* text, uint32_t& val) {
	val = 0;
	char ch;
	while((ch = *text++) != 0) {
		if(ch >= '0' && ch <= '9') {
			ch -= '0';
		} else if(ch >= 'A' && ch <= 'F') {
			ch -= 'A' + 10;
		} else if(ch >= 'a' && ch <= 'f') {
			ch -= 'a' + 10;
		} else {
			return false;
		}
		val <<= 4;
		val |= ch;
	}
	return true;
}

static void dump_(uint32_t adr, const uint8_t* src, uint8_t len) {
	utils::format("%05X:") % adr;
	for(uint8_t i = 0; i < len; ++i) {
		utils::format(" %02X") % static_cast<uint32_t>(src[i]);
	}
	sci_putch('\n');
}

 __attribute__ ((section (".exttext")))
int main(int argc, char *argv[])
{
	using namespace device;

// クロック関係レジスタ・プロテクト解除
	PRCR.PRC0 = 1;

// 高速オンチップオシレーターへ切り替え(20MHz)
// ※ F_CLK を設定する事（Makefile内）
	OCOCR.HOCOE = 1;
	wait_(1000);
	SCKCR.HSCKSEL = 1;
	CKSTPR.SCKSEL = 1;

	// タイマーＢ初期化
	{
		uint8_t ir_level = 2;
		timer_b_.start_timer(60, ir_level);
	}

	// UART の設定 (P1_4: TXD0[out], P1_5: RXD0[in])
	// ※シリアルライターでは、RXD 端子は、P1_6 となっているので注意！
	{
		utils::PORT_MAP(utils::port_map::P14::TXD0);
		utils::PORT_MAP(utils::port_map::P15::RXD0);
		uint8_t ir_level = 1;
		uart0_.start(19200, ir_level);
	}

	// I2C クラスの初期化
	{
		i2c_io_.init();
	}

	// EEPROMを開始
	{
		// 24FC1025: 128KB、ID0, ページサイズ128バイト
		eeprom_.start(eeprom::M128KB::ID0, 128);

		// 24FC512:  64KB、 ID0, ページサイズ128バイト
//		eeprom_.start(eeprom::M64KB::ID0, 128);
	}

	sci_puts("Start R8C EEPROM monitor\n");
	command_.set_prompt("# ");

	// LED シグナル用ポートを出力
	PD1.B0 = 1;

	uint8_t cnt = 0;
	while(1) {
		timer_b_.sync();

		if(cnt >= 20) {
			cnt = 0;
		}
		if(cnt < 10) P1.B0 = 1;
		else P1.B0 = 0;
		++cnt;

		// コマンド入力と、コマンド解析
		if(command_.service()) {
			uint8_t cmdn = command_.get_words();
			bool err = true;
			if(cmdn == 1) {
				if(check_key_word_(0, "help")) {
					sci_puts("read xxxx\n");
					sci_puts("write yyyy aa bb cc ...\n");
					err = false;
				}
			} else if(cmdn == 2) {
				if(check_key_word_(0, "read")) {
					char buff[9];
					if(command_.get_word(1, sizeof(buff), buff)) {
						uint32_t adr;
						if(get_value_(buff, adr)) {
							uint8_t tmp[8];
							if(eeprom_.read(adr, tmp, 8)) {
								dump_(adr, tmp, 8);
							} else {
								sci_puts("Stall eeprom read...\n");
							}
							err = false;
						}
					}
				}
			} else if(cmdn >= 3 && cmdn <= 10) {
				if(check_key_word_(0, "write")) {
					char buff[9];
					if(command_.get_word(1, sizeof(buff), buff)) {
						uint32_t adr;
						if(get_value_(buff, adr)) {
							cmdn -= 2;
							uint8_t tmp[8];
							bool f = true;
							for(uint8_t i = 0; i < cmdn; ++i) {
								if(command_.get_word(2 + i, sizeof(buff), buff)) {
									uint32_t data;
									if(get_value_(buff, data)) {
										tmp[i] = data;
									} else {
										f = false;
										break;
									}
								} else {
									f = false;
									break;
								}
							}
							if(f) {
								if(!eeprom_.write(adr, tmp, cmdn)) {
									sci_puts("Stall eeprom write...\n");
								}
								err = false;
							}
						}
					}
				}
			}
			if(cmdn > 0 && err) {
				sci_puts("Command error: ");
				sci_puts(command_.get_command());
				sci_putch('\n');
			}
		}
	}
}
<|endoftext|>


<commit_before>#pragma once

#include <iostream>
#include <fstream>
#include <string>

template <typename T>
struct Node
{
	Node<T>* leftNode;
	Node<T>* rightNode;
	T value;

	Node(int value)
	{
		this->value = value;
		leftNode = nullptr;
		rightNode = nullptr;
	}
};

template <typename T>
class BinarySearchTree
{
private:
	Node<T>* _root;
	int _count;

public:
	BinarySearchTree();

	void destroyTree(Node<T>* node);

	~BinarySearchTree();

	T value_() const;

	T count() const;

	Node<T>* leftNode_() const;

	Node<T>* rightNode_() const;

	Node<T>* root() const;

	void insertElement(Node<T>* &node, const T &value);

	bool isInserted(const T& value);

	Node<T>* findElement(const T& value) const;

	bool isFound(const T& value) const;

	void infile(std::string filename);

	void outfile(Node<T>* root, std::ostream& outfile);

	void out(std::string filename);

	void paintTree(const Node<T>* node, int level) const;
};

template <typename T>
T BinarySearchTree<T>::value_() const
{
	return _root->value;
}

template <typename T>
T BinarySearchTree<T>::count() const
{
	return _count;
}

template <typename T>
Node<T>* BinarySearchTree<T>::root() const
{
	return _root;
}

template <typename T>
Node<T>* BinarySearchTree<T>::leftNode_() const
{
	return _root->leftNode;
}

template <typename T>
Node<T>* BinarySearchTree<T>::rightNode_() const
{
	return _root->rightNode;
}

template <typename T>
BinarySearchTree<T>::BinarySearchTree()
{
	_root = nullptr;
	_count = 0;
}

template <typename T>
void BinarySearchTree<T>::destroyTree(Node<T>* node)
{
	if (!node)
		return;

	if (node->leftNode)
	{
		destroyTree(node->leftNode);
		node->leftNode = nullptr;
	}

	if (node->rightNode)
	{
		destroyTree(node->rightNode);
		node->rightNode = nullptr;
	}
	delete node;
}

template <typename T>
BinarySearchTree<T>::~BinarySearchTree()
{
	destroyTree(_root);
}

template <typename T>
void BinarySearchTree<T>::insertElement(const T &value, Node<T>* &node=0)
{
	if (node)
	{
		if (value < node->value)
		{
			insert(node->leftNode, value);
		}
		else if (value > node->value)
		{
			insert(node->rightNode, value);
		}
		else
		{
			return;
		}
	}
	else
	{
		node = new Node<T>(value);
	}
	_count++;
}

template <typename T>
bool BinarySearchTree<T>::isInserted(const T& value)
{
	Node<T> *retNode = insertElement( value);
	if (retNode)
		return true;
	else
		return false;
}

template <typename T>
Node<T>*  BinarySearchTree<T>::findElement(const T& value) const
{
	Node<T> *currNode = _root;

	while (currNode)
	{
		if (currNode->value == value)
			break;
		else
		{
			if (currNode->value < value)
				currNode = currNode->rightNode;
			else currNode = currNode->leftNode;
		}
	}
	return currNode;
}

template <typename T>
bool BinarySearchTree<T>::isFound(const T& value) const
{
	Node<T> *retNode = findElement(value);
	if (retNode)
		return true;
	else
		return false;
}

template <typename T>
void BinarySearchTree<T>::infile(std::string filename)
{
	std::ifstream infile;
	infile.open(filename);
	T value;
	infile >> _count;
	infile >> value;

	while (infile)
	{
		infile >> value;
		insertElement(value);
	}

	infile.close();
	_count /= 2;
}

template <typename T>
void BinarySearchTree<T>::outfile(Node<T>* root, std::ostream& ofile)
{
	if (!root)
		return;

	else
	{
		ofile << root->value << "\t";
		outfile(root->rightNode, ofile);
		outfile(root->leftNode, ofile);
	}
}

template <typename T>
void BinarySearchTree<T>::out(std::string filename)
{
	Node<T>* root;
	std::ofstream ofile(filename);

	if (!ofile)
		std::cout << "Error! Please, try again!" << std::endl;
	else
		out(root, ofile);
	ofile.close();
}

template <typename T>
void BinarySearchTree<T>::paintTree(const Node<T>* node, int level) const
{
	if (node)
	{
		paintTree(node->rightNode, level++);

		for (int i = 0; i < level; i++)
		{
			std::cout << "-";
		}

		std::cout << node->value << std::endl;
		paintTree(node->leftNode, level++);
	}
}
<commit_msg>Update binary_search_tree.hpp<commit_after>#pragma once

#include <iostream>
#include <fstream>
#include <string>

template <typename T>
struct Node
{
	Node<T>* leftNode;
	Node<T>* rightNode;
	T value;

	Node(int value)
	{
		this->value = value;
		leftNode = nullptr;
		rightNode = nullptr;
	}
};

template <typename T>
class BinarySearchTree
{
private:
	Node<T>* _root;
	int _count;

public:
	BinarySearchTree();

	void destroyTree(Node<T>* node);

	~BinarySearchTree();

	T value_() const;

	T count() const;

	Node<T>* leftNode_() const;

	Node<T>* rightNode_() const;

	Node<T>* root() const;

	void insertElement(Node<T>* &node, const T &value);

	bool isInserted(const T& value);

	Node<T>* findElement(const T& value) const;

	bool isFound(const T& value) const;

	void infile(std::string filename);

	void outfile(Node<T>* root, std::ostream& outfile);

	void out(std::string filename);

	void paintTree(const Node<T>* node, int level) const;
};

template <typename T>
T BinarySearchTree<T>::value_() const
{
	return _root->value;
}

template <typename T>
T BinarySearchTree<T>::count() const
{
	return _count;
}

template <typename T>
Node<T>* BinarySearchTree<T>::root() const
{
	return _root;
}

template <typename T>
Node<T>* BinarySearchTree<T>::leftNode_() const
{
	return _root->leftNode;
}

template <typename T>
Node<T>* BinarySearchTree<T>::rightNode_() const
{
	return _root->rightNode;
}

template <typename T>
BinarySearchTree<T>::BinarySearchTree()
{
	_root = nullptr;
	_count = 0;
}

template <typename T>
void BinarySearchTree<T>::destroyTree(Node<T>* node)
{
	if (!node)
		return;

	if (node->leftNode)
	{
		destroyTree(node->leftNode);
		node->leftNode = nullptr;
	}

	if (node->rightNode)
	{
		destroyTree(node->rightNode);
		node->rightNode = nullptr;
	}
	delete node;
}

template <typename T>
BinarySearchTree<T>::~BinarySearchTree()
{
	destroyTree(_root);
}

template <typename T>
void BinarySearchTree<T>::insertElement(Node<T>* &node, const T &value);
{
	if (node)
	{
		if (value < node->value)
		{
			insert(node->leftNode, value);
		}
		else if (value > node->value)
		{
			insert(node->rightNode, value);
		}
		else
		{
			return;
		}
	}
	else
	{
		node = new Node<T>(value);
	}
	_count++;
}

template <typename T>
void BinarySearchTree<T>::insert(const T& value)
{
	insert(root, value);
}

template <typename T>
Node<T>*  BinarySearchTree<T>::findElement(const T& value) const
{
	Node<T> *currNode = _root;

	while (currNode)
	{
		if (currNode->value == value)
			break;
		else
		{
			if (currNode->value < value)
				currNode = currNode->rightNode;
			else currNode = currNode->leftNode;
		}
	}
	return currNode;
}

template <typename T>
bool BinarySearchTree<T>::isFound(const T& value) const
{
	Node<T> *retNode = findElement(value);
	if (retNode)
		return true;
	else
		return false;
}

template <typename T>
void BinarySearchTree<T>::infile(std::string filename)
{
	std::ifstream infile;
	infile.open(filename);
	T value;
	infile >> _count;
	infile >> value;

	while (infile)
	{
		infile >> value;
		insertElement(value);
	}

	infile.close();
	_count /= 2;
}

template <typename T>
void BinarySearchTree<T>::outfile(Node<T>* root, std::ostream& ofile)
{
	if (!root)
		return;

	else
	{
		ofile << root->value << "\t";
		outfile(root->rightNode, ofile);
		outfile(root->leftNode, ofile);
	}
}

template <typename T>
void BinarySearchTree<T>::out(std::string filename)
{
	Node<T>* root;
	std::ofstream ofile(filename);

	if (!ofile)
		std::cout << "Error! Please, try again!" << std::endl;
	else
		out(root, ofile);
	ofile.close();
}

template <typename T>
void BinarySearchTree<T>::paintTree(const Node<T>* node, int level) const
{
	if (node)
	{
		paintTree(node->rightNode, level++);

		for (int i = 0; i < level; i++)
		{
			std::cout << "-";
		}

		std::cout << node->value << std::endl;
		paintTree(node->leftNode, level++);
	}
}
<|endoftext|>


<commit_before>void Reciprocal_lattice::init(int lmax)
{
    Timer t("sirius::Reciprocal_lattice::init");

    //int max_frac_coord[3];
    vector3d<int> max_frac_coord = find_translation_limits<reciprocal>(pw_cutoff());

    fft_.init(&max_frac_coord[0]);

    mdarray<int, 2> gvec_tmp(3, fft_.size());
    std::vector< std::pair<double, int> > gvec_tmp_length;

    int ig = 0;
    for (int i0 = fft_.grid_limits(0, 0); i0 <= fft_.grid_limits(0, 1); i0++)
    {
        for (int i1 = fft_.grid_limits(1, 0); i1 <= fft_.grid_limits(1, 1); i1++)
        {
            for (int i2 = fft_.grid_limits(2, 0); i2 <= fft_.grid_limits(2, 1); i2++)
            {
                gvec_tmp(0, ig) = i0;
                gvec_tmp(1, ig) = i1;
                gvec_tmp(2, ig) = i2;

                vector3d<int> fracc(i0, i1, i2);
                vector3d<double> cartc = get_coordinates<cartesian, reciprocal>(fracc);

                gvec_tmp_length.push_back(std::pair<double, int>(cartc.length(), ig++));
            }
        }
    }

    Timer t1("sirius::Reciprocal_lattice::init|sort_G");
    // sort G-vectors by length
    std::sort(gvec_tmp_length.begin(), gvec_tmp_length.end());
    t1.stop();

    // create sorted list of G-vectors
    gvec_.set_dimensions(3, fft_.size());
    gvec_.allocate();

    // find number of G-vectors within the cutoff
    num_gvec_ = 0;
    for (int i = 0; i < fft_.size(); i++)
    {
        for (int j = 0; j < 3; j++) gvec_(j, i) = gvec_tmp(j, gvec_tmp_length[i].second);

        if (gvec_tmp_length[i].first <= pw_cutoff_) num_gvec_++;
    }

    index_by_gvec_.set_dimensions(dimension(fft_.grid_limits(0, 0), fft_.grid_limits(0, 1)),
                                  dimension(fft_.grid_limits(1, 0), fft_.grid_limits(1, 1)),
                                  dimension(fft_.grid_limits(2, 0), fft_.grid_limits(2, 1)));
    index_by_gvec_.allocate();

    fft_index_.resize(fft_.size());

    gvec_shell_.resize(fft_.size());
    gvec_shell_len_.clear();

    for (int ig = 0; ig < fft_.size(); ig++)
    {
        int i0 = gvec_(0, ig);
        int i1 = gvec_(1, ig);
        int i2 = gvec_(2, ig);

        // mapping from G-vector to it's index
        index_by_gvec_(i0, i1, i2) = ig;

        // mapping of FFT buffer linear index
        fft_index_[ig] = fft_.index(i0, i1, i2);

        // find G-shells
        double t = gvec_tmp_length[ig].first;
        if (gvec_shell_len_.empty() || fabs(t - gvec_shell_len_.back()) > 1e-10) gvec_shell_len_.push_back(t);
        gvec_shell_[ig] = (int)gvec_shell_len_.size() - 1;
    }

    //ig_by_igs_.clear();
    //ig_by_igs_.resize(num_gvec_shells());
    //for (int ig = 0; ig < num_gvec_; ig++)
    //{
    //    int igs = gvec_shell_[ig];
    //    ig_by_igs_[igs].push_back(ig);
    //}

    // create split index
    spl_num_gvec_.split(num_gvec(), Platform::num_mpi_ranks(), Platform::mpi_rank());

    spl_fft_size_.split(fft().size(), Platform::num_mpi_ranks(), Platform::mpi_rank());

    // precompute spherical harmonics of G-vectors
    gvec_ylm_.set_dimensions(Utils::lmmax(lmax), spl_num_gvec_.local_size());
    gvec_ylm_.allocate();

    Timer t2("sirius::Reciprocal_lattice::init|ylm_G");
    for (int igloc = 0; igloc < spl_num_gvec_.local_size(); igloc++)
    {
        int ig = spl_num_gvec_[igloc];
        double rtp[3];
        SHT::spherical_coordinates(gvec_cart(ig), rtp);
        SHT::spherical_harmonics(lmax, rtp[1], rtp[2], &gvec_ylm_(0, igloc));
    }
    t2.stop();

    update();
}

void Reciprocal_lattice::update()
{
    Timer t2("sirius::Reciprocal_lattice::update");
    // precompute G-vector phase factors
    gvec_phase_factors_.set_dimensions(spl_num_gvec_.local_size(), num_atoms());
    gvec_phase_factors_.allocate();
    for (int igloc = 0; igloc < spl_num_gvec_.local_size(); igloc++)
    {
        int ig = spl_num_gvec_[igloc];
        for (int ia = 0; ia < num_atoms(); ia++) gvec_phase_factors_(igloc, ia) = gvec_phase_factor<global>(ig, ia);
    }
}

void Reciprocal_lattice::clear()
{
    fft_.clear();
    gvec_.deallocate();
    gvec_shell_len_.clear();
    gvec_shell_.clear();
    index_by_gvec_.deallocate();
    fft_index_.clear();
}

void Reciprocal_lattice::print_info()
{
    printf("\n");
    printf("plane wave cutoff : %f\n", pw_cutoff());
    printf("number of G-vectors within the cutoff : %i\n", num_gvec());
    printf("number of G-shells : %i\n", num_gvec_shells());
    printf("FFT grid size : %i %i %i   total : %i\n", fft_.size(0), fft_.size(1), fft_.size(2), fft_.size());
    printf("FFT grid limits : %i %i   %i %i   %i %i\n", fft_.grid_limits(0, 0), fft_.grid_limits(0, 1),
                                                        fft_.grid_limits(1, 0), fft_.grid_limits(1, 1),
                                                        fft_.grid_limits(2, 0), fft_.grid_limits(2, 1));
}

template <index_domain_t index_domain>
inline int Reciprocal_lattice::gvec_shell(int ig)
{
    switch (index_domain)
    {
        case global:
        {
            assert(ig >= 0 && ig < (int)gvec_shell_.size());
            return gvec_shell_[ig];
            break;
        }
        case local:
        {
            return gvec_shell_[spl_num_gvec_[ig]];
            break;
        }
    }
}

template <index_domain_t index_domain>
inline complex16 Reciprocal_lattice::gvec_phase_factor(int ig, int ia)
{
    switch (index_domain)
    {
        case global:
        {
            return exp(complex16(0.0, twopi * Utils::scalar_product(vector3d<int>(gvec(ig)), atom(ia)->position())));
            break;
        }
        case local:
        {
            return gvec_phase_factors_(ig, ia);
            break;
        }
    }
}

template <index_domain_t index_domain>
inline void Reciprocal_lattice::gvec_ylm_array(int ig, complex16* ylm, int lmax)
{
    switch (index_domain)
    {
        case local:
        {
            int lmmax = Utils::lmmax(lmax);
            assert(lmmax <= gvec_ylm_.size(0));
            memcpy(ylm, &gvec_ylm_(0, ig), lmmax * sizeof(complex16));
            return;
        }
        case global:
        {
            double rtp[3];
            SHT::spherical_coordinates(gvec_cart(ig), rtp);
            SHT::spherical_harmonics(lmax, rtp[1], rtp[2], ylm);
            return;
        }
    }
}
<commit_msg>remove unused code<commit_after>void Reciprocal_lattice::init(int lmax)
{
    Timer t("sirius::Reciprocal_lattice::init");

    vector3d<int> max_frac_coord = find_translation_limits<reciprocal>(pw_cutoff());

    fft_.init(&max_frac_coord[0]);

    mdarray<int, 2> gvec_tmp(3, fft_.size());
    std::vector< std::pair<double, int> > gvec_tmp_length;

    int ig = 0;
    for (int i0 = fft_.grid_limits(0, 0); i0 <= fft_.grid_limits(0, 1); i0++)
    {
        for (int i1 = fft_.grid_limits(1, 0); i1 <= fft_.grid_limits(1, 1); i1++)
        {
            for (int i2 = fft_.grid_limits(2, 0); i2 <= fft_.grid_limits(2, 1); i2++)
            {
                gvec_tmp(0, ig) = i0;
                gvec_tmp(1, ig) = i1;
                gvec_tmp(2, ig) = i2;

                vector3d<int> fracc(i0, i1, i2);
                vector3d<double> cartc = get_coordinates<cartesian, reciprocal>(fracc);

                gvec_tmp_length.push_back(std::pair<double, int>(cartc.length(), ig++));
            }
        }
    }

    Timer t1("sirius::Reciprocal_lattice::init|sort_G");
    // sort G-vectors by length
    std::sort(gvec_tmp_length.begin(), gvec_tmp_length.end());
    t1.stop();

    // create sorted list of G-vectors
    gvec_.set_dimensions(3, fft_.size());
    gvec_.allocate();

    // find number of G-vectors within the cutoff
    num_gvec_ = 0;
    for (int i = 0; i < fft_.size(); i++)
    {
        for (int j = 0; j < 3; j++) gvec_(j, i) = gvec_tmp(j, gvec_tmp_length[i].second);

        if (gvec_tmp_length[i].first <= pw_cutoff_) num_gvec_++;
    }

    index_by_gvec_.set_dimensions(dimension(fft_.grid_limits(0, 0), fft_.grid_limits(0, 1)),
                                  dimension(fft_.grid_limits(1, 0), fft_.grid_limits(1, 1)),
                                  dimension(fft_.grid_limits(2, 0), fft_.grid_limits(2, 1)));
    index_by_gvec_.allocate();

    fft_index_.resize(fft_.size());

    gvec_shell_.resize(fft_.size());
    gvec_shell_len_.clear();

    for (int ig = 0; ig < fft_.size(); ig++)
    {
        int i0 = gvec_(0, ig);
        int i1 = gvec_(1, ig);
        int i2 = gvec_(2, ig);

        // mapping from G-vector to it's index
        index_by_gvec_(i0, i1, i2) = ig;

        // mapping of FFT buffer linear index
        fft_index_[ig] = fft_.index(i0, i1, i2);

        // find G-shells
        double t = gvec_tmp_length[ig].first;
        if (gvec_shell_len_.empty() || fabs(t - gvec_shell_len_.back()) > 1e-10) gvec_shell_len_.push_back(t);
        gvec_shell_[ig] = (int)gvec_shell_len_.size() - 1;
    }

    // create split index
    spl_num_gvec_.split(num_gvec(), Platform::num_mpi_ranks(), Platform::mpi_rank());

    spl_fft_size_.split(fft().size(), Platform::num_mpi_ranks(), Platform::mpi_rank());

    // precompute spherical harmonics of G-vectors
    gvec_ylm_.set_dimensions(Utils::lmmax(lmax), spl_num_gvec_.local_size());
    gvec_ylm_.allocate();

    Timer t2("sirius::Reciprocal_lattice::init|ylm_G");
    for (int igloc = 0; igloc < spl_num_gvec_.local_size(); igloc++)
    {
        int ig = spl_num_gvec_[igloc];
        double rtp[3];
        SHT::spherical_coordinates(gvec_cart(ig), rtp);
        SHT::spherical_harmonics(lmax, rtp[1], rtp[2], &gvec_ylm_(0, igloc));
    }
    t2.stop();

    update();
}

void Reciprocal_lattice::update()
{
    Timer t2("sirius::Reciprocal_lattice::update");
    // precompute G-vector phase factors
    gvec_phase_factors_.set_dimensions(spl_num_gvec_.local_size(), num_atoms());
    gvec_phase_factors_.allocate();
    for (int igloc = 0; igloc < spl_num_gvec_.local_size(); igloc++)
    {
        int ig = spl_num_gvec_[igloc];
        for (int ia = 0; ia < num_atoms(); ia++) gvec_phase_factors_(igloc, ia) = gvec_phase_factor<global>(ig, ia);
    }
}

void Reciprocal_lattice::clear()
{
    fft_.clear();
    gvec_.deallocate();
    gvec_shell_len_.clear();
    gvec_shell_.clear();
    index_by_gvec_.deallocate();
    fft_index_.clear();
}

void Reciprocal_lattice::print_info()
{
    printf("\n");
    printf("plane wave cutoff : %f\n", pw_cutoff());
    printf("number of G-vectors within the cutoff : %i\n", num_gvec());
    printf("number of G-shells : %i\n", num_gvec_shells());
    printf("FFT grid size : %i %i %i   total : %i\n", fft_.size(0), fft_.size(1), fft_.size(2), fft_.size());
    printf("FFT grid limits : %i %i   %i %i   %i %i\n", fft_.grid_limits(0, 0), fft_.grid_limits(0, 1),
                                                        fft_.grid_limits(1, 0), fft_.grid_limits(1, 1),
                                                        fft_.grid_limits(2, 0), fft_.grid_limits(2, 1));
}

template <index_domain_t index_domain>
inline int Reciprocal_lattice::gvec_shell(int ig)
{
    switch (index_domain)
    {
        case global:
        {
            assert(ig >= 0 && ig < (int)gvec_shell_.size());
            return gvec_shell_[ig];
            break;
        }
        case local:
        {
            return gvec_shell_[spl_num_gvec_[ig]];
            break;
        }
    }
}

template <index_domain_t index_domain>
inline complex16 Reciprocal_lattice::gvec_phase_factor(int ig, int ia)
{
    switch (index_domain)
    {
        case global:
        {
            return exp(complex16(0.0, twopi * Utils::scalar_product(vector3d<int>(gvec(ig)), atom(ia)->position())));
            break;
        }
        case local:
        {
            return gvec_phase_factors_(ig, ia);
            break;
        }
    }
}

template <index_domain_t index_domain>
inline void Reciprocal_lattice::gvec_ylm_array(int ig, complex16* ylm, int lmax)
{
    switch (index_domain)
    {
        case local:
        {
            int lmmax = Utils::lmmax(lmax);
            assert(lmmax <= gvec_ylm_.size(0));
            memcpy(ylm, &gvec_ylm_(0, ig), lmmax * sizeof(complex16));
            return;
        }
        case global:
        {
            double rtp[3];
            SHT::spherical_coordinates(gvec_cart(ig), rtp);
            SHT::spherical_harmonics(lmax, rtp[1], rtp[2], ylm);
            return;
        }
    }
}
<|endoftext|>