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

// This sample teaches how to reuse a test fixture in multiple test
// cases by deriving sub-fixtures from it.
//
// 这个例子主要用于展示，如何通过从测试固件中派生子固件，在多重测试中重用
// 测试固件。
//
// When you define a test fixture, you specify the name of the test
// case that will use this fixture.  Therefore, a test fixture can
// be used by only one test case.
//
// 当你定义一个测试固件时，你确定这个使用测试固件的测试用例集的名称，因此
// 一个测试固件只能够被一个测试用例集所使用
//
// Sometimes, more than one test cases may want to use the same or
// slightly different test fixtures.  For example, you may want to
// make sure that all tests for a GUI library don't leak important
// system resources like fonts and brushes.  In Google Test, you do
// this by putting the shared logic in a super (as in "super class")
// test fixture, and then have each test case use a fixture derived
// from this super fixture.
//
// 有些时候，不止一个测试用例集需要使用相同或者有细微差异的测试固件。例如
// 你想确定，针对一个GUI库的所有测试用例集都没有泄漏重要的系统资源，如字体
// 和话刷。在Google Test中，你可以把共享的逻辑放在一个超级测试固件中，然后
// 每一个测试用例集所使用的测试固件都可以从这个超级测试固件类中派生。

#include <limits.h>
#include <time.h>
#include "sample3-inl.h"
#include "gtest/gtest.h"
#include "sample1.h"

// In this sample, we want to ensure that every test finishes within
// ~5 seconds.  If a test takes longer to run, we consider it a
// failure.
//
// We put the code for timing a test in a test fixture called
// "QuickTest".  QuickTest is intended to be the super fixture that
// other fixtures derive from, therefore there is no test case with
// the name "QuickTest".  This is OK.
//
// Later, we will derive multiple test fixtures from QuickTest.
//
// 在这里例子中，我们需要确保每一个测试都在5s中结束。如果一个测试运行的时间
// 长于5s，我们就认为这个测试失败了
//
// 我们在测试固件中放置计算测试花费时间的代码，并将其称为QuickTest。QuickTest
// 作为超级测试固件而存在，而后续的测试固件都从其派生，所以并没有测试用例集所
// 绑定的测试固件被命名为QuickTest,之后我们将从QuickTest类中派生出多个测试固件
//
class QuickTest : public testing::Test {
 protected:
  // Remember that SetUp() is run immediately before a test starts.
  // This is a good place to record the start time.
  // 记住SetUp()函数，在一个测试开始之前执行，所以在其内部可以用来记录开始时间
  //
  virtual void SetUp() {
    start_time_ = time(NULL);
  }

  // TearDown() is invoked immediately after a test finishes.  Here we
  // check if the test was too slow.
  //
  // TearDown()函数在一个测试结束之后被调起，所以在这里我们检测一个测试是否太慢
  //
  virtual void TearDown() {
    // Gets the time when the test finishes
    const time_t end_time = time(NULL);

    // Asserts that the test took no more than ~5 seconds.  Did you
    // know that you can use assertions in SetUp() and TearDown() as
    // well?
    //
    // 下面是断言的结果
    EXPECT_TRUE(end_time - start_time_ <= 5) << "The test took too long.";
  }

  // The UTC time (in seconds) when the test starts
  // 超级固件定义的开始时间成员变量
  time_t start_time_;
};

// We derive a fixture named IntegerFunctionTest from the QuickTest
// fixture.  All tests using this fixture will be automatically
// required to be quick.
//
// 我们从QuickTest超级固件中派生出一个名为IntergerFunctionTest的测试固件
// 所有使用这个测试固件的测试，都将自动计算测试运行所话时间
//
class IntegerFunctionTest : public QuickTest {
  // We don't need any more logic than already in the QuickTest fixture.
  // Therefore the body is empty.
  // 由于不需要添加新的测试逻辑，所以此函数体为空
  //
};

// Now we can write tests in the IntegerFunctionTest test case.
// 现在在IntegerFunctionTest测试集中，编写测试用例
//
// Tests Factorial()
TEST_F(IntegerFunctionTest, Factorial) {
  // Tests factorial of negative numbers.
  //sleep(6);
  EXPECT_EQ(1, Factorial(-5));
  EXPECT_EQ(1, Factorial(-1));
  EXPECT_GT(Factorial(-10), 0);

  // Tests factorial of 0.
  EXPECT_EQ(1, Factorial(0));

  // Tests factorial of positive numbers.
  EXPECT_EQ(1, Factorial(1));
  EXPECT_EQ(2, Factorial(2));
  EXPECT_EQ(6, Factorial(3));
  EXPECT_EQ(40320, Factorial(8));
}

// Tests IsPrime()
TEST_F(IntegerFunctionTest, IsPrime) {
  // Tests negative input.
  EXPECT_FALSE(IsPrime(-1));
  EXPECT_FALSE(IsPrime(-2));
  EXPECT_FALSE(IsPrime(INT_MIN));

  // Tests some trivial cases.
  EXPECT_FALSE(IsPrime(0));
  EXPECT_FALSE(IsPrime(1));
  EXPECT_TRUE(IsPrime(2));
  EXPECT_TRUE(IsPrime(3));

  // Tests positive input.
  EXPECT_FALSE(IsPrime(4));
  EXPECT_TRUE(IsPrime(5));
  EXPECT_FALSE(IsPrime(6));
  EXPECT_TRUE(IsPrime(23));
}

// The next test case (named "QueueTest") also needs to be quick, so
// we derive another fixture from QuickTest.
//
// The QueueTest test fixture has some logic and shared objects in
// addition to what's in QuickTest already.  We define the additional
// stuff inside the body of the test fixture, as usual.
//
// 同样，可以从超级固件中派生出另一个测试固件用于队列测试，QueueTest固件
// 还有一些其他的逻辑，以及共享的对象除了计算测试时间之外，所以我们像平常
// 一样在测试固件内部进行定义
//
class QueueTest : public QuickTest {
 protected:
  virtual void SetUp() {
    // First, we need to set up the super fixture (QuickTest).
    // 首先需要调用超级固件的setup，这个地方由于不是指针或者引用调用，所以
    // 不涉及多态
    QuickTest::SetUp();

    // Second, some additional setup for this fixture.
    q1_.Enqueue(1);
    q2_.Enqueue(2);
    q2_.Enqueue(3);
  }

  // By default, TearDown() inherits the behavior of
  // QuickTest::TearDown().  As we have no additional cleaning work
  // for QueueTest, we omit it here.
  //
  // 之前已有翻译，这里不再赘述
  //
  // virtual void TearDown() {
  //   QuickTest::TearDown();
  // }

  Queue<int> q0_;
  Queue<int> q1_;
  Queue<int> q2_;
};

// Now, let's write tests using the QueueTest fixture.

// Tests the default constructor.
TEST_F(QueueTest, DefaultConstructor) {
  EXPECT_EQ(0u, q0_.Size());
}

// Tests Dequeue().
TEST_F(QueueTest, Dequeue) {
  int* n = q0_.Dequeue();
  EXPECT_TRUE(n == NULL);

  n = q1_.Dequeue();
  EXPECT_TRUE(n != NULL);
  EXPECT_EQ(1, *n);
  EXPECT_EQ(0u, q1_.Size());
  delete n;

  n = q2_.Dequeue();
  EXPECT_TRUE(n != NULL);
  EXPECT_EQ(2, *n);
  EXPECT_EQ(1u, q2_.Size());
  delete n;
}

// If necessary, you can derive further test fixtures from a derived
// fixture itself.  For example, you can derive another fixture from
// QueueTest.  Google Test imposes no limit on how deep the hierarchy
// can be.  In practice, however, you probably don't want it to be too
// deep as to be confusing.
//
// 如果必要的话，你也可以从已派生的固件进行再次的派生。例如你可以从QueueTest
// 这个固件中再次派生。GoogleTest对你究竟从中派生多少次并没有限制，但是派生的
// 层次太深，则容易使人迷惑
//
//
<commit_msg>在sample5中添加翻译，并在学习指南中添加相应说明<commit_after>// Copyright 2005, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)

// This sample teaches how to reuse a test fixture in multiple test
// cases by deriving sub-fixtures from it.
//
// 这个例子主要用于展示，如何通过从测试固件中派生子固件，在多重测试中重用
// 测试固件。
//
// When you define a test fixture, you specify the name of the test
// case that will use this fixture.  Therefore, a test fixture can
// be used by only one test case.
//
// 当你定义一个测试固件时，你确定这个使用测试固件的测试用例集的名称，因此
// 一个测试固件只能够被一个测试用例集所使用
//
// Sometimes, more than one test cases may want to use the same or
// slightly different test fixtures.  For example, you may want to
// make sure that all tests for a GUI library don't leak important
// system resources like fonts and brushes.  In Google Test, you do
// this by putting the shared logic in a super (as in "super class")
// test fixture, and then have each test case use a fixture derived
// from this super fixture.
//
// 有些时候，不止一个测试用例集需要使用相同或者有细微差异的测试固件。例如
// 你想确定，针对一个GUI库的所有测试用例集都没有泄漏重要的系统资源，如字体
// 和话刷。在Google Test中，你可以把共享的逻辑放在一个超级测试固件中，然后
// 每一个测试用例集所使用的测试固件都可以从这个超级测试固件类中派生。

#include <limits.h>
#include <time.h>
#include "sample3-inl.h"
#include "gtest/gtest.h"
#include "sample1.h"

// In this sample, we want to ensure that every test finishes within
// ~5 seconds.  If a test takes longer to run, we consider it a
// failure.
//
// We put the code for timing a test in a test fixture called
// "QuickTest".  QuickTest is intended to be the super fixture that
// other fixtures derive from, therefore there is no test case with
// the name "QuickTest".  This is OK.
//
// Later, we will derive multiple test fixtures from QuickTest.
//
// 在这里例子中，我们需要确保每一个测试都在5s中结束。如果一个测试运行的时间
// 长于5s，我们就认为这个测试失败了
//
// 我们在测试固件中放置计算测试花费时间的代码，并将其称为QuickTest。QuickTest
// 作为超级测试固件而存在，而后续的测试固件都从其派生，所以并没有测试用例集所
// 绑定的测试固件被命名为QuickTest,之后我们将从QuickTest类中派生出多个测试固件
//
class QuickTest : public testing::Test {
 protected:
  // Remember that SetUp() is run immediately before a test starts.
  // This is a good place to record the start time.
  // 记住SetUp()函数，在一个测试开始之前执行，所以在其内部可以用来记录开始时间
  //
  virtual void SetUp() {
    start_time_ = time(NULL);
  }

  // TearDown() is invoked immediately after a test finishes.  Here we
  // check if the test was too slow.
  //
  // TearDown()函数在一个测试结束之后被调起，所以在这里我们检测一个测试是否太慢
  //
  virtual void TearDown() {
    // Gets the time when the test finishes
    const time_t end_time = time(NULL);

    // Asserts that the test took no more than ~5 seconds.  Did you
    // know that you can use assertions in SetUp() and TearDown() as
    // well?
    //
    // 下面是断言的结果
    EXPECT_TRUE(end_time - start_time_ <= 5) << "The test took too long.";
  }

  // The UTC time (in seconds) when the test starts
  // 超级固件定义的开始时间成员变量
  time_t start_time_;
};

// We derive a fixture named IntegerFunctionTest from the QuickTest
// fixture.  All tests using this fixture will be automatically
// required to be quick.
//
// 我们从QuickTest超级固件中派生出一个名为IntergerFunctionTest的测试固件
// 所有使用这个测试固件的测试，都将自动计算测试运行所话时间
//
class IntegerFunctionTest : public QuickTest {
  // We don't need any more logic than already in the QuickTest fixture.
  // Therefore the body is empty.
  // 由于不需要添加新的测试逻辑，所以此函数体为空
  //
};

// Now we can write tests in the IntegerFunctionTest test case.
// 现在在IntegerFunctionTest测试集中，编写测试用例
//
// Tests Factorial()
TEST_F(IntegerFunctionTest, Factorial) {
  // Tests factorial of negative numbers.
  //sleep(6);
  EXPECT_EQ(1, Factorial(-5));
  EXPECT_EQ(1, Factorial(-1));
  EXPECT_GT(Factorial(-10), 0);

  // Tests factorial of 0.
  EXPECT_EQ(1, Factorial(0));

  // Tests factorial of positive numbers.
  EXPECT_EQ(1, Factorial(1));
  EXPECT_EQ(2, Factorial(2));
  EXPECT_EQ(6, Factorial(3));
  EXPECT_EQ(40320, Factorial(8));
}

// Tests IsPrime()
TEST_F(IntegerFunctionTest, IsPrime) {
  // Tests negative input.
  EXPECT_FALSE(IsPrime(-1));
  EXPECT_FALSE(IsPrime(-2));
  EXPECT_FALSE(IsPrime(INT_MIN));

  // Tests some trivial cases.
  EXPECT_FALSE(IsPrime(0));
  EXPECT_FALSE(IsPrime(1));
  EXPECT_TRUE(IsPrime(2));
  EXPECT_TRUE(IsPrime(3));

  // Tests positive input.
  EXPECT_FALSE(IsPrime(4));
  EXPECT_TRUE(IsPrime(5));
  EXPECT_FALSE(IsPrime(6));
  EXPECT_TRUE(IsPrime(23));
}

// The next test case (named "QueueTest") also needs to be quick, so
// we derive another fixture from QuickTest.
//
// The QueueTest test fixture has some logic and shared objects in
// addition to what's in QuickTest already.  We define the additional
// stuff inside the body of the test fixture, as usual.
//
// 同样，可以从超级固件中派生出另一个测试固件用于队列测试，QueueTest固件
// 还有一些其他的逻辑，以及共享的对象除了计算测试时间之外，所以我们像平常
// 一样在测试固件内部进行定义
//
class QueueTest : public QuickTest {
 protected:
  virtual void SetUp() {
    // First, we need to set up the super fixture (QuickTest).
    // 首先需要调用超级固件的setup，这个地方由于不是指针或者引用调用，所以
    // 不涉及多态
    QuickTest::SetUp();

    // Second, some additional setup for this fixture.
    q1_.Enqueue(1);
    q2_.Enqueue(2);
    q2_.Enqueue(3);
  }

  // By default, TearDown() inherits the behavior of
  // QuickTest::TearDown().  As we have no additional cleaning work
  // for QueueTest, we omit it here.
  //
  // 之前已有翻译，这里不再赘述
  //
  // virtual void TearDown() {
  //   QuickTest::TearDown();
  // }

  Queue<int> q0_;
  Queue<int> q1_;
  Queue<int> q2_;
};

// Now, let's write tests using the QueueTest fixture.
// 现在，让我们使用QueueTest 测试固件来写测试用例

// Tests the default constructor.
TEST_F(QueueTest, DefaultConstructor) {
  EXPECT_EQ(0u, q0_.Size());
}

// Tests Dequeue().
TEST_F(QueueTest, Dequeue) {
  int* n = q0_.Dequeue();
  EXPECT_TRUE(n == NULL);

  n = q1_.Dequeue();
  EXPECT_TRUE(n != NULL);
  EXPECT_EQ(1, *n);
  EXPECT_EQ(0u, q1_.Size());
  delete n;

  n = q2_.Dequeue();
  EXPECT_TRUE(n != NULL);
  EXPECT_EQ(2, *n);
  EXPECT_EQ(1u, q2_.Size());
  delete n;
}

// If necessary, you can derive further test fixtures from a derived
// fixture itself.  For example, you can derive another fixture from
// QueueTest.  Google Test imposes no limit on how deep the hierarchy
// can be.  In practice, however, you probably don't want it to be too
// deep as to be confusing.
//
// 如果必要的话，你也可以从已派生的固件进行再次的派生。例如你可以从QueueTest
// 这个固件中再次派生。GoogleTest对你究竟从中派生多少次并没有限制，但是派生的
// 层次太深，则容易使人迷惑
//
//
<|endoftext|>


<commit_before>#ifndef DATATRANSFER_P2P_CONNECTOR_HPP
#define DATATRANSFER_P2P_CONNECTOR_HPP

#include <functional>
#include <memory>

#include "message_handler_base.hpp"
#include "serializer.hpp"
#include "deserializer.hpp"

namespace datatransfer {

template <typename mutex>
struct MutexLocker
{
private:
	mutex& _mtx;

public:
	explicit MutexLocker(mutex& mtx) : _mtx(mtx) { _mtx.lock(); }
	~MutexLocker() { _mtx.unlock(); }
};

template<typename mutex,
		 typename input_output_stream,
		 typename wait_policy,
		 typename thread,
                 typename serialization_policy,
		 unsigned int MAX_MESSAGE_SIZE=1024>
class p2p_connector
		: wait_policy
{
	using message_handler_callback = std::function<void(const void*)>;
        using message_handler_array = message_handler_callback[serialization_policy::NUMBER_OF_MESSAGES];
        using write_policy = typename serialization_policy::template serialization<input_output_stream>::write_policy;
        using read_policy = typename serialization_policy::template serialization<input_output_stream>::read_policy;
        using checksum_policy = typename serialization_policy::template serialization<input_output_stream>::checksum_policy;

    template<int N,
             int Count>
    struct CallbackHelper
    {
        static void callback(const typename checksum_policy::data_type& checksum,
                             packet<uint8_t[MAX_MESSAGE_SIZE], checksum_policy>& rx_packet,
                             const message_handler_array& message_handlers)
        {
            if (N == rx_packet.header.id)
            {
                using type = typename serialization_policy::template data<N>::type;

                packet<type, checksum_policy> decoded_packet(reinterpret_cast<type&>(rx_packet.data), rx_packet.header.id);

                if (checksum == decoded_packet.calculate_crc())
                {
                    auto id = rx_packet.header.id - 1;
                    if (message_handlers[id])
                    {
                        message_handlers[id](rx_packet.data);
                    }
                }
            }
            else
            {
                CallbackHelper<N+1,Count-1>::callback(checksum, rx_packet, message_handlers);
            }
        }
    };

    template<int N>
    struct CallbackHelper<N,0>
    {
        static void callback(const typename checksum_policy::data_type& checksum,
                             packet<uint8_t[MAX_MESSAGE_SIZE], checksum_policy>& rx_packet,
                             const message_handler_array& message_handlers)
        {}
    };

	template<int N,
			 int Count>
	struct DeserializeHelper
	{
        void static deserializeType(int data_type, deserializer<read_policy>& deserializer, uint8_t* read_buffer)
		{
			if (N == data_type )
			{
                if (serialization_policy::template data<N>::length > 0)
                                deserializer(reinterpret_cast<typename serialization_policy::template data<N>::type&>(*read_buffer));
			}
			else
			{
				DeserializeHelper<N+1,Count-1>::deserializeType(data_type, deserializer,read_buffer);
			}
		}
	};

	template<int N>
	struct DeserializeHelper<N, 0>
	{
        void static deserializeType(uint8_t, deserializer<read_policy>&, uint8_t*) { }
	};

	enum parse_state
	{
		WAIT_FOR_SYNC_1,
		WAIT_FOR_SYNC_2,
		WAIT_FOR_ID,
		WAIT_FOR_CRC
	};

protected:
	mutex _send_mutex;
	bool _stop_thread;
	unsigned int _wait_ms;
	input_output_stream& _iostream;
	message_handler_array _message_handlers;
	thread _read_thread;
    packet<uint8_t[MAX_MESSAGE_SIZE], checksum_policy> _rx_packet;
    uint8_t _read_buffer[MAX_MESSAGE_SIZE];
	parse_state _parse_state;

public:
	p2p_connector(input_output_stream& stream,
				  unsigned int waitMs=5)
		: _stop_thread(false)
		, _wait_ms(waitMs)
		, _iostream(stream)
        , _read_thread([this] () { run_read(); })
        , _rx_packet(_read_buffer)
		, _parse_state(WAIT_FOR_SYNC_1)
	{}

	~p2p_connector()
	{
		_stop_thread = true;
		_read_thread.join();
	}

	template<int T>
	void registerMessageHandler(message_handler_callback handler)
	{
                static_assert(serialization_policy::valid(T), "T is not a valid message type");

		_message_handlers[T-1] = handler;
	}

    template<int T>
    void deregisterMessageHandler()
    {
        static_assert(serialization_policy::valid(T), "T is not a valid message type");

        _message_handlers[T-1] = nullptr;
    }

	template<int T>
        void send(typename serialization_policy::template data<T>::type& data)
	{
                static_assert(serialization_policy::valid(T), "T is not a valid message type");
                using data_type = typename serialization_policy::template data<T>::type;

		MutexLocker<mutex> locker(_send_mutex);

		if (_iostream.good())
		{
            packet<data_type, checksum_policy> p(data, T);
			p.footer.checksum = p.calculate_crc();

			serializer<write_policy> s(_iostream);
			s(p);

			_iostream.flush();
		}
	}

protected:
	void run_read()
	{
		while(!_stop_thread)
		{
			if (_iostream.good())
			{
				int c;
				while (((c = _iostream.get()) >= 0) && !_stop_thread)
				{
					switch (_parse_state)
					{
						case WAIT_FOR_SYNC_1:
							if (c == _rx_packet.header.SYNC_1)
								_parse_state = WAIT_FOR_SYNC_2;
						break;
						case WAIT_FOR_SYNC_2:
							if (c == _rx_packet.header.SYNC_2)
								_parse_state = WAIT_FOR_ID;
							else
								_parse_state = WAIT_FOR_SYNC_1;
						break;
						case WAIT_FOR_ID:
                        {
                                                        if (!serialization_policy::valid(c))
							{
								// Silently fail on error
								_parse_state = WAIT_FOR_SYNC_1;
							}
							else
							{
                                _rx_packet.header.id = c;
                                deserializer<read_policy> d(_iostream);

                                DeserializeHelper<1, serialization_policy::NUMBER_OF_MESSAGES> helper;
                                helper.deserializeType(_rx_packet.header.id, d, _read_buffer);

                                _parse_state = WAIT_FOR_CRC;
                            }
                        }
						break;
						case WAIT_FOR_CRC:
                        {
                            CallbackHelper<1, serialization_policy::NUMBER_OF_MESSAGES> helper;
                            helper.callback(c, _rx_packet, _message_handlers);
							_parse_state = WAIT_FOR_SYNC_1;
                        }
						break;
					}
				}
			}

			wait_policy::wait(_wait_ms);
		}
	}
};
}
#endif // DATATRANSFER_P2P_CONNECTOR_HPP
<commit_msg>Remove read thread from p2p_connector<commit_after>#ifndef DATATRANSFER_P2P_CONNECTOR_HPP
#define DATATRANSFER_P2P_CONNECTOR_HPP

#include <memory>

#include "message_handler_base.hpp"
#include "serializer.hpp"
#include "deserializer.hpp"

namespace datatransfer {

template <typename mutex>
struct MutexLocker
{
private:
    mutex& _mtx;

public:
    explicit MutexLocker(mutex& mtx) : _mtx(mtx) { _mtx.lock(); }
    ~MutexLocker() { _mtx.unlock(); }
};

template<typename mutex,
         typename input_output_stream,
         typename serialization_policy,
         unsigned int MAX_MESSAGE_SIZE=1024>
class p2p_connector
{
    using message_handler_callback = std::function<void(const void*)>;
    using message_handler_array = message_handler_callback[serialization_policy::NUMBER_OF_MESSAGES];
    using write_policy = typename serialization_policy::template serialization<input_output_stream>::write_policy;
    using read_policy = typename serialization_policy::template serialization<input_output_stream>::read_policy;
    using checksum_policy = typename serialization_policy::template serialization<input_output_stream>::checksum_policy;

    template<int N,
             int Count>
    struct CallbackHelper
    {
        static void callback(const typename checksum_policy::data_type& checksum,
                             packet<uint8_t[MAX_MESSAGE_SIZE], checksum_policy>& rx_packet,
                             const message_handler_array& message_handlers)
        {
            if (N == rx_packet.header.id)
            {
                using type = typename serialization_policy::template data<N>::type;

                packet<type, checksum_policy> decoded_packet(reinterpret_cast<type&>(rx_packet.data), rx_packet.header.id);

                if (checksum == decoded_packet.calculate_crc())
                {
                    auto id = rx_packet.header.id - 1;
                    if (message_handlers[id])
                    {
                        message_handlers[id](rx_packet.data);
                    }
                }
            }
            else
            {
                CallbackHelper<N+1,Count-1>::callback(checksum, rx_packet, message_handlers);
            }
        }
    };

    template<int N>
    struct CallbackHelper<N,0>
    {
        static void callback(const typename checksum_policy::data_type& checksum,
                             packet<uint8_t[MAX_MESSAGE_SIZE], checksum_policy>& rx_packet,
                             const message_handler_array& message_handlers)
        {}
    };

    template<int N,
             int Count>
    struct DeserializeHelper
    {
        void static deserializeType(int data_type, deserializer<read_policy>& deserializer, uint8_t* read_buffer)
        {
            if (N == data_type )
            {
                if (serialization_policy::template data<N>::length > 0)
                    deserializer(reinterpret_cast<typename serialization_policy::template data<N>::type&>(*read_buffer));
            }
            else
            {
                DeserializeHelper<N+1,Count-1>::deserializeType(data_type, deserializer,read_buffer);
            }
        }
    };

    template<int N>
    struct DeserializeHelper<N, 0>
    {
        void static deserializeType(uint8_t, deserializer<read_policy>&, uint8_t*) { }
    };

    enum parse_state
    {
        WAIT_FOR_SYNC_1,
        WAIT_FOR_SYNC_2,
        WAIT_FOR_ID,
        WAIT_FOR_CRC
    };

protected:
    mutex _send_mutex;
    input_output_stream& _iostream;
    message_handler_array _message_handlers;
    packet<uint8_t[MAX_MESSAGE_SIZE], checksum_policy> _rx_packet;
    uint8_t _read_buffer[MAX_MESSAGE_SIZE];
    parse_state _parse_state;

public:
    p2p_connector(input_output_stream& stream)
        : _iostream(stream)
        , _rx_packet(_read_buffer)
        , _parse_state(WAIT_FOR_SYNC_1)
    {}

    ~p2p_connector() {}

    template<int T>
    void registerMessageHandler(message_handler_callback handler)
    {
        static_assert(serialization_policy::valid(T), "T is not a valid message type");

        _message_handlers[T-1] = handler;
    }

    template<int T>
    void deregisterMessageHandler()
    {
        static_assert(serialization_policy::valid(T), "T is not a valid message type");

        _message_handlers[T-1] = nullptr;
    }

    template<int T>
    void send(typename serialization_policy::template data<T>::type& data)
    {
        static_assert(serialization_policy::valid(T), "T is not a valid message type");
        using data_type = typename serialization_policy::template data<T>::type;

        MutexLocker<mutex> locker(_send_mutex);

        if (_iostream.good())
        {
            packet<data_type, checksum_policy> p(data, T);
            p.footer.checksum = p.calculate_crc();

            serializer<write_policy> s(_iostream);
            s(p);

            _iostream.flush();
        }
    }

    void read()
    {
        if (_iostream.good())
        {
            int c;
            while ((c = _iostream.get()) >= 0)
            {
                switch (_parse_state)
                {
                    case WAIT_FOR_SYNC_1:
                        if (c == _rx_packet.header.SYNC_1)
                            _parse_state = WAIT_FOR_SYNC_2;
                    break;
                    case WAIT_FOR_SYNC_2:
                        if (c == _rx_packet.header.SYNC_2)
                            _parse_state = WAIT_FOR_ID;
                        else
                            _parse_state = WAIT_FOR_SYNC_1;
                    break;
                    case WAIT_FOR_ID:
                    {
                        if (!serialization_policy::valid(c))
                        {
                            // Silently fail on error
                            _parse_state = WAIT_FOR_SYNC_1;
                        }
                        else
                        {
                            _rx_packet.header.id = c;
                            deserializer<read_policy> d(_iostream);

                            DeserializeHelper<1, serialization_policy::NUMBER_OF_MESSAGES> helper;
                            helper.deserializeType(_rx_packet.header.id, d, _read_buffer);

                            _parse_state = WAIT_FOR_CRC;
                        }
                    }
                    break;
                    case WAIT_FOR_CRC:
                    {
                        CallbackHelper<1, serialization_policy::NUMBER_OF_MESSAGES> helper;
                        helper.callback(c, _rx_packet, _message_handlers);
                        _parse_state = WAIT_FOR_SYNC_1;
                    }
                    break;
                }
            }
        }
    }
};
}
#endif // DATATRANSFER_P2P_CONNECTOR_HPP
<|endoftext|>


<commit_before>#include <iostream>

#include "occa.hpp"

int main(int argc, char **argv){
  int entries = 5;

  float *a  = new float[entries];
  float *b  = new float[entries];
  float *ab = new float[entries];

  for(int i = 0; i < entries; ++i){
    a[i]  = i;
    b[i]  = 1 - i;
    ab[i] = 0;
  }

  // occa::availableDevices<occa::OpenCL>();

  std::string mode = "OpenCL";
  int platformID = 0;
  int deviceID   = 0;

  occa::device device;
  occa::kernel addVectors;
  occa::memory o_a, o_b, o_ab;

  device.setup(mode, platformID, deviceID);

  o_a  = device.malloc(entries*sizeof(float));
  o_b  = device.malloc(entries*sizeof(float));
  o_ab = device.malloc(entries*sizeof(float));

  addVectors = device.buildKernelFromSource("addVectors.okl",
                                            "addVectors");

  int dims = 1;
  int itemsPerGroup(2);
  int groups((entries + itemsPerGroup - 1)/itemsPerGroup);

  addVectors.setWorkingDims(dims, itemsPerGroup, groups);

  o_a.copyFrom(a);
  o_b.copyFrom(b);

  occa::initTimer(device);

  occa::tic("addVectors");

  addVectors(entries, o_a, o_b, o_ab);

  double elapsedTime = occa::toc("addVectors", addVectors);

  o_ab.copyTo(ab);

  std::cout << "Elapsed time = " << elapsedTime << " s" << std::endl;

  occa::printTimer();

  for(int i = 0; i < 5; ++i)
    std::cout << i << ": " << ab[i] << '\n';

  delete [] a;
  delete [] b;
  delete [] ab;

  addVectors.free();
  o_a.free();
  o_b.free();
  o_ab.free();
  device.free();

  return 0;
}
<commit_msg>[Parser] Make 'OpenMP' the default mode in addVectors<commit_after>#include <iostream>

#include "occa.hpp"

int main(int argc, char **argv){
  int entries = 5;

  float *a  = new float[entries];
  float *b  = new float[entries];
  float *ab = new float[entries];

  for(int i = 0; i < entries; ++i){
    a[i]  = i;
    b[i]  = 1 - i;
    ab[i] = 0;
  }

  // occa::availableDevices<occa::OpenCL>();

  std::string mode = "OpenMP";
  int platformID = 0;
  int deviceID   = 0;

  occa::device device;
  occa::kernel addVectors;
  occa::memory o_a, o_b, o_ab;

  device.setup(mode, platformID, deviceID);

  o_a  = device.malloc(entries*sizeof(float));
  o_b  = device.malloc(entries*sizeof(float));
  o_ab = device.malloc(entries*sizeof(float));

  addVectors = device.buildKernelFromSource("addVectors.okl",
                                            "addVectors");

  int dims = 1;
  int itemsPerGroup(2);
  int groups((entries + itemsPerGroup - 1)/itemsPerGroup);

  addVectors.setWorkingDims(dims, itemsPerGroup, groups);

  o_a.copyFrom(a);
  o_b.copyFrom(b);

  occa::initTimer(device);

  occa::tic("addVectors");

  addVectors(entries, o_a, o_b, o_ab);

  double elapsedTime = occa::toc("addVectors", addVectors);

  o_ab.copyTo(ab);

  std::cout << "Elapsed time = " << elapsedTime << " s" << std::endl;

  occa::printTimer();

  for(int i = 0; i < 5; ++i)
    std::cout << i << ": " << ab[i] << '\n';

  delete [] a;
  delete [] b;
  delete [] ab;

  addVectors.free();
  o_a.free();
  o_b.free();
  o_ab.free();
  device.free();

  return 0;
}
<|endoftext|>


<commit_before>/* mockturtle: C++ logic network library
 * Copyright (C) 2018  EPFL
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following
 * conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

/*!
  \file aiger_reader.hpp
  \brief Lorina reader for AIGER files

  \author Mathias Soeken
*/

#pragma once

#include <lorina/aiger.hpp>
#include "../networks/aig.hpp"
#include "../traits.hpp"

namespace mockturtle
{

template<typename Ntk, typename StorageContainer = std::unordered_map<signal<Ntk>,std::vector<std::string>>>
class NameMap
{
public:
  using signal = typename Ntk::signal;

public:
  NameMap() = default;

  void insert( signal const& s, std::string const& name )
  {
    auto const it = _names.find( s );
    if ( it == _names.end() )
    {
      _names[ s ] = { name };
    }
    else
    {
      it->second.push_back( name );
    }
  }

  std::vector<std::string> operator[]( signal const& s )
  {
    return _names[s];
  }

  std::vector<std::string> operator[]( signal const& s ) const
  {
    return _names[s];
  }

  std::vector<std::string> get_name( signal const& s ) const
  {
    return _names.at( s );
  }

  bool has_name( signal const& s, std::string const& name ) const
  {
    auto const it = _names.find( s );
    if ( it == _names.end() )
    {
      return false;
    }
    return ( std::find( it->second.begin(), it->second.end(), name ) != it->second.end() );
  }

protected:
  StorageContainer _names;
}; // NameMap

/*! \brief Lorina reader callback for Aiger files.
 *
 * **Required network functions:**
 * - `create_pi`
 * - `create_po`
 * - `get_constant`
 * - `create_not`
 * - `create_and`
 *
   \verbatim embed:rst

   Example

   .. code-block:: c++

      aig_network aig;
      lorina::read_aiger( "file.aig", aiger_reader( aig ) );

      mig_network mig;
      lorina::read_aiger( "file.aig", aiger_reader( mig ) );
   \endverbatim
 */
template<typename Ntk>
class aiger_reader : public lorina::aiger_reader
{
public:
  explicit aiger_reader( Ntk& ntk, NameMap<Ntk> *names = nullptr ) : _ntk( ntk ), _names( names )
  {
    static_assert( is_network_type_v<Ntk>, "Ntk is not a network type" );
    static_assert( has_create_pi_v<Ntk>, "Ntk does not implement the create_pi function" );
    static_assert( has_create_po_v<Ntk>, "Ntk does not implement the create_po function" );
    static_assert( has_get_constant_v<Ntk>, "Ntk does not implement the get_constant function" );
    static_assert( has_create_not_v<Ntk>, "Ntk does not implement the create_not function" );
    static_assert( has_create_and_v<Ntk>, "Ntk does not implement the create_and function" );
  }

  ~aiger_reader()
  {
    for ( auto out : outputs )
    {
      auto lit = std::get<0>( out );
      auto signal = signals[lit >> 1];
      if ( lit & 1 )
      {
        signal = _ntk.create_not( signal );
      }
      _ntk.create_po( signal );
      if ( _names )
        _names->insert( signal, std::get<1>( out ) );
    }
  }

  void on_header( std::size_t, std::size_t num_inputs, std::size_t num_latches, std::size_t, std::size_t ) const override
  {
    (void)num_latches;
    assert( num_latches == 0 && "AIG has latches, not supported yet." );

    /* constant */
    signals.push_back( _ntk.get_constant( false ) );

    /* create inputs */
    for ( auto i = 0u; i < num_inputs; ++i )
    {
      signals.push_back( _ntk.create_pi() );
    }
  }

  void on_input_name( unsigned index, const std::string& name ) const override
  {
    if ( _names )
      _names->insert( signals[1 + index], name );
  }

  void on_output_name( unsigned index, const std::string& name ) const override
  {
    std::get<1>( outputs[index] ) = name;
  }

  void on_and( unsigned index, unsigned left_lit, unsigned right_lit ) const override
  {
    (void)index;
    assert( signals.size() == index );

    auto left = signals[left_lit >> 1];
    if ( left_lit & 1 )
    {
      left = _ntk.create_not( left );
    }

    auto right = signals[right_lit >> 1];
    if ( right_lit & 1 )
    {
      right = _ntk.create_not( right );
    }

    signals.push_back( _ntk.create_and( left, right ) );
  }

  void on_output( unsigned index, unsigned lit ) const override
  {
    (void)index;
    assert( index == outputs.size() );
    outputs.push_back( std::make_tuple( lit, "" ) );
  }

private:
  Ntk& _ntk;

  mutable std::vector<std::tuple<unsigned,std::string>> outputs;
  mutable std::vector<signal<Ntk>> signals;
  mutable NameMap<Ntk>* _names;
};

/*! \brief Lorina reader callback for Aiger files.
 *
 * **Required network functions:**
 * - `create_pi`
 * - `create_po`
 * - `create_ro`
 * - `create_ri`
 * - `get_constant`
 * - `create_not`
 * - `create_and`
 *
   \verbatim embed:rst

   Example

   .. code-block:: c++

      aig_network aig;
      lorina::read_aiger( "file.aig", aiger_reader( aig ) );

      mig_network mig;
      lorina::read_aiger( "file.aig", aiger_reader( mig ) );
   \endverbatim
 */
template<>
class aiger_reader<aig_network> : public lorina::aiger_reader
{
public:
  explicit aiger_reader( aig_network& ntk, NameMap<aig_network>* names = nullptr ) : _ntk( ntk ), _names( names )
  {
    static_assert( is_network_type_v<aig_network>, "Ntk is not a network type" );
    static_assert( has_create_pi_v<aig_network>, "Ntk does not implement the create_pi function" );
    static_assert( has_create_po_v<aig_network>, "Ntk does not implement the create_po function" );
    static_assert( has_create_ro_v<aig_network>, "Ntk does not implement the create_ro function" );
    static_assert( has_create_ri_v<aig_network>, "Ntk does not implement the create_ri function" );
    static_assert( has_get_constant_v<aig_network>, "Ntk does not implement the get_constant function" );
    static_assert( has_create_not_v<aig_network>, "Ntk does not implement the create_not function" );
    static_assert( has_create_and_v<aig_network>, "Ntk does not implement the create_and function" );
  }

  ~aiger_reader()
  {
    for ( auto out : outputs )
    {
      auto const lit = std::get<0>( out );
      auto signal = signals[lit >> 1];
      if ( lit & 1 )
      {
        signal = _ntk.create_not( signal );
      }
      if ( _names )
        _names->insert( signal, std::get<1>( out ) );
      _ntk.create_po( signal );
    }

    auto count = 0;
    for ( auto latch : latches )
    {
      const auto lit = std::get<0>( latch );
      auto signal = signals[lit >> 1];
      if ( lit & 1 )
      {
        signal = _ntk.create_not( signal );
      }
      if ( _names )
        _names->insert( signal, std::get<2>( latch ) + "_next" );
      _ntk.create_ri( signal );
    }
  }

  void on_header( std::size_t, std::size_t num_inputs, std::size_t num_latches, std::size_t, std::size_t ) const override
  {
    _num_inputs = num_inputs;

    /* constant */
    signals.push_back( _ntk.get_constant( false ) );

    /* create primary inputs (pi) */
    for ( auto i = 0u; i < num_inputs; ++i )
    {
      signals.push_back( _ntk.create_pi() );
    }

    /* create latch outputs (ro) */
    for ( auto i = 0u; i < num_latches; ++i )
    {
      signals.push_back( _ntk.create_ro() );
    }
  }

  void on_input_name( unsigned index, const std::string& name ) const override
  {
    if ( _names )
      _names->insert( signals[1 + index], name );
  }

  void on_output_name( unsigned index, const std::string& name ) const override
  {
    std::get<1>( outputs[index] ) = name;
  }

  void on_latch_name( unsigned index, const std::string& name ) const override
  {
    if ( _names )
      _names->insert( signals[1 + _num_inputs + index], name );
    std::get<2>( latches[index] ) = name;
  }

  void on_and( unsigned index, unsigned left_lit, unsigned right_lit ) const override
  {
    (void)index;
    assert( signals.size() == index );

    auto left = signals[left_lit >> 1];
    if ( left_lit & 1 )
    {
      left = _ntk.create_not( left );
    }

    auto right = signals[right_lit >> 1];
    if ( right_lit & 1 )
    {
      right = _ntk.create_not( right );
    }

    signals.push_back( _ntk.create_and( left, right ) );
  }

  void on_latch( unsigned index, unsigned next, latch_init_value reset ) const override
  {
    (void)index;
    latches.push_back( std::make_tuple( next, reset, "" ) );
  }

  void on_output( unsigned index, unsigned lit ) const override
  {
    (void)index;
    assert( index == outputs.size() );
    outputs.push_back( std::make_tuple( lit,"" ) );
  }

private:
  aig_network& _ntk;

  mutable uint32_t _num_inputs = 0;
  mutable std::vector<std::tuple<unsigned,std::string>> outputs;
  mutable std::vector<aig_network::signal> signals;
  mutable std::vector<std::tuple<unsigned,latch_init_value,std::string>> latches;
  mutable NameMap<aig_network>* _names;
};

} /* namespace mockturtle */
<commit_msg>aiger_reader.<commit_after>/* mockturtle: C++ logic network library
 * Copyright (C) 2018  EPFL
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following
 * conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

/*!
  \file aiger_reader.hpp
  \brief Lorina reader for AIGER files

  \author Mathias Soeken
*/

#pragma once

#include <lorina/aiger.hpp>
#include "../networks/aig.hpp"
#include "../traits.hpp"

namespace mockturtle
{

template<
  typename Ntk
, typename StorageContainerMap = std::unordered_map<signal<Ntk>,std::vector<std::string>>
, typename StorageContainerReverseMap = std::unordered_map<std::string, signal<Ntk>>
>
class NameMap
{
public:
  using signal = typename Ntk::signal;

public:
  NameMap() = default;

  void insert( signal const& s, std::string const& name )
  {
    /* update direct map */
    auto const it = _names.find( s );
    if ( it == _names.end() )
    {
      _names[s] = { name };
    }
    else
    {
      it->second.push_back( name );
    }

    /* update reverse map */
    auto const rev_it = _rev_names.find( name );
    if ( rev_it != _rev_names.end() )
    {
      std::cout << "[w] signal name `" << name << "` is used twice" << std::endl;
    }
    _rev_names.insert( std::make_pair( name, s ) );
  }

  std::vector<std::string> operator[]( signal const& s )
  {
    return _names[s];
  }

  std::vector<std::string> operator[]( signal const& s ) const
  {
    return _names.at( s );
  }

  std::vector<std::string> get_name( signal const& s ) const
  {
    return _names.at( s );
  }

  bool has_name( signal const& s, std::string const& name ) const
  {
    auto const it = _names.find( s );
    if ( it == _names.end() )
    {
      return false;
    }
    return ( std::find( it->second.begin(), it->second.end(), name ) != it->second.end() );
  }

  StorageContainerReverseMap get_name_to_signal_mapping() const
  {
    return _rev_names;
  }

protected:
  StorageContainerMap _names;
  StorageContainerReverseMap _rev_names;
}; // NameMap

/*! \brief Lorina reader callback for Aiger files.
 *
 * **Required network functions:**
 * - `create_pi`
 * - `create_po`
 * - `get_constant`
 * - `create_not`
 * - `create_and`
 *
   \verbatim embed:rst

   Example

   .. code-block:: c++

      aig_network aig;
      lorina::read_aiger( "file.aig", aiger_reader( aig ) );

      mig_network mig;
      lorina::read_aiger( "file.aig", aiger_reader( mig ) );
   \endverbatim
 */
template<typename Ntk>
class aiger_reader : public lorina::aiger_reader
{
public:
  explicit aiger_reader( Ntk& ntk, NameMap<Ntk> *names = nullptr ) : _ntk( ntk ), _names( names )
  {
    static_assert( is_network_type_v<Ntk>, "Ntk is not a network type" );
    static_assert( has_create_pi_v<Ntk>, "Ntk does not implement the create_pi function" );
    static_assert( has_create_po_v<Ntk>, "Ntk does not implement the create_po function" );
    static_assert( has_get_constant_v<Ntk>, "Ntk does not implement the get_constant function" );
    static_assert( has_create_not_v<Ntk>, "Ntk does not implement the create_not function" );
    static_assert( has_create_and_v<Ntk>, "Ntk does not implement the create_and function" );
  }

  ~aiger_reader()
  {
    for ( auto out : outputs )
    {
      auto lit = std::get<0>( out );
      auto signal = signals[lit >> 1];
      if ( lit & 1 )
      {
        signal = _ntk.create_not( signal );
      }
      _ntk.create_po( signal );
      if ( _names )
        _names->insert( signal, std::get<1>( out ) );
    }
  }

  void on_header( std::size_t, std::size_t num_inputs, std::size_t num_latches, std::size_t, std::size_t ) const override
  {
    (void)num_latches;
    assert( num_latches == 0 && "AIG has latches, not supported yet." );

    /* constant */
    signals.push_back( _ntk.get_constant( false ) );

    /* create inputs */
    for ( auto i = 0u; i < num_inputs; ++i )
    {
      signals.push_back( _ntk.create_pi() );
    }
  }

  void on_input_name( unsigned index, const std::string& name ) const override
  {
    if ( _names )
      _names->insert( signals[1 + index], name );
  }

  void on_output_name( unsigned index, const std::string& name ) const override
  {
    std::get<1>( outputs[index] ) = name;
  }

  void on_and( unsigned index, unsigned left_lit, unsigned right_lit ) const override
  {
    (void)index;
    assert( signals.size() == index );

    auto left = signals[left_lit >> 1];
    if ( left_lit & 1 )
    {
      left = _ntk.create_not( left );
    }

    auto right = signals[right_lit >> 1];
    if ( right_lit & 1 )
    {
      right = _ntk.create_not( right );
    }

    signals.push_back( _ntk.create_and( left, right ) );
  }

  void on_output( unsigned index, unsigned lit ) const override
  {
    (void)index;
    assert( index == outputs.size() );
    outputs.emplace_back( lit, "" );
  }

private:
  Ntk& _ntk;

  mutable std::vector<std::tuple<unsigned,std::string>> outputs;
  mutable std::vector<signal<Ntk>> signals;
  mutable NameMap<Ntk>* _names;
};

/*! \brief Lorina reader callback for Aiger files.
 *
 * **Required network functions:**
 * - `create_pi`
 * - `create_po`
 * - `create_ro`
 * - `create_ri`
 * - `get_constant`
 * - `create_not`
 * - `create_and`
 *
   \verbatim embed:rst

   Example

   .. code-block:: c++

      aig_network aig;
      lorina::read_aiger( "file.aig", aiger_reader( aig ) );

      mig_network mig;
      lorina::read_aiger( "file.aig", aiger_reader( mig ) );
   \endverbatim
 */
template<>
class aiger_reader<aig_network> : public lorina::aiger_reader
{
public:
  explicit aiger_reader( aig_network& ntk, NameMap<aig_network>* names = nullptr ) : _ntk( ntk ), _names( names )
  {
    static_assert( is_network_type_v<aig_network>, "Ntk is not a network type" );
    static_assert( has_create_pi_v<aig_network>, "Ntk does not implement the create_pi function" );
    static_assert( has_create_po_v<aig_network>, "Ntk does not implement the create_po function" );
    static_assert( has_create_ro_v<aig_network>, "Ntk does not implement the create_ro function" );
    static_assert( has_create_ri_v<aig_network>, "Ntk does not implement the create_ri function" );
    static_assert( has_get_constant_v<aig_network>, "Ntk does not implement the get_constant function" );
    static_assert( has_create_not_v<aig_network>, "Ntk does not implement the create_not function" );
    static_assert( has_create_and_v<aig_network>, "Ntk does not implement the create_and function" );
  }

  ~aiger_reader()
  {
    for ( auto out : outputs )
    {
      auto const lit = std::get<0>( out );
      auto signal = signals[lit >> 1];
      if ( lit & 1 )
      {
        signal = _ntk.create_not( signal );
      }
      if ( _names )
        _names->insert( signal, std::get<1>( out ) );
      _ntk.create_po( signal );
    }

    auto count = 0;
    for ( auto latch : latches )
    {
      const auto lit = std::get<0>( latch );
      auto signal = signals[lit >> 1];
      if ( lit & 1 )
      {
        signal = _ntk.create_not( signal );
      }
      if ( _names )
        _names->insert( signal, std::get<2>( latch ) + "_next" );
      _ntk.create_ri( signal );
    }
  }

  void on_header( std::size_t, std::size_t num_inputs, std::size_t num_latches, std::size_t, std::size_t ) const override
  {
    _num_inputs = num_inputs;

    /* constant */
    signals.push_back( _ntk.get_constant( false ) );

    /* create primary inputs (pi) */
    for ( auto i = 0u; i < num_inputs; ++i )
    {
      signals.push_back( _ntk.create_pi() );
    }

    /* create latch outputs (ro) */
    for ( auto i = 0u; i < num_latches; ++i )
    {
      signals.push_back( _ntk.create_ro() );
    }
  }

  void on_input_name( unsigned index, const std::string& name ) const override
  {
    if ( _names )
      _names->insert( signals[1 + index], name );
  }

  void on_output_name( unsigned index, const std::string& name ) const override
  {
    std::get<1>( outputs[index] ) = name;
  }

  void on_latch_name( unsigned index, const std::string& name ) const override
  {
    if ( _names )
      _names->insert( signals[1 + _num_inputs + index], name );
    std::get<2>( latches[index] ) = name;
  }

  void on_and( unsigned index, unsigned left_lit, unsigned right_lit ) const override
  {
    (void)index;
    assert( signals.size() == index );

    auto left = signals[left_lit >> 1];
    if ( left_lit & 1 )
    {
      left = _ntk.create_not( left );
    }

    auto right = signals[right_lit >> 1];
    if ( right_lit & 1 )
    {
      right = _ntk.create_not( right );
    }

    signals.push_back( _ntk.create_and( left, right ) );
  }

  void on_latch( unsigned index, unsigned next, latch_init_value reset ) const override
  {
    (void)index;
    latches.push_back( std::make_tuple( next, reset, "" ) );
  }

  void on_output( unsigned index, unsigned lit ) const override
  {
    (void)index;
    assert( index == outputs.size() );
    outputs.emplace_back( lit, "" );
  }

private:
  aig_network& _ntk;

  mutable uint32_t _num_inputs = 0;
  mutable std::vector<std::tuple<unsigned,std::string>> outputs;
  mutable std::vector<aig_network::signal> signals;
  mutable std::vector<std::tuple<unsigned,latch_init_value,std::string>> latches;
  mutable NameMap<aig_network>* _names;
};

} /* namespace mockturtle */
<|endoftext|>


<commit_before>#include "keyboardselectcontainer.h"
#include "languagelistitem.h"
#include "grouptitlewidget.h"
#include "dcplanguageconf.h"
#include "languagetranslation.h"

#include <QDebug>
#include <duilayout.h>
#include <duilinearlayoutpolicy.h>
#include <duigridlayoutpolicy.h>
#include <duilabel.h>
#include <duilocale.h>
#include <DuiMessageBox>

KeyboardSelectContainer::KeyboardSelectContainer(const QString &title,
                                                 QStringList itemList,
                                                 DuiWidget *parent)
                        :DuiWidget(parent),
                         m_titleText(title),
                         m_itemList(itemList)
{
    initWidget();
    QStringList keyboardList = DcpLanguageConf::instance()->keyboardLanguages();
    QStringListIterator iterator(keyboardList);
    while (iterator.hasNext())
    {
        this->selectItem(iterator.next());
    }
}

KeyboardSelectContainer::~KeyboardSelectContainer()
{
}

void KeyboardSelectContainer::selectItem(const QString &text)
{
    for (int i = 0; i < m_listItemVector.size(); i++)
    {
        if (text == m_listItemVector[i]->text())
        {
            m_listItemVector[i]->checked(true);
        }
    }
}

void KeyboardSelectContainer::initWidget()
{
    // mainLayout
    DuiLayout *mainLayout = new DuiLayout(this);
    DuiLinearLayoutPolicy *mainLayoutPolicy =
            new DuiLinearLayoutPolicy(mainLayout, Qt::Vertical);
    mainLayout->setPolicy(mainLayoutPolicy);

    GroupTitleWidget *titleLabel = new GroupTitleWidget(m_titleText, this);
    mainLayoutPolicy->addItemAtPosition(titleLabel, 0, Qt::AlignCenter);

    // gridLayout
    DuiLayout *gridLayout = new DuiLayout(NULL);
    DuiGridLayoutPolicy *itemLayout = new DuiGridLayoutPolicy(gridLayout);
    gridLayout->setPolicy(itemLayout);

    QStringListIterator iterator(m_itemList);
    while (iterator.hasNext())
    {
        QString name = iterator.next();
        m_listItemVector.append(new LanguageListItem(name, this));
    }

    for (int i = 0; i < m_listItemVector.size(); i++)
    {
        itemLayout->addItemAtPosition(m_listItemVector[i], i / 2, i % 2);
        connect(m_listItemVector[i], SIGNAL(clicked(QString)), this,
                SLOT(itemClicked(QString)));
    }

    mainLayoutPolicy->addItemAtPosition(gridLayout, 1, Qt::AlignCenter);
}

void KeyboardSelectContainer::itemClicked(QString language)
{
    for (int i = 0, checkCount = m_listItemVector.size();
             i < m_listItemVector.size(); i++)
    {
        if (m_listItemVector[i]->isChecked())
        {
            DcpLanguageConf::instance()->removeKeyboardLanguage(m_listItemVector[i]->text());
            DcpLanguageConf::instance()->addKeyboardLanguage(m_listItemVector[i]->text());
        } else {
            checkCount--;
            bool doRemove = true;
            if (checkCount < 1)
            {
                DuiMessageBox mb("Keep last language?",
                                 DuiMessageBox::Ok|DuiMessageBox::Cancel);
                mb.exec();
                doRemove = mb.result() != DuiDialog::Rejected;
                }
            if (doRemove)
            DcpLanguageConf::instance()->removeKeyboardLanguage(language);
            else
               selectItem(language);
        }
    }
}
<commit_msg>keep dialog fix 2<commit_after>#include "keyboardselectcontainer.h"
#include "languagelistitem.h"
#include "grouptitlewidget.h"
#include "dcplanguageconf.h"
#include "languagetranslation.h"

#include <QDebug>
#include <duilayout.h>
#include <duilinearlayoutpolicy.h>
#include <duigridlayoutpolicy.h>
#include <duilabel.h>
#include <duilocale.h>
#include <DuiMessageBox>

KeyboardSelectContainer::KeyboardSelectContainer(const QString &title,
                                                 QStringList itemList,
                                                 DuiWidget *parent)
                        :DuiWidget(parent),
                         m_titleText(title),
                         m_itemList(itemList)
{
    initWidget();
    QStringList keyboardList = DcpLanguageConf::instance()->keyboardLanguages();
    QStringListIterator iterator(keyboardList);
    while (iterator.hasNext())
    {
        this->selectItem(iterator.next());
    }
}

KeyboardSelectContainer::~KeyboardSelectContainer()
{
}

void KeyboardSelectContainer::selectItem(const QString &text)
{
    for (int i = 0; i < m_listItemVector.size(); i++)
    {
        if (text == m_listItemVector[i]->text())
        {
            m_listItemVector[i]->checked(true);
        }
    }
}

void KeyboardSelectContainer::initWidget()
{
    // mainLayout
    DuiLayout *mainLayout = new DuiLayout(this);
    DuiLinearLayoutPolicy *mainLayoutPolicy =
            new DuiLinearLayoutPolicy(mainLayout, Qt::Vertical);
    mainLayout->setPolicy(mainLayoutPolicy);

    GroupTitleWidget *titleLabel = new GroupTitleWidget(m_titleText, this);
    mainLayoutPolicy->addItemAtPosition(titleLabel, 0, Qt::AlignCenter);

    // gridLayout
    DuiLayout *gridLayout = new DuiLayout(NULL);
    DuiGridLayoutPolicy *itemLayout = new DuiGridLayoutPolicy(gridLayout);
    gridLayout->setPolicy(itemLayout);

    QStringListIterator iterator(m_itemList);
    while (iterator.hasNext())
    {
        QString name = iterator.next();
        m_listItemVector.append(new LanguageListItem(name, this));
    }

    for (int i = 0; i < m_listItemVector.size(); i++)
    {
        itemLayout->addItemAtPosition(m_listItemVector[i], i / 2, i % 2);
        connect(m_listItemVector[i], SIGNAL(clicked(QString)), this,
                SLOT(itemClicked(QString)));
    }

    mainLayoutPolicy->addItemAtPosition(gridLayout, 1, Qt::AlignCenter);
}

void KeyboardSelectContainer::itemClicked(QString language)
{
    for (int i = 0, checkCount = m_listItemVector.size();
             i < m_listItemVector.size(); i++)
    {
        if (m_listItemVector[i]->isChecked())
        {
            DcpLanguageConf::instance()->removeKeyboardLanguage(m_listItemVector[i]->text());
            DcpLanguageConf::instance()->addKeyboardLanguage(m_listItemVector[i]->text());
        } else {
            checkCount--;
            bool doKeep = false;
            if (checkCount < 1)
            {
                DuiMessageBox mb("Keep last language?",
                                 DuiMessageBox::Ok|DuiMessageBox::Cancel);
                mb.exec();
                doKeep = mb.result() == DuiDialog::Accepted;
                }
            if (doKeep)
               selectItem(language);
            else
                DcpLanguageConf::instance()->removeKeyboardLanguage(language);
        }
    }
}
<|endoftext|>


<commit_before>//
//  Sharp BoosterPackLCD SPI
//  Example for library for Sharp BoosterPack LCD with hardware SPI
//
//
//  Author :  Stefan Schauer
//  Date   :  Mar 05, 2015
//  Version:  1.02
//  File   :  LCD_SharpBoosterPack_SPI_main.c
//
//  Version:  1.01 : added support for CC3200
//  Version:  1.02 : added print class
//
//  Based on the LCD5110 Library
//  Created by Rei VILO on 28/05/12
//  Copyright (c) 2012 http://embeddedcomputing.weebly.com
//  Licence CC = BY SA NC
//

#include <energia.h>
#include "LCD_SharpBoosterPack_SPI.h"
#include "SPI.h"

uint8_t _pinReset;
uint8_t _pinSerialData;
uint8_t _pinDISP;
uint8_t _pinVCC;
uint8_t _pinChipSelect;
uint8_t _pinSerialClock;

// Booster Pack Pins
    //  7 - P2.2 for SPI_CLK mode
    // 15 - P1.6 for SPI_SIMO mode
    //  6 - P2.4 output pin for SPI_CS
    //  2 - P4.2 as output to supply the LCD
    //  5 - P4.3 as output for DISP
    // Set display's VCC and DISP pins to high

static const uint8_t P_CS   = 6;
static const uint8_t P_VCC  = 2;
static const uint8_t P_DISP = 5;

#define SHARP_LCD_TRAILER_BYTE              0x00

#define SHARP_LCD_CMD_CHANGE_VCOM           0x00
#define SHARP_LCD_CMD_CLEAR_SCREEN          0x20
#define SHARP_LCD_CMD_WRITE_LINE            0x80

unsigned char DisplayBuffer[LCD_VERTICAL_MAX][LCD_HORIZONTAL_MAX/8];

unsigned char VCOMbit = 0x40;
#define SHARP_VCOM_TOGGLE_BIT               0x40

unsigned char flagSendToggleVCOMCommand = 0;
#define SHARP_SEND_COMMAND_RUNNING          0x01
#define SHARP_REQUEST_TOGGLE_VCOM           0x02

static void SendToggleVCOMCommand(void);

uint8_t textx = 0;
uint8_t texty = 0;
uint8_t textstartx =0;
uint8_t textstarty =0;
uint8_t lineSpacing[NUM_OF_FONTS] = {9,16};

LCD_SharpBoosterPack_SPI::LCD_SharpBoosterPack_SPI() {
    LCD_SharpBoosterPack_SPI(
                 P_CS,    // Chip Select
                 P_VCC,   // Vcc display
                 P_DISP   // DISP
    );
}

LCD_SharpBoosterPack_SPI::LCD_SharpBoosterPack_SPI(uint8_t pinChipSelect, uint8_t pinDISP, uint8_t pinVCC) {
    _pinChipSelect  = pinChipSelect;
    _pinDISP = pinDISP;
    _pinVCC  = pinVCC;
}

void LCD_SharpBoosterPack_SPI::setXY(uint8_t x, uint8_t y, uint8_t  ulValue) {
    if( ulValue != 0)
        DisplayBuffer[y][x>>3] &= ~(0x80 >> (x & 0x7));
    else
        DisplayBuffer[y][x>>3] |= (0x80 >> (x & 0x7));
}

void LCD_SharpBoosterPack_SPI::begin() {
    SPI.begin();
    //SPI.setClockDivider(SPI_CLOCK_DIV2);
    SPI.setBitOrder(MSBFIRST);
    SPI.setDataMode(SPI_MODE0);

    pinMode(_pinChipSelect, OUTPUT);
    pinMode(_pinDISP, OUTPUT);
    pinMode(_pinVCC, OUTPUT);

    digitalWrite(_pinChipSelect, LOW);
    digitalWrite(_pinVCC, HIGH);
    digitalWrite(_pinDISP, HIGH);

    TA0_enableVCOMToggle();

    clear();
    _font = 0;
}

String LCD_SharpBoosterPack_SPI::WhoAmI() {
    return "Sharp LCD BoosterPack";
}

void LCD_SharpBoosterPack_SPI::clear() {

  unsigned char command = SHARP_LCD_CMD_CLEAR_SCREEN;

  // set flag to indicate command transmit is running
  flagSendToggleVCOMCommand |= SHARP_SEND_COMMAND_RUNNING;

  command |= VCOMbit;                    //COM inversion bit

  // Set P2.4 High for CS
  digitalWrite(_pinChipSelect, HIGH);

  SPI.transfer(command);
  SPI.transfer(SHARP_LCD_TRAILER_BYTE);

  // Wait for last byte to be sent, then drop SCS
  delayMicroseconds(10);

  // Set P2.4 High for CS
  digitalWrite(_pinChipSelect, LOW);

  // clear flag to indicate command transmit is free
  flagSendToggleVCOMCommand &= ~SHARP_SEND_COMMAND_RUNNING;
  SendToggleVCOMCommand(); // send toggle if required

  clearBuffer();

}

void LCD_SharpBoosterPack_SPI::clearBuffer() {
    unsigned int i=0,j=0;
    for(i =0; i< LCD_VERTICAL_MAX; i++)
    for(j =0; j< (LCD_HORIZONTAL_MAX>>3); j++)
       DisplayBuffer[i][j] = 0xff;
}

void LCD_SharpBoosterPack_SPI::setFont(tNumOfFontsType font) {
    _font = font;
}

void LCD_SharpBoosterPack_SPI::setLineSpacing(uint8_t pixel) {
    lineSpacing[_font] = pixel;
}

void LCD_SharpBoosterPack_SPI::text(uint8_t x, uint8_t y, String s) {
	text(x, y, s, LCDWrapNextLine);
}

void LCD_SharpBoosterPack_SPI::text(uint8_t x, uint8_t y, String s, tLCDWrapType wrap) {
    uint8_t i;
    uint8_t j;
    int8_t k;
    int8_t deltax = 5;
    int8_t deltay = lineSpacing[_font];
	uint8_t c;

	setCharXY(x, y);
    if (_font==1) {
		deltax = 11;
	}

	for (j=0; j<s.length(); j++) {
		c = s.charAt(j);
		if  ((wrap == LCDWrapLine)     && (textx+deltax > LCD_HORIZONTAL_MAX)) {textx = textstartx;}
		if  ((wrap == LCDWrapNextLine) && (textx+deltax > LCD_HORIZONTAL_MAX)) {textx = textstartx; texty += deltay;}
		if  (c == '\n') {textx = textstartx; texty += deltay;}
		else if  (c >= ' ') {
			if (_font==0) {
				for (i=0; i<deltax; i++){
					for (k=7; k>=0; k--) setXY(textx, texty+k, Terminal6x8[c-' '][i]&(1<<k));
					textx += 1;
				}
			}
			if (_font==1) {
				for (i=0; i<deltax; i++){
					for (k=7; k>=0; k--){
						setXY(textx, texty+k,   Terminal11x16[c-' '][2*i]&(1<<k));
						setXY(textx, texty+k+8, Terminal11x16[c-' '][2*i+1]&(1<<k));
					}
					textx += 1;
				}
			}
			textx += 1;  // spacing
		}
	}
}

void LCD_SharpBoosterPack_SPI::text(uint8_t x, uint8_t y, uint8_t c) {
	setCharXY(x, y);
	write(c);
}

size_t LCD_SharpBoosterPack_SPI::write(uint8_t c) {
    uint8_t i;
    int8_t k;
	const tLCDWrapType wrap = LCDWrapNextLine;
    int8_t deltax = 5;
    int8_t deltay = 9;

    if (_font==1) {
		deltax = 11;
		deltay = 16;
	}

	if  ((wrap == LCDWrapLine)     && (textx+deltax > LCD_HORIZONTAL_MAX)) {textx = textstartx;}
	if  ((wrap == LCDWrapNextLine) && (textx+deltax > LCD_HORIZONTAL_MAX)) {textx = textstartx; texty += deltay;}
	if  (c == '\n') {textx = textstartx; texty += deltay;}
	else if  (c >= ' ') {
		if (_font==0) {
			for (i=0; i<deltax; i++){
				for (k=7; k>=0; k--) setXY(textx, texty+k, Terminal6x8[c-' '][i]&(1<<k));
				textx += 1;
			}
		}
		if (_font==1) {
			for (i=0; i<deltax; i++){
				for (k=7; k>=0; k--){
					setXY(textx, texty+k,   Terminal11x16[c-' '][2*i]&(1<<k));
					setXY(textx, texty+k+8, Terminal11x16[c-' '][2*i+1]&(1<<k));
				}
				textx += 1;
			}
		}
		textx += 1;  // spacing
	}
}

void LCD_SharpBoosterPack_SPI::setCharXY(uint8_t x, uint8_t y) {
	textx =x;
	texty =y;
	textstartx =x;
	textstarty =y;
}

const uint8_t referse_data[] = {0x0, 0x8, 0x4, 0xC, 0x2, 0xA, 0x6, 0xE, 0x1, 0x9, 0x5, 0xD, 0x3, 0xB, 0x7, 0xF};
uint8_t reverse(uint8_t x)
{
  uint8_t b = 0;

  b  = referse_data[x & 0xF]<<4;
  b |= referse_data[(x & 0xF0)>>4];
  return b;
}

void LCD_SharpBoosterPack_SPI::flush (void)
{
    unsigned char *pucData = &DisplayBuffer[0][0];
    long xi =0;
    long xj = 0;
    //image update mode(1X000000b)
    unsigned char command = SHARP_LCD_CMD_WRITE_LINE;

    // set flag to indicate command transmit is running
    flagSendToggleVCOMCommand |= SHARP_SEND_COMMAND_RUNNING;
    //COM inversion bit
    command |= VCOMbit;
    // Set P2.4 High for CS
    digitalWrite(_pinChipSelect, HIGH);

    SPI.transfer((char)command);
    for(xj=0; xj<LCD_VERTICAL_MAX; xj++)
    {
        SPI.transfer((char)reverse(xj + 1));

        for(xi=0; xi<(LCD_HORIZONTAL_MAX>>3); xi++)
        {
            SPI.transfer((char)*(pucData++));
        }
        SPI.transfer(SHARP_LCD_TRAILER_BYTE);
    }

    SPI.transfer((char)SHARP_LCD_TRAILER_BYTE);
	delayMicroseconds(10);

    // Set P2.4 Low for CS
    digitalWrite(_pinChipSelect, LOW);
    // clear flag to indicate command transmit is free
    flagSendToggleVCOMCommand &= ~SHARP_SEND_COMMAND_RUNNING;
    SendToggleVCOMCommand(); // send toggle if required
}

static void SendToggleVCOMCommand(void)
{
    if(!(flagSendToggleVCOMCommand & SHARP_REQUEST_TOGGLE_VCOM)){ // no request pending ?
        VCOMbit ^= SHARP_VCOM_TOGGLE_BIT;                 // Toggle VCOM Bit
    }

    if(flagSendToggleVCOMCommand & SHARP_SEND_COMMAND_RUNNING){
        // set request flag
        flagSendToggleVCOMCommand |= SHARP_REQUEST_TOGGLE_VCOM;
    }else{  // if no communication to LCD -> send toggle sequence now
        unsigned char command = SHARP_LCD_CMD_CHANGE_VCOM;
        command |= VCOMbit;                    //COM inversion bit

        // Set P2.4 High for CS
        digitalWrite(_pinChipSelect, HIGH);

        SPI.transfer((char)command);
        SPI.transfer((char)SHARP_LCD_TRAILER_BYTE);

        // Wait for last byte to be sent, then drop SCS
		delayMicroseconds(10);
        // Set P2.4 High for CS
        digitalWrite(_pinChipSelect, LOW);
        // clear request flag
        flagSendToggleVCOMCommand &= ~SHARP_REQUEST_TOGGLE_VCOM;
    }
}

struct OneMsTaskTimer_t timer_task = {1000, SendToggleVCOMCommand, 0, 0};

void LCD_SharpBoosterPack_SPI::TA0_enableVCOMToggle()
{
    // generate Int. each 4096*8*32768Hz = 1 sec
    //
    // Base address for first timer
    //
    OneMsTaskTimer::add(&timer_task);
	OneMsTaskTimer::start();
}

void LCD_SharpBoosterPack_SPI::TA0_turnOff()
{
  OneMsTaskTimer::stop();
}

<commit_msg>Update LCD_SharpBoosterPack_SPI.cpp<commit_after>//
//  Sharp BoosterPackLCD SPI
//  Example for library for Sharp BoosterPack LCD with hardware SPI
//
//
//  Author :  Stefan Schauer
//  Date   :  Mar 05, 2015
//  Version:  1.02
//  File   :  LCD_SharpBoosterPack_SPI_main.c
//
//  Version:  1.01 : added support for CC3200
//  Version:  1.02 : added print class
//
//  Based on the LCD5110 Library
//  Created by Rei VILO on 28/05/12
//  Copyright (c) 2012 http://embeddedcomputing.weebly.com
//  Licence CC = BY SA NC
//

#include <Energia.h>
#include "LCD_SharpBoosterPack_SPI.h"
#include "SPI.h"

uint8_t _pinReset;
uint8_t _pinSerialData;
uint8_t _pinDISP;
uint8_t _pinVCC;
uint8_t _pinChipSelect;
uint8_t _pinSerialClock;

// Booster Pack Pins
    //  7 - P2.2 for SPI_CLK mode
    // 15 - P1.6 for SPI_SIMO mode
    //  6 - P2.4 output pin for SPI_CS
    //  2 - P4.2 as output to supply the LCD
    //  5 - P4.3 as output for DISP
    // Set display's VCC and DISP pins to high

static const uint8_t P_CS   = 6;
static const uint8_t P_VCC  = 2;
static const uint8_t P_DISP = 5;

#define SHARP_LCD_TRAILER_BYTE              0x00

#define SHARP_LCD_CMD_CHANGE_VCOM           0x00
#define SHARP_LCD_CMD_CLEAR_SCREEN          0x20
#define SHARP_LCD_CMD_WRITE_LINE            0x80

unsigned char DisplayBuffer[LCD_VERTICAL_MAX][LCD_HORIZONTAL_MAX/8];

unsigned char VCOMbit = 0x40;
#define SHARP_VCOM_TOGGLE_BIT               0x40

unsigned char flagSendToggleVCOMCommand = 0;
#define SHARP_SEND_COMMAND_RUNNING          0x01
#define SHARP_REQUEST_TOGGLE_VCOM           0x02

static void SendToggleVCOMCommand(void);

uint8_t textx = 0;
uint8_t texty = 0;
uint8_t textstartx =0;
uint8_t textstarty =0;
uint8_t lineSpacing[NUM_OF_FONTS] = {9,16};

LCD_SharpBoosterPack_SPI::LCD_SharpBoosterPack_SPI() {
    LCD_SharpBoosterPack_SPI(
                 P_CS,    // Chip Select
                 P_VCC,   // Vcc display
                 P_DISP   // DISP
    );
}

LCD_SharpBoosterPack_SPI::LCD_SharpBoosterPack_SPI(uint8_t pinChipSelect, uint8_t pinDISP, uint8_t pinVCC) {
    _pinChipSelect  = pinChipSelect;
    _pinDISP = pinDISP;
    _pinVCC  = pinVCC;
}

void LCD_SharpBoosterPack_SPI::setXY(uint8_t x, uint8_t y, uint8_t  ulValue) {
    if( ulValue != 0)
        DisplayBuffer[y][x>>3] &= ~(0x80 >> (x & 0x7));
    else
        DisplayBuffer[y][x>>3] |= (0x80 >> (x & 0x7));
}

void LCD_SharpBoosterPack_SPI::begin() {
    SPI.begin();
    //SPI.setClockDivider(SPI_CLOCK_DIV2);
    SPI.setBitOrder(MSBFIRST);
    SPI.setDataMode(SPI_MODE0);

    pinMode(_pinChipSelect, OUTPUT);
    pinMode(_pinDISP, OUTPUT);
    pinMode(_pinVCC, OUTPUT);

    digitalWrite(_pinChipSelect, LOW);
    digitalWrite(_pinVCC, HIGH);
    digitalWrite(_pinDISP, HIGH);

    TA0_enableVCOMToggle();

    clear();
    _font = 0;
}

String LCD_SharpBoosterPack_SPI::WhoAmI() {
    return "Sharp LCD BoosterPack";
}

void LCD_SharpBoosterPack_SPI::clear() {

  unsigned char command = SHARP_LCD_CMD_CLEAR_SCREEN;

  // set flag to indicate command transmit is running
  flagSendToggleVCOMCommand |= SHARP_SEND_COMMAND_RUNNING;

  command |= VCOMbit;                    //COM inversion bit

  // Set P2.4 High for CS
  digitalWrite(_pinChipSelect, HIGH);

  SPI.transfer(command);
  SPI.transfer(SHARP_LCD_TRAILER_BYTE);

  // Wait for last byte to be sent, then drop SCS
  delayMicroseconds(10);

  // Set P2.4 High for CS
  digitalWrite(_pinChipSelect, LOW);

  // clear flag to indicate command transmit is free
  flagSendToggleVCOMCommand &= ~SHARP_SEND_COMMAND_RUNNING;
  SendToggleVCOMCommand(); // send toggle if required

  clearBuffer();

}

void LCD_SharpBoosterPack_SPI::clearBuffer() {
    unsigned int i=0,j=0;
    for(i =0; i< LCD_VERTICAL_MAX; i++)
    for(j =0; j< (LCD_HORIZONTAL_MAX>>3); j++)
       DisplayBuffer[i][j] = 0xff;
}

void LCD_SharpBoosterPack_SPI::setFont(tNumOfFontsType font) {
    _font = font;
}

void LCD_SharpBoosterPack_SPI::setLineSpacing(uint8_t pixel) {
    lineSpacing[_font] = pixel;
}

void LCD_SharpBoosterPack_SPI::text(uint8_t x, uint8_t y, String s) {
	text(x, y, s, LCDWrapNextLine);
}

void LCD_SharpBoosterPack_SPI::text(uint8_t x, uint8_t y, String s, tLCDWrapType wrap) {
    uint8_t i;
    uint8_t j;
    int8_t k;
    int8_t deltax = 5;
    int8_t deltay = lineSpacing[_font];
	uint8_t c;

	setCharXY(x, y);
    if (_font==1) {
		deltax = 11;
	}

	for (j=0; j<s.length(); j++) {
		c = s.charAt(j);
		if  ((wrap == LCDWrapLine)     && (textx+deltax > LCD_HORIZONTAL_MAX)) {textx = textstartx;}
		if  ((wrap == LCDWrapNextLine) && (textx+deltax > LCD_HORIZONTAL_MAX)) {textx = textstartx; texty += deltay;}
		if  (c == '\n') {textx = textstartx; texty += deltay;}
		else if  (c >= ' ') {
			if (_font==0) {
				for (i=0; i<deltax; i++){
					for (k=7; k>=0; k--) setXY(textx, texty+k, Terminal6x8[c-' '][i]&(1<<k));
					textx += 1;
				}
			}
			if (_font==1) {
				for (i=0; i<deltax; i++){
					for (k=7; k>=0; k--){
						setXY(textx, texty+k,   Terminal11x16[c-' '][2*i]&(1<<k));
						setXY(textx, texty+k+8, Terminal11x16[c-' '][2*i+1]&(1<<k));
					}
					textx += 1;
				}
			}
			textx += 1;  // spacing
		}
	}
}

void LCD_SharpBoosterPack_SPI::text(uint8_t x, uint8_t y, uint8_t c) {
	setCharXY(x, y);
	write(c);
}

size_t LCD_SharpBoosterPack_SPI::write(uint8_t c) {
    uint8_t i;
    int8_t k;
	const tLCDWrapType wrap = LCDWrapNextLine;
    int8_t deltax = 5;
    int8_t deltay = 9;

    if (_font==1) {
		deltax = 11;
		deltay = 16;
	}

	if  ((wrap == LCDWrapLine)     && (textx+deltax > LCD_HORIZONTAL_MAX)) {textx = textstartx;}
	if  ((wrap == LCDWrapNextLine) && (textx+deltax > LCD_HORIZONTAL_MAX)) {textx = textstartx; texty += deltay;}
	if  (c == '\n') {textx = textstartx; texty += deltay;}
	else if  (c >= ' ') {
		if (_font==0) {
			for (i=0; i<deltax; i++){
				for (k=7; k>=0; k--) setXY(textx, texty+k, Terminal6x8[c-' '][i]&(1<<k));
				textx += 1;
			}
		}
		if (_font==1) {
			for (i=0; i<deltax; i++){
				for (k=7; k>=0; k--){
					setXY(textx, texty+k,   Terminal11x16[c-' '][2*i]&(1<<k));
					setXY(textx, texty+k+8, Terminal11x16[c-' '][2*i+1]&(1<<k));
				}
				textx += 1;
			}
		}
		textx += 1;  // spacing
	}
}

void LCD_SharpBoosterPack_SPI::setCharXY(uint8_t x, uint8_t y) {
	textx =x;
	texty =y;
	textstartx =x;
	textstarty =y;
}

const uint8_t referse_data[] = {0x0, 0x8, 0x4, 0xC, 0x2, 0xA, 0x6, 0xE, 0x1, 0x9, 0x5, 0xD, 0x3, 0xB, 0x7, 0xF};
uint8_t reverse(uint8_t x)
{
  uint8_t b = 0;

  b  = referse_data[x & 0xF]<<4;
  b |= referse_data[(x & 0xF0)>>4];
  return b;
}

void LCD_SharpBoosterPack_SPI::flush (void)
{
    unsigned char *pucData = &DisplayBuffer[0][0];
    long xi =0;
    long xj = 0;
    //image update mode(1X000000b)
    unsigned char command = SHARP_LCD_CMD_WRITE_LINE;

    // set flag to indicate command transmit is running
    flagSendToggleVCOMCommand |= SHARP_SEND_COMMAND_RUNNING;
    //COM inversion bit
    command |= VCOMbit;
    // Set P2.4 High for CS
    digitalWrite(_pinChipSelect, HIGH);

    SPI.transfer((char)command);
    for(xj=0; xj<LCD_VERTICAL_MAX; xj++)
    {
        SPI.transfer((char)reverse(xj + 1));

        for(xi=0; xi<(LCD_HORIZONTAL_MAX>>3); xi++)
        {
            SPI.transfer((char)*(pucData++));
        }
        SPI.transfer(SHARP_LCD_TRAILER_BYTE);
    }

    SPI.transfer((char)SHARP_LCD_TRAILER_BYTE);
	delayMicroseconds(10);

    // Set P2.4 Low for CS
    digitalWrite(_pinChipSelect, LOW);
    // clear flag to indicate command transmit is free
    flagSendToggleVCOMCommand &= ~SHARP_SEND_COMMAND_RUNNING;
    SendToggleVCOMCommand(); // send toggle if required
}

static void SendToggleVCOMCommand(void)
{
    if(!(flagSendToggleVCOMCommand & SHARP_REQUEST_TOGGLE_VCOM)){ // no request pending ?
        VCOMbit ^= SHARP_VCOM_TOGGLE_BIT;                 // Toggle VCOM Bit
    }

    if(flagSendToggleVCOMCommand & SHARP_SEND_COMMAND_RUNNING){
        // set request flag
        flagSendToggleVCOMCommand |= SHARP_REQUEST_TOGGLE_VCOM;
    }else{  // if no communication to LCD -> send toggle sequence now
        unsigned char command = SHARP_LCD_CMD_CHANGE_VCOM;
        command |= VCOMbit;                    //COM inversion bit

        // Set P2.4 High for CS
        digitalWrite(_pinChipSelect, HIGH);

        SPI.transfer((char)command);
        SPI.transfer((char)SHARP_LCD_TRAILER_BYTE);

        // Wait for last byte to be sent, then drop SCS
		delayMicroseconds(10);
        // Set P2.4 High for CS
        digitalWrite(_pinChipSelect, LOW);
        // clear request flag
        flagSendToggleVCOMCommand &= ~SHARP_REQUEST_TOGGLE_VCOM;
    }
}

struct OneMsTaskTimer_t timer_task = {1000, SendToggleVCOMCommand, 0, 0};

void LCD_SharpBoosterPack_SPI::TA0_enableVCOMToggle()
{
    // generate Int. each 4096*8*32768Hz = 1 sec
    //
    // Base address for first timer
    //
    OneMsTaskTimer::add(&timer_task);
	OneMsTaskTimer::start();
}

void LCD_SharpBoosterPack_SPI::TA0_turnOff()
{
  OneMsTaskTimer::stop();
}

<|endoftext|>


<commit_before>#pragma once
#include "pin.hpp"

template <unsigned P>
class Led : protected Pin

{
public:

    static constexpr uint8_t pin = P;

    void on()            {Pin
::high();}
    void off()           {Pin
::low();}
    void set(bool value) {Pin
::set(value);}
    bool isOn() const    {return Pin
::isHigh();}
    bool isOff() const   {return Pin
::isLow();}
    bool get() const     {return Pin
::get();}

    Led
& operator=(bool value) { set(value); return *this; }
    bool operator*() { return get(); }

};

template <unsigned P>
class AnalogLed : protected AnalogOutputPin

{
public:

    static constexpr uint8_t pin = P;

    void on(uint8_t brightness)  {AnalogOutputPin
::set(brightness);}
    void off()                   {on(0);}
    void set(uint8_t brightness) {on(brightness);}
    bool isOn() const            {return get() > 0;}
    bool isOff() const           {!isOff();}
    uint8_t get() const          {return AnalogOutputPin
::get();}
    uint8_t brightness() const   {return get();}

    AnalogLed
& operator=(uint8_t brightness) { set(value); return *this; }
    bool operator*() { return get(); }

    AnalogLed
& operator+=(int delta) { set(get()+delta); return *this; }
    AnalogLed
& operator-=(int delta) { set(get()-delta); return *this; }

};

using BuiltinLed = Led<LED_BUILTIN>;
using BuiltinAnalogLed = AnalogLed<LED_BUILTIN>;
<commit_msg>Leds must start off.<commit_after>#pragma once
#include "pin.hpp"

template <unsigned P>
class Led : protected Pin

{
public:

    static constexpr uint8_t pin = P;

    Led() {off();}

    void on()            {Pin
::high();}
    void off()           {Pin
::low();}
    void set(bool value) {Pin
::set(value);}
    bool isOn() const    {return Pin
::isHigh();}
    bool isOff() const   {return Pin
::isLow();}
    bool get() const     {return Pin
::get();}

    Led
& operator=(bool value) { set(value); return *this; }
    bool operator*() { return get(); }

};

template <unsigned P>
class AnalogLed : protected AnalogOutputPin

{
public:

    static constexpr uint8_t pin = P;

    AnalogLed() {off();}

    void on(uint8_t brightness)  {AnalogOutputPin
::set(brightness);}
    void off()                   {on(0);}
    void set(uint8_t brightness) {on(brightness);}
    bool isOn() const            {return get() > 0;}
    bool isOff() const           {!isOff();}
    uint8_t get() const          {return AnalogOutputPin
::get();}
    uint8_t brightness() const   {return get();}

    AnalogLed
& operator=(uint8_t brightness) { set(value); return *this; }
    bool operator*() { return get(); }

    AnalogLed
& operator+=(int delta) { set(get()+delta); return *this; }
    AnalogLed
& operator-=(int delta) { set(get()-delta); return *this; }

};

using BuiltinLed = Led<LED_BUILTIN>;
using BuiltinAnalogLed = AnalogLed<LED_BUILTIN>;
<|endoftext|>


<commit_before>/*
 *
 * Area - Program that ask the user to enter the height and the width of
 *        triangle and print out the the area.
 *
 * Author - Moses Olawoyin <m.bastford@gmail.com
 * Date - 05 March 2015
 */

#include <iostream>

int calc_area( int width, int height)
{
    return (width * height)/2;

}

int main ( int argc, char *argv[])
{
    int width;
    int height;
    int area;

    std::cout <<"Enter the height" << std::endl;
    std::cin >> height;

    std::cout <<"Enter the width"<< std::endl;
    std::cin >> width;

    area = calc_area(width, height);

    std::cout << "The area of the triangle is :"<< area << std::endl;

    return 0;
}
<commit_msg>created function to capture input. closes #67<commit_after>/*
 *
 * Area - Program that ask the user to enter the height and the width of
 *        triangle and print out the the area.
 *
 * Author - Moses Olawoyin <m.bastford@gmail.com
 * Date - 05 March 2015
 */

#include <iostream>

int read_int(std::string prompt)
{
    int value;

    std::cout << prompt << ":";
    std::cin  >> value;

   return value;
}

int calc_area( int width, int height)
{
    return (width * height)/2;

}

int main ( int argc, char *argv[])
{
    int width;
    int height;
    int area;

    width = read_int( "Enter the width");
    height =read_int( "Enter the height");
    area = calc_area(width, height);

    std::cout << "The area of the triangle is :"<< area << std::endl;

    return 0;
}
<|endoftext|>


<commit_before>//----------------------------------------------------------------------------
/// \file  get_tick_count.hpp
//----------------------------------------------------------------------------
/// \brief This file contains implementation of a function that
/// reads CPU ticks.
//----------------------------------------------------------------------------
// Copyright (c) 1993-2009 Douglas C. Schmidt
// Author:  Serge Aleynikov <saleyn@gmail.com>
// Created: 2009-11-16
//----------------------------------------------------------------------------
/*
***** BEGIN LICENSE BLOCK *****

This file may be included in various open-source projects.

Copyright (C) 2009 Serge Aleynikov <saleyn@gmail.com>

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.

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

***** END LICENSE BLOCK *****
*/

#ifndef _UTIL_GET_TICK_COUNT_HPP_
#define _UTIL_GET_TICK_COUNT_HPP_

namespace util {

    typedef unsigned long long hrtime_t;

    typedef union {
        struct {
            unsigned int hi;
            unsigned int lo;
        } l;
        hrtime_t ll;
    } tick_t;

namespace detail {

    // Tick count code for PowerPC (Apple G3, G4, G5)
    #ifdef _CPU_POWERPC
    static inline hrtime_t get_tick_count() {
        tick_t t;
        __asm__ __volatile__ (
        "1:\n\t"
            "mftbu %0\n\t"
            "mftb %1\n\t"
            "mftbu r6\n\t"
            "cmpw r6,%0\n\t"
            "bne 1b"
            : "=r" (t.l.hi), "=r" (t.l.lo)
            :
            : "r6");
        return t.ll;
    }
    #elif (defined(_CPU_IA32) || defined(_CPU_IA64) || defined(__x86_64))
    /* Tick count code for IA-32 architecture (Intel and AMD x86, and 64-bit
     * versions). */
    static inline hrtime_t get_tick_count() {
        tick_t t;
        __asm__ __volatile__ ("rdtsc" : "=a" (t.l.hi), "=d" (t.l.lo));
        return t.ll;
    }
    #elif defined(_CPU_SPARC_V8PLUS)
    // Tick count code for SPARC architecture
    static inline hrtime_t get_tick_count() {
        tick_t t;
        __asm__ __volatile__ ("rd %%tick, %0" : "=r" (t->ll));
        return t.ll;
    }
    #elif defined(_WIN32)
    static inline hrtime_t get_tick_count() {
        tick_t t;
        // Use RDTSC instruction to get clocks count
        __asm push EAX
        __asm push EDX
        __asm __emit 0fh __asm __emit 031h // RDTSC
        __asm mov t.lo, EAX
        __asm mov t.hi, EDX
        __asm pop EDX
        __asm pop EAX
        return t.ll;
    }
    #endif

} // namespace detail
} // namespace util

#endif // _UTIL_GET_TICK_COUNT
<commit_msg>correct ifdef added for i386 arch<commit_after>//----------------------------------------------------------------------------
/// \file  get_tick_count.hpp
//----------------------------------------------------------------------------
/// \brief This file contains implementation of a function that
/// reads CPU ticks.
//----------------------------------------------------------------------------
// Copyright (c) 1993-2009 Douglas C. Schmidt
// Author:  Serge Aleynikov <saleyn@gmail.com>
// Created: 2009-11-16
//----------------------------------------------------------------------------
/*
***** BEGIN LICENSE BLOCK *****

This file may be included in various open-source projects.

Copyright (C) 2009 Serge Aleynikov <saleyn@gmail.com>

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.

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

***** END LICENSE BLOCK *****
*/

#ifndef _UTIL_GET_TICK_COUNT_HPP_
#define _UTIL_GET_TICK_COUNT_HPP_

namespace util {

    typedef unsigned long long hrtime_t;

    typedef union {
        struct {
            unsigned int hi;
            unsigned int lo;
        } l;
        hrtime_t ll;
    } tick_t;

namespace detail {

    // Tick count code for PowerPC (Apple G3, G4, G5)
    #ifdef _CPU_POWERPC
    static inline hrtime_t get_tick_count() {
        tick_t t;
        __asm__ __volatile__ (
        "1:\n\t"
            "mftbu %0\n\t"
            "mftb %1\n\t"
            "mftbu r6\n\t"
            "cmpw r6,%0\n\t"
            "bne 1b"
            : "=r" (t.l.hi), "=r" (t.l.lo)
            :
            : "r6");
        return t.ll;
    }
    #elif (defined(_CPU_IA32) || defined(_CPU_IA64) || defined(__i386__) || defined(__x86_64))
    /* Tick count code for IA-32 architecture (Intel and AMD x86, and 64-bit
     * versions). */
    static inline hrtime_t get_tick_count() {
        tick_t t;
        __asm__ __volatile__ ("rdtsc" : "=a" (t.l.hi), "=d" (t.l.lo));
        return t.ll;
    }
    #elif defined(_CPU_SPARC_V8PLUS)
    // Tick count code for SPARC architecture
    static inline hrtime_t get_tick_count() {
        tick_t t;
        __asm__ __volatile__ ("rd %%tick, %0" : "=r" (t->ll));
        return t.ll;
    }
    #elif defined(_WIN32)
    static inline hrtime_t get_tick_count() {
        tick_t t;
        // Use RDTSC instruction to get clocks count
        __asm push EAX
        __asm push EDX
        __asm __emit 0fh __asm __emit 031h // RDTSC
        __asm mov t.lo, EAX
        __asm mov t.hi, EDX
        __asm pop EDX
        __asm pop EAX
        return t.ll;
    }
    #endif

} // namespace detail
} // namespace util

#endif // _UTIL_GET_TICK_COUNT
<|endoftext|>


<commit_before>/***************************************************************************
**
** Copyright (C) 2013 Jolla Ltd.
** Contact: Robin Burchell <robin.burchell@jollamobile.com>
**
** This file is part of lipstick.
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation
** and appearing in the file LICENSE.LGPL included in the packaging
** of this file.
**
****************************************************************************/

#include "connectionselector.h"

#include <QGuiApplication>
#include "homewindow.h"
#include <QQuickItem>
#include <QQmlContext>
#include <QScreen>
#include <QTimer>
#include "utilities/closeeventeater.h"
#include "connectionselector.h"

ConnectionSelector::ConnectionSelector(QObject *parent) :
    QObject(parent),
    window(new HomeWindow())
{
    QTimer::singleShot(0, this, SLOT(createWindow()));
}

ConnectionSelector::~ConnectionSelector()
{
    delete window;
}

void ConnectionSelector::createWindow()
{
    window->setGeometry(QRect(QPoint(), QGuiApplication::primaryScreen()->size()));
    window->setWindowTitle("Connection");
    window->setContextProperty("connectionSelector", this);
    window->setContextProperty("initialSize", QGuiApplication::primaryScreen()->size());
    window->setSource(QUrl("qrc:/qml/ConnectionSelector.qml"));
    window->installEventFilter(new CloseEventEater(this));
}

void ConnectionSelector::setWindowVisible(bool visible)
{
    if (visible) {
        if (!window->isVisible()) {
            window->showFullScreen();
            emit windowVisibleChanged();
        }
    } else if (window != 0 && window->isVisible()) {
        window->hide();
        emit windowVisibleChanged();
    }
}

bool ConnectionSelector::windowVisible() const
{
    return window != 0 && window->isVisible();
}
<commit_msg>[lipstick] Only create the connection selector window after the compositor has been initialized<commit_after>/***************************************************************************
**
** Copyright (C) 2013 Jolla Ltd.
** Contact: Robin Burchell <robin.burchell@jollamobile.com>
**
** This file is part of lipstick.
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation
** and appearing in the file LICENSE.LGPL included in the packaging
** of this file.
**
****************************************************************************/

#include "connectionselector.h"

#include <QGuiApplication>
#include "homewindow.h"
#include <QQuickItem>
#include <QQmlContext>
#include <QScreen>
#include <QTimer>
#include "utilities/closeeventeater.h"
#include "connectionselector.h"

ConnectionSelector::ConnectionSelector(QObject *parent) :
    QObject(parent),
    window(0)
{
    QTimer::singleShot(0, this, SLOT(createWindow()));
}

ConnectionSelector::~ConnectionSelector()
{
    delete window;
}

void ConnectionSelector::createWindow()
{
    window = new HomeWindow();
    window->setGeometry(QRect(QPoint(), QGuiApplication::primaryScreen()->size()));
    window->setWindowTitle("Connection");
    window->setContextProperty("connectionSelector", this);
    window->setContextProperty("initialSize", QGuiApplication::primaryScreen()->size());
    window->setSource(QUrl("qrc:/qml/ConnectionSelector.qml"));
    window->installEventFilter(new CloseEventEater(this));
}

void ConnectionSelector::setWindowVisible(bool visible)
{
    if (visible) {
        if (!window->isVisible()) {
            window->showFullScreen();
            emit windowVisibleChanged();
        }
    } else if (window != 0 && window->isVisible()) {
        window->hide();
        emit windowVisibleChanged();
    }
}

bool ConnectionSelector::windowVisible() const
{
    return window != 0 && window->isVisible();
}
<|endoftext|>


<commit_before>#include "dsa_common.h"

#include "subscribe_response_message.h"

#include "util/date_time.h"

namespace dsa {
SubscribeResponseMessage::SubscribeResponseMessage(const uint8_t* data,
                                                   size_t size)
    : ResponseMessage(data, size) {
  parse_dynamic_data(data + StaticHeaders::TOTAL_SIZE,
                     static_headers.header_size - StaticHeaders::TOTAL_SIZE,
                     size - static_headers.header_size);
}

SubscribeResponseMessage::SubscribeResponseMessage()
    : ResponseMessage(MessageType::SUBSCRIBE_RESPONSE) {}

SubscribeResponseMessage::SubscribeResponseMessage(Var&& value)
    : ResponseMessage(MessageType::SUBSCRIBE_RESPONSE) {
  set_value(MessageValue(std::move(value), DateTime::get_ts()));
}

MessageValue SubscribeResponseMessage::get_value() const {
  return MessageValue(body->data(), body->size());
}
void SubscribeResponseMessage::set_value(MessageValue&& value) {
  body = value.to_msgpack();

  // invalidate message_size
  static_headers.message_size = 0;
}

void SubscribeResponseMessage::print_body(std::ostream& os) const {
  if (body->size() > 0) {
    if (body->size() < 256) {
      MessageValue value = get_value();
      if (value.meta.is_map()) {
        os << " META: " << value.meta.to_json();
      }
      os << " VALUE: " << value.value.to_json();
    } else {
      os << " BODY SIZE: " << body->size();
    }
  }
}

}  // namespace dsa
<commit_msg>fix print message of SubscribeResponseMessage<commit_after>#include "dsa_common.h"

#include "subscribe_response_message.h"

#include "util/date_time.h"

namespace dsa {
SubscribeResponseMessage::SubscribeResponseMessage(const uint8_t* data,
                                                   size_t size)
    : ResponseMessage(data, size) {
  parse_dynamic_data(data + StaticHeaders::TOTAL_SIZE,
                     static_headers.header_size - StaticHeaders::TOTAL_SIZE,
                     size - static_headers.header_size);
}

SubscribeResponseMessage::SubscribeResponseMessage()
    : ResponseMessage(MessageType::SUBSCRIBE_RESPONSE) {}

SubscribeResponseMessage::SubscribeResponseMessage(Var&& value)
    : ResponseMessage(MessageType::SUBSCRIBE_RESPONSE) {
  set_value(MessageValue(std::move(value), DateTime::get_ts()));
}

MessageValue SubscribeResponseMessage::get_value() const {
  return MessageValue(body->data(), body->size());
}
void SubscribeResponseMessage::set_value(MessageValue&& value) {
  body = value.to_msgpack();

  // invalidate message_size
  static_headers.message_size = 0;
}

void SubscribeResponseMessage::print_body(std::ostream& os) const {
  if (body != nullptr && body->size() > 0) {
    if (body->size() < 256) {
      MessageValue value = get_value();
      if (value.meta.is_map()) {
        os << " META: " << value.meta.to_json();
      }
      os << " VALUE: " << value.value.to_json();
    } else {
      os << " BODY SIZE: " << body->size();
    }
  }
}

}  // namespace dsa
<|endoftext|>