<commit_before>/*

Mozzie - An MQTT plugin for the X-Plane flight simulator.
Copyright (C) 2017  Ben Russell - br@x-plugins.com

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 3 of the License, or
(at your option) any later version.

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, see <http://www.gnu.org/licenses/>.

*/

#include "Mozzie.h"

#include <iostream>

#include <XPLMUtilities.h>

#include <mosquittopp.h>
#include <cstring>

// Heavily influenced by; http://wiki.neuromeka.net/index.php?title=Implementing_MQTT_Client_using_C%2B%2B_with_libmosquitto#MQTT_Wrapper

Mozzie::Mozzie( const std::string &id ) : mosquittopp( id.c_str() ){

    mosqpp::lib_init();

    // publish sim time
    //_datarefs.push_back( new XPDref("sim/time/total_running_time_sec") );
    _datarefs.push_back( new XPDref("sim/cockpit2/gauges/indicators/wind_speed_kts") );

    // publish compass heading, perhaps filter through on-change detection..
    _datarefs.push_back( new XPDref("sim/cockpit2/gauges/indicators/compass_heading_deg_mag") );

}

Mozzie::~Mozzie() {

    Mozzie::debug("Mozzie destructor..\n");

}

bool Mozzie::open( const std::string &host, int port) {

    int keepalive = 120; //seconds

    connect( host.c_str(), port, keepalive ); // Connect to MQTT broker.

}

void Mozzie::close(){

    this->publish(
            NULL, //mid
            "sim/connected", //topic
            2, //payload length
            (void*)"0", //payload
            0, //qos
            0 //retain
    );

    this->loop();

    disconnect();

}

void Mozzie::on_connect(int rc) {

    char caDbg[1024];
    snprintf( caDbg, 1024, "Connected. Code: %d\n", rc );
    Mozzie::debug( caDbg );

    if( 0 == rc ){

        // Issue a connection notice over MQTT.
        this->publish(
                NULL, //mid
                "sim/connected", //topic
                2, //payload length
                (void*)"1", //payload
                0, //qos
                0 //retain
        );

    } //if we connected..

} //::on_connect()

void Mozzie::on_message(const struct mosquitto_message *message) {
    Mozzie::debug("::on_message..\n");

} //::on_message()

void Mozzie::on_subscribe(int mid, int quos_count, const int *granted_quos) {
    Mozzie::debug("Subscription succeeded.\n");

} //::on_subscribe()

void Mozzie::xp_data_pump() {

    // Iterate over a list of exported datarefs.
    for (std::vector<XPDref*>::iterator it = _datarefs.begin() ; it != _datarefs.end(); ++it){

        XPDref* dref = *it;

        // reads from x-plane and does compare with internal cache
        dref->update();

        // check to see if we need to update the MQTT server with a new value?
        if( dref->_send_it ){

#if 1
            //send as converted text
            char caTmp[16];
            snprintf( caTmp, 16, "%0.5f", dref->_val );
            size_t payload_size = strlen( caTmp );

            publish(
                    NULL, //mid - int
                    dref->_name.c_str(), //topic - char*
                    payload_size, //payload length - int
                    (void*)caTmp, //payload - void*
                    0, //qos - int: 0,1,2
                    false //retain - bool
            );
#else
            //send as binary
            publish(
                    NULL, //mid - int
                    dref->_name.c_str(), //topic - char*
                    4, //payload length - int
                    (void*)&dref->_val, //payload - void*
                    0, //qos - int: 0,1,2
                    true //retain - bool
            );
#endif

        } //send it?

    } //loop over all queued drefs

} //::data_pump()

// Static
void Mozzie::debug( const std::string msg ){

    std::string sOutput = "Mozzie: " + msg;

#if 1
    XPLMDebugString( sOutput.c_str() );
#else
    printf( "%s", sOutput.c_str() );
#endif

} //::debug()

// X-Plane flight loop that handles MQTT processing.
// Static
float Mozzie::flcb(float inElapsedSinceLastCall,
                  float inElapsedTimeSinceLastFlightLoop,
                  int inCounter,
                  void *inRefcon) {

    Mozzie* tmp_mozzie = reinterpret_cast<Mozzie*>(inRefcon);

    tmp_mozzie->xp_data_pump(); //x-plane io data pump

    tmp_mozzie->loop(); //mosquitto lib data pump

    return -1.f; // Every frame.

}

void Mozzie::ipc_msg(
        XPLMPluginID	inFromWho,
        int				inMessage,
        void *			inParam
        ){

    switch( inMessage ){

        // Connection Params
        case e_Mozzie_Set_Client_ID:
            break;

        case e_Mozzie_Set_Host:
            break;

        case e_Mozzie_Set_Port:
            break;

        // Connection Control
        case e_Mozzie_Connect:

            break;

        case e_Mozzie_Disconnect:
            this->disconnect();
            break;

        // Subscription Control
        case e_Mozzie_Set_QOS:
            break;

        case e_Mozzie_Subscribe:
            /*
            this->subscribe(
                    mid,
                    sub name,
                    qos
                    );
                    */
            break;

        case e_Mozzie_UnSubscribe:
            break;

        // Publication Control
        case e_Mozzie_Publish:
            break;

        case e_Mozzie_UnPublish:
            break;

        // Message Control
        case e_Mozzie_Set_Topic:
            break;

        case e_Mozzie_Set_Message:
            break;

        case e_Mozzie_Send:
            break;

        default:
            break;
    }

}

//eof

<commit_msg>Mozzie: Tweaks order of operations so that libmosquitto is properly serviced BEFORE we attempt to push data to it. Ensures that timed-out connections etc are dealt with properly.<commit_after>/*

Mozzie - An MQTT plugin for the X-Plane flight simulator.
Copyright (C) 2017  Ben Russell - br@x-plugins.com

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 3 of the License, or
(at your option) any later version.

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, see <http://www.gnu.org/licenses/>.

*/

#include "Mozzie.h"

#include <iostream>

#include <XPLMUtilities.h>

#include <mosquittopp.h>
#include <cstring>

// Heavily influenced by; http://wiki.neuromeka.net/index.php?title=Implementing_MQTT_Client_using_C%2B%2B_with_libmosquitto#MQTT_Wrapper

Mozzie::Mozzie( const std::string &id ) : mosquittopp( id.c_str() ){

    mosqpp::lib_init();

    // publish sim time
    //_datarefs.push_back( new XPDref("sim/time/total_running_time_sec") );
    _datarefs.push_back( new XPDref("sim/cockpit2/gauges/indicators/wind_speed_kts") );

    // publish compass heading, perhaps filter through on-change detection..
    //_datarefs.push_back( new XPDref("sim/cockpit2/gauges/indicators/compass_heading_deg_mag") );

    // slow moving dref, better for debug.
    _datarefs.push_back( new XPDref("sim/flightmodel/weight/m_fuel_total") );

}

Mozzie::~Mozzie() {

    Mozzie::debug("Mozzie destructor..\n");

}

bool Mozzie::open( const std::string &host, int port) {

    int keepalive = 120; //seconds

    connect( host.c_str(), port, keepalive ); // Connect to MQTT broker.

}

void Mozzie::close(){

    this->publish(
            NULL, //mid
            "sim/connected", //topic
            2, //payload length
            (void*)"0", //payload
            0, //qos
            0 //retain
    );

    this->loop();

    disconnect();

}

void Mozzie::on_connect(int rc) {

    char caDbg[1024];
    snprintf( caDbg, 1024, "Connected. Code: %d\n", rc );
    Mozzie::debug( caDbg );

    if( 0 == rc ){

        // Issue a connection notice over MQTT.
        this->publish(
                NULL, //mid
                "sim/connected", //topic
                2, //payload length
                (void*)"1", //payload
                0, //qos
                0 //retain
        );

    } //if we connected..

} //::on_connect()

void Mozzie::on_message(const struct mosquitto_message *message) {
    Mozzie::debug("::on_message..\n");

} //::on_message()

void Mozzie::on_subscribe(int mid, int quos_count, const int *granted_quos) {
    Mozzie::debug("Subscription succeeded.\n");

} //::on_subscribe()

void Mozzie::xp_data_pump() {

    // Iterate over a list of exported datarefs.
    for (std::vector<XPDref*>::iterator it = _datarefs.begin() ; it != _datarefs.end(); ++it){

        XPDref* dref = *it;

        // reads from x-plane and does compare with internal cache
        dref->update();

        // check to see if we need to update the MQTT server with a new value?
        if( dref->_send_it ){

#if 1
            //send as converted text
            char caTmp[16];
            snprintf( caTmp, 16, "%0.5f", dref->_val );
            size_t payload_size = strlen( caTmp );

            publish(
                    NULL, //mid - int
                    dref->_name.c_str(), //topic - char*
                    payload_size, //payload length - int
                    (void*)caTmp, //payload - void*
                    0, //qos - int: 0,1,2
                    false //retain - bool
            );
#else
            //send as binary
            publish(
                    NULL, //mid - int
                    dref->_name.c_str(), //topic - char*
                    4, //payload length - int
                    (void*)&dref->_val, //payload - void*
                    0, //qos - int: 0,1,2
                    true //retain - bool
            );
#endif

        } //send it?

    } //loop over all queued drefs

} //::data_pump()

// Static
void Mozzie::debug( const std::string msg ){

    std::string sOutput = "Mozzie: " + msg;

#if 1
    XPLMDebugString( sOutput.c_str() );
#else
    printf( "%s", sOutput.c_str() );
#endif

} //::debug()

// X-Plane flight loop that handles MQTT processing.
// Static
float Mozzie::flcb(float inElapsedSinceLastCall,
                  float inElapsedTimeSinceLastFlightLoop,
                  int inCounter,
                  void *inRefcon) {

    Mozzie* tmp_mozzie = reinterpret_cast<Mozzie*>(inRefcon);

    tmp_mozzie->loop(); //mosquitto lib data pump

    tmp_mozzie->xp_data_pump(); //x-plane io data pump

    return -1.f; // Every frame.

}

void Mozzie::ipc_msg(
        XPLMPluginID	inFromWho,
        int				inMessage,
        void *			inParam
        ){

    switch( inMessage ){

        // Connection Params
        case e_Mozzie_Set_Client_ID:
            break;

        case e_Mozzie_Set_Host:
            break;

        case e_Mozzie_Set_Port:
            break;

        // Connection Control
        case e_Mozzie_Connect:

            break;

        case e_Mozzie_Disconnect:
            this->disconnect();
            break;

        // Subscription Control
        case e_Mozzie_Set_QOS:
            break;

        case e_Mozzie_Subscribe:
            /*
            this->subscribe(
                    mid,
                    sub name,
                    qos
                    );
                    */
            break;

        case e_Mozzie_UnSubscribe:
            break;

        // Publication Control
        case e_Mozzie_Publish:
            break;

        case e_Mozzie_UnPublish:
            break;

        // Message Control
        case e_Mozzie_Set_Topic:
            break;

        case e_Mozzie_Set_Message:
            break;

        case e_Mozzie_Send:
            break;

        default:
            break;
    }

}

//eof

<|endoftext|>


<commit_before>// Copyright 2015 XLGAMES Inc.
//
// Distributed under the MIT License (See
// accompanying file "LICENSE" or the website
// http://www.opensource.org/licenses/mit-license.php)

#define _SCL_SECURE_NO_WARNINGS

#include "BlockSerializer.h"
#include "../Utility/MemoryUtils.h"
#include "../Utility/Streams/Serialization.h"
#include <vector>

namespace Serialization
{

        ////////////////////////////////////////////////////////////

    template<typename Type>
        void PushBack(std::vector<uint8>& buffer, const Type& type)
    {
        std::copy(  (const uint8*)&type, (const uint8*)PtrAdd(&type, sizeof(Type)),
                    std::back_inserter(buffer));
    }

    void NascentBlockSerializer::PushBackPointer(size_t value)
    {
        PushBack(_memory, value);
    }

    void    NascentBlockSerializer::PushBackPlaceholder(SpecialBuffer::Enum specialBuffer)
    {
        if (specialBuffer == SpecialBuffer::String) {
            _memory.insert(_memory.end(), sizeof(std::string), 0);
        } else if (specialBuffer == SpecialBuffer::VertexBuffer || specialBuffer == SpecialBuffer::IndexBuffer) {
            assert(0);
        } else if (specialBuffer == SpecialBuffer::Vector) {
            _memory.insert(_memory.end(), sizeof(std::vector<unsigned, BlockSerializerAllocator<unsigned>>), 0);
        } else if (specialBuffer == SpecialBuffer::UniquePtr) {
            _memory.insert(_memory.end(), sizeof(std::unique_ptr<void, BlockSerializerDeleter<void>>), 0);
        } else if (specialBuffer == SpecialBuffer::Unknown) {
            PushBackPointer(0);
        }
    }

    void    NascentBlockSerializer::SerializeSpecialBuffer(
                    SpecialBuffer::Enum specialBuffer,
                    const void* begin, const void* end)
    {
        InternalPointer newPointer;
        newPointer._pointerOffset    = _memory.size();
        newPointer._subBlockOffset   = _trailingSubBlocks.size();
        newPointer._subBlockSize     = ptrdiff_t(end) - ptrdiff_t(begin);
        newPointer._specialBuffer    = specialBuffer;
        _internalPointers.push_back(newPointer);

        std::copy((const uint8*)begin, (const uint8*)end, std::back_inserter(_trailingSubBlocks));

            //
            //      =<>=    Write blank space for this special buffer   =<>=
            //
        PushBackPlaceholder(specialBuffer);
    }

    void    NascentBlockSerializer::SerializeValue(uint8     value)
    {
        std::copy(  (const uint8*)&value, (const uint8*)PtrAdd(&value, sizeof(value)),
                    std::back_inserter(_memory));
    }

    void    NascentBlockSerializer::SerializeValue(uint16    value)
    {
        std::copy(  (const uint8*)&value, (const uint8*)PtrAdd(&value, sizeof(value)),
                    std::back_inserter(_memory));
    }

    void    NascentBlockSerializer::SerializeValue(uint32    value)
    {
        std::copy(  (const uint8*)&value, (const uint8*)PtrAdd(&value, sizeof(value)),
                    std::back_inserter(_memory));
    }

    void    NascentBlockSerializer::SerializeValue(uint64    value)
    {
        std::copy(  (const uint8*)&value, (const uint8*)PtrAdd(&value, sizeof(value)),
                    std::back_inserter(_memory));
    }

    void    NascentBlockSerializer::SerializeValue(float     value)
    {
        std::copy(  (const uint8*)&value, (const uint8*)PtrAdd(&value, sizeof(value)),
                    std::back_inserter(_memory));
    }

    void    NascentBlockSerializer::AddPadding(unsigned sizeInBytes)
    {
        _memory.insert(_memory.end(), sizeInBytes, 0);
    }

    void NascentBlockSerializer::PushBackRaw(const void* data, size_t size)
    {
        std::copy(  (const uint8*)data, (const uint8*)PtrAdd(data, size),
                    std::back_inserter(_memory));
    }

    void NascentBlockSerializer::PushBackRaw_SubBlock(const void* data, size_t size)
    {
        std::copy(  (const uint8*)data, (const uint8*)PtrAdd(data, size),
                    std::back_inserter(_trailingSubBlocks));
    }

    void NascentBlockSerializer::RegisterInternalPointer(const InternalPointer& ptr)
    {
        _internalPointers.push_back(ptr);
    }

    void    NascentBlockSerializer::SerializeSubBlock(NascentBlockSerializer& subBlock, SpecialBuffer::Enum specialBuffer)
    {
            //
            //      Merge in the block we've just serialised, and write
            //      an internal pointer record for it.
            //

        InternalPointer ptr;
        ptr._pointerOffset   = _memory.size();
        ptr._subBlockOffset  = _trailingSubBlocks.size();
        ptr._subBlockSize    = subBlock._memory.size();
        ptr._specialBuffer   = specialBuffer;
        RegisterInternalPointer(ptr);

        PushBackPlaceholder(specialBuffer);

            //
            //      All of the internal pointer records should be merged in
            //      on an offset, also.
            //

        for (auto i=subBlock._internalPointers.cbegin(); i!=subBlock._internalPointers.cend(); ++i) {
            InternalPointer p = *i;
            if (p._pointerOffset & PtrFlagBit) {
                p._pointerOffset     = (p._pointerOffset&PtrMask) + subBlock._memory.size();
            }
            p._pointerOffset    +=  ptr._subBlockOffset;

                //
                //      Because the pointer itself is in the "subblock" part, we
                //      need tag it some way, to prevent confusion with pointers
                //      in the "memory" part. Let's just set it negative.
                //
            p._pointerOffset     |= PtrFlagBit;
            p._subBlockOffset    +=  ptr._subBlockOffset + subBlock._memory.size();
            RegisterInternalPointer(p);
        }

        PushBackRaw_SubBlock(AsPointer(subBlock._memory.begin()), subBlock._memory.size());
        PushBackRaw_SubBlock(AsPointer(subBlock._trailingSubBlocks.begin()), subBlock._trailingSubBlocks.size());
    }

    void NascentBlockSerializer::SerializeRawSubBlock(const void* begin, const void* end, SpecialBuffer::Enum specialBuffer)
    {
        auto size = size_t(end) - size_t(begin);

        InternalPointer ptr;
        ptr._pointerOffset   = _memory.size();
        ptr._subBlockOffset  = _trailingSubBlocks.size();
        ptr._subBlockSize    = size;
        ptr._specialBuffer   = specialBuffer;
        RegisterInternalPointer(ptr);

        PushBackPlaceholder(specialBuffer);
        PushBackRaw_SubBlock(begin, size);
    }

    void NascentBlockSerializer::SerializeValue(const std::string& value)
    {
        SerializeSpecialBuffer(SpecialBuffer::String, AsPointer(value.begin()), AsPointer(value.end()));
    }

    class Header
    {
    public:
        size_t  _rawMemorySize;
        size_t  _internalPointerCount;
    };

    size_t      NascentBlockSerializer::Size() const
    {
        return sizeof(Header)
            + _memory.size()
            + _trailingSubBlocks.size()
            + _internalPointers.size() * sizeof(InternalPointer);
    }

    std::unique_ptr<uint8[]>      NascentBlockSerializer::AsMemoryBlock() const
    {
        std::unique_ptr<uint8[]> result = std::make_unique<uint8[]>(Size());

        ((Header*)result.get())->_rawMemorySize = _memory.size() + _trailingSubBlocks.size();
        ((Header*)result.get())->_internalPointerCount = _internalPointers.size();

        std::copy(  AsPointer(_memory.begin()), AsPointer(_memory.end()),
                    PtrAdd(result.get(), sizeof(Header)));

        std::copy(  AsPointer(_trailingSubBlocks.begin()), AsPointer(_trailingSubBlocks.end()),
                    PtrAdd(result.get(), _memory.size() + sizeof(Header)));

        InternalPointer* d = (InternalPointer*)PtrAdd(result.get(), _memory.size() + _trailingSubBlocks.size() + sizeof(Header));
        for (auto i=_internalPointers.cbegin(); i!=_internalPointers.cend(); ++i, ++d) {
            *d = *i;
                //      pointers in the subblock part are marked as negative... But what about zero?
                //      It could be in the memory part, or the subblock part
            if (d->_pointerOffset & PtrFlagBit) {
                d->_pointerOffset = (d->_pointerOffset&PtrMask) + _memory.size();
            }
            d->_subBlockOffset += _memory.size();
        }

        return result;
    }

    NascentBlockSerializer::NascentBlockSerializer()
    {
    }

    NascentBlockSerializer::~NascentBlockSerializer()
    {

    }

    #undef new

    void        Block_Initialize(void* block, const void* base)
    {
        if (!base) { base = block; }

        const Header& h = *(const Header*)block;
        const NascentBlockSerializer::InternalPointer* ptrTable =
            (const NascentBlockSerializer::InternalPointer*)PtrAdd(block, sizeof(Header)+h._rawMemorySize);

        for (unsigned c=0; c<h._internalPointerCount; ++c) {
            const NascentBlockSerializer::InternalPointer& ptr = ptrTable[c];
            if (ptr._specialBuffer == NascentBlockSerializer::SpecialBuffer::Unknown) {
                *(size_t*)PtrAdd(block, sizeof(Header)+ptr._pointerOffset) =
                    ptr._subBlockOffset + size_t(base) + sizeof(Header);
            } else if ( ptr._specialBuffer == NascentBlockSerializer::SpecialBuffer::VertexBuffer
                ||      ptr._specialBuffer == NascentBlockSerializer::SpecialBuffer::IndexBuffer) {
                assert(0);
            } else if (ptr._specialBuffer == NascentBlockSerializer::SpecialBuffer::String) {
                new(PtrAdd(block, sizeof(Header)+ptr._pointerOffset)) std::string(
                    (const char*)(ptr._subBlockOffset + size_t(base) + sizeof(Header)),
                    ptr._subBlockSize);
            } else if (ptr._specialBuffer == NascentBlockSerializer::SpecialBuffer::Vector) {
                size_t* o = (size_t*)PtrAdd(block, sizeof(Header)+ptr._pointerOffset);
                #if (STL_ACTIVE == STL_MSVC) && (_ITERATOR_DEBUG_LEVEL != 0)
                        //  in debug, to produce a valid vector, we need to add one of these proxy
                        //  objects. it requires some extra memory management; but fortunately it's
                        //  just debug builds!
                        //  Note that this requires that the caller correctly call the destructors
                        //  on the returned objects to make sure the vector destructor deletes this
                        //  object!
                    auto proxy = std::make_unique<std::_Container_proxy>();
                    proxy->_Mycont = (std::_Container_base12*)o;
                    *o++ = size_t(proxy.release());
                #endif
                o[0] = (ptr._subBlockOffset + size_t(base) + sizeof(Header));
                o[1] = (ptr._subBlockOffset + ptr._subBlockSize + size_t(base) + sizeof(Header));
                o[2] = (ptr._subBlockOffset + ptr._subBlockSize + size_t(base) + sizeof(Header));
                *(unsigned*)(&o[3]) = 1;
            } else if (ptr._specialBuffer == NascentBlockSerializer::SpecialBuffer::UniquePtr) {
                size_t* o = (size_t*)PtrAdd(block, sizeof(Header)+ptr._pointerOffset);
                o[0] = (ptr._subBlockOffset + size_t(base) + sizeof(Header));
                *(unsigned*)(&o[1]) = 1;
            }
        }
    }

    #if !defined(DEBUG_NEW)
        #define new DEBUG_NEW
    #endif

    const void*       Block_GetFirstObject(const void* blockStart)
    {
        return PtrAdd(blockStart, sizeof(Header));
    }

    size_t          Block_GetSize(const void* block)
    {
        const Header& h = *(const Header*)block;
        return h._rawMemorySize + h._internalPointerCount * sizeof(NascentBlockSerializer::InternalPointer) + sizeof(Header);
    }

    std::unique_ptr<uint8[]>  Block_Duplicate(const void* block)
    {
        size_t size = Block_GetSize(block);
        std::unique_ptr<uint8[]> result = std::make_unique<uint8[]>(size);
        XlCopyMemory(result.get(), block, size);
        return std::move(result);
    }

}

<commit_msg>Fix for block serializer in VS2015 - position of the allocator within the vector object has changed position - it's a hack; but it's just a very useful hack<commit_after>// Copyright 2015 XLGAMES Inc.
//
// Distributed under the MIT License (See
// accompanying file "LICENSE" or the website
// http://www.opensource.org/licenses/mit-license.php)

#define _SCL_SECURE_NO_WARNINGS

#include "BlockSerializer.h"
#include "../Utility/MemoryUtils.h"
#include "../Utility/Streams/Serialization.h"
#include <vector>

namespace Serialization
{

        ////////////////////////////////////////////////////////////

    template<typename Type>
        void PushBack(std::vector<uint8>& buffer, const Type& type)
    {
        std::copy(  (const uint8*)&type, (const uint8*)PtrAdd(&type, sizeof(Type)),
                    std::back_inserter(buffer));
    }

    void NascentBlockSerializer::PushBackPointer(size_t value)
    {
        PushBack(_memory, value);
    }

    void    NascentBlockSerializer::PushBackPlaceholder(SpecialBuffer::Enum specialBuffer)
    {
        if (specialBuffer == SpecialBuffer::String) {
            _memory.insert(_memory.end(), sizeof(std::string), 0);
        } else if (specialBuffer == SpecialBuffer::VertexBuffer || specialBuffer == SpecialBuffer::IndexBuffer) {
            assert(0);
        } else if (specialBuffer == SpecialBuffer::Vector) {
            _memory.insert(_memory.end(), sizeof(std::vector<unsigned, BlockSerializerAllocator<unsigned>>), 0);
        } else if (specialBuffer == SpecialBuffer::UniquePtr) {
            _memory.insert(_memory.end(), sizeof(std::unique_ptr<void, BlockSerializerDeleter<void>>), 0);
        } else if (specialBuffer == SpecialBuffer::Unknown) {
            PushBackPointer(0);
        }
    }

    void    NascentBlockSerializer::SerializeSpecialBuffer(
                    SpecialBuffer::Enum specialBuffer,
                    const void* begin, const void* end)
    {
        InternalPointer newPointer;
        newPointer._pointerOffset    = _memory.size();
        newPointer._subBlockOffset   = _trailingSubBlocks.size();
        newPointer._subBlockSize     = ptrdiff_t(end) - ptrdiff_t(begin);
        newPointer._specialBuffer    = specialBuffer;
        _internalPointers.push_back(newPointer);

        std::copy((const uint8*)begin, (const uint8*)end, std::back_inserter(_trailingSubBlocks));

            //
            //      =<>=    Write blank space for this special buffer   =<>=
            //
        PushBackPlaceholder(specialBuffer);
    }

    void    NascentBlockSerializer::SerializeValue(uint8     value)
    {
        std::copy(  (const uint8*)&value, (const uint8*)PtrAdd(&value, sizeof(value)),
                    std::back_inserter(_memory));
    }

    void    NascentBlockSerializer::SerializeValue(uint16    value)
    {
        std::copy(  (const uint8*)&value, (const uint8*)PtrAdd(&value, sizeof(value)),
                    std::back_inserter(_memory));
    }

    void    NascentBlockSerializer::SerializeValue(uint32    value)
    {
        std::copy(  (const uint8*)&value, (const uint8*)PtrAdd(&value, sizeof(value)),
                    std::back_inserter(_memory));
    }

    void    NascentBlockSerializer::SerializeValue(uint64    value)
    {
        std::copy(  (const uint8*)&value, (const uint8*)PtrAdd(&value, sizeof(value)),
                    std::back_inserter(_memory));
    }

    void    NascentBlockSerializer::SerializeValue(float     value)
    {
        std::copy(  (const uint8*)&value, (const uint8*)PtrAdd(&value, sizeof(value)),
                    std::back_inserter(_memory));
    }

    void    NascentBlockSerializer::AddPadding(unsigned sizeInBytes)
    {
        _memory.insert(_memory.end(), sizeInBytes, 0);
    }

    void NascentBlockSerializer::PushBackRaw(const void* data, size_t size)
    {
        std::copy(  (const uint8*)data, (const uint8*)PtrAdd(data, size),
                    std::back_inserter(_memory));
    }

    void NascentBlockSerializer::PushBackRaw_SubBlock(const void* data, size_t size)
    {
        std::copy(  (const uint8*)data, (const uint8*)PtrAdd(data, size),
                    std::back_inserter(_trailingSubBlocks));
    }

    void NascentBlockSerializer::RegisterInternalPointer(const InternalPointer& ptr)
    {
        _internalPointers.push_back(ptr);
    }

    void    NascentBlockSerializer::SerializeSubBlock(NascentBlockSerializer& subBlock, SpecialBuffer::Enum specialBuffer)
    {
            //
            //      Merge in the block we've just serialised, and write
            //      an internal pointer record for it.
            //

        InternalPointer ptr;
        ptr._pointerOffset   = _memory.size();
        ptr._subBlockOffset  = _trailingSubBlocks.size();
        ptr._subBlockSize    = subBlock._memory.size();
        ptr._specialBuffer   = specialBuffer;
        RegisterInternalPointer(ptr);

        PushBackPlaceholder(specialBuffer);

            //
            //      All of the internal pointer records should be merged in
            //      on an offset, also.
            //

        for (auto i=subBlock._internalPointers.cbegin(); i!=subBlock._internalPointers.cend(); ++i) {
            InternalPointer p = *i;
            if (p._pointerOffset & PtrFlagBit) {
                p._pointerOffset     = (p._pointerOffset&PtrMask) + subBlock._memory.size();
            }
            p._pointerOffset    +=  ptr._subBlockOffset;

                //
                //      Because the pointer itself is in the "subblock" part, we
                //      need tag it some way, to prevent confusion with pointers
                //      in the "memory" part. Let's just set it negative.
                //
            p._pointerOffset     |= PtrFlagBit;
            p._subBlockOffset    +=  ptr._subBlockOffset + subBlock._memory.size();
            RegisterInternalPointer(p);
        }

        PushBackRaw_SubBlock(AsPointer(subBlock._memory.begin()), subBlock._memory.size());
        PushBackRaw_SubBlock(AsPointer(subBlock._trailingSubBlocks.begin()), subBlock._trailingSubBlocks.size());
    }

    void NascentBlockSerializer::SerializeRawSubBlock(const void* begin, const void* end, SpecialBuffer::Enum specialBuffer)
    {
        auto size = size_t(end) - size_t(begin);

        InternalPointer ptr;
        ptr._pointerOffset   = _memory.size();
        ptr._subBlockOffset  = _trailingSubBlocks.size();
        ptr._subBlockSize    = size;
        ptr._specialBuffer   = specialBuffer;
        RegisterInternalPointer(ptr);

        PushBackPlaceholder(specialBuffer);
        PushBackRaw_SubBlock(begin, size);
    }

    void NascentBlockSerializer::SerializeValue(const std::string& value)
    {
        SerializeSpecialBuffer(SpecialBuffer::String, AsPointer(value.begin()), AsPointer(value.end()));
    }

    class Header
    {
    public:
        size_t  _rawMemorySize;
        size_t  _internalPointerCount;
    };

    size_t      NascentBlockSerializer::Size() const
    {
        return sizeof(Header)
            + _memory.size()
            + _trailingSubBlocks.size()
            + _internalPointers.size() * sizeof(InternalPointer);
    }

    std::unique_ptr<uint8[]>      NascentBlockSerializer::AsMemoryBlock() const
    {
        std::unique_ptr<uint8[]> result = std::make_unique<uint8[]>(Size());

        ((Header*)result.get())->_rawMemorySize = _memory.size() + _trailingSubBlocks.size();
        ((Header*)result.get())->_internalPointerCount = _internalPointers.size();

        std::copy(  AsPointer(_memory.begin()), AsPointer(_memory.end()),
                    PtrAdd(result.get(), sizeof(Header)));

        std::copy(  AsPointer(_trailingSubBlocks.begin()), AsPointer(_trailingSubBlocks.end()),
                    PtrAdd(result.get(), _memory.size() + sizeof(Header)));

        InternalPointer* d = (InternalPointer*)PtrAdd(result.get(), _memory.size() + _trailingSubBlocks.size() + sizeof(Header));
        for (auto i=_internalPointers.cbegin(); i!=_internalPointers.cend(); ++i, ++d) {
            *d = *i;
                //      pointers in the subblock part are marked as negative... But what about zero?
                //      It could be in the memory part, or the subblock part
            if (d->_pointerOffset & PtrFlagBit) {
                d->_pointerOffset = (d->_pointerOffset&PtrMask) + _memory.size();
            }
            d->_subBlockOffset += _memory.size();
        }

        return result;
    }

    NascentBlockSerializer::NascentBlockSerializer()
    {
    }

    NascentBlockSerializer::~NascentBlockSerializer()
    {

    }

    #undef new

    void        Block_Initialize(void* block, const void* base)
    {
        if (!base) { base = block; }

        const Header& h = *(const Header*)block;
        const NascentBlockSerializer::InternalPointer* ptrTable =
            (const NascentBlockSerializer::InternalPointer*)PtrAdd(block, sizeof(Header)+h._rawMemorySize);

        for (unsigned c=0; c<h._internalPointerCount; ++c) {
            const NascentBlockSerializer::InternalPointer& ptr = ptrTable[c];
            if (ptr._specialBuffer == NascentBlockSerializer::SpecialBuffer::Unknown) {
                *(size_t*)PtrAdd(block, sizeof(Header)+ptr._pointerOffset) =
                    ptr._subBlockOffset + size_t(base) + sizeof(Header);
            } else if ( ptr._specialBuffer == NascentBlockSerializer::SpecialBuffer::VertexBuffer
                ||      ptr._specialBuffer == NascentBlockSerializer::SpecialBuffer::IndexBuffer) {
                assert(0);
            } else if (ptr._specialBuffer == NascentBlockSerializer::SpecialBuffer::String) {
                new(PtrAdd(block, sizeof(Header)+ptr._pointerOffset)) std::string(
                    (const char*)(ptr._subBlockOffset + size_t(base) + sizeof(Header)),
                    ptr._subBlockSize);
            } else if (ptr._specialBuffer == NascentBlockSerializer::SpecialBuffer::Vector) {
                size_t* o = (size_t*)PtrAdd(block, sizeof(Header)+ptr._pointerOffset);

				#if (STL_ACTIVE == STL_MSVC) && (_MSC_VER >= 1900)
						// This is the flag in the BlockSerializerAllocator in the vector
						// It's a bit of an awkward hack... but one it's one of those hacks
						//		-- once it's working, it works well.
						// In VS2015, it changed position with in vector object. Actually the
						// new position might be less ideal, because it's before the more
						// commonly accessed begin/end pointers.
					*(unsigned*)o = 1; o = PtrAdd(o, sizeof(unsigned));
				#endif

                #if (STL_ACTIVE == STL_MSVC) && (_ITERATOR_DEBUG_LEVEL != 0)
                        //  in debug, to produce a valid vector, we need to add one of these proxy
                        //  objects. it requires some extra memory management; but fortunately it's
                        //  just debug builds!
                        //  Note that this requires that the caller correctly call the destructors
                        //  on the returned objects to make sure the vector destructor deletes this
                        //  object!
                    auto proxy = std::make_unique<std::_Container_proxy>();
                    proxy->_Mycont = (std::_Container_base12*)o;
                    *o++ = size_t(proxy.release());
                #endif
                o[0] = (ptr._subBlockOffset + size_t(base) + sizeof(Header));
                o[1] = (ptr._subBlockOffset + ptr._subBlockSize + size_t(base) + sizeof(Header));
                o[2] = (ptr._subBlockOffset + ptr._subBlockSize + size_t(base) + sizeof(Header));

				#if (STL_ACTIVE == STL_MSVC) && (_MSC_VER < 1900)
					*(unsigned*)(&o[3]) = 1;
				#endif

            } else if (ptr._specialBuffer == NascentBlockSerializer::SpecialBuffer::UniquePtr) {
                size_t* o = (size_t*)PtrAdd(block, sizeof(Header)+ptr._pointerOffset);
                o[0] = (ptr._subBlockOffset + size_t(base) + sizeof(Header));
                *(unsigned*)(&o[1]) = 1;
            }
        }
    }

    #if !defined(DEBUG_NEW)
        #define new DEBUG_NEW
    #endif

    const void*       Block_GetFirstObject(const void* blockStart)
    {
        return PtrAdd(blockStart, sizeof(Header));
    }

    size_t          Block_GetSize(const void* block)
    {
        const Header& h = *(const Header*)block;
        return h._rawMemorySize + h._internalPointerCount * sizeof(NascentBlockSerializer::InternalPointer) + sizeof(Header);
    }

    std::unique_ptr<uint8[]>  Block_Duplicate(const void* block)
    {
        size_t size = Block_GetSize(block);
        std::unique_ptr<uint8[]> result = std::make_unique<uint8[]>(size);
        XlCopyMemory(result.get(), block, size);
        return std::move(result);
    }

}

<|endoftext|>


<commit_before>#include <ros/ros.h>
#include <actionlib/client/simple_action_client.h>
#include <actionlib/client/terminal_state.h>
#include <motion_planning_msgs/PlanPickAction.h>
#include <motion_msgs/GripperPose.h>

//tf
#include <tf/transform_datatypes.h>

int main (int argc, char **argv) {
  ros::init(argc, argv, "test_plan_pick");
  ros::NodeHandle n;

  if ( argc != 2 && argc != 4)
    return 0;

  // create the action client
  // true causes the client to spin its own thread
  actionlib::SimpleActionClient<motion_planning_msgs::PlanPickAction> ac("youbot_3/motion_planning/plan_pick", true);
  ros::ServiceClient pose_c = n.serviceClient<motion_msgs::GripperPose>("youbot_3/motion/gripper_pose");

  ROS_INFO("Waiting for action server to start.");
  // wait for the action server to start
  ac.waitForServer(); //will wait for infinite time

  ROS_INFO("Action server started, sending goal.");
  // send a goal to the action
  motion_planning_msgs::PlanPickGoal goal;
  geometry_msgs::PoseStamped target_pose;
  target_pose.header.frame_id = "youbot_1/base_footprint";

  if (argc == 2) {
    int command = atoi(argv[1]);
    // simulate some cube poses wrt to base frame
    if (command == 1) {
      // face forward
      target_pose.pose.position.x = 0.42;
      target_pose.pose.position.y = -0.19;
      target_pose.pose.position.z = 0.02;
      target_pose.pose.orientation = tf::createQuaternionMsgFromRollPitchYaw(-0.41, 0.048, -1.97);
    } else if (command == 2) {
      // face left
      target_pose.pose.position.x = 0.09;
      target_pose.pose.position.y = 0.29;
      target_pose.pose.position.z = 0.02;
      target_pose.pose.orientation = tf::createQuaternionMsgFromRollPitchYaw(-0.01, -0.002, -0.07);
    } else if (command == 3) {
      // face right
      target_pose.pose.position.x = 0.11;
      target_pose.pose.position.y = -0.3;
      target_pose.pose.position.z = 0.02;
      target_pose.pose.orientation = tf::createQuaternionMsgFromRollPitchYaw(0.01, -0.01, 3.06);
    } else if (command == 4) {
      // face right for controlled simulation
      target_pose.pose.position.x = 0.12;
      target_pose.pose.position.y = -0.29;
      target_pose.pose.position.z = 0.0;
      target_pose.pose.orientation = tf::createQuaternionMsgFromRollPitchYaw(0.01, -0.01, 3.12);
    } else if (command == 5) {
      // face forward
      target_pose.pose.position.x = 0.44;
      target_pose.pose.position.y = -0.001;
      target_pose.pose.position.z = 0.001;
      target_pose.pose.orientation = tf::createQuaternionMsgFromRollPitchYaw(-0.41, 0.048, -1.97);
    }
  } else {
    target_pose.pose.position.x = atof(argv[1]);
    target_pose.pose.position.y = atof(argv[2]);
    target_pose.pose.position.z = atof(argv[3]);
    target_pose.pose.orientation = tf::createQuaternionMsgFromRollPitchYaw(-0.41, 0.048, -1.97);
  }
  goal.object_pose = target_pose;
  ac.sendGoal(goal);

  ac.waitForResult();
  ROS_INFO("Action server result: %d", ac.getResult()->success);

  //exit
  return 0;
}
<commit_msg>fix bug in pick client was using youbot_1 instead of 3<commit_after>#include <ros/ros.h>
#include <actionlib/client/simple_action_client.h>
#include <actionlib/client/terminal_state.h>
#include <motion_planning_msgs/PlanPickAction.h>
#include <motion_msgs/GripperPose.h>

//tf
#include <tf/transform_datatypes.h>

int main (int argc, char **argv) {
  ros::init(argc, argv, "test_plan_pick");
  ros::NodeHandle n;

  if ( argc != 2 && argc != 4)
    return 0;

  // create the action client
  // true causes the client to spin its own thread
  actionlib::SimpleActionClient<motion_planning_msgs::PlanPickAction> ac("youbot_3/motion_planning/plan_pick", true);
  ros::ServiceClient pose_c = n.serviceClient<motion_msgs::GripperPose>("youbot_3/motion/gripper_pose");

  ROS_INFO("Waiting for action server to start.");
  // wait for the action server to start
  ac.waitForServer(); //will wait for infinite time

  ROS_INFO("Action server started, sending goal.");
  // send a goal to the action
  motion_planning_msgs::PlanPickGoal goal;
  geometry_msgs::PoseStamped target_pose;
  target_pose.header.frame_id = "youbot_3/base_footprint";

  if (argc == 2) {
    int command = atoi(argv[1]);
    // simulate some cube poses wrt to base frame
    if (command == 1) {
      // face forward
      target_pose.pose.position.x = 0.42;
      target_pose.pose.position.y = -0.19;
      target_pose.pose.position.z = 0.02;
      target_pose.pose.orientation = tf::createQuaternionMsgFromRollPitchYaw(-0.41, 0.048, -1.97);
    } else if (command == 2) {
      // face left
      target_pose.pose.position.x = 0.09;
      target_pose.pose.position.y = 0.29;
      target_pose.pose.position.z = 0.02;
      target_pose.pose.orientation = tf::createQuaternionMsgFromRollPitchYaw(-0.01, -0.002, -0.07);
    } else if (command == 3) {
      // face right
      target_pose.pose.position.x = 0.11;
      target_pose.pose.position.y = -0.3;
      target_pose.pose.position.z = 0.02;
      target_pose.pose.orientation = tf::createQuaternionMsgFromRollPitchYaw(0.01, -0.01, 3.06);
    } else if (command == 4) {
      // face right for controlled simulation
      target_pose.pose.position.x = 0.12;
      target_pose.pose.position.y = -0.29;
      target_pose.pose.position.z = 0.0;
      target_pose.pose.orientation = tf::createQuaternionMsgFromRollPitchYaw(0.01, -0.01, 3.12);
    } else if (command == 5) {
      // face forward
      target_pose.pose.position.x = 0.44;
      target_pose.pose.position.y = -0.001;
      target_pose.pose.position.z = 0.001;
      target_pose.pose.orientation = tf::createQuaternionMsgFromRollPitchYaw(-0.41, 0.048, -1.97);
    }
  } else {
    target_pose.pose.position.x = atof(argv[1]);
    target_pose.pose.position.y = atof(argv[2]);
    target_pose.pose.position.z = atof(argv[3]);
    target_pose.pose.orientation = tf::createQuaternionMsgFromRollPitchYaw(-0.41, 0.048, -1.97);
  }
  goal.object_pose = target_pose;
  ac.sendGoal(goal);

  ac.waitForResult();
  ROS_INFO("Action server result: %d", ac.getResult()->success);

  //exit
  return 0;
}
<|endoftext|>


<commit_before>/*
 * opencog/atoms/core/Checkers.cc
 *
 * Copyright (C) 2017 Linas Vepstas
 * All Rights Reserved
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Free Software Foundation and including the exceptions
 * at http://opencog.org/wiki/Licenses
 *
 * 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 Affero General Public License
 * along with this program; if not, write to:
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include <opencog/atoms/base/Atom.h>
#include <opencog/atoms/base/ClassServer.h>

using namespace opencog;

/// Provide static factory-time type checking.
/// This only performs a very simple kind of type checking;
/// it does not check deep types, nor does it check arity.

/// Check to see if every input atom is of Evaluatable type.
bool check_evaluatable(const Handle& bool_atom)
{
	// Make an exception for AndLink, its used in pattern matcher
	// in an unseemly way.
	if (bool_atom->get_type() == AND_LINK) return true;

	for (const Handle& h: bool_atom->getOutgoingSet())
	{
		Type t = h->get_type();
		// PutLinks and GetLinks cannot be type-checked statically.
		// Checking has to be defered until runtime.
		if (PUT_LINK == t) continue;
		if (GET_LINK == t) continue;
		if (VARIABLE_NODE == t) continue;
		if (DEFINED_PREDICATE_NODE == t) continue;

		// Fucking quote links. I hate those with a passion.
		if (QUOTE_LINK == t) continue;
		if (UNQUOTE_LINK == t) continue;

		if (not h->is_type(EVALUATABLE_LINK)) return false;
	}
	return true;
}

/// Check to see if every input atom is of Numeric type.
bool check_numeric(const Handle& bool_atom)
{
	for (const Handle& h: bool_atom->getOutgoingSet())
	{
		Type t = h->get_type();
		// PutLinks and GetLinks cannot be type-checked statically.
		// Checking has to be defered until runtime.
		if (PUT_LINK == t) continue;
		if (GET_LINK == t) continue;
		if (EXECUTION_OUTPUT_LINK == t) continue;

		if (VARIABLE_NODE == t) continue;
		if (NUMBER_NODE == t) continue;

		// TODO - look up the schema, and make sure its numeric, also.
		if (DEFINED_SCHEMA_NODE == t) continue;

		// Oddly enough, sets of numbers are allowed.
		if (SET_LINK == t and check_numeric(h)) continue;

		if (not h->is_type(NUMERIC_OUTPUT_LINK)) return false;
	}
	return true;
}

/// Check the type constructors that expect types as input.
bool check_type_ctors(const Handle& bool_atom)
{
	for (const Handle& h: bool_atom->getOutgoingSet())
	{
		Type t = h->get_type();
		if (h->is_type(TYPE_NODE)) continue;

		// Intervals are commonly used with GlobNodes.
		if (INTERVAL_LINK == t) continue;

		if (not h->is_type(TYPE_OUTPUT_LINK)) return false;
	}
	return true;
}

/* This runs when the shared lib is loaded. */
static __attribute__ ((constructor)) void init(void)
{
	classserver().addValidator(BOOLEAN_LINK, check_evaluatable);
	classserver().addValidator(NUMERIC_LINK, check_numeric);
	classserver().addValidator(TYPE_LINK, check_type_ctors);
}
<commit_msg>Be more lenient towards PredicateNode<commit_after>/*
 * opencog/atoms/core/Checkers.cc
 *
 * Copyright (C) 2017 Linas Vepstas
 * All Rights Reserved
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Free Software Foundation and including the exceptions
 * at http://opencog.org/wiki/Licenses
 *
 * 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 Affero General Public License
 * along with this program; if not, write to:
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include <opencog/atoms/base/Atom.h>
#include <opencog/atoms/base/ClassServer.h>

using namespace opencog;

/// Provide static factory-time type checking.
/// This only performs a very simple kind of type checking;
/// it does not check deep types, nor does it check arity.

/// Check to see if every input atom is of Evaluatable type.
bool check_evaluatable(const Handle& bool_atom)
{
	// Make an exception for AndLink, its used in pattern matcher
	// in an unseemly way.
	if (bool_atom->get_type() == AND_LINK) return true;

	for (const Handle& h: bool_atom->getOutgoingSet())
	{
		Type t = h->get_type();
		// PutLinks and GetLinks cannot be type-checked statically.
		// Checking has to be defered until runtime.
		if (PUT_LINK == t) continue;
		if (GET_LINK == t) continue;
		if (VARIABLE_NODE == t) continue;
		if (DEFINED_PREDICATE_NODE == t) continue;

		// XXX This is kind-of pushing it, but OK, allow PredicateNode
		if (PREDICATE_NODE == t) continue;

		// Fucking quote links. I hate those with a passion.
		if (QUOTE_LINK == t) continue;
		if (UNQUOTE_LINK == t) continue;

		if (not h->is_type(EVALUATABLE_LINK)) return false;
	}
	return true;
}

/// Check to see if every input atom is of Numeric type.
bool check_numeric(const Handle& bool_atom)
{
	for (const Handle& h: bool_atom->getOutgoingSet())
	{
		Type t = h->get_type();
		// PutLinks and GetLinks cannot be type-checked statically.
		// Checking has to be defered until runtime.
		if (PUT_LINK == t) continue;
		if (GET_LINK == t) continue;
		if (EXECUTION_OUTPUT_LINK == t) continue;

		if (VARIABLE_NODE == t) continue;
		if (NUMBER_NODE == t) continue;

		// TODO - look up the schema, and make sure its numeric, also.
		if (DEFINED_SCHEMA_NODE == t) continue;

		// Oddly enough, sets of numbers are allowed.
		if (SET_LINK == t and check_numeric(h)) continue;

		if (not h->is_type(NUMERIC_OUTPUT_LINK)) return false;
	}
	return true;
}

/// Check the type constructors that expect types as input.
bool check_type_ctors(const Handle& bool_atom)
{
	for (const Handle& h: bool_atom->getOutgoingSet())
	{
		Type t = h->get_type();
		if (h->is_type(TYPE_NODE)) continue;

		// Intervals are commonly used with GlobNodes.
		if (INTERVAL_LINK == t) continue;

		if (not h->is_type(TYPE_OUTPUT_LINK)) return false;
	}
	return true;
}

/* This runs when the shared lib is loaded. */
static __attribute__ ((constructor)) void init(void)
{
	classserver().addValidator(BOOLEAN_LINK, check_evaluatable);
	classserver().addValidator(NUMERIC_LINK, check_numeric);
	classserver().addValidator(TYPE_LINK, check_type_ctors);
}
<|endoftext|>


<commit_before>/* Copyright 2015 Samsung Electronics Co., LTD
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/***************************************************************************
 * Containing data about how to position an object.
 ***************************************************************************/

#include "transform.h"

#include "glm/gtc/type_ptr.hpp"

#include "objects/scene_object.h"
#include <math.h>
namespace gvr {

Transform::Transform() :
        Component(Transform::getComponentType()), position_(glm::vec3(0.0f, 0.0f, 0.0f)),
        rotation_(
                glm::quat(1.0f, 0.0f, 0.0f, 0.0f)), scale_(
        glm::vec3(1.0f, 1.0f, 1.0f)), model_matrix_(
        Lazy<glm::mat4>(glm::mat4())) {
}

Transform::~Transform() {
    owner_object_->onTransformChanged();
}

void Transform::invalidate()
{
    mutex_.lock();
    model_matrix_.invalidate();
    mutex_.unlock();
}

void Transform::invalidate(bool rotationUpdated)
{
    SceneObject* owner = owner_object();

    invalidate();
    if (rotationUpdated)
    {
        // scale rotation_ if needed to avoid overflow
        static const float threshold = sqrt(FLT_MAX) / 2.0f;
        static const float scale_factor = 0.5f / sqrt(FLT_MAX);
        mutex_.lock();
        if (rotation_.w > threshold || rotation_.x > threshold ||
            rotation_.y > threshold || rotation_.z > threshold)
        {
            rotation_.w *= scale_factor;
            rotation_.x *= scale_factor;
            rotation_.y *= scale_factor;
            rotation_.z *= scale_factor;
        }
        mutex_.unlock();
    }
    if (owner)
    {
        owner->onTransformChanged();
        owner->dirtyHierarchicalBoundingVolume();
    }
}

glm::mat4 Transform::getModelMatrix(bool forceRecalculate) {
    if (!isModelMatrixValid() || forceRecalculate) {
        mutex_.lock();
        glm::mat4 translation_matrix = glm::translate(glm::mat4(), position_);
        glm::mat4 rotation_matrix = glm::mat4_cast(rotation_);
        glm::mat4 scale_matrix = glm::scale(glm::mat4(), scale_);
        mutex_.unlock();

        glm::mat4 trs_matrix = translation_matrix * rotation_matrix
                               * scale_matrix;
        if (owner_object()->parent() != 0) {
            Transform *const t = owner_object()->parent()->transform();
            if (nullptr != t) {
                glm::mat4 model_matrix = t->getModelMatrix() * trs_matrix;
                mutex_.lock();
                model_matrix_.validate(model_matrix);
                mutex_.unlock();
            }
        } else {
            mutex_.lock();
            model_matrix_.validate(trs_matrix);
            mutex_.unlock();
        }
    }
    mutex_.lock();
    glm::mat4 elem = model_matrix_.element();
    mutex_.unlock();
    return elem;
}

glm::mat4 Transform::getLocalModelMatrix() {
    mutex_.lock();
    glm::mat4 translation_matrix = glm::translate(glm::mat4(), position_);
    glm::mat4 rotation_matrix = glm::mat4_cast(rotation_);
    glm::mat4 scale_matrix = glm::scale(glm::mat4(), scale_);
    mutex_.unlock();
    glm::mat4 trs_matrix = translation_matrix * rotation_matrix
                           * scale_matrix;
    return trs_matrix;
}

void Transform::setModelMatrix(glm::mat4 matrix) {

    glm::vec3 new_position(matrix[3][0], matrix[3][1], matrix[3][2]);

    glm::vec3 Xaxis(matrix[0][0], matrix[0][1], matrix[0][2]);
    glm::vec3 Yaxis(matrix[1][0], matrix[1][1], matrix[1][2]);
    glm::vec3 Zaxis(matrix[2][0], matrix[2][1], matrix[2][2]);

    double zs = glm::dot(glm::cross(Xaxis, Yaxis), Zaxis);
    double ys = glm::dot(glm::cross(Zaxis, Xaxis), Yaxis);
    double xs = glm::dot(glm::cross(Yaxis, Zaxis), Xaxis);

    xs = std::signbit(xs);
    ys = std::signbit(ys);
    zs = std::signbit(zs);

    xs = (xs > 0.0 ? -1 : 1);
    ys = (ys > 0.0 ? -1 : 1);
    zs = (zs > 0.0 ? -1 : 1);

    glm::vec3 new_scale;
    new_scale.x = xs * glm::sqrt(
            matrix[0][0] * matrix[0][0] + matrix[0][1] * matrix[0][1]
            + matrix[0][2] * matrix[0][2]);
    new_scale.y = ys * glm::sqrt(
            matrix[1][0] * matrix[1][0] + matrix[1][1] * matrix[1][1]
            + matrix[1][2] * matrix[1][2]);
    new_scale.z = zs * glm::sqrt(
            matrix[2][0] * matrix[2][0] + matrix[2][1] * matrix[2][1]
            + matrix[2][2] * matrix[2][2]);

    glm::mat3 rotation_mat(matrix[0][0] / new_scale.x,
                           matrix[0][1] / new_scale.y, matrix[0][2] / new_scale.z,
                           matrix[1][0] / new_scale.x, matrix[1][1] / new_scale.y,
                           matrix[1][2] / new_scale.z, matrix[2][0] / new_scale.x,
                           matrix[2][1] / new_scale.y, matrix[2][2] / new_scale.z);
    mutex_.lock();
    position_ = new_position;
    scale_ = new_scale;
    rotation_ = glm::quat_cast(rotation_mat);
    mutex_.unlock();
    invalidate(true);
}

void Transform::translate(float x, float y, float z) {
    mutex_.lock();
    position_ += glm::vec3(x, y, z);
    mutex_.unlock();
    invalidate(false);
}

// angle in radians
void Transform::setRotationByAxis(float angle, float x, float y, float z) {
    mutex_.lock();
    rotation_ = glm::angleAxis(angle, glm::vec3(x, y, z));
    mutex_.unlock();
    invalidate(true);
}

void Transform::rotate(float w, float x, float y, float z) {
    mutex_.lock();
    rotation_ = glm::quat(w, x, y, z) * rotation_;
    mutex_.unlock();
    invalidate(true);
}

// angle in radians
void Transform::rotateByAxis(float angle, float x, float y, float z) {
    mutex_.lock();
    rotation_ = glm::angleAxis(angle, glm::vec3(x, y, z)) * rotation_;
    mutex_.unlock();
    invalidate(true);
}

// angle in radians
void Transform::rotateByAxisWithPivot(float angle, float axis_x, float axis_y,
                                      float axis_z, float pivot_x, float pivot_y,
                                      float pivot_z) {
    glm::quat axis_rotation = glm::angleAxis(angle,
                                             glm::vec3(axis_x, axis_y, axis_z));
    mutex_.lock();
    rotation_ = axis_rotation * rotation_;
    glm::vec3 pivot(pivot_x, pivot_y, pivot_z);
    glm::vec3 relative_position = position_ - pivot;
    relative_position = glm::rotate(axis_rotation, relative_position);
    position_ = relative_position + pivot;
    mutex_.unlock();
    invalidate(true);
}

void Transform::rotateWithPivot(float w, float x, float y, float z,
                                float pivot_x, float pivot_y, float pivot_z) {
    glm::quat rotation(w, x, y, z);
    mutex_.lock();
    rotation_ = rotation * rotation_;
    glm::vec3 pivot(pivot_x, pivot_y, pivot_z);
    glm::vec3 relative_position = position_ - pivot;
    relative_position = glm::rotate(rotation, relative_position);
    position_ = relative_position + pivot;
    mutex_.unlock();
    invalidate(true);
}

void Transform::onAttach(SceneObject *owner_object) {
    owner_object->onTransformChanged();
}

void Transform::onDetach(SceneObject *owner_object) {
    owner_object->onTransformChanged();
}
}
<commit_msg>Owner object could be null<commit_after>/* Copyright 2015 Samsung Electronics Co., LTD
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/***************************************************************************
 * Containing data about how to position an object.
 ***************************************************************************/

#include "transform.h"

#include "glm/gtc/type_ptr.hpp"

#include "objects/scene_object.h"
#include <math.h>
namespace gvr {

Transform::Transform() :
        Component(Transform::getComponentType()), position_(glm::vec3(0.0f, 0.0f, 0.0f)),
        rotation_(
                glm::quat(1.0f, 0.0f, 0.0f, 0.0f)), scale_(
        glm::vec3(1.0f, 1.0f, 1.0f)), model_matrix_(
        Lazy<glm::mat4>(glm::mat4())) {
}

Transform::~Transform() {
    if(owner_object_) {
        owner_object_->onTransformChanged();
    }
}

void Transform::invalidate()
{
    mutex_.lock();
    model_matrix_.invalidate();
    mutex_.unlock();
}

void Transform::invalidate(bool rotationUpdated)
{
    SceneObject* owner = owner_object();

    invalidate();
    if (rotationUpdated)
    {
        // scale rotation_ if needed to avoid overflow
        static const float threshold = sqrt(FLT_MAX) / 2.0f;
        static const float scale_factor = 0.5f / sqrt(FLT_MAX);
        mutex_.lock();
        if (rotation_.w > threshold || rotation_.x > threshold ||
            rotation_.y > threshold || rotation_.z > threshold)
        {
            rotation_.w *= scale_factor;
            rotation_.x *= scale_factor;
            rotation_.y *= scale_factor;
            rotation_.z *= scale_factor;
        }
        mutex_.unlock();
    }
    if (owner)
    {
        owner->onTransformChanged();
        owner->dirtyHierarchicalBoundingVolume();
    }
}

glm::mat4 Transform::getModelMatrix(bool forceRecalculate) {
    if (!isModelMatrixValid() || forceRecalculate) {
        mutex_.lock();
        glm::mat4 translation_matrix = glm::translate(glm::mat4(), position_);
        glm::mat4 rotation_matrix = glm::mat4_cast(rotation_);
        glm::mat4 scale_matrix = glm::scale(glm::mat4(), scale_);
        mutex_.unlock();

        glm::mat4 trs_matrix = translation_matrix * rotation_matrix
                               * scale_matrix;
        if (owner_object()->parent() != 0) {
            Transform *const t = owner_object()->parent()->transform();
            if (nullptr != t) {
                glm::mat4 model_matrix = t->getModelMatrix() * trs_matrix;
                mutex_.lock();
                model_matrix_.validate(model_matrix);
                mutex_.unlock();
            }
        } else {
            mutex_.lock();
            model_matrix_.validate(trs_matrix);
            mutex_.unlock();
        }
    }
    mutex_.lock();
    glm::mat4 elem = model_matrix_.element();
    mutex_.unlock();
    return elem;
}

glm::mat4 Transform::getLocalModelMatrix() {
    mutex_.lock();
    glm::mat4 translation_matrix = glm::translate(glm::mat4(), position_);
    glm::mat4 rotation_matrix = glm::mat4_cast(rotation_);
    glm::mat4 scale_matrix = glm::scale(glm::mat4(), scale_);
    mutex_.unlock();
    glm::mat4 trs_matrix = translation_matrix * rotation_matrix
                           * scale_matrix;
    return trs_matrix;
}

void Transform::setModelMatrix(glm::mat4 matrix) {

    glm::vec3 new_position(matrix[3][0], matrix[3][1], matrix[3][2]);

    glm::vec3 Xaxis(matrix[0][0], matrix[0][1], matrix[0][2]);
    glm::vec3 Yaxis(matrix[1][0], matrix[1][1], matrix[1][2]);
    glm::vec3 Zaxis(matrix[2][0], matrix[2][1], matrix[2][2]);

    double zs = glm::dot(glm::cross(Xaxis, Yaxis), Zaxis);
    double ys = glm::dot(glm::cross(Zaxis, Xaxis), Yaxis);
    double xs = glm::dot(glm::cross(Yaxis, Zaxis), Xaxis);

    xs = std::signbit(xs);
    ys = std::signbit(ys);
    zs = std::signbit(zs);

    xs = (xs > 0.0 ? -1 : 1);
    ys = (ys > 0.0 ? -1 : 1);
    zs = (zs > 0.0 ? -1 : 1);

    glm::vec3 new_scale;
    new_scale.x = xs * glm::sqrt(
            matrix[0][0] * matrix[0][0] + matrix[0][1] * matrix[0][1]
            + matrix[0][2] * matrix[0][2]);
    new_scale.y = ys * glm::sqrt(
            matrix[1][0] * matrix[1][0] + matrix[1][1] * matrix[1][1]
            + matrix[1][2] * matrix[1][2]);
    new_scale.z = zs * glm::sqrt(
            matrix[2][0] * matrix[2][0] + matrix[2][1] * matrix[2][1]
            + matrix[2][2] * matrix[2][2]);

    glm::mat3 rotation_mat(matrix[0][0] / new_scale.x,
                           matrix[0][1] / new_scale.y, matrix[0][2] / new_scale.z,
                           matrix[1][0] / new_scale.x, matrix[1][1] / new_scale.y,
                           matrix[1][2] / new_scale.z, matrix[2][0] / new_scale.x,
                           matrix[2][1] / new_scale.y, matrix[2][2] / new_scale.z);
    mutex_.lock();
    position_ = new_position;
    scale_ = new_scale;
    rotation_ = glm::quat_cast(rotation_mat);
    mutex_.unlock();
    invalidate(true);
}

void Transform::translate(float x, float y, float z) {
    mutex_.lock();
    position_ += glm::vec3(x, y, z);
    mutex_.unlock();
    invalidate(false);
}

// angle in radians
void Transform::setRotationByAxis(float angle, float x, float y, float z) {
    mutex_.lock();
    rotation_ = glm::angleAxis(angle, glm::vec3(x, y, z));
    mutex_.unlock();
    invalidate(true);
}

void Transform::rotate(float w, float x, float y, float z) {
    mutex_.lock();
    rotation_ = glm::quat(w, x, y, z) * rotation_;
    mutex_.unlock();
    invalidate(true);
}

// angle in radians
void Transform::rotateByAxis(float angle, float x, float y, float z) {
    mutex_.lock();
    rotation_ = glm::angleAxis(angle, glm::vec3(x, y, z)) * rotation_;
    mutex_.unlock();
    invalidate(true);
}

// angle in radians
void Transform::rotateByAxisWithPivot(float angle, float axis_x, float axis_y,
                                      float axis_z, float pivot_x, float pivot_y,
                                      float pivot_z) {
    glm::quat axis_rotation = glm::angleAxis(angle,
                                             glm::vec3(axis_x, axis_y, axis_z));
    mutex_.lock();
    rotation_ = axis_rotation * rotation_;
    glm::vec3 pivot(pivot_x, pivot_y, pivot_z);
    glm::vec3 relative_position = position_ - pivot;
    relative_position = glm::rotate(axis_rotation, relative_position);
    position_ = relative_position + pivot;
    mutex_.unlock();
    invalidate(true);
}

void Transform::rotateWithPivot(float w, float x, float y, float z,
                                float pivot_x, float pivot_y, float pivot_z) {
    glm::quat rotation(w, x, y, z);
    mutex_.lock();
    rotation_ = rotation * rotation_;
    glm::vec3 pivot(pivot_x, pivot_y, pivot_z);
    glm::vec3 relative_position = position_ - pivot;
    relative_position = glm::rotate(rotation, relative_position);
    position_ = relative_position + pivot;
    mutex_.unlock();
    invalidate(true);
}

void Transform::onAttach(SceneObject *owner_object) {
    owner_object->onTransformChanged();
}

void Transform::onDetach(SceneObject *owner_object) {
    owner_object->onTransformChanged();
}
}
<|endoftext|>


<commit_before>// Copyright 2016 Benjamin Glatzel
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Precompiled header file
#include "stdafx_vulkan.h"
#include "stdafx.h"

namespace Intrinsic
{
namespace Renderer
{
namespace Vulkan
{
namespace Resources
{
void BufferManager::createResources(const BufferRefArray& p_Buffers)
{
  VkCommandBuffer copyCmd = RenderSystem::beginTemporaryCommandBuffer();

  _INTR_ARRAY(VkBuffer) stagingBuffersToDestroy;
  stagingBuffersToDestroy.reserve(p_Buffers.size());

  for (uint32_t i = 0u; i < p_Buffers.size(); ++i)
  {
    BufferRef bufferRef = p_Buffers[i];

    VkBufferCreateInfo bufferCreateInfo = {};
    {
      bufferCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
      bufferCreateInfo.pNext = nullptr;
      bufferCreateInfo.usage =
          Helper::mapBufferTypeToVkUsageFlagBits(_descBufferType(bufferRef)) |
          VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
      bufferCreateInfo.size = _descSizeInBytes(bufferRef);
      bufferCreateInfo.queueFamilyIndexCount = 0;
      bufferCreateInfo.pQueueFamilyIndices = nullptr;
      bufferCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
      bufferCreateInfo.flags = 0u;
    }

    VkBuffer& buffer = _vkBuffer(bufferRef);
    _INTR_ASSERT(buffer == VK_NULL_HANDLE);

    VkResult result = vkCreateBuffer(RenderSystem::_vkDevice, &bufferCreateInfo,
                                     nullptr, &buffer);
    _INTR_VK_CHECK_RESULT(result);

    VkMemoryRequirements memReqs;
    vkGetBufferMemoryRequirements(RenderSystem::_vkDevice, buffer, &memReqs);

    MemoryPoolType::Enum memoryPoolType = _descMemoryPoolType(bufferRef);
    MemoryAllocationInfo& memoryAllocationInfo =
        _memoryAllocationInfo(bufferRef);
    VkDeviceMemory deviceMemory =
        GpuMemoryManager::getDeviceMemory(memoryPoolType);

    bool needsAlloc = true;

    // Try to keep memory for static buffers
    if (memoryPoolType >= MemoryPoolType::kRangeStartStatic &&
        memoryPoolType <= MemoryPoolType::kRangeEndStatic)
    {
      if (memoryAllocationInfo.memoryPoolType == memoryPoolType &&
          memReqs.size <= memoryAllocationInfo.sizeInBytes &&
          memReqs.alignment == memoryAllocationInfo.alignmentInBytes &&
          deviceMemory == memoryAllocationInfo.vkDeviceMemory)
      {
        needsAlloc = false;
      }
    }

    if (needsAlloc)
    {
      memoryAllocationInfo.sizeInBytes = (uint32_t)memReqs.size;
      memoryAllocationInfo.alignmentInBytes = (uint32_t)memReqs.alignment;
      memoryAllocationInfo.memoryPoolType = memoryPoolType;
      memoryAllocationInfo.vkDeviceMemory = deviceMemory;
      memoryAllocationInfo.offsetInBytes = GpuMemoryManager::allocateOffset(
          memoryPoolType, (uint32_t)memReqs.size, (uint32_t)memReqs.alignment);
    }

    result = vkBindBufferMemory(RenderSystem::_vkDevice, buffer,
                                memoryAllocationInfo.vkDeviceMemory,
                                memoryAllocationInfo.offsetInBytes);
    _INTR_VK_CHECK_RESULT(result);

    void* initialData = _descInitialData(bufferRef);
    if (initialData)
    {
      VkBufferCreateInfo stagingBufferCreateInfo = bufferCreateInfo;
      {
        stagingBufferCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
      }

      VkBuffer stagingBuffer;
      result = vkCreateBuffer(RenderSystem::_vkDevice, &stagingBufferCreateInfo,
                              nullptr, &stagingBuffer);
      _INTR_VK_CHECK_RESULT(result);

      // We've run out of memory - flush the command buffer and reset the
      // allocator
      if (GpuMemoryManager::calcAvailableMemoryInBytes(
              MemoryPoolType::kVolatileStagingBuffers) < memReqs.size)
      {
        RenderSystem::flushTemporaryCommandBuffer();
        GpuMemoryManager::resetAllocator(
            MemoryPoolType::kVolatileStagingBuffers);
        copyCmd = RenderSystem::beginTemporaryCommandBuffer();
      }

      const uint32_t stagingMemOffset = GpuMemoryManager::allocateOffset(
          MemoryPoolType::kVolatileStagingBuffers, (uint32_t)memReqs.size,
          (uint32_t)memReqs.alignment);

      result = vkBindBufferMemory(RenderSystem::_vkDevice, stagingBuffer,
                                  GpuMemoryManager::getDeviceMemory(
                                      MemoryPoolType::kVolatileStagingBuffers),
                                  stagingMemOffset);
      _INTR_VK_CHECK_RESULT(result);

      // Copy initial data to staging memory
      {
        memcpy(
            GpuMemoryManager::getHostVisibleMemoryForOffset(stagingMemOffset),
            initialData, _descSizeInBytes(bufferRef));
      }

      VkBufferCopy bufferCopy = {};
      {
        bufferCopy.dstOffset = 0u;
        bufferCopy.srcOffset = 0u;
        bufferCopy.size = _descSizeInBytes(bufferRef);
      }

      // Finally copy from the staging buffer to the actual buffer
      vkCmdCopyBuffer(copyCmd, stagingBuffer, buffer, 1u, &bufferCopy);
    }
  }

  RenderSystem::flushTemporaryCommandBuffer();

  for (uint32_t i = 0u; i < stagingBuffersToDestroy.size(); ++i)
  {
    vkDestroyBuffer(RenderSystem::_vkDevice, stagingBuffersToDestroy[i],
                    nullptr);
  }

  GpuMemoryManager::resetAllocator(MemoryPoolType::kVolatileStagingBuffers);
}
}
}
}
}
<commit_msg>Fixed Vulkan validation warning<commit_after>// Copyright 2016 Benjamin Glatzel
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Precompiled header file
#include "stdafx_vulkan.h"
#include "stdafx.h"

namespace Intrinsic
{
namespace Renderer
{
namespace Vulkan
{
namespace Resources
{
void BufferManager::createResources(const BufferRefArray& p_Buffers)
{
  VkCommandBuffer copyCmd = RenderSystem::beginTemporaryCommandBuffer();

  _INTR_ARRAY(VkBuffer) stagingBuffersToDestroy;
  stagingBuffersToDestroy.reserve(p_Buffers.size());

  for (uint32_t i = 0u; i < p_Buffers.size(); ++i)
  {
    BufferRef bufferRef = p_Buffers[i];

    VkBufferCreateInfo bufferCreateInfo = {};
    {
      bufferCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
      bufferCreateInfo.pNext = nullptr;
      bufferCreateInfo.usage =
          Helper::mapBufferTypeToVkUsageFlagBits(_descBufferType(bufferRef)) |
          VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
      bufferCreateInfo.size = _descSizeInBytes(bufferRef);
      bufferCreateInfo.queueFamilyIndexCount = 0;
      bufferCreateInfo.pQueueFamilyIndices = nullptr;
      bufferCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
      bufferCreateInfo.flags = 0u;
    }

    VkBuffer& buffer = _vkBuffer(bufferRef);
    _INTR_ASSERT(buffer == VK_NULL_HANDLE);

    VkResult result = vkCreateBuffer(RenderSystem::_vkDevice, &bufferCreateInfo,
                                     nullptr, &buffer);
    _INTR_VK_CHECK_RESULT(result);

    VkMemoryRequirements memReqs;
    vkGetBufferMemoryRequirements(RenderSystem::_vkDevice, buffer, &memReqs);

    MemoryPoolType::Enum memoryPoolType = _descMemoryPoolType(bufferRef);
    MemoryAllocationInfo& memoryAllocationInfo =
        _memoryAllocationInfo(bufferRef);
    VkDeviceMemory deviceMemory =
        GpuMemoryManager::getDeviceMemory(memoryPoolType);

    bool needsAlloc = true;

    // Try to keep memory for static buffers
    if (memoryPoolType >= MemoryPoolType::kRangeStartStatic &&
        memoryPoolType <= MemoryPoolType::kRangeEndStatic)
    {
      if (memoryAllocationInfo.memoryPoolType == memoryPoolType &&
          memReqs.size <= memoryAllocationInfo.sizeInBytes &&
          memReqs.alignment == memoryAllocationInfo.alignmentInBytes &&
          deviceMemory == memoryAllocationInfo.vkDeviceMemory)
      {
        needsAlloc = false;
      }
    }

    if (needsAlloc)
    {
      memoryAllocationInfo.sizeInBytes = (uint32_t)memReqs.size;
      memoryAllocationInfo.alignmentInBytes = (uint32_t)memReqs.alignment;
      memoryAllocationInfo.memoryPoolType = memoryPoolType;
      memoryAllocationInfo.vkDeviceMemory = deviceMemory;
      memoryAllocationInfo.offsetInBytes = GpuMemoryManager::allocateOffset(
          memoryPoolType, (uint32_t)memReqs.size, (uint32_t)memReqs.alignment);
    }

    result = vkBindBufferMemory(RenderSystem::_vkDevice, buffer,
                                memoryAllocationInfo.vkDeviceMemory,
                                memoryAllocationInfo.offsetInBytes);
    _INTR_VK_CHECK_RESULT(result);

    void* initialData = _descInitialData(bufferRef);
    if (initialData)
    {
      VkBufferCreateInfo stagingBufferCreateInfo = bufferCreateInfo;
      {
        stagingBufferCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
      }

      VkBuffer stagingBuffer;
      result = vkCreateBuffer(RenderSystem::_vkDevice, &stagingBufferCreateInfo,
                              nullptr, &stagingBuffer);
      _INTR_VK_CHECK_RESULT(result);

      // We've run out of memory - flush the command buffer and reset the
      // allocator
      if (GpuMemoryManager::calcAvailableMemoryInBytes(
              MemoryPoolType::kVolatileStagingBuffers) < memReqs.size)
      {
        RenderSystem::flushTemporaryCommandBuffer();
        GpuMemoryManager::resetAllocator(
            MemoryPoolType::kVolatileStagingBuffers);
        copyCmd = RenderSystem::beginTemporaryCommandBuffer();
      }

      VkMemoryRequirements stagingMemReqs;
      vkGetBufferMemoryRequirements(RenderSystem::_vkDevice, stagingBuffer,
                                    &stagingMemReqs);

      const uint32_t stagingMemOffset = GpuMemoryManager::allocateOffset(
          MemoryPoolType::kVolatileStagingBuffers,
          (uint32_t)stagingMemReqs.size, (uint32_t)stagingMemReqs.alignment);

      result = vkBindBufferMemory(RenderSystem::_vkDevice, stagingBuffer,
                                  GpuMemoryManager::getDeviceMemory(
                                      MemoryPoolType::kVolatileStagingBuffers),
                                  stagingMemOffset);
      _INTR_VK_CHECK_RESULT(result);

      // Copy initial data to staging memory
      {
        memcpy(
            GpuMemoryManager::getHostVisibleMemoryForOffset(stagingMemOffset),
            initialData, _descSizeInBytes(bufferRef));
      }

      VkBufferCopy bufferCopy = {};
      {
        bufferCopy.dstOffset = 0u;
        bufferCopy.srcOffset = 0u;
        bufferCopy.size = _descSizeInBytes(bufferRef);
      }

      // Finally copy from the staging buffer to the actual buffer
      vkCmdCopyBuffer(copyCmd, stagingBuffer, buffer, 1u, &bufferCopy);
    }
  }

  RenderSystem::flushTemporaryCommandBuffer();

  for (uint32_t i = 0u; i < stagingBuffersToDestroy.size(); ++i)
  {
    vkDestroyBuffer(RenderSystem::_vkDevice, stagingBuffersToDestroy[i],
                    nullptr);
  }

  GpuMemoryManager::resetAllocator(MemoryPoolType::kVolatileStagingBuffers);
}
}
}
}
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
 *
 * This file is part of Orfeo Toolbox
 *
 *     https://www.orfeo-toolbox.org/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef otbVectorPrediction_hxx
#define otbVectorPrediction_hxx

#include "otbVectorPrediction.h"

namespace otb
{
namespace Wrapper
{

template <bool RegressionMode>
void           VectorPrediction<RegressionMode>::DoInit()
{
  DoInitSpecialization();

  // Assert that the all needed parameters have ben definied in DoInitSpecialization
  assert(GetParameterByKey("in") != nullptr);
  assert(GetParameterByKey("instat") != nullptr);
  assert(GetParameterByKey("model") != nullptr);
  assert(GetParameterByKey("cfield") != nullptr);
  assert(GetParameterByKey("feat") != nullptr);
  assert(GetParameterByKey("out") != nullptr);
}

template <bool RegressionMode>
void           VectorPrediction<RegressionMode>::DoUpdateParameters()
{
  if (HasValue("in"))
  {
    auto shapefileName = GetParameterString("in");

    auto ogrDS = otb::ogr::DataSource::New(shapefileName, otb::ogr::DataSource::Modes::Read);
    auto layer     = ogrDS->GetLayer(0);
    OGRFeatureDefn& layerDefn = layer.GetLayerDefn();

    ClearChoices("feat");

    for (int iField = 0; iField < layerDefn.GetFieldCount(); iField++)
    {
      auto fieldDefn = layerDefn.GetFieldDefn(iField);
      std::string item = fieldDefn->GetNameRef();
      std::string key(item);
      key.erase(std::remove_if(key.begin(), key.end(), IsNotAlphaNum), key.end());
      std::transform(key.begin(), key.end(), key.begin(), tolower);

      auto fieldType = fieldDefn->GetType();
      if (fieldType == OFTInteger || fieldType == OFTInteger64 || fieldType == OFTReal)
      {
        std::string tmpKey = "feat." + key;
        AddChoice(tmpKey, item);
      }
    }
  }
}

template <bool RegressionMode>
void           VectorPrediction<RegressionMode>::DoExecute()
{
  auto shapefileName = GetParameterString("in");

  auto source = otb::ogr::DataSource::New(shapefileName, otb::ogr::DataSource::Modes::Read);
  auto layer  = source->GetLayer(0);

  typename ListSampleType::Pointer input = ListSampleType::New();

  const int nbFeatures = GetSelectedItems("feat").size();
  input->SetMeasurementVectorSize(nbFeatures);

  for (auto const& feature : layer)
  {
    MeasurementType mv;
    mv.SetSize(nbFeatures);
    for (int idx = 0; idx < nbFeatures; ++idx)
    {
      // Beware that itemIndex differs from ogr layer field index
      unsigned int itemIndex = GetSelectedItems("feat")[idx];
      std::string  fieldName = GetChoiceNames("feat")[itemIndex];

      auto field = feature[fieldName];
      switch (field.GetType())
      {
      case OFTInteger || OFTInteger64:
        mv[idx] = static_cast<ValueType>(field.template GetValue<int>());
        break;
      case OFTReal:
        mv[idx] = static_cast<ValueType>(field.template GetValue<double>());
        break;
      default:
        itkExceptionMacro(<< "incorrect field type: " << field.GetType() << ".");
      }
    }
    input->PushBack(mv);
  }

  // Statistics for shift/scale
  MeasurementType meanMeasurementVector;
  MeasurementType stddevMeasurementVector;
  if (HasValue("instat") && IsParameterEnabled("instat"))
  {
    typename StatisticsReader::Pointer statisticsReader = StatisticsReader::New();
    std::string                        XMLfile          = GetParameterString("instat");
    statisticsReader->SetFileName(XMLfile);
    meanMeasurementVector   = statisticsReader->GetStatisticVectorByName("mean");
    stddevMeasurementVector = statisticsReader->GetStatisticVectorByName("stddev");
  }
  else
  {
    meanMeasurementVector.SetSize(nbFeatures);
    meanMeasurementVector.Fill(0.);
    stddevMeasurementVector.SetSize(nbFeatures);
    stddevMeasurementVector.Fill(1.);
  }

  typename ShiftScaleFilterType::Pointer trainingShiftScaleFilter = ShiftScaleFilterType::New();
  trainingShiftScaleFilter->SetInput(input);
  trainingShiftScaleFilter->SetShifts(meanMeasurementVector);
  trainingShiftScaleFilter->SetScales(stddevMeasurementVector);
  trainingShiftScaleFilter->Update();
  otbAppLogINFO("mean used: " << meanMeasurementVector);
  otbAppLogINFO("standard deviation used: " << stddevMeasurementVector);

  otbAppLogINFO("Loading model");
  m_Model = MachineLearningModelFactoryType::CreateMachineLearningModel(GetParameterString("model"), MachineLearningModelFactoryType::ReadMode);

  if (m_Model.IsNull())
  {
    otbAppLogFATAL(<< "Error when loading model " << GetParameterString("model") << " : unsupported model type");
  }

  m_Model->SetRegressionMode(RegressionMode);

  m_Model->Load(GetParameterString("model"));
  otbAppLogINFO("Model loaded");

  ListSampleType::Pointer listSample = trainingShiftScaleFilter->GetOutput();

  typename ConfidenceListSampleType::Pointer quality;

  bool computeConfidenceMap = shouldComputeConfidenceMap();

  typename LabelListSampleType::Pointer target;
  if (computeConfidenceMap)
  {
    quality = ConfidenceListSampleType::New();
    target  = m_Model->PredictBatch(listSample, quality);
  }
  else
  {
    target = m_Model->PredictBatch(listSample);
  }

  ogr::DataSource::Pointer output;
  ogr::DataSource::Pointer buffer     = ogr::DataSource::New();
  bool                     updateMode = false;
  if (IsParameterEnabled("out") && HasValue("out"))
  {
    // Create new OGRDataSource
    output                   = ogr::DataSource::New(GetParameterString("out"), ogr::DataSource::Modes::Overwrite);
    otb::ogr::Layer newLayer = output->CreateLayer(GetParameterString("out"), const_cast<OGRSpatialReference*>(layer.GetSpatialRef()), layer.GetGeomType());
    // Copy existing fields
    OGRFeatureDefn& inLayerDefn = layer.GetLayerDefn();
    for (int k = 0; k < inLayerDefn.GetFieldCount(); k++)
    {
      OGRFieldDefn fieldDefn(inLayerDefn.GetFieldDefn(k));
      newLayer.CreateField(fieldDefn);
    }
  }
  else
  {
    // Update mode
    updateMode = true;
    otbAppLogINFO("Update input vector data.");
    // fill temporary buffer for the transfer
    otb::ogr::Layer inputLayer = layer;
    layer                      = buffer->CopyLayer(inputLayer, std::string("Buffer"));
    // close input data source
    source->Clear();
    // Re-open input data source in update mode
    output = otb::ogr::DataSource::New(shapefileName, otb::ogr::DataSource::Modes::Update_LayerUpdate);
  }

  otb::ogr::Layer outLayer = output->GetLayer(0);

  OGRErr errStart = outLayer.ogr().StartTransaction();
  if (errStart != OGRERR_NONE)
  {
    itkExceptionMacro(<< "Unable to start transaction for OGR layer " << outLayer.ogr().GetName() << ".");
  }

  OGRFeatureDefn& layerDefn = layer.GetLayerDefn();

  // Add the field of prediction in the output layer if field not exist

  const OGRFieldType labelType = RegressionMode ? OFTReal : OFTInteger;

  int idx = layerDefn.GetFieldIndex(GetParameterString("cfield").c_str());
  if (idx >= 0)
  {
    if (layerDefn.GetFieldDefn(idx)->GetType() != labelType)
      itkExceptionMacro("Field name " << GetParameterString("cfield") << " already exists with a different type!");
  }
  else
  {
    OGRFieldDefn   predictedField(GetParameterString("cfield").c_str(), labelType);
    ogr::FieldDefn predictedFieldDef(predictedField);
    outLayer.CreateField(predictedFieldDef);
  }

  // Add confidence field in the output layer
  std::string confFieldName("confidence");
  if (computeConfidenceMap)
  {
    idx = layerDefn.GetFieldIndex(confFieldName.c_str());
    if (idx >= 0)
    {
      if (layerDefn.GetFieldDefn(idx)->GetType() != OFTReal)
        itkExceptionMacro("Field name " << confFieldName << " already exists with a different type!");
    }
    else
    {
      OGRFieldDefn confidenceField(confFieldName.c_str(), OFTReal);
      confidenceField.SetWidth(confidenceField.GetWidth());
      confidenceField.SetPrecision(confidenceField.GetPrecision());
      ogr::FieldDefn confFieldDefn(confidenceField);
      outLayer.CreateField(confFieldDefn);
    }
  }

  // Fill output layer
  unsigned int count          = 0;
  std::string  classfieldname = GetParameterString("cfield");
  for (auto const& feature : layer)
  {
    ogr::Feature dstFeature(outLayer.GetLayerDefn());
    dstFeature.SetFrom(feature, TRUE);
    dstFeature.SetFID(feature.GetFID());
    auto field = dstFeature[classfieldname];
    switch (field.GetType())
    {
    case OFTInteger || OFTInteger64:
      field.template SetValue<int>(target->GetMeasurementVector(count)[0]);
      break;
    case OFTReal:
      field.template SetValue<double>(target->GetMeasurementVector(count)[0]);
      break;
    case OFTString:
      field.template SetValue<std::string>(std::to_string(target->GetMeasurementVector(count)[0]));
      break;
    default:
      itkExceptionMacro(<< "incorrect field type: " << field.GetType() << ".");
    }
    if (computeConfidenceMap)
      dstFeature[confFieldName].SetValue<double>(quality->GetMeasurementVector(count)[0]);
    if (updateMode)
    {
      outLayer.SetFeature(dstFeature);
    }
    else
    {
      outLayer.CreateFeature(dstFeature);
    }
  }

  if (outLayer.ogr().TestCapability("Transactions"))
  {
    const OGRErr errCommitX = outLayer.ogr().CommitTransaction();
    if (errCommitX != OGRERR_NONE)
    {
      itkExceptionMacro(<< "Unable to commit transaction for OGR layer " << outLayer.ogr().GetName() << ".");
    }
  }

  output->SyncToDisk();
}

} // end namespace wrapper
} // end namespace otb

#endif
<commit_msg>BUG: fix factorized switch case<commit_after>/*
 * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
 *
 * This file is part of Orfeo Toolbox
 *
 *     https://www.orfeo-toolbox.org/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef otbVectorPrediction_hxx
#define otbVectorPrediction_hxx

#include "otbVectorPrediction.h"

namespace otb
{
namespace Wrapper
{

template <bool RegressionMode>
void           VectorPrediction<RegressionMode>::DoInit()
{
  DoInitSpecialization();

  // Assert that the all needed parameters have ben definied in DoInitSpecialization
  assert(GetParameterByKey("in") != nullptr);
  assert(GetParameterByKey("instat") != nullptr);
  assert(GetParameterByKey("model") != nullptr);
  assert(GetParameterByKey("cfield") != nullptr);
  assert(GetParameterByKey("feat") != nullptr);
  assert(GetParameterByKey("out") != nullptr);
}

template <bool RegressionMode>
void           VectorPrediction<RegressionMode>::DoUpdateParameters()
{
  if (HasValue("in"))
  {
    auto shapefileName = GetParameterString("in");

    auto ogrDS = otb::ogr::DataSource::New(shapefileName, otb::ogr::DataSource::Modes::Read);
    auto layer     = ogrDS->GetLayer(0);
    OGRFeatureDefn& layerDefn = layer.GetLayerDefn();

    ClearChoices("feat");

    for (int iField = 0; iField < layerDefn.GetFieldCount(); iField++)
    {
      auto fieldDefn = layerDefn.GetFieldDefn(iField);
      std::string item = fieldDefn->GetNameRef();
      std::string key(item);
      key.erase(std::remove_if(key.begin(), key.end(), IsNotAlphaNum), key.end());
      std::transform(key.begin(), key.end(), key.begin(), tolower);

      auto fieldType = fieldDefn->GetType();
      if (fieldType == OFTInteger || fieldType == OFTInteger64 || fieldType == OFTReal)
      {
        std::string tmpKey = "feat." + key;
        AddChoice(tmpKey, item);
      }
    }
  }
}

template <bool RegressionMode>
void           VectorPrediction<RegressionMode>::DoExecute()
{
  auto shapefileName = GetParameterString("in");

  auto source = otb::ogr::DataSource::New(shapefileName, otb::ogr::DataSource::Modes::Read);
  auto layer  = source->GetLayer(0);

  typename ListSampleType::Pointer input = ListSampleType::New();

  const int nbFeatures = GetSelectedItems("feat").size();
  input->SetMeasurementVectorSize(nbFeatures);

  for (auto const& feature : layer)
  {
    MeasurementType mv;
    mv.SetSize(nbFeatures);
    for (int idx = 0; idx < nbFeatures; ++idx)
    {
      // Beware that itemIndex differs from ogr layer field index
      unsigned int itemIndex = GetSelectedItems("feat")[idx];
      std::string  fieldName = GetChoiceNames("feat")[itemIndex];

      auto field = feature[fieldName];
      switch (field.GetType())
      {
      case OFTInteger:
      case OFTInteger64:
        mv[idx] = static_cast<ValueType>(field.template GetValue<int>());
        break;
      case OFTReal:
        mv[idx] = static_cast<ValueType>(field.template GetValue<double>());
        break;
      default:
        itkExceptionMacro(<< "incorrect field type: " << field.GetType() << ".");
      }
    }
    input->PushBack(mv);
  }

  // Statistics for shift/scale
  MeasurementType meanMeasurementVector;
  MeasurementType stddevMeasurementVector;
  if (HasValue("instat") && IsParameterEnabled("instat"))
  {
    typename StatisticsReader::Pointer statisticsReader = StatisticsReader::New();
    std::string                        XMLfile          = GetParameterString("instat");
    statisticsReader->SetFileName(XMLfile);
    meanMeasurementVector   = statisticsReader->GetStatisticVectorByName("mean");
    stddevMeasurementVector = statisticsReader->GetStatisticVectorByName("stddev");
  }
  else
  {
    meanMeasurementVector.SetSize(nbFeatures);
    meanMeasurementVector.Fill(0.);
    stddevMeasurementVector.SetSize(nbFeatures);
    stddevMeasurementVector.Fill(1.);
  }

  typename ShiftScaleFilterType::Pointer trainingShiftScaleFilter = ShiftScaleFilterType::New();
  trainingShiftScaleFilter->SetInput(input);
  trainingShiftScaleFilter->SetShifts(meanMeasurementVector);
  trainingShiftScaleFilter->SetScales(stddevMeasurementVector);
  trainingShiftScaleFilter->Update();
  otbAppLogINFO("mean used: " << meanMeasurementVector);
  otbAppLogINFO("standard deviation used: " << stddevMeasurementVector);

  otbAppLogINFO("Loading model");
  m_Model = MachineLearningModelFactoryType::CreateMachineLearningModel(GetParameterString("model"), MachineLearningModelFactoryType::ReadMode);

  if (m_Model.IsNull())
  {
    otbAppLogFATAL(<< "Error when loading model " << GetParameterString("model") << " : unsupported model type");
  }

  m_Model->SetRegressionMode(RegressionMode);

  m_Model->Load(GetParameterString("model"));
  otbAppLogINFO("Model loaded");

  ListSampleType::Pointer listSample = trainingShiftScaleFilter->GetOutput();

  typename ConfidenceListSampleType::Pointer quality;

  bool computeConfidenceMap = shouldComputeConfidenceMap();

  typename LabelListSampleType::Pointer target;
  if (computeConfidenceMap)
  {
    quality = ConfidenceListSampleType::New();
    target  = m_Model->PredictBatch(listSample, quality);
  }
  else
  {
    target = m_Model->PredictBatch(listSample);
  }

  ogr::DataSource::Pointer output;
  ogr::DataSource::Pointer buffer     = ogr::DataSource::New();
  bool                     updateMode = false;
  if (IsParameterEnabled("out") && HasValue("out"))
  {
    // Create new OGRDataSource
    output                   = ogr::DataSource::New(GetParameterString("out"), ogr::DataSource::Modes::Overwrite);
    otb::ogr::Layer newLayer = output->CreateLayer(GetParameterString("out"), const_cast<OGRSpatialReference*>(layer.GetSpatialRef()), layer.GetGeomType());
    // Copy existing fields
    OGRFeatureDefn& inLayerDefn = layer.GetLayerDefn();
    for (int k = 0; k < inLayerDefn.GetFieldCount(); k++)
    {
      OGRFieldDefn fieldDefn(inLayerDefn.GetFieldDefn(k));
      newLayer.CreateField(fieldDefn);
    }
  }
  else
  {
    // Update mode
    updateMode = true;
    otbAppLogINFO("Update input vector data.");
    // fill temporary buffer for the transfer
    otb::ogr::Layer inputLayer = layer;
    layer                      = buffer->CopyLayer(inputLayer, std::string("Buffer"));
    // close input data source
    source->Clear();
    // Re-open input data source in update mode
    output = otb::ogr::DataSource::New(shapefileName, otb::ogr::DataSource::Modes::Update_LayerUpdate);
  }

  otb::ogr::Layer outLayer = output->GetLayer(0);

  OGRErr errStart = outLayer.ogr().StartTransaction();
  if (errStart != OGRERR_NONE)
  {
    itkExceptionMacro(<< "Unable to start transaction for OGR layer " << outLayer.ogr().GetName() << ".");
  }

  OGRFeatureDefn& layerDefn = layer.GetLayerDefn();

  // Add the field of prediction in the output layer if field not exist

  const OGRFieldType labelType = RegressionMode ? OFTReal : OFTInteger;

  int idx = layerDefn.GetFieldIndex(GetParameterString("cfield").c_str());
  if (idx >= 0)
  {
    if (layerDefn.GetFieldDefn(idx)->GetType() != labelType)
      itkExceptionMacro("Field name " << GetParameterString("cfield") << " already exists with a different type!");
  }
  else
  {
    OGRFieldDefn   predictedField(GetParameterString("cfield").c_str(), labelType);
    ogr::FieldDefn predictedFieldDef(predictedField);
    outLayer.CreateField(predictedFieldDef);
  }

  // Add confidence field in the output layer
  std::string confFieldName("confidence");
  if (computeConfidenceMap)
  {
    idx = layerDefn.GetFieldIndex(confFieldName.c_str());
    if (idx >= 0)
    {
      if (layerDefn.GetFieldDefn(idx)->GetType() != OFTReal)
        itkExceptionMacro("Field name " << confFieldName << " already exists with a different type!");
    }
    else
    {
      OGRFieldDefn confidenceField(confFieldName.c_str(), OFTReal);
      confidenceField.SetWidth(confidenceField.GetWidth());
      confidenceField.SetPrecision(confidenceField.GetPrecision());
      ogr::FieldDefn confFieldDefn(confidenceField);
      outLayer.CreateField(confFieldDefn);
    }
  }

  // Fill output layer
  unsigned int count          = 0;
  std::string  classfieldname = GetParameterString("cfield");
  for (auto const& feature : layer)
  {
    ogr::Feature dstFeature(outLayer.GetLayerDefn());
    dstFeature.SetFrom(feature, TRUE);
    dstFeature.SetFID(feature.GetFID());
    auto field = dstFeature[classfieldname];
    switch (field.GetType())
    {
    case OFTInteger64:
    case OFTInteger:
      field.template SetValue<int>(target->GetMeasurementVector(count)[0]);
      break;
    case OFTReal:
      field.template SetValue<double>(target->GetMeasurementVector(count)[0]);
      break;
    case OFTString:
      field.template SetValue<std::string>(std::to_string(target->GetMeasurementVector(count)[0]));
      break;
    default:
      itkExceptionMacro(<< "incorrect field type: " << field.GetType() << ".");
    }
    if (computeConfidenceMap)
      dstFeature[confFieldName].SetValue<double>(quality->GetMeasurementVector(count)[0]);
    if (updateMode)
    {
      outLayer.SetFeature(dstFeature);
    }
    else
    {
      outLayer.CreateFeature(dstFeature);
    }
  }

  if (outLayer.ogr().TestCapability("Transactions"))
  {
    const OGRErr errCommitX = outLayer.ogr().CommitTransaction();
    if (errCommitX != OGRERR_NONE)
    {
      itkExceptionMacro(<< "Unable to commit transaction for OGR layer " << outLayer.ogr().GetName() << ".");
    }
  }

  output->SyncToDisk();
}

} // end namespace wrapper
} // end namespace otb

#endif
<|endoftext|>


<commit_before>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "config.h"
#include "webkit/extensions/v8/playback_extension.h"

namespace extensions_v8 {

const char* kPlaybackExtensionName = "v8/PlaybackMode";

v8::Extension* PlaybackExtension::Get() {
  v8::Extension* extension = new v8::Extension(
      kPlaybackExtensionName,
      "(function () {"
      "  var orig_date = Date;"
      "  Math.random = function() {"
      "    return 0.5;"
      "  };"
      "  Date.__proto__.now = function() {"
      "    return new orig_date(1204251968254);"
      "  };"
      "  Date = function() {"
      "    return Date.now();"
      "  };"
      "})()");
    return extension;
}

}  // namespace extensions_v8
<commit_msg>Update playback extension so that javascript functions return consistent (but not constant) values in an attempt to preserve the functionality but improve compatibility of the extension.<commit_after>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "config.h"
#include "webkit/extensions/v8/playback_extension.h"

namespace extensions_v8 {

const char* kPlaybackExtensionName = "v8/PlaybackMode";

v8::Extension* PlaybackExtension::Get() {
  v8::Extension* extension = new v8::Extension(
      kPlaybackExtensionName,
      "(function () {"
      "  var orig_date = Date;"
      "  var x = 0;"
      "  var time_seed = 1204251968254;"
      "  Math.random = function() {"
      "    x += .1;"
      "    return (x % 1);"
      "  };"
      "  Date.__proto__.now = function() {"
      "    time_seed += 50;"
      "    return new orig_date(time_seed);"
      "  };"
      "  Date = function() {"
      "    return Date.now();"
      "  };"
      "})()");
    return extension;
}

}  // namespace extensions_v8
<|endoftext|>