<commit_before>#include "replayState.h"

#include <deque>
#include <boost/bind.hpp>
#include <boost/thread.hpp>

#include "libwatcher/message.h"
#include "serverConnection.h"
#include "Assert.h"
#include "database.h"
#include "watcherd.h"

using namespace util;
using namespace watcher;
using namespace watcher::event;

//< default value for number of events to prefetch from the database
const unsigned int DEFAULT_BUFFER_SIZE = 10U; /* db rows */
const unsigned int DEFAULT_STEP = 250U /* ms */;

/** Internal structure used for implementing the class.  Used to avoid
 * dependencies for the user of the class.  These would normally be private
 * members of ReplayState.
 */
struct ReplayState::impl {
    boost::weak_ptr<ServerConnection> conn;
    std::deque<MessagePtr> events;
    boost::asio::deadline_timer timer;
    Timestamp ts; // the current effective time
    Timestamp last_event; // timestamp of last event retrieved from db
    float speed; //< playback speed
    unsigned int bufsiz; //< number of database rows to prefetch
    Timestamp step;
    enum run_state { paused, running } state;

    /*
     * Lock used for event queue.  This is required due to the seek() member
     * function, which can be called from a different thread.
     */
    boost::mutex lock;

    impl(ServerConnectionPtr& ptr) :
        conn(ptr), timer(ptr->io_service()), ts(0), last_event(0), bufsiz(DEFAULT_BUFFER_SIZE),
        step(DEFAULT_STEP), state(paused)
    {
        TRACE_ENTER();
        TRACE_EXIT();
    }
};

ReplayState::ReplayState(ServerConnectionPtr ptr, Timestamp t, float playback_speed) :
    impl_(new impl(ptr))
{
    TRACE_ENTER();
    Assert<Bad_arg>(t >= 0);
    impl_->ts = t;
    impl_->last_event = t;

    speed(playback_speed);
    TRACE_EXIT();
}

Timestamp ReplayState::tell() const
{
    TRACE_ENTER();
    TRACE_EXIT_RET(impl_->ts);
    return impl_->ts;
}

ReplayState& ReplayState::pause()
{
    TRACE_ENTER();
    LOG_DEBUG("cancelling timer");
    impl_->timer.cancel();
    impl_->state = impl::paused;
    TRACE_EXIT();
    return *this;
}

ReplayState& ReplayState::seek(Timestamp t)
{
    TRACE_ENTER();

    impl::run_state oldstate;
    {
        boost::mutex::scoped_lock L(impl_->lock);
        oldstate = impl_->state;
        pause();
        impl_->events.clear();
        impl_->ts = t;
        if (t == -1)
            impl_->last_event = std::numeric_limits<Timestamp>::max();
        else
            impl_->last_event = t;
    }
    if (oldstate == impl::running)
        run();
    TRACE_EXIT();
    return *this;
}

ReplayState& ReplayState::speed(float f)
{
    TRACE_ENTER();
    Assert<Bad_arg>(f != 0);
    /* If speed changes direction, need to clear the event list.
     * Check for sign change by noting that positive*negative==negative
     */
    if (impl_->speed * f < 0) {
        impl::run_state oldstate;
        {
            boost::mutex::scoped_lock L(impl_->lock);

            oldstate = impl_->state;
            pause();

            impl_->events.clear();

            /*
             * Avoid setting .last_event when SpeedMessage is received
             * prior to the first StartMessage.
             */
            if (impl_->ts != 0 && impl_->ts != -1)
                impl_->last_event = impl_->ts;

            impl_->speed = f;
        }
        if (oldstate == impl::running)
            run();
    } else
        impl_->speed = f;
    LOG_DEBUG("ts=" << impl_->ts << " last_event=" << impl_->last_event);
    TRACE_EXIT();
    return *this;
}

ReplayState& ReplayState::buffer_size(unsigned int n)
{
    TRACE_ENTER();
    Assert<Bad_arg>(n != 0);
    impl_->bufsiz = n;
    TRACE_EXIT();
    return *this;
}

ReplayState& ReplayState::time_step(unsigned int n)
{
    TRACE_ENTER();
    Assert<Bad_arg>(n != 0);
    impl_->step = n;
    TRACE_EXIT();
    return *this;
}

/* function object for accepting events output from Database::getEvents() */
struct event_output {
    std::deque<MessagePtr>& q;
    event_output(std::deque<MessagePtr>& qq) : q(qq) {}
    void operator() (MessagePtr m) { q.push_back(m); }
};

/** Schedule an asynchronous task to replay events from the database to a GUI
 * client.  If the local cache of upcoming events is empty, prefetch a block of
 * events from the database.
 *
 * The code is written such that it will work when playing events forward or in
 * reverse.
 */
void ReplayState::run()
{
    TRACE_ENTER();
    boost::mutex::scoped_lock L(impl_->lock);

    if (impl_->events.empty()) {
        // queue is empty, pre-fetch more items from the DB

        boost::function<void(MessagePtr)> cb(event_output(impl_->events));
        LOG_DEBUG("fetching events " << (impl_->speed > 0 ? "> " : "< ") << impl_->last_event);
        get_db_handle().getEvents(cb,
                                  impl_->last_event,
                                  (impl_->speed >= 0) ? Database::forward : Database::reverse,
                                  impl_->bufsiz);

        if (!impl_->events.empty()) {
            /* When starting to replay, assume that time T=0 is the time of the
             * first event in the stream.
             * T= -1 is EOF.
             * Convert to timestamp of first item in the returned events.
             *
             * When playing in reverse, the first item in the list is the last event in the database.
             */
            if (impl_->ts == 0 || impl_->ts == -1)
                impl_->ts = impl_->events.front()->timestamp;

            // save timestamp of last event retrieved to avoid duplication
            impl_->last_event = impl_->events.back()->timestamp;
        }
    }

    if (! impl_->events.empty()) {
        // time until next event
        Timestamp delta = impl_->events.front()->timestamp - impl_->ts;
        LOG_DEBUG("Next event in " << delta << " ms");

        // update our notion of the current time after the timer expires
        impl_->ts = impl_->events.front()->timestamp;

        /* Adjust for playback speed.  Note that when playing events in reverse, both speed
         * delta will be negative, which will turn delta into a positive value for the
         * async_wait() call, which is exactly what is required.  */
        delta /= impl_->speed;

        impl_->timer.expires_from_now(boost::posix_time::millisec(delta));
        impl_->timer.async_wait(boost::bind(&ReplayState::timer_handler, shared_from_this(), boost::asio::placeholders::error));
        impl_->state = impl::running;
    } else {
        /*
         * FIXME what should happen when the end of the event stream is reached?
         * One option would be to convert to live stream at this point.
         */
        impl_->state = impl::paused;
    }
    TRACE_EXIT();
}

/** Replay events to a GUI client when a timer expires.
 *
 * The run() member function is reponsible for prefetching events from the
 * database and storing them in the class object.  When a timer expires, run
 * through the locally stored events and send those that occurred within the
 * last time slice.  The task is then rescheduled when the next most recent
 * event needs to be transmitted.
 */
void ReplayState::timer_handler(const boost::system::error_code& ec)
{
    TRACE_ENTER();
    if (ec == boost::asio::error::operation_aborted)
        LOG_DEBUG("timer was cancelled");
    else if (impl_->state == impl::paused) {
        LOG_DEBUG("timer expired but state is paused!");
    } else {
        std::vector<MessagePtr> msgs;
        {
            boost::mutex::scoped_lock L(impl_->lock);

            while (! impl_->events.empty()) {
                MessagePtr m = impl_->events.front();
                /* Replay all events in the current time step.  Use the absolute value
                 * of the difference in order for forward and reverse replay to work
                 * properly. */
                if (abs(m->timestamp - impl_->ts) >= impl_->step)
                    break;
                msgs.push_back(m);
                impl_->events.pop_front();
            }
        }

        ServerConnectionPtr srv = impl_->conn.lock();
        if (srv) { /* connection is still alive */
            srv->sendMessage(msgs);
            run(); // reschedule this task
        }
    }
    TRACE_EXIT();
}

/* This is required to be defined, otherwise a the default dtor will cause a
 * compiler error due to use of scoped_ptr with an incomplete type.
 */
ReplayState::~ReplayState()
{
    TRACE_ENTER();
    TRACE_EXIT();
}

float ReplayState::speed() const
{
    return impl_->speed;
}
<commit_msg>add debug message when last row of db is fetched<commit_after>#include "replayState.h"

#include <deque>
#include <boost/bind.hpp>
#include <boost/thread.hpp>

#include "libwatcher/message.h"
#include "serverConnection.h"
#include "Assert.h"
#include "database.h"
#include "watcherd.h"

using namespace util;
using namespace watcher;
using namespace watcher::event;

//< default value for number of events to prefetch from the database
const unsigned int DEFAULT_BUFFER_SIZE = 10U; /* db rows */
const unsigned int DEFAULT_STEP = 250U /* ms */;

/** Internal structure used for implementing the class.  Used to avoid
 * dependencies for the user of the class.  These would normally be private
 * members of ReplayState.
 */
struct ReplayState::impl {
    boost::weak_ptr<ServerConnection> conn;
    std::deque<MessagePtr> events;
    boost::asio::deadline_timer timer;
    Timestamp ts; // the current effective time
    Timestamp last_event; // timestamp of last event retrieved from db
    float speed; //< playback speed
    unsigned int bufsiz; //< number of database rows to prefetch
    Timestamp step;
    enum run_state { paused, running } state;

    /*
     * Lock used for event queue.  This is required due to the seek() member
     * function, which can be called from a different thread.
     */
    boost::mutex lock;

    impl(ServerConnectionPtr& ptr) :
        conn(ptr), timer(ptr->io_service()), ts(0), last_event(0), bufsiz(DEFAULT_BUFFER_SIZE),
        step(DEFAULT_STEP), state(paused)
    {
        TRACE_ENTER();
        TRACE_EXIT();
    }
};

ReplayState::ReplayState(ServerConnectionPtr ptr, Timestamp t, float playback_speed) :
    impl_(new impl(ptr))
{
    TRACE_ENTER();
    Assert<Bad_arg>(t >= 0);
    impl_->ts = t;
    impl_->last_event = t;

    speed(playback_speed);
    TRACE_EXIT();
}

Timestamp ReplayState::tell() const
{
    TRACE_ENTER();
    TRACE_EXIT_RET(impl_->ts);
    return impl_->ts;
}

ReplayState& ReplayState::pause()
{
    TRACE_ENTER();
    LOG_DEBUG("cancelling timer");
    impl_->timer.cancel();
    impl_->state = impl::paused;
    TRACE_EXIT();
    return *this;
}

ReplayState& ReplayState::seek(Timestamp t)
{
    TRACE_ENTER();

    impl::run_state oldstate;
    {
        boost::mutex::scoped_lock L(impl_->lock);
        oldstate = impl_->state;
        pause();
        impl_->events.clear();
        impl_->ts = t;
        if (t == -1)
            impl_->last_event = std::numeric_limits<Timestamp>::max();
        else
            impl_->last_event = t;
    }
    if (oldstate == impl::running)
        run();
    TRACE_EXIT();
    return *this;
}

ReplayState& ReplayState::speed(float f)
{
    TRACE_ENTER();
    Assert<Bad_arg>(f != 0);
    /* If speed changes direction, need to clear the event list.
     * Check for sign change by noting that positive*negative==negative
     */
    if (impl_->speed * f < 0) {
        impl::run_state oldstate;
        {
            boost::mutex::scoped_lock L(impl_->lock);

            oldstate = impl_->state;
            pause();

            impl_->events.clear();

            /*
             * Avoid setting .last_event when SpeedMessage is received
             * prior to the first StartMessage.
             */
            if (impl_->ts != 0 && impl_->ts != -1)
                impl_->last_event = impl_->ts;

            impl_->speed = f;
        }
        if (oldstate == impl::running)
            run();
    } else
        impl_->speed = f;
    LOG_DEBUG("ts=" << impl_->ts << " last_event=" << impl_->last_event);
    TRACE_EXIT();
    return *this;
}

ReplayState& ReplayState::buffer_size(unsigned int n)
{
    TRACE_ENTER();
    Assert<Bad_arg>(n != 0);
    impl_->bufsiz = n;
    TRACE_EXIT();
    return *this;
}

ReplayState& ReplayState::time_step(unsigned int n)
{
    TRACE_ENTER();
    Assert<Bad_arg>(n != 0);
    impl_->step = n;
    TRACE_EXIT();
    return *this;
}

/* function object for accepting events output from Database::getEvents() */
struct event_output {
    std::deque<MessagePtr>& q;
    event_output(std::deque<MessagePtr>& qq) : q(qq) {}
    void operator() (MessagePtr m) { q.push_back(m); }
};

/** Schedule an asynchronous task to replay events from the database to a GUI
 * client.  If the local cache of upcoming events is empty, prefetch a block of
 * events from the database.
 *
 * The code is written such that it will work when playing events forward or in
 * reverse.
 */
void ReplayState::run()
{
    TRACE_ENTER();
    boost::mutex::scoped_lock L(impl_->lock);

    if (impl_->events.empty()) {
        // queue is empty, pre-fetch more items from the DB

        boost::function<void(MessagePtr)> cb(event_output(impl_->events));
        LOG_DEBUG("fetching events " << (impl_->speed > 0 ? "> " : "< ") << impl_->last_event);
        get_db_handle().getEvents(cb,
                                  impl_->last_event,
                                  (impl_->speed >= 0) ? Database::forward : Database::reverse,
                                  impl_->bufsiz);

        if (!impl_->events.empty()) {
            /* When starting to replay, assume that time T=0 is the time of the
             * first event in the stream.
             * T= -1 is EOF.
             * Convert to timestamp of first item in the returned events.
             *
             * When playing in reverse, the first item in the list is the last event in the database.
             */
            if (impl_->ts == 0 || impl_->ts == -1)
                impl_->ts = impl_->events.front()->timestamp;

            // save timestamp of last event retrieved to avoid duplication
            impl_->last_event = impl_->events.back()->timestamp;
        }
    }

    if (! impl_->events.empty()) {
        // time until next event
        Timestamp delta = impl_->events.front()->timestamp - impl_->ts;
        LOG_DEBUG("Next event in " << delta << " ms");

        // update our notion of the current time after the timer expires
        impl_->ts = impl_->events.front()->timestamp;

        /* Adjust for playback speed.  Note that when playing events in reverse, both speed
         * delta will be negative, which will turn delta into a positive value for the
         * async_wait() call, which is exactly what is required.  */
        delta /= impl_->speed;

        impl_->timer.expires_from_now(boost::posix_time::millisec(delta));
        impl_->timer.async_wait(boost::bind(&ReplayState::timer_handler, shared_from_this(), boost::asio::placeholders::error));
        impl_->state = impl::running;
    } else {
        /*
         * FIXME what should happen when the end of the event stream is reached?
         * One option would be to convert to live stream at this point.
         */
        LOG_DEBUG("reached end of database, pausing playback");
        impl_->state = impl::paused;
    }
    TRACE_EXIT();
}

/** Replay events to a GUI client when a timer expires.
 *
 * The run() member function is reponsible for prefetching events from the
 * database and storing them in the class object.  When a timer expires, run
 * through the locally stored events and send those that occurred within the
 * last time slice.  The task is then rescheduled when the next most recent
 * event needs to be transmitted.
 */
void ReplayState::timer_handler(const boost::system::error_code& ec)
{
    TRACE_ENTER();
    if (ec == boost::asio::error::operation_aborted)
        LOG_DEBUG("timer was cancelled");
    else if (impl_->state == impl::paused) {
        LOG_DEBUG("timer expired but state is paused!");
    } else {
        std::vector<MessagePtr> msgs;
        {
            boost::mutex::scoped_lock L(impl_->lock);

            while (! impl_->events.empty()) {
                MessagePtr m = impl_->events.front();
                /* Replay all events in the current time step.  Use the absolute value
                 * of the difference in order for forward and reverse replay to work
                 * properly. */
                if (abs(m->timestamp - impl_->ts) >= impl_->step)
                    break;
                msgs.push_back(m);
                impl_->events.pop_front();
            }
        }

        ServerConnectionPtr srv = impl_->conn.lock();
        if (srv) { /* connection is still alive */
            srv->sendMessage(msgs);
            run(); // reschedule this task
        }
    }
    TRACE_EXIT();
}

/* This is required to be defined, otherwise a the default dtor will cause a
 * compiler error due to use of scoped_ptr with an incomplete type.
 */
ReplayState::~ReplayState()
{
    TRACE_ENTER();
    TRACE_EXIT();
}

float ReplayState::speed() const
{
    return impl_->speed;
}
<|endoftext|>


<commit_before>// Copyright (c) 2013 Plenluno All rights reserved.

#include <gtest/gtest.h>
#include <libnode/node.h>
#include <libnode/message_queue.h>

#include <libj/status.h>
#include <libj/thread.h>
#include <libj/console.h>

namespace libj {
namespace node {

class GTestMsgQueueOnMessage : LIBJ_JS_FUNCTION(GTestMsgQueueOnMessage)
 public:
    GTestMsgQueueOnMessage(
        MessageQueue::Ptr mq,
        UInt numPost)
        : count_(0)
        , numPost_(numPost)
        , msgQueue_(mq) {}

    UInt count() { return count_; }

    virtual Value operator()(JsArray::Ptr args) {
        console::log(args->get(0));
        count_++;
        if (count_ >= numPost_) msgQueue_->stop();
        return Status::OK;
    }

 private:
    UInt count_;
    UInt numPost_;
    MessageQueue::Ptr msgQueue_;
};

class GTestMsgQueueNodeRun : LIBJ_JS_FUNCTION(GTestMsgQueueNodeRun)
 public:
    virtual Value operator()(JsArray::Ptr args) {
        node::run();
        return Status::OK;
    }
};

class GTestMsgQueuePostMessage : LIBJ_JS_FUNCTION(GTestMsgQueuePostMessage)
 public:
    GTestMsgQueuePostMessage(
        MessageQueue::Ptr mq,
        UInt numPost)
        : numPost_(numPost)
        , msgQueue_(mq) {}

    virtual Value operator()(JsArray::Ptr args) {
        for (UInt i = 0; i < numPost_; i++) {
            msgQueue_->postMessage(i);
        }
        return Status::OK;
    }

 private:
    UInt numPost_;
    MessageQueue::Ptr msgQueue_;
};

static const UInt NUM_POSTS = 7;
static const UInt NUM_THREADS = 5;

TEST(GTestMessageQueue, TestPostMessageSameThread) {
    MessageQueue::Ptr mq = MessageQueue::create();
    mq->start();

    GTestMsgQueueOnMessage::Ptr onMessage(
        new GTestMsgQueueOnMessage(mq, NUM_POSTS));
    mq->on(MessageQueue::EVENT_MESSAGE, onMessage);

    for (UInt i = 0; i < NUM_POSTS; i++) {
        mq->postMessage(String::create("msg"));
    }

    node::run();

    ASSERT_EQ(NUM_POSTS, onMessage->count());
}

TEST(GTestMessageQueue, TestPostMessageMultiThread) {
    MessageQueue::Ptr mq = MessageQueue::create();
    mq->start();

    GTestMsgQueueOnMessage::Ptr onMessage(
        new GTestMsgQueueOnMessage(mq, NUM_POSTS * NUM_THREADS));
    mq->on(MessageQueue::EVENT_MESSAGE, onMessage);

    Thread::Ptr nodeRun(Thread::create(
        Function::Ptr(new GTestMsgQueueNodeRun())));

    JsArray::Ptr threads = JsArray::create();
    for (Size i = 0; i < NUM_THREADS; i++) {
        threads->add(Thread::create(
            Function::Ptr(new GTestMsgQueuePostMessage(mq, NUM_POSTS))));
    }

    nodeRun->start();

    for (Size i = 0; i < NUM_THREADS; i++) {
        threads->getPtr<Thread>(i)->start();
    }

    nodeRun->join();

    for (Size i = 0; i < NUM_THREADS; i++) {
        threads->getPtr<Thread>(i)->join();
    }

    ASSERT_EQ(NUM_POSTS * NUM_THREADS, onMessage->count());
}

}  // namespace node
}  // namespace libj
<commit_msg>fix memory leaks<commit_after>// Copyright (c) 2013 Plenluno All rights reserved.

#include <gtest/gtest.h>
#include <libnode/node.h>
#include <libnode/message_queue.h>

#include <libj/status.h>
#include <libj/thread.h>

namespace libj {
namespace node {

class GTestMsgQueueOnMessage : LIBJ_JS_FUNCTION(GTestMsgQueueOnMessage)
 public:
    GTestMsgQueueOnMessage(
        MessageQueue::Ptr mq,
        UInt numPost)
        : count_(0)
        , numPost_(numPost)
        , msgQueue_(mq) {}

    UInt count() { return count_; }

    virtual Value operator()(JsArray::Ptr args) {
        count_++;
        if (count_ >= numPost_) {
            msgQueue_->stop();
            msgQueue_ = MessageQueue::null();
        }
        return Status::OK;
    }

 private:
    UInt count_;
    UInt numPost_;
    MessageQueue::Ptr msgQueue_;
};

class GTestMsgQueueNodeRun : LIBJ_JS_FUNCTION(GTestMsgQueueNodeRun)
 public:
    virtual Value operator()(JsArray::Ptr args) {
        node::run();
        return Status::OK;
    }
};

class GTestMsgQueuePostMessage : LIBJ_JS_FUNCTION(GTestMsgQueuePostMessage)
 public:
    GTestMsgQueuePostMessage(
        MessageQueue::Ptr mq,
        UInt numPost)
        : numPost_(numPost)
        , msgQueue_(mq) {}

    virtual Value operator()(JsArray::Ptr args) {
        for (UInt i = 0; i < numPost_; i++) {
            msgQueue_->postMessage(i);
        }
        return Status::OK;
    }

 private:
    UInt numPost_;
    MessageQueue::Ptr msgQueue_;
};

static const UInt NUM_POSTS = 7;
static const UInt NUM_THREADS = 5;

TEST(GTestMessageQueue, TestPostMessageSameThread) {
    MessageQueue::Ptr mq = MessageQueue::create();
    mq->start();

    GTestMsgQueueOnMessage::Ptr onMessage(
        new GTestMsgQueueOnMessage(mq, NUM_POSTS));
    mq->on(MessageQueue::EVENT_MESSAGE, onMessage);

    for (UInt i = 0; i < NUM_POSTS; i++) {
        mq->postMessage(String::create("msg"));
    }

    node::run();

    ASSERT_EQ(NUM_POSTS, onMessage->count());
}

TEST(GTestMessageQueue, TestPostMessageMultiThread) {
    MessageQueue::Ptr mq = MessageQueue::create();
    mq->start();

    GTestMsgQueueOnMessage::Ptr onMessage(
        new GTestMsgQueueOnMessage(mq, NUM_POSTS * NUM_THREADS));
    mq->on(MessageQueue::EVENT_MESSAGE, onMessage);

    Thread::Ptr nodeRun(Thread::create(
        Function::Ptr(new GTestMsgQueueNodeRun())));

    JsArray::Ptr threads = JsArray::create();
    for (Size i = 0; i < NUM_THREADS; i++) {
        threads->add(Thread::create(
            Function::Ptr(new GTestMsgQueuePostMessage(mq, NUM_POSTS))));
    }

    nodeRun->start();

    for (Size i = 0; i < NUM_THREADS; i++) {
        threads->getPtr<Thread>(i)->start();
    }

    nodeRun->join();

    for (Size i = 0; i < NUM_THREADS; i++) {
        threads->getPtr<Thread>(i)->join();
    }

    ASSERT_EQ(NUM_POSTS * NUM_THREADS, onMessage->count());
}

}  // namespace node
}  // namespace libj
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: embeddoc.hxx,v $
 *
 *  $Revision: 1.11 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 18:55:53 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    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.
 *
 *    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
 *
 ************************************************************************/

#ifndef _EMBEDDOC_HXX_
#define _EMBEDDOC_HXX_
#if defined(_MSC_VER) && (_MSC_VER >= 1300)
#undef _DEBUG
#endif

#include "common.h"
#include <oleidl.h>

#include <hash_map>

#ifndef _COM_SUN_STAR_UNO_REFERENCE_H_
#include <com/sun/star/uno/Reference.h>
#endif
#ifndef _COM_SUN_STAR_UNO_SEQUENCE_H_
#include <com/sun/star/uno/SEQUENCE.h>
#endif

#include "docholder.hxx"

typedef ::std::hash_map< DWORD, IAdviseSink* > AdviseSinkHashMap;
typedef ::std::hash_map< DWORD, IAdviseSink* >::iterator AdviseSinkHashMapIterator;

class GDIMetaFile;
class CIIAObj;

class EmbedDocument_Impl
    : public IPersistStorage,
      public IDataObject,
      public IOleObject,
      public IOleInPlaceObject,
      public IPersistFile,
      public IDispatch
{
protected:
    ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >
                fillArgsForLoading_Impl( ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > xStream,
                                         DWORD nStreamMode,
                                         LPCOLESTR pFilePath = NULL );
    ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >
                fillArgsForStoring_Impl( ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream > xStream );

    HRESULT SaveTo_Impl( IStorage* pStg );

    sal_uInt64 getMetaFileHandle_Impl( sal_Bool isEnhMeta );

public:
    EmbedDocument_Impl( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& smgr,
                        const GUID* guid );
    ~EmbedDocument_Impl();

    /* IUnknown methods */
    STDMETHOD(QueryInterface)(REFIID riid, LPVOID FAR * ppvObj);
    STDMETHOD_(ULONG, AddRef)();
    STDMETHOD_(ULONG, Release)();

    /* IPersistMethod */
    STDMETHOD(GetClassID)(CLSID *pClassID);

    /* IPersistStorage methods */
    STDMETHOD(IsDirty) ();
    STDMETHOD(InitNew) ( IStorage *pStg );
    STDMETHOD(Load) ( IStorage* pStr );
    STDMETHOD(Save) ( IStorage *pStgSave, BOOL fSameAsLoad );
    STDMETHOD(SaveCompleted) ( IStorage *pStgNew );
    STDMETHOD(HandsOffStorage) (void);

    /* IDataObject methods */
    STDMETHOD(GetData) ( FORMATETC * pFormatetc, STGMEDIUM * pMedium );
    STDMETHOD(GetDataHere) ( FORMATETC * pFormatetc, STGMEDIUM * pMedium );
    STDMETHOD(QueryGetData) ( FORMATETC * pFormatetc );
    STDMETHOD(GetCanonicalFormatEtc) ( FORMATETC * pFormatetcIn, FORMATETC * pFormatetcOut );
    STDMETHOD(SetData) ( FORMATETC * pFormatetc, STGMEDIUM * pMedium, BOOL fRelease );
    STDMETHOD(EnumFormatEtc) ( DWORD dwDirection, IEnumFORMATETC ** ppFormatetc );
    STDMETHOD(DAdvise) ( FORMATETC * pFormatetc, DWORD advf, IAdviseSink * pAdvSink, DWORD * pdwConnection );
    STDMETHOD(DUnadvise) ( DWORD dwConnection );
    STDMETHOD(EnumDAdvise) ( IEnumSTATDATA ** ppenumAdvise );

    /* IOleObject methods */
    STDMETHOD(SetClientSite) ( IOleClientSite* pSite );
    STDMETHOD(GetClientSite) ( IOleClientSite** pSite );
    STDMETHOD(SetHostNames) ( LPCOLESTR szContainerApp, LPCOLESTR szContainerObj );
    STDMETHOD(Close) ( DWORD dwSaveOption);
    STDMETHOD(SetMoniker) ( DWORD dwWhichMoniker, IMoniker *pmk );
    STDMETHOD(GetMoniker) ( DWORD dwAssign, DWORD dwWhichMoniker, IMoniker **ppmk );
    STDMETHOD(InitFromData) ( IDataObject *pDataObject, BOOL fCreation, DWORD dwReserved );
    STDMETHOD(GetClipboardData) ( DWORD dwReserved, IDataObject **ppDataObject );
    STDMETHOD(DoVerb) ( LONG iVerb, LPMSG lpmsg, IOleClientSite *pActiveSite, LONG lindex, HWND hwndParent, LPCRECT lprcPosRect );
    STDMETHOD(EnumVerbs) ( IEnumOLEVERB **ppEnumOleVerb );
    STDMETHOD(Update) ();
    STDMETHOD(IsUpToDate) ();
    STDMETHOD(GetUserClassID) ( CLSID *pClsid );
    STDMETHOD(GetUserType) ( DWORD dwFormOfType, LPOLESTR *pszUserType );
    STDMETHOD(SetExtent) ( DWORD dwDrawAspect, SIZEL *psizel );
    STDMETHOD(GetExtent) ( DWORD dwDrawAspect, SIZEL *psizel );
    STDMETHOD(Advise) ( IAdviseSink *pAdvSink, DWORD *pdwConnection );
    STDMETHOD(Unadvise) ( DWORD dwConnection );
    STDMETHOD(EnumAdvise) ( IEnumSTATDATA **ppenumAdvise );
    STDMETHOD(GetMiscStatus) ( DWORD dwAspect, DWORD *pdwStatus );
    STDMETHOD(SetColorScheme) ( LOGPALETTE *pLogpal );

    /* IOleInPlaceObject methods */
    STDMETHOD(GetWindow)(HWND *);
    STDMETHOD(ContextSensitiveHelp)(BOOL);
    STDMETHOD(InPlaceDeactivate)();
    STDMETHOD(UIDeactivate)();
    STDMETHOD(SetObjectRects)(LPCRECT, LPCRECT);
    STDMETHOD(ReactivateAndUndo)();

    /* IPersistFile methods */
    STDMETHOD(Load) ( LPCOLESTR pszFileName, DWORD dwMode );
    STDMETHOD(Save) ( LPCOLESTR pszFileName, BOOL fRemember );
    STDMETHOD(SaveCompleted) ( LPCOLESTR pszFileName );
    STDMETHOD(GetCurFile) ( LPOLESTR *ppszFileName );

    /* IDispatch methods */
    STDMETHOD(GetTypeInfoCount) ( unsigned int FAR*  pctinfo );
    STDMETHOD(GetTypeInfo) ( unsigned int iTInfo, LCID lcid, ITypeInfo FAR* FAR* ppTInfo );
    STDMETHOD(GetIDsOfNames) ( REFIID riid, OLECHAR FAR* FAR* rgszNames, unsigned int cNames, LCID lcid, DISPID FAR* rgDispId );
    STDMETHOD(Invoke) ( DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS FAR* pDispParams, VARIANT FAR* pVarResult, EXCEPINFO FAR* pExcepInfo, unsigned int FAR* puArgErr );

    // c++ - methods

    void notify();
    HRESULT SaveObject();
    HRESULT ShowObject();
    GUID GetGUID() const { return m_guid; }

protected:
    oslInterlockedCount                 m_refCount;

    ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_xFactory;

    DocumentHolder*                     m_pDocHolder;
    ::rtl::OUString                     m_aFileName;

    CComPtr< IStorage >                 m_pMasterStorage;
    CComPtr< IStream >                  m_pOwnStream;
    CComPtr< IStream >                  m_pExtStream;
    GUID                                m_guid;

    sal_Bool                            m_bIsDirty;

    CComPtr< IOleClientSite >           m_pClientSite;
    CComPtr< IDataAdviseHolder >        m_pDAdviseHolder;

    AdviseSinkHashMap                   m_aAdviseHashMap;
    DWORD                               m_nAdviseNum;
};

#endif //_EMBEDDOC_HXX_

<commit_msg>INTEGRATION: CWS rtfpp2 (1.11.12); FILE MERGED 2006/02/06 16:30:48 mba 1.11.12.1: #128676#: superfluous notification of DataChanged after saving<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: embeddoc.hxx,v $
 *
 *  $Revision: 1.12 $
 *
 *  last change: $Author: rt $ $Date: 2006-02-09 13:37:27 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    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.
 *
 *    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
 *
 ************************************************************************/

#ifndef _EMBEDDOC_HXX_
#define _EMBEDDOC_HXX_
#if defined(_MSC_VER) && (_MSC_VER >= 1300)
#undef _DEBUG
#endif

#include "common.h"
#include <oleidl.h>

#include <hash_map>

#ifndef _COM_SUN_STAR_UNO_REFERENCE_H_
#include <com/sun/star/uno/Reference.h>
#endif
#ifndef _COM_SUN_STAR_UNO_SEQUENCE_H_
#include <com/sun/star/uno/SEQUENCE.h>
#endif

#include "docholder.hxx"

typedef ::std::hash_map< DWORD, IAdviseSink* > AdviseSinkHashMap;
typedef ::std::hash_map< DWORD, IAdviseSink* >::iterator AdviseSinkHashMapIterator;

class GDIMetaFile;
class CIIAObj;

class EmbedDocument_Impl
    : public IPersistStorage,
      public IDataObject,
      public IOleObject,
      public IOleInPlaceObject,
      public IPersistFile,
      public IDispatch
{
protected:
    ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >
                fillArgsForLoading_Impl( ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > xStream,
                                         DWORD nStreamMode,
                                         LPCOLESTR pFilePath = NULL );
    ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >
                fillArgsForStoring_Impl( ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream > xStream );

    HRESULT SaveTo_Impl( IStorage* pStg );

    sal_uInt64 getMetaFileHandle_Impl( sal_Bool isEnhMeta );

public:
    EmbedDocument_Impl( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& smgr,
                        const GUID* guid );
    ~EmbedDocument_Impl();

    /* IUnknown methods */
    STDMETHOD(QueryInterface)(REFIID riid, LPVOID FAR * ppvObj);
    STDMETHOD_(ULONG, AddRef)();
    STDMETHOD_(ULONG, Release)();

    /* IPersistMethod */
    STDMETHOD(GetClassID)(CLSID *pClassID);

    /* IPersistStorage methods */
    STDMETHOD(IsDirty) ();
    STDMETHOD(InitNew) ( IStorage *pStg );
    STDMETHOD(Load) ( IStorage* pStr );
    STDMETHOD(Save) ( IStorage *pStgSave, BOOL fSameAsLoad );
    STDMETHOD(SaveCompleted) ( IStorage *pStgNew );
    STDMETHOD(HandsOffStorage) (void);

    /* IDataObject methods */
    STDMETHOD(GetData) ( FORMATETC * pFormatetc, STGMEDIUM * pMedium );
    STDMETHOD(GetDataHere) ( FORMATETC * pFormatetc, STGMEDIUM * pMedium );
    STDMETHOD(QueryGetData) ( FORMATETC * pFormatetc );
    STDMETHOD(GetCanonicalFormatEtc) ( FORMATETC * pFormatetcIn, FORMATETC * pFormatetcOut );
    STDMETHOD(SetData) ( FORMATETC * pFormatetc, STGMEDIUM * pMedium, BOOL fRelease );
    STDMETHOD(EnumFormatEtc) ( DWORD dwDirection, IEnumFORMATETC ** ppFormatetc );
    STDMETHOD(DAdvise) ( FORMATETC * pFormatetc, DWORD advf, IAdviseSink * pAdvSink, DWORD * pdwConnection );
    STDMETHOD(DUnadvise) ( DWORD dwConnection );
    STDMETHOD(EnumDAdvise) ( IEnumSTATDATA ** ppenumAdvise );

    /* IOleObject methods */
    STDMETHOD(SetClientSite) ( IOleClientSite* pSite );
    STDMETHOD(GetClientSite) ( IOleClientSite** pSite );
    STDMETHOD(SetHostNames) ( LPCOLESTR szContainerApp, LPCOLESTR szContainerObj );
    STDMETHOD(Close) ( DWORD dwSaveOption);
    STDMETHOD(SetMoniker) ( DWORD dwWhichMoniker, IMoniker *pmk );
    STDMETHOD(GetMoniker) ( DWORD dwAssign, DWORD dwWhichMoniker, IMoniker **ppmk );
    STDMETHOD(InitFromData) ( IDataObject *pDataObject, BOOL fCreation, DWORD dwReserved );
    STDMETHOD(GetClipboardData) ( DWORD dwReserved, IDataObject **ppDataObject );
    STDMETHOD(DoVerb) ( LONG iVerb, LPMSG lpmsg, IOleClientSite *pActiveSite, LONG lindex, HWND hwndParent, LPCRECT lprcPosRect );
    STDMETHOD(EnumVerbs) ( IEnumOLEVERB **ppEnumOleVerb );
    STDMETHOD(Update) ();
    STDMETHOD(IsUpToDate) ();
    STDMETHOD(GetUserClassID) ( CLSID *pClsid );
    STDMETHOD(GetUserType) ( DWORD dwFormOfType, LPOLESTR *pszUserType );
    STDMETHOD(SetExtent) ( DWORD dwDrawAspect, SIZEL *psizel );
    STDMETHOD(GetExtent) ( DWORD dwDrawAspect, SIZEL *psizel );
    STDMETHOD(Advise) ( IAdviseSink *pAdvSink, DWORD *pdwConnection );
    STDMETHOD(Unadvise) ( DWORD dwConnection );
    STDMETHOD(EnumAdvise) ( IEnumSTATDATA **ppenumAdvise );
    STDMETHOD(GetMiscStatus) ( DWORD dwAspect, DWORD *pdwStatus );
    STDMETHOD(SetColorScheme) ( LOGPALETTE *pLogpal );

    /* IOleInPlaceObject methods */
    STDMETHOD(GetWindow)(HWND *);
    STDMETHOD(ContextSensitiveHelp)(BOOL);
    STDMETHOD(InPlaceDeactivate)();
    STDMETHOD(UIDeactivate)();
    STDMETHOD(SetObjectRects)(LPCRECT, LPCRECT);
    STDMETHOD(ReactivateAndUndo)();

    /* IPersistFile methods */
    STDMETHOD(Load) ( LPCOLESTR pszFileName, DWORD dwMode );
    STDMETHOD(Save) ( LPCOLESTR pszFileName, BOOL fRemember );
    STDMETHOD(SaveCompleted) ( LPCOLESTR pszFileName );
    STDMETHOD(GetCurFile) ( LPOLESTR *ppszFileName );

    /* IDispatch methods */
    STDMETHOD(GetTypeInfoCount) ( unsigned int FAR*  pctinfo );
    STDMETHOD(GetTypeInfo) ( unsigned int iTInfo, LCID lcid, ITypeInfo FAR* FAR* ppTInfo );
    STDMETHOD(GetIDsOfNames) ( REFIID riid, OLECHAR FAR* FAR* rgszNames, unsigned int cNames, LCID lcid, DISPID FAR* rgDispId );
    STDMETHOD(Invoke) ( DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS FAR* pDispParams, VARIANT FAR* pVarResult, EXCEPINFO FAR* pExcepInfo, unsigned int FAR* puArgErr );

    // c++ - methods

    void notify( bool bDataChanged = true );
    HRESULT SaveObject();
    HRESULT ShowObject();
    GUID GetGUID() const { return m_guid; }

protected:
    oslInterlockedCount                 m_refCount;

    ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_xFactory;

    DocumentHolder*                     m_pDocHolder;
    ::rtl::OUString                     m_aFileName;

    CComPtr< IStorage >                 m_pMasterStorage;
    CComPtr< IStream >                  m_pOwnStream;
    CComPtr< IStream >                  m_pExtStream;
    GUID                                m_guid;

    sal_Bool                            m_bIsDirty;

    CComPtr< IOleClientSite >           m_pClientSite;
    CComPtr< IDataAdviseHolder >        m_pDAdviseHolder;

    AdviseSinkHashMap                   m_aAdviseHashMap;
    DWORD                               m_nAdviseNum;
};

#endif //_EMBEDDOC_HXX_

<|endoftext|>


<commit_before>/**
 * \file Constants.hpp
 * \brief Defines some useful constants used throughout graphics applications.
 * These are fully templated and default to float.
 */

#ifndef ATLAS_INCLUDE_ATLAS_CORE_CONSTANTS_HPP
#define ATLAS_INCLUDE_ATLAS_CORE_CONSTANTS_HPP

#pragma once

#include <limits>

namespace atlas
{
    namespace core
    {
        /**
         * Returns the defined epsilon value for that data type.
         * @tparam The numerical data type.
         */
        template <typename GenType = float>
        constexpr GenType epsilon()
        {
            return std::numeric_limits<GenType>::epsilon();
        }

        template <typename GenType = float>
        constexpr GenType negInfinity()
        {
            return std::numeric_limits<GenType>::lowest();
        }

        /**
         * Returns the "infinity" (maximum value) that the specified data type
         * can represent.
         * @tparam The numerical data type.
         */
        template <typename GenType = float>
        constexpr GenType infinity()
        {
            return std::numeric_limits<GenType>::max();
        }
    }
}

#endif<commit_msg>[brief] Adds enable_if to infinity constants.<commit_after>/**
 * \file Constants.hpp
 * \brief Defines some useful constants used throughout graphics applications.
 * These are fully templated and default to float.
 */

#ifndef ATLAS_INCLUDE_ATLAS_CORE_CONSTANTS_HPP
#define ATLAS_INCLUDE_ATLAS_CORE_CONSTANTS_HPP

#pragma once

#include <limits>

namespace atlas
{
    namespace core
    {
        /**
         * Returns the defined epsilon value for that data type.
         * @tparam The numerical data type.
         */
        template <typename GenType = float>
        constexpr GenType epsilon()
        {
            return std::numeric_limits<GenType>::epsilon();
        }

        /**
         * Returns the "infinity" (maximum value) that the specified data type
         * can represent.
         * @tparam The numerical data type.
         */
        template <typename GenType = float>
        constexpr typename std::enable_if<
            std::numeric_limits<GenType>::has_infinity, GenType>::type
        infinity()
        {
            return std::numeric_limits<GenType>::infinity();
        }

        template <typename GenType = float>
        constexpr typename std::enable_if<
            std::numeric_limits<GenType>::has_infinity, GenType>::type
            negInfinity()
        {
            return GenType(-1) * infinity<GenType>();
        }
    }
}

#endif<|endoftext|>


<commit_before>//=======================================================================
// Copyright (c) 2014 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#ifndef DLL_CONV_RBM_MP_DESC_HPP
#define DLL_CONV_RBM_MP_DESC_HPP

#include "base_conf.hpp"
#include "contrastive_divergence.hpp"
#include "watcher.hpp"
#include "tmp.hpp"

namespace dll {

/*!
 * \brief Describe a Convolutional Restricted Boltzmann Machine with
 * Probabilistic Max Pooling layer.
 *
 * This struct should be used to define a RBM either as standalone or for a DBN.
 * Once configured, the ::rbm_t member returns the type of the configured RBM.
 */
template<std::size_t NV_T, std::size_t NH_T, std::size_t K_T, std::size_t C_T, typename... Parameters>
struct conv_rbm_mp_desc {
    static constexpr const std::size_t NV = NV_T;
    static constexpr const std::size_t NH = NH_T;
    static constexpr const std::size_t K = K_T;
    static constexpr const std::size_t C = C_T;

    static constexpr const bool Momentum = detail::is_present<momentum, Parameters...>::value;
    static constexpr const std::size_t BatchSize = detail::get_value<batch_size<1>, Parameters...>::value;
    static constexpr const unit_type visible_unit = detail::get_value<visible<unit_type::BINARY>, Parameters...>::value;
    static constexpr const unit_type hidden_unit = detail::get_value<hidden<unit_type::BINARY>, Parameters...>::value;
    static constexpr const unit_type PoolingUnit = detail::get_value<pooling_unit<unit_type::BINARY>, Parameters...>::value;
    static constexpr const decay_type Decay = detail::get_value<weight_decay<decay_type::NONE>, Parameters...>::value;
    static constexpr const bool Sparsity = detail::is_present<sparsity, Parameters...>::value;

    /*! The type of the trainer to use to train the RBM */
    template <typename RBM>
    using trainer_t = typename detail::get_template_type<trainer<cd1_trainer_t>, Parameters...>::template type<RBM>;

    /*! The type of the watched to use during training */
    template <typename RBM>
    using watcher_t = typename detail::get_template_type<watcher<default_rbm_watcher>, Parameters...>::template type<RBM>;

    /*! The RBM type */
    using rbm_t = conv_rbm_mp<conv_rbm_mp_desc<NV_T, NH_T, K_T, C_T, Parameters...>>;

    //Validate all parameters

    static_assert(NV > 0, "A matrix of at least 1x1 is necessary for the visible units");
    static_assert(NH > 0, "A matrix of at least 1x1 is necessary for the hidden units");
    static_assert(K > 0, "At least one base is necessary");
    static_assert(C > 0, "At least one pooling group is necessary");

    //Make sure only valid types are passed to the configuration list
    static_assert(
        detail::is_valid<detail::tmp_list<
                momentum, batch_size_id, visible_id, hidden_id, pooling_unit_id,
                weight_decay_id, sparsity, trainer_id>
            , Parameters...>::value,
        "Invalid parameters type");

    static_assert(BatchSize > 0, "Batch size must be at least 1");

    static_assert(!Sparsity || (Sparsity && hidden_unit == unit_type::BINARY),
        "Sparsity only works with binary hidden units");
};

} //end of dbn namespace

#endif<commit_msg>Fix watcher parameters<commit_after>//=======================================================================
// Copyright (c) 2014 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#ifndef DLL_CONV_RBM_MP_DESC_HPP
#define DLL_CONV_RBM_MP_DESC_HPP

#include "base_conf.hpp"
#include "contrastive_divergence.hpp"
#include "watcher.hpp"
#include "tmp.hpp"

namespace dll {

/*!
 * \brief Describe a Convolutional Restricted Boltzmann Machine with
 * Probabilistic Max Pooling layer.
 *
 * This struct should be used to define a RBM either as standalone or for a DBN.
 * Once configured, the ::rbm_t member returns the type of the configured RBM.
 */
template<std::size_t NV_T, std::size_t NH_T, std::size_t K_T, std::size_t C_T, typename... Parameters>
struct conv_rbm_mp_desc {
    static constexpr const std::size_t NV = NV_T;
    static constexpr const std::size_t NH = NH_T;
    static constexpr const std::size_t K = K_T;
    static constexpr const std::size_t C = C_T;

    static constexpr const bool Momentum = detail::is_present<momentum, Parameters...>::value;
    static constexpr const std::size_t BatchSize = detail::get_value<batch_size<1>, Parameters...>::value;
    static constexpr const unit_type visible_unit = detail::get_value<visible<unit_type::BINARY>, Parameters...>::value;
    static constexpr const unit_type hidden_unit = detail::get_value<hidden<unit_type::BINARY>, Parameters...>::value;
    static constexpr const unit_type PoolingUnit = detail::get_value<pooling_unit<unit_type::BINARY>, Parameters...>::value;
    static constexpr const decay_type Decay = detail::get_value<weight_decay<decay_type::NONE>, Parameters...>::value;
    static constexpr const bool Sparsity = detail::is_present<sparsity, Parameters...>::value;

    /*! The type of the trainer to use to train the RBM */
    template <typename RBM>
    using trainer_t = typename detail::get_template_type<trainer<cd1_trainer_t>, Parameters...>::template type<RBM>;

    /*! The type of the watched to use during training */
    template <typename RBM>
    using watcher_t = typename detail::get_template_type<watcher<default_rbm_watcher>, Parameters...>::template type<RBM>;

    /*! The RBM type */
    using rbm_t = conv_rbm_mp<conv_rbm_mp_desc<NV_T, NH_T, K_T, C_T, Parameters...>>;

    //Validate all parameters

    static_assert(NV > 0, "A matrix of at least 1x1 is necessary for the visible units");
    static_assert(NH > 0, "A matrix of at least 1x1 is necessary for the hidden units");
    static_assert(K > 0, "At least one base is necessary");
    static_assert(C > 0, "At least one pooling group is necessary");

    //Make sure only valid types are passed to the configuration list
    static_assert(
        detail::is_valid<detail::tmp_list<
                momentum, batch_size_id, visible_id, hidden_id, pooling_unit_id,
                weight_decay_id, sparsity, trainer_id, watcher_id>
            , Parameters...>::value,
        "Invalid parameters type");

    static_assert(BatchSize > 0, "Batch size must be at least 1");

    static_assert(!Sparsity || (Sparsity && hidden_unit == unit_type::BINARY),
        "Sparsity only works with binary hidden units");
};

} //end of dbn namespace

#endif<|endoftext|>


<commit_before>//=======================================================================
// Copyright (c) 2014-2016 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#pragma once

namespace etl {

/*!
 * \brief Define traits to get vectorization information for types when no vector mode is available.
 */
template <typename T>
struct no_intrinsic_traits {
    static constexpr const bool vectorizable     = false;      ///< Boolean flag indicating if the type is vectorizable or not
    static constexpr const std::size_t size      = 1;          ///< Numbers of elements done at once
    static constexpr const std::size_t alignment = alignof(T); ///< Necessary number of bytes of alignment for this type

    using intrinsic_type = T;
};

struct no_vec {
    template<typename T>
    using traits = no_intrinsic_traits<T>;

    template<typename T>
    using vec_type = typename traits<T>::intrinsic_type;

    template <typename F, typename M>
    static inline void storeu(F* /*memory*/, M /*value*/) {}

    template <typename F, typename M>
    static inline void store(F* /*memory*/, M /*value*/) {}

    template <typename F>
    static F load(const F* /*memory*/) {}

    template <typename F>
    static F loadu(const F* /*memory*/) {}

    template <typename F>
    static F set(F /*value*/) {}

    template <typename M>
    static M add(M /*lhs*/, M /*rhs*/) {}

    template <typename M>
    static M sub(M /*lhs*/, M /*rhs*/) {}

    template <typename M>
    static M mul(M /*lhs*/, M /*rhs*/) {}

    template <typename M>
    static M div(M /*lhs*/, M /*rhs*/) {}

    template <typename M>
    static M sqrt(M /*value*/) {}

    template <typename M>
    static M minus(M /*value*/) {}
};

} //end of namespace etl
<commit_msg>A bit of doc<commit_after>//=======================================================================
// Copyright (c) 2014-2016 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#pragma once

namespace etl {

/*!
 * \brief Define traits to get vectorization information for types when no vector mode is available.
 */
template <typename T>
struct no_intrinsic_traits {
    static constexpr const bool vectorizable     = false;      ///< Boolean flag indicating if the type is vectorizable or not
    static constexpr const std::size_t size      = 1;          ///< Numbers of elements done at once
    static constexpr const std::size_t alignment = alignof(T); ///< Necessary number of bytes of alignment for this type

    using intrinsic_type = T;
};

/*!
 * \brief Vectorization support when no vectorization is enabled.
 *
 * This class is purely here to ensure compilation, it will never be called at runtime
 */
struct no_vec {
    /*!
     * \brief The traits for this vectorization implementation
     */
    template<typename T>
    using traits = no_intrinsic_traits<T>;

    /*!
     * \brief The vector type for this vectorization implementation
     */
    template<typename T>
    using vec_type = typename traits<T>::intrinsic_type;

    /*!
     * \brief Unaligned store value to memory
     * \param memory The target memory
     * \param value The value to store
     */
    template <typename F, typename M>
    static inline void storeu(F* memory, M value) {
        cpp_unused(memory);
        cpp_unused(value);
    }

    /*!
     * \brief Aligned store value to memory
     * \param memory The target memory
     * \param value The value to store
     */
    template <typename F, typename M>
    static inline void store(F* memory, M value) {
        cpp_unused(memory);
        cpp_unused(value);
    }

    /*!
     * \brief Aligned load a vector from memory
     * \param memory The target memory
     * \return Vector of values from memory
     */
    template <typename F>
    static F load(const F* memory) {
        cpp_unused(memory);
    }

    /*!
     * \brief Unaligned load a vector from memory
     * \param memory The target memory
     * \return Vector of values from memory
     */
    template <typename F>
    static F loadu(const F* memory) {
        cpp_unused(memory);
    }

    /*!
     * \brief Create a vector containing the given value
     * \param value The value
     * \return Vector of value
     */
    template <typename F>
    static F set(F value) {
        cpp_unused(value);
    }

    /*!
     * \brief Vector addition or lhs and rhs
     * \param lhs The left hand side of the operation
     * \param rhs The right hand side of the operation
     * \return Vector of the results
     */
    template <typename M>
    static M add(M lhs, M rhs) {
        cpp_unused(lhs);
        cpp_unused(rhs);
    }

    /*!
     * \brief Vector subtraction or lhs and rhs
     * \param lhs The left hand side of the operation
     * \param rhs The right hand side of the operation
     * \return Vector of the results
     */
    template <typename M>
    static M sub(M lhs, M rhs) {
        cpp_unused(lhs);
        cpp_unused(rhs);
    }

    /*!
     * \brief Vector multiplication or lhs and rhs
     * \param lhs The left hand side of the operation
     * \param rhs The right hand side of the operation
     * \return Vector of the results
     */
    template <typename M>
    static M mul(M lhs, M rhs) {
        cpp_unused(lhs);
        cpp_unused(rhs);
    }

    /*!
     * \brief Vector division or lhs and rhs
     * \param lhs The left hand side of the operation
     * \param rhs The right hand side of the operation
     * \return Vector of the results
     */
    template <typename M>
    static M div(M lhs, M rhs) {
        cpp_unused(lhs);
        cpp_unused(rhs);
    }

    /*!
     * \brief Vector square root
     * \param value The input values
     * \return The square root of the input values
     */
    template <typename M>
    static M sqrt(M value) {
        cpp_unused(value);
    }

    /*!
     * \brief Compute the negative value of the input
     * \param value The input values
     * \return The negative values of the input values
     */
    template <typename M>
    static M minus(M value) {
        cpp_unused(value);
    }
};

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


<commit_before>/*

Copyright (c) 2009, Arvid Norberg
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 the author 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.

*/

#ifndef TORRENT_SOCKET_IO_HPP_INCLUDED
#define TORRENT_SOCKET_IO_HPP_INCLUDED

#include "libtorrent/socket.hpp"
#include "libtorrent/address.hpp"
#include "libtorrent/io.hpp"
#include "libtorrent/error_code.hpp"
#include "libtorrent/lazy_entry.hpp"
#include <string>

namespace libtorrent
{
	TORRENT_EXPORT std::string print_address(address const& addr);
	TORRENT_EXPORT std::string print_endpoint(tcp::endpoint const& ep);
	TORRENT_EXPORT std::string print_endpoint(udp::endpoint const& ep);

	namespace detail
	{
		template<class OutIt>
		void write_address(address const& a, OutIt& out)
		{
#if TORRENT_USE_IPV6
			if (a.is_v4())
			{
#endif
				write_uint32(a.to_v4().to_ulong(), out);
#if TORRENT_USE_IPV6
			}
			else if (a.is_v6())
			{
				address_v6::bytes_type bytes
					= a.to_v6().to_bytes();
				std::copy(bytes.begin(), bytes.end(), out);
			}
#endif
		}

		template<class InIt>
		address read_v4_address(InIt& in)
		{
			unsigned long ip = read_uint32(in);
			return address_v4(ip);
		}

#if TORRENT_USE_IPV6
		template<class InIt>
		address read_v6_address(InIt& in)
		{
			typedef address_v6::bytes_type bytes_t;
			bytes_t bytes;
			for (bytes_t::iterator i = bytes.begin()
				, end(bytes.end()); i != end; ++i)
				*i = read_uint8(in);
			return address_v6(bytes);
		}
#endif

		template<class Endpoint, class OutIt>
		void write_endpoint(Endpoint const& e, OutIt& out)
		{
			write_address(e.address(), out);
			write_uint16(e.port(), out);
		}

		template<class Endpoint, class InIt>
		Endpoint read_v4_endpoint(InIt& in)
		{
			address addr = read_v4_address(in);
			int port = read_uint16(in);
			return Endpoint(addr, port);
		}

#if TORRENT_USE_IPV6
		template<class Endpoint, class InIt>
		Endpoint read_v6_endpoint(InIt& in)
		{
			address addr = read_v6_address(in);
			int port = read_uint16(in);
			return Endpoint(addr, port);
		}
#endif

		template <class EndpointType>
		void read_endpoint_list(libtorrent::lazy_entry const* n, std::vector<EndpointType>& epl)
		{
			using namespace libtorrent;
			if (n->type() != lazy_entry::list_t) return;
			for (int i = 0; i < n->list_size(); ++i)
			{
				lazy_entry const* e = n->list_at(i);
				if (e->type() != lazy_entry::string_t) return;
				if (e->string_length() < 6) continue;
				char const* in = e->string_ptr();
				if (e->string_length() == 6)
					epl.push_back(read_v4_endpoint<EndpointType>(in));
#if TORRENT_USE_IPV6
				else if (e->string_length() == 18)
					epl.push_back(read_v6_endpoint<EndpointType>(in));
#endif
			}
		}

	}

}

#endif

<commit_msg>fixed bug in write_address<commit_after>/*

Copyright (c) 2009, Arvid Norberg
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 the author 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.

*/

#ifndef TORRENT_SOCKET_IO_HPP_INCLUDED
#define TORRENT_SOCKET_IO_HPP_INCLUDED

#include "libtorrent/socket.hpp"
#include "libtorrent/address.hpp"
#include "libtorrent/io.hpp"
#include "libtorrent/error_code.hpp"
#include "libtorrent/lazy_entry.hpp"
#include <string>

namespace libtorrent
{
	TORRENT_EXPORT std::string print_address(address const& addr);
	TORRENT_EXPORT std::string print_endpoint(tcp::endpoint const& ep);
	TORRENT_EXPORT std::string print_endpoint(udp::endpoint const& ep);

	namespace detail
	{
		template<class OutIt>
		void write_address(address const& a, OutIt& out)
		{
#if TORRENT_USE_IPV6
			if (a.is_v4())
			{
#endif
				write_uint32(a.to_v4().to_ulong(), out);
#if TORRENT_USE_IPV6
			}
			else if (a.is_v6())
			{
				typedef address_v6::bytes_type bytes_t;
				bytes_t bytes = a.to_v6().to_bytes();
				for (bytes_t::iterator i = bytes.begin()
					, end(bytes.end()); i != end; ++i)
					write_uint8(*i, out);
			}
#endif
		}

		template<class InIt>
		address read_v4_address(InIt& in)
		{
			unsigned long ip = read_uint32(in);
			return address_v4(ip);
		}

#if TORRENT_USE_IPV6
		template<class InIt>
		address read_v6_address(InIt& in)
		{
			typedef address_v6::bytes_type bytes_t;
			bytes_t bytes;
			for (bytes_t::iterator i = bytes.begin()
				, end(bytes.end()); i != end; ++i)
				*i = read_uint8(in);
			return address_v6(bytes);
		}
#endif

		template<class Endpoint, class OutIt>
		void write_endpoint(Endpoint const& e, OutIt& out)
		{
			write_address(e.address(), out);
			write_uint16(e.port(), out);
		}

		template<class Endpoint, class InIt>
		Endpoint read_v4_endpoint(InIt& in)
		{
			address addr = read_v4_address(in);
			int port = read_uint16(in);
			return Endpoint(addr, port);
		}

#if TORRENT_USE_IPV6
		template<class Endpoint, class InIt>
		Endpoint read_v6_endpoint(InIt& in)
		{
			address addr = read_v6_address(in);
			int port = read_uint16(in);
			return Endpoint(addr, port);
		}
#endif

		template <class EndpointType>
		void read_endpoint_list(libtorrent::lazy_entry const* n, std::vector<EndpointType>& epl)
		{
			using namespace libtorrent;
			if (n->type() != lazy_entry::list_t) return;
			for (int i = 0; i < n->list_size(); ++i)
			{
				lazy_entry const* e = n->list_at(i);
				if (e->type() != lazy_entry::string_t) return;
				if (e->string_length() < 6) continue;
				char const* in = e->string_ptr();
				if (e->string_length() == 6)
					epl.push_back(read_v4_endpoint<EndpointType>(in));
#if TORRENT_USE_IPV6
				else if (e->string_length() == 18)
					epl.push_back(read_v6_endpoint<EndpointType>(in));
#endif
			}
		}

	}

}

#endif

<|endoftext|>


<commit_before>/* This file is part of Zanshin

   Copyright 2014 Kevin Ottens <ervin@kde.org>

   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License as
   published by the Free Software Foundation; either version 2 of
   the License or (at your option) version 3 or any later version
   accepted by the membership of KDE e.V. (or its successor approved
   by the membership of KDE e.V.), which shall act as a proxy
   defined in Section 14 of version 3 of the license.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
   USA.
*/

#include "itemdelegate.h"

#include <QStyleOptionViewItemV4>

#include "domain/note.h"
#include "domain/task.h"
#include "presentation/querytreemodelbase.h"

using namespace Widgets;

ItemDelegate::ItemDelegate(QObject *parent)
    : QStyledItemDelegate(parent)
{
}

QSize ItemDelegate::sizeHint(const QStyleOptionViewItem &option,
                                   const QModelIndex &index) const
{
    // Make sure they all get the height needed for a check indicator
    QStyleOptionViewItemV4 opt = option;
    opt.features = QStyleOptionViewItemV4::HasCheckIndicator;
    QSize res = QStyledItemDelegate::sizeHint(opt, index);
    return res;
}

void ItemDelegate::paint(QPainter *painter,
                         const QStyleOptionViewItem &option,
                         const QModelIndex &index) const
{
    QStyleOptionViewItemV4 opt = option;

    Domain::Task::Ptr task;
    Domain::Note::Ptr note;

    QVariant data = index.data(Presentation::QueryTreeModelBase::ObjectRole);
    auto artifact = data.value<Domain::Artifact::Ptr>();
    if (artifact) {
        task = artifact.dynamicCast<Domain::Task>();
        note = artifact.dynamicCast<Domain::Note>();
    } else {
        task = data.value<Domain::Task::Ptr>();
        note = data.value<Domain::Note::Ptr>();
    }

    if (task) {
        if (task->isDone()) {
            opt.font.setStrikeOut(true);
        } else {
            if (task->startDate().isValid()
             && task->startDate().date() <= QDate::currentDate()) {
                opt.font.setBold(true);
            }

            if (task->dueDate().isValid()) {
                if (task->dueDate().date() < QDate::currentDate()) {
                    opt.font.setBold(true);
                    opt.palette.setColor(QPalette::Text, QColor(Qt::red));
                    opt.palette.setColor(QPalette::HighlightedText, QColor(Qt::red));

                } else if (task->dueDate().date() == QDate::currentDate()) {
                    opt.font.setBold(true);
                    opt.palette.setColor(QPalette::Text, QColor("orange"));
                    opt.palette.setColor(QPalette::HighlightedText, QColor("orange"));
                }
            }
        }
    }

    if (note) {
        opt.features |= QStyleOptionViewItemV4::HasDecoration;
        opt.icon = QIcon::fromTheme("text-plain");
    }

    QStyledItemDelegate::paint(painter, opt, index);
}
<commit_msg>Display delegated tasks differently<commit_after>/* This file is part of Zanshin

   Copyright 2014 Kevin Ottens <ervin@kde.org>

   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License as
   published by the Free Software Foundation; either version 2 of
   the License or (at your option) version 3 or any later version
   accepted by the membership of KDE e.V. (or its successor approved
   by the membership of KDE e.V.), which shall act as a proxy
   defined in Section 14 of version 3 of the license.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
   USA.
*/

#include "itemdelegate.h"

#include <QApplication>
#include <QStyleOptionViewItemV4>

#include "domain/note.h"
#include "domain/task.h"
#include "presentation/querytreemodelbase.h"

using namespace Widgets;

ItemDelegate::ItemDelegate(QObject *parent)
    : QStyledItemDelegate(parent)
{
}

QSize ItemDelegate::sizeHint(const QStyleOptionViewItem &option,
                                   const QModelIndex &index) const
{
    // Make sure they all get the height needed for a check indicator
    QStyleOptionViewItemV4 opt = option;
    opt.features = QStyleOptionViewItemV4::HasCheckIndicator;
    QSize res = QStyledItemDelegate::sizeHint(opt, index);
    return res;
}

void ItemDelegate::paint(QPainter *painter,
                         const QStyleOptionViewItem &option,
                         const QModelIndex &index) const
{
    QStyleOptionViewItemV4 opt = option;
    initStyleOption(&opt, index);

    Domain::Task::Ptr task;
    Domain::Note::Ptr note;

    QVariant data = index.data(Presentation::QueryTreeModelBase::ObjectRole);
    auto artifact = data.value<Domain::Artifact::Ptr>();
    if (artifact) {
        task = artifact.dynamicCast<Domain::Task>();
        note = artifact.dynamicCast<Domain::Note>();
    } else {
        task = data.value<Domain::Task::Ptr>();
        note = data.value<Domain::Note::Ptr>();
    }

    if (task) {
        if (task->isDone()) {
            opt.font.setStrikeOut(true);
        } else {
            if (task->startDate().isValid()
             && task->startDate().date() <= QDate::currentDate()) {
                opt.font.setBold(true);
            }

            if (task->dueDate().isValid()) {
                if (task->dueDate().date() < QDate::currentDate()) {
                    opt.font.setBold(true);
                    opt.palette.setColor(QPalette::Text, QColor(Qt::red));
                    opt.palette.setColor(QPalette::HighlightedText, QColor(Qt::red));

                } else if (task->dueDate().date() == QDate::currentDate()) {
                    opt.font.setBold(true);
                    opt.palette.setColor(QPalette::Text, QColor("orange"));
                    opt.palette.setColor(QPalette::HighlightedText, QColor("orange"));
                }
            }
        }

        if (task->delegate().isValid()) {
            opt.text = QString("(%1) %2").arg(task->delegate().display(), opt.text);
            opt.font.setItalic(true);
        }
    }

    if (note) {
        opt.features |= QStyleOptionViewItemV4::HasDecoration;
        opt.icon = QIcon::fromTheme("text-plain");
    }

    const QWidget *widget = opt.widget;
    QStyle *style = widget ? widget->style() : QApplication::style();
    style->drawControl(QStyle::CE_ItemViewItem, &opt, painter, widget);
}
<|endoftext|>


<commit_before>#include <stdexcept>
#include <unordered_map>

#include "windowsx.h"

#include "windowswindow.hh"
#include "windowsopenglcontext.hh"
#include "system/mousebutton.hh"
#include "system/keycode.hh"

static char appName[] = "Test Application";

using System::KeyCode;

class KeyMap : public std::unordered_map<WPARAM, System::KeyCode>
{
public:
    KeyMap() : std::unordered_map<WPARAM, System::KeyCode>() {
        (*this)[VK_PRIOR]   = KeyCode::KeyPageUp;
        (*this)[VK_NEXT]    = KeyCode::KeyPageDown;
        (*this)[VK_END]     = KeyCode::KeyEnd;
        (*this)[VK_HOME]    = KeyCode::KeyHome;
        (*this)[VK_INSERT]  = KeyCode::KeyInsert;
        (*this)[VK_DELETE]  = KeyCode::KeyDelete;

        (*this)[VK_RIGHT]   = KeyCode::KeyRightArrow;
        (*this)[VK_DOWN]    = KeyCode::KeyDownArrow;
        (*this)[VK_LEFT]    = KeyCode::KeyLeftArrow;
        (*this)[VK_UP]      = KeyCode::KeyUpArrow;

        (*this)[VK_ESCAPE]  = KeyCode::KeyEscape;
        (*this)[VK_TAB]     = KeyCode::KeyTab;
        (*this)[VK_SHIFT]   = KeyCode::KeyShift;
        (*this)[VK_MENU]    = KeyCode::KeyAlt;
        (*this)[VK_CONTROL] = KeyCode::KeyControl;
        (*this)[VK_CAPITAL] = KeyCode::KeyCapsLock;

        (*this)[VK_RCONTROL] = KeyCode::KeyRightControl;
        (*this)[VK_LCONTROL] = KeyCode::KeyLeftControl;
        (*this)[VK_RSHIFT]   = KeyCode::KeyRightShift;
        (*this)[VK_LSHIFT]   = KeyCode::KeyLeftShift;

        (*this)[VK_BACK]    = KeyCode::KeyBackspace;
        (*this)[VK_RETURN]  = KeyCode::KeyEnter;
        (*this)[VK_SPACE]   = KeyCode::KeySpace;

        (*this)[0x30]       = KeyCode::Key0;
        (*this)[0x31]       = KeyCode::Key1;
        (*this)[0x32]       = KeyCode::Key2;
        (*this)[0x33]       = KeyCode::Key3;
        (*this)[0x34]       = KeyCode::Key4;
        (*this)[0x35]       = KeyCode::Key5;
        (*this)[0x36]       = KeyCode::Key6;
        (*this)[0x37]       = KeyCode::Key7;
        (*this)[0x38]       = KeyCode::Key8;
        (*this)[0x39]       = KeyCode::Key9;

        (*this)[VK_NUMPAD0] = KeyCode::KeyNumpad0;
        (*this)[VK_NUMPAD1] = KeyCode::KeyNumpad1;
        (*this)[VK_NUMPAD2] = KeyCode::KeyNumpad2;
        (*this)[VK_NUMPAD3] = KeyCode::KeyNumpad3;
        (*this)[VK_NUMPAD4] = KeyCode::KeyNumpad4;
        (*this)[VK_NUMPAD5] = KeyCode::KeyNumpad5;
        (*this)[VK_NUMPAD6] = KeyCode::KeyNumpad6;
        (*this)[VK_NUMPAD7] = KeyCode::KeyNumpad7;
        (*this)[VK_NUMPAD8] = KeyCode::KeyNumpad8;
        (*this)[VK_NUMPAD9] = KeyCode::KeyNumpad9;

        (*this)[VK_MULTIPLY] = KeyCode::KeyMultiply;
        (*this)[VK_ADD]      = KeyCode::KeyPlus;
        (*this)[VK_SUBTRACT] = KeyCode::KeyMinus;
        (*this)[VK_DIVIDE]   = KeyCode::KeyDivide;
        (*this)[VK_DECIMAL]  = KeyCode::KeyDecimal;

        (*this)[0x41]       = KeyCode::KeyA;
        (*this)[0x42]       = KeyCode::KeyB;
        (*this)[0x43]       = KeyCode::KeyC;
        (*this)[0x44]       = KeyCode::KeyD;
        (*this)[0x45]       = KeyCode::KeyE;
        (*this)[0x46]       = KeyCode::KeyF;
        (*this)[0x47]       = KeyCode::KeyG;
        (*this)[0x48]       = KeyCode::KeyH;
        (*this)[0x49]       = KeyCode::KeyI;
        (*this)[0x4A]       = KeyCode::KeyJ;
        (*this)[0x4B]       = KeyCode::KeyK;
        (*this)[0x4C]       = KeyCode::KeyL;
        (*this)[0x4D]       = KeyCode::KeyM;
        (*this)[0x4E]       = KeyCode::KeyN;
        (*this)[0x4F]       = KeyCode::KeyO;
        (*this)[0x50]       = KeyCode::KeyP;
        (*this)[0x51]       = KeyCode::KeyQ;
        (*this)[0x52]       = KeyCode::KeyR;
        (*this)[0x53]       = KeyCode::KeyS;
        (*this)[0x54]       = KeyCode::KeyT;
        (*this)[0x55]       = KeyCode::KeyU;
        (*this)[0x56]       = KeyCode::KeyV;
        (*this)[0x57]       = KeyCode::KeyW;
        (*this)[0x59]       = KeyCode::KeyY;
        (*this)[0x5A]       = KeyCode::KeyZ;
    }
};

static KeyMap keyMap;
static std::unordered_map<HWND, WindowsWindow*> windowMap;

WindowsWindow::WindowsWindow(const char *windowName, Framework::ISystemWindowController *controller, HINSTANCE processInstance, int commandShow)
    : m_controller(controller), m_openGLContext(NULL)
{
    m_windowHandle = WindowsWindow::makeWindow(windowName, processInstance, commandShow);
    windowMap[m_windowHandle] = this;

    ShowWindow(m_windowHandle, commandShow);
    UpdateWindow(m_windowHandle);

    unsigned int windowWidth, windowHeight;
    GetWindowSize(&windowWidth, &windowHeight);
    m_controller->OnWindowResize(windowWidth, windowHeight);
}

HWND WindowsWindow::makeWindow(const char *windowName, HINSTANCE processInstance, int commandShow)
{
    WNDCLASSEX windowClass;

    windowClass.cbSize        = sizeof(WNDCLASSEX);
    windowClass.style         = CS_VREDRAW | CS_HREDRAW;
    windowClass.lpfnWndProc   = WndProc;
    windowClass.cbClsExtra    = 0;
    windowClass.cbWndExtra    = 0;
    windowClass.hInstance     = processInstance;
    windowClass.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
    windowClass.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);
    windowClass.hCursor       = LoadCursor(NULL, IDC_ARROW);
    windowClass.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH);
    windowClass.lpszClassName = appName;
    windowClass.lpszMenuName  = NULL;

    RegisterClassEx(&windowClass);

    return CreateWindow(appName, windowName, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, processInstance, NULL);
}

WindowsWindow::~WindowsWindow()
{
    if (m_openGLContext != NULL)
        delete m_openGLContext;

    windowMap[m_windowHandle] = NULL;
}

int WindowsWindow::DoMessageLoop()
{
    MSG message;

    Ready();

    while (GetMessage(&message, NULL, 0, 0))
    {
        TranslateMessage(&message);
        DispatchMessage(&message);
    }

    return message.wParam;
}

System::OpenGLContext *WindowsWindow::getOrCreateOpenGLContext()
{
    if (m_openGLContext == NULL)
        m_openGLContext = new WindowsOpenGLContext(m_windowHandle);

    return m_openGLContext;
}

void WindowsWindow::GetWindowSize(unsigned int *width, unsigned int *height)
{
    RECT rect;

    GetClientRect(m_windowHandle, &rect);

    *width = rect.right - rect.left;
    *height = rect.bottom - rect.top;
}

bool WindowsWindow::SetMousePosition(unsigned int posX, unsigned int posY)
{
    POINT point;

    point.x = posX;
    point.y = posY;

    bool success = ClientToScreen(m_windowHandle, &point) ? SetCursorPos(point.x, point.y) : false;
    if (success)
        m_controller->OnMouseMove(point.x, point.y);

    return success;
}

void WindowsWindow::Destroy()
{
    SendNotifyMessage(m_windowHandle, WM_DESTROY, 0, 0);
}

void WindowsWindow::Close()
{
    SendNotifyMessage(m_windowHandle, WM_CLOSE, 0, 0);
}

void WindowsWindow::Ready()
{
    m_controller->OnWindowReady();
}

void WindowsWindow::onClose()
{
    m_controller->OnWindowClose();
}

void WindowsWindow::KeyDown(WPARAM key)
{
    m_controller->OnKeyDown(keyMap[key]);
}

void WindowsWindow::WindowResize(WPARAM wParam, LPARAM lParam)
{
    m_controller->OnWindowResize(LOWORD(lParam), HIWORD(lParam));
}

void WindowsWindow::KeyUp(WPARAM key)
{
    m_controller->OnKeyUp(keyMap[key]);
}

void WindowsWindow::MouseMove(WPARAM wParam, LPARAM lParam)
{
    m_controller->OnMouseMove(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
}

void WindowsWindow::LeftMouseButtonDown(WPARAM wParam, LPARAM lParam)
{
    m_controller->OnMouseButtonDown(System::MouseButton::ButtonOne);
}

void WindowsWindow::RightMouseButtonDown(WPARAM wParam, LPARAM lParam)
{
    m_controller->OnMouseButtonDown(System::MouseButton::ButtonTwo);
}

void WindowsWindow::LeftMouseButtonUp(WPARAM wParam, LPARAM lParam)
{
    m_controller->OnMouseButtonUp(System::MouseButton::ButtonOne);
}

void WindowsWindow::RightMouseButtonUp(WPARAM wParam, LPARAM lParam)
{
    m_controller->OnMouseButtonUp(System::MouseButton::ButtonTwo);
}

void WindowsWindow::MouseScrollWheel(WPARAM wParam, LPARAM lParam)
{
    m_controller->OnMouseScroll(GET_WHEEL_DELTA_WPARAM(wParam) / WHEEL_DELTA);
}

LRESULT CALLBACK WindowsWindow::WndProc(HWND windowHandle, UINT message, WPARAM wparam, LPARAM lparam)
{
    switch(message)
    {
    case WM_KEYDOWN:
        windowMap[windowHandle]->KeyDown(wparam);
        return 0;

    case WM_KEYUP:
        windowMap[windowHandle]->KeyUp(wparam);
        return 0;

    case WM_MOUSEMOVE:
        windowMap[windowHandle]->MouseMove(wparam, lparam);
        return 0;

    case WM_LBUTTONDOWN:
        windowMap[windowHandle]->LeftMouseButtonDown(wparam, lparam);
        return 0;

    case WM_LBUTTONUP:
        windowMap[windowHandle]->LeftMouseButtonUp(wparam, lparam);
        return 0;

    case WM_RBUTTONDOWN:
        windowMap[windowHandle]->RightMouseButtonDown(wparam, lparam);
        return 0;

    case WM_RBUTTONUP:
        windowMap[windowHandle]->RightMouseButtonUp(wparam, lparam);
        return 0;

    case WM_MOUSEWHEEL:
        windowMap[windowHandle]->MouseScrollWheel(wparam, lparam);
        return 0;

    case WM_SIZE:
        windowMap[windowHandle]->WindowResize(wparam, lparam);
        return 0;

    case WM_CLOSE:
        windowMap[windowHandle]->onClose();
        return 0;

    case WM_DESTROY:
        PostQuitMessage(0);
        windowMap[windowHandle] = NULL;
        return 0;

    default:
        return DefWindowProc(windowHandle, message, wparam, lparam);
    }
}
<commit_msg>Take advantage of some STL exception throwing<commit_after>#include <stdexcept>
#include <unordered_map>

#include "windowsx.h"

#include "windowswindow.hh"
#include "windowsopenglcontext.hh"
#include "system/mousebutton.hh"
#include "system/keycode.hh"

static char appName[] = "Test Application";

using System::KeyCode;

class KeyMap : public std::unordered_map<WPARAM, System::KeyCode>
{
public:
    KeyMap() : std::unordered_map<WPARAM, System::KeyCode>() {
        (*this)[VK_PRIOR]   = KeyCode::KeyPageUp;
        (*this)[VK_NEXT]    = KeyCode::KeyPageDown;
        (*this)[VK_END]     = KeyCode::KeyEnd;
        (*this)[VK_HOME]    = KeyCode::KeyHome;
        (*this)[VK_INSERT]  = KeyCode::KeyInsert;
        (*this)[VK_DELETE]  = KeyCode::KeyDelete;

        (*this)[VK_RIGHT]   = KeyCode::KeyRightArrow;
        (*this)[VK_DOWN]    = KeyCode::KeyDownArrow;
        (*this)[VK_LEFT]    = KeyCode::KeyLeftArrow;
        (*this)[VK_UP]      = KeyCode::KeyUpArrow;

        (*this)[VK_ESCAPE]  = KeyCode::KeyEscape;
        (*this)[VK_TAB]     = KeyCode::KeyTab;
        (*this)[VK_SHIFT]   = KeyCode::KeyShift;
        (*this)[VK_MENU]    = KeyCode::KeyAlt;
        (*this)[VK_CONTROL] = KeyCode::KeyControl;
        (*this)[VK_CAPITAL] = KeyCode::KeyCapsLock;

        (*this)[VK_RCONTROL] = KeyCode::KeyRightControl;
        (*this)[VK_LCONTROL] = KeyCode::KeyLeftControl;
        (*this)[VK_RSHIFT]   = KeyCode::KeyRightShift;
        (*this)[VK_LSHIFT]   = KeyCode::KeyLeftShift;

        (*this)[VK_BACK]    = KeyCode::KeyBackspace;
        (*this)[VK_RETURN]  = KeyCode::KeyEnter;
        (*this)[VK_SPACE]   = KeyCode::KeySpace;

        (*this)[0x30]       = KeyCode::Key0;
        (*this)[0x31]       = KeyCode::Key1;
        (*this)[0x32]       = KeyCode::Key2;
        (*this)[0x33]       = KeyCode::Key3;
        (*this)[0x34]       = KeyCode::Key4;
        (*this)[0x35]       = KeyCode::Key5;
        (*this)[0x36]       = KeyCode::Key6;
        (*this)[0x37]       = KeyCode::Key7;
        (*this)[0x38]       = KeyCode::Key8;
        (*this)[0x39]       = KeyCode::Key9;

        (*this)[VK_NUMPAD0] = KeyCode::KeyNumpad0;
        (*this)[VK_NUMPAD1] = KeyCode::KeyNumpad1;
        (*this)[VK_NUMPAD2] = KeyCode::KeyNumpad2;
        (*this)[VK_NUMPAD3] = KeyCode::KeyNumpad3;
        (*this)[VK_NUMPAD4] = KeyCode::KeyNumpad4;
        (*this)[VK_NUMPAD5] = KeyCode::KeyNumpad5;
        (*this)[VK_NUMPAD6] = KeyCode::KeyNumpad6;
        (*this)[VK_NUMPAD7] = KeyCode::KeyNumpad7;
        (*this)[VK_NUMPAD8] = KeyCode::KeyNumpad8;
        (*this)[VK_NUMPAD9] = KeyCode::KeyNumpad9;

        (*this)[VK_MULTIPLY] = KeyCode::KeyMultiply;
        (*this)[VK_ADD]      = KeyCode::KeyPlus;
        (*this)[VK_SUBTRACT] = KeyCode::KeyMinus;
        (*this)[VK_DIVIDE]   = KeyCode::KeyDivide;
        (*this)[VK_DECIMAL]  = KeyCode::KeyDecimal;

        (*this)[0x41]       = KeyCode::KeyA;
        (*this)[0x42]       = KeyCode::KeyB;
        (*this)[0x43]       = KeyCode::KeyC;
        (*this)[0x44]       = KeyCode::KeyD;
        (*this)[0x45]       = KeyCode::KeyE;
        (*this)[0x46]       = KeyCode::KeyF;
        (*this)[0x47]       = KeyCode::KeyG;
        (*this)[0x48]       = KeyCode::KeyH;
        (*this)[0x49]       = KeyCode::KeyI;
        (*this)[0x4A]       = KeyCode::KeyJ;
        (*this)[0x4B]       = KeyCode::KeyK;
        (*this)[0x4C]       = KeyCode::KeyL;
        (*this)[0x4D]       = KeyCode::KeyM;
        (*this)[0x4E]       = KeyCode::KeyN;
        (*this)[0x4F]       = KeyCode::KeyO;
        (*this)[0x50]       = KeyCode::KeyP;
        (*this)[0x51]       = KeyCode::KeyQ;
        (*this)[0x52]       = KeyCode::KeyR;
        (*this)[0x53]       = KeyCode::KeyS;
        (*this)[0x54]       = KeyCode::KeyT;
        (*this)[0x55]       = KeyCode::KeyU;
        (*this)[0x56]       = KeyCode::KeyV;
        (*this)[0x57]       = KeyCode::KeyW;
        (*this)[0x59]       = KeyCode::KeyY;
        (*this)[0x5A]       = KeyCode::KeyZ;
    }
};

static KeyMap keyMap;
static std::unordered_map<HWND, WindowsWindow*> windowMap;

WindowsWindow::WindowsWindow(const char *windowName, Framework::ISystemWindowController *controller, HINSTANCE processInstance, int commandShow)
    : m_controller(controller), m_openGLContext(NULL)
{
    m_windowHandle = WindowsWindow::makeWindow(windowName, processInstance, commandShow);
    windowMap[m_windowHandle] = this;

    ShowWindow(m_windowHandle, commandShow);
    UpdateWindow(m_windowHandle);

    unsigned int windowWidth, windowHeight;
    GetWindowSize(&windowWidth, &windowHeight);
    m_controller->OnWindowResize(windowWidth, windowHeight);
}

HWND WindowsWindow::makeWindow(const char *windowName, HINSTANCE processInstance, int commandShow)
{
    WNDCLASSEX windowClass;

    windowClass.cbSize        = sizeof(WNDCLASSEX);
    windowClass.style         = CS_VREDRAW | CS_HREDRAW;
    windowClass.lpfnWndProc   = WndProc;
    windowClass.cbClsExtra    = 0;
    windowClass.cbWndExtra    = 0;
    windowClass.hInstance     = processInstance;
    windowClass.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
    windowClass.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);
    windowClass.hCursor       = LoadCursor(NULL, IDC_ARROW);
    windowClass.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH);
    windowClass.lpszClassName = appName;
    windowClass.lpszMenuName  = NULL;

    RegisterClassEx(&windowClass);

    return CreateWindow(appName, windowName, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, processInstance, NULL);
}

WindowsWindow::~WindowsWindow()
{
    if (m_openGLContext != NULL)
        delete m_openGLContext;

    windowMap[m_windowHandle] = NULL;
}

int WindowsWindow::DoMessageLoop()
{
    MSG message;

    Ready();

    while (GetMessage(&message, NULL, 0, 0))
    {
        TranslateMessage(&message);
        DispatchMessage(&message);
    }

    return message.wParam;
}

System::OpenGLContext *WindowsWindow::getOrCreateOpenGLContext()
{
    if (m_openGLContext == NULL)
        m_openGLContext = new WindowsOpenGLContext(m_windowHandle);

    return m_openGLContext;
}

void WindowsWindow::GetWindowSize(unsigned int *width, unsigned int *height)
{
    RECT rect;

    GetClientRect(m_windowHandle, &rect);

    *width = rect.right - rect.left;
    *height = rect.bottom - rect.top;
}

bool WindowsWindow::SetMousePosition(unsigned int posX, unsigned int posY)
{
    POINT point;

    point.x = posX;
    point.y = posY;

    bool success = ClientToScreen(m_windowHandle, &point) ? SetCursorPos(point.x, point.y) : false;
    if (success)
        m_controller->OnMouseMove(point.x, point.y);

    return success;
}

void WindowsWindow::Destroy()
{
    SendNotifyMessage(m_windowHandle, WM_DESTROY, 0, 0);
}

void WindowsWindow::Close()
{
    SendNotifyMessage(m_windowHandle, WM_CLOSE, 0, 0);
}

void WindowsWindow::Ready()
{
    m_controller->OnWindowReady();
}

void WindowsWindow::onClose()
{
    m_controller->OnWindowClose();
}

void WindowsWindow::KeyDown(WPARAM key)
{
    m_controller->OnKeyDown(keyMap[key]);
}

void WindowsWindow::WindowResize(WPARAM wParam, LPARAM lParam)
{
    m_controller->OnWindowResize(LOWORD(lParam), HIWORD(lParam));
}

void WindowsWindow::KeyUp(WPARAM key)
{
    m_controller->OnKeyUp(keyMap[key]);
}

void WindowsWindow::MouseMove(WPARAM wParam, LPARAM lParam)
{
    m_controller->OnMouseMove(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
}

void WindowsWindow::LeftMouseButtonDown(WPARAM wParam, LPARAM lParam)
{
    m_controller->OnMouseButtonDown(System::MouseButton::ButtonOne);
}

void WindowsWindow::RightMouseButtonDown(WPARAM wParam, LPARAM lParam)
{
    m_controller->OnMouseButtonDown(System::MouseButton::ButtonTwo);
}

void WindowsWindow::LeftMouseButtonUp(WPARAM wParam, LPARAM lParam)
{
    m_controller->OnMouseButtonUp(System::MouseButton::ButtonOne);
}

void WindowsWindow::RightMouseButtonUp(WPARAM wParam, LPARAM lParam)
{
    m_controller->OnMouseButtonUp(System::MouseButton::ButtonTwo);
}

void WindowsWindow::MouseScrollWheel(WPARAM wParam, LPARAM lParam)
{
    m_controller->OnMouseScroll(GET_WHEEL_DELTA_WPARAM(wParam) / WHEEL_DELTA);
}

LRESULT CALLBACK WindowsWindow::WndProc(HWND windowHandle, UINT message, WPARAM wparam, LPARAM lparam)
{
    switch(message)
    {
    case WM_KEYDOWN:
        windowMap.at(windowHandle)->KeyDown(wparam);
        return 0;

    case WM_KEYUP:
        windowMap.at(windowHandle)->KeyUp(wparam);
        return 0;

    case WM_MOUSEMOVE:
        windowMap.at(windowHandle)->MouseMove(wparam, lparam);
        return 0;

    case WM_LBUTTONDOWN:
        windowMap.at(windowHandle)->LeftMouseButtonDown(wparam, lparam);
        return 0;

    case WM_LBUTTONUP:
        windowMap.at(windowHandle)->LeftMouseButtonUp(wparam, lparam);
        return 0;

    case WM_RBUTTONDOWN:
        windowMap.at(windowHandle)->RightMouseButtonDown(wparam, lparam);
        return 0;

    case WM_RBUTTONUP:
        windowMap.at(windowHandle)->RightMouseButtonUp(wparam, lparam);
        return 0;

    case WM_MOUSEWHEEL:
        windowMap.at(windowHandle)->MouseScrollWheel(wparam, lparam);
        return 0;

    case WM_SIZE:
        windowMap.at(windowHandle)->WindowResize(wparam, lparam);
        return 0;

    case WM_CLOSE:
        windowMap.at(windowHandle)->onClose();
        return 0;

    case WM_DESTROY:
        PostQuitMessage(0);
        windowMap.at(windowHandle) = NULL;
        return 0;

    default:
        return DefWindowProc(windowHandle, message, wparam, lparam);
    }
}
<|endoftext|>