<commit_before>/*
 * Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
 */

#pragma once

#include <cassert>
#include <algorithm>
#include <uavcan/error.hpp>
#include <uavcan/stdint.hpp>
#include <uavcan/transport/transfer_receiver.hpp>
#include <uavcan/transport/perf_counter.hpp>
#include <uavcan/linked_list.hpp>
#include <uavcan/map.hpp>
#include <uavcan/debug.hpp>
#include <uavcan/transport/crc.hpp>
#include <uavcan/data_type.hpp>

namespace uavcan
{
/**
 * Container for received transfer.
 */
class IncomingTransfer : public ITransferBuffer
{
    MonotonicTime ts_mono_;
    UtcTime ts_utc_;
    TransferType transfer_type_;
    TransferID transfer_id_;
    NodeID src_node_id_;
    uint8_t iface_index_;

    /// That's a no-op, asserts in debug builds
    int write(unsigned offset, const uint8_t* data, unsigned len);

protected:
    IncomingTransfer(MonotonicTime ts_mono, UtcTime ts_utc, TransferType transfer_type,
                     TransferID transfer_id, NodeID source_node_id, uint8_t iface_index)
        : ts_mono_(ts_mono)
        , ts_utc_(ts_utc)
        , transfer_type_(transfer_type)
        , transfer_id_(transfer_id)
        , src_node_id_(source_node_id)
        , iface_index_(iface_index)
    { }

public:
    /**
     * Dispose the payload buffer. Further calls to read() will not be possible.
     */
    virtual void release() { }

    MonotonicTime getMonotonicTimestamp() const { return ts_mono_; }
    UtcTime getUtcTimestamp()             const { return ts_utc_; }
    TransferType getTransferType()        const { return transfer_type_; }
    TransferID getTransferID()            const { return transfer_id_; }
    NodeID getSrcNodeID()                 const { return src_node_id_; }
    uint8_t getIfaceIndex()               const { return iface_index_; }
};

/**
 * Internal.
 */
class SingleFrameIncomingTransfer : public IncomingTransfer
{
    const uint8_t* const payload_;
    const uint8_t payload_len_;
public:
    SingleFrameIncomingTransfer(const RxFrame& frm);
    int read(unsigned offset, uint8_t* data, unsigned len) const;
};

/**
 * Internal.
 */
class MultiFrameIncomingTransfer : public IncomingTransfer, Noncopyable
{
    TransferBufferAccessor& buf_acc_;
public:
    MultiFrameIncomingTransfer(MonotonicTime ts_mono, UtcTime ts_utc, const RxFrame& last_frame,
                               TransferBufferAccessor& tba);
    int read(unsigned offset, uint8_t* data, unsigned len) const;
    void release() { buf_acc_.remove(); }
};

/**
 * Internal, refer to transport dispatcher.
 */
class TransferListenerBase : public LinkedListNode<TransferListenerBase>, Noncopyable
{
    const DataTypeDescriptor& data_type_;
    const TransferCRC crc_base_;                      ///< Pre-initialized with data type hash, thus constant
    TransferPerfCounter& perf_;

    bool checkPayloadCrc(const uint16_t compare_with, const ITransferBuffer& tbb) const;

protected:
    TransferListenerBase(TransferPerfCounter& perf, const DataTypeDescriptor& data_type)
        : data_type_(data_type)
        , crc_base_(data_type.getSignature().toTransferCRC())
        , perf_(perf)
    { }

    virtual ~TransferListenerBase() { }

    void handleReception(TransferReceiver& receiver, const RxFrame& frame, TransferBufferAccessor& tba);

    virtual void handleIncomingTransfer(IncomingTransfer& transfer) = 0;

public:
    const DataTypeDescriptor& getDataTypeDescriptor() const { return data_type_; }

    virtual void handleFrame(const RxFrame& frame) = 0;
    virtual void cleanup(MonotonicTime ts) = 0;
};

/**
 * This class should be derived by transfer receivers (subscribers, servers).
 */
template <unsigned MaxBufSize, unsigned NumStaticBufs, unsigned NumStaticReceivers>
class TransferListener : public TransferListenerBase
{
    typedef TransferBufferManager<MaxBufSize, NumStaticBufs> BufferManager;
    BufferManager bufmgr_;
    Map<TransferBufferManagerKey, TransferReceiver, NumStaticReceivers> receivers_;

    class TimedOutReceiverPredicate
    {
        const MonotonicTime ts_;
        BufferManager& bufmgr_;

    public:
        TimedOutReceiverPredicate(MonotonicTime ts, BufferManager& bufmgr)
            : ts_(ts)
            , bufmgr_(bufmgr)
        { }

        bool operator()(const TransferBufferManagerKey& key, const TransferReceiver& value) const
        {
            if (value.isTimedOut(ts_))
            {
                UAVCAN_TRACE("TransferListener", "Timed out receiver: %s", key.toString().c_str());
                /*
                 * TransferReceivers do not own their buffers - this helps the Map<> container to copy them
                 * around quickly and safely (using default assignment operator). Downside is that we need to
                 * destroy the buffers manually.
                 * Maybe it is not good that the predicate has side effects, but I ran out of better ideas.
                 */
                bufmgr_.remove(key);
                return true;
            }
            return false;
        }
    };

    void cleanup(MonotonicTime ts)
    {
        receivers_.removeWhere(TimedOutReceiverPredicate(ts, bufmgr_));
        assert(receivers_.isEmpty() ? bufmgr_.isEmpty() : 1);
    }

protected:
    void handleFrame(const RxFrame& frame)
    {
        const TransferBufferManagerKey key(frame.getSrcNodeID(), frame.getTransferType());

        TransferReceiver* recv = receivers_.access(key);
        if (recv == NULL)
        {
            if (!frame.isFirst())
            {
                return;
            }

            TransferReceiver new_recv;
            recv = receivers_.insert(key, new_recv);
            if (recv == NULL)
            {
                UAVCAN_TRACE("TransferListener", "Receiver registration failed; frame %s", frame.toString().c_str());
                return;
            }
        }
        TransferBufferAccessor tba(bufmgr_, key);
        handleReception(*recv, frame, tba);
    }

public:
    TransferListener(TransferPerfCounter& perf, const DataTypeDescriptor& data_type, IAllocator& allocator)
        : TransferListenerBase(perf, data_type)
        , bufmgr_(allocator)
        , receivers_(allocator)
    {
        StaticAssert<(NumStaticReceivers >= NumStaticBufs)>::check();  // Otherwise it would be meaningless
    }

    virtual ~TransferListener()
    {
        // Map must be cleared before bufmgr is destructed
        receivers_.removeAll();
    }
};

/**
 * This class should be derived by callers.
 */
template <unsigned MaxBufSize>
class ServiceResponseTransferListener : public TransferListener<MaxBufSize, 1, 1>
{
public:
    struct ExpectedResponseParams
    {
        NodeID src_node_id;
        TransferID transfer_id;

        ExpectedResponseParams()
        {
            assert(!src_node_id.isValid());
        }

        ExpectedResponseParams(NodeID src_node_id, TransferID transfer_id)
            : src_node_id(src_node_id)
            , transfer_id(transfer_id)
        {
            assert(src_node_id.isUnicast());
        }

        bool match(const RxFrame& frame) const
        {
            assert(frame.getTransferType() == TransferTypeServiceResponse);
            return (frame.getSrcNodeID() == src_node_id) && (frame.getTransferID() == transfer_id);
        }
    };

private:
    typedef TransferListener<MaxBufSize, 1, 1> BaseType;

    ExpectedResponseParams response_params_;

    void handleFrame(const RxFrame& frame)
    {
        if (!response_params_.match(frame))
        {
            UAVCAN_TRACE("ServiceResponseTransferListener", "Rejected %s [need snid=%i tid=%i]",
                         frame.toString().c_str(),
                         int(response_params_.src_node_id.get()), int(response_params_.transfer_id.get()));
            return;
        }
        UAVCAN_TRACE("ServiceResponseTransferListener", "Accepted %s", frame.toString().c_str());
        BaseType::handleFrame(frame);
    }

public:
    ServiceResponseTransferListener(TransferPerfCounter& perf, const DataTypeDescriptor& data_type,
                                    IAllocator& allocator)
        : BaseType(perf, data_type, allocator)
    { }

    void setExpectedResponseParams(const ExpectedResponseParams& erp)
    {
        response_params_ = erp;
    }

    const ExpectedResponseParams& getExpectedResponseParams() const { return response_params_; }

    void stopAcceptingAnything()
    {
        response_params_ = ExpectedResponseParams();
    }
};

}
<commit_msg>Removed annoying debug trace in ServiceResponseTransferListener<commit_after>/*
 * Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
 */

#pragma once

#include <cassert>
#include <algorithm>
#include <uavcan/error.hpp>
#include <uavcan/stdint.hpp>
#include <uavcan/transport/transfer_receiver.hpp>
#include <uavcan/transport/perf_counter.hpp>
#include <uavcan/linked_list.hpp>
#include <uavcan/map.hpp>
#include <uavcan/debug.hpp>
#include <uavcan/transport/crc.hpp>
#include <uavcan/data_type.hpp>

namespace uavcan
{
/**
 * Container for received transfer.
 */
class IncomingTransfer : public ITransferBuffer
{
    MonotonicTime ts_mono_;
    UtcTime ts_utc_;
    TransferType transfer_type_;
    TransferID transfer_id_;
    NodeID src_node_id_;
    uint8_t iface_index_;

    /// That's a no-op, asserts in debug builds
    int write(unsigned offset, const uint8_t* data, unsigned len);

protected:
    IncomingTransfer(MonotonicTime ts_mono, UtcTime ts_utc, TransferType transfer_type,
                     TransferID transfer_id, NodeID source_node_id, uint8_t iface_index)
        : ts_mono_(ts_mono)
        , ts_utc_(ts_utc)
        , transfer_type_(transfer_type)
        , transfer_id_(transfer_id)
        , src_node_id_(source_node_id)
        , iface_index_(iface_index)
    { }

public:
    /**
     * Dispose the payload buffer. Further calls to read() will not be possible.
     */
    virtual void release() { }

    MonotonicTime getMonotonicTimestamp() const { return ts_mono_; }
    UtcTime getUtcTimestamp()             const { return ts_utc_; }
    TransferType getTransferType()        const { return transfer_type_; }
    TransferID getTransferID()            const { return transfer_id_; }
    NodeID getSrcNodeID()                 const { return src_node_id_; }
    uint8_t getIfaceIndex()               const { return iface_index_; }
};

/**
 * Internal.
 */
class SingleFrameIncomingTransfer : public IncomingTransfer
{
    const uint8_t* const payload_;
    const uint8_t payload_len_;
public:
    SingleFrameIncomingTransfer(const RxFrame& frm);
    int read(unsigned offset, uint8_t* data, unsigned len) const;
};

/**
 * Internal.
 */
class MultiFrameIncomingTransfer : public IncomingTransfer, Noncopyable
{
    TransferBufferAccessor& buf_acc_;
public:
    MultiFrameIncomingTransfer(MonotonicTime ts_mono, UtcTime ts_utc, const RxFrame& last_frame,
                               TransferBufferAccessor& tba);
    int read(unsigned offset, uint8_t* data, unsigned len) const;
    void release() { buf_acc_.remove(); }
};

/**
 * Internal, refer to transport dispatcher.
 */
class TransferListenerBase : public LinkedListNode<TransferListenerBase>, Noncopyable
{
    const DataTypeDescriptor& data_type_;
    const TransferCRC crc_base_;                      ///< Pre-initialized with data type hash, thus constant
    TransferPerfCounter& perf_;

    bool checkPayloadCrc(const uint16_t compare_with, const ITransferBuffer& tbb) const;

protected:
    TransferListenerBase(TransferPerfCounter& perf, const DataTypeDescriptor& data_type)
        : data_type_(data_type)
        , crc_base_(data_type.getSignature().toTransferCRC())
        , perf_(perf)
    { }

    virtual ~TransferListenerBase() { }

    void handleReception(TransferReceiver& receiver, const RxFrame& frame, TransferBufferAccessor& tba);

    virtual void handleIncomingTransfer(IncomingTransfer& transfer) = 0;

public:
    const DataTypeDescriptor& getDataTypeDescriptor() const { return data_type_; }

    virtual void handleFrame(const RxFrame& frame) = 0;
    virtual void cleanup(MonotonicTime ts) = 0;
};

/**
 * This class should be derived by transfer receivers (subscribers, servers).
 */
template <unsigned MaxBufSize, unsigned NumStaticBufs, unsigned NumStaticReceivers>
class TransferListener : public TransferListenerBase
{
    typedef TransferBufferManager<MaxBufSize, NumStaticBufs> BufferManager;
    BufferManager bufmgr_;
    Map<TransferBufferManagerKey, TransferReceiver, NumStaticReceivers> receivers_;

    class TimedOutReceiverPredicate
    {
        const MonotonicTime ts_;
        BufferManager& bufmgr_;

    public:
        TimedOutReceiverPredicate(MonotonicTime ts, BufferManager& bufmgr)
            : ts_(ts)
            , bufmgr_(bufmgr)
        { }

        bool operator()(const TransferBufferManagerKey& key, const TransferReceiver& value) const
        {
            if (value.isTimedOut(ts_))
            {
                UAVCAN_TRACE("TransferListener", "Timed out receiver: %s", key.toString().c_str());
                /*
                 * TransferReceivers do not own their buffers - this helps the Map<> container to copy them
                 * around quickly and safely (using default assignment operator). Downside is that we need to
                 * destroy the buffers manually.
                 * Maybe it is not good that the predicate has side effects, but I ran out of better ideas.
                 */
                bufmgr_.remove(key);
                return true;
            }
            return false;
        }
    };

    void cleanup(MonotonicTime ts)
    {
        receivers_.removeWhere(TimedOutReceiverPredicate(ts, bufmgr_));
        assert(receivers_.isEmpty() ? bufmgr_.isEmpty() : 1);
    }

protected:
    void handleFrame(const RxFrame& frame)
    {
        const TransferBufferManagerKey key(frame.getSrcNodeID(), frame.getTransferType());

        TransferReceiver* recv = receivers_.access(key);
        if (recv == NULL)
        {
            if (!frame.isFirst())
            {
                return;
            }

            TransferReceiver new_recv;
            recv = receivers_.insert(key, new_recv);
            if (recv == NULL)
            {
                UAVCAN_TRACE("TransferListener", "Receiver registration failed; frame %s", frame.toString().c_str());
                return;
            }
        }
        TransferBufferAccessor tba(bufmgr_, key);
        handleReception(*recv, frame, tba);
    }

public:
    TransferListener(TransferPerfCounter& perf, const DataTypeDescriptor& data_type, IAllocator& allocator)
        : TransferListenerBase(perf, data_type)
        , bufmgr_(allocator)
        , receivers_(allocator)
    {
        StaticAssert<(NumStaticReceivers >= NumStaticBufs)>::check();  // Otherwise it would be meaningless
    }

    virtual ~TransferListener()
    {
        // Map must be cleared before bufmgr is destructed
        receivers_.removeAll();
    }
};

/**
 * This class should be derived by callers.
 */
template <unsigned MaxBufSize>
class ServiceResponseTransferListener : public TransferListener<MaxBufSize, 1, 1>
{
public:
    struct ExpectedResponseParams
    {
        NodeID src_node_id;
        TransferID transfer_id;

        ExpectedResponseParams()
        {
            assert(!src_node_id.isValid());
        }

        ExpectedResponseParams(NodeID src_node_id, TransferID transfer_id)
            : src_node_id(src_node_id)
            , transfer_id(transfer_id)
        {
            assert(src_node_id.isUnicast());
        }

        bool match(const RxFrame& frame) const
        {
            assert(frame.getTransferType() == TransferTypeServiceResponse);
            return (frame.getSrcNodeID() == src_node_id) && (frame.getTransferID() == transfer_id);
        }
    };

private:
    typedef TransferListener<MaxBufSize, 1, 1> BaseType;

    ExpectedResponseParams response_params_;

    void handleFrame(const RxFrame& frame)
    {
        if (response_params_.match(frame))
        {
            BaseType::handleFrame(frame);
        }
    }

public:
    ServiceResponseTransferListener(TransferPerfCounter& perf, const DataTypeDescriptor& data_type,
                                    IAllocator& allocator)
        : BaseType(perf, data_type, allocator)
    { }

    void setExpectedResponseParams(const ExpectedResponseParams& erp)
    {
        response_params_ = erp;
    }

    const ExpectedResponseParams& getExpectedResponseParams() const { return response_params_; }

    void stopAcceptingAnything()
    {
        response_params_ = ExpectedResponseParams();
    }
};

}
<|endoftext|>


<commit_before>//
// BundleActivator.cpp
//
// $Id: //iot/Main/Tf/src/BundleActivator.cpp#2 $
//
// Copyright (c) 2015, Applied Informatics Software Engineering GmbH.
// All rights reserved.
//
// SPDX-License-Identifier: Apache-2.0
//

#include "Poco/OSP/BundleActivator.h"
#include "Poco/OSP/BundleContext.h"
#include "Poco/OSP/Bundle.h"
#include "Poco/OSP/ServiceRegistry.h"
#include "Poco/OSP/ServiceRef.h"
#include "Poco/OSP/ServiceFinder.h"
#include "Poco/OSP/PreferencesService.h"
#include "Poco/RemotingNG/ORB.h"
#include "IoT/Serial/SerialDeviceImpl.h"
#include "IoT/Devices/SerialDeviceServerHelper.h"
#include "Poco/ClassLibrary.h"
#include "Poco/Format.h"
#include "Poco/NumberFormatter.h"
#include <vector>

using Poco::OSP::BundleContext;
using Poco::OSP::ServiceRegistry;
using Poco::OSP::ServiceRef;
using Poco::OSP::ServiceFinder;
using Poco::OSP::Properties;
using Poco::OSP::PreferencesService;

namespace IoT {
namespace Serial {

class BundleActivator: public Poco::OSP::BundleActivator
{
public:
	BundleActivator()
	{
	}

	~BundleActivator()
	{
	}

	void createSerialDevice(const std::string& uid, SerialDeviceImpl::SerialPortPtr pSerialPort)
	{
		typedef Poco::RemotingNG::ServerHelper<IoT::Devices::SerialDevice> ServerHelper;

		Poco::SharedPtr<IoT::Devices::SerialDevice> pDevice = new SerialDeviceImpl(pSerialPort);
		std::string symbolicName = pDevice->getPropertyString("symbolicName");
		Poco::RemotingNG::Identifiable::ObjectId oid = symbolicName;
		oid += '#';
		oid += uid;
		ServerHelper::RemoteObjectPtr pDeviceRemoteObject = ServerHelper::createRemoteObject(pDevice, oid);

		Properties props;
		props.set("io.macchina.device", symbolicName);
		props.set("io.macchina.serialport.device", pSerialPort->device());

		ServiceRef::Ptr pServiceRef = _pContext->registry().registerService(oid, pDeviceRemoteObject, props);
		_serviceRefs.push_back(pServiceRef);
	}

	void start(BundleContext::Ptr pContext)
	{
		_pContext = pContext;
		_pPrefs = ServiceFinder::find<PreferencesService>(pContext);

		Poco::Util::AbstractConfiguration::Keys keys;
		_pPrefs->configuration()->keys("serial.ports", keys);
		int index = 0;
		for (std::vector<std::string>::const_iterator it = keys.begin(); it != keys.end(); ++it)
		{
			std::string baseKey = "serial.ports.";
			baseKey += *it;

			std::string device = _pPrefs->configuration()->getString(baseKey + ".device", "");
			std::string params = _pPrefs->configuration()->getString(baseKey + ".params", "8N1");
			int speed = _pPrefs->configuration()->getInt(baseKey + ".speed", 9600);

			try
			{
				pContext->logger().information(Poco::format("Creating serial port for device '%s'.", device));

				SerialDeviceImpl::SerialPortPtr pSerialPort = new SerialPort(device, speed, params);

				if (_pPrefs->configuration()->getBool(baseKey + ".rs485.enable", false))
				{
					SerialPort::RS485Params rs485Params;
					rs485Params.flags = SerialPort::RS485Params::RS485_ENABLED;
					if (_pPrefs->configuration()->getBool(baseKey + ".rs485.rtsOnSend", false))
						rs485Params.flags |= SerialPort::RS485Params::RS485_RTS_ON_SEND;
					if (_pPrefs->configuration()->getBool(baseKey + ".rs485.rtsAfterSend", false))
						rs485Params.flags |= SerialPort::RS485Params::RS485_RTS_AFTER_SEND;
					if (_pPrefs->configuration()->getBool(baseKey + ".rs485.useGPIO", false))
						rs485Params.flags |= SerialPort::RS485Params::RS485_USE_GPIO;

					rs485Params.delayRTSBeforeSend = _pPrefs->configuration()->getInt(baseKey + ".rs485.delayRTSBeforeSend", 0);
					rs485Params.delayRTSAfterSend  = _pPrefs->configuration()->getInt(baseKey + ".rs485.delayRTSAfterSend", 0);
					rs485Params.gpioPin            = _pPrefs->configuration()->getInt(baseKey + ".rs485.gpioPin", 0);

					pSerialPort->configureRS485(rs485Params);
				}

				createSerialDevice(Poco::NumberFormatter::format(index), pSerialPort);
			}
			catch (Poco::Exception& exc)
			{
				pContext->logger().error(Poco::format("Cannot create serial port for device '%s': %s", device, exc.displayText()));
			}
			index++;
		}
	}

	void stop(BundleContext::Ptr pContext)
	{
		for (std::vector<ServiceRef::Ptr>::iterator it = _serviceRefs.begin(); it != _serviceRefs.end(); ++it)
		{
			_pContext->registry().unregisterService(*it);
		}
		_serviceRefs.clear();
		_pPrefs = 0;
		_pContext = 0;
	}

private:
	BundleContext::Ptr _pContext;
	PreferencesService::Ptr _pPrefs;
	std::vector<ServiceRef::Ptr> _serviceRefs;
};

} } // namespace IoT::Serial

POCO_BEGIN_MANIFEST(Poco::OSP::BundleActivator)
	POCO_EXPORT_CLASS(IoT::Serial::BundleActivator)
POCO_END_MANIFEST
<commit_msg>improve serial configuration: use config key instead of index for uid<commit_after>//
// BundleActivator.cpp
//
// $Id: //iot/Main/Tf/src/BundleActivator.cpp#2 $
//
// Copyright (c) 2015, Applied Informatics Software Engineering GmbH.
// All rights reserved.
//
// SPDX-License-Identifier: Apache-2.0
//

#include "Poco/OSP/BundleActivator.h"
#include "Poco/OSP/BundleContext.h"
#include "Poco/OSP/Bundle.h"
#include "Poco/OSP/ServiceRegistry.h"
#include "Poco/OSP/ServiceRef.h"
#include "Poco/OSP/ServiceFinder.h"
#include "Poco/OSP/PreferencesService.h"
#include "Poco/RemotingNG/ORB.h"
#include "IoT/Serial/SerialDeviceImpl.h"
#include "IoT/Devices/SerialDeviceServerHelper.h"
#include "Poco/ClassLibrary.h"
#include "Poco/Format.h"
#include "Poco/NumberFormatter.h"
#include <vector>

using Poco::OSP::BundleContext;
using Poco::OSP::ServiceRegistry;
using Poco::OSP::ServiceRef;
using Poco::OSP::ServiceFinder;
using Poco::OSP::Properties;
using Poco::OSP::PreferencesService;

namespace IoT {
namespace Serial {

class BundleActivator: public Poco::OSP::BundleActivator
{
public:
	BundleActivator()
	{
	}

	~BundleActivator()
	{
	}

	void createSerialDevice(const std::string& uid, SerialDeviceImpl::SerialPortPtr pSerialPort)
	{
		typedef Poco::RemotingNG::ServerHelper<IoT::Devices::SerialDevice> ServerHelper;

		Poco::SharedPtr<IoT::Devices::SerialDevice> pDevice = new SerialDeviceImpl(pSerialPort);
		std::string symbolicName = pDevice->getPropertyString("symbolicName");
		Poco::RemotingNG::Identifiable::ObjectId oid = symbolicName;
		oid += '#';
		oid += uid;
		ServerHelper::RemoteObjectPtr pDeviceRemoteObject = ServerHelper::createRemoteObject(pDevice, oid);

		Properties props;
		props.set("io.macchina.device", symbolicName);
		props.set("io.macchina.serialport.device", pSerialPort->device());

		ServiceRef::Ptr pServiceRef = _pContext->registry().registerService(oid, pDeviceRemoteObject, props);
		_serviceRefs.push_back(pServiceRef);
	}

	void start(BundleContext::Ptr pContext)
	{
		_pContext = pContext;
		_pPrefs = ServiceFinder::find<PreferencesService>(pContext);

		Poco::Util::AbstractConfiguration::Keys keys;
		_pPrefs->configuration()->keys("serial.ports", keys);

		for (std::vector<std::string>::const_iterator it = keys.begin(); it != keys.end(); ++it)
		{
			std::string baseKey = "serial.ports.";
			baseKey += *it;

			std::string device = _pPrefs->configuration()->getString(baseKey + ".device", "");
			std::string params = _pPrefs->configuration()->getString(baseKey + ".params", "8N1");
			int speed = _pPrefs->configuration()->getInt(baseKey + ".speed", 9600);

			try
			{
				pContext->logger().information(Poco::format("Creating serial port for device '%s'.", device));

				SerialDeviceImpl::SerialPortPtr pSerialPort = new SerialPort(device, speed, params);

				if (_pPrefs->configuration()->getBool(baseKey + ".rs485.enable", false))
				{
					SerialPort::RS485Params rs485Params;
					rs485Params.flags = SerialPort::RS485Params::RS485_ENABLED;
					if (_pPrefs->configuration()->getBool(baseKey + ".rs485.rtsOnSend", false))
						rs485Params.flags |= SerialPort::RS485Params::RS485_RTS_ON_SEND;
					if (_pPrefs->configuration()->getBool(baseKey + ".rs485.rtsAfterSend", false))
						rs485Params.flags |= SerialPort::RS485Params::RS485_RTS_AFTER_SEND;
					if (_pPrefs->configuration()->getBool(baseKey + ".rs485.useGPIO", false))
						rs485Params.flags |= SerialPort::RS485Params::RS485_USE_GPIO;

					rs485Params.delayRTSBeforeSend = _pPrefs->configuration()->getInt(baseKey + ".rs485.delayRTSBeforeSend", 0);
					rs485Params.delayRTSAfterSend  = _pPrefs->configuration()->getInt(baseKey + ".rs485.delayRTSAfterSend", 0);
					rs485Params.gpioPin            = _pPrefs->configuration()->getInt(baseKey + ".rs485.gpioPin", 0);

					pSerialPort->configureRS485(rs485Params);
				}

				createSerialDevice(*it, pSerialPort);
			}
			catch (Poco::Exception& exc)
			{
				pContext->logger().error(Poco::format("Cannot create serial port for device '%s': %s", device, exc.displayText()));
			}
		}
	}

	void stop(BundleContext::Ptr pContext)
	{
		for (std::vector<ServiceRef::Ptr>::iterator it = _serviceRefs.begin(); it != _serviceRefs.end(); ++it)
		{
			_pContext->registry().unregisterService(*it);
		}
		_serviceRefs.clear();
		_pPrefs = 0;
		_pContext = 0;
	}

private:
	BundleContext::Ptr _pContext;
	PreferencesService::Ptr _pPrefs;
	std::vector<ServiceRef::Ptr> _serviceRefs;
};

} } // namespace IoT::Serial

POCO_BEGIN_MANIFEST(Poco::OSP::BundleActivator)
	POCO_EXPORT_CLASS(IoT::Serial::BundleActivator)
POCO_END_MANIFEST
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used 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. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "mockcompositor.h"

namespace Impl {

void shell_surface_move(wl_client *client,
                        wl_resource *surface_resource,
                        wl_resource *input_device_resource,
                        uint32_t time)
{
    Q_UNUSED(client);
    Q_UNUSED(surface_resource);
    Q_UNUSED(input_device_resource);
    Q_UNUSED(time);
}

void shell_surface_resize(wl_client *client,
                          wl_resource *surface_resource,
                          wl_resource *input_device_resource,
                          uint32_t time,
                          uint32_t edges)
{
    Q_UNUSED(client);
    Q_UNUSED(surface_resource);
    Q_UNUSED(input_device_resource);
    Q_UNUSED(time);
    Q_UNUSED(edges);

}

void shell_surface_set_toplevel(wl_client *client,
                                wl_resource *surface_resource)
{
    Q_UNUSED(client);
    Q_UNUSED(surface_resource);
}

void shell_surface_set_transient(wl_client *client,
                                 wl_resource *surface_resource,
                                 wl_resource *parent_surface_resource,
                                 int x,
                                 int y,
                                 uint32_t flags)
{

    Q_UNUSED(client);
    Q_UNUSED(surface_resource);
    Q_UNUSED(parent_surface_resource);
    Q_UNUSED(x);
    Q_UNUSED(y);
    Q_UNUSED(flags);
}

void shell_surface_set_fullscreen(wl_client *client,
                                  wl_resource *surface_resource,
                                  uint32_t method,
                                  uint32_t framerate,
                                  wl_resource *output)
{
    Q_UNUSED(client);
    Q_UNUSED(surface_resource);
    Q_UNUSED(method);
    Q_UNUSED(framerate);
    Q_UNUSED(output);
}

void shell_surface_set_popup(wl_client *client, wl_resource *resource,
                             wl_resource *input_device, uint32_t time,
                             wl_resource *parent,
                             int32_t x, int32_t y,
                             uint32_t flags)
{
    Q_UNUSED(client);
    Q_UNUSED(resource);
    Q_UNUSED(input_device);
    Q_UNUSED(time);
    Q_UNUSED(parent);
    Q_UNUSED(x);
    Q_UNUSED(y);
    Q_UNUSED(flags);
}

void shell_surface_set_maximized(wl_client *client,
                                 wl_resource *surface_resource,
                                 wl_resource *output)
{
    Q_UNUSED(client);
    Q_UNUSED(surface_resource);
    Q_UNUSED(output);
}

static void get_shell_surface(wl_client *client, wl_resource *compositorResource, uint32_t id, wl_resource *surfaceResource)
{
    const struct wl_shell_surface_interface shellSurfaceInterface = {
        shell_surface_move,
        shell_surface_resize,
        shell_surface_set_toplevel,
        shell_surface_set_transient,
        shell_surface_set_fullscreen,
        shell_surface_set_popup,
        shell_surface_set_maximized
    };

    Q_UNUSED(compositorResource);
    wl_client_add_object(client, &wl_shell_surface_interface, &shellSurfaceInterface, id, surfaceResource->data);
}

void Compositor::bindShell(wl_client *client, void *compositorData, uint32_t version, uint32_t id)
{
    static const struct wl_shell_interface shellInterface = {
        get_shell_surface
    };

    Q_UNUSED(version);
    wl_client_add_object(client, &wl_shell_interface, &shellInterface, id, compositorData);
}

}

<commit_msg>Fixed mockshell error in client auto test<commit_after>/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used 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. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "mockcompositor.h"

namespace Impl {

void shell_surface_move(wl_client *client,
                        wl_resource *surface_resource,
                        wl_resource *input_device_resource,
                        uint32_t time)
{
    Q_UNUSED(client);
    Q_UNUSED(surface_resource);
    Q_UNUSED(input_device_resource);
    Q_UNUSED(time);
}

void shell_surface_resize(wl_client *client,
                          wl_resource *surface_resource,
                          wl_resource *input_device_resource,
                          uint32_t time,
                          uint32_t edges)
{
    Q_UNUSED(client);
    Q_UNUSED(surface_resource);
    Q_UNUSED(input_device_resource);
    Q_UNUSED(time);
    Q_UNUSED(edges);

}

void shell_surface_set_toplevel(wl_client *client,
                                wl_resource *surface_resource)
{
    Q_UNUSED(client);
    Q_UNUSED(surface_resource);
}

void shell_surface_set_transient(wl_client *client,
                                 wl_resource *surface_resource,
                                 wl_resource *parent_surface_resource,
                                 int x,
                                 int y,
                                 uint32_t flags)
{

    Q_UNUSED(client);
    Q_UNUSED(surface_resource);
    Q_UNUSED(parent_surface_resource);
    Q_UNUSED(x);
    Q_UNUSED(y);
    Q_UNUSED(flags);
}

void shell_surface_set_fullscreen(wl_client *client,
                                  wl_resource *surface_resource,
                                  uint32_t method,
                                  uint32_t framerate,
                                  wl_resource *output)
{
    Q_UNUSED(client);
    Q_UNUSED(surface_resource);
    Q_UNUSED(method);
    Q_UNUSED(framerate);
    Q_UNUSED(output);
}

void shell_surface_set_popup(wl_client *client, wl_resource *resource,
                             wl_resource *input_device, uint32_t time,
                             wl_resource *parent,
                             int32_t x, int32_t y,
                             uint32_t flags)
{
    Q_UNUSED(client);
    Q_UNUSED(resource);
    Q_UNUSED(input_device);
    Q_UNUSED(time);
    Q_UNUSED(parent);
    Q_UNUSED(x);
    Q_UNUSED(y);
    Q_UNUSED(flags);
}

void shell_surface_set_maximized(wl_client *client,
                                 wl_resource *surface_resource,
                                 wl_resource *output)
{
    Q_UNUSED(client);
    Q_UNUSED(surface_resource);
    Q_UNUSED(output);
}

static void get_shell_surface(wl_client *client, wl_resource *compositorResource, uint32_t id, wl_resource *surfaceResource)
{
    static const struct wl_shell_surface_interface shellSurfaceInterface = {
        shell_surface_move,
        shell_surface_resize,
        shell_surface_set_toplevel,
        shell_surface_set_transient,
        shell_surface_set_fullscreen,
        shell_surface_set_popup,
        shell_surface_set_maximized
    };

    Q_UNUSED(compositorResource);
    wl_client_add_object(client, &wl_shell_surface_interface, &shellSurfaceInterface, id, surfaceResource->data);
}

void Compositor::bindShell(wl_client *client, void *compositorData, uint32_t version, uint32_t id)
{
    static const struct wl_shell_interface shellInterface = {
        get_shell_surface
    };

    Q_UNUSED(version);
    wl_client_add_object(client, &wl_shell_interface, &shellInterface, id, compositorData);
}

}

<|endoftext|>


<commit_before>/*********************************************************************************
 *
 * Inviwo - Interactive Visualization Workshop
 *
 * Copyright (c) 2015 Inviwo Foundation
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 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.
 *
 *********************************************************************************/

#include <inviwo/core/util/tinydirinterface.h>
#include <inviwo/core/util/exception.h>
#include <cerrno>

namespace inviwo {

TinyDirInterface::TinyDirInterface()
    : isOpen_(false)
    , mode_(ListMode::FilesOnly)
    , path_()
{
    // initialize tinydir struct
    memset(&resource_, 0, sizeof(tinydir_dir));
}

TinyDirInterface::~TinyDirInterface() {
    close();
}

bool TinyDirInterface::open(const std::string &path) {
    // close previous directory
    close();

    if (path.empty())
        return false;

    path_ = path;
    int errCode = tinydir_open(&resource_, path_.c_str());
    isOpen_ = (errCode == 0);

    return isOpen_;
}

void TinyDirInterface::close() {
    if (isOpen_) {
        path_ = std::string();
        tinydir_close(&resource_);
        isOpen_ = false;
    }
}

void TinyDirInterface::setListMode(ListMode mode) {
    mode_ = mode;
}

TinyDirInterface::ListMode TinyDirInterface::getListMode() const {
    return mode_;
}

bool TinyDirInterface::isOpen() const {
    return isOpen_;
}

bool TinyDirInterface::isNextEntryAvailable() const {
    return (isOpen_ && resource_.has_next);
}

std::string TinyDirInterface::getNextEntry() {
    return getNextEntry(false);

}

std::string TinyDirInterface::getNextEntryWithBasePath() {
    return getNextEntry(true);
}

std::vector<std::string> TinyDirInterface::getContents() {
    std::vector<std::string> files;
    while (isNextEntryAvailable()) {
        std::string entry{ getNextEntry(false) };
        // getNextEntry might return an empty string depending on the ListMode setting
        if (!entry.empty()) {
            files.push_back(entry);
        }
    }

    // ascending sort based on file name and then on the extension
    std::sort(files.begin(), files.end(), [](const std::string &a, const std::string &b) {
        std::size_t pos = a.rfind(".");
        bool extFound = (pos != std::string::npos);
        std::string filenameA{ extFound ? a.substr(0, pos) : a };
        std::string extA{ extFound ? a.substr(pos + 1, std::string::npos) : "" };

        pos = b.rfind(".");
        extFound = (pos != std::string::npos);
        std::string filenameB{ extFound ? b.substr(0, pos) : b };
        std::string extB{ extFound ? b.substr(pos + 1, std::string::npos) : "" };

        int nameComp = filenameA.compare(filenameB);
        // file a is to be sorted before b, if the file name is 'smaller' in
        // lexical order or if the file names are identical and the extension is 'smaller'
        return ((nameComp < 0) || ((nameComp == 0) && (extA.compare(extB) < 0)));
    });
    return files;
}

std::vector<std::string> TinyDirInterface::getContentsWithBasePath() {
    std::vector<std::string> files;
    while (isNextEntryAvailable()) {
        files.push_back(getNextEntry(true));
    }
    return files;
}

std::string TinyDirInterface::getNextEntry(bool includeBasePath) {
    if (!isOpen_)
        return{};

    std::string str{};
    bool foundEntry = false;
    while (resource_.has_next && !foundEntry) {
        // query next entry
        tinydir_file file;
        int errnum = tinydir_readfile(&resource_, &file);
        if (errnum != 0) {
            // cannot access entry
            std::string errMsg{ "Cannot access entry in \"" };
            errMsg.append(resource_.path);
            errMsg.append("\": ");
            errMsg.append(strerror(errnum));

            throw FileException(errMsg);
        }

        // check whether entry matches current ListMode setting
        foundEntry = ((mode_ == ListMode::FilesAndDirectories)
            || ((file.is_dir == 0) != (mode_ == ListMode::DirectoriesOnly)));
        if (foundEntry) {
            str = (includeBasePath ? file.path : file.name);
        }
        tinydir_next(&resource_);
    }
    // close resource if no more entries are available
    if (!resource_.has_next) {
        close();
    }
    return str;
}

} // namespace inviwo
<commit_msg>Core: PCH fix in tinydirinterface.cpp<commit_after>/*********************************************************************************
 *
 * Inviwo - Interactive Visualization Workshop
 *
 * Copyright (c) 2015 Inviwo Foundation
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 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.
 *
 *********************************************************************************/

#include <inviwo/core/util/tinydirinterface.h>
#include <inviwo/core/util/exception.h>
#include <algorithm>
#include <cerrno>

namespace inviwo {

TinyDirInterface::TinyDirInterface()
    : isOpen_(false)
    , mode_(ListMode::FilesOnly)
    , path_()
{
    // initialize tinydir struct
    memset(&resource_, 0, sizeof(tinydir_dir));
}

TinyDirInterface::~TinyDirInterface() {
    close();
}

bool TinyDirInterface::open(const std::string &path) {
    // close previous directory
    close();

    if (path.empty())
        return false;

    path_ = path;
    int errCode = tinydir_open(&resource_, path_.c_str());
    isOpen_ = (errCode == 0);

    return isOpen_;
}

void TinyDirInterface::close() {
    if (isOpen_) {
        path_ = std::string();
        tinydir_close(&resource_);
        isOpen_ = false;
    }
}

void TinyDirInterface::setListMode(ListMode mode) {
    mode_ = mode;
}

TinyDirInterface::ListMode TinyDirInterface::getListMode() const {
    return mode_;
}

bool TinyDirInterface::isOpen() const {
    return isOpen_;
}

bool TinyDirInterface::isNextEntryAvailable() const {
    return (isOpen_ && resource_.has_next);
}

std::string TinyDirInterface::getNextEntry() {
    return getNextEntry(false);

}

std::string TinyDirInterface::getNextEntryWithBasePath() {
    return getNextEntry(true);
}

std::vector<std::string> TinyDirInterface::getContents() {
    std::vector<std::string> files;
    while (isNextEntryAvailable()) {
        std::string entry{ getNextEntry(false) };
        // getNextEntry might return an empty string depending on the ListMode setting
        if (!entry.empty()) {
            files.push_back(entry);
        }
    }

    // ascending sort based on file name and then on the extension
    std::sort(files.begin(), files.end(), [](const std::string &a, const std::string &b) {
        std::size_t pos = a.rfind(".");
        bool extFound = (pos != std::string::npos);
        std::string filenameA{ extFound ? a.substr(0, pos) : a };
        std::string extA{ extFound ? a.substr(pos + 1, std::string::npos) : "" };

        pos = b.rfind(".");
        extFound = (pos != std::string::npos);
        std::string filenameB{ extFound ? b.substr(0, pos) : b };
        std::string extB{ extFound ? b.substr(pos + 1, std::string::npos) : "" };

        int nameComp = filenameA.compare(filenameB);
        // file a is to be sorted before b, if the file name is 'smaller' in
        // lexical order or if the file names are identical and the extension is 'smaller'
        return ((nameComp < 0) || ((nameComp == 0) && (extA.compare(extB) < 0)));
    });
    return files;
}

std::vector<std::string> TinyDirInterface::getContentsWithBasePath() {
    std::vector<std::string> files;
    while (isNextEntryAvailable()) {
        files.push_back(getNextEntry(true));
    }
    return files;
}

std::string TinyDirInterface::getNextEntry(bool includeBasePath) {
    if (!isOpen_)
        return{};

    std::string str{};
    bool foundEntry = false;
    while (resource_.has_next && !foundEntry) {
        // query next entry
        tinydir_file file;
        int errnum = tinydir_readfile(&resource_, &file);
        if (errnum != 0) {
            // cannot access entry
            std::string errMsg{ "Cannot access entry in \"" };
            errMsg.append(resource_.path);
            errMsg.append("\": ");
            errMsg.append(strerror(errnum));

            throw FileException(errMsg);
        }

        // check whether entry matches current ListMode setting
        foundEntry = ((mode_ == ListMode::FilesAndDirectories)
            || ((file.is_dir == 0) != (mode_ == ListMode::DirectoriesOnly)));
        if (foundEntry) {
            str = (includeBasePath ? file.path : file.name);
        }
        tinydir_next(&resource_);
    }
    // close resource if no more entries are available
    if (!resource_.has_next) {
        close();
    }
    return str;
}

} // namespace inviwo
<|endoftext|>


<commit_before>//
//  ex9_33.cpp
//  Exercise 9.33
//
//  Created by pezy on 12/3/14.
//
//  @Brief  In the final example in this section what would happen
//          if we did not assign the result of insert to begin?
//          Write a program that omits this assignment to see if your expectation was correct.
//  @Answer crash, cause the iterator is invalid after insert.

#include <iostream>
#include <vector>

using std::vector; using std::cout; using std::endl;

int main()
{
    vector<int> v{ 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    auto begin = v.begin();
    while (begin != v.end()) {
        ++begin;
        /*begin = */v.insert(begin, 42);
        ++begin;
    }

    for (auto i : v)
        cout << i << " ";

    return 0;
}
<commit_msg>Update ex9_33.cpp<commit_after>//
//  ex9_33.cpp
//  Exercise 9.33
//
//  Created by pezy on 12/3/14.
//
//  @Brief  In the final example in this section what would happen
//          if we did not assign the result of insert to begin?
//          Write a program that omits this assignment to see if your expectation was correct.
//  @Answer Crash, because the iterator is invalid after inserting.

#include <iostream>
#include <vector>

using std::vector; using std::cout; using std::endl;

int main()
{
    vector<int> v{ 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    auto begin = v.begin();
    while (begin != v.end()) {
        ++begin;
        /*begin = */v.insert(begin, 42);
        ++begin;
    }

    for (auto i : v)
        cout << i << " ";

    return 0;
}
<|endoftext|>


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

#include "DesktopOptions.hpp"

#include <QtGui>
#include <QApplication>
#include <QDesktopWidget>

#include <core/Random.hpp>
#include <core/system/System.hpp>
#include <core/system/Environment.hpp>

#include "DesktopInfo.hpp"
#include "DesktopUtils.hpp"

using namespace rstudio::core;

namespace rstudio {
namespace desktop {

#ifdef _WIN32
// Defined in DesktopRVersion.cpp
QString binDirToHomeDir(QString binDir);
#endif

QString scratchPath;

Options& options()
{
   static Options singleton;
   return singleton;
}

void Options::initFromCommandLine(const QStringList& arguments)
{
   for (int i=1; i<arguments.size(); i++)
   {
      const QString &arg = arguments.at(i);
      if (arg == QString::fromUtf8(kRunDiagnosticsOption))
         runDiagnostics_ = true;
   }

   // synchronize zoom level with desktop frame
   desktopInfo().setZoomLevel(zoomLevel());
}

void Options::restoreMainWindowBounds(QMainWindow* win)
{
   // NOTE: win->saveGeometry and win->restoreGeometry are unreliable in
   // Qt 5.11.1 (they do not successfully restore the window size if the
   // display bounds have changed) so we explicitly save and restore the
   // bounds as a rectangle
   QString key = QStringLiteral("mainwindow/bounds");
   if (settings_.contains(key))
   {
      QRect bounds = settings_.value(key).toRect();
      win->setGeometry(bounds);
   }
   else
   {
      QSize size = QSize(1200, 900).boundedTo(
            QApplication::desktop()->availableGeometry().size());
      if (size.width() > 800 && size.height() > 500)
      {
         // Only use default size if it seems sane; otherwise let Qt set it
         win->resize(size);
      }
   }
}

void Options::saveMainWindowBounds(QMainWindow* win)
{
   // NOTE: win->saveGeometry and win->restoreGeometry are unreliable in
   // Qt 5.11.1 (they do not successfully restore the window size if the
   // display bounds have changed) so we explicitly save and restore the
   // bounds as a rectangle
   QVariant bounds = win->geometry();
   settings_.setValue(QStringLiteral("mainwindow/bounds"), bounds);
}

QString Options::portNumber() const
{
   // lookup / generate on demand
   if (portNumber_.length() == 0)
   {
      // Use a random-ish port number to avoid collisions between different
      // instances of rdesktop-launched rsessions
      int base = std::abs(core::random::uniformRandomInteger<int>());
      portNumber_ = QString::number((base % 40000) + 8080);

      // recalculate the local peer and set RS_LOCAL_PEER so that
      // rsession and it's children can use it
#ifdef _WIN32
      QString localPeer = QString::fromUtf8("\\\\.\\pipe\\") +
                          portNumber_ + QString::fromUtf8("-rsession");
      localPeer_ = localPeer.toUtf8().constData();
      core::system::setenv("RS_LOCAL_PEER", localPeer_);
#endif
   }

   return portNumber_;
}

QString Options::newPortNumber()
{
   portNumber_.clear();
   return portNumber();
}

std::string Options::localPeer() const
{
   return localPeer_;
}

namespace {
QString findFirstMatchingFont(const QStringList& fonts,
                              QString defaultFont,
                              bool fixedWidthOnly)
{
   for (int i = 0; i < fonts.size(); i++)
   {
      QFont font(fonts.at(i));
      if (font.exactMatch())
         if (!fixedWidthOnly || isFixedWidthFont(QFont(fonts.at(i))))
            return fonts.at(i);
   }
   return defaultFont;
}
} // anonymous namespace

QString Options::proportionalFont() const
{
   static QString detectedFont;

   QString font =
         settings_.value(QString::fromUtf8("font.proportional")).toString();
   if (!font.isEmpty())
   {
      return font;
   }

   if (!detectedFont.isEmpty())
      return detectedFont;

   QStringList fontList;
#if defined(_WIN32)
   fontList <<
           QString::fromUtf8("Segoe UI") << QString::fromUtf8("Verdana") <<  // Windows
           QString::fromUtf8("Lucida Sans") << QString::fromUtf8("DejaVu Sans") <<  // Linux
           QString::fromUtf8("Lucida Grande") <<          // Mac
           QString::fromUtf8("Helvetica");
#elif defined(__APPLE__)
   fontList <<
           QString::fromUtf8("Lucida Grande") <<          // Mac
           QString::fromUtf8("Lucida Sans") << QString::fromUtf8("DejaVu Sans") <<  // Linux
           QString::fromUtf8("Segoe UI") << QString::fromUtf8("Verdana") <<  // Windows
           QString::fromUtf8("Helvetica");
#else
   fontList <<
           QString::fromUtf8("Lucida Sans") << QString::fromUtf8("DejaVu Sans") <<  // Linux
           QString::fromUtf8("Lucida Grande") <<          // Mac
           QString::fromUtf8("Segoe UI") << QString::fromUtf8("Verdana") <<  // Windows
           QString::fromUtf8("Helvetica");
#endif
   return QString::fromUtf8("\"") +
         findFirstMatchingFont(fontList, QString::fromUtf8("sans-serif"), false) +
         QString::fromUtf8("\"");
}

void Options::setFixedWidthFont(QString font)
{
   if (font.isEmpty())
      settings_.remove(QString::fromUtf8("font.fixedWidth"));
   else
      settings_.setValue(QString::fromUtf8("font.fixedWidth"),
                         font);
}

QString Options::fixedWidthFont() const
{
   static QString detectedFont;

   QString font =
         settings_.value(QString::fromUtf8("font.fixedWidth")).toString();
   if (!font.isEmpty())
   {
      return QString::fromUtf8("\"") + font + QString::fromUtf8("\"");
   }

   if (!detectedFont.isEmpty())
      return detectedFont;

   QStringList fontList;
   fontList <<
#if defined(Q_OS_MAC)
           QString::fromUtf8("Monaco")
#elif defined (Q_OS_LINUX)
           QString::fromUtf8("Ubuntu Mono") << QString::fromUtf8("Droid Sans Mono") << QString::fromUtf8("DejaVu Sans Mono") << QString::fromUtf8("Monospace")
#else
           QString::fromUtf8("Lucida Console") << QString::fromUtf8("Consolas") // Windows;
#endif
           ;

   return detectedFont = QString::fromUtf8("\"") +
         findFirstMatchingFont(fontList, QString::fromUtf8("monospace"), true) +
         QString::fromUtf8("\"");
}

double Options::zoomLevel() const
{
   QVariant zoom = settings_.value(QString::fromUtf8("view.zoomLevel"), 1.0);
   return zoom.toDouble();
}

void Options::setZoomLevel(double zoomLevel)
{
   desktopInfo().setZoomLevel(zoomLevel);
   settings_.setValue(QString::fromUtf8("view.zoomLevel"), zoomLevel);
}

bool Options::enableAccessibility() const
{
   QVariant accessibility = settings_.value(QString::fromUtf8("view.accessibility"), false);
   return accessibility.toBool();
}

void Options::setEnableAccessibility(bool enable)
{
   settings_.setValue(QString::fromUtf8("view.accessibility"), enable);
}

bool Options::clipboardMonitoring() const
{
   QVariant monitoring = settings_.value(QString::fromUtf8("clipboard.monitoring"), true);
   return monitoring.toBool();
}

void Options::setClipboardMonitoring(bool monitoring)
{
   settings_.setValue(QString::fromUtf8("clipboard.monitoring"), monitoring);
}

#ifdef _WIN32
QString Options::rBinDir() const
{
   QString value = settings_.value(QString::fromUtf8("RBinDir")).toString();
   return value.isNull() ? QString() : value;
}

void Options::setRBinDir(QString path)
{
   settings_.setValue(QString::fromUtf8("RBinDir"), path);
}

#endif

FilePath Options::scriptsPath() const
{
   return scriptsPath_;
}

void Options::setScriptsPath(const FilePath& scriptsPath)
{
   scriptsPath_ = scriptsPath;
}

FilePath Options::executablePath() const
{
   if (executablePath_.empty())
   {
      Error error = core::system::executablePath(QApplication::arguments().at(0).toUtf8(),
                                                 &executablePath_);
      if (error)
         LOG_ERROR(error);
   }
   return executablePath_;
}

FilePath Options::supportingFilePath() const
{
   if (supportingFilePath_.empty())
   {
      // default to install path
      core::system::installPath("..",
                                QApplication::arguments().at(0).toUtf8(),
                                &supportingFilePath_);

      // adapt for OSX resource bundles
#ifdef __APPLE__
         if (supportingFilePath_.complete("Info.plist").exists())
            supportingFilePath_ = supportingFilePath_.complete("Resources");
#endif
   }
   return supportingFilePath_;
}

FilePath Options::wwwDocsPath() const
{
   FilePath supportingFilePath = desktop::options().supportingFilePath();
   FilePath wwwDocsPath = supportingFilePath.complete("www/docs");
   if (!wwwDocsPath.exists())
      wwwDocsPath = supportingFilePath.complete("../gwt/www/docs");
#ifdef __APPLE__
   if (!wwwDocsPath.exists())
      wwwDocsPath = supportingFilePath.complete("../../../../../gwt/www/docs");
#endif
   return wwwDocsPath;
}

#ifdef _WIN32

FilePath Options::urlopenerPath() const
{
   FilePath parentDir = scriptsPath();

   // detect dev configuration
   if (parentDir.filename() == "desktop")
      parentDir = parentDir.complete("urlopener");

   return parentDir.complete("urlopener.exe");
}

FilePath Options::rsinversePath() const
{
   FilePath parentDir = scriptsPath();

   // detect dev configuration
   if (parentDir.filename() == "desktop")
      parentDir = parentDir.complete("synctex/rsinverse");

   return parentDir.complete("rsinverse.exe");
}

#endif

QStringList Options::ignoredUpdateVersions() const
{
   return settings_.value(QString::fromUtf8("ignoredUpdateVersions"), QStringList()).toStringList();
}

void Options::setIgnoredUpdateVersions(const QStringList& ignoredVersions)
{
   settings_.setValue(QString::fromUtf8("ignoredUpdateVersions"), ignoredVersions);
}

core::FilePath Options::scratchTempDir(core::FilePath defaultPath)
{
   core::FilePath dir(scratchPath.toUtf8().constData());

   if (!dir.empty() && dir.exists())
   {
      dir = dir.childPath("tmp");
      core::Error error = dir.ensureDirectory();
      if (!error)
         return dir;
   }
   return defaultPath;
}

void Options::cleanUpScratchTempDir()
{
   core::FilePath temp = scratchTempDir(core::FilePath());
   if (!temp.empty())
      temp.removeIfExists();
}

} // namespace desktop
} // namespace rstudio
<commit_msg>fix bug where fallback font would not be successfully used<commit_after>/*
 * DesktopOptions.cpp
 *
 * Copyright (C) 2009-18 by RStudio, Inc.
 *
 * Unless you have received this program directly from RStudio pursuant
 * to the terms of a commercial license agreement with RStudio, then
 * this program is licensed to you under the terms of version 3 of the
 * GNU Affero General Public License. This program is distributed WITHOUT
 * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
 * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
 *
 */

#include "DesktopOptions.hpp"

#include <QtGui>
#include <QApplication>
#include <QDesktopWidget>

#include <core/Random.hpp>
#include <core/system/System.hpp>
#include <core/system/Environment.hpp>

#include "DesktopInfo.hpp"
#include "DesktopUtils.hpp"

using namespace rstudio::core;

namespace rstudio {
namespace desktop {

#ifdef _WIN32
// Defined in DesktopRVersion.cpp
QString binDirToHomeDir(QString binDir);
#endif

QString scratchPath;

Options& options()
{
   static Options singleton;
   return singleton;
}

void Options::initFromCommandLine(const QStringList& arguments)
{
   for (int i=1; i<arguments.size(); i++)
   {
      const QString &arg = arguments.at(i);
      if (arg == QString::fromUtf8(kRunDiagnosticsOption))
         runDiagnostics_ = true;
   }

   // synchronize zoom level with desktop frame
   desktopInfo().setZoomLevel(zoomLevel());
}

void Options::restoreMainWindowBounds(QMainWindow* win)
{
   // NOTE: win->saveGeometry and win->restoreGeometry are unreliable in
   // Qt 5.11.1 (they do not successfully restore the window size if the
   // display bounds have changed) so we explicitly save and restore the
   // bounds as a rectangle
   QString key = QStringLiteral("mainwindow/bounds");
   if (settings_.contains(key))
   {
      QRect bounds = settings_.value(key).toRect();
      win->setGeometry(bounds);
   }
   else
   {
      QSize size = QSize(1200, 900).boundedTo(
            QApplication::desktop()->availableGeometry().size());
      if (size.width() > 800 && size.height() > 500)
      {
         // Only use default size if it seems sane; otherwise let Qt set it
         win->resize(size);
      }
   }
}

void Options::saveMainWindowBounds(QMainWindow* win)
{
   // NOTE: win->saveGeometry and win->restoreGeometry are unreliable in
   // Qt 5.11.1 (they do not successfully restore the window size if the
   // display bounds have changed) so we explicitly save and restore the
   // bounds as a rectangle
   QVariant bounds = win->geometry();
   settings_.setValue(QStringLiteral("mainwindow/bounds"), bounds);
}

QString Options::portNumber() const
{
   // lookup / generate on demand
   if (portNumber_.length() == 0)
   {
      // Use a random-ish port number to avoid collisions between different
      // instances of rdesktop-launched rsessions
      int base = std::abs(core::random::uniformRandomInteger<int>());
      portNumber_ = QString::number((base % 40000) + 8080);

      // recalculate the local peer and set RS_LOCAL_PEER so that
      // rsession and it's children can use it
#ifdef _WIN32
      QString localPeer = QString::fromUtf8("\\\\.\\pipe\\") +
                          portNumber_ + QString::fromUtf8("-rsession");
      localPeer_ = localPeer.toUtf8().constData();
      core::system::setenv("RS_LOCAL_PEER", localPeer_);
#endif
   }

   return portNumber_;
}

QString Options::newPortNumber()
{
   portNumber_.clear();
   return portNumber();
}

std::string Options::localPeer() const
{
   return localPeer_;
}

namespace {
QString findFirstMatchingFont(const QStringList& fonts,
                              QString defaultFont,
                              bool fixedWidthOnly)
{
   for (int i = 0; i < fonts.size(); i++)
   {
      QFont font(fonts.at(i));
      if (font.exactMatch())
         if (!fixedWidthOnly || isFixedWidthFont(QFont(fonts.at(i))))
            return fonts.at(i);
   }
   return defaultFont;
}
} // anonymous namespace

QString Options::proportionalFont() const
{
   static QString detectedFont;

   QString font =
         settings_.value(QString::fromUtf8("font.proportional")).toString();
   if (!font.isEmpty())
   {
      return font;
   }

   if (!detectedFont.isEmpty())
      return detectedFont;

   QStringList fontList;
#if defined(_WIN32)
   fontList <<
           QString::fromUtf8("Segoe UI") << QString::fromUtf8("Verdana") <<  // Windows
           QString::fromUtf8("Lucida Sans") << QString::fromUtf8("DejaVu Sans") <<  // Linux
           QString::fromUtf8("Lucida Grande") <<          // Mac
           QString::fromUtf8("Helvetica");
#elif defined(__APPLE__)
   fontList <<
           QString::fromUtf8("Lucida Grande") <<          // Mac
           QString::fromUtf8("Lucida Sans") << QString::fromUtf8("DejaVu Sans") <<  // Linux
           QString::fromUtf8("Segoe UI") << QString::fromUtf8("Verdana") <<  // Windows
           QString::fromUtf8("Helvetica");
#else
   fontList <<
           QString::fromUtf8("Lucida Sans") << QString::fromUtf8("DejaVu Sans") <<  // Linux
           QString::fromUtf8("Lucida Grande") <<          // Mac
           QString::fromUtf8("Segoe UI") << QString::fromUtf8("Verdana") <<  // Windows
           QString::fromUtf8("Helvetica");
#endif

   QString sansSerif = QStringLiteral("sans-serif");
   QString selectedFont = findFirstMatchingFont(fontList, sansSerif, false);

   // NOTE: browsers will refuse to render a default font if the name is in
   // quotes; e.g. "sans-serif" is a signal to look for a font called sans-serif
   // rather than use the default sans-serif font!
   if (selectedFont == sansSerif)
      return sansSerif;
   else
      return QStringLiteral("\"%1\"").arg(selectedFont);
}

void Options::setFixedWidthFont(QString font)
{
   if (font.isEmpty())
      settings_.remove(QString::fromUtf8("font.fixedWidth"));
   else
      settings_.setValue(QString::fromUtf8("font.fixedWidth"),
                         font);
}

QString Options::fixedWidthFont() const
{
   static QString detectedFont;

   QString font =
         settings_.value(QString::fromUtf8("font.fixedWidth")).toString();
   if (!font.isEmpty())
   {
      return QString::fromUtf8("\"") + font + QString::fromUtf8("\"");
   }

   if (!detectedFont.isEmpty())
      return detectedFont;

   QStringList fontList;
   fontList <<
#if defined(Q_OS_MAC)
           QString::fromUtf8("Monaco")
#elif defined (Q_OS_LINUX)
           QString::fromUtf8("Ubuntu Mono") << QString::fromUtf8("Droid Sans Mono") << QString::fromUtf8("DejaVu Sans Mono") << QString::fromUtf8("Monospace")
#else
           QString::fromUtf8("Lucida Console") << QString::fromUtf8("Consolas") // Windows;
#endif
           ;

   // NOTE: browsers will refuse to render a default font if the name is in
   // quotes; e.g. "monospace" is a signal to look for a font called monospace
   // rather than use the default monospace font!
   QString monospace = QStringLiteral("monospace");
   QString matchingFont = findFirstMatchingFont(fontList, monospace, true);
   if (matchingFont == monospace)
      return monospace;
   else
      return QStringLiteral("\"%1\"").arg(matchingFont);
}

double Options::zoomLevel() const
{
   QVariant zoom = settings_.value(QString::fromUtf8("view.zoomLevel"), 1.0);
   return zoom.toDouble();
}

void Options::setZoomLevel(double zoomLevel)
{
   desktopInfo().setZoomLevel(zoomLevel);
   settings_.setValue(QString::fromUtf8("view.zoomLevel"), zoomLevel);
}

bool Options::enableAccessibility() const
{
   QVariant accessibility = settings_.value(QString::fromUtf8("view.accessibility"), false);
   return accessibility.toBool();
}

void Options::setEnableAccessibility(bool enable)
{
   settings_.setValue(QString::fromUtf8("view.accessibility"), enable);
}

bool Options::clipboardMonitoring() const
{
   QVariant monitoring = settings_.value(QString::fromUtf8("clipboard.monitoring"), true);
   return monitoring.toBool();
}

void Options::setClipboardMonitoring(bool monitoring)
{
   settings_.setValue(QString::fromUtf8("clipboard.monitoring"), monitoring);
}

#ifdef _WIN32
QString Options::rBinDir() const
{
   QString value = settings_.value(QString::fromUtf8("RBinDir")).toString();
   return value.isNull() ? QString() : value;
}

void Options::setRBinDir(QString path)
{
   settings_.setValue(QString::fromUtf8("RBinDir"), path);
}

#endif

FilePath Options::scriptsPath() const
{
   return scriptsPath_;
}

void Options::setScriptsPath(const FilePath& scriptsPath)
{
   scriptsPath_ = scriptsPath;
}

FilePath Options::executablePath() const
{
   if (executablePath_.empty())
   {
      Error error = core::system::executablePath(QApplication::arguments().at(0).toUtf8(),
                                                 &executablePath_);
      if (error)
         LOG_ERROR(error);
   }
   return executablePath_;
}

FilePath Options::supportingFilePath() const
{
   if (supportingFilePath_.empty())
   {
      // default to install path
      core::system::installPath("..",
                                QApplication::arguments().at(0).toUtf8(),
                                &supportingFilePath_);

      // adapt for OSX resource bundles
#ifdef __APPLE__
         if (supportingFilePath_.complete("Info.plist").exists())
            supportingFilePath_ = supportingFilePath_.complete("Resources");
#endif
   }
   return supportingFilePath_;
}

FilePath Options::wwwDocsPath() const
{
   FilePath supportingFilePath = desktop::options().supportingFilePath();
   FilePath wwwDocsPath = supportingFilePath.complete("www/docs");
   if (!wwwDocsPath.exists())
      wwwDocsPath = supportingFilePath.complete("../gwt/www/docs");
#ifdef __APPLE__
   if (!wwwDocsPath.exists())
      wwwDocsPath = supportingFilePath.complete("../../../../../gwt/www/docs");
#endif
   return wwwDocsPath;
}

#ifdef _WIN32

FilePath Options::urlopenerPath() const
{
   FilePath parentDir = scriptsPath();

   // detect dev configuration
   if (parentDir.filename() == "desktop")
      parentDir = parentDir.complete("urlopener");

   return parentDir.complete("urlopener.exe");
}

FilePath Options::rsinversePath() const
{
   FilePath parentDir = scriptsPath();

   // detect dev configuration
   if (parentDir.filename() == "desktop")
      parentDir = parentDir.complete("synctex/rsinverse");

   return parentDir.complete("rsinverse.exe");
}

#endif

QStringList Options::ignoredUpdateVersions() const
{
   return settings_.value(QString::fromUtf8("ignoredUpdateVersions"), QStringList()).toStringList();
}

void Options::setIgnoredUpdateVersions(const QStringList& ignoredVersions)
{
   settings_.setValue(QString::fromUtf8("ignoredUpdateVersions"), ignoredVersions);
}

core::FilePath Options::scratchTempDir(core::FilePath defaultPath)
{
   core::FilePath dir(scratchPath.toUtf8().constData());

   if (!dir.empty() && dir.exists())
   {
      dir = dir.childPath("tmp");
      core::Error error = dir.ensureDirectory();
      if (!error)
         return dir;
   }
   return defaultPath;
}

void Options::cleanUpScratchTempDir()
{
   core::FilePath temp = scratchTempDir(core::FilePath());
   if (!temp.empty())
      temp.removeIfExists();
}

} // namespace desktop
} // namespace rstudio
<|endoftext|>


<commit_before>/*
* This file is part of ATLAS. It is subject to the license terms in
* the LICENSE file found in the top-level directory of this distribution.
* (Also avialable at http://www.apache.org/licenses/LICENSE-2.0.txt)
* You may not use this file except in compliance with the License.
*/
#include <iostream>
#include <assimp/postprocess.h>
#include <assimp/scene.h>
#include "AssimpImporter.hpp"

namespace AssimpWorker {

	AssimpImporter::AssimpImporter() :
		importer()
	{
		return;
	}

	AssimpImporter::~AssimpImporter(){
		return;
	}

	const aiScene* AssimpImporter::importSceneFromFile(std::string fileName, Log& log){
		importer.SetPropertyBool(AI_CONFIG_PP_FD_REMOVE, true); //remove degenerate polys
		importer.SetPropertyInteger(AI_CONFIG_PP_SBP_REMOVE, aiPrimitiveType_LINE | aiPrimitiveType_POINT); //Drop all primitives that aren't triangles
		const aiScene* scene = importer.ReadFile(fileName, aiProcessPreset_TargetRealtime_Quality);
		if (!scene) {
			log.error("Scene not imported: "+fileName);
		}
		log.error(importer.GetErrorString());
		return scene;
	}

}
<commit_msg>AssimpWorker: only log error if one occured, also add file name of errors.<commit_after>/*
* This file is part of ATLAS. It is subject to the license terms in
* the LICENSE file found in the top-level directory of this distribution.
* (Also avialable at http://www.apache.org/licenses/LICENSE-2.0.txt)
* You may not use this file except in compliance with the License.
*/
#include <iostream>
#include <assimp/postprocess.h>
#include <assimp/scene.h>
#include "AssimpImporter.hpp"

namespace AssimpWorker {

	AssimpImporter::AssimpImporter() :
		importer()
	{
		return;
	}

	AssimpImporter::~AssimpImporter(){
		return;
	}

	const aiScene* AssimpImporter::importSceneFromFile(std::string fileName, Log& log){
		importer.SetPropertyBool(AI_CONFIG_PP_FD_REMOVE, true); //remove degenerate polys
		importer.SetPropertyInteger(AI_CONFIG_PP_SBP_REMOVE, aiPrimitiveType_LINE | aiPrimitiveType_POINT); //Drop all primitives that aren't triangles
		const aiScene* scene = importer.ReadFile(fileName, aiProcessPreset_TargetRealtime_Quality);
		if (!scene) {
			log.error("Scene not imported: "+fileName);
		}
		const char* errorString = importer.GetErrorString();
		if (strlen(errorString) != 0) {
			// error string is not empty: an error occured.
			log.error(fileName + ": " + errorString);
		}
		return scene;
	}

}
<|endoftext|>


<commit_before>/*
  NUI3 - C++ cross-platform GUI framework for OpenGL based applications
  Copyright (C) 2002-2003 Sebastien Metrot

  licence: see nui3/LICENCE.TXT
*/

#include "nui.h"
#include "nuiColorAttributeEditor.h"
#include "nuiHBox.h"
#include "nuiPositioner.h"
#include "nuiColorSelector.h"
#include "nuiPopupView.h"

nuiColorAttributeEditor::nuiColorAttributeEditor(const nuiAttrib<nuiColor>& rAttribute)
	: nuiAttributeEditor(),
    mEventSink(this),
    mAttribute(rAttribute)
{
  SetObjectClass(_T("nuiColorAttributeEditor"));
  nuiHBox* hbox = Init();

  mpColorPane = new nuiPane(mAttribute.Get(), nuiColor(0.f, 0.f, 0.f, 1.f));
  mpColorPane->SetUserSize(10.f, 10.f);
  mpButton->AddChild(mpColorPane);

	nuiPositioner* pos = new nuiPositioner(nuiRight);
	pos->AddChild(mpButton);
  hbox->SetCell(1, pos);
	hbox->SetCellExpand(0, nuiExpandShrinkAndGrow);

  mEventSink.Connect(mpButton->Activated, &nuiColorAttributeEditor::OnClicked);

	// the visual object of the property need to be warned when the property value has been set without a user control
  mSink.Connect(mAttribute.GetChangedSignal(), nuiMakeDelegate(this, &nuiColorAttributeEditor::OnAttributeChanged));
}

nuiColorAttributeEditor::nuiColorAttributeEditor(const nuiAttrib<const nuiColor&>& rAttribute)
	: nuiAttributeEditor(),
    mEventSink(this),
    mConstAttribute(rAttribute)
{
  SetObjectClass(_T("nuiColorAttributeEditor"));
  nuiHBox* hbox = Init();

  mpColorPane = new nuiPane(mConstAttribute.Get(), nuiColor(0.f, 0.f, 0.f, 1.f));
  mpColorPane->SetUserSize(10.f, 10.f);
  mpButton->AddChild(mpColorPane);

	nuiPositioner* pos = new nuiPositioner(nuiRight);
	pos->AddChild(mpButton);
  hbox->SetCell(1, pos);
	hbox->SetCellExpand(0, nuiExpandShrinkAndGrow);

  mEventSink.Connect(mpButton->Activated, &nuiColorAttributeEditor::OnClicked);

	// the visual object of the property need to be warned when the property value has been set without a user control
  mSink.Connect(mConstAttribute.GetChangedSignal(), nuiMakeDelegate(this, &nuiColorAttributeEditor::OnConstAttributeChanged));
}

nuiHBox* nuiColorAttributeEditor::Init()
{
  //Init static color list
  if (mColors.size() == 0)
  {
    mColors.push_back(nuiColor(255, 172, 42, 255));
    mColors.push_back(nuiColor(5, 45, 104, 255));
    mColors.push_back(nuiColor(139, 28, 36, 255));
    mColors.push_back(nuiColor(184, 0, 0, 255));
    mColors.push_back(nuiColor(0, 114, 54, 255));
    mColors.push_back(nuiColor(237, 10, 104, 255));
    mColors.push_back(nuiColor(241, 58, 36, 255));
    mColors.push_back(nuiColor(77, 184, 73, 255));
    mColors.push_back(nuiColor(234, 27, 60, 255));
    mColors.push_back(nuiColor(40, 78, 182, 255));
    mColors.push_back(nuiColor(86, 42, 143, 255));
    mColors.push_back(nuiColor(241, 114, 33, 255));
    mColors.push_back(nuiColor(51, 51, 51, 255));
    mColors.push_back(nuiColor(230, 230, 230, 255));
  }

	nuiHBox* hbox = new nuiHBox(2);
	AddChild(hbox);

	hbox->SetCell(0, new nuiLabel(_T("color")));
	hbox->SetCellExpand(0, nuiExpandShrinkAndGrow);

  mpButton = new nuiButton();
  mpButton->SetDrawSelf(false);

  return hbox;
}

nuiColorAttributeEditor::~nuiColorAttributeEditor()
{

}

bool nuiColorAttributeEditor::OnClicked(const nuiEvent& rEvent)
{
  if (mAttribute.IsValid())
    mpSelector = new nuiColorSelector(mAttribute.Get(), mColors);
  else
    mpSelector = new nuiColorSelector(mConstAttribute.Get(), mColors);

  nuiPopupView* pPopup = new nuiPopupView(mpColorPane, mpColorPane->GetRect().Left(), mpColorPane->GetRect().Top());
  pPopup->AddChild(mpSelector);

  mEventSink.Connect(mpSelector->ColorChanged, &nuiColorAttributeEditor::OnChanged);
  return true;
}

bool nuiColorAttributeEditor::OnChanged(const nuiEvent& rEvent)
{
  if (mAttribute.IsValid())
    mAttribute.Set(mpSelector->GetCurrentColor());
	else
    mConstAttribute.Set(mpSelector->GetCurrentColor());

  return false;
}

void nuiColorAttributeEditor::OnAttributeChanged(nuiColor value)
{
  mpColorPane->SetColor(eShapeFill, value);
  mpColorPane->Invalidate();
}

void nuiColorAttributeEditor::OnConstAttributeChanged(const nuiColor& value)
{
  mpColorPane->SetColor(eShapeFill, value);
  mpColorPane->Invalidate();
}
<commit_msg>fixed minor ColorPane update in nuiColorAttributeEditor<commit_after>/*
  NUI3 - C++ cross-platform GUI framework for OpenGL based applications
  Copyright (C) 2002-2003 Sebastien Metrot

  licence: see nui3/LICENCE.TXT
*/

#include "nui.h"
#include "nuiColorAttributeEditor.h"
#include "nuiHBox.h"
#include "nuiPositioner.h"
#include "nuiColorSelector.h"
#include "nuiPopupView.h"

nuiColorAttributeEditor::nuiColorAttributeEditor(const nuiAttrib<nuiColor>& rAttribute)
	: nuiAttributeEditor(),
    mEventSink(this),
    mAttribute(rAttribute)
{
  SetObjectClass(_T("nuiColorAttributeEditor"));
  nuiHBox* hbox = Init();

  mpColorPane = new nuiPane(mAttribute.Get(), nuiColor(0.f, 0.f, 0.f, 1.f));
  mpColorPane->SetUserSize(10.f, 10.f);
  mpButton->AddChild(mpColorPane);

	nuiPositioner* pos = new nuiPositioner(nuiRight);
	pos->AddChild(mpButton);
  hbox->SetCell(1, pos);
	hbox->SetCellExpand(0, nuiExpandShrinkAndGrow);

  mEventSink.Connect(mpButton->Activated, &nuiColorAttributeEditor::OnClicked);

	// the visual object of the property need to be warned when the property value has been set without a user control
  mSink.Connect(mAttribute.GetChangedSignal(), nuiMakeDelegate(this, &nuiColorAttributeEditor::OnAttributeChanged));
}

nuiColorAttributeEditor::nuiColorAttributeEditor(const nuiAttrib<const nuiColor&>& rAttribute)
	: nuiAttributeEditor(),
    mEventSink(this),
    mConstAttribute(rAttribute)
{
  SetObjectClass(_T("nuiColorAttributeEditor"));
  nuiHBox* hbox = Init();

  mpColorPane = new nuiPane(mConstAttribute.Get(), nuiColor(0.f, 0.f, 0.f, 1.f));
  mpColorPane->SetUserSize(10.f, 10.f);
  mpButton->AddChild(mpColorPane);

	nuiPositioner* pos = new nuiPositioner(nuiRight);
	pos->AddChild(mpButton);
  hbox->SetCell(1, pos);
	hbox->SetCellExpand(0, nuiExpandShrinkAndGrow);

  mEventSink.Connect(mpButton->Activated, &nuiColorAttributeEditor::OnClicked);

	// the visual object of the property need to be warned when the property value has been set without a user control
  mSink.Connect(mConstAttribute.GetChangedSignal(), nuiMakeDelegate(this, &nuiColorAttributeEditor::OnConstAttributeChanged));
}

nuiHBox* nuiColorAttributeEditor::Init()
{
  //Init static color list
  if (mColors.size() == 0)
  {
    mColors.push_back(nuiColor(255, 172, 42, 255));
    mColors.push_back(nuiColor(5, 45, 104, 255));
    mColors.push_back(nuiColor(139, 28, 36, 255));
    mColors.push_back(nuiColor(184, 0, 0, 255));
    mColors.push_back(nuiColor(0, 114, 54, 255));
    mColors.push_back(nuiColor(237, 10, 104, 255));
    mColors.push_back(nuiColor(241, 58, 36, 255));
    mColors.push_back(nuiColor(77, 184, 73, 255));
    mColors.push_back(nuiColor(234, 27, 60, 255));
    mColors.push_back(nuiColor(40, 78, 182, 255));
    mColors.push_back(nuiColor(86, 42, 143, 255));
    mColors.push_back(nuiColor(241, 114, 33, 255));
    mColors.push_back(nuiColor(51, 51, 51, 255));
    mColors.push_back(nuiColor(230, 230, 230, 255));
  }

	nuiHBox* hbox = new nuiHBox(2);
	AddChild(hbox);

	hbox->SetCell(0, new nuiLabel(_T("color")));
	hbox->SetCellExpand(0, nuiExpandShrinkAndGrow);

  mpButton = new nuiButton();
  mpButton->SetDrawSelf(false);

  return hbox;
}

nuiColorAttributeEditor::~nuiColorAttributeEditor()
{

}

bool nuiColorAttributeEditor::OnClicked(const nuiEvent& rEvent)
{
  if (mAttribute.IsValid())
    mpSelector = new nuiColorSelector(mAttribute.Get(), mColors);
  else
    mpSelector = new nuiColorSelector(mConstAttribute.Get(), mColors);

  nuiPopupView* pPopup = new nuiPopupView(mpColorPane, mpColorPane->GetRect().Left(), mpColorPane->GetRect().Top());
  pPopup->AddChild(mpSelector);

  mEventSink.Connect(mpSelector->ColorChanged, &nuiColorAttributeEditor::OnChanged);
  return true;
}

bool nuiColorAttributeEditor::OnChanged(const nuiEvent& rEvent)
{
  if (mAttribute.IsValid())
    mAttribute.Set(mpSelector->GetCurrentColor());
	else
    mConstAttribute.Set(mpSelector->GetCurrentColor());

  return false;
}

void nuiColorAttributeEditor::OnAttributeChanged(nuiColor value)
{
//  mpColorPane->SetColor(eShapeFill, value);
  mpColorPane->SetFillColor(value);
  mpColorPane->Invalidate();
}

void nuiColorAttributeEditor::OnConstAttributeChanged(const nuiColor& value)
{
//  mpColorPane->SetColor(eShapeFill, value);
  mpColorPane->SetFillColor(value);
  mpColorPane->Invalidate();
}
<|endoftext|>