<commit_before>/*
 * This file is open source software, licensed to you under the terms
 * of the Apache License, Version 2.0 (the "License").  See the NOTICE file
 * distributed with this work for additional information regarding copyright
 * ownership.  You may not use this file except in compliance with the License.
 *
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
/*
 * Copyright (C) 2017 ScyllaDB
 */

#include <seastar/core/linux-aio.hh>
#include <seastar/core/print.hh>
#include <unistd.h>
#include <sys/syscall.h>
#include <atomic>
#include <algorithm>
#include <errno.h>
#include <string.h>

namespace seastar {

namespace internal {

namespace linux_abi {

struct linux_aio_ring {
    uint32_t id;
    uint32_t nr;
    std::atomic<uint32_t> head;
    std::atomic<uint32_t> tail;
    uint32_t magic;
    uint32_t compat_features;
    uint32_t incompat_features;
    uint32_t header_length;
};

}

using namespace linux_abi;

static linux_aio_ring* to_ring(aio_context_t io_context) {
    return reinterpret_cast<linux_aio_ring*>(uintptr_t(io_context));
}

static bool usable(const linux_aio_ring* ring) {
    return ring->magic == 0xa10a10a1 && ring->incompat_features == 0;
}

int io_setup(int nr_events, aio_context_t* io_context) {
    return ::syscall(SYS_io_setup, nr_events, io_context);
}

int io_destroy(aio_context_t io_context) {
   return ::syscall(SYS_io_destroy, io_context);
}

int io_submit(aio_context_t io_context, long nr, iocb** iocbs) {
    return ::syscall(SYS_io_submit, io_context, nr, iocbs);
}

int io_cancel(aio_context_t io_context, iocb* iocb, io_event* result) {
    return ::syscall(SYS_io_cancel, io_context, iocb, result);
}

static int try_reap_events(aio_context_t io_context, long min_nr, long nr, io_event* events, const ::timespec* timeout,
        bool force_syscall) {
    auto ring = to_ring(io_context);
    if (usable(ring) && !force_syscall) {
        // Try to complete in userspace, if enough available events,
        // or if the timeout is zero

        // We're the only writer to ->head, so we can load with memory_order_relaxed (assuming
        // only a single thread calls io_getevents()).
        auto head = ring->head.load(std::memory_order_relaxed);
        // The kernel will write to the ring from an interrupt and then release with a write
        // to ring->tail, so we must memory_order_acquire here.
        auto tail = ring->tail.load(std::memory_order_acquire); // kernel writes from interrupts
        auto available = tail - head;
        if (tail < head) {
            available += ring->nr;
        }
        if (available >= uint32_t(min_nr)
                || (timeout && timeout->tv_sec == 0 && timeout->tv_nsec == 0)) {
            if (!available) {
                return 0;
            }
            auto ring_events = reinterpret_cast<const io_event*>(uintptr_t(io_context) + ring->header_length);
            auto now = std::min<uint32_t>(nr, available);
            auto start = ring_events + head;
            head += now;
            if (head < ring->nr) {
                std::copy(start, start + now, events);
            } else {
                head -= ring->nr;
                auto p = std::copy(start, ring_events + ring->nr, events);
                std::copy(ring_events, ring_events + head, p);
            }
            // The kernel will read ring->head and update its view of how many entries
            // in the ring are available, so memory_order_release to make sure any ring
            // accesses are completed before the update to ring->head is visible.
            ring->head.store(head, std::memory_order_release);
            return now;
        }
    }
    return -1;
}

int io_getevents(aio_context_t io_context, long min_nr, long nr, io_event* events, const ::timespec* timeout,
        bool force_syscall) {
    auto r = try_reap_events(io_context, min_nr, nr, events, timeout, force_syscall);
    if (r >= 0) {
        return r;
    }
    return ::syscall(SYS_io_getevents, io_context, min_nr, nr, events, timeout);
}

#ifndef __NR_io_pgetevents

#  if defined(__x86_64__)
#    define __NR_io_pgetevents 333
#  elif defined(__i386__)
#    define __NR_io_pgetevents 385
#  endif

#endif

int io_pgetevents(aio_context_t io_context, long min_nr, long nr, io_event* events, const ::timespec* timeout, const sigset_t* sigmask,
        bool force_syscall) {
#ifdef __NR_io_pgetevents
    auto r = try_reap_events(io_context, min_nr, nr, events, timeout, force_syscall);
    if (r >= 0) {
        return r;
    }
    aio_sigset as;
    as.sigmask = sigmask;
    as.sigsetsize = 8;  // Can't use sizeof(*sigmask) because user and kernel sigset_t are inconsistent
    return ::syscall(__NR_io_pgetevents, io_context, min_nr, nr, events, timeout, &as);
#else
    errno = ENOSYS;
    return -1;
#endif
}

void setup_aio_context(size_t nr, linux_abi::aio_context_t* io_context) {
    auto r = io_setup(nr, io_context);
    if (r < 0) {
        char buf[1024];
        char *msg = strerror_r(errno, buf, sizeof(buf));
        throw std::runtime_error(fmt::format("Could not setup Async I/O: {}. The most common cause is not enough request capacity in /proc/sys/fs/aio-max-nr. Try increasing that number or reducing the amount of logical CPUs available for your application", msg));
    }
}

}

}
<commit_msg>core: linux_aio_ring is not usable under valgrind<commit_after>/*
 * This file is open source software, licensed to you under the terms
 * of the Apache License, Version 2.0 (the "License").  See the NOTICE file
 * distributed with this work for additional information regarding copyright
 * ownership.  You may not use this file except in compliance with the License.
 *
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
/*
 * Copyright (C) 2017 ScyllaDB
 */

#include <seastar/core/linux-aio.hh>
#include <seastar/core/print.hh>
#include <unistd.h>
#include <sys/syscall.h>
#include <atomic>
#include <algorithm>
#include <errno.h>
#include <string.h>
#include <valgrind/valgrind.h>

namespace seastar {

namespace internal {

namespace linux_abi {

struct linux_aio_ring {
    uint32_t id;
    uint32_t nr;
    std::atomic<uint32_t> head;
    std::atomic<uint32_t> tail;
    uint32_t magic;
    uint32_t compat_features;
    uint32_t incompat_features;
    uint32_t header_length;
};

}

using namespace linux_abi;

static linux_aio_ring* to_ring(aio_context_t io_context) {
    return reinterpret_cast<linux_aio_ring*>(uintptr_t(io_context));
}

static bool usable(const linux_aio_ring* ring) {
    return ring->magic == 0xa10a10a1 && ring->incompat_features == 0 && !RUNNING_ON_VALGRIND;
}

int io_setup(int nr_events, aio_context_t* io_context) {
    return ::syscall(SYS_io_setup, nr_events, io_context);
}

int io_destroy(aio_context_t io_context) {
   return ::syscall(SYS_io_destroy, io_context);
}

int io_submit(aio_context_t io_context, long nr, iocb** iocbs) {
    return ::syscall(SYS_io_submit, io_context, nr, iocbs);
}

int io_cancel(aio_context_t io_context, iocb* iocb, io_event* result) {
    return ::syscall(SYS_io_cancel, io_context, iocb, result);
}

static int try_reap_events(aio_context_t io_context, long min_nr, long nr, io_event* events, const ::timespec* timeout,
        bool force_syscall) {
    auto ring = to_ring(io_context);
    if (usable(ring) && !force_syscall) {
        // Try to complete in userspace, if enough available events,
        // or if the timeout is zero

        // We're the only writer to ->head, so we can load with memory_order_relaxed (assuming
        // only a single thread calls io_getevents()).
        auto head = ring->head.load(std::memory_order_relaxed);
        // The kernel will write to the ring from an interrupt and then release with a write
        // to ring->tail, so we must memory_order_acquire here.
        auto tail = ring->tail.load(std::memory_order_acquire); // kernel writes from interrupts
        auto available = tail - head;
        if (tail < head) {
            available += ring->nr;
        }
        if (available >= uint32_t(min_nr)
                || (timeout && timeout->tv_sec == 0 && timeout->tv_nsec == 0)) {
            if (!available) {
                return 0;
            }
            auto ring_events = reinterpret_cast<const io_event*>(uintptr_t(io_context) + ring->header_length);
            auto now = std::min<uint32_t>(nr, available);
            auto start = ring_events + head;
            head += now;
            if (head < ring->nr) {
                std::copy(start, start + now, events);
            } else {
                head -= ring->nr;
                auto p = std::copy(start, ring_events + ring->nr, events);
                std::copy(ring_events, ring_events + head, p);
            }
            // The kernel will read ring->head and update its view of how many entries
            // in the ring are available, so memory_order_release to make sure any ring
            // accesses are completed before the update to ring->head is visible.
            ring->head.store(head, std::memory_order_release);
            return now;
        }
    }
    return -1;
}

int io_getevents(aio_context_t io_context, long min_nr, long nr, io_event* events, const ::timespec* timeout,
        bool force_syscall) {
    auto r = try_reap_events(io_context, min_nr, nr, events, timeout, force_syscall);
    if (r >= 0) {
        return r;
    }
    return ::syscall(SYS_io_getevents, io_context, min_nr, nr, events, timeout);
}

#ifndef __NR_io_pgetevents

#  if defined(__x86_64__)
#    define __NR_io_pgetevents 333
#  elif defined(__i386__)
#    define __NR_io_pgetevents 385
#  endif

#endif

int io_pgetevents(aio_context_t io_context, long min_nr, long nr, io_event* events, const ::timespec* timeout, const sigset_t* sigmask,
        bool force_syscall) {
#ifdef __NR_io_pgetevents
    auto r = try_reap_events(io_context, min_nr, nr, events, timeout, force_syscall);
    if (r >= 0) {
        return r;
    }
    aio_sigset as;
    as.sigmask = sigmask;
    as.sigsetsize = 8;  // Can't use sizeof(*sigmask) because user and kernel sigset_t are inconsistent
    return ::syscall(__NR_io_pgetevents, io_context, min_nr, nr, events, timeout, &as);
#else
    errno = ENOSYS;
    return -1;
#endif
}

void setup_aio_context(size_t nr, linux_abi::aio_context_t* io_context) {
    auto r = io_setup(nr, io_context);
    if (r < 0) {
        char buf[1024];
        char *msg = strerror_r(errno, buf, sizeof(buf));
        throw std::runtime_error(fmt::format("Could not setup Async I/O: {}. The most common cause is not enough request capacity in /proc/sys/fs/aio-max-nr. Try increasing that number or reducing the amount of logical CPUs available for your application", msg));
    }
}

}

}
<|endoftext|>


<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 "base/keyboard_codes.h"
#include "chrome/browser/automation/ui_controls.h"
#include "chrome/browser/views/chrome_views_delegate.h"
#include "chrome/browser/views/frame/browser_view.h"
#include "chrome/test/in_process_browser_test.h"
#include "chrome/test/ui_test_utils.h"
#include "views/view.h"
#include "views/accessibility/view_accessibility.h"
#include "views/widget/widget.h"
#include "views/window/window.h"

namespace {

class BrowserKeyboardAccessibility : public InProcessBrowserTest,
                                     public ChromeViewsDelegate {
 public:
  BrowserKeyboardAccessibility()
      : is_waiting_(false),
        current_view_(NULL) {
    // Set ourselves as the currently active ViewsDelegate.
    ViewsDelegate::views_delegate = this;
  }

  ~BrowserKeyboardAccessibility() {}

  // Overidden from ChromeViewsDelegate.
  // Save the last notification sent by views::View::NotifyAccessibilityEvent.
  virtual void NotifyAccessibilityEvent(
      views::View* view, AccessibilityTypes::Event event_type) {
    current_view_  = view;
    current_event_type_ = event_type;

    // Are we within a message loop waiting for a particular event?
    // TODO(phajdan.jr): remove logging after fixing http://crbug.com/50663.
    LOG(ERROR) << "Got notification; is_waiting_ is "
               << (is_waiting_ ? "true" : "false");
    if (is_waiting_) {
      is_waiting_ = false;
      MessageLoop::current()->Quit();
    }
  }

  // Helper that performs tabbing until it cycles back to the original focus.
  void TabCyclerForwardAndBack(gfx::NativeWindow hwnd);
  void TabCycler(gfx::NativeWindow hwnd, bool forward_tab);

  views::View* current_view() const { return current_view_; }

  gfx::NativeWindow current_view_native_window() const {
    return current_view()->GetWidget()->GetNativeView();
  }

  AccessibilityTypes::Event current_event() const {
    return current_event_type_;
  }

  void set_waiting(bool value) { is_waiting_ = value; }

 private:
  // Are we waiting for an event?
  bool is_waiting_;

  // View of interest (i.e. for testing or one we are waiting to gain focus).
  views::View* current_view_;

  // Event type of interest.
  AccessibilityTypes::Event current_event_type_;
};

// This test is disabled, see bug 50864.
IN_PROC_BROWSER_TEST_F(BrowserKeyboardAccessibility,
                       DISABLED_TabInAboutChromeDialog) {
  views::Window* about_chrome_window =
      BrowserView::GetBrowserViewForNativeWindow(
          browser()->window()->GetNativeHandle())->ShowAboutChromeDialog();

  TabCyclerForwardAndBack(about_chrome_window->GetNativeWindow());
}

// This test is disabled, see bug 50864.
IN_PROC_BROWSER_TEST_F(BrowserKeyboardAccessibility,
                       DISABLED_TabInClearBrowsingDataDialog) {
  browser()->OpenClearBrowsingDataDialog();
  TabCyclerForwardAndBack(current_view_native_window());
}

// This test is disabled, see bug 50864.
IN_PROC_BROWSER_TEST_F(BrowserKeyboardAccessibility,
                       DISABLED_TabInImportSettingsDialog) {
  browser()->OpenImportSettingsDialog();
  TabCyclerForwardAndBack(current_view_native_window());
}

// This test is disabled, see bug 50864.
IN_PROC_BROWSER_TEST_F(BrowserKeyboardAccessibility,
                       DISABLED_TabInKeywordEditor) {
  browser()->OpenKeywordEditor();
  TabCyclerForwardAndBack(current_view_native_window());
}

// This test is disabled, see bug 50864.
IN_PROC_BROWSER_TEST_F(BrowserKeyboardAccessibility,
                       DISABLED_TabInOptionsDialog) {
  browser()->OpenOptionsDialog();

  // Tab through each of the three tabs.
  for (int i = 0; i < 3; ++i) {
    // TODO(phajdan.jr): remove logging after fixing http://crbug.com/50663.
    LOG(ERROR) << "Iteration no. " << i;

    TabCyclerForwardAndBack(current_view_native_window());

    // TODO(phajdan.jr): remove logging after fixing http://crbug.com/50663.
    LOG(ERROR) << "Sending TAB key event...";
    ui_controls::SendKeyPressNotifyWhenDone(current_view_native_window(),
                                            base::VKEY_TAB,
                                            true, false, false, false,
                                            new MessageLoop::QuitTask());
    set_waiting(true);
    ui_test_utils::RunMessageLoop();
  }
}

// This test is disabled, see bug 50864.
IN_PROC_BROWSER_TEST_F(BrowserKeyboardAccessibility,
                       DISABLED_TabInPasswordManager) {
  browser()->OpenPasswordManager();
  TabCyclerForwardAndBack(current_view_native_window());
}

// TODO(dtseng): http://www.crbug.com/50402
IN_PROC_BROWSER_TEST_F(BrowserKeyboardAccessibility,
                       FAILS_TabInSyncMyBookmarksDialog) {
  browser()->OpenSyncMyBookmarksDialog();
  TabCyclerForwardAndBack(current_view_native_window());
}

// This test is disabled, see bug 50864.
IN_PROC_BROWSER_TEST_F(BrowserKeyboardAccessibility,
                       DISABLED_TabInTaskManager) {
  browser()->OpenTaskManager();
  TabCyclerForwardAndBack(current_view_native_window());
}

// This test is disabled, see bug 50864.
IN_PROC_BROWSER_TEST_F(BrowserKeyboardAccessibility,
                       DISABLED_TabInToolbar) {
  gfx::NativeWindow native_window = browser()->window()->GetNativeHandle();
  ui_controls::SendKeyPressNotifyWhenDone(native_window,
                                          base::VKEY_T,
                                          false, true, true, false,
                                          new MessageLoop::QuitTask());
  set_waiting(true);
  ui_test_utils::RunMessageLoop();
  TabCyclerForwardAndBack(current_view_native_window());
}

// This test is disabled, see bug 50864.
IN_PROC_BROWSER_TEST_F(BrowserKeyboardAccessibility,
                       DISABLED_TabInUpdateChromeDialog) {
  browser()->OpenUpdateChromeDialog();
  TabCyclerForwardAndBack(current_view_native_window());
}

void BrowserKeyboardAccessibility::TabCyclerForwardAndBack(
    gfx::NativeWindow hwnd) {
  TabCycler(hwnd, true);
  TabCycler(hwnd, false);
}

void BrowserKeyboardAccessibility::TabCycler(gfx::NativeWindow hwnd,
                                             bool forward_tab) {
  // Wait for a focus event on the provided native window.
  while (current_event() != AccessibilityTypes::EVENT_FOCUS ||
         current_view_native_window() != hwnd) {
    // TODO(phajdan.jr): remove logging after fixing http://crbug.com/50663.
    LOG(ERROR) << "Runnig message loop...";
    set_waiting(true);
    ui_test_utils::RunMessageLoop();
  }
  // TODO(phajdan.jr): remove logging after fixing http://crbug.com/50663.
  LOG(ERROR) << "After the loop.";

  views::View* first_focused_item = current_view();

  ASSERT_TRUE(first_focused_item != NULL);

  views::View* next_focused_item = first_focused_item;

  // Keep tabbing until we reach the originally focused view.
  do {
    // TODO(phajdan.jr): remove logging after fixing http://crbug.com/50663.
    LOG(ERROR) << "Sending TAB key event.";
    ui_controls::SendKeyPressNotifyWhenDone(hwnd, base::VKEY_TAB,
        false, !forward_tab, false, false, new MessageLoop::QuitTask());
    set_waiting(true);
    ui_test_utils::RunMessageLoop();
    next_focused_item = current_view();
  } while (first_focused_item != next_focused_item);
  // TODO(phajdan.jr): remove logging after fixing http://crbug.com/50663.
  LOG(ERROR) << "After second loop.";
}

}  // namespace
<commit_msg>Uninitialized member in BrowserKeyboardAccessibility.<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 "base/keyboard_codes.h"
#include "chrome/browser/automation/ui_controls.h"
#include "chrome/browser/views/chrome_views_delegate.h"
#include "chrome/browser/views/frame/browser_view.h"
#include "chrome/test/in_process_browser_test.h"
#include "chrome/test/ui_test_utils.h"
#include "views/view.h"
#include "views/accessibility/view_accessibility.h"
#include "views/widget/widget.h"
#include "views/window/window.h"

namespace {

class BrowserKeyboardAccessibility : public InProcessBrowserTest,
                                     public ChromeViewsDelegate {
 public:
  BrowserKeyboardAccessibility()
      : is_waiting_(false),
        current_view_(NULL),
        current_event_type_(AccessibilityTypes::EVENT_FOCUS) {
    // Set ourselves as the currently active ViewsDelegate.
    ViewsDelegate::views_delegate = this;
  }

  ~BrowserKeyboardAccessibility() {}

  // Overridden from ChromeViewsDelegate.
  // Save the last notification sent by views::View::NotifyAccessibilityEvent.
  virtual void NotifyAccessibilityEvent(
      views::View* view, AccessibilityTypes::Event event_type) {
    current_view_  = view;
    current_event_type_ = event_type;

    // Are we within a message loop waiting for a particular event?
    // TODO(phajdan.jr): remove logging after fixing http://crbug.com/50663.
    LOG(ERROR) << "Got notification; is_waiting_ is "
               << (is_waiting_ ? "true" : "false");
    if (is_waiting_) {
      is_waiting_ = false;
      MessageLoop::current()->Quit();
    }
  }

  // Helper that performs tabbing until it cycles back to the original focus.
  void TabCyclerForwardAndBack(gfx::NativeWindow hwnd);
  void TabCycler(gfx::NativeWindow hwnd, bool forward_tab);

  views::View* current_view() const { return current_view_; }

  gfx::NativeWindow current_view_native_window() const {
    return current_view()->GetWidget()->GetNativeView();
  }

  AccessibilityTypes::Event current_event() const {
    return current_event_type_;
  }

  void set_waiting(bool value) { is_waiting_ = value; }

 private:
  // Are we waiting for an event?
  bool is_waiting_;

  // View of interest (i.e. for testing or one we are waiting to gain focus).
  views::View* current_view_;

  // Event type of interest.
  AccessibilityTypes::Event current_event_type_;
};

// This test is disabled, see bug 50864.
IN_PROC_BROWSER_TEST_F(BrowserKeyboardAccessibility,
                       DISABLED_TabInAboutChromeDialog) {
  views::Window* about_chrome_window =
      BrowserView::GetBrowserViewForNativeWindow(
          browser()->window()->GetNativeHandle())->ShowAboutChromeDialog();

  TabCyclerForwardAndBack(about_chrome_window->GetNativeWindow());
}

// This test is disabled, see bug 50864.
IN_PROC_BROWSER_TEST_F(BrowserKeyboardAccessibility,
                       DISABLED_TabInClearBrowsingDataDialog) {
  browser()->OpenClearBrowsingDataDialog();
  TabCyclerForwardAndBack(current_view_native_window());
}

// This test is disabled, see bug 50864.
IN_PROC_BROWSER_TEST_F(BrowserKeyboardAccessibility,
                       DISABLED_TabInImportSettingsDialog) {
  browser()->OpenImportSettingsDialog();
  TabCyclerForwardAndBack(current_view_native_window());
}

// This test is disabled, see bug 50864.
IN_PROC_BROWSER_TEST_F(BrowserKeyboardAccessibility,
                       DISABLED_TabInKeywordEditor) {
  browser()->OpenKeywordEditor();
  TabCyclerForwardAndBack(current_view_native_window());
}

// This test is disabled, see bug 50864.
IN_PROC_BROWSER_TEST_F(BrowserKeyboardAccessibility,
                       DISABLED_TabInOptionsDialog) {
  browser()->OpenOptionsDialog();

  // Tab through each of the three tabs.
  for (int i = 0; i < 3; ++i) {
    // TODO(phajdan.jr): remove logging after fixing http://crbug.com/50663.
    LOG(ERROR) << "Iteration no. " << i;

    TabCyclerForwardAndBack(current_view_native_window());

    // TODO(phajdan.jr): remove logging after fixing http://crbug.com/50663.
    LOG(ERROR) << "Sending TAB key event...";
    ui_controls::SendKeyPressNotifyWhenDone(current_view_native_window(),
                                            base::VKEY_TAB,
                                            true, false, false, false,
                                            new MessageLoop::QuitTask());
    set_waiting(true);
    ui_test_utils::RunMessageLoop();
  }
}

// This test is disabled, see bug 50864.
IN_PROC_BROWSER_TEST_F(BrowserKeyboardAccessibility,
                       DISABLED_TabInPasswordManager) {
  browser()->OpenPasswordManager();
  TabCyclerForwardAndBack(current_view_native_window());
}

// TODO(dtseng): http://www.crbug.com/50402
IN_PROC_BROWSER_TEST_F(BrowserKeyboardAccessibility,
                       FAILS_TabInSyncMyBookmarksDialog) {
  browser()->OpenSyncMyBookmarksDialog();
  TabCyclerForwardAndBack(current_view_native_window());
}

// This test is disabled, see bug 50864.
IN_PROC_BROWSER_TEST_F(BrowserKeyboardAccessibility,
                       DISABLED_TabInTaskManager) {
  browser()->OpenTaskManager();
  TabCyclerForwardAndBack(current_view_native_window());
}

// This test is disabled, see bug 50864.
IN_PROC_BROWSER_TEST_F(BrowserKeyboardAccessibility,
                       DISABLED_TabInToolbar) {
  gfx::NativeWindow native_window = browser()->window()->GetNativeHandle();
  ui_controls::SendKeyPressNotifyWhenDone(native_window,
                                          base::VKEY_T,
                                          false, true, true, false,
                                          new MessageLoop::QuitTask());
  set_waiting(true);
  ui_test_utils::RunMessageLoop();
  TabCyclerForwardAndBack(current_view_native_window());
}

// This test is disabled, see bug 50864.
IN_PROC_BROWSER_TEST_F(BrowserKeyboardAccessibility,
                       DISABLED_TabInUpdateChromeDialog) {
  browser()->OpenUpdateChromeDialog();
  TabCyclerForwardAndBack(current_view_native_window());
}

void BrowserKeyboardAccessibility::TabCyclerForwardAndBack(
    gfx::NativeWindow hwnd) {
  TabCycler(hwnd, true);
  TabCycler(hwnd, false);
}

void BrowserKeyboardAccessibility::TabCycler(gfx::NativeWindow hwnd,
                                             bool forward_tab) {
  // Wait for a focus event on the provided native window.
  while (current_event() != AccessibilityTypes::EVENT_FOCUS ||
         current_view_native_window() != hwnd) {
    // TODO(phajdan.jr): remove logging after fixing http://crbug.com/50663.
    LOG(ERROR) << "Runnig message loop...";
    set_waiting(true);
    ui_test_utils::RunMessageLoop();
  }
  // TODO(phajdan.jr): remove logging after fixing http://crbug.com/50663.
  LOG(ERROR) << "After the loop.";

  views::View* first_focused_item = current_view();

  ASSERT_TRUE(first_focused_item != NULL);

  views::View* next_focused_item = first_focused_item;

  // Keep tabbing until we reach the originally focused view.
  do {
    // TODO(phajdan.jr): remove logging after fixing http://crbug.com/50663.
    LOG(ERROR) << "Sending TAB key event.";
    ui_controls::SendKeyPressNotifyWhenDone(hwnd, base::VKEY_TAB,
        false, !forward_tab, false, false, new MessageLoop::QuitTask());
    set_waiting(true);
    ui_test_utils::RunMessageLoop();
    next_focused_item = current_view();
  } while (first_focused_item != next_focused_item);
  // TODO(phajdan.jr): remove logging after fixing http://crbug.com/50663.
  LOG(ERROR) << "After second loop.";
}

}  // namespace
<|endoftext|>


<commit_before>/*
 * Software License Agreement (BSD License)
 *
 *  Copyright (c) 2010, Willow Garage, Inc.
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of Willow Garage, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *
 */

#ifndef PCL_SURFACE_IMPL_MARCHING_CUBES_RBF_H_
#define PCL_SURFACE_IMPL_MARCHING_CUBES_RBF_H_

#include <pcl/surface/marching_cubes_rbf.h>
#include <pcl/common/common.h>
#include <pcl/common/vector_average.h>
#include <pcl/Vertices.h>
#include <pcl/kdtree/kdtree_flann.h>

//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointNT>
pcl::MarchingCubesRBF<PointNT>::MarchingCubesRBF ()
  : MarchingCubes<PointNT> (),
    off_surface_epsilon_ (0.1f)
{
}

//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointNT>
pcl::MarchingCubesRBF<PointNT>::~MarchingCubesRBF ()
{
}

//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointNT> void
pcl::MarchingCubesRBF<PointNT>::voxelizeData ()
{
  // Initialize data structures
  unsigned int N = input_->size ();
  Eigen::MatrixXd M (2*N, 2*N),
                  d (2*N, 1);

  for (unsigned int row_i = 0; row_i < 2*N; ++row_i)
  {
    // boolean variable to determine whether we are in the off_surface domain for the rows
    bool row_off = (row_i >= N) ? 1 : 0;
    for (unsigned int col_i = 0; col_i < 2*N; ++col_i)
    {
      // boolean variable to determine whether we are in the off_surface domain for the columns
      bool col_off = (col_i >= N) ? 1 : 0;
      M (row_i, col_i) = kernel (input_->points[col_i%N].getVector3fMap () + input_->points[col_i%N].getNormalVector3fMap () * col_off * off_surface_epsilon_,
                                 input_->points[row_i%N].getVector3fMap () + input_->points[row_i%N].getNormalVector3fMap () * row_off * off_surface_epsilon_);
    }

    d (row_i, 0) = row_off * off_surface_epsilon_;
  }

  // Solve for the weights
  Eigen::MatrixXd w (2*N, 1);

  // Solve_linear_system (M, d, w);
  w = M.fullPivHouseholderQr ().solve (d);

  std::vector<float> weights_;
  std::vector<Eigen::Vector3f> centers_;
  weights_.resize (2*N);
  centers_.resize (2*N);
  for (unsigned int i = 0; i < N; ++i)
  {
    centers_[i] = input_->points[i].getVector3fMap ();
    centers_[i + N] = input_->points[i].getVector3fMap () + input_->points[i].getNormalVector3fMap () * off_surface_epsilon_;
    weights_[i] = w (i, 0);
    weights_[i + N] = w (i + N, 0);
  }

  for (int x = 0; x < res_x_; ++x)
    for (int y = 0; y < res_y_; ++y)
      for (int z = 0; z < res_z_; ++z)
      {
        Eigen::Vector3f point;
        point[0] = min_p_[0] + (max_p_[0] - min_p_[0]) * x / res_x_;
        point[1] = min_p_[1] + (max_p_[1] - min_p_[1]) * y / res_y_;
        point[2] = min_p_[2] + (max_p_[2] - min_p_[2]) * z / res_z_;

        float f = 0.0f;
        std::vector<float>::const_iterator w_it (weights_.begin());
        for (std::vector<Eigen::Vector3f>::const_iterator c_it = centers_.begin ();
             c_it != centers_.end (); ++c_it, ++w_it)
          f += *w_it * kernel (*c_it, point);

        grid_[x * res_y_*res_z_ + y * res_z_ + z] = f;
      }
}

//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointNT> float
pcl::MarchingCubesRBF<PointNT>::kernel (Eigen::Vector3f c, Eigen::Vector3f x)
{
  float r = (x - c).norm();
  return r*r*r;
}

#define PCL_INSTANTIATE_MarchingCubesRBF(T) template class PCL_EXPORTS pcl::MarchingCubesRBF<T>;

#endif    // PCL_SURFACE_IMPL_MARCHING_CUBES_HOPPE_H_

<commit_msg>marching cubes, printf test for teamcity<commit_after>/*
 * Software License Agreement (BSD License)
 *
 *  Copyright (c) 2010, Willow Garage, Inc.
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of Willow Garage, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *
 */

#ifndef PCL_SURFACE_IMPL_MARCHING_CUBES_RBF_H_
#define PCL_SURFACE_IMPL_MARCHING_CUBES_RBF_H_

#include <pcl/surface/marching_cubes_rbf.h>
#include <pcl/common/common.h>
#include <pcl/common/vector_average.h>
#include <pcl/Vertices.h>
#include <pcl/kdtree/kdtree_flann.h>

//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointNT>
pcl::MarchingCubesRBF<PointNT>::MarchingCubesRBF ()
  : MarchingCubes<PointNT> (),
    off_surface_epsilon_ (0.1f)
{
}

//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointNT>
pcl::MarchingCubesRBF<PointNT>::~MarchingCubesRBF ()
{
}

//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointNT> void
pcl::MarchingCubesRBF<PointNT>::voxelizeData ()
{
  // Initialize data structures
  unsigned int N = input_->size ();
  Eigen::MatrixXd M (2*N, 2*N),
                  d (2*N, 1);

  for (unsigned int row_i = 0; row_i < 2*N; ++row_i)
  {
    // boolean variable to determine whether we are in the off_surface domain for the rows
    bool row_off = (row_i >= N) ? 1 : 0;
    for (unsigned int col_i = 0; col_i < 2*N; ++col_i)
    {
      // boolean variable to determine whether we are in the off_surface domain for the columns
      bool col_off = (col_i >= N) ? 1 : 0;
      M (row_i, col_i) = kernel (input_->points[col_i%N].getVector3fMap () + input_->points[col_i%N].getNormalVector3fMap () * col_off * off_surface_epsilon_,
                                 input_->points[row_i%N].getVector3fMap () + input_->points[row_i%N].getNormalVector3fMap () * row_off * off_surface_epsilon_);
    }

    d (row_i, 0) = row_off * off_surface_epsilon_;
  }

  // Solve for the weights
  Eigen::MatrixXd w (2*N, 1);

  // Solve_linear_system (M, d, w);
  w = M.fullPivLu ().solve (d);

  std::vector<float> weights (2*N);
  std::vector<Eigen::Vector3f> centers (2*N);
  for (unsigned int i = 0; i < N; ++i)
  {
    centers[i] = input_->points[i].getVector3fMap ();
    centers[i + N] = input_->points[i].getVector3fMap () + input_->points[i].getNormalVector3fMap () * off_surface_epsilon_;
    weights[i] = w (i, 0);
    weights[i + N] = w (i + N, 0);

    printf ("centers %d %f %f %f weights %f    %f %f %f   %f\n", i, centers[i][0], centers[i][1], centers[i][2], weights[i],
                                                                    centers[i+N][0], centers[i+N][1], centers[i+N][2], weights[i+N]);
  }

  for (int x = 0; x < res_x_; ++x)
    for (int y = 0; y < res_y_; ++y)
      for (int z = 0; z < res_z_; ++z)
      {
        Eigen::Vector3f point;
        point[0] = min_p_[0] + (max_p_[0] - min_p_[0]) * x / res_x_;
        point[1] = min_p_[1] + (max_p_[1] - min_p_[1]) * y / res_y_;
        point[2] = min_p_[2] + (max_p_[2] - min_p_[2]) * z / res_z_;

        float f = 0.0f;
        std::vector<float>::const_iterator w_it (weights.begin());
        for (std::vector<Eigen::Vector3f>::const_iterator c_it = centers.begin ();
             c_it != centers.end (); ++c_it, ++w_it)
          f += *w_it * kernel (*c_it, point);

        grid_[x * res_y_*res_z_ + y * res_z_ + z] = f;
      }
}

//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointNT> float
pcl::MarchingCubesRBF<PointNT>::kernel (Eigen::Vector3f c, Eigen::Vector3f x)
{
  float r = (x - c).norm();
  return r*r*r;
}

#define PCL_INSTANTIATE_MarchingCubesRBF(T) template class PCL_EXPORTS pcl::MarchingCubesRBF<T>;

#endif    // PCL_SURFACE_IMPL_MARCHING_CUBES_HOPPE_H_

<|endoftext|>


<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 <oleacc.h>

#include "app/l10n_util.h"
#include "base/scoped_comptr_win.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_window.h"
#include "chrome/browser/view_ids.h"
#include "chrome/browser/views/bookmark_bar_view.h"
#include "chrome/browser/views/frame/browser_view.h"
#include "chrome/browser/views/toolbar_view.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/in_process_browser_test.h"
#include "chrome/test/ui_test_utils.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "views/accessibility/view_accessibility_wrapper.h"
#include "views/widget/root_view.h"
#include "views/widget/widget_win.h"
#include "views/window/window.h"

namespace {

VARIANT id_self = {VT_I4, CHILDID_SELF};

// Dummy class to force creation of ATL module, needed by COM to instantiate
// ViewAccessibility.
class TestAtlModule : public CAtlDllModuleT< TestAtlModule > {};
TestAtlModule test_atl_module_;

class BrowserViewsAccessibilityTest : public InProcessBrowserTest {
 public:
  BrowserViewsAccessibilityTest() {
    ::CoInitialize(NULL);
  }

  ~BrowserViewsAccessibilityTest() {
    ::CoUninitialize();
  }

  // Retrieves an instance of BrowserWindowTesting
  BrowserWindowTesting* GetBrowserWindowTesting() {
    BrowserWindow* browser_window = browser()->window();

    if (!browser_window)
      return NULL;

    return browser_window->GetBrowserWindowTesting();
  }

  // Retrieve an instance of BrowserView
  BrowserView* GetBrowserView() {
    return BrowserView::GetBrowserViewForNativeWindow(
               browser()->window()->GetNativeHandle());
  }

  // Retrieves and initializes an instance of LocationBarView.
  LocationBarView* GetLocationBarView() {
    BrowserWindowTesting* browser_window_testing = GetBrowserWindowTesting();

    if (!browser_window_testing)
      return NULL;

    return GetBrowserWindowTesting()->GetLocationBarView();
  }

  // Retrieves and initializes an instance of ToolbarView.
  ToolbarView* GetToolbarView() {
    BrowserWindowTesting* browser_window_testing = GetBrowserWindowTesting();

    if (!browser_window_testing)
      return NULL;

    return browser_window_testing->GetToolbarView();
  }

  // Retrieves and initializes an instance of BookmarkBarView.
  BookmarkBarView* GetBookmarkBarView() {
    BrowserWindowTesting* browser_window_testing = GetBrowserWindowTesting();

    if (!browser_window_testing)
      return NULL;

    return browser_window_testing->GetBookmarkBarView();
  }

  // Retrieves and verifies the accessibility object for the given View.
  void TestViewAccessibilityObject(views::View* view, std::wstring name,
                                   int32 role) {
    ASSERT_TRUE(NULL != view);

    ScopedComPtr<IAccessible> acc_obj;
    HRESULT hr = view->GetViewAccessibilityWrapper()->GetInstance(
        IID_IAccessible, reinterpret_cast<void**>(&acc_obj));
    ASSERT_EQ(S_OK, hr);
    ASSERT_TRUE(NULL != acc_obj);

    TestAccessibilityInfo(acc_obj, name, role);
  }

  // Verifies MSAA Name and Role properties of the given IAccessible.
  void TestAccessibilityInfo(IAccessible* acc_obj, std::wstring name,
                             int32 role) {
    // Verify MSAA Name property.
    BSTR acc_name;

    HRESULT hr = acc_obj->get_accName(id_self, &acc_name);
    ASSERT_EQ(S_OK, hr);
    EXPECT_STREQ(acc_name, name.c_str());

    // Verify MSAA Role property.
    VARIANT acc_role;
    ::VariantInit(&acc_role);

    hr = acc_obj->get_accRole(id_self, &acc_role);
    ASSERT_EQ(S_OK, hr);
    EXPECT_EQ(VT_I4, acc_role.vt);
    EXPECT_EQ(role, acc_role.lVal);

    ::VariantClear(&acc_role);
    ::SysFreeString(acc_name);
  }
};

// Retrieve accessibility object for main window and verify accessibility info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest,
                       TestChromeWindowAccObj) {
  BrowserWindow* browser_window = browser()->window();
  ASSERT_TRUE(NULL != browser_window);
  HWND hwnd = browser_window->GetNativeHandle();
  ASSERT_TRUE(NULL != hwnd);

  // Get accessibility object.
  ScopedComPtr<IAccessible> acc_obj;
  HRESULT hr = ::AccessibleObjectFromWindow(hwnd, OBJID_WINDOW, IID_IAccessible,
                                            reinterpret_cast<void**>(&acc_obj));
  ASSERT_EQ(S_OK, hr);
  ASSERT_TRUE(NULL != acc_obj);

  ui_test_utils::NavigateToURL(browser(), GURL(chrome::kAboutBlankURL));
  std::wstring title =
      l10n_util::GetStringF(IDS_BROWSER_WINDOW_TITLE_FORMAT,
                            ASCIIToWide(chrome::kAboutBlankURL));
  TestAccessibilityInfo(acc_obj, title, ROLE_SYSTEM_WINDOW);
}

// Retrieve accessibility object for non client view and verify accessibility
// info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestNonClientViewAccObj) {
  views::View* non_client_view =
  GetBrowserView()->GetWindow()->GetNonClientView();

  TestViewAccessibilityObject(non_client_view,
      l10n_util::GetString(IDS_PRODUCT_NAME),
      ROLE_SYSTEM_WINDOW);
}

// Retrieve accessibility object for browser root view and verify
// accessibility info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest,
                       TestBrowserRootViewAccObj) {
  views::View* browser_root_view =
      GetBrowserView()->frame()->GetFrameView()->GetRootView();

  TestViewAccessibilityObject(browser_root_view,
                              l10n_util::GetString(IDS_PRODUCT_NAME),
                              ROLE_SYSTEM_APPLICATION);
}

// Retrieve accessibility object for browser view and verify accessibility info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestBrowserViewAccObj) {
  // Verify root view MSAA name and role.
  TestViewAccessibilityObject(GetBrowserView(),
                              l10n_util::GetString(IDS_PRODUCT_NAME),
                              ROLE_SYSTEM_CLIENT);
}

// Retrieve accessibility object for toolbar view and verify accessibility info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestToolbarViewAccObj) {
  // Verify toolbar MSAA name and role.
  TestViewAccessibilityObject(GetToolbarView(),
                              l10n_util::GetString(IDS_ACCNAME_TOOLBAR),
                              ROLE_SYSTEM_TOOLBAR);
}

// Retrieve accessibility object for Back button and verify accessibility info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestBackButtonAccObj) {
  // Verify Back button MSAA name and role.
  TestViewAccessibilityObject(
      GetToolbarView()->GetViewByID(VIEW_ID_BACK_BUTTON),
      l10n_util::GetString(IDS_ACCNAME_BACK), ROLE_SYSTEM_BUTTONDROPDOWN);
}

// Retrieve accessibility object for Forward button and verify accessibility
// info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestForwardButtonAccObj) {
  // Verify Forward button MSAA name and role.
  TestViewAccessibilityObject(
      GetToolbarView()->GetViewByID(VIEW_ID_FORWARD_BUTTON),
      l10n_util::GetString(IDS_ACCNAME_FORWARD), ROLE_SYSTEM_BUTTONDROPDOWN);
}

// Retrieve accessibility object for Reload button and verify accessibility
// info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestReloadButtonAccObj) {
  // Verify Reload button MSAA name and role.
  TestViewAccessibilityObject(
      GetToolbarView()->GetViewByID(VIEW_ID_RELOAD_BUTTON),
      l10n_util::GetString(IDS_ACCNAME_RELOAD), ROLE_SYSTEM_PUSHBUTTON);
}

// Retrieve accessibility object for Home button and verify accessibility info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestHomeButtonAccObj) {
  // Verify Home button MSAA name and role.
  TestViewAccessibilityObject(
      GetToolbarView()->GetViewByID(VIEW_ID_HOME_BUTTON),
      l10n_util::GetString(IDS_ACCNAME_HOME), ROLE_SYSTEM_PUSHBUTTON);
}

// Retrieve accessibility object for Star button and verify accessibility info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest,
                       TestStarButtonAccObj) {
  // Verify Star button MSAA name and role.
  TestViewAccessibilityObject(
      GetToolbarView()->GetViewByID(VIEW_ID_STAR_BUTTON),
      l10n_util::GetString(IDS_ACCNAME_STAR), ROLE_SYSTEM_PUSHBUTTON);
}

// Retrieve accessibility object for location bar view and verify accessibility
// info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest,
                       TestLocationBarViewAccObj) {
  // Verify location bar MSAA name and role.
  TestViewAccessibilityObject(GetLocationBarView(),
                              l10n_util::GetString(IDS_ACCNAME_LOCATION),
                              ROLE_SYSTEM_GROUPING);
}

// Retrieve accessibility object for Go button and verify accessibility info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestGoButtonAccObj) {
  // Verify Go button MSAA name and role.
  TestViewAccessibilityObject(GetToolbarView()->GetViewByID(VIEW_ID_GO_BUTTON),
                              l10n_util::GetString(IDS_ACCNAME_GO),
                              ROLE_SYSTEM_PUSHBUTTON);
}

// Retrieve accessibility object for Page menu button and verify accessibility
// info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestPageMenuAccObj) {
  // Verify Page menu button MSAA name and role.
  TestViewAccessibilityObject(GetToolbarView()->GetViewByID(VIEW_ID_PAGE_MENU),
                              l10n_util::GetString(IDS_ACCNAME_PAGE),
                              ROLE_SYSTEM_BUTTONMENU);
}

// Retrieve accessibility object for App menu button and verify accessibility
// info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestAppMenuAccObj) {
  // Verify App menu button MSAA name and role.
  TestViewAccessibilityObject(GetToolbarView()->GetViewByID(VIEW_ID_APP_MENU),
                              l10n_util::GetString(IDS_ACCNAME_APP),
                              ROLE_SYSTEM_BUTTONMENU);
}

IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest,
                       TestBookmarkBarViewAccObj) {
  TestViewAccessibilityObject(GetBookmarkBarView(),
                              l10n_util::GetString(IDS_ACCNAME_BOOKMARKS),
                              ROLE_SYSTEM_TOOLBAR);
}

IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest,
                       TestAboutChromeViewAccObj) {
  //  Firstly, test that the WindowDelegate got updated.
  views::Window* aboutChromeWindow = GetBrowserView()->ShowAboutChromeDialog();
  EXPECT_STREQ(aboutChromeWindow->GetDelegate()->GetWindowTitle().c_str(),
               l10n_util::GetString(IDS_ABOUT_CHROME_TITLE).c_str());
  EXPECT_EQ(aboutChromeWindow->GetDelegate()->accessible_role(),
            AccessibilityTypes::ROLE_DIALOG);

  // Also test the accessibility object directly.
  ScopedComPtr<IAccessible> acc_obj;
  HRESULT hr =
    ::AccessibleObjectFromWindow(aboutChromeWindow->GetNativeWindow(),
                                 OBJID_CLIENT,
                                 IID_IAccessible,
                                 reinterpret_cast<void**>(&acc_obj));
  ASSERT_EQ(S_OK, hr);
  ASSERT_TRUE(NULL != acc_obj);

  TestAccessibilityInfo(acc_obj, l10n_util::GetString(IDS_ABOUT_CHROME_TITLE),
                        ROLE_SYSTEM_DIALOG);
}
}  // Namespace.

<commit_msg>Revert 47582 - Fix flakyness of browser_tests:BrowserViewsAccessibilityTest.TestChromeWindowAccObj<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 <oleacc.h>

#include "app/l10n_util.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_window.h"
#include "chrome/browser/view_ids.h"
#include "chrome/browser/views/bookmark_bar_view.h"
#include "chrome/browser/views/frame/browser_view.h"
#include "chrome/browser/views/toolbar_view.h"
#include "chrome/test/in_process_browser_test.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "views/accessibility/view_accessibility_wrapper.h"
#include "views/widget/root_view.h"
#include "views/widget/widget_win.h"
#include "views/window/window.h"

namespace {

VARIANT id_self = {VT_I4, CHILDID_SELF};

// Dummy class to force creation of ATL module, needed by COM to instantiate
// ViewAccessibility.
class TestAtlModule : public CAtlDllModuleT< TestAtlModule > {};
TestAtlModule test_atl_module_;

class BrowserViewsAccessibilityTest : public InProcessBrowserTest {
 public:
  BrowserViewsAccessibilityTest() {
    ::CoInitialize(NULL);
  }

  ~BrowserViewsAccessibilityTest() {
    ::CoUninitialize();
  }

  // Retrieves an instance of BrowserWindowTesting
  BrowserWindowTesting* GetBrowserWindowTesting() {
    BrowserWindow* browser_window = browser()->window();

    if (!browser_window)
      return NULL;

    return browser_window->GetBrowserWindowTesting();
  }

  // Retrieve an instance of BrowserView
  BrowserView* GetBrowserView() {
    return BrowserView::GetBrowserViewForNativeWindow(
               browser()->window()->GetNativeHandle());
  }

  // Retrieves and initializes an instance of LocationBarView.
  LocationBarView* GetLocationBarView() {
    BrowserWindowTesting* browser_window_testing = GetBrowserWindowTesting();

    if (!browser_window_testing)
      return NULL;

    return GetBrowserWindowTesting()->GetLocationBarView();
  }

  // Retrieves and initializes an instance of ToolbarView.
  ToolbarView* GetToolbarView() {
    BrowserWindowTesting* browser_window_testing = GetBrowserWindowTesting();

    if (!browser_window_testing)
      return NULL;

    return browser_window_testing->GetToolbarView();
  }

  // Retrieves and initializes an instance of BookmarkBarView.
  BookmarkBarView* GetBookmarkBarView() {
    BrowserWindowTesting* browser_window_testing = GetBrowserWindowTesting();

    if (!browser_window_testing)
      return NULL;

    return browser_window_testing->GetBookmarkBarView();
  }

  // Retrieves and verifies the accessibility object for the given View.
  void TestViewAccessibilityObject(views::View* view, std::wstring name,
                                   int32 role) {
    ASSERT_TRUE(NULL != view);

    IAccessible* acc_obj = NULL;
    HRESULT hr = view->GetViewAccessibilityWrapper()->GetInstance(
        IID_IAccessible, reinterpret_cast<void**>(&acc_obj));
    ASSERT_EQ(S_OK, hr);
    ASSERT_TRUE(NULL != acc_obj);

    TestAccessibilityInfo(acc_obj, name, role);
  }

  // Verifies MSAA Name and Role properties of the given IAccessible.
  void TestAccessibilityInfo(IAccessible* acc_obj, std::wstring name,
                             int32 role) {
    // Verify MSAA Name property.
    BSTR acc_name;

    HRESULT hr = acc_obj->get_accName(id_self, &acc_name);
    ASSERT_EQ(S_OK, hr);
    EXPECT_STREQ(acc_name, name.c_str());

    // Verify MSAA Role property.
    VARIANT acc_role;
    ::VariantInit(&acc_role);

    hr = acc_obj->get_accRole(id_self, &acc_role);
    ASSERT_EQ(S_OK, hr);
    EXPECT_EQ(VT_I4, acc_role.vt);
    EXPECT_EQ(role, acc_role.lVal);

    ::VariantClear(&acc_role);
    ::SysFreeString(acc_name);
  }
};

// Retrieve accessibility object for main window and verify accessibility info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest,
                       FLAKY_TestChromeWindowAccObj) {
  BrowserWindow* browser_window = browser()->window();
  ASSERT_TRUE(NULL != browser_window);

  HWND hwnd = browser_window->GetNativeHandle();
  ASSERT_TRUE(NULL != hwnd);

  // Get accessibility object.
  IAccessible* acc_obj = NULL;
  HRESULT hr = ::AccessibleObjectFromWindow(hwnd, OBJID_WINDOW, IID_IAccessible,
                                            reinterpret_cast<void**>(&acc_obj));
  ASSERT_EQ(S_OK, hr);
  ASSERT_TRUE(NULL != acc_obj);

  // TODO(ctguil): Fix. The window title could be "New Tab - Chromium" or
  // "about:blank - Chromium"
  TestAccessibilityInfo(acc_obj, l10n_util::GetString(IDS_PRODUCT_NAME),
                        ROLE_SYSTEM_WINDOW);

  acc_obj->Release();
}

// Retrieve accessibility object for non client view and verify accessibility
// info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestNonClientViewAccObj) {
  views::View* non_client_view =
  GetBrowserView()->GetWindow()->GetNonClientView();

  TestViewAccessibilityObject(non_client_view,
      l10n_util::GetString(IDS_PRODUCT_NAME),
      ROLE_SYSTEM_WINDOW);
}

// Retrieve accessibility object for browser root view and verify
// accessibility info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest,
                       TestBrowserRootViewAccObj) {
  views::View* browser_root_view =
      GetBrowserView()->frame()->GetFrameView()->GetRootView();

  TestViewAccessibilityObject(browser_root_view,
                              l10n_util::GetString(IDS_PRODUCT_NAME),
                              ROLE_SYSTEM_APPLICATION);
}

// Retrieve accessibility object for browser view and verify accessibility info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestBrowserViewAccObj) {
  // Verify root view MSAA name and role.
  TestViewAccessibilityObject(GetBrowserView(),
                              l10n_util::GetString(IDS_PRODUCT_NAME),
                              ROLE_SYSTEM_CLIENT);
}

// Retrieve accessibility object for toolbar view and verify accessibility info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestToolbarViewAccObj) {
  // Verify toolbar MSAA name and role.
  TestViewAccessibilityObject(GetToolbarView(),
                              l10n_util::GetString(IDS_ACCNAME_TOOLBAR),
                              ROLE_SYSTEM_TOOLBAR);
}

// Retrieve accessibility object for Back button and verify accessibility info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestBackButtonAccObj) {
  // Verify Back button MSAA name and role.
  TestViewAccessibilityObject(
      GetToolbarView()->GetViewByID(VIEW_ID_BACK_BUTTON),
      l10n_util::GetString(IDS_ACCNAME_BACK), ROLE_SYSTEM_BUTTONDROPDOWN);
}

// Retrieve accessibility object for Forward button and verify accessibility
// info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestForwardButtonAccObj) {
  // Verify Forward button MSAA name and role.
  TestViewAccessibilityObject(
      GetToolbarView()->GetViewByID(VIEW_ID_FORWARD_BUTTON),
      l10n_util::GetString(IDS_ACCNAME_FORWARD), ROLE_SYSTEM_BUTTONDROPDOWN);
}

// Retrieve accessibility object for Reload button and verify accessibility
// info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestReloadButtonAccObj) {
  // Verify Reload button MSAA name and role.
  TestViewAccessibilityObject(
      GetToolbarView()->GetViewByID(VIEW_ID_RELOAD_BUTTON),
      l10n_util::GetString(IDS_ACCNAME_RELOAD), ROLE_SYSTEM_PUSHBUTTON);
}

// Retrieve accessibility object for Home button and verify accessibility info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestHomeButtonAccObj) {
  // Verify Home button MSAA name and role.
  TestViewAccessibilityObject(
      GetToolbarView()->GetViewByID(VIEW_ID_HOME_BUTTON),
      l10n_util::GetString(IDS_ACCNAME_HOME), ROLE_SYSTEM_PUSHBUTTON);
}

// Retrieve accessibility object for Star button and verify accessibility info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest,
                       TestStarButtonAccObj) {
  // Verify Star button MSAA name and role.
  TestViewAccessibilityObject(
      GetToolbarView()->GetViewByID(VIEW_ID_STAR_BUTTON),
      l10n_util::GetString(IDS_ACCNAME_STAR), ROLE_SYSTEM_PUSHBUTTON);
}

// Retrieve accessibility object for location bar view and verify accessibility
// info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest,
                       TestLocationBarViewAccObj) {
  // Verify location bar MSAA name and role.
  TestViewAccessibilityObject(GetLocationBarView(),
                              l10n_util::GetString(IDS_ACCNAME_LOCATION),
                              ROLE_SYSTEM_GROUPING);
}

// Retrieve accessibility object for Go button and verify accessibility info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestGoButtonAccObj) {
  // Verify Go button MSAA name and role.
  TestViewAccessibilityObject(GetToolbarView()->GetViewByID(VIEW_ID_GO_BUTTON),
                              l10n_util::GetString(IDS_ACCNAME_GO),
                              ROLE_SYSTEM_PUSHBUTTON);
}

// Retrieve accessibility object for Page menu button and verify accessibility
// info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestPageMenuAccObj) {
  // Verify Page menu button MSAA name and role.
  TestViewAccessibilityObject(GetToolbarView()->GetViewByID(VIEW_ID_PAGE_MENU),
                              l10n_util::GetString(IDS_ACCNAME_PAGE),
                              ROLE_SYSTEM_BUTTONMENU);
}

// Retrieve accessibility object for App menu button and verify accessibility
// info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestAppMenuAccObj) {
  // Verify App menu button MSAA name and role.
  TestViewAccessibilityObject(GetToolbarView()->GetViewByID(VIEW_ID_APP_MENU),
                              l10n_util::GetString(IDS_ACCNAME_APP),
                              ROLE_SYSTEM_BUTTONMENU);
}

IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest,
                       TestBookmarkBarViewAccObj) {
  TestViewAccessibilityObject(GetBookmarkBarView(),
                              l10n_util::GetString(IDS_ACCNAME_BOOKMARKS),
                              ROLE_SYSTEM_TOOLBAR);
}

IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest,
                       TestAboutChromeViewAccObj) {
  //  Firstly, test that the WindowDelegate got updated.
  views::Window* aboutChromeWindow = GetBrowserView()->ShowAboutChromeDialog();
  EXPECT_STREQ(aboutChromeWindow->GetDelegate()->GetWindowTitle().c_str(),
               l10n_util::GetString(IDS_ABOUT_CHROME_TITLE).c_str());
  EXPECT_EQ(aboutChromeWindow->GetDelegate()->accessible_role(),
            AccessibilityTypes::ROLE_DIALOG);

  // Also test the accessibility object directly.
  IAccessible* acc_obj = NULL;
  HRESULT hr =
    ::AccessibleObjectFromWindow(aboutChromeWindow->GetNativeWindow(),
                                 OBJID_CLIENT,
                                 IID_IAccessible,
                                 reinterpret_cast<void**>(&acc_obj));
  ASSERT_EQ(S_OK, hr);
  ASSERT_TRUE(NULL != acc_obj);

  TestAccessibilityInfo(acc_obj, l10n_util::GetString(IDS_ABOUT_CHROME_TITLE),
                        ROLE_SYSTEM_DIALOG);

  acc_obj->Release();
}
}  // Namespace.

<|endoftext|>


<commit_before>/**
 * Copyright 2014 Open Connectome Project (http://openconnecto.me)
 * Written by Disa Mhembere (disa@jhu.edu)
 *
 * This file is part of FlashGraph.
 *
 * 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 CURRENT_KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <signal.h>
#ifdef PROFILER
#include <google/profiler.h>
#endif

#include <vector>
#include <algorithm>

#include "thread.h"
#include "io_interface.h"
#include "container.h"
#include "concurrency.h"

#include "vertex_index.h"
#include "graph_engine.h"
#include "graph_config.h"
#include "FGlib.h"
#include "save_result.h"

vsize_t CURRENT_K; // Min degree necessary to be part of the k-core graph
vsize_t PREVIOUS_K;
bool all_greater_than_core = true;

enum kcore_stage_t
{
	INIT_DEGREE,
	KCORE,
};
kcore_stage_t stage;

class kcore_vertex: public compute_vertex
{
	bool deleted;
	vsize_t core;
	vsize_t degree;

	public:
	kcore_vertex(vertex_id_t id): compute_vertex(id) {
		this->deleted = false;
		this->core = -1;
		this->degree = 0;
	}

	bool is_deleted() const {
		return deleted;
	}

	void _delete() {
		this->deleted = true;
	}

	void set_core(vsize_t core) {
		this->core = core;
	}

	const vsize_t get_core() const {
		return this->core;
	}

	vsize_t get_degree() {
		return degree;
	}

	size_t get_result() const {
		return get_core();
	}

	void run(vertex_program &prog);

	void run(vertex_program &prog, const page_vertex &vertex);

	void run_on_message(vertex_program &prog, const vertex_message &msg);

	void run_on_vertex_header(vertex_program &prog, const vertex_header &header) {
		degree = header.get_num_edges();
		this->core = degree == 0 ? 0 :
			degree == 1 ? 1 : -1; // Everyone between kmin < core > kmax will get this core
		this->deleted = degree == 0 ? true : false; // If your degree you're already deleted
	}
};

// If I am to be deleted, multicast this message to all my neighbors
// and activate them
class deleted_message: public vertex_message
{
	public:
		deleted_message(): vertex_message(sizeof(deleted_message), true) {
		}
};

void multicast_delete_msg(vertex_program &prog,
		const page_vertex &vertex, edge_type E)
{
	int num_dests = vertex.get_num_edges(E);
	edge_seq_iterator it = vertex.get_neigh_seq_it(E, 0, num_dests);

	// Doesn't matter who sent it, just --degree on reception
	deleted_message msg;
	prog.multicast_msg(it, msg);
}

void kcore_vertex::run(vertex_program &prog) {
	if (stage == INIT_DEGREE) {
		vertex_id_t id = get_id();
		request_vertex_headers(&id, 1);
		return;
	}

	if ( degree > CURRENT_K ) {
		return;
	}

	if (!is_deleted()) {
		vertex_id_t id = get_id();
		request_vertices(&id, 1); // put my edgelist in page cache

		if (all_greater_than_core) {
			all_greater_than_core = false;
		}
	}
}

void kcore_vertex::run(vertex_program &prog, const page_vertex &vertex) {
	if (is_deleted()) {
		return; // Nothing to be done here
	}

	if ( get_degree() < CURRENT_K ) {
		set_core(CURRENT_K - 1); // This is true because you must make it past CURRENT_K-1 to be here
		_delete();

		// Send two multicast messages - [IN_EDGE, OUT_EDGE]
		multicast_delete_msg(prog, vertex, IN_EDGE);
		multicast_delete_msg(prog, vertex, OUT_EDGE);
	}
}

void kcore_vertex::run_on_message(vertex_program &prog, const vertex_message &msg) {
	if (is_deleted()) {
		return; // nothing to be done here
	}
	// else
	degree--;
}

class count_vertex_query: public vertex_query
{
	size_t num;
	public:
	count_vertex_query() {
		num = 0;
	}

	virtual void run(graph_engine &graph, compute_vertex &v) {
		kcore_vertex &kcore_v = (kcore_vertex &) v;
		if (!kcore_v.is_deleted())
			num++;
	}

	virtual void merge(graph_engine &graph, vertex_query::ptr q) {
		count_vertex_query *cvq = (count_vertex_query *) q.get();
		num += cvq->num;
	}

	virtual ptr clone() {
		return vertex_query::ptr(new count_vertex_query());
	}

	size_t get_num() const {
		return num;
	}
};

// Max degree corresponds to the highest core
class max_degree_query: public vertex_query
{
	vsize_t max_degree;
	public:
	max_degree_query() {
		max_degree = 0;
	}

	virtual void run(graph_engine &graph, compute_vertex &v) {
		kcore_vertex& kv = (kcore_vertex&) v;
		if ((kv.get_degree()) > max_degree) {
			max_degree = kv.get_degree();
		}
	}

	virtual void merge(graph_engine &graph, vertex_query::ptr q) {
		max_degree_query *mdq = (max_degree_query *) q.get();
		if (max_degree < mdq->max_degree) {
			max_degree = mdq->max_degree;
		}
	}

	virtual ptr clone() {
		return vertex_query::ptr(new max_degree_query());
	}

	vsize_t get_max_degree() const {
		return max_degree;
	}
};

// Figure out the lowest REMAINING degree in the graph
class min_degree_query: public vertex_query
{
	vsize_t min_degree;
	public:
	min_degree_query() {
		min_degree = std::numeric_limits<vsize_t>::max();
	}

	virtual void run(graph_engine &graph, compute_vertex &v) {
		kcore_vertex kcore_v = (kcore_vertex&) v;
		if (!kcore_v.is_deleted()) {
			if (kcore_v.get_degree() < min_degree) {
				min_degree = kcore_v.get_degree();
			}
		}
	}

	virtual void merge(graph_engine &graph, vertex_query::ptr q) {
		min_degree_query *mdq = (min_degree_query *) q.get();
		if (min_degree > mdq->min_degree) {
			min_degree = mdq->min_degree;
		}
	}

	virtual ptr clone() {
		return vertex_query::ptr(new min_degree_query());
	}

	vsize_t get_min_degree() const {
		return min_degree;
	}
};

// Helpers
void print_func(vertex_id_t i) {
	std::cout << " " << i;
}
void print_active(std::vector<vertex_id_t> v) {
	std::cout << "[";
	for_each (v.begin(), v.end(), print_func);
	std::cout <<  " ]\n";
}
// End Helpers

void set_kmax(graph_engine::ptr graph, size_t& kmax)
{
	printf("Computing kmax as max_degree ...\n");
	vertex_query::ptr mdq(new max_degree_query());
	graph->query_on_all(mdq);
	kmax = ((max_degree_query *) mdq.get())->get_max_degree();
}

class activate_k_filter: public vertex_filter {
	vsize_t min;
	public:
	activate_k_filter (vsize_t min) {
		this->min = min;
	}
	bool keep(compute_vertex &v) {
		kcore_vertex &kcore_v = (kcore_vertex &) v;
		return kcore_v.get_degree() < min;
	}
};

FG_vector<size_t>::ptr compute_kcore(FG_graph::ptr fg,
		size_t k, size_t kmax)
{
	graph_index::ptr index = NUMA_graph_index<kcore_vertex>::create(
			fg->get_index_file());
	graph_engine::ptr graph = graph_engine::create(fg->get_graph_file(),
			index, fg->get_configs());

	if (k < 0 || k > graph->get_max_vertex_id()) {
		fprintf(stderr, "'k' must be between 2 and the number of nodes in the graph\n");
		exit(-1);
	}

	struct timeval start, end;
	gettimeofday(&start, NULL);

	CURRENT_K = k;
	printf("Running the init degree stage ...\n");
	stage = INIT_DEGREE;
	graph->start_all();
	graph->wait4complete();
	stage = KCORE;

	if (kmax == 0 && k != 0) {
		set_kmax(graph, kmax);
	}
	printf("Setting kmax as %lu\n", kmax);

	for (; CURRENT_K <= kmax; CURRENT_K++) {

		std::shared_ptr<vertex_filter> filter
			= std::shared_ptr<vertex_filter>(new activate_k_filter(CURRENT_K));

		graph->start(filter, vertex_program_creater::ptr());
		graph->wait4complete();

		if (all_greater_than_core) { // There's a chance we can hop forward
			vertex_query::ptr mdq(new min_degree_query());
			graph->query_on_all(mdq);
			vsize_t min_degree_remaining = ((min_degree_query *) mdq.get())->get_min_degree();

			if (min_degree_remaining == std::numeric_limits<vsize_t>::max()) {
				printf("No more active vertices left!\n");
				break;
			}

			printf("\n\nThe graphs minimum degree remaining is %u\n\n", min_degree_remaining);
			// Effectively jumps us to the CURRENT_K + 1th core
			CURRENT_K = min_degree_remaining; // NOTE: Careful - messing with the loop variable :/

			if (CURRENT_K > kmax) {
				printf("\nTerminating computation at kmax\n");
				break;
			}
		}
		all_greater_than_core = true;

#if 1
		vertex_query::ptr cvq(new count_vertex_query());
		graph->query_on_all(cvq);
		size_t in_k_core = ((count_vertex_query *) cvq.get())->get_num();
		printf("\n******************************************\n"
				"%d-core shows %ld vertices > %d degree\n"
				"\n******************************************\n",
				CURRENT_K, in_k_core, CURRENT_K);
#endif
		PREVIOUS_K = CURRENT_K;
	}

	gettimeofday(&end, NULL);
	printf("\nK-core took %f sec to complete\n", time_diff(start, end));

	FG_vector<size_t>::ptr ret = FG_vector<size_t>::create(
			graph->get_num_vertices());

	graph->query_on_all(vertex_query::ptr(
				new save_query<size_t, kcore_vertex>(ret)));

	return ret;
}

<commit_msg>[Graph]: remove unnecessary check in k-core.<commit_after>/**
 * Copyright 2014 Open Connectome Project (http://openconnecto.me)
 * Written by Disa Mhembere (disa@jhu.edu)
 *
 * This file is part of FlashGraph.
 *
 * 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 CURRENT_KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <signal.h>
#ifdef PROFILER
#include <google/profiler.h>
#endif

#include <vector>
#include <algorithm>

#include "thread.h"
#include "io_interface.h"
#include "container.h"
#include "concurrency.h"

#include "vertex_index.h"
#include "graph_engine.h"
#include "graph_config.h"
#include "FGlib.h"
#include "save_result.h"

vsize_t CURRENT_K; // Min degree necessary to be part of the k-core graph
vsize_t PREVIOUS_K;
bool all_greater_than_core = true;

enum kcore_stage_t
{
	INIT_DEGREE,
	KCORE,
};
kcore_stage_t stage;

class kcore_vertex: public compute_vertex
{
	bool deleted;
	vsize_t core;
	vsize_t degree;

	public:
	kcore_vertex(vertex_id_t id): compute_vertex(id) {
		this->deleted = false;
		this->core = -1;
		this->degree = 0;
	}

	bool is_deleted() const {
		return deleted;
	}

	void _delete() {
		this->deleted = true;
	}

	void set_core(vsize_t core) {
		this->core = core;
	}

	const vsize_t get_core() const {
		return this->core;
	}

	vsize_t get_degree() {
		return degree;
	}

	size_t get_result() const {
		return get_core();
	}

	void run(vertex_program &prog);

	void run(vertex_program &prog, const page_vertex &vertex);

	void run_on_message(vertex_program &prog, const vertex_message &msg);

	void run_on_vertex_header(vertex_program &prog, const vertex_header &header) {
		degree = header.get_num_edges();
		this->core = degree == 0 ? 0 :
			degree == 1 ? 1 : -1; // Everyone between kmin < core > kmax will get this core
		this->deleted = degree == 0 ? true : false; // If your degree you're already deleted
	}
};

// If I am to be deleted, multicast this message to all my neighbors
// and activate them
class deleted_message: public vertex_message
{
	public:
		deleted_message(): vertex_message(sizeof(deleted_message), true) {
		}
};

void multicast_delete_msg(vertex_program &prog,
		const page_vertex &vertex, edge_type E)
{
	int num_dests = vertex.get_num_edges(E);
	edge_seq_iterator it = vertex.get_neigh_seq_it(E, 0, num_dests);

	// Doesn't matter who sent it, just --degree on reception
	deleted_message msg;
	prog.multicast_msg(it, msg);
}

void kcore_vertex::run(vertex_program &prog) {
	if (stage == INIT_DEGREE) {
		vertex_id_t id = get_id();
		request_vertex_headers(&id, 1);
		return;
	}

	if ( degree > CURRENT_K ) {
		return;
	}

	if (!is_deleted()) {
		vertex_id_t id = get_id();
		request_vertices(&id, 1); // put my edgelist in page cache

		if (all_greater_than_core) {
			all_greater_than_core = false;
		}
	}
}

void kcore_vertex::run(vertex_program &prog, const page_vertex &vertex) {
	if (is_deleted()) {
		return; // Nothing to be done here
	}

	if ( get_degree() < CURRENT_K ) {
		set_core(CURRENT_K - 1); // This is true because you must make it past CURRENT_K-1 to be here
		_delete();

		// Send two multicast messages - [IN_EDGE, OUT_EDGE]
		multicast_delete_msg(prog, vertex, IN_EDGE);
		multicast_delete_msg(prog, vertex, OUT_EDGE);
	}
}

void kcore_vertex::run_on_message(vertex_program &prog, const vertex_message &msg) {
	if (is_deleted()) {
		return; // nothing to be done here
	}
	// else
	degree--;
}

class count_vertex_query: public vertex_query
{
	size_t num;
	public:
	count_vertex_query() {
		num = 0;
	}

	virtual void run(graph_engine &graph, compute_vertex &v) {
		kcore_vertex &kcore_v = (kcore_vertex &) v;
		if (!kcore_v.is_deleted())
			num++;
	}

	virtual void merge(graph_engine &graph, vertex_query::ptr q) {
		count_vertex_query *cvq = (count_vertex_query *) q.get();
		num += cvq->num;
	}

	virtual ptr clone() {
		return vertex_query::ptr(new count_vertex_query());
	}

	size_t get_num() const {
		return num;
	}
};

// Max degree corresponds to the highest core
class max_degree_query: public vertex_query
{
	vsize_t max_degree;
	public:
	max_degree_query() {
		max_degree = 0;
	}

	virtual void run(graph_engine &graph, compute_vertex &v) {
		kcore_vertex& kv = (kcore_vertex&) v;
		if ((kv.get_degree()) > max_degree) {
			max_degree = kv.get_degree();
		}
	}

	virtual void merge(graph_engine &graph, vertex_query::ptr q) {
		max_degree_query *mdq = (max_degree_query *) q.get();
		if (max_degree < mdq->max_degree) {
			max_degree = mdq->max_degree;
		}
	}

	virtual ptr clone() {
		return vertex_query::ptr(new max_degree_query());
	}

	vsize_t get_max_degree() const {
		return max_degree;
	}
};

// Figure out the lowest REMAINING degree in the graph
class min_degree_query: public vertex_query
{
	vsize_t min_degree;
	public:
	min_degree_query() {
		min_degree = std::numeric_limits<vsize_t>::max();
	}

	virtual void run(graph_engine &graph, compute_vertex &v) {
		kcore_vertex kcore_v = (kcore_vertex&) v;
		if (!kcore_v.is_deleted()) {
			if (kcore_v.get_degree() < min_degree) {
				min_degree = kcore_v.get_degree();
			}
		}
	}

	virtual void merge(graph_engine &graph, vertex_query::ptr q) {
		min_degree_query *mdq = (min_degree_query *) q.get();
		if (min_degree > mdq->min_degree) {
			min_degree = mdq->min_degree;
		}
	}

	virtual ptr clone() {
		return vertex_query::ptr(new min_degree_query());
	}

	vsize_t get_min_degree() const {
		return min_degree;
	}
};

// Helpers
void print_func(vertex_id_t i) {
	std::cout << " " << i;
}
void print_active(std::vector<vertex_id_t> v) {
	std::cout << "[";
	for_each (v.begin(), v.end(), print_func);
	std::cout <<  " ]\n";
}
// End Helpers

void set_kmax(graph_engine::ptr graph, size_t& kmax)
{
	printf("Computing kmax as max_degree ...\n");
	vertex_query::ptr mdq(new max_degree_query());
	graph->query_on_all(mdq);
	kmax = ((max_degree_query *) mdq.get())->get_max_degree();
}

class activate_k_filter: public vertex_filter {
	vsize_t min;
	public:
	activate_k_filter (vsize_t min) {
		this->min = min;
	}
	bool keep(compute_vertex &v) {
		kcore_vertex &kcore_v = (kcore_vertex &) v;
		return kcore_v.get_degree() < min;
	}
};

FG_vector<size_t>::ptr compute_kcore(FG_graph::ptr fg,
		size_t k, size_t kmax)
{
	graph_index::ptr index = NUMA_graph_index<kcore_vertex>::create(
			fg->get_index_file());
	graph_engine::ptr graph = graph_engine::create(fg->get_graph_file(),
			index, fg->get_configs());

	if (k > graph->get_max_vertex_id()) {
		fprintf(stderr, "'k' must be between 2 and the number of nodes in the graph\n");
		exit(-1);
	}

	struct timeval start, end;
	gettimeofday(&start, NULL);

	CURRENT_K = k;
	printf("Running the init degree stage ...\n");
	stage = INIT_DEGREE;
	graph->start_all();
	graph->wait4complete();
	stage = KCORE;

	if (kmax == 0 && k != 0) {
		set_kmax(graph, kmax);
	}
	printf("Setting kmax as %lu\n", kmax);

	for (; CURRENT_K <= kmax; CURRENT_K++) {

		std::shared_ptr<vertex_filter> filter
			= std::shared_ptr<vertex_filter>(new activate_k_filter(CURRENT_K));

		graph->start(filter, vertex_program_creater::ptr());
		graph->wait4complete();

		if (all_greater_than_core) { // There's a chance we can hop forward
			vertex_query::ptr mdq(new min_degree_query());
			graph->query_on_all(mdq);
			vsize_t min_degree_remaining = ((min_degree_query *) mdq.get())->get_min_degree();

			if (min_degree_remaining == std::numeric_limits<vsize_t>::max()) {
				printf("No more active vertices left!\n");
				break;
			}

			printf("\n\nThe graphs minimum degree remaining is %u\n\n", min_degree_remaining);
			// Effectively jumps us to the CURRENT_K + 1th core
			CURRENT_K = min_degree_remaining; // NOTE: Careful - messing with the loop variable :/

			if (CURRENT_K > kmax) {
				printf("\nTerminating computation at kmax\n");
				break;
			}
		}
		all_greater_than_core = true;

#if 1
		vertex_query::ptr cvq(new count_vertex_query());
		graph->query_on_all(cvq);
		size_t in_k_core = ((count_vertex_query *) cvq.get())->get_num();
		printf("\n******************************************\n"
				"%d-core shows %ld vertices > %d degree\n"
				"\n******************************************\n",
				CURRENT_K, in_k_core, CURRENT_K);
#endif
		PREVIOUS_K = CURRENT_K;
	}

	gettimeofday(&end, NULL);
	printf("\nK-core took %f sec to complete\n", time_diff(start, end));

	FG_vector<size_t>::ptr ret = FG_vector<size_t>::create(
			graph->get_num_vertices());

	graph->query_on_all(vertex_query::ptr(
				new save_query<size_t, kcore_vertex>(ret)));

	return ret;
}

<|endoftext|>


<commit_before>/*
   For more information, please see: http://software.sci.utah.edu

   The MIT License

   Copyright (c) 2012 Interactive Visualization and Data Analysis Group.

   Permission is hereby granted, free of charge, to any person obtaining a
   copy of this software and associated documentation files (the "Software"),
   to deal in the Software without restriction, including without limitation
   the rights to use, copy, modify, merge, publish, distribute, sublicense,
   and/or sell copies of the Software, and to permit persons to whom the
   Software is furnished to do so, subject to the following conditions:

   The above copyright notice and this permission notice shall be included
   in all copies or substantial portions of the Software.

   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
   DEALINGS IN THE SOFTWARE.
*/
#include "StdTuvokDefines.h"
#ifdef _MSC_VER
# include <memory>
#else
# include <tr1/memory>
#endif
#include <fstream>
#include "Basics/Mesh.h"
#include "Controller/Controller.h"
#include "LinesGeoConverter.h"
#include "TuvokIOError.h"

namespace tuvok {

LinesGeoConverter::LinesGeoConverter() {
  m_vSupportedExt.push_back("IV3DLINES");
  m_vSupportedExt.push_back("LNE");
  m_vConverterDesc = "IV3D Hacky Lines";
}

using namespace io;
std::tr1::shared_ptr<Mesh>
LinesGeoConverter::ConvertToMesh(const std::string& rawFilename) {
  MESSAGE("Converting %s...", rawFilename.c_str());
  std::ifstream lines(rawFilename.c_str(), std::ios::in);

  if(!lines) {
    throw DSOpenFailed(rawFilename.c_str(), "open failed", __FILE__, __LINE__);
  }

  uint64_t n_vertices;
  lines >> n_vertices;
  if(!lines || n_vertices == 0) {
    throw DSParseFailed(rawFilename.c_str(), "number of vertices", __FILE__,
                        __LINE__);
  }
  MESSAGE("%llu vertices.", n_vertices);
  VertVec vertices(n_vertices);
  for(uint64_t i=0; i < n_vertices; ++i) {
    FLOATVECTOR3 tmp;
    lines >> tmp[0] >> tmp[1] >> tmp[2];
    vertices[i] = tmp;
  }
  if(!lines) {
    throw DSParseFailed(rawFilename.c_str(), "vertices list short", __FILE__,
                        __LINE__);
  }

  uint64_t n_edges;
  lines >> n_edges;
  if(!lines) {
    throw DSParseFailed("number of edges", __FILE__, __LINE__);
  }
  MESSAGE("%llu edges.", n_edges);
  IndexVec edges(n_edges*2); // an indexVec holds a single elem, not a pair
  for(uint64_t i=0; i < n_edges; ++i) {
    UINTVECTOR2 e;
    lines >> e[0] >> e[1];
    edges[i+0] = e[0]-1;
    edges[i+1] = e[1]-1;
  }
  if(!lines) {
    throw DSParseFailed("error reading edge list", __FILE__, __LINE__);
  }

  uint64_t n_colors;
  lines >> n_colors;
  if(!lines || n_colors == 0) {
    throw DSParseFailed("number of colors", __FILE__, __LINE__);
  }
  MESSAGE("%llu colors.", n_colors);
  ColorVec colors(n_colors);
  FLOATVECTOR3 c;
  for(uint64_t i=0; i < n_colors; ++i) {
    lines >> c[0] >> c[1] >> c[2];
    colors[i] = c;
  }
  if(!lines) {
    throw std::runtime_error("error reading color array");
  }

  uint64_t n_color_indices;
  lines >> n_color_indices;
  if(!lines || n_color_indices == 0) {
    throw DSParseFailed("number of color indices", __FILE__, __LINE__);
  }
  MESSAGE("%llu color indices", n_color_indices);
  IndexVec c_indices(n_color_indices);
  uint32_t cindex;
  for(uint64_t i=0; i < n_color_indices; ++i) {
    lines >> cindex;
    c_indices[i] = cindex-1;
  }
  if(!lines) {
    throw DSParseFailed("short color index list", __FILE__, __LINE__);
  }

  // we're good, except the data are in a different coordinate space.
  // oops!  Subtract 0.5 from X and Y to get it into the right place.
  for(VertVec::iterator v = vertices.begin(); v != vertices.end(); ++v) {
    *v = FLOATVECTOR3((*v)[0]-0.5, (*v)[1]-0.5, (*v)[2]);
  }

  return std::tr1::shared_ptr<Mesh>(new Mesh(
    vertices, NormVec(), TexCoordVec(), colors, edges,
    IndexVec(), IndexVec(), c_indices, false, false,
    "Esra-mesh", Mesh::MT_LINES
  ));
}

}
<commit_msg>Resolve VS2010 warnings.<commit_after>/*
   For more information, please see: http://software.sci.utah.edu

   The MIT License

   Copyright (c) 2012 Interactive Visualization and Data Analysis Group.

   Permission is hereby granted, free of charge, to any person obtaining a
   copy of this software and associated documentation files (the "Software"),
   to deal in the Software without restriction, including without limitation
   the rights to use, copy, modify, merge, publish, distribute, sublicense,
   and/or sell copies of the Software, and to permit persons to whom the
   Software is furnished to do so, subject to the following conditions:

   The above copyright notice and this permission notice shall be included
   in all copies or substantial portions of the Software.

   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
   DEALINGS IN THE SOFTWARE.
*/
#include "StdTuvokDefines.h"
#ifdef _MSC_VER
# include <memory>
#else
# include <tr1/memory>
#endif
#include <fstream>
#include "Basics/Mesh.h"
#include "Controller/Controller.h"
#include "LinesGeoConverter.h"
#include "TuvokIOError.h"

namespace tuvok {

LinesGeoConverter::LinesGeoConverter() {
  m_vSupportedExt.push_back("IV3DLINES");
  m_vSupportedExt.push_back("LNE");
  m_vConverterDesc = "IV3D Hacky Lines";
}

using namespace io;
std::tr1::shared_ptr<Mesh>
LinesGeoConverter::ConvertToMesh(const std::string& rawFilename) {
  MESSAGE("Converting %s...", rawFilename.c_str());
  std::ifstream lines(rawFilename.c_str(), std::ios::in);

  if(!lines) {
    throw DSOpenFailed(rawFilename.c_str(), "open failed", __FILE__, __LINE__);
  }

  uint64_t n_vertices;
  lines >> n_vertices;
  if(!lines || n_vertices == 0) {
    throw DSParseFailed(rawFilename.c_str(), "number of vertices", __FILE__,
                        __LINE__);
  }
  size_t n_vertices_st = static_cast<size_t>(n_vertices);
  MESSAGE("%llu vertices.", n_vertices);
  VertVec vertices(n_vertices_st);
  for(size_t i=0; i < n_vertices_st; ++i) {
    FLOATVECTOR3 tmp;
    lines >> tmp[0] >> tmp[1] >> tmp[2];
    vertices[i] = tmp;
  }
  if(!lines) {
    throw DSParseFailed(rawFilename.c_str(), "vertices list short", __FILE__,
                        __LINE__);
  }

  uint64_t n_edges;
  lines >> n_edges;
  if(!lines) {
    throw DSParseFailed("number of edges", __FILE__, __LINE__);
  }
  MESSAGE("%llu edges.", n_edges);
  size_t n_edges_st = static_cast<size_t>(n_edges);
  IndexVec edges(static_cast<size_t>(n_edges*2)); // an indexVec holds a single elem, not a pair
  for(size_t i=0; i < n_edges_st; ++i) {
    UINTVECTOR2 e;
    lines >> e[0] >> e[1];
    edges[i+0] = e[0]-1;
    edges[i+1] = e[1]-1;
  }
  if(!lines) {
    throw DSParseFailed("error reading edge list", __FILE__, __LINE__);
  }

  uint64_t n_colors;
  lines >> n_colors;
  if(!lines || n_colors == 0) {
    throw DSParseFailed("number of colors", __FILE__, __LINE__);
  }
  MESSAGE("%llu colors.", n_colors);
  size_t n_colors_st = static_cast<size_t>(n_colors);
  ColorVec colors(n_colors_st);
  FLOATVECTOR3 c;
  for(size_t i=0; i < n_colors; ++i) {
    lines >> c[0] >> c[1] >> c[2];
    colors[i] = c;
  }
  if(!lines) {
    throw std::runtime_error("error reading color array");
  }

  uint64_t n_color_indices;
  lines >> n_color_indices;
  if(!lines || n_color_indices == 0) {
    throw DSParseFailed("number of color indices", __FILE__, __LINE__);
  }
  MESSAGE("%llu color indices", n_color_indices);
  size_t n_color_indices_st = static_cast<size_t>(n_color_indices);
  IndexVec c_indices(n_color_indices_st);
  uint32_t cindex;
  for(size_t i=0; i < n_color_indices_st; ++i) {
    lines >> cindex;
    c_indices[i] = cindex-1;
  }
  if(!lines) {
    throw DSParseFailed("short color index list", __FILE__, __LINE__);
  }

  // we're good, except the data are in a different coordinate space.
  // oops!  Subtract 0.5 from X and Y to get it into the right place.
  for(VertVec::iterator v = vertices.begin(); v != vertices.end(); ++v) {
    *v = FLOATVECTOR3((*v)[0]-0.5f, (*v)[1]-0.5f, (*v)[2]);
  }

  return std::tr1::shared_ptr<Mesh>(new Mesh(
    vertices, NormVec(), TexCoordVec(), colors, edges,
    IndexVec(), IndexVec(), c_indices, false, false,
    "Esra-mesh", Mesh::MT_LINES
  ));
}

}
<|endoftext|>


<commit_before>#include <entities/room.hpp>
#include <glm/gtc/noise.hpp>
#include <glm/gtc/random.hpp>
#include <mos/util.hpp>
#include <algorithm.hpp>

Room::Room(mos::Assets &assets, const glm::mat4 &transform) {
  room_.transform = transform;
  size_.x = simplex_int(room_.position(), 3, 6);
  size_.y = simplex_int(room_.position() * .5f, 3, 6);

  const auto entry_pos = mos::position(transform);

  room_type = simplex_int(entry_pos, 0, 3);

  //TODO: Move to own class.
  std::vector<mos::Model> floor_models;
  std::vector<mos::Model> edge_models;
  mos::Model corner_model;
  mos::Model entry_model;

  if (room_type == 2) {
    corner_model = assets.model("room_corner.model");
    entry_model = assets.model("room_entry.model");
    floor_models = {assets.model("room_floor.model")};
    edge_models = {assets.model("room_edge0.model"),
                   assets.model("room_edge1.model"),
                   assets.model("room_edge2.model"),
                   assets.model("room_edge3.model"),
                   assets.model("room_edge4.model")};
  } else if (room_type == 1) {
    corner_model = assets.model("room_corner_metal.model");
    entry_model = assets.model("room_entry_metal.model");
    floor_models = {assets.model("room_floor_metal.model")};
    edge_models = {assets.model("room_edge_metal0.model"),
                   assets.model("room_edge_metal1.model")};
  } else if (room_type == 0) {
    corner_model = assets.model("room_corner_wood.model");
    entry_model = assets.model("room_entry_wood.model");
    floor_models = {assets.model("room_floor_wood.model")};
    edge_models = {assets.model("room_edge_wood0.model"),
                   assets.model("room_edge_wood1.model")};
  }

  // Items
  const std::vector<mos::Model> items{assets.model("plant.model"),
                                      assets.model("table.model"),
                                      assets.model("package.model")};

  //Entry door
  entry_model.transform = glm::rotate(glm::translate(glm::mat4(1.0f), {.5f, .0f, .0f}), 0.0f, {.0f, .0f, 1.f});
  room_.models.push_back(entry_model);

  //Exit door
  entry_model.transform =
      glm::rotate(glm::translate(glm::mat4(1.0f), {size_.x - .5f, .0f, .0f}), 0.0f, {.0f, .0f, 1.f});
  room_.models.push_back(entry_model);

  corner_model.transform =
      glm::rotate(glm::translate(glm::mat4(1.0f), {0.5f, size_.y - 1.0f, .0f}), 0.0f, {.0f, .0f, 1.f});
  room_.models.push_back(corner_model);

  corner_model.transform = glm::rotate(glm::translate(glm::mat4(1.0f), {size_.x - 0.5f, size_.y - 1.0f, .0f}),
                                       -glm::half_pi<float>(),
                                       {.0f, .0f, 1.f});
  room_.models.push_back(corner_model);

  int left = simplex_int(room_.position() * 0.5f, 1, size_.x - 1);
  int right = simplex_int(room_.position(), 1, size_.x - 1);

  for (float x = 1.0f; x < (size_.x - 1.0f); x++) {
    const auto t0 = glm::rotate(glm::translate(glm::mat4(1.0f), {x + .5f, .0f, .0f}),
                                glm::half_pi<float>(),
                                {.0f, .0f, 1.f});
    const auto t1 = glm::rotate(glm::translate(glm::mat4(1.0f), {x + .5f, size_.y - 1.0f, .0f}),
                                -glm::half_pi<float>(),
                                {.0f, .0f, 1.f});

    auto edge_model = edge_models[simplex_int(mos::position(t0), 0, edge_models.size())];
    auto floor_model = floor_models[0];
    if (x != float(left)) {
      edge_model.transform = t0;
      room_.models.push_back(edge_model);
    } else {
      floor_model.transform = t0;
      room_.models.push_back(floor_model);
    }
    if (x != float(right)) {
      edge_model = edge_models[simplex_int(mos::position(t1), 0, edge_models.size())];
      edge_model.transform = t1;
      room_.models.push_back(edge_model);
    } else {
      floor_model.transform = t1;
      room_.models.push_back(floor_model);
    }
    /*

    */

    for (float y = 1; y < (size_.y - 1.f); y++) {

      auto floor_pos = glm::vec3(x + 0.5f, y, 0.0f);
      floor_model.position(floor_pos);
      room_.models.push_back(floor_model);

      if (simplex_bool(entry_pos + floor_pos)) {
        auto item = items[simplex_int(entry_pos + floor_pos, 0, items.size())];
        item.position(floor_pos);
        items_.push_back(item);
      }

      const auto t0 = glm::rotate(glm::translate(glm::mat4(1.0f), {0.5f, y, .0f}), 0.0f, {.0f, .0f, 1.f});
      edge_model = edge_models[simplex_int(mos::position(t0), 0, edge_models.size())];
      edge_model.transform = t0;
      room_.models.push_back(edge_model);

      const auto t1 =
          glm::rotate(glm::translate(glm::mat4(1.0f), {size_.x - 0.5f, y, .0f}), glm::pi<float>(), {.0f, .0f, 1.f});
      edge_model = edge_models[simplex_int(mos::position(t1), 0, edge_models.size())];
      edge_model.transform = t1;
      room_.models.push_back(edge_model);
    }
  }

  box_ = mos::Box::create_from_model(room_);
  box_.extent -= 0.01;

  exits.push_back(
      Door(assets, transform *
          glm::translate(glm::mat4(1.0f), glm::vec3(size_.x, 0.0f, 0.0f))));

  exits.push_back(
      Door(assets, transform *
          glm::translate(glm::mat4(1.0f), glm::vec3((left) + 0.5f, -0.5f, 0.0f))
          * glm::rotate(glm::mat4(1.0f), -glm::half_pi<float>(), glm::vec3(0.0f, 0.0f, 1.0f))));

  exits.push_back(
      Door(assets, transform *
          glm::translate(glm::mat4(1.0f), glm::vec3((right) + 0.5f, float(size_.y) - 0.5f, 0.0f)) *
          glm::rotate(glm::mat4(1.0f), glm::half_pi<float>(), glm::vec3(0.0f, 0.0f, 1.0f))));

}

mos::Model Room::model() {
  auto r = room_;
  r.models.insert(r.end(), items_.begin(), items_.end());
  return r;
}

void Room::print(std::ostream &os) {
  os << "Room, " << "type: " << room_type;
}
void Room::update(const float dt) {

}

<commit_msg>checkpoint.<commit_after>#include <entities/room.hpp>
#include <glm/gtc/noise.hpp>
#include <glm/gtc/random.hpp>
#include <mos/util.hpp>
#include <algorithm.hpp>

Room::Room(mos::Assets &assets, const glm::mat4 &transform) {
  room_.transform = transform;
  size_.x = simplex_int(room_.position(), 3, 6);
  size_.y = simplex_int(room_.position() * .5f, 3, 6);

  const auto entry_pos = mos::position(transform);

  room_type = simplex_int(entry_pos, 0, 3);

  //TODO: Move to own class.
  std::vector<mos::Model> floor_models;
  std::vector<mos::Model> edge_models;
  mos::Model corner_model;
  mos::Model entry_model;

  if (room_type == 2) {
    corner_model = assets.model("room_corner.model");
    entry_model = assets.model("room_entry.model");
    floor_models = {assets.model("room_floor.model")};
    edge_models = {assets.model("room_edge0.model"),
                   assets.model("room_edge1.model"),
                   assets.model("room_edge2.model"),
                   assets.model("room_edge3.model"),
                   assets.model("room_edge4.model")};
  } else if (room_type == 1) {
    corner_model = assets.model("room_corner_metal.model");
    entry_model = assets.model("room_entry_metal.model");
    floor_models = {assets.model("room_floor_metal.model")};
    edge_models = {assets.model("room_edge_metal0.model"),
                   assets.model("room_edge_metal1.model")};
  } else if (room_type == 0) {
    corner_model = assets.model("room_corner_wood.model");
    entry_model = assets.model("room_entry_wood.model");
    floor_models = {assets.model("room_floor_wood.model")};
    edge_models = {assets.model("room_edge_wood0.model"),
                   assets.model("room_edge_wood1.model")};
  }

  // Items
  const std::vector<mos::Model> items{assets.model("plant.model"),
                                      assets.model("table.model"),
                                      assets.model("package.model")};

  //Entry door
  entry_model.transform = glm::rotate(glm::translate(glm::mat4(1.0f), {.5f, .0f, .0f}), 0.0f, {.0f, .0f, 1.f});
  room_.models.push_back(entry_model);

  //Exit door
  entry_model.transform =
      glm::rotate(glm::translate(glm::mat4(1.0f), {size_.x - .5f, .0f, .0f}), 0.0f, {.0f, .0f, 1.f});
  room_.models.push_back(entry_model);

  corner_model.transform =
      glm::rotate(glm::translate(glm::mat4(1.0f), {0.5f, size_.y - 1.0f, .0f}), 0.0f, {.0f, .0f, 1.f});
  room_.models.push_back(corner_model);

  corner_model.transform = glm::rotate(glm::translate(glm::mat4(1.0f), {size_.x - 0.5f, size_.y - 1.0f, .0f}),
                                       -glm::half_pi<float>(),
                                       {.0f, .0f, 1.f});
  room_.models.push_back(corner_model);

  int left = simplex_int(room_.position() * 0.5f, 1, size_.x - 1);
  int right = simplex_int(room_.position(), 1, size_.x - 1);

  for (float x = 1.0f; x < (size_.x - 1.0f); x++) {
    const auto t0 = glm::rotate(glm::translate(glm::mat4(1.0f), {x + .5f, .0f, .0f}),
                                glm::half_pi<float>(),
                                {.0f, .0f, 1.f});
    const auto t1 = glm::rotate(glm::translate(glm::mat4(1.0f), {x + .5f, size_.y - 1.0f, .0f}),
                                -glm::half_pi<float>(),
                                {.0f, .0f, 1.f});

    auto edge_model = edge_models[simplex_int(mos::position(t0), 0, edge_models.size())];
    auto floor_model = floor_models[0];
    if (x != float(left)) {
      edge_model.transform = t0;
      room_.models.push_back(edge_model);
    } else {
      floor_model.transform = t0;
      room_.models.push_back(floor_model);
    }
    if (x != float(right)) {
      edge_model = edge_models[simplex_int(mos::position(t1), 0, edge_models.size())];
      edge_model.transform = t1;
      room_.models.push_back(edge_model);
    } else {
      floor_model.transform = t1;
      room_.models.push_back(floor_model);
    }
    /*

    */

    for (float y = 1; y < (size_.y - 1.f); y++) {

      auto floor_pos = glm::vec3(x + 0.5f, y, 0.0f);
      floor_model.position(floor_pos);
      room_.models.push_back(floor_model);

      if (simplex_bool(entry_pos + floor_pos)) {
        auto item = items[simplex_int(entry_pos + floor_pos, 0, items.size())];
        item.position(floor_pos);
        items_.push_back(item);
      }

      const auto t0 = glm::rotate(glm::translate(glm::mat4(1.0f), {0.5f, y, .0f}), 0.0f, {.0f, .0f, 1.f});
      edge_model = edge_models[simplex_int(mos::position(t0), 0, edge_models.size())];
      edge_model.transform = t0;
      room_.models.push_back(edge_model);

      const auto t1 =
          glm::rotate(glm::translate(glm::mat4(1.0f), {size_.x - 0.5f, y, .0f}), glm::pi<float>(), {.0f, .0f, 1.f});
      edge_model = edge_models[simplex_int(mos::position(t1), 0, edge_models.size())];
      edge_model.transform = t1;
      room_.models.push_back(edge_model);
    }
  }

  box_ = mos::Box::create_from_model(room_);
  box_.extent -= 0.01;

  exits.push_back(
      Door(assets, transform *
          glm::translate(glm::mat4(1.0f), glm::vec3(size_.x, 0.0f, 0.0f))));

  exits.push_back(
      Door(assets, transform *
          glm::translate(glm::mat4(1.0f), glm::vec3((left) + 0.5f, -0.5f, 0.0f))
          * glm::rotate(glm::mat4(1.0f), -glm::half_pi<float>(), glm::vec3(0.0f, 0.0f, 1.0f))));

  exits.push_back(
      Door(assets, transform *
          glm::translate(glm::mat4(1.0f), glm::vec3((right) + 0.5f, float(size_.y) - 0.5f, 0.0f)) *
          glm::rotate(glm::mat4(1.0f), glm::half_pi<float>(), glm::vec3(0.0f, 0.0f, 1.0f))));

  room_.models.insert(room_.end(), items_.begin(), items_.end());
}

mos::Model Room::model() {
  return room_;
}

void Room::print(std::ostream &os) {
  os << "Room, " << "type: " << room_type;
}
void Room::update(const float dt) {

}

<|endoftext|>