<commit_before>/*
* Copyright (C) 2011 Apple Inc. All rights reserved.
* Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB.  If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/

#include "content/browser/PopupMenuWin.h"
#include "content/browser/PlatformEventHandler.h"
#include "third_party/WebKit/Source/platform/geometry/win/IntRectWin.h"
#include "third_party/WebKit/Source/web/WebPagePopupImpl.h"
#include "third_party/WebKit/Source/web/WebViewImpl.h"
#include "third_party/WebKit/Source/web/WebSettingsImpl.h"
#include "third_party/WebKit/Source/web/WebLocalFrameImpl.h"
#include "third_party/WebKit/Source/core/frame/LocalDOMWindow.h"
#include "third_party/WebKit/Source/core/frame/FrameView.h"
#include "third_party/WebKit/Source/core/dom/Document.h"
#include "third_party/WebKit/public/web/WebFrameClient.h"
#include "third_party/WebKit/public/web/WebInputEvent.h"
#include "third_party/WebKit/public/web/WebLocalFrame.h"
#include "third_party/WebKit/public/platform/Platform.h"
#include "skia/ext/bitmap_platform_device_win.h"
#include "cc/trees/LayerTreeHost.h"

using namespace blink;

namespace content {

#define HIGH_BIT_MASK_SHORT 0x8000

#define WM_INIT_MENU (WM_USER + 201)
#define WM_COMMIT    (WM_USER + 202)

// Default Window animation duration in milliseconds
static const int defaultAnimationDuration = 200;
// Maximum height of a popup window
static const int maxPopupHeight = 320;

const int optionSpacingMiddle = 1;
const int popupWindowBorderWidth = 1;
const int smoothScrollAnimationDuration = 5000;

static LPCWSTR kPopupWindowClassName = L"PopupWindowClass";

PopupMenuWin::PopupMenuWin(HWND hWnd, IntPoint offset, WebViewImpl* webViewImpl)
    : m_asynStartCreateWndTimer(this, &PopupMenuWin::asynStartCreateWnd)
{
    m_hPopup = NULL;
    m_popupImpl = nullptr;
    m_needsCommit = true;
    m_hasResize = true;
    m_needResize = true;
    m_initialize = false;
    m_isCommiting = false;
    m_lastFrameTimeMonotonic = 0;
    m_memoryCanvas = nullptr;
    m_layerTreeHost = nullptr;
    m_webViewImpl = webViewImpl;
    m_hParentWnd = hWnd;
    m_rect.setWidth(1);
    m_rect.setHeight(1);
    m_offset.setX(offset.x());
    m_offset.setY(offset.y());
}

PopupMenuWin::~PopupMenuWin()
{
    if (m_memoryCanvas)
        delete m_memoryCanvas;
    m_memoryCanvas = nullptr;

    if (m_layerTreeHost)
        delete m_layerTreeHost;
    m_layerTreeHost = nullptr;
}

static void destroyWindowAsyn(HWND hWnd)
{
    ::DestroyWindow(hWnd);
}

void PopupMenuWin::closeWidgetSoon()
{
    m_layerTreeHost->applyActions(false);
    m_initialize = false;
    SetWindowLongPtr(m_hPopup, 0, 0);
    blink::Platform::current()->currentThread()->postTask(FROM_HERE, WTF::bind(&destroyWindowAsyn, m_hPopup));
    //delete this;
}

void PopupMenuWin::registerClass()
{
    static bool haveRegisteredWindowClass = false;
    if (haveRegisteredWindowClass)
        return;

    WNDCLASSEX wcex;
    wcex.cbSize = sizeof(WNDCLASSEX);
    wcex.hIconSm = 0;
    wcex.style = CS_DROPSHADOW;

    wcex.lpfnWndProc = PopupMenuWndProc;
    wcex.cbClsExtra = 0;
    wcex.cbWndExtra = sizeof(PopupMenuWin*); // For the PopupMenu pointer
    wcex.hInstance = NULL;
    wcex.hIcon = 0;
    wcex.hCursor = LoadCursor(0, IDC_ARROW);
    wcex.hbrBackground = 0;
    wcex.lpszMenuName = 0;
    wcex.lpszClassName = kPopupWindowClassName;

    haveRegisteredWindowClass = true;

    RegisterClassEx(&wcex);
}

LRESULT CALLBACK PopupMenuWin::PopupMenuWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    PopupMenuWin* popup = nullptr;
    if (popup = reinterpret_cast<PopupMenuWin*>(::GetWindowLongPtr(hWnd, 0)))
        return popup->wndProc(hWnd, message, wParam, lParam);

    if (message == WM_CREATE) {
        LPCREATESTRUCT createStruct = reinterpret_cast<LPCREATESTRUCT>(lParam);
        popup = (PopupMenuWin*)createStruct->lpCreateParams;
        // Associate the PopupMenu with the window.
        SetWindowLongPtr(hWnd, 0, reinterpret_cast<LONG_PTR>(popup));
        return 0;
    }

    return ::DefWindowProc(hWnd, message, wParam, lParam);
}

LRESULT PopupMenuWin::wndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    LRESULT lResult = 0;

    switch (message) {
    case WM_MOUSEMOVE:
    case WM_LBUTTONDOWN:
    case WM_LBUTTONUP: {
        if (!m_initialize)
            break;
        BOOL bHandle = FALSE;
        m_platformEventHandler->fireMouseEvent(hWnd, message, wParam, lParam, &bHandle);
        if (bHandle)
            return 0;
        break;
    }
    case WM_MOUSEWHEEL: {
        break;
    }

    case WM_SYSKEYDOWN:
    case WM_KEYDOWN: {
        if (!m_initialize)
            break;
        unsigned int virtualKeyCode = wParam;
        WebKeyboardEvent keyEvent = PlatformEventHandler::buildKeyboardEvent(WebInputEvent::RawKeyDown, message, wParam, lParam);

        bool handled = m_webViewImpl->handleInputEvent(keyEvent);
        if (handled)
            return 0;
        break;
    }
    case WM_CHAR: {
        lResult = 0;
        switch (wParam) {
        case 0x0D:   // Enter/Return
            //m_popupImpl->close();
//             index = focusedIndex();
//             ASSERT(index >= 0);
//             client()->valueChanged(index);
            break;
        case 0x1B:   // Escape
            //m_popupImpl->close();
            break;
        case 0x09:   // TAB
        case 0x08:   // Backspace
        case 0x0A:   // Linefeed
        default:     // Character
            lResult = 1;
            break;
        }
        break;
    }

    case WM_PAINT: {
        PAINTSTRUCT paintInfo;
        ::BeginPaint(popupHandle(), &paintInfo);
        paint(paintInfo.hdc, paintInfo.rcPaint);
        ::EndPaint(popupHandle(), &paintInfo);
        lResult = 0;
        break;
    }
    case WM_PRINTCLIENT:
        //paint(clientRect(), (HDC)wParam);
        break;
    case WM_GETOBJECT:
        //onGetObject(wParam, lParam, lResult);
        break;

    case WM_TIMER:
        beginMainFrame();
        break;
    case WM_KILLFOCUS:
        ::ShowWindow(m_hPopup, SW_HIDE);
        break;
    case WM_INIT_MENU:
        initialize();
        break;
    case WM_COMMIT:
        beginMainFrame();
        break;
    case WM_MOUSEACTIVATE: // 
        lResult = MA_NOACTIVATE;
        break;
    default:
        lResult = ::DefWindowProc(hWnd, message, wParam, lParam);
    }

    return lResult;
}

void PopupMenuWin::beginMainFrame()
{
    m_isCommiting = false;
    if (!m_needsCommit || !m_initialize)
        return;
    m_needsCommit = false;

    blink::WebPagePopup* popup = m_popupImpl;

    updataSize();

    double lastFrameTimeMonotonic = WTF::currentTime();
    WebBeginFrameArgs frameTime(m_lastFrameTimeMonotonic, 0, lastFrameTimeMonotonic - m_lastFrameTimeMonotonic);
    popup->beginFrame(frameTime);
    popup->layout();

    if (0)
        m_layerTreeHost->showDebug();

    m_layerTreeHost->recordDraw();

    m_layerTreeHost->preDrawFrame();
    updataPaint();
    m_layerTreeHost->postDrawFrame();
}

void PopupMenuWin::updataSize()
{
    if (!m_needResize)
        return;
    m_needResize = false;

    blink::WebPagePopup* popup = m_popupImpl;

    bool needsCommit = m_needsCommit;
    blink::IntSize size(m_rect.width(), m_rect.height());
    if (m_layerTreeHost)
        m_layerTreeHost->setViewportSize(size);
    popup->resize(size);
    m_needsCommit = needsCommit;

    POINT pos = { m_rect.x() + m_offset.x(), m_rect.y() + m_offset.y() };
    ::ClientToScreen(m_hParentWnd, &pos);

    ::MoveWindow(m_hPopup, pos.x, pos.y, m_rect.width(), m_rect.height(), false);
}

void PopupMenuWin::show(WebNavigationPolicy)
{
    m_needResize = true;
    m_hasResize = true;
    m_needsCommit = true;

    if (!m_isCommiting && m_hPopup) {
        m_isCommiting = true;
        ::PostMessage(m_hPopup, WM_COMMIT, 0, 0);
    }
}

void PopupMenuWin::paint(HDC hdc, RECT rcPaint)
{
    if (!m_memoryCanvas)
        return;
    skia::DrawToNativeContext(m_memoryCanvas, hdc, rcPaint.left, rcPaint.top, &rcPaint);
}

void PopupMenuWin::updataPaint()
{
    if (!m_initialize)
        return;

    if (!m_memoryCanvas || m_hasResize) {
        m_hasResize = false;

        if (m_memoryCanvas)
            delete m_memoryCanvas;
        m_memoryCanvas = skia::CreatePlatformCanvas(m_rect.width(), m_rect.height(), !false);
    }

    IntRect clip(0, 0, m_rect.width(), m_rect.height());

    HDC hMemoryDC = skia::BeginPlatformPaint(m_memoryCanvas);
    m_memoryCanvas->save();

    SkPaint paint;
    paint.setAntiAlias(true);
    m_memoryCanvas->drawPaint(paint);
    m_layerTreeHost->drawToCanvas(m_memoryCanvas, clip);
    m_memoryCanvas->restore();
    skia::EndPlatformPaint(m_memoryCanvas);
}

void PopupMenuWin::asynStartCreateWnd(blink::Timer<PopupMenuWin>*)
{
    registerClass();

    DWORD exStyle = WS_EX_LTRREADING | WS_EX_TOOLWINDOW;
    m_hPopup = ::CreateWindowExW(exStyle, kPopupWindowClassName, L"MbPopupMenu",
        WS_POPUP, 0, 0, 2, 2, /*NULL*/m_hParentWnd, 0, NULL, this); // ָ
    //::ShowWindow(m_hPopup, SW_SHOW);
    //::UpdateWindow(m_hPopup);
    //::SetTimer(m_hPopup, 1, 10, nullptr);
    ::SetWindowPos(m_hPopup, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW /*| SWP_NOACTIVATE*/); // 
    ::SetFocus(m_hPopup);
    ::SetCapture(m_hPopup);
}

WebWidget* PopupMenuWin::createWnd()
{
    m_asynStartCreateWndTimer.startOneShot(0.0, FROM_HERE);
    initialize();
    return m_popupImpl;
}

void PopupMenuWin::initialize()
{
    if (m_initialize)
        return;
    m_initialize = true;

    m_layerTreeHost = new cc::LayerTreeHost(this, nullptr);
    m_popupImpl = WebPagePopup::create(this);
    m_platformEventHandler = new PlatformEventHandler(m_popupImpl, nullptr);
    m_layerTreeHost->setWebGestureCurveTarget(m_webViewImpl);
    m_popupImpl->setFocus(true);
}

WebWidget* PopupMenuWin::create(HWND hWnd, blink::IntPoint offset, WebViewImpl* webViewImpl, WebPopupType type, PopupMenuWin** result)
{
    PopupMenuWin* self = new PopupMenuWin(hWnd, offset, webViewImpl);
    if (result)
        *result = self;
    return self->createWnd();
}

void PopupMenuWin::didInvalidateRect(const blink::WebRect& r)
{
    ::InvalidateRect(m_hPopup, NULL, TRUE);
    m_needsCommit = true;
    if (!m_isCommiting && m_hPopup) {
        m_isCommiting = true;
        ::PostMessage(m_hPopup, WM_COMMIT, 0, 0);
    }
}

void PopupMenuWin::didAutoResize(const WebSize& newSize)
{
    didUpdateLayoutSize(newSize);
}

void PopupMenuWin::didUpdateLayoutSize(const WebSize& newSize)
{
    m_needResize = true;
    m_hasResize = true;
    m_needsCommit = true;
    if (!m_isCommiting && m_hPopup) {
        m_isCommiting = true;
        ::PostMessage(m_hPopup, WM_COMMIT, 0, 0);
    }
}

static void trimWidthHeight(blink::IntRect& rect)
{
    if (0 == rect.width())
        rect.setWidth(1);

    if (0 == rect.height())
        rect.setHeight(1);
}

void PopupMenuWin::setWindowRect(const WebRect& r)
{
    m_rect = r;
    trimWidthHeight(m_rect);

    m_needResize = true;
    m_hasResize = true;
    m_needsCommit = true;
    if (!m_isCommiting && m_hPopup) {
        m_isCommiting = true;
        ::PostMessage(m_hPopup, WM_COMMIT, 0, 0);
    }
}

void PopupMenuWin::scheduleAnimation()
{
    m_needsCommit = true;
    if (!m_isCommiting && m_hPopup) {
        m_isCommiting = true;
        ::PostMessage(m_hPopup, WM_COMMIT, 0, 0);
    }
}

WebLayerTreeView* PopupMenuWin::layerTreeView()
{
    return m_layerTreeHost;
}

bool PopupMenuWin::initSetting()
{
    return true;
}

DEFINE_TRACE(PopupMenuWin)
{
}

} // content<commit_msg>* 修复下拉框黑屏的bug。原因是新渲染架构下，没有调用m_layerTreeHost->beginRecordActions等 * 修复下拉框退出时的断言错误。原因是退出时要清理actions<commit_after>/*
* Copyright (C) 2011 Apple Inc. All rights reserved.
* Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB.  If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/

#include "content/browser/PopupMenuWin.h"
#include "content/browser/PlatformEventHandler.h"
#include "third_party/WebKit/Source/platform/geometry/win/IntRectWin.h"
#include "third_party/WebKit/Source/web/WebPagePopupImpl.h"
#include "third_party/WebKit/Source/web/WebViewImpl.h"
#include "third_party/WebKit/Source/web/WebSettingsImpl.h"
#include "third_party/WebKit/Source/web/WebLocalFrameImpl.h"
#include "third_party/WebKit/Source/core/frame/LocalDOMWindow.h"
#include "third_party/WebKit/Source/core/frame/FrameView.h"
#include "third_party/WebKit/Source/core/dom/Document.h"
#include "third_party/WebKit/public/web/WebFrameClient.h"
#include "third_party/WebKit/public/web/WebInputEvent.h"
#include "third_party/WebKit/public/web/WebLocalFrame.h"
#include "third_party/WebKit/public/platform/Platform.h"
#include "skia/ext/bitmap_platform_device_win.h"
#include "cc/trees/LayerTreeHost.h"

using namespace blink;

namespace content {

#define HIGH_BIT_MASK_SHORT 0x8000

#define WM_INIT_MENU (WM_USER + 201)
#define WM_COMMIT    (WM_USER + 202)

// Default Window animation duration in milliseconds
static const int defaultAnimationDuration = 200;
// Maximum height of a popup window
static const int maxPopupHeight = 320;

const int optionSpacingMiddle = 1;
const int popupWindowBorderWidth = 1;
const int smoothScrollAnimationDuration = 5000;

static LPCWSTR kPopupWindowClassName = L"PopupWindowClass";

PopupMenuWin::PopupMenuWin(HWND hWnd, IntPoint offset, WebViewImpl* webViewImpl)
    : m_asynStartCreateWndTimer(this, &PopupMenuWin::asynStartCreateWnd)
{
    m_hPopup = NULL;
    m_popupImpl = nullptr;
    m_needsCommit = true;
    m_hasResize = true;
    m_needResize = true;
    m_initialize = false;
    m_isCommiting = false;
    m_lastFrameTimeMonotonic = 0;
    m_memoryCanvas = nullptr;
    m_layerTreeHost = nullptr;
    m_webViewImpl = webViewImpl;
    m_hParentWnd = hWnd;
    m_rect.setWidth(1);
    m_rect.setHeight(1);
    m_offset.setX(offset.x());
    m_offset.setY(offset.y());
}

PopupMenuWin::~PopupMenuWin()
{
    if (m_memoryCanvas)
        delete m_memoryCanvas;
    m_memoryCanvas = nullptr;

    if (m_layerTreeHost) {
        m_layerTreeHost->applyActions(true);
        delete m_layerTreeHost;
    }
    m_layerTreeHost = nullptr;
}

static void destroyWindowAsyn(HWND hWnd)
{
    ::DestroyWindow(hWnd);
}

void PopupMenuWin::closeWidgetSoon()
{
    m_layerTreeHost->applyActions(false);
    m_initialize = false;
    SetWindowLongPtr(m_hPopup, 0, 0);
    blink::Platform::current()->currentThread()->postTask(FROM_HERE, WTF::bind(&destroyWindowAsyn, m_hPopup));
    //delete this;
}

void PopupMenuWin::registerClass()
{
    static bool haveRegisteredWindowClass = false;
    if (haveRegisteredWindowClass)
        return;

    WNDCLASSEX wcex;
    wcex.cbSize = sizeof(WNDCLASSEX);
    wcex.hIconSm = 0;
    wcex.style = CS_DROPSHADOW;

    wcex.lpfnWndProc = PopupMenuWndProc;
    wcex.cbClsExtra = 0;
    wcex.cbWndExtra = sizeof(PopupMenuWin*); // For the PopupMenu pointer
    wcex.hInstance = NULL;
    wcex.hIcon = 0;
    wcex.hCursor = LoadCursor(0, IDC_ARROW);
    wcex.hbrBackground = 0;
    wcex.lpszMenuName = 0;
    wcex.lpszClassName = kPopupWindowClassName;

    haveRegisteredWindowClass = true;

    RegisterClassEx(&wcex);
}

LRESULT CALLBACK PopupMenuWin::PopupMenuWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    PopupMenuWin* popup = nullptr;
    if (popup = reinterpret_cast<PopupMenuWin*>(::GetWindowLongPtr(hWnd, 0)))
        return popup->wndProc(hWnd, message, wParam, lParam);

    if (message == WM_CREATE) {
        LPCREATESTRUCT createStruct = reinterpret_cast<LPCREATESTRUCT>(lParam);
        popup = (PopupMenuWin*)createStruct->lpCreateParams;
        // Associate the PopupMenu with the window.
        SetWindowLongPtr(hWnd, 0, reinterpret_cast<LONG_PTR>(popup));
        return 0;
    }

    return ::DefWindowProc(hWnd, message, wParam, lParam);
}

LRESULT PopupMenuWin::wndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    LRESULT lResult = 0;

    switch (message) {
    case WM_MOUSEMOVE:
    case WM_LBUTTONDOWN:
    case WM_LBUTTONUP: {
        if (!m_initialize)
            break;
        BOOL bHandle = FALSE;
        m_platformEventHandler->fireMouseEvent(hWnd, message, wParam, lParam, &bHandle);
        if (bHandle)
            return 0;
        break;
    }
    case WM_MOUSEWHEEL: {
        break;
    }

    case WM_SYSKEYDOWN:
    case WM_KEYDOWN: {
        if (!m_initialize)
            break;
        unsigned int virtualKeyCode = wParam;
        WebKeyboardEvent keyEvent = PlatformEventHandler::buildKeyboardEvent(WebInputEvent::RawKeyDown, message, wParam, lParam);

        bool handled = m_webViewImpl->handleInputEvent(keyEvent);
        if (handled)
            return 0;
        break;
    }
    case WM_CHAR: {
        lResult = 0;
        switch (wParam) {
        case 0x0D:   // Enter/Return
            //m_popupImpl->close();
//             index = focusedIndex();
//             ASSERT(index >= 0);
//             client()->valueChanged(index);
            break;
        case 0x1B:   // Escape
            //m_popupImpl->close();
            break;
        case 0x09:   // TAB
        case 0x08:   // Backspace
        case 0x0A:   // Linefeed
        default:     // Character
            lResult = 1;
            break;
        }
        break;
    }

    case WM_PAINT: {
        PAINTSTRUCT paintInfo;
        ::BeginPaint(popupHandle(), &paintInfo);
        paint(paintInfo.hdc, paintInfo.rcPaint);
        ::EndPaint(popupHandle(), &paintInfo);
        lResult = 0;
        break;
    }
    case WM_PRINTCLIENT:
        //paint(clientRect(), (HDC)wParam);
        break;
    case WM_GETOBJECT:
        //onGetObject(wParam, lParam, lResult);
        break;

    case WM_TIMER:
        beginMainFrame();
        break;
    case WM_KILLFOCUS:
        ::ShowWindow(m_hPopup, SW_HIDE);
        break;
    case WM_INIT_MENU:
        initialize();
        break;
    case WM_COMMIT:
        beginMainFrame();
        break;
    case WM_MOUSEACTIVATE: // 
        lResult = MA_NOACTIVATE;
        break;
    default:
        lResult = ::DefWindowProc(hWnd, message, wParam, lParam);
    }

    return lResult;
}

void PopupMenuWin::beginMainFrame()
{
    m_isCommiting = false;
    if (!m_needsCommit || !m_initialize)
        return;
    m_needsCommit = false;

    blink::WebPagePopup* popup = m_popupImpl;

    updataSize();

    m_layerTreeHost->beginRecordActions(true);

    double lastFrameTimeMonotonic = WTF::currentTime();
    WebBeginFrameArgs frameTime(m_lastFrameTimeMonotonic, 0, lastFrameTimeMonotonic - m_lastFrameTimeMonotonic);
    popup->beginFrame(frameTime);
    popup->layout();

    if (0)
        m_layerTreeHost->showDebug();

    m_layerTreeHost->recordDraw();

    m_layerTreeHost->preDrawFrame();
    updataPaint();
    m_layerTreeHost->postDrawFrame();

    m_layerTreeHost->endRecordActions();
}

void PopupMenuWin::updataSize()
{
    if (!m_needResize)
        return;
    m_needResize = false;

    blink::WebPagePopup* popup = m_popupImpl;

    bool needsCommit = m_needsCommit;
    blink::IntSize size(m_rect.width(), m_rect.height());
    if (m_layerTreeHost)
        m_layerTreeHost->setViewportSize(size);
    popup->resize(size);
    m_needsCommit = needsCommit;

    POINT pos = { m_rect.x() + m_offset.x(), m_rect.y() + m_offset.y() };
    ::ClientToScreen(m_hParentWnd, &pos);

    ::MoveWindow(m_hPopup, pos.x, pos.y, m_rect.width(), m_rect.height(), false);
}

void PopupMenuWin::show(WebNavigationPolicy)
{
    m_needResize = true;
    m_hasResize = true;
    m_needsCommit = true;

    if (!m_isCommiting && m_hPopup) {
        m_isCommiting = true;
        ::PostMessage(m_hPopup, WM_COMMIT, 0, 0);
    }
}

void PopupMenuWin::paint(HDC hdc, RECT rcPaint)
{
    if (!m_memoryCanvas)
        return;
    skia::DrawToNativeContext(m_memoryCanvas, hdc, rcPaint.left, rcPaint.top, &rcPaint);
}

void PopupMenuWin::updataPaint()
{
    if (!m_initialize)
        return;

    if (!m_memoryCanvas || m_hasResize) {
        m_hasResize = false;

        if (m_memoryCanvas)
            delete m_memoryCanvas;
        m_memoryCanvas = skia::CreatePlatformCanvas(m_rect.width(), m_rect.height(), !false);
    }

    IntRect clip(0, 0, m_rect.width(), m_rect.height());

    HDC hMemoryDC = skia::BeginPlatformPaint(m_memoryCanvas);
    m_memoryCanvas->save();

    SkPaint paint;
    paint.setAntiAlias(true);
    m_memoryCanvas->drawPaint(paint);
    m_layerTreeHost->drawToCanvas(m_memoryCanvas, clip);
    m_memoryCanvas->restore();
    skia::EndPlatformPaint(m_memoryCanvas);
}

void PopupMenuWin::asynStartCreateWnd(blink::Timer<PopupMenuWin>*)
{
    registerClass();

    DWORD exStyle = WS_EX_LTRREADING | WS_EX_TOOLWINDOW;
    m_hPopup = ::CreateWindowExW(exStyle, kPopupWindowClassName, L"MbPopupMenu",
        WS_POPUP, 0, 0, 2, 2, /*NULL*/m_hParentWnd, 0, NULL, this); // ָ
    //::ShowWindow(m_hPopup, SW_SHOW);
    //::UpdateWindow(m_hPopup);
    //::SetTimer(m_hPopup, 1, 10, nullptr);
    ::SetWindowPos(m_hPopup, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW /*| SWP_NOACTIVATE*/); // 
    ::SetFocus(m_hPopup);
    ::SetCapture(m_hPopup);
}

WebWidget* PopupMenuWin::createWnd()
{
    m_asynStartCreateWndTimer.startOneShot(0.0, FROM_HERE);
    initialize();
    return m_popupImpl;
}

void PopupMenuWin::initialize()
{
    if (m_initialize)
        return;
    m_initialize = true;

    m_layerTreeHost = new cc::LayerTreeHost(this, nullptr);
    m_popupImpl = WebPagePopup::create(this);
    m_platformEventHandler = new PlatformEventHandler(m_popupImpl, nullptr);
    m_layerTreeHost->setWebGestureCurveTarget(m_webViewImpl);
    m_popupImpl->setFocus(true);
}

WebWidget* PopupMenuWin::create(HWND hWnd, blink::IntPoint offset, WebViewImpl* webViewImpl, WebPopupType type, PopupMenuWin** result)
{
    PopupMenuWin* self = new PopupMenuWin(hWnd, offset, webViewImpl);
    if (result)
        *result = self;
    return self->createWnd();
}

void PopupMenuWin::didInvalidateRect(const blink::WebRect& r)
{
    ::InvalidateRect(m_hPopup, NULL, TRUE);
    m_needsCommit = true;
    if (!m_isCommiting && m_hPopup) {
        m_isCommiting = true;
        ::PostMessage(m_hPopup, WM_COMMIT, 0, 0);
    }
}

void PopupMenuWin::didAutoResize(const WebSize& newSize)
{
    didUpdateLayoutSize(newSize);
}

void PopupMenuWin::didUpdateLayoutSize(const WebSize& newSize)
{
    m_needResize = true;
    m_hasResize = true;
    m_needsCommit = true;
    if (!m_isCommiting && m_hPopup) {
        m_isCommiting = true;
        ::PostMessage(m_hPopup, WM_COMMIT, 0, 0);
    }
}

static void trimWidthHeight(blink::IntRect& rect)
{
    if (0 == rect.width())
        rect.setWidth(1);

    if (0 == rect.height())
        rect.setHeight(1);
}

void PopupMenuWin::setWindowRect(const WebRect& r)
{
    m_rect = r;
    trimWidthHeight(m_rect);

    m_needResize = true;
    m_hasResize = true;
    m_needsCommit = true;
    if (!m_isCommiting && m_hPopup) {
        m_isCommiting = true;
        ::PostMessage(m_hPopup, WM_COMMIT, 0, 0);
    }
}

void PopupMenuWin::scheduleAnimation()
{
    m_needsCommit = true;
    if (!m_isCommiting && m_hPopup) {
        m_isCommiting = true;
        ::PostMessage(m_hPopup, WM_COMMIT, 0, 0);
    }
}

WebLayerTreeView* PopupMenuWin::layerTreeView()
{
    return m_layerTreeHost;
}

bool PopupMenuWin::initSetting()
{
    return true;
}

DEFINE_TRACE(PopupMenuWin)
{
}

} // content<|endoftext|>


<commit_before>/*******************************************************
 * Copyright (c) 2014, ArrayFire
 * All rights reserved.
 *
 * This file is distributed under 3-clause BSD license.
 * The complete license agreement can be obtained at:
 * http://arrayfire.com/licenses/BSD-3-Clause
 ********************************************************/

#include <af/exception.h>
#include <err_common.hpp>
#include <type_util.hpp>
#include <string>
#include <sstream>
#include <cstring>
#include <cstdio>
#include <algorithm>

#if defined(WITH_GRAPHICS) && !defined(AF_UNIFIED)
#include <graphics_common.hpp>
#endif

using std::string;
using std::stringstream;

AfError::AfError(const char * const funcName,
                 const int line,
                 const char * const message, af_err err)
    : logic_error   (message),
      functionName  (funcName),
      lineNumber(line),
      error(err)
{}

AfError::AfError(string funcName,
                 const int line,
                 string message, af_err err)
    : logic_error   (message),
      functionName  (funcName),
      lineNumber(line),
      error(err)
{}

const string&
AfError::getFunctionName() const
{
    return functionName;
}

int
AfError::getLine() const
{
    return lineNumber;
}

af_err
AfError::getError() const
{
    return error;
}

AfError::~AfError() throw() {}

TypeError::TypeError(const char * const  funcName,
                     const int line,
                     const int index, const af_dtype type)
    : AfError (funcName, line, "Invalid data type", AF_ERR_TYPE),
      argIndex(index),
      errTypeName(getName(type))
{}

const string& TypeError::getTypeName() const
{
    return errTypeName;
}

int TypeError::getArgIndex() const
{
    return argIndex;
}

ArgumentError::ArgumentError(const char * const  funcName,
                             const int line,
                             const int index,
                             const char * const  expectString)
    : AfError(funcName, line, "Invalid argument", AF_ERR_ARG),
      argIndex(index),
      expected(expectString)
{

}

const string& ArgumentError::getExpectedCondition() const
{
    return expected;
}

int ArgumentError::getArgIndex() const
{
    return argIndex;
}

SupportError::SupportError(const char * const funcName,
                           const int line,
                           const char * const back)
    : AfError(funcName, line, "Unsupported Error", AF_ERR_NOT_SUPPORTED),
      backend(back)
{}

const string& SupportError::getBackendName() const
{
    return backend;
}

DimensionError::DimensionError(const char * const  funcName,
                             const int line,
                             const int index,
                             const char * const  expectString)
    : AfError(funcName, line, "Invalid size", AF_ERR_SIZE),
      argIndex(index),
      expected(expectString)
{

}

const string& DimensionError::getExpectedCondition() const
{
    return expected;
}

int DimensionError::getArgIndex() const
{
    return argIndex;
}

static const int MAX_ERR_SIZE = 1024;
static std::string global_err_string;

void
print_error(const stringstream &msg)
{
    const char* perr = getenv("AF_PRINT_ERRORS");
    if(perr != nullptr) {
        if(std::strncmp(perr, "0", 1) != 0)
            fprintf(stderr, "%s\n", msg.str().c_str());
    }
    global_err_string = msg.str();
}

void af_get_last_error(char **str, dim_t *len)
{
    *len = std::min(MAX_ERR_SIZE, (int)global_err_string.size());

    if (*len == 0) {
        *str = NULL;
    }

    *str = new char[*len + 1];
    memcpy(*str, global_err_string.c_str(), *len * sizeof(char));

    (*str)[*len] = '\0';
    global_err_string = std::string("");
}

const char *af_err_to_string(const af_err err)
{
    switch (err) {
    case AF_SUCCESS:            return "Success";
    case AF_ERR_INTERNAL:       return "Internal error";
    case AF_ERR_NO_MEM:         return "Device out of memory";
    case AF_ERR_DRIVER:         return "Driver not available or incompatible";
    case AF_ERR_RUNTIME:        return "Runtime error ";
    case AF_ERR_INVALID_ARRAY:  return "Invalid array";
    case AF_ERR_ARG:            return "Invalid input argument";
    case AF_ERR_SIZE:           return "Invalid input size";
    case AF_ERR_DIFF_TYPE:      return "Input types are not the same";
    case AF_ERR_NOT_SUPPORTED:  return "Function not supported";
    case AF_ERR_NOT_CONFIGURED: return "Function not configured to build";
    case AF_ERR_TYPE:           return "Function does not support this data type";
    case AF_ERR_NO_DBL:         return "Double precision not supported for this device";
    case AF_ERR_LOAD_LIB:       return "Failed to load dynamic library";
    case AF_ERR_LOAD_SYM:       return "Failed to load symbol";
    case AF_ERR_UNKNOWN:
    default:
        return "Unknown error";
    }
}

af_err processException()
{
    stringstream    ss;
    af_err          err= AF_ERR_INTERNAL;

    try {
        throw;
    } catch (const DimensionError &ex) {
        ss << "In function " << ex.getFunctionName()
           << "(" << ex.getLine() << "):\n"
           << "Invalid dimension for argument " << ex.getArgIndex() << "\n"
           << "Expected: " << ex.getExpectedCondition() << "\n";

        print_error(ss);
        err = AF_ERR_SIZE;
    } catch (const ArgumentError &ex) {
        ss << "In function " << ex.getFunctionName()
           << "(" << ex.getLine() << "):\n"
           << "Invalid argument at index " << ex.getArgIndex() << "\n"
           << "Expected: " << ex.getExpectedCondition() << "\n";

        print_error(ss);
        err = AF_ERR_ARG;
    } catch (const SupportError &ex) {
        ss << ex.getFunctionName()
           << " not supported for " << ex.getBackendName()
           << " backend\n";

        print_error(ss);
        err = AF_ERR_NOT_SUPPORTED;
    } catch (const TypeError &ex) {
        ss << "In function " << ex.getFunctionName()
           << "(" << ex.getLine() << "):\n"
           << "Invalid type for argument " << ex.getArgIndex() << "\n";

        print_error(ss);
        err = AF_ERR_TYPE;
    } catch (const AfError &ex) {
        ss << "Error in " << ex.getFunctionName()
           << "(" << ex.getLine() << "):\n"
           << ex.what() << "\n";

        print_error(ss);
        err = ex.getError();
#if defined(WITH_GRAPHICS) && !defined(AF_UNIFIED)
    } catch (const fg::Error &ex) {
        ss << ex << "\n";
        print_error(ss);
        err = AF_ERR_INTERNAL;
#endif
    } catch (...) {
        print_error(ss);
        err = AF_ERR_UNKNOWN;
    }

    return err;
}
<commit_msg>Added documentation link when library fails to load in unified<commit_after>/*******************************************************
 * Copyright (c) 2014, ArrayFire
 * All rights reserved.
 *
 * This file is distributed under 3-clause BSD license.
 * The complete license agreement can be obtained at:
 * http://arrayfire.com/licenses/BSD-3-Clause
 ********************************************************/

#include <af/exception.h>
#include <err_common.hpp>
#include <type_util.hpp>
#include <string>
#include <sstream>
#include <cstring>
#include <cstdio>
#include <algorithm>

#if defined(WITH_GRAPHICS) && !defined(AF_UNIFIED)
#include <graphics_common.hpp>
#endif

using std::string;
using std::stringstream;

AfError::AfError(const char * const funcName,
                 const int line,
                 const char * const message, af_err err)
    : logic_error   (message),
      functionName  (funcName),
      lineNumber(line),
      error(err)
{}

AfError::AfError(string funcName,
                 const int line,
                 string message, af_err err)
    : logic_error   (message),
      functionName  (funcName),
      lineNumber(line),
      error(err)
{}

const string&
AfError::getFunctionName() const
{
    return functionName;
}

int
AfError::getLine() const
{
    return lineNumber;
}

af_err
AfError::getError() const
{
    return error;
}

AfError::~AfError() throw() {}

TypeError::TypeError(const char * const  funcName,
                     const int line,
                     const int index, const af_dtype type)
    : AfError (funcName, line, "Invalid data type", AF_ERR_TYPE),
      argIndex(index),
      errTypeName(getName(type))
{}

const string& TypeError::getTypeName() const
{
    return errTypeName;
}

int TypeError::getArgIndex() const
{
    return argIndex;
}

ArgumentError::ArgumentError(const char * const  funcName,
                             const int line,
                             const int index,
                             const char * const  expectString)
    : AfError(funcName, line, "Invalid argument", AF_ERR_ARG),
      argIndex(index),
      expected(expectString)
{

}

const string& ArgumentError::getExpectedCondition() const
{
    return expected;
}

int ArgumentError::getArgIndex() const
{
    return argIndex;
}

SupportError::SupportError(const char * const funcName,
                           const int line,
                           const char * const back)
    : AfError(funcName, line, "Unsupported Error", AF_ERR_NOT_SUPPORTED),
      backend(back)
{}

const string& SupportError::getBackendName() const
{
    return backend;
}

DimensionError::DimensionError(const char * const  funcName,
                             const int line,
                             const int index,
                             const char * const  expectString)
    : AfError(funcName, line, "Invalid size", AF_ERR_SIZE),
      argIndex(index),
      expected(expectString)
{

}

const string& DimensionError::getExpectedCondition() const
{
    return expected;
}

int DimensionError::getArgIndex() const
{
    return argIndex;
}

static const int MAX_ERR_SIZE = 1024;
static std::string global_err_string;

void
print_error(const stringstream &msg)
{
    const char* perr = getenv("AF_PRINT_ERRORS");
    if(perr != nullptr) {
        if(std::strncmp(perr, "0", 1) != 0)
            fprintf(stderr, "%s\n", msg.str().c_str());
    }
    global_err_string = msg.str();
}

void af_get_last_error(char **str, dim_t *len)
{
    *len = std::min(MAX_ERR_SIZE, (int)global_err_string.size());

    if (*len == 0) {
        *str = NULL;
    }

    *str = new char[*len + 1];
    memcpy(*str, global_err_string.c_str(), *len * sizeof(char));

    (*str)[*len] = '\0';
    global_err_string = std::string("");
}

const char *af_err_to_string(const af_err err)
{
    switch (err) {
    case AF_SUCCESS:            return "Success";
    case AF_ERR_INTERNAL:       return "Internal error";
    case AF_ERR_NO_MEM:         return "Device out of memory";
    case AF_ERR_DRIVER:         return "Driver not available or incompatible";
    case AF_ERR_RUNTIME:        return "Runtime error ";
    case AF_ERR_INVALID_ARRAY:  return "Invalid array";
    case AF_ERR_ARG:            return "Invalid input argument";
    case AF_ERR_SIZE:           return "Invalid input size";
    case AF_ERR_DIFF_TYPE:      return "Input types are not the same";
    case AF_ERR_NOT_SUPPORTED:  return "Function not supported";
    case AF_ERR_NOT_CONFIGURED: return "Function not configured to build";
    case AF_ERR_TYPE:           return "Function does not support this data type";
    case AF_ERR_NO_DBL:         return "Double precision not supported for this device";
    case AF_ERR_LOAD_LIB:       return "Failed to load dynamic library. See http://www.arrayfire.com/docs/unifiedbackend.htm for instructions to set up environment for Unified backend";
    case AF_ERR_LOAD_SYM:       return "Failed to load symbol";
    case AF_ERR_UNKNOWN:
    default:
        return "Unknown error";
    }
}

af_err processException()
{
    stringstream    ss;
    af_err          err= AF_ERR_INTERNAL;

    try {
        throw;
    } catch (const DimensionError &ex) {
        ss << "In function " << ex.getFunctionName()
           << "(" << ex.getLine() << "):\n"
           << "Invalid dimension for argument " << ex.getArgIndex() << "\n"
           << "Expected: " << ex.getExpectedCondition() << "\n";

        print_error(ss);
        err = AF_ERR_SIZE;
    } catch (const ArgumentError &ex) {
        ss << "In function " << ex.getFunctionName()
           << "(" << ex.getLine() << "):\n"
           << "Invalid argument at index " << ex.getArgIndex() << "\n"
           << "Expected: " << ex.getExpectedCondition() << "\n";

        print_error(ss);
        err = AF_ERR_ARG;
    } catch (const SupportError &ex) {
        ss << ex.getFunctionName()
           << " not supported for " << ex.getBackendName()
           << " backend\n";

        print_error(ss);
        err = AF_ERR_NOT_SUPPORTED;
    } catch (const TypeError &ex) {
        ss << "In function " << ex.getFunctionName()
           << "(" << ex.getLine() << "):\n"
           << "Invalid type for argument " << ex.getArgIndex() << "\n";

        print_error(ss);
        err = AF_ERR_TYPE;
    } catch (const AfError &ex) {
        ss << "Error in " << ex.getFunctionName()
           << "(" << ex.getLine() << "):\n"
           << ex.what() << "\n";

        print_error(ss);
        err = ex.getError();
#if defined(WITH_GRAPHICS) && !defined(AF_UNIFIED)
    } catch (const fg::Error &ex) {
        ss << ex << "\n";
        print_error(ss);
        err = AF_ERR_INTERNAL;
#endif
    } catch (...) {
        print_error(ss);
        err = AF_ERR_UNKNOWN;
    }

    return err;
}
<|endoftext|>


<commit_before>#include <QCoreApplication>

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>

#ifndef M_PI
#define M_PI 3.14159265359
#endif

double drand48()
{
    return((double)(rand())/((double)RAND_MAX));
}

void normalDistRand(double stdDev,double* randomNumbers)
    {
        /* Generate a random number in polar coordinates */
        double radius = sqrt(-2.0*log(drand48()));
        double angle = 2.0*M_PI*drand48();
        /* transform the number back into cartesian coordinates */
        randomNumbers[0] = stdDev*radius*sin(angle);
        randomNumbers[1] = stdDev*radius*cos(angle);
    }

double linear(long steps,
              double a,double gamma,double r,double d,double g,
              double *x,double *y,double *z, double dt,
              int n,
              double beta,double tau,
              FILE *fp,
              int q,
              double h,double s,double *v,double *w)
    {
        int m=0;
        int p;
        p=(m+n-1)%(n-1);
        double B[2];
        int calcRandom=0;
        for (long k=0;k<steps;k++)
        {
            if(calcRandom==0)
                normalDistRand(sqrt(dt),B); //noise in most recent time step

            //x[0]=y[m]+(y[m]*(gamma-gamma*y[m]+(a-gamma)*z[m])-(g*y[p]/(1-z[p])))*dt
            //x[0]=x[0]+beta*y[m]*(1-y[m])+0.5*beta*y[m]*(1-y[m])*beta*(1-2*y[m])*(B[calcRandom]*B[calcRandom]-dt);

            //Computes the deterministic component for Macroalgae
            x[0]=y[m]+(y[m]*(gamma-gamma*y[m]+(a-gamma)*z[m])-(g*y[p]/(1-z[p])))*dt;

            //Adds in the noise
            //x[0]=x[0]+beta*y[m]*B[calcRandom]+0.5*beta*y[m]*beta*(B[calcRandom]*B[calcRandom]-dt);
            x[0]=x[0]+beta*y[m]*B[calcRandom]+0.5*beta*beta*y[m]*(B[calcRandom]*B[calcRandom]-dt);

            //Computes the deterministic component for Coral
            x[1]=z[m]+(z[m]*(r-d-(a+r)*y[m]-r*z[m]))*dt;

            x[2]=v[m]+(v[m]*(gamma-gamma*v[m]+(a-gamma)*w[m])-(g*v[p]/(1-w[p])))*dt;
            x[2]=x[2]+beta*v[m]*(1-v[m])*B[calcRandom]+0.5*beta*(1-2*v[m])*beta*v[m]*(1-v[m])*(B[calcRandom]*B[calcRandom]-dt);
            x[3]=w[m]+(w[m]*(r-d-(a+r)*v[m]-r*w[m]))*dt;

            /****************************************************************
                Account for extinction and overgrowing!!
            ****************************************************************/
            for(int i=0;i<4;++i)
                {
                    if(x[i]<0.0)
                        x[i] = 0.0;
                    else if (x[i]>1.0)
                        x[i] = 1.0;
                }

            //Updates delay and cell index
            m=(m+1)%(n-1);
            p=(m+1)%(n-1);
            y[m]=x[0];
            z[m]=x[1];
            v[m]=x[2];
            w[m]=x[3];
            calcRandom = (calcRandom+1)%2; // update which random number to use.
            //fprintf(fp,"%f,%f,%f,%f,%f,%f\n",x[0],x[1],1-x[0]-x[1],x[2],x[3],1-x[2]-x[3]);
        }

        //printf("%f\t%f\t%f\t%f\t%f\n",dt,beta,tau,x[0],x[1]);
        fprintf(fp,"%f,%f,%f,%f,%i,%f,%f,%f,%f,%f,%f,%f,%f,%f\n",dt,beta,g,tau,q+1,h,s,1-h-s,x[0],x[1],1-x[0]-x[1],x[2],x[3],1-x[2]-x[3]);
        return 0;
    }

/* ****************************************************************
     main

     The main function. Called at the start of the program.
**************************************************************** */
int main(int argc, char *argv[])
{
    QCoreApplication b(argc, argv);

        long steps;    // The number of steps to take in a single simulation.
        double *v,*w,*x,*y,*z;  // The variables used for the state of the system.

        /*
            Define the constants.

            These are the parameters that are used in the operator for the
            differential equations.
         */
        double a    	 = 0.1;
        double g    	 = 0.3;
        double gamma	 = 0.8;
        double r    	 = 1.0;
        double d    	 = 0.44;
    //	double tau		 = 0.5;
        double beta 	 = .5;
        double chi		 = r*gamma/(r+a)-gamma+a;					//Intermediate Step
        double xi		 = -(d*gamma/(r+a)+a);						//Intermediate Step
        double cbar		 = (-xi-sqrt(xi*xi-4*chi*g))/(2*chi);		//Intermediate Step
        double coralSaddle		 = 1-cbar;									//Saddle point value for coral
        double macroSaddle		 = (r-r*coralSaddle-d)/(r+a);						//Saddle point value for macroalgae
        double gZero	 = ((d*a*r+d*d)*(gamma-a))/(r*r);
        double gOne		 = (gamma*(a+d))/(a+r);
        double omega	 = sqrt((r*r*(g*g-gZero*gZero))/(d*d));
        double tauZero	 = (1/omega)*acos(gZero/g);

        double dt,final;    // The time step and the final time.
        int trials;         // The number of simulations to make.

        final=100;  // Set the final time.
        trials=10000; // Set the number of trials to perform.

        // Set the smallest time step
        dt=0.0001;

        // Set tau
        double tau = 0.5;

        // Sets the seed for the random numbers
        srand(time(NULL));

        // Create a CSV File
        FILE*fp;
                //String fileName = "trials-g" + std::toString(g) + "-tau" + std::toString(tau);
        fp=fopen("trials.csv","w");
        //fprintf(fp,"dt,beta,g,tau,trial,initMacro,initCoral,initTurf,macroalgae,coral,turf\n");
        fprintf(fp,"dt,beta,g,tau,trial,initMacro,initCoral,initTurf,macroalgae,coral,turf,lgMacro,lgCoral,lgTurf\n");
        //fprintf(fp,"macroalgae,coral,turf,lgmacroalgae,lgcoral,lgturf\n");
        //printf("dt\t\tbeta\t\ttau\t\tMacroalgae\tCoral\n");

/*		for (g=0.1;g<=0.8;g=g+0.02)
            {
                //Redefine initial conditions and critical points for varying g
                cbar		 = (-xi-sqrt(xi*xi-4*chi*g))/(2*chi);
                coralSaddle		 = 1-cbar;
                macroSaddle		 = (r-r*coralSaddle-d)/(r+a);
                omega	 = sqrt((r*r*(g*g-gZero*gZero))/(d*d));
                tauZero	 = (1/omega)*acos(gZero/g);
                if (coralSaddle>0 && coralSaddle<1 && macroSaddle>0 && macroSaddle<1 && tauZero>0)
            for (double aleph=0;aleph<=5;aleph=aleph+1)
            {

                tau=.3*(1+aleph)*tauZero;
                dt=0.0001;
*/			// The number of cells needed for the delay (changes with dt)
            int n;
            n=(int)abs(tau/dt+0.5);

            // Allocate the space for the state of the system
            x=(double *) calloc(4,sizeof(double));
            y=(double *) calloc(n,sizeof(double));		//macroalgae for multiplicative noise
            z=(double *) calloc(n,sizeof(double));		//coral for multiplicative noise
            v=(double *) calloc(n,sizeof(double));		//macroalgae for logistic noise
            w=(double *) calloc(n,sizeof(double));		//coral for logistic noise
                while (dt<=0.0001)
                {
                    //printf("%f\t%f\n",dt,fmod(tau,dt));
                    std::cout << "dt = " << dt << std::endl;
                    if ((int)(10000*tau+.5)%(int)(dt*10000+.5)==0)
                    {
                        //index = tau/dt;
                        n=(int)(tau/dt+.5);
                        //printf("%i\n",n);
                        steps=(long)(final/dt);
                        for (int k=0;k<trials;k++)
                        {
                            y[0]=macroSaddle; //initial Macroalgae level
                            z[0]=coralSaddle; //initial Coral level
                            v[0]=macroSaddle;
                            w[0]=coralSaddle;
                            for (int l=1;l<n;l++) //fills in "negative" times for both y and z
                            {
                                y[l]=y[0];
                                z[l]=z[0];
                                v[l]=v[0];
                                w[l]=w[0];
                            }
                            //fprintf(fp,"%f,%f,%f,%f,%f,%f\n",y[0],z[0],1-y[0]-z[0],v[0],w[0],1-v[0]-w[0]);
                            linear(steps,a,gamma,r,d,g,x,y,z,dt,n,beta,tau,fp,k,macroSaddle,coralSaddle,v,w);
                        }
                    }
                    dt=dt+0.0001;
                }
            free(x);
            free(y);
            free(z);
            free(v);
            free(w);
            //}
            //}

        fclose(fp);

        return b.exec();
}
<commit_msg>Added an option to the simulation with noise to output the progress of the simulations<commit_after>#include <QCoreApplication>

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>

#ifndef M_PI
#define M_PI 3.14159265359
#endif

#define SHOW_PROGRESS

double drand48()
{
    return((double)(rand())/((double)RAND_MAX));
}

void normalDistRand(double stdDev,double* randomNumbers)
    {
        /* Generate a random number in polar coordinates */
        double radius = sqrt(-2.0*log(drand48()));
        double angle = 2.0*M_PI*drand48();
        /* transform the number back into cartesian coordinates */
        randomNumbers[0] = stdDev*radius*sin(angle);
        randomNumbers[1] = stdDev*radius*cos(angle);
    }

double linear(long steps,
              double a,double gamma,double r,double d,double g,
              double *x,double *y,double *z, double dt,
              int n,
              double beta,double tau,
              FILE *fp,
              int q,
              double h,double s,double *v,double *w)
    {
        int m=0;
        int p;
        p=(m+n-1)%(n-1);
        double B[2];
        int calcRandom=0;
        for (long k=0;k<steps;k++)
        {
            if(calcRandom==0)
                normalDistRand(sqrt(dt),B); //noise in most recent time step

            //x[0]=y[m]+(y[m]*(gamma-gamma*y[m]+(a-gamma)*z[m])-(g*y[p]/(1-z[p])))*dt
            //x[0]=x[0]+beta*y[m]*(1-y[m])+0.5*beta*y[m]*(1-y[m])*beta*(1-2*y[m])*(B[calcRandom]*B[calcRandom]-dt);

            //Computes the deterministic component for Macroalgae
            x[0]=y[m]+(y[m]*(gamma-gamma*y[m]+(a-gamma)*z[m])-(g*y[p]/(1-z[p])))*dt;

            //Adds in the noise
            //x[0]=x[0]+beta*y[m]*B[calcRandom]+0.5*beta*y[m]*beta*(B[calcRandom]*B[calcRandom]-dt);
            x[0]=x[0]+beta*y[m]*B[calcRandom]+0.5*beta*beta*y[m]*(B[calcRandom]*B[calcRandom]-dt);

            //Computes the deterministic component for Coral
            x[1]=z[m]+(z[m]*(r-d-(a+r)*y[m]-r*z[m]))*dt;

            x[2]=v[m]+(v[m]*(gamma-gamma*v[m]+(a-gamma)*w[m])-(g*v[p]/(1-w[p])))*dt;
            x[2]=x[2]+beta*v[m]*(1-v[m])*B[calcRandom]+0.5*beta*(1-2*v[m])*beta*v[m]*(1-v[m])*(B[calcRandom]*B[calcRandom]-dt);
            x[3]=w[m]+(w[m]*(r-d-(a+r)*v[m]-r*w[m]))*dt;

            /****************************************************************
                Account for extinction and overgrowing!!
            ****************************************************************/
            for(int i=0;i<4;++i)
                {
                    if(x[i]<0.0)
                        x[i] = 0.0;
                    else if (x[i]>1.0)
                        x[i] = 1.0;
                }

            //Updates delay and cell index
            m=(m+1)%(n-1);
            p=(m+1)%(n-1);
            y[m]=x[0];
            z[m]=x[1];
            v[m]=x[2];
            w[m]=x[3];
            calcRandom = (calcRandom+1)%2; // update which random number to use.
            //fprintf(fp,"%f,%f,%f,%f,%f,%f\n",x[0],x[1],1-x[0]-x[1],x[2],x[3],1-x[2]-x[3]);
        }

        //printf("%f\t%f\t%f\t%f\t%f\n",dt,beta,tau,x[0],x[1]);
        fprintf(fp,"%f,%f,%f,%f,%i,%f,%f,%f,%f,%f,%f,%f,%f,%f\n",dt,beta,g,tau,q+1,h,s,1-h-s,x[0],x[1],1-x[0]-x[1],x[2],x[3],1-x[2]-x[3]);
        return 0;
    }

/* ****************************************************************
     main

     The main function. Called at the start of the program.
**************************************************************** */
int main(int argc, char *argv[])
{
    QCoreApplication b(argc, argv);

        long steps;    // The number of steps to take in a single simulation.
        double *v,*w,*x,*y,*z;  // The variables used for the state of the system.

        /*
            Define the constants.

            These are the parameters that are used in the operator for the
            differential equations.
         */
        double a    	 = 0.1;
        double g    	 = 0.3;
        double gamma	 = 0.8;
        double r    	 = 1.0;
        double d    	 = 0.44;
    //	double tau		 = 0.5;
        double beta 	 = .5;
        double chi		 = r*gamma/(r+a)-gamma+a;					//Intermediate Step
        double xi		 = -(d*gamma/(r+a)+a);						//Intermediate Step
        double cbar		 = (-xi-sqrt(xi*xi-4*chi*g))/(2*chi);		//Intermediate Step
        double coralSaddle		 = 1-cbar;									//Saddle point value for coral
        double macroSaddle		 = (r-r*coralSaddle-d)/(r+a);						//Saddle point value for macroalgae
        double gZero	 = ((d*a*r+d*d)*(gamma-a))/(r*r);
        double gOne		 = (gamma*(a+d))/(a+r);
        double omega	 = sqrt((r*r*(g*g-gZero*gZero))/(d*d));
        double tauZero	 = (1/omega)*acos(gZero/g);

        double dt,final;    // The time step and the final time.
        int trials;         // The number of simulations to make.

        final=100;  // Set the final time.
        trials=10000; // Set the number of trials to perform.

        // Set the smallest time step
        dt=0.0001;

        // Set tau
        double tau = 0.5;

        // Sets the seed for the random numbers
        srand(time(NULL));

        // Create a CSV File
        FILE*fp;
                //String fileName = "trials-g" + std::toString(g) + "-tau" + std::toString(tau);
        fp=fopen("trials.csv","w");
        //fprintf(fp,"dt,beta,g,tau,trial,initMacro,initCoral,initTurf,macroalgae,coral,turf\n");
        fprintf(fp,"dt,beta,g,tau,trial,initMacro,initCoral,initTurf,macroalgae,coral,turf,lgMacro,lgCoral,lgTurf\n");
        //fprintf(fp,"macroalgae,coral,turf,lgmacroalgae,lgcoral,lgturf\n");
        //printf("dt\t\tbeta\t\ttau\t\tMacroalgae\tCoral\n");

/*		for (g=0.1;g<=0.8;g=g+0.02)
            {
                //Redefine initial conditions and critical points for varying g
                cbar		 = (-xi-sqrt(xi*xi-4*chi*g))/(2*chi);
                coralSaddle		 = 1-cbar;
                macroSaddle		 = (r-r*coralSaddle-d)/(r+a);
                omega	 = sqrt((r*r*(g*g-gZero*gZero))/(d*d));
                tauZero	 = (1/omega)*acos(gZero/g);
                if (coralSaddle>0 && coralSaddle<1 && macroSaddle>0 && macroSaddle<1 && tauZero>0)
            for (double aleph=0;aleph<=5;aleph=aleph+1)
            {

                tau=.3*(1+aleph)*tauZero;
                dt=0.0001;
*/			// The number of cells needed for the delay (changes with dt)
            int n;
            n=(int)abs(tau/dt+0.5);

            // Allocate the space for the state of the system
            x=(double *) calloc(4,sizeof(double));
            y=(double *) calloc(n,sizeof(double));		//macroalgae for multiplicative noise
            z=(double *) calloc(n,sizeof(double));		//coral for multiplicative noise
            v=(double *) calloc(n,sizeof(double));		//macroalgae for logistic noise
            w=(double *) calloc(n,sizeof(double));		//coral for logistic noise
                while (dt<=0.0001)
                {
                    //printf("%f\t%f\n",dt,fmod(tau,dt));
#ifdef SHOW_PROGRESS
                    std::cout << "dt = " << dt << std::endl;
#endif
                    if ((int)(10000*tau+.5)%(int)(dt*10000+.5)==0)
                    {
                        //index = tau/dt;
                        n=(int)(tau/dt+.5);
                        //printf("%i\n",n);
                        steps=(long)(final/dt);
                        for (int k=0;k<trials;k++)
                        {
                            y[0]=macroSaddle; //initial Macroalgae level
                            z[0]=coralSaddle; //initial Coral level
                            v[0]=macroSaddle;
                            w[0]=coralSaddle;
                            for (int l=1;l<n;l++) //fills in "negative" times for both y and z
                            {
                                y[l]=y[0];
                                z[l]=z[0];
                                v[l]=v[0];
                                w[l]=w[0];
                            }
                            //fprintf(fp,"%f,%f,%f,%f,%f,%f\n",y[0],z[0],1-y[0]-z[0],v[0],w[0],1-v[0]-w[0]);
                            linear(steps,a,gamma,r,d,g,x,y,z,dt,n,beta,tau,fp,k,macroSaddle,coralSaddle,v,w);
#ifdef SHOW_PROGRESS
                            if(k%25 == 0)
                                std::cout << "  Simulation number " << k << std::endl;
#endif
                        }
                    }
                    dt=dt+0.0001;
                }
            free(x);
            free(y);
            free(z);
            free(v);
            free(w);
            //}
            //}

        fclose(fp);

        return b.exec();
}
<|endoftext|>


<commit_before>/*
 * Copyright 1999-2000,2004 The Apache Software Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * $Log$
 * Revision 1.9  2004/09/28 02:14:13  cargilld
 * Add support for validating annotations.
 *
 * Revision 1.8  2004/09/08 13:55:57  peiyongz
 * Apache License Version 2.0
 *
 * Revision 1.7  2004/01/29 11:46:29  cargilld
 * Code cleanup changes to get rid of various compiler diagnostic messages.
 *
 * Revision 1.6  2003/12/01 23:23:25  neilg
 * fix for bug 25118; thanks to Jeroen Witmond
 *
 * Revision 1.5  2003/07/30 14:48:38  peiyongz
 * Allow default value
 *
 * Revision 1.4  2003/05/16 21:36:55  knoaman
 * Memory manager implementation: Modify constructors to pass in the memory manager.
 *
 * Revision 1.3  2002/11/04 15:00:21  tng
 * C++ Namespace Support.
 *
 * Revision 1.2  2002/02/20 18:17:01  tng
 * [Bug 5977] Warnings on generating apiDocs.
 *
 * Revision 1.1.1.1  2002/02/01 22:21:50  peiyongz
 * sane_include
 *
 * Revision 1.6  2000/12/14 18:49:54  tng
 * Fix API document generation warning: "Warning: end of member group without matching begin"
 *
 * Revision 1.5  2000/02/24 20:00:22  abagchi
 * Swat for removing Log from API docs
 *
 * Revision 1.4  2000/02/15 23:59:06  roddey
 * More updated documentation of Framework classes.
 *
 * Revision 1.3  2000/02/15 01:21:30  roddey
 * Some initial documentation improvements. More to come...
 *
 * Revision 1.2  2000/02/06 07:47:46  rahulj
 * Year 2K copyright swat.
 *
 * Revision 1.1  2000/01/12 00:13:26  roddey
 * These were moved from internal/ to framework/, which was something that should have
 * happened long ago. They are really framework type of classes.
 *
 * Revision 1.1.1.1  1999/11/09 01:08:10  twl
 * Initial checkin
 *
 * Revision 1.2  1999/11/08 20:44:43  rahul
 * Swat for adding in Product name and CVS comment log variable.
 *
 */

#if !defined(MEMBUFINPUTSOURCE_HPP)
#define MEMBUFINPUTSOURCE_HPP

#include <xercesc/sax/InputSource.hpp>

XERCES_CPP_NAMESPACE_BEGIN

class BinInputStream;

/**
 *  This class is a derivative of the standard InputSource class. It provides
 *  for the parser access to data stored in a memory buffer. The type of
 *  buffer and its host specific attributes are of little concern here. The
 *  only real requirement is that the memory be readable by the current
 *  process.
 *
 *  Note that the memory buffer size is expressed in bytes, not in
 *  characters. If you pass it text data, you must account for the bytes
 *  per character when indicating the buffer size.
 *
 *  As with all InputSource derivatives. The primary objective of an input
 *  source is to create an input stream via which the parser can spool in
 *  data from the referenced source. In this case, there are two options
 *  available.
 *
 *  The passed buffer can be adopted or merely referenced. If it is adopted,
 *  then it must be dynamically allocated and will be destroyed when the
 *  input source is destroyed (no reference counting!.) If not adopted, the
 *  caller must insure that it remains valid until the input source object
 *  is destroyed.
 *
 *  The other option indicates whether each stream created for this input
 *  source should get its own copy of the data, or whether it should just
 *  stream the data directly from this object's copy of the data. The same
 *  rules apply here, in that the buffer must either be copied by the
 *  stream or it must remain valid until the stream is destroyed.
 */
class XMLPARSER_EXPORT MemBufInputSource : public InputSource
{
public :
    // -----------------------------------------------------------------------
    //  Constructors and Destructor
    // -----------------------------------------------------------------------

    /** @name Constructors */
    //@{

    /**
      * A memory buffer input source is constructed from a buffer of byte
      * data, and the count of bytes in that buffer. The parser will parse
      * from this memory buffer until it has eaten the indicated number of
      * bytes.
      *
      * Note that the system id provided serves two purposes. Firstly it is
      * going to be displayed in error messages as the source of the error.
      * And secondly, any entities which are refered to from this entity
      * via relative paths/URLs will be relative to this fake system id.
      *
      * @param  srcDocBytes     The actual data buffer to be parsed from.
      * @param  byteCount       The count of bytes (not characters, bytes!)
      *                         in the buffer.
      * @param  bufId           A fake system id for the buffer.
      * @param  adoptBuffer     Indicates whether this object should adopt
      *                         the buffer (i.e. make a copy of it) or just
      *                         use it in place.
      * @param  manager         Pointer to the memory manager to be used to
      *                         allocate objects.
      */
    MemBufInputSource
    (
        const   XMLByte* const  srcDocBytes
        , const unsigned int    byteCount
        , const XMLCh* const    bufId
        , const bool            adoptBuffer = false
        , MemoryManager* const  manager = XMLPlatformUtils::fgMemoryManager
    );

    /**
      * This constructor is identical to the previous one, except that it takes
      * the fake system id in local code page form and transcodes it internally.
      */
    MemBufInputSource
    (
        const   XMLByte* const  srcDocBytes
        , const unsigned int    byteCount
        , const char* const     bufId
        , const bool            adoptBuffer = false
        , MemoryManager* const  manager = XMLPlatformUtils::fgMemoryManager
    );
    //@}

    /** @name Destructor */
    //@{
    /**
      * If the buffer was adopted, the copy made during construction is deleted
      * at this point.
      */
    ~MemBufInputSource();
    //@}

    // -----------------------------------------------------------------------
    //  Virtual input source interface
    // -----------------------------------------------------------------------

    /** @name Virtual methods */
    //@{

    /**
      * This method will return a binary input stream derivative that will
      * parse from the memory buffer. If setCopyBufToStream() has been set,
      * then the stream will make its own copy. Otherwise, it will use the
      * buffer as is (in which case it must remain valid until the stream
      * is no longer in use, i.e. the parse completes.)
      *
      * @return A dynamically allocated binary input stream derivative that
      *         can parse from the memory buffer.
      */
    BinInputStream* makeStream() const;

    //@}

    // -----------------------------------------------------------------------
    //  Setter methods
    // -----------------------------------------------------------------------

    /** @name Setter methods */

    //@{

    /**
      * By default, for safety's sake, each newly created stream from this
      * input source will make its own copy of the buffer to stream from. This
      * avoids having to deal with aliasing of the buffer for simple work. But,
      * for higher performance applications or for large buffers, this is
      * obviously not optimal.
      *
      * In such cases, you can call this method to turn off that default
      * action. Once turned off, the streams will just get a pointer to the
      * buffer and parse directly from that. In this case, you must insure that
      * the buffer remains valid for as long as any parse events are still
      * using it.
      *
      * @param  newState    The new boolean flag state to set.
      */
    void setCopyBufToStream(const bool newState);

    /**
      * This methods allows the MemBufInputSource to be used for more than
      * one input source, instead of destructing/constructing another
      * MemBufInputSource.
      *
      * @param  srcDocBytes     The actual data buffer to be parsed from.
      * @param  byteCount       The count of bytes (not characters, bytes!)
      *                         in the buffer.
      */
    void resetMemBufInputSource(const   XMLByte* const  srcDocBytes
                                , const unsigned int    byteCount);
    //@}

private :
    // -----------------------------------------------------------------------
    //  Unimplemented constructors and operators
    // -----------------------------------------------------------------------
    MemBufInputSource(const MemBufInputSource&);
    MemBufInputSource& operator=(const MemBufInputSource&);

    // -----------------------------------------------------------------------
    //  Private data members
    //
    //  fAdopted
    //      Indicates whether the buffer is adopted or not. If so, then it
    //      is destroyed when the input source is destroyed.
    //
    //  fByteCount
    //      The size of the source document.
    //
    //  fCopyBufToStream
    //      This defaults to true (the safe option), which causes it to
    //      give a copy of the buffer to any streams it creates. If you set
    //      it to false, it will allow the streams to just reference the
    //      buffer (in which case this input source must stay alive as long
    //      as the buffer is in use by the stream.)
    //
    //  fSrcBytes
    //      The source memory buffer that is being spooled from. Whether it
    //      belongs to the this input source or not is controlled by the
    //      fAdopted flag.
    // -----------------------------------------------------------------------
    bool            fAdopted;
    unsigned int    fByteCount;
    bool            fCopyBufToStream;
    const XMLByte*  fSrcBytes;
};

inline void MemBufInputSource::setCopyBufToStream(const bool newState)
{
    fCopyBufToStream = newState;
}

XERCES_CPP_NAMESPACE_END

#endif
<commit_msg>Updated doc to refect real behaviour with adoptBuffer.<commit_after>/*
 * Copyright 1999-2000,2004 The Apache Software Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * $Log$
 * Revision 1.10  2005/03/17 11:07:04  gareth
 * Updated doc to refect real behaviour with adoptBuffer.
 *
 * Revision 1.9  2004/09/28 02:14:13  cargilld
 * Add support for validating annotations.
 *
 * Revision 1.8  2004/09/08 13:55:57  peiyongz
 * Apache License Version 2.0
 *
 * Revision 1.7  2004/01/29 11:46:29  cargilld
 * Code cleanup changes to get rid of various compiler diagnostic messages.
 *
 * Revision 1.6  2003/12/01 23:23:25  neilg
 * fix for bug 25118; thanks to Jeroen Witmond
 *
 * Revision 1.5  2003/07/30 14:48:38  peiyongz
 * Allow default value
 *
 * Revision 1.4  2003/05/16 21:36:55  knoaman
 * Memory manager implementation: Modify constructors to pass in the memory manager.
 *
 * Revision 1.3  2002/11/04 15:00:21  tng
 * C++ Namespace Support.
 *
 * Revision 1.2  2002/02/20 18:17:01  tng
 * [Bug 5977] Warnings on generating apiDocs.
 *
 * Revision 1.1.1.1  2002/02/01 22:21:50  peiyongz
 * sane_include
 *
 * Revision 1.6  2000/12/14 18:49:54  tng
 * Fix API document generation warning: "Warning: end of member group without matching begin"
 *
 * Revision 1.5  2000/02/24 20:00:22  abagchi
 * Swat for removing Log from API docs
 *
 * Revision 1.4  2000/02/15 23:59:06  roddey
 * More updated documentation of Framework classes.
 *
 * Revision 1.3  2000/02/15 01:21:30  roddey
 * Some initial documentation improvements. More to come...
 *
 * Revision 1.2  2000/02/06 07:47:46  rahulj
 * Year 2K copyright swat.
 *
 * Revision 1.1  2000/01/12 00:13:26  roddey
 * These were moved from internal/ to framework/, which was something that should have
 * happened long ago. They are really framework type of classes.
 *
 * Revision 1.1.1.1  1999/11/09 01:08:10  twl
 * Initial checkin
 *
 * Revision 1.2  1999/11/08 20:44:43  rahul
 * Swat for adding in Product name and CVS comment log variable.
 *
 */

#if !defined(MEMBUFINPUTSOURCE_HPP)
#define MEMBUFINPUTSOURCE_HPP

#include <xercesc/sax/InputSource.hpp>

XERCES_CPP_NAMESPACE_BEGIN

class BinInputStream;

/**
 *  This class is a derivative of the standard InputSource class. It provides
 *  for the parser access to data stored in a memory buffer. The type of
 *  buffer and its host specific attributes are of little concern here. The
 *  only real requirement is that the memory be readable by the current
 *  process.
 *
 *  Note that the memory buffer size is expressed in bytes, not in
 *  characters. If you pass it text data, you must account for the bytes
 *  per character when indicating the buffer size.
 *
 *  As with all InputSource derivatives. The primary objective of an input
 *  source is to create an input stream via which the parser can spool in
 *  data from the referenced source. In this case, there are two options
 *  available.
 *
 *  The passed buffer can be adopted or merely referenced. If it is adopted,
 *  then it must be dynamically allocated and will be destroyed when the
 *  input source is destroyed (no reference counting!.) If not adopted, the
 *  caller must insure that it remains valid until the input source object
 *  is destroyed.
 *
 *  The other option indicates whether each stream created for this input
 *  source should get its own copy of the data, or whether it should just
 *  stream the data directly from this object's copy of the data. The same
 *  rules apply here, in that the buffer must either be copied by the
 *  stream or it must remain valid until the stream is destroyed.
 */
class XMLPARSER_EXPORT MemBufInputSource : public InputSource
{
public :
    // -----------------------------------------------------------------------
    //  Constructors and Destructor
    // -----------------------------------------------------------------------

    /** @name Constructors */
    //@{

    /**
      * A memory buffer input source is constructed from a buffer of byte
      * data, and the count of bytes in that buffer. The parser will parse
      * from this memory buffer until it has eaten the indicated number of
      * bytes.
      *
      * Note that the system id provided serves two purposes. Firstly it is
      * going to be displayed in error messages as the source of the error.
      * And secondly, any entities which are refered to from this entity
      * via relative paths/URLs will be relative to this fake system id.
      *
      * @param  srcDocBytes     The actual data buffer to be parsed from.
      * @param  byteCount       The count of bytes (not characters, bytes!)
      *                         in the buffer.
      * @param  bufId           A fake system id for the buffer.
      * @param  adoptBuffer     Indicates whether this object should adopt
      *                         the buffer (i.e. become responsible for
      * deletion) or just
      *                         use it in place.
      * @param  manager         Pointer to the memory manager to be used to
      *                         allocate objects.
      */
    MemBufInputSource
    (
        const   XMLByte* const  srcDocBytes
        , const unsigned int    byteCount
        , const XMLCh* const    bufId
        , const bool            adoptBuffer = false
        , MemoryManager* const  manager = XMLPlatformUtils::fgMemoryManager
    );

    /**
      * This constructor is identical to the previous one, except that it takes
      * the fake system id in local code page form and transcodes it internally.
      */
    MemBufInputSource
    (
        const   XMLByte* const  srcDocBytes
        , const unsigned int    byteCount
        , const char* const     bufId
        , const bool            adoptBuffer = false
        , MemoryManager* const  manager = XMLPlatformUtils::fgMemoryManager
    );
    //@}

    /** @name Destructor */
    //@{
    /**
      * If the buffer was adopted, the copy made during construction is deleted
      * at this point.
      */
    ~MemBufInputSource();
    //@}

    // -----------------------------------------------------------------------
    //  Virtual input source interface
    // -----------------------------------------------------------------------

    /** @name Virtual methods */
    //@{

    /**
      * This method will return a binary input stream derivative that will
      * parse from the memory buffer. If setCopyBufToStream() has been set,
      * then the stream will make its own copy. Otherwise, it will use the
      * buffer as is (in which case it must remain valid until the stream
      * is no longer in use, i.e. the parse completes.)
      *
      * @return A dynamically allocated binary input stream derivative that
      *         can parse from the memory buffer.
      */
    BinInputStream* makeStream() const;

    //@}

    // -----------------------------------------------------------------------
    //  Setter methods
    // -----------------------------------------------------------------------

    /** @name Setter methods */

    //@{

    /**
      * By default, for safety's sake, each newly created stream from this
      * input source will make its own copy of the buffer to stream from. This
      * avoids having to deal with aliasing of the buffer for simple work. But,
      * for higher performance applications or for large buffers, this is
      * obviously not optimal.
      *
      * In such cases, you can call this method to turn off that default
      * action. Once turned off, the streams will just get a pointer to the
      * buffer and parse directly from that. In this case, you must insure that
      * the buffer remains valid for as long as any parse events are still
      * using it.
      *
      * @param  newState    The new boolean flag state to set.
      */
    void setCopyBufToStream(const bool newState);

    /**
      * This methods allows the MemBufInputSource to be used for more than
      * one input source, instead of destructing/constructing another
      * MemBufInputSource.
      *
      * @param  srcDocBytes     The actual data buffer to be parsed from.
      * @param  byteCount       The count of bytes (not characters, bytes!)
      *                         in the buffer.
      */
    void resetMemBufInputSource(const   XMLByte* const  srcDocBytes
                                , const unsigned int    byteCount);
    //@}

private :
    // -----------------------------------------------------------------------
    //  Unimplemented constructors and operators
    // -----------------------------------------------------------------------
    MemBufInputSource(const MemBufInputSource&);
    MemBufInputSource& operator=(const MemBufInputSource&);

    // -----------------------------------------------------------------------
    //  Private data members
    //
    //  fAdopted
    //      Indicates whether the buffer is adopted or not. If so, then it
    //      is destroyed when the input source is destroyed.
    //
    //  fByteCount
    //      The size of the source document.
    //
    //  fCopyBufToStream
    //      This defaults to true (the safe option), which causes it to
    //      give a copy of the buffer to any streams it creates. If you set
    //      it to false, it will allow the streams to just reference the
    //      buffer (in which case this input source must stay alive as long
    //      as the buffer is in use by the stream.)
    //
    //  fSrcBytes
    //      The source memory buffer that is being spooled from. Whether it
    //      belongs to the this input source or not is controlled by the
    //      fAdopted flag.
    // -----------------------------------------------------------------------
    bool            fAdopted;
    unsigned int    fByteCount;
    bool            fCopyBufToStream;
    const XMLByte*  fSrcBytes;
};

inline void MemBufInputSource::setCopyBufToStream(const bool newState)
{
    fCopyBufToStream = newState;
}

XERCES_CPP_NAMESPACE_END

#endif
<|endoftext|>


<commit_before>#define _USE_MATH_DEFINES
#define DEBUG_INPUT
#include "ChatMessage.h"
#include "Events/InputState.h"
#include "Entity.h"
#include "MapClient.h"
#include <cmath>

void ChatMessage::serializeto(BitStream &bs) const
{
    bs.StorePackedBits(1,type()-MapEventTypes::evFirstServerToClient);
    bs.StorePackedBits(10,m_source_player_id);
    bs.StorePackedBits(3,m_channel_type);
    bs.StoreString(m_msg);
    bs.StorePackedBits(1,0); // no messages follow
}

void ChatMessage::serializefrom(BitStream &src)
{
    m_source_player_id = src.GetPackedBits(10);
    m_channel_type = src.GetPackedBits(3);
    src.GetString(m_msg);
}

ChatMessage *ChatMessage::adminMessage(const QString &msg)
{
    ChatMessage * res = new ChatMessage;
    res->m_channel_type = CHAT_Admin;
    res->m_source_player_id=1;
    res->m_msg = msg;
    return res;
}

ChatMessage *ChatMessage::localMessage(const QString &msg, Entity *src)
{
    ChatMessage * res = new ChatMessage;
    res->m_channel_type = CHAT_Local;
    res->m_source_player_id=src->getIdx();
    res->m_msg = msg;
    return res;
}

ChatMessage *ChatMessage::broadcastMessage(const QString &msg, Entity *src)
{
    ChatMessage * res = new ChatMessage;
    res->m_channel_type = CHAT_Broadcast;
    res->m_source_player_id=src->getIdx();
    res->m_msg = msg;
    return res;
}

void sendAdminMessage(MapClient * tgt, const char * msg)
{
    if(tgt)
        tgt->link()->putq(new PreUpdateCommand(ChatMessage::adminMessage(msg)));
}
<commit_msg>Chat messages were terminating the list of commands.<commit_after>#define _USE_MATH_DEFINES
#define DEBUG_INPUT
#include "ChatMessage.h"
#include "Events/InputState.h"
#include "Entity.h"
#include "MapClient.h"
#include <cmath>

void ChatMessage::serializeto(BitStream &bs) const
{
    bs.StorePackedBits(1,type()-MapEventTypes::evFirstServerToClient);
    bs.StorePackedBits(10,m_source_player_id);
    bs.StorePackedBits(3,m_channel_type);
    bs.StoreString(m_msg);
}

void ChatMessage::serializefrom(BitStream &src)
{
    m_source_player_id = src.GetPackedBits(10);
    m_channel_type = src.GetPackedBits(3);
    src.GetString(m_msg);
}

ChatMessage *ChatMessage::adminMessage(const QString &msg)
{
    ChatMessage * res = new ChatMessage;
    res->m_channel_type = CHAT_Admin;
    res->m_source_player_id=1;
    res->m_msg = msg;
    return res;
}

ChatMessage *ChatMessage::localMessage(const QString &msg, Entity *src)
{
    ChatMessage * res = new ChatMessage;
    res->m_channel_type = CHAT_Local;
    res->m_source_player_id=src->getIdx();
    res->m_msg = msg;
    return res;
}

ChatMessage *ChatMessage::broadcastMessage(const QString &msg, Entity *src)
{
    ChatMessage * res = new ChatMessage;
    res->m_channel_type = CHAT_Broadcast;
    res->m_source_player_id=src->getIdx();
    res->m_msg = msg;
    return res;
}

void sendAdminMessage(MapClient * tgt, const char * msg)
{
    if(tgt)
        tgt->link()->putq(new PreUpdateCommand(ChatMessage::adminMessage(msg)));
}
<|endoftext|>


<commit_before>//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

// Regression test for PR42676.

// RUN: %cxx %flags %s -o %t.exe %compile_flags -D_LIBCPP_HIDE_FROM_ABI_PER_TU
// RUN: %t.exe

#include <memory>
#include <string>

int main() {
    std::string s1(10u, '-', std::allocator<char>()); (void)s1;
    std::string s2("hello", std::allocator<char>()); (void)s2;
    std::string s3("hello"); (void)s3;
}
<commit_msg>[libc++] Add missing %link_flags to .sh.cpp test<commit_after>//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

// Regression test for PR42676.

// RUN: %cxx %flags %s -o %t.exe %compile_flags %link_flags -D_LIBCPP_HIDE_FROM_ABI_PER_TU
// RUN: %t.exe

#include <memory>
#include <string>

int main() {
    std::string s1(10u, '-', std::allocator<char>()); (void)s1;
    std::string s2("hello", std::allocator<char>()); (void)s2;
    std::string s3("hello"); (void)s3;
}
<|endoftext|>


<commit_before>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2016.  All rights reserved
 */
#ifndef _Stroika_Foundation_Characters_ToString_inl_
#define _Stroika_Foundation_Characters_ToString_inl_    1

#include    <wchar.h>

#include    "../Configuration/Concepts.h"
#include    "FloatConversion.h"
#include    "StringBuilder.h"

/*
 ********************************************************************************
 ***************************** Implementation Details ***************************
 ********************************************************************************
 */
namespace   Stroika {
    namespace   Foundation {
        namespace   Characters {

            /*
             ********************************************************************************
             ********************************* ToString *************************************
             ********************************************************************************
             */
            namespace Private_ {

                STROIKA_FOUNDATION_CONFIGURATION_DEFINE_HAS(ToString, (x.ToString ()));
                STROIKA_FOUNDATION_CONFIGURATION_DEFINE_HAS(beginenditerable, (x.begin () != x.end ()));

                template    <typename T>
                inline  String  ToString_ (const T& t, typename enable_if<has_ToString<T>::value>::type* = 0)
                {
                    return t.ToString ();
                }

                template    <typename T>
                inline  String  ToString_ (const T& t, typename enable_if<has_beginenditerable<T>::value and not is_convertible<T, String>::value>::type* = 0)
                {
                    StringBuilder sb;
                    sb << L"{";
                    bool didFirst { false };
                    for (auto i : t) {
                        if (didFirst) {
                            sb << L", ";
                        }
                        else {
                            sb << L" ";
                        }
                        sb << ToString (i);
                        didFirst = true;
                    }
                    if (didFirst) {
                        sb << L" ";
                    }
                    sb << L"}";
                    return sb.str ();
                }

                template    <typename T>
                inline  String  ToString_ (const T& t, typename enable_if<is_convertible<T, String>::value>::type* = 0)
                {
                    return static_cast<String> (t);
                }

                /*
                 * From section from section 3.9.1 of http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf
                 *      There are five standard signed integer types : signed char, short int, int,
                 *      long int, and long long int. In this list, each type provides at least as much
                 *      storage as those preceding it in the list.
                 *      For each of the standard signed integer types, there exists a corresponding (but different)
                 *      standard unsigned integer type: unsigned char, unsigned short int, unsigned int, unsigned long int,
                 *      and unsigned long long int, each of which occupies the same amount of storage and has the
                 *      same alignment requirements.
                 */
                template    <typename T>
                inline  String  ToString_ (const T& t, typename enable_if<is_same<T, bool>::value>::type* = 0)
                {
                    return t ? String_Constant { L"true" } :
                           String_Constant { L"false" };
                }
                template    <typename T>
                inline  String  ToString_ (const T& t, typename enable_if<is_same<T, signed char>::value>::type* = 0)
                {
                    wchar_t buf[1024];
                    (void)::swprintf (buf, NEltsOf (buf), L"%d", t);
                    return buf;
                }
                template    <typename T>
                inline  String  ToString_ (const T& t, typename enable_if<is_same<T, short int>::value>::type* = 0)
                {
                    wchar_t buf[1024];
                    (void)::swprintf (buf, NEltsOf (buf), L"%d", t);
                    return buf;
                }
                template    <typename T>
                inline  String  ToString_ (const T& t, typename enable_if<is_same<T, int>::value>::type* = 0)
                {
                    wchar_t buf[1024];
                    (void)::swprintf (buf, NEltsOf (buf), L"%d", t);
                    return buf;
                }
                template    <typename T>
                inline  String  ToString_ (const T& t, typename enable_if<is_same<T, long int>::value>::type* = 0)
                {
                    wchar_t buf[1024];
                    (void)::swprintf (buf, NEltsOf (buf), L"%ld", t);
                    return buf;
                }
                template    <typename T>
                inline  String  ToString_ (const T& t, typename enable_if<is_same<T, long long int>::value>::type* = 0)
                {
                    wchar_t buf[1024];
                    (void)::swprintf (buf, NEltsOf (buf), L"%lld", t);
                    return buf;
                }
                template    <typename T>
                inline  String  ToString_ (const T& t, typename enable_if<is_same<T, unsigned char>::value>::type* = 0)
                {
                    wchar_t buf[1024];
                    (void)::swprintf (buf, NEltsOf (buf), L"0x%ud", t);
                    return buf;
                }
                template    <typename T>
                inline  String  ToString_ (const T& t, typename enable_if<is_same<T, unsigned short>::value>::type* = 0)
                {
                    wchar_t buf[1024];
                    (void)::swprintf (buf, NEltsOf (buf), L"0x%ud", t);
                    return buf;
                }
                template    <typename T>
                inline  String  ToString_ (const T& t, typename enable_if<is_same<T, unsigned int>::value>::type* = 0)
                {
                    wchar_t buf[1024];
                    (void)::swprintf (buf, NEltsOf (buf), L"0x%ud", t);
                    return buf;
                }
                template    <typename T>
                inline  String  ToString_ (const T& t, typename enable_if<is_same<T, unsigned long>::value>::type* = 0)
                {
                    wchar_t buf[1024];
                    (void)::swprintf (buf, NEltsOf (buf), L"0x%uld", t);
                    return buf;
                }
                template    <typename T>
                inline  String  ToString_ (const T& t, typename enable_if<is_same<T, unsigned long long>::value>::type* = 0)
                {
                    wchar_t buf[1024];
                    (void)::swprintf (buf, NEltsOf (buf), L"0x%ulld", t);
                    return buf;
                }

                template    <typename T>
                inline  String  ToString_ (const T& t, typename enable_if < is_floating_point<T>::value>::type* = 0)
                {
                    return Float2String (t);
                }
            }

            template    <typename T>
            inline  String  ToString (const T& t)
            {
                return Private_::ToString_<T> (t);
            }

        }
    }
}
#endif  /*_Stroika_Foundation_Characters_ToString_inl_*/
<commit_msg>missing #include<commit_after>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2016.  All rights reserved
 */
#ifndef _Stroika_Foundation_Characters_ToString_inl_
#define _Stroika_Foundation_Characters_ToString_inl_    1

#include    <wchar.h>

#include    "../Configuration/Concepts.h"
#include    "FloatConversion.h"
#include    "StringBuilder.h"
#include    "String_Constant.h"

/*
 ********************************************************************************
 ***************************** Implementation Details ***************************
 ********************************************************************************
 */
namespace   Stroika {
    namespace   Foundation {
        namespace   Characters {

            /*
             ********************************************************************************
             ********************************* ToString *************************************
             ********************************************************************************
             */
            namespace Private_ {

                STROIKA_FOUNDATION_CONFIGURATION_DEFINE_HAS(ToString, (x.ToString ()));
                STROIKA_FOUNDATION_CONFIGURATION_DEFINE_HAS(beginenditerable, (x.begin () != x.end ()));

                template    <typename T>
                inline  String  ToString_ (const T& t, typename enable_if<has_ToString<T>::value>::type* = 0)
                {
                    return t.ToString ();
                }

                template    <typename T>
                inline  String  ToString_ (const T& t, typename enable_if<has_beginenditerable<T>::value and not is_convertible<T, String>::value>::type* = 0)
                {
                    StringBuilder sb;
                    sb << L"{";
                    bool didFirst { false };
                    for (auto i : t) {
                        if (didFirst) {
                            sb << L", ";
                        }
                        else {
                            sb << L" ";
                        }
                        sb << ToString (i);
                        didFirst = true;
                    }
                    if (didFirst) {
                        sb << L" ";
                    }
                    sb << L"}";
                    return sb.str ();
                }

                template    <typename T>
                inline  String  ToString_ (const T& t, typename enable_if<is_convertible<T, String>::value>::type* = 0)
                {
                    return static_cast<String> (t);
                }

                /*
                 * From section from section 3.9.1 of http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf
                 *      There are five standard signed integer types : signed char, short int, int,
                 *      long int, and long long int. In this list, each type provides at least as much
                 *      storage as those preceding it in the list.
                 *      For each of the standard signed integer types, there exists a corresponding (but different)
                 *      standard unsigned integer type: unsigned char, unsigned short int, unsigned int, unsigned long int,
                 *      and unsigned long long int, each of which occupies the same amount of storage and has the
                 *      same alignment requirements.
                 */
                template    <typename T>
                inline  String  ToString_ (const T& t, typename enable_if<is_same<T, bool>::value>::type* = 0)
                {
                    return t ? String_Constant { L"true" } :
                           String_Constant { L"false" };
                }
                template    <typename T>
                inline  String  ToString_ (const T& t, typename enable_if<is_same<T, signed char>::value>::type* = 0)
                {
                    wchar_t buf[1024];
                    (void)::swprintf (buf, NEltsOf (buf), L"%d", t);
                    return buf;
                }
                template    <typename T>
                inline  String  ToString_ (const T& t, typename enable_if<is_same<T, short int>::value>::type* = 0)
                {
                    wchar_t buf[1024];
                    (void)::swprintf (buf, NEltsOf (buf), L"%d", t);
                    return buf;
                }
                template    <typename T>
                inline  String  ToString_ (const T& t, typename enable_if<is_same<T, int>::value>::type* = 0)
                {
                    wchar_t buf[1024];
                    (void)::swprintf (buf, NEltsOf (buf), L"%d", t);
                    return buf;
                }
                template    <typename T>
                inline  String  ToString_ (const T& t, typename enable_if<is_same<T, long int>::value>::type* = 0)
                {
                    wchar_t buf[1024];
                    (void)::swprintf (buf, NEltsOf (buf), L"%ld", t);
                    return buf;
                }
                template    <typename T>
                inline  String  ToString_ (const T& t, typename enable_if<is_same<T, long long int>::value>::type* = 0)
                {
                    wchar_t buf[1024];
                    (void)::swprintf (buf, NEltsOf (buf), L"%lld", t);
                    return buf;
                }
                template    <typename T>
                inline  String  ToString_ (const T& t, typename enable_if<is_same<T, unsigned char>::value>::type* = 0)
                {
                    wchar_t buf[1024];
                    (void)::swprintf (buf, NEltsOf (buf), L"0x%ud", t);
                    return buf;
                }
                template    <typename T>
                inline  String  ToString_ (const T& t, typename enable_if<is_same<T, unsigned short>::value>::type* = 0)
                {
                    wchar_t buf[1024];
                    (void)::swprintf (buf, NEltsOf (buf), L"0x%ud", t);
                    return buf;
                }
                template    <typename T>
                inline  String  ToString_ (const T& t, typename enable_if<is_same<T, unsigned int>::value>::type* = 0)
                {
                    wchar_t buf[1024];
                    (void)::swprintf (buf, NEltsOf (buf), L"0x%ud", t);
                    return buf;
                }
                template    <typename T>
                inline  String  ToString_ (const T& t, typename enable_if<is_same<T, unsigned long>::value>::type* = 0)
                {
                    wchar_t buf[1024];
                    (void)::swprintf (buf, NEltsOf (buf), L"0x%uld", t);
                    return buf;
                }
                template    <typename T>
                inline  String  ToString_ (const T& t, typename enable_if<is_same<T, unsigned long long>::value>::type* = 0)
                {
                    wchar_t buf[1024];
                    (void)::swprintf (buf, NEltsOf (buf), L"0x%ulld", t);
                    return buf;
                }

                template    <typename T>
                inline  String  ToString_ (const T& t, typename enable_if < is_floating_point<T>::value>::type* = 0)
                {
                    return Float2String (t);
                }
            }

            template    <typename T>
            inline  String  ToString (const T& t)
            {
                return Private_::ToString_<T> (t);
            }

        }
    }
}
#endif  /*_Stroika_Foundation_Characters_ToString_inl_*/
<|endoftext|>