<commit_before>// Copyright (c) 2010 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 "chrome/browser/chrome_thread.h"
#include "chrome/browser/speech/speech_input_bubble_controller.h"
#include "gfx/rect.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace speech_input {

// A mock bubble class which fakes a focus change or recognition cancel by the
// user and closing of the info bubble.
class MockSpeechInputBubble : public SpeechInputBubble {
 public:
  enum BubbleType {
    BUBBLE_TEST_FOCUS_CHANGED,
    BUBBLE_TEST_RECOGNITION_CANCELLED
  };

  MockSpeechInputBubble(TabContents*, Delegate* delegate, const gfx::Rect&) {
    MessageLoop::current()->PostTask(
        FROM_HERE, NewRunnableFunction(&InvokeDelegate, delegate));
  }

  static void InvokeDelegate(Delegate* delegate) {
    if (type_ == BUBBLE_TEST_FOCUS_CHANGED)
      delegate->InfoBubbleClosed();
    else
      delegate->RecognitionCancelled();
  }

  static void set_type(BubbleType type) {
    type_ = type;
  }

  virtual void SetRecognizingMode() {}

 private:
  static BubbleType type_;
};

// The test fixture.
class SpeechInputBubbleControllerTest
    : public SpeechInputBubbleControllerDelegate,
      public testing::Test {
 public:
  SpeechInputBubbleControllerTest()
      : io_loop_(MessageLoop::TYPE_IO),
        ui_thread_(ChromeThread::UI),  // constructs a new thread and loop
        io_thread_(ChromeThread::IO, &io_loop_),  // resuses main thread loop
        recognition_cancelled_(false),
        focus_changed_(false) {
  }

  // SpeechInputBubbleControllerDelegate methods.
  virtual void RecognitionCancelled(int caller_id) {
    EXPECT_TRUE(ChromeThread::CurrentlyOn(ChromeThread::IO));
    recognition_cancelled_ = true;
    MessageLoop::current()->Quit();
  }

  virtual void SpeechInputFocusChanged(int caller_id) {
    EXPECT_TRUE(ChromeThread::CurrentlyOn(ChromeThread::IO));
    focus_changed_ = true;
    MessageLoop::current()->Quit();
  }

  // testing::Test methods.
  virtual void SetUp() {
    SpeechInputBubble::set_factory(
        &SpeechInputBubbleControllerTest::CreateBubble);
    ui_thread_.Start();
  }

  virtual void TearDown() {
    SpeechInputBubble::set_factory(NULL);
    ui_thread_.Stop();
  }

  static SpeechInputBubble* CreateBubble(TabContents* tab_contents,
                                         SpeechInputBubble::Delegate* delegate,
                                         const gfx::Rect& element_rect) {
    EXPECT_TRUE(ChromeThread::CurrentlyOn(ChromeThread::UI));
    return new MockSpeechInputBubble(tab_contents, delegate, element_rect);
  }

 protected:
  // The main thread of the test is marked as the IO thread and we create a new
  // one for the UI thread.
  MessageLoop io_loop_;
  ChromeThread ui_thread_;
  ChromeThread io_thread_;
  bool recognition_cancelled_;
  bool focus_changed_;
};

MockSpeechInputBubble::BubbleType MockSpeechInputBubble::type_ =
    MockSpeechInputBubble::BUBBLE_TEST_FOCUS_CHANGED;

// Test that the speech bubble UI gets created in the UI thread and that the
// focus changed callback comes back in the IO thread.
TEST_F(SpeechInputBubbleControllerTest, TestFocusChanged) {
  MockSpeechInputBubble::set_type(
      MockSpeechInputBubble::BUBBLE_TEST_FOCUS_CHANGED);

  scoped_refptr<SpeechInputBubbleController> controller(
      new SpeechInputBubbleController(this));

  controller->CreateBubble(0, 1, 1, gfx::Rect(1, 1));
  MessageLoop::current()->Run();
  EXPECT_TRUE(focus_changed_);
  EXPECT_FALSE(recognition_cancelled_);
}

// Test that the speech bubble UI gets created in the UI thread and that the
// recognition cancelled callback comes back in the IO thread.
TEST_F(SpeechInputBubbleControllerTest, TestRecognitionCancelled) {
  MockSpeechInputBubble::set_type(
      MockSpeechInputBubble::BUBBLE_TEST_RECOGNITION_CANCELLED);

  scoped_refptr<SpeechInputBubbleController> controller(
      new SpeechInputBubbleController(this));

  controller->CreateBubble(0, 1, 1, gfx::Rect(1, 1));
  MessageLoop::current()->Run();
  EXPECT_TRUE(recognition_cancelled_);
  EXPECT_FALSE(focus_changed_);
}

}  // namespace speech_input
<commit_msg>Marked SpeechInputBubbleControllerTest.TestFocusChanged as disabled.<commit_after>// Copyright (c) 2010 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 "chrome/browser/chrome_thread.h"
#include "chrome/browser/speech/speech_input_bubble_controller.h"
#include "gfx/rect.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace speech_input {

// A mock bubble class which fakes a focus change or recognition cancel by the
// user and closing of the info bubble.
class MockSpeechInputBubble : public SpeechInputBubble {
 public:
  enum BubbleType {
    BUBBLE_TEST_FOCUS_CHANGED,
    BUBBLE_TEST_RECOGNITION_CANCELLED
  };

  MockSpeechInputBubble(TabContents*, Delegate* delegate, const gfx::Rect&) {
    MessageLoop::current()->PostTask(
        FROM_HERE, NewRunnableFunction(&InvokeDelegate, delegate));
  }

  static void InvokeDelegate(Delegate* delegate) {
    if (type_ == BUBBLE_TEST_FOCUS_CHANGED)
      delegate->InfoBubbleClosed();
    else
      delegate->RecognitionCancelled();
  }

  static void set_type(BubbleType type) {
    type_ = type;
  }

  virtual void SetRecognizingMode() {}

 private:
  static BubbleType type_;
};

// The test fixture.
class SpeechInputBubbleControllerTest
    : public SpeechInputBubbleControllerDelegate,
      public testing::Test {
 public:
  SpeechInputBubbleControllerTest()
      : io_loop_(MessageLoop::TYPE_IO),
        ui_thread_(ChromeThread::UI),  // constructs a new thread and loop
        io_thread_(ChromeThread::IO, &io_loop_),  // resuses main thread loop
        recognition_cancelled_(false),
        focus_changed_(false) {
  }

  // SpeechInputBubbleControllerDelegate methods.
  virtual void RecognitionCancelled(int caller_id) {
    EXPECT_TRUE(ChromeThread::CurrentlyOn(ChromeThread::IO));
    recognition_cancelled_ = true;
    MessageLoop::current()->Quit();
  }

  virtual void SpeechInputFocusChanged(int caller_id) {
    EXPECT_TRUE(ChromeThread::CurrentlyOn(ChromeThread::IO));
    focus_changed_ = true;
    MessageLoop::current()->Quit();
  }

  // testing::Test methods.
  virtual void SetUp() {
    SpeechInputBubble::set_factory(
        &SpeechInputBubbleControllerTest::CreateBubble);
    ui_thread_.Start();
  }

  virtual void TearDown() {
    SpeechInputBubble::set_factory(NULL);
    ui_thread_.Stop();
  }

  static SpeechInputBubble* CreateBubble(TabContents* tab_contents,
                                         SpeechInputBubble::Delegate* delegate,
                                         const gfx::Rect& element_rect) {
    EXPECT_TRUE(ChromeThread::CurrentlyOn(ChromeThread::UI));
    return new MockSpeechInputBubble(tab_contents, delegate, element_rect);
  }

 protected:
  // The main thread of the test is marked as the IO thread and we create a new
  // one for the UI thread.
  MessageLoop io_loop_;
  ChromeThread ui_thread_;
  ChromeThread io_thread_;
  bool recognition_cancelled_;
  bool focus_changed_;
};

MockSpeechInputBubble::BubbleType MockSpeechInputBubble::type_ =
    MockSpeechInputBubble::BUBBLE_TEST_FOCUS_CHANGED;

// Test that the speech bubble UI gets created in the UI thread and that the
// focus changed callback comes back in the IO thread.
//
// Crashes on Win only.  http://crbug.com/54044
#if defined(OS_WIN)
#define MAYBE_TestFocusChanged DISABLED_TestFocusChanged
#else
#define MAYBE_TestFocusChanged TestFocusChanged
#endif
TEST_F(SpeechInputBubbleControllerTest, MAYBE_TestFocusChanged) {
  MockSpeechInputBubble::set_type(
      MockSpeechInputBubble::BUBBLE_TEST_FOCUS_CHANGED);

  scoped_refptr<SpeechInputBubbleController> controller(
      new SpeechInputBubbleController(this));

  controller->CreateBubble(0, 1, 1, gfx::Rect(1, 1));
  MessageLoop::current()->Run();
  EXPECT_TRUE(focus_changed_);
  EXPECT_FALSE(recognition_cancelled_);
}

// Test that the speech bubble UI gets created in the UI thread and that the
// recognition cancelled callback comes back in the IO thread.
TEST_F(SpeechInputBubbleControllerTest, TestRecognitionCancelled) {
  MockSpeechInputBubble::set_type(
      MockSpeechInputBubble::BUBBLE_TEST_RECOGNITION_CANCELLED);

  scoped_refptr<SpeechInputBubbleController> controller(
      new SpeechInputBubbleController(this));

  controller->CreateBubble(0, 1, 1, gfx::Rect(1, 1));
  MessageLoop::current()->Run();
  EXPECT_TRUE(recognition_cancelled_);
  EXPECT_FALSE(focus_changed_);
}

}  // namespace speech_input
<|endoftext|>


<commit_before>// Copyright 2014 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 "chrome/browser/ui/extensions/extension_action_view_controller.h"

#include "base/logging.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/extensions/api/commands/command_service.h"
#include "chrome/browser/extensions/api/extension_action/extension_action_api.h"
#include "chrome/browser/extensions/extension_action.h"
#include "chrome/browser/extensions/extension_view_host.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/sessions/session_tab_helper.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/extensions/accelerator_priority.h"
#include "chrome/browser/ui/extensions/extension_action_platform_delegate.h"
#include "chrome/browser/ui/toolbar/toolbar_action_view_delegate.h"
#include "chrome/common/extensions/api/extension_action/action_info.h"
#include "content/public/browser/notification_details.h"
#include "content/public/browser/notification_source.h"
#include "extensions/browser/extension_host.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/notification_types.h"
#include "extensions/common/extension.h"
#include "extensions/common/manifest_constants.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/gfx/image/image_skia_operations.h"

using extensions::ActionInfo;
using extensions::CommandService;

ExtensionActionViewController::ExtensionActionViewController(
    const extensions::Extension* extension,
    Browser* browser,
    ExtensionAction* extension_action)
    : extension_(extension),
      browser_(browser),
      extension_action_(extension_action),
      popup_host_(nullptr),
      view_delegate_(nullptr),
      platform_delegate_(ExtensionActionPlatformDelegate::Create(this)),
      icon_factory_(browser->profile(), extension, extension_action, this),
      icon_observer_(nullptr),
      extension_registry_(
          extensions::ExtensionRegistry::Get(browser_->profile())) {
  DCHECK(extension_action);
  DCHECK(extension_action->action_type() == ActionInfo::TYPE_PAGE ||
         extension_action->action_type() == ActionInfo::TYPE_BROWSER);
  DCHECK(extension);
}

ExtensionActionViewController::~ExtensionActionViewController() {
}

const std::string& ExtensionActionViewController::GetId() const {
  return extension_->id();
}

void ExtensionActionViewController::SetDelegate(
    ToolbarActionViewDelegate* delegate) {
  DCHECK((delegate == nullptr) ^ (view_delegate_ == nullptr));
  if (delegate) {
    view_delegate_ = delegate;
    platform_delegate_->OnDelegateSet();
  } else {
    if (is_showing_popup())
      HidePopup();
    platform_delegate_.reset();
    view_delegate_ = nullptr;
  }
}

gfx::Image ExtensionActionViewController::GetIcon(
    content::WebContents* web_contents) {
  if (!ExtensionIsValid())
    return gfx::Image();

  return icon_factory_.GetIcon(SessionTabHelper::IdForTab(web_contents));
}

gfx::ImageSkia ExtensionActionViewController::GetIconWithBadge() {
  if (!ExtensionIsValid())
    return gfx::ImageSkia();

  content::WebContents* web_contents = view_delegate_->GetCurrentWebContents();
  gfx::Size spacing(0, 3);
  gfx::ImageSkia icon = *GetIcon(web_contents).ToImageSkia();
  if (!IsEnabled(web_contents))
    icon = gfx::ImageSkiaOperations::CreateTransparentImage(icon, .25);
  return extension_action_->GetIconWithBadge(
      icon, SessionTabHelper::IdForTab(web_contents), spacing);
}

base::string16 ExtensionActionViewController::GetActionName() const {
  if (!ExtensionIsValid())
    return base::string16();

  return base::UTF8ToUTF16(extension_->name());
}

base::string16 ExtensionActionViewController::GetAccessibleName(
    content::WebContents* web_contents) const {
  if (!ExtensionIsValid())
    return base::string16();

  std::string title =
      extension_action()->GetTitle(SessionTabHelper::IdForTab(web_contents));
  return base::UTF8ToUTF16(title.empty() ? extension()->name() : title);
}

base::string16 ExtensionActionViewController::GetTooltip(
    content::WebContents* web_contents) const {
  return GetAccessibleName(web_contents);
}

bool ExtensionActionViewController::IsEnabled(
    content::WebContents* web_contents) const {
  if (!ExtensionIsValid())
    return false;

  return extension_action_->GetIsVisible(
      SessionTabHelper::IdForTab(web_contents)) ||
      extensions::ExtensionActionAPI::Get(browser_->profile())->
          ExtensionWantsToRun(extension(), web_contents);
}

bool ExtensionActionViewController::WantsToRun(
    content::WebContents* web_contents) const {
  return extensions::ExtensionActionAPI::Get(browser_->profile())->
      ExtensionWantsToRun(extension(), web_contents);
}

bool ExtensionActionViewController::HasPopup(
    content::WebContents* web_contents) const {
  if (!ExtensionIsValid())
    return false;

  int tab_id = SessionTabHelper::IdForTab(web_contents);
  return (tab_id < 0) ? false : extension_action_->HasPopup(tab_id);
}

void ExtensionActionViewController::HidePopup() {
  if (is_showing_popup()) {
    platform_delegate_->CloseOwnPopup();
    // We need to do these actions synchronously (instead of closing and then
    // performing the rest of the cleanup in Observe()) because the extension
    // host can close asynchronously, and we need to keep the view delegate
    // up-to-date.
    OnPopupClosed();
  }
}

gfx::NativeView ExtensionActionViewController::GetPopupNativeView() {
  return platform_delegate_->GetPopupNativeView();
}

ui::MenuModel* ExtensionActionViewController::GetContextMenu() {
  if (!ExtensionIsValid() || !extension()->ShowConfigureContextMenus())
    return nullptr;

  // Reconstruct the menu every time because the menu's contents are dynamic.
  context_menu_model_ = make_scoped_refptr(new ExtensionContextMenuModel(
      extension(), browser_, this));
  return context_menu_model_.get();
}

bool ExtensionActionViewController::IsMenuRunning() const {
  return platform_delegate_->IsMenuRunning();
}

bool ExtensionActionViewController::CanDrag() const {
  return true;
}

bool ExtensionActionViewController::ExecuteAction(bool by_user) {
  return ExecuteAction(SHOW_POPUP, by_user);
}

void ExtensionActionViewController::UpdateState() {
  if (!ExtensionIsValid())
    return;

  view_delegate_->UpdateState();
}

bool ExtensionActionViewController::ExecuteAction(PopupShowAction show_action,
                                                  bool grant_tab_permissions) {
  if (!ExtensionIsValid())
    return false;

  if (extensions::ExtensionActionAPI::Get(browser_->profile())
          ->ExecuteExtensionAction(
              extension_, browser_, grant_tab_permissions) ==
      ExtensionAction::ACTION_SHOW_POPUP) {
    GURL popup_url = extension_action_->GetPopupUrl(
        SessionTabHelper::IdForTab(view_delegate_->GetCurrentWebContents()));
    return static_cast<ExtensionActionViewController*>(
               view_delegate_->GetPreferredPopupViewController())
        ->ShowPopupWithUrl(show_action, popup_url, grant_tab_permissions);
  }
  return false;
}

void ExtensionActionViewController::PaintExtra(
    gfx::Canvas* canvas,
    const gfx::Rect& bounds,
    content::WebContents* web_contents) const {
  if (!ExtensionIsValid())
    return;

  int tab_id = SessionTabHelper::IdForTab(web_contents);
  if (tab_id >= 0)
    extension_action_->PaintBadge(canvas, bounds, tab_id);
}

void ExtensionActionViewController::RegisterCommand() {
  if (!ExtensionIsValid())
    return;

  platform_delegate_->RegisterCommand();
}

void ExtensionActionViewController::InspectPopup() {
  ExecuteAction(SHOW_POPUP_AND_INSPECT, true);
}

void ExtensionActionViewController::OnIconUpdated() {
  if (icon_observer_)
    icon_observer_->OnIconUpdated();
  if (view_delegate_)
    view_delegate_->UpdateState();
}

void ExtensionActionViewController::Observe(
    int type,
    const content::NotificationSource& source,
    const content::NotificationDetails& details) {
  // TODO(devlin): Ew. Notifications. Extract out an observer interface for
  // ExtensionHost and convert this.
  DCHECK_EQ(extensions::NOTIFICATION_EXTENSION_HOST_DESTROYED, type);
  extensions::ExtensionHost* host =
      content::Details<extensions::ExtensionHost>(details).ptr();
  if (host == popup_host_)
    OnPopupClosed();
}

bool ExtensionActionViewController::ExtensionIsValid() const {
  return extension_registry_->enabled_extensions().Contains(extension_->id());
}

bool ExtensionActionViewController::GetExtensionCommand(
    extensions::Command* command) {
  DCHECK(command);
  if (!ExtensionIsValid())
    return false;

  CommandService* command_service = CommandService::Get(browser_->profile());
  if (extension_action_->action_type() == ActionInfo::TYPE_PAGE) {
    return command_service->GetPageActionCommand(
        extension_->id(), CommandService::ACTIVE, command, NULL);
  }
  return command_service->GetBrowserActionCommand(
      extension_->id(), CommandService::ACTIVE, command, NULL);
}

bool ExtensionActionViewController::ShowPopupWithUrl(
    PopupShowAction show_action,
    const GURL& popup_url,
    bool grant_tab_permissions) {
  if (!ExtensionIsValid())
    return false;

  bool already_showing = is_showing_popup();

  // Always hide the current popup, even if it's not owned by this extension.
  // Only one popup should be visible at a time.
  platform_delegate_->CloseActivePopup();

  // If we were showing a popup already, then we treat the action to open the
  // same one as a desire to close it (like clicking a menu button that was
  // already open).
  if (already_showing)
    return false;

  popup_host_ = platform_delegate_->ShowPopupWithUrl(
      show_action, popup_url, grant_tab_permissions);
  if (popup_host_) {
    // Lazily register for notifications about extension host destructions.
    static const int kType = extensions::NOTIFICATION_EXTENSION_HOST_DESTROYED;
    content::Source<content::BrowserContext> source(browser_->profile());
    if (!registrar_.IsRegistered(this, kType, source))
      registrar_.Add(this, kType, source);

    view_delegate_->OnPopupShown(grant_tab_permissions);
  }
  return is_showing_popup();
}

void ExtensionActionViewController::OnPopupClosed() {
  popup_host_ = nullptr;
  view_delegate_->OnPopupClosed();
}
<commit_msg>[Extensions Toolbar] Observe original profile for extension host notifications<commit_after>// Copyright 2014 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 "chrome/browser/ui/extensions/extension_action_view_controller.h"

#include "base/logging.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/extensions/api/commands/command_service.h"
#include "chrome/browser/extensions/api/extension_action/extension_action_api.h"
#include "chrome/browser/extensions/extension_action.h"
#include "chrome/browser/extensions/extension_view_host.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/sessions/session_tab_helper.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/extensions/accelerator_priority.h"
#include "chrome/browser/ui/extensions/extension_action_platform_delegate.h"
#include "chrome/browser/ui/toolbar/toolbar_action_view_delegate.h"
#include "chrome/common/extensions/api/extension_action/action_info.h"
#include "content/public/browser/notification_details.h"
#include "content/public/browser/notification_source.h"
#include "extensions/browser/extension_host.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/notification_types.h"
#include "extensions/common/extension.h"
#include "extensions/common/manifest_constants.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/gfx/image/image_skia_operations.h"

using extensions::ActionInfo;
using extensions::CommandService;

ExtensionActionViewController::ExtensionActionViewController(
    const extensions::Extension* extension,
    Browser* browser,
    ExtensionAction* extension_action)
    : extension_(extension),
      browser_(browser),
      extension_action_(extension_action),
      popup_host_(nullptr),
      view_delegate_(nullptr),
      platform_delegate_(ExtensionActionPlatformDelegate::Create(this)),
      icon_factory_(browser->profile(), extension, extension_action, this),
      icon_observer_(nullptr),
      extension_registry_(
          extensions::ExtensionRegistry::Get(browser_->profile())) {
  DCHECK(extension_action);
  DCHECK(extension_action->action_type() == ActionInfo::TYPE_PAGE ||
         extension_action->action_type() == ActionInfo::TYPE_BROWSER);
  DCHECK(extension);
}

ExtensionActionViewController::~ExtensionActionViewController() {
}

const std::string& ExtensionActionViewController::GetId() const {
  return extension_->id();
}

void ExtensionActionViewController::SetDelegate(
    ToolbarActionViewDelegate* delegate) {
  DCHECK((delegate == nullptr) ^ (view_delegate_ == nullptr));
  if (delegate) {
    view_delegate_ = delegate;
    platform_delegate_->OnDelegateSet();
  } else {
    if (is_showing_popup())
      HidePopup();
    platform_delegate_.reset();
    view_delegate_ = nullptr;
  }
}

gfx::Image ExtensionActionViewController::GetIcon(
    content::WebContents* web_contents) {
  if (!ExtensionIsValid())
    return gfx::Image();

  return icon_factory_.GetIcon(SessionTabHelper::IdForTab(web_contents));
}

gfx::ImageSkia ExtensionActionViewController::GetIconWithBadge() {
  if (!ExtensionIsValid())
    return gfx::ImageSkia();

  content::WebContents* web_contents = view_delegate_->GetCurrentWebContents();
  gfx::Size spacing(0, 3);
  gfx::ImageSkia icon = *GetIcon(web_contents).ToImageSkia();
  if (!IsEnabled(web_contents))
    icon = gfx::ImageSkiaOperations::CreateTransparentImage(icon, .25);
  return extension_action_->GetIconWithBadge(
      icon, SessionTabHelper::IdForTab(web_contents), spacing);
}

base::string16 ExtensionActionViewController::GetActionName() const {
  if (!ExtensionIsValid())
    return base::string16();

  return base::UTF8ToUTF16(extension_->name());
}

base::string16 ExtensionActionViewController::GetAccessibleName(
    content::WebContents* web_contents) const {
  if (!ExtensionIsValid())
    return base::string16();

  std::string title =
      extension_action()->GetTitle(SessionTabHelper::IdForTab(web_contents));
  return base::UTF8ToUTF16(title.empty() ? extension()->name() : title);
}

base::string16 ExtensionActionViewController::GetTooltip(
    content::WebContents* web_contents) const {
  return GetAccessibleName(web_contents);
}

bool ExtensionActionViewController::IsEnabled(
    content::WebContents* web_contents) const {
  if (!ExtensionIsValid())
    return false;

  return extension_action_->GetIsVisible(
      SessionTabHelper::IdForTab(web_contents)) ||
      extensions::ExtensionActionAPI::Get(browser_->profile())->
          ExtensionWantsToRun(extension(), web_contents);
}

bool ExtensionActionViewController::WantsToRun(
    content::WebContents* web_contents) const {
  return extensions::ExtensionActionAPI::Get(browser_->profile())->
      ExtensionWantsToRun(extension(), web_contents);
}

bool ExtensionActionViewController::HasPopup(
    content::WebContents* web_contents) const {
  if (!ExtensionIsValid())
    return false;

  int tab_id = SessionTabHelper::IdForTab(web_contents);
  return (tab_id < 0) ? false : extension_action_->HasPopup(tab_id);
}

void ExtensionActionViewController::HidePopup() {
  if (is_showing_popup()) {
    platform_delegate_->CloseOwnPopup();
    // We need to do these actions synchronously (instead of closing and then
    // performing the rest of the cleanup in Observe()) because the extension
    // host can close asynchronously, and we need to keep the view delegate
    // up-to-date.
    OnPopupClosed();
  }
}

gfx::NativeView ExtensionActionViewController::GetPopupNativeView() {
  return platform_delegate_->GetPopupNativeView();
}

ui::MenuModel* ExtensionActionViewController::GetContextMenu() {
  if (!ExtensionIsValid() || !extension()->ShowConfigureContextMenus())
    return nullptr;

  // Reconstruct the menu every time because the menu's contents are dynamic.
  context_menu_model_ = make_scoped_refptr(new ExtensionContextMenuModel(
      extension(), browser_, this));
  return context_menu_model_.get();
}

bool ExtensionActionViewController::IsMenuRunning() const {
  return platform_delegate_->IsMenuRunning();
}

bool ExtensionActionViewController::CanDrag() const {
  return true;
}

bool ExtensionActionViewController::ExecuteAction(bool by_user) {
  return ExecuteAction(SHOW_POPUP, by_user);
}

void ExtensionActionViewController::UpdateState() {
  if (!ExtensionIsValid())
    return;

  view_delegate_->UpdateState();
}

bool ExtensionActionViewController::ExecuteAction(PopupShowAction show_action,
                                                  bool grant_tab_permissions) {
  if (!ExtensionIsValid())
    return false;

  if (extensions::ExtensionActionAPI::Get(browser_->profile())
          ->ExecuteExtensionAction(
              extension_, browser_, grant_tab_permissions) ==
      ExtensionAction::ACTION_SHOW_POPUP) {
    GURL popup_url = extension_action_->GetPopupUrl(
        SessionTabHelper::IdForTab(view_delegate_->GetCurrentWebContents()));
    return static_cast<ExtensionActionViewController*>(
               view_delegate_->GetPreferredPopupViewController())
        ->ShowPopupWithUrl(show_action, popup_url, grant_tab_permissions);
  }
  return false;
}

void ExtensionActionViewController::PaintExtra(
    gfx::Canvas* canvas,
    const gfx::Rect& bounds,
    content::WebContents* web_contents) const {
  if (!ExtensionIsValid())
    return;

  int tab_id = SessionTabHelper::IdForTab(web_contents);
  if (tab_id >= 0)
    extension_action_->PaintBadge(canvas, bounds, tab_id);
}

void ExtensionActionViewController::RegisterCommand() {
  if (!ExtensionIsValid())
    return;

  platform_delegate_->RegisterCommand();
}

void ExtensionActionViewController::InspectPopup() {
  ExecuteAction(SHOW_POPUP_AND_INSPECT, true);
}

void ExtensionActionViewController::OnIconUpdated() {
  if (icon_observer_)
    icon_observer_->OnIconUpdated();
  if (view_delegate_)
    view_delegate_->UpdateState();
}

void ExtensionActionViewController::Observe(
    int type,
    const content::NotificationSource& source,
    const content::NotificationDetails& details) {
  // TODO(devlin): Ew. Notifications. Extract out an observer interface for
  // ExtensionHost and convert this.
  DCHECK_EQ(extensions::NOTIFICATION_EXTENSION_HOST_DESTROYED, type);
  extensions::ExtensionHost* host =
      content::Details<extensions::ExtensionHost>(details).ptr();
  if (host == popup_host_)
    OnPopupClosed();
}

bool ExtensionActionViewController::ExtensionIsValid() const {
  return extension_registry_->enabled_extensions().Contains(extension_->id());
}

bool ExtensionActionViewController::GetExtensionCommand(
    extensions::Command* command) {
  DCHECK(command);
  if (!ExtensionIsValid())
    return false;

  CommandService* command_service = CommandService::Get(browser_->profile());
  if (extension_action_->action_type() == ActionInfo::TYPE_PAGE) {
    return command_service->GetPageActionCommand(
        extension_->id(), CommandService::ACTIVE, command, NULL);
  }
  return command_service->GetBrowserActionCommand(
      extension_->id(), CommandService::ACTIVE, command, NULL);
}

bool ExtensionActionViewController::ShowPopupWithUrl(
    PopupShowAction show_action,
    const GURL& popup_url,
    bool grant_tab_permissions) {
  if (!ExtensionIsValid())
    return false;

  bool already_showing = is_showing_popup();

  // Always hide the current popup, even if it's not owned by this extension.
  // Only one popup should be visible at a time.
  platform_delegate_->CloseActivePopup();

  // If we were showing a popup already, then we treat the action to open the
  // same one as a desire to close it (like clicking a menu button that was
  // already open).
  if (already_showing)
    return false;

  popup_host_ = platform_delegate_->ShowPopupWithUrl(
      show_action, popup_url, grant_tab_permissions);
  if (popup_host_) {
    // Lazily register for notifications about extension host destructions.
    static const int kType = extensions::NOTIFICATION_EXTENSION_HOST_DESTROYED;
    content::Source<content::BrowserContext> source(
        browser_->profile()->GetOriginalProfile());
    if (!registrar_.IsRegistered(this, kType, source))
      registrar_.Add(this, kType, source);

    view_delegate_->OnPopupShown(grant_tab_permissions);
  }
  return is_showing_popup();
}

void ExtensionActionViewController::OnPopupClosed() {
  popup_host_ = nullptr;
  view_delegate_->OnPopupClosed();
}
<|endoftext|>


<commit_before>#ifndef KMC_KLANG_EITHER_HPP
#define KMC_KLANG_EITHER_HPP

#include <cassert>

namespace klang {

struct LeftTag {};
struct RightTag {};

constexpr LeftTag left_tag;
constexpr RightTag right_tag;

template <typename L, typename R>
class Either {
 public:
  Either(LeftTag, const L& left)
      : is_right_{false}, left_{left}
  {}
  Either(LeftTag, L&& left)
      : is_right_{false}, left_{std::move(left)}
  {}
  Either(RightTag, const R& right)
      : is_right_{true}, right_{right}
  {}
  Either(RightTag, R&& right)
      : is_right_{true}, right_{std::move(right)}
  {}
  Either(const Either& that)
      : is_right_{that.is_right_} {
    construct(that);
  }
  Either(Either&& that)
      : is_right_{that.is_right_} {
    construct(std::move(that));
  }
  Either& operator=(const Either& that) {
    assign(that);
    return *this;
  }
  Either& operator=(Either&& that) {
    assign(std::move(that));
    return *this;
  }
  ~Either() {
    destruct();
  }
  void swap(Either& that) {
    Either tmp{std::move(*this)};
    *this = std::move(that);
    that = std::move(tmp);
  }
  explicit operator bool() const {
    return is_right_;
  }
  const R& operator*() const& {
    assert(is_right_);
    return right_;
  }
  R& operator*() & {
    assert(is_right_);
    return right_;
  }
  R&& operator*() && {
    assert(is_right_);
    return std::move(right_);
  }
  const R* operator->() const {
    assert(is_right_);
    return &right_;
  }
  R* operator->() {
    assert(is_right_);
    return &right_;
  }
  template <typename L_, typename R_>
  friend class Either;
  friend void swap(Either& lhs, Either& rhs) {
    lhs.swap(rhs);
  }
  friend bool operator==(const Either& lhs, const Either& rhs) {
    if (lhs.is_right_ != rhs.is_right_) {
      return false;
    } else if (lhs.is_right_) {
      return lhs.right_ == rhs.right_;
    } else {
      return lhs.left_ == rhs.left_;
    }
  }
  friend bool operator<(const Either& lhs, const Either& rhs) {
    if (lhs.is_right_ != rhs.is_right_) {
      return rhs.is_right_;
    } else if (lhs.is_right_) {
      return lhs.right_ < rhs.right_;
    } else {
      return lhs.left_ < rhs.left_;
    }
  }
 private:
  void construct(const Either& src) {
    if (src.is_right_) {
      new (&right_) R{src.right_};
    } else {
      new (&left_) L{src.left_};
    }
  }
  void construct(Either&& src) {
    if (src.is_right_) {
      new (&right_) R{std::move(src.right_)};
    } else {
      new (&left_) L{std::move(src.left_)};
    }
  }
  void assign(const Either& src) {
    if (is_right_ == src.is_right_) {
      if (is_right_) {
        right_ = src.right_;
      } else {
        left_ = src.left_;
      }
    } else {
      destruct();
      construct(src);
      is_right_ = src.is_right_;
    }
  }
  void assign(Either&& src) {
    if (is_right_ == src.is_right_) {
      if (is_right_) {
        right_ = std::move(src.right_);
      } else {
        left_ = std::move(src.left_);
      }
    } else {
      destruct();
      construct(std::move(src));
      is_right_ = src.is_right_;
    }
  }
  void destruct() {
    if (is_right_) {
      right_.~R();
    } else {
      left_.~L();
    }
  }
 private:
  bool is_right_;
  union {
    L left_;
    R right_;
  };
};

}  // namespace klang

#endif  // KMC_KLANG_EITHER_HPP
<commit_msg>Add Left and Right wrapper class<commit_after>#ifndef KMC_KLANG_EITHER_HPP
#define KMC_KLANG_EITHER_HPP

#include <cassert>
#include <utility>

namespace klang {

struct LeftTag {};
struct RightTag {};

constexpr LeftTag left_tag;
constexpr RightTag right_tag;

template <typename L>
class Left {
 public:
  explicit Left(const L& src)
      : left_{src}
  {}
  explicit Left(L&& src)
      : left_{std::move(src)}
  {}
  Left(const Left&) = default;
  Left(Left&&) = default;
  Left& operator=(const Left&) = default;
  Left& operator=(Left&&) = default;
  void swap(Left& that) {
    using std::swap;
    swap(left_, that.left_);
  }
  const L& value() const& {
    return left_;
  }
  L&& value() && {
    return std::move(left_);
  }
  template <typename L_>
  friend class Left;
  friend void swap(Left& lhs, Left& rhs) {
    lhs.swap(rhs);
  }
  friend bool operator==(const Left& lhs, const Left& rhs) {
    return lhs.left_ == rhs.left_;
  }
  friend bool operator<(const Left& lhs, const Left& rhs) {
    return lhs.left_ < rhs.left_;
  }
 private:
  L left_;
};

template <typename R>
class Right {
 public:
  explicit Right(const R& src)
      : right_{src}
  {}
  explicit Right(R&& src)
      : right_{std::move(src)}
  {}
  Right(const Right&) = default;
  Right(Right&&) = default;
  Right& operator=(const Right&) = default;
  Right& operator=(Right&&) = default;
  void swap(Right& that) {
    using std::swap;
    swap(right_, that.right_);
  }
  const R& value() const& {
    return right_;
  }
  R&& value() && {
    return std::move(right_);
  }
  template <typename R_>
  friend class Right;
  friend void swap(Right& lhs, Right& rhs) {
    lhs.swap(rhs);
  }
  friend bool operator==(const Right& lhs, const Right& rhs) {
    return lhs.right_ == rhs.right_;
  }
  friend bool operator<(const Right& lhs, const Right& rhs) {
    return lhs.right_ < rhs.right_;
  }
 private:
  R right_;
};

template <typename L, typename R>
class Either {
 public:
  Either(LeftTag, const L& left)
      : is_right_{false}, left_{left}
  {}
  Either(LeftTag, L&& left)
      : is_right_{false}, left_{std::move(left)}
  {}
  Either(RightTag, const R& right)
      : is_right_{true}, right_{right}
  {}
  Either(RightTag, R&& right)
      : is_right_{true}, right_{std::move(right)}
  {}
  Either(const Either& that)
      : is_right_{that.is_right_} {
    construct(that);
  }
  Either(Either&& that)
      : is_right_{that.is_right_} {
    construct(std::move(that));
  }
  Either& operator=(const Either& that) {
    assign(that);
    return *this;
  }
  Either& operator=(Either&& that) {
    assign(std::move(that));
    return *this;
  }
  ~Either() {
    destruct();
  }
  void swap(Either& that) {
    Either tmp{std::move(*this)};
    *this = std::move(that);
    that = std::move(tmp);
  }
  explicit operator bool() const {
    return is_right_;
  }
  const R& operator*() const& {
    assert(is_right_);
    return right_;
  }
  R& operator*() & {
    assert(is_right_);
    return right_;
  }
  R&& operator*() && {
    assert(is_right_);
    return std::move(right_);
  }
  const R* operator->() const {
    assert(is_right_);
    return &right_;
  }
  R* operator->() {
    assert(is_right_);
    return &right_;
  }
  template <typename L_, typename R_>
  friend class Either;
  friend void swap(Either& lhs, Either& rhs) {
    lhs.swap(rhs);
  }
  friend bool operator==(const Either& lhs, const Either& rhs) {
    if (lhs.is_right_ != rhs.is_right_) {
      return false;
    } else if (lhs.is_right_) {
      return lhs.right_ == rhs.right_;
    } else {
      return lhs.left_ == rhs.left_;
    }
  }
  friend bool operator<(const Either& lhs, const Either& rhs) {
    if (lhs.is_right_ != rhs.is_right_) {
      return rhs.is_right_;
    } else if (lhs.is_right_) {
      return lhs.right_ < rhs.right_;
    } else {
      return lhs.left_ < rhs.left_;
    }
  }
 private:
  void construct(const Either& src) {
    if (src.is_right_) {
      new (&right_) R{src.right_};
    } else {
      new (&left_) L{src.left_};
    }
  }
  void construct(Either&& src) {
    if (src.is_right_) {
      new (&right_) R{std::move(src.right_)};
    } else {
      new (&left_) L{std::move(src.left_)};
    }
  }
  void assign(const Either& src) {
    if (is_right_ == src.is_right_) {
      if (is_right_) {
        right_ = src.right_;
      } else {
        left_ = src.left_;
      }
    } else {
      destruct();
      construct(src);
      is_right_ = src.is_right_;
    }
  }
  void assign(Either&& src) {
    if (is_right_ == src.is_right_) {
      if (is_right_) {
        right_ = std::move(src.right_);
      } else {
        left_ = std::move(src.left_);
      }
    } else {
      destruct();
      construct(std::move(src));
      is_right_ = src.is_right_;
    }
  }
  void destruct() {
    if (is_right_) {
      right_.~R();
    } else {
      left_.~L();
    }
  }
 private:
  bool is_right_;
  union {
    L left_;
    R right_;
  };
};

}  // namespace klang

#endif  // KMC_KLANG_EITHER_HPP
<|endoftext|>


<commit_before>#include "ovpCBoxAlgorithmStimulationListener.h"

using namespace OpenViBE;
using namespace OpenViBE::Kernel;
using namespace OpenViBE::Plugins;

using namespace OpenViBEPlugins;
using namespace OpenViBEPlugins::Tools;

boolean CBoxAlgorithmStimulationListener::initialize(void)
{
	IBox& l_rStaticBoxContext=this->getStaticBoxContext();
	for(uint32 i=0; i<l_rStaticBoxContext.getInputCount(); i++)
	{
		IAlgorithmProxy* m_pStreamDecoder=&this->getAlgorithmManager().getAlgorithm(this->getAlgorithmManager().createAlgorithm(OVP_GD_ClassId_Algorithm_StimulationStreamDecoder));
		m_pStreamDecoder->initialize();
		m_vStreamDecoder.push_back(m_pStreamDecoder);
	}

	CString l_sSettingValue;
	l_rStaticBoxContext.getSettingValue(0, l_sSettingValue);
	m_eLogLevel=static_cast<ELogLevel>(getTypeManager().getEnumerationEntryValueFromName(OV_TypeId_LogLevel, l_sSettingValue));

	return true;
}

boolean CBoxAlgorithmStimulationListener::uninitialize(void)
{
	IBox& l_rStaticBoxContext=this->getStaticBoxContext();
	for(uint32 i=0; i<l_rStaticBoxContext.getInputCount(); i++)
	{
		m_vStreamDecoder[i]->uninitialize();
		this->getAlgorithmManager().releaseAlgorithm(*m_vStreamDecoder[i]);
	}
	m_vStreamDecoder.clear();

	return true;
}

boolean CBoxAlgorithmStimulationListener::processInput(uint32 ui32InputIndex)
{
	getBoxAlgorithmContext()->markAlgorithmAsReadyToProcess();
	return true;
}

boolean CBoxAlgorithmStimulationListener::process(void)
{
	IBox& l_rStaticBoxContext=this->getStaticBoxContext();
	IBoxIO& l_rDynamicBoxContext=this->getDynamicBoxContext();

	for(uint32 i=0; i<l_rStaticBoxContext.getInputCount(); i++)
	{
		for(uint32 j=0; j<l_rDynamicBoxContext.getInputChunkCount(i); j++)
		{
			TParameterHandler < const IMemoryBuffer* > ip_pMemoryBufferToDecode(m_vStreamDecoder[i]->getInputParameter(OVP_GD_Algorithm_StimulationStreamDecoder_InputParameterId_MemoryBufferToDecode));
			TParameterHandler < const IStimulationSet* > op_pStimulationSet(m_vStreamDecoder[i]->getOutputParameter(OVP_GD_Algorithm_StimulationStreamDecoder_OutputParameterId_StimulationSet));
			ip_pMemoryBufferToDecode=l_rDynamicBoxContext.getInputChunk(i, j);

			m_vStreamDecoder[i]->process();
			if(m_vStreamDecoder[i]->isOutputTriggerActive(OVP_GD_Algorithm_StimulationStreamDecoder_OutputTriggerId_ReceivedHeader))
			{
			}
			if(m_vStreamDecoder[i]->isOutputTriggerActive(OVP_GD_Algorithm_StimulationStreamDecoder_OutputTriggerId_ReceivedBuffer))
			{
				CString l_sInputName;
				l_rStaticBoxContext.getInputName(i, l_sInputName);
				for(uint64 k=0; k<op_pStimulationSet->getStimulationCount(); k++)
				{
					this->getLogManager() << m_eLogLevel
						<< "For input " << i << " with name " << l_sInputName
						<< " got stimulation " << op_pStimulationSet->getStimulationIdentifier(k)
						<< "[" << this->getTypeManager().getEnumerationEntryNameFromValue(OV_TypeId_Stimulation, op_pStimulationSet->getStimulationIdentifier(k)) << "]"
						<< " at date " << time64(op_pStimulationSet->getStimulationDate(k))
						<< " and duration " << time64(op_pStimulationSet->getStimulationDuration(k))
						<< "\n";
				}
			}
			if(m_vStreamDecoder[i]->isOutputTriggerActive(OVP_GD_Algorithm_StimulationStreamDecoder_OutputTriggerId_ReceivedEnd))
			{
			}
			l_rDynamicBoxContext.markInputAsDeprecated(i, j);
		}
	}

	return true;
}
<commit_msg>openvibe-plugins/tools  * ovpCBoxAlgorithmStimulationListener.cpp : added a warning message when a stimulation date is out of chunk range<commit_after>#include "ovpCBoxAlgorithmStimulationListener.h"

using namespace OpenViBE;
using namespace OpenViBE::Kernel;
using namespace OpenViBE::Plugins;

using namespace OpenViBEPlugins;
using namespace OpenViBEPlugins::Tools;

boolean CBoxAlgorithmStimulationListener::initialize(void)
{
	IBox& l_rStaticBoxContext=this->getStaticBoxContext();
	for(uint32 i=0; i<l_rStaticBoxContext.getInputCount(); i++)
	{
		IAlgorithmProxy* m_pStreamDecoder=&this->getAlgorithmManager().getAlgorithm(this->getAlgorithmManager().createAlgorithm(OVP_GD_ClassId_Algorithm_StimulationStreamDecoder));
		m_pStreamDecoder->initialize();
		m_vStreamDecoder.push_back(m_pStreamDecoder);
	}

	CString l_sSettingValue;
	l_rStaticBoxContext.getSettingValue(0, l_sSettingValue);
	m_eLogLevel=static_cast<ELogLevel>(getTypeManager().getEnumerationEntryValueFromName(OV_TypeId_LogLevel, l_sSettingValue));

	return true;
}

boolean CBoxAlgorithmStimulationListener::uninitialize(void)
{
	IBox& l_rStaticBoxContext=this->getStaticBoxContext();
	for(uint32 i=0; i<l_rStaticBoxContext.getInputCount(); i++)
	{
		m_vStreamDecoder[i]->uninitialize();
		this->getAlgorithmManager().releaseAlgorithm(*m_vStreamDecoder[i]);
	}
	m_vStreamDecoder.clear();

	return true;
}

boolean CBoxAlgorithmStimulationListener::processInput(uint32 ui32InputIndex)
{
	getBoxAlgorithmContext()->markAlgorithmAsReadyToProcess();
	return true;
}

boolean CBoxAlgorithmStimulationListener::process(void)
{
	IBox& l_rStaticBoxContext=this->getStaticBoxContext();
	IBoxIO& l_rDynamicBoxContext=this->getDynamicBoxContext();

	for(uint32 i=0; i<l_rStaticBoxContext.getInputCount(); i++)
	{
		for(uint32 j=0; j<l_rDynamicBoxContext.getInputChunkCount(i); j++)
		{
			TParameterHandler < const IMemoryBuffer* > ip_pMemoryBufferToDecode(m_vStreamDecoder[i]->getInputParameter(OVP_GD_Algorithm_StimulationStreamDecoder_InputParameterId_MemoryBufferToDecode));
			TParameterHandler < const IStimulationSet* > op_pStimulationSet(m_vStreamDecoder[i]->getOutputParameter(OVP_GD_Algorithm_StimulationStreamDecoder_OutputParameterId_StimulationSet));
			ip_pMemoryBufferToDecode=l_rDynamicBoxContext.getInputChunk(i, j);

			m_vStreamDecoder[i]->process();
			if(m_vStreamDecoder[i]->isOutputTriggerActive(OVP_GD_Algorithm_StimulationStreamDecoder_OutputTriggerId_ReceivedHeader))
			{
			}
			if(m_vStreamDecoder[i]->isOutputTriggerActive(OVP_GD_Algorithm_StimulationStreamDecoder_OutputTriggerId_ReceivedBuffer))
			{
				CString l_sInputName;
				l_rStaticBoxContext.getInputName(i, l_sInputName);
				for(uint64 k=0; k<op_pStimulationSet->getStimulationCount(); k++)
				{
					this->getLogManager() << m_eLogLevel
						<< "For input " << i << " with name " << l_sInputName
						<< " got stimulation " << op_pStimulationSet->getStimulationIdentifier(k)
						<< "[" << this->getTypeManager().getEnumerationEntryNameFromValue(OV_TypeId_Stimulation, op_pStimulationSet->getStimulationIdentifier(k)) << "]"
						<< " at date " << time64(op_pStimulationSet->getStimulationDate(k))
						<< " and duration " << time64(op_pStimulationSet->getStimulationDuration(k))
						<< "\n";
					if(op_pStimulationSet->getStimulationDate(k) < l_rDynamicBoxContext.getInputChunkStartTime(i, j) || op_pStimulationSet->getStimulationDate(k) > l_rDynamicBoxContext.getInputChunkEndTime(i, j))
					{
						this->getLogManager() << LogLevel_Warning
							<< "The stimulation date is out of chunk range ! "
							<< " Stimulation date is " << time64(op_pStimulationSet->getStimulationDate(k))
							<< " and chunk range is [" << time64(l_rDynamicBoxContext.getInputChunkStartTime(i, j)) << ", " << time64(l_rDynamicBoxContext.getInputChunkEndTime(i, j)) << "]\n";
					}
				}
			}
			if(m_vStreamDecoder[i]->isOutputTriggerActive(OVP_GD_Algorithm_StimulationStreamDecoder_OutputTriggerId_ReceivedEnd))
			{
			}
			l_rDynamicBoxContext.markInputAsDeprecated(i, j);
		}
	}

	return true;
}
<|endoftext|>


<commit_before>#include "engine.h"
#include "random.h"
#include "gameEntity.h"
#include "Updatable.h"
#include "collisionable.h"

#ifdef __linux__
#include <fenv.h>
#endif
#ifdef __WIN32__
#include <float.h>
#endif

#ifdef DEBUG
#include <typeinfo>
int DEBUG_PobjCount;
PObject* DEBUG_PobjListStart;
#endif

#ifdef ENABLE_CRASH_LOGGER
#ifdef __WIN32__
//Exception handler for mingw, from https://github.com/jrfonseca/drmingw
#include <exchndl.h>
#endif//__WIN32__
#endif//ENABLE_CRASH_LOGGER

Engine* engine;

Engine::Engine()
{
    engine = this;
#ifdef ENABLE_CRASH_LOGGER
#ifdef __WIN32__
    ExcHndlInit();
#endif//__WIN32__
#endif//ENABLE_CRASH_LOGGER
#ifdef __linux__
    feenableexcept(FE_DIVBYZERO | FE_INVALID);
#endif
#ifdef __WIN32__
    unsigned int current_word = 0;
    _controlfp_s(&current_word, _EM_INVALID | _EM_ZERODIVIDE, _MCW_EM);
#endif
    initRandom();
    windowManager = nullptr;
    CollisionManager::initialize();
    InputHandler::initialize();
    gameSpeed = 1.0;
    running = true;
    elapsedTime = 0.0;

    soundManager = new SoundManager();
}
Engine::~Engine()
{
    if (windowManager)
        windowManager->close();
    delete soundManager;
    soundManager = nullptr;
}

void Engine::registerObject(string name, P<PObject> obj)
{
    objectMap[name] = obj;
}

P<PObject> Engine::getObject(string name)
{
    if (!objectMap[name])
        return NULL;
    return objectMap[name];
}

void Engine::runMainLoop()
{
    windowManager = dynamic_cast<WindowManager*>(*getObject("windowManager"));
    if (!windowManager)
    {
        sf::Clock frameTimeClock;
        while(running)
        {
            float delta = frameTimeClock.getElapsedTime().asSeconds();
            frameTimeClock.restart();
            if (delta > 0.5)
                delta = 0.5;
            if (delta < 0.001)
                delta = 0.001;
            delta *= gameSpeed;

            entityList.update();
            foreach(Updatable, u, updatableList)
                u->update(delta);
            elapsedTime += delta;
            CollisionManager::handleCollisions(delta);
            ScriptObject::clearDestroyedObjects();
            soundManager->updateTick();

            sf::sleep(sf::seconds(1.0/60.0 - delta));
            //if (elapsedTime > 2.0)
            //    break;
        }
    }else{
        sf::Clock frameTimeClock;
#ifdef DEBUG
        sf::Clock debugOutputClock;
#endif
        while(running && windowManager->window.isOpen())
        {
            InputHandler::preEventsUpdate();
            // Handle events
            sf::Event event;
            while (windowManager->window.pollEvent(event))
            {
                handleEvent(event);
            }
            InputHandler::postEventsUpdate();

#ifdef DEBUG
            if (sf::Keyboard::isKeyPressed(sf::Keyboard::Escape) && windowManager->hasFocus())
                running = false;

            if (debugOutputClock.getElapsedTime().asSeconds() > 1.0)
            {
                printf("Object count: %4d %4d %4d\n", DEBUG_PobjCount, updatableList.size(), entityList.size());
                debugOutputClock.restart();
            }
#endif

            float delta = frameTimeClock.restart().asSeconds();
            if (delta > 0.5)
                delta = 0.5;
            if (delta < 0.001)
                delta = 0.001;
            delta *= gameSpeed;
#ifdef DEBUG
            if (sf::Keyboard::isKeyPressed(sf::Keyboard::Tab))
                delta /= 5.0;
            if (sf::Keyboard::isKeyPressed(sf::Keyboard::Tilde))
                delta *= 5.0;
#endif
            EngineTiming engine_timing;

            sf::Clock engine_timing_clock;
            entityList.update();
            foreach(Updatable, u, updatableList)
                u->update(delta);
            elapsedTime += delta;
            engine_timing.update = engine_timing_clock.restart().asSeconds();
            CollisionManager::handleCollisions(delta);
            engine_timing.collision = engine_timing_clock.restart().asSeconds();
            ScriptObject::clearDestroyedObjects();
            soundManager->updateTick();

            // Clear the window
            windowManager->render();
            engine_timing.render = engine_timing_clock.restart().asSeconds();
            engine_timing.server_update = 0.0f;
            if (game_server)
                engine_timing.server_update = game_server->getUpdateTime();

            last_engine_timing = engine_timing;
        }
        soundManager->stopMusic();
    }
}

void Engine::handleEvent(sf::Event& event)
{
    // Window closed: exit
    if ((event.type == sf::Event::Closed))
        running = false;
    if (event.type == sf::Event::GainedFocus)
        windowManager->windowHasFocus = true;
    if (event.type == sf::Event::LostFocus)
        windowManager->windowHasFocus = false;
#ifdef DEBUG
    if ((event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::L))
    {
        int n = 0;
        printf("---------------------\n");
        for(PObject* obj = DEBUG_PobjListStart; obj; obj = obj->DEBUG_PobjListNext)
            printf("%c%4d: %4d: %s\n", obj->isDestroyed() ? '>' : ' ', n++, obj->getRefCount(), typeid(*obj).name());
        printf("---------------------\n");
    }
#endif
    InputHandler::handleEvent(event);
    if (event.type == sf::Event::Resized)
        windowManager->setupView();
#ifdef __ANDROID__
    //Focus lost and focus gained events are used when the application window is created and destroyed.
    if (event.type == sf::Event::LostFocus)
        running = false;

    //The MouseEntered and MouseLeft events are received when the activity needs to pause or resume.
    if (event.type == sf::Event::MouseLeft)
    {
        //Pause is when a small popup is on top of the window. So keep running.
        while(windowManager->window.isOpen() && windowManager->window.waitEvent(event))
        {
            if (event.type != sf::Event::MouseLeft)
                handleEvent(event);
            if (event.type == sf::Event::MouseEntered)
                break;
        }
    }
#endif//__ANDROID__
}

void Engine::setGameSpeed(float speed)
{
    gameSpeed = speed;
}

float Engine::getGameSpeed()
{
    return gameSpeed;
}

float Engine::getElapsedTime()
{
    return elapsedTime;
}

Engine::EngineTiming Engine::getEngineTiming()
{
    return last_engine_timing;
}

void Engine::shutdown()
{
    running = false;
}
<commit_msg>Revert "Enable floating point exceptions."<commit_after>#include "engine.h"
#include "random.h"
#include "gameEntity.h"
#include "Updatable.h"
#include "collisionable.h"

#ifdef DEBUG
#include <typeinfo>
int DEBUG_PobjCount;
PObject* DEBUG_PobjListStart;
#endif

#ifdef ENABLE_CRASH_LOGGER
#ifdef __WIN32__
//Exception handler for mingw, from https://github.com/jrfonseca/drmingw
#include <exchndl.h>
#endif//__WIN32__
#endif//ENABLE_CRASH_LOGGER

Engine* engine;

Engine::Engine()
{
    engine = this;
#ifdef ENABLE_CRASH_LOGGER
#ifdef __WIN32__
    ExcHndlInit();
#endif//__WIN32__
#endif//ENABLE_CRASH_LOGGER
    initRandom();
    windowManager = nullptr;
    CollisionManager::initialize();
    InputHandler::initialize();
    gameSpeed = 1.0;
    running = true;
    elapsedTime = 0.0;

    soundManager = new SoundManager();
}
Engine::~Engine()
{
    if (windowManager)
        windowManager->close();
    delete soundManager;
    soundManager = nullptr;
}

void Engine::registerObject(string name, P<PObject> obj)
{
    objectMap[name] = obj;
}

P<PObject> Engine::getObject(string name)
{
    if (!objectMap[name])
        return NULL;
    return objectMap[name];
}

void Engine::runMainLoop()
{
    windowManager = dynamic_cast<WindowManager*>(*getObject("windowManager"));
    if (!windowManager)
    {
        sf::Clock frameTimeClock;
        while(running)
        {
            float delta = frameTimeClock.getElapsedTime().asSeconds();
            frameTimeClock.restart();
            if (delta > 0.5)
                delta = 0.5;
            if (delta < 0.001)
                delta = 0.001;
            delta *= gameSpeed;

            entityList.update();
            foreach(Updatable, u, updatableList)
                u->update(delta);
            elapsedTime += delta;
            CollisionManager::handleCollisions(delta);
            ScriptObject::clearDestroyedObjects();
            soundManager->updateTick();

            sf::sleep(sf::seconds(1.0/60.0 - delta));
            //if (elapsedTime > 2.0)
            //    break;
        }
    }else{
        sf::Clock frameTimeClock;
#ifdef DEBUG
        sf::Clock debugOutputClock;
#endif
        while(running && windowManager->window.isOpen())
        {
            InputHandler::preEventsUpdate();
            // Handle events
            sf::Event event;
            while (windowManager->window.pollEvent(event))
            {
                handleEvent(event);
            }
            InputHandler::postEventsUpdate();

#ifdef DEBUG
            if (sf::Keyboard::isKeyPressed(sf::Keyboard::Escape) && windowManager->hasFocus())
                running = false;

            if (debugOutputClock.getElapsedTime().asSeconds() > 1.0)
            {
                printf("Object count: %4d %4d %4d\n", DEBUG_PobjCount, updatableList.size(), entityList.size());
                debugOutputClock.restart();
            }
#endif

            float delta = frameTimeClock.restart().asSeconds();
            if (delta > 0.5)
                delta = 0.5;
            if (delta < 0.001)
                delta = 0.001;
            delta *= gameSpeed;
#ifdef DEBUG
            if (sf::Keyboard::isKeyPressed(sf::Keyboard::Tab))
                delta /= 5.0;
            if (sf::Keyboard::isKeyPressed(sf::Keyboard::Tilde))
                delta *= 5.0;
#endif
            EngineTiming engine_timing;

            sf::Clock engine_timing_clock;
            entityList.update();
            foreach(Updatable, u, updatableList)
                u->update(delta);
            elapsedTime += delta;
            engine_timing.update = engine_timing_clock.restart().asSeconds();
            CollisionManager::handleCollisions(delta);
            engine_timing.collision = engine_timing_clock.restart().asSeconds();
            ScriptObject::clearDestroyedObjects();
            soundManager->updateTick();

            // Clear the window
            windowManager->render();
            engine_timing.render = engine_timing_clock.restart().asSeconds();
            engine_timing.server_update = 0.0f;
            if (game_server)
                engine_timing.server_update = game_server->getUpdateTime();

            last_engine_timing = engine_timing;
        }
        soundManager->stopMusic();
    }
}

void Engine::handleEvent(sf::Event& event)
{
    // Window closed: exit
    if ((event.type == sf::Event::Closed))
        running = false;
    if (event.type == sf::Event::GainedFocus)
        windowManager->windowHasFocus = true;
    if (event.type == sf::Event::LostFocus)
        windowManager->windowHasFocus = false;
#ifdef DEBUG
    if ((event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::L))
    {
        int n = 0;
        printf("---------------------\n");
        for(PObject* obj = DEBUG_PobjListStart; obj; obj = obj->DEBUG_PobjListNext)
            printf("%c%4d: %4d: %s\n", obj->isDestroyed() ? '>' : ' ', n++, obj->getRefCount(), typeid(*obj).name());
        printf("---------------------\n");
    }
#endif
    InputHandler::handleEvent(event);
    if (event.type == sf::Event::Resized)
        windowManager->setupView();
#ifdef __ANDROID__
    //Focus lost and focus gained events are used when the application window is created and destroyed.
    if (event.type == sf::Event::LostFocus)
        running = false;

    //The MouseEntered and MouseLeft events are received when the activity needs to pause or resume.
    if (event.type == sf::Event::MouseLeft)
    {
        //Pause is when a small popup is on top of the window. So keep running.
        while(windowManager->window.isOpen() && windowManager->window.waitEvent(event))
        {
            if (event.type != sf::Event::MouseLeft)
                handleEvent(event);
            if (event.type == sf::Event::MouseEntered)
                break;
        }
    }
#endif//__ANDROID__
}

void Engine::setGameSpeed(float speed)
{
    gameSpeed = speed;
}

float Engine::getGameSpeed()
{
    return gameSpeed;
}

float Engine::getElapsedTime()
{
    return elapsedTime;
}

Engine::EngineTiming Engine::getEngineTiming()
{
    return last_engine_timing;
}

void Engine::shutdown()
{
    running = false;
}
<|endoftext|>


<commit_before>// Module:  Log4CPLUS
// File:    filter.cxx
// Created: 5/2003
// Author:  Tad E. Smith
//
//
// Copyright 2003-2015 Tad E. Smith
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <log4cplus/spi/filter.h>
#include <log4cplus/helpers/loglog.h>
#include <log4cplus/helpers/stringhelper.h>
#include <log4cplus/helpers/property.h>
#include <log4cplus/spi/loggingevent.h>
#include <log4cplus/thread/syncprims-pub-impl.h>

namespace log4cplus { namespace spi {

///////////////////////////////////////////////////////////////////////////////
// global methods
///////////////////////////////////////////////////////////////////////////////

FilterResult
checkFilter(const Filter* filter, const InternalLoggingEvent& event)
{
    const Filter* currentFilter = filter;
    while(currentFilter) {
        FilterResult result = currentFilter->decide(event);
        if(result != NEUTRAL) {
            return result;
        }

        currentFilter = currentFilter->next.get();
    }

    return ACCEPT;
}

///////////////////////////////////////////////////////////////////////////////
// Filter implementation
///////////////////////////////////////////////////////////////////////////////

Filter::Filter()
{
}

Filter::~Filter()
{
}

void
Filter::appendFilter(FilterPtr filter)
{
    if (! next)
        next = filter;
    else
        next->appendFilter(filter);
}

///////////////////////////////////////////////////////////////////////////////
// DenyAllFilter implementation
///////////////////////////////////////////////////////////////////////////////

DenyAllFilter::DenyAllFilter ()
{ }

DenyAllFilter::DenyAllFilter (const helpers::Properties&)
{ }

FilterResult
DenyAllFilter::decide(const InternalLoggingEvent&) const
{
    return DENY;
}

///////////////////////////////////////////////////////////////////////////////
// LogLevelMatchFilter implementation
///////////////////////////////////////////////////////////////////////////////

LogLevelMatchFilter::LogLevelMatchFilter()
{
    init();
}

LogLevelMatchFilter::LogLevelMatchFilter(const helpers::Properties& properties)
{
    init();

    properties.getBool (acceptOnMatch, LOG4CPLUS_TEXT("AcceptOnMatch"));

    tstring const & log_level_to_match
        = properties.getProperty( LOG4CPLUS_TEXT("LogLevelToMatch") );
    logLevelToMatch = getLogLevelManager().fromString(log_level_to_match);
}

void
LogLevelMatchFilter::init()
{
    acceptOnMatch = true;
    logLevelToMatch = NOT_SET_LOG_LEVEL;
}

FilterResult
LogLevelMatchFilter::decide(const InternalLoggingEvent& event) const
{
    if(logLevelToMatch == NOT_SET_LOG_LEVEL) {
        return NEUTRAL;
    }

    bool matchOccured = (logLevelToMatch == event.getLogLevel());

    if(matchOccured) {
        return (acceptOnMatch ? ACCEPT : DENY);
    }
    else {
        return NEUTRAL;
    }
}

///////////////////////////////////////////////////////////////////////////////
// LogLevelRangeFilter implementation
///////////////////////////////////////////////////////////////////////////////

LogLevelRangeFilter::LogLevelRangeFilter()
{
    init();
}

LogLevelRangeFilter::LogLevelRangeFilter(const helpers::Properties& properties)
{
    init();

    properties.getBool (acceptOnMatch = false,
        LOG4CPLUS_TEXT("AcceptOnMatch"));

    tstring const & log_level_min
        = properties.getProperty( LOG4CPLUS_TEXT("LogLevelMin") );
    logLevelMin = getLogLevelManager().fromString(log_level_min);

    tstring const & log_level_max
        = properties.getProperty( LOG4CPLUS_TEXT("LogLevelMax") );
    logLevelMax = getLogLevelManager().fromString(log_level_max);
}

void
LogLevelRangeFilter::init()
{
    acceptOnMatch = true;
    logLevelMin = NOT_SET_LOG_LEVEL;
    logLevelMax = NOT_SET_LOG_LEVEL;
}

FilterResult
LogLevelRangeFilter::decide(const InternalLoggingEvent& event) const
{
    if((logLevelMin != NOT_SET_LOG_LEVEL) && (event.getLogLevel() < logLevelMin)) {
        // priority of event is less than minimum
        return DENY;
    }

    if((logLevelMax != NOT_SET_LOG_LEVEL) && (event.getLogLevel() > logLevelMax)) {
        // priority of event is greater than maximum
        return DENY;
    }

    if(acceptOnMatch) {
        // this filter set up to bypass later filters and always return
        // accept if priority in range
        return ACCEPT;
    }
    else {
        // event is ok for this filter; allow later filters to have a look...
        return NEUTRAL;
    }
}

///////////////////////////////////////////////////////////////////////////////
// StringMatchFilter implementation
///////////////////////////////////////////////////////////////////////////////

StringMatchFilter::StringMatchFilter()
{
    init();
}

StringMatchFilter::StringMatchFilter(const helpers::Properties& properties)
{
    init();

    properties.getBool (acceptOnMatch = false,
        LOG4CPLUS_TEXT("AcceptOnMatch"));
    stringToMatch = properties.getProperty( LOG4CPLUS_TEXT("StringToMatch") );
}

void
StringMatchFilter::init()
{
    acceptOnMatch = true;
}

FilterResult
StringMatchFilter::decide(const InternalLoggingEvent& event) const
{
    const tstring& message = event.getMessage();

    if(stringToMatch.empty () || message.empty ()) {
        return NEUTRAL;
    }

    if(message.find(stringToMatch) == tstring::npos) {
        return NEUTRAL;
    }
    else {  // we've got a match
        return (acceptOnMatch ? ACCEPT : DENY);
    }
}

//
//
//

FunctionFilter::FunctionFilter (FunctionFilter::Function f)
    : function (std::move (f))
{ }

FilterResult
FunctionFilter::decide(const InternalLoggingEvent& event) const
{
    return function (event);
}

} } // namespace log4cplus { namespace spi {
<commit_msg>Cover DenyAllFilter and LogLevelMatchFilter by unit tests.<commit_after>// Module:  Log4CPLUS
// File:    filter.cxx
// Created: 5/2003
// Author:  Tad E. Smith
//
//
// Copyright 2003-2015 Tad E. Smith
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <log4cplus/spi/filter.h>
#include <log4cplus/helpers/loglog.h>
#include <log4cplus/helpers/stringhelper.h>
#include <log4cplus/helpers/property.h>
#include <log4cplus/spi/loggingevent.h>
#include <log4cplus/thread/syncprims-pub-impl.h>

#if defined (LOG4CPLUS_WITH_UNIT_TESTS)
#include <log4cplus/logger.h>
#include <catch.hpp>
#endif

namespace log4cplus { namespace spi {

///////////////////////////////////////////////////////////////////////////////
// global methods
///////////////////////////////////////////////////////////////////////////////

FilterResult
checkFilter(const Filter* filter, const InternalLoggingEvent& event)
{
    const Filter* currentFilter = filter;
    while(currentFilter) {
        FilterResult result = currentFilter->decide(event);
        if(result != NEUTRAL) {
            return result;
        }

        currentFilter = currentFilter->next.get();
    }

    return ACCEPT;
}

///////////////////////////////////////////////////////////////////////////////
// Filter implementation
///////////////////////////////////////////////////////////////////////////////

Filter::Filter()
{
}

Filter::~Filter()
{
}

void
Filter::appendFilter(FilterPtr filter)
{
    if (! next)
        next = filter;
    else
        next->appendFilter(filter);
}

///////////////////////////////////////////////////////////////////////////////
// DenyAllFilter implementation
///////////////////////////////////////////////////////////////////////////////

DenyAllFilter::DenyAllFilter ()
{ }

DenyAllFilter::DenyAllFilter (const helpers::Properties&)
{ }

FilterResult
DenyAllFilter::decide(const InternalLoggingEvent&) const
{
    return DENY;
}

///////////////////////////////////////////////////////////////////////////////
// LogLevelMatchFilter implementation
///////////////////////////////////////////////////////////////////////////////

LogLevelMatchFilter::LogLevelMatchFilter()
{
    init();
}

LogLevelMatchFilter::LogLevelMatchFilter(const helpers::Properties& properties)
{
    init();

    properties.getBool (acceptOnMatch, LOG4CPLUS_TEXT("AcceptOnMatch"));

    tstring const & log_level_to_match
        = properties.getProperty( LOG4CPLUS_TEXT("LogLevelToMatch") );
    logLevelToMatch = getLogLevelManager().fromString(log_level_to_match);
}

void
LogLevelMatchFilter::init()
{
    acceptOnMatch = true;
    logLevelToMatch = NOT_SET_LOG_LEVEL;
}

FilterResult
LogLevelMatchFilter::decide(const InternalLoggingEvent& event) const
{
    if(logLevelToMatch == NOT_SET_LOG_LEVEL) {
        return NEUTRAL;
    }

    bool matchOccured = (logLevelToMatch == event.getLogLevel());

    if(matchOccured) {
        return (acceptOnMatch ? ACCEPT : DENY);
    }
    else {
        return NEUTRAL;
    }
}

///////////////////////////////////////////////////////////////////////////////
// LogLevelRangeFilter implementation
///////////////////////////////////////////////////////////////////////////////

LogLevelRangeFilter::LogLevelRangeFilter()
{
    init();
}

LogLevelRangeFilter::LogLevelRangeFilter(const helpers::Properties& properties)
{
    init();

    properties.getBool (acceptOnMatch = false,
        LOG4CPLUS_TEXT("AcceptOnMatch"));

    tstring const & log_level_min
        = properties.getProperty( LOG4CPLUS_TEXT("LogLevelMin") );
    logLevelMin = getLogLevelManager().fromString(log_level_min);

    tstring const & log_level_max
        = properties.getProperty( LOG4CPLUS_TEXT("LogLevelMax") );
    logLevelMax = getLogLevelManager().fromString(log_level_max);
}

void
LogLevelRangeFilter::init()
{
    acceptOnMatch = true;
    logLevelMin = NOT_SET_LOG_LEVEL;
    logLevelMax = NOT_SET_LOG_LEVEL;
}

FilterResult
LogLevelRangeFilter::decide(const InternalLoggingEvent& event) const
{
    if((logLevelMin != NOT_SET_LOG_LEVEL) && (event.getLogLevel() < logLevelMin)) {
        // priority of event is less than minimum
        return DENY;
    }

    if((logLevelMax != NOT_SET_LOG_LEVEL) && (event.getLogLevel() > logLevelMax)) {
        // priority of event is greater than maximum
        return DENY;
    }

    if(acceptOnMatch) {
        // this filter set up to bypass later filters and always return
        // accept if priority in range
        return ACCEPT;
    }
    else {
        // event is ok for this filter; allow later filters to have a look...
        return NEUTRAL;
    }
}

///////////////////////////////////////////////////////////////////////////////
// StringMatchFilter implementation
///////////////////////////////////////////////////////////////////////////////

StringMatchFilter::StringMatchFilter()
{
    init();
}

StringMatchFilter::StringMatchFilter(const helpers::Properties& properties)
{
    init();

    properties.getBool (acceptOnMatch = false,
        LOG4CPLUS_TEXT("AcceptOnMatch"));
    stringToMatch = properties.getProperty( LOG4CPLUS_TEXT("StringToMatch") );
}

void
StringMatchFilter::init()
{
    acceptOnMatch = true;
}

FilterResult
StringMatchFilter::decide(const InternalLoggingEvent& event) const
{
    const tstring& message = event.getMessage();

    if(stringToMatch.empty () || message.empty ()) {
        return NEUTRAL;
    }

    if(message.find(stringToMatch) == tstring::npos) {
        return NEUTRAL;
    }
    else {  // we've got a match
        return (acceptOnMatch ? ACCEPT : DENY);
    }
}

//
//
//

FunctionFilter::FunctionFilter (FunctionFilter::Function f)
    : function (std::move (f))
{ }

FilterResult
FunctionFilter::decide(const InternalLoggingEvent& event) const
{
    return function (event);
}

#if defined (LOG4CPLUS_WITH_UNIT_TESTS)
CATCH_TEST_CASE ("Filter", "[filter]")
{
    FilterPtr filter;
    Logger log (Logger::getInstance (LOG4CPLUS_TEXT ("test")));
    InternalLoggingEvent info_ev (log.getName (), INFO_LOG_LEVEL,
        LOG4CPLUS_C_STR_TO_TSTRING (LOG4CPLUS_TEXT ("info log message")),
        __FILE__, __LINE__);
    InternalLoggingEvent error_ev (log.getName (), ERROR_LOG_LEVEL,
        LOG4CPLUS_C_STR_TO_TSTRING (LOG4CPLUS_TEXT ("error log message")),
        __FILE__, __LINE__);

    CATCH_SECTION ("deny all filter")
    {
        filter = new DenyAllFilter;
        CATCH_REQUIRE (filter->decide (info_ev) == DENY);
        CATCH_REQUIRE (checkFilter (filter.get (), info_ev) == DENY);
    }

    CATCH_SECTION ("log level match filter")
    {
        helpers::Properties props;
        props.setProperty (LOG4CPLUS_TEXT("LogLevelToMatch"),
            LOG4CPLUS_TEXT ("INFO"));
        filter = new LogLevelMatchFilter (props);
        CATCH_REQUIRE (filter->decide (info_ev) == ACCEPT);
    }
}

#endif

} } // namespace log4cplus { namespace spi {
<|endoftext|>


<commit_before>#include "filters.hh"

#include "buffer.hh"
#include "selection.hh"

namespace Kakoune
{

void preserve_indent(Buffer& buffer, Selection& selection, String& content)
{
    if (content == "\n")
    {
        BufferIterator line_begin = buffer.iterator_at_line_begin(selection.last() - 1);
        BufferIterator first_non_white = line_begin;
        while ((*first_non_white == '\t' or *first_non_white == ' ') and
               not first_non_white.is_end())
            ++first_non_white;

        content += buffer.string(line_begin, first_non_white);
    }
}

void cleanup_whitespaces(Buffer& buffer, Selection& selection, String& content)
{
    const BufferIterator& position = selection.last();
    if (content[0] == '\n' and not position.is_begin())
    {
        BufferIterator whitespace_start = position-1;
        while ((*whitespace_start == ' ' or *whitespace_start == '\t') and
               not whitespace_start .is_begin())
            --whitespace_start;
        ++whitespace_start;
        if (whitespace_start!= position)
            buffer.erase(whitespace_start, position);
    }
}

void expand_tabulations(Buffer& buffer, Selection& selection, String& content)
{
    const int tabstop = buffer.options()["tabstop"].get<int>();
    if (content == "\t")
    {
        int column = 0;
        const BufferIterator& position = selection.last();
        for (auto line_it = buffer.iterator_at_line_begin(position);
             line_it != position; ++line_it)
        {
            kak_assert(*line_it != '\n');
            if (*line_it == '\t')
                column += tabstop - (column % tabstop);
            else
               ++column;
        }

        int count = tabstop - (column % tabstop);
        content = String();
        for (int i = 0; i < count; ++i)
            content += ' ';
    }
}

struct RegexFilter
{
    RegexFilter(const String& line_match, const String& insert_match,
                const String& replacement)
    : m_line_match(line_match.c_str()), m_insert_match(insert_match.c_str()),
      m_replacement(replacement.c_str()) {}

    void operator() (Buffer& buffer, Selection& selection, String& content)
    {
        const auto& position = selection.last();
        auto line_begin = buffer.iterator_at_line_begin(position);
        boost::match_results<BufferIterator> results;
        if (boost::regex_match(content.c_str(), m_insert_match) and
            boost::regex_match(line_begin, position, results, m_line_match))
        {
            content = results.format(m_replacement.c_str());
            auto it = std::find(content.begin(), content.end(), '$');
            if (it != content.end())
            {
                ++it;
                if (it != content.end() && *it == 'c')
                {
                    String suffix(it+1, content.end());
                    content = String(content.begin(), it-1);

                    auto first = selection.first();
                    auto last = selection.last();
                    buffer.insert(position, suffix);
                    if (selection.first() == selection.last())
                        selection.first() -= suffix.length();
                    selection.last() -= suffix.length();
                }
            }
        }
    }

private:
    Regex  m_line_match;
    Regex  m_insert_match;
    String m_replacement;
};

FilterAndId regex_filter_factory(const FilterParameters& params)
{
    if (params.size() != 3)
        throw runtime_error("wrong parameter count");

    return FilterAndId{"re" + params[0] + "__" + params[1],
                       RegexFilter{params[0], params[1], params[2]}};
}

template<void (*filter_func)(Buffer&, Selection&, String&)>
class SimpleFilterFactory
{
public:
    SimpleFilterFactory(const String& id) : m_id(id) {}

    FilterAndId operator()(const FilterParameters& params) const
    {
        return FilterAndId(m_id, FilterFunc(filter_func));
    }
private:
    String m_id;
};

FilterAndId filter_group_factory(const FilterParameters& params)
{
    if (params.size() != 1)
        throw runtime_error("wrong parameter count");

    return FilterAndId(params[0], FilterGroup());
}

void register_filters()
{
    FilterRegistry& registry = FilterRegistry::instance();

    registry.register_func("preserve_indent", SimpleFilterFactory<preserve_indent>("preserve_indent"));
    registry.register_func("cleanup_whitespaces", SimpleFilterFactory<cleanup_whitespaces>("cleanup_whitespaces"));
    registry.register_func("expand_tabulations", SimpleFilterFactory<expand_tabulations>("expand_tabulations"));
    registry.register_func("regex", regex_filter_factory);
    registry.register_func("group", filter_group_factory);
}

}
<commit_msg>minor code cleanups in filters.cc<commit_after>#include "filters.hh"

#include "buffer.hh"
#include "selection.hh"

namespace Kakoune
{

void preserve_indent(Buffer& buffer, Selection& selection, String& content)
{
    if (content == "\n")
    {
        BufferCoord line_begin{selection.last().line(), 0};
        auto first_non_white = buffer.iterator_at(line_begin);
        while ((*first_non_white == '\t' or *first_non_white == ' ') and
               not first_non_white.is_end())
            ++first_non_white;

        content += buffer.string(line_begin, first_non_white);
    }
}

void cleanup_whitespaces(Buffer& buffer, Selection& selection, String& content)
{
    const auto position = buffer.iterator_at(selection.last());
    if (content[0] == '\n' and not position.is_begin())
    {
        auto whitespace_start = position-1;
        while ((*whitespace_start == ' ' or *whitespace_start == '\t') and
               not whitespace_start .is_begin())
            --whitespace_start;
        ++whitespace_start;
        if (whitespace_start != position)
            buffer.erase(whitespace_start, position);
    }
}

void expand_tabulations(Buffer& buffer, Selection& selection, String& content)
{
    const int tabstop = buffer.options()["tabstop"].get<int>();
    if (content == "\t")
    {
        int column = 0;
        const auto position = buffer.iterator_at(selection.last());
        for (auto it = buffer.iterator_at_line_begin(position);
             it != position; ++it)
        {
            kak_assert(*it != '\n');
            if (*it == '\t')
                column += tabstop - (column % tabstop);
            else
               ++column;
        }

        CharCount count = tabstop - (column % tabstop);
        content = String(' ', count);
    }
}

struct RegexFilter
{
    RegexFilter(const String& line_match, const String& insert_match,
                const String& replacement)
    : m_line_match(line_match.c_str()), m_insert_match(insert_match.c_str()),
      m_replacement(replacement.c_str()) {}

    void operator() (Buffer& buffer, Selection& selection, String& content)
    {
        const auto position = buffer.iterator_at(selection.last());
        auto line_begin = buffer.iterator_at_line_begin(position);
        boost::match_results<BufferIterator> results;
        if (boost::regex_match(content.c_str(), m_insert_match) and
            boost::regex_match(line_begin, position, results, m_line_match))
        {
            content = results.format(m_replacement.c_str());
            auto it = std::find(content.begin(), content.end(), '$');
            if (it != content.end())
            {
                ++it;
                if (it != content.end() && *it == 'c')
                {
                    String suffix(it+1, content.end());
                    content = String(content.begin(), it-1);

                    auto first = selection.first();
                    auto last = selection.last();
                    buffer.insert(position, suffix);
                    if (selection.first() == selection.last())
                        selection.first() -= suffix.length();
                    selection.last() -= suffix.length();
                }
            }
        }
    }

private:
    Regex  m_line_match;
    Regex  m_insert_match;
    String m_replacement;
};

FilterAndId regex_filter_factory(const FilterParameters& params)
{
    if (params.size() != 3)
        throw runtime_error("wrong parameter count");

    return FilterAndId{"re" + params[0] + "__" + params[1],
                       RegexFilter{params[0], params[1], params[2]}};
}

template<void (*filter_func)(Buffer&, Selection&, String&)>
class SimpleFilterFactory
{
public:
    SimpleFilterFactory(const String& id) : m_id(id) {}

    FilterAndId operator()(const FilterParameters& params) const
    {
        return FilterAndId(m_id, FilterFunc(filter_func));
    }
private:
    String m_id;
};

FilterAndId filter_group_factory(const FilterParameters& params)
{
    if (params.size() != 1)
        throw runtime_error("wrong parameter count");

    return FilterAndId(params[0], FilterGroup());
}

void register_filters()
{
    FilterRegistry& registry = FilterRegistry::instance();

    registry.register_func("preserve_indent", SimpleFilterFactory<preserve_indent>("preserve_indent"));
    registry.register_func("cleanup_whitespaces", SimpleFilterFactory<cleanup_whitespaces>("cleanup_whitespaces"));
    registry.register_func("expand_tabulations", SimpleFilterFactory<expand_tabulations>("expand_tabulations"));
    registry.register_func("regex", regex_filter_factory);
    registry.register_func("group", filter_group_factory);
}

}
<|endoftext|>


<commit_before>/*
 *  Copyright 2001, 2002, 2006, 2011 Adrian Thurston <thurston@complang.org>
 */

/*
 * Setting conditions and merging states with conditions are similar activities
 * when expressed in code. The critical difference is that a merge is a union
 * of multiple paths. We have to take both paths. Setting a condition, however,
 * is a restriction. We have to expand the transition to follow both values of
 * the condition, then remove the one that is not set.
 */

#include "fsmgraph.h"
#include "mergesort.h"
#include "parsedata.h"

#include <assert.h>
#include <iostream>

long TransAp::condFullSize()
	{ return condSpace == 0 ? 1 : condSpace->fullSize(); }

void FsmAp::expandConds( StateAp *fromState, TransAp *trans, const CondSet &fromCS, const CondSet &mergedCS )
{
	/* Need to transform condition element to the merged set. */
	for ( CondList::Iter cti = trans->tcap()->condList; cti.lte(); cti++ ) {
		long origVal = cti->key.getVal();
		long newVal = 0;

		/* Iterate the bit positions in the from set. */
		for ( CondSet::Iter csi = fromCS; csi.lte(); csi++ ) {
			/* If set, find it in the merged set and flip the bit to 1. */
			if ( origVal & (1 << csi.pos()) ) {
				/* The condition is set. Find the bit position in the merged
				 * set. */
				Action **cim = mergedCS.find( *csi );
				long bitPos = (cim - mergedCS.data);
				newVal |= 1 << bitPos;
			}
		}

		if ( origVal != newVal )
			cti->key = newVal;
	}

	/* Need to double up the whole transition list for each condition test in
	 * merged that is not in from. The one we add has the bit in question set.
	 * */
	for ( CondSet::Iter csi = mergedCS; csi.lte(); csi++ ) {
		Action **cim = fromCS.find( *csi );
		if ( cim == 0 ) {
			CondList newItems;
			for ( CondList::Iter cti = trans->tcap()->condList; cti.lte(); cti++ ) {
				/* Sub-transition for conditions. */
				CondAp *cond = new CondAp( trans );

				/* Attach only if our caller wants the expanded transitions
				 * attached. */
				attachTrans( fromState, cti->toState, cond );

				/* Call the user callback to add in the original source transition. */
				addInTrans( cond, cti.ptr );

				cond->key = cti->key.getVal() | (1 << csi.pos());

				newItems.append( cond );
			}

			/* Merge newItems in. Both the condList and newItems are sorted. Make
			 * a sorted list out of them. */
			CondAp *dest = trans->tcap()->condList.head;
			while ( dest != 0 && newItems.head != 0 ) {
				if ( newItems.head->key.getVal() > dest->key.getVal() ) {
					dest = dest->next;
				}
				else {
					/* Pop the item for insertion. */
					CondAp *ins = newItems.detachFirst();
					trans->tcap()->condList.addBefore( dest, ins );
				}
			}

			/* Append the rest of the items. */
			trans->tcap()->condList.append( newItems );
		}
	}
}

void FsmAp::expandCondTransitions( StateAp *fromState,
		TransAp *destTrans, TransAp *srcTrans )
{
	CondSet destCS, srcCS;
	CondSet mergedCS;

	if ( destTrans->condSpace != 0 )
		destCS.insert( destTrans->condSpace->condSet );

	if ( srcTrans->condSpace != 0 )
		srcCS.insert( srcTrans->condSpace->condSet );

	mergedCS.insert( destCS );
	mergedCS.insert( srcCS );

	expandConds( fromState, destTrans, destCS, mergedCS );
	expandConds( fromState, srcTrans, srcCS, mergedCS );

	CondSpace *mergedCondSpace = addCondSpace( mergedCS );
	destTrans->condSpace = mergedCondSpace;
}

CondSpace *FsmAp::addCondSpace( const CondSet &condSet )
{
	CondSpace *condSpace = ctx->condData->condSpaceMap.find( condSet );
	if ( condSpace == 0 ) {
		condSpace = new CondSpace( condSet );
		ctx->condData->condSpaceMap.insert( condSpace );
	}
	return condSpace;
}

void FsmAp::embedCondition( MergeData &md, StateAp *state, Action *condAction, bool sense )
{
	for ( TransList::Iter tr = state->outList; tr.lte(); tr++ ) {

		/* The original cond set. */
		CondSet origCS;
		if ( tr->condSpace != 0 )
			origCS.insert( tr->condSpace->condSet );

		/* The merged cond set. */
		CondSet mergedCS;
		mergedCS.insert( origCS );
		mergedCS.insert( condAction );

		/* Allocate a cond space for the merged set. */
		CondSpace *mergedCondSpace = addCondSpace( mergedCS );
		tr->condSpace = mergedCondSpace;

		/* Translate original condition values, making space for the new bit
		 * (possibly) introduced by the condition embedding. */
		for ( CondList::Iter cti = tr->tcap()->condList; cti.lte(); cti++ ) {
			long origVal = cti->key.getVal();
			long newVal = 0;

			/* For every set bit in the orig, find it's position in the merged
			 * and set the bit appropriately. */
			for ( CondSet::Iter csi = origCS; csi.lte(); csi++ ) {
				/* If set, find it in the merged set and flip the bit to 1. If
				 * not set, there is nothing to do (convenient eh?) */
				if ( origVal & (1 << csi.pos()) ) {
					/* The condition is set. Find the bit position in the
					 * merged set. */
					Action **cim = mergedCS.find( *csi );
					long bitPos = (cim - mergedCS.data);
					newVal |= 1 << bitPos;
				}
			}

			if ( origVal != newVal ) {
				std::cerr << "orig: " << origVal << " new: " << newVal << std::endl;
				cti->key = newVal;
			}

			/* Now set the new bit appropriately. Since it defaults to zero we
			 * only take action if sense is positive. */
			if ( sense ) {
				Action **cim = mergedCS.find( condAction );
				int pos = cim - mergedCS.data;
				cti->key = cti->key.getVal() | (1 << pos);
			}
		}
	}
}

void FsmAp::embedCondition( StateAp *state, Action *condAction, bool sense )
{
	MergeData md;

	/* Turn on misfit accounting to possibly catch the old start state. */
	setMisfitAccounting( true );

	/* Worker. */
	embedCondition( md, state, condAction, sense );

	/* Fill in any states that were newed up as combinations of others. */
	fillInStates( md );

	/* Remove the misfits and turn off misfit accounting. */
	removeMisfits();
	setMisfitAccounting( false );
}
<commit_msg>condition embedding now replaces the TransDataAp with the cond version<commit_after>/*
 *  Copyright 2001, 2002, 2006, 2011 Adrian Thurston <thurston@complang.org>
 */

/*
 * Setting conditions and merging states with conditions are similar activities
 * when expressed in code. The critical difference is that a merge is a union
 * of multiple paths. We have to take both paths. Setting a condition, however,
 * is a restriction. We have to expand the transition to follow both values of
 * the condition, then remove the one that is not set.
 */

#include "fsmgraph.h"
#include "mergesort.h"
#include "parsedata.h"

#include <assert.h>
#include <iostream>

long TransAp::condFullSize()
	{ return condSpace == 0 ? 1 : condSpace->fullSize(); }

void FsmAp::expandConds( StateAp *fromState, TransAp *trans, const CondSet &fromCS, const CondSet &mergedCS )
{
	/* Need to transform condition element to the merged set. */
	for ( CondList::Iter cti = trans->tcap()->condList; cti.lte(); cti++ ) {
		long origVal = cti->key.getVal();
		long newVal = 0;

		/* Iterate the bit positions in the from set. */
		for ( CondSet::Iter csi = fromCS; csi.lte(); csi++ ) {
			/* If set, find it in the merged set and flip the bit to 1. */
			if ( origVal & (1 << csi.pos()) ) {
				/* The condition is set. Find the bit position in the merged
				 * set. */
				Action **cim = mergedCS.find( *csi );
				long bitPos = (cim - mergedCS.data);
				newVal |= 1 << bitPos;
			}
		}

		if ( origVal != newVal )
			cti->key = newVal;
	}

	/* Need to double up the whole transition list for each condition test in
	 * merged that is not in from. The one we add has the bit in question set.
	 * */
	for ( CondSet::Iter csi = mergedCS; csi.lte(); csi++ ) {
		Action **cim = fromCS.find( *csi );
		if ( cim == 0 ) {
			CondList newItems;
			for ( CondList::Iter cti = trans->tcap()->condList; cti.lte(); cti++ ) {
				/* Sub-transition for conditions. */
				CondAp *cond = new CondAp( trans );

				/* Attach only if our caller wants the expanded transitions
				 * attached. */
				attachTrans( fromState, cti->toState, cond );

				/* Call the user callback to add in the original source transition. */
				addInTrans( cond, cti.ptr );

				cond->key = cti->key.getVal() | (1 << csi.pos());

				newItems.append( cond );
			}

			/* Merge newItems in. Both the condList and newItems are sorted. Make
			 * a sorted list out of them. */
			CondAp *dest = trans->tcap()->condList.head;
			while ( dest != 0 && newItems.head != 0 ) {
				if ( newItems.head->key.getVal() > dest->key.getVal() ) {
					dest = dest->next;
				}
				else {
					/* Pop the item for insertion. */
					CondAp *ins = newItems.detachFirst();
					trans->tcap()->condList.addBefore( dest, ins );
				}
			}

			/* Append the rest of the items. */
			trans->tcap()->condList.append( newItems );
		}
	}
}

void FsmAp::expandCondTransitions( StateAp *fromState,
		TransAp *destTrans, TransAp *srcTrans )
{
	CondSet destCS, srcCS;
	CondSet mergedCS;

	if ( destTrans->condSpace != 0 )
		destCS.insert( destTrans->condSpace->condSet );

	if ( srcTrans->condSpace != 0 )
		srcCS.insert( srcTrans->condSpace->condSet );

	mergedCS.insert( destCS );
	mergedCS.insert( srcCS );

	expandConds( fromState, destTrans, destCS, mergedCS );
	expandConds( fromState, srcTrans, srcCS, mergedCS );

	CondSpace *mergedCondSpace = addCondSpace( mergedCS );
	destTrans->condSpace = mergedCondSpace;
}

CondSpace *FsmAp::addCondSpace( const CondSet &condSet )
{
	CondSpace *condSpace = ctx->condData->condSpaceMap.find( condSet );
	if ( condSpace == 0 ) {
		condSpace = new CondSpace( condSet );
		ctx->condData->condSpaceMap.insert( condSpace );
	}
	return condSpace;
}

void FsmAp::embedCondition( MergeData &md, StateAp *state, Action *condAction, bool sense )
{
	/* First replace TransDataAp with cond versions. */
	TransList destList;
	for ( TransList::Iter tr = state->outList; tr.lte(); ) {
		TransList::Iter next = tr.next();
		if ( tr->plain() ) {
			TransDataAp *trans = tr->tdap();

			/* Detach in list. */

			TransCondAp *newTrans = new TransCondAp();
			newTrans->lowKey = trans->lowKey;
			newTrans->highKey = trans->highKey;
			newTrans->condSpace = tr->condSpace;

			CondAp *newCond = new CondAp( newTrans );
			newCond->key = 0;
			newTrans->condList.append( newCond );

			newCond->lmActionTable.setActions( trans->lmActionTable );
			newCond->actionTable.setActions( trans->actionTable );
			newCond->priorTable.setPriors( trans->priorTable );

			attachTrans( state, trans->toState, newCond );

			detachTrans( state, trans->toState, trans );
			delete trans;

			destList.append( newTrans );
		}
		else {
			destList.append( tr );
		}

		tr = next;
	}

	state->outList.abandon();
	state->outList.transfer( destList );

	for ( TransList::Iter tr = state->outList; tr.lte(); tr++ ) {
		/* The original cond set. */
		CondSet origCS;
		if ( tr->condSpace != 0 )
			origCS.insert( tr->condSpace->condSet );

		/* The merged cond set. */
		CondSet mergedCS;
		mergedCS.insert( origCS );
		mergedCS.insert( condAction );

		/* Allocate a cond space for the merged set. */
		CondSpace *mergedCondSpace = addCondSpace( mergedCS );
		tr->condSpace = mergedCondSpace;

		/* Translate original condition values, making space for the new bit
		 * (possibly) introduced by the condition embedding. */
		for ( CondList::Iter cti = tr->tcap()->condList; cti.lte(); cti++ ) {
			long origVal = cti->key.getVal();
			long newVal = 0;

			/* For every set bit in the orig, find it's position in the merged
			 * and set the bit appropriately. */
			for ( CondSet::Iter csi = origCS; csi.lte(); csi++ ) {
				/* If set, find it in the merged set and flip the bit to 1. If
				 * not set, there is nothing to do (convenient eh?) */
				if ( origVal & (1 << csi.pos()) ) {
					/* The condition is set. Find the bit position in the
					 * merged set. */
					Action **cim = mergedCS.find( *csi );
					long bitPos = (cim - mergedCS.data);
					newVal |= 1 << bitPos;
				}
			}

			if ( origVal != newVal ) {
				std::cerr << "orig: " << origVal << " new: " << newVal << std::endl;
				cti->key = newVal;
			}

			/* Now set the new bit appropriately. Since it defaults to zero we
			 * only take action if sense is positive. */
			if ( sense ) {
				Action **cim = mergedCS.find( condAction );
				int pos = cim - mergedCS.data;
				cti->key = cti->key.getVal() | (1 << pos);
			}
		}
	}
}

void FsmAp::embedCondition( StateAp *state, Action *condAction, bool sense )
{
	MergeData md;

	/* Turn on misfit accounting to possibly catch the old start state. */
	setMisfitAccounting( true );

	/* Worker. */
	embedCondition( md, state, condAction, sense );

	/* Fill in any states that were newed up as combinations of others. */
	fillInStates( md );

	/* Remove the misfits and turn off misfit accounting. */
	removeMisfits();
	setMisfitAccounting( false );
}
<|endoftext|>