<commit_before>// Copyright 2015 Google Inc. All rights reserved.
//
// 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.

#include "benchmark/reporter.h"

#include <cstdint>
#include <cstdio>
#include <iostream>
#include <string>
#include <tuple>
#include <vector>

#include "check.h"
#include "colorprint.h"
#include "string_util.h"
#include "walltime.h"

namespace benchmark {

bool ConsoleReporter::ReportContext(const Context& context) {
  name_field_width_ = context.name_field_width;

  std::cerr << "Run on (" << context.num_cpus << " X " << context.mhz_per_cpu
            << " MHz CPU " << ((context.num_cpus > 1) ? "s" : "") << ")\n";

  std::cerr << LocalDateTimeString() << "\n";

  if (context.cpu_scaling_enabled) {
    std::cerr << "***WARNING*** CPU scaling is enabled, the benchmark "
                 "real time measurements may be noisy and will incur extra "
                 "overhead.\n";
  }

#ifndef NDEBUG
  std::cerr << "***WARNING*** Library was built as DEBUG. Timings may be "
               "affected.\n";
#endif

  int output_width = fprintf(stdout, "%-*s %13s %13s %10s\n",
                             static_cast<int>(name_field_width_), "Benchmark",
                             "Time", "CPU", "Iterations");
  std::cout << std::string(output_width - 1, '-') << "\n";

  return true;
}

void ConsoleReporter::ReportRuns(const std::vector<Run>& reports) {
  if (reports.empty()) {
    return;
  }

  for (Run const& run : reports) {
    CHECK_EQ(reports[0].benchmark_name, run.benchmark_name);
    PrintRunData(run);
  }

  if (reports.size() < 2) {
    // We don't report aggregated data if there was a single run.
    return;
  }

  Run mean_data;
  Run stddev_data;
  BenchmarkReporter::ComputeStats(reports, &mean_data, &stddev_data);

  // Output using PrintRun.
  PrintRunData(mean_data);
  PrintRunData(stddev_data);
}

void ConsoleReporter::ReportComplexity(const std::vector<Run> & complexity_reports) {
  if (complexity_reports.size() < 2) {
    // We don't report asymptotic complexity data if there was a single run.
    return;
  }

  Run big_o_data;
  Run rms_data;
  BenchmarkReporter::ComputeBigO(complexity_reports, &big_o_data, &rms_data);

  // Output using PrintRun.
  PrintRunData(big_o_data);
  PrintRunData(rms_data);
}

void ConsoleReporter::PrintRunData(const Run& result) {
  // Format bytes per second
  std::string rate;
  if (result.bytes_per_second > 0) {
    rate = StrCat(" ", HumanReadableNumber(result.bytes_per_second), "B/s");
  }

  // Format items per second
  std::string items;
  if (result.items_per_second > 0) {
    items = StrCat(" ", HumanReadableNumber(result.items_per_second),
                   " items/s");
  }

  double multiplier;
  const char* timeLabel;
  std::tie(timeLabel, multiplier) = GetTimeUnitAndMultiplier(result.time_unit);

  ColorPrintf((result.report_big_o ||result.report_rms) ? COLOR_BLUE : COLOR_GREEN, "%-*s ",
              name_field_width_, result.benchmark_name.c_str());

  if(result.report_big_o) {
    std::string big_o = result.report_big_o ? GetBigO(result.complexity) : "";
    ColorPrintf(COLOR_YELLOW, "%10.4f %s %10.4f %s ",
                result.real_accumulated_time * multiplier,
                big_o.c_str(),
                result.cpu_accumulated_time * multiplier,
                big_o.c_str());
  }
  else if(result.report_rms) {
    ColorPrintf(COLOR_YELLOW, "%10.0f %s %10.0f %s ",
                result.real_accumulated_time * multiplier * 100,
                "%",
                result.cpu_accumulated_time * multiplier * 100,
                "%");
  }
  else if (result.iterations == 0) {
    ColorPrintf(COLOR_YELLOW, "%10.0f %s %10.0f %s ",
                result.real_accumulated_time * multiplier,
                timeLabel,
                result.cpu_accumulated_time * multiplier,
                timeLabel);
  } else {
    ColorPrintf(COLOR_YELLOW, "%10.0f %s %10.0f %s ",
                (result.real_accumulated_time * multiplier) /
                    (static_cast<double>(result.iterations)),
                timeLabel,
                (result.cpu_accumulated_time * multiplier) /
                    (static_cast<double>(result.iterations)),
                timeLabel);
  }

  if(!result.report_big_o && !result.report_rms)
    ColorPrintf(COLOR_CYAN, "%10lld", result.iterations);

  if (!rate.empty()) {
    ColorPrintf(COLOR_DEFAULT, " %*s", 13, rate.c_str());
  }

  if (!items.empty()) {
    ColorPrintf(COLOR_DEFAULT, " %*s", 18, items.c_str());
  }

  if (!result.report_label.empty()) {
    ColorPrintf(COLOR_DEFAULT, " %s", result.report_label.c_str());
  }

  ColorPrintf(COLOR_DEFAULT, "\n");
}

}  // end namespace benchmark
<commit_msg>simplify format string for complexity output<commit_after>// Copyright 2015 Google Inc. All rights reserved.
//
// 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.

#include "benchmark/reporter.h"

#include <cstdint>
#include <cstdio>
#include <iostream>
#include <string>
#include <tuple>
#include <vector>

#include "check.h"
#include "colorprint.h"
#include "string_util.h"
#include "walltime.h"

namespace benchmark {

bool ConsoleReporter::ReportContext(const Context& context) {
  name_field_width_ = context.name_field_width;

  std::cerr << "Run on (" << context.num_cpus << " X " << context.mhz_per_cpu
            << " MHz CPU " << ((context.num_cpus > 1) ? "s" : "") << ")\n";

  std::cerr << LocalDateTimeString() << "\n";

  if (context.cpu_scaling_enabled) {
    std::cerr << "***WARNING*** CPU scaling is enabled, the benchmark "
                 "real time measurements may be noisy and will incur extra "
                 "overhead.\n";
  }

#ifndef NDEBUG
  std::cerr << "***WARNING*** Library was built as DEBUG. Timings may be "
               "affected.\n";
#endif

  int output_width = fprintf(stdout, "%-*s %13s %13s %10s\n",
                             static_cast<int>(name_field_width_), "Benchmark",
                             "Time", "CPU", "Iterations");
  std::cout << std::string(output_width - 1, '-') << "\n";

  return true;
}

void ConsoleReporter::ReportRuns(const std::vector<Run>& reports) {
  if (reports.empty()) {
    return;
  }

  for (Run const& run : reports) {
    CHECK_EQ(reports[0].benchmark_name, run.benchmark_name);
    PrintRunData(run);
  }

  if (reports.size() < 2) {
    // We don't report aggregated data if there was a single run.
    return;
  }

  Run mean_data;
  Run stddev_data;
  BenchmarkReporter::ComputeStats(reports, &mean_data, &stddev_data);

  // Output using PrintRun.
  PrintRunData(mean_data);
  PrintRunData(stddev_data);
}

void ConsoleReporter::ReportComplexity(const std::vector<Run> & complexity_reports) {
  if (complexity_reports.size() < 2) {
    // We don't report asymptotic complexity data if there was a single run.
    return;
  }

  Run big_o_data;
  Run rms_data;
  BenchmarkReporter::ComputeBigO(complexity_reports, &big_o_data, &rms_data);

  // Output using PrintRun.
  PrintRunData(big_o_data);
  PrintRunData(rms_data);
}

void ConsoleReporter::PrintRunData(const Run& result) {
  // Format bytes per second
  std::string rate;
  if (result.bytes_per_second > 0) {
    rate = StrCat(" ", HumanReadableNumber(result.bytes_per_second), "B/s");
  }

  // Format items per second
  std::string items;
  if (result.items_per_second > 0) {
    items = StrCat(" ", HumanReadableNumber(result.items_per_second),
                   " items/s");
  }

  double multiplier;
  const char* timeLabel;
  std::tie(timeLabel, multiplier) = GetTimeUnitAndMultiplier(result.time_unit);

  ColorPrintf((result.report_big_o ||result.report_rms) ? COLOR_BLUE : COLOR_GREEN, "%-*s ",
              name_field_width_, result.benchmark_name.c_str());

  if(result.report_big_o) {
    std::string big_o = result.report_big_o ? GetBigO(result.complexity) : "";
    ColorPrintf(COLOR_YELLOW, "%10.4f %s %10.4f %s ",
                result.real_accumulated_time * multiplier,
                big_o.c_str(),
                result.cpu_accumulated_time * multiplier,
                big_o.c_str());
  }
  else if(result.report_rms) {
    ColorPrintf(COLOR_YELLOW, "%10.0f %% %10.0f %% ",
                result.real_accumulated_time * multiplier * 100,
                result.cpu_accumulated_time * multiplier * 100);
  }
  else if (result.iterations == 0) {
    ColorPrintf(COLOR_YELLOW, "%10.0f %s %10.0f %s ",
                result.real_accumulated_time * multiplier,
                timeLabel,
                result.cpu_accumulated_time * multiplier,
                timeLabel);
  } else {
    ColorPrintf(COLOR_YELLOW, "%10.0f %s %10.0f %s ",
                (result.real_accumulated_time * multiplier) /
                    (static_cast<double>(result.iterations)),
                timeLabel,
                (result.cpu_accumulated_time * multiplier) /
                    (static_cast<double>(result.iterations)),
                timeLabel);
  }

  if(!result.report_big_o && !result.report_rms)
    ColorPrintf(COLOR_CYAN, "%10lld", result.iterations);

  if (!rate.empty()) {
    ColorPrintf(COLOR_DEFAULT, " %*s", 13, rate.c_str());
  }

  if (!items.empty()) {
    ColorPrintf(COLOR_DEFAULT, " %*s", 18, items.c_str());
  }

  if (!result.report_label.empty()) {
    ColorPrintf(COLOR_DEFAULT, " %s", result.report_label.c_str());
  }

  ColorPrintf(COLOR_DEFAULT, "\n");
}

}  // end namespace benchmark
<|endoftext|>


<commit_before>/*ckwg +5
 * Copyright 2011 by Kitware, Inc. All Rights Reserved. Please refer to
 * KITWARE_LICENSE.TXT for licensing information, or contact General Counsel,
 * Kitware, Inc., 28 Corporate Drive, Clifton Park, NY 12065.
 */

#include <vistk/pipeline/schedule.h>
#include <vistk/pipeline/schedule_exception.h>

#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
#include <boost/python/class.hpp>
#include <boost/python/exception_translator.hpp>
#include <boost/python/module.hpp>
#include <boost/python/override.hpp>
#include <boost/python/pure_virtual.hpp>

/**
 * \file schedule.cxx
 *
 * \brief Python bindings for \link vistk::schedule\endlink.
 */

using namespace boost::python;

static void translator(vistk::schedule_exception const& e);

class wrap_schedule
  : public vistk::schedule
  , public wrapper<vistk::schedule>
{
  public:
    wrap_schedule(vistk::config_t const& config, vistk::pipeline_t const& pipe);
    ~wrap_schedule();

    void start();
    void wait();
    void stop();

    override get_pure_override(char const* name);
};

BOOST_PYTHON_MODULE(schedule)
{
  register_exception_translator<
    vistk::schedule_exception>(translator);

  class_<wrap_schedule, boost::noncopyable>("PythonSchedule"
    , "The base class for Python schedules."
    , no_init)
    .def(init<vistk::config_t, vistk::pipeline_t>())
    .def("start", pure_virtual(&vistk::schedule::start)
      , "Start the execution of the pipeline.")
    .def("wait", pure_virtual(&vistk::schedule::wait)
      , "Wait until the pipeline execution is complete.")
    .def("stop", pure_virtual(&vistk::schedule::stop)
      , "Stop the execution of the pipeline.")
  ;
}

void
translator(vistk::schedule_exception const& e)
{
  PyErr_SetString(PyExc_RuntimeError, e.what());
}

wrap_schedule
::wrap_schedule(vistk::config_t const& config, vistk::pipeline_t const& pipe)
  : vistk::schedule(config, pipe)
{
}

wrap_schedule
::~wrap_schedule()
{
}

void
wrap_schedule
::start()
{
  get_pure_override("start")();
}

void
wrap_schedule
::wait()
{
  get_pure_override("wait")();
}

void
wrap_schedule
::stop()
{
  get_pure_override("stop")();
}

override
wrap_schedule
::get_pure_override(char const* name)
{
  override const o = get_override(name);

  if (!o)
  {
    std::ostringstream sstr;
    sstr << name << " is not implemented";
    throw std::runtime_error(sstr.str().c_str());
  }

  return o;
}
<commit_msg>Add the pipeline method to schedules<commit_after>/*ckwg +5
 * Copyright 2011 by Kitware, Inc. All Rights Reserved. Please refer to
 * KITWARE_LICENSE.TXT for licensing information, or contact General Counsel,
 * Kitware, Inc., 28 Corporate Drive, Clifton Park, NY 12065.
 */

#include <vistk/pipeline/pipeline.h>
#include <vistk/pipeline/schedule.h>
#include <vistk/pipeline/schedule_exception.h>

#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
#include <boost/python/class.hpp>
#include <boost/python/exception_translator.hpp>
#include <boost/python/module.hpp>
#include <boost/python/override.hpp>
#include <boost/python/pure_virtual.hpp>

/**
 * \file schedule.cxx
 *
 * \brief Python bindings for \link vistk::schedule\endlink.
 */

using namespace boost::python;

static void translator(vistk::schedule_exception const& e);

class wrap_schedule
  : public vistk::schedule
  , public wrapper<vistk::schedule>
{
  public:
    wrap_schedule(vistk::config_t const& config, vistk::pipeline_t const& pipe);
    ~wrap_schedule();

    void start();
    void wait();
    void stop();

    vistk::pipeline_t _pipeline() const;

    override get_pure_override(char const* name);
};

BOOST_PYTHON_MODULE(schedule)
{
  register_exception_translator<
    vistk::schedule_exception>(translator);

  class_<wrap_schedule, boost::noncopyable>("PythonSchedule"
    , "The base class for Python schedules."
    , no_init)
    .def(init<vistk::config_t, vistk::pipeline_t>())
    .def("start", pure_virtual(&vistk::schedule::start)
      , "Start the execution of the pipeline.")
    .def("wait", pure_virtual(&vistk::schedule::wait)
      , "Wait until the pipeline execution is complete.")
    .def("stop", pure_virtual(&vistk::schedule::stop)
      , "Stop the execution of the pipeline.")
    .def("pipeline", &wrap_schedule::_pipeline
      , "The pipeline the schedule is to run.")
  ;
}

void
translator(vistk::schedule_exception const& e)
{
  PyErr_SetString(PyExc_RuntimeError, e.what());
}

wrap_schedule
::wrap_schedule(vistk::config_t const& config, vistk::pipeline_t const& pipe)
  : vistk::schedule(config, pipe)
{
}

wrap_schedule
::~wrap_schedule()
{
}

void
wrap_schedule
::start()
{
  get_pure_override("start")();
}

void
wrap_schedule
::wait()
{
  get_pure_override("wait")();
}

void
wrap_schedule
::stop()
{
  get_pure_override("stop")();
}

vistk::pipeline_t
wrap_schedule
::_pipeline() const
{
  return pipeline();
}

override
wrap_schedule
::get_pure_override(char const* name)
{
  override const o = get_override(name);

  if (!o)
  {
    std::ostringstream sstr;
    sstr << name << " is not implemented";
    throw std::runtime_error(sstr.str().c_str());
  }

  return o;
}
<|endoftext|>


<commit_before>/*      _______   __   __   __   ______   __   __   _______   __   __
 *     / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___  /\ /  |\/ /\
 *    / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
 *   / / /__   / / // / // / // / /    / ___  / // ___  / // /| ' / /
 *  / /_// /\ / /_// / // / // /_/_   / / // / // /\_/ / // / |  / /
 * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
 * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
 *
 * Copyright (c) 2004 darkbits                              Js_./
 * Per Larsson a.k.a finalman                          _RqZ{a<^_aa
 * Olof Naessn a.k.a jansem/yakslem                _asww7!uY`>  )\a//
 *                                                 _Qhm`] _f "'c  1!5m
 * Visit: http://guichan.darkbits.org             )Qk<P ` _: :+' .'  "{[
 *                                               .)j(] .d_/ '-(  P .   S
 * License: (BSD)                                <Td/Z <fP"5(\"??"\a.  .L
 * Redistribution and use in source and          _dV>ws?a-?'      ._/L  #'
 * binary forms, with or without                 )4d[#7r, .   '     )d`)[
 * modification, are permitted provided         _Q-5'5W..j/?'   -?!\)cam'
 * that the following conditions are met:       j<<WP+k/);.        _W=j f
 * 1. Redistributions of source code must       .$%w\/]Q  . ."'  .  mj$
 *    retain the above copyright notice,        ]E.pYY(Q]>.   a     J@\
 *    this list of conditions and the           j(]1u<sE"L,. .   ./^ ]{a
 *    following disclaimer.                     4'_uomm\.  )L);-4     (3=
 * 2. Redistributions in binary form must        )_]X{Z('a_"a7'<a"a,  ]"[
 *    reproduce the above copyright notice,       #}<]m7`Za??4,P-"'7. ).m
 *    this list of conditions and the            ]d2e)Q(<Q(  ?94   b-  LQ/
 *    following disclaimer in the                <B!</]C)d_, '(<' .f. =C+m
 *    documentation and/or other materials      .Z!=J ]e []('-4f _ ) -.)m]'
 *    provided with the distribution.          .w[5]' _[ /.)_-"+?   _/ <W"
 * 3. Neither the name of Guichan nor the      :$we` _! + _/ .        j?
 *    names of its contributors may be used     =3)= _f  (_yQmWW$#(    "
 *    to endorse or promote products derived     -   W,  sQQQQmZQ#Wwa]..
 *    from this software without specific        (js, \[QQW$QWW#?!V"".
 *    prior written permission.                    ]y:.<\..          .
 *                                                 -]n w/ '         [.
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT       )/ )/           !
 * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY         <  (; sac    ,    '
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING,               ]^ .-  %
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF            c <   r
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR            aga<  <La
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE          5%  )P'-3L
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR        _bQf` y`..)a
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,          ,J?4P'.P"_(\?d'.,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES               _Pa,)!f/<[]/  ?"
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT      _2-..:. .r+_,.. .
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,     ?a.<%"'  " -'.a_ _,
 * 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.
 */

/*
 * For comments regarding functions please see the header file.
 */

#include "guichan/graphics.hpp"
#include "guichan/exception.hpp"
#include "guichan/font.hpp"

namespace gcn
{

  Graphics::Graphics()
  {
    mFont = NULL;

  } // end graphics

  bool Graphics::pushClipArea(Rectangle area)
  {
    if (mClipStack.empty())
    {
      ClipRectangle carea;
      carea.x = area.x;
      carea.y = area.y;
      carea.width = area.width;
      carea.height = area.height;
      mClipStack.push(carea);
      return true;
    }

    ClipRectangle top = mClipStack.top();
    ClipRectangle carea;
    carea = area;
    carea.xOffset = top.xOffset + carea.x;
    carea.yOffset = top.yOffset + carea.y;
    carea.x += top.xOffset;
    carea.y += top.yOffset;

    bool result = carea.intersect(top);

    mClipStack.push(carea);

    return result;

  } // end pushClipArea

  void Graphics::popClipArea()
  {

    if (mClipStack.empty())
    {
      throw GCN_EXCEPTION("Graphics::popClipArea. Tried to pop clip area from empty stack.");
    }

    mClipStack.pop();

  } // end popClipArea

  void Graphics::drawImage(const Image* image, int dstX, int dstY)
  {
    drawImage(image, 0, 0, dstX, dstY, image->getWidth(), image->getHeight());

  } // end drawImage

  void Graphics::setFont(Font* font)
  {
    mFont = font;

  } // end setFont

  void Graphics::drawText(const std::string& text, int x, int y)
  {
    if (mFont == NULL)
    {
      throw GCN_EXCEPTION("Graphics::drawText. No font set.");
    }

    mFont->drawString(this, text, x, y);

  } // end drawText

	void Graphics::drawTextCenter(const std::string& text, int x, int y)
	{
		if (mFont == NULL)
		{
      throw GCN_EXCEPTION("Graphics::drawTextCenter. No font set.");
		}

		int width = mFont->getWidth(text);

		mFont->drawString(this, text, x - width / 2, y);
	}

	void Graphics::drawTextRight(const std::string& text, int x, int y)
	{
		if (mFont == NULL)
		{
      throw GCN_EXCEPTION("Graphics::drawTextRight. No font set.");
		}

		int width = mFont->getWidth(text);

		mFont->drawString(this, text, x - width, y);
	}

} // end gcn
<commit_msg>Added getColor and merged drawText, drawTextCenter and drawTextLeft into one function drawText which also takes an alignment parameter.<commit_after>/*      _______   __   __   __   ______   __   __   _______   __   __
 *     / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___  /\ /  |\/ /\
 *    / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
 *   / / /__   / / // / // / // / /    / ___  / // ___  / // /| ' / /
 *  / /_// /\ / /_// / // / // /_/_   / / // / // /\_/ / // / |  / /
 * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
 * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
 *
 * Copyright (c) 2004 darkbits                              Js_./
 * Per Larsson a.k.a finalman                          _RqZ{a<^_aa
 * Olof Naessn a.k.a jansem/yakslem                _asww7!uY`>  )\a//
 *                                                 _Qhm`] _f "'c  1!5m
 * Visit: http://guichan.darkbits.org             )Qk<P ` _: :+' .'  "{[
 *                                               .)j(] .d_/ '-(  P .   S
 * License: (BSD)                                <Td/Z <fP"5(\"??"\a.  .L
 * Redistribution and use in source and          _dV>ws?a-?'      ._/L  #'
 * binary forms, with or without                 )4d[#7r, .   '     )d`)[
 * modification, are permitted provided         _Q-5'5W..j/?'   -?!\)cam'
 * that the following conditions are met:       j<<WP+k/);.        _W=j f
 * 1. Redistributions of source code must       .$%w\/]Q  . ."'  .  mj$
 *    retain the above copyright notice,        ]E.pYY(Q]>.   a     J@\
 *    this list of conditions and the           j(]1u<sE"L,. .   ./^ ]{a
 *    following disclaimer.                     4'_uomm\.  )L);-4     (3=
 * 2. Redistributions in binary form must        )_]X{Z('a_"a7'<a"a,  ]"[
 *    reproduce the above copyright notice,       #}<]m7`Za??4,P-"'7. ).m
 *    this list of conditions and the            ]d2e)Q(<Q(  ?94   b-  LQ/
 *    following disclaimer in the                <B!</]C)d_, '(<' .f. =C+m
 *    documentation and/or other materials      .Z!=J ]e []('-4f _ ) -.)m]'
 *    provided with the distribution.          .w[5]' _[ /.)_-"+?   _/ <W"
 * 3. Neither the name of Guichan nor the      :$we` _! + _/ .        j?
 *    names of its contributors may be used     =3)= _f  (_yQmWW$#(    "
 *    to endorse or promote products derived     -   W,  sQQQQmZQ#Wwa]..
 *    from this software without specific        (js, \[QQW$QWW#?!V"".
 *    prior written permission.                    ]y:.<\..          .
 *                                                 -]n w/ '         [.
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT       )/ )/           !
 * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY         <  (; sac    ,    '
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING,               ]^ .-  %
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF            c <   r
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR            aga<  <La
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE          5%  )P'-3L
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR        _bQf` y`..)a
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,          ,J?4P'.P"_(\?d'.,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES               _Pa,)!f/<[]/  ?"
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT      _2-..:. .r+_,.. .
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,     ?a.<%"'  " -'.a_ _,
 * 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.
 */

/*
 * For comments regarding functions please see the header file.
 */

#include "guichan/graphics.hpp"
#include "guichan/exception.hpp"
#include "guichan/font.hpp"

namespace gcn
{

  Graphics::Graphics()
  {
    mFont = NULL;

  } // end graphics

  bool Graphics::pushClipArea(Rectangle area)
  {
    if (mClipStack.empty())
    {
      ClipRectangle carea;
      carea.x = area.x;
      carea.y = area.y;
      carea.width = area.width;
      carea.height = area.height;
      mClipStack.push(carea);
      return true;
    }

    ClipRectangle top = mClipStack.top();
    ClipRectangle carea;
    carea = area;
    carea.xOffset = top.xOffset + carea.x;
    carea.yOffset = top.yOffset + carea.y;
    carea.x += top.xOffset;
    carea.y += top.yOffset;

    bool result = carea.intersect(top);

    mClipStack.push(carea);

    return result;

  } // end pushClipArea

  void Graphics::popClipArea()
  {

    if (mClipStack.empty())
    {
      throw GCN_EXCEPTION("Graphics::popClipArea. Tried to pop clip area from empty stack.");
    }

    mClipStack.pop();

  } // end popClipArea

  void Graphics::drawImage(const Image* image, int dstX, int dstY)
  {
    drawImage(image, 0, 0, dstX, dstY, image->getWidth(), image->getHeight());

  } // end drawImage

  void Graphics::setFont(Font* font)
  {
    mFont = font;

  } // end setFont

  void Graphics::drawText(const std::string& text, int x, int y,
													unsigned int alignment)
  {
    if (mFont == NULL)
    {
      throw GCN_EXCEPTION("Graphics::drawText. No font set.");
    }

		switch (alignment)
		{
			case LEFT:
				mFont->drawString(this, text, x, y);
				break;
			case CENTER:
				mFont->drawString(this, text, x - mFont->getWidth(text) / 2, y);
				break;
			case RIGHT:
				mFont->drawString(this, text, x - mFont->getWidth(text), y);
				break;
			default:
				throw GCN_EXCEPTION("Graphics::drawText. Unknown alignment.");
		}

  } // end drawText

} // end gcn
<|endoftext|>


<commit_before>//
// Created by mistlight on 1/28/2017.
//

#include <src/core/tasks/PlayerScanTask.h>
#include <QDebug>
#include <include/vlc/vlc.h>
#include <src/simple-lib/ThreadPool.h>
#include <QThread>
#include "ScanPlayer.h"

Core::ScanPlayer::ScanPlayer() {
    /* Load the VLC engine */
    this->inst = libvlc_new(0, NULL);
    if(this->inst == NULL) {
        qWarning() << "ERROR";
        throw "Exception has occured, cannot init vlc engine from Scanning";
    }

    this->mediaPlayer = libvlc_media_player_new(this->inst);
    if(this->mediaPlayer == NULL) {
        qWarning() << "ERROR: Could not create media player in Scanning";
    }

    this->threadPool = std::unique_ptr<ThreadPool>(new ThreadPool(1));
    this->hasScanFinished = true;
}

void Core::ScanPlayer::addAudiobook(std::shared_ptr<AudiobookProxy> audiobook) {
    qDebug() << "Scan audiobook called";
    auto fileList = audiobook->getFilesForAudiobook();
    this->mutex.lock();
    for(int i = 0; i < fileList.size(); i++) {
        this->fileQueue.push(fileList[i]);
    }
    this->mutex.unlock();

    this->startScanTask(audiobook);
}

void Core::ScanPlayer::addAudiobookFile(std::shared_ptr<AudiobookFileProxy> file) {
    // don't need to call this function on already scanned items
    if(file->getMediaDuration() > 0) {
        return;
    }

    this->mutex.lock();
    this->fileQueue.push(file);
    this->mutex.unlock();

    this->startScanTask(nullptr);
}

void Core::ScanPlayer::startScanTask(std::shared_ptr<AudiobookProxy> audiobook) {
    auto scanTask = new PlayerScanTask(this, audiobook);
    this->scanThread.start(scanTask);
}

void Core::ScanPlayer::performScan() {
    this->mutex.lock();

    qDebug() << "Scan task started";

    while(!this->fileQueue.empty()) {
        this->hasScanFinished = false;
        std::shared_ptr<AudiobookFileProxy> & element = this->fileQueue.front();
        this->currentlyScanning = element;
        qDebug() << "Currently scanning file: " << element->path();

        auto path =  element->path();
        auto currentFile = std::unique_ptr<QFile>(new QFile(path));

        if(!currentFile->open(QIODevice::ReadWrite)) {
            qDebug() << "QFILE FAILED!: " << path;
            return;
        }

        this->mediaItem = libvlc_media_new_fd(this->inst, currentFile->handle());
        if(this->mediaItem == NULL) {
            return;
        }

        libvlc_media_player_set_media(this->mediaPlayer, this->mediaItem);
        libvlc_media_player_play(this->mediaPlayer);

        libvlc_event_manager_t* eventManager = libvlc_media_event_manager(this->mediaItem);

        libvlc_event_attach(eventManager,
                            libvlc_MediaParsedChanged,
                            (libvlc_callback_t) [](const struct libvlc_event_t * event, void *data) {
                                auto player = reinterpret_cast<ScanPlayer*>(data);
                                int parsedStatus = libvlc_media_is_parsed(player->mediaItem);

                                if(parsedStatus) {
                                    player->threadPool->enqueue([player]() {
                                        long long duration = libvlc_media_get_duration(player->mediaItem);
                                        if(duration > 0) {
                                            player->currentlyScanning->setMediaDuration(duration);
                                            qDebug() << "performScan() SUCCESS: " << player->currentlyScanning->path();
                                        } else {
                                            qWarning() << "performScan() failed for: " << player->currentlyScanning->path();
                                        }

                                        player->hasScanFinished = true;
                                    });
                                }
                            },
                            this);

        while(!hasScanFinished) {
            QThread::msleep(10);
        }

        libvlc_media_player_stop(this->mediaPlayer);

        this->fileQueue.pop();
    }

    this->mutex.unlock();
    qDebug() << "Scan task ended";

}

void Core::ScanPlayer::retrieveScanResults() {

}

<commit_msg>remove debugging messages<commit_after>//
// Created by mistlight on 1/28/2017.
//

#include <src/core/tasks/PlayerScanTask.h>
#include <QDebug>
#include <include/vlc/vlc.h>
#include <src/simple-lib/ThreadPool.h>
#include <QThread>
#include "ScanPlayer.h"

Core::ScanPlayer::ScanPlayer() {
    /* Load the VLC engine */
    this->inst = libvlc_new(0, NULL);
    if(this->inst == NULL) {
        qWarning() << "ERROR";
        throw "Exception has occured, cannot init vlc engine from Scanning";
    }

    this->mediaPlayer = libvlc_media_player_new(this->inst);
    if(this->mediaPlayer == NULL) {
        qWarning() << "ERROR: Could not create media player in Scanning";
    }

    this->threadPool = std::unique_ptr<ThreadPool>(new ThreadPool(1));
    this->hasScanFinished = true;
}

void Core::ScanPlayer::addAudiobook(std::shared_ptr<AudiobookProxy> audiobook) {
    auto fileList = audiobook->getFilesForAudiobook();
    this->mutex.lock();
    for(int i = 0; i < fileList.size(); i++) {
        this->fileQueue.push(fileList[i]);
    }
    this->mutex.unlock();

    this->startScanTask(audiobook);
}

void Core::ScanPlayer::addAudiobookFile(std::shared_ptr<AudiobookFileProxy> file) {
    // don't need to call this function on already scanned items
    if(file->getMediaDuration() > 0) {
        return;
    }

    this->mutex.lock();
    this->fileQueue.push(file);
    this->mutex.unlock();

    this->startScanTask(nullptr);
}

void Core::ScanPlayer::startScanTask(std::shared_ptr<AudiobookProxy> audiobook) {
    auto scanTask = new PlayerScanTask(this, audiobook);
    this->scanThread.start(scanTask);
}

void Core::ScanPlayer::performScan() {
    this->mutex.lock();

    qDebug() << "Scan task started";
    while(!this->fileQueue.empty()) {
        this->hasScanFinished = false;
        std::shared_ptr<AudiobookFileProxy> & element = this->fileQueue.front();
        this->currentlyScanning = element;

        auto path =  element->path();
        auto currentFile = std::unique_ptr<QFile>(new QFile(path));

        if(!currentFile->open(QIODevice::ReadWrite)) {
            qDebug() << "QFILE FAILED!: " << path;
            return;
        }

        this->mediaItem = libvlc_media_new_fd(this->inst, currentFile->handle());
        if(this->mediaItem == NULL) {
            return;
        }

        libvlc_media_player_set_media(this->mediaPlayer, this->mediaItem);
        libvlc_media_player_play(this->mediaPlayer);

        libvlc_event_manager_t* eventManager = libvlc_media_event_manager(this->mediaItem);

        libvlc_event_attach(eventManager,
                            libvlc_MediaParsedChanged,
                            (libvlc_callback_t) [](const struct libvlc_event_t * event, void *data) {
                                auto player = reinterpret_cast<ScanPlayer*>(data);
                                int parsedStatus = libvlc_media_is_parsed(player->mediaItem);

                                if(parsedStatus) {
                                    player->threadPool->enqueue([player]() {
                                        long long duration = libvlc_media_get_duration(player->mediaItem);
                                        if(duration > 0) {
                                            player->currentlyScanning->setMediaDuration(duration);
                                        } else {
                                            qWarning() << "performScan() failed for: " << player->currentlyScanning->path();
                                        }

                                        player->hasScanFinished = true;
                                    });
                                }
                            },
                            this);

        while(!hasScanFinished) {
            QThread::msleep(10);
        }

        libvlc_media_player_stop(this->mediaPlayer);

        this->fileQueue.pop();
    }

    this->mutex.unlock();
    qDebug() << "Scan task ended";

}

void Core::ScanPlayer::retrieveScanResults() {

}

<|endoftext|>


<commit_before>/*
  This file is part of Ingen.
  Copyright 2007-2015 David Robillard <http://drobilla.net/>

  Ingen is free software: you can redistribute it and/or modify it under the
  terms of the GNU Affero General Public License as published by the Free
  Software Foundation, either version 3 of the License, or any later version.

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

  You should have received a copy of the GNU Affero General Public License
  along with Ingen.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "ingen/Forge.hpp"
#include "ingen/Log.hpp"
#include "ingen/Properties.hpp"
#include "ingen/URIs.hpp"
#include "ingen/World.hpp"
#include "ingen/client/ObjectModel.hpp"
#include "lilv/lilv.h"

#include "RDFS.hpp"

#include <utility>

namespace ingen {
namespace gui {
namespace rdfs {

std::string
label(World& world, const LilvNode* node)
{
	LilvNode* rdfs_label = lilv_new_uri(
		world.lilv_world(), LILV_NS_RDFS "label");
	LilvNodes* labels = lilv_world_find_nodes(
		world.lilv_world(), node, rdfs_label, nullptr);

	const LilvNode* first = lilv_nodes_get_first(labels);
	std::string     label = first ? lilv_node_as_string(first) : "";

	lilv_nodes_free(labels);
	lilv_node_free(rdfs_label);
	return label;
}

std::string
comment(World& world, const LilvNode* node)
{
	LilvNode* rdfs_comment = lilv_new_uri(
		world.lilv_world(), LILV_NS_RDFS "comment");
	LilvNodes* comments = lilv_world_find_nodes(
		world.lilv_world(), node, rdfs_comment, nullptr);

	const LilvNode* first   = lilv_nodes_get_first(comments);
	std::string     comment = first ? lilv_node_as_string(first) : "";

	lilv_nodes_free(comments);
	lilv_node_free(rdfs_comment);
	return comment;
}

static void
closure(World& world, const LilvNode* pred, URISet& types, bool super)
{
	unsigned added = 0;
	do {
		added = 0;
		URISet klasses;
		for (const auto& t : types) {
			LilvNode*  type    = lilv_new_uri(world.lilv_world(), t.c_str());
			LilvNodes* matches = (super)
				? lilv_world_find_nodes(
					world.lilv_world(), type, pred, nullptr)
				: lilv_world_find_nodes(
					world.lilv_world(), nullptr, pred, type);
			LILV_FOREACH(nodes, m, matches) {
				const LilvNode* klass_node = lilv_nodes_get(matches, m);
				if (lilv_node_is_uri(klass_node)) {
					URI klass(lilv_node_as_uri(klass_node));
					if (!types.count(klass)) {
						++added;
						klasses.insert(klass);
					}
				}
			}
			lilv_nodes_free(matches);
			lilv_node_free(type);
		}
		types.insert(klasses.begin(), klasses.end());
	} while (added > 0);
}

void
classes(World& world, URISet& types, bool super)
{
	LilvNode* rdfs_subClassOf = lilv_new_uri(
		world.lilv_world(), LILV_NS_RDFS "subClassOf");

	closure(world, rdfs_subClassOf, types, super);

	lilv_node_free(rdfs_subClassOf);
}

void
datatypes(World& world, URISet& types, bool super)
{
	LilvNode* owl_onDatatype = lilv_new_uri(
		world.lilv_world(), LILV_NS_OWL "onDatatype");

	closure(world, owl_onDatatype, types, super);

	lilv_node_free(owl_onDatatype);
}

URISet
types(World& world, const std::shared_ptr<const client::ObjectModel>& model)
{
	using PropIter  = Properties::const_iterator;
	using PropRange = std::pair<PropIter, PropIter>;

	// Start with every rdf:type
	URISet types;
	types.insert(URI(LILV_NS_RDFS "Resource"));
	PropRange range = model->properties().equal_range(world.uris().rdf_type);
	for (auto t = range.first; t != range.second; ++t) {
		if (t->second.type() == world.forge().URI ||
		    t->second.type() == world.forge().URID) {
			const URI type(world.forge().str(t->second, false));
			types.insert(type);
			if (world.uris().ingen_Graph == type) {
				// Add lv2:Plugin as a type for graphs so plugin properties show up
				types.insert(world.uris().lv2_Plugin);
			}
		} else {
			world.log().error("<%1%> has non-URI type\n", model->uri());
		}
	}

	// Add every superclass of every type, recursively
	rdfs::classes(world, types, true);

	return types;
}

URISet
properties(World&                                            world,
           const std::shared_ptr<const client::ObjectModel>& model)
{
	URISet properties;
	URISet types = rdfs::types(world, model);

	LilvNode* rdf_type = lilv_new_uri(world.lilv_world(),
	                                  LILV_NS_RDF "type");
	LilvNode* rdf_Property = lilv_new_uri(world.lilv_world(),
	                                      LILV_NS_RDF "Property");
	LilvNode* rdfs_domain = lilv_new_uri(world.lilv_world(),
	                                     LILV_NS_RDFS "domain");

	LilvNodes* props = lilv_world_find_nodes(
		world.lilv_world(), nullptr, rdf_type, rdf_Property);
	LILV_FOREACH(nodes, p, props) {
		const LilvNode* prop = lilv_nodes_get(props, p);
		if (lilv_node_is_uri(prop)) {
			LilvNodes* domains = lilv_world_find_nodes(
				world.lilv_world(), prop, rdfs_domain, nullptr);
			unsigned n_matching_domains = 0;
			LILV_FOREACH(nodes, d, domains) {
				const LilvNode* domain_node = lilv_nodes_get(domains, d);
				if (!lilv_node_is_uri(domain_node)) {
					// TODO: Blank node domains (e.g. unions)
					continue;
				}

				const URI domain(lilv_node_as_uri(domain_node));
				if (types.count(domain)) {
					++n_matching_domains;
				}
			}

			if (lilv_nodes_size(domains) == 0 || (
				    n_matching_domains > 0 &&
				    n_matching_domains == lilv_nodes_size(domains))) {
				properties.insert(URI(lilv_node_as_uri(prop)));
			}

			lilv_nodes_free(domains);
		}
	}

	lilv_node_free(rdfs_domain);
	lilv_node_free(rdf_Property);
	lilv_node_free(rdf_type);

	return properties;
}

Objects
instances(World& world, const URISet& types)
{
	LilvNode* rdf_type = lilv_new_uri(
		world.lilv_world(), LILV_NS_RDF "type");

	Objects result;
	for (const auto& t : types) {
		LilvNode*  type    = lilv_new_uri(world.lilv_world(), t.c_str());
		LilvNodes* objects = lilv_world_find_nodes(
			world.lilv_world(), nullptr, rdf_type, type);
		LILV_FOREACH(nodes, o, objects) {
			const LilvNode* object = lilv_nodes_get(objects, o);
			if (!lilv_node_is_uri(object)) {
				continue;
			}
			const std::string label = rdfs::label(world, object);
			result.emplace(label, URI(lilv_node_as_string(object)));
		}
		lilv_node_free(type);
	}

	lilv_node_free(rdf_type);
	return result;
}

URISet
range(World& world, const LilvNode* prop, bool recursive)
{
	LilvNode* rdfs_range = lilv_new_uri(
		world.lilv_world(), LILV_NS_RDFS "range");

	LilvNodes* nodes = lilv_world_find_nodes(
		world.lilv_world(), prop, rdfs_range, nullptr);

	URISet ranges;
	LILV_FOREACH(nodes, n, nodes) {
		ranges.insert(URI(lilv_node_as_string(lilv_nodes_get(nodes, n))));
	}

	if (recursive) {
		rdfs::classes(world, ranges, false);
	}

	lilv_nodes_free(nodes);
	lilv_node_free(rdfs_range);
	return ranges;
}

bool
is_a(World& world, const LilvNode* inst, const LilvNode* klass)
{
	LilvNode* rdf_type = lilv_new_uri(world.lilv_world(), LILV_NS_RDF "type");

	const bool is_instance = lilv_world_ask(
		world.lilv_world(), inst, rdf_type, klass);

	lilv_node_free(rdf_type);
	return is_instance;
}

} // namespace rdfs
} // namespace gui
} // namespace ingen
<commit_msg>Fix invalid URI mapping when a property range is a blank node<commit_after>/*
  This file is part of Ingen.
  Copyright 2007-2015 David Robillard <http://drobilla.net/>

  Ingen is free software: you can redistribute it and/or modify it under the
  terms of the GNU Affero General Public License as published by the Free
  Software Foundation, either version 3 of the License, or any later version.

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

  You should have received a copy of the GNU Affero General Public License
  along with Ingen.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "ingen/Forge.hpp"
#include "ingen/Log.hpp"
#include "ingen/Properties.hpp"
#include "ingen/URIs.hpp"
#include "ingen/World.hpp"
#include "ingen/client/ObjectModel.hpp"
#include "lilv/lilv.h"

#include "RDFS.hpp"

#include <utility>

namespace ingen {
namespace gui {
namespace rdfs {

std::string
label(World& world, const LilvNode* node)
{
	LilvNode* rdfs_label = lilv_new_uri(
		world.lilv_world(), LILV_NS_RDFS "label");
	LilvNodes* labels = lilv_world_find_nodes(
		world.lilv_world(), node, rdfs_label, nullptr);

	const LilvNode* first = lilv_nodes_get_first(labels);
	std::string     label = first ? lilv_node_as_string(first) : "";

	lilv_nodes_free(labels);
	lilv_node_free(rdfs_label);
	return label;
}

std::string
comment(World& world, const LilvNode* node)
{
	LilvNode* rdfs_comment = lilv_new_uri(
		world.lilv_world(), LILV_NS_RDFS "comment");
	LilvNodes* comments = lilv_world_find_nodes(
		world.lilv_world(), node, rdfs_comment, nullptr);

	const LilvNode* first   = lilv_nodes_get_first(comments);
	std::string     comment = first ? lilv_node_as_string(first) : "";

	lilv_nodes_free(comments);
	lilv_node_free(rdfs_comment);
	return comment;
}

static void
closure(World& world, const LilvNode* pred, URISet& types, bool super)
{
	unsigned added = 0;
	do {
		added = 0;
		URISet klasses;
		for (const auto& t : types) {
			LilvNode*  type    = lilv_new_uri(world.lilv_world(), t.c_str());
			LilvNodes* matches = (super)
				? lilv_world_find_nodes(
					world.lilv_world(), type, pred, nullptr)
				: lilv_world_find_nodes(
					world.lilv_world(), nullptr, pred, type);
			LILV_FOREACH(nodes, m, matches) {
				const LilvNode* klass_node = lilv_nodes_get(matches, m);
				if (lilv_node_is_uri(klass_node)) {
					URI klass(lilv_node_as_uri(klass_node));
					if (!types.count(klass)) {
						++added;
						klasses.insert(klass);
					}
				}
			}
			lilv_nodes_free(matches);
			lilv_node_free(type);
		}
		types.insert(klasses.begin(), klasses.end());
	} while (added > 0);
}

void
classes(World& world, URISet& types, bool super)
{
	LilvNode* rdfs_subClassOf = lilv_new_uri(
		world.lilv_world(), LILV_NS_RDFS "subClassOf");

	closure(world, rdfs_subClassOf, types, super);

	lilv_node_free(rdfs_subClassOf);
}

void
datatypes(World& world, URISet& types, bool super)
{
	LilvNode* owl_onDatatype = lilv_new_uri(
		world.lilv_world(), LILV_NS_OWL "onDatatype");

	closure(world, owl_onDatatype, types, super);

	lilv_node_free(owl_onDatatype);
}

URISet
types(World& world, const std::shared_ptr<const client::ObjectModel>& model)
{
	using PropIter  = Properties::const_iterator;
	using PropRange = std::pair<PropIter, PropIter>;

	// Start with every rdf:type
	URISet types;
	types.insert(URI(LILV_NS_RDFS "Resource"));
	PropRange range = model->properties().equal_range(world.uris().rdf_type);
	for (auto t = range.first; t != range.second; ++t) {
		if (t->second.type() == world.forge().URI ||
		    t->second.type() == world.forge().URID) {
			const URI type(world.forge().str(t->second, false));
			types.insert(type);
			if (world.uris().ingen_Graph == type) {
				// Add lv2:Plugin as a type for graphs so plugin properties show up
				types.insert(world.uris().lv2_Plugin);
			}
		} else {
			world.log().error("<%1%> has non-URI type\n", model->uri());
		}
	}

	// Add every superclass of every type, recursively
	rdfs::classes(world, types, true);

	return types;
}

URISet
properties(World&                                            world,
           const std::shared_ptr<const client::ObjectModel>& model)
{
	URISet properties;
	URISet types = rdfs::types(world, model);

	LilvNode* rdf_type = lilv_new_uri(world.lilv_world(),
	                                  LILV_NS_RDF "type");
	LilvNode* rdf_Property = lilv_new_uri(world.lilv_world(),
	                                      LILV_NS_RDF "Property");
	LilvNode* rdfs_domain = lilv_new_uri(world.lilv_world(),
	                                     LILV_NS_RDFS "domain");

	LilvNodes* props = lilv_world_find_nodes(
		world.lilv_world(), nullptr, rdf_type, rdf_Property);
	LILV_FOREACH(nodes, p, props) {
		const LilvNode* prop = lilv_nodes_get(props, p);
		if (lilv_node_is_uri(prop)) {
			LilvNodes* domains = lilv_world_find_nodes(
				world.lilv_world(), prop, rdfs_domain, nullptr);
			unsigned n_matching_domains = 0;
			LILV_FOREACH(nodes, d, domains) {
				const LilvNode* domain_node = lilv_nodes_get(domains, d);
				if (!lilv_node_is_uri(domain_node)) {
					// TODO: Blank node domains (e.g. unions)
					continue;
				}

				const URI domain(lilv_node_as_uri(domain_node));
				if (types.count(domain)) {
					++n_matching_domains;
				}
			}

			if (lilv_nodes_size(domains) == 0 || (
				    n_matching_domains > 0 &&
				    n_matching_domains == lilv_nodes_size(domains))) {
				properties.insert(URI(lilv_node_as_uri(prop)));
			}

			lilv_nodes_free(domains);
		}
	}

	lilv_node_free(rdfs_domain);
	lilv_node_free(rdf_Property);
	lilv_node_free(rdf_type);

	return properties;
}

Objects
instances(World& world, const URISet& types)
{
	LilvNode* rdf_type = lilv_new_uri(
		world.lilv_world(), LILV_NS_RDF "type");

	Objects result;
	for (const auto& t : types) {
		LilvNode*  type    = lilv_new_uri(world.lilv_world(), t.c_str());
		LilvNodes* objects = lilv_world_find_nodes(
			world.lilv_world(), nullptr, rdf_type, type);
		LILV_FOREACH(nodes, o, objects) {
			const LilvNode* object = lilv_nodes_get(objects, o);
			if (!lilv_node_is_uri(object)) {
				continue;
			}
			const std::string label = rdfs::label(world, object);
			result.emplace(label, URI(lilv_node_as_string(object)));
		}
		lilv_node_free(type);
	}

	lilv_node_free(rdf_type);
	return result;
}

URISet
range(World& world, const LilvNode* prop, bool recursive)
{
	LilvNode* rdfs_range = lilv_new_uri(
		world.lilv_world(), LILV_NS_RDFS "range");

	LilvNodes* nodes = lilv_world_find_nodes(
		world.lilv_world(), prop, rdfs_range, nullptr);

	URISet ranges;
	LILV_FOREACH(nodes, n, nodes) {
		if (lilv_node_is_uri(lilv_nodes_get(nodes, n))) {
			ranges.insert(URI(lilv_node_as_string(lilv_nodes_get(nodes, n))));
		}
	}

	if (recursive) {
		rdfs::classes(world, ranges, false);
	}

	lilv_nodes_free(nodes);
	lilv_node_free(rdfs_range);
	return ranges;
}

bool
is_a(World& world, const LilvNode* inst, const LilvNode* klass)
{
	LilvNode* rdf_type = lilv_new_uri(world.lilv_world(), LILV_NS_RDF "type");

	const bool is_instance = lilv_world_ask(
		world.lilv_world(), inst, rdf_type, klass);

	lilv_node_free(rdf_type);
	return is_instance;
}

} // namespace rdfs
} // namespace gui
} // namespace ingen
<|endoftext|>


<commit_before>#include "histogram.h"
#include <algorithm>
#include <limits>
#include <cstdlib>
#include <cmath>
#include <iostream>

#include <glog/logging.h>

Histogram::Histogram(unsigned int num_bins):
  max_num_bins_(num_bins),
  dirty_(true),
  cumsums_(num_bins+1) { };

void Histogram::Update(double x, double y) {
  BinVal val;
  val.m = 1;
  val.y = y;
  Bin bin;
  bin.p = x;
  bin.val = val;
  HistogramTypeIter insert_location = std::lower_bound(bins_.begin(), bins_.end(), bin);
  if (insert_location != bins_.end() && insert_location->p == x) {
    insert_location->val.m += 1;
    insert_location->val.y += y;
  }
  else {
    bins_.insert(insert_location, bin);
    Trim();
  }
  dirty_ = true;
  CHECK(bins_.size() > 0) << "Bin size is 0 after Update";
};

void Histogram::Merge(const Histogram& other) {
  for (unsigned int i = 0; i < other.bins_.size(); ++i) {
    bins_.push_back(other.bins_[i]);
  }
  std::sort(bins_.begin(), bins_.end());
  Trim();
  dirty_ = true;
};

// Compute the additional offset to be added to the accumulated sum
double trapezoid_estimate(double s, double p1, double p2, double v1, double v2) {
  // Bottom base w.r.t trepezoid truncated at s
  // TODO: Remove max() if not handling boundary cases here
  double vs = v1 + (v2 - v1) * std::max((s - p1), 0.0) / (p2 - p1);
  double as = (v1 + vs) * std::max((s - p1), 0.0) / 2;
  double a2 = (v1 + v2) * (p2 - p1) / 2;
  double R = (v1 + v2) / 2;
  //LOG(INFO) << "as : a2: -->" << as << " vs " <<a2;
  double res = (as / a2) * R;
  return res;
};

Histogram::BinVal Histogram::Interpolate(double x) const {
  // TODO: assert the x in between p_min and p_max
  // TODO: For completeness sake, need to handle -ve and +ve infinity, as it2
  // below might hit the boundaries
  Bin bin;
  bin.p = x;
  HistogramTypeConstIter it2 = std::upper_bound(bins_.begin(), bins_.end(), bin);
  HistogramTypeConstIter it1 = it2 - 1;
  //LOG(INFO) << "it2 index: " << it2 - bins_.begin() << "; is end: " << (it2 == bins_.end())?1:0;
  //LOG(INFO) << "bins_ max: " << it2 - bins_.begin();
  double m_summed = 0.0;
  double y_summed = 0.0;
  /*
  for (HistogramTypeConstIter it = bins_.begin(); it != it2; ++it) {
    if (it != it1) {
      m_summed += it->val.m;
      y_summed += it->val.y;
    }
    else{
      m_summed += it->val.m / 2.0;
      y_summed += it->val.y / 2.0;
    }
  }
  */
  PrecomputeCumsums();
  if (it2 != bins_.begin()) {
    unsigned int index_upto = it2 - bins_.begin() - 1;
    m_summed = cumsums_[index_upto].m;
    y_summed = cumsums_[index_upto].y;
  }

  double m_offset, y_offset;
  // Take care of two critical bin locations: first and last
  if (it2 == bins_.begin()) {
    //LOG(INFO) << "Handling special case of neg_inf!";
    double p_neg_inf = bins_[0].p - (bins_[1].p - bins_[0].p);
    //LOG(INFO) << "p_0: " << it2->p << " m_0: " << it2->val.m;
    if (x < p_neg_inf) {
      m_offset = 0;
      y_offset = 0;
    }
    else {
      m_offset = trapezoid_estimate(x, p_neg_inf, it2->p, 0.0, it2->val.m);
      y_offset = trapezoid_estimate(x, p_neg_inf, it2->p, 0.0, it2->val.y);
    }
    //LOG(INFO) << "p_neg_inf: " << p_neg_inf << " offsets: " << m_offset << " " << y_offset;
  }
  else if (it2 == bins_.end()) {
    //LOG(INFO) << "Handling special case of pos_inf!";
    double p_pos_inf = bins_[bins_.size()-1].p + (bins_[bins_.size()-1].p -
        bins_[bins_.size()-2].p);
    if (x > p_pos_inf) {
      m_offset = it2->val.m / 2;
      y_offset = it2->val.y / 2;
    }
    else{
      m_offset = trapezoid_estimate(x, it2->p, p_pos_inf, it1->val.m, 0.0);
      y_offset = trapezoid_estimate(x, it2->p, p_pos_inf, it1->val.y, 0.0);
    }
    //LOG(INFO) << "p_pos_inf: " << p_pos_inf << " offsets: " << m_offset << " " << y_offset;
  }
  else {
    m_offset = trapezoid_estimate(x, it1->p, it2->p, it1->val.m, it2->val.m);
    y_offset = trapezoid_estimate(x, it1->p, it2->p, it1->val.y, it2->val.y);
  }

  BinVal val;
  val.m = m_summed + m_offset;
  val.y = y_summed + y_offset;
  return val;
};

Histogram::BinVal Histogram::InterpolateInf() const {
  /*
  double m_summed = 0.0;
  double y_summed = 0.0;
  for (HistogramTypeConstIter it = bins_.begin(); it != bins_.end(); ++it) {
    m_summed += it->val.m;
    y_summed += it->val.y;
  }
  BinVal val;
  val.m = m_summed;
  val.y = y_summed;
  return val;
  */
  PrecomputeCumsums();
  const BinVal& binval = cumsums_[bins_.size()];
  return binval;
};

void Histogram::Trim() {
  while (bins_.size() > max_num_bins_) {
    // TODO: Handle ties in minimum distance
    double min_dist = std::numeric_limits<double>::max();
    unsigned int combine_location = 0;
    for (unsigned int i = 0; i < bins_.size() - 1; ++i) {
      double dist = std::fabs(bins_[i].p - bins_[i+1].p);
      if (dist < min_dist) {
        min_dist = dist;
        combine_location = i;
      }
    }
    //std::cout << "combine_location: " << combine_location << std::endl;
    //std::cout << "min_dist: " << min_dist << std::endl;
    int i = combine_location;
    int j = combine_location + 1;
    bins_[i].p = ((bins_[i].p * bins_[i].val.m) +
                  (bins_[j].p * bins_[j].val.m)) /
                 (bins_[i].val.m + bins_[j].val.m);
    bins_[i].val.m += bins_[j].val.m;
    bins_[i].val.y += bins_[j].val.y;
    bins_.erase(bins_.begin() + j);
  }
};

// Implements Algorithm 4 in Ben-Haim-10 paper
std::vector<double> Histogram::Uniform(int N) const {
  // N corresponds to tilde B in the paper
  CHECK(N >= 1) << "Histogram's Uniform routine requires N >= 1";
  //CHECK(bins_.size() >= 2) << "Histogrom does not have enough bins";
  std::vector<double> results;
  double sum_m = 0.0;
  for (unsigned int i = 0; i < bins_.size(); ++i) {
    sum_m += bins_[i].val.m;
  }
  std::vector<double> cumsums(bins_.size(), 0.0);
  for (unsigned int i = 0; i < bins_.size(); ++i) {
    // Special case of Sum / Interpolate where the target x is always at the
    // center of a bin -- can be computed inplace directly
    if (i == 0) {
      cumsums[i] = bins_[i].val.m / 2.0;
    }
    else {
      cumsums[i] = cumsums[i-1]
                   + bins_[i-1].val.m / 2.0
                   + bins_[i].val.m / 2.0;
    }
  }
  for (int j = 1; j <= N - 1; ++j) {
    double s = ((double)j / N) * sum_m;
    // This is (i+1) -- the first element that is larger than s
    std::vector<double>::iterator it = std::upper_bound(cumsums.begin(),
                                                        cumsums.end(), s);

    if (it == cumsums.begin()) {
      continue;
    }

    unsigned int i = it - cumsums.begin() - 1;
    double d = s - cumsums[i];
    double a = bins_[i+1].val.m - bins_[i].val.m;
    double z;
    if (std::fabs(a) > 10e-8) {
      double b = 2.0 * bins_[i].val.m;
      double c = -2.0 * d;
      z = (- b + sqrt(b*b - 4*a*c)) / (2*a);
    }
    else {
      z = d / bins_[i].val.m;
    }
    double uj = bins_[i].p + (bins_[i+1].p - bins_[i].p)*z;
    results.push_back(uj);
  }

  return results;
};

void Histogram::PrecomputeCumsums() const {
  // Pre-compute the cummulative sums
  // cumsums_[i] means summations up to 1//2 of the i-th bin.

  // Only recompute when necessary
  if (!dirty_) {
    return;
  }

  for (unsigned int i = 0; i < bins_.size(); ++i) {
    if (i == 0) {
      cumsums_[i].m = bins_[i].val.m / 2.0;
      cumsums_[i].y = bins_[i].val.y / 2.0;
    }
    else {
      cumsums_[i].m = cumsums_[i-1].m
                      + bins_[i-1].val.m / 2.0
                      + bins_[i].val.m / 2.0;

      cumsums_[i].y = cumsums_[i-1].y
                      + bins_[i-1].val.y / 2.0
                      + bins_[i].val.y / 2.0;
    }
  }
  // Sums at +ve infinity (i.e. sum up all)
  unsigned int index_inf = bins_.size();
  cumsums_[index_inf].m = cumsums_[index_inf-1].m + bins_.back().val.m/2.0;
  cumsums_[index_inf].y = cumsums_[index_inf-1].y + bins_.back().val.y/2.0;
  dirty_ = false;
};
<commit_msg>Use caching in Uniform procedure<commit_after>#include "histogram.h"
#include <algorithm>
#include <limits>
#include <cstdlib>
#include <cmath>
#include <iostream>

#include <glog/logging.h>

Histogram::Histogram(unsigned int num_bins):
  max_num_bins_(num_bins),
  dirty_(true),
  cumsums_(num_bins+1) { };

void Histogram::Update(double x, double y) {
  BinVal val;
  val.m = 1;
  val.y = y;
  Bin bin;
  bin.p = x;
  bin.val = val;
  HistogramTypeIter insert_location = std::lower_bound(bins_.begin(), bins_.end(), bin);
  if (insert_location != bins_.end() && insert_location->p == x) {
    insert_location->val.m += 1;
    insert_location->val.y += y;
  }
  else {
    bins_.insert(insert_location, bin);
    Trim();
  }
  dirty_ = true;
  CHECK(bins_.size() > 0) << "Bin size is 0 after Update";
};

void Histogram::Merge(const Histogram& other) {
  for (unsigned int i = 0; i < other.bins_.size(); ++i) {
    bins_.push_back(other.bins_[i]);
  }
  std::sort(bins_.begin(), bins_.end());
  Trim();
  dirty_ = true;
};

// Compute the additional offset to be added to the accumulated sum
double trapezoid_estimate(double s, double p1, double p2, double v1, double v2) {
  // Bottom base w.r.t trepezoid truncated at s
  // TODO: Remove max() if not handling boundary cases here
  double vs = v1 + (v2 - v1) * std::max((s - p1), 0.0) / (p2 - p1);
  double as = (v1 + vs) * std::max((s - p1), 0.0) / 2;
  double a2 = (v1 + v2) * (p2 - p1) / 2;
  double R = (v1 + v2) / 2;
  //LOG(INFO) << "as : a2: -->" << as << " vs " <<a2;
  double res = (as / a2) * R;
  return res;
};

Histogram::BinVal Histogram::Interpolate(double x) const {
  // TODO: assert the x in between p_min and p_max
  // TODO: For completeness sake, need to handle -ve and +ve infinity, as it2
  // below might hit the boundaries
  Bin bin;
  bin.p = x;
  HistogramTypeConstIter it2 = std::upper_bound(bins_.begin(), bins_.end(), bin);
  HistogramTypeConstIter it1 = it2 - 1;
  //LOG(INFO) << "it2 index: " << it2 - bins_.begin() << "; is end: " << (it2 == bins_.end())?1:0;
  //LOG(INFO) << "bins_ max: " << it2 - bins_.begin();
  double m_summed = 0.0;
  double y_summed = 0.0;
  /*
  for (HistogramTypeConstIter it = bins_.begin(); it != it2; ++it) {
    if (it != it1) {
      m_summed += it->val.m;
      y_summed += it->val.y;
    }
    else{
      m_summed += it->val.m / 2.0;
      y_summed += it->val.y / 2.0;
    }
  }
  */
  PrecomputeCumsums();
  if (it2 != bins_.begin()) {
    unsigned int index_upto = it2 - bins_.begin() - 1;
    m_summed = cumsums_[index_upto].m;
    y_summed = cumsums_[index_upto].y;
  }

  double m_offset, y_offset;
  // Take care of two critical bin locations: first and last
  if (it2 == bins_.begin()) {
    //LOG(INFO) << "Handling special case of neg_inf!";
    double p_neg_inf = bins_[0].p - (bins_[1].p - bins_[0].p);
    //LOG(INFO) << "p_0: " << it2->p << " m_0: " << it2->val.m;
    if (x < p_neg_inf) {
      m_offset = 0;
      y_offset = 0;
    }
    else {
      m_offset = trapezoid_estimate(x, p_neg_inf, it2->p, 0.0, it2->val.m);
      y_offset = trapezoid_estimate(x, p_neg_inf, it2->p, 0.0, it2->val.y);
    }
    //LOG(INFO) << "p_neg_inf: " << p_neg_inf << " offsets: " << m_offset << " " << y_offset;
  }
  else if (it2 == bins_.end()) {
    //LOG(INFO) << "Handling special case of pos_inf!";
    double p_pos_inf = bins_[bins_.size()-1].p + (bins_[bins_.size()-1].p -
        bins_[bins_.size()-2].p);
    if (x > p_pos_inf) {
      m_offset = it2->val.m / 2;
      y_offset = it2->val.y / 2;
    }
    else{
      m_offset = trapezoid_estimate(x, it2->p, p_pos_inf, it1->val.m, 0.0);
      y_offset = trapezoid_estimate(x, it2->p, p_pos_inf, it1->val.y, 0.0);
    }
    //LOG(INFO) << "p_pos_inf: " << p_pos_inf << " offsets: " << m_offset << " " << y_offset;
  }
  else {
    m_offset = trapezoid_estimate(x, it1->p, it2->p, it1->val.m, it2->val.m);
    y_offset = trapezoid_estimate(x, it1->p, it2->p, it1->val.y, it2->val.y);
  }

  BinVal val;
  val.m = m_summed + m_offset;
  val.y = y_summed + y_offset;
  return val;
};

Histogram::BinVal Histogram::InterpolateInf() const {
  /*
  double m_summed = 0.0;
  double y_summed = 0.0;
  for (HistogramTypeConstIter it = bins_.begin(); it != bins_.end(); ++it) {
    m_summed += it->val.m;
    y_summed += it->val.y;
  }
  BinVal val;
  val.m = m_summed;
  val.y = y_summed;
  return val;
  */
  PrecomputeCumsums();
  const BinVal& binval = cumsums_[bins_.size()];
  return binval;
};

void Histogram::Trim() {
  while (bins_.size() > max_num_bins_) {
    // TODO: Handle ties in minimum distance
    double min_dist = std::numeric_limits<double>::max();
    unsigned int combine_location = 0;
    for (unsigned int i = 0; i < bins_.size() - 1; ++i) {
      double dist = std::fabs(bins_[i].p - bins_[i+1].p);
      if (dist < min_dist) {
        min_dist = dist;
        combine_location = i;
      }
    }
    //std::cout << "combine_location: " << combine_location << std::endl;
    //std::cout << "min_dist: " << min_dist << std::endl;
    int i = combine_location;
    int j = combine_location + 1;
    bins_[i].p = ((bins_[i].p * bins_[i].val.m) +
                  (bins_[j].p * bins_[j].val.m)) /
                 (bins_[i].val.m + bins_[j].val.m);
    bins_[i].val.m += bins_[j].val.m;
    bins_[i].val.y += bins_[j].val.y;
    bins_.erase(bins_.begin() + j);
  }
};

// Implements Algorithm 4 in Ben-Haim-10 paper
std::vector<double> Histogram::Uniform(int N) const {
  // N corresponds to tilde B in the paper
  CHECK(N >= 1) << "Histogram's Uniform routine requires N >= 1";
  //CHECK(bins_.size() >= 2) << "Histogrom does not have enough bins";
  std::vector<double> results;
  /*
  double sum_m = 0.0;
  for (unsigned int i = 0; i < bins_.size(); ++i) {
    sum_m += bins_[i].val.m;
  }
  std::vector<double> cumsums(bins_.size(), 0.0);
  for (unsigned int i = 0; i < bins_.size(); ++i) {
    // Special case of Sum / Interpolate where the target x is always at the
    // center of a bin -- can be computed inplace directly
    if (i == 0) {
      cumsums[i] = bins_[i].val.m / 2.0;
    }
    else {
      cumsums[i] = cumsums[i-1]
                   + bins_[i-1].val.m / 2.0
                   + bins_[i].val.m / 2.0;
    }
  }
  */
  PrecomputeCumsums();

  // Last of cumsums_ adds up all bins
  double sum_m = cumsums_.back().m;

  BinVal binval;
  for (int j = 1; j <= N - 1; ++j) {
    double s = ((double)j / N) * sum_m;
    // This is (i+1) -- the first element that is larger than s
    //std::vector<double>::iterator it = std::upper_bound(cumsums.begin(),
                                                        //cumsums.end(), s);
    binval.m = s;
    std::vector<BinVal>::iterator it = std::upper_bound(
        cumsums_.begin(), cumsums_.end(), binval,
        [](const BinVal& a, const BinVal& b) -> bool { return a.m < b.m; });

    if (it == cumsums_.begin()) {
      continue;
    }

    unsigned int i = it - cumsums_.begin() - 1;
    double d = s - cumsums_[i].m;
    double a = bins_[i+1].val.m - bins_[i].val.m;
    double z;
    if (std::fabs(a) > 10e-8) {
      double b = 2.0 * bins_[i].val.m;
      double c = -2.0 * d;
      z = (- b + sqrt(b*b - 4*a*c)) / (2*a);
    }
    else {
      z = d / bins_[i].val.m;
    }
    double uj = bins_[i].p + (bins_[i+1].p - bins_[i].p)*z;
    results.push_back(uj);
  }

  return results;
};

void Histogram::PrecomputeCumsums() const {
  // Pre-compute the cummulative sums
  // cumsums_[i] means summations up to 1//2 of the i-th bin.

  // Only recompute when necessary
  if (!dirty_) {
    return;
  }

  for (unsigned int i = 0; i < bins_.size(); ++i) {
    if (i == 0) {
      cumsums_[i].m = bins_[i].val.m / 2.0;
      cumsums_[i].y = bins_[i].val.y / 2.0;
    }
    else {
      cumsums_[i].m = cumsums_[i-1].m
                      + bins_[i-1].val.m / 2.0
                      + bins_[i].val.m / 2.0;

      cumsums_[i].y = cumsums_[i-1].y
                      + bins_[i-1].val.y / 2.0
                      + bins_[i].val.y / 2.0;
    }
  }
  // Sums at +ve infinity (i.e. sum up all)
  unsigned int index_inf = bins_.size();
  cumsums_[index_inf].m = cumsums_[index_inf-1].m + bins_.back().val.m/2.0;
  cumsums_[index_inf].y = cumsums_[index_inf-1].y + bins_.back().val.y/2.0;
  dirty_ = false;
};
<|endoftext|>


<commit_before>#include "core/world/tile.h"
#include "core/world/tile_descriptor.h"

namespace eversim { namespace core { namespace world {
	tile_descriptor blank_tile = {
		"blank"
	};

	bool tile::point_inside(glm::vec2 p) const
	{
		auto center = position();
		auto min = center - glm::vec2(size() / 2);
		auto max = center + glm::vec2(size() / 2);

		return p.x >= min.x && p.x < max.x && p.y >= min.y && p.y < max.y;
	}
}}}
<commit_msg>super hacky rendering implementation<commit_after>#include "core/world/tile.h"
#include "core/world/tile_descriptor.h"
#include "core/rendering/render_manager.h"

// VERY hacky!
extern eversim::core::rendering::ShaderProgram* default_shader;

namespace eversim { namespace core { namespace world {
	tile_descriptor blank_tile = {
		"blank"
	};

	bool tile::point_inside(glm::vec2 p) const
	{
		auto center = position();
		auto min = center - glm::vec2(size() / 2);
		auto max = center + glm::vec2(size() / 2);

		return p.x >= min.x && p.x < max.x && p.y >= min.y && p.y < max.y;
	}

	void tile::initialize_graphics(rendering::render_manager& mng)
	{
		auto const& tex_name = descriptor->texture_name;
		if (tex_name.empty())
			return;
		display = mng.register_entity();
		auto M = display->get_M();
		M[2] = glm::vec3(position() - glm::vec2(size()), 1);
		display->set_M(M);

		LOG(WARNING) << "Hacky solution for tile display!";
		static std::map<std::string, rendering::Texture> textures;

		const auto it = textures.find(tex_name);
		if(it == textures.end())
		{
			textures[tex_name] = rendering::Texture(tex_name);
		}

		display->set_Texture(textures[tex_name]);
		display->set_ShaderProgram(default_shader);

	}
}}}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2016 tildearrow
 *
 * 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.
 */
#ifdef _WIN32
#define FONT "C:\\Windows\\Fonts\\segoeui.ttf"
#elif __APPLE__
#define FONT "/System/Library/Fonts/SFNSDisplay-Regular.otf"
#elif __linux__
#define FONT "/usr/share/fonts/TTF/Ubuntu-R.ttf"
#else
#warning "really? please tell me if you are compiling on this OS"
#endif

#include "includes.h"
#include "font.h"
#include "ui.h"
SDL_Window* mainWindow;
SDL_Renderer* mainRenderer;
SDL_Event* event;
int mouseX;
int mouseY;
unsigned int mouseB;
unsigned int mouseBold;
SDL_Color color;
bool willquit;
uisystem* ui;
font* mainFont;
int curview;
int cureditid, curedittype;
const char* viewname[6]={"Graphics","Audio","Entity Types","Scenes","Functions"};

struct graphic {
  string name;
  int id;
  int width;
  int height;
  int originX, originY;
  int subgraphics;
  bool background;
  unsigned char** data;
  int colmode;
  unsigned char** colmask;
};

struct audio {
  string name;
  int id;
  int size;
  float* data;
  int finaltype;
};

struct etype {
  string name;
  int id;
  int initialgraphic;
  int initialsubgraphic;
  int parent;
  int category;
  std::vector<string> eventcode;
  string headercode;
};

struct viewport {
  SDL_Rect view, port;
  float viewangle, portangle;
};

struct scene {
  string name;
  int width;
  int height;
  bool freeze;
  std::vector<viewport> viewports;
};

struct function {
  string name;
  string code;
};

std::vector<graphic> graphics;
std::vector<audio> sounds;
std::vector<etype> etypes;
std::vector<scene> scenes;

void doNothing(){
  printf("hello world!\n");
}

void drawscreen() {
  SDL_RenderDrawLine(mainRenderer,0,32,1024,32);
  SDL_RenderDrawLine(mainRenderer,256,32,256,600);
  SDL_RenderDrawLine(mainRenderer,0,53,256,53);
  mainFont->drawf(128,41,color,1,1,"%s List",viewname[curview]);
  switch (curview) {
    case 0:
      for (int i=0; i<graphics.size(); i++) {
        mainFont->draw(0,64+(i*20),color,0,0,false,graphics[i].name);
      }
      break;
    case 1:
      for (int i=0; i<sounds.size(); i++) {
        mainFont->draw(0,64+(i*20),color,0,0,false,sounds[i].name);
      }
      break;
    case 2:
      for (int i=0; i<etypes.size(); i++) {
        mainFont->draw(0,64+(i*20),color,0,0,false,etypes[i].name);
      }
      break;
  }
}

void goGraphicsView() {
  curview=0;
}

void goAudioView() {
  curview=1;
}

void goETypesView() {
  curview=2;
}

void goScenesView() {
  curview=3;
}

void goFunctionsView() {
  curview=4;
}

void makeNewResource() {
  printf("ok, will be done\n");
  // make new resource
  int formersize;
  switch (curview) {
    case 0:
      formersize=graphics.size();
      graphics.resize(formersize+1);
      graphics[formersize].id=formersize;
      graphics[formersize].name="graphic";
      graphics[formersize].name+=std::to_string(formersize);
      break;
    case 1:
      formersize=sounds.size();
      sounds.resize(formersize+1);
      sounds[formersize].id=formersize;
      sounds[formersize].name="sound";
      sounds[formersize].name+=std::to_string(formersize);
      break;
    case 2:
      formersize=etypes.size();
      etypes.resize(formersize+1);
      etypes[formersize].id=formersize;
      etypes[formersize].name="type";
      etypes[formersize].name+=std::to_string(formersize);
      break;
  }
}

int main() {
  willquit=false;
  // init everything
  SDL_Init(SDL_INIT_VIDEO);
  TTF_Init();
  ui=new uisystem;
  event=new SDL_Event;
  string title;
  title="LowerTriad";
  mainWindow=SDL_CreateWindow(title.c_str(),0,0,1024,600,SDL_WINDOW_RESIZABLE);
  if (!mainWindow) {
    printf("i'm sorry, but window can't be created: %s\n",SDL_GetError());
    return 1;
  }
  mainRenderer=SDL_CreateRenderer(mainWindow,-1,SDL_RENDERER_ACCELERATED|SDL_RENDERER_PRESENTVSYNC);
  // initialize UI
  mainFont=new font;
  mainFont->setrenderer(mainRenderer);
  if (!mainFont->load(FONT,14)) {
    printf("can't load font, which means this application is going to crash now...\n");
  }
  ui->setrenderer(mainRenderer);
  color.r=0; color.g=255; color.b=0; color.a=255;
  ui->setfont(mainFont);
  ui->addbutton(0,0,48,22,"Prepare","Prepare CMake project",color,color,doNothing);
  ui->addbutton(48,0,40,22,"Build","Build game",color,color,doNothing);
  ui->addbutton(100,0,32,22,"Run","Run compiled game",color,color,doNothing);
  ui->addbutton(132,0,56,22,"Package","Create package",color,color,doNothing);

  ui->addbutton(200,0,64,22,"Graphics","",color,color,goGraphicsView);
  ui->addbutton(264,0,50,22,"Audio","",color,color,goAudioView);
  ui->addbutton(314,0,80,22,"EntityTypes","",color,color,goETypesView);
  ui->addbutton(394,0,50,22,"Scenes","",color,color,goScenesView);
  ui->addbutton(444,0,72,22,"Functions","",color,color,goFunctionsView);
  ui->addbutton(225,32,32,22,"Add","",color,color,makeNewResource);

  ui->setmouse(&mouseX,&mouseY,&mouseB,&mouseBold);
  // initialize IDE variables
  cureditid=-1; curedittype=0; curview=0;
  while (1) {
    // check events
    while (SDL_PollEvent(event)) {
      if (event->type==SDL_QUIT) {
        willquit=true;
      }
    }
    SDL_SetRenderDrawColor(mainRenderer,0,0,0,0);
    SDL_RenderClear(mainRenderer);
    mouseBold=mouseB;
    mouseB=SDL_GetMouseState(&mouseX, &mouseY);
    ui->drawall();
    drawscreen();
    SDL_RenderPresent(mainRenderer);
    if (willquit) {
      break;
    }
  }
  return 0;
}
<commit_msg>ui and code changes<commit_after>/*
 * Copyright (c) 2016 tildearrow
 *
 * 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.
 */
#ifdef _WIN32
#define FONT "C:\\Windows\\Fonts\\segoeui.ttf"
#elif __APPLE__
#define FONT "/System/Library/Fonts/SFNSDisplay-Regular.otf"
#elif __linux__
#define FONT "/usr/share/fonts/TTF/Ubuntu-R.ttf"
#else
#warning "really? please tell me if you are compiling on this OS"
#endif

#include "includes.h"
#include "font.h"
#include "ui.h"
SDL_Window* mainWindow;
SDL_Renderer* mainRenderer;
SDL_Event* event;
int mouseX;
int mouseY;
unsigned int mouseB;
unsigned int mouseBold;
SDL_Color color;
bool willquit;
uisystem* ui;
font* mainFont;
int curview;
int cureditid, curedittype;
const char* viewname[6]={"Graphics","Audio","Entity Types","Scenes","Functions"};

struct graphic {
  string name;
  int id;
  int width;
  int height;
  int originX, originY;
  int subgraphics;
  bool background;
  unsigned char** data;
  int colmode;
  unsigned char** colmask;
};

struct audio {
  string name;
  int id;
  int size;
  float* data;
  int finaltype;
};

struct etype {
  string name;
  int id;
  int initialgraphic;
  int initialsubgraphic;
  int parent;
  int category;
  std::vector<string> eventcode;
  string headercode;
};

struct viewport {
  SDL_Rect view, port;
  float viewangle, portangle;
};

struct scene {
  string name;
  int id;
  int width;
  int height;
  bool freeze;
  std::vector<viewport> viewports;
};

struct function {
  string name;
  int id;
  string code;
};

std::vector<graphic> graphics;
std::vector<audio> sounds;
std::vector<etype> etypes;
std::vector<scene> scenes;
std::vector<function> functions;

void doNothing(){
  printf("hello world!\n");
}

void drawScreen() {
  SDL_RenderDrawLine(mainRenderer,0,32,1024,32);
  SDL_RenderDrawLine(mainRenderer,256,32,256,600);
  SDL_RenderDrawLine(mainRenderer,0,53,256,53);
  mainFont->drawf(128,41,color,1,1,"%s List",viewname[curview]);
  switch (curview) {
    case 0:
      for (int i=0; i<graphics.size(); i++) {
        mainFont->draw(0+((cureditid==i)?(16):(0)),64+(i*20),color,0,0,false,graphics[i].name);
      }
      break;
    case 1:
      for (int i=0; i<sounds.size(); i++) {
        mainFont->draw(0,64+(i*20),color,0,0,false,sounds[i].name);
      }
      break;
    case 2:
      for (int i=0; i<etypes.size(); i++) {
        mainFont->draw(0,64+(i*20),color,0,0,false,etypes[i].name);
      }
      break;
    case 3:
      for (int i=0; i<scenes.size(); i++) {
        mainFont->draw(0,64+(i*20),color,0,0,false,scenes[i].name);
      }
      break;
    case 4:
      for (int i=0; i<functions.size(); i++) {
        mainFont->draw(0,64+(i*20),color,0,0,false,functions[i].name);
      }
      break;
  }
}

void goGraphicsView() {
  curview=0;
}

void goAudioView() {
  curview=1;
}

void goETypesView() {
  curview=2;
}

void goScenesView() {
  curview=3;
}

void goFunctionsView() {
  curview=4;
}

void handleMouse() {
  if (mouseB&1) {
    if (mouseX<256 && mouseY>64) {
      cureditid=(mouseY-64)/20;
    }
  }
}

void makeNewResource() {
  // make new resource
  int formersize;
  switch (curview) {
    case 0:
      formersize=graphics.size();
      graphics.resize(formersize+1);
      graphics[formersize].id=formersize;
      graphics[formersize].name="graphic";
      graphics[formersize].name+=std::to_string(formersize);
      break;
    case 1:
      formersize=sounds.size();
      sounds.resize(formersize+1);
      sounds[formersize].id=formersize;
      sounds[formersize].name="sound";
      sounds[formersize].name+=std::to_string(formersize);
      break;
    case 2:
      formersize=etypes.size();
      etypes.resize(formersize+1);
      etypes[formersize].id=formersize;
      etypes[formersize].name="type";
      etypes[formersize].name+=std::to_string(formersize);
      break;
    case 3:
      formersize=scenes.size();
      scenes.resize(formersize+1);
      scenes[formersize].id=formersize;
      scenes[formersize].name="scene";
      scenes[formersize].name+=std::to_string(formersize);
      break;
    case 4:
      formersize=functions.size();
      functions.resize(formersize+1);
      functions[formersize].id=formersize;
      functions[formersize].name="func";
      functions[formersize].name+=std::to_string(formersize);
      break;
  }
}

int main() {
  willquit=false;
  // init everything
  SDL_Init(SDL_INIT_VIDEO);
  TTF_Init();
  ui=new uisystem;
  event=new SDL_Event;
  string title;
  title="LowerTriad";
  mainWindow=SDL_CreateWindow(title.c_str(),0,0,1024,600,SDL_WINDOW_RESIZABLE);
  if (!mainWindow) {
    printf("i'm sorry, but window can't be created: %s\n",SDL_GetError());
    return 1;
  }
  mainRenderer=SDL_CreateRenderer(mainWindow,-1,SDL_RENDERER_ACCELERATED|SDL_RENDERER_PRESENTVSYNC);
  // initialize UI
  mainFont=new font;
  mainFont->setrenderer(mainRenderer);
  if (!mainFont->load(FONT,14)) {
    printf("can't load font, which means this application is going to crash now...\n");
  }
  ui->setrenderer(mainRenderer);
  color.r=0; color.g=255; color.b=0; color.a=255;
  ui->setfont(mainFont);
  ui->addbutton(0,0,48,22,"Prepare","Prepare CMake project",color,color,doNothing);
  ui->addbutton(48,0,40,22,"Build","Build game",color,color,doNothing);
  ui->addbutton(100,0,32,22,"Run","Run compiled game",color,color,doNothing);
  ui->addbutton(132,0,56,22,"Package","Create package",color,color,doNothing);

  ui->addbutton(200,0,64,22,"Graphics","",color,color,goGraphicsView);
  ui->addbutton(264,0,50,22,"Audio","",color,color,goAudioView);
  ui->addbutton(314,0,80,22,"EntityTypes","",color,color,goETypesView);
  ui->addbutton(394,0,50,22,"Scenes","",color,color,goScenesView);
  ui->addbutton(444,0,72,22,"Functions","",color,color,goFunctionsView);
  ui->addbutton(225,32,32,22,"Add","",color,color,makeNewResource);

  ui->setmouse(&mouseX,&mouseY,&mouseB,&mouseBold);
  // initialize IDE variables
  cureditid=-1; curedittype=0; curview=0;
  while (1) {
    // check events
    while (SDL_PollEvent(event)) {
      if (event->type==SDL_QUIT) {
        willquit=true;
      }
    }
    SDL_SetRenderDrawColor(mainRenderer,0,0,0,0);
    SDL_RenderClear(mainRenderer);
    mouseBold=mouseB;
    mouseB=SDL_GetMouseState(&mouseX, &mouseY);
    handleMouse();
    ui->drawall();
    drawScreen();
    SDL_RenderPresent(mainRenderer);
    if (willquit) {
      break;
    }
  }
  return 0;
}
<|endoftext|>