<commit_before>//
// Copyright (c) 2013-2014 Christoph Malek
// See LICENSE for more information.
//

#ifndef RJ_GAME_POPUP_HPP
#define RJ_GAME_POPUP_HPP

#include <rectojump/core/render.hpp>
#include <rectojump/global/common.hpp>
#include <rectojump/global/errors.hpp>
#include <rectojump/shared/utils.hpp>

#include <mlk/log/log.h>
#include <mlk/time/simple_timer.h>

namespace rj
{
	class popup
	{
		rndr* m_render; // need pointer here

		sf::RectangleShape m_shape;
		sf::Text m_text;
		mlk::tm::simple_timer m_lifetime_timer;
		std::uint8_t m_current_alpha{255};
		bool m_destroyed{false};

	public:
		popup(rndr* r, const sf::Font& font, const std::string& text, const vec2f& pos, mlk::ulong lifetime = 3000,
			  const sf::Color& bg_color = to_rgb("#aaaaaa", 200), const sf::Color& outline_color = to_rgb("#707070"),
			  const sf::Color& fontcolor = to_rgb("#505050")) :
			m_render{r},
			m_text{text, font, 18},
			m_lifetime_timer{lifetime}
		{
			auto size(m_text.getGlobalBounds());
			vec2f origin{size.width / 2.f, size.height / 2.f};
			m_text.setOrigin(origin);
			m_text.setPosition(pos.x + 2.f, pos.y + 6.f);
			m_text.setColor(fontcolor);
			m_shape.setOrigin(origin.x, origin.y);
			m_shape.setPosition(pos);
			m_shape.setSize({size.width, size.height});
			m_shape.setOutlineThickness(1.f);
			m_shape.setOutlineColor(outline_color);
			m_shape.setFillColor(bg_color);
			m_lifetime_timer.run();
		}

		void update(dur)
		{
			if(m_lifetime_timer.timed_out())
			{
				if(m_current_alpha <= 0)
				{
					m_destroyed = true;
					return;
				}

				--m_current_alpha;
				auto scolor(m_shape.getFillColor());
				scolor.a = m_current_alpha;
				m_shape.setFillColor(scolor);

				auto ocolor(m_shape.getOutlineColor());
				ocolor.a = m_current_alpha;
				m_shape.setOutlineColor(ocolor);

				auto tcolor(m_text.getColor());
				tcolor.a = m_current_alpha;
				m_text.setColor(tcolor);
			}
		}

		void render()
		{
			if(m_render == nullptr)
			{
				mlk::lerr(errors::cl_nullptr_access)["rj::popup"];
				return;
			}
			(*m_render)(m_shape, m_text);
		}

		bool is_destroyed() const noexcept
		{return m_destroyed;}
	};
}

#endif // RJ_GAME_POPUP_HPP
<commit_msg>game > popup changed some stuff<commit_after>//
// Copyright (c) 2013-2014 Christoph Malek
// See LICENSE for more information.
//

#ifndef RJ_GAME_POPUP_HPP
#define RJ_GAME_POPUP_HPP

#include <rectojump/core/render.hpp>
#include <rectojump/global/common.hpp>
#include <rectojump/global/errors.hpp>
#include <rectojump/shared/utils.hpp>

#include <mlk/log/log.h>
#include <mlk/time/simple_timer.h>

namespace rj
{
	class popup
	{
		rndr* m_render; // need pointer here

		sf::RectangleShape m_shape;
		sf::Text m_text;
		mlk::tm::simple_timer m_lifetime_timer;
		std::uint8_t m_current_alpha{255};
		bool m_destroyed{false};

	public:
		popup(rndr* r, const sf::Font& font, const std::string& text, const vec2f& pos, mlk::ulong lifetime = 3000,
			  const sf::Color& bg_color = to_rgb("#aaaaaa", 200), const sf::Color& outline_color = to_rgb("#707070"),
			  const sf::Color& fontcolor = to_rgb("#505050")) :
			m_render{r},
			m_text{text, font, 18},
			m_lifetime_timer{lifetime}
		{
			auto size(m_text.getGlobalBounds());
			vec2f origin{size.width / 2.f, size.height / 2.f};
			m_text.setOrigin(origin);
			m_text.setPosition(pos);
			m_text.setColor(fontcolor);
			m_shape.setOrigin(origin);
			m_shape.setPosition(pos);
			m_shape.setSize({size.width, size.height + 10.f});
			m_shape.setOutlineThickness(1.f);
			m_shape.setOutlineColor(outline_color);
			m_shape.setFillColor(bg_color);
			m_lifetime_timer.run();
		}

		void update(dur)
		{
			if(m_lifetime_timer.timed_out())
			{
				if(m_current_alpha <= 0)
				{
					m_destroyed = true;
					return;
				}

				--m_current_alpha;
				auto scolor(m_shape.getFillColor());
				scolor.a = m_current_alpha;
				m_shape.setFillColor(scolor);

				auto ocolor(m_shape.getOutlineColor());
				ocolor.a = m_current_alpha;
				m_shape.setOutlineColor(ocolor);

				auto tcolor(m_text.getColor());
				tcolor.a = m_current_alpha;
				m_text.setColor(tcolor);
			}
		}

		void render()
		{
			if(m_render == nullptr)
			{
				mlk::lerr(errors::cl_nullptr_access)["rj::popup"];
				return;
			}
			(*m_render)(m_shape, m_text);
		}

		bool is_destroyed() const noexcept
		{return m_destroyed;}
	};
}

#endif // RJ_GAME_POPUP_HPP
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2010, Gostai S.A.S.
 *
 * This software is provided "as is" without warranty of any kind,
 * either expressed or implied, including but not limited to the
 * implied warranties of fitness for a particular purpose.
 *
 * See the LICENSE file for more information.
 */

#ifndef SCHED_COROUTINE_DATA_HXX
# define SCHED_COROUTINE_DATA_HXX

SCHED_API extern void (*coroutine_free_hook)(Coro*);

namespace sched
{
  template <typename T>
  inline
  CoroutineKey<T>::CoroutineKey()
  {
  }

  template <typename T>
  inline
  CoroutineKey<T>::~CoroutineKey()
  {
  }

  /// Return the unmutable identity of coroutines and handle the case where
  /// the main coroutine is changing its identity.
  template <typename T>
  inline
  typename CoroutineKey<T>::type
  CoroutineKey<T>::current()
  {
    type t = coroutine_current();
    // Handle when the main coroutine is changing its identity from
    // Anonymous (null pointer) to a known coroutine.
    if (t == coroutine_main())
      return type();
    return coroutine_current();
  }

  template <typename T>
  inline
  void
  CoroutineKey<T>::register_free_hook(boost::function1<void, type> free)
  {
    add_coroutine_free_hook(free);
  }

  template <typename T>
  inline
  void
  CoroutineKey<T>::set_hook()
  {
  }

}

#endif

<commit_msg>Avoid a second call to coroutine_current.<commit_after>/*
 * Copyright (C) 2010, Gostai S.A.S.
 *
 * This software is provided "as is" without warranty of any kind,
 * either expressed or implied, including but not limited to the
 * implied warranties of fitness for a particular purpose.
 *
 * See the LICENSE file for more information.
 */

#ifndef SCHED_COROUTINE_DATA_HXX
# define SCHED_COROUTINE_DATA_HXX

SCHED_API extern void (*coroutine_free_hook)(Coro*);

namespace sched
{
  template <typename T>
  inline
  CoroutineKey<T>::CoroutineKey()
  {
  }

  template <typename T>
  inline
  CoroutineKey<T>::~CoroutineKey()
  {
  }

  /// Return the unmutable identity of coroutines and handle the case where
  /// the main coroutine is changing its identity.
  template <typename T>
  inline
  typename CoroutineKey<T>::type
  CoroutineKey<T>::current()
  {
    type t = coroutine_current();
    // Handle when the main coroutine is changing its identity from
    // Anonymous (null pointer) to a known coroutine.
    if (t == coroutine_main())
      return type();
    return t;
  }

  template <typename T>
  inline
  void
  CoroutineKey<T>::register_free_hook(boost::function1<void, type> free)
  {
    add_coroutine_free_hook(free);
  }

  template <typename T>
  inline
  void
  CoroutineKey<T>::set_hook()
  {
  }

}

#endif

<|endoftext|>


<commit_before>/*
 * Copyright (C) 2011 Mauricio Fernandez <mfp@acm.org>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version,
 * with the special exception on linking described in file LICENSE.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include <leveldb/db.h>
#include <leveldb/comparator.h>
#include "crc.h"

#if defined(OS_MACOSX)
  #include <machine/endian.h>
#elif defined(OS_SOLARIS)
  #include <sys/isa_defs.h>
  #ifdef _LITTLE_ENDIAN
    #define LITTLE_ENDIAN
  #else
    #define BIG_ENDIAN
  #endif
#else
  #include <endian.h>
#endif

#ifdef LITTLE_ENDIAN
#define IS_LITTLE_ENDIAN true
#else
#define IS_LITTLE_ENDIAN (__BYTE_ORDER == __LITTLE_ENDIAN)
#endif

extern "C" {

#include <caml/mlvalues.h>
#include <caml/memory.h>
#include <caml/alloc.h>

const char cMetadata_prefix = 0;
const char cDatum_prefix = 1;

static int64_t
decode_var_int(const char *p)
{
 int64_t n = 0;
 int shift = 0;

 do {
     n += (*p & 0x7F) << shift;
     shift += 7;
 } while (*p++ & 0x80);

 return n;
}

class OBigStoreComparator1 : public leveldb::Comparator {
    public:
    OBigStoreComparator1() {}

    virtual const char* Name() const {
        return "org.eigenclass/OBigStoreComparator1";
    }

    virtual int Compare(const leveldb::Slice& a, const leveldb::Slice& b) const {
        size_t sa = a.size(), sb = b.size();

        if(!sa && sb) return -1;
        if(!sb && sa) return 1;
        if(!sa && !sb) return 0;

        // need some care here: cannot do a[0] - b[0] because they are signed
        // chars
        if(a[0] != b[0]) return a.compare(b);

        switch(a[0]) {
            case '1': {
                // first compare keyspaces
                int ksa = decode_var_int(a.data() + 1),
                    ksb = decode_var_int(b.data() + 1);
                // don't expect billions of keyspaces, no pb with overflow
                int kscmp = ksa - ksb;
                if(kscmp) return kscmp;

                // then compare table ids
                int kslen_a = (a[sa - 4] >> 3) & 0x7,
                    kslen_b = (b[sb - 4] >> 3) & 0x7,
                    tlen_a = a[sa - 4] & 0x7,
                    tlen_b = b[sb - 4] & 0x7;

                int ta = decode_var_int(a.data() + 1 + kslen_a),
                    tb = decode_var_int(b.data() + 1 + kslen_b);

                // both ta and tb should be small, overflow not an issue in
                // practice
                int tblcmp = ta - tb;
                if(tblcmp) return tblcmp;

                // compare types
                int type_a = a[1 + kslen_a + tlen_a],
                    type_b = a[1 + kslen_b + tlen_b];
                int tycmp = type_a - type_b;
                if(tycmp) return tycmp;

                // then decode column and key lengths, then compare the
                // latter, then the former

                int last_a = a[sa - 3], last_b = b[sb - 3];
                int clen_len_a = last_a & 0x7,
                    clen_len_b = last_b & 0x7;
                int klen_len_a = (last_a >> 3) & 0x7,
                    klen_len_b = (last_b >> 3) & 0x7;

                int64_t klen_a, klen_b;

                klen_a = decode_var_int(a.data() + sa - 4 - clen_len_a - klen_len_a);
                klen_b = decode_var_int(b.data() + sb - 4 - clen_len_b - klen_len_b);

                leveldb::Slice key_a(a.data() + 1 + kslen_a + tlen_a + 1, klen_a),
                               key_b(b.data() + 1 + kslen_b + tlen_b + 1, klen_b);

                int keycmp = key_a.compare(key_b);
                if(keycmp) return keycmp;

                int64_t clen_a, clen_b;
                clen_a = decode_var_int(a.data() + sa - 4 - clen_len_a);
                clen_b = decode_var_int(b.data() + sb - 4 - clen_len_b);

                leveldb::Slice col_a(a.data() + 1 + kslen_a + tlen_a + 1 + klen_a, clen_a),
                               col_b(b.data() + 1 + kslen_b + tlen_b + 1 + klen_b, clen_b);

                int colcmp = col_a.compare(col_b);
                return colcmp;

                break;
            }
            default:
                // bytewise comparison for all others
                return a.compare(b);
        }

    }

    virtual void FindShortestSeparator(std::string *start,
                                       const leveldb::Slice& limit) const {
        return;
    }

    virtual void FindShortSuccessor(std::string *key) const {
        return;
    }
};

static const OBigStoreComparator1 comparator1;

CAMLprim const leveldb::Comparator*
obigstore_custom_comparator() {
    return &comparator1;
}

CAMLprim value
obigstore_apply_custom_comparator(value s1, value s2)
{
 CAMLparam2(s1, s2);
 leveldb::Slice d1(String_val(s1), string_length(s1)),
                d2(String_val(s2), string_length(s2));

 CAMLreturn(Val_int(comparator1.Compare(d1, d2)));
}

static value
blit_int64_le(value dst, value off, int64_t v)
{
#ifdef IS_LITTLE_ENDIAN
 /* optimized by gcc to plain store */
 memcpy(&Byte_u(dst, Long_val(off)), &v, sizeof(v));
#else
 uint8_t *d = &Byte_u(dst, Long_val(off));
 uint8_t *s = (uint8_t *)&v;

 d[0] = s[7]; d[1] = s[6]; d[2] = s[5]; d[3] = s[4];
 d[4] = s[3]; d[5] = s[2]; d[6] = s[1]; d[7] = s[0];
#endif
 return(Val_unit);
}

static value
blit_int64_be(value dst, value off, int64_t v)
{
#ifndef IS_LITTLE_ENDIAN
 /* optimized by gcc to plain store */
 memcpy(&Byte_u(dst, Long_val(off)), &v, sizeof(v));
#else
 uint8_t *d = &Byte_u(dst, Long_val(off));
 uint8_t *s = (uint8_t *)&v;

 d[0] = s[7]; d[1] = s[6]; d[2] = s[5]; d[3] = s[4];
 d[4] = s[3]; d[5] = s[2]; d[6] = s[1]; d[7] = s[0];
#endif

 return(Val_unit);
}

CAMLprim value
obigstore_bytea_blit_int64_complement_le(value dst, value off, value n)
{
 return blit_int64_le(dst, off, Int64_val(n) ^ -1);
}

CAMLprim value
obigstore_bytea_blit_int64_le(value dst, value off, value n)
{
 return blit_int64_le(dst, off, Int64_val(n));
}

CAMLprim value
obigstore_bytea_blit_int64_complement_be(value dst, value off, value n)
{
 return blit_int64_be(dst, off, Int64_val(n) ^ -1);
}

CAMLprim value
obigstore_bytea_blit_int64_be(value dst, value off, value n)
{
 return blit_int64_be(dst, off, Int64_val(n));
}

static int64_t
decode_int64_le(value s, value off)
{
#ifdef IS_LITTLE_ENDIAN
  int64_t v;
  memcpy(&v, &Byte_u(s, Long_val(off)), sizeof(v));
  return v;
#else
  uint8_t *s_ = &Byte_u(s, Long_val(off));
  union {
      int64_t ll;
      unsigned char c[8];
  } x;

  x.c[0] = s_[7]; x.c[1] = s_[6]; x.c[2] = s_[5]; x.c[3] = x[4];
  x.c[4] = s_[3]; x.c[5] = s_[2]; x.c[6] = s_[1]; x.c[7] = x[0];
  return x.ll;
#endif
}

static int64_t
decode_int64_be(value s, value off)
{
#ifndef IS_LITTLE_ENDIAN
  int64_t v;

  /* gcc optimizes this idiom to a plain load */
  memcpy(&v, &Byte_u(s, Long_val(off)), sizeof(v));
  return v;
#else
  uint8_t *s_ = &Byte_u(s, Long_val(off));
  union {
      int64_t ll;
      uint8_t c[8];
  } x;

  x.c[0] = s_[7]; x.c[1] = s_[6]; x.c[2] = s_[5]; x.c[3] = s_[4];
  x.c[4] = s_[3]; x.c[5] = s_[2]; x.c[6] = s_[1]; x.c[7] = s_[0];

  return x.ll;
#endif
}

CAMLprim value
obigstore_decode_int64_le(value s, value off)
{
 return caml_copy_int64(decode_int64_le(s, off));
}

CAMLprim value
obigstore_decode_int64_complement_le(value s, value off)
{
 return caml_copy_int64(decode_int64_le(s, off) ^ -1);
}

CAMLprim value
obigstore_decode_int64_be(value s, value off)
{
 return caml_copy_int64(decode_int64_be(s, off));
}

CAMLprim value
obigstore_decode_int64_complement_be(value s, value off)
{
 return caml_copy_int64(decode_int64_be(s, off) ^ -1);
}

CAMLprim value
obigstore_bytea_blit_int_as_i32_le(value dst, value off, value n)
{
 int32_t v = Long_val(n);

#ifdef IS_LITTLE_ENDIAN
 /* optimized by gcc to plain store */
 memcpy(&Byte_u(dst, Long_val(off)), &v, sizeof(v));
#else
 uint8_t *d = &Byte_u(dst, Long_val(off));
 uint8_t *s = (uint8_t *)&v;

 d[0] = s[3]; d[1] = s[2]; d[2] = s[1]; d[3] = s[0];
#endif

 return(Val_unit);
}

CAMLprim value
obigstore_bytea_blit_int_as_i32_be(value dst, value off, value n)
{
 int32_t v = Long_val(n);

#ifndef IS_LITTLE_ENDIAN
 memcpy(&Byte_u(dst, Long_val(off)), &v, sizeof(v));
#else
 uint8_t *d = &Byte_u(dst, Long_val(off));
 uint8_t *s = (uint8_t *)&v;

 d[0] = s[3]; d[1] = s[2]; d[2] = s[1]; d[3] = s[0];
#endif

 return(Val_unit);
}

static uint32_t
update_crc32c(uint32_t crc, const uint8_t *buf, size_t size)
{
 crc ^= 0xFFFFFFFF;
 while(size--) {
     crc = (crc >> 8) ^ crc32ctable[(crc ^ *buf++) & 0xFF];
 }
 crc ^= 0xFFFFFFFF;
 return crc;
}

CAMLprim value
obigstore_crc32c_string(value s)
{
 CAMLparam1(s);
 CAMLlocal1(ret);

 ret = caml_alloc_string(4);
 uint32_t *p = (uint32_t *) String_val(ret);
 *p = update_crc32c(0, &Byte_u(s, 0), string_length(s));
 CAMLreturn(ret);
}

CAMLprim value
obigstore_crc32c_update(value t, value s, value off, value len)
{
 uint32_t *p = (uint32_t *)String_val(t);
 *p = update_crc32c(*p, &Byte_u(s, Long_val(off)), Long_val(len));
 return Val_unit;
}

CAMLprim value
obigstore_crc32c_ensure_lsb(value t)
{
 #ifndef IS_LITTLE_ENDIAN
 const uint8_t *p = &Byte_u(t, 0);
 uint8_t n;
 n = p[0]; p[0] = p[3]; p[3] = n;
 n = p[1]; p[1] = p[2]; p[2] = n;
 #endif

 return Val_unit;
}

}
<commit_msg>Obs_crc32c.string: ensure result is in LSB-first order.<commit_after>/*
 * Copyright (C) 2011 Mauricio Fernandez <mfp@acm.org>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version,
 * with the special exception on linking described in file LICENSE.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include <leveldb/db.h>
#include <leveldb/comparator.h>
#include "crc.h"

#if defined(OS_MACOSX)
  #include <machine/endian.h>
#elif defined(OS_SOLARIS)
  #include <sys/isa_defs.h>
  #ifdef _LITTLE_ENDIAN
    #define LITTLE_ENDIAN
  #else
    #define BIG_ENDIAN
  #endif
#else
  #include <endian.h>
#endif

#ifdef LITTLE_ENDIAN
#define IS_LITTLE_ENDIAN true
#else
#define IS_LITTLE_ENDIAN (__BYTE_ORDER == __LITTLE_ENDIAN)
#endif

extern "C" {

#include <caml/mlvalues.h>
#include <caml/memory.h>
#include <caml/alloc.h>

const char cMetadata_prefix = 0;
const char cDatum_prefix = 1;

static int64_t
decode_var_int(const char *p)
{
 int64_t n = 0;
 int shift = 0;

 do {
     n += (*p & 0x7F) << shift;
     shift += 7;
 } while (*p++ & 0x80);

 return n;
}

class OBigStoreComparator1 : public leveldb::Comparator {
    public:
    OBigStoreComparator1() {}

    virtual const char* Name() const {
        return "org.eigenclass/OBigStoreComparator1";
    }

    virtual int Compare(const leveldb::Slice& a, const leveldb::Slice& b) const {
        size_t sa = a.size(), sb = b.size();

        if(!sa && sb) return -1;
        if(!sb && sa) return 1;
        if(!sa && !sb) return 0;

        // need some care here: cannot do a[0] - b[0] because they are signed
        // chars
        if(a[0] != b[0]) return a.compare(b);

        switch(a[0]) {
            case '1': {
                // first compare keyspaces
                int ksa = decode_var_int(a.data() + 1),
                    ksb = decode_var_int(b.data() + 1);
                // don't expect billions of keyspaces, no pb with overflow
                int kscmp = ksa - ksb;
                if(kscmp) return kscmp;

                // then compare table ids
                int kslen_a = (a[sa - 4] >> 3) & 0x7,
                    kslen_b = (b[sb - 4] >> 3) & 0x7,
                    tlen_a = a[sa - 4] & 0x7,
                    tlen_b = b[sb - 4] & 0x7;

                int ta = decode_var_int(a.data() + 1 + kslen_a),
                    tb = decode_var_int(b.data() + 1 + kslen_b);

                // both ta and tb should be small, overflow not an issue in
                // practice
                int tblcmp = ta - tb;
                if(tblcmp) return tblcmp;

                // compare types
                int type_a = a[1 + kslen_a + tlen_a],
                    type_b = a[1 + kslen_b + tlen_b];
                int tycmp = type_a - type_b;
                if(tycmp) return tycmp;

                // then decode column and key lengths, then compare the
                // latter, then the former

                int last_a = a[sa - 3], last_b = b[sb - 3];
                int clen_len_a = last_a & 0x7,
                    clen_len_b = last_b & 0x7;
                int klen_len_a = (last_a >> 3) & 0x7,
                    klen_len_b = (last_b >> 3) & 0x7;

                int64_t klen_a, klen_b;

                klen_a = decode_var_int(a.data() + sa - 4 - clen_len_a - klen_len_a);
                klen_b = decode_var_int(b.data() + sb - 4 - clen_len_b - klen_len_b);

                leveldb::Slice key_a(a.data() + 1 + kslen_a + tlen_a + 1, klen_a),
                               key_b(b.data() + 1 + kslen_b + tlen_b + 1, klen_b);

                int keycmp = key_a.compare(key_b);
                if(keycmp) return keycmp;

                int64_t clen_a, clen_b;
                clen_a = decode_var_int(a.data() + sa - 4 - clen_len_a);
                clen_b = decode_var_int(b.data() + sb - 4 - clen_len_b);

                leveldb::Slice col_a(a.data() + 1 + kslen_a + tlen_a + 1 + klen_a, clen_a),
                               col_b(b.data() + 1 + kslen_b + tlen_b + 1 + klen_b, clen_b);

                int colcmp = col_a.compare(col_b);
                return colcmp;

                break;
            }
            default:
                // bytewise comparison for all others
                return a.compare(b);
        }

    }

    virtual void FindShortestSeparator(std::string *start,
                                       const leveldb::Slice& limit) const {
        return;
    }

    virtual void FindShortSuccessor(std::string *key) const {
        return;
    }
};

static const OBigStoreComparator1 comparator1;

CAMLprim const leveldb::Comparator*
obigstore_custom_comparator() {
    return &comparator1;
}

CAMLprim value
obigstore_apply_custom_comparator(value s1, value s2)
{
 CAMLparam2(s1, s2);
 leveldb::Slice d1(String_val(s1), string_length(s1)),
                d2(String_val(s2), string_length(s2));

 CAMLreturn(Val_int(comparator1.Compare(d1, d2)));
}

static value
blit_int64_le(value dst, value off, int64_t v)
{
#ifdef IS_LITTLE_ENDIAN
 /* optimized by gcc to plain store */
 memcpy(&Byte_u(dst, Long_val(off)), &v, sizeof(v));
#else
 uint8_t *d = &Byte_u(dst, Long_val(off));
 uint8_t *s = (uint8_t *)&v;

 d[0] = s[7]; d[1] = s[6]; d[2] = s[5]; d[3] = s[4];
 d[4] = s[3]; d[5] = s[2]; d[6] = s[1]; d[7] = s[0];
#endif
 return(Val_unit);
}

static value
blit_int64_be(value dst, value off, int64_t v)
{
#ifndef IS_LITTLE_ENDIAN
 /* optimized by gcc to plain store */
 memcpy(&Byte_u(dst, Long_val(off)), &v, sizeof(v));
#else
 uint8_t *d = &Byte_u(dst, Long_val(off));
 uint8_t *s = (uint8_t *)&v;

 d[0] = s[7]; d[1] = s[6]; d[2] = s[5]; d[3] = s[4];
 d[4] = s[3]; d[5] = s[2]; d[6] = s[1]; d[7] = s[0];
#endif

 return(Val_unit);
}

CAMLprim value
obigstore_bytea_blit_int64_complement_le(value dst, value off, value n)
{
 return blit_int64_le(dst, off, Int64_val(n) ^ -1);
}

CAMLprim value
obigstore_bytea_blit_int64_le(value dst, value off, value n)
{
 return blit_int64_le(dst, off, Int64_val(n));
}

CAMLprim value
obigstore_bytea_blit_int64_complement_be(value dst, value off, value n)
{
 return blit_int64_be(dst, off, Int64_val(n) ^ -1);
}

CAMLprim value
obigstore_bytea_blit_int64_be(value dst, value off, value n)
{
 return blit_int64_be(dst, off, Int64_val(n));
}

static int64_t
decode_int64_le(value s, value off)
{
#ifdef IS_LITTLE_ENDIAN
  int64_t v;
  memcpy(&v, &Byte_u(s, Long_val(off)), sizeof(v));
  return v;
#else
  uint8_t *s_ = &Byte_u(s, Long_val(off));
  union {
      int64_t ll;
      unsigned char c[8];
  } x;

  x.c[0] = s_[7]; x.c[1] = s_[6]; x.c[2] = s_[5]; x.c[3] = x[4];
  x.c[4] = s_[3]; x.c[5] = s_[2]; x.c[6] = s_[1]; x.c[7] = x[0];
  return x.ll;
#endif
}

static int64_t
decode_int64_be(value s, value off)
{
#ifndef IS_LITTLE_ENDIAN
  int64_t v;

  /* gcc optimizes this idiom to a plain load */
  memcpy(&v, &Byte_u(s, Long_val(off)), sizeof(v));
  return v;
#else
  uint8_t *s_ = &Byte_u(s, Long_val(off));
  union {
      int64_t ll;
      uint8_t c[8];
  } x;

  x.c[0] = s_[7]; x.c[1] = s_[6]; x.c[2] = s_[5]; x.c[3] = s_[4];
  x.c[4] = s_[3]; x.c[5] = s_[2]; x.c[6] = s_[1]; x.c[7] = s_[0];

  return x.ll;
#endif
}

CAMLprim value
obigstore_decode_int64_le(value s, value off)
{
 return caml_copy_int64(decode_int64_le(s, off));
}

CAMLprim value
obigstore_decode_int64_complement_le(value s, value off)
{
 return caml_copy_int64(decode_int64_le(s, off) ^ -1);
}

CAMLprim value
obigstore_decode_int64_be(value s, value off)
{
 return caml_copy_int64(decode_int64_be(s, off));
}

CAMLprim value
obigstore_decode_int64_complement_be(value s, value off)
{
 return caml_copy_int64(decode_int64_be(s, off) ^ -1);
}

CAMLprim value
obigstore_bytea_blit_int_as_i32_le(value dst, value off, value n)
{
 int32_t v = Long_val(n);

#ifdef IS_LITTLE_ENDIAN
 /* optimized by gcc to plain store */
 memcpy(&Byte_u(dst, Long_val(off)), &v, sizeof(v));
#else
 uint8_t *d = &Byte_u(dst, Long_val(off));
 uint8_t *s = (uint8_t *)&v;

 d[0] = s[3]; d[1] = s[2]; d[2] = s[1]; d[3] = s[0];
#endif

 return(Val_unit);
}

CAMLprim value
obigstore_bytea_blit_int_as_i32_be(value dst, value off, value n)
{
 int32_t v = Long_val(n);

#ifndef IS_LITTLE_ENDIAN
 memcpy(&Byte_u(dst, Long_val(off)), &v, sizeof(v));
#else
 uint8_t *d = &Byte_u(dst, Long_val(off));
 uint8_t *s = (uint8_t *)&v;

 d[0] = s[3]; d[1] = s[2]; d[2] = s[1]; d[3] = s[0];
#endif

 return(Val_unit);
}

static uint32_t
update_crc32c(uint32_t crc, const uint8_t *buf, size_t size)
{
 crc ^= 0xFFFFFFFF;
 while(size--) {
     crc = (crc >> 8) ^ crc32ctable[(crc ^ *buf++) & 0xFF];
 }
 crc ^= 0xFFFFFFFF;
 return crc;
}

CAMLprim value
obigstore_crc32c_update(value t, value s, value off, value len)
{
 uint32_t *p = (uint32_t *)String_val(t);
 *p = update_crc32c(*p, &Byte_u(s, Long_val(off)), Long_val(len));
 return Val_unit;
}

CAMLprim value
obigstore_crc32c_ensure_lsb(value t)
{
 #ifndef IS_LITTLE_ENDIAN
 const uint8_t *p = &Byte_u(t, 0);
 uint8_t n;
 n = p[0]; p[0] = p[3]; p[3] = n;
 n = p[1]; p[1] = p[2]; p[2] = n;
 #endif

 return Val_unit;
}

CAMLprim value
obigstore_crc32c_string(value s)
{
 CAMLparam1(s);
 CAMLlocal1(ret);

 ret = caml_alloc_string(4);
 uint32_t *p = (uint32_t *) String_val(ret);
 *p = update_crc32c(0, &Byte_u(s, 0), string_length(s));
 #ifndef IS_LITTLE_ENDIAN
 obigstore_crc32c_ensure_lsb(ret);
 #endif
 CAMLreturn(ret);
}

}
<|endoftext|>


<commit_before>#ifndef VSMC_INTERNAL_CONFIG_HPP
#define VSMC_INTERNAL_CONFIG_HPP

#include <vsmc/internal/version.hpp>
#include <vsmc/internal/compiler.hpp>

// BLAS support

#ifndef VSMC_HAS_CBLAS
#define VSMC_HAS_CBLAS 0
#endif

#ifndef VSMC_CBLAS_INT_TYPE
#define VSMC_CBLAS_INT_TYPE int
#endif

#ifndef VSMC_CBLAS_HEADER
#if defined(__APPLE__) || defined(__MACOSX)
#define VSMC_CBLAS_HEADER <vecLib/cblas.h>
#else
#define VSMC_CBLAS_HEADER <cblas.h>
#endif
#endif

// nullptr

#ifndef VSMC_NULLPTR
#if VSMC_HAS_CXX11_NULLPTR && VSMC_HAS_CXX11LIB_FUNCTIONAL
#define VSMC_NULLPTR nullptr
#else
#define VSMC_NULLPTR 0
#endif
#endif

// cstdint

#ifndef __STDC_CONSTANT_MACROS
#define __STDC_CONSTANT_MACROS
#endif

// size_type

#ifndef VSMC_SIZE_TYPE
#define VSMC_SIZE_TYPE std::size_t
#endif

// RNG types

#ifndef VSMC_USE_RANDOM123
#define VSMC_USE_RANDOM123 1
#endif

#ifndef VSMC_SEED_TYPE
#define VSMC_SEED_TYPE vsmc::Seed
#endif

#ifndef VSMC_RNG_SEED
#define VSMC_RNG_SEED 0
#endif

#ifndef VSMC_CBRNG_TYPE
#define VSMC_CBRNG_TYPE r123::Threefry4x64
#endif

#ifndef VSMC_SEQRNG_TYPE
#define VSMC_SEQRNG_TYPE vsmc::cxx11::mt19937
#endif

#if VSMC_USE_RANDOM123
#define VSMC_PRLRNG_TYPE r123::Engine<VSMC_CBRNG_TYPE>
#else
#define VSMC_PRLRNG_TYPE vsmc::cxx11::mt19937
#endif

// Optional features

#ifndef VSMC_USE_CILK
#define VSMC_USE_CILK 0
#endif

#ifndef VSMC_USE_OMP
#define VSMC_USE_OMP 0
#endif

#ifndef VSMC_USE_STD
#define VSMC_USE_STD 0
#endif

#ifndef VSMC_USE_TBB
#define VSMC_USE_TBB 0
#endif

#ifndef VSMC_USE_CL
#define VSMC_USE_CL 0
#endif

// C++ Language features
#if VSMC_HAS_CXX11_EXPLICIT_CONVERSIONS
#define VSMC_EXPLICIT_OPERATOR explicit
#else
#define VSMC_EXPLICIT_OPERATOR
#endif

#if VSMC_HAS_CXX11_NOEXCEPT
#define VSMC_NOEXCEPT noexcept
#else
#define VSMC_NOEXCEPT
#endif

// C++11 Libraries from the standard library

#ifndef VSMC_HAS_CXX11LIB_FUNCTIONAL
#define VSMC_HAS_CXX11LIB_FUNCTIONAL 0
#endif

#ifndef VSMC_HAS_CXX11LIB_RANDOM
#define VSMC_HAS_CXX11LIB_RANDOM 0
#endif

#ifndef VSMC_HAS_CXX11LIB_TYPE_TRAITS
#define VSMC_HAS_CXX11LIB_TYPE_TRAITS 0
#endif

#endif // VSMC_INTERNAL_CONFIG_HPP
<commit_msg>contexper macro<commit_after>#ifndef VSMC_INTERNAL_CONFIG_HPP
#define VSMC_INTERNAL_CONFIG_HPP

#include <vsmc/internal/version.hpp>
#include <vsmc/internal/compiler.hpp>

// BLAS support

#ifndef VSMC_HAS_CBLAS
#define VSMC_HAS_CBLAS 0
#endif

#ifndef VSMC_CBLAS_INT_TYPE
#define VSMC_CBLAS_INT_TYPE int
#endif

#ifndef VSMC_CBLAS_HEADER
#if defined(__APPLE__) || defined(__MACOSX)
#define VSMC_CBLAS_HEADER <vecLib/cblas.h>
#else
#define VSMC_CBLAS_HEADER <cblas.h>
#endif
#endif

// nullptr

#ifndef VSMC_NULLPTR
#if VSMC_HAS_CXX11_NULLPTR && VSMC_HAS_CXX11LIB_FUNCTIONAL
#define VSMC_NULLPTR nullptr
#else
#define VSMC_NULLPTR 0
#endif
#endif

// cstdint

#ifndef __STDC_CONSTANT_MACROS
#define __STDC_CONSTANT_MACROS
#endif

// size_type

#ifndef VSMC_SIZE_TYPE
#define VSMC_SIZE_TYPE std::size_t
#endif

// RNG types

#ifndef VSMC_USE_RANDOM123
#define VSMC_USE_RANDOM123 1
#endif

#ifndef VSMC_SEED_TYPE
#define VSMC_SEED_TYPE vsmc::Seed
#endif

#ifndef VSMC_RNG_SEED
#define VSMC_RNG_SEED 0
#endif

#ifndef VSMC_CBRNG_TYPE
#define VSMC_CBRNG_TYPE r123::Threefry4x64
#endif

#ifndef VSMC_SEQRNG_TYPE
#define VSMC_SEQRNG_TYPE vsmc::cxx11::mt19937
#endif

#if VSMC_USE_RANDOM123
#define VSMC_PRLRNG_TYPE r123::Engine<VSMC_CBRNG_TYPE>
#else
#define VSMC_PRLRNG_TYPE vsmc::cxx11::mt19937
#endif

// Optional features

#ifndef VSMC_USE_CILK
#define VSMC_USE_CILK 0
#endif

#ifndef VSMC_USE_OMP
#define VSMC_USE_OMP 0
#endif

#ifndef VSMC_USE_STD
#define VSMC_USE_STD 0
#endif

#ifndef VSMC_USE_TBB
#define VSMC_USE_TBB 0
#endif

#ifndef VSMC_USE_CL
#define VSMC_USE_CL 0
#endif

// C++11 Language features
#ifndef VSMC_HAS_CXX11_CONSTEXPR
#define VSMC_CONSTEXPER constexpr
#else
#define VSMC_CONSTEXPER
#endif

#if VSMC_HAS_CXX11_EXPLICIT_CONVERSIONS
#define VSMC_EXPLICIT_OPERATOR explicit
#else
#define VSMC_EXPLICIT_OPERATOR
#endif

#if VSMC_HAS_CXX11_NOEXCEPT
#define VSMC_NOEXCEPT noexcept
#else
#define VSMC_NOEXCEPT
#endif

// C++11 Libraries from the standard library

#ifndef VSMC_HAS_CXX11LIB_FUNCTIONAL
#define VSMC_HAS_CXX11LIB_FUNCTIONAL 0
#endif

#ifndef VSMC_HAS_CXX11LIB_RANDOM
#define VSMC_HAS_CXX11LIB_RANDOM 0
#endif

#ifndef VSMC_HAS_CXX11LIB_TYPE_TRAITS
#define VSMC_HAS_CXX11LIB_TYPE_TRAITS 0
#endif

#endif // VSMC_INTERNAL_CONFIG_HPP
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2016-2018 metaverse core developers (see MVS-AUTHORS)
 *
 * This file is part of metaverse.
 *
 * metaverse is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License with
 * additional permissions to the one published by the Free Software
 * Foundation, either version 3 of the License, or (at your option)
 * any later version. For more information see LICENSE.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
#include <metaverse/bitcoin/chain/attachment/asset/asset_mit.hpp>
#include <sstream>
#include <metaverse/bitcoin/utility/container_sink.hpp>
#include <metaverse/bitcoin/utility/container_source.hpp>
#include <metaverse/bitcoin/utility/istream_reader.hpp>
#include <metaverse/bitcoin/utility/ostream_writer.hpp>
#include <metaverse/blockchain/block_chain_impl.hpp>
#include <metaverse/blockchain/validate_transaction.hpp>
#include <metaverse/mgbubble/utility/Compare.hpp>

namespace libbitcoin {
namespace chain {

// use 1~127 to represent normal mit status type
// add plus 128 to them to make their status type in tracing state.
// status >128 means no content should be store
constexpr uint8_t MIT_STATUS_MASK = 0x7f;
constexpr uint8_t MIT_STATUS_SHORT_OFFSET = 0x80;

asset_mit::asset_mit()
{
    reset();
}

asset_mit::asset_mit(const std::string& symbol,
               const std::string& address, const std::string& content)
    : symbol_(symbol)
    , address_(address)
    , content_(content)
    , status_(MIT_STATUS_NONE)
{
}

void asset_mit::reset()
{
    symbol_ = "";
    address_ = "";
    content_ = "";
    status_ = MIT_STATUS_NONE;
}

bool asset_mit::is_valid() const
{
    return !(symbol_.empty()
             || address_.empty()
             || is_invalid_status()
             || (!is_register_status() && !content_.empty())
             || ((symbol_.size() + 1) > ASSET_MIT_SYMBOL_FIX_SIZE)
             || ((address_.size() + 1) > ASSET_MIT_ADDRESS_FIX_SIZE)
             || ((content_.size() + 1) > ASSET_MIT_CONTENT_FIX_SIZE)
            );
}

bool asset_mit::operator< (const asset_mit& other) const
{
    return symbol_.compare(other.symbol_) < 0;
}

asset_mit asset_mit::factory_from_data(const data_chunk& data)
{
    asset_mit instance;
    instance.from_data(data);
    return instance;
}

asset_mit asset_mit::factory_from_data(std::istream& stream)
{
    asset_mit instance;
    instance.from_data(stream);
    return instance;
}

asset_mit asset_mit::factory_from_data(reader& source)
{
    asset_mit instance;
    instance.from_data(source);
    return instance;
}

bool asset_mit::from_data(const data_chunk& data)
{
    data_source istream(data);
    return from_data(istream);
}

bool asset_mit::from_data(std::istream& stream)
{
    istream_reader source(stream);
    return from_data(source);
}

bool asset_mit::from_data(reader& source)
{
    reset();

    status_ = source.read_byte();
    symbol_ = source.read_string();
    address_ = source.read_string();
    if (is_register_status()) {
        content_ = source.read_string();
    }

    auto result = static_cast<bool>(source);
    if (!result)
        reset();

    return result;
}

data_chunk asset_mit::to_short_data() const
{
    data_chunk data;
    data_sink ostream(data);
    ostream_writer sink(ostream);
    // store status with offset, specify to store no content.
    sink.write_byte(get_status() + MIT_STATUS_SHORT_OFFSET);
    sink.write_string(symbol_);
    sink.write_string(address_);
    ostream.flush();
    return data;
}

data_chunk asset_mit::to_data() const
{
    data_chunk data;
    data_sink ostream(data);
    to_data(ostream);
    ostream.flush();
    return data;
}

void asset_mit::to_data(std::ostream& stream) const
{
    ostream_writer sink(stream);
    to_data(sink);
}

void asset_mit::to_data(writer& sink) const
{
    sink.write_byte(status_);
    sink.write_string(symbol_);
    sink.write_string(address_);
    if (is_register_status()) {
        sink.write_string(content_);
    }
}

uint64_t asset_mit::serialized_size() const
{
    if (is_register_status()) {
        size_t len = (symbol_.size() + 1) + (address_.size() + 1) + (content_.size() + 1)
                     + ASSET_MIT_STATUS_FIX_SIZE;
        return std::min(len, ASSET_MIT_FIX_SIZE);
    }
    size_t len = (symbol_.size() + 1) + (address_.size() + 1) + ASSET_MIT_STATUS_FIX_SIZE;
    return std::min(len, ASSET_MIT_TRANSFER_FIX_SIZE);
}

std::string asset_mit::to_string() const
{
    std::ostringstream ss;
    ss << "\t status = " << get_status_name() << "\n";
    ss << "\t symbol = " << symbol_ << "\n";
    ss << "\t address = " << address_ << "\n";
    if (is_register_status()) {
        ss << "\t content = " << content_ << "\n";
    }
    return ss.str();
}

const std::string& asset_mit::get_symbol() const
{
    return symbol_;
}

void asset_mit::set_symbol(const std::string& symbol)
{
    size_t len = std::min((symbol.size() + 1), ASSET_MIT_SYMBOL_FIX_SIZE);
    symbol_ = symbol.substr(0, len);
}

const std::string& asset_mit::get_address() const
{
    return address_;
}

void asset_mit::set_address(const std::string& address)
{
    size_t len = std::min((address.size() + 1), ASSET_MIT_ADDRESS_FIX_SIZE);
    address_ = address.substr(0, len);
}

const std::string& asset_mit::get_content() const
{
    return content_;
}

void asset_mit::set_content(const std::string& content)
{
    size_t len = std::min((content.size() + 1), ASSET_MIT_CONTENT_FIX_SIZE);
    content_ = content.substr(0, len);
}

uint8_t asset_mit::get_status() const
{
    return status_ & MIT_STATUS_MASK;
}

void asset_mit::set_status(uint8_t status)
{
    status_ = status & MIT_STATUS_MASK;
}

std::string asset_mit::status_to_string(uint8_t status)
{
    if (status == MIT_STATUS_REGISTER) {
        return "registered";
    }
    else if (status == MIT_STATUS_TRANSFER) {
        return "transfered";
    }
    else {
        return "none";
    }
}

std::string asset_mit::get_status_name() const
{
    return status_to_string(get_status());
}

bool asset_mit::is_register_status() const
{
    return status_ == MIT_STATUS_REGISTER;
}

bool asset_mit::is_transfer_status() const
{
    return status_ == MIT_STATUS_TRANSFER;
}

bool asset_mit::is_invalid_status() const
{
    return status_ <= MIT_STATUS_NONE || status_ >= MIT_STATUS_MAX;
}

///////////////////////////////////////////////////
///////////// asset_mit_info //////////////////////
///////////////////////////////////////////////////
void asset_mit_info::reset()
{
    output_height = 0;
    timestamp = 0;
    from_did = "";
    to_did = "";
    mit.reset();
}

asset_mit_info asset_mit_info::factory_from_data(reader& source)
{
    asset_mit_info instance;
    instance.reset();

    instance.output_height = source.read_4_bytes_little_endian();
    instance.timestamp = source.read_4_bytes_little_endian();
    instance.from_did = source.read_string();
    instance.to_did = source.read_string();
    instance.mit = asset_mit::factory_from_data(source);

    auto result = static_cast<bool>(source);
    if (!result) {
        instance.reset();
    }

    return instance;
}

data_chunk asset_mit_info::to_data() const
{
    data_chunk data;
    data_sink ostream(data);
    ostream_writer sink(ostream);

    sink.write_4_bytes_little_endian(output_height);
    sink.write_4_bytes_little_endian(timestamp);
    sink.write_string(from_did);
    sink.write_string(to_did);
    sink.write_data(mit.to_short_data());

    ostream.flush();
    return data;
}

} // namspace chain
} // namspace libbitcoin
<commit_msg>update is_valid()<commit_after>/**
 * Copyright (c) 2016-2018 metaverse core developers (see MVS-AUTHORS)
 *
 * This file is part of metaverse.
 *
 * metaverse is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License with
 * additional permissions to the one published by the Free Software
 * Foundation, either version 3 of the License, or (at your option)
 * any later version. For more information see LICENSE.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
#include <metaverse/bitcoin/chain/attachment/asset/asset_mit.hpp>
#include <sstream>
#include <metaverse/bitcoin/utility/container_sink.hpp>
#include <metaverse/bitcoin/utility/container_source.hpp>
#include <metaverse/bitcoin/utility/istream_reader.hpp>
#include <metaverse/bitcoin/utility/ostream_writer.hpp>
#include <metaverse/blockchain/block_chain_impl.hpp>
#include <metaverse/blockchain/validate_transaction.hpp>
#include <metaverse/mgbubble/utility/Compare.hpp>

namespace libbitcoin {
namespace chain {

// use 1~127 to represent normal mit status type
// add plus 128 to them to make their status type in tracing state.
// status >128 means no content should be store
constexpr uint8_t MIT_STATUS_MASK = 0x7f;
constexpr uint8_t MIT_STATUS_SHORT_OFFSET = 0x80;

asset_mit::asset_mit()
{
    reset();
}

asset_mit::asset_mit(const std::string& symbol,
                     const std::string& address, const std::string& content)
    : symbol_(symbol)
    , address_(address)
    , content_(content)
    , status_(MIT_STATUS_NONE)
{
}

void asset_mit::reset()
{
    symbol_ = "";
    address_ = "";
    content_ = "";
    status_ = MIT_STATUS_NONE;
}

bool asset_mit::is_valid() const
{
    return !(symbol_.empty()
             || address_.empty()
             || is_invalid_status()
             || (!is_register_status() && !content_.empty())
             || (symbol_.size() + 1 + address_.size() + 1 + content_.size() + 1
                 > ASSET_MIT_SYMBOL_FIX_SIZE + ASSET_MIT_ADDRESS_FIX_SIZE + ASSET_MIT_CONTENT_FIX_SIZE));
}

bool asset_mit::operator< (const asset_mit& other) const
{
    return symbol_.compare(other.symbol_) < 0;
}

asset_mit asset_mit::factory_from_data(const data_chunk& data)
{
    asset_mit instance;
    instance.from_data(data);
    return instance;
}

asset_mit asset_mit::factory_from_data(std::istream& stream)
{
    asset_mit instance;
    instance.from_data(stream);
    return instance;
}

asset_mit asset_mit::factory_from_data(reader& source)
{
    asset_mit instance;
    instance.from_data(source);
    return instance;
}

bool asset_mit::from_data(const data_chunk& data)
{
    data_source istream(data);
    return from_data(istream);
}

bool asset_mit::from_data(std::istream& stream)
{
    istream_reader source(stream);
    return from_data(source);
}

bool asset_mit::from_data(reader& source)
{
    reset();

    status_ = source.read_byte();
    symbol_ = source.read_string();
    address_ = source.read_string();
    if (is_register_status()) {
        content_ = source.read_string();
    }

    auto result = static_cast<bool>(source);
    if (!result)
        reset();

    return result;
}

data_chunk asset_mit::to_short_data() const
{
    data_chunk data;
    data_sink ostream(data);
    ostream_writer sink(ostream);
    // store status with offset, specify to store no content.
    sink.write_byte(get_status() + MIT_STATUS_SHORT_OFFSET);
    sink.write_string(symbol_);
    sink.write_string(address_);
    ostream.flush();
    return data;
}

data_chunk asset_mit::to_data() const
{
    data_chunk data;
    data_sink ostream(data);
    to_data(ostream);
    ostream.flush();
    return data;
}

void asset_mit::to_data(std::ostream& stream) const
{
    ostream_writer sink(stream);
    to_data(sink);
}

void asset_mit::to_data(writer& sink) const
{
    sink.write_byte(status_);
    sink.write_string(symbol_);
    sink.write_string(address_);
    if (is_register_status()) {
        sink.write_string(content_);
    }
}

uint64_t asset_mit::serialized_size() const
{
    if (is_register_status()) {
        size_t len = (symbol_.size() + 1) + (address_.size() + 1) + (content_.size() + 1)
                     + ASSET_MIT_STATUS_FIX_SIZE;
        return std::min(len, ASSET_MIT_FIX_SIZE);
    }
    size_t len = (symbol_.size() + 1) + (address_.size() + 1) + ASSET_MIT_STATUS_FIX_SIZE;
    return std::min(len, ASSET_MIT_TRANSFER_FIX_SIZE);
}

std::string asset_mit::to_string() const
{
    std::ostringstream ss;
    ss << "\t status = " << get_status_name() << "\n";
    ss << "\t symbol = " << symbol_ << "\n";
    ss << "\t address = " << address_ << "\n";
    if (is_register_status()) {
        ss << "\t content = " << content_ << "\n";
    }
    return ss.str();
}

const std::string& asset_mit::get_symbol() const
{
    return symbol_;
}

void asset_mit::set_symbol(const std::string& symbol)
{
    size_t len = std::min((symbol.size() + 1), ASSET_MIT_SYMBOL_FIX_SIZE);
    symbol_ = symbol.substr(0, len);
}

const std::string& asset_mit::get_address() const
{
    return address_;
}

void asset_mit::set_address(const std::string& address)
{
    size_t len = std::min((address.size() + 1), ASSET_MIT_ADDRESS_FIX_SIZE);
    address_ = address.substr(0, len);
}

const std::string& asset_mit::get_content() const
{
    return content_;
}

void asset_mit::set_content(const std::string& content)
{
    size_t len = std::min((content.size() + 1), ASSET_MIT_CONTENT_FIX_SIZE);
    content_ = content.substr(0, len);
}

uint8_t asset_mit::get_status() const
{
    return status_ & MIT_STATUS_MASK;
}

void asset_mit::set_status(uint8_t status)
{
    status_ = status & MIT_STATUS_MASK;
}

std::string asset_mit::status_to_string(uint8_t status)
{
    if (status == MIT_STATUS_REGISTER) {
        return "registered";
    }
    else if (status == MIT_STATUS_TRANSFER) {
        return "transfered";
    }
    else {
        return "none";
    }
}

std::string asset_mit::get_status_name() const
{
    return status_to_string(get_status());
}

bool asset_mit::is_register_status() const
{
    return status_ == MIT_STATUS_REGISTER;
}

bool asset_mit::is_transfer_status() const
{
    return status_ == MIT_STATUS_TRANSFER;
}

bool asset_mit::is_invalid_status() const
{
    return status_ <= MIT_STATUS_NONE || status_ >= MIT_STATUS_MAX;
}

///////////////////////////////////////////////////
///////////// asset_mit_info //////////////////////
///////////////////////////////////////////////////
void asset_mit_info::reset()
{
    output_height = 0;
    timestamp = 0;
    from_did = "";
    to_did = "";
    mit.reset();
}

asset_mit_info asset_mit_info::factory_from_data(reader& source)
{
    asset_mit_info instance;
    instance.reset();

    instance.output_height = source.read_4_bytes_little_endian();
    instance.timestamp = source.read_4_bytes_little_endian();
    instance.from_did = source.read_string();
    instance.to_did = source.read_string();
    instance.mit = asset_mit::factory_from_data(source);

    auto result = static_cast<bool>(source);
    if (!result) {
        instance.reset();
    }

    return instance;
}

data_chunk asset_mit_info::to_data() const
{
    data_chunk data;
    data_sink ostream(data);
    ostream_writer sink(ostream);

    sink.write_4_bytes_little_endian(output_height);
    sink.write_4_bytes_little_endian(timestamp);
    sink.write_string(from_did);
    sink.write_string(to_did);
    sink.write_data(mit.to_short_data());

    ostream.flush();
    return data;
}

} // namspace chain
} // namspace libbitcoin
<|endoftext|>


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

  This source file is part of the tomviz project.

  Copyright Kitware, Inc.

  This source code is released under the New BSD License, (the "License").

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

******************************************************************************/
#include "ModuleContour.h"
#include "ModuleContourWidget.h"

#include "ActiveObjects.h"
#include "DataSource.h"
#include "DoubleSliderWidget.h"
#include "Operator.h"
#include "Utilities.h"

#include "pqApplicationCore.h"
#include "pqColorChooserButton.h"
#include "pqPropertyLinks.h"
#include "pqSettings.h"
#include "pqSignalAdaptors.h"
#include "pqWidgetRangeDomain.h"

#include "vtkAlgorithm.h"
#include "vtkDataObject.h"
#include "vtkNew.h"
#include "vtkPVArrayInformation.h"
#include "vtkPVDataInformation.h"
#include "vtkPVDataSetAttributesInformation.h"
#include "vtkSMPVRepresentationProxy.h"
#include "vtkSMParaViewPipelineControllerWithRendering.h"
#include "vtkSMPropertyHelper.h"
#include "vtkSMSessionProxyManager.h"
#include "vtkSMSourceProxy.h"
#include "vtkSMViewProxy.h"
#include "vtkSmartPointer.h"

#include <algorithm>
#include <cfloat>
#include <functional>
#include <string>
#include <vector>

#include <QCheckBox>
#include <QDialog>
#include <QDialogButtonBox>
#include <QJsonArray>
#include <QJsonObject>
#include <QLayout>
#include <QPointer>
#include <QSettings>

namespace tomviz {

class ModuleContour::Private
{
public:
  std::string ColorArrayName;
  bool UseSolidColor = false;
  pqPropertyLinks Links;
  QPointer<DataSource> ColorByDataSource = nullptr;
};

ModuleContour::ModuleContour(QObject* parentObject) : Module(parentObject)
{
  d = new Private;
  d->Links.setAutoUpdateVTKObjects(true);
}

ModuleContour::~ModuleContour()
{
  finalize();

  delete d;
  d = nullptr;
}

QIcon ModuleContour::icon() const
{
  return QIcon(":/icons/pqIsosurface.png");
}

bool ModuleContour::initialize(DataSource* data, vtkSMViewProxy* vtkView)
{
  if (!Module::initialize(data, vtkView)) {
    return false;
  }

  auto producer = data->proxy();

  vtkNew<vtkSMParaViewPipelineControllerWithRendering> controller;
  vtkSMSessionProxyManager* pxm = producer->GetSessionProxyManager();

  vtkSmartPointer<vtkSMProxy> contourProxy;
  contourProxy.TakeReference(pxm->NewProxy("filters", "FlyingEdges"));

  m_contourFilter = vtkSMSourceProxy::SafeDownCast(contourProxy);
  Q_ASSERT(m_contourFilter);
  controller->PreInitializeProxy(m_contourFilter);
  vtkSMPropertyHelper(m_contourFilter, "Input").Set(producer);
  vtkSMPropertyHelper(m_contourFilter, "ComputeScalars", /*quiet*/ true).Set(1);

  double contourStartVal = dataSource()->initialContourValue();

  // Check if this start value has been set by the outside (i. e., by double
  // clicking on the histogram). If not, then we will set it ourselves.
  if (contourStartVal == DBL_MAX) {
    // Get the range to calculate an initial value for the contour
    double range[2];
    dataSource()->getRange(range);

    // Use 2/3 of the range for the initial value of the contour
    contourStartVal = 2.0 / 3.0 * (range[1] - range[0]) + range[0];
  } else {
    // We will only use the initial contour value once. Reset it after
    // its first use.
    dataSource()->setInitialContourValue(DBL_MAX);
  }

  vtkSMPropertyHelper(m_contourFilter, "ContourValues").Set(contourStartVal);

  // Ask the user if they would like to change the initial value for the contour
  userSelectInitialContourValue();

  controller->PostInitializeProxy(m_contourFilter);
  controller->RegisterPipelineProxy(m_contourFilter);

  m_activeRepresentation = controller->Show(m_contourFilter, 0, vtkView);

  // Color by the data source by default
  d->ColorByDataSource = dataSource();

  // Give the proxy a friendly name for the GUI/Python world.
  if (auto p = convert<pqProxy*>(contourProxy)) {
    p->rename(label());
  }

  connect(data, SIGNAL(activeScalarsChanged()), SLOT(onScalarArrayChanged()));
  onScalarArrayChanged();

  return true;
}

void ModuleContour::updateColorMap()
{
  Q_ASSERT(m_activeRepresentation);
  vtkSMPropertyHelper(m_activeRepresentation, "LookupTable").Set(colorMap());

  updateScalarColoring();

  vtkSMPropertyHelper(m_activeRepresentation, "Visibility")
    .Set(visibility() ? 1 : 0);
  m_activeRepresentation->UpdateVTKObjects();
}

bool ModuleContour::finalize()
{
  vtkNew<vtkSMParaViewPipelineControllerWithRendering> controller;
  controller->UnRegisterProxy(m_contourFilter);
  m_contourFilter = nullptr;
  m_activeRepresentation = nullptr;
  return true;
}

bool ModuleContour::setVisibility(bool val)
{
  Q_ASSERT(m_activeRepresentation);
  vtkSMPropertyHelper(m_activeRepresentation, "Visibility").Set(val ? 1 : 0);
  m_activeRepresentation->UpdateVTKObjects();

  return true;
}

bool ModuleContour::visibility() const
{
  if (m_activeRepresentation) {
    return vtkSMPropertyHelper(m_activeRepresentation, "Visibility")
             .GetAsInt() != 0;
  } else {
    return false;
  }
}

void ModuleContour::setIsoValue(double value)
{
  vtkSMPropertyHelper(m_contourFilter, "ContourValues").Set(value);
  m_contourFilter->UpdateVTKObjects();
}

double ModuleContour::getIsoValue() const
{
  return vtkSMPropertyHelper(m_contourFilter, "ContourValues").GetAsDouble();
}

void ModuleContour::addToPanel(QWidget* panel)
{
  Q_ASSERT(m_contourFilter);

  if (panel->layout()) {
    delete panel->layout();
  }

  QVBoxLayout* layout = new QVBoxLayout;
  panel->setLayout(layout);

  // Create, update and connect
  m_controllers = new ModuleContourWidget;
  layout->addWidget(m_controllers);

  m_controllers->setUseSolidColor(d->UseSolidColor);

  connect(m_controllers, SIGNAL(useSolidColor(const bool)), this,
          SLOT(setUseSolidColor(const bool)));
  m_controllers->addPropertyLinks(d->Links, m_activeRepresentation,
                                  m_contourFilter);
  connect(m_controllers, SIGNAL(propertyChanged()), this,
          SLOT(onPropertyChanged()));

  onPropertyChanged();
}

void ModuleContour::onPropertyChanged()
{
  d->Links.accept();

  if (!m_controllers) {
    return;
  }

  d->ColorByDataSource = dataSource();
  setVisibility(true);

  updateColorMap();

  m_activeRepresentation->MarkDirty(m_activeRepresentation);
  m_activeRepresentation->UpdateVTKObjects();

  emit renderNeeded();
}

void ModuleContour::onScalarArrayChanged()
{
  QString arrayName = dataSource()->activeScalars();
  vtkSMPropertyHelper(m_contourFilter, "SelectInputScalars")
    .SetInputArrayToProcess(vtkDataObject::FIELD_ASSOCIATION_POINTS,
                            arrayName.toLatin1().data());
  m_contourFilter->UpdateVTKObjects();

  onPropertyChanged();

  emit renderNeeded();
}

QJsonObject ModuleContour::serialize() const
{
  auto json = Module::serialize();
  auto props = json["properties"].toObject();

  vtkSMPropertyHelper contourValues(
    m_contourFilter->GetProperty("ContourValues"));
  props["contourValue"] = contourValues.GetAsDouble();
  props["useSolidColor"] = d->UseSolidColor;

  auto toJson = [](vtkSMProxy* representation) {
    QJsonObject obj;
    QJsonArray color;
    vtkSMPropertyHelper diffuseColor(
      representation->GetProperty("DiffuseColor"));
    for (int i = 0; i < 3; i++) {
      color.append(diffuseColor.GetAsDouble(i));
    }
    obj["color"] = color;

    QJsonObject lighting;
    vtkSMPropertyHelper ambient(representation->GetProperty("Ambient"));
    lighting["ambient"] = ambient.GetAsDouble();
    vtkSMPropertyHelper diffuse(representation->GetProperty("Diffuse"));
    lighting["diffuse"] = diffuse.GetAsDouble();
    vtkSMPropertyHelper specular(representation->GetProperty("Specular"));
    lighting["specular"] = specular.GetAsDouble();
    vtkSMPropertyHelper specularPower(
      representation->GetProperty("SpecularPower"));
    lighting["specularPower"] = specularPower.GetAsDouble();
    obj["lighting"] = lighting;

    vtkSMPropertyHelper representationHelper(
      representation->GetProperty("Representation"));
    obj["representation"] = representationHelper.GetAsString();

    vtkSMPropertyHelper opacity(representation->GetProperty("Opacity"));
    obj["opacity"] = opacity.GetAsDouble();

    vtkSMPropertyHelper mapScalars(representation->GetProperty("MapScalars"));
    obj["mapScalars"] = mapScalars.GetAsInt() == 1;

    return obj;
  };

  props["activeRepresentation"] = toJson(m_activeRepresentation);

  json["properties"] = props;

  return json;
}

bool ModuleContour::deserialize(const QJsonObject& json)
{
  if (!Module::deserialize(json)) {
    return false;
  }
  if (json["properties"].isObject()) {
    auto props = json["properties"].toObject();
    if (m_contourFilter != nullptr) {
      vtkSMPropertyHelper(m_contourFilter, "ContourValues")
        .Set(props["contourValue"].toDouble());
      m_contourFilter->UpdateVTKObjects();
    }

    d->UseSolidColor = props["useSolidColor"].toBool();
    if (m_controllers) {
      m_controllers->setUseSolidColor(d->UseSolidColor);
    }

    auto toRep = [](vtkSMProxy* representation, const QJsonObject& state) {
      QJsonObject lighting = state["lighting"].toObject();
      vtkSMPropertyHelper ambient(representation, "Ambient");
      ambient.Set(lighting["ambient"].toDouble());
      vtkSMPropertyHelper diffuse(representation, "Diffuse");
      diffuse.Set(lighting["diffuse"].toDouble());
      vtkSMPropertyHelper specular(representation, "Specular");
      specular.Set(lighting["specular"].toDouble());
      vtkSMPropertyHelper specularPower(representation, "SpecularPower");
      specularPower.Set(lighting["specularPower"].toDouble());
      auto color = state["color"].toArray();
      vtkSMPropertyHelper diffuseColor(representation, "DiffuseColor");
      for (int i = 0; i < 3; i++) {
        diffuseColor.Set(i, color[i].toDouble());
      }
      vtkSMPropertyHelper opacity(representation, "Opacity");
      opacity.Set(state["opacity"].toDouble());
      vtkSMPropertyHelper mapScalars(representation, "MapScalars");
      mapScalars.Set(state["mapScalars"].toBool() ? 1 : 0);
      representation->UpdateVTKObjects();
    };

    if (props.contains("activeRepresentation")) {
      auto activeRepresentationState = props["activeRepresentation"].toObject();
      toRep(m_activeRepresentation, activeRepresentationState);
    }

    return true;
  }
  return false;
}

void ModuleContour::dataSourceMoved(double newX, double newY, double newZ)
{
  double pos[3] = { newX, newY, newZ };
  vtkSMPropertyHelper(m_activeRepresentation, "Position").Set(pos, 3);
  m_activeRepresentation->MarkDirty(m_activeRepresentation);
  m_activeRepresentation->UpdateVTKObjects();
}

DataSource* ModuleContour::colorMapDataSource() const
{
  return d->ColorByDataSource.data() ? d->ColorByDataSource.data()
                                     : dataSource();
}

bool ModuleContour::isProxyPartOfModule(vtkSMProxy* proxy)
{
  return proxy == m_contourFilter.Get();
}

vtkSmartPointer<vtkDataObject> ModuleContour::getDataToExport()
{
  return vtkAlgorithm::SafeDownCast(m_contourFilter->GetClientSideObject())
    ->GetOutputDataObject(0);
}

std::string ModuleContour::getStringForProxy(vtkSMProxy* proxy)
{
  if (proxy == m_contourFilter.Get()) {
    return "Contour";
  } else {
    qWarning("Gave bad proxy to module in save animation state");
    return "";
  }
}

vtkSMProxy* ModuleContour::getProxyForString(const std::string& str)
{
  if (str == "Contour") {
    return m_contourFilter.Get();
  } else {
    return nullptr;
  }
}

QList<DataSource*> ModuleContour::getChildDataSources()
{
  QList<DataSource*> childSources;
  auto source = dataSource();
  if (!source) {
    return childSources;
  }

  // Iterate over Operators and obtain child data sources
  auto ops = source->operators();
  for (int i = 0; i < ops.size(); ++i) {
    auto op = ops[i];
    if (!op || !op->hasChildDataSource()) {
      continue;
    }

    auto child = op->childDataSource();
    if (!child) {
      continue;
    }

    childSources.append(child);
  }

  return childSources;
}

void ModuleContour::updateScalarColoring()
{
  if (!d->ColorByDataSource) {
    return;
  }

  std::string arrayName(d->ColorArrayName);

  // Get the active point scalars from the resample filter
  vtkPVDataInformation* dataInfo = nullptr;
  vtkPVDataSetAttributesInformation* attributeInfo = nullptr;
  vtkPVArrayInformation* arrayInfo = nullptr;
  if (d->ColorByDataSource) {
    dataInfo = d->ColorByDataSource->proxy()->GetDataInformation(0);
  }
  if (dataInfo) {
    attributeInfo = dataInfo->GetAttributeInformation(
      vtkDataObject::FIELD_ASSOCIATION_POINTS);
  }
  if (attributeInfo) {
    arrayInfo =
      attributeInfo->GetAttributeInformation(vtkDataSetAttributes::SCALARS);
  }
  if (arrayInfo) {
    arrayName = arrayInfo->GetName();
  }

  vtkSMPropertyHelper colorArrayHelper(m_activeRepresentation,
                                       "ColorArrayName");
  if (d->UseSolidColor) {
    colorArrayHelper.SetInputArrayToProcess(
      vtkDataObject::FIELD_ASSOCIATION_POINTS, "");
  } else {
    colorArrayHelper.SetInputArrayToProcess(
      vtkDataObject::FIELD_ASSOCIATION_POINTS, arrayName.c_str());
  }

  ActiveObjects::instance().colorMapChanged(d->ColorByDataSource);
}

void ModuleContour::setUseSolidColor(const bool useSolidColor)
{
  d->UseSolidColor = useSolidColor;
  updateColorMap();
  emit renderNeeded();
}

void ModuleContour::userSelectInitialContourValue()
{
  QSettings* settings = pqApplicationCore::instance()->settings();
  bool userConfirmInitialValue =
    settings->value("ContourSettings.UserConfirmInitialValue", true).toBool();

  if (!userConfirmInitialValue)
    return;

  QDialog dialog;
  QVBoxLayout layout;
  dialog.setLayout(&layout);
  dialog.setWindowTitle(tr("Initial Contour Value"));

  // Get the range of the dataset
  double range[2];
  dataSource()->getRange(range);

  DoubleSliderWidget w(true);
  w.setMinimum(range[0]);
  w.setMaximum(range[1]);

  // We want to round this to two decimal places
  double isoValue = getIsoValue();
  isoValue = QString::number(isoValue, 'f', 2).toDouble();
  w.setValue(isoValue);

  w.setLineEditWidth(50);

  layout.addWidget(&w);

  QCheckBox dontAskAgain("Don't ask again");
  layout.addWidget(&dontAskAgain);
  layout.setAlignment(&dontAskAgain, Qt::AlignCenter);

  QDialogButtonBox ok(QDialogButtonBox::Ok);
  layout.addWidget(&ok);
  layout.setAlignment(&ok, Qt::AlignCenter);
  connect(&ok, &QDialogButtonBox::accepted, &dialog, &QDialog::accept);

  dialog.exec();

  if (dontAskAgain.isChecked())
    settings->setValue("ContourSettings.UserConfirmInitialValue", false);

  setIsoValue(w.value());
}

} // end of namespace tomviz
<commit_msg>Contour Module: unregister active representation<commit_after>/******************************************************************************

  This source file is part of the tomviz project.

  Copyright Kitware, Inc.

  This source code is released under the New BSD License, (the "License").

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

******************************************************************************/
#include "ModuleContour.h"
#include "ModuleContourWidget.h"

#include "ActiveObjects.h"
#include "DataSource.h"
#include "DoubleSliderWidget.h"
#include "Operator.h"
#include "Utilities.h"

#include "pqApplicationCore.h"
#include "pqColorChooserButton.h"
#include "pqPropertyLinks.h"
#include "pqSettings.h"
#include "pqSignalAdaptors.h"
#include "pqWidgetRangeDomain.h"

#include "vtkAlgorithm.h"
#include "vtkDataObject.h"
#include "vtkNew.h"
#include "vtkPVArrayInformation.h"
#include "vtkPVDataInformation.h"
#include "vtkPVDataSetAttributesInformation.h"
#include "vtkSMPVRepresentationProxy.h"
#include "vtkSMParaViewPipelineControllerWithRendering.h"
#include "vtkSMPropertyHelper.h"
#include "vtkSMSessionProxyManager.h"
#include "vtkSMSourceProxy.h"
#include "vtkSMViewProxy.h"
#include "vtkSmartPointer.h"

#include <algorithm>
#include <cfloat>
#include <functional>
#include <string>
#include <vector>

#include <QCheckBox>
#include <QDialog>
#include <QDialogButtonBox>
#include <QJsonArray>
#include <QJsonObject>
#include <QLayout>
#include <QPointer>
#include <QSettings>

namespace tomviz {

class ModuleContour::Private
{
public:
  std::string ColorArrayName;
  bool UseSolidColor = false;
  pqPropertyLinks Links;
  QPointer<DataSource> ColorByDataSource = nullptr;
};

ModuleContour::ModuleContour(QObject* parentObject) : Module(parentObject)
{
  d = new Private;
  d->Links.setAutoUpdateVTKObjects(true);
}

ModuleContour::~ModuleContour()
{
  finalize();

  delete d;
  d = nullptr;
}

QIcon ModuleContour::icon() const
{
  return QIcon(":/icons/pqIsosurface.png");
}

bool ModuleContour::initialize(DataSource* data, vtkSMViewProxy* vtkView)
{
  if (!Module::initialize(data, vtkView)) {
    return false;
  }

  auto producer = data->proxy();

  vtkNew<vtkSMParaViewPipelineControllerWithRendering> controller;
  vtkSMSessionProxyManager* pxm = producer->GetSessionProxyManager();

  vtkSmartPointer<vtkSMProxy> contourProxy;
  contourProxy.TakeReference(pxm->NewProxy("filters", "FlyingEdges"));

  m_contourFilter = vtkSMSourceProxy::SafeDownCast(contourProxy);
  Q_ASSERT(m_contourFilter);
  controller->PreInitializeProxy(m_contourFilter);
  vtkSMPropertyHelper(m_contourFilter, "Input").Set(producer);
  vtkSMPropertyHelper(m_contourFilter, "ComputeScalars", /*quiet*/ true).Set(1);

  double contourStartVal = dataSource()->initialContourValue();

  // Check if this start value has been set by the outside (i. e., by double
  // clicking on the histogram). If not, then we will set it ourselves.
  if (contourStartVal == DBL_MAX) {
    // Get the range to calculate an initial value for the contour
    double range[2];
    dataSource()->getRange(range);

    // Use 2/3 of the range for the initial value of the contour
    contourStartVal = 2.0 / 3.0 * (range[1] - range[0]) + range[0];
  } else {
    // We will only use the initial contour value once. Reset it after
    // its first use.
    dataSource()->setInitialContourValue(DBL_MAX);
  }

  vtkSMPropertyHelper(m_contourFilter, "ContourValues").Set(contourStartVal);

  // Ask the user if they would like to change the initial value for the contour
  userSelectInitialContourValue();

  controller->PostInitializeProxy(m_contourFilter);
  controller->RegisterPipelineProxy(m_contourFilter);

  m_activeRepresentation = controller->Show(m_contourFilter, 0, vtkView);

  // Color by the data source by default
  d->ColorByDataSource = dataSource();

  // Give the proxy a friendly name for the GUI/Python world.
  if (auto p = convert<pqProxy*>(contourProxy)) {
    p->rename(label());
  }

  connect(data, SIGNAL(activeScalarsChanged()), SLOT(onScalarArrayChanged()));
  onScalarArrayChanged();

  return true;
}

void ModuleContour::updateColorMap()
{
  Q_ASSERT(m_activeRepresentation);
  vtkSMPropertyHelper(m_activeRepresentation, "LookupTable").Set(colorMap());

  updateScalarColoring();

  vtkSMPropertyHelper(m_activeRepresentation, "Visibility")
    .Set(visibility() ? 1 : 0);
  m_activeRepresentation->UpdateVTKObjects();
}

bool ModuleContour::finalize()
{
  vtkNew<vtkSMParaViewPipelineControllerWithRendering> controller;
  controller->UnRegisterProxy(m_activeRepresentation);
  controller->UnRegisterProxy(m_contourFilter);
  m_activeRepresentation = nullptr;
  m_contourFilter = nullptr;
  return true;
}

bool ModuleContour::setVisibility(bool val)
{
  Q_ASSERT(m_activeRepresentation);
  vtkSMPropertyHelper(m_activeRepresentation, "Visibility").Set(val ? 1 : 0);
  m_activeRepresentation->UpdateVTKObjects();

  return true;
}

bool ModuleContour::visibility() const
{
  if (m_activeRepresentation) {
    return vtkSMPropertyHelper(m_activeRepresentation, "Visibility")
             .GetAsInt() != 0;
  } else {
    return false;
  }
}

void ModuleContour::setIsoValue(double value)
{
  vtkSMPropertyHelper(m_contourFilter, "ContourValues").Set(value);
  m_contourFilter->UpdateVTKObjects();
}

double ModuleContour::getIsoValue() const
{
  return vtkSMPropertyHelper(m_contourFilter, "ContourValues").GetAsDouble();
}

void ModuleContour::addToPanel(QWidget* panel)
{
  Q_ASSERT(m_contourFilter);

  if (panel->layout()) {
    delete panel->layout();
  }

  QVBoxLayout* layout = new QVBoxLayout;
  panel->setLayout(layout);

  // Create, update and connect
  m_controllers = new ModuleContourWidget;
  layout->addWidget(m_controllers);

  m_controllers->setUseSolidColor(d->UseSolidColor);

  connect(m_controllers, SIGNAL(useSolidColor(const bool)), this,
          SLOT(setUseSolidColor(const bool)));
  m_controllers->addPropertyLinks(d->Links, m_activeRepresentation,
                                  m_contourFilter);
  connect(m_controllers, SIGNAL(propertyChanged()), this,
          SLOT(onPropertyChanged()));

  onPropertyChanged();
}

void ModuleContour::onPropertyChanged()
{
  d->Links.accept();

  if (!m_controllers) {
    return;
  }

  d->ColorByDataSource = dataSource();
  setVisibility(true);

  updateColorMap();

  m_activeRepresentation->MarkDirty(m_activeRepresentation);
  m_activeRepresentation->UpdateVTKObjects();

  emit renderNeeded();
}

void ModuleContour::onScalarArrayChanged()
{
  QString arrayName = dataSource()->activeScalars();
  vtkSMPropertyHelper(m_contourFilter, "SelectInputScalars")
    .SetInputArrayToProcess(vtkDataObject::FIELD_ASSOCIATION_POINTS,
                            arrayName.toLatin1().data());
  m_contourFilter->UpdateVTKObjects();

  onPropertyChanged();

  emit renderNeeded();
}

QJsonObject ModuleContour::serialize() const
{
  auto json = Module::serialize();
  auto props = json["properties"].toObject();

  vtkSMPropertyHelper contourValues(
    m_contourFilter->GetProperty("ContourValues"));
  props["contourValue"] = contourValues.GetAsDouble();
  props["useSolidColor"] = d->UseSolidColor;

  auto toJson = [](vtkSMProxy* representation) {
    QJsonObject obj;
    QJsonArray color;
    vtkSMPropertyHelper diffuseColor(
      representation->GetProperty("DiffuseColor"));
    for (int i = 0; i < 3; i++) {
      color.append(diffuseColor.GetAsDouble(i));
    }
    obj["color"] = color;

    QJsonObject lighting;
    vtkSMPropertyHelper ambient(representation->GetProperty("Ambient"));
    lighting["ambient"] = ambient.GetAsDouble();
    vtkSMPropertyHelper diffuse(representation->GetProperty("Diffuse"));
    lighting["diffuse"] = diffuse.GetAsDouble();
    vtkSMPropertyHelper specular(representation->GetProperty("Specular"));
    lighting["specular"] = specular.GetAsDouble();
    vtkSMPropertyHelper specularPower(
      representation->GetProperty("SpecularPower"));
    lighting["specularPower"] = specularPower.GetAsDouble();
    obj["lighting"] = lighting;

    vtkSMPropertyHelper representationHelper(
      representation->GetProperty("Representation"));
    obj["representation"] = representationHelper.GetAsString();

    vtkSMPropertyHelper opacity(representation->GetProperty("Opacity"));
    obj["opacity"] = opacity.GetAsDouble();

    vtkSMPropertyHelper mapScalars(representation->GetProperty("MapScalars"));
    obj["mapScalars"] = mapScalars.GetAsInt() == 1;

    return obj;
  };

  props["activeRepresentation"] = toJson(m_activeRepresentation);

  json["properties"] = props;

  return json;
}

bool ModuleContour::deserialize(const QJsonObject& json)
{
  if (!Module::deserialize(json)) {
    return false;
  }
  if (json["properties"].isObject()) {
    auto props = json["properties"].toObject();
    if (m_contourFilter != nullptr) {
      vtkSMPropertyHelper(m_contourFilter, "ContourValues")
        .Set(props["contourValue"].toDouble());
      m_contourFilter->UpdateVTKObjects();
    }

    d->UseSolidColor = props["useSolidColor"].toBool();
    if (m_controllers) {
      m_controllers->setUseSolidColor(d->UseSolidColor);
    }

    auto toRep = [](vtkSMProxy* representation, const QJsonObject& state) {
      QJsonObject lighting = state["lighting"].toObject();
      vtkSMPropertyHelper ambient(representation, "Ambient");
      ambient.Set(lighting["ambient"].toDouble());
      vtkSMPropertyHelper diffuse(representation, "Diffuse");
      diffuse.Set(lighting["diffuse"].toDouble());
      vtkSMPropertyHelper specular(representation, "Specular");
      specular.Set(lighting["specular"].toDouble());
      vtkSMPropertyHelper specularPower(representation, "SpecularPower");
      specularPower.Set(lighting["specularPower"].toDouble());
      auto color = state["color"].toArray();
      vtkSMPropertyHelper diffuseColor(representation, "DiffuseColor");
      for (int i = 0; i < 3; i++) {
        diffuseColor.Set(i, color[i].toDouble());
      }
      vtkSMPropertyHelper opacity(representation, "Opacity");
      opacity.Set(state["opacity"].toDouble());
      vtkSMPropertyHelper mapScalars(representation, "MapScalars");
      mapScalars.Set(state["mapScalars"].toBool() ? 1 : 0);
      representation->UpdateVTKObjects();
    };

    if (props.contains("activeRepresentation")) {
      auto activeRepresentationState = props["activeRepresentation"].toObject();
      toRep(m_activeRepresentation, activeRepresentationState);
    }

    return true;
  }
  return false;
}

void ModuleContour::dataSourceMoved(double newX, double newY, double newZ)
{
  double pos[3] = { newX, newY, newZ };
  vtkSMPropertyHelper(m_activeRepresentation, "Position").Set(pos, 3);
  m_activeRepresentation->MarkDirty(m_activeRepresentation);
  m_activeRepresentation->UpdateVTKObjects();
}

DataSource* ModuleContour::colorMapDataSource() const
{
  return d->ColorByDataSource.data() ? d->ColorByDataSource.data()
                                     : dataSource();
}

bool ModuleContour::isProxyPartOfModule(vtkSMProxy* proxy)
{
  return proxy == m_contourFilter.Get();
}

vtkSmartPointer<vtkDataObject> ModuleContour::getDataToExport()
{
  return vtkAlgorithm::SafeDownCast(m_contourFilter->GetClientSideObject())
    ->GetOutputDataObject(0);
}

std::string ModuleContour::getStringForProxy(vtkSMProxy* proxy)
{
  if (proxy == m_contourFilter.Get()) {
    return "Contour";
  } else {
    qWarning("Gave bad proxy to module in save animation state");
    return "";
  }
}

vtkSMProxy* ModuleContour::getProxyForString(const std::string& str)
{
  if (str == "Contour") {
    return m_contourFilter.Get();
  } else {
    return nullptr;
  }
}

QList<DataSource*> ModuleContour::getChildDataSources()
{
  QList<DataSource*> childSources;
  auto source = dataSource();
  if (!source) {
    return childSources;
  }

  // Iterate over Operators and obtain child data sources
  auto ops = source->operators();
  for (int i = 0; i < ops.size(); ++i) {
    auto op = ops[i];
    if (!op || !op->hasChildDataSource()) {
      continue;
    }

    auto child = op->childDataSource();
    if (!child) {
      continue;
    }

    childSources.append(child);
  }

  return childSources;
}

void ModuleContour::updateScalarColoring()
{
  if (!d->ColorByDataSource) {
    return;
  }

  std::string arrayName(d->ColorArrayName);

  // Get the active point scalars from the resample filter
  vtkPVDataInformation* dataInfo = nullptr;
  vtkPVDataSetAttributesInformation* attributeInfo = nullptr;
  vtkPVArrayInformation* arrayInfo = nullptr;
  if (d->ColorByDataSource) {
    dataInfo = d->ColorByDataSource->proxy()->GetDataInformation(0);
  }
  if (dataInfo) {
    attributeInfo = dataInfo->GetAttributeInformation(
      vtkDataObject::FIELD_ASSOCIATION_POINTS);
  }
  if (attributeInfo) {
    arrayInfo =
      attributeInfo->GetAttributeInformation(vtkDataSetAttributes::SCALARS);
  }
  if (arrayInfo) {
    arrayName = arrayInfo->GetName();
  }

  vtkSMPropertyHelper colorArrayHelper(m_activeRepresentation,
                                       "ColorArrayName");
  if (d->UseSolidColor) {
    colorArrayHelper.SetInputArrayToProcess(
      vtkDataObject::FIELD_ASSOCIATION_POINTS, "");
  } else {
    colorArrayHelper.SetInputArrayToProcess(
      vtkDataObject::FIELD_ASSOCIATION_POINTS, arrayName.c_str());
  }

  ActiveObjects::instance().colorMapChanged(d->ColorByDataSource);
}

void ModuleContour::setUseSolidColor(const bool useSolidColor)
{
  d->UseSolidColor = useSolidColor;
  updateColorMap();
  emit renderNeeded();
}

void ModuleContour::userSelectInitialContourValue()
{
  QSettings* settings = pqApplicationCore::instance()->settings();
  bool userConfirmInitialValue =
    settings->value("ContourSettings.UserConfirmInitialValue", true).toBool();

  if (!userConfirmInitialValue)
    return;

  QDialog dialog;
  QVBoxLayout layout;
  dialog.setLayout(&layout);
  dialog.setWindowTitle(tr("Initial Contour Value"));

  // Get the range of the dataset
  double range[2];
  dataSource()->getRange(range);

  DoubleSliderWidget w(true);
  w.setMinimum(range[0]);
  w.setMaximum(range[1]);

  // We want to round this to two decimal places
  double isoValue = getIsoValue();
  isoValue = QString::number(isoValue, 'f', 2).toDouble();
  w.setValue(isoValue);

  w.setLineEditWidth(50);

  layout.addWidget(&w);

  QCheckBox dontAskAgain("Don't ask again");
  layout.addWidget(&dontAskAgain);
  layout.setAlignment(&dontAskAgain, Qt::AlignCenter);

  QDialogButtonBox ok(QDialogButtonBox::Ok);
  layout.addWidget(&ok);
  layout.setAlignment(&ok, Qt::AlignCenter);
  connect(&ok, &QDialogButtonBox::accepted, &dialog, &QDialog::accept);

  dialog.exec();

  if (dontAskAgain.isChecked())
    settings->setValue("ContourSettings.UserConfirmInitialValue", false);

  setIsoValue(w.value());
}

} // end of namespace tomviz
<|endoftext|>


<commit_before>/*
 * ColorUtils.cpp
 *
 * Copyright (C) 2009-15 by RStudio, Inc.
 *
 * Unless you have received this program directly from RStudio pursuant
 * to the terms of a commercial license agreement with RStudio, then
 * this program is licensed to you under the terms of version 3 of the
 * GNU Affero General Public License. This program is distributed WITHOUT
 * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
 * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
 *
 */

#include <core/ColorUtils.hpp>

#include <boost/format.hpp>

namespace rstudio {
namespace core {
namespace color_utils {

// HSV/RGB conversion code originally via
// http://stackoverflow.com/a/6930407/347549; modified to remove C-style casts,
// fix formatting, etc.

rgb hsv2rgb(const hsv& in)
{
   double hh, p, q, t, ff;
   long   i;
   rgb    out;

   if (in.s <= 0.0)
   {
      out.r = in.v;
      out.g = in.v;
      out.b = in.v;
      return out;
   }

   hh = in.h;
   if (hh >= 360.0)
      hh = 0.0;
   hh /= 60.0;
   i = static_cast<long>(hh);
   ff = hh - i;
   p = in.v * (1.0 - in.s);
   q = in.v * (1.0 - (in.s * ff));
   t = in.v * (1.0 - (in.s * (1.0 - ff)));

   switch (i)
   {
   case 0:
      out.r = in.v;
      out.g = t;
      out.b = p;
      break;
   case 1:
      out.r = q;
      out.g = in.v;
      out.b = p;
      break;
   case 2:
      out.r = p;
      out.g = in.v;
      out.b = t;
      break;
   case 3:
      out.r = p;
      out.g = q;
      out.b = in.v;
      break;
   case 4:
      out.r = t;
      out.g = p;
      out.b = in.v;
      break;
   case 5:
   default:
      out.r = in.v;
      out.g = p;
      out.b = q;
      break;
   }
   return out;
}

// given RGB values, convert to an HTML color string
std::string rgb2html(const rgb& in)
{
   return (boost::format("#%1$#x%2$#x%3$#x") %
      static_cast<int>((in.r/100.0)*255.0) %
      static_cast<int>((in.g/100.0)*255.0) %
      static_cast<int>((in.b/100.0)*255.0)).str();
}

} // namespace color_utils
} // namespace core
} // namespace rstudio

<commit_msg>use raw 0 - 1 values as percentages when converting to HTML RGB<commit_after>/*
 * ColorUtils.cpp
 *
 * Copyright (C) 2009-15 by RStudio, Inc.
 *
 * Unless you have received this program directly from RStudio pursuant
 * to the terms of a commercial license agreement with RStudio, then
 * this program is licensed to you under the terms of version 3 of the
 * GNU Affero General Public License. This program is distributed WITHOUT
 * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
 * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
 *
 */

#include <core/ColorUtils.hpp>

#include <boost/format.hpp>

namespace rstudio {
namespace core {
namespace color_utils {

// HSV/RGB conversion code originally via
// http://stackoverflow.com/a/6930407/347549; modified to remove C-style casts,
// fix formatting, etc.

rgb hsv2rgb(const hsv& in)
{
   double hh, p, q, t, ff;
   long   i;
   rgb    out;

   if (in.s <= 0.0)
   {
      out.r = in.v;
      out.g = in.v;
      out.b = in.v;
      return out;
   }

   hh = in.h;
   if (hh >= 360.0)
      hh = 0.0;
   hh /= 60.0;
   i = static_cast<long>(hh);
   ff = hh - i;
   p = in.v * (1.0 - in.s);
   q = in.v * (1.0 - (in.s * ff));
   t = in.v * (1.0 - (in.s * (1.0 - ff)));

   switch (i)
   {
   case 0:
      out.r = in.v;
      out.g = t;
      out.b = p;
      break;
   case 1:
      out.r = q;
      out.g = in.v;
      out.b = p;
      break;
   case 2:
      out.r = p;
      out.g = in.v;
      out.b = t;
      break;
   case 3:
      out.r = p;
      out.g = q;
      out.b = in.v;
      break;
   case 4:
      out.r = t;
      out.g = p;
      out.b = in.v;
      break;
   case 5:
   default:
      out.r = in.v;
      out.g = p;
      out.b = q;
      break;
   }
   return out;
}

// given RGB values, convert to an HTML color string
std::string rgb2html(const rgb& in)
{
   return (boost::format("#%02X%02X%02X") %
      static_cast<int>(in.r * 255.0) %
      static_cast<int>(in.g * 255.0) %
      static_cast<int>(in.b * 255.0)).str();
}

} // namespace color_utils
} // namespace core
} // namespace rstudio

<|endoftext|>