<commit_before>/******************************************************************************
 *                       ____    _    _____                                   *
 *                      / ___|  / \  |  ___|    C++                           *
 *                     | |     / _ \ | |_       Actor                         *
 *                     | |___ / ___ \|  _|      Framework                     *
 *                      \____/_/   \_|_|                                      *
 *                                                                            *
 * Copyright (C) 2011 - 2015                                                  *
 * Dominik Charousset <dominik.charousset (at) haw-hamburg.de>                *
 *                                                                            *
 * Distributed under the terms and conditions of the BSD 3-Clause License or  *
 * (at your option) under the terms and conditions of the Boost Software      *
 * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE.       *
 *                                                                            *
 * If you did not receive a copy of the license files, see                    *
 * http://opensource.org/licenses/BSD-3-Clause and                            *
 * http://www.boost.org/LICENSE_1_0.txt.                                      *
 ******************************************************************************/

#include "caf/none.hpp"
#include "caf/config.hpp"
#include "caf/make_counted.hpp"

#include "caf/io/broker.hpp"
#include "caf/io/middleman.hpp"

#include "caf/detail/logging.hpp"
#include "caf/detail/singletons.hpp"
#include "caf/detail/scope_guard.hpp"
#include "caf/detail/sync_request_bouncer.hpp"

namespace caf {
namespace io {

class abstract_broker::continuation {
public:
  continuation(intrusive_ptr<abstract_broker> bptr, mailbox_element_ptr mptr)
      : self_(std::move(bptr)),
        ptr_(std::move(mptr)) {
    // nop
  }

  continuation(continuation&&) = default;

  inline void operator()() {
    CAF_PUSH_AID(self_->id());
    CAF_LOG_TRACE("");
    self_->invoke_message(ptr_);
  }

private:
  intrusive_ptr<abstract_broker> self_;
  mailbox_element_ptr ptr_;
};

void abstract_broker::enqueue(mailbox_element_ptr ptr, execution_unit*) {
  backend().post(continuation{this, std::move(ptr)});
}

void abstract_broker::enqueue(const actor_addr& sender, message_id mid,
                              message msg, execution_unit* eu) {
  enqueue(mailbox_element::make(sender, mid, std::move(msg)), eu);
}

void abstract_broker::launch(execution_unit*, bool, bool is_hidden) {
  // add implicit reference count held by the middleman
  ref();
  is_registered(! is_hidden);
  CAF_PUSH_AID(id());
  CAF_LOGF_TRACE("init and launch broker with ID " << id());
  // we want to make sure initialization is executed in MM context
  do_become(
    [=](sys_atom) {
      CAF_LOGF_TRACE("ID " << id());
      bhvr_stack_.pop_back();
      // launch backends now, because user-defined initialization
      // might call functions like add_connection
      for (auto& kvp : doormen_) {
        kvp.second->launch();
      }
      initialize();
    },
    true);
  enqueue(invalid_actor_addr, invalid_message_id,
          make_message(sys_atom::value), nullptr);
}

void abstract_broker::cleanup(uint32_t reason) {
  CAF_LOG_TRACE(CAF_ARG(reason));
  planned_exit_reason(reason);
  on_exit();
  close_all();
  CAF_ASSERT(doormen_.empty());
  CAF_ASSERT(scribes_.empty());
  cache_.clear();
  local_actor::cleanup(reason);
  deref(); // release implicit reference count from middleman
}

abstract_broker::~abstract_broker() {
  CAF_LOG_TRACE("");
}

void abstract_broker::configure_read(connection_handle hdl,
                                     receive_policy::config cfg) {
  CAF_LOG_TRACE(CAF_MARG(hdl, id) << ", cfg = {" << static_cast<int>(cfg.first)
                                  << ", " << cfg.second << "}");
  by_id(hdl).configure_read(cfg);
}

std::vector<char>& abstract_broker::wr_buf(connection_handle hdl) {
  return by_id(hdl).wr_buf();
}

void abstract_broker::write(connection_handle hdl, size_t bs, const void* buf) {
  auto& out = wr_buf(hdl);
  auto first = reinterpret_cast<const char*>(buf);
  auto last = first + bs;
  out.insert(out.end(), first, last);
}

void abstract_broker::flush(connection_handle hdl) {
  by_id(hdl).flush();
}

std::vector<connection_handle> abstract_broker::connections() const {
  std::vector<connection_handle> result;
  result.reserve(scribes_.size());
  for (auto& kvp : scribes_) {
    result.push_back(kvp.first);
  }
  return result;
}

void abstract_broker::add_scribe(const intrusive_ptr<scribe>& ptr) {
  scribes_.emplace(ptr->hdl(), ptr);
}
connection_handle abstract_broker::add_tcp_scribe(const std::string& hostname,
                                                  uint16_t port) {
  CAF_LOG_TRACE(CAF_ARG(hostname) << ", " << CAF_ARG(port));
  return backend().add_tcp_scribe(this, hostname, port);
}

void abstract_broker::assign_tcp_scribe(connection_handle hdl) {
  CAF_LOG_TRACE(CAF_MARG(hdl, id));
  backend().assign_tcp_scribe(this, hdl);
}

connection_handle
abstract_broker::add_tcp_scribe(network::native_socket fd) {
  CAF_LOG_TRACE(CAF_ARG(fd));
  return backend().add_tcp_scribe(this, fd);
}

void abstract_broker::add_doorman(const intrusive_ptr<doorman>& ptr) {
  doormen_.emplace(ptr->hdl(), ptr);
  if (is_initialized())
    ptr->launch();
}

std::pair<accept_handle, uint16_t>
abstract_broker::add_tcp_doorman(uint16_t port, const char* in,
                                 bool reuse_addr) {
  CAF_LOG_TRACE(CAF_ARG(port) << ", in = " << (in ? in : "nullptr")
                << ", " << CAF_ARG(reuse_addr));
  return backend().add_tcp_doorman(this, port, in, reuse_addr);
}

void abstract_broker::assign_tcp_doorman(accept_handle hdl) {
  CAF_LOG_TRACE(CAF_MARG(hdl, id));
  backend().assign_tcp_doorman(this, hdl);
}

accept_handle abstract_broker::add_tcp_doorman(network::native_socket fd) {
  CAF_LOG_TRACE(CAF_ARG(fd));
  return backend().add_tcp_doorman(this, fd);
}

uint16_t abstract_broker::local_port(accept_handle hdl) {
  auto i = doormen_.find(hdl);
  return i != doormen_.end() ? i->second->port() : 0;
}

optional<accept_handle> abstract_broker::hdl_by_port(uint16_t port) {
  for (auto& kvp : doormen_)
    if (kvp.second->port() == port)
      return kvp.first;
  return none;
}

void abstract_broker::invoke_message(mailbox_element_ptr& ptr) {
  CAF_LOG_TRACE(CAF_TARG(ptr->msg, to_string));
  if (exit_reason() != exit_reason::not_exited || ! has_behavior()) {
    CAF_LOG_DEBUG("actor already finished execution"
                  << ", planned_exit_reason = " << planned_exit_reason()
                  << ", has_behavior() = " << has_behavior());
    if (ptr->mid.valid()) {
      detail::sync_request_bouncer srb{exit_reason()};
      srb(ptr->sender, ptr->mid);
    }
    return;
  }
  // prepare actor for invocation of message handler
  try {
    auto& bhvr = this->awaits_response()
                 ? this->awaited_response_handler()
                 : this->bhvr_stack().back();
    auto bid = this->awaited_response_id();
    switch (local_actor::invoke_message(ptr, bhvr, bid)) {
      case im_success: {
        CAF_LOG_DEBUG("handle_message returned hm_msg_handled");
        while (has_behavior()
               && planned_exit_reason() == exit_reason::not_exited
               && invoke_message_from_cache()) {
          // rinse and repeat
        }
        break;
      }
      case im_dropped:
        CAF_LOG_DEBUG("handle_message returned hm_drop_msg");
        break;
      case im_skipped: {
        CAF_LOG_DEBUG("handle_message returned hm_skip_msg or hm_cache_msg");
        if (ptr) {
          cache_.push_second_back(ptr.release());
        }
        break;
      }
    }
  }
  catch (std::exception& e) {
    CAF_LOG_INFO("broker killed due to an unhandled exception: "
                 << to_verbose_string(e));
    // keep compiler happy in non-debug mode
    static_cast<void>(e);
    quit(exit_reason::unhandled_exception);
  }
  catch (...) {
    CAF_LOG_ERROR("broker killed due to an unknown exception");
    quit(exit_reason::unhandled_exception);
  }
  // safe to actually release behaviors now
  bhvr_stack().cleanup();
  // cleanup actor if needed
  if (planned_exit_reason() != exit_reason::not_exited) {
    cleanup(planned_exit_reason());
  } else if (! has_behavior()) {
    CAF_LOG_DEBUG("no behavior set, quit for normal exit reason");
    quit(exit_reason::normal);
    cleanup(planned_exit_reason());
  }
}

void abstract_broker::invoke_message(const actor_addr& sender,
                                     message_id mid,
                                     message& msg) {
  auto ptr = mailbox_element::make(sender, mid, message{});
  ptr->msg.swap(msg);
  invoke_message(ptr);
  if (ptr)
    ptr->msg.swap(msg);
}

void abstract_broker::close_all() {
  CAF_LOG_TRACE("");
  while (! doormen_.empty()) {
    // stop_reading will remove the doorman from doormen_
    doormen_.begin()->second->stop_reading();
  }
  while (! scribes_.empty()) {
    // stop_reading will remove the scribe from scribes_
    scribes_.begin()->second->stop_reading();
  }
}

abstract_broker::abstract_broker() : mm_(*middleman::instance()) {
  // nop
}

abstract_broker::abstract_broker(middleman& ptr) : mm_(ptr) {
  // nop
}

network::multiplexer& abstract_broker::backend() {
  return mm_.backend();
}

bool abstract_broker::invoke_message_from_cache() {
  CAF_LOG_TRACE("");
  auto& bhvr = this->awaits_response()
               ? this->awaited_response_handler()
               : this->bhvr_stack().back();
  auto bid = this->awaited_response_id();
  auto i = cache_.second_begin();
  auto e = cache_.second_end();
  CAF_LOG_DEBUG(std::distance(i, e) << " elements in cache");
  return cache_.invoke(static_cast<local_actor*>(this), i, e, bhvr, bid);
}

} // namespace io
} // namespace caf
<commit_msg>Remove logging from broker destructor<commit_after>/******************************************************************************
 *                       ____    _    _____                                   *
 *                      / ___|  / \  |  ___|    C++                           *
 *                     | |     / _ \ | |_       Actor                         *
 *                     | |___ / ___ \|  _|      Framework                     *
 *                      \____/_/   \_|_|                                      *
 *                                                                            *
 * Copyright (C) 2011 - 2015                                                  *
 * Dominik Charousset <dominik.charousset (at) haw-hamburg.de>                *
 *                                                                            *
 * Distributed under the terms and conditions of the BSD 3-Clause License or  *
 * (at your option) under the terms and conditions of the Boost Software      *
 * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE.       *
 *                                                                            *
 * If you did not receive a copy of the license files, see                    *
 * http://opensource.org/licenses/BSD-3-Clause and                            *
 * http://www.boost.org/LICENSE_1_0.txt.                                      *
 ******************************************************************************/

#include "caf/none.hpp"
#include "caf/config.hpp"
#include "caf/make_counted.hpp"

#include "caf/io/broker.hpp"
#include "caf/io/middleman.hpp"

#include "caf/detail/logging.hpp"
#include "caf/detail/singletons.hpp"
#include "caf/detail/scope_guard.hpp"
#include "caf/detail/sync_request_bouncer.hpp"

namespace caf {
namespace io {

class abstract_broker::continuation {
public:
  continuation(intrusive_ptr<abstract_broker> bptr, mailbox_element_ptr mptr)
      : self_(std::move(bptr)),
        ptr_(std::move(mptr)) {
    // nop
  }

  continuation(continuation&&) = default;

  inline void operator()() {
    CAF_PUSH_AID(self_->id());
    CAF_LOG_TRACE("");
    self_->invoke_message(ptr_);
  }

private:
  intrusive_ptr<abstract_broker> self_;
  mailbox_element_ptr ptr_;
};

void abstract_broker::enqueue(mailbox_element_ptr ptr, execution_unit*) {
  backend().post(continuation{this, std::move(ptr)});
}

void abstract_broker::enqueue(const actor_addr& sender, message_id mid,
                              message msg, execution_unit* eu) {
  enqueue(mailbox_element::make(sender, mid, std::move(msg)), eu);
}

void abstract_broker::launch(execution_unit*, bool, bool is_hidden) {
  // add implicit reference count held by the middleman
  ref();
  is_registered(! is_hidden);
  CAF_PUSH_AID(id());
  CAF_LOGF_TRACE("init and launch broker with ID " << id());
  // we want to make sure initialization is executed in MM context
  do_become(
    [=](sys_atom) {
      CAF_LOGF_TRACE("ID " << id());
      bhvr_stack_.pop_back();
      // launch backends now, because user-defined initialization
      // might call functions like add_connection
      for (auto& kvp : doormen_) {
        kvp.second->launch();
      }
      initialize();
    },
    true);
  enqueue(invalid_actor_addr, invalid_message_id,
          make_message(sys_atom::value), nullptr);
}

void abstract_broker::cleanup(uint32_t reason) {
  CAF_LOG_TRACE(CAF_ARG(reason));
  planned_exit_reason(reason);
  on_exit();
  close_all();
  CAF_ASSERT(doormen_.empty());
  CAF_ASSERT(scribes_.empty());
  cache_.clear();
  local_actor::cleanup(reason);
  deref(); // release implicit reference count from middleman
}

abstract_broker::~abstract_broker() {
  // nop
}

void abstract_broker::configure_read(connection_handle hdl,
                                     receive_policy::config cfg) {
  CAF_LOG_TRACE(CAF_MARG(hdl, id) << ", cfg = {" << static_cast<int>(cfg.first)
                                  << ", " << cfg.second << "}");
  by_id(hdl).configure_read(cfg);
}

std::vector<char>& abstract_broker::wr_buf(connection_handle hdl) {
  return by_id(hdl).wr_buf();
}

void abstract_broker::write(connection_handle hdl, size_t bs, const void* buf) {
  auto& out = wr_buf(hdl);
  auto first = reinterpret_cast<const char*>(buf);
  auto last = first + bs;
  out.insert(out.end(), first, last);
}

void abstract_broker::flush(connection_handle hdl) {
  by_id(hdl).flush();
}

std::vector<connection_handle> abstract_broker::connections() const {
  std::vector<connection_handle> result;
  result.reserve(scribes_.size());
  for (auto& kvp : scribes_) {
    result.push_back(kvp.first);
  }
  return result;
}

void abstract_broker::add_scribe(const intrusive_ptr<scribe>& ptr) {
  scribes_.emplace(ptr->hdl(), ptr);
}
connection_handle abstract_broker::add_tcp_scribe(const std::string& hostname,
                                                  uint16_t port) {
  CAF_LOG_TRACE(CAF_ARG(hostname) << ", " << CAF_ARG(port));
  return backend().add_tcp_scribe(this, hostname, port);
}

void abstract_broker::assign_tcp_scribe(connection_handle hdl) {
  CAF_LOG_TRACE(CAF_MARG(hdl, id));
  backend().assign_tcp_scribe(this, hdl);
}

connection_handle
abstract_broker::add_tcp_scribe(network::native_socket fd) {
  CAF_LOG_TRACE(CAF_ARG(fd));
  return backend().add_tcp_scribe(this, fd);
}

void abstract_broker::add_doorman(const intrusive_ptr<doorman>& ptr) {
  doormen_.emplace(ptr->hdl(), ptr);
  if (is_initialized())
    ptr->launch();
}

std::pair<accept_handle, uint16_t>
abstract_broker::add_tcp_doorman(uint16_t port, const char* in,
                                 bool reuse_addr) {
  CAF_LOG_TRACE(CAF_ARG(port) << ", in = " << (in ? in : "nullptr")
                << ", " << CAF_ARG(reuse_addr));
  return backend().add_tcp_doorman(this, port, in, reuse_addr);
}

void abstract_broker::assign_tcp_doorman(accept_handle hdl) {
  CAF_LOG_TRACE(CAF_MARG(hdl, id));
  backend().assign_tcp_doorman(this, hdl);
}

accept_handle abstract_broker::add_tcp_doorman(network::native_socket fd) {
  CAF_LOG_TRACE(CAF_ARG(fd));
  return backend().add_tcp_doorman(this, fd);
}

uint16_t abstract_broker::local_port(accept_handle hdl) {
  auto i = doormen_.find(hdl);
  return i != doormen_.end() ? i->second->port() : 0;
}

optional<accept_handle> abstract_broker::hdl_by_port(uint16_t port) {
  for (auto& kvp : doormen_)
    if (kvp.second->port() == port)
      return kvp.first;
  return none;
}

void abstract_broker::invoke_message(mailbox_element_ptr& ptr) {
  CAF_LOG_TRACE(CAF_TARG(ptr->msg, to_string));
  if (exit_reason() != exit_reason::not_exited || ! has_behavior()) {
    CAF_LOG_DEBUG("actor already finished execution"
                  << ", planned_exit_reason = " << planned_exit_reason()
                  << ", has_behavior() = " << has_behavior());
    if (ptr->mid.valid()) {
      detail::sync_request_bouncer srb{exit_reason()};
      srb(ptr->sender, ptr->mid);
    }
    return;
  }
  // prepare actor for invocation of message handler
  try {
    auto& bhvr = this->awaits_response()
                 ? this->awaited_response_handler()
                 : this->bhvr_stack().back();
    auto bid = this->awaited_response_id();
    switch (local_actor::invoke_message(ptr, bhvr, bid)) {
      case im_success: {
        CAF_LOG_DEBUG("handle_message returned hm_msg_handled");
        while (has_behavior()
               && planned_exit_reason() == exit_reason::not_exited
               && invoke_message_from_cache()) {
          // rinse and repeat
        }
        break;
      }
      case im_dropped:
        CAF_LOG_DEBUG("handle_message returned hm_drop_msg");
        break;
      case im_skipped: {
        CAF_LOG_DEBUG("handle_message returned hm_skip_msg or hm_cache_msg");
        if (ptr) {
          cache_.push_second_back(ptr.release());
        }
        break;
      }
    }
  }
  catch (std::exception& e) {
    CAF_LOG_INFO("broker killed due to an unhandled exception: "
                 << to_verbose_string(e));
    // keep compiler happy in non-debug mode
    static_cast<void>(e);
    quit(exit_reason::unhandled_exception);
  }
  catch (...) {
    CAF_LOG_ERROR("broker killed due to an unknown exception");
    quit(exit_reason::unhandled_exception);
  }
  // safe to actually release behaviors now
  bhvr_stack().cleanup();
  // cleanup actor if needed
  if (planned_exit_reason() != exit_reason::not_exited) {
    cleanup(planned_exit_reason());
  } else if (! has_behavior()) {
    CAF_LOG_DEBUG("no behavior set, quit for normal exit reason");
    quit(exit_reason::normal);
    cleanup(planned_exit_reason());
  }
}

void abstract_broker::invoke_message(const actor_addr& sender,
                                     message_id mid,
                                     message& msg) {
  auto ptr = mailbox_element::make(sender, mid, message{});
  ptr->msg.swap(msg);
  invoke_message(ptr);
  if (ptr)
    ptr->msg.swap(msg);
}

void abstract_broker::close_all() {
  CAF_LOG_TRACE("");
  while (! doormen_.empty()) {
    // stop_reading will remove the doorman from doormen_
    doormen_.begin()->second->stop_reading();
  }
  while (! scribes_.empty()) {
    // stop_reading will remove the scribe from scribes_
    scribes_.begin()->second->stop_reading();
  }
}

abstract_broker::abstract_broker() : mm_(*middleman::instance()) {
  // nop
}

abstract_broker::abstract_broker(middleman& ptr) : mm_(ptr) {
  // nop
}

network::multiplexer& abstract_broker::backend() {
  return mm_.backend();
}

bool abstract_broker::invoke_message_from_cache() {
  CAF_LOG_TRACE("");
  auto& bhvr = this->awaits_response()
               ? this->awaited_response_handler()
               : this->bhvr_stack().back();
  auto bid = this->awaited_response_id();
  auto i = cache_.second_begin();
  auto e = cache_.second_end();
  CAF_LOG_DEBUG(std::distance(i, e) << " elements in cache");
  return cache_.invoke(static_cast<local_actor*>(this), i, e, bhvr, bid);
}

} // namespace io
} // namespace caf
<|endoftext|>


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

#include "libcef/browser/browser_context.h"

#include <map>

#include "libcef/browser/browser_host_impl.h"
#include "libcef/browser/context.h"
#include "libcef/browser/download_manager_delegate.h"
#include "libcef/browser/resource_context.h"
#include "libcef/browser/thread_util.h"
#include "libcef/browser/url_request_context_getter.h"

#include "base/bind.h"
#include "base/logging.h"
#include "base/threading/thread.h"
#include "content/public/browser/download_manager.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/geolocation_permission_context.h"
#include "content/public/browser/speech_recognition_preferences.h"

using content::BrowserThread;

namespace {

class CefGeolocationPermissionContext
    : public content::GeolocationPermissionContext {
 public:
  // CefGeolocationCallback implementation.
  class CallbackImpl : public CefGeolocationCallback {
   public:
    typedef base::Callback<void(bool)>  // NOLINT(readability/function)
        CallbackType;

    explicit CallbackImpl(
        CefGeolocationPermissionContext* context,
        int bridge_id,
        const CallbackType& callback)
        : context_(context),
          bridge_id_(bridge_id),
          callback_(callback) {}

    virtual void Continue(bool allow) OVERRIDE {
      if (CEF_CURRENTLY_ON_IOT()) {
        if (!callback_.is_null()) {
          // Callback must be executed on the UI thread.
          CEF_POST_TASK(CEF_UIT,
              base::Bind(&CallbackImpl::Run, callback_, allow));
          context_->RemoveCallback(bridge_id_);
        }
      } else {
        CEF_POST_TASK(CEF_IOT,
            base::Bind(&CallbackImpl::Continue, this, allow));
      }
    }

    void Disconnect() {
      callback_.Reset();
      context_ = NULL;
    }

   private:
    static void Run(const CallbackType& callback, bool allow) {
      CEF_REQUIRE_UIT();
      callback.Run(allow);
    }

    CefGeolocationPermissionContext* context_;
    int bridge_id_;
    CallbackType callback_;

    IMPLEMENT_REFCOUNTING(CallbackImpl);
  };

  CefGeolocationPermissionContext() {}

  virtual void RequestGeolocationPermission(
      int render_process_id,
      int render_view_id,
      int bridge_id,
      const GURL& requesting_frame,
      base::Callback<void(bool)> callback)  // NOLINT(readability/function)
      OVERRIDE {
    CEF_REQUIRE_IOT();

    CefRefPtr<CefBrowserHostImpl> browser =
        CefBrowserHostImpl::GetBrowserByRoutingID(render_process_id,
                                                  render_view_id);
    if (browser.get()) {
      CefRefPtr<CefClient> client = browser->GetClient();
      if (client.get()) {
        CefRefPtr<CefGeolocationHandler> handler =
            client->GetGeolocationHandler();
        if (handler.get()) {
          CefRefPtr<CallbackImpl> callbackPtr(
              new CallbackImpl(this, bridge_id, callback));

          // Add the callback reference to the map.
          callback_map_.insert(std::make_pair(bridge_id, callbackPtr));

          // Notify the handler.
          handler->OnRequestGeolocationPermission(browser.get(),
              requesting_frame.spec(), bridge_id, callbackPtr.get());
          return;
        }
      }
    }

    // Disallow geolocation access by default.
    callback.Run(false);
  }

  virtual void CancelGeolocationPermissionRequest(
      int render_process_id,
      int render_view_id,
      int bridge_id,
      const GURL& requesting_frame) OVERRIDE {
    RemoveCallback(bridge_id);

    CefRefPtr<CefBrowserHostImpl> browser =
        CefBrowserHostImpl::GetBrowserByRoutingID(render_process_id,
                                                  render_view_id);
    if (browser.get()) {
      CefRefPtr<CefClient> client = browser->GetClient();
      if (client.get()) {
        CefRefPtr<CefGeolocationHandler> handler =
            client->GetGeolocationHandler();
        if (handler.get()) {
          // Notify the handler.
          handler->OnCancelGeolocationPermission(browser.get(),
              requesting_frame.spec(), bridge_id);
        }
      }
    }
  }

  void RemoveCallback(int bridge_id) {
    CEF_REQUIRE_IOT();

    // Disconnect the callback and remove the reference from the map.
    CallbackMap::iterator it = callback_map_.find(bridge_id);
    if (it != callback_map_.end()) {
      it->second->Disconnect();
      callback_map_.erase(it);
    }
  }

 private:
  // Map of bridge ids to callback references.
  typedef std::map<int, CefRefPtr<CallbackImpl> > CallbackMap;
  CallbackMap callback_map_;

  DISALLOW_COPY_AND_ASSIGN(CefGeolocationPermissionContext);
};

class CefSpeechRecognitionPreferences
    : public content::SpeechRecognitionPreferences {
 public:
  CefSpeechRecognitionPreferences() {
  }

  // Overridden from SpeechRecognitionPreferences:
  virtual bool FilterProfanities() const OVERRIDE {
    return false;
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(CefSpeechRecognitionPreferences);
};

}  // namespace

CefBrowserContext::CefBrowserContext()
    : use_osr_next_contents_view_(false) {
  // Initialize the request context getter.
  url_request_getter_ = new CefURLRequestContextGetter(
      false,
      GetPath(),
      BrowserThread::UnsafeGetMessageLoopForThread(BrowserThread::IO),
      BrowserThread::UnsafeGetMessageLoopForThread(BrowserThread::FILE));
}

CefBrowserContext::~CefBrowserContext() {
  // Delete the download manager delegate here because otherwise we'll crash
  // when it's accessed from the content::BrowserContext destructor.
  if (download_manager_delegate_.get())
    download_manager_delegate_.reset(NULL);

  if (resource_context_.get()) {
    BrowserThread::DeleteSoon(
        BrowserThread::IO, FROM_HERE, resource_context_.release());
  }
}

FilePath CefBrowserContext::GetPath() {
  return _Context->cache_path();
}

bool CefBrowserContext::IsOffTheRecord() const {
  return false;
}

content::DownloadManagerDelegate*
    CefBrowserContext::GetDownloadManagerDelegate() {
  DCHECK(!download_manager_delegate_.get());

  content::DownloadManager* manager = BrowserContext::GetDownloadManager(this);
  download_manager_delegate_.reset(new CefDownloadManagerDelegate(manager));
  return download_manager_delegate_.get();
}

net::URLRequestContextGetter* CefBrowserContext::GetRequestContext() {
  return url_request_getter_;
}

net::URLRequestContextGetter*
    CefBrowserContext::GetRequestContextForRenderProcess(
        int renderer_child_id) {
  CefRefPtr<CefBrowserHostImpl> browser =
      CefBrowserHostImpl::GetBrowserByChildID(renderer_child_id);
  if (browser.get())
    return browser->GetRequestContext();
  return GetRequestContext();
}

net::URLRequestContextGetter*
    CefBrowserContext::GetMediaRequestContext() {
  return GetRequestContext();
}

net::URLRequestContextGetter*
    CefBrowserContext::GetMediaRequestContextForRenderProcess(
        int renderer_child_id)  {
  return GetRequestContext();
}

net::URLRequestContextGetter*
    CefBrowserContext::GetMediaRequestContextForStoragePartition(
        const FilePath& partition_path,
        bool in_memory) {
  return GetRequestContext();
}

net::URLRequestContextGetter*
    CefBrowserContext::GetRequestContextForStoragePartition(
        const FilePath& partition_path,
        bool in_memory) {
  return NULL;
}

content::ResourceContext* CefBrowserContext::GetResourceContext() {
  if (!resource_context_.get()) {
    resource_context_.reset(new CefResourceContext(
        static_cast<CefURLRequestContextGetter*>(GetRequestContext())));
  }
  return resource_context_.get();
}

content::GeolocationPermissionContext*
    CefBrowserContext::GetGeolocationPermissionContext() {
  if (!geolocation_permission_context_) {
    geolocation_permission_context_ =
        new CefGeolocationPermissionContext();
  }
  return geolocation_permission_context_;
}

content::SpeechRecognitionPreferences*
    CefBrowserContext::GetSpeechRecognitionPreferences() {
  if (!speech_recognition_preferences_.get())
    speech_recognition_preferences_ = new CefSpeechRecognitionPreferences();
  return speech_recognition_preferences_.get();
}

quota::SpecialStoragePolicy* CefBrowserContext::GetSpecialStoragePolicy() {
  return NULL;
}

bool CefBrowserContext::use_osr_next_contents_view() const {
  return use_osr_next_contents_view_;
}

void CefBrowserContext::set_use_osr_next_contents_view(bool override) {
  use_osr_next_contents_view_ = override;
}
<commit_msg>Fix assertion when returning NULL from CefClient::GetGeolocationHandler (issue #857).<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "libcef/browser/browser_context.h"

#include <map>

#include "libcef/browser/browser_host_impl.h"
#include "libcef/browser/context.h"
#include "libcef/browser/download_manager_delegate.h"
#include "libcef/browser/resource_context.h"
#include "libcef/browser/thread_util.h"
#include "libcef/browser/url_request_context_getter.h"

#include "base/bind.h"
#include "base/logging.h"
#include "base/threading/thread.h"
#include "content/public/browser/download_manager.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/geolocation_permission_context.h"
#include "content/public/browser/speech_recognition_preferences.h"

using content::BrowserThread;

namespace {

class CefGeolocationPermissionContext
    : public content::GeolocationPermissionContext {
 public:
  // CefGeolocationCallback implementation.
  class CallbackImpl : public CefGeolocationCallback {
   public:
    typedef base::Callback<void(bool)>  // NOLINT(readability/function)
        CallbackType;

    explicit CallbackImpl(
        CefGeolocationPermissionContext* context,
        int bridge_id,
        const CallbackType& callback)
        : context_(context),
          bridge_id_(bridge_id),
          callback_(callback) {}

    virtual void Continue(bool allow) OVERRIDE {
      if (CEF_CURRENTLY_ON_IOT()) {
        if (!callback_.is_null()) {
          // Callback must be executed on the UI thread.
          CEF_POST_TASK(CEF_UIT,
              base::Bind(&CallbackImpl::Run, callback_, allow));
          context_->RemoveCallback(bridge_id_);
        }
      } else {
        CEF_POST_TASK(CEF_IOT,
            base::Bind(&CallbackImpl::Continue, this, allow));
      }
    }

    void Disconnect() {
      callback_.Reset();
      context_ = NULL;
    }

   private:
    static void Run(const CallbackType& callback, bool allow) {
      CEF_REQUIRE_UIT();
      callback.Run(allow);
    }

    CefGeolocationPermissionContext* context_;
    int bridge_id_;
    CallbackType callback_;

    IMPLEMENT_REFCOUNTING(CallbackImpl);
  };

  CefGeolocationPermissionContext() {}

  virtual void RequestGeolocationPermission(
      int render_process_id,
      int render_view_id,
      int bridge_id,
      const GURL& requesting_frame,
      base::Callback<void(bool)> callback)  // NOLINT(readability/function)
      OVERRIDE {
    CEF_REQUIRE_IOT();

    CefRefPtr<CefBrowserHostImpl> browser =
        CefBrowserHostImpl::GetBrowserByRoutingID(render_process_id,
                                                  render_view_id);
    if (browser.get()) {
      CefRefPtr<CefClient> client = browser->GetClient();
      if (client.get()) {
        CefRefPtr<CefGeolocationHandler> handler =
            client->GetGeolocationHandler();
        if (handler.get()) {
          CefRefPtr<CallbackImpl> callbackPtr(
              new CallbackImpl(this, bridge_id, callback));

          // Add the callback reference to the map.
          callback_map_.insert(std::make_pair(bridge_id, callbackPtr));

          // Notify the handler.
          handler->OnRequestGeolocationPermission(browser.get(),
              requesting_frame.spec(), bridge_id, callbackPtr.get());
          return;
        }
      }
    }

    // Disallow geolocation access by default.
    CEF_POST_TASK(CEF_UIT, base::Bind(callback, false));
  }

  virtual void CancelGeolocationPermissionRequest(
      int render_process_id,
      int render_view_id,
      int bridge_id,
      const GURL& requesting_frame) OVERRIDE {
    RemoveCallback(bridge_id);

    CefRefPtr<CefBrowserHostImpl> browser =
        CefBrowserHostImpl::GetBrowserByRoutingID(render_process_id,
                                                  render_view_id);
    if (browser.get()) {
      CefRefPtr<CefClient> client = browser->GetClient();
      if (client.get()) {
        CefRefPtr<CefGeolocationHandler> handler =
            client->GetGeolocationHandler();
        if (handler.get()) {
          // Notify the handler.
          handler->OnCancelGeolocationPermission(browser.get(),
              requesting_frame.spec(), bridge_id);
        }
      }
    }
  }

  void RemoveCallback(int bridge_id) {
    CEF_REQUIRE_IOT();

    // Disconnect the callback and remove the reference from the map.
    CallbackMap::iterator it = callback_map_.find(bridge_id);
    if (it != callback_map_.end()) {
      it->second->Disconnect();
      callback_map_.erase(it);
    }
  }

 private:
  // Map of bridge ids to callback references.
  typedef std::map<int, CefRefPtr<CallbackImpl> > CallbackMap;
  CallbackMap callback_map_;

  DISALLOW_COPY_AND_ASSIGN(CefGeolocationPermissionContext);
};

class CefSpeechRecognitionPreferences
    : public content::SpeechRecognitionPreferences {
 public:
  CefSpeechRecognitionPreferences() {
  }

  // Overridden from SpeechRecognitionPreferences:
  virtual bool FilterProfanities() const OVERRIDE {
    return false;
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(CefSpeechRecognitionPreferences);
};

}  // namespace

CefBrowserContext::CefBrowserContext()
    : use_osr_next_contents_view_(false) {
  // Initialize the request context getter.
  url_request_getter_ = new CefURLRequestContextGetter(
      false,
      GetPath(),
      BrowserThread::UnsafeGetMessageLoopForThread(BrowserThread::IO),
      BrowserThread::UnsafeGetMessageLoopForThread(BrowserThread::FILE));
}

CefBrowserContext::~CefBrowserContext() {
  // Delete the download manager delegate here because otherwise we'll crash
  // when it's accessed from the content::BrowserContext destructor.
  if (download_manager_delegate_.get())
    download_manager_delegate_.reset(NULL);

  if (resource_context_.get()) {
    BrowserThread::DeleteSoon(
        BrowserThread::IO, FROM_HERE, resource_context_.release());
  }
}

FilePath CefBrowserContext::GetPath() {
  return _Context->cache_path();
}

bool CefBrowserContext::IsOffTheRecord() const {
  return false;
}

content::DownloadManagerDelegate*
    CefBrowserContext::GetDownloadManagerDelegate() {
  DCHECK(!download_manager_delegate_.get());

  content::DownloadManager* manager = BrowserContext::GetDownloadManager(this);
  download_manager_delegate_.reset(new CefDownloadManagerDelegate(manager));
  return download_manager_delegate_.get();
}

net::URLRequestContextGetter* CefBrowserContext::GetRequestContext() {
  return url_request_getter_;
}

net::URLRequestContextGetter*
    CefBrowserContext::GetRequestContextForRenderProcess(
        int renderer_child_id) {
  CefRefPtr<CefBrowserHostImpl> browser =
      CefBrowserHostImpl::GetBrowserByChildID(renderer_child_id);
  if (browser.get())
    return browser->GetRequestContext();
  return GetRequestContext();
}

net::URLRequestContextGetter*
    CefBrowserContext::GetMediaRequestContext() {
  return GetRequestContext();
}

net::URLRequestContextGetter*
    CefBrowserContext::GetMediaRequestContextForRenderProcess(
        int renderer_child_id)  {
  return GetRequestContext();
}

net::URLRequestContextGetter*
    CefBrowserContext::GetMediaRequestContextForStoragePartition(
        const FilePath& partition_path,
        bool in_memory) {
  return GetRequestContext();
}

net::URLRequestContextGetter*
    CefBrowserContext::GetRequestContextForStoragePartition(
        const FilePath& partition_path,
        bool in_memory) {
  return NULL;
}

content::ResourceContext* CefBrowserContext::GetResourceContext() {
  if (!resource_context_.get()) {
    resource_context_.reset(new CefResourceContext(
        static_cast<CefURLRequestContextGetter*>(GetRequestContext())));
  }
  return resource_context_.get();
}

content::GeolocationPermissionContext*
    CefBrowserContext::GetGeolocationPermissionContext() {
  if (!geolocation_permission_context_) {
    geolocation_permission_context_ =
        new CefGeolocationPermissionContext();
  }
  return geolocation_permission_context_;
}

content::SpeechRecognitionPreferences*
    CefBrowserContext::GetSpeechRecognitionPreferences() {
  if (!speech_recognition_preferences_.get())
    speech_recognition_preferences_ = new CefSpeechRecognitionPreferences();
  return speech_recognition_preferences_.get();
}

quota::SpecialStoragePolicy* CefBrowserContext::GetSpecialStoragePolicy() {
  return NULL;
}

bool CefBrowserContext::use_osr_next_contents_view() const {
  return use_osr_next_contents_view_;
}

void CefBrowserContext::set_use_osr_next_contents_view(bool override) {
  use_osr_next_contents_view_ = override;
}
<|endoftext|>


<commit_before>#include "cmbNucConflictDialog.h"
#include "ui_name_conflict_gui.h"

#include <QMainWindow>

cmbNucConflictDialog::cmbNucConflictDialog(QMainWindow* mainWindow, cmbNucPinLibrary * lib, PinCell * p)
: QDialog(mainWindow,  Qt::CustomizeWindowHint), pinLibrary(lib), pin(p)
{
  this->ui = new Ui_name_conflict_gui;

  this->ui->setupUi(this);

  this->ui->NewName->setText(pin->getName().c_str());
  this->ui->NewLabel->setText(pin->getLabel().c_str());
  checkLabels();

  connect( this->ui->Ignore, SIGNAL(toggled(bool)), this, SLOT( selectedIgnore(bool) ) );
  connect( this->ui->OverWrite, SIGNAL(toggled(bool)), this, SLOT(selectedReplace(bool)) );
  connect( this->ui->Rename, SIGNAL(toggled(bool)), this, SLOT(selectedRename(bool)) );
  connect( this->ui->NewLabel, SIGNAL(textEdited(const QString &)), this, SLOT(labelChanged(QString)));
  connect( this->ui->NewName, SIGNAL(textEdited(const QString &)), this, SLOT(nameChanged(QString)));
  connect( this->ui->Apply, SIGNAL(clicked(QAbstractButton *)), this, SLOT(apply()));
}

cmbNucConflictDialog::~cmbNucConflictDialog()
{
  delete ui;
}

void cmbNucConflictDialog::nameChanged(QString v)
{
  bool t = checkLabels();
  if(mode == RENAME) this->ui->Apply->setEnabled(t);
}

void cmbNucConflictDialog::labelChanged(QString v)
{
  bool t = checkLabels();
  if(mode == RENAME) this->ui->Apply->setEnabled(t);
}

void cmbNucConflictDialog::selectedReplace(bool v)
{
  if(v)
  {
    mode = REPLACE;
    this->ui->Apply->setEnabled( true );
    this->ui->NewName->setText(pin->getName().c_str());
    this->ui->NewLabel->setText(pin->getLabel().c_str());
    checkLabels();
    this->ui->NewValue->setEnabled(false);
  }
}

void cmbNucConflictDialog::selectedRename(bool v)
{
  if(v)
  {
    mode = RENAME;
    this->ui->NewValue->setEnabled(true);
    this->ui->Apply->setEnabled(checkLabels());
  }
}

void cmbNucConflictDialog::selectedIgnore(bool v)
{
  if(v)
  {
    mode = IGNORE;
    this->ui->Apply->setEnabled( true );
    this->ui->NewName->setText(pin->getName().c_str());
    this->ui->NewLabel->setText(pin->getLabel().c_str());
    checkLabels();
    this->ui->NewValue->setEnabled(false);
  }
}

void cmbNucConflictDialog::apply()
{
  int rt = 0;
  switch( mode )
  {
    case REPLACE:
      rt = cmbNucPinLibrary::Replace;
      break;
    case IGNORE:
      rt = cmbNucPinLibrary::KeepOriginal;
      break;
    case RENAME:
      rt = cmbNucPinLibrary::KeepOriginal;
      pin->setLabel(this->ui->NewLabel->text().toStdString());
      pin->setName(this->ui->NewName->text().toStdString());
      break;
  }
  this->done( rt );
}

bool cmbNucConflictDialog::checkLabels()
{
  bool r = true;
  std::string name = this->ui->NewName->text().toStdString();
  std::string label = this->ui->NewLabel->text().toStdString();
  if(pinLibrary->nameConflicts(name))
  {
    r = false;
    this->ui->NewName->setStyleSheet("QLineEdit#NewName{color:red}");
  }
  else
  {
    this->ui->NewName->setStyleSheet("QLineEdit#NewName{color:blue}");
  }
  if(pinLibrary->labelConflicts(label))
  {
    r = false;
    this->ui->NewLabel->setStyleSheet("QLineEdit#NewLabel{color:red}");
  }
  else
  {
    this->ui->NewLabel->setStyleSheet("QLineEdit#NewLabel{color:blue}");
  }
  return true;
}
<commit_msg>add window bar<commit_after>#include "cmbNucConflictDialog.h"
#include "ui_name_conflict_gui.h"

#include <QMainWindow>

cmbNucConflictDialog::cmbNucConflictDialog(QMainWindow* mainWindow, cmbNucPinLibrary * lib, PinCell * p)
: QDialog(mainWindow,  Qt::CustomizeWindowHint | Qt::WindowTitleHint ), pinLibrary(lib), pin(p)
{
  this->ui = new Ui_name_conflict_gui;

  this->ui->setupUi(this);

  this->ui->NewName->setText(pin->getName().c_str());
  this->ui->NewLabel->setText(pin->getLabel().c_str());
  checkLabels();

  connect( this->ui->Ignore, SIGNAL(toggled(bool)), this, SLOT( selectedIgnore(bool) ) );
  connect( this->ui->OverWrite, SIGNAL(toggled(bool)), this, SLOT(selectedReplace(bool)) );
  connect( this->ui->Rename, SIGNAL(toggled(bool)), this, SLOT(selectedRename(bool)) );
  connect( this->ui->NewLabel, SIGNAL(textEdited(const QString &)), this, SLOT(labelChanged(QString)));
  connect( this->ui->NewName, SIGNAL(textEdited(const QString &)), this, SLOT(nameChanged(QString)));
  connect( this->ui->Apply, SIGNAL(clicked(QAbstractButton *)), this, SLOT(apply()));
}

cmbNucConflictDialog::~cmbNucConflictDialog()
{
  delete ui;
}

void cmbNucConflictDialog::nameChanged(QString v)
{
  bool t = checkLabels();
  if(mode == RENAME) this->ui->Apply->setEnabled(t);
}

void cmbNucConflictDialog::labelChanged(QString v)
{
  bool t = checkLabels();
  if(mode == RENAME) this->ui->Apply->setEnabled(t);
}

void cmbNucConflictDialog::selectedReplace(bool v)
{
  if(v)
  {
    mode = REPLACE;
    this->ui->Apply->setEnabled( true );
    this->ui->NewName->setText(pin->getName().c_str());
    this->ui->NewLabel->setText(pin->getLabel().c_str());
    checkLabels();
    this->ui->NewValue->setEnabled(false);
  }
}

void cmbNucConflictDialog::selectedRename(bool v)
{
  if(v)
  {
    mode = RENAME;
    this->ui->NewValue->setEnabled(true);
    this->ui->Apply->setEnabled(checkLabels());
  }
}

void cmbNucConflictDialog::selectedIgnore(bool v)
{
  if(v)
  {
    mode = IGNORE;
    this->ui->Apply->setEnabled( true );
    this->ui->NewName->setText(pin->getName().c_str());
    this->ui->NewLabel->setText(pin->getLabel().c_str());
    checkLabels();
    this->ui->NewValue->setEnabled(false);
  }
}

void cmbNucConflictDialog::apply()
{
  int rt = 0;
  switch( mode )
  {
    case REPLACE:
      rt = cmbNucPinLibrary::Replace;
      break;
    case IGNORE:
      rt = cmbNucPinLibrary::KeepOriginal;
      break;
    case RENAME:
      rt = cmbNucPinLibrary::KeepOriginal;
      pin->setLabel(this->ui->NewLabel->text().toStdString());
      pin->setName(this->ui->NewName->text().toStdString());
      break;
  }
  this->done( rt );
}

bool cmbNucConflictDialog::checkLabels()
{
  bool r = true;
  std::string name = this->ui->NewName->text().toStdString();
  std::string label = this->ui->NewLabel->text().toStdString();
  if(pinLibrary->nameConflicts(name))
  {
    r = false;
    this->ui->NewName->setStyleSheet("QLineEdit#NewName{color:red}");
  }
  else
  {
    this->ui->NewName->setStyleSheet("QLineEdit#NewName{color:blue}");
  }
  if(pinLibrary->labelConflicts(label))
  {
    r = false;
    this->ui->NewLabel->setStyleSheet("QLineEdit#NewLabel{color:red}");
  }
  else
  {
    this->ui->NewLabel->setStyleSheet("QLineEdit#NewLabel{color:blue}");
  }
  return true;
}
<|endoftext|>


<commit_before>/* bzflag
 * Copyright (c) 1993 - 2004 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

/* common headers */
#include "common.h"

/* interface header */
#include "WinJoystick.h"

/* implementation headers */
#include <mmsystem.h>
#include "ErrorHandler.h"
#include "TextUtils.h"

WinJoystick::WinJoystick() : inited(false)
{
}

WinJoystick::~WinJoystick()
{
}

void	      WinJoystick::initJoystick(const char* joystickName)
{
  inited = false;

  if (!strcmp(joystickName, "off") || !strcmp(joystickName, "")) {
    return;
  }

  if (strlen(joystickName) < 11) {
    printError("Invalid joystick name.");
    return;
  }

  if (joystickName[10] == '1')
    JoystickID = JOYSTICKID1;
  else if (joystickName[10] == '2')
    JoystickID = JOYSTICKID2;

  JOYINFO joyInfo;
  JOYCAPS joyCaps;
  if ((joyGetPos(JoystickID, &joyInfo) != JOYERR_NOERROR) ||
      (joyGetDevCaps(JoystickID, &joyCaps, sizeof(joyCaps)) != JOYERR_NOERROR)) {
    printError("Unable to initialize joystick.  Perhaps it is not plugged in?");
    return;
  }

  xMin = (float)joyCaps.wXmin;
  xMax = (float)joyCaps.wXmax;
  yMin = (float)joyCaps.wYmin;
  yMax = (float)joyCaps.wYmax;

  inited = true;
}

bool	      WinJoystick::joystick() const
{
  return inited;
}

void	      WinJoystick::getJoy(int& x, int& y) const
{
  if (!inited)
    return;

  JOYINFOEX joyInfo;
  // we're only interested in position
  joyInfo.dwFlags = JOY_RETURNX | JOY_RETURNY | JOY_USEDEADZONE;
  joyInfo.dwSize = sizeof(joyInfo);

  // check for errors
  if (joyGetPosEx(JoystickID, &joyInfo) != JOYERR_NOERROR) {
    printError("Could not get extended info from joystick");
    return;
  }

  // adjust X and Y to scale
  x = (joyInfo.dwXpos / xMax) * 2000 - 1000;
  y = (joyInfo.dwYpos / yMax) * 2000 - 1000;

  // ballistic
  x = (x * abs(x)) / 1000;
  y = (y * abs(y)) / 1000;

}

unsigned long WinJoystick::getJoyButtons() const
{
  if (!inited)
    return 0;

  JOYINFOEX joyInfo;
  // we're only interested in buttons
  joyInfo.dwFlags = JOY_RETURNBUTTONS;
  joyInfo.dwSize = sizeof(joyInfo);

  // check for errors
  if (joyGetPosEx(JoystickID, &joyInfo) != JOYERR_NOERROR) {
    printError("Could not get extended info from joystick");
    return 0;
  }

  unsigned long retbuts = joyInfo.dwButtons;
  unsigned long buttons = 0;
  if (retbuts & JOY_BUTTON1)  buttons = buttons | 0x00001;
  if (retbuts & JOY_BUTTON2)  buttons = buttons | 0x00002;
  if (retbuts & JOY_BUTTON3)  buttons = buttons | 0x00004;
  if (retbuts & JOY_BUTTON4)  buttons = buttons | 0x00008;
  if (retbuts & JOY_BUTTON5)  buttons = buttons | 0x00010;
  if (retbuts & JOY_BUTTON6)  buttons = buttons | 0x00020;
  if (retbuts & JOY_BUTTON7)  buttons = buttons | 0x00040;
  if (retbuts & JOY_BUTTON8)  buttons = buttons | 0x00080;
  if (retbuts & JOY_BUTTON9)  buttons = buttons | 0x00100;
  if (retbuts & JOY_BUTTON10) buttons = buttons | 0x00200;

  return buttons;
}

void	      WinJoystick::getJoyDevices(std::vector<std::string> &list) const
{
  list.clear();
  if (joyGetNumDevs() != 0) {
    // we have at least one joystick driver, get the name of both joystick IDs if they exist.
    JOYCAPS joyCaps;
    if (joyGetDevCaps(JOYSTICKID1, &joyCaps, sizeof(joyCaps)) == JOYERR_NOERROR) {
      list.push_back(string_util::format("Joystick 1 (%s)", joyCaps.szPname));
    }
    if (joyGetDevCaps(JOYSTICKID2, &joyCaps, sizeof(joyCaps)) == JOYERR_NOERROR) {
      list.push_back(string_util::format("Joystick 2 (%s)", joyCaps.szPname));
    }
  }
}

// Local Variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<commit_msg>quell MingW warning<commit_after>/* bzflag
 * Copyright (c) 1993 - 2004 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

/* common headers */
#include "common.h"

/* interface header */
#include "WinJoystick.h"

/* implementation headers */
#include <mmsystem.h>
#include "ErrorHandler.h"
#include "TextUtils.h"

WinJoystick::WinJoystick() : inited(false)
{
}

WinJoystick::~WinJoystick()
{
}

void	      WinJoystick::initJoystick(const char* joystickName)
{
  inited = false;

  if (!strcmp(joystickName, "off") || !strcmp(joystickName, "")) {
    return;
  }

  if (strlen(joystickName) < 11) {
    printError("Invalid joystick name.");
    return;
  }

  if (joystickName[10] == '1')
    JoystickID = JOYSTICKID1;
  else if (joystickName[10] == '2')
    JoystickID = JOYSTICKID2;

  JOYINFO joyInfo;
  JOYCAPS joyCaps;
  if ((joyGetPos(JoystickID, &joyInfo) != JOYERR_NOERROR) ||
      (joyGetDevCaps(JoystickID, &joyCaps, sizeof(joyCaps)) != JOYERR_NOERROR)) {
    printError("Unable to initialize joystick.  Perhaps it is not plugged in?");
    return;
  }

  xMin = (float)joyCaps.wXmin;
  xMax = (float)joyCaps.wXmax;
  yMin = (float)joyCaps.wYmin;
  yMax = (float)joyCaps.wYmax;

  inited = true;
}

bool	      WinJoystick::joystick() const
{
  return inited;
}

void	      WinJoystick::getJoy(int& x, int& y) const
{
  if (!inited)
    return;

  JOYINFOEX joyInfo;
  // we're only interested in position
  joyInfo.dwFlags = JOY_RETURNX | JOY_RETURNY | JOY_USEDEADZONE;
  joyInfo.dwSize = sizeof(joyInfo);

  // check for errors
  if (joyGetPosEx(JoystickID, &joyInfo) != JOYERR_NOERROR) {
    printError("Could not get extended info from joystick");
    return;
  }

  // adjust X and Y to scale
  x = (int)((joyInfo.dwXpos / xMax) * 2000 - 1000);
  y = (int)((joyInfo.dwYpos / yMax) * 2000 - 1000);

  // ballistic
  x = (x * abs(x)) / 1000;
  y = (y * abs(y)) / 1000;

}

unsigned long WinJoystick::getJoyButtons() const
{
  if (!inited)
    return 0;

  JOYINFOEX joyInfo;
  // we're only interested in buttons
  joyInfo.dwFlags = JOY_RETURNBUTTONS;
  joyInfo.dwSize = sizeof(joyInfo);

  // check for errors
  if (joyGetPosEx(JoystickID, &joyInfo) != JOYERR_NOERROR) {
    printError("Could not get extended info from joystick");
    return 0;
  }

  unsigned long retbuts = joyInfo.dwButtons;
  unsigned long buttons = 0;
  if (retbuts & JOY_BUTTON1)  buttons = buttons | 0x00001;
  if (retbuts & JOY_BUTTON2)  buttons = buttons | 0x00002;
  if (retbuts & JOY_BUTTON3)  buttons = buttons | 0x00004;
  if (retbuts & JOY_BUTTON4)  buttons = buttons | 0x00008;
  if (retbuts & JOY_BUTTON5)  buttons = buttons | 0x00010;
  if (retbuts & JOY_BUTTON6)  buttons = buttons | 0x00020;
  if (retbuts & JOY_BUTTON7)  buttons = buttons | 0x00040;
  if (retbuts & JOY_BUTTON8)  buttons = buttons | 0x00080;
  if (retbuts & JOY_BUTTON9)  buttons = buttons | 0x00100;
  if (retbuts & JOY_BUTTON10) buttons = buttons | 0x00200;

  return buttons;
}

void	      WinJoystick::getJoyDevices(std::vector<std::string> &list) const
{
  list.clear();
  if (joyGetNumDevs() != 0) {
    // we have at least one joystick driver, get the name of both joystick IDs if they exist.
    JOYCAPS joyCaps;
    if (joyGetDevCaps(JOYSTICKID1, &joyCaps, sizeof(joyCaps)) == JOYERR_NOERROR) {
      list.push_back(string_util::format("Joystick 1 (%s)", joyCaps.szPname));
    }
    if (joyGetDevCaps(JOYSTICKID2, &joyCaps, sizeof(joyCaps)) == JOYERR_NOERROR) {
      list.push_back(string_util::format("Joystick 2 (%s)", joyCaps.szPname));
    }
  }
}

// Local Variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<|endoftext|>


<commit_before>#ifdef HAVE_CMAKE_CONFIG
  #include "cmake_config.h"
#elif defined (HAVE_CONFIG_H)
  #include "config.h"
#endif // ifdef HAVE_CMAKE_CONFIG

#include <boost/filesystem.hpp>

#include <dune/common/exceptions.hh>
#include <dune/common/mpihelper.hh>
#include <dune/common/timer.hh>

#include <dune/stuff/common/parameter/tree.hh>
#include <dune/stuff/common/logging.hh>
#include <dune/stuff/grid/provider.hh>
#include <dune/stuff/grid/boundaryinfo.hh>
#include <dune/stuff/function/expression.hh>

#include <dune/detailed/solvers/stationary/linear/elliptic/model.hh>
#include <dune/detailed/solvers/stationary/linear/elliptic/finitevolume/dune-pdelab.hh>

#ifdef POLORDER
  const int polOrder = POLORDER;
#else
  const int polOrder = 1;
#endif

const std::string id = "stationary.linear.elliptic.fv.dp";

using namespace Dune;
using namespace Dune::Detailed::Solvers;

/**
  \brief      Creates a parameter file if it does not exist.

              Nothing is done if the file already exists. If not, a parameter file will be created with all neccessary
              keys and values.
  \param[in]  filename
              (Relative) path to the file.
  **/
void ensureParamFile(std::string filename)
{
  // only write param file if there is none
  if (!boost::filesystem::exists(filename)) {
    std::ofstream file;
    file.open(filename);
    file << "[" << id << "]" << std::endl;
    file << "grid = stuff.grid.provider.cube" << std::endl;
    file << "model = detailed.solvers.stationary.linear.elliptic.model.default" << std::endl;
    file << "filename = " << id << std::endl;
    file << "[stuff.grid.provider.cube]" << std::endl;
    file << "lowerLeft = [0.0; 0.0; 0.0]" << std::endl;
    file << "upperRight = [1.0; 1.0; 1.0]" << std::endl;
    file << "numElements = 4" << std::endl;
    file << "[stuff.boundaryinfo.idbased]" << std::endl;
    file << "dirichlet = [1; 2; 3]" << std::endl;
    file << "neumann = [4]" << std::endl;
    file << "[detailed.solvers.stationary.linear.elliptic.model.default]" << std::endl;
    file << "diffusion.order = 0"  << std::endl;
    file << "diffusion.variable = x" << std::endl;
    file << "diffusion.expression = [1.0; 1.0; 1.0]"  << std::endl;
    file << "force.order = 0"  << std::endl;
    file << "force.variable = x" << std::endl;
    file << "force.expression = [1.0; 1.0; 1.0]"  << std::endl;
    file << "dirichlet.order = 0"  << std::endl;
    file << "dirichlet.variable = x" << std::endl;
    file << "dirichlet.expression = [1.0; 1.0; 1.0]"  << std::endl;
    file << "neumann.order = 0"  << std::endl;
    file << "neumann.variable = x" << std::endl;
    file << "neumann.expression = [1.0; 1.0; 1.0]"  << std::endl;
    file << "[detailed.solvers.stationary.linear.elliptic.model.thermalblock]" << std::endl;
    file << "diffusion.order = 0"  << std::endl;
    file << "diffusion.lowerLeft = [0.0; 0.0; 0.0]" << std::endl; // should coincide with the grid
    file << "diffusion.upperRight = [1.0; 1.0; 1.0]" << std::endl; // should coincide with the grid
    file << "diffusion.numElements = [2; 2; 2]"  << std::endl;
    file << "diffusion.components = [1.0; 10.0; 3.0; 2.1]"  << std::endl;
    file << "force.order = 0"  << std::endl;
    file << "force.variable = x" << std::endl;
    file << "force.expression = [1.0; 1.0; 1.0]"  << std::endl;
    file << "dirichlet.order = 0"  << std::endl;
    file << "dirichlet.variable = x" << std::endl;
    file << "dirichlet.expression = [1.0; 1.0; 1.0]"  << std::endl;
    file << "neumann.order = 0"  << std::endl;
    file << "neumann.variable = x" << std::endl;
    file << "neumann.expression = [1.0; 1.0; 1.0]"  << std::endl;
    file << "[detailed.solvers.stationary.linear.elliptic.finitevolume.dune-pdelab]" << std::endl;
    file << "solve.type = eigen.bicgstab.incompletelut" << std::endl;
    file << "solve.maxIter = 5000"  << std::endl;
    file << "solve.precision = 1e-12"  << std::endl;
    file << "visualize.name = solution"  << std::endl;
    file.close();
  } // only write param file if there is none
} // void ensureParamFile()

int main(int argc, char** argv)
{
  try {
    // mpi
    MPIHelper::instance(argc, argv);

    // parameter
    const std::string filename = id + ".param";
    ensureParamFile(filename);
    Stuff::Common::ParameterTreeX paramTree(argc, argv, filename);
    paramTree.assertSub(id);

    // logger
    Stuff::Common::Logger().create(Stuff::Common::LOG_INFO |
                                   Stuff::Common::LOG_CONSOLE |
                                   Stuff::Common::LOG_DEBUG);
    Stuff::Common::LogStream& info = Stuff::Common::Logger().info();
    Stuff::Common::LogStream& debug = Stuff::Common::Logger().debug();

    // timer
    Timer timer;

    // grid
    info << "setting up grid: " << std::endl;
    debug.suspend();
    typedef Stuff::Grid::Provider::Interface<> GridProviderType;
    const std::string gridType = paramTree.get< std::string >(id + ".grid");
    const GridProviderType* gridProvider = Stuff::Grid::Provider::create(gridType,
                                                                         paramTree);
    typedef GridProviderType::GridType GridType;
    const shared_ptr< const GridType > grid = gridProvider->grid();
    typedef GridType::LeafGridView GridViewType;
    const shared_ptr< const GridViewType > gridView(new GridViewType(grid->leafView()));
    info << "  done (took " << timer.elapsed()
         << " sec, has " << grid->size(0) << " element";
    if (grid->size(0) > 1)
      info << "s";
    info << ")" << std::endl;
    info << "visualizing grid... " << std::flush;
    timer.reset();
    gridProvider->visualize(paramTree.get(id + ".filename", id) + ".grid");
    info << " done (took " << timer.elapsed() << " sek)" << std::endl;
    debug.resume();

    // model
    info << "setting up model... " << std::flush;
    timer.reset();
    const unsigned int DUNE_UNUSED(dimDomain) = GridProviderType::dim;
    const unsigned int DUNE_UNUSED(dimRange) = 1;
    typedef GridProviderType::CoordinateType::value_type DomainFieldType;
    typedef DomainFieldType RangeFieldType;
    typedef Stationary::Linear::Elliptic::Model::Interface< DomainFieldType, dimDomain,
                                                            RangeFieldType, dimRange >
        ModelType;
    const std::string modelType = paramTree.get< std::string >(id + ".model");
    const shared_ptr< const ModelType > model(
          Stationary::Linear::Elliptic::Model::create< DomainFieldType, dimDomain, RangeFieldType, dimRange >(modelType,
                                                                                paramTree));
    typedef Stuff::Grid::BoundaryInfo::IdBased BoundaryInfoType;
    const shared_ptr< const BoundaryInfoType > boundaryInfo(new BoundaryInfoType(
          BoundaryInfoType::createFromParamTree(paramTree)));
    info << "done (took " << timer.elapsed() << " sec)" << std::endl;

    // solver
    info << "initializing solver:" << std::endl;
    typedef Stationary::Linear::Elliptic::FiniteVolume::DunePdelab< ModelType,
                                                                    GridViewType,
                                                                    BoundaryInfoType,
                                                                    polOrder >
             SolverType;
    const Stuff::Common::ParameterTreeX solverTree = paramTree.sub(SolverType::id());
    SolverType solver(model, gridView, boundaryInfo);
    solver.init("  ", debug);

    info << "solving:" << std::endl;
    typedef SolverType::VectorBackendType SolutionType;
    Dune::shared_ptr< SolutionType > solution = solver.createVector();
    solver.solve(*solution, paramTree, "  ", debug);

    info << "postprocessing:" << std::endl;

//    solver.visualize(*solution,
//                     paramTree.get(id + ".filename", id) + ".solution",
//                     solverTree.get("visualize.name", "solution"),
//                     "  ",
//                     debug);

    Dune::shared_ptr< SolverType::DiscreteGridFunctionType > discreteFunction = solver.createDiscreteFunction(*solution,"discreteFunction");
    solver.visualize(discreteFunction,
                     paramTree.get(id + ".filename", id) + ".solution",
                     "  ",
                     debug);

    // if we came that far we can as well be happy about it
    return 0;
  } catch (Dune::Exception& e) {
    std::cerr << "Dune reported error: " << e.what() << std::endl;
  } catch (std::exception& e) {
    std::cerr << e.what() << std::endl;
  } catch ( ... ) {
    std::cerr << "Unknown exception thrown!" << std::endl;
  } // try
} // main
<commit_msg>[examples...elliptic.finitevolume.dune_pdelab] update, should work now<commit_after>#ifdef HAVE_CMAKE_CONFIG
  #include "cmake_config.h"
#elif defined (HAVE_CONFIG_H)
  #include "config.h"
#endif // ifdef HAVE_CMAKE_CONFIG

#include <boost/filesystem.hpp>

#include <dune/common/exceptions.hh>
#include <dune/common/mpihelper.hh>
#include <dune/common/timer.hh>

#include <dune/stuff/common/parameter/tree.hh>
#include <dune/stuff/common/logging.hh>
#include <dune/stuff/grid/provider.hh>
#include <dune/stuff/grid/boundaryinfo.hh>
#include <dune/stuff/function/expression.hh>

#include <dune/detailed/solvers/stationary/linear/elliptic/model.hh>
#include <dune/detailed/solvers/stationary/linear/elliptic/finitevolume/dune-pdelab.hh>

#ifdef POLORDER
  const int polOrder = POLORDER;
#else
  const int polOrder = 1;
#endif

const std::string id = "stationary.linear.elliptic.fv.dp";

using namespace Dune;
using namespace Dune::Detailed::Solvers;

/**
  \brief      Creates a parameter file if it does not exist.

              Nothing is done if the file already exists. If not, a parameter file will be created with all neccessary
              keys and values.
  \param[in]  filename
              (Relative) path to the file.
  **/
void ensureParamFile(std::string filename)
{
  // only write param file if there is none
  if (!boost::filesystem::exists(filename)) {
    std::ofstream file;
    file.open(filename);
    file << "[" << id << "]" << std::endl;
    file << "grid = stuff.grid.provider.cube" << std::endl;
    file << "model = detailed.solvers.stationary.linear.elliptic.model.default" << std::endl;
    file << "filename = " << id << std::endl;
    file << "[stuff.grid.provider.cube]" << std::endl;
    file << "lowerLeft = [0.0; 0.0; 0.0]" << std::endl;
    file << "upperRight = [1.0; 1.0; 1.0]" << std::endl;
    file << "numElements = 20" << std::endl;
    file << "[stuff.boundaryinfo.idbased]" << std::endl;
    file << "dirichlet = [1; 4]" << std::endl;
    file << "neumann = [2; 3]" << std::endl;
    file << "[detailed.solvers.stationary.linear.elliptic.model.default]" << std::endl;
    file << "diffusion.order = 0"  << std::endl;
    file << "diffusion.variable = x" << std::endl;
    file << "diffusion.expression = [1.0; 1.0; 1.0]"  << std::endl;
    file << "force.order = 0"  << std::endl;
    file << "force.variable = x" << std::endl;
    file << "force.expression = [1.0; 1.0; 1.0]"  << std::endl;
    file << "dirichlet.order = 0"  << std::endl;
    file << "dirichlet.variable = x" << std::endl;
    file << "dirichlet.expression = [0.0; 0.0; 0.0]"  << std::endl;
    file << "neumann.order = 0"  << std::endl;
    file << "neumann.variable = x" << std::endl;
    file << "neumann.expression = [0.0; 0.0; 0.0]"  << std::endl;
    file << "[detailed.solvers.stationary.linear.elliptic.model.thermalblock]" << std::endl;
    file << "diffusion.order = 0"  << std::endl;
    file << "diffusion.lowerLeft = [0.0; 0.0; 0.0]" << std::endl; // should coincide with the grid
    file << "diffusion.upperRight = [1.0; 1.0; 1.0]" << std::endl; // should coincide with the grid
    file << "diffusion.numElements = [2; 2; 2]"  << std::endl;
    file << "diffusion.components = [1.0; 10.0; 3.0; 2.1]"  << std::endl;
    file << "force.order = 0"  << std::endl;
    file << "force.variable = x" << std::endl;
    file << "force.expression = [1.0; 1.0; 1.0]"  << std::endl;
    file << "dirichlet.order = 0"  << std::endl;
    file << "dirichlet.variable = x" << std::endl;
    file << "dirichlet.expression = [1.0; 1.0; 1.0]"  << std::endl;
    file << "neumann.order = 0"  << std::endl;
    file << "neumann.variable = x" << std::endl;
    file << "neumann.expression = [1.0; 1.0; 1.0]"  << std::endl;
    file << "[detailed.solvers.stationary.linear.elliptic.finitevolume.dune-pdelab]" << std::endl;
    file << "solve.type = eigen.bicgstab.incompletelut" << std::endl;
    file << "solve.maxIter = 5000"  << std::endl;
    file << "solve.precision = 1e-12"  << std::endl;
    file << "visualize.name = solution"  << std::endl;
    file.close();
  } // only write param file if there is none
} // void ensureParamFile()

int main(int argc, char** argv)
{
  try {
    // mpi
    MPIHelper::instance(argc, argv);

    // parameter
    const std::string filename = id + ".param";
    ensureParamFile(filename);
    Stuff::Common::ParameterTreeX paramTree(argc, argv, filename);
    paramTree.assertSub(id);

    // logger
    Stuff::Common::Logger().create(Stuff::Common::LOG_INFO |
                                   Stuff::Common::LOG_CONSOLE |
                                   Stuff::Common::LOG_DEBUG);
    Stuff::Common::LogStream& info = Stuff::Common::Logger().info();
    Stuff::Common::LogStream& debug = Stuff::Common::Logger().debug();

    // timer
    Timer timer;

    // grid
    info << "setting up grid: " << std::endl;
    debug.suspend();
    typedef Stuff::Grid::Provider::Interface<> GridProviderType;
    const std::string gridType = paramTree.get< std::string >(id + ".grid");
    const GridProviderType* gridProvider = Stuff::Grid::Provider::create(gridType,
                                                                         paramTree);
    typedef GridProviderType::GridType GridType;
    const shared_ptr< const GridType > grid = gridProvider->grid();
    typedef GridType::LeafGridView GridViewType;
    const shared_ptr< const GridViewType > gridView(new GridViewType(grid->leafView()));
    info << "  done (took " << timer.elapsed()
         << " sec, has " << grid->size(0) << " element";
    if (grid->size(0) > 1)
      info << "s";
    info << ")" << std::endl;
    info << "visualizing grid... " << std::flush;
    timer.reset();
    gridProvider->visualize(paramTree.get(id + ".filename", id) + ".grid");
    info << " done (took " << timer.elapsed() << " sek)" << std::endl;
    debug.resume();

    // model
    info << "setting up model... " << std::flush;
    timer.reset();
    const unsigned int DUNE_UNUSED(dimDomain) = GridProviderType::dim;
    const unsigned int DUNE_UNUSED(dimRange) = 1;
    typedef GridProviderType::CoordinateType::value_type DomainFieldType;
    typedef DomainFieldType RangeFieldType;
    typedef Stationary::Linear::Elliptic::Model::Interface< DomainFieldType, dimDomain,
                                                            RangeFieldType, dimRange >
        ModelType;
    const std::string modelType = paramTree.get< std::string >(id + ".model");
    const shared_ptr< const ModelType > model(
          Stationary::Linear::Elliptic::Model::create< DomainFieldType, dimDomain, RangeFieldType, dimRange >(modelType,
                                                                                paramTree));
    typedef Stuff::Grid::BoundaryInfo::IdBased BoundaryInfoType;
    const shared_ptr< const BoundaryInfoType > boundaryInfo(new BoundaryInfoType(
          BoundaryInfoType::createFromParamTree(paramTree)));
    info << "done (took " << timer.elapsed() << " sec)" << std::endl;

    // solver
    info << "initializing solver:" << std::endl;
    typedef Stationary::Linear::Elliptic::FiniteVolume::DunePdelab< ModelType,
                                                                    GridViewType,
                                                                    BoundaryInfoType,
                                                                    polOrder >
             SolverType;
    const Stuff::Common::ParameterTreeX solverTree = paramTree.sub(SolverType::id());
    SolverType solver(model, gridView, boundaryInfo);
    solver.init("  ", debug);

    info << "solving:" << std::endl;
    typedef SolverType::VectorBackendType SolutionType;
    Dune::shared_ptr< SolutionType > solution = solver.createVector();
    solver.solve(*solution,
                 paramTree,
                 solverTree.get("solve.maxIter", 1000),
                 solverTree.get("solve.precision", 1e-12),
                 "  ",
                 debug);

    info << "postprocessing:" << std::endl;
    Dune::shared_ptr< SolverType::DiscreteFunctionType > discreteFunction = solver.createDiscreteFunction(*solution);
    solver.visualize(discreteFunction,
                     paramTree.get(id + ".filename", id) + ".solution",
                     solverTree.get("visualize.name", "solution"),
                     "  ",
                     debug);

    // if we came that far we can as well be happy about it
    return 0;
  } catch (Dune::Exception& e) {
    std::cerr << "Dune reported error: " << e.what() << std::endl;
  } catch (std::exception& e) {
    std::cerr << e.what() << std::endl;
  } catch ( ... ) {
    std::cerr << "Unknown exception thrown!" << std::endl;
  } // try
} // main
<|endoftext|>


<commit_before>/* This file is part of the KDE project
   Copyright (C) 2004 David Faure <faure@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 "testdistrlist.h"

#include <distributionlist.h>
using KPIM::DistributionList;

#include <config.h>

#include <kabc/stdaddressbook.h>
#include <kurl.h>
#include <kapplication.h>
#include <kio/netaccess.h>
#include <kio/job.h>
#include <kdebug.h>
#include <kcmdlineargs.h>

#include <qdir.h>
#include <qfileinfo.h>

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>

int main(int argc, char *argv[])
{
    // Use another directory than the real one, just to keep things clean
    // KDEHOME needs to be writable though, for a ksycoca database
    setenv( "KDEHOME", QFile::encodeName( QDir::homeDirPath() + "/.kde-testdistrlist" ), true );
    setenv( "KDE_FORK_SLAVES", "yes", true ); // simpler, for the final cleanup

    KApplication::disableAutoDcopRegistration();
    KCmdLineArgs::init(argc,argv,"testdistrlist", 0, 0, 0, 0);
    KApplication app;

    TestDistrList test;
    test.setup();
    test.runAll();
    test.cleanup();
    kdDebug() << "All tests OK." << endl;
    return 0;
}

void TestDistrList::setup()
{
    // We need a std addressbook
    KABC::AddressBook *ab = KABC::StdAddressBook::self();
    KABC::StdAddressBook::setAutomaticSave( false );

    // and two contacts
    KABC::Addressee addr1;
    addr1.setName( "addr1" );
    addr1.setFormattedName( "addr1" );
    addr1.insertEmail( "addr1@kde.org", true );
    addr1.insertEmail( "addr1-alternate@kde.org" );
    ab->insertAddressee( addr1 );
    assert( addr1.emails().count() == 2 );

    KABC::Addressee addr2;
    addr2.setName( "addr2" );
    addr2.insertEmail( "addr2@kde.org", true );
    addr2.insertEmail( "addr2-alternate@kde.org" );
    ab->insertAddressee( addr2 );
    assert( addr2.emails().count() == 2 );

    assert( !ab->findByName( "addr1" ).isEmpty() );
    assert( !ab->findByName( "addr2" ).isEmpty() );
}

void TestDistrList::runAll()
{
    testEmpty();
    testNewList();
    testInsertEntry();
    testRemoveEntry();
    testDuplicate();
    testDeleteList();
}

bool TestDistrList::check(const QString& txt, QString a, QString b)
{
    if (a.isEmpty())
        a = QString::null;
    if (b.isEmpty())
        b = QString::null;
    if (a == b) {
        kdDebug() << txt << " : checking '" << a << "' against expected value '" << b << "'... " << "ok" << endl;
    }
    else {
        kdDebug() << txt << " : checking '" << a << "' against expected value '" << b << "'... " << "KO !" << endl;
        cleanup();
        exit(1);
    }
    return true;
}

void TestDistrList::cleanup()
{
    kdDebug() << k_funcinfo << endl;
    KABC::AddressBook *ab = KABC::StdAddressBook::self();
    ab->clear();
    KABC::StdAddressBook::close();

    QString kdehome = QFile::decodeName( getenv("KDEHOME") );
    KURL urlkdehome; urlkdehome.setPath( kdehome );
    KIO::NetAccess::del( urlkdehome, 0 );
}

void TestDistrList::testEmpty()
{
    kdDebug() << k_funcinfo << endl;
    DistributionList dl;
    assert( dl.isEmpty() );
}

void TestDistrList::testNewList()
{
    kdDebug() << k_funcinfo << endl;
    DistributionList dl;
    dl.setName( "foo" );
    assert( !dl.isEmpty() );
    check( "name set", dl.formattedName(), "foo" );
    assert( DistributionList::isDistributionList( dl ) );

    KABC::AddressBook *ab = KABC::StdAddressBook::self();
    ab->insertAddressee( dl );
#if 0 // can't do that until we have KABC::AddressBook::findByFormattedName, or we use setName()
    KABC::Addressee::List addrList = ab->findByName( "foo" );
    assert( addrList.count() == 1 );
    KABC::Addressee addr = addrList.first();
    assert( !addr.isEmpty() );
    check( "correct name", addr.name(), "foo" );
    assert( DistributionList::isDistributionList( addr ) );
#else
    KABC::Addressee addr = dl;
#endif

    DistributionList dl2 = DistributionList::findByName( ab, "foo" );
    assert( !dl2.isEmpty() );
    check( "correct name", dl2.formattedName(), "foo" );
    assert( DistributionList::isDistributionList( dl2 ) );

    // Test the ctor that takes an addressee
    DistributionList dl3( addr );
    assert( !dl3.isEmpty() );
    assert( DistributionList::isDistributionList( dl3 ) );
    check( "correct name", dl3.formattedName(), "foo" );
}

void TestDistrList::testInsertEntry()
{
    kdDebug() << k_funcinfo << endl;
    KABC::AddressBook *ab = KABC::StdAddressBook::self();
    DistributionList dl = DistributionList::findByName( ab, "foo" );
    assert( !dl.isEmpty() );

#if 0 // the usual method
    KABC::Addressee addr1 = ab->findByName( "addr1" ).first();
    assert( !addr1.isEmpty() );
    dl.insertEntry( addr1 );
#else // the kolab-resource method
    dl.insertEntry( "addr1" );
#endif

    KABC::Addressee addr2 = ab->findByName( "addr2" ).first();
    assert( !addr2.isEmpty() );
    dl.insertEntry( addr2, "addr2-alternate@kde.org" );

    // Try inserting it again, should do nothing
    dl.insertEntry( addr2, "addr2-alternate@kde.org" );

    // And insert it with another email address
    dl.insertEntry( addr2, "addr2@kde.org" );

    // Test entries()
    DistributionList::Entry::List entries = dl.entries( ab );
    check( "entries count", QString::number( entries.count() ), "3" );
    check( "first entry", entries[0].addressee.name(), "addr1" );
    check( "first entry", entries[0].email, QString::null );
    check( "second entry", entries[1].addressee.name(), "addr2" );
    check( "second entry", entries[1].email, "addr2-alternate@kde.org" );
    check( "third entry", entries[2].addressee.name(), "addr2" );
    check( "third entry", entries[2].email, "addr2@kde.org" );

    // Test emails()
    QStringList emails = dl.emails( ab );
    kdDebug() << emails << endl;
    assert( emails.count() == 3 );
    check( "first email", emails[0], "addr1 <addr1@kde.org>" );
    check( "second email", emails[1], "addr2 <addr2-alternate@kde.org>" );
    check( "third email", emails[2], "addr2 <addr2@kde.org>" );

    // Commit changes to the addressbook !!
    ab->insertAddressee( dl );
}

void TestDistrList::testRemoveEntry()
{
    kdDebug() << k_funcinfo << endl;
    KABC::AddressBook *ab = KABC::StdAddressBook::self();
    DistributionList dl = DistributionList::findByName( ab, "foo" );
    assert( !dl.isEmpty() );
    DistributionList::Entry::List entries = dl.entries( ab );
    check( "entries count before removeEntry", QString::number( entries.count() ), "3" );

    // Removing an empty entry shouldn't do anything
    dl.removeEntry( KABC::Addressee() );
    check( "entries count after removing empty entry", QString::number( dl.entries(ab).count() ), "3" );

    KABC::Addressee addr1 = ab->findByName( "addr1" ).first();
    assert( !addr1.isEmpty() );
    // Removing an entry with the wrong email passed, shouldn't do anything
    dl.removeEntry( addr1, "foo@foobar.com" );
    check( "entries count after removing entry with invalid email", QString::number( dl.entries(ab).count() ), "3" );

    // Now remove entry correctly
    dl.removeEntry( addr1 );
    check( "removeEntry(addr1) worked", QString::number( dl.entries(ab).count() ), "2" );
    QStringList emails = dl.emails( ab );
    assert( emails.count() == 2 );
    check( "first email", emails[0], "addr2 <addr2-alternate@kde.org>" );

    // Now move on to addr2. First remove with no or a wrong email (nothing should happen)
    KABC::Addressee addr2 = ab->findByName( "addr2" ).first();
    assert( !addr2.isEmpty() );
    dl.removeEntry( addr2 );
    check( "entries count after removing entry with no email", QString::number( dl.entries(ab).count() ), "2" );

    // Now remove addr2 correctly
    dl.removeEntry( addr2, "addr2@kde.org" );
    check( "entries count after removing addr2", QString::number( dl.entries(ab).count() ), "1" );
    dl.removeEntry( addr2, "addr2-alternate@kde.org" );
    check( "entries count after removing alternate addr2", QString::number( dl.entries(ab).count() ), "0" );
    assert( dl.entries(ab).isEmpty() );
    assert( dl.emails(ab).isEmpty() );
    assert( DistributionList::isDistributionList( dl ) );

    ab->insertAddressee( dl );
}

void TestDistrList::testDuplicate()
{
    kdDebug() << k_funcinfo << endl;
    // This is a special test for the case where we have a contact and a distr list with the same name
    KABC::AddressBook *ab = KABC::StdAddressBook::self();
    KABC::Addressee addr;
    addr.setName( "foo" );
    addr.insertEmail( "foo@kde.org", true );
    ab->insertAddressee( addr );

#if 0 // we need a findByFormattedName
    KABC::Addressee::List addrList = ab->findByName( "foo" );
    assert( addrList.count() == 2 );

    bool a = DistributionList::isDistributionList( addrList.first() );
    bool b = DistributionList::isDistributionList( addrList.last() );
    // one is a distr list, but not both
    assert( a || b );
    //
    assert( ! ( a && b ) );
#endif

    DistributionList dl = DistributionList::findByName( ab, "foo" );
    assert( !dl.isEmpty() );
    assert( DistributionList::isDistributionList( dl ) );
    assert( dl.formattedName() == "foo" );
}

void TestDistrList::testDeleteList()
{
    kdDebug() << k_funcinfo << endl;

    KABC::AddressBook *ab = KABC::StdAddressBook::self();
    DistributionList dl = DistributionList::findByName( ab, "foo" );
    assert( !dl.isEmpty() );
    ab->removeAddressee( dl );
    dl = DistributionList::findByName( ab, "foo" );
    assert( dl.isEmpty() );
}

#include "testdistrlist.moc"
<commit_msg>Remove X dependency for this test.<commit_after>/* This file is part of the KDE project
   Copyright (C) 2004 David Faure <faure@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 "testdistrlist.h"

#include <distributionlist.h>
using KPIM::DistributionList;

#include <config.h>

#include <kabc/stdaddressbook.h>
#include <kurl.h>
#include <kapplication.h>
#include <kio/netaccess.h>
#include <kio/job.h>
#include <kdebug.h>
#include <kcmdlineargs.h>

#include <qdir.h>
#include <qfileinfo.h>

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>

int main(int argc, char *argv[])
{
    // Use another directory than the real one, just to keep things clean
    // KDEHOME needs to be writable though, for a ksycoca database
    setenv( "KDEHOME", QFile::encodeName( QDir::homeDirPath() + "/.kde-testdistrlist" ), true );
    setenv( "KDE_FORK_SLAVES", "yes", true ); // simpler, for the final cleanup

    KApplication::disableAutoDcopRegistration();
    KCmdLineArgs::init(argc,argv,"testdistrlist", 0, 0, 0, 0);
    KApplication app( false, false );

    TestDistrList test;
    test.setup();
    test.runAll();
    test.cleanup();
    kdDebug() << "All tests OK." << endl;
    return 0;
}

void TestDistrList::setup()
{
    // We need a std addressbook
    KABC::AddressBook *ab = KABC::StdAddressBook::self();
    KABC::StdAddressBook::setAutomaticSave( false );

    // and two contacts
    KABC::Addressee addr1;
    addr1.setName( "addr1" );
    addr1.setFormattedName( "addr1" );
    addr1.insertEmail( "addr1@kde.org", true );
    addr1.insertEmail( "addr1-alternate@kde.org" );
    ab->insertAddressee( addr1 );
    assert( addr1.emails().count() == 2 );

    KABC::Addressee addr2;
    addr2.setName( "addr2" );
    addr2.insertEmail( "addr2@kde.org", true );
    addr2.insertEmail( "addr2-alternate@kde.org" );
    ab->insertAddressee( addr2 );
    assert( addr2.emails().count() == 2 );

    assert( !ab->findByName( "addr1" ).isEmpty() );
    assert( !ab->findByName( "addr2" ).isEmpty() );
}

void TestDistrList::runAll()
{
    testEmpty();
    testNewList();
    testInsertEntry();
    testRemoveEntry();
    testDuplicate();
    testDeleteList();
}

bool TestDistrList::check(const QString& txt, QString a, QString b)
{
    if (a.isEmpty())
        a = QString::null;
    if (b.isEmpty())
        b = QString::null;
    if (a == b) {
        kdDebug() << txt << " : checking '" << a << "' against expected value '" << b << "'... " << "ok" << endl;
    }
    else {
        kdDebug() << txt << " : checking '" << a << "' against expected value '" << b << "'... " << "KO !" << endl;
        cleanup();
        exit(1);
    }
    return true;
}

// taken from KMail
#include <sys/types.h>
#include <dirent.h>
static bool removeDirAndContentsRecursively( const QString & path )
{
  kdDebug() << k_funcinfo << path << endl;
  bool success = true;

  QDir d;
  d.setPath( path );
  d.setFilter( QDir::Files | QDir::Dirs | QDir::Hidden );

  const QFileInfoList *list = d.entryInfoList();
  QFileInfoListIterator it( *list );
  QFileInfo *fi;

  while ( (fi = it.current()) != 0 ) {
    if( fi->isDir() && !fi->isSymLink() ) {
      if ( fi->fileName() != "." && fi->fileName() != ".." )
        success = success && removeDirAndContentsRecursively( fi->absFilePath() );
    } else {
      success = success && d.remove( fi->absFilePath() );
    }
    ++it;
  }

  if ( success ) {
    success = success && d.rmdir( path ); // nuke ourselves, we should be empty now
  }
  return success;
}

void TestDistrList::cleanup()
{
    kdDebug() << k_funcinfo << endl;
    KABC::AddressBook *ab = KABC::StdAddressBook::self();
    ab->clear();
    KABC::StdAddressBook::close();

    QString kdehome = QFile::decodeName( getenv("KDEHOME") );
    KURL urlkdehome; urlkdehome.setPath( kdehome );
    // don't use KIO::NetAccess here since it needs X
    // KIO::NetAccess::del( urlkdehome, 0 )i;
    assert( removeDirAndContentsRecursively( kdehome ) );
}

void TestDistrList::testEmpty()
{
    kdDebug() << k_funcinfo << endl;
    DistributionList dl;
    assert( dl.isEmpty() );
}

void TestDistrList::testNewList()
{
    kdDebug() << k_funcinfo << endl;
    DistributionList dl;
    dl.setName( "foo" );
    assert( !dl.isEmpty() );
    check( "name set", dl.formattedName(), "foo" );
    assert( DistributionList::isDistributionList( dl ) );

    KABC::AddressBook *ab = KABC::StdAddressBook::self();
    ab->insertAddressee( dl );
#if 0 // can't do that until we have KABC::AddressBook::findByFormattedName, or we use setName()
    KABC::Addressee::List addrList = ab->findByName( "foo" );
    assert( addrList.count() == 1 );
    KABC::Addressee addr = addrList.first();
    assert( !addr.isEmpty() );
    check( "correct name", addr.name(), "foo" );
    assert( DistributionList::isDistributionList( addr ) );
#else
    KABC::Addressee addr = dl;
#endif

    DistributionList dl2 = DistributionList::findByName( ab, "foo" );
    assert( !dl2.isEmpty() );
    check( "correct name", dl2.formattedName(), "foo" );
    assert( DistributionList::isDistributionList( dl2 ) );

    // Test the ctor that takes an addressee
    DistributionList dl3( addr );
    assert( !dl3.isEmpty() );
    assert( DistributionList::isDistributionList( dl3 ) );
    check( "correct name", dl3.formattedName(), "foo" );
}

void TestDistrList::testInsertEntry()
{
    kdDebug() << k_funcinfo << endl;
    KABC::AddressBook *ab = KABC::StdAddressBook::self();
    DistributionList dl = DistributionList::findByName( ab, "foo" );
    assert( !dl.isEmpty() );

#if 0 // the usual method
    KABC::Addressee addr1 = ab->findByName( "addr1" ).first();
    assert( !addr1.isEmpty() );
    dl.insertEntry( addr1 );
#else // the kolab-resource method
    dl.insertEntry( "addr1" );
#endif

    KABC::Addressee addr2 = ab->findByName( "addr2" ).first();
    assert( !addr2.isEmpty() );
    dl.insertEntry( addr2, "addr2-alternate@kde.org" );

    // Try inserting it again, should do nothing
    dl.insertEntry( addr2, "addr2-alternate@kde.org" );

    // And insert it with another email address
    dl.insertEntry( addr2, "addr2@kde.org" );

    // Test entries()
    DistributionList::Entry::List entries = dl.entries( ab );
    check( "entries count", QString::number( entries.count() ), "3" );
    check( "first entry", entries[0].addressee.name(), "addr1" );
    check( "first entry", entries[0].email, QString::null );
    check( "second entry", entries[1].addressee.name(), "addr2" );
    check( "second entry", entries[1].email, "addr2-alternate@kde.org" );
    check( "third entry", entries[2].addressee.name(), "addr2" );
    check( "third entry", entries[2].email, "addr2@kde.org" );

    // Test emails()
    QStringList emails = dl.emails( ab );
    kdDebug() << emails << endl;
    assert( emails.count() == 3 );
    check( "first email", emails[0], "addr1 <addr1@kde.org>" );
    check( "second email", emails[1], "addr2 <addr2-alternate@kde.org>" );
    check( "third email", emails[2], "addr2 <addr2@kde.org>" );

    // Commit changes to the addressbook !!
    ab->insertAddressee( dl );
}

void TestDistrList::testRemoveEntry()
{
    kdDebug() << k_funcinfo << endl;
    KABC::AddressBook *ab = KABC::StdAddressBook::self();
    DistributionList dl = DistributionList::findByName( ab, "foo" );
    assert( !dl.isEmpty() );
    DistributionList::Entry::List entries = dl.entries( ab );
    check( "entries count before removeEntry", QString::number( entries.count() ), "3" );

    // Removing an empty entry shouldn't do anything
    dl.removeEntry( KABC::Addressee() );
    check( "entries count after removing empty entry", QString::number( dl.entries(ab).count() ), "3" );

    KABC::Addressee addr1 = ab->findByName( "addr1" ).first();
    assert( !addr1.isEmpty() );
    // Removing an entry with the wrong email passed, shouldn't do anything
    dl.removeEntry( addr1, "foo@foobar.com" );
    check( "entries count after removing entry with invalid email", QString::number( dl.entries(ab).count() ), "3" );

    // Now remove entry correctly
    dl.removeEntry( addr1 );
    check( "removeEntry(addr1) worked", QString::number( dl.entries(ab).count() ), "2" );
    QStringList emails = dl.emails( ab );
    assert( emails.count() == 2 );
    check( "first email", emails[0], "addr2 <addr2-alternate@kde.org>" );

    // Now move on to addr2. First remove with no or a wrong email (nothing should happen)
    KABC::Addressee addr2 = ab->findByName( "addr2" ).first();
    assert( !addr2.isEmpty() );
    dl.removeEntry( addr2 );
    check( "entries count after removing entry with no email", QString::number( dl.entries(ab).count() ), "2" );

    // Now remove addr2 correctly
    dl.removeEntry( addr2, "addr2@kde.org" );
    check( "entries count after removing addr2", QString::number( dl.entries(ab).count() ), "1" );
    dl.removeEntry( addr2, "addr2-alternate@kde.org" );
    check( "entries count after removing alternate addr2", QString::number( dl.entries(ab).count() ), "0" );
    assert( dl.entries(ab).isEmpty() );
    assert( dl.emails(ab).isEmpty() );
    assert( DistributionList::isDistributionList( dl ) );

    ab->insertAddressee( dl );
}

void TestDistrList::testDuplicate()
{
    kdDebug() << k_funcinfo << endl;
    // This is a special test for the case where we have a contact and a distr list with the same name
    KABC::AddressBook *ab = KABC::StdAddressBook::self();
    KABC::Addressee addr;
    addr.setName( "foo" );
    addr.insertEmail( "foo@kde.org", true );
    ab->insertAddressee( addr );

#if 0 // we need a findByFormattedName
    KABC::Addressee::List addrList = ab->findByName( "foo" );
    assert( addrList.count() == 2 );

    bool a = DistributionList::isDistributionList( addrList.first() );
    bool b = DistributionList::isDistributionList( addrList.last() );
    // one is a distr list, but not both
    assert( a || b );
    //
    assert( ! ( a && b ) );
#endif

    DistributionList dl = DistributionList::findByName( ab, "foo" );
    assert( !dl.isEmpty() );
    assert( DistributionList::isDistributionList( dl ) );
    assert( dl.formattedName() == "foo" );
}

void TestDistrList::testDeleteList()
{
    kdDebug() << k_funcinfo << endl;

    KABC::AddressBook *ab = KABC::StdAddressBook::self();
    DistributionList dl = DistributionList::findByName( ab, "foo" );
    assert( !dl.isEmpty() );
    ab->removeAddressee( dl );
    dl = DistributionList::findByName( ab, "foo" );
    assert( dl.isEmpty() );
}

#include "testdistrlist.moc"
<|endoftext|>


<commit_before>#include "stdafx.h"
#include "ImageController.h"

lload::CImageController::CImageController()
{
	m_imageLoader = std::make_unique<CImageLoader>(L"./images/");
	m_imageLoader->SetImagePageSize(m_pageSize);

	m_collections.push_back({});
	m_imageLoader->Load(m_collections.back(), 0);
	m_currentCollection = m_collections.begin();
}

bool lload::CImageController::NeedUpdate()
{
	return m_needUpdate;
}

void lload::CImageController::NextPage()
{
	if (m_currentCollectionIndex == m_collections.size() - 1)
	{
		m_currentCollectionIndex = 0;
		m_currentCollection = std::begin(m_collections);
	}
	else if(m_collections.size() != 0)
	{
		m_currentCollectionIndex++;
		m_currentCollection++;
	}

	UpdateCollections(false);
}

void lload::CImageController::PrevPage()
{
	if (m_currentCollectionIndex == 0)
	{
		if (m_collections.size() != 0)
		{
			m_currentCollectionIndex = m_collections.size() - 1;
		}
		m_currentCollection = std::end(m_collections);
	}
	else
	{
		m_currentCollectionIndex--;
		m_currentCollection--;
	}

	UpdateCollections(true);
}

lload::CImageCollection & lload::CImageController::GetPage()
{
	return *m_currentCollection;
}

void lload::CImageController::UpdateCollections(bool left)
{
	if (left)
	{
		if (m_currentCollectionIndex > 0)
		{
			m_collections.push_front({});
			m_imageLoader->Load(m_collections.front(), (m_currentCollectionIndex - 1) * m_pageSize);
			if (m_collections.size() > 3)
			{
				m_collections.pop_back();
			}
			else if (m_collections.size() == 1)
			{
				m_currentCollection = m_collections.begin();
			}
		}
	}
	else
	{
		if (m_currentCollectionIndex * m_pageSize < m_imageLoader->GetFileNumber())
		{
			m_collections.push_back({});
			m_imageLoader->Load(m_collections.back(), (m_currentCollectionIndex + 1) * m_pageSize);
			if (m_collections.size() > 3)
			{
				m_collections.pop_front();
			}
			else if (m_collections.size() == 1)
			{
				m_currentCollection = m_collections.begin();
			}
		}
	}
}
<commit_msg>Вывод контроллера в консоль изменен<commit_after>#include "stdafx.h"
#include "ImageController.h"

lload::CImageController::CImageController()
{
	m_imageLoader = std::make_unique<CImageLoader>(L"./images/");
	m_imageLoader->SetImagePageSize(m_pageSize);

	//load first page
	m_collections.push_back({});
	m_imageLoader->Load(m_collections.back(), 0);
	m_currentCollection = m_collections.begin();
	m_currentCollectionIndex = 0;
	UpdateCollections(false);//load next page
}

bool lload::CImageController::NeedUpdate()
{
	return m_needUpdate;
}

void lload::CImageController::NextPage()
{
	if(m_currentCollection != m_collections.end())
	{

		m_currentCollectionIndex++;
		m_currentCollection++;

		UpdateCollections(false);
	}
}

void lload::CImageController::PrevPage()
{
	if (m_currentCollectionIndex > 0)
	{
		m_currentCollectionIndex--;
		m_currentCollection--;
		UpdateCollections(true);
	}
}

lload::CImageCollection & lload::CImageController::GetPage()
{
	return *m_currentCollection;
}

void lload::CImageController::UpdateCollections(bool left)
{
	if (left)
	{
		//load left page
		if (m_currentCollectionIndex > 0)
		{
			m_collections.push_front({});
			m_imageLoader->Load(m_collections.front(), (m_currentCollectionIndex - 1) * m_pageSize);
			if (m_collections.size() > 3 && m_currentCollectionIndex != 0)
			{
				m_collections.pop_back();
			}
		}
	}
	else if (m_currentCollectionIndex * m_pageSize < m_imageLoader->GetFileNumber())
	{
		std::cout << m_currentCollectionIndex * m_pageSize << " " << m_imageLoader->GetFileNumber() << '\n';
		//load right page
		m_collections.push_back({});
		try
		{
			m_imageLoader->Load(m_collections.back(), (m_currentCollectionIndex + 1) * m_pageSize);
		}
		catch (...)
		{
			m_collections.pop_back();
		}

		if (m_collections.size() > 3)
		{
			m_collections.pop_front();
		}
	}
}
<|endoftext|>