<commit_before>#pragma once

#include <vector>
#include <functional>
#include <optional>
#include <sstream>
#include <string>

#include "any.hpp"

namespace apc
{
    namespace parsers
    {
        namespace many_ns
        {
            using namespace res;
            using namespace std;

            enum class ManyErrCause
            {
                ParserFailed,
                ConditionFailed,
            };

            template< typename E >
            struct ManyErr
            {
                optional<E> prev;

                unsigned int expected_at_least;
                unsigned int step;

                ManyErrCause cause;

                size_t inner_offset;

                ManyErr(optional<E> prev, unsigned int al, unsigned int step, ManyErrCause cause, size_t offset)
                    : prev(move(prev))
                    , expected_at_least(al)
                    , step(step)
                    , cause(cause)
                    , inner_offset(offset) {}

                tuple<string, size_t> description()
                {
                    stringstream sstream;
                    sstream << "Many error because ";

                    switch (cause)
                    {
                    case ManyErrCause::ParserFailed:
                        sstream << "parser number " << step+1
                                << " failed. Expected at least " << expected_at_least
                                << ' ' << (expected_at_least == 1 ? "value" : "values");
                        break;

                    case ManyErrCause::ConditionFailed:
                        sstream << "return value of parser number " << step+1
                                << " did not satisfy the condition. Expected at least"
                                << expected_at_least << ' '
                                << (expected_at_least == 1 ? "value" : "values");
                        break;
                    }

                    return { sstream.str(), inner_offset };
                }
            };

            template< typename P, template< typename > class C = vector >
            struct Many
            {
                P parser;

                optional<unsigned int> _at_least;
                optional<unsigned int> _at_most;

                function<bool(typename P::Ok&)> _take_while;

                using Ok = C<typename P::Ok>;
                using Err = ManyErr<typename P::Err>;

                Many(P parser)
                    : parser(move(parser))
                    , _at_least(nullopt)
                    , _at_most(nullopt)
                    , _take_while([](auto& x) { return true; }) {}

                Many<P>& at_least(unsigned int n)
                {
                    _at_least = n;
                    return *this;
                }

                Many<P>& at_most(unsigned int n)
                {
                    _at_most = n;
                    return *this;
                }

                Many<P>& take_while(function<bool(typename P::Ok&)> pred)
                {
                    _take_while = pred;
                    return *this;
                }

                Many<P>& take_until(function<bool(typename P::Ok&)> pred)
                {
                    _take_while = [pred](typename P::Ok& t)
                        {
                            return !pred(t);
                        };

                    return *this;
                }

                template< typename I >
                Result<Ok, Err, I> parse(I b, I e)
                {
                    if (b >= e)
                    {
                        return EOI("Many position 1");
                    }

                    I iter = b;
                    unsigned int taken = 0;
                    C<typename P::Ok> ret;

                    do
                    {
                        auto res = parser.parse(iter, e);

                        if (is_ok(res))
                        {
                            auto res_ok = unwrap_ok(move(res));

                            bool take_while_res = _take_while(res_ok.res);

                            if (take_while_res == false &&
                                _at_least.has_value() &&
                                taken < _at_least)
                            {
                                return err(ManyErr<typename P::Err>(
                                               nullopt,
                                               *_at_least,
                                               taken,
                                               ManyErrCause::ConditionFailed,
                                               distance(b, iter)),
                                           iter
                                    );
                            }

                            if (take_while_res == false)
                            {
                                return ok(move(ret), iter);
                            }

                            iter = res_ok.pos;

                            ret.push_back(move(res_ok.res));
                            taken++;
                        }
                        else if (is_err(res))
                        {
                            auto res_err = unwrap_err(move(res));

                            if (_at_least.has_value() && taken < *_at_least)
                            {
                                return err(ManyErr<typename P::Err>(
                                               move(res_err.err),
                                               *_at_least,
                                               taken,
                                               ManyErrCause::ParserFailed,
                                               distance(b, iter)),
                                           res_err.pos
                                    );
                            }

                            return ok(move(ret), iter);
                        }
                        else
                        {
                            if (_at_least.has_value() && taken < *_at_least)
                            {
                                auto res_eoi = unwrap_eoi(move(res));

                                res_eoi.trace.push_back("Many position "s + to_string(taken+1));

                                return res_eoi;
                            }

                            return ok(move(ret), iter);
                        }
                    } while (!(_at_most.has_value() && taken >= *_at_most));

                    return ok(move(ret), iter);
                }
            };
        }

        template< typename P, template< typename > class C >
        auto many(P parser)
        {
            return many_ns::Many<P, C>(move(parser));
        }

        template< typename T, template< typename > class C >
        auto many()
        {
            return many<any_ns::Any<T>, C>(any<T>());
        }

        template< typename P >
        auto many_str(P parser)
        {
            return many_ns::Many<P, basic_string>(move(parser));
        }

        template< typename T >
        auto many_str()
        {
            return many<any_ns::Any<T>, basic_string>(any<T>());
        }
    }
}
<commit_msg>Change how many modifiers work<commit_after>#pragma once

#include <vector>
#include <functional>
#include <optional>
#include <sstream>
#include <string>

#include "any.hpp"

namespace apc
{
    namespace parsers
    {
        namespace many_ns
        {
            using namespace res;
            using namespace std;

            enum class ManyErrCause
            {
                ParserFailed,
                ConditionFailed,
            };

            template< typename E >
            struct ManyErr
            {
                optional<E> prev;

                unsigned int expected_at_least;
                unsigned int step;

                ManyErrCause cause;

                size_t inner_offset;

                ManyErr(optional<E> prev, unsigned int al, unsigned int step, ManyErrCause cause, size_t offset)
                    : prev(move(prev))
                    , expected_at_least(al)
                    , step(step)
                    , cause(cause)
                    , inner_offset(offset) {}

                tuple<string, size_t> description()
                {
                    stringstream sstream;
                    sstream << "Many error because ";

                    switch (cause)
                    {
                    case ManyErrCause::ParserFailed:
                        sstream << "parser number " << step+1
                                << " failed. Expected at least " << expected_at_least
                                << ' ' << (expected_at_least == 1 ? "value" : "values");
                        break;

                    case ManyErrCause::ConditionFailed:
                        sstream << "return value of parser number " << step+1
                                << " did not satisfy the condition. Expected at least"
                                << expected_at_least << ' '
                                << (expected_at_least == 1 ? "value" : "values");
                        break;
                    }

                    return { sstream.str(), inner_offset };
                }
            };

            template< typename P, template< typename > class C = vector >
            struct Many
            {
                P parser;

            private:

                optional<unsigned int> _at_least;
                optional<unsigned int> _at_most;

                function<bool(typename P::Ok&)> _take_while;

            public:

                using Ok = C<typename P::Ok>;
                using Err = ManyErr<typename P::Err>;

                Many(P parser)
                    : parser(move(parser))
                    , _at_least(nullopt)
                    , _at_most(nullopt)
                    , _take_while([](auto& x) { return true; }) {}

                Many<P, C> at_least(unsigned int n)
                {
                    _at_least = n;
                    return *this;
                }

                Many<P, C> at_most(unsigned int n)
                {
                    _at_most = n;
                    return *this;
                }

                Many<P, C> take_while(function<bool(typename P::Ok&)> pred)
                {
                    _take_while = pred;
                    return *this;
                }

                Many<P, C> take_until(function<bool(typename P::Ok&)> pred)
                {
                    _take_while = [pred](typename P::Ok& t)
                        {
                            return !pred(t);
                        };

                    return *this;
                }

                Many<P, C>&& at_least_mv(unsigned int n)
                {
                    _at_least = n;
                    return move(*this);
                }

                Many<P, C>&& at_most_mv(unsigned int n)
                {
                    _at_most = n;
                    return move(*this);
                }

                Many<P, C>&& take_while_mv(function<bool(typename P::Ok&)> pred)
                {
                    _take_while = pred;
                    return move(*this);
                }

                Many<P, C>&& take_until_mv(function<bool(typename P::Ok&)> pred)
                {
                    _take_while = [pred](typename P::Ok& t)
                        {
                            return !pred(t);
                        };

                    return move(*this);
                }

                template< typename I >
                Result<Ok, Err, I> parse(I b, I e)
                {
                    if (b >= e)
                    {
                        return EOI("Many position 1");
                    }

                    I iter = b;
                    unsigned int taken = 0;
                    C<typename P::Ok> ret;

                    do
                    {
                        auto res = parser.parse(iter, e);

                        if (is_ok(res))
                        {
                            auto res_ok = unwrap_ok(move(res));

                            bool take_while_res = _take_while(res_ok.res);

                            if (take_while_res == false &&
                                _at_least.has_value() &&
                                taken < _at_least)
                            {
                                return err(ManyErr<typename P::Err>(
                                               nullopt,
                                               *_at_least,
                                               taken,
                                               ManyErrCause::ConditionFailed,
                                               distance(b, iter)),
                                           iter
                                    );
                            }

                            if (take_while_res == false)
                            {
                                return ok(move(ret), iter);
                            }

                            iter = res_ok.pos;

                            ret.push_back(move(res_ok.res));
                            taken++;
                        }
                        else if (is_err(res))
                        {
                            auto res_err = unwrap_err(move(res));

                            if (_at_least.has_value() && taken < *_at_least)
                            {
                                return err(ManyErr<typename P::Err>(
                                               move(res_err.err),
                                               *_at_least,
                                               taken,
                                               ManyErrCause::ParserFailed,
                                               distance(b, iter)),
                                           res_err.pos
                                    );
                            }

                            return ok(move(ret), iter);
                        }
                        else
                        {
                            if (_at_least.has_value() && taken < *_at_least)
                            {
                                auto res_eoi = unwrap_eoi(move(res));

                                res_eoi.trace.push_back("Many position "s + to_string(taken+1));

                                return res_eoi;
                            }

                            return ok(move(ret), iter);
                        }
                    } while (!(_at_most.has_value() && taken >= *_at_most));

                    return ok(move(ret), iter);
                }
            };
        }

        template< typename P, template< typename > class C >
        auto many(P parser)
        {
            return many_ns::Many<P, C>(move(parser));
        }

        template< typename T, template< typename > class C >
        auto many()
        {
            return many<any_ns::Any<T>, C>(any<T>());
        }

        template< typename P >
        auto many_str(P parser)
        {
            return many_ns::Many<P, basic_string>(move(parser));
        }

        template< typename T >
        auto many_str()
        {
            return many<any_ns::Any<T>, basic_string>(any<T>());
        }

        auto many_space() {
            auto ret = many_str<char>();
            ret.take_while([](char& c) { return isspace(c); });
            return ret;
        }
    }
}
<|endoftext|>


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

#include "app/resource_bundle.h"

#include <gtk/gtk.h>

#include "app/app_paths.h"
#include "app/gfx/font.h"
#include "app/gfx/gtk_util.h"
#include "app/l10n_util.h"
#include "base/base_paths.h"
#include "base/data_pack.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/logging.h"
#include "base/path_service.h"
#include "base/string_piece.h"
#include "base/string_util.h"
#include "third_party/skia/include/core/SkBitmap.h"

namespace {

// Convert the raw image data into a GdkPixbuf.  The GdkPixbuf that is returned
// has a ref count of 1 so the caller must call g_object_unref to free the
// memory.
GdkPixbuf* LoadPixbuf(RefCountedStaticMemory* data, bool rtl_enabled) {
  ScopedGObject<GdkPixbufLoader>::Type loader(gdk_pixbuf_loader_new());
  bool ok = gdk_pixbuf_loader_write(loader.get(),
      reinterpret_cast<const guint8*>(data->front()), data->size(), NULL);
  if (!ok)
    return NULL;
  // Calling gdk_pixbuf_loader_close forces the data to be parsed by the
  // loader.  We must do this before calling gdk_pixbuf_loader_get_pixbuf.
  ok = gdk_pixbuf_loader_close(loader.get(), NULL);
  if (!ok)
    return NULL;
  GdkPixbuf* pixbuf = gdk_pixbuf_loader_get_pixbuf(loader.get());
  if (!pixbuf)
    return NULL;

  if ((l10n_util::GetTextDirection() == l10n_util::RIGHT_TO_LEFT) &&
      rtl_enabled) {
    // |pixbuf| will get unreffed and destroyed (see below). The returned value
    // has ref count 1.
    return gdk_pixbuf_flip(pixbuf, TRUE);
  } else {
    // The pixbuf is owned by the loader, so add a ref so when we delete the
    // loader (when the ScopedGObject goes out of scope), the pixbuf still
    // exists.
    g_object_ref(pixbuf);
    return pixbuf;
  }
}

}  // namespace

void ResourceBundle::FreeGdkPixBufs() {
  for (GdkPixbufMap::iterator i = gdk_pixbufs_.begin();
       i != gdk_pixbufs_.end(); i++) {
    g_object_unref(i->second);
  }
  gdk_pixbufs_.clear();
}

// static
FilePath ResourceBundle::GetResourcesFilePath() {
  FilePath resources_file_path;
  PathService::Get(base::DIR_EXE, &resources_file_path);
  if (resources_file_path.empty())
    return resources_file_path;
  return resources_file_path.Append(FILE_PATH_LITERAL("chrome.pak"));
}

// static
FilePath ResourceBundle::GetLocaleFilePath(const std::string& app_locale) {
  FilePath locale_file_path;
  PathService::Get(app::DIR_LOCALES, &locale_file_path);
  if (locale_file_path.empty())
    return locale_file_path;
  if (app_locale.empty())
    return FilePath();
  locale_file_path = locale_file_path.AppendASCII(app_locale + ".pak");
  if (!file_util::PathExists(locale_file_path))
    return FilePath();
  return locale_file_path;
}

GdkPixbuf* ResourceBundle::GetPixbufImpl(int resource_id, bool rtl_enabled) {
  // Use the negative |resource_id| for the key for BIDI-aware images.
  int key = rtl_enabled ? -resource_id : resource_id;

  // Check to see if we already have the pixbuf in the cache.
  {
    AutoLock lock_scope(lock_);
    GdkPixbufMap::const_iterator found = gdk_pixbufs_.find(key);
    if (found != gdk_pixbufs_.end())
      return found->second;
  }

  scoped_refptr<RefCountedStaticMemory> data(
      LoadDataResourceBytes(resource_id));
  GdkPixbuf* pixbuf = LoadPixbuf(data.get(), rtl_enabled);

  // We loaded successfully.  Cache the pixbuf.
  if (pixbuf) {
    AutoLock lock_scope(lock_);

    // Another thread raced us, and has already cached the pixbuf.
    if (gdk_pixbufs_.count(key)) {
      g_object_unref(pixbuf);
      return gdk_pixbufs_[key];
    }

    gdk_pixbufs_[key] = pixbuf;
    return pixbuf;
  }

  // We failed to retrieve the bitmap, show a debugging red square.
  {
    LOG(WARNING) << "Unable to load GdkPixbuf with id " << resource_id;
    NOTREACHED();  // Want to assert in debug mode.

    AutoLock lock_scope(lock_);  // Guard empty_bitmap initialization.

    static GdkPixbuf* empty_bitmap = NULL;
    if (!empty_bitmap) {
      // The placeholder bitmap is bright red so people notice the problem.
      // This bitmap will be leaked, but this code should never be hit.
      scoped_ptr<SkBitmap> skia_bitmap(new SkBitmap());
      skia_bitmap->setConfig(SkBitmap::kARGB_8888_Config, 32, 32);
      skia_bitmap->allocPixels();
      skia_bitmap->eraseARGB(255, 255, 0, 0);
      empty_bitmap = gfx::GdkPixbufFromSkBitmap(skia_bitmap.get());
    }
    return empty_bitmap;
  }
}

GdkPixbuf* ResourceBundle::GetPixbufNamed(int resource_id) {
  return GetPixbufImpl(resource_id, false);
}

GdkPixbuf* ResourceBundle::GetRTLEnabledPixbufNamed(int resource_id) {
  return GetPixbufImpl(resource_id, true);
}
<commit_msg>Modify LoadPixbuf() so it returns NULL when the |data| parameter is NULL.<commit_after>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "app/resource_bundle.h"

#include <gtk/gtk.h>

#include "app/app_paths.h"
#include "app/gfx/font.h"
#include "app/gfx/gtk_util.h"
#include "app/l10n_util.h"
#include "base/base_paths.h"
#include "base/data_pack.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/logging.h"
#include "base/path_service.h"
#include "base/string_piece.h"
#include "base/string_util.h"
#include "third_party/skia/include/core/SkBitmap.h"

namespace {

// Convert the raw image data into a GdkPixbuf.  The GdkPixbuf that is returned
// has a ref count of 1 so the caller must call g_object_unref to free the
// memory.
GdkPixbuf* LoadPixbuf(RefCountedStaticMemory* data, bool rtl_enabled) {
  ScopedGObject<GdkPixbufLoader>::Type loader(gdk_pixbuf_loader_new());
  bool ok = data && gdk_pixbuf_loader_write(loader.get(),
      reinterpret_cast<const guint8*>(data->front()), data->size(), NULL);
  if (!ok)
    return NULL;
  // Calling gdk_pixbuf_loader_close forces the data to be parsed by the
  // loader.  We must do this before calling gdk_pixbuf_loader_get_pixbuf.
  ok = gdk_pixbuf_loader_close(loader.get(), NULL);
  if (!ok)
    return NULL;
  GdkPixbuf* pixbuf = gdk_pixbuf_loader_get_pixbuf(loader.get());
  if (!pixbuf)
    return NULL;

  if ((l10n_util::GetTextDirection() == l10n_util::RIGHT_TO_LEFT) &&
      rtl_enabled) {
    // |pixbuf| will get unreffed and destroyed (see below). The returned value
    // has ref count 1.
    return gdk_pixbuf_flip(pixbuf, TRUE);
  } else {
    // The pixbuf is owned by the loader, so add a ref so when we delete the
    // loader (when the ScopedGObject goes out of scope), the pixbuf still
    // exists.
    g_object_ref(pixbuf);
    return pixbuf;
  }
}

}  // namespace

void ResourceBundle::FreeGdkPixBufs() {
  for (GdkPixbufMap::iterator i = gdk_pixbufs_.begin();
       i != gdk_pixbufs_.end(); i++) {
    g_object_unref(i->second);
  }
  gdk_pixbufs_.clear();
}

// static
FilePath ResourceBundle::GetResourcesFilePath() {
  FilePath resources_file_path;
  PathService::Get(base::DIR_EXE, &resources_file_path);
  if (resources_file_path.empty())
    return resources_file_path;
  return resources_file_path.Append(FILE_PATH_LITERAL("chrome.pak"));
}

// static
FilePath ResourceBundle::GetLocaleFilePath(const std::string& app_locale) {
  FilePath locale_file_path;
  PathService::Get(app::DIR_LOCALES, &locale_file_path);
  if (locale_file_path.empty())
    return locale_file_path;
  if (app_locale.empty())
    return FilePath();
  locale_file_path = locale_file_path.AppendASCII(app_locale + ".pak");
  if (!file_util::PathExists(locale_file_path))
    return FilePath();
  return locale_file_path;
}

GdkPixbuf* ResourceBundle::GetPixbufImpl(int resource_id, bool rtl_enabled) {
  // Use the negative |resource_id| for the key for BIDI-aware images.
  int key = rtl_enabled ? -resource_id : resource_id;

  // Check to see if we already have the pixbuf in the cache.
  {
    AutoLock lock_scope(lock_);
    GdkPixbufMap::const_iterator found = gdk_pixbufs_.find(key);
    if (found != gdk_pixbufs_.end())
      return found->second;
  }

  scoped_refptr<RefCountedStaticMemory> data(
      LoadDataResourceBytes(resource_id));
  GdkPixbuf* pixbuf = LoadPixbuf(data.get(), rtl_enabled);

  // We loaded successfully.  Cache the pixbuf.
  if (pixbuf) {
    AutoLock lock_scope(lock_);

    // Another thread raced us, and has already cached the pixbuf.
    if (gdk_pixbufs_.count(key)) {
      g_object_unref(pixbuf);
      return gdk_pixbufs_[key];
    }

    gdk_pixbufs_[key] = pixbuf;
    return pixbuf;
  }

  // We failed to retrieve the bitmap, show a debugging red square.
  {
    LOG(WARNING) << "Unable to load GdkPixbuf with id " << resource_id;
    NOTREACHED();  // Want to assert in debug mode.

    AutoLock lock_scope(lock_);  // Guard empty_bitmap initialization.

    static GdkPixbuf* empty_bitmap = NULL;
    if (!empty_bitmap) {
      // The placeholder bitmap is bright red so people notice the problem.
      // This bitmap will be leaked, but this code should never be hit.
      scoped_ptr<SkBitmap> skia_bitmap(new SkBitmap());
      skia_bitmap->setConfig(SkBitmap::kARGB_8888_Config, 32, 32);
      skia_bitmap->allocPixels();
      skia_bitmap->eraseARGB(255, 255, 0, 0);
      empty_bitmap = gfx::GdkPixbufFromSkBitmap(skia_bitmap.get());
    }
    return empty_bitmap;
  }
}

GdkPixbuf* ResourceBundle::GetPixbufNamed(int resource_id) {
  return GetPixbufImpl(resource_id, false);
}

GdkPixbuf* ResourceBundle::GetRTLEnabledPixbufNamed(int resource_id) {
  return GetPixbufImpl(resource_id, true);
}
<|endoftext|>


<commit_before>#include <stdexcept>
#include <assert.h>
#include <boost/filesystem/path.hpp>
#include <boost/filesystem/operations.hpp>
#include "PsfVm.h"
#include "Log.h"
#include "MA_MIPSIV.h"
#include "xml/Writer.h"
#include "xml/Parser.h"

#define LOG_NAME ("psfvm")

using namespace Iop;
namespace filesystem = boost::filesystem;

CPsfVm::CPsfVm() :
m_status(PAUSED),
m_singleStep(false),
m_soundHandler(NULL)
{
	m_isThreadOver = false;
	m_thread = new boost::thread(boost::bind(&CPsfVm::ThreadProc, this));
}

CPsfVm::~CPsfVm()
{
	if(m_thread)
	{
		Pause();
		m_isThreadOver = true;
		m_thread->join();

		delete m_thread;
		m_thread = NULL;

		assert(m_soundHandler == NULL);
	}
}

void CPsfVm::Reset()
{
	m_subSystem.reset();
	if(m_soundHandler)
	{
		m_soundHandler->Reset();
	}
}

void CPsfVm::SetSubSystem(const PsfVmSubSystemPtr& subSystem)
{
	m_subSystem = subSystem;
	m_subSystem->OnNewFrame.connect(std::tr1::cref(OnNewFrame));
}

#ifdef DEBUGGER_INCLUDED

#define TAGS_PATH				("./tags/")
#define TAGS_SECTION_TAGS		("tags")
#define TAGS_SECTION_FUNCTIONS	("functions")
#define TAGS_SECTION_COMMENTS	("comments")

std::string CPsfVm::MakeTagPackagePath(const char* packageName)
{
	filesystem::path tagsPath(TAGS_PATH);
	if(!filesystem::exists(tagsPath))
	{
		filesystem::create_directory(tagsPath);
	}
	return std::string(TAGS_PATH) + std::string(packageName) + ".tags.xml";
}

void CPsfVm::LoadDebugTags(const char* packageName)
{
	try
	{
		std::string packagePath = MakeTagPackagePath(packageName);
		boost::scoped_ptr<Framework::Xml::CNode> document(Framework::Xml::CParser::ParseDocument(Framework::CStdStream(packagePath.c_str(), "rb")));
		Framework::Xml::CNode* tagsSection = document->Select(TAGS_SECTION_TAGS);
		if(tagsSection == NULL) return;
		m_subSystem->GetCpu().m_Functions.Unserialize(tagsSection, TAGS_SECTION_FUNCTIONS);
		m_subSystem->GetCpu().m_Comments.Unserialize(tagsSection, TAGS_SECTION_COMMENTS);
		m_subSystem->LoadDebugTags(tagsSection);
	}
	catch(...)
	{

	}
}

void CPsfVm::SaveDebugTags(const char* packageName)
{
	std::string packagePath = MakeTagPackagePath(packageName);
	boost::scoped_ptr<Framework::Xml::CNode> document(new Framework::Xml::CNode(TAGS_SECTION_TAGS, true));
	m_subSystem->GetCpu().m_Functions.Serialize(document.get(), TAGS_SECTION_FUNCTIONS);
	m_subSystem->GetCpu().m_Comments.Serialize(document.get(), TAGS_SECTION_COMMENTS);
	m_subSystem->SaveDebugTags(document.get());
	Framework::Xml::CWriter::WriteDocument(&Framework::CStdStream(packagePath.c_str(), "wb"), document.get());
}

#endif

CVirtualMachine::STATUS CPsfVm::GetStatus() const
{
	return m_status;
}

void CPsfVm::Pause()
{
	if(m_status == PAUSED) return;
	m_mailBox.SendCall(std::bind(&CPsfVm::PauseImpl, this), true);
}

void CPsfVm::PauseImpl()
{
	m_status = PAUSED;
	OnRunningStateChange();
	OnMachineStateChange();
}

void CPsfVm::Resume()
{
	m_status = RUNNING;
	if(!OnRunningStateChange.empty())
	{
		OnRunningStateChange();
	}
}

CDebuggable CPsfVm::GetDebugInfo()
{
	CDebuggable debug;
	debug.Step = std::bind(&CPsfVm::Step, this);
	debug.GetCpu = std::bind(&CPsfVm::GetCpu, this);
#ifdef DEBUGGER_INCLUDED
	debug.biosDebugInfoProvider = m_subSystem->GetBiosDebugInfoProvider();
#endif
	return debug;
}

CMIPS& CPsfVm::GetCpu()
{
	return m_subSystem->GetCpu();
}

CSpuBase& CPsfVm::GetSpuCore(unsigned int coreId)
{
	return m_subSystem->GetSpuCore(coreId);
}

uint8* CPsfVm::GetRam()
{
	return m_subSystem->GetRam();
}

void CPsfVm::Step()
{
#ifdef DEBUGGER_INCLUDED
	m_subSystem->DisableBreakpointsOnce();
#endif
	m_singleStep = true;
	m_status = RUNNING;
	OnRunningStateChange();
}

void CPsfVm::SetSpuHandler(const SpuHandlerFactory& factory)
{
	m_mailBox.SendCall(bind(&CPsfVm::SetSpuHandlerImpl, this, factory));
}

void CPsfVm::SetSpuHandlerImpl(const SpuHandlerFactory& factory)
{
	if(m_soundHandler)
	{
		delete m_soundHandler;
		m_soundHandler = NULL;
	}
	m_soundHandler = factory();
}

void CPsfVm::SetReverbEnabled(bool enabled)
{
	m_mailBox.SendCall(std::bind(&CPsfVm::SetReverbEnabledImpl, this, enabled));
}

void CPsfVm::SetReverbEnabledImpl(bool enabled)
{
	assert(m_subSystem != NULL);
	if(m_subSystem == NULL) return;
	m_subSystem->GetSpuCore(0).SetReverbEnabled(enabled);
	m_subSystem->GetSpuCore(1).SetReverbEnabled(enabled);
}

void CPsfVm::SetVolumeAdjust(float volumeAdjust)
{
	m_mailBox.SendCall(std::bind(&CPsfVm::SetVolumeAdjustImpl, this, volumeAdjust));
}

void CPsfVm::SetVolumeAdjustImpl(float volumeAdjust)
{
	assert(m_subSystem != NULL);
	if(m_subSystem == NULL) return;
	m_subSystem->GetSpuCore(0).SetVolumeAdjust(volumeAdjust);
	m_subSystem->GetSpuCore(1).SetVolumeAdjust(volumeAdjust);
}

void CPsfVm::ThreadProc()
{
	while(!m_isThreadOver)
	{
		while(m_mailBox.IsPending())
		{
			m_mailBox.ReceiveCall();
		}
		if(m_status == PAUSED)
		{
			 //Sleep during 100ms
			boost::this_thread::sleep(boost::posix_time::milliseconds(16));
		}
		else
		{
			m_subSystem->Update(m_singleStep, m_soundHandler);
#ifdef DEBUGGER_INCLUDED
			if(m_subSystem->MustBreak() || m_singleStep)
			{
				m_status = PAUSED;
				m_singleStep = false;
				OnMachineStateChange();
				OnRunningStateChange();
			}
#endif
		}
	}

	if(m_soundHandler != NULL)
	{
		delete m_soundHandler;
		m_soundHandler = NULL;
	}
}
<commit_msg>PsfPlayer: We should also disable breakpoints once when resuming the VM.<commit_after>#include <stdexcept>
#include <assert.h>
#include <boost/filesystem/path.hpp>
#include <boost/filesystem/operations.hpp>
#include "PsfVm.h"
#include "Log.h"
#include "MA_MIPSIV.h"
#include "xml/Writer.h"
#include "xml/Parser.h"

#define LOG_NAME ("psfvm")

using namespace Iop;
namespace filesystem = boost::filesystem;

CPsfVm::CPsfVm() :
m_status(PAUSED),
m_singleStep(false),
m_soundHandler(NULL)
{
	m_isThreadOver = false;
	m_thread = new boost::thread(boost::bind(&CPsfVm::ThreadProc, this));
}

CPsfVm::~CPsfVm()
{
	if(m_thread)
	{
		Pause();
		m_isThreadOver = true;
		m_thread->join();

		delete m_thread;
		m_thread = NULL;

		assert(m_soundHandler == NULL);
	}
}

void CPsfVm::Reset()
{
	m_subSystem.reset();
	if(m_soundHandler)
	{
		m_soundHandler->Reset();
	}
}

void CPsfVm::SetSubSystem(const PsfVmSubSystemPtr& subSystem)
{
	m_subSystem = subSystem;
	m_subSystem->OnNewFrame.connect(std::tr1::cref(OnNewFrame));
}

#ifdef DEBUGGER_INCLUDED

#define TAGS_PATH				("./tags/")
#define TAGS_SECTION_TAGS		("tags")
#define TAGS_SECTION_FUNCTIONS	("functions")
#define TAGS_SECTION_COMMENTS	("comments")

std::string CPsfVm::MakeTagPackagePath(const char* packageName)
{
	filesystem::path tagsPath(TAGS_PATH);
	if(!filesystem::exists(tagsPath))
	{
		filesystem::create_directory(tagsPath);
	}
	return std::string(TAGS_PATH) + std::string(packageName) + ".tags.xml";
}

void CPsfVm::LoadDebugTags(const char* packageName)
{
	try
	{
		std::string packagePath = MakeTagPackagePath(packageName);
		boost::scoped_ptr<Framework::Xml::CNode> document(Framework::Xml::CParser::ParseDocument(Framework::CStdStream(packagePath.c_str(), "rb")));
		Framework::Xml::CNode* tagsSection = document->Select(TAGS_SECTION_TAGS);
		if(tagsSection == NULL) return;
		m_subSystem->GetCpu().m_Functions.Unserialize(tagsSection, TAGS_SECTION_FUNCTIONS);
		m_subSystem->GetCpu().m_Comments.Unserialize(tagsSection, TAGS_SECTION_COMMENTS);
		m_subSystem->LoadDebugTags(tagsSection);
	}
	catch(...)
	{

	}
}

void CPsfVm::SaveDebugTags(const char* packageName)
{
	std::string packagePath = MakeTagPackagePath(packageName);
	boost::scoped_ptr<Framework::Xml::CNode> document(new Framework::Xml::CNode(TAGS_SECTION_TAGS, true));
	m_subSystem->GetCpu().m_Functions.Serialize(document.get(), TAGS_SECTION_FUNCTIONS);
	m_subSystem->GetCpu().m_Comments.Serialize(document.get(), TAGS_SECTION_COMMENTS);
	m_subSystem->SaveDebugTags(document.get());
	Framework::Xml::CWriter::WriteDocument(&Framework::CStdStream(packagePath.c_str(), "wb"), document.get());
}

#endif

CVirtualMachine::STATUS CPsfVm::GetStatus() const
{
	return m_status;
}

void CPsfVm::Pause()
{
	if(m_status == PAUSED) return;
	m_mailBox.SendCall(std::bind(&CPsfVm::PauseImpl, this), true);
}

void CPsfVm::PauseImpl()
{
	m_status = PAUSED;
	OnRunningStateChange();
	OnMachineStateChange();
}

void CPsfVm::Resume()
{
#ifdef DEBUGGER_INCLUDED
	m_subSystem->DisableBreakpointsOnce();
#endif
	m_status = RUNNING;
	if(!OnRunningStateChange.empty())
	{
		OnRunningStateChange();
	}
}

CDebuggable CPsfVm::GetDebugInfo()
{
	CDebuggable debug;
	debug.Step = std::bind(&CPsfVm::Step, this);
	debug.GetCpu = std::bind(&CPsfVm::GetCpu, this);
#ifdef DEBUGGER_INCLUDED
	debug.biosDebugInfoProvider = m_subSystem->GetBiosDebugInfoProvider();
#endif
	return debug;
}

CMIPS& CPsfVm::GetCpu()
{
	return m_subSystem->GetCpu();
}

CSpuBase& CPsfVm::GetSpuCore(unsigned int coreId)
{
	return m_subSystem->GetSpuCore(coreId);
}

uint8* CPsfVm::GetRam()
{
	return m_subSystem->GetRam();
}

void CPsfVm::Step()
{
#ifdef DEBUGGER_INCLUDED
	m_subSystem->DisableBreakpointsOnce();
#endif
	m_singleStep = true;
	m_status = RUNNING;
	OnRunningStateChange();
}

void CPsfVm::SetSpuHandler(const SpuHandlerFactory& factory)
{
	m_mailBox.SendCall(bind(&CPsfVm::SetSpuHandlerImpl, this, factory));
}

void CPsfVm::SetSpuHandlerImpl(const SpuHandlerFactory& factory)
{
	if(m_soundHandler)
	{
		delete m_soundHandler;
		m_soundHandler = NULL;
	}
	m_soundHandler = factory();
}

void CPsfVm::SetReverbEnabled(bool enabled)
{
	m_mailBox.SendCall(std::bind(&CPsfVm::SetReverbEnabledImpl, this, enabled));
}

void CPsfVm::SetReverbEnabledImpl(bool enabled)
{
	assert(m_subSystem != NULL);
	if(m_subSystem == NULL) return;
	m_subSystem->GetSpuCore(0).SetReverbEnabled(enabled);
	m_subSystem->GetSpuCore(1).SetReverbEnabled(enabled);
}

void CPsfVm::SetVolumeAdjust(float volumeAdjust)
{
	m_mailBox.SendCall(std::bind(&CPsfVm::SetVolumeAdjustImpl, this, volumeAdjust));
}

void CPsfVm::SetVolumeAdjustImpl(float volumeAdjust)
{
	assert(m_subSystem != NULL);
	if(m_subSystem == NULL) return;
	m_subSystem->GetSpuCore(0).SetVolumeAdjust(volumeAdjust);
	m_subSystem->GetSpuCore(1).SetVolumeAdjust(volumeAdjust);
}

void CPsfVm::ThreadProc()
{
	while(!m_isThreadOver)
	{
		while(m_mailBox.IsPending())
		{
			m_mailBox.ReceiveCall();
		}
		if(m_status == PAUSED)
		{
			 //Sleep during 100ms
			boost::this_thread::sleep(boost::posix_time::milliseconds(16));
		}
		else
		{
			m_subSystem->Update(m_singleStep, m_soundHandler);
#ifdef DEBUGGER_INCLUDED
			if(m_subSystem->MustBreak() || m_singleStep)
			{
				m_status = PAUSED;
				m_singleStep = false;
				OnMachineStateChange();
				OnRunningStateChange();
			}
#endif
		}
	}

	if(m_soundHandler != NULL)
	{
		delete m_soundHandler;
		m_soundHandler = NULL;
	}
}
<|endoftext|>


<commit_before>#include "base64.h"

#include <cstdint>
#include <iostream>

#include "../leanify.h"

int Base64Decode(const char *in, size_t in_len, uint8_t *out, size_t *out_len)
{
    static const uint8_t d[] =
    {
        66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 64, 66, 66, 64, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
        66, 66, 66, 66, 66, 66, 66, 64, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 62, 66, 66, 66, 63, 52, 53,
        54, 55, 56, 57, 58, 59, 60, 61, 66, 66, 66, 65, 66, 66, 66, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
        10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 66, 66, 66, 66, 66, 66, 26, 27, 28,
        29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 66, 66,
        66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
        66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
        66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
        66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
        66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
        66, 66, 66, 66, 66, 66
    };

    uint32_t buf = 1;
    size_t len = 0;

    for (size_t i = 0; i < in_len; i++)
    {
        uint8_t c = d[(uint8_t)in[i]];

        switch (c)
        {
        case 66:
            return 2;   /* invalid input, return error */
        case 65:
            i = in_len; /* pad character, end of data */
        case 64:
            continue;   /* skip whitespace */
        default:
            buf = buf << 6 | c;

            /* If the buffer is full, split it into bytes */
            if (buf & 0x1000000)
            {
                if ((len += 3) > *out_len) return 1; /* buffer overflow */
                *out++ = buf >> 16;
                *out++ = buf >> 8;
                *out++ = buf;
                buf = 1;
            }
        }
    }

    if (buf & 0x40000)
    {
        if ((len += 2) > *out_len) return 1; /* buffer overflow */
        *out++ = buf >> 10;
        *out++ = buf >> 2;
    }
    else if (buf & 0x1000)
    {
        if (++len > *out_len) return 1; /* buffer overflow */
        *out++ = buf >> 4;
    }

    *out_len = len; /* modify to reflect the actual output size */
    return 0;
}

size_t Base64Encode(const void *in, size_t in_len, char *out)
{
    static const char base64chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    const uint8_t *data = (const uint8_t *)in;
    size_t resultIndex = 0;

    /* increment over the length of the string, three characters at a time */
    for (size_t x = 0; x < in_len; x += 3)
    {
        /* these three 8-bit (ASCII) characters become one 24-bit number */
        uint32_t n = data[x] << 16;

        if ((x + 2) < in_len)
        {
            n += (data[x + 1] << 8) + data[x + 2];
        }
        else if ((x + 1) < in_len)
        {
            n += data[x + 1] << 8;
        }

        /*
        * if we have one byte available, then its encoding is spread
        * out over two characters
        */
        out[resultIndex++] = base64chars[(uint8_t)(n >> 18) & 63];
        out[resultIndex++] = base64chars[(uint8_t)(n >> 12) & 63];

        if ((x + 2) < in_len)
        {
            out[resultIndex++] = base64chars[(uint8_t)(n >> 6) & 63];
            out[resultIndex++] = base64chars[(uint8_t)n & 63];
        }
        else
        {
            if ((x + 1) < in_len)
            {
                out[resultIndex++] = base64chars[(uint8_t)(n >> 6) & 63];
            }
            else
            {
                out[resultIndex++] = '=';
            }
            out[resultIndex++] = '=';
        }

    }
    return resultIndex;
}

size_t Base64::Leanify(size_t size_leanified /*= 0*/)
{
    // 4 base64 character contains information of 3 bytes
    size_t binary_len = size * 3 / 4;
    unsigned char *binary_data = new unsigned char[binary_len];

    if (Base64Decode(fp, size, binary_data, &binary_len))
    {
        std::cerr << "Base64 decode error." << std::endl;
        delete[] binary_data;
        return size;
    }

    // Leanify embedded file
    binary_len = LeanifyFile(binary_data, binary_len);

    // encode back
    size = Base64Encode(binary_data, binary_len, fp - size_leanified);

    delete[] binary_data;
    return size;
}
<commit_msg>Base64: make sure data is moved even if error occurs<commit_after>#include "base64.h"

#include <cstdint>
#include <iostream>

#include "../leanify.h"

int Base64Decode(const char *in, size_t in_len, uint8_t *out, size_t *out_len)
{
    static const uint8_t d[] =
    {
        66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 64, 66, 66, 64, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
        66, 66, 66, 66, 66, 66, 66, 64, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 62, 66, 66, 66, 63, 52, 53,
        54, 55, 56, 57, 58, 59, 60, 61, 66, 66, 66, 65, 66, 66, 66, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
        10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 66, 66, 66, 66, 66, 66, 26, 27, 28,
        29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 66, 66,
        66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
        66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
        66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
        66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
        66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
        66, 66, 66, 66, 66, 66
    };

    uint32_t buf = 1;
    size_t len = 0;

    for (size_t i = 0; i < in_len; i++)
    {
        uint8_t c = d[(uint8_t)in[i]];

        switch (c)
        {
        case 66:
            return 2;   /* invalid input, return error */
        case 65:
            i = in_len; /* pad character, end of data */
        case 64:
            continue;   /* skip whitespace */
        default:
            buf = buf << 6 | c;

            /* If the buffer is full, split it into bytes */
            if (buf & 0x1000000)
            {
                if ((len += 3) > *out_len) return 1; /* buffer overflow */
                *out++ = buf >> 16;
                *out++ = buf >> 8;
                *out++ = buf;
                buf = 1;
            }
        }
    }

    if (buf & 0x40000)
    {
        if ((len += 2) > *out_len) return 1; /* buffer overflow */
        *out++ = buf >> 10;
        *out++ = buf >> 2;
    }
    else if (buf & 0x1000)
    {
        if (++len > *out_len) return 1; /* buffer overflow */
        *out++ = buf >> 4;
    }

    *out_len = len; /* modify to reflect the actual output size */
    return 0;
}

size_t Base64Encode(const void *in, size_t in_len, char *out)
{
    static const char base64chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    const uint8_t *data = (const uint8_t *)in;
    size_t resultIndex = 0;

    /* increment over the length of the string, three characters at a time */
    for (size_t x = 0; x < in_len; x += 3)
    {
        /* these three 8-bit (ASCII) characters become one 24-bit number */
        uint32_t n = data[x] << 16;

        if ((x + 2) < in_len)
        {
            n += (data[x + 1] << 8) + data[x + 2];
        }
        else if ((x + 1) < in_len)
        {
            n += data[x + 1] << 8;
        }

        /*
        * if we have one byte available, then its encoding is spread
        * out over two characters
        */
        out[resultIndex++] = base64chars[(uint8_t)(n >> 18) & 63];
        out[resultIndex++] = base64chars[(uint8_t)(n >> 12) & 63];

        if ((x + 2) < in_len)
        {
            out[resultIndex++] = base64chars[(uint8_t)(n >> 6) & 63];
            out[resultIndex++] = base64chars[(uint8_t)n & 63];
        }
        else
        {
            if ((x + 1) < in_len)
            {
                out[resultIndex++] = base64chars[(uint8_t)(n >> 6) & 63];
            }
            else
            {
                out[resultIndex++] = '=';
            }
            out[resultIndex++] = '=';
        }

    }
    return resultIndex;
}

size_t Base64::Leanify(size_t size_leanified /*= 0*/)
{
    // 4 base64 character contains information of 3 bytes
    size_t binary_len = size * 3 / 4;
    unsigned char *binary_data = new unsigned char[binary_len];

    if (Base64Decode(fp, size, binary_data, &binary_len))
    {
        std::cerr << "Base64 decode error." << std::endl;
        delete[] binary_data;
        return Format::Leanify(size_leanified);
    }

    // Leanify embedded file
    binary_len = LeanifyFile(binary_data, binary_len);

    fp -= size_leanified;
    // encode back
    size = Base64Encode(binary_data, binary_len, fp);

    delete[] binary_data;
    return size;
}
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the examples of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "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 Nokia Corporation and its Subsidiary(-ies) 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."
** $QT_END_LICENSE$
**
****************************************************************************/
#include "tap.h"

bool TapSensorFilter::filter(QTapReading *reading)
{
    QString output;
    switch (reading->tapDirection()) {
    case QTapReading::X:         output = "X";         break;
    case QTapReading::Y:         output = "Y";         break;
    case QTapReading::Z:         output = "Z";         break;
    case QTapReading::X_Pos:     output = "X pos";     break;
    case QTapReading::Y_Pos:     output = "Y pos";     break;
    case QTapReading::Z_Pos:     output = "Z pos";     break;
    case QTapReading::X_Neg:     output = "X neg";     break;
    case QTapReading::Y_Neg:     output = "Y neg";     break;
    case QTapReading::Z_Neg:     output = "Z neg";     break;
    case QTapReading::Undefined: output = "Undefined"; break;
    default: output = "Invalid enum value";
    }
    emit reading->isDoubleTap()?doubleHappened(output):singleHappened(output);
    return false; // don't store the reading in the sensor
}

<commit_msg>enum changes<commit_after>/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the examples of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "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 Nokia Corporation and its Subsidiary(-ies) 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."
** $QT_END_LICENSE$
**
****************************************************************************/
#include "tap.h"

bool TapSensorFilter::filter(QTapReading *reading)
{
    QString output;
    switch (reading->tapDirection()) {
        case QTapReading::X:
        case QTapReading::X_Both:
                output = "X";         break;
        case QTapReading::Y:
        case QTapReading::Y_Both:
                output = "Y";         break;
        case QTapReading::Z:
        case QTapReading::Z_Both:
                output = "Z";         break;
        case QTapReading::X_Pos:     output = "X pos";     break;
        case QTapReading::Y_Pos:     output = "Y pos";     break;
        case QTapReading::Z_Pos:     output = "Z pos";     break;
        case QTapReading::X_Neg:     output = "X neg";     break;
        case QTapReading::Y_Neg:     output = "Y neg";     break;
        case QTapReading::Z_Neg:     output = "Z neg";     break;
        case QTapReading::Undefined: output = "Undefined"; break;
        default: output = "Invalid enum value";
    }
    emit reading->isDoubleTap()?doubleHappened(output):singleHappened(output);
    return false; // don't store the reading in the sensor
}

<|endoftext|>


<commit_before>
#pragma once

#include "geometry/named_quantities.hpp"
#include "quantities/si.hpp"

// Epochs for expressing instants of Temps Atomique International (or Terrestial
// Time, which is parallel to it).
namespace principia {

using geometry::Instant;
using quantities::si::Day;
using quantities::si::Hour;
using quantities::si::Minute;
using quantities::si::Second;

namespace astronomy {

// |J2000| represents to the standard epoch J2000.0.
// According to Resolution B1 (On the Use of Julian Dates) of the XXIIIrd IAU
// general assembly, "it is recommended that JD be specified as SI seconds in
// Terrestrial Time (TT)", see http://goo.gl/oPemRm. J2000.0 is by definition
// JD 2451545.0, i.e., noon on the first of January, 2000 (TT). One computes the
// corresponding Temps Atomique International using TT = TAI + 32.184 s. The
// corresponding UTC is obtained by subtracting 10 s of inital offset and 22
// leap seconds.
// +2000-01-01T12:00:00.000 (Terrestial Time).
// +2000-01-01T11:59:27.816 (Temps Atomique International).
// +2000-01-01T11:58:55.816 (UTC).
Instant constexpr J2000;

// Unix epoch, obtained by subtracting 30 years (including 7 leap years)
// and the UTC time of day at J2000.0 from J2000.0.
// +2000-01-01T00:00:00.000 (UTC)
Instant const UnixEpoch = J2000 - ((30 * 365 + 7) * Day + 11 * Hour +
                                   58 * Minute + 55.816 * Second);

// The Julian Date JD |days|. J2000.0 is JD 2451545.0. |days| is the number of
// days since -4712-01-01-T12:00:00.000 (Terrestrial Time, Julian calendar).
Instant JulianDate(double const days);
// The Modified Julian Date MJD |days|. MJD is defined as JD - 2400000.5 days,
// so |ModifiedJulianDate(0)| is +1858-11-17-T00:00:00.000 (Terrestrial Time).
Instant ModifiedJulianDate(double const days);

}  // namespace astronomy
}  // namespace principia

#include "astronomy/epoch_body.hpp"
<commit_msg>constexpr placement<commit_after>
#pragma once

#include "geometry/named_quantities.hpp"
#include "quantities/si.hpp"

// Epochs for expressing instants of Temps Atomique International (or Terrestial
// Time, which is parallel to it).
namespace principia {

using geometry::Instant;
using quantities::si::Day;
using quantities::si::Hour;
using quantities::si::Minute;
using quantities::si::Second;

namespace astronomy {

// |J2000| represents to the standard epoch J2000.0.
// According to Resolution B1 (On the Use of Julian Dates) of the XXIIIrd IAU
// general assembly, "it is recommended that JD be specified as SI seconds in
// Terrestrial Time (TT)", see http://goo.gl/oPemRm. J2000.0 is by definition
// JD 2451545.0, i.e., noon on the first of January, 2000 (TT). One computes the
// corresponding Temps Atomique International using TT = TAI + 32.184 s. The
// corresponding UTC is obtained by subtracting 10 s of inital offset and 22
// leap seconds.
// +2000-01-01T12:00:00.000 (Terrestial Time).
// +2000-01-01T11:59:27.816 (Temps Atomique International).
// +2000-01-01T11:58:55.816 (UTC).
constexpr Instant J2000;

// Unix epoch, obtained by subtracting 30 years (including 7 leap years)
// and the UTC time of day at J2000.0 from J2000.0.
// +2000-01-01T00:00:00.000 (UTC)
Instant const UnixEpoch = J2000 - ((30 * 365 + 7) * Day + 11 * Hour +
                                   58 * Minute + 55.816 * Second);

// The Julian Date JD |days|. J2000.0 is JD 2451545.0. |days| is the number of
// days since -4712-01-01-T12:00:00.000 (Terrestrial Time, Julian calendar).
Instant JulianDate(double const days);
// The Modified Julian Date MJD |days|. MJD is defined as JD - 2400000.5 days,
// so |ModifiedJulianDate(0)| is +1858-11-17-T00:00:00.000 (Terrestrial Time).
Instant ModifiedJulianDate(double const days);

}  // namespace astronomy
}  // namespace principia

#include "astronomy/epoch_body.hpp"
<|endoftext|>


<commit_before>#include <chrono>
#include <iostream>

#include "utility.hpp"

// Inludes common necessary includes for development using depthai library
#include "depthai/depthai.hpp"

static const std::vector<std::string> labelMap = {"person", ""};

static std::atomic<bool> fullFrameTracking{false};

int main(int argc, char** argv) {
    using namespace std;
    using namespace std::chrono;
    std::string nnPath(BLOB_PATH);
    std::string videoPath(VIDEO_PATH);

    // If path to blob specified, use that
    if(argc > 2) {
        nnPath = std::string(argv[1]);
        videoPath = std::string(argv[2]);
    }

    // Print which blob we are using
    printf("Using blob at path: %s\n", nnPath.c_str());
    printf("Using video at path: %s\n", videoPath.c_str());

    // Create pipeline
    dai::Pipeline pipeline;

    // Define sources and outputs
    auto manip = pipeline.create<dai::node::ImageManip>();
    auto objectTracker = pipeline.create<dai::node::ObjectTracker>();
    auto detectionNetwork = pipeline.create<dai::node::MobileNetDetectionNetwork>();

    auto manipOut = pipeline.create<dai::node::XLinkOut>();
    auto xinFrame = pipeline.create<dai::node::XLinkIn>();
    auto trackerOut = pipeline.create<dai::node::XLinkOut>();
    auto xlinkOut = pipeline.create<dai::node::XLinkOut>();
    auto nnOut = pipeline.create<dai::node::XLinkOut>();

    manipOut->setStreamName("manip");
    xinFrame->setStreamName("inFrame");
    xlinkOut->setStreamName("trackerFrame");
    trackerOut->setStreamName("tracklets");
    nnOut->setStreamName("nn");

    // Properties
    xinFrame->setMaxDataSize(1920 * 1080 * 3);

    manip->initialConfig.setResizeThumbnail(384, 384);
    // manip->initialConfig.setResize(384, 384);
    // manip->initialConfig.setKeepAspectRatio(false); //squash the image to not lose FOV
    // The NN model expects BGR input. By default ImageManip output type would be same as input (gray in this case)
    manip->initialConfig.setFrameType(dai::ImgFrame::Type::BGR888p);
    manip->inputImage.setBlocking(true);

    // setting node configs
    detectionNetwork->setBlobPath(nnPath);
    detectionNetwork->setConfidenceThreshold(0.5);
    detectionNetwork->input.setBlocking(true);

    objectTracker->inputTrackerFrame.setBlocking(true);
    objectTracker->inputDetectionFrame.setBlocking(true);
    objectTracker->inputDetections.setBlocking(true);
    objectTracker->setDetectionLabelsToTrack({0});  // track only person
    // possible tracking types: ZERO_TERM_COLOR_HISTOGRAM, ZERO_TERM_IMAGELESS
    objectTracker->setTrackerType(dai::TrackerType::ZERO_TERM_COLOR_HISTOGRAM);
    // take the smallest ID when new object is tracked, possible options: SMALLEST_ID, UNIQUE_ID
    objectTracker->setTrackerIdAssigmentPolicy(dai::TrackerIdAssigmentPolicy::SMALLEST_ID);

    // Linking
    manip->out.link(manipOut->input);
    manip->out.link(detectionNetwork->input);
    xinFrame->out.link(manip->inputImage);
    xinFrame->out.link(objectTracker->inputTrackerFrame);
    detectionNetwork->out.link(nnOut->input);
    detectionNetwork->out.link(objectTracker->inputDetections);
    detectionNetwork->passthrough.link(objectTracker->inputDetectionFrame);
    objectTracker->out.link(trackerOut->input);
    objectTracker->passthroughTrackerFrame.link(xlinkOut->input);

    // Connect to device and start pipeline
    dai::Device device(pipeline);

    auto qIn = device.getInputQueue("inFrame", 4);
    auto trackerFrameQ = device.getOutputQueue("trackerFrame", 4);
    auto tracklets = device.getOutputQueue("tracklets", 4);
    auto qManip = device.getOutputQueue("manip", 4);
    auto qDet = device.getOutputQueue("nn", 4);

    auto startTime = steady_clock::now();
    int counter = 0;
    float fps = 0;
    cv::Mat frame;
    cv::Mat manipFrame;
    std::vector<dai::ImgDetection> detections;

    // Add bounding boxes and text to the frame and show it to the user
    auto displayFrame = [](std::string name, cv::Mat frame, std::vector<dai::ImgDetection>& detections) {
        auto color = cv::Scalar(255, 0, 0);
        // nn data, being the bounding box locations, are in <0..1> range - they need to be normalized with frame width/height
        for(auto& detection : detections) {
            int x1 = detection.xmin * frame.cols;
            int y1 = detection.ymin * frame.rows;
            int x2 = detection.xmax * frame.cols;
            int y2 = detection.ymax * frame.rows;

            int labelIndex = detection.label;
            std::string labelStr = to_string(labelIndex);
            if(labelIndex < labelMap.size()) {
                labelStr = labelMap[labelIndex];
            }
            cv::putText(frame, labelStr, cv::Point(x1 + 10, y1 + 20), cv::FONT_HERSHEY_TRIPLEX, 0.5, color);
            std::stringstream confStr;
            confStr << std::fixed << std::setprecision(2) << detection.confidence * 100;
            cv::putText(frame, confStr.str(), cv::Point(x1 + 10, y1 + 40), cv::FONT_HERSHEY_TRIPLEX, 0.5, color);
            cv::rectangle(frame, cv::Rect(cv::Point(x1, y1), cv::Point(x2, y2)), color, cv::FONT_HERSHEY_SIMPLEX);
        }
        // Show the frame
        cv::imshow(name, frame);
    };

    cv::VideoCapture cap(videoPath);

    while(cap.isOpened()) {
        // Read frame from video
        cap >> frame;
        if(frame.empty()) break;

        auto img = std::make_shared<dai::ImgFrame>();
        frame = resizeKeepAspectRatio(frame, cv::Size(1280, 720), cv::Scalar(0));
        toPlanar(frame, img->getData());
        img->setWidth(1280);
        img->setHeight(720);
        img->setType(dai::ImgFrame::Type::BGR888p);
        qIn->send(img);

        auto trackFrame = trackerFrameQ->tryGet<dai::ImgFrame>();
        if(!trackFrame) {
            continue;
        }

        auto track = tracklets->get<dai::Tracklets>();
        auto inManip = qManip->get<dai::ImgFrame>();
        auto inDet = qDet->get<dai::ImgDetections>();

        counter++;
        auto currentTime = steady_clock::now();
        auto elapsed = duration_cast<duration<float>>(currentTime - startTime);
        if(elapsed > seconds(1)) {
            fps = counter / elapsed.count();
            counter = 0;
            startTime = currentTime;
        }

        detections = inDet->detections;
        manipFrame = inManip->getCvFrame();
        displayFrame("nn", manipFrame, detections);

        auto color = cv::Scalar(255, 0, 0);
        cv::Mat trackerFrame = trackFrame->getCvFrame();
        auto trackletsData = track->tracklets;
        for(auto& t : trackletsData) {
            auto roi = t.roi.denormalize(trackerFrame.cols, trackerFrame.rows);
            int x1 = roi.topLeft().x;
            int y1 = roi.topLeft().y;
            int x2 = roi.bottomRight().x;
            int y2 = roi.bottomRight().y;

            int labelIndex = t.label;
            std::string labelStr = to_string(labelIndex);
            if(labelIndex < labelMap.size()) {
                labelStr = labelMap[labelIndex];
            }
            cv::putText(trackerFrame, labelStr, cv::Point(x1 + 10, y1 + 20), cv::FONT_HERSHEY_TRIPLEX, 0.5, color);

            std::stringstream idStr;
            idStr << "ID: " << t.id;
            cv::putText(trackerFrame, idStr.str(), cv::Point(x1 + 10, y1 + 40), cv::FONT_HERSHEY_TRIPLEX, 0.5, color);
            std::stringstream statusStr;
            statusStr << "Status: " << t.status;
            cv::putText(trackerFrame, statusStr.str(), cv::Point(x1 + 10, y1 + 60), cv::FONT_HERSHEY_TRIPLEX, 0.5, color);

            cv::rectangle(trackerFrame, cv::Rect(cv::Point(x1, y1), cv::Point(x2, y2)), color, cv::FONT_HERSHEY_SIMPLEX);
        }

        std::stringstream fpsStr;
        fpsStr << "NN fps:" << std::fixed << std::setprecision(2) << fps;
        cv::putText(trackerFrame, fpsStr.str(), cv::Point(2, trackFrame->getHeight() - 4), cv::FONT_HERSHEY_TRIPLEX, 0.4, color);

        cv::imshow("tracker", trackerFrame);

        int key = cv::waitKey(1);
        if(key == 'q' || key == 'Q') {
            return 0;
        }
    }
    return 0;
}
<commit_msg>Add timestamp<commit_after>#include <chrono>
#include <iostream>

#include "utility.hpp"

// Inludes common necessary includes for development using depthai library
#include "depthai/depthai.hpp"

static const std::vector<std::string> labelMap = {"person", ""};

static std::atomic<bool> fullFrameTracking{false};

int main(int argc, char** argv) {
    using namespace std;
    using namespace std::chrono;
    std::string nnPath(BLOB_PATH);
    std::string videoPath(VIDEO_PATH);

    // If path to blob specified, use that
    if(argc > 2) {
        nnPath = std::string(argv[1]);
        videoPath = std::string(argv[2]);
    }

    // Print which blob we are using
    printf("Using blob at path: %s\n", nnPath.c_str());
    printf("Using video at path: %s\n", videoPath.c_str());

    // Create pipeline
    dai::Pipeline pipeline;

    // Define sources and outputs
    auto manip = pipeline.create<dai::node::ImageManip>();
    auto objectTracker = pipeline.create<dai::node::ObjectTracker>();
    auto detectionNetwork = pipeline.create<dai::node::MobileNetDetectionNetwork>();

    auto manipOut = pipeline.create<dai::node::XLinkOut>();
    auto xinFrame = pipeline.create<dai::node::XLinkIn>();
    auto trackerOut = pipeline.create<dai::node::XLinkOut>();
    auto xlinkOut = pipeline.create<dai::node::XLinkOut>();
    auto nnOut = pipeline.create<dai::node::XLinkOut>();

    manipOut->setStreamName("manip");
    xinFrame->setStreamName("inFrame");
    xlinkOut->setStreamName("trackerFrame");
    trackerOut->setStreamName("tracklets");
    nnOut->setStreamName("nn");

    // Properties
    xinFrame->setMaxDataSize(1920 * 1080 * 3);

    manip->initialConfig.setResizeThumbnail(384, 384);
    // manip->initialConfig.setResize(384, 384);
    // manip->initialConfig.setKeepAspectRatio(false); //squash the image to not lose FOV
    // The NN model expects BGR input. By default ImageManip output type would be same as input (gray in this case)
    manip->initialConfig.setFrameType(dai::ImgFrame::Type::BGR888p);
    manip->inputImage.setBlocking(true);

    // setting node configs
    detectionNetwork->setBlobPath(nnPath);
    detectionNetwork->setConfidenceThreshold(0.5);
    detectionNetwork->input.setBlocking(true);

    objectTracker->inputTrackerFrame.setBlocking(true);
    objectTracker->inputDetectionFrame.setBlocking(true);
    objectTracker->inputDetections.setBlocking(true);
    objectTracker->setDetectionLabelsToTrack({0});  // track only person
    // possible tracking types: ZERO_TERM_COLOR_HISTOGRAM, ZERO_TERM_IMAGELESS
    objectTracker->setTrackerType(dai::TrackerType::ZERO_TERM_COLOR_HISTOGRAM);
    // take the smallest ID when new object is tracked, possible options: SMALLEST_ID, UNIQUE_ID
    objectTracker->setTrackerIdAssigmentPolicy(dai::TrackerIdAssigmentPolicy::SMALLEST_ID);

    // Linking
    manip->out.link(manipOut->input);
    manip->out.link(detectionNetwork->input);
    xinFrame->out.link(manip->inputImage);
    xinFrame->out.link(objectTracker->inputTrackerFrame);
    detectionNetwork->out.link(nnOut->input);
    detectionNetwork->out.link(objectTracker->inputDetections);
    detectionNetwork->passthrough.link(objectTracker->inputDetectionFrame);
    objectTracker->out.link(trackerOut->input);
    objectTracker->passthroughTrackerFrame.link(xlinkOut->input);

    // Connect to device and start pipeline
    dai::Device device(pipeline);

    auto qIn = device.getInputQueue("inFrame", 4);
    auto trackerFrameQ = device.getOutputQueue("trackerFrame", 4);
    auto tracklets = device.getOutputQueue("tracklets", 4);
    auto qManip = device.getOutputQueue("manip", 4);
    auto qDet = device.getOutputQueue("nn", 4);

    auto startTime = steady_clock::now();
    int counter = 0;
    float fps = 0;
    cv::Mat frame;
    cv::Mat manipFrame;
    std::vector<dai::ImgDetection> detections;

    // Add bounding boxes and text to the frame and show it to the user
    auto displayFrame = [](std::string name, cv::Mat frame, std::vector<dai::ImgDetection>& detections) {
        auto color = cv::Scalar(255, 0, 0);
        // nn data, being the bounding box locations, are in <0..1> range - they need to be normalized with frame width/height
        for(auto& detection : detections) {
            int x1 = detection.xmin * frame.cols;
            int y1 = detection.ymin * frame.rows;
            int x2 = detection.xmax * frame.cols;
            int y2 = detection.ymax * frame.rows;

            int labelIndex = detection.label;
            std::string labelStr = to_string(labelIndex);
            if(labelIndex < labelMap.size()) {
                labelStr = labelMap[labelIndex];
            }
            cv::putText(frame, labelStr, cv::Point(x1 + 10, y1 + 20), cv::FONT_HERSHEY_TRIPLEX, 0.5, color);
            std::stringstream confStr;
            confStr << std::fixed << std::setprecision(2) << detection.confidence * 100;
            cv::putText(frame, confStr.str(), cv::Point(x1 + 10, y1 + 40), cv::FONT_HERSHEY_TRIPLEX, 0.5, color);
            cv::rectangle(frame, cv::Rect(cv::Point(x1, y1), cv::Point(x2, y2)), color, cv::FONT_HERSHEY_SIMPLEX);
        }
        // Show the frame
        cv::imshow(name, frame);
    };

    cv::VideoCapture cap(videoPath);
    auto baseTs = steady_clock::now();
    float simulatedFps = 30;

    while(cap.isOpened()) {
        // Read frame from video
        cap >> frame;
        if(frame.empty()) break;

        auto img = std::make_shared<dai::ImgFrame>();
        frame = resizeKeepAspectRatio(frame, cv::Size(1280, 720), cv::Scalar(0));
        toPlanar(frame, img->getData());
        img->setTimestamp(baseTs);
        baseTs += steady_clock::duration(static_cast<int64_t>((1000 * 1000 * 1000 / simulatedFps)));
        img->setWidth(1280);
        img->setHeight(720);
        img->setType(dai::ImgFrame::Type::BGR888p);
        qIn->send(img);

        auto trackFrame = trackerFrameQ->tryGet<dai::ImgFrame>();
        if(!trackFrame) {
            continue;
        }

        auto track = tracklets->get<dai::Tracklets>();
        auto inManip = qManip->get<dai::ImgFrame>();
        auto inDet = qDet->get<dai::ImgDetections>();

        counter++;
        auto currentTime = steady_clock::now();
        auto elapsed = duration_cast<duration<float>>(currentTime - startTime);
        if(elapsed > seconds(1)) {
            fps = counter / elapsed.count();
            counter = 0;
            startTime = currentTime;
        }

        detections = inDet->detections;
        manipFrame = inManip->getCvFrame();
        displayFrame("nn", manipFrame, detections);

        auto color = cv::Scalar(255, 0, 0);
        cv::Mat trackerFrame = trackFrame->getCvFrame();
        auto trackletsData = track->tracklets;
        for(auto& t : trackletsData) {
            auto roi = t.roi.denormalize(trackerFrame.cols, trackerFrame.rows);
            int x1 = roi.topLeft().x;
            int y1 = roi.topLeft().y;
            int x2 = roi.bottomRight().x;
            int y2 = roi.bottomRight().y;

            int labelIndex = t.label;
            std::string labelStr = to_string(labelIndex);
            if(labelIndex < labelMap.size()) {
                labelStr = labelMap[labelIndex];
            }
            cv::putText(trackerFrame, labelStr, cv::Point(x1 + 10, y1 + 20), cv::FONT_HERSHEY_TRIPLEX, 0.5, color);

            std::stringstream idStr;
            idStr << "ID: " << t.id;
            cv::putText(trackerFrame, idStr.str(), cv::Point(x1 + 10, y1 + 40), cv::FONT_HERSHEY_TRIPLEX, 0.5, color);
            std::stringstream statusStr;
            statusStr << "Status: " << t.status;
            cv::putText(trackerFrame, statusStr.str(), cv::Point(x1 + 10, y1 + 60), cv::FONT_HERSHEY_TRIPLEX, 0.5, color);

            cv::rectangle(trackerFrame, cv::Rect(cv::Point(x1, y1), cv::Point(x2, y2)), color, cv::FONT_HERSHEY_SIMPLEX);
        }

        std::stringstream fpsStr;
        fpsStr << "NN fps:" << std::fixed << std::setprecision(2) << fps;
        cv::putText(trackerFrame, fpsStr.str(), cv::Point(2, trackFrame->getHeight() - 4), cv::FONT_HERSHEY_TRIPLEX, 0.4, color);

        cv::imshow("tracker", trackerFrame);

        int key = cv::waitKey(1);
        if(key == 'q' || key == 'Q') {
            return 0;
        }
    }
    return 0;
}
<|endoftext|>


<commit_before>////////////////////////////////////////////////////////////////////////////////
/// @brief Thread
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2014 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
///     http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Dr. Frank Celler
/// @author Achim Brandt
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
/// @author Copyright 2008-2013, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////

#include "Thread.h"

#ifdef _WIN32
#include "BasicsC/win-utils.h"
#endif

#include <errno.h>
#include <signal.h>

#include "Basics/ConditionLocker.h"
#include "BasicsC/logging.h"

using namespace triagens::basics;

// -----------------------------------------------------------------------------
// --SECTION--                                            static private methods
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @brief static started with access to the private variables
////////////////////////////////////////////////////////////////////////////////

void Thread::startThread (void* arg) {
  Thread * ptr = static_cast<Thread*>(arg);

  ptr->runMe();
  ptr->cleanup();
}

// -----------------------------------------------------------------------------
// --SECTION--                                             static public methods
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @brief returns the process id
////////////////////////////////////////////////////////////////////////////////

TRI_pid_t Thread::currentProcessId () {
  return TRI_CurrentProcessId();
}

////////////////////////////////////////////////////////////////////////////////
/// @brief returns the thread process id
////////////////////////////////////////////////////////////////////////////////

TRI_pid_t Thread::currentThreadProcessId () {
  return TRI_CurrentThreadProcessId();
}

////////////////////////////////////////////////////////////////////////////////
/// @brief returns the thread id
////////////////////////////////////////////////////////////////////////////////

TRI_tid_t Thread::currentThreadId () {
  return TRI_CurrentThreadId();
}

// -----------------------------------------------------------------------------
// --SECTION--                                      constructors and destructors
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @brief constructs a thread
////////////////////////////////////////////////////////////////////////////////

Thread::Thread (std::string const& name)
  : _name(name),
    _asynchronousCancelation(false),
    _thread(),
    _threadId(),
    _finishedCondition(0),
    _started(0),
    _running(0),
    _joined(0) {
  TRI_InitThread(&_thread);
}

////////////////////////////////////////////////////////////////////////////////
/// @brief deletes the thread
////////////////////////////////////////////////////////////////////////////////

Thread::~Thread () {
  int res;

  if (_running != 0) {
    if (! isSilent()) {
      LOG_WARNING("forcefully shutting down thread '%s'", _name.c_str());
    }

    res = TRI_StopThread(&_thread);

    if (res != TRI_ERROR_NO_ERROR) {
      LOG_WARNING("unable to stop thread '%s': %s", _name.c_str(), TRI_errno_string(res));
    }
  }

  if (! _joined) {
    res = TRI_DetachThread(&_thread);

    if (res != TRI_ERROR_NO_ERROR) {
      LOG_WARNING("unable to detach thread '%s': %s", _name.c_str(), TRI_errno_string(res));
    }
  }
}

// -----------------------------------------------------------------------------
// --SECTION--                                                    public methods
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @brief whether or not the thread is chatty on shutdown
////////////////////////////////////////////////////////////////////////////////

bool Thread::isSilent () {
  return false;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief getter for running
////////////////////////////////////////////////////////////////////////////////

bool Thread::isRunning () {
  return _running != 0;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief returns a thread identifier
////////////////////////////////////////////////////////////////////////////////

TRI_tid_t Thread::threadId () {
  return _threadId;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief starts the thread
////////////////////////////////////////////////////////////////////////////////

bool Thread::start (ConditionVariable * finishedCondition) {
  _finishedCondition = finishedCondition;

  if (_started != 0) {
    LOG_FATAL_AND_EXIT("called started on an already started thread");
  }

  _started = 1;

  string text = "[" + _name + "]";
  bool ok = TRI_StartThread(&_thread, &_threadId, text.c_str(), &startThread, this);

  if (! ok) {
    LOG_ERROR("could not start thread '%s': %s", _name.c_str(), strerror(errno));
  }

  return ok;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief stops the thread
////////////////////////////////////////////////////////////////////////////////

int Thread::stop () {
  if (_running != 0) {
    LOG_TRACE("trying to cancel (aka stop) the thread '%s'", _name.c_str());
    return TRI_StopThread(&_thread);
  }

  return TRI_ERROR_NO_ERROR;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief joins the thread
////////////////////////////////////////////////////////////////////////////////

int Thread::join () {
  int res = TRI_ERROR_NO_ERROR;

  if (! _joined) {
    res = TRI_JoinThread(&_thread);

    if (res == TRI_ERROR_NO_ERROR) {
      _joined = 1;
    }
  }

  return res;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief stops and joins the thread
////////////////////////////////////////////////////////////////////////////////

int Thread::shutdown () {
  size_t const MAX_TRIES = 10;
  size_t const WAIT = 10000;

  for (size_t i = 0;  i < MAX_TRIES;  ++i) {
    if (_running == 0) {
      break;
    }

    usleep(WAIT);
  }

  if (_running != 0) {
    int res = TRI_StopThread(&_thread);

    if (res != TRI_ERROR_NO_ERROR) {
      LOG_WARNING("unable to stop thread '%s': %s",
                  _name.c_str(),
                  TRI_errno_string(res));
    }
  }

  return this->join();
}

// -----------------------------------------------------------------------------
// --SECTION--                                                 protected methods
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @brief allows asynchrounous cancelation
////////////////////////////////////////////////////////////////////////////////

void Thread::allowAsynchronousCancelation () {
  if (_started) {
    if (_running) {
      if (TRI_IsSelfThread(&_thread)) {
        LOG_DEBUG("set asynchronous cancelation for thread '%s'", _name.c_str());
        TRI_AllowCancelation();
      }
      else {
        LOG_ERROR("cannot change cancelation type of an already running thread from the outside");
      }
    }
    else {
      LOG_WARNING("thread has already stopped, it is useless to change the cancelation type");
    }
  }
  else {
    _asynchronousCancelation = true;
  }
}

// -----------------------------------------------------------------------------
// --SECTION--                                                   private methods
// -----------------------------------------------------------------------------

void Thread::runMe () {
  if (_asynchronousCancelation) {
    LOG_DEBUG("set asynchronous cancelation for thread '%s'", _name.c_str());
    TRI_AllowCancelation();
  }

  _running = 1;

  try {
    run();
  }
  catch (...) {
    _running = 0;
    if (! isSilent()) {
      LOG_WARNING("exception caught in thread '%s'", _name.c_str());
    }
    throw;
  }

  _running = 0;

  if (_finishedCondition != 0) {
    CONDITION_LOCKER(locker, *_finishedCondition);
    locker.broadcast();
  }
}

// -----------------------------------------------------------------------------
// --SECTION--                                                       END-OF-FILE
// -----------------------------------------------------------------------------

// Local Variables:
// mode: outline-minor
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
// End:
<commit_msg>upgrade error message<commit_after>////////////////////////////////////////////////////////////////////////////////
/// @brief Thread
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2014 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
///     http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Dr. Frank Celler
/// @author Achim Brandt
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
/// @author Copyright 2008-2013, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////

#include "Thread.h"

#ifdef _WIN32
#include "BasicsC/win-utils.h"
#endif

#include <errno.h>
#include <signal.h>

#include "Basics/ConditionLocker.h"
#include "BasicsC/logging.h"

using namespace triagens::basics;

// -----------------------------------------------------------------------------
// --SECTION--                                            static private methods
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @brief static started with access to the private variables
////////////////////////////////////////////////////////////////////////////////

void Thread::startThread (void* arg) {
  Thread * ptr = static_cast<Thread*>(arg);

  ptr->runMe();
  ptr->cleanup();
}

// -----------------------------------------------------------------------------
// --SECTION--                                             static public methods
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @brief returns the process id
////////////////////////////////////////////////////////////////////////////////

TRI_pid_t Thread::currentProcessId () {
  return TRI_CurrentProcessId();
}

////////////////////////////////////////////////////////////////////////////////
/// @brief returns the thread process id
////////////////////////////////////////////////////////////////////////////////

TRI_pid_t Thread::currentThreadProcessId () {
  return TRI_CurrentThreadProcessId();
}

////////////////////////////////////////////////////////////////////////////////
/// @brief returns the thread id
////////////////////////////////////////////////////////////////////////////////

TRI_tid_t Thread::currentThreadId () {
  return TRI_CurrentThreadId();
}

// -----------------------------------------------------------------------------
// --SECTION--                                      constructors and destructors
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @brief constructs a thread
////////////////////////////////////////////////////////////////////////////////

Thread::Thread (std::string const& name)
  : _name(name),
    _asynchronousCancelation(false),
    _thread(),
    _threadId(),
    _finishedCondition(0),
    _started(0),
    _running(0),
    _joined(0) {
  TRI_InitThread(&_thread);
}

////////////////////////////////////////////////////////////////////////////////
/// @brief deletes the thread
////////////////////////////////////////////////////////////////////////////////

Thread::~Thread () {
  int res;

  if (_running != 0) {
    if (! isSilent()) {
      LOG_WARNING("forcefully shutting down thread '%s'", _name.c_str());
    }

    res = TRI_StopThread(&_thread);

    if (res != TRI_ERROR_NO_ERROR) {
      LOG_WARNING("unable to stop thread '%s': %s", _name.c_str(), TRI_errno_string(res));
    }
  }

  if (! _joined) {
    res = TRI_DetachThread(&_thread);

    if (res != TRI_ERROR_NO_ERROR) {
      LOG_WARNING("unable to detach thread '%s': %s", _name.c_str(), TRI_errno_string(res));
    }
  }
}

// -----------------------------------------------------------------------------
// --SECTION--                                                    public methods
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @brief whether or not the thread is chatty on shutdown
////////////////////////////////////////////////////////////////////////////////

bool Thread::isSilent () {
  return false;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief getter for running
////////////////////////////////////////////////////////////////////////////////

bool Thread::isRunning () {
  return _running != 0;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief returns a thread identifier
////////////////////////////////////////////////////////////////////////////////

TRI_tid_t Thread::threadId () {
  return _threadId;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief starts the thread
////////////////////////////////////////////////////////////////////////////////

bool Thread::start (ConditionVariable * finishedCondition) {
  _finishedCondition = finishedCondition;

  if (_started != 0) {
    LOG_FATAL_AND_EXIT("called started on an already started thread");
  }

  _started = 1;

  string text = "[" + _name + "]";
  bool ok = TRI_StartThread(&_thread, &_threadId, text.c_str(), &startThread, this);

  if (! ok) {
    LOG_ERROR("could not start thread '%s': %s", _name.c_str(), strerror(errno));
  }

  return ok;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief stops the thread
////////////////////////////////////////////////////////////////////////////////

int Thread::stop () {
  if (_running != 0) {
    LOG_TRACE("trying to cancel (aka stop) the thread '%s'", _name.c_str());
    return TRI_StopThread(&_thread);
  }

  return TRI_ERROR_NO_ERROR;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief joins the thread
////////////////////////////////////////////////////////////////////////////////

int Thread::join () {
  int res = TRI_ERROR_NO_ERROR;

  if (! _joined) {
    res = TRI_JoinThread(&_thread);

    if (res == TRI_ERROR_NO_ERROR) {
      _joined = 1;
    }
  }

  return res;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief stops and joins the thread
////////////////////////////////////////////////////////////////////////////////

int Thread::shutdown () {
  size_t const MAX_TRIES = 10;
  size_t const WAIT = 10000;

  for (size_t i = 0;  i < MAX_TRIES;  ++i) {
    if (_running == 0) {
      break;
    }

    usleep(WAIT);
  }

  if (_running != 0) {
    int res = TRI_StopThread(&_thread);

    if (res != TRI_ERROR_NO_ERROR) {
      LOG_WARNING("unable to stop thread '%s': %s",
                  _name.c_str(),
                  TRI_errno_string(res));
    }
  }

  return this->join();
}

// -----------------------------------------------------------------------------
// --SECTION--                                                 protected methods
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @brief allows asynchrounous cancelation
////////////////////////////////////////////////////////////////////////////////

void Thread::allowAsynchronousCancelation () {
  if (_started) {
    if (_running) {
      if (TRI_IsSelfThread(&_thread)) {
        LOG_DEBUG("set asynchronous cancelation for thread '%s'", _name.c_str());
        TRI_AllowCancelation();
      }
      else {
        LOG_ERROR("cannot change cancelation type of an already running thread from the outside");
      }
    }
    else {
      LOG_WARNING("thread has already stopped, it is useless to change the cancelation type");
    }
  }
  else {
    _asynchronousCancelation = true;
  }
}

// -----------------------------------------------------------------------------
// --SECTION--                                                   private methods
// -----------------------------------------------------------------------------

void Thread::runMe () {
  if (_asynchronousCancelation) {
    LOG_DEBUG("set asynchronous cancelation for thread '%s'", _name.c_str());
    TRI_AllowCancelation();
  }

  _running = 1;

  try {
    run();
  }
  catch (...) {
    _running = 0;
    if (! isSilent()) {
      LOG_ERROR("exception caught in thread '%s'", _name.c_str());
    }
    throw;
  }

  _running = 0;

  if (_finishedCondition != 0) {
    CONDITION_LOCKER(locker, *_finishedCondition);
    locker.broadcast();
  }
}

// -----------------------------------------------------------------------------
// --SECTION--                                                       END-OF-FILE
// -----------------------------------------------------------------------------

// Local Variables:
// mode: outline-minor
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
// End:
<|endoftext|>