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

#define __STDC_LIMIT_MACROS

// C
#include <cassert>
#include <cstdlib>

// POSIX
#include <sys/stat.h>
#include <sys/types.h>

// C++
#include <limits>

// STL
#include <iomanip>
#include <set>
#include <sstream>
#include <tr1/functional>

// Google Log
#include <glog/logging.h>

// po6
#include <po6/pathname.h>

// e
#include <e/timer.h>

// HyperDex
#include <hyperdex/configuration.h>
#include <hyperdex/coordinatorlink.h>

// HyperDaemon
#include "datalayer.h"

using hyperdex::regionid;
using hyperdex::entityid;
using hyperdex::instance;
using hyperdex::configuration;
using hyperdex::coordinatorlink;

typedef e::intrusive_ptr<hyperdisk::disk> disk_ptr;
typedef std::map<hyperdex::regionid, disk_ptr> disk_map_t;

hyperdaemon :: datalayer :: datalayer(coordinatorlink* cl, const po6::pathname& base)
    : m_cl(cl)
    , m_shutdown(false)
    , m_base(base)
    , m_flusher(std::tr1::bind(&datalayer::flush_loop, this))
    , m_lock()
    , m_disks()
{
    m_flusher.start();
}

hyperdaemon :: datalayer :: ~datalayer() throw ()
{
    if (!m_shutdown)
    {
        shutdown();
    }

    m_flusher.join();
}

void
hyperdaemon :: datalayer :: prepare(const configuration& newconfig, const instance& us)
{
    // Create new disks which we do not currently have.
    std::map<regionid, e::intrusive_ptr<hyperdisk::disk> > disks;

    // Grab a copy of all the disks we do have.
    {
        po6::threads::rwlock::rdhold hold(&m_lock);
        disks = m_disks;
    }

    for (std::map<entityid, instance>::const_iterator e = newconfig.entity_mapping().begin();
            e != newconfig.entity_mapping().end(); ++e)
    {
        if (e->first.space != std::numeric_limits<uint32_t>::max() - 1 && e->second == us
            && disks.find(e->first.get_region()) == disks.end())
        {
            std::map<regionid, size_t>::iterator region_size;
            region_size = newconfig.regions().find(e->first.get_region());

            if (region_size != newconfig.regions().end())
            {
                create_disk(e->first.get_region(), region_size->second);
            }
            else
            {
                LOG(ERROR) << "There is a logic error in the configuration object.";
            }
        }
    }

    std::map<uint16_t, regionid> transfers = newconfig.transfers_to(us);

    for (std::map<uint16_t, regionid>::const_iterator t = transfers.begin();
            t != transfers.end(); ++t)
    {
        if (disks.find(t->second) == disks.end())
        {
            std::map<regionid, size_t>::iterator region_size;
            region_size = newconfig.regions().find(t->second);

            if (region_size != newconfig.regions().end())
            {
                create_disk(t->second, region_size->second);
            }
            else
            {
                LOG(ERROR) << "There is a logic error in the configuration object.";
            }
        }
    }
}

void
hyperdaemon :: datalayer :: reconfigure(const configuration&, const instance&)
{
    // Do nothing.
}

void
hyperdaemon :: datalayer :: cleanup(const configuration& newconfig, const instance& us)
{
    // Delete disks which are no longer in the config.
    disk_map_t disks;
    std::map<uint16_t, regionid> transfers = newconfig.transfers_to(us);

    // Grab a copy of all the regions we do have.
    {
        po6::threads::rwlock::rdhold hold(&m_lock);
        disks = m_disks;
    }

    for (disk_map_t::iterator d = disks.begin(); d != disks.end(); ++d)
    {
        bool keep = false;
        std::map<entityid, instance>::const_iterator start;
        std::map<entityid, instance>::const_iterator end;
        start = newconfig.entity_mapping().lower_bound(entityid(d->first, 0));
        end = newconfig.entity_mapping().upper_bound(entityid(d->first, UINT8_MAX));

        for (; start != end; ++start)
        {
            if (start->second == us)
            {
                keep = true;
            }
        }

        for (std::map<uint16_t, regionid>::const_iterator t = transfers.begin();
                t != transfers.end(); ++t)
        {
            if (t->second == d->first)
            {
                keep = true;
            }
        }

        if (!keep)
        {
            drop_disk(d->first);
        }
    }
}

void
hyperdaemon :: datalayer :: shutdown()
{
    m_shutdown = true;
}

e::intrusive_ptr<hyperdisk::snapshot>
hyperdaemon :: datalayer :: make_snapshot(const regionid& ri)
{
    e::intrusive_ptr<hyperdisk::disk> r = get_region(ri);

    if (!r)
    {
        return e::intrusive_ptr<hyperdisk::snapshot>();
    }

    return r->make_snapshot();
}

e::intrusive_ptr<hyperdisk::rolling_snapshot>
hyperdaemon :: datalayer :: make_rolling_snapshot(const regionid& ri)
{
    e::intrusive_ptr<hyperdisk::disk> r = get_region(ri);

    if (!r)
    {
        return e::intrusive_ptr<hyperdisk::rolling_snapshot>();
    }

    return r->make_rolling_snapshot();
}

void
hyperdaemon :: datalayer :: trickle(const regionid& ri)
{
    e::intrusive_ptr<hyperdisk::disk> r = get_region(ri);

    if (r)
    {
        r->flush();
    }
}

hyperdisk::returncode
hyperdaemon :: datalayer :: get(const regionid& ri,
                                const e::buffer& key,
                                std::vector<e::buffer>* value,
                                uint64_t* version)
{
    e::intrusive_ptr<hyperdisk::disk> r = get_region(ri);

    if (!r)
    {
        return hyperdisk::MISSINGDISK;
    }

    return r->get(key, value, version);
}

hyperdisk::returncode
hyperdaemon :: datalayer :: put(const regionid& ri,
                                const e::buffer& key,
                                const std::vector<e::buffer>& value,
                                uint64_t version)
{
    e::intrusive_ptr<hyperdisk::disk> r = get_region(ri);

    if (!r)
    {
        return hyperdisk::MISSINGDISK;
    }

    return r->put(key, value, version);
}

hyperdisk::returncode
hyperdaemon :: datalayer :: del(const regionid& ri,
                                const e::buffer& key)
{
    e::intrusive_ptr<hyperdisk::disk> r = get_region(ri);

    if (!r)
    {
        return hyperdisk::MISSINGDISK;
    }

    return r->del(key);
}

e::intrusive_ptr<hyperdisk::disk>
hyperdaemon :: datalayer :: get_region(const regionid& ri)
{
    po6::threads::rwlock::rdhold hold(&m_lock);
    disk_map_t::iterator i;
    i = m_disks.find(ri);

    if (i == m_disks.end())
    {
        return e::intrusive_ptr<hyperdisk::disk>();
    }
    else
    {
        return i->second;
    }
}

void
hyperdaemon :: datalayer :: flush_loop()
{
    LOG(WARNING) << "Flush thread started.";
    uint64_t count = 0;

    while (!m_shutdown)
    {
        bool sleep = true;
        std::set<e::intrusive_ptr<hyperdisk::disk> > to_flush;

        { // Hold the lock only in this scope.
            po6::threads::rwlock::rdhold hold(&m_lock);

            for (disk_map_t::iterator i = m_disks.begin();
                    i != m_disks.end(); ++i)
            {
                to_flush.insert(i->second);
            }
        }

        for (std::set<e::intrusive_ptr<hyperdisk::disk> >::iterator i = to_flush.begin();
                    i != to_flush.end(); ++i)
        {
            if (count % 10 == 0)
            {
                (*i)->preallocate();
            }

            switch ((*i)->flush())
            {
                case hyperdisk::SUCCESS:
                    sleep = false;
                    break;
                case hyperdisk::FLUSHNONE:
                    break;
                case hyperdisk::DATAFULL:
                    LOG(INFO) << "flush returned DATAFULL";
                    break;
                case hyperdisk::SEARCHFULL:
                    LOG(INFO) << "flush returned SEARCHFULL";
                    break;
                case hyperdisk::MISSINGDISK:
                    LOG(INFO) << "flush returned MISSINGDISK";
                    break;
                case hyperdisk::NOTFOUND:
                    LOG(INFO) << "flush returned NOTFOUND";
                    break;
                case hyperdisk::WRONGARITY:
                    LOG(INFO) << "flush returned WRONGARITY";
                    break;
                case hyperdisk::SYNCFAILED:
                    LOG(INFO) << "flush returned SYNCFAILED";
                    break;
                case hyperdisk::DROPFAILED:
                    LOG(INFO) << "flush returned DROPFAILED";
                    break;
                default:
                    assert(!"Programming error.");
            }
        }

        if (sleep)
        {
            e::sleep_ms(0, 100);
        }

        ++count;
    }
}

void
hyperdaemon :: datalayer :: create_disk(const regionid& ri, uint16_t num_columns)
{
    LOG(INFO) << "Creating " << ri << " with " << num_columns << " columns.";
    std::ostringstream ostr;
    ostr << ri;
    po6::pathname path = po6::join(m_base, po6::pathname(ostr.str()));
    disk_ptr d = new hyperdisk::disk(path, num_columns);
    po6::threads::rwlock::wrhold hold(&m_lock);
    m_disks.insert(std::make_pair(ri, d));
}

void
hyperdaemon :: datalayer :: drop_disk(const regionid& ri)
{
    po6::threads::rwlock::wrhold hold(&m_lock);
    disk_map_t::iterator i;
    i = m_disks.find(ri);

    if (i != m_disks.end())
    {
        LOG(INFO) << "Dropping " << ri << ".";
        i->second->drop();
        m_disks.erase(i);
    }
}
<commit_msg>Output errno info when datalayer ops fail.<commit_after>// Copyright (c) 2011, Cornell University
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//     * Redistributions of source code must retain the above copyright notice,
//       this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//     * Neither the name of HyperDex nor the names of its contributors may be
//       used to endorse or promote products derived from this software without
//       specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.

#define __STDC_LIMIT_MACROS

// C
#include <cassert>
#include <cstdlib>

// POSIX
#include <sys/stat.h>
#include <sys/types.h>

// C++
#include <limits>

// STL
#include <iomanip>
#include <set>
#include <sstream>
#include <tr1/functional>

// Google Log
#include <glog/logging.h>

// po6
#include <po6/pathname.h>

// e
#include <e/timer.h>

// HyperDex
#include <hyperdex/configuration.h>
#include <hyperdex/coordinatorlink.h>

// HyperDaemon
#include "datalayer.h"

using hyperdex::regionid;
using hyperdex::entityid;
using hyperdex::instance;
using hyperdex::configuration;
using hyperdex::coordinatorlink;

typedef e::intrusive_ptr<hyperdisk::disk> disk_ptr;
typedef std::map<hyperdex::regionid, disk_ptr> disk_map_t;

hyperdaemon :: datalayer :: datalayer(coordinatorlink* cl, const po6::pathname& base)
    : m_cl(cl)
    , m_shutdown(false)
    , m_base(base)
    , m_flusher(std::tr1::bind(&datalayer::flush_loop, this))
    , m_lock()
    , m_disks()
{
    m_flusher.start();
}

hyperdaemon :: datalayer :: ~datalayer() throw ()
{
    if (!m_shutdown)
    {
        shutdown();
    }

    m_flusher.join();
}

void
hyperdaemon :: datalayer :: prepare(const configuration& newconfig, const instance& us)
{
    // Create new disks which we do not currently have.
    std::map<regionid, e::intrusive_ptr<hyperdisk::disk> > disks;

    // Grab a copy of all the disks we do have.
    {
        po6::threads::rwlock::rdhold hold(&m_lock);
        disks = m_disks;
    }

    for (std::map<entityid, instance>::const_iterator e = newconfig.entity_mapping().begin();
            e != newconfig.entity_mapping().end(); ++e)
    {
        if (e->first.space != std::numeric_limits<uint32_t>::max() - 1 && e->second == us
            && disks.find(e->first.get_region()) == disks.end())
        {
            std::map<regionid, size_t>::iterator region_size;
            region_size = newconfig.regions().find(e->first.get_region());

            if (region_size != newconfig.regions().end())
            {
                create_disk(e->first.get_region(), region_size->second);
            }
            else
            {
                LOG(ERROR) << "There is a logic error in the configuration object.";
            }
        }
    }

    std::map<uint16_t, regionid> transfers = newconfig.transfers_to(us);

    for (std::map<uint16_t, regionid>::const_iterator t = transfers.begin();
            t != transfers.end(); ++t)
    {
        if (disks.find(t->second) == disks.end())
        {
            std::map<regionid, size_t>::iterator region_size;
            region_size = newconfig.regions().find(t->second);

            if (region_size != newconfig.regions().end())
            {
                create_disk(t->second, region_size->second);
            }
            else
            {
                LOG(ERROR) << "There is a logic error in the configuration object.";
            }
        }
    }
}

void
hyperdaemon :: datalayer :: reconfigure(const configuration&, const instance&)
{
    // Do nothing.
}

void
hyperdaemon :: datalayer :: cleanup(const configuration& newconfig, const instance& us)
{
    // Delete disks which are no longer in the config.
    disk_map_t disks;
    std::map<uint16_t, regionid> transfers = newconfig.transfers_to(us);

    // Grab a copy of all the regions we do have.
    {
        po6::threads::rwlock::rdhold hold(&m_lock);
        disks = m_disks;
    }

    for (disk_map_t::iterator d = disks.begin(); d != disks.end(); ++d)
    {
        bool keep = false;
        std::map<entityid, instance>::const_iterator start;
        std::map<entityid, instance>::const_iterator end;
        start = newconfig.entity_mapping().lower_bound(entityid(d->first, 0));
        end = newconfig.entity_mapping().upper_bound(entityid(d->first, UINT8_MAX));

        for (; start != end; ++start)
        {
            if (start->second == us)
            {
                keep = true;
            }
        }

        for (std::map<uint16_t, regionid>::const_iterator t = transfers.begin();
                t != transfers.end(); ++t)
        {
            if (t->second == d->first)
            {
                keep = true;
            }
        }

        if (!keep)
        {
            drop_disk(d->first);
        }
    }
}

void
hyperdaemon :: datalayer :: shutdown()
{
    m_shutdown = true;
}

e::intrusive_ptr<hyperdisk::snapshot>
hyperdaemon :: datalayer :: make_snapshot(const regionid& ri)
{
    e::intrusive_ptr<hyperdisk::disk> r = get_region(ri);

    if (!r)
    {
        return e::intrusive_ptr<hyperdisk::snapshot>();
    }

    return r->make_snapshot();
}

e::intrusive_ptr<hyperdisk::rolling_snapshot>
hyperdaemon :: datalayer :: make_rolling_snapshot(const regionid& ri)
{
    e::intrusive_ptr<hyperdisk::disk> r = get_region(ri);

    if (!r)
    {
        return e::intrusive_ptr<hyperdisk::rolling_snapshot>();
    }

    return r->make_rolling_snapshot();
}

void
hyperdaemon :: datalayer :: trickle(const regionid& ri)
{
    e::intrusive_ptr<hyperdisk::disk> r = get_region(ri);

    if (r)
    {
        r->flush();
    }
}

hyperdisk::returncode
hyperdaemon :: datalayer :: get(const regionid& ri,
                                const e::buffer& key,
                                std::vector<e::buffer>* value,
                                uint64_t* version)
{
    e::intrusive_ptr<hyperdisk::disk> r = get_region(ri);

    if (!r)
    {
        return hyperdisk::MISSINGDISK;
    }

    return r->get(key, value, version);
}

hyperdisk::returncode
hyperdaemon :: datalayer :: put(const regionid& ri,
                                const e::buffer& key,
                                const std::vector<e::buffer>& value,
                                uint64_t version)
{
    e::intrusive_ptr<hyperdisk::disk> r = get_region(ri);

    if (!r)
    {
        return hyperdisk::MISSINGDISK;
    }

    return r->put(key, value, version);
}

hyperdisk::returncode
hyperdaemon :: datalayer :: del(const regionid& ri,
                                const e::buffer& key)
{
    e::intrusive_ptr<hyperdisk::disk> r = get_region(ri);

    if (!r)
    {
        return hyperdisk::MISSINGDISK;
    }

    return r->del(key);
}

e::intrusive_ptr<hyperdisk::disk>
hyperdaemon :: datalayer :: get_region(const regionid& ri)
{
    po6::threads::rwlock::rdhold hold(&m_lock);
    disk_map_t::iterator i;
    i = m_disks.find(ri);

    if (i == m_disks.end())
    {
        return e::intrusive_ptr<hyperdisk::disk>();
    }
    else
    {
        return i->second;
    }
}

void
hyperdaemon :: datalayer :: flush_loop()
{
    LOG(WARNING) << "Flush thread started.";
    uint64_t count = 0;

    while (!m_shutdown)
    {
        bool sleep = true;
        std::set<e::intrusive_ptr<hyperdisk::disk> > to_flush;

        { // Hold the lock only in this scope.
            po6::threads::rwlock::rdhold hold(&m_lock);

            for (disk_map_t::iterator i = m_disks.begin();
                    i != m_disks.end(); ++i)
            {
                to_flush.insert(i->second);
            }
        }

        for (std::set<e::intrusive_ptr<hyperdisk::disk> >::iterator i = to_flush.begin();
                    i != to_flush.end(); ++i)
        {
            if (count % 10 == 0)
            {
                (*i)->preallocate();
            }

            switch ((*i)->flush())
            {
                case hyperdisk::SUCCESS:
                    sleep = false;
                    break;
                case hyperdisk::FLUSHNONE:
                    break;
                case hyperdisk::DATAFULL:
                    LOG(INFO) << "flush returned DATAFULL";
                    break;
                case hyperdisk::SEARCHFULL:
                    LOG(INFO) << "flush returned SEARCHFULL";
                    break;
                case hyperdisk::MISSINGDISK:
                    LOG(INFO) << "flush returned MISSINGDISK";
                    break;
                case hyperdisk::NOTFOUND:
                    LOG(INFO) << "flush returned NOTFOUND";
                    break;
                case hyperdisk::WRONGARITY:
                    LOG(INFO) << "flush returned WRONGARITY";
                    break;
                case hyperdisk::SYNCFAILED:
                    PLOG(INFO) << "flush returned SYNCFAILED";
                    break;
                case hyperdisk::DROPFAILED:
                    PLOG(INFO) << "flush returned DROPFAILED";
                    break;
                default:
                    assert(!"Programming error.");
            }
        }

        if (sleep)
        {
            e::sleep_ms(0, 100);
        }

        ++count;
    }
}

void
hyperdaemon :: datalayer :: create_disk(const regionid& ri, uint16_t num_columns)
{
    LOG(INFO) << "Creating " << ri << " with " << num_columns << " columns.";
    std::ostringstream ostr;
    ostr << ri;
    po6::pathname path = po6::join(m_base, po6::pathname(ostr.str()));
    disk_ptr d = new hyperdisk::disk(path, num_columns);
    po6::threads::rwlock::wrhold hold(&m_lock);
    m_disks.insert(std::make_pair(ri, d));
}

void
hyperdaemon :: datalayer :: drop_disk(const regionid& ri)
{
    po6::threads::rwlock::wrhold hold(&m_lock);
    disk_map_t::iterator i;
    i = m_disks.find(ri);

    if (i != m_disks.end())
    {
        LOG(INFO) << "Dropping " << ri << ".";
        i->second->drop();
        m_disks.erase(i);
    }
}
<|endoftext|>


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

#define __STDC_LIMIT_MACROS

// C
#include <cassert>
#include <cstdlib>

// POSIX
#include <sys/stat.h>
#include <sys/types.h>

// C++
#include <limits>

// STL
#include <iomanip>
#include <set>
#include <sstream>
#include <tr1/functional>

// Google Log
#include <glog/logging.h>

// po6
#include <po6/pathname.h>

// e
#include <e/timer.h>

// HyperDex
#include "hyperdex/hyperdex/configuration.h"
#include "hyperdex/hyperdex/coordinatorlink.h"

// HyperDaemon
#include "hyperdaemon/datalayer.h"
#include "hyperdaemon/runtimeconfig.h"

using hyperdex::regionid;
using hyperdex::entityid;
using hyperdex::instance;
using hyperdex::configuration;
using hyperdex::coordinatorlink;

typedef e::intrusive_ptr<hyperdisk::disk> disk_ptr;
typedef std::map<hyperdex::regionid, disk_ptr> disk_map_t;

hyperdaemon :: datalayer :: datalayer(coordinatorlink* cl, const po6::pathname& base)
    : m_cl(cl)
    , m_shutdown(false)
    , m_base(base)
    , m_optimistic_io_thread(std::tr1::bind(&datalayer::optimistic_io_thread, this))
    , m_flush_threads()
    , m_disks()
    , m_preallocate_rr()
    , m_last_preallocation(0)
    , m_optimistic_rr()
    , m_last_dose_of_optimism(0)
{
    m_optimistic_io_thread.start();

    for (size_t i = 0; i < FLUSH_THREADS; ++i)
    {
        std::tr1::shared_ptr<po6::threads::thread>
            t(new po6::threads::thread(std::tr1::bind(&datalayer::flush_thread, this)));
        t->start();
        m_flush_threads.push_back(t);
    }
}

hyperdaemon :: datalayer :: ~datalayer() throw ()
{
    if (!m_shutdown)
    {
        shutdown();
    }

    m_optimistic_io_thread.join();

    for (size_t i = 0; i < m_flush_threads.size(); ++i)
    {
        m_flush_threads[i]->join();
    }
}

void
hyperdaemon :: datalayer :: prepare(const configuration& newconfig, const instance& us)
{
    std::set<regionid> regions = newconfig.regions_for(us);

    for (std::set<regionid>::const_iterator r = regions.begin();
            r != regions.end(); ++r)
    {
        if (!m_disks.contains(*r))
        {
            create_disk(*r, newconfig.disk_hasher(r->get_subspace()),
                        newconfig.dimensions(r->get_space()));
        }
    }
}

void
hyperdaemon :: datalayer :: reconfigure(const configuration&, const instance&)
{
    // Do nothing.
}

void
hyperdaemon :: datalayer :: cleanup(const configuration& newconfig, const instance& us)
{
    std::set<regionid> regions = newconfig.regions_for(us);

    for (disk_map_t::iterator d = m_disks.begin(); d != m_disks.end(); d.next())
    {
        if (regions.find(d.key()) == regions.end())
        {
            drop_disk(d.key());
        }
    }
}

void
hyperdaemon :: datalayer :: shutdown()
{
    m_shutdown = true;
}

e::intrusive_ptr<hyperdisk::snapshot>
hyperdaemon :: datalayer :: make_snapshot(const regionid& ri,
                                          const hyperspacehashing::search& terms)
{
    e::intrusive_ptr<hyperdisk::disk> r;

    if (!m_disks.lookup(ri, &r))
    {
        return e::intrusive_ptr<hyperdisk::snapshot>();
    }

    return r->make_snapshot(terms);
}

e::intrusive_ptr<hyperdisk::rolling_snapshot>
hyperdaemon :: datalayer :: make_rolling_snapshot(const regionid& ri)
{
    e::intrusive_ptr<hyperdisk::disk> r;

    if (!m_disks.lookup(ri, &r))
    {
        return e::intrusive_ptr<hyperdisk::rolling_snapshot>();
    }

    return r->make_rolling_snapshot();
}

hyperdisk::returncode
hyperdaemon :: datalayer :: get(const regionid& ri,
                                const e::slice& key,
                                std::vector<e::slice>* value,
                                uint64_t* version,
                                hyperdisk::reference* ref)
{
    e::intrusive_ptr<hyperdisk::disk> r;

    if (!m_disks.lookup(ri, &r))
    {
        return hyperdisk::MISSINGDISK;
    }

    return r->get(key, value, version, ref);
}

hyperdisk::returncode
hyperdaemon :: datalayer :: put(const regionid& ri,
                                std::tr1::shared_ptr<e::buffer> backing,
                                const e::slice& key,
                                const std::vector<e::slice>& value,
                                uint64_t version)
{
    e::intrusive_ptr<hyperdisk::disk> r;

    if (!m_disks.lookup(ri, &r))
    {
        return hyperdisk::MISSINGDISK;
    }

    return r->put(backing, key, value, version);
}

hyperdisk::returncode
hyperdaemon :: datalayer :: del(const regionid& ri,
                                std::tr1::shared_ptr<e::buffer> backing,
                                const e::slice& key)
{
    e::intrusive_ptr<hyperdisk::disk> r;

    if (!m_disks.lookup(ri, &r))
    {
        return hyperdisk::MISSINGDISK;
    }

    return r->del(backing, key);
}

hyperdisk::returncode
hyperdaemon :: datalayer :: flush(const regionid& ri,
                                  size_t n)
{
    e::intrusive_ptr<hyperdisk::disk> r;

    if (!m_disks.lookup(ri, &r))
    {
        return hyperdisk::MISSINGDISK;
    }

    return r->flush(n);
}

typedef std::map<hyperdex::regionid, e::intrusive_ptr<hyperdisk::disk> > disk_map_t;
typedef std::queue<hyperdex::regionid> disk_queue_t;

void
hyperdaemon :: datalayer :: optimistic_io_thread()
{
    LOG(WARNING) << "Started optimistic-I/O thread.";

    while (!m_shutdown)
    {
        // Ensure that all regions are in the preallocation and optimistic-I/O
        // queues.
        for (disk_map_t::iterator d = m_disks.begin(); d != m_disks.end(); d.next())
        {
            if (std::find(m_preallocate_rr.begin(), m_preallocate_rr.end(), d.key())
                    == m_preallocate_rr.end())
            {
                m_preallocate_rr.push_back(d.key());
            }

            if (std::find(m_optimistic_rr.begin(), m_optimistic_rr.end(), d.key())
                    == m_optimistic_rr.end())
            {
                m_optimistic_rr.push_back(d.key());
            }
        }

        // We rate-limit the number of preallocations we do each second.
        uint64_t nanos_since_last_prealloc = e::time() - m_last_preallocation;
        uint64_t preallocation_interval = 1000000000. / PREALLOCATIONS_PER_SECOND;

        if (nanos_since_last_prealloc / preallocation_interval >= 1)
        {
            for (size_t i = 0; i < m_preallocate_rr.size(); ++i)
            {
                e::intrusive_ptr<hyperdisk::disk> d;

                if (m_disks.lookup(m_preallocate_rr.front(), &d))
                {
                    m_preallocate_rr.push_back(m_preallocate_rr.front());
                    hyperdisk::returncode ret = d->preallocate();

                    if (ret == hyperdisk::SUCCESS)
                    {
                        break;
                    }
                    else if (ret == hyperdisk::DIDNOTHING)
                    {
                    }
                    else
                    {
                        PLOG(WARNING) << "Disk preallocation failed";
                    }
                }

                m_preallocate_rr.pop_front();
            }

            m_last_preallocation = e::time();
        }

        // We rate-limit the number of optimistic splits we do each second.
        uint64_t nanos_since_last_optimism = e::time() - m_last_dose_of_optimism;
        uint64_t optimism_interval = 1000000000. / OPTIMISM_BURSTS_PER_SECOND;

        if (nanos_since_last_optimism / optimism_interval >= 1)
        {
            for (size_t i = 0; i < m_optimistic_rr.size(); ++i)
            {
                e::intrusive_ptr<hyperdisk::disk> d;

                if (m_disks.lookup(m_optimistic_rr.front(), &d))
                {
                    m_optimistic_rr.push_back(m_optimistic_rr.front());
                    hyperdisk::returncode ret = d->do_optimistic_io();

                    if (ret == hyperdisk::SUCCESS)
                    {
                        break;
                    }
                    else if (ret == hyperdisk::DIDNOTHING)
                    {
                    }
                    else
                    {
                        PLOG(WARNING) << "Optimistic disk I/O failed";
                    }
                }

                m_optimistic_rr.pop_front();
            }

            m_last_dose_of_optimism = e::time();
        }

        __sync_and_and_fetch(&m_flushed_recently, false);

        do
        {
            e::sleep_ms(0, 10);
        } while (!__sync_and_and_fetch(&m_flushed_recently, true));
    }
}

void
hyperdaemon :: datalayer :: flush_thread()
{
    LOG(WARNING) << "Started data-flush thread.";

    while (!m_shutdown)
    {
        bool sleep = true;

        for (disk_map_t::iterator d = m_disks.begin();
                d != m_disks.end(); d.next())
        {
            hyperdisk::returncode ret = d.value()->flush(10000);

            if (ret == hyperdisk::SUCCESS)
            {
                sleep = false;
            }
            else if (ret == hyperdisk::DIDNOTHING)
            {
            }
            else if (ret == hyperdisk::DATAFULL || ret == hyperdisk::SEARCHFULL)
            {
                hyperdisk::returncode ioret;
                ioret = d.value()->do_mandatory_io();

                if (ioret != hyperdisk::SUCCESS && ioret != hyperdisk::DIDNOTHING)
                {
                    PLOG(ERROR) << "Disk I/O returned " << ioret;
                }
            }
            else
            {
                PLOG(ERROR) << "Disk flush returned " << ret;
            }
        }

        if (sleep)
        {
            e::sleep_ms(0, 10);
        }
        else
        {
            __sync_or_and_fetch(&m_flushed_recently, true);
        }
    }
}

void
hyperdaemon :: datalayer :: create_disk(const regionid& ri,
                                        const hyperspacehashing::mask::hasher& hasher,
                                        uint16_t num_columns)
{
    std::ostringstream ostr;
    ostr << ri;
    po6::pathname path = po6::join(m_base, po6::pathname(ostr.str()));
    disk_ptr d = hyperdisk::disk::create(path, hasher, num_columns);

    if (m_disks.insert(ri, d))
    {
        LOG(INFO) << "Created disk " << ri << " with " << num_columns << " columns";
    }
    else
    {
        LOG(ERROR) << "Could not create disk " << ri << " because it already exists";
    }
}

void
hyperdaemon :: datalayer :: drop_disk(const regionid& ri)
{
    if (m_disks.remove(ri))
    {
        LOG(INFO) << "Dropped disk " << ri;
    }
    else
    {
        LOG(ERROR) << "Could not drop disk " << ri << " because it already exists";
    }
}
<commit_msg>Make the daemon respond to ^C.<commit_after>// Copyright (c) 2011, Cornell University
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//     * Redistributions of source code must retain the above copyright notice,
//       this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//     * Neither the name of HyperDex nor the names of its contributors may be
//       used to endorse or promote products derived from this software without
//       specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.

#define __STDC_LIMIT_MACROS

// C
#include <cassert>
#include <cstdlib>

// POSIX
#include <sys/stat.h>
#include <sys/types.h>

// C++
#include <limits>

// STL
#include <iomanip>
#include <set>
#include <sstream>
#include <tr1/functional>

// Google Log
#include <glog/logging.h>

// po6
#include <po6/pathname.h>

// e
#include <e/timer.h>

// HyperDex
#include "hyperdex/hyperdex/configuration.h"
#include "hyperdex/hyperdex/coordinatorlink.h"

// HyperDaemon
#include "hyperdaemon/datalayer.h"
#include "hyperdaemon/runtimeconfig.h"

using hyperdex::regionid;
using hyperdex::entityid;
using hyperdex::instance;
using hyperdex::configuration;
using hyperdex::coordinatorlink;

typedef e::intrusive_ptr<hyperdisk::disk> disk_ptr;
typedef std::map<hyperdex::regionid, disk_ptr> disk_map_t;

hyperdaemon :: datalayer :: datalayer(coordinatorlink* cl, const po6::pathname& base)
    : m_cl(cl)
    , m_shutdown(false)
    , m_base(base)
    , m_optimistic_io_thread(std::tr1::bind(&datalayer::optimistic_io_thread, this))
    , m_flush_threads()
    , m_disks()
    , m_preallocate_rr()
    , m_last_preallocation(0)
    , m_optimistic_rr()
    , m_last_dose_of_optimism(0)
{
    m_optimistic_io_thread.start();

    for (size_t i = 0; i < FLUSH_THREADS; ++i)
    {
        std::tr1::shared_ptr<po6::threads::thread>
            t(new po6::threads::thread(std::tr1::bind(&datalayer::flush_thread, this)));
        t->start();
        m_flush_threads.push_back(t);
    }
}

hyperdaemon :: datalayer :: ~datalayer() throw ()
{
    if (!m_shutdown)
    {
        shutdown();
    }

    m_optimistic_io_thread.join();

    for (size_t i = 0; i < m_flush_threads.size(); ++i)
    {
        m_flush_threads[i]->join();
    }
}

void
hyperdaemon :: datalayer :: prepare(const configuration& newconfig, const instance& us)
{
    std::set<regionid> regions = newconfig.regions_for(us);

    for (std::set<regionid>::const_iterator r = regions.begin();
            r != regions.end(); ++r)
    {
        if (!m_disks.contains(*r))
        {
            create_disk(*r, newconfig.disk_hasher(r->get_subspace()),
                        newconfig.dimensions(r->get_space()));
        }
    }
}

void
hyperdaemon :: datalayer :: reconfigure(const configuration&, const instance&)
{
    // Do nothing.
}

void
hyperdaemon :: datalayer :: cleanup(const configuration& newconfig, const instance& us)
{
    std::set<regionid> regions = newconfig.regions_for(us);

    for (disk_map_t::iterator d = m_disks.begin(); d != m_disks.end(); d.next())
    {
        if (regions.find(d.key()) == regions.end())
        {
            drop_disk(d.key());
        }
    }
}

void
hyperdaemon :: datalayer :: shutdown()
{
    m_shutdown = true;
}

e::intrusive_ptr<hyperdisk::snapshot>
hyperdaemon :: datalayer :: make_snapshot(const regionid& ri,
                                          const hyperspacehashing::search& terms)
{
    e::intrusive_ptr<hyperdisk::disk> r;

    if (!m_disks.lookup(ri, &r))
    {
        return e::intrusive_ptr<hyperdisk::snapshot>();
    }

    return r->make_snapshot(terms);
}

e::intrusive_ptr<hyperdisk::rolling_snapshot>
hyperdaemon :: datalayer :: make_rolling_snapshot(const regionid& ri)
{
    e::intrusive_ptr<hyperdisk::disk> r;

    if (!m_disks.lookup(ri, &r))
    {
        return e::intrusive_ptr<hyperdisk::rolling_snapshot>();
    }

    return r->make_rolling_snapshot();
}

hyperdisk::returncode
hyperdaemon :: datalayer :: get(const regionid& ri,
                                const e::slice& key,
                                std::vector<e::slice>* value,
                                uint64_t* version,
                                hyperdisk::reference* ref)
{
    e::intrusive_ptr<hyperdisk::disk> r;

    if (!m_disks.lookup(ri, &r))
    {
        return hyperdisk::MISSINGDISK;
    }

    return r->get(key, value, version, ref);
}

hyperdisk::returncode
hyperdaemon :: datalayer :: put(const regionid& ri,
                                std::tr1::shared_ptr<e::buffer> backing,
                                const e::slice& key,
                                const std::vector<e::slice>& value,
                                uint64_t version)
{
    e::intrusive_ptr<hyperdisk::disk> r;

    if (!m_disks.lookup(ri, &r))
    {
        return hyperdisk::MISSINGDISK;
    }

    return r->put(backing, key, value, version);
}

hyperdisk::returncode
hyperdaemon :: datalayer :: del(const regionid& ri,
                                std::tr1::shared_ptr<e::buffer> backing,
                                const e::slice& key)
{
    e::intrusive_ptr<hyperdisk::disk> r;

    if (!m_disks.lookup(ri, &r))
    {
        return hyperdisk::MISSINGDISK;
    }

    return r->del(backing, key);
}

hyperdisk::returncode
hyperdaemon :: datalayer :: flush(const regionid& ri,
                                  size_t n)
{
    e::intrusive_ptr<hyperdisk::disk> r;

    if (!m_disks.lookup(ri, &r))
    {
        return hyperdisk::MISSINGDISK;
    }

    return r->flush(n);
}

typedef std::map<hyperdex::regionid, e::intrusive_ptr<hyperdisk::disk> > disk_map_t;
typedef std::queue<hyperdex::regionid> disk_queue_t;

void
hyperdaemon :: datalayer :: optimistic_io_thread()
{
    LOG(WARNING) << "Started optimistic-I/O thread.";

    while (!m_shutdown)
    {
        // Ensure that all regions are in the preallocation and optimistic-I/O
        // queues.
        for (disk_map_t::iterator d = m_disks.begin(); d != m_disks.end(); d.next())
        {
            if (std::find(m_preallocate_rr.begin(), m_preallocate_rr.end(), d.key())
                    == m_preallocate_rr.end())
            {
                m_preallocate_rr.push_back(d.key());
            }

            if (std::find(m_optimistic_rr.begin(), m_optimistic_rr.end(), d.key())
                    == m_optimistic_rr.end())
            {
                m_optimistic_rr.push_back(d.key());
            }
        }

        // We rate-limit the number of preallocations we do each second.
        uint64_t nanos_since_last_prealloc = e::time() - m_last_preallocation;
        uint64_t preallocation_interval = 1000000000. / PREALLOCATIONS_PER_SECOND;

        if (nanos_since_last_prealloc / preallocation_interval >= 1)
        {
            for (size_t i = 0; i < m_preallocate_rr.size(); ++i)
            {
                e::intrusive_ptr<hyperdisk::disk> d;

                if (m_disks.lookup(m_preallocate_rr.front(), &d))
                {
                    m_preallocate_rr.push_back(m_preallocate_rr.front());
                    hyperdisk::returncode ret = d->preallocate();

                    if (ret == hyperdisk::SUCCESS)
                    {
                        break;
                    }
                    else if (ret == hyperdisk::DIDNOTHING)
                    {
                    }
                    else
                    {
                        PLOG(WARNING) << "Disk preallocation failed";
                    }
                }

                m_preallocate_rr.pop_front();
            }

            m_last_preallocation = e::time();
        }

        // We rate-limit the number of optimistic splits we do each second.
        uint64_t nanos_since_last_optimism = e::time() - m_last_dose_of_optimism;
        uint64_t optimism_interval = 1000000000. / OPTIMISM_BURSTS_PER_SECOND;

        if (nanos_since_last_optimism / optimism_interval >= 1)
        {
            for (size_t i = 0; i < m_optimistic_rr.size(); ++i)
            {
                e::intrusive_ptr<hyperdisk::disk> d;

                if (m_disks.lookup(m_optimistic_rr.front(), &d))
                {
                    m_optimistic_rr.push_back(m_optimistic_rr.front());
                    hyperdisk::returncode ret = d->do_optimistic_io();

                    if (ret == hyperdisk::SUCCESS)
                    {
                        break;
                    }
                    else if (ret == hyperdisk::DIDNOTHING)
                    {
                    }
                    else
                    {
                        PLOG(WARNING) << "Optimistic disk I/O failed";
                    }
                }

                m_optimistic_rr.pop_front();
            }

            m_last_dose_of_optimism = e::time();
        }

        __sync_and_and_fetch(&m_flushed_recently, false);

        do
        {
            e::sleep_ms(0, 10);
        } while (!m_shutdown && !__sync_and_and_fetch(&m_flushed_recently, true));
    }
}

void
hyperdaemon :: datalayer :: flush_thread()
{
    LOG(WARNING) << "Started data-flush thread.";

    while (!m_shutdown)
    {
        bool sleep = true;

        for (disk_map_t::iterator d = m_disks.begin();
                d != m_disks.end(); d.next())
        {
            hyperdisk::returncode ret = d.value()->flush(10000);

            if (ret == hyperdisk::SUCCESS)
            {
                sleep = false;
            }
            else if (ret == hyperdisk::DIDNOTHING)
            {
            }
            else if (ret == hyperdisk::DATAFULL || ret == hyperdisk::SEARCHFULL)
            {
                hyperdisk::returncode ioret;
                ioret = d.value()->do_mandatory_io();

                if (ioret != hyperdisk::SUCCESS && ioret != hyperdisk::DIDNOTHING)
                {
                    PLOG(ERROR) << "Disk I/O returned " << ioret;
                }
            }
            else
            {
                PLOG(ERROR) << "Disk flush returned " << ret;
            }
        }

        if (sleep)
        {
            e::sleep_ms(0, 10);
        }
        else
        {
            __sync_or_and_fetch(&m_flushed_recently, true);
        }
    }
}

void
hyperdaemon :: datalayer :: create_disk(const regionid& ri,
                                        const hyperspacehashing::mask::hasher& hasher,
                                        uint16_t num_columns)
{
    std::ostringstream ostr;
    ostr << ri;
    po6::pathname path = po6::join(m_base, po6::pathname(ostr.str()));
    disk_ptr d = hyperdisk::disk::create(path, hasher, num_columns);

    if (m_disks.insert(ri, d))
    {
        LOG(INFO) << "Created disk " << ri << " with " << num_columns << " columns";
    }
    else
    {
        LOG(ERROR) << "Could not create disk " << ri << " because it already exists";
    }
}

void
hyperdaemon :: datalayer :: drop_disk(const regionid& ri)
{
    if (m_disks.remove(ri))
    {
        LOG(INFO) << "Dropped disk " << ri;
    }
    else
    {
        LOG(ERROR) << "Could not drop disk " << ri << " because it already exists";
    }
}
<|endoftext|>


<commit_before>//============================================================================
// Name        : ComputerVision.cpp
// Author      : Luke Hsiao, Clover Wu
// Version     :
// Copyright   : Copyright 2015 Team Vektor Krum
// Description : Hello World in C++, Ansi-style
//============================================================================

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include <iostream>
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"

using namespace cv;
using namespace std;

 int main( int argc, char** argv )
 {
    VideoCapture cap(0); //capture the video from webcam

    if ( !cap.isOpened() )  // if not success, exit program
    {
         cout << "Cannot open the web cam" << endl;
         return -1;
    }

    namedWindow("Control", CV_WINDOW_AUTOSIZE); //create a window called "Control"

  int iLowH = 170;
  int iHighH = 179;

  int iLowS = 150;
  int iHighS = 255;

  int iLowV = 60;
  int iHighV = 255;

  //Create trackbars in "Control" window
  createTrackbar("LowH", "Control", &iLowH, 179); //Hue (0 - 179)
  createTrackbar("HighH", "Control", &iHighH, 179);

  createTrackbar("LowS", "Control", &iLowS, 255); //Saturation (0 - 255)
  createTrackbar("HighS", "Control", &iHighS, 255);

  createTrackbar("LowV", "Control", &iLowV, 255);//Value (0 - 255)
  createTrackbar("HighV", "Control", &iHighV, 255);

  int iLastX = -1;
  int iLastY = -1;

  //Capture a temporary image from the camera
  Mat imgTmp;
  cap.read(imgTmp);

  //Create a black image with the size as the camera output
  Mat imgLines = Mat::zeros( imgTmp.size(), CV_8UC3 );;

  while (true)
  {
    Mat imgOriginal;

    bool bSuccess = cap.read(imgOriginal); // read a new frame from video

    if (!bSuccess) {//if not success, break loop
      cout << "Cannot read a frame from video stream" << endl;
      break;
    }

    Mat imgHSV;

    cvtColor(imgOriginal, imgHSV, COLOR_BGR2HSV); //Convert the captured frame from BGR to HSV

    Mat imgThresholded;

    inRange(imgHSV, Scalar(iLowH, iLowS, iLowV), Scalar(iHighH, iHighS, iHighV), imgThresholded); //Threshold the image

    //morphological opening (removes small objects from the foreground)
    erode(imgThresholded, imgThresholded, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)) );
    dilate( imgThresholded, imgThresholded, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)) );

    //morphological closing (removes small holes from the foreground)
    dilate( imgThresholded, imgThresholded, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)) );
    erode(imgThresholded, imgThresholded, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)) );

    //Calculate the moments of the thresholded image
    Moments oMoments = moments(imgThresholded);

    double dM01 = oMoments.m01;
    double dM10 = oMoments.m10;
    double dArea = oMoments.m00;

    // if the area <= 10000, I consider that the there are no object in the image and it's because of the noise, the area is not zero
    if (dArea > 10000) {
      //calculate the position of the ball
      int posX = dM10 / dArea;
      int posY = dM01 / dArea;

      if (iLastX >= 0 && iLastY >= 0 && posX >= 0 && posY >= 0) {
        //Draw a red line from the previous point to the current point
        line(imgLines, Point(posX, posY), Point(iLastX, iLastY), Scalar(0,0,255), 2);
      }

      iLastX = posX;
      iLastY = posY;
    }

    imshow("Thresholded Image", imgThresholded); //show the thresholded image

    imgOriginal = imgOriginal + imgLines;
    imshow("Original", imgOriginal); //show the original image

    if (waitKey(30) == 27) { //wait for 'esc' key press for 30ms. If 'esc' key is pressed, break loop
      cout << "esc key is pressed by user" << endl;
      break;
    }
  }
  return 0;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
<commit_msg>Updated header description<commit_after>//============================================================================
// Name        : ComputerVision.cpp
// Author      : Luke Hsiao, Clover Wu
// Version     :
// Copyright   : Copyright 2015 Team Vektor Krum
// Description : This program receives video data from the Soccer Field's
//               overhead camera, processes the images, and outputs
//               the (x,y) positions of all 4 robots, the ball, and all
//               robot's orientations.
//============================================================================

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include <iostream>
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"

using namespace cv;
using namespace std;

 int main( int argc, char** argv )
 {
    VideoCapture cap(0); //capture the video from webcam

    if ( !cap.isOpened() )  // if not success, exit program
    {
         cout << "Cannot open the web cam" << endl;
         return -1;
    }

    namedWindow("Control", CV_WINDOW_AUTOSIZE); //create a window called "Control"

  int iLowH = 170;
  int iHighH = 179;

  int iLowS = 150;
  int iHighS = 255;

  int iLowV = 60;
  int iHighV = 255;

  //Create trackbars in "Control" window
  createTrackbar("LowH", "Control", &iLowH, 179); //Hue (0 - 179)
  createTrackbar("HighH", "Control", &iHighH, 179);

  createTrackbar("LowS", "Control", &iLowS, 255); //Saturation (0 - 255)
  createTrackbar("HighS", "Control", &iHighS, 255);

  createTrackbar("LowV", "Control", &iLowV, 255);//Value (0 - 255)
  createTrackbar("HighV", "Control", &iHighV, 255);

  int iLastX = -1;
  int iLastY = -1;

  //Capture a temporary image from the camera
  Mat imgTmp;
  cap.read(imgTmp);

  //Create a black image with the size as the camera output
  Mat imgLines = Mat::zeros( imgTmp.size(), CV_8UC3 );;

  while (true)
  {
    Mat imgOriginal;

    bool bSuccess = cap.read(imgOriginal); // read a new frame from video

    if (!bSuccess) {//if not success, break loop
      cout << "Cannot read a frame from video stream" << endl;
      break;
    }

    Mat imgHSV;

    cvtColor(imgOriginal, imgHSV, COLOR_BGR2HSV); //Convert the captured frame from BGR to HSV

    Mat imgThresholded;

    inRange(imgHSV, Scalar(iLowH, iLowS, iLowV), Scalar(iHighH, iHighS, iHighV), imgThresholded); //Threshold the image

    //morphological opening (removes small objects from the foreground)
    erode(imgThresholded, imgThresholded, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)) );
    dilate( imgThresholded, imgThresholded, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)) );

    //morphological closing (removes small holes from the foreground)
    dilate( imgThresholded, imgThresholded, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)) );
    erode(imgThresholded, imgThresholded, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)) );

    //Calculate the moments of the thresholded image
    Moments oMoments = moments(imgThresholded);

    double dM01 = oMoments.m01;
    double dM10 = oMoments.m10;
    double dArea = oMoments.m00;

    // if the area <= 10000, I consider that the there are no object in the image and it's because of the noise, the area is not zero
    if (dArea > 10000) {
      //calculate the position of the ball
      int posX = dM10 / dArea;
      int posY = dM01 / dArea;

      if (iLastX >= 0 && iLastY >= 0 && posX >= 0 && posY >= 0) {
        //Draw a red line from the previous point to the current point
        line(imgLines, Point(posX, posY), Point(iLastX, iLastY), Scalar(0,0,255), 2);
      }

      iLastX = posX;
      iLastY = posY;
    }

    imshow("Thresholded Image", imgThresholded); //show the thresholded image

    imgOriginal = imgOriginal + imgLines;
    imshow("Original", imgOriginal); //show the original image

    if (waitKey(30) == 27) { //wait for 'esc' key press for 30ms. If 'esc' key is pressed, break loop
      cout << "esc key is pressed by user" << endl;
      break;
    }
  }
  return 0;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
<|endoftext|>


<commit_before>/*
 Copyright (C) 2011 by Ivan Safrin

 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
 in the Software without restriction, including without limitation the rights
 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 copies of the Software, and to permit persons to whom the Software is
 furnished to do so, subject to the following conditions:

 The above copyright notice and this permission notice shall be included in
 all copies or substantial portions of the Software.

 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 THE SOFTWARE.
*/

#include "PolyMaterial.h"
#include "PolyLogger.h"
#include "PolyShader.h"
#include "PolyRenderer.h"
#include "PolyCoreServices.h"
#include "PolyCore.h"
#include "PolyTexture.h"

using namespace Polycode;

Material::Material(const String& name) : Resource(Resource::RESOURCE_MATERIAL) {
	this->name = name;
	fp16RenderTargets = false;
	shaderModule = NULL;
	blendingMode = Renderer::BLEND_MODE_NORMAL;
	screenMaterial = false;
    wireframe = false;
}

Material::~Material() {

	Logger::log("deleting material (%s)\n", name.c_str());

	clearShaders();
}

void Material::setName(const String &name) {
	this->name = name;
    setResourceName(name);
	dispatchEvent(new Event(), Event::RESOURCE_CHANGE_EVENT);
}

void Material::clearShaders() {
	// do not delete shaders here, they're shared
/*
	for(int i=0; i < materialShaders.size(); i++)	{
		delete materialShaders[i];
	}
	*/

	for(int i=0; i < materialShaders.size(); i++)	{
		materialShaders[i]->removeAllHandlersForListener(this);
	}
	materialShaders.clear();

	for(int i=0; i < shaderBindings.size(); i++)	{
		delete shaderBindings[i];
	}
	shaderBindings.clear();

	for(int i=0; i < renderTargets.size(); i++)	{
		delete renderTargets[i];
	}
	renderTargets.clear();
}

void Material::recreateRenderTargets() {
	for(int i=0; i < renderTargets.size(); i++) {
		recreateRenderTarget(renderTargets[i]);
	}
}

void Material::recreateRenderTarget(ShaderRenderTarget *renderTarget) {
	int textureWidth;
	int textureHeight;
	Texture *newTexture;

	if(renderTarget->sizeMode == ShaderRenderTarget::SIZE_MODE_NORMALIZED) {
		Number safeWidth = renderTarget->width;
		Number safeHeight = renderTarget->height;
		if(safeWidth > 1.0)
			safeWidth = 1.0;
		if(safeHeight > 1.0)
			safeHeight = 1.0;

		if(safeWidth < 0.0)
			safeWidth = 0.0;
		if(safeHeight < 0.0)
			safeHeight = 0.0;

		if(renderTarget->normalizedWidth > 0 && renderTarget->normalizedHeight > 0) {
			textureWidth = (int) (renderTarget->normalizedWidth * safeWidth);
			textureHeight = (int) (renderTarget->normalizedHeight * safeHeight);
		} else {
			textureWidth = (int) (CoreServices::getInstance()->getCore()->getXRes() * safeWidth);
			textureHeight = (int) (CoreServices::getInstance()->getCore()->getYRes() * safeHeight);
		}
	} else {
		textureWidth = (int)renderTarget->width;
		textureHeight = (int)renderTarget->height;
	}

	CoreServices::getInstance()->getRenderer()->createRenderTextures(&newTexture, NULL, textureWidth, textureHeight, fp16RenderTargets);
	newTexture->setResourceName(renderTarget->id);

	Texture *oldTexture = renderTarget->texture;
	renderTarget->texture = newTexture;

	if(oldTexture) {
		for(int i=0; i < shaderBindings.size(); i++) {

			for(int j=0; j < shaderBindings[i]->getNumRenderTargetBindings(); j++) {
				if(shaderBindings[i]->getRenderTargetBinding(j)->texture == oldTexture) {
					shaderBindings[i]->getRenderTargetBinding(j)->texture = newTexture;
					shaderBindings[i]->clearTexture(shaderBindings[i]->getRenderTargetBinding(j)->name);
					shaderBindings[i]->addTexture(shaderBindings[i]->getRenderTargetBinding(j)->name, newTexture);
				}
			}
		}

		CoreServices::getInstance()->getRenderer()->destroyTexture(oldTexture);
	}
}

void Material::handleEvent(Event *event) {
	std::vector<Shader*> _materialShaders = materialShaders;
	clearShaders();
	for(int i=0; i < _materialShaders.size(); i++)	{
		ShaderBinding *newShaderBinding = _materialShaders[i]->createBinding();
		addShader(_materialShaders[i], newShaderBinding);
	}
	dispatchEvent(new Event(), Event::RESOURCE_RELOAD_EVENT);
}

void Material::removeShader(int shaderIndex) {
	if(shaderIndex >= 0 && shaderIndex < materialShaders.size()) {
		materialShaders.erase(materialShaders.begin() + shaderIndex);
		shaderBindings.erase(shaderBindings.begin() + shaderIndex);
	}
}

void Material::addShaderAtIndex(Shader *shader,ShaderBinding *shaderBinding, int shaderIndex) {
	materialShaders.insert(materialShaders.begin()+shaderIndex, shader);
	shaderBindings.insert(shaderBindings.begin()+shaderIndex, shaderBinding);

	shader->addEventListener(this, Event::RESOURCE_RELOAD_EVENT);
	CoreServices::getInstance()->getRenderer()->setRendererShaderParams(shader, shaderBinding);

	for(int i=0; i < shader->expectedParams.size(); i++) {
		if(!shaderBinding->getLocalParamByName(shader->expectedParams[i].name)) {
			shaderBinding->addParam(shader->expectedParams[i].type, shader->expectedParams[i].name);
		}
	}
}

void Material::addShader(Shader *shader,ShaderBinding *shaderBinding) {
	materialShaders.push_back(shader);
	shaderBindings.push_back(shaderBinding);

	shader->addEventListener(this, Event::RESOURCE_RELOAD_EVENT);
	CoreServices::getInstance()->getRenderer()->setRendererShaderParams(shader, shaderBinding);

	for(int i=0; i < shader->expectedParams.size(); i++) {
		if(!shaderBinding->getLocalParamByName(shader->expectedParams[i].name)) {
			shaderBinding->addParam(shader->expectedParams[i].type, shader->expectedParams[i].name);
		}
	}
}

unsigned int Material::getNumShaders() const {
	return materialShaders.size();
}

const String& Material::getName() const {
	return name;
}

Shader *Material::getShader(unsigned int index) const {
	if(index < materialShaders.size()) {
		return materialShaders[index];
	} else {
		return NULL;
	}
}

ShaderBinding *Material::getShaderBinding(unsigned int index) const {
	if(index < shaderBindings.size()) {
		return shaderBindings[index];
	} else {
		return NULL;
	}
}

void Material::loadMaterial(const String& fileName) {

}

void Material::addShaderRenderTarget(ShaderRenderTarget *newTarget) {
	renderTargets.push_back(newTarget);
}

int Material::getNumShaderRenderTargets() {
	return renderTargets.size();
}

ShaderRenderTarget *Material::getShaderRenderTarget(unsigned int index) {
	return renderTargets[index];
}

void Material::removeShaderRenderTarget(int index) {
	if(index >= 0 && index < renderTargets.size()) {
		ShaderRenderTarget *renderTarget = renderTargets[index];
		renderTargets.erase(renderTargets.begin() + index);
		delete renderTarget;
	}
}
<commit_msg>Don't completely destroy shader bindings of textures, etc when reloading shaders. just fix up the parameters. otherwise material texture settings get dropped and not recreated.<commit_after>/*
 Copyright (C) 2011 by Ivan Safrin

 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
 in the Software without restriction, including without limitation the rights
 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 copies of the Software, and to permit persons to whom the Software is
 furnished to do so, subject to the following conditions:

 The above copyright notice and this permission notice shall be included in
 all copies or substantial portions of the Software.

 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 THE SOFTWARE.
*/

#include "PolyMaterial.h"
#include "PolyLogger.h"
#include "PolyShader.h"
#include "PolyRenderer.h"
#include "PolyCoreServices.h"
#include "PolyCore.h"
#include "PolyTexture.h"

using namespace Polycode;

Material::Material(const String& name) : Resource(Resource::RESOURCE_MATERIAL) {
	this->name = name;
	fp16RenderTargets = false;
	shaderModule = NULL;
	blendingMode = Renderer::BLEND_MODE_NORMAL;
	screenMaterial = false;
    wireframe = false;
}

Material::~Material() {

	Logger::log("deleting material (%s)\n", name.c_str());

	clearShaders();
}

void Material::setName(const String &name) {
	this->name = name;
    setResourceName(name);
	dispatchEvent(new Event(), Event::RESOURCE_CHANGE_EVENT);
}

void Material::clearShaders() {
	// do not delete shaders here, they're shared
/*
	for(int i=0; i < materialShaders.size(); i++)	{
		delete materialShaders[i];
	}
	*/

	for(int i=0; i < materialShaders.size(); i++)	{
		materialShaders[i]->removeAllHandlersForListener(this);
	}
	materialShaders.clear();

	for(int i=0; i < shaderBindings.size(); i++)	{
		delete shaderBindings[i];
	}
	shaderBindings.clear();

	for(int i=0; i < renderTargets.size(); i++)	{
		delete renderTargets[i];
	}
	renderTargets.clear();
}

void Material::recreateRenderTargets() {
	for(int i=0; i < renderTargets.size(); i++) {
		recreateRenderTarget(renderTargets[i]);
	}
}

void Material::recreateRenderTarget(ShaderRenderTarget *renderTarget) {
	int textureWidth;
	int textureHeight;
	Texture *newTexture;

	if(renderTarget->sizeMode == ShaderRenderTarget::SIZE_MODE_NORMALIZED) {
		Number safeWidth = renderTarget->width;
		Number safeHeight = renderTarget->height;
		if(safeWidth > 1.0)
			safeWidth = 1.0;
		if(safeHeight > 1.0)
			safeHeight = 1.0;

		if(safeWidth < 0.0)
			safeWidth = 0.0;
		if(safeHeight < 0.0)
			safeHeight = 0.0;

		if(renderTarget->normalizedWidth > 0 && renderTarget->normalizedHeight > 0) {
			textureWidth = (int) (renderTarget->normalizedWidth * safeWidth);
			textureHeight = (int) (renderTarget->normalizedHeight * safeHeight);
		} else {
			textureWidth = (int) (CoreServices::getInstance()->getCore()->getXRes() * safeWidth);
			textureHeight = (int) (CoreServices::getInstance()->getCore()->getYRes() * safeHeight);
		}
	} else {
		textureWidth = (int)renderTarget->width;
		textureHeight = (int)renderTarget->height;
	}

	CoreServices::getInstance()->getRenderer()->createRenderTextures(&newTexture, NULL, textureWidth, textureHeight, fp16RenderTargets);
	newTexture->setResourceName(renderTarget->id);

	Texture *oldTexture = renderTarget->texture;
	renderTarget->texture = newTexture;

	if(oldTexture) {
		for(int i=0; i < shaderBindings.size(); i++) {

			for(int j=0; j < shaderBindings[i]->getNumRenderTargetBindings(); j++) {
				if(shaderBindings[i]->getRenderTargetBinding(j)->texture == oldTexture) {
					shaderBindings[i]->getRenderTargetBinding(j)->texture = newTexture;
					shaderBindings[i]->clearTexture(shaderBindings[i]->getRenderTargetBinding(j)->name);
					shaderBindings[i]->addTexture(shaderBindings[i]->getRenderTargetBinding(j)->name, newTexture);
				}
			}
		}

		CoreServices::getInstance()->getRenderer()->destroyTexture(oldTexture);
	}
}

void Material::handleEvent(Event *event) {
	//Fix the bindings when we detect a reload
	for (int i = 0; i < materialShaders.size(); i++) {
		Shader* shader = materialShaders[i];
		ShaderBinding* shaderBinding = shaderBindings[i];
		CoreServices::getInstance()->getRenderer()->setRendererShaderParams(shader, shaderBinding);

		for(int i=0; i < shader->expectedParams.size(); i++) {
			if(!shaderBinding->getLocalParamByName(shader->expectedParams[i].name)) {
				shaderBinding->addParam(shader->expectedParams[i].type, shader->expectedParams[i].name);
			}
		}
	}
	dispatchEvent(new Event(), Event::RESOURCE_RELOAD_EVENT);
}

void Material::removeShader(int shaderIndex) {
	if(shaderIndex >= 0 && shaderIndex < materialShaders.size()) {
		materialShaders.erase(materialShaders.begin() + shaderIndex);
		shaderBindings.erase(shaderBindings.begin() + shaderIndex);
	}
}

void Material::addShaderAtIndex(Shader *shader,ShaderBinding *shaderBinding, int shaderIndex) {
	materialShaders.insert(materialShaders.begin()+shaderIndex, shader);
	shaderBindings.insert(shaderBindings.begin()+shaderIndex, shaderBinding);

	shader->addEventListener(this, Event::RESOURCE_RELOAD_EVENT);
	CoreServices::getInstance()->getRenderer()->setRendererShaderParams(shader, shaderBinding);

	for(int i=0; i < shader->expectedParams.size(); i++) {
		if(!shaderBinding->getLocalParamByName(shader->expectedParams[i].name)) {
			shaderBinding->addParam(shader->expectedParams[i].type, shader->expectedParams[i].name);
		}
	}
}

void Material::addShader(Shader *shader,ShaderBinding *shaderBinding) {
	materialShaders.push_back(shader);
	shaderBindings.push_back(shaderBinding);

	shader->addEventListener(this, Event::RESOURCE_RELOAD_EVENT);
	CoreServices::getInstance()->getRenderer()->setRendererShaderParams(shader, shaderBinding);

	for(int i=0; i < shader->expectedParams.size(); i++) {
		if(!shaderBinding->getLocalParamByName(shader->expectedParams[i].name)) {
			shaderBinding->addParam(shader->expectedParams[i].type, shader->expectedParams[i].name);
		}
	}
}

unsigned int Material::getNumShaders() const {
	return materialShaders.size();
}

const String& Material::getName() const {
	return name;
}

Shader *Material::getShader(unsigned int index) const {
	if(index < materialShaders.size()) {
		return materialShaders[index];
	} else {
		return NULL;
	}
}

ShaderBinding *Material::getShaderBinding(unsigned int index) const {
	if(index < shaderBindings.size()) {
		return shaderBindings[index];
	} else {
		return NULL;
	}
}

void Material::loadMaterial(const String& fileName) {

}

void Material::addShaderRenderTarget(ShaderRenderTarget *newTarget) {
	renderTargets.push_back(newTarget);
}

int Material::getNumShaderRenderTargets() {
	return renderTargets.size();
}

ShaderRenderTarget *Material::getShaderRenderTarget(unsigned int index) {
	return renderTargets[index];
}

void Material::removeShaderRenderTarget(int index) {
	if(index >= 0 && index < renderTargets.size()) {
		ShaderRenderTarget *renderTarget = renderTargets[index];
		renderTargets.erase(renderTargets.begin() + index);
		delete renderTarget;
	}
}
<|endoftext|>


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

Program:   Medical Imaging & Interaction Toolkit
Language:  C++
Date:      $Date$
Version:   $Revision$

Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.

This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

#include "mitkPixelType.h"
#include <itkVector.h>
#include <itkRGBPixel.h>
#include <itkRGBAPixel.h>
#include <itkCovariantVector.h>
#include "itkDiffusionTensor3D.h"
#include "itkConfidenceDiffusionTensor3D.h"

mitk::PixelType::PixelType() : m_TypeId( NULL ), m_Type( ipPicUnknown ), m_Bpe( 0 ), m_NumberOfComponents( 1 )
{

}

mitk::PixelType::PixelType( const mitk::PixelType& aPixelType )
{
  Initialize( *aPixelType.GetTypeId(), aPixelType.GetNumberOfComponents() );
}

mitk::PixelType::PixelType( const std::type_info& aTypeId, int numberOfComponents, ItkIOPixelType anItkIoPixelType ) : m_TypeId( &aTypeId ), m_NumberOfComponents( numberOfComponents )
{
  Initialize( aTypeId, numberOfComponents, anItkIoPixelType );
}

mitk::PixelType::PixelType( ipPicType_t type, int bpe, int numberOfComponents ) : m_Type( type ), m_Bpe( bpe ), m_NumberOfComponents( numberOfComponents )
{
  Initialize( type, bpe, numberOfComponents );
}

mitk::PixelType::PixelType( const ipPicDescriptor* pic ) : m_NumberOfComponents( 1 )
{
   if ( pic != NULL )
      Initialize( pic->type, pic->bpe );
   else
   {
      m_TypeId = NULL;
      //  itkExceptionMacro("pic.IsNull() has no pixel type.");
   }
}

bool mitk::PixelType::operator==(const mitk::PixelType& rhs) const
{
  std::cout << "operator==" << std::endl;

std::cout << "m_Type = " << m_Type << " " << rhs.m_Type << std::endl;
std::cout << "m_Bpe = " << m_Bpe << " " << rhs.m_Bpe << std::endl;
std::cout << "m_NumberOfComponents = " << m_NumberOfComponents << " " << rhs.m_NumberOfComponents << std::endl;
std::cout << "m_BitsPerComponent = " << m_BitsPerComponent << " " << rhs.m_BitsPerComponent << std::endl;

   return (
     *(this->m_TypeId) == *(rhs.m_TypeId)
    && this->m_Type == rhs.m_Type
    && this->m_Bpe == rhs.m_Bpe
    && this->m_NumberOfComponents == rhs.m_NumberOfComponents
    && this->m_BitsPerComponent == rhs.m_BitsPerComponent
    );
}

bool mitk::PixelType::operator!=(const mitk::PixelType& rhs) const
{
  return !(this->operator==(rhs));
}

bool mitk::PixelType::operator==(const std::type_info& typeId) const
{
  if (GetItkTypeId() == NULL)
    return false;
  return (*GetItkTypeId() == typeId);
}

bool mitk::PixelType::operator!=(const std::type_info& typeId) const
{
  return !(this->operator==(typeId));
}

#define SET_ITK_TYPE_ID(anItkIoPixelType_test, numberOfComponents_test, ITK_TYPE)     \
  if ( (itk::ImageIOBase::anItkIoPixelType_test == anItkIoPixelType ) &&              \
       (numberOfComponents_test == m_NumberOfComponents)                              \
     )                                                                                \
  {                                                                                \
    m_ItkTypeId = &typeid(ITK_TYPE);                                                  \
  }

#define SET_TYPE(TYPE, IPPIC_TYPE)                                                    \
  if ( *m_TypeId == typeid( TYPE ) )                                                  \
  {                                                                                \
    m_Type = IPPIC_TYPE;                                                              \
    m_Bpe = sizeof(TYPE) * 8 * m_NumberOfComponents;                                  \
                                                                                \
    typedef itk::Vector<TYPE, 3> Vector3Type;                                         \
    typedef itk::CovariantVector<TYPE, 3> CovariantVector3Type;                       \
    typedef itk::Point<TYPE, 3> Point3Type;                                           \
    typedef itk::Vector<TYPE, 2> Vector2Type;                                         \
    typedef itk::CovariantVector<TYPE, 2> CovariantVector2Type;                       \
    typedef itk::Point<TYPE, 2> Point2Type;                                           \
                                                                                \
    SET_ITK_TYPE_ID(UNKNOWNPIXELTYPE, 1, TYPE ) else                                  \
    SET_ITK_TYPE_ID(SCALAR, 1, TYPE ) else                                            \
                                                                                \
    SET_ITK_TYPE_ID(RGB, 3, itk::RGBPixel<TYPE> ) else                                \
    SET_ITK_TYPE_ID(DIFFUSIONTENSOR3D, 6, itk::DiffusionTensor3D<TYPE> ) else                                \
    SET_ITK_TYPE_ID(VECTOR, 3, Vector3Type ) else                                     \
    SET_ITK_TYPE_ID(COVARIANTVECTOR, 3, CovariantVector3Type ) else                   \
    SET_ITK_TYPE_ID(POINT, 3, Point3Type ) else                                       \
                                                                                \
    SET_ITK_TYPE_ID(VECTOR, 2, Vector2Type ) else                                     \
    SET_ITK_TYPE_ID(COVARIANTVECTOR, 2, CovariantVector2Type ) else                   \
    SET_ITK_TYPE_ID(POINT, 2, Point2Type ) else                                       \
    {                                                                                \
    }                                                                                \
  }                                                                                \
  else

void mitk::PixelType::Initialize( const std::type_info& aTypeId, int numberOfComponents, ItkIOPixelType anItkIoPixelType )
{
   m_TypeId = &aTypeId;
   m_NumberOfComponents = numberOfComponents;
   if(m_NumberOfComponents == 1)
     m_ItkTypeId = &aTypeId;
   else
     m_ItkTypeId = NULL;
   SET_TYPE(double, ipPicFloat)
   SET_TYPE(float, ipPicFloat)
   SET_TYPE(long, ipPicInt)
   SET_TYPE(unsigned long, ipPicUInt)
   SET_TYPE(int, ipPicInt)
   SET_TYPE(unsigned int, ipPicUInt)
   SET_TYPE(short, ipPicInt)
   SET_TYPE(unsigned short, ipPicUInt)
   SET_TYPE(char, ipPicInt)
   SET_TYPE(unsigned char, ipPicUInt)
   if ( *m_TypeId == typeid( itk::Vector<double,3> ) )
   {
      m_TypeId = & typeid( double );
      m_NumberOfComponents *= 3;
      m_Type = ipPicFloat;
      m_Bpe = sizeof(double) * 8 * m_NumberOfComponents;
      m_ItkTypeId = &typeid( itk::Vector<double,3> );
   }
   else if ( *m_TypeId == typeid( itk::Vector<float,3> ) )
   {
      m_TypeId = & typeid( float );
      m_NumberOfComponents *= 3;
      m_Type = ipPicFloat;
      m_Bpe = sizeof(float) * 8 * m_NumberOfComponents;
      m_ItkTypeId = &typeid( itk::Vector<float,3> );
   }
   else if ( *m_TypeId == typeid( itk::Vector<double,2> ) )
   {
      m_TypeId = & typeid( double );
      m_NumberOfComponents *= 2;
      m_Type = ipPicFloat;
      m_Bpe = sizeof(double) * 8 * m_NumberOfComponents;
      m_ItkTypeId = &typeid( itk::Vector<double,2> );
   }
   else if ( *m_TypeId == typeid( itk::Vector<float,2> ) )
   {
     m_TypeId = & typeid( float );
     m_NumberOfComponents *= 2;
     m_Type = ipPicFloat;
     m_Bpe = sizeof(float) * 8 * m_NumberOfComponents;
     m_ItkTypeId = &typeid( itk::Vector<float,2> );
   }
   else if ( *m_TypeId == typeid( itk::DiffusionTensor3D<float> ) )
   {
     m_TypeId = & typeid( float );
     m_NumberOfComponents *= 6;
     m_Type = ipPicFloat;
     m_Bpe = sizeof(float) * 8 * m_NumberOfComponents;
     m_ItkTypeId = &typeid( itk::DiffusionTensor3D<float> );
   }
   else if ( *m_TypeId == typeid( itk::DiffusionTensor3D<double> ) )
   {
     m_TypeId = & typeid( double );
     m_NumberOfComponents *= 6;
     m_Type = ipPicFloat;
     m_Bpe = sizeof(double) * 8 * m_NumberOfComponents;
     m_ItkTypeId = &typeid( itk::DiffusionTensor3D<double> );
   }
   else if ( *m_TypeId == typeid( itk::ConfidenceDiffusionTensor3D<float> ) )
   {
     m_TypeId = & typeid( float );
     m_NumberOfComponents *= 7;
     m_Type = ipPicFloat;
     m_Bpe = sizeof(float) * 8 * m_NumberOfComponents;
     m_ItkTypeId = &typeid( itk::ConfidenceDiffusionTensor3D<float> );
   }
   else if ( *m_TypeId == typeid( itk::ConfidenceDiffusionTensor3D<double> ) )
   {
     m_TypeId = & typeid( double );
     m_NumberOfComponents *= 7;
     m_Type = ipPicFloat;
     m_Bpe = sizeof(double) * 8 * m_NumberOfComponents;
     m_ItkTypeId = &typeid( itk::ConfidenceDiffusionTensor3D<double> );
   }
   else if ( *m_TypeId == typeid( itk::RGBPixel<unsigned char> ) )
   {
      m_Type = ipPicUInt;
      m_NumberOfComponents = 3;
      m_Bpe = sizeof(unsigned char) * 8 * m_NumberOfComponents;
      m_ItkTypeId = &typeid( itk::RGBPixel<unsigned char> );
   }
   else if ( *m_TypeId == typeid( itk::RGBAPixel<unsigned char> ) )
   {
      itkExceptionMacro( "Pixel type currently not supported." );
   }
   else
   {
      itkExceptionMacro( "Pixel type currently not supported." );
   }
   m_BitsPerComponent = m_Bpe / m_NumberOfComponents;
}

void mitk::PixelType::Initialize( ipPicType_t type, int bpe, int numberOfComponents )
{
   m_Type = type;
   m_Bpe = bpe;
   m_NumberOfComponents = numberOfComponents;
   switch ( type )
   {
   case ipPicUnknown:
      m_TypeId = &typeid( void* );
      break;
   case ipPicBool:
      m_TypeId = &typeid( bool );
      m_Bpe = sizeof(bool) * 8 * numberOfComponents;
      break;
   case ipPicASCII:
      m_TypeId = &typeid( char );
      m_Bpe = sizeof(char) * 8 * numberOfComponents;
      break;
   case ipPicInt:
      switch ( bpe / numberOfComponents )
      {
      case 8:
         m_TypeId = &typeid( char );
         break;
      case 16:
         m_TypeId = &typeid( short );
         break;
      case 32:
         m_TypeId = &typeid( int );
         break;
      case 64:
         m_TypeId = &typeid( long );
         break;
      default:
         m_TypeId = NULL;
         itkExceptionMacro( "Pixel type currently not supported." );
      }
      break;
   case ipPicUInt:
      switch ( bpe / numberOfComponents )
      {
      case 8:
         m_TypeId = &typeid( unsigned char );
         break;
      case 16:
         m_TypeId = &typeid( unsigned short );
         break;
      case 24:
         m_TypeId = &typeid( unsigned char );
         m_NumberOfComponents = numberOfComponents = 3;
         break;
      case 32:
         m_TypeId = &typeid( unsigned int );
         break;
      case 64:
         m_TypeId = &typeid( unsigned long );
         break;
      default:
         m_TypeId = NULL;
         itkExceptionMacro( "Pixel type currently not supported." );
      }
      break;
   case ipPicFloat:
      switch ( bpe / numberOfComponents )
      {
      case 32:
         m_TypeId = &typeid( float );
         break;
      case 64:
         m_TypeId = &typeid( double );
         break;
      default:
         m_TypeId = NULL;
         itkExceptionMacro( "Pixel type currently not supported." );
      }
      break;
   case ipPicNonUniform:
      m_TypeId = &typeid( void* );
      break;
   case ipPicTSV:
      m_TypeId = &typeid( void* );
      break;
   default:
      m_TypeId = NULL;
      itkExceptionMacro( "Pixel type currently not supported." );
      break;
   }
   m_BitsPerComponent = m_Bpe / numberOfComponents;

   if(m_NumberOfComponents == 1)
     m_ItkTypeId = m_TypeId;
   else
     m_ItkTypeId = NULL;
}

std::string mitk::PixelType::GetItkTypeAsString() const
{
  if (GetItkTypeId()==NULL)
  {
    return "unknown";
  }
  else
  {
    return GetItkTypeId()->name();
  }
}
<commit_msg>ENH (#1691): enabling itk::vector as pixel type<commit_after>/*=========================================================================

Program:   Medical Imaging & Interaction Toolkit
Language:  C++
Date:      $Date$
Version:   $Revision$

Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.

This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

#include "mitkPixelType.h"
#include <itkVector.h>
#include <itkRGBPixel.h>
#include <itkRGBAPixel.h>
#include <itkCovariantVector.h>
#include "itkDiffusionTensor3D.h"
#include "itkConfidenceDiffusionTensor3D.h"

#define HUNDRED_VECS(HUN)   \
  TEN_VECS(HUN)                \
  TEN_VECS(HUN+10)             \
  TEN_VECS(HUN+20)             \
  TEN_VECS(HUN+30)             \
  TEN_VECS(HUN+40)             \
  TEN_VECS(HUN+50)             \
  TEN_VECS(HUN+60)             \
  TEN_VECS(HUN+70)             \
  TEN_VECS(HUN+80)             \
  TEN_VECS(HUN+90)             \

#define TEN_VECS(TEN)   \
  if(false){}               \
  N_VEC(TEN+ 1)                \
  N_VEC(TEN+ 2)             \
  N_VEC(TEN+ 3)             \
  N_VEC(TEN+ 4)             \
  N_VEC(TEN+ 5)             \
  N_VEC(TEN+ 6)             \
  N_VEC(TEN+ 7)             \
  N_VEC(TEN+ 8)             \
  N_VEC(TEN+ 9)             \
  N_VEC(TEN+10)             \

#define N_VEC(N_DIRS)       \
  _N_VEC(N_DIRS,double)     \
  _N_VEC(N_DIRS,float)      \

#define _N_VEC(N_DIRS,PIXTYPE)                                                          \
  else if ( *m_TypeId == typeid( itk::Vector<PIXTYPE,N_DIRS> ))  \
  {                                                                                \
  found = true;                                                                      \
  m_TypeId = & typeid( PIXTYPE );                                                    \
  m_NumberOfComponents *= N_DIRS;                                                \
  m_Type = ipPicFloat;                                                               \
  m_Bpe = sizeof(PIXTYPE) * 8 * m_NumberOfComponents;                                \
  m_ItkTypeId = &typeid( itk::Vector<PIXTYPE,N_DIRS> );     \
  }                                                                                \

mitk::PixelType::PixelType() : m_TypeId( NULL ), m_Type( ipPicUnknown ), m_Bpe( 0 ), m_NumberOfComponents( 1 )
{

}

mitk::PixelType::PixelType( const mitk::PixelType& aPixelType )
{
  Initialize( *aPixelType.GetTypeId(), aPixelType.GetNumberOfComponents() );
}

mitk::PixelType::PixelType( const std::type_info& aTypeId, int numberOfComponents, ItkIOPixelType anItkIoPixelType ) : m_TypeId( &aTypeId ), m_NumberOfComponents( numberOfComponents )
{
  Initialize( aTypeId, numberOfComponents, anItkIoPixelType );
}

mitk::PixelType::PixelType( ipPicType_t type, int bpe, int numberOfComponents ) : m_Type( type ), m_Bpe( bpe ), m_NumberOfComponents( numberOfComponents )
{
  Initialize( type, bpe, numberOfComponents );
}

mitk::PixelType::PixelType( const ipPicDescriptor* pic ) : m_NumberOfComponents( 1 )
{
   if ( pic != NULL )
      Initialize( pic->type, pic->bpe );
   else
   {
      m_TypeId = NULL;
      //  itkExceptionMacro("pic.IsNull() has no pixel type.");
   }
}

bool mitk::PixelType::operator==(const mitk::PixelType& rhs) const
{
  std::cout << "operator==" << std::endl;

std::cout << "m_Type = " << m_Type << " " << rhs.m_Type << std::endl;
std::cout << "m_Bpe = " << m_Bpe << " " << rhs.m_Bpe << std::endl;
std::cout << "m_NumberOfComponents = " << m_NumberOfComponents << " " << rhs.m_NumberOfComponents << std::endl;
std::cout << "m_BitsPerComponent = " << m_BitsPerComponent << " " << rhs.m_BitsPerComponent << std::endl;

   return (
     *(this->m_TypeId) == *(rhs.m_TypeId)
    && this->m_Type == rhs.m_Type
    && this->m_Bpe == rhs.m_Bpe
    && this->m_NumberOfComponents == rhs.m_NumberOfComponents
    && this->m_BitsPerComponent == rhs.m_BitsPerComponent
    );
}

bool mitk::PixelType::operator!=(const mitk::PixelType& rhs) const
{
  return !(this->operator==(rhs));
}

bool mitk::PixelType::operator==(const std::type_info& typeId) const
{
  if (GetItkTypeId() == NULL)
    return false;
  return (*GetItkTypeId() == typeId);
}

bool mitk::PixelType::operator!=(const std::type_info& typeId) const
{
  return !(this->operator==(typeId));
}

#define SET_ITK_TYPE_ID(anItkIoPixelType_test, numberOfComponents_test, ITK_TYPE)     \
  if ( (itk::ImageIOBase::anItkIoPixelType_test == anItkIoPixelType ) &&              \
       (numberOfComponents_test == m_NumberOfComponents)                              \
     )                                                                                \
  {                                                                                \
    m_ItkTypeId = &typeid(ITK_TYPE);                                                  \
  }

#define SET_TYPE(TYPE, IPPIC_TYPE)                                                    \
  if ( *m_TypeId == typeid( TYPE ) )                                                  \
  {                                                                                \
    m_Type = IPPIC_TYPE;                                                              \
    m_Bpe = sizeof(TYPE) * 8 * m_NumberOfComponents;                                  \
                                                                                \
    typedef itk::Vector<TYPE, 3> Vector3Type;                                         \
    typedef itk::CovariantVector<TYPE, 3> CovariantVector3Type;                       \
    typedef itk::Point<TYPE, 3> Point3Type;                                           \
    typedef itk::Vector<TYPE, 2> Vector2Type;                                         \
    typedef itk::CovariantVector<TYPE, 2> CovariantVector2Type;                       \
    typedef itk::Point<TYPE, 2> Point2Type;                                           \
                                                                                \
    SET_ITK_TYPE_ID(UNKNOWNPIXELTYPE, 1, TYPE ) else                                  \
    SET_ITK_TYPE_ID(SCALAR, 1, TYPE ) else                                            \
                                                                                \
    SET_ITK_TYPE_ID(RGB, 3, itk::RGBPixel<TYPE> ) else                                \
    SET_ITK_TYPE_ID(DIFFUSIONTENSOR3D, 6, itk::DiffusionTensor3D<TYPE> ) else         \
    SET_ITK_TYPE_ID(VECTOR, 3, Vector3Type ) else                                     \
    SET_ITK_TYPE_ID(COVARIANTVECTOR, 3, CovariantVector3Type ) else                   \
    SET_ITK_TYPE_ID(POINT, 3, Point3Type ) else                                       \
                                                                                \
    SET_ITK_TYPE_ID(VECTOR, 2, Vector2Type ) else                                     \
    SET_ITK_TYPE_ID(COVARIANTVECTOR, 2, CovariantVector2Type ) else                   \
    SET_ITK_TYPE_ID(POINT, 2, Point2Type ) else                                       \
    {                                                                                \
    }                                                                                \
  }                                                                                \
  else

void mitk::PixelType::Initialize( const std::type_info& aTypeId, int numberOfComponents, ItkIOPixelType anItkIoPixelType )
{
   m_TypeId = &aTypeId;
   m_NumberOfComponents = numberOfComponents;
   if(m_NumberOfComponents == 1)
     m_ItkTypeId = &aTypeId;
   else
     m_ItkTypeId = NULL;
   SET_TYPE(double, ipPicFloat)
   SET_TYPE(float, ipPicFloat)
   SET_TYPE(long, ipPicInt)
   SET_TYPE(unsigned long, ipPicUInt)
   SET_TYPE(int, ipPicInt)
   SET_TYPE(unsigned int, ipPicUInt)
   SET_TYPE(short, ipPicInt)
   SET_TYPE(unsigned short, ipPicUInt)
   SET_TYPE(char, ipPicInt)
   SET_TYPE(unsigned char, ipPicUInt)
   if ( *m_TypeId == typeid( itk::DiffusionTensor3D<float> ) )
   {
     m_TypeId = & typeid( float );
     m_NumberOfComponents *= 6;
     m_Type = ipPicFloat;
     m_Bpe = sizeof(float) * 8 * m_NumberOfComponents;
     m_ItkTypeId = &typeid( itk::DiffusionTensor3D<float> );
   }
   else if ( *m_TypeId == typeid( itk::DiffusionTensor3D<double> ) )
   {
     m_TypeId = & typeid( double );
     m_NumberOfComponents *= 6;
     m_Type = ipPicFloat;
     m_Bpe = sizeof(double) * 8 * m_NumberOfComponents;
     m_ItkTypeId = &typeid( itk::DiffusionTensor3D<double> );
   }
   else if ( *m_TypeId == typeid( itk::ConfidenceDiffusionTensor3D<float> ) )
   {
     m_TypeId = & typeid( float );
     m_NumberOfComponents *= 7;
     m_Type = ipPicFloat;
     m_Bpe = sizeof(float) * 8 * m_NumberOfComponents;
     m_ItkTypeId = &typeid( itk::ConfidenceDiffusionTensor3D<float> );
   }
   else if ( *m_TypeId == typeid( itk::ConfidenceDiffusionTensor3D<double> ) )
   {
     m_TypeId = & typeid( double );
     m_NumberOfComponents *= 7;
     m_Type = ipPicFloat;
     m_Bpe = sizeof(double) * 8 * m_NumberOfComponents;
     m_ItkTypeId = &typeid( itk::ConfidenceDiffusionTensor3D<double> );
   }
   else if ( *m_TypeId == typeid( itk::RGBPixel<unsigned char> ) )
   {
     m_Type = ipPicUInt;
     m_NumberOfComponents = 3;
     m_Bpe = sizeof(unsigned char) * 8 * m_NumberOfComponents;
     m_ItkTypeId = &typeid( itk::RGBPixel<unsigned char> );
   }
   else if ( *m_TypeId == typeid( itk::RGBAPixel<unsigned char> ) )
   {
     itkExceptionMacro( "Pixel type currently not supported." );
   }
   else
   {
     bool found = false;

     // the following lines allow for fixed-size vector images up to a certain size limit
     // (commented out for shorter compile times)
     //HUNDRED_VECS(000)
     //HUNDRED_VECS(100)
     //HUNDRED_VECS(200)
     //HUNDRED_VECS(300)
     //HUNDRED_VECS(400)
     //HUNDRED_VECS(500)
     //HUNDRED_VECS(600)
     //HUNDRED_VECS(700)

     // allow for fixed-size vectors of specific length
     // (inspired by itkPointshell.cpp, precompiled q-ball configs)
     TEN_VECS(0)
     N_VEC(11)
     N_VEC(12)
     N_VEC(42)
     N_VEC(92)
     N_VEC(162)
     N_VEC(252)
     N_VEC(362)
     N_VEC(492)
     N_VEC(642)
     N_VEC(812)
     N_VEC(1002)

     if(!found)
       itkExceptionMacro( "Pixel type currently not supported." );
   }
   m_BitsPerComponent = m_Bpe / m_NumberOfComponents;
}

void mitk::PixelType::Initialize( ipPicType_t type, int bpe, int numberOfComponents )
{
   m_Type = type;
   m_Bpe = bpe;
   m_NumberOfComponents = numberOfComponents;
   switch ( type )
   {
   case ipPicUnknown:
      m_TypeId = &typeid( void* );
      break;
   case ipPicBool:
      m_TypeId = &typeid( bool );
      m_Bpe = sizeof(bool) * 8 * numberOfComponents;
      break;
   case ipPicASCII:
      m_TypeId = &typeid( char );
      m_Bpe = sizeof(char) * 8 * numberOfComponents;
      break;
   case ipPicInt:
      switch ( bpe / numberOfComponents )
      {
      case 8:
         m_TypeId = &typeid( char );
         break;
      case 16:
         m_TypeId = &typeid( short );
         break;
      case 32:
         m_TypeId = &typeid( int );
         break;
      case 64:
         m_TypeId = &typeid( long );
         break;
      default:
         m_TypeId = NULL;
         itkExceptionMacro( "Pixel type currently not supported." );
      }
      break;
   case ipPicUInt:
      switch ( bpe / numberOfComponents )
      {
      case 8:
         m_TypeId = &typeid( unsigned char );
         break;
      case 16:
         m_TypeId = &typeid( unsigned short );
         break;
      case 24:
         m_TypeId = &typeid( unsigned char );
         m_NumberOfComponents = numberOfComponents = 3;
         break;
      case 32:
         m_TypeId = &typeid( unsigned int );
         break;
      case 64:
         m_TypeId = &typeid( unsigned long );
         break;
      default:
         m_TypeId = NULL;
         itkExceptionMacro( "Pixel type currently not supported." );
      }
      break;
   case ipPicFloat:
      switch ( bpe / numberOfComponents )
      {
      case 32:
         m_TypeId = &typeid( float );
         break;
      case 64:
         m_TypeId = &typeid( double );
         break;
      default:
         m_TypeId = NULL;
         itkExceptionMacro( "Pixel type currently not supported." );
      }
      break;
   case ipPicNonUniform:
      m_TypeId = &typeid( void* );
      break;
   case ipPicTSV:
      m_TypeId = &typeid( void* );
      break;
   default:
      m_TypeId = NULL;
      itkExceptionMacro( "Pixel type currently not supported." );
      break;
   }
   m_BitsPerComponent = m_Bpe / numberOfComponents;

   if(m_NumberOfComponents == 1)
     m_ItkTypeId = m_TypeId;
   else
     m_ItkTypeId = NULL;
}

std::string mitk::PixelType::GetItkTypeAsString() const
{
  if (GetItkTypeId()==NULL)
  {
    return "unknown";
  }
  else
  {
    return GetItkTypeId()->name();
  }
}
<|endoftext|>


<commit_before>#include <string>
#include "CppUnitTest.h"
#include <Map/Node.h>
#include <Creation/Create.h>

using namespace Microsoft::VisualStudio::CppUnitTestFramework;
using namespace Engine::Maps;
using namespace Engine::Entity;

namespace UnitTests {

TEST_CLASS(NodeTest) {
  TEST_METHOD(testContainsActorWhenNotContained) {
    Node* n = Creation::Create::newNode("TestableNode");
    Actor* a = Creation::Create::newActor("TestableActor");
    Assert::IsTrue(a != nullptr);
    n->addActor(a);

    Assert::IsTrue(n->containsActor(a));
    delete n;
  }

  TEST_METHOD(testContainsActorWhenContained) {
    Node n;
    Actor* a = Creation::Create::newActor("TestableActor");
    Assert::IsFalse(a == nullptr);
    Assert::IsFalse(n.containsActor(a));
    delete a;
  }
};

}<commit_msg>Node not ptr<commit_after>#include <string>
#include "CppUnitTest.h"
#include <Map/Node.h>
#include <Creation/Create.h>

using namespace Microsoft::VisualStudio::CppUnitTestFramework;
using namespace Engine::Maps;
using namespace Engine::Entity;

namespace UnitTests {

TEST_CLASS(NodeTest) {
  TEST_METHOD(testContainsActorWhenNotContained) {
    Node n;
    Actor* a = Creation::Create::newActor("TestableActor");
    Assert::IsTrue(a != nullptr);
    n.addActor(a);

    Assert::IsTrue(n.containsActor(a));
  }

  TEST_METHOD(testContainsActorWhenContained) {
    Node n;
    Actor* a = Creation::Create::newActor("TestableActor");
    Assert::IsFalse(a == nullptr);
    Assert::IsFalse(n.containsActor(a));
    delete a;
  }
};

}<|endoftext|>


<commit_before>#include "MapManager.h"

#include "UnitManager.h"

//#include <algorithm>

BWAPI::TilePosition startPos;

Neolib::MapManager mapManager;

struct sortLocations {
	static bool fromStartPos(const BWEM::Base *lhs, const BWEM::Base *rhs) {
		return rhs->Location().getApproxDistance(startPos) < rhs->Location().getApproxDistance(startPos);
	}
};

namespace Neolib {

	void MapManager::init() {
		BWEM::Map::Instance().Initialize();
		BWEM::Map::Instance().EnableAutomaticPathAnalysis();

		for (auto &a : BWEM::Map::Instance().Areas())
			for (auto &b : a.Bases())
				allBases.push_back(&b);

		for (auto &b : allBases) {
			if (BWAPI::Broodwar->isVisible(b->Location())) {
				startPos = b->Location();
				std::sort(allBases.begin(), allBases.end(), sortLocations::fromStartPos);
			}
		}
	}

	void MapManager::onFrame() {
		for (auto it = unexploredBases.begin(); it != unexploredBases.end(); ++it) {
			if (BWAPI::Broodwar->isVisible((*it)->Location())) {
				unexploredBases.erase(it);
				break;
			}
		}
	}

	const std::vector <const BWEM::Base*> MapManager::getAllBases() const {
		return allBases;
	}
	const std::set    <const BWEM::Base*> MapManager::getUnexploredBases() const {
		return unexploredBases;
	}

	const BWAPI::TilePosition MapManager::getNextBasePosition() const {
		for (auto &b : allBases) {
			if (BWAPI::Broodwar->canBuildHere(b->Location(), BWAPI::UnitTypes::Terran_Command_Center)) {
				for (auto &eu : unitManager.getKnownEnemies())
					if (eu.second.first.getApproxDistance(BWAPI::Position(b->Location())) < 1000)
						goto skiplocation;

				return b->Location();
				skiplocation:;
			}
		}

		return BWAPI::TilePosition(-1, -1);
	}
}
<commit_msg>Here is the expansion issue<commit_after>#include "MapManager.h"

#include "UnitManager.h"

//#include <algorithm>

BWAPI::TilePosition startPos;

Neolib::MapManager mapManager;

struct sortLocations {
	static bool fromStartPos(const BWEM::Base *lhs, const BWEM::Base *rhs) {
		return lhs->Location().getApproxDistance(startPos) < rhs->Location().getApproxDistance(startPos);
	}
};

namespace Neolib {

	void MapManager::init() {
		BWEM::Map::Instance().Initialize();
		BWEM::Map::Instance().EnableAutomaticPathAnalysis();

		for (auto &a : BWEM::Map::Instance().Areas())
			for (auto &b : a.Bases())
				allBases.push_back(&b);

		for (auto &b : allBases) {
			if (BWAPI::Broodwar->isVisible(b->Location())) {
				startPos = b->Location();
				std::sort(allBases.begin(), allBases.end(), sortLocations::fromStartPos);
			}
		}
	}

	void MapManager::onFrame() {
		for (auto it = unexploredBases.begin(); it != unexploredBases.end(); ++it) {
			if (BWAPI::Broodwar->isVisible((*it)->Location())) {
				unexploredBases.erase(it);
				break;
			}
		}
	}

	const std::vector <const BWEM::Base*> MapManager::getAllBases() const {
		return allBases;
	}
	const std::set    <const BWEM::Base*> MapManager::getUnexploredBases() const {
		return unexploredBases;
	}

	const BWAPI::TilePosition MapManager::getNextBasePosition() const {
		for (auto &b : allBases) {
			if (BWAPI::Broodwar->canBuildHere(b->Location(), BWAPI::UnitTypes::Terran_Command_Center)) {
				for (auto &eu : unitManager.getKnownEnemies())
					if (eu.second.first.getApproxDistance(BWAPI::Position(b->Location())) < 1000)
						goto skiplocation;

				return b->Location();
				skiplocation:;
			}
		}

		return BWAPI::TilePosition(-1, -1);
	}
}
<|endoftext|>