<commit_before>/*ckwg +29
 * Copyright 2011-2013 by Kitware, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  * Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 *  * Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 *  * Neither name of Kitware, Inc. nor the names of any 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 AUTHORS OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"

#include <boost/algorithm/string/case_conv.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/bind.hpp>
#include <boost/foreach.hpp>
#include <boost/none.hpp>

#include <algorithm>
#include <iterator>
#include <sstream>

/**
 * \file config.cxx
 *
 * \brief Implementation of \link sprokit::config configuration\endlink in the pipeline.
 */

namespace sprokit
{

config::key_t const config::block_sep = key_t(":");
config::key_t const config::global_value = key_t("_global");

static bool does_not_begin_with(config::key_t const& key, config::key_t const& name);
static config::key_t strip_block_name(config::key_t const& subblock, config::key_t const& key);

config_t
config
::empty_config(key_t const& name)
{
  return config_t(new config(name, config_t()));
}

config
::~config()
{
}

config_t
config
::subblock(key_t const& key) const
{
  config_t conf = empty_config(key);

  BOOST_FOREACH (key_t const& key_name, available_values())
  {
    if (does_not_begin_with(key_name, key))
    {
      continue;
    }

    key_t const stripped_key_name = strip_block_name(key, key_name);

    conf->set_value(stripped_key_name, get_value(key_name));
  }

  return conf;
}

config_t
config
::subblock_view(key_t const& key)
{
  return config_t(new config(key, shared_from_this()));
}

void
config
::set_value(key_t const& key, value_t const& value)
{
  if (m_parent)
  {
    m_parent->set_value(m_name + block_sep + key, value);
  }
  else
  {
    if (is_read_only(key))
    {
      value_t const current_value = get_value<value_t>(key, value_t());

      throw set_on_read_only_value_exception(key, current_value, value);
    }

    m_store[key] = value;
  }
}

void
config
::unset_value(key_t const& key)
{
  if (m_parent)
  {
    m_parent->unset_value(m_name + block_sep + key);
  }
  else
  {
    if (is_read_only(key))
    {
      value_t const current_value = get_value<value_t>(key, value_t());

      throw unset_on_read_only_value_exception(key, current_value);
    }

    store_t::iterator const i = m_store.find(key);

    if (i == m_store.end())
    {
      throw no_such_configuration_value_exception(key);
    }

    m_store.erase(i);
  }
}

bool
config
::is_read_only(key_t const& key) const
{
  return (0 != m_ro_list.count(key));
}

void
config
::mark_read_only(key_t const& key)
{
  m_ro_list.insert(key);
}

void
config
::merge_config(config_t const& conf)
{
  config::keys_t const keys = conf->available_values();

  BOOST_FOREACH (key_t const& key, keys)
  {
    value_t const& val = conf->get_value<value_t>(key);

    set_value(key, val);
  }
}

config::keys_t
config
::available_values() const
{
  keys_t keys;

  if (m_parent)
  {
    keys_t parent_keys = m_parent->available_values();

    keys_t::iterator const i = std::remove_if(parent_keys.begin(), parent_keys.end(), boost::bind(does_not_begin_with, _1, m_name));

    parent_keys.erase(i, parent_keys.end());

    std::transform(parent_keys.begin(), parent_keys.end(), std::back_inserter(keys), boost::bind(strip_block_name, m_name, _1));
  }
  else
  {
    BOOST_FOREACH (store_t::value_type const& value, m_store)
    {
      key_t const& key = value.first;

      keys.push_back(key);
    }
  }

  return keys;
}

bool
config
::has_value(key_t const& key) const
{
  if (m_parent)
  {
    return m_parent->has_value(m_name + block_sep + key);
  }

  return (0 != m_store.count(key));
}

config
::config(key_t const& name, config_t parent)
  : m_parent(parent)
  , m_name(name)
  , m_store()
  , m_ro_list()
{
}

boost::optional<config::value_t>
config
::find_value(key_t const& key) const
{
  if (!has_value(key))
  {
    return boost::none;
  }

  return get_value(key);
}

config::value_t
config
::get_value(key_t const& key) const
{
  if (m_parent)
  {
    return m_parent->get_value(m_name + block_sep + key);
  }

  store_t::const_iterator i = m_store.find(key);

  if (i == m_store.end())
  {
    return value_t();
  }

  return i->second;
}

configuration_exception
::configuration_exception() SPROKIT_NOTHROW
  : pipeline_exception()
{
}

configuration_exception
::~configuration_exception() SPROKIT_NOTHROW
{
}

bad_configuration_cast
::bad_configuration_cast(char const* reason) SPROKIT_NOTHROW
  : configuration_exception()
{
  m_what = reason;
}

bad_configuration_cast
::~bad_configuration_cast() SPROKIT_NOTHROW
{
}

no_such_configuration_value_exception
::no_such_configuration_value_exception(config::key_t const& key) SPROKIT_NOTHROW
  : configuration_exception()
  , m_key(key)
{
  std::ostringstream sstr;

  sstr << "There is no configuration value with the key "
          "\'" << m_key << "\'.";

  m_what = sstr.str();
}

no_such_configuration_value_exception
::~no_such_configuration_value_exception() SPROKIT_NOTHROW
{
}

bad_configuration_cast_exception
::bad_configuration_cast_exception(config::key_t const& key, config::value_t const& value, char const* type, char const* reason) SPROKIT_NOTHROW
  : configuration_exception()
  , m_key(key)
  , m_value(value)
  , m_type(type)
  , m_reason(reason)
{
  std::ostringstream sstr;

  sstr << "Failed to cast key \'" << m_key << "\' "
          "with value \'" << m_value << "\' as "
          "a \'" << m_type << "\': " << m_reason << ".";

  m_what = sstr.str();
}

bad_configuration_cast_exception
::~bad_configuration_cast_exception() SPROKIT_NOTHROW
{
}

set_on_read_only_value_exception
::set_on_read_only_value_exception(config::key_t const& key, config::value_t const& value, config::value_t const& new_value) SPROKIT_NOTHROW
  : configuration_exception()
  , m_key(key)
  , m_value(value)
  , m_new_value(new_value)
{
  std::ostringstream sstr;

  sstr << "The key \'" << m_key << "\' "
          "was marked as read-only with the value "
          "\'" << m_value << "\' was attempted to be "
          "set to \'" << m_new_value << "\'.";

  m_what = sstr.str();
}

set_on_read_only_value_exception
::~set_on_read_only_value_exception() SPROKIT_NOTHROW
{
}

unset_on_read_only_value_exception
::unset_on_read_only_value_exception(config::key_t const& key, config::value_t const& value) SPROKIT_NOTHROW
  : configuration_exception()
  , m_key(key)
  , m_value(value)
{
  std::ostringstream sstr;

  sstr << "The key \'" << m_key << "\' "
          "was marked as read-only with the value "
          "\'" << m_value << "\' was attempted to be "
          "unset.";

  m_what = sstr.str();
}

unset_on_read_only_value_exception
::~unset_on_read_only_value_exception() SPROKIT_NOTHROW
{
}

template <>
bool
config_cast_inner(config::value_t const& value)
{
  static config::value_t const true_string = config::value_t("true");
  static config::value_t const false_string = config::value_t("false");

  config::value_t const value_lower = boost::to_lower_copy(value);

  if (value_lower == true_string)
  {
    return true;
  }
  else if (value_lower == false_string)
  {
    return false;
  }

  return config_cast_default<bool>(value);
}

bool
does_not_begin_with(config::key_t const& key, config::key_t const& name)
{
  static config::key_t const global_start = config::global_value + config::block_sep;

  return (!boost::starts_with(key, name + config::block_sep) &&
          !boost::starts_with(key, global_start));
}

config::key_t
strip_block_name(config::key_t const& subblock, config::key_t const& key)
{
  if (!boost::starts_with(key, subblock + config::block_sep))
  {
    return key;
  }

  return key.substr(subblock.size() + config::block_sep.size());
}

std::ostream& operator<<( std::ostream& str, sprokit::config const& obj )
{
  sprokit::config::keys_t all_keys = obj.available_values();

  BOOST_FOREACH( sprokit::config::key_t key, all_keys )
  {
    std::string ro;

    sprokit::config::value_t const val = obj.get_value< sprokit::config::value_t > ( key );
    if (obj.is_read_only( key ) ) ro = "[ro]";

    str << key << ro << " = " << val << std::endl;
  }

  return str;
}

} // end namespace
<commit_msg>Convert output operator to print() method.<commit_after>/*ckwg +29
 * Copyright 2011-2013 by Kitware, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  * Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 *  * Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 *  * Neither name of Kitware, Inc. nor the names of any 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 AUTHORS OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"

#include <boost/algorithm/string/case_conv.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/bind.hpp>
#include <boost/foreach.hpp>
#include <boost/none.hpp>

#include <algorithm>
#include <iterator>
#include <sstream>

/**
 * \file config.cxx
 *
 * \brief Implementation of \link sprokit::config configuration\endlink in the pipeline.
 */

namespace sprokit
{

config::key_t const config::block_sep = key_t(":");
config::key_t const config::global_value = key_t("_global");

static bool does_not_begin_with(config::key_t const& key, config::key_t const& name);
static config::key_t strip_block_name(config::key_t const& subblock, config::key_t const& key);

config_t
config
::empty_config(key_t const& name)
{
  return config_t(new config(name, config_t()));
}

config
::~config()
{
}

config_t
config
::subblock(key_t const& key) const
{
  config_t conf = empty_config(key);

  BOOST_FOREACH (key_t const& key_name, available_values())
  {
    if (does_not_begin_with(key_name, key))
    {
      continue;
    }

    key_t const stripped_key_name = strip_block_name(key, key_name);

    conf->set_value(stripped_key_name, get_value(key_name));
  }

  return conf;
}

config_t
config
::subblock_view(key_t const& key)
{
  return config_t(new config(key, shared_from_this()));
}

void
config
::set_value(key_t const& key, value_t const& value)
{
  if (m_parent)
  {
    m_parent->set_value(m_name + block_sep + key, value);
  }
  else
  {
    if (is_read_only(key))
    {
      value_t const current_value = get_value<value_t>(key, value_t());

      throw set_on_read_only_value_exception(key, current_value, value);
    }

    m_store[key] = value;
  }
}

void
config
::unset_value(key_t const& key)
{
  if (m_parent)
  {
    m_parent->unset_value(m_name + block_sep + key);
  }
  else
  {
    if (is_read_only(key))
    {
      value_t const current_value = get_value<value_t>(key, value_t());

      throw unset_on_read_only_value_exception(key, current_value);
    }

    store_t::iterator const i = m_store.find(key);

    if (i == m_store.end())
    {
      throw no_such_configuration_value_exception(key);
    }

    m_store.erase(i);
  }
}

bool
config
::is_read_only(key_t const& key) const
{
  return (0 != m_ro_list.count(key));
}

void
config
::mark_read_only(key_t const& key)
{
  m_ro_list.insert(key);
}

void
config
::merge_config(config_t const& conf)
{
  config::keys_t const keys = conf->available_values();

  BOOST_FOREACH (key_t const& key, keys)
  {
    value_t const& val = conf->get_value<value_t>(key);

    set_value(key, val);
  }
}

config::keys_t
config
::available_values() const
{
  keys_t keys;

  if (m_parent)
  {
    keys_t parent_keys = m_parent->available_values();

    keys_t::iterator const i = std::remove_if(parent_keys.begin(), parent_keys.end(), boost::bind(does_not_begin_with, _1, m_name));

    parent_keys.erase(i, parent_keys.end());

    std::transform(parent_keys.begin(), parent_keys.end(), std::back_inserter(keys), boost::bind(strip_block_name, m_name, _1));
  }
  else
  {
    BOOST_FOREACH (store_t::value_type const& value, m_store)
    {
      key_t const& key = value.first;

      keys.push_back(key);
    }
  }

  return keys;
}

bool
config
::has_value(key_t const& key) const
{
  if (m_parent)
  {
    return m_parent->has_value(m_name + block_sep + key);
  }

  return (0 != m_store.count(key));
}

void
config
::print(std::ostream& str)
{
  sprokit::config::keys_t all_keys = this->available_values();

  BOOST_FOREACH(sprokit::config::key_t key, all_keys)
  {
    std::string ro;

    sprokit::config::value_t const val = this->get_value< sprokit::config::value_t > (key);
    if (this->is_read_only(key))
    {
      ro = "[ro]";
    }

    str << key << ro << " = " << val << std::endl;
  }
}

config
::config(key_t const& name, config_t parent)
  : m_parent(parent)
  , m_name(name)
  , m_store()
  , m_ro_list()
{
}

boost::optional<config::value_t>
config
::find_value(key_t const& key) const
{
  if (!has_value(key))
  {
    return boost::none;
  }

  return get_value(key);
}

config::value_t
config
::get_value(key_t const& key) const
{
  if (m_parent)
  {
    return m_parent->get_value(m_name + block_sep + key);
  }

  store_t::const_iterator i = m_store.find(key);

  if (i == m_store.end())
  {
    return value_t();
  }

  return i->second;
}

configuration_exception
::configuration_exception() SPROKIT_NOTHROW
  : pipeline_exception()
{
}

configuration_exception
::~configuration_exception() SPROKIT_NOTHROW
{
}

bad_configuration_cast
::bad_configuration_cast(char const* reason) SPROKIT_NOTHROW
  : configuration_exception()
{
  m_what = reason;
}

bad_configuration_cast
::~bad_configuration_cast() SPROKIT_NOTHROW
{
}

no_such_configuration_value_exception
::no_such_configuration_value_exception(config::key_t const& key) SPROKIT_NOTHROW
  : configuration_exception()
  , m_key(key)
{
  std::ostringstream sstr;

  sstr << "There is no configuration value with the key "
          "\'" << m_key << "\'.";

  m_what = sstr.str();
}

no_such_configuration_value_exception
::~no_such_configuration_value_exception() SPROKIT_NOTHROW
{
}

bad_configuration_cast_exception
::bad_configuration_cast_exception(config::key_t const& key, config::value_t const& value, char const* type, char const* reason) SPROKIT_NOTHROW
  : configuration_exception()
  , m_key(key)
  , m_value(value)
  , m_type(type)
  , m_reason(reason)
{
  std::ostringstream sstr;

  sstr << "Failed to cast key \'" << m_key << "\' "
          "with value \'" << m_value << "\' as "
          "a \'" << m_type << "\': " << m_reason << ".";

  m_what = sstr.str();
}

bad_configuration_cast_exception
::~bad_configuration_cast_exception() SPROKIT_NOTHROW
{
}

set_on_read_only_value_exception
::set_on_read_only_value_exception(config::key_t const& key, config::value_t const& value, config::value_t const& new_value) SPROKIT_NOTHROW
  : configuration_exception()
  , m_key(key)
  , m_value(value)
  , m_new_value(new_value)
{
  std::ostringstream sstr;

  sstr << "The key \'" << m_key << "\' "
          "was marked as read-only with the value "
          "\'" << m_value << "\' was attempted to be "
          "set to \'" << m_new_value << "\'.";

  m_what = sstr.str();
}

set_on_read_only_value_exception
::~set_on_read_only_value_exception() SPROKIT_NOTHROW
{
}

unset_on_read_only_value_exception
::unset_on_read_only_value_exception(config::key_t const& key, config::value_t const& value) SPROKIT_NOTHROW
  : configuration_exception()
  , m_key(key)
  , m_value(value)
{
  std::ostringstream sstr;

  sstr << "The key \'" << m_key << "\' "
          "was marked as read-only with the value "
          "\'" << m_value << "\' was attempted to be "
          "unset.";

  m_what = sstr.str();
}

unset_on_read_only_value_exception
::~unset_on_read_only_value_exception() SPROKIT_NOTHROW
{
}

template <>
bool
config_cast_inner(config::value_t const& value)
{
  static config::value_t const true_string = config::value_t("true");
  static config::value_t const false_string = config::value_t("false");

  config::value_t const value_lower = boost::to_lower_copy(value);

  if (value_lower == true_string)
  {
    return true;
  }
  else if (value_lower == false_string)
  {
    return false;
  }

  return config_cast_default<bool>(value);
}

bool
does_not_begin_with(config::key_t const& key, config::key_t const& name)
{
  static config::key_t const global_start = config::global_value + config::block_sep;

  return (!boost::starts_with(key, name + config::block_sep) &&
          !boost::starts_with(key, global_start));
}

config::key_t
strip_block_name(config::key_t const& subblock, config::key_t const& key)
{
  if (!boost::starts_with(key, subblock + config::block_sep))
  {
    return key;
  }

  return key.substr(subblock.size() + config::block_sep.size());
}

} // end namespace
<|endoftext|>


<commit_before>#include "window.h"
#include "element.h"
#include "display.h"

#define internal static
#define local_persist static

ax_window *AXLibConstructWindow(ax_application *Application, AXUIElementRef WindowRef)
{
    ax_window *Window = (ax_window *) malloc(sizeof(ax_window));
    memset(Window, '\0', sizeof(ax_window));

    Window->Ref = (AXUIElementRef) CFRetain(WindowRef);
    Window->Application = Application;
    Window->ID = AXLibGetWindowID(WindowRef);
    Window->Name = AXLibGetWindowTitle(WindowRef);

    Window->Position = AXLibGetWindowPosition(WindowRef);
    Window->Size = AXLibGetWindowSize(WindowRef);

    if(AXLibIsWindowMovable(Window->Ref))
        AXLibAddFlags(Window, AXWindow_Movable);

    if(AXLibIsWindowResizable(Window->Ref))
        AXLibAddFlags(Window, AXWindow_Resizable);

    AXLibGetWindowRole(Window->Ref, &Window->Type.Role);
    AXLibGetWindowSubrole(Window->Ref, &Window->Type.Subrole);

    return Window;
}

/* TODO(koekeishiya): Need to implement support for adding other roles that should be accepted
                      by this particular ax_window instance. */
bool AXLibIsWindowStandard(ax_window *Window)
{
    bool Result = ((CFEqual(Window->Type.Role, kAXWindowRole)) &&
                   (CFEqual(Window->Type.Subrole, kAXStandardWindowSubrole)));
    return Result;
}

void AXLibDestroyWindow(ax_window *Window)
{
    if(Window->Ref)
        CFRelease(Window->Ref);

    if(Window->Type.Role)
        CFRelease(Window->Type.Role);

    if(Window->Type.Subrole)
        CFRelease(Window->Type.Subrole);

    Window->Ref = NULL;
    Window->Type.Role = NULL;
    Window->Type.Subrole = NULL;
    Window->Application = NULL;
    free(Window);
}
<commit_msg>be consistent in which variable we use<commit_after>#include "window.h"
#include "element.h"
#include "display.h"

#define internal static
#define local_persist static

ax_window *AXLibConstructWindow(ax_application *Application, AXUIElementRef WindowRef)
{
    ax_window *Window = (ax_window *) malloc(sizeof(ax_window));
    memset(Window, '\0', sizeof(ax_window));

    Window->Ref = (AXUIElementRef) CFRetain(WindowRef);
    Window->Application = Application;
    Window->ID = AXLibGetWindowID(Window->Ref);
    Window->Name = AXLibGetWindowTitle(Window->Ref);

    Window->Position = AXLibGetWindowPosition(Window->Ref);
    Window->Size = AXLibGetWindowSize(Window->Ref);

    if(AXLibIsWindowMovable(Window->Ref))
        AXLibAddFlags(Window, AXWindow_Movable);

    if(AXLibIsWindowResizable(Window->Ref))
        AXLibAddFlags(Window, AXWindow_Resizable);

    AXLibGetWindowRole(Window->Ref, &Window->Type.Role);
    AXLibGetWindowSubrole(Window->Ref, &Window->Type.Subrole);

    return Window;
}

/* TODO(koekeishiya): Need to implement support for adding other roles that should be accepted
                      by this particular ax_window instance. */
bool AXLibIsWindowStandard(ax_window *Window)
{
    bool Result = ((CFEqual(Window->Type.Role, kAXWindowRole)) &&
                   (CFEqual(Window->Type.Subrole, kAXStandardWindowSubrole)));
    return Result;
}

void AXLibDestroyWindow(ax_window *Window)
{
    if(Window->Ref)
        CFRelease(Window->Ref);

    if(Window->Type.Role)
        CFRelease(Window->Type.Role);

    if(Window->Type.Subrole)
        CFRelease(Window->Type.Subrole);

    Window->Ref = NULL;
    Window->Type.Role = NULL;
    Window->Type.Subrole = NULL;
    Window->Application = NULL;
    free(Window);
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2016-2018 Immo Software
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * o Redistributions of source code must retain the above copyright notice, this list
 *   of conditions and the following disclaimer.
 *
 * o 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.
 *
 * o Neither the name of the copyright holder 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 HOLDER 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.
 */
/*!
 * @file
 * @brief Source for Ar microkernel runloops.
 */

#include "ar_internal.h"
#include <string.h>
#include <assert.h>

using namespace Ar;

//------------------------------------------------------------------------------
// Code
//------------------------------------------------------------------------------

// See ar_kernel.h for documentation of this function.
ar_status_t ar_runloop_create(ar_runloop_t * runloop, const char * name)
{
    if (!runloop)
    {
        return kArInvalidParameterError;
    }
    if (ar_port_get_irq_state())
    {
        return kArNotFromInterruptError;
    }

    memset(runloop, 0, sizeof(ar_runloop_t));

    runloop->m_name = name ? name : AR_ANONYMOUS_OBJECT_NAME;
    runloop->m_timers.m_predicate = ar_timer_sort_by_wakeup;

#if AR_GLOBAL_OBJECT_LISTS
    runloop->m_createdNode.m_obj = runloop;
    g_ar_objects.runloops.add(&runloop->m_createdNode);
#endif

    return kArSuccess;
}

// See ar_kernel.h for documentation of this function.
ar_status_t ar_runloop_delete(ar_runloop_t * runloop)
{
    if (!runloop)
    {
        return kArInvalidParameterError;
    }
    if (ar_port_get_irq_state())
    {
        return kArNotFromInterruptError;
    }
    if (runloop->m_isRunning)
    {
        return kArInvalidStateError;
    }

#if AR_GLOBAL_OBJECT_LISTS
    g_ar_objects.runloops.remove(&runloop->m_createdNode);
#endif

    return kArSuccess;
}

ar_status_t ar_runloop_run(ar_runloop_t * runloop, uint32_t timeout, ar_runloop_result_t * object)
{
    if (!runloop)
    {
        return kArInvalidParameterError;
    }
    // It's ok to nest runs of the runloop, but only on a single thread.
    if (runloop->m_isRunning && runloop->m_thread != g_ar.currentThread)
    {
        return kArRunLoopAlreadyRunningError;
    }
    // Another check to make sure no other runloop is already running on the current thread.
    if (g_ar.currentThread->m_runLoop && g_ar.currentThread->m_runLoop != runloop)
    {
        return kArRunLoopAlreadyRunningError;
    }
    // Disallow running from interrupt context.
    if (ar_port_get_irq_state())
    {
        return kArNotFromInterruptError;
    }

    // Clear returned object.
    if (object)
    {
        object->m_queue = NULL;
    }

    // Associate this runloop with the current thread.
    g_ar.currentThread->m_runLoop = runloop;
    runloop->m_thread = g_ar.currentThread;

    // Clear stop flag.
    runloop->m_stop = false;

    // Set running flag.
    runloop->m_isRunning = true;

    // Prepare timeout.
    uint32_t startTime = g_ar.tickCount;
    uint32_t timeoutTicks = timeout;
    if (timeout != kArInfiniteTimeout)
    {
        timeoutTicks = ar_milliseconds_to_ticks(timeout);
    }

    ar_status_t returnStatus = kArRunLoopStopped;

    // Run it.
    do {
        // Invoke timers.
        ar_kernel_run_timers(runloop->m_timers);

        // Invoke one queued function.
        if (runloop->m_functionCount)
        {
            uint16_t i = runloop->m_functionHead;
            uint16_t iPlusOne = (i + 1) % AR_RUNLOOP_FUNCTION_QUEUE_SIZE;

            ar_runloop_t::_ar_runloop_function_info fn = runloop->m_functions[i];

            ar_atomic_add32(&runloop->m_functionCount, -1);
            // This is the only line that modifies m_functionHead.
            runloop->m_functionHead = iPlusOne;

            assert(fn.function);
            fn.function(fn.param);
        }

        // Check pending queues.
        if (!runloop->m_queues.isEmpty())
        {
            ar_queue_t * queue = runloop->m_queues.getHead<ar_queue_t>();
            assert(queue);
            if (queue->m_count < 2)
            {
                runloop->m_queues.remove(queue);
            }

            if (queue->m_count > 0)
            {
                if (queue->m_runLoopHandler)
                {
                    // Call out to run loop queue source handler.
                    queue->m_runLoopHandler(queue, queue->m_runLoopHandlerParam);
                }
                else
                {
                    // No handler associated with this queue, so exit the run loop.
                    if (object)
                    {
                        object->m_queue = queue;
                    }

                    returnStatus = kArRunLoopQueueReceived;
                    break;
                }
            }
        }

        // Check timeout. Adjust the timeout based on how long we've run so far.
        uint32_t blockTimeoutTicks = timeoutTicks;
        if (blockTimeoutTicks != kArInfiniteTimeout)
        {
            uint32_t deltaTicks = g_ar.tickCount - startTime;
            if (deltaTicks >= timeoutTicks)
            {
                // Timed out, exit runloop.
                returnStatus = kArTimeoutError;
                break;
            }
            blockTimeoutTicks -= deltaTicks;
        }

        // Make sure we don't sleep past the next scheduled timer.
        if (!runloop->m_timers.isEmpty())
        {
            ar_timer_t * timer = runloop->m_timers.getHead<ar_timer_t>();
            uint32_t wakeupDeltaTicks = timer->m_wakeupTime - g_ar.tickCount;
            // kArInfiniteTimeout is the max 32-bit value, so wakeupDeltaTicks will always be <=
            if (wakeupDeltaTicks < blockTimeoutTicks)
            {
                blockTimeoutTicks = wakeupDeltaTicks;
            }
        }

        // Don't sleep if there are queued functions or sources.
        if (!runloop->m_functionCount && runloop->m_queues.isEmpty())
        {
            // Sleep the runloop's thread for the adjusted timeout.
            uint32_t blockTimeout = (blockTimeoutTicks == kArInfiniteTimeout)
                                        ? kArInfiniteTimeout
                                        : ar_ticks_to_milliseconds(blockTimeoutTicks);
            if (blockTimeout)
            {
                ar_thread_sleep(blockTimeout);
            }
        }
    } while (!runloop->m_stop);

    // Clear associated thread.
    g_ar.currentThread->m_runLoop = NULL;
    runloop->m_thread = NULL;

    // Clear running flag.
    runloop->m_isRunning = false;

    // TODO return different status for timed out versus stopped?
    return returnStatus;
}

void ar_runloop_wake(ar_runloop_t * runloop)
{
    ar_thread_t * thread = runloop->m_thread;
    if (runloop->m_isRunning && thread)
    {
        ar_thread_resume(thread);
    }
}

ar_status_t ar_runloop_stop(ar_runloop_t * runloop)
{
    if (!runloop)
    {
        return kArInvalidParameterError;
    }

    // Set the stop flag.
    runloop->m_stop = true;

    // Wake the runloop in case it is blocked.
    ar_runloop_wake(runloop);

    return kArSuccess;
}

ar_status_t ar_runloop_perform(ar_runloop_t * runloop, ar_runloop_function_t function, void * param)
{
    if (!runloop || !function)
    {
        return kArInvalidParameterError;
    }

    // TODO block if queue is full?
    int32_t tail = ar_kernel_atomic_queue_insert(1, runloop->m_functionCount, runloop->m_functionTail, AR_RUNLOOP_FUNCTION_QUEUE_SIZE);
    if (tail == -1)
    {
        return kArQueueFullError;
    }
    ar_runloop_t::_ar_runloop_function_info & fn = runloop->m_functions[tail];
    fn.function = function;
    fn.param = param;

    // Wake the runloop in case it is blocked.
    ar_runloop_wake(runloop);

    return kArSuccess;
}

ar_status_t ar_runloop_add_timer(ar_runloop_t * runloop, ar_timer_t * timer)
{
    if (!runloop || !timer)
    {
        return kArInvalidParameterError;
    }

    timer->m_runLoop = runloop;

    return kArSuccess;
}

ar_status_t ar_runloop_add_queue(ar_runloop_t * runloop, ar_queue_t * queue, ar_runloop_queue_handler_t callback, void * param)
{
    if (!runloop || !queue)
    {
        return kArInvalidParameterError;
    }

    // A queue can only be added to one runloop at a time.
    if (queue->m_runLoop != NULL && queue->m_runLoop != runloop)
    {
        return kArAlreadyAttachedError;
    }

    // Set runloop on the queue.
    queue->m_runLoopHandler = callback;
    queue->m_runLoopHandlerParam = param;
    queue->m_runLoop = runloop;

    return kArSuccess;
}

ar_runloop_t * ar_runloop_get_current(void)
{
    return g_ar.currentThread->m_runLoop;
}

const char * ar_runloop_get_name(ar_runloop_t * runloop)
{
    return runloop ? runloop->m_name : NULL;
}

//------------------------------------------------------------------------------
// EOF
//------------------------------------------------------------------------------
<commit_msg>Fixed nested runloop invocations clearing flags on exit.<commit_after>/*
 * Copyright (c) 2016-2018 Immo Software
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * o Redistributions of source code must retain the above copyright notice, this list
 *   of conditions and the following disclaimer.
 *
 * o 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.
 *
 * o Neither the name of the copyright holder 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 HOLDER 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.
 */
/*!
 * @file
 * @brief Source for Ar microkernel runloops.
 */

#include "ar_internal.h"
#include <string.h>
#include <assert.h>

using namespace Ar;

//------------------------------------------------------------------------------
// Code
//------------------------------------------------------------------------------

// See ar_kernel.h for documentation of this function.
ar_status_t ar_runloop_create(ar_runloop_t * runloop, const char * name)
{
    if (!runloop)
    {
        return kArInvalidParameterError;
    }
    if (ar_port_get_irq_state())
    {
        return kArNotFromInterruptError;
    }

    memset(runloop, 0, sizeof(ar_runloop_t));

    runloop->m_name = name ? name : AR_ANONYMOUS_OBJECT_NAME;
    runloop->m_timers.m_predicate = ar_timer_sort_by_wakeup;

#if AR_GLOBAL_OBJECT_LISTS
    runloop->m_createdNode.m_obj = runloop;
    g_ar_objects.runloops.add(&runloop->m_createdNode);
#endif

    return kArSuccess;
}

// See ar_kernel.h for documentation of this function.
ar_status_t ar_runloop_delete(ar_runloop_t * runloop)
{
    if (!runloop)
    {
        return kArInvalidParameterError;
    }
    if (ar_port_get_irq_state())
    {
        return kArNotFromInterruptError;
    }
    if (runloop->m_isRunning)
    {
        return kArInvalidStateError;
    }

#if AR_GLOBAL_OBJECT_LISTS
    g_ar_objects.runloops.remove(&runloop->m_createdNode);
#endif

    return kArSuccess;
}

ar_status_t ar_runloop_run(ar_runloop_t * runloop, uint32_t timeout, ar_runloop_result_t * object)
{
    if (!runloop)
    {
        return kArInvalidParameterError;
    }
    // It's ok to nest runs of the runloop, but only on a single thread.
    if (runloop->m_isRunning && runloop->m_thread != g_ar.currentThread)
    {
        return kArRunLoopAlreadyRunningError;
    }
    // Another check to make sure no other runloop is already running on the current thread.
    if (g_ar.currentThread->m_runLoop && g_ar.currentThread->m_runLoop != runloop)
    {
        return kArRunLoopAlreadyRunningError;
    }
    // Disallow running from interrupt context.
    if (ar_port_get_irq_state())
    {
        return kArNotFromInterruptError;
    }

    // Clear returned object.
    if (object)
    {
        object->m_queue = NULL;
    }

    bool isNested = runloop->m_isRunning;
    if (!isNested)
    {
        // Associate this runloop with the current thread.
        g_ar.currentThread->m_runLoop = runloop;
        runloop->m_thread = g_ar.currentThread;

        // Clear stop flag.
        runloop->m_stop = false;

        // Set running flag.
        runloop->m_isRunning = true;
    }

    // Prepare timeout.
    uint32_t startTime = g_ar.tickCount;
    uint32_t timeoutTicks = timeout;
    if (timeout != kArInfiniteTimeout)
    {
        timeoutTicks = ar_milliseconds_to_ticks(timeout);
    }

    ar_status_t returnStatus = kArRunLoopStopped;

    // Run it.
    do {
        // Invoke timers.
        ar_kernel_run_timers(runloop->m_timers);

        // Invoke one queued function.
        if (runloop->m_functionCount)
        {
            uint16_t i = runloop->m_functionHead;
            uint16_t iPlusOne = (i + 1) % AR_RUNLOOP_FUNCTION_QUEUE_SIZE;

            ar_runloop_t::_ar_runloop_function_info fn = runloop->m_functions[i];

            ar_atomic_add32(&runloop->m_functionCount, -1);
            // This is the only line that modifies m_functionHead.
            runloop->m_functionHead = iPlusOne;

            assert(fn.function);
            fn.function(fn.param);
        }

        // Check pending queues.
        if (!runloop->m_queues.isEmpty())
        {
            ar_queue_t * queue = runloop->m_queues.getHead<ar_queue_t>();
            assert(queue);
            if (queue->m_count < 2)
            {
                runloop->m_queues.remove(queue);
            }

            if (queue->m_count > 0)
            {
                if (queue->m_runLoopHandler)
                {
                    // Call out to run loop queue source handler.
                    queue->m_runLoopHandler(queue, queue->m_runLoopHandlerParam);
                }
                else
                {
                    // No handler associated with this queue, so exit the run loop.
                    if (object)
                    {
                        object->m_queue = queue;
                    }

                    returnStatus = kArRunLoopQueueReceived;
                    break;
                }
            }
        }

        // Check timeout. Adjust the timeout based on how long we've run so far.
        uint32_t blockTimeoutTicks = timeoutTicks;
        if (blockTimeoutTicks != kArInfiniteTimeout)
        {
            uint32_t deltaTicks = g_ar.tickCount - startTime;
            if (deltaTicks >= timeoutTicks)
            {
                // Timed out, exit runloop.
                returnStatus = kArTimeoutError;
                break;
            }
            blockTimeoutTicks -= deltaTicks;
        }

        // Make sure we don't sleep past the next scheduled timer.
        if (!runloop->m_timers.isEmpty())
        {
            ar_timer_t * timer = runloop->m_timers.getHead<ar_timer_t>();
            uint32_t wakeupDeltaTicks = timer->m_wakeupTime - g_ar.tickCount;
            // kArInfiniteTimeout is the max 32-bit value, so wakeupDeltaTicks will always be <=
            if (wakeupDeltaTicks < blockTimeoutTicks)
            {
                blockTimeoutTicks = wakeupDeltaTicks;
            }
        }

        // Don't sleep if there are queued functions or sources.
        if (!runloop->m_functionCount && runloop->m_queues.isEmpty())
        {
            // Sleep the runloop's thread for the adjusted timeout.
            uint32_t blockTimeout = (blockTimeoutTicks == kArInfiniteTimeout)
                                        ? kArInfiniteTimeout
                                        : ar_ticks_to_milliseconds(blockTimeoutTicks);
            if (blockTimeout)
            {
                ar_thread_sleep(blockTimeout);
            }
        }
    } while (!runloop->m_stop);

    if (!isNested)
    {
        // Clear associated thread.
        g_ar.currentThread->m_runLoop = NULL;
        runloop->m_thread = NULL;

        // Clear running flag.
        runloop->m_isRunning = false;
    }

    // TODO return different status for timed out versus stopped?
    return returnStatus;
}

void ar_runloop_wake(ar_runloop_t * runloop)
{
    ar_thread_t * thread = runloop->m_thread;
    if (runloop->m_isRunning && thread)
    {
        ar_thread_resume(thread);
    }
}

ar_status_t ar_runloop_stop(ar_runloop_t * runloop)
{
    if (!runloop)
    {
        return kArInvalidParameterError;
    }

    // Set the stop flag.
    runloop->m_stop = true;

    // Wake the runloop in case it is blocked.
    ar_runloop_wake(runloop);

    return kArSuccess;
}

ar_status_t ar_runloop_perform(ar_runloop_t * runloop, ar_runloop_function_t function, void * param)
{
    if (!runloop || !function)
    {
        return kArInvalidParameterError;
    }

    // TODO block if queue is full?
    int32_t tail = ar_kernel_atomic_queue_insert(1, runloop->m_functionCount, runloop->m_functionTail, AR_RUNLOOP_FUNCTION_QUEUE_SIZE);
    if (tail == -1)
    {
        return kArQueueFullError;
    }
    ar_runloop_t::_ar_runloop_function_info & fn = runloop->m_functions[tail];
    fn.function = function;
    fn.param = param;

    // Wake the runloop in case it is blocked.
    ar_runloop_wake(runloop);

    return kArSuccess;
}

ar_status_t ar_runloop_add_timer(ar_runloop_t * runloop, ar_timer_t * timer)
{
    if (!runloop || !timer)
    {
        return kArInvalidParameterError;
    }

    timer->m_runLoop = runloop;

    return kArSuccess;
}

ar_status_t ar_runloop_add_queue(ar_runloop_t * runloop, ar_queue_t * queue, ar_runloop_queue_handler_t callback, void * param)
{
    if (!runloop || !queue)
    {
        return kArInvalidParameterError;
    }

    // A queue can only be added to one runloop at a time.
    if (queue->m_runLoop != NULL && queue->m_runLoop != runloop)
    {
        return kArAlreadyAttachedError;
    }

    // Set runloop on the queue.
    queue->m_runLoopHandler = callback;
    queue->m_runLoopHandlerParam = param;
    queue->m_runLoop = runloop;

    return kArSuccess;
}

ar_runloop_t * ar_runloop_get_current(void)
{
    return g_ar.currentThread->m_runLoop;
}

const char * ar_runloop_get_name(ar_runloop_t * runloop)
{
    return runloop ? runloop->m_name : NULL;
}

//------------------------------------------------------------------------------
// EOF
//------------------------------------------------------------------------------
<|endoftext|>


<commit_before>#include <limits>
#include <numeric>
#include <cmath>
#include <vector>
#include <iostream>
#include <af/dim4.hpp>
#include <ArrayInfo.hpp>

namespace af
{

using std::vector;
using std::numeric_limits;
using std::abs;

dim4::dim4( dim_type first,
            dim_type second,
            dim_type third,
            dim_type fourth)
{
    dims[0] = first;
    dims[1] = second;
    dims[2] = third;
    dims[3] = fourth;
}

dim4::dim4(const dim4& other)
{
    dims[0] = other.dims[0];
    dims[1] = other.dims[1];
    dims[2] = other.dims[2];
    dims[3] = other.dims[3];
}

dim_type
dim4::elements() const
{
    return dims[0] * dims[1] * dims[2] * dims[3];
}

dim_type
dim4::elements()
{
    return static_cast<const dim4&>(*this).elements();
}

dim_type
dim4::ndims() const
{
    dim_type ret = 4;
    for(int i = 3; i >= 0; i--) {
        if(dims[i] == 1)    {   ret--;  }
        else                {   break;  }
    }
    return ret;
}

dim_type
dim4::ndims()
{
    return static_cast<const dim4&>(*this).ndims();
}

const dim_type&
dim4::operator[](const unsigned dim) const
{
    return dims[dim];
}

dim_type &
dim4::operator[](const unsigned dim)
{
    return const_cast<dim_type&>(static_cast<const dim4&>((*this))[dim]);
}

bool
dim4::operator==(const dim4 &other) const
{
    bool ret = true;
    for(unsigned i = 0; i < 4 && ret; i++) {
        ret = (*this)[i] == other[i];
    }
    return ret;
}

bool
dim4::operator!=(const dim4 &other) const
{
    return !((*this) == other);
}

dim4&
dim4::operator*=(const dim4 &other)
{
    for(unsigned i = 0; i < 4; i++) {
        (*this)[i] *= other[i];
    }
    return *this;
}

dim4&
dim4::operator+=(const dim4 &other)
{
    for(unsigned i = 0; i < 4; i++) {
        (*this)[i] = (*this)[i] + other[i];
    }
    return *this;
}

dim4&
dim4::operator-=(const dim4 &other)
{
    for(unsigned i = 0; i < 4; i++) {
        (*this)[i] = (*this)[i] - other[i];
    }
    return *this;
}

bool
isSpan(const af_seq &seq)          { return (seq.step == 0); }

size_t
seqElements(const af_seq &seq) {
    size_t out = 0;
    if      (seq.step > 0)  { out = ((seq.end - seq.begin) / abs(seq.step)) + 1;    }
    else if (seq.step < 0)  { out = ((seq.begin - seq.end) / abs(seq.step)) + 1;    }
    else                    { out = numeric_limits<size_t>::max();                  }

    return out;
}

dim4
toDims(const vector<af_seq>& seqs, dim4 parentDims)
{
    dim4 out(1, 1, 1, 1);
    for(unsigned i = 0; i < seqs.size(); i++ ) {
        if  (isSpan(seqs[i]))   { out[i] = parentDims[i];          }
        else                    { out[i] = seqElements(seqs[i]);   }
    }
    return out;
}

dim4
toOffset(const vector<af_seq>& seqs)
{
    dim4 out(0, 0, 0, 0);
    for(unsigned i = 0; i < seqs.size(); i++ ) {
        if      (seqs[i].step != 0) {   out[i] = seqs[i].begin; }
        else                        {   out[i] = 0;             }
    }
    return out;
}

dim4
toStride(const vector<af_seq>& seqs, af::dim4 parentDims)
{
    dim4 out(calcStrides(parentDims));
    for(unsigned i = 0; i < seqs.size(); i++ ) {
        if  (seqs[i].step != 0) {   out[i] *= seqs[i].step; }
    }
    return out;
}
}
<commit_msg>ndims() now returns atleast 1 instead of 0 from before.<commit_after>#include <limits>
#include <numeric>
#include <cmath>
#include <vector>
#include <iostream>
#include <af/dim4.hpp>
#include <ArrayInfo.hpp>

namespace af
{

using std::vector;
using std::numeric_limits;
using std::abs;

dim4::dim4( dim_type first,
            dim_type second,
            dim_type third,
            dim_type fourth)
{
    dims[0] = first;
    dims[1] = second;
    dims[2] = third;
    dims[3] = fourth;
}

dim4::dim4(const dim4& other)
{
    dims[0] = other.dims[0];
    dims[1] = other.dims[1];
    dims[2] = other.dims[2];
    dims[3] = other.dims[3];
}

dim_type
dim4::elements() const
{
    return dims[0] * dims[1] * dims[2] * dims[3];
}

dim_type
dim4::elements()
{
    return static_cast<const dim4&>(*this).elements();
}

dim_type
dim4::ndims() const
{
    dim_type ret = 4;
    for(int i = 3; i >= 1; i--) {
        if(dims[i] == 1)    {   ret--;  }
        else                {   break;  }
    }
    return ret;
}

dim_type
dim4::ndims()
{
    return static_cast<const dim4&>(*this).ndims();
}

const dim_type&
dim4::operator[](const unsigned dim) const
{
    return dims[dim];
}

dim_type &
dim4::operator[](const unsigned dim)
{
    return const_cast<dim_type&>(static_cast<const dim4&>((*this))[dim]);
}

bool
dim4::operator==(const dim4 &other) const
{
    bool ret = true;
    for(unsigned i = 0; i < 4 && ret; i++) {
        ret = (*this)[i] == other[i];
    }
    return ret;
}

bool
dim4::operator!=(const dim4 &other) const
{
    return !((*this) == other);
}

dim4&
dim4::operator*=(const dim4 &other)
{
    for(unsigned i = 0; i < 4; i++) {
        (*this)[i] *= other[i];
    }
    return *this;
}

dim4&
dim4::operator+=(const dim4 &other)
{
    for(unsigned i = 0; i < 4; i++) {
        (*this)[i] = (*this)[i] + other[i];
    }
    return *this;
}

dim4&
dim4::operator-=(const dim4 &other)
{
    for(unsigned i = 0; i < 4; i++) {
        (*this)[i] = (*this)[i] - other[i];
    }
    return *this;
}

bool
isSpan(const af_seq &seq)          { return (seq.step == 0); }

size_t
seqElements(const af_seq &seq) {
    size_t out = 0;
    if      (seq.step > 0)  { out = ((seq.end - seq.begin) / abs(seq.step)) + 1;    }
    else if (seq.step < 0)  { out = ((seq.begin - seq.end) / abs(seq.step)) + 1;    }
    else                    { out = numeric_limits<size_t>::max();                  }

    return out;
}

dim4
toDims(const vector<af_seq>& seqs, dim4 parentDims)
{
    dim4 out(1, 1, 1, 1);
    for(unsigned i = 0; i < seqs.size(); i++ ) {
        if  (isSpan(seqs[i]))   { out[i] = parentDims[i];          }
        else                    { out[i] = seqElements(seqs[i]);   }
    }
    return out;
}

dim4
toOffset(const vector<af_seq>& seqs)
{
    dim4 out(0, 0, 0, 0);
    for(unsigned i = 0; i < seqs.size(); i++ ) {
        if      (seqs[i].step != 0) {   out[i] = seqs[i].begin; }
        else                        {   out[i] = 0;             }
    }
    return out;
}

dim4
toStride(const vector<af_seq>& seqs, af::dim4 parentDims)
{
    dim4 out(calcStrides(parentDims));
    for(unsigned i = 0; i < seqs.size(); i++ ) {
        if  (seqs[i].step != 0) {   out[i] *= seqs[i].step; }
    }
    return out;
}
}
<|endoftext|>


<commit_before>/* This file is part of the KDE project
Copyright (C) 2010 Dominik Haumann <dhaumann kde org>

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License version 2 as published by the Free Software Foundation.

This library 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
Library General Public License for more details.

You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB.  If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/

#include "kwriteapp.h"

#include <ktexteditor/editor.h>
#include <ktexteditor/editorchooser.h>
#include <kcmdlineargs.h>
#include <kmessagebox.h>

#include <QFileInfo>
#include <QTextCodec>

KWriteApp::KWriteApp(KCmdLineArgs *m_args)
  : KApplication ()
  , m_args(m_args)
{
  m_editor = KTextEditor::EditorChooser::editor();

  if ( !m_editor )
  {
    KMessageBox::error(0, i18n("A KDE text-editor component could not be found.\n"
                                  "Please check your KDE installation."));
    exit(1);
  }

  // read from global config once
  m_editor->readConfig(KGlobal::config().data());

  KTextEditor::ContainerInterface *iface =
    qobject_cast<KTextEditor::ContainerInterface*>(m_editor);
  if (iface) {
    iface->setContainer(this);
  }

  init();
}

KWriteApp::~KWriteApp()
{
}

KWriteApp *KWriteApp::self ()
{
  return static_cast<KWriteApp *>(kapp);
}

void KWriteApp::init()
{
  if (isSessionRestored())
  {
    KWrite::restore();
  }
  else
  {
    bool nav = false;
    int line = 0, column = 0;

    QTextCodec *codec = m_args->isSet("encoding") ? QTextCodec::codecForName(m_args->getOption("encoding").toLocal8Bit()) : 0;

    if (m_args->isSet ("line"))
    {
      line = m_args->getOption ("line").toInt() - 1;
      nav = true;
    }

    if (m_args->isSet ("column"))
    {
      column = m_args->getOption ("column").toInt() - 1;
      nav = true;
    }

    if ( m_args->count() == 0 )
    {
        KWrite *t = new KWrite;

        if( m_args->isSet( "stdin" ) )
        {
          QTextStream input(stdin, QIODevice::ReadOnly);

          // set chosen codec
          if (codec)
            input.setCodec (codec);

          QString line;
          QString text;

          do
          {
            line = input.readLine();
            text.append( line + '\n' );
          } while( !line.isNull() );

          KTextEditor::Document *doc = t->view()->document();
          if( doc )
              doc->setText( text );
        }

        if (nav && t->view())
          t->view()->setCursorPosition (KTextEditor::Cursor (line, column));
    }
    else
    {
      int docs_opened = 0;
      for ( int z = 0; z < m_args->count(); z++ )
      {
        // this file is no local dir, open it, else warn
        bool noDir = !m_args->url(z).isLocalFile() || !QFileInfo (m_args->url(z).toLocalFile()).isDir();

        if (noDir)
        {
          ++docs_opened;
          KWrite *t = new KWrite();

          t->view()->document()->setSuppressOpeningErrorDialogs (true);

          if (codec)
            t->view()->document()->setEncoding(codec->name());

          t->loadURL( m_args->url( z ) );

          t->view()->document()->setSuppressOpeningErrorDialogs (false);

          if (nav)
            t->view()->setCursorPosition (KTextEditor::Cursor (line, column));
        }
        else
        {
          KMessageBox::sorry(0, i18n("The file '%1' could not be opened: it is not a normal file, it is a folder.", m_args->url(z).url()));
        }
      }
      if (!docs_opened) kapp->exit(1); // see http://bugs.kde.org/show_bug.cgi?id=124708
    }
  }

  // no window there, uh, ohh, for example borked session config !!!
  // create at least one !!
  if (KWrite::noWindows())
    new KWrite();
}

//BEGIN KTextEditor::MdiContainer
void KWriteApp::setActiveView(KTextEditor::View *view)
{
  Q_UNUSED(view)
  // NOTE: not implemented
}

KTextEditor::View *KWriteApp::activeView()
{
  KWrite *window = qobject_cast<KWrite*>(activeWindow());
  if (window) {
    return window->view();
  }
  return 0;
//   return KWriteApp::self()->activeMainWindow()->viewManager()->activeView();
}

KTextEditor::Document *KWriteApp::createDocument()
{
  // NOTE: not implemented
  kWarning() << "WARNING: interface call not implemented";
  return 0;
}

bool KWriteApp::closeDocument(KTextEditor::Document *doc)
{
  Q_UNUSED(doc)
  // NOTE: not implemented
  kWarning() << "WARNING: interface call not implemented";
  return false;
}

KTextEditor::View *KWriteApp::createView(KTextEditor::Document *doc)
{
  Q_UNUSED(doc)
  // NOTE: not implemented
  kWarning() << "WARNING: interface call not implemented";
  return 0;
}

bool KWriteApp::closeView(KTextEditor::View *view)
{
  Q_UNUSED(view)
  // NOTE: not implemented
  kWarning() << "WARNING: interface call not implemented";
  return false;
}
//END KTextEditor::MdiContainer

// kate: space-indent on; indent-width 2; replace-tabs on;

<commit_msg>use ::exit() istead of QCoreApplication::exit()<commit_after>/* This file is part of the KDE project
Copyright (C) 2010 Dominik Haumann <dhaumann kde org>

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License version 2 as published by the Free Software Foundation.

This library 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
Library General Public License for more details.

You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB.  If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/

#include "kwriteapp.h"

#include <ktexteditor/editor.h>
#include <ktexteditor/editorchooser.h>
#include <kcmdlineargs.h>
#include <kmessagebox.h>

#include <QFileInfo>
#include <QTextCodec>

KWriteApp::KWriteApp(KCmdLineArgs *m_args)
  : KApplication ()
  , m_args(m_args)
{
  m_editor = KTextEditor::EditorChooser::editor();

  if ( !m_editor )
  {
    KMessageBox::error(0, i18n("A KDE text-editor component could not be found.\n"
                                  "Please check your KDE installation."));
    ::exit(1); // ::exit() instead of exit(), that calls QCoreApplication::exit()
  }

  // read from global config once
  m_editor->readConfig(KGlobal::config().data());

  KTextEditor::ContainerInterface *iface =
    qobject_cast<KTextEditor::ContainerInterface*>(m_editor);
  if (iface) {
    iface->setContainer(this);
  }

  init();
}

KWriteApp::~KWriteApp()
{
}

KWriteApp *KWriteApp::self ()
{
  return static_cast<KWriteApp *>(kapp);
}

void KWriteApp::init()
{
  if (isSessionRestored())
  {
    KWrite::restore();
  }
  else
  {
    bool nav = false;
    int line = 0, column = 0;

    QTextCodec *codec = m_args->isSet("encoding") ? QTextCodec::codecForName(m_args->getOption("encoding").toLocal8Bit()) : 0;

    if (m_args->isSet ("line"))
    {
      line = m_args->getOption ("line").toInt() - 1;
      nav = true;
    }

    if (m_args->isSet ("column"))
    {
      column = m_args->getOption ("column").toInt() - 1;
      nav = true;
    }

    if ( m_args->count() == 0 )
    {
        KWrite *t = new KWrite;

        if( m_args->isSet( "stdin" ) )
        {
          QTextStream input(stdin, QIODevice::ReadOnly);

          // set chosen codec
          if (codec)
            input.setCodec (codec);

          QString line;
          QString text;

          do
          {
            line = input.readLine();
            text.append( line + '\n' );
          } while( !line.isNull() );

          KTextEditor::Document *doc = t->view()->document();
          if( doc )
              doc->setText( text );
        }

        if (nav && t->view())
          t->view()->setCursorPosition (KTextEditor::Cursor (line, column));
    }
    else
    {
      int docs_opened = 0;
      for ( int z = 0; z < m_args->count(); z++ )
      {
        // this file is no local dir, open it, else warn
        bool noDir = !m_args->url(z).isLocalFile() || !QFileInfo (m_args->url(z).toLocalFile()).isDir();

        if (noDir)
        {
          ++docs_opened;
          KWrite *t = new KWrite();

          t->view()->document()->setSuppressOpeningErrorDialogs (true);

          if (codec)
            t->view()->document()->setEncoding(codec->name());

          t->loadURL( m_args->url( z ) );

          t->view()->document()->setSuppressOpeningErrorDialogs (false);

          if (nav)
            t->view()->setCursorPosition (KTextEditor::Cursor (line, column));
        }
        else
        {
          KMessageBox::sorry(0, i18n("The file '%1' could not be opened: it is not a normal file, it is a folder.", m_args->url(z).url()));
        }
      }
      if (!docs_opened) kapp->exit(1); // see http://bugs.kde.org/show_bug.cgi?id=124708
    }
  }

  // no window there, uh, ohh, for example borked session config !!!
  // create at least one !!
  if (KWrite::noWindows())
    new KWrite();
}

//BEGIN KTextEditor::MdiContainer
void KWriteApp::setActiveView(KTextEditor::View *view)
{
  Q_UNUSED(view)
  // NOTE: not implemented
}

KTextEditor::View *KWriteApp::activeView()
{
  KWrite *window = qobject_cast<KWrite*>(activeWindow());
  if (window) {
    return window->view();
  }
  return 0;
//   return KWriteApp::self()->activeMainWindow()->viewManager()->activeView();
}

KTextEditor::Document *KWriteApp::createDocument()
{
  // NOTE: not implemented
  kWarning() << "WARNING: interface call not implemented";
  return 0;
}

bool KWriteApp::closeDocument(KTextEditor::Document *doc)
{
  Q_UNUSED(doc)
  // NOTE: not implemented
  kWarning() << "WARNING: interface call not implemented";
  return false;
}

KTextEditor::View *KWriteApp::createView(KTextEditor::Document *doc)
{
  Q_UNUSED(doc)
  // NOTE: not implemented
  kWarning() << "WARNING: interface call not implemented";
  return 0;
}

bool KWriteApp::closeView(KTextEditor::View *view)
{
  Q_UNUSED(view)
  // NOTE: not implemented
  kWarning() << "WARNING: interface call not implemented";
  return false;
}
//END KTextEditor::MdiContainer

// kate: space-indent on; indent-width 2; replace-tabs on;

<|endoftext|>


<commit_before>// Copyright (c) 2010-2020, Lawrence Livermore National Security, LLC. Produced
// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
// LICENSE and NOTICE for details. LLNL-CODE-806117.
//
// This file is part of the MFEM library. For more information and source code
// availability visit https://mfem.org.
//
// MFEM is free software; you can redistribute it and/or modify it under the
// terms of the BSD-3 license. We welcome feedback and contributions, see file
// CONTRIBUTING.md for details.

#ifndef MFEM_LIBCEED_HPP
#define MFEM_LIBCEED_HPP

#include "../../config/config.hpp"

#ifdef MFEM_USE_CEED
#include "../../general/device.hpp"
#include "../../linalg/vector.hpp"
#include <ceed.h>
#include <ceed-hash.h>
#include <tuple>
#include <unordered_map>

namespace mfem
{

class FiniteElementSpace;
class GridFunction;
class IntegrationRule;
class Coefficient;

// Hash table for CeedBasis
using CeedBasisKey = std::tuple<FiniteElementSpace*, IntegrationRule*, int, int>;
struct CeedBasisHash
{
   std::size_t operator()(const CeedBasisKey& k) const
   {
      return CeedHashCombine(CeedHashCombine(CeedHashInt(reinterpret_cast<CeedHash64_t>(std::get<0>(k))),
                                             CeedHashInt(reinterpret_cast<CeedHash64_t>(std::get<1>(k)))),
                             CeedHashCombine(CeedHashInt(std::get<2>(k)),
                                             CeedHashInt(std::get<3>(k))));
   }
};
using CeedBasisMap = std::unordered_map<const CeedBasisKey, CeedBasis, CeedBasisHash>;

// Hash table for CeedElemRestriction
using CeedRestrKey = std::tuple<FiniteElementSpace*, int, int>;
struct CeedRestrHash
{
   std::size_t operator()(const CeedRestrKey& k) const
   {
      return CeedHashCombine(CeedHashCombine(CeedHashInt(reinterpret_cast<CeedHash64_t>(std::get<0>(k))),
                                             CeedHashInt(std::get<1>(k))),
                             CeedHashInt(std::get<2>(k)));
   }
};
using CeedRestrMap = std::unordered_map<const CeedRestrKey, CeedElemRestriction, CeedRestrHash>;

namespace internal {
   extern Ceed ceed; // defined in device.cpp
   extern CeedBasisMap basis_map;
   extern CeedRestrMap restr_map;
}

/// A structure used to pass additional data to f_build_diff and f_apply_diff
struct BuildContext { CeedInt dim, space_dim; CeedScalar coeff; };

enum class CeedCoeff { Const, Grid };

struct CeedConstCoeff
{
   double val;
};

struct CeedGridCoeff
{
   const GridFunction* coeff;
   CeedBasis basis;
   CeedElemRestriction restr;
   CeedVector coeffVector;
};

struct CeedData
{
   CeedOperator build_oper, oper;
   CeedBasis basis, mesh_basis;
   CeedElemRestriction restr, mesh_restr, restr_i, mesh_restr_i;
   CeedQFunction apply_qfunc, build_qfunc;
   CeedVector node_coords, rho;
   CeedCoeff coeff_type;
   void* coeff;
   CeedQFunctionContext build_ctx;
   BuildContext build_ctx_data;

   CeedVector u, v;

   ~CeedData()
   {
      CeedOperatorDestroy(&build_oper);
      CeedOperatorDestroy(&oper);
      CeedElemRestrictionDestroy(&restr_i);
      CeedElemRestrictionDestroy(&mesh_restr_i);
      CeedQFunctionDestroy(&apply_qfunc);
      CeedQFunctionDestroy(&build_qfunc);
      CeedVectorDestroy(&node_coords);
      CeedVectorDestroy(&rho);
      if (coeff_type==CeedCoeff::Grid)
      {
         CeedGridCoeff* c = (CeedGridCoeff*)coeff;
         CeedBasisDestroy(&c->basis);
         CeedElemRestrictionDestroy(&c->restr);
         CeedVectorDestroy(&c->coeffVector);
         delete c;
      }
      else
      {
         delete (CeedConstCoeff*)coeff;
      }
      CeedVectorDestroy(&u);
      CeedVectorDestroy(&v);
   }

};

/** This structure contains the data to assemble a PA operator with libCEED.
    See libceed/mass.cpp or libceed/diffusion.cpp for examples. */
struct CeedPAOperator
{
   /** The finite element space for the trial and test functions. */
   const FiniteElementSpace &fes;
   /** The Integration Rule to use to compote the operator. */
   const IntegrationRule &ir;
   /** The number of quadrature data at each quadrature point. */
   int qdatasize;
   /** The path to the header containing the functions for libCEED. */
   std::string header;
   /** The name of the Qfunction to build the quadrature data with a constant
       coefficient.*/
   std::string const_func;
   /** The Qfunction to build the quadrature data with constant coefficient. */
   CeedQFunctionUser const_qf;
   /** The name of the Qfunction to build the quadrature data with grid function
       coefficient. */
   std::string grid_func;
   /** The Qfunction to build the quad. data with grid function coefficient. */
   CeedQFunctionUser grid_qf;
   /** The name of the Qfunction to apply the operator. */
   std::string apply_func;
   /** The Qfunction to apply the operator. */
   CeedQFunctionUser apply_qf;
   /** The evaluation mode to apply to the trial function (CEED_EVAL_INTERP,
       CEED_EVAL_GRAD, etc.) */
   CeedEvalMode trial_op;
   /** The evaluation mode to apply to the test function ( CEED_EVAL_INTERP,
       CEED_EVAL_GRAD, etc.)*/
   CeedEvalMode test_op;
};

/** @brief Identifies the type of coefficient of the Integrator to initialize
    accordingly the CeedData. */
void InitCeedCoeff(Coefficient* Q, CeedData* ptr);

/// Initialize a CeedBasis and a CeedElemRestriction
void InitCeedBasisAndRestriction(const FiniteElementSpace &fes,
                                 const IntegrationRule &ir,
                                 Ceed ceed, CeedBasis *basis,
                                 CeedElemRestriction *restr);

/// Return the path to the libCEED q-function headers.
const std::string &GetCeedPath();

/** This function initializes an arbitrary linear operator using the partial
    assembly decomposition in libCEED. The operator details are described by the
    struct CEEDPAOperator input. */
void CeedPAAssemble(const CeedPAOperator& op,
                    CeedData& ceedData);

/** @brief Function that applies a libCEED PA operator. */
void CeedAddMultPA(const CeedData *ceedDataPtr,
                   const Vector &x,
                   Vector &y);

/** @brief Function that assembles a libCEED PA operator diagonal. */
void CeedAssembleDiagonalPA(const CeedData *ceedDataPtr,
                            Vector &diag);

/** @brief Function that determines if a CEED kernel should be used, based on
    the current mfem::Device configuration. */
inline bool DeviceCanUseCeed()
{
   return Device::Allows(Backend::CEED_CUDA) ||
          (Device::Allows(Backend::CEED_CPU) &&
           !Device::Allows(Backend::DEVICE_MASK|Backend::OMP_MASK));
}

} // namespace mfem

#else // MFEM_USE_CEED

namespace mfem
{
inline bool DeviceCanUseCeed()
{
   return false;
}

} // namespace mfem

#endif // MFEM_USE_CEED

#endif // MFEM_LIBCEED_HPP
<commit_msg>style updates from Travis<commit_after>// Copyright (c) 2010-2020, Lawrence Livermore National Security, LLC. Produced
// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
// LICENSE and NOTICE for details. LLNL-CODE-806117.
//
// This file is part of the MFEM library. For more information and source code
// availability visit https://mfem.org.
//
// MFEM is free software; you can redistribute it and/or modify it under the
// terms of the BSD-3 license. We welcome feedback and contributions, see file
// CONTRIBUTING.md for details.

#ifndef MFEM_LIBCEED_HPP
#define MFEM_LIBCEED_HPP

#include "../../config/config.hpp"

#ifdef MFEM_USE_CEED
#include "../../general/device.hpp"
#include "../../linalg/vector.hpp"
#include <ceed.h>
#include <ceed-hash.h>
#include <tuple>
#include <unordered_map>

namespace mfem
{

class FiniteElementSpace;
class GridFunction;
class IntegrationRule;
class Coefficient;

// Hash table for CeedBasis
using CeedBasisKey =
   std::tuple<FiniteElementSpace*, IntegrationRule*, int, int>;
struct CeedBasisHash
{
   std::size_t operator()(const CeedBasisKey& k) const
   {
      return CeedHashCombine(CeedHashCombine(CeedHashInt(
                                                reinterpret_cast<CeedHash64_t>(std::get<0>(k))),
                                             CeedHashInt(
                                                reinterpret_cast<CeedHash64_t>(std::get<1>(k)))),
                             CeedHashCombine(CeedHashInt(std::get<2>(k)),
                                             CeedHashInt(std::get<3>(k))));
   }
};
using CeedBasisMap =
   std::unordered_map<const CeedBasisKey, CeedBasis, CeedBasisHash>;

// Hash table for CeedElemRestriction
using CeedRestrKey = std::tuple<FiniteElementSpace*, int, int>;
struct CeedRestrHash
{
   std::size_t operator()(const CeedRestrKey& k) const
   {
      return CeedHashCombine(CeedHashCombine(CeedHashInt(
                                                reinterpret_cast<CeedHash64_t>(std::get<0>(k))),
                                             CeedHashInt(std::get<1>(k))),
                             CeedHashInt(std::get<2>(k)));
   }
};
using CeedRestrMap =
   std::unordered_map<const CeedRestrKey, CeedElemRestriction, CeedRestrHash>;

namespace internal
{
extern Ceed ceed; // defined in device.cpp
extern CeedBasisMap basis_map;
extern CeedRestrMap restr_map;
}

/// A structure used to pass additional data to f_build_diff and f_apply_diff
struct BuildContext { CeedInt dim, space_dim; CeedScalar coeff; };

enum class CeedCoeff { Const, Grid };

struct CeedConstCoeff
{
   double val;
};

struct CeedGridCoeff
{
   const GridFunction* coeff;
   CeedBasis basis;
   CeedElemRestriction restr;
   CeedVector coeffVector;
};

struct CeedData
{
   CeedOperator build_oper, oper;
   CeedBasis basis, mesh_basis;
   CeedElemRestriction restr, mesh_restr, restr_i, mesh_restr_i;
   CeedQFunction apply_qfunc, build_qfunc;
   CeedVector node_coords, rho;
   CeedCoeff coeff_type;
   void* coeff;
   CeedQFunctionContext build_ctx;
   BuildContext build_ctx_data;

   CeedVector u, v;

   ~CeedData()
   {
      CeedOperatorDestroy(&build_oper);
      CeedOperatorDestroy(&oper);
      CeedElemRestrictionDestroy(&restr_i);
      CeedElemRestrictionDestroy(&mesh_restr_i);
      CeedQFunctionDestroy(&apply_qfunc);
      CeedQFunctionDestroy(&build_qfunc);
      CeedVectorDestroy(&node_coords);
      CeedVectorDestroy(&rho);
      if (coeff_type==CeedCoeff::Grid)
      {
         CeedGridCoeff* c = (CeedGridCoeff*)coeff;
         CeedBasisDestroy(&c->basis);
         CeedElemRestrictionDestroy(&c->restr);
         CeedVectorDestroy(&c->coeffVector);
         delete c;
      }
      else
      {
         delete (CeedConstCoeff*)coeff;
      }
      CeedVectorDestroy(&u);
      CeedVectorDestroy(&v);
   }

};

/** This structure contains the data to assemble a PA operator with libCEED.
    See libceed/mass.cpp or libceed/diffusion.cpp for examples. */
struct CeedPAOperator
{
   /** The finite element space for the trial and test functions. */
   const FiniteElementSpace &fes;
   /** The Integration Rule to use to compote the operator. */
   const IntegrationRule &ir;
   /** The number of quadrature data at each quadrature point. */
   int qdatasize;
   /** The path to the header containing the functions for libCEED. */
   std::string header;
   /** The name of the Qfunction to build the quadrature data with a constant
       coefficient.*/
   std::string const_func;
   /** The Qfunction to build the quadrature data with constant coefficient. */
   CeedQFunctionUser const_qf;
   /** The name of the Qfunction to build the quadrature data with grid function
       coefficient. */
   std::string grid_func;
   /** The Qfunction to build the quad. data with grid function coefficient. */
   CeedQFunctionUser grid_qf;
   /** The name of the Qfunction to apply the operator. */
   std::string apply_func;
   /** The Qfunction to apply the operator. */
   CeedQFunctionUser apply_qf;
   /** The evaluation mode to apply to the trial function (CEED_EVAL_INTERP,
       CEED_EVAL_GRAD, etc.) */
   CeedEvalMode trial_op;
   /** The evaluation mode to apply to the test function ( CEED_EVAL_INTERP,
       CEED_EVAL_GRAD, etc.)*/
   CeedEvalMode test_op;
};

/** @brief Identifies the type of coefficient of the Integrator to initialize
    accordingly the CeedData. */
void InitCeedCoeff(Coefficient* Q, CeedData* ptr);

/// Initialize a CeedBasis and a CeedElemRestriction
void InitCeedBasisAndRestriction(const FiniteElementSpace &fes,
                                 const IntegrationRule &ir,
                                 Ceed ceed, CeedBasis *basis,
                                 CeedElemRestriction *restr);

/// Return the path to the libCEED q-function headers.
const std::string &GetCeedPath();

/** This function initializes an arbitrary linear operator using the partial
    assembly decomposition in libCEED. The operator details are described by the
    struct CEEDPAOperator input. */
void CeedPAAssemble(const CeedPAOperator& op,
                    CeedData& ceedData);

/** @brief Function that applies a libCEED PA operator. */
void CeedAddMultPA(const CeedData *ceedDataPtr,
                   const Vector &x,
                   Vector &y);

/** @brief Function that assembles a libCEED PA operator diagonal. */
void CeedAssembleDiagonalPA(const CeedData *ceedDataPtr,
                            Vector &diag);

/** @brief Function that determines if a CEED kernel should be used, based on
    the current mfem::Device configuration. */
inline bool DeviceCanUseCeed()
{
   return Device::Allows(Backend::CEED_CUDA) ||
          (Device::Allows(Backend::CEED_CPU) &&
           !Device::Allows(Backend::DEVICE_MASK|Backend::OMP_MASK));
}

} // namespace mfem

#else // MFEM_USE_CEED

namespace mfem
{
inline bool DeviceCanUseCeed()
{
   return false;
}

} // namespace mfem

#endif // MFEM_USE_CEED

#endif // MFEM_LIBCEED_HPP
<|endoftext|>


<commit_before>#ifndef __ET_HEADERS__
#define __ET_HEADERS__

#define CPPHTTPLIB_ZLIB_SUPPORT (1)
#define CPPHTTPLIB_OPENSSL_SUPPORT (1)
// httplib has to come before windows.h
#include "httplib.h"

#if __FreeBSD__
#define _WITH_GETLINE
#endif

#if __APPLE__
#include <sys/ucred.h>
#include <util.h>
#elif __FreeBSD__
#include <libutil.h>
#include <sys/socket.h>
#elif __NetBSD__  // do not need pty.h on NetBSD
#include <util.h>
#elif defined(_MSC_VER)
#include <WinSock2.h>
#include <Ws2tcpip.h>
#include <afunix.h>
#include <signal.h>

#include <codecvt>
inline int close(int fd) { return ::closesocket(fd); }
#else
#include <pty.h>
#include <signal.h>
#endif

#ifdef WIN32
#else
#include <arpa/inet.h>
#include <grp.h>
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <paths.h>
#include <pthread.h>
#include <pwd.h>
#include <resolv.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/wait.h>
#include <termios.h>
#include <unistd.h>
#endif

#include <errno.h>
#include <fcntl.h>
#include <google/protobuf/message_lite.h>
#include <sodium.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <time.h>

#include <algorithm>
#include <array>
#include <atomic>
#include <ctime>
#include <deque>
#include <exception>
#include <fstream>
#include <iostream>
#include <locale>
#include <memory>
#include <mutex>
#include <set>
#include <sstream>
#include <streambuf>
#include <string>
#include <thread>
#include <unordered_map>
#include <unordered_set>
#include <vector>

#if __has_include(<filesystem>)
#include <filesystem>
#else
#include <experimental/filesystem>
using namespace std::experimental;
#endif

#include "ET.pb.h"
#include "ETerminal.pb.h"
#include "ThreadPool.h"
#include "base64.h"
#include "easylogging++.h"
#include "sago/platform_folders.h"
#include "sole.hpp"

#if !defined(__ANDROID__)
#include "ust.hpp"
#endif

#ifdef WITH_UTEMPTER
#include <utempter.h>
#endif

#if defined(_MSC_VER)
#define popen _popen
#define pclose _pclose

/* ssize_t is not defined on Windows */
#ifndef ssize_t
#if defined(_WIN64)
typedef signed __int64 ssize_t;
#else
typedef int ssize_t;
#endif
#endif /* !ssize_t */

/* On MSVC, ssize_t is SSIZE_T */
#ifdef _MSC_VER
#include <BaseTsd.h>
#define ssize_t SSIZE_T
#endif

#endif

using namespace std;

// The ET protocol version supported by this binary
static const int PROTOCOL_VERSION = 6;

// Nonces for CryptoHandler
static const unsigned char CLIENT_SERVER_NONCE_MSB = 0;
static const unsigned char SERVER_CLIENT_NONCE_MSB = 1;

// system ssh config files
const string SYSTEM_SSH_CONFIG_PATH = "/etc/ssh/ssh_config";
const string USER_SSH_CONFIG_PATH = "/.ssh/config";

// Keepalive configs
const int CLIENT_KEEP_ALIVE_DURATION = 5;
// This should be at least double the value of CLIENT_KEEP_ALIVE_DURATION to
// allow enough time.
const int SERVER_KEEP_ALIVE_DURATION = 11;

#if defined(__ANDROID__)
#define STFATAL LOG(FATAL) << "No Stack Trace on Android" << endl

#define STERROR LOG(ERROR) << "No Stack Trace on Android" << endl
#else
#define STFATAL LOG(FATAL) << "Stack Trace: " << endl << ust::generate()

#define STERROR LOG(ERROR) << "Stack Trace: " << endl << ust::generate()
#endif

#ifdef WIN32
inline string WindowsErrnoToString() {
  const int BUFSIZE = 4096;
  char buf[BUFSIZE];
  FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
                     FORMAT_MESSAGE_IGNORE_INSERTS,
                 NULL, WSAGetLastError(),
                 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf, BUFSIZE, NULL);
  string s(buf, BUFSIZE);
  return s;
}
#define FATAL_FAIL(X)                             \
  if (((X) == -1))                                \
    LOG(FATAL) << "Error: (" << WSAGetLastError() \
               << "): " << WindowsErrnoToString();

#define FATAL_FAIL_UNLESS_EINVAL(X) FATAL_FAIL(X)

#else
#define FATAL_FAIL(X) \
  if (((X) == -1)) STFATAL << "Error: (" << errno << "): " << strerror(errno);

// On BSD/OSX we can get EINVAL if the remote side has closed the connection
// before we have initialized it.
#define FATAL_FAIL_UNLESS_EINVAL(X)   \
  if (((X) == -1) && errno != EINVAL) \
    STFATAL << "Error: (" << errno << "): " << strerror(errno);
#endif

#ifndef ET_VERSION
#define ET_VERSION "unknown"
#endif

namespace et {
inline std::ostream& operator<<(std::ostream& os,
                                const et::SocketEndpoint& se) {
  if (se.has_name()) {
    os << se.name();
  }
  if (se.has_port()) {
    os << ":" << se.port();
  }
  return os;
}

template <typename Out>
inline void split(const std::string& s, char delim, Out result) {
  std::stringstream ss;
  ss.str(s);
  std::string item;
  while (std::getline(ss, item, delim)) {
    *(result++) = item;
  }
}

inline std::vector<std::string> split(const std::string& s, char delim) {
  std::vector<std::string> elems;
  split(s, delim, std::back_inserter(elems));
  return elems;
}

inline bool replace(std::string& str, const std::string& from,
                    const std::string& to) {
  size_t start_pos = str.find(from);
  if (start_pos == std::string::npos) return false;
  str.replace(start_pos, from.length(), to);
  return true;
}

inline int replaceAll(std::string& str, const std::string& from,
                      const std::string& to) {
  if (from.empty()) return 0;
  int retval = 0;
  size_t start_pos = 0;
  while ((start_pos = str.find(from, start_pos)) != std::string::npos) {
    retval++;
    str.replace(start_pos, from.length(), to);
    start_pos += to.length();  // In case 'to' contains 'from', like replacing
                               // 'x' with 'yx'
  }
  return retval;
}

template <typename T>
inline T stringToProto(const string& s) {
  T t;
  if (!t.ParseFromString(s)) {
    STFATAL << "Error parsing string to proto: " << s.length() << " " << s;
  }
  return t;
}

template <typename T>
inline string protoToString(const T& t) {
  string s;
  if (!t.SerializeToString(&s)) {
    STFATAL << "Error serializing proto to string";
  }
  return s;
}

inline bool waitOnSocketData(int fd) {
  fd_set fdset;
  FD_ZERO(&fdset);
  FD_SET(fd, &fdset);
  timeval tv;
  tv.tv_sec = 1;
  tv.tv_usec = 0;
  VLOG(4) << "Before selecting sockFd";
  FATAL_FAIL(select(fd + 1, &fdset, NULL, NULL, &tv));
  return FD_ISSET(fd, &fdset);
}

inline string genRandomAlphaNum(int len) {
  static const char alphanum[] =
      "0123456789"
      "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
      "abcdefghijklmnopqrstuvwxyz";
  string s(len, '\0');

  for (int i = 0; i < len; ++i) {
    s[i] = alphanum[randombytes_uniform(sizeof(alphanum) - 1)];
  }

  return s;
}

inline string GetTempDirectory() {
#ifdef WIN32
  WCHAR buf[65536];
  int retval = GetTempPath(65536, buf);
  int a = 0;
  std::wstring_convert<std::codecvt_utf8_utf16<wchar_t> > converter;
  std::string tmpDir = converter.to_bytes(wstring(buf, retval));
#else
  string tmpDir = _PATH_TMP;
#endif
  return tmpDir;
}

inline void HandleTerminate() {
  std::set_terminate([]() -> void {
    std::exception_ptr eptr = std::current_exception();
    if (eptr) {
      try {
        std::rethrow_exception(eptr);
      } catch (const std::exception& e) {
        STFATAL << "Uncaught c++ exception: " << e.what();
      }
    } else {
      STFATAL << "Uncaught c++ exception (unknown)";
    }
  });
}

inline void InterruptSignalHandler(int signum) {
  STERROR << "Got interrupt";
  CLOG(INFO, "stdout") << endl
                       << "Got interrupt (perhaps ctrl+c?).  Exiting." << endl;
  ::exit(signum);
}

}  // namespace et

inline bool operator==(const google::protobuf::MessageLite& msg_a,
                       const google::protobuf::MessageLite& msg_b) {
  return (msg_a.GetTypeName() == msg_b.GetTypeName()) &&
         (msg_a.SerializeAsString() == msg_b.SerializeAsString());
}

inline bool operator!=(const google::protobuf::MessageLite& msg_a,
                       const google::protobuf::MessageLite& msg_b) {
  return (msg_a.GetTypeName() != msg_b.GetTypeName()) ||
         (msg_a.SerializeAsString() != msg_b.SerializeAsString());
}

#endif
<commit_msg>Do not handle termination more than once.  #423<commit_after>#ifndef __ET_HEADERS__
#define __ET_HEADERS__

#define CPPHTTPLIB_ZLIB_SUPPORT (1)
#define CPPHTTPLIB_OPENSSL_SUPPORT (1)
// httplib has to come before windows.h
#include "httplib.h"

#if __FreeBSD__
#define _WITH_GETLINE
#endif

#if __APPLE__
#include <sys/ucred.h>
#include <util.h>
#elif __FreeBSD__
#include <libutil.h>
#include <sys/socket.h>
#elif __NetBSD__  // do not need pty.h on NetBSD
#include <util.h>
#elif defined(_MSC_VER)
#include <WinSock2.h>
#include <Ws2tcpip.h>
#include <afunix.h>
#include <signal.h>

#include <codecvt>
inline int close(int fd) { return ::closesocket(fd); }
#else
#include <pty.h>
#include <signal.h>
#endif

#ifdef WIN32
#else
#include <arpa/inet.h>
#include <grp.h>
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <paths.h>
#include <pthread.h>
#include <pwd.h>
#include <resolv.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/wait.h>
#include <termios.h>
#include <unistd.h>
#endif

#include <errno.h>
#include <fcntl.h>
#include <google/protobuf/message_lite.h>
#include <sodium.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <time.h>

#include <algorithm>
#include <array>
#include <atomic>
#include <ctime>
#include <deque>
#include <exception>
#include <fstream>
#include <iostream>
#include <locale>
#include <memory>
#include <mutex>
#include <set>
#include <sstream>
#include <streambuf>
#include <string>
#include <thread>
#include <unordered_map>
#include <unordered_set>
#include <vector>

#if __has_include(<filesystem>)
#include <filesystem>
#else
#include <experimental/filesystem>
using namespace std::experimental;
#endif

#include "ET.pb.h"
#include "ETerminal.pb.h"
#include "ThreadPool.h"
#include "base64.h"
#include "easylogging++.h"
#include "sago/platform_folders.h"
#include "sole.hpp"

#if !defined(__ANDROID__)
#include "ust.hpp"
#endif

#ifdef WITH_UTEMPTER
#include <utempter.h>
#endif

#if defined(_MSC_VER)
#define popen _popen
#define pclose _pclose

/* ssize_t is not defined on Windows */
#ifndef ssize_t
#if defined(_WIN64)
typedef signed __int64 ssize_t;
#else
typedef int ssize_t;
#endif
#endif /* !ssize_t */

/* On MSVC, ssize_t is SSIZE_T */
#ifdef _MSC_VER
#include <BaseTsd.h>
#define ssize_t SSIZE_T
#endif

#endif

using namespace std;

// The ET protocol version supported by this binary
static const int PROTOCOL_VERSION = 6;

// Nonces for CryptoHandler
static const unsigned char CLIENT_SERVER_NONCE_MSB = 0;
static const unsigned char SERVER_CLIENT_NONCE_MSB = 1;

// system ssh config files
const string SYSTEM_SSH_CONFIG_PATH = "/etc/ssh/ssh_config";
const string USER_SSH_CONFIG_PATH = "/.ssh/config";

// Keepalive configs
const int CLIENT_KEEP_ALIVE_DURATION = 5;
// This should be at least double the value of CLIENT_KEEP_ALIVE_DURATION to
// allow enough time.
const int SERVER_KEEP_ALIVE_DURATION = 11;

#if defined(__ANDROID__)
#define STFATAL LOG(FATAL) << "No Stack Trace on Android" << endl

#define STERROR LOG(ERROR) << "No Stack Trace on Android" << endl
#else
#define STFATAL LOG(FATAL) << "Stack Trace: " << endl << ust::generate()

#define STERROR LOG(ERROR) << "Stack Trace: " << endl << ust::generate()
#endif

#ifdef WIN32
inline string WindowsErrnoToString() {
  const int BUFSIZE = 4096;
  char buf[BUFSIZE];
  FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
                     FORMAT_MESSAGE_IGNORE_INSERTS,
                 NULL, WSAGetLastError(),
                 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf, BUFSIZE, NULL);
  string s(buf, BUFSIZE);
  return s;
}
#define FATAL_FAIL(X)                             \
  if (((X) == -1))                                \
    LOG(FATAL) << "Error: (" << WSAGetLastError() \
               << "): " << WindowsErrnoToString();

#define FATAL_FAIL_UNLESS_EINVAL(X) FATAL_FAIL(X)

#else
#define FATAL_FAIL(X) \
  if (((X) == -1)) STFATAL << "Error: (" << errno << "): " << strerror(errno);

// On BSD/OSX we can get EINVAL if the remote side has closed the connection
// before we have initialized it.
#define FATAL_FAIL_UNLESS_EINVAL(X)   \
  if (((X) == -1) && errno != EINVAL) \
    STFATAL << "Error: (" << errno << "): " << strerror(errno);
#endif

#ifndef ET_VERSION
#define ET_VERSION "unknown"
#endif

namespace et {
inline std::ostream& operator<<(std::ostream& os,
                                const et::SocketEndpoint& se) {
  if (se.has_name()) {
    os << se.name();
  }
  if (se.has_port()) {
    os << ":" << se.port();
  }
  return os;
}

template <typename Out>
inline void split(const std::string& s, char delim, Out result) {
  std::stringstream ss;
  ss.str(s);
  std::string item;
  while (std::getline(ss, item, delim)) {
    *(result++) = item;
  }
}

inline std::vector<std::string> split(const std::string& s, char delim) {
  std::vector<std::string> elems;
  split(s, delim, std::back_inserter(elems));
  return elems;
}

inline bool replace(std::string& str, const std::string& from,
                    const std::string& to) {
  size_t start_pos = str.find(from);
  if (start_pos == std::string::npos) return false;
  str.replace(start_pos, from.length(), to);
  return true;
}

inline int replaceAll(std::string& str, const std::string& from,
                      const std::string& to) {
  if (from.empty()) return 0;
  int retval = 0;
  size_t start_pos = 0;
  while ((start_pos = str.find(from, start_pos)) != std::string::npos) {
    retval++;
    str.replace(start_pos, from.length(), to);
    start_pos += to.length();  // In case 'to' contains 'from', like replacing
                               // 'x' with 'yx'
  }
  return retval;
}

template <typename T>
inline T stringToProto(const string& s) {
  T t;
  if (!t.ParseFromString(s)) {
    STFATAL << "Error parsing string to proto: " << s.length() << " " << s;
  }
  return t;
}

template <typename T>
inline string protoToString(const T& t) {
  string s;
  if (!t.SerializeToString(&s)) {
    STFATAL << "Error serializing proto to string";
  }
  return s;
}

inline bool waitOnSocketData(int fd) {
  fd_set fdset;
  FD_ZERO(&fdset);
  FD_SET(fd, &fdset);
  timeval tv;
  tv.tv_sec = 1;
  tv.tv_usec = 0;
  VLOG(4) << "Before selecting sockFd";
  FATAL_FAIL(select(fd + 1, &fdset, NULL, NULL, &tv));
  return FD_ISSET(fd, &fdset);
}

inline string genRandomAlphaNum(int len) {
  static const char alphanum[] =
      "0123456789"
      "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
      "abcdefghijklmnopqrstuvwxyz";
  string s(len, '\0');

  for (int i = 0; i < len; ++i) {
    s[i] = alphanum[randombytes_uniform(sizeof(alphanum) - 1)];
  }

  return s;
}

inline string GetTempDirectory() {
#ifdef WIN32
  WCHAR buf[65536];
  int retval = GetTempPath(65536, buf);
  int a = 0;
  std::wstring_convert<std::codecvt_utf8_utf16<wchar_t> > converter;
  std::string tmpDir = converter.to_bytes(wstring(buf, retval));
#else
  string tmpDir = _PATH_TMP;
#endif
  return tmpDir;
}

inline void HandleTerminate() {
  static bool first = true;
  if (first) {
    first = false;
  } else {
    // If we are recursively terminating, just bail
    return;
  }
  std::set_terminate([]() -> void {
    std::exception_ptr eptr = std::current_exception();
    if (eptr) {
      try {
        std::rethrow_exception(eptr);
      } catch (const std::exception& e) {
        STFATAL << "Uncaught c++ exception: " << e.what();
      }
    } else {
      STFATAL << "Uncaught c++ exception (unknown)";
    }
  });
}

inline void InterruptSignalHandler(int signum) {
  STERROR << "Got interrupt";
  CLOG(INFO, "stdout") << endl
                       << "Got interrupt (perhaps ctrl+c?).  Exiting." << endl;
  ::exit(signum);
}

}  // namespace et

inline bool operator==(const google::protobuf::MessageLite& msg_a,
                       const google::protobuf::MessageLite& msg_b) {
  return (msg_a.GetTypeName() == msg_b.GetTypeName()) &&
         (msg_a.SerializeAsString() == msg_b.SerializeAsString());
}

inline bool operator!=(const google::protobuf::MessageLite& msg_a,
                       const google::protobuf::MessageLite& msg_b) {
  return (msg_a.GetTypeName() != msg_b.GetTypeName()) ||
         (msg_a.SerializeAsString() != msg_b.SerializeAsString());
}

#endif
<|endoftext|>


<commit_before>#include "pch.h"
#include "GameMenuLayer.h"
#include "ResourceManager.h"
#include "ButtonLayer.h"

GameMenuLayer::GameMenuLayer()
{

}

GameMenuLayer::~GameMenuLayer()
{

}

bool GameMenuLayer::init()
{
	if (!Layer::init())
	{
		return false;
	}
	auto winSize = cocos2d::Director::getInstance()->getWinSize();
	m_WinWidth = winSize.width;
	m_WinHeight = winSize.height;

	m_GameMenuBackGround = GET_RESOURCE_MANAGER()->createSprite(ST_GAMEMENU_BACKGROUND);
	m_GameMenuFrame = GET_RESOURCE_MANAGER()->createSprite(ST_GAMEMENU_FRAME);

	setUIProperties(m_GameMenuBackGround, cocos2d::Point(0.5, 0.5), cocos2d::Point(m_WinWidth / 2, m_WinHeight / 2), 0.75f, false, 50);
	setUIProperties(m_GameMenuFrame, cocos2d::Point(0.5, 0.5), cocos2d::Point(m_WinWidth / 2, m_WinHeight / 2), 0.75f, false, 51);

	m_Button1 = ButtonLayer::create();
	m_Button2 = ButtonLayer::create();
	m_Button1->setButtonProperties(GAMEMENU_BUTTON, cocos2d::Point(m_GameMenuFrame->getBoundingBox().getMinX(), m_GameMenuFrame->getBoundingBox().getMinY()),
									cocos2d::Point(m_GameMenuFrame->getContentSize().width / 2, m_GameMenuFrame->getContentSize().height / 2), "Resume");
	m_Button2->setButtonProperties(GAMEMENU_BUTTON, cocos2d::Point(m_GameMenuFrame->getBoundingBox().getMinX(), m_GameMenuFrame->getBoundingBox().getMinY()),
									cocos2d::Point(m_GameMenuFrame->getContentSize().width / 2, m_GameMenuFrame->getContentSize().height / 2 - 55), "Save and Quit");

	//temporary buttons
	m_Button1->setButtonFunc(std::bind(&GameMenuLayer::quitGame, this));
	m_Button2->setButtonFunc(std::bind(&GameMenuLayer::quitGame, this));

	//add Children
	m_GameMenuFrame->addChild(m_Button1);
	m_GameMenuFrame->addChild(m_Button2);
	this->addChild(m_GameMenuBackGround);
	this->addChild(m_GameMenuFrame);
	return true;
}

void GameMenuLayer::update(float dTime)
{
	m_Button1->update(dTime);
	m_Button2->update(dTime);

}

void GameMenuLayer::resumeGame()
{

}

void GameMenuLayer::quitGame()
{
	exit(0);
}

void GameMenuLayer::showGameMenu()
{
	m_GameMenuBackGround->setVisible(true);
	m_GameMenuFrame->setVisible(true);
}

void GameMenuLayer::hideGameMenu()
{
	m_GameMenuBackGround->setVisible(false);
	m_GameMenuFrame->setVisible(false);
}
<commit_msg>rect bug<commit_after>#include "pch.h"
#include "GameMenuLayer.h"
#include "ResourceManager.h"
#include "ButtonLayer.h"

GameMenuLayer::GameMenuLayer()
{

}

GameMenuLayer::~GameMenuLayer()
{

}

bool GameMenuLayer::init()
{
	if (!Layer::init())
	{
		return false;
	}
	auto winSize = cocos2d::Director::getInstance()->getWinSize();
	m_WinWidth = winSize.width;
	m_WinHeight = winSize.height;

	m_GameMenuBackGround = GET_RESOURCE_MANAGER()->createSprite(ST_GAMEMENU_BACKGROUND);
	m_GameMenuFrame = GET_RESOURCE_MANAGER()->createSprite(ST_GAMEMENU_FRAME);

	setUIProperties(m_GameMenuBackGround, cocos2d::Point(0.5, 0.5), cocos2d::Point(m_WinWidth / 2, m_WinHeight / 2), 0.75f, false, 50);
	setUIProperties(m_GameMenuFrame, cocos2d::Point(0.5, 0.5), cocos2d::Point(m_WinWidth / 2, m_WinHeight / 2), 0.75f, false, 51);

	m_Button1 = ButtonLayer::create();
	m_Button2 = ButtonLayer::create();
	m_Button1->setButtonProperties(GAMEMENU_BUTTON, cocos2d::Point(m_GameMenuFrame->getBoundingBox().getMinX(), m_GameMenuFrame->getBoundingBox().getMinY()),
									cocos2d::Point(m_GameMenuFrame->getContentSize().width / 2, m_GameMenuFrame->getContentSize().height / 2), "Resume");
	m_Button2->setButtonProperties(GAMEMENU_BUTTON, cocos2d::Point(m_GameMenuFrame->getBoundingBox().getMinX(), m_GameMenuFrame->getBoundingBox().getMinY()),
									cocos2d::Point(m_GameMenuFrame->getContentSize().width / 2, m_GameMenuFrame->getContentSize().height / 2 - 55), "Save and Quit");

	//temporary buttons
	m_Button1->setButtonFunc(std::bind(&GameMenuLayer::quitGame, this));
	m_Button2->setButtonFunc(std::bind(&GameMenuLayer::quitGame, this));

	//add Children
	m_GameMenuFrame->addChild(m_Button1);
	m_GameMenuFrame->addChild(m_Button2);
	this->addChild(m_GameMenuBackGround);
	this->addChild(m_GameMenuFrame);
	return true;
}

void GameMenuLayer::update(float dTime)
{
	m_Button1->update(dTime);
	m_Button2->update(dTime);

}

void GameMenuLayer::resumeGame()
{

}

void GameMenuLayer::quitGame()
{
	//exit(0);
}

void GameMenuLayer::showGameMenu()
{
	m_GameMenuBackGround->setVisible(true);
	m_GameMenuFrame->setVisible(true);
}

void GameMenuLayer::hideGameMenu()
{
	m_GameMenuBackGround->setVisible(false);
	m_GameMenuFrame->setVisible(false);
}
<|endoftext|>