<commit_before>// 21 april 2016
#include "winapi.hpp"
#include "../ui.h"
#include "../ui_windows.h"
#include "../common/uipriv.h"
#include "resources.hpp"
#include "compilerver.hpp"

// ui internal window messages
enum {
	// redirected WM_COMMAND and WM_NOTIFY
	msgCOMMAND = WM_APP + 0x40,		// start offset just to be safe
	msgNOTIFY,
	msgHSCROLL,
	msgQueued,
	msgD2DScratchPaint,
};

// alloc.cpp
extern void initAlloc(void);
extern void uninitAlloc(void);

// events.cpp
extern BOOL runWM_COMMAND(WPARAM wParam, LPARAM lParam, LRESULT *lResult);
extern BOOL runWM_NOTIFY(WPARAM wParam, LPARAM lParam, LRESULT *lResult);
extern BOOL runWM_HSCROLL(WPARAM wParam, LPARAM lParam, LRESULT *lResult);
extern void issueWM_WININICHANGE(WPARAM wParam, LPARAM lParam);

// utf16.cpp
#define emptyUTF16() ((WCHAR *) uiAlloc(1 * sizeof (WCHAR), "WCHAR[]"))
#define emptyUTF8() ((char *) uiAlloc(1 * sizeof (char), "char[]"))
extern WCHAR *toUTF16(const char *str);
extern char *toUTF8(const WCHAR *wstr);
extern WCHAR *utf16dup(const WCHAR *orig);
extern WCHAR *strf(const WCHAR *format, ...);
extern WCHAR *vstrf(const WCHAR *format, va_list ap);
extern WCHAR *debugstrf(const WCHAR *format, ...);
extern WCHAR *debugvstrf(const WCHAR *format, va_list ap);
extern char *LFtoCRLF(const char *lfonly);
extern void CRLFtoLF(const char *s);

// debug.cpp
// see http://stackoverflow.com/questions/14421656/is-there-widely-available-wide-character-variant-of-file
// we turn __LINE__ into a string because PRIiMAX can't be converted to a wide string in MSVC (it seems to be defined as "ll" "i" according to the compiler errors)
// also note the use of __FUNCTION__ here; __func__ doesn't seem to work for some reason
#define _ws2(m) L ## m
#define _ws(m) _ws2(m)
#define _ws2n(m) L ## #m
#define _wsn(m) _ws2n(m)
#define debugargs const WCHAR *file, const WCHAR *line, const WCHAR *func
extern HRESULT _logLastError(debugargs, const WCHAR *s);
#define logLastError(s) _logLastError(_ws(__FILE__), _wsn(__LINE__), _ws(__FUNCTION__), s)
extern HRESULT _logHRESULT(debugargs, const WCHAR *s, HRESULT hr);
#define logHRESULT(s, hr) _logHRESULT(_ws(__FILE__), _wsn(__LINE__), _ws(__FUNCTION__), s, hr)
extern void _implbug(debugargs, const WCHAR *format, ...);
#define implbug(...) _implbug(_ws(__FILE__), _wsn(__LINE__), _ws(__FUNCTION__), __VA_ARGS__)

// winutil.cpp
extern int windowClassOf(HWND hwnd, ...);
extern void mapWindowRect(HWND from, HWND to, RECT *r);
extern DWORD getStyle(HWND hwnd);
extern void setStyle(HWND hwnd, DWORD style);
extern DWORD getExStyle(HWND hwnd);
extern void setExStyle(HWND hwnd, DWORD exstyle);
extern void clientSizeToWindowSize(HWND hwnd, intmax_t *width, intmax_t *height, BOOL hasMenubar);
extern HWND parentOf(HWND child);
extern HWND parentToplevel(HWND child);
extern void setWindowInsertAfter(HWND hwnd, HWND insertAfter);
extern void getClientRect(HWND, RECT *);
extern void getWindowRect(HWND, RECT *);

// text.cpp
extern WCHAR *windowTextAndLen(HWND hwnd, LRESULT *len);
extern WCHAR *windowText(HWND hwnd);
extern void setWindowText(HWND hwnd, WCHAR *wtext);

// init.cpp
extern HINSTANCE hInstance;
extern int nCmdShow;
extern HFONT hMessageFont;
extern HBRUSH hollowBrush;
extern uiInitOptions options;

// utilwin.cpp
extern HWND utilWindow;
extern const char *initUtilWindow(HICON hDefaultIcon, HCURSOR hDefaultCursor);
extern void uninitUtilWindow(void);

// main.cpp
extern int registerMessageFilter(void);
extern void unregisterMessageFilter(void);

// parent.cpp
extern void paintContainerBackground(HWND hwnd, HDC dc, RECT *paintRect);
extern BOOL handleParentMessages(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *lResult);

// d2dscratch.cpp
extern ATOM registerD2DScratchClass(HICON hDefaultIcon, HCURSOR hDefaultCursor);
extern void unregisterD2DScratchClass(void);
extern HWND newD2DScratch(HWND parent, RECT *rect, HMENU controlID, SUBCLASSPROC subclass, DWORD_PTR subclassData);

// area.cpp
#define areaClass L"libui_uiAreaClass"
extern ATOM registerAreaClass(HICON, HCURSOR);
extern void unregisterArea(void);

// areaevents.cpp
extern BOOL areaFilter(MSG *);

// window.cpp
extern ATOM registerWindowClass(HICON, HCURSOR);
extern void unregisterWindowClass(void);
extern void ensureMinimumWindowSize(uiWindow *);

// container.cpp
#define containerClass L"libui_uiContainerClass"
extern ATOM initContainer(HICON, HCURSOR);
extern void uninitContainer(void);

// TODO
#include "_uipriv_migrate.hpp"

// TODO
// child.cpp
extern struct child *newChild(uiControl *child, uiControl *parent, HWND parentHWND);
extern struct child *newChildWithTabPage(uiControl *child, uiControl *parent, HWND parentHWND);
extern void childRemove(struct child *c);
extern void childDestroy(struct child *c);
extern HWND childHWND(struct child *c);
extern void childMinimumSize(struct child *c, uiWindowsSizing *d, intmax_t *width, intmax_t *height);
extern void childRelayout(struct child *c, intmax_t x, intmax_t y, intmax_t width, intmax_t height);
extern void childQueueRelayout(struct child *c);
extern int childVisible(struct child *c);
extern void childUpdateState(struct child *c);
extern void childAssignControlIDZOrder(struct child *c, LONG_PTR *controlID, HWND *insertAfter);
extern void childSetSoleControlID(struct child *c);
extern HWND childTabPage(struct child *c);
extern int childMargined(struct child *c);
extern void childSetMargined(struct child *c, int margined);
extern int childFlag(struct child *c);
extern void childSetFlag(struct child *c, int flag);
extern intmax_t childIntmax(struct child *c, int n);
extern void childSetIntmax(struct child *c, int n, intmax_t to);
<commit_msg>More TODOs.<commit_after>// 21 april 2016
#include "winapi.hpp"
#include "../ui.h"
#include "../ui_windows.h"
#include "../common/uipriv.h"
#include "resources.hpp"
#include "compilerver.hpp"

// ui internal window messages
enum {
	// redirected WM_COMMAND and WM_NOTIFY
	msgCOMMAND = WM_APP + 0x40,		// start offset just to be safe
	msgNOTIFY,
	msgHSCROLL,
	msgQueued,
	// TODO convert to a function like with container
	msgD2DScratchPaint,
};

// alloc.cpp
extern void initAlloc(void);
extern void uninitAlloc(void);

// events.cpp
extern BOOL runWM_COMMAND(WPARAM wParam, LPARAM lParam, LRESULT *lResult);
extern BOOL runWM_NOTIFY(WPARAM wParam, LPARAM lParam, LRESULT *lResult);
extern BOOL runWM_HSCROLL(WPARAM wParam, LPARAM lParam, LRESULT *lResult);
extern void issueWM_WININICHANGE(WPARAM wParam, LPARAM lParam);

// utf16.cpp
#define emptyUTF16() ((WCHAR *) uiAlloc(1 * sizeof (WCHAR), "WCHAR[]"))
#define emptyUTF8() ((char *) uiAlloc(1 * sizeof (char), "char[]"))
extern WCHAR *toUTF16(const char *str);
extern char *toUTF8(const WCHAR *wstr);
extern WCHAR *utf16dup(const WCHAR *orig);
extern WCHAR *strf(const WCHAR *format, ...);
extern WCHAR *vstrf(const WCHAR *format, va_list ap);
extern WCHAR *debugstrf(const WCHAR *format, ...);
extern WCHAR *debugvstrf(const WCHAR *format, va_list ap);
extern char *LFtoCRLF(const char *lfonly);
extern void CRLFtoLF(const char *s);

// debug.cpp
// see http://stackoverflow.com/questions/14421656/is-there-widely-available-wide-character-variant-of-file
// we turn __LINE__ into a string because PRIiMAX can't be converted to a wide string in MSVC (it seems to be defined as "ll" "i" according to the compiler errors)
// also note the use of __FUNCTION__ here; __func__ doesn't seem to work for some reason
#define _ws2(m) L ## m
#define _ws(m) _ws2(m)
#define _ws2n(m) L ## #m
#define _wsn(m) _ws2n(m)
#define debugargs const WCHAR *file, const WCHAR *line, const WCHAR *func
extern HRESULT _logLastError(debugargs, const WCHAR *s);
#define logLastError(s) _logLastError(_ws(__FILE__), _wsn(__LINE__), _ws(__FUNCTION__), s)
extern HRESULT _logHRESULT(debugargs, const WCHAR *s, HRESULT hr);
#define logHRESULT(s, hr) _logHRESULT(_ws(__FILE__), _wsn(__LINE__), _ws(__FUNCTION__), s, hr)
extern void _implbug(debugargs, const WCHAR *format, ...);
#define implbug(...) _implbug(_ws(__FILE__), _wsn(__LINE__), _ws(__FUNCTION__), __VA_ARGS__)

// winutil.cpp
extern int windowClassOf(HWND hwnd, ...);
extern void mapWindowRect(HWND from, HWND to, RECT *r);
extern DWORD getStyle(HWND hwnd);
extern void setStyle(HWND hwnd, DWORD style);
extern DWORD getExStyle(HWND hwnd);
extern void setExStyle(HWND hwnd, DWORD exstyle);
extern void clientSizeToWindowSize(HWND hwnd, intmax_t *width, intmax_t *height, BOOL hasMenubar);
extern HWND parentOf(HWND child);
extern HWND parentToplevel(HWND child);
extern void setWindowInsertAfter(HWND hwnd, HWND insertAfter);
extern void getClientRect(HWND, RECT *);
extern void getWindowRect(HWND, RECT *);

// text.cpp
extern WCHAR *windowTextAndLen(HWND hwnd, LRESULT *len);
extern WCHAR *windowText(HWND hwnd);
extern void setWindowText(HWND hwnd, WCHAR *wtext);

// init.cpp
extern HINSTANCE hInstance;
extern int nCmdShow;
extern HFONT hMessageFont;
extern HBRUSH hollowBrush;
extern uiInitOptions options;

// utilwin.cpp
extern HWND utilWindow;
extern const char *initUtilWindow(HICON hDefaultIcon, HCURSOR hDefaultCursor);
extern void uninitUtilWindow(void);

// main.cpp
extern int registerMessageFilter(void);
extern void unregisterMessageFilter(void);

// parent.cpp
extern void paintContainerBackground(HWND hwnd, HDC dc, RECT *paintRect);
extern BOOL handleParentMessages(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *lResult);

// d2dscratch.cpp
extern ATOM registerD2DScratchClass(HICON hDefaultIcon, HCURSOR hDefaultCursor);
extern void unregisterD2DScratchClass(void);
extern HWND newD2DScratch(HWND parent, RECT *rect, HMENU controlID, SUBCLASSPROC subclass, DWORD_PTR subclassData);

// area.cpp
#define areaClass L"libui_uiAreaClass"
extern ATOM registerAreaClass(HICON, HCURSOR);
extern void unregisterArea(void);

// areaevents.cpp
extern BOOL areaFilter(MSG *);

// window.cpp
extern ATOM registerWindowClass(HICON, HCURSOR);
extern void unregisterWindowClass(void);
extern void ensureMinimumWindowSize(uiWindow *);

// container.cpp
#define containerClass L"libui_uiContainerClass"
extern ATOM initContainer(HICON, HCURSOR);
extern void uninitContainer(void);

// TODO
#include "_uipriv_migrate.hpp"

// TODO
// child.cpp
extern struct child *newChild(uiControl *child, uiControl *parent, HWND parentHWND);
extern struct child *newChildWithTabPage(uiControl *child, uiControl *parent, HWND parentHWND);
extern void childRemove(struct child *c);
extern void childDestroy(struct child *c);
extern HWND childHWND(struct child *c);
extern void childMinimumSize(struct child *c, uiWindowsSizing *d, intmax_t *width, intmax_t *height);
extern void childRelayout(struct child *c, intmax_t x, intmax_t y, intmax_t width, intmax_t height);
extern void childQueueRelayout(struct child *c);
extern int childVisible(struct child *c);
extern void childUpdateState(struct child *c);
extern void childAssignControlIDZOrder(struct child *c, LONG_PTR *controlID, HWND *insertAfter);
extern void childSetSoleControlID(struct child *c);
extern HWND childTabPage(struct child *c);
extern int childMargined(struct child *c);
extern void childSetMargined(struct child *c, int margined);
extern int childFlag(struct child *c);
extern void childSetFlag(struct child *c, int flag);
extern intmax_t childIntmax(struct child *c, int n);
extern void childSetIntmax(struct child *c, int n, intmax_t to);
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: FNumericFunctions.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 05:56:06 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#include <cmath>
#include "file/FNumericFunctions.hxx"
#include <rtl/math.hxx>

using namespace connectivity;
using namespace connectivity::file;
//------------------------------------------------------------------
ORowSetValue OOp_Abs::operate(const ORowSetValue& lhs) const
{
    if ( lhs.isNull() )
        return lhs;

    double nVal(lhs);
    if ( nVal < 0 )
        nVal *= -1.0;
    return fabs(nVal);
}
//------------------------------------------------------------------
ORowSetValue OOp_Sign::operate(const ORowSetValue& lhs) const
{
    if ( lhs.isNull() )
        return lhs;

    sal_Int32 nRet = 0;
    double nVal(lhs);
    if ( nVal < 0 )
        nRet = -1;
    else if ( nVal > 0 )
        nRet = 1;

    return nRet;
}
//------------------------------------------------------------------
ORowSetValue OOp_Mod::operate(const ORowSetValue& lhs,const ORowSetValue& rhs) const
{
    if ( lhs.isNull() || rhs.isNull() )
        return ORowSetValue();

    return fmod((double)lhs,(double)rhs);
}
//------------------------------------------------------------------
ORowSetValue OOp_Floor::operate(const ORowSetValue& lhs) const
{
    if ( lhs.isNull() )
        return lhs;

    return floor((double)lhs);
}
// -----------------------------------------------------------------------------
ORowSetValue OOp_Ceiling::operate(const ORowSetValue& lhs) const
{
    if ( lhs.isNull() )
        return lhs;

    double nVal(lhs);
    return ceil(nVal);
}
// -----------------------------------------------------------------------------
ORowSetValue OOp_Round::operate(const ::std::vector<ORowSetValue>& lhs) const
{
    if ( lhs.empty() || lhs.size() > 2 )
        return ORowSetValue();

    size_t nSize = lhs.size();
    double nVal = lhs[nSize-1];

    sal_Int32 nDec = 0;
    if ( nSize == 2 && !lhs[0].isNull() )
        nDec = lhs[0];
    return ::rtl::math::round(nVal,nDec);
}
// -----------------------------------------------------------------------------
ORowSetValue OOp_Exp::operate(const ORowSetValue& lhs) const
{
    if ( lhs.isNull() )
        return lhs;

    double nVal(lhs);
    return exp(nVal);
}
// -----------------------------------------------------------------------------
ORowSetValue OOp_Ln::operate(const ORowSetValue& lhs) const
{
    if ( lhs.isNull() || static_cast<double>(lhs) < 0.0 )
        return lhs;

    double nVal(lhs);
    nVal = log(nVal);
    if ( rtl::math::isNan(nVal) )
        return ORowSetValue();
    return nVal;
}
// -----------------------------------------------------------------------------
ORowSetValue OOp_Log::operate(const ::std::vector<ORowSetValue>& lhs) const
{
    if ( lhs.empty() || lhs.size() > 2 )
        return ORowSetValue();
    size_t nSize = lhs.size();
    double nVal = log( (double)lhs[nSize-1] );

    if ( nSize == 2 && !lhs[0].isNull() )
        nVal /= log((double)lhs[0]);

    if ( rtl::math::isNan(nVal) )
        return ORowSetValue();
    return nVal;
}
// -----------------------------------------------------------------------------
ORowSetValue OOp_Log10::operate(const ORowSetValue& lhs) const
{
    if ( lhs.isNull() || static_cast<double>(lhs) < 0.0 )
        return lhs;

    double nVal = log((double)lhs);
    if ( rtl::math::isNan(nVal) )
        return ORowSetValue();
    nVal /= log(10.0);
    return nVal;
}
// -----------------------------------------------------------------------------
ORowSetValue OOp_Pow::operate(const ORowSetValue& lhs,const ORowSetValue& rhs) const
{
    if ( lhs.isNull() || rhs.isNull() )
        return lhs;

    return pow((double)lhs,(double)rhs);
}
//------------------------------------------------------------------
ORowSetValue OOp_Sqrt::operate(const ORowSetValue& lhs) const
{
    if ( lhs.isNull() )
        return lhs;

    double nVal = sqrt((double)lhs);
    if ( rtl::math::isNan(nVal) )
        return ORowSetValue();
    return nVal;
}
// -----------------------------------------------------------------------------
ORowSetValue OOp_Pi::operate(const ::std::vector<ORowSetValue>& lhs) const
{
    return 3.141592653589793116;
}
// -----------------------------------------------------------------------------
ORowSetValue OOp_Cos::operate(const ORowSetValue& lhs) const
{
    if ( lhs.isNull() )
        return lhs;

    return cos((double)lhs);
}
// -----------------------------------------------------------------------------
ORowSetValue OOp_Sin::operate(const ORowSetValue& lhs) const
{
    if ( lhs.isNull() )
        return lhs;

    return sin((double)lhs);
}
// -----------------------------------------------------------------------------
ORowSetValue OOp_Tan::operate(const ORowSetValue& lhs) const
{
    if ( lhs.isNull() )
        return lhs;

    return tan((double)lhs);
}
// -----------------------------------------------------------------------------
ORowSetValue OOp_ACos::operate(const ORowSetValue& lhs) const
{
    if ( lhs.isNull() )
        return lhs;

    return acos((double)lhs);
}
// -----------------------------------------------------------------------------
ORowSetValue OOp_ASin::operate(const ORowSetValue& lhs) const
{
    if ( lhs.isNull() )
        return lhs;

    return asin((double)lhs);
}
// -----------------------------------------------------------------------------
ORowSetValue OOp_ATan::operate(const ORowSetValue& lhs) const
{
    if ( lhs.isNull() )
        return lhs;

    return atan((double)lhs);
}
// -----------------------------------------------------------------------------
ORowSetValue OOp_ATan2::operate(const ORowSetValue& lhs,const ORowSetValue& rhs) const
{
    if ( lhs.isNull() || rhs.isNull() )
        return lhs;

    return atan2((double)lhs,(double)rhs);
}
// -----------------------------------------------------------------------------
ORowSetValue OOp_Degrees::operate(const ORowSetValue& lhs) const
{
    if ( lhs.isNull() )
        return lhs;

    double nLhs = lhs;
    return nLhs*180*(1.0/3.141592653589793116);
}
// -----------------------------------------------------------------------------
ORowSetValue OOp_Radians::operate(const ORowSetValue& lhs) const
{
    if ( lhs.isNull() )
        return lhs;

    double nLhs = lhs;
    return nLhs*3.141592653589793116*(1.0/180.0);
}
// -----------------------------------------------------------------------------
<commit_msg>INTEGRATION: CWS warnings01 (1.5.30); FILE MERGED 2005/11/16 12:59:01 fs 1.5.30.1: #i57457# warning free code<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: FNumericFunctions.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-20 01:25:40 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#include <cmath>
#include "file/FNumericFunctions.hxx"
#include <rtl/math.hxx>

using namespace connectivity;
using namespace connectivity::file;
//------------------------------------------------------------------
ORowSetValue OOp_Abs::operate(const ORowSetValue& lhs) const
{
    if ( lhs.isNull() )
        return lhs;

    double nVal(lhs);
    if ( nVal < 0 )
        nVal *= -1.0;
    return fabs(nVal);
}
//------------------------------------------------------------------
ORowSetValue OOp_Sign::operate(const ORowSetValue& lhs) const
{
    if ( lhs.isNull() )
        return lhs;

    sal_Int32 nRet = 0;
    double nVal(lhs);
    if ( nVal < 0 )
        nRet = -1;
    else if ( nVal > 0 )
        nRet = 1;

    return nRet;
}
//------------------------------------------------------------------
ORowSetValue OOp_Mod::operate(const ORowSetValue& lhs,const ORowSetValue& rhs) const
{
    if ( lhs.isNull() || rhs.isNull() )
        return ORowSetValue();

    return fmod((double)lhs,(double)rhs);
}
//------------------------------------------------------------------
ORowSetValue OOp_Floor::operate(const ORowSetValue& lhs) const
{
    if ( lhs.isNull() )
        return lhs;

    return floor((double)lhs);
}
// -----------------------------------------------------------------------------
ORowSetValue OOp_Ceiling::operate(const ORowSetValue& lhs) const
{
    if ( lhs.isNull() )
        return lhs;

    double nVal(lhs);
    return ceil(nVal);
}
// -----------------------------------------------------------------------------
ORowSetValue OOp_Round::operate(const ::std::vector<ORowSetValue>& lhs) const
{
    if ( lhs.empty() || lhs.size() > 2 )
        return ORowSetValue();

    size_t nSize = lhs.size();
    double nVal = lhs[nSize-1];

    sal_Int32 nDec = 0;
    if ( nSize == 2 && !lhs[0].isNull() )
        nDec = lhs[0];
    return ::rtl::math::round(nVal,nDec);
}
// -----------------------------------------------------------------------------
ORowSetValue OOp_Exp::operate(const ORowSetValue& lhs) const
{
    if ( lhs.isNull() )
        return lhs;

    double nVal(lhs);
    return exp(nVal);
}
// -----------------------------------------------------------------------------
ORowSetValue OOp_Ln::operate(const ORowSetValue& lhs) const
{
    if ( lhs.isNull() || static_cast<double>(lhs) < 0.0 )
        return lhs;

    double nVal(lhs);
    nVal = log(nVal);
    if ( rtl::math::isNan(nVal) )
        return ORowSetValue();
    return nVal;
}
// -----------------------------------------------------------------------------
ORowSetValue OOp_Log::operate(const ::std::vector<ORowSetValue>& lhs) const
{
    if ( lhs.empty() || lhs.size() > 2 )
        return ORowSetValue();
    size_t nSize = lhs.size();
    double nVal = log( (double)lhs[nSize-1] );

    if ( nSize == 2 && !lhs[0].isNull() )
        nVal /= log((double)lhs[0]);

    if ( rtl::math::isNan(nVal) )
        return ORowSetValue();
    return nVal;
}
// -----------------------------------------------------------------------------
ORowSetValue OOp_Log10::operate(const ORowSetValue& lhs) const
{
    if ( lhs.isNull() || static_cast<double>(lhs) < 0.0 )
        return lhs;

    double nVal = log((double)lhs);
    if ( rtl::math::isNan(nVal) )
        return ORowSetValue();
    nVal /= log(10.0);
    return nVal;
}
// -----------------------------------------------------------------------------
ORowSetValue OOp_Pow::operate(const ORowSetValue& lhs,const ORowSetValue& rhs) const
{
    if ( lhs.isNull() || rhs.isNull() )
        return lhs;

    return pow((double)lhs,(double)rhs);
}
//------------------------------------------------------------------
ORowSetValue OOp_Sqrt::operate(const ORowSetValue& lhs) const
{
    if ( lhs.isNull() )
        return lhs;

    double nVal = sqrt((double)lhs);
    if ( rtl::math::isNan(nVal) )
        return ORowSetValue();
    return nVal;
}
// -----------------------------------------------------------------------------
ORowSetValue OOp_Pi::operate(const ::std::vector<ORowSetValue>& /*lhs*/) const
{
    return 3.141592653589793116;
}
// -----------------------------------------------------------------------------
ORowSetValue OOp_Cos::operate(const ORowSetValue& lhs) const
{
    if ( lhs.isNull() )
        return lhs;

    return cos((double)lhs);
}
// -----------------------------------------------------------------------------
ORowSetValue OOp_Sin::operate(const ORowSetValue& lhs) const
{
    if ( lhs.isNull() )
        return lhs;

    return sin((double)lhs);
}
// -----------------------------------------------------------------------------
ORowSetValue OOp_Tan::operate(const ORowSetValue& lhs) const
{
    if ( lhs.isNull() )
        return lhs;

    return tan((double)lhs);
}
// -----------------------------------------------------------------------------
ORowSetValue OOp_ACos::operate(const ORowSetValue& lhs) const
{
    if ( lhs.isNull() )
        return lhs;

    return acos((double)lhs);
}
// -----------------------------------------------------------------------------
ORowSetValue OOp_ASin::operate(const ORowSetValue& lhs) const
{
    if ( lhs.isNull() )
        return lhs;

    return asin((double)lhs);
}
// -----------------------------------------------------------------------------
ORowSetValue OOp_ATan::operate(const ORowSetValue& lhs) const
{
    if ( lhs.isNull() )
        return lhs;

    return atan((double)lhs);
}
// -----------------------------------------------------------------------------
ORowSetValue OOp_ATan2::operate(const ORowSetValue& lhs,const ORowSetValue& rhs) const
{
    if ( lhs.isNull() || rhs.isNull() )
        return lhs;

    return atan2((double)lhs,(double)rhs);
}
// -----------------------------------------------------------------------------
ORowSetValue OOp_Degrees::operate(const ORowSetValue& lhs) const
{
    if ( lhs.isNull() )
        return lhs;

    double nLhs = lhs;
    return nLhs*180*(1.0/3.141592653589793116);
}
// -----------------------------------------------------------------------------
ORowSetValue OOp_Radians::operate(const ORowSetValue& lhs) const
{
    if ( lhs.isNull() )
        return lhs;

    double nLhs = lhs;
    return nLhs*3.141592653589793116*(1.0/180.0);
}
// -----------------------------------------------------------------------------
<|endoftext|>


<commit_before>#include <algorithm>

#include "ParamRenderArea.h"

#include <QPainter>
#include <QKeyEvent>
#include <iostream>

ParamRenderArea::ParamRenderArea(const QPainterPath &path, QWidget *parent)
        : QWidget(parent), path(path) {
    penWidth = 0.1f;
    rotationAngle = 0;
    offset.setX(50);
    offset.setY(50);
    triangulation = std::vector<ParameterTriangle *>();
    setBackgroundRole(QPalette::Base);
    std::random_shuffle(colors.begin(), colors.end());
}

QSize ParamRenderArea::minimumSizeHint() const {
    return QSize(50, 50);
}

QSize ParamRenderArea::sizeHint() const {
    return QSize(100, 100);
}

void ParamRenderArea::setPenWidth(float width) {
    penWidth = width;
    update();
}

void ParamRenderArea::setPenColor(const QColor &color) {
    penColor = color;
    update();
}

void ParamRenderArea::paintEvent(QPaintEvent *) {
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
    painter.scale(width() / 100.0, height() / 100.0);
    painter.translate(offset);
    painter.rotate(-rotationAngle);
    painter.translate(-offset);
    painter.setPen(QPen(penColor, penWidth, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));

    int colorID = 0;

    // draw all shapes
    for (QList<QPointF> sha : shapeList) {
        QLinearGradient g(0, 0, 0, 100);
        g.setColorAt(0.0, colors.at(colorID));
        g.setColorAt(1.0, colors.at(colorID));
        painter.setBrush(g);
        QPainterPath tP;
        tP.moveTo(sha.first());
        for (int i = 0; i < sha.size(); ++i) {
            tP.lineTo(sha.at(i));
        }
        painter.drawPath(tP);
        colorID = (colorID + 1) % colors.size();
    }

    // draw current path
    QLinearGradient gradient(0, 0, 0, 100);
    gradient.setColorAt(0.0, colors.at(colorID));
    gradient.setColorAt(1.0, colors.at(colorID));
    painter.setBrush(gradient);
    painter.drawPath(path);

    // draw parameter triangulation
    QPainter trip(this);
    trip.setRenderHint(QPainter::Antialiasing);
    trip.scale(width() / 100.0, height() / 100.0);
    trip.translate(offset);
    trip.rotate(-rotationAngle);
    trip.translate(-offset);
    trip.setPen(QPen(Qt::black, 1.0f * penWidth, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
    for (ParameterTriangle *t : triangulation) {
        QPainterPath tP;
        tP.moveTo(denormalize(t->getPoint(0)));
        tP.lineTo(denormalize(t->getPoint(1)));
        tP.lineTo(denormalize(t->getPoint(2)));
        tP.lineTo(denormalize(t->getPoint(0)));
        trip.drawPath(tP);
    }
}

void ParamRenderArea::mousePressEvent(QMouseEvent *event) {
    QPointF pos = convertPos(event);
    if (event->button() == Qt::RightButton) {
        QList<QPointF> shape;
        std::copy(waypoints.begin(), waypoints.end(), std::back_inserter(shape));
        path = QPainterPath();
        waypoints.clear();
    } else {
        waypoints.push_back(pos);
        path = QPainterPath();
        path.moveTo(waypoints[0]);
        for (int i = 1; i < waypoints.size(); ++i) {
            path.lineTo(waypoints[i]);
        }
        path.closeSubpath();
    }
    update();
}

QPointF ParamRenderArea::convertPos(QMouseEvent *e) {
    return QPointF(100 * e->x() / width(), 100 * e->y() / height());
}

QList<QList<QPointF> > ParamRenderArea::getShapes() {
    if (shapeList.isEmpty()) {
        QList<QPointF> s;
        s.push_back(denormalize(QVector2D(0.0f, 0.0f)));
        s.push_back(denormalize(QVector2D(1.0f, 0.0f)));
        s.push_back(denormalize(QVector2D(1.0f, 1.0f)));
        s.push_back(denormalize(QVector2D(0.0f, 1.0f)));
        shapeList.append(s);
    }
    return shapeList;
}

void ParamRenderArea::keyPressEvent(QKeyEvent *event) {
    switch (event->key()) {
        case Qt::Key_Backspace:
            removeLastWaypoint();
            break;
        case Qt::Key_Return:
            saveCurrentShape();
            break;
        default:
            break;
    }
}

void ParamRenderArea::removeLastWaypoint() {
    if (!waypoints.empty()) {
        waypoints.pop_back();
    }
    if (!waypoints.empty()) {
        path = QPainterPath();
        path.moveTo(waypoints[0]);
        for (int i = 1; i < waypoints.size(); ++i) {
            path.lineTo(waypoints[i]);
        }
        path.closeSubpath();
    }
    update();
}

void ParamRenderArea::saveCurrentShape() {
    QPainterPath p;
    if (!waypoints.empty()) {
        p.moveTo(waypoints[0]);
        for (int i = 1; i < waypoints.size(); ++i) {
            p.lineTo(waypoints[i]);
        }
        p.closeSubpath();
    }
    QList<QPointF> wp;
    for (QPointF po : waypoints) {
        wp.push_back(po);
    }
    shapeList.append(wp);
    waypoints.clear();
}

void ParamRenderArea::clearShapes() {
    shapeList.clear();
    waypoints.clear();
    triangulation.clear();
    update();
}

void ParamRenderArea::mouseDoubleClickEvent(QMouseEvent *event) { }

void ParamRenderArea::drawTriangulation(std::vector<ParameterTriangle *> triangulation_) {
    triangulation = triangulation_;
    update();
}

QPointF ParamRenderArea::denormalize(QVector2D v) {
    return QPointF(100.0f * v.x(), 100.0f - 100.f * v.y());
}

<commit_msg>added random waypoint manipulation for evoiding dificult cases.<commit_after>#include <algorithm>

#include "ParamRenderArea.h"

#include <QPainter>
#include <QKeyEvent>
#include <iostream>

ParamRenderArea::ParamRenderArea(const QPainterPath &path, QWidget *parent)
        : QWidget(parent), path(path) {
    penWidth = 0.1f;
    rotationAngle = 0;
    offset.setX(50);
    offset.setY(50);
    triangulation = std::vector<ParameterTriangle *>();
    setBackgroundRole(QPalette::Base);
    std::random_shuffle(colors.begin(), colors.end());
}

QSize ParamRenderArea::minimumSizeHint() const {
    return QSize(50, 50);
}

QSize ParamRenderArea::sizeHint() const {
    return QSize(100, 100);
}

void ParamRenderArea::setPenWidth(float width) {
    penWidth = width;
    update();
}

void ParamRenderArea::setPenColor(const QColor &color) {
    penColor = color;
    update();
}

void ParamRenderArea::paintEvent(QPaintEvent *) {
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
    painter.scale(width() / 100.0, height() / 100.0);
    painter.translate(offset);
    painter.rotate(-rotationAngle);
    painter.translate(-offset);
    painter.setPen(QPen(penColor, penWidth, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));

    int colorID = 0;

    // draw all shapes
    for (QList<QPointF> sha : shapeList) {
        QLinearGradient g(0, 0, 0, 100);
        g.setColorAt(0.0, colors.at(colorID));
        g.setColorAt(1.0, colors.at(colorID));
        painter.setBrush(g);
        QPainterPath tP;
        tP.moveTo(sha.first());
        for (int i = 0; i < sha.size(); ++i) {
            tP.lineTo(sha.at(i));
        }
        painter.drawPath(tP);
        colorID = (colorID + 1) % colors.size();
    }

    // draw current path
    QLinearGradient gradient(0, 0, 0, 100);
    gradient.setColorAt(0.0, colors.at(colorID));
    gradient.setColorAt(1.0, colors.at(colorID));
    painter.setBrush(gradient);
    painter.drawPath(path);

    // draw parameter triangulation
    QPainter trip(this);
    trip.setRenderHint(QPainter::Antialiasing);
    trip.scale(width() / 100.0, height() / 100.0);
    trip.translate(offset);
    trip.rotate(-rotationAngle);
    trip.translate(-offset);
    trip.setPen(QPen(Qt::black, 1.0f * penWidth, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
    for (ParameterTriangle *t : triangulation) {
        QPainterPath tP;
        tP.moveTo(denormalize(t->getPoint(0)));
        tP.lineTo(denormalize(t->getPoint(1)));
        tP.lineTo(denormalize(t->getPoint(2)));
        tP.lineTo(denormalize(t->getPoint(0)));
        trip.drawPath(tP);
    }
}

void ParamRenderArea::mousePressEvent(QMouseEvent *event) {
    QPointF pos = convertPos(event);
    if (event->button() == Qt::RightButton) {
        QList<QPointF> shape;
        std::copy(waypoints.begin(), waypoints.end(), std::back_inserter(shape));
        path = QPainterPath();
        waypoints.clear();
    } else {
        waypoints.push_back(pos);
        path = QPainterPath();
        path.moveTo(waypoints[0]);
        for (int i = 1; i < waypoints.size(); ++i) {
            path.lineTo(waypoints[i]);
        }
        path.closeSubpath();
    }
    update();
}

QPointF ParamRenderArea::convertPos(QMouseEvent *e) {
    return QPointF(100 * e->x() / width(), 100 * e->y() / height());
}

QList<QList<QPointF> > ParamRenderArea::getShapes() {
    if (shapeList.isEmpty()) {
        QList<QPointF> s;
        s.push_back(denormalize(QVector2D(0.0f, 0.0f)));
        s.push_back(denormalize(QVector2D(1.0f, 0.0f)));
        s.push_back(denormalize(QVector2D(1.0f, 1.0f)));
        s.push_back(denormalize(QVector2D(0.0f, 1.0f)));
        shapeList.append(s);
    }
    return shapeList;
}

void ParamRenderArea::keyPressEvent(QKeyEvent *event) {
    switch (event->key()) {
        case Qt::Key_Backspace:
            removeLastWaypoint();
            break;
        case Qt::Key_Return:
            saveCurrentShape();
            break;
        default:
            break;
    }
}

void ParamRenderArea::removeLastWaypoint() {
    if (!waypoints.empty()) {
        waypoints.pop_back();
    }
    if (!waypoints.empty()) {
        path = QPainterPath();
        path.moveTo(waypoints[0]);
        for (int i = 1; i < waypoints.size(); ++i) {
            path.lineTo(waypoints[i]);
        }
        path.closeSubpath();
    }
    update();
}

void ParamRenderArea::saveCurrentShape() {
    QPainterPath p;
    if (!waypoints.empty()) {
        waypoints[0].setY(waypoints[0].y()+0.001*((rand()%19)-9));
        p.moveTo(waypoints[0]);
        for (int i = 1; i < waypoints.size(); ++i) {
            waypoints[i].setY(waypoints[i].y()+0.001*((rand()%19)-9));
            p.lineTo(waypoints[i]);
        }
        p.closeSubpath();
    }
    QList<QPointF> wp;
    for (QPointF po : waypoints) {
        wp.push_back(po);
    }
    shapeList.append(wp);
    waypoints.clear();
}

void ParamRenderArea::clearShapes() {
    shapeList.clear();
    waypoints.clear();
    triangulation.clear();
    update();
}

void ParamRenderArea::mouseDoubleClickEvent(QMouseEvent *event) { }

void ParamRenderArea::drawTriangulation(std::vector<ParameterTriangle *> triangulation_) {
    triangulation = triangulation_;
    update();
}

QPointF ParamRenderArea::denormalize(QVector2D v) {
    return QPointF(100.0f * v.x(), 100.0f - 100.f * v.y());
}

<|endoftext|>


<commit_before>//
// Copyright (c) 2008-2014 the Urho3D project.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//

#include "Precompiled.h"
#include "Camera.h"
#include "Context.h"
#include "Drawable2D.h"
#include "Geometry.h"
#include "GraphicsEvents.h"
#include "IndexBuffer.h"
#include "Log.h"
#include "Material.h"
#include "Node.h"
#include "Profiler.h"
#include "Renderer2D.h"
#include "Scene.h"
#include "Sort.h"
#include "Technique.h"
#include "Texture2D.h"
#include "VertexBuffer.h"
#include "WorkQueue.h"

#include "DebugNew.h"

namespace Urho3D
{

extern const char* blendModeNames[];

Renderer2D::Renderer2D(Context* context) :
    Drawable(context, DRAWABLE_GEOMETRY),
    indexBuffer_(new IndexBuffer(context_)),
    vertexBuffer_(new VertexBuffer(context_)),
    orderDirty_(true),
    frustum_(0),
    indexCount_(0),
    vertexCount_(0)
{
    SubscribeToEvent(E_BEGINVIEWUPDATE, HANDLER(Renderer2D, HandleBeginViewUpdate));
}

Renderer2D::~Renderer2D()
{
}

void Renderer2D::RegisterObject(Context* context)
{
    context->RegisterFactory<Renderer2D>();
}

static inline bool CompareDrawable2Ds(Drawable2D* lhs, Drawable2D* rhs)
{
    if (lhs->GetLayer() != rhs->GetLayer())
        return lhs->GetLayer() < rhs->GetLayer();

    if (lhs->GetOrderInLayer() != rhs->GetOrderInLayer())
        return lhs->GetOrderInLayer() < rhs->GetOrderInLayer();

    Material* lhsUsedMaterial = lhs->GetMaterial();
    Material* rhsUsedMaterial = rhs->GetMaterial();
    if (lhsUsedMaterial != rhsUsedMaterial)
        return lhsUsedMaterial->GetNameHash() < rhsUsedMaterial->GetNameHash();

    return lhs->GetID() < rhs->GetID();
}

void Renderer2D::ProcessRayQuery(const RayOctreeQuery& query, PODVector<RayQueryResult>& results)
{
    if (orderDirty_)
    {
        Sort(drawables_.Begin(), drawables_.End(), CompareDrawable2Ds);
        orderDirty_ = false;
    }

    unsigned resultSize = results.Size();
    for (unsigned i = drawables_.Size() - 1; i < drawables_.Size(); --i)
    {
        drawables_[i]->ProcessRayQuery(query, results);
        if (results.Size() != resultSize)
            return;
    }
}

void Renderer2D::UpdateBatches(const FrameInfo& frame)
{
    unsigned count = batches_.Size();

    // Update non-thread critical parts of the source batches
    for (unsigned i = 0; i < count; ++i)
    {
        batches_[i].distance_ = 10.0f + (count - i) * 0.001f;
        batches_[i].worldTransform_ = &Matrix3x4::IDENTITY;
    }
}

void Renderer2D::UpdateGeometry(const FrameInfo& frame)
{
    // Fill index buffer
    if (indexBuffer_->GetIndexCount() < indexCount_ || indexBuffer_->IsDataLost())
    {
        bool largeIndices = vertexCount_ > 0xffff;
        indexBuffer_->SetSize(indexCount_, largeIndices);
        void* buffer = indexBuffer_->Lock(0, indexCount_, true);
        if (buffer)
        {
            unsigned quadCount = indexCount_ / 6;
            if (largeIndices)
            {
                unsigned* dest = reinterpret_cast<unsigned*>(buffer);
                for (unsigned i = 0; i < quadCount; ++i)
                {
                    unsigned base = i * 4;
                    dest[0] = base;
                    dest[1] = base + 1;
                    dest[2] = base + 2;
                    dest[3] = base;
                    dest[4] = base + 2;
                    dest[5] = base + 3;
                    dest += 6;
                }
            }
            else
            {
                unsigned short* dest = reinterpret_cast<unsigned short*>(buffer);
                for (unsigned i = 0; i < quadCount; ++i)
                {
                    unsigned base = i * 4;
                    dest[0] = (unsigned short)(base);
                    dest[1] = (unsigned short)(base + 1);
                    dest[2] = (unsigned short)(base + 2);
                    dest[3] = (unsigned short)(base);
                    dest[4] = (unsigned short)(base + 2);
                    dest[5] = (unsigned short)(base + 3);
                    dest += 6;
                }
            }

            indexBuffer_->Unlock();
        }
        else
        {
            LOGERROR("Failed to lock index buffer");
            return;
        }
    }

    if (vertexBuffer_->GetVertexCount() < vertexCount_)
        vertexBuffer_->SetSize(vertexCount_, MASK_VERTEX2D);

    if (vertexCount_)
    {
        Vertex2D* dest = reinterpret_cast<Vertex2D*>(vertexBuffer_->Lock(0, vertexCount_, true));
        if (dest)
        {
            for (unsigned d = 0; d < drawables_.Size(); ++d)
            {
                if (!drawables_[d]->GetVisibility() || drawables_[d]->GetVertices().Empty())
                    continue;

                const Vector<Vertex2D>& vertices = drawables_[d]->GetVertices();
                for (unsigned i = 0; i < vertices.Size(); ++i)
                    dest[i] = vertices[i];
                dest += vertices.Size();
            }

            vertexBuffer_->Unlock();
        }
        else
            LOGERROR("Failed to lock vertex buffer");
    }
}

UpdateGeometryType Renderer2D::GetUpdateGeometryType()
{
    return UPDATE_MAIN_THREAD;
}

void Renderer2D::AddDrawable(Drawable2D* drawable)
{
    if (!drawable)
        return;

    drawables_.Push(drawable);
    materialDirtyDrawables_.Push(drawable);

    orderDirty_ = true;
}

void Renderer2D::RemoveDrawable(Drawable2D* drawable)
{
    if (!drawable)
        return;

    drawables_.Remove(drawable);
    materialDirtyDrawables_.Remove(drawable);
    orderDirty_ = true;
}

void Renderer2D::MarkMaterialDirty(Drawable2D* drawable)
{
    materialDirtyDrawables_.Push(drawable);
}

bool Renderer2D::CheckVisibility(Drawable2D* drawable) const
{
    const BoundingBox& box = drawable->GetWorldBoundingBox();
    if (frustum_)
        return frustum_->IsInsideFast(box) != OUTSIDE;

    return frustumBoundingBox_.IsInsideFast(box) != OUTSIDE;
}

void Renderer2D::OnWorldBoundingBoxUpdate()
{
    // Set a large dummy bounding box to ensure the renderer is rendered
    boundingBox_.Define(-M_LARGE_VALUE, M_LARGE_VALUE);
    worldBoundingBox_ = boundingBox_;
}

static void CheckDrawableVisibility(const WorkItem* item, unsigned threadIndex)
{
    Renderer2D* renderer = reinterpret_cast<Renderer2D*>(item->aux_);
    Drawable2D** start = reinterpret_cast<Drawable2D**>(item->start_);
    Drawable2D** end = reinterpret_cast<Drawable2D**>(item->end_);

    while (start != end)
    {
        Drawable2D* drawable = *start++;
        if (renderer->CheckVisibility(drawable) && drawable->GetMaterial() && drawable->GetVertices().Size())
            drawable->SetVisibility(true);
        else
            drawable->SetVisibility(false);
    }
}

void Renderer2D::HandleBeginViewUpdate(StringHash eventType, VariantMap& eventData)
{
    using namespace BeginViewUpdate;

    Scene* scene = GetScene();
    // Check that we are updating the correct scene
    if (scene != eventData[P_SCENE].GetPtr())
        return;

    PROFILE(UpdateRenderer2D);

    if (!materialDirtyDrawables_.Empty())
    {
        for (unsigned i = 0; i < materialDirtyDrawables_.Size(); ++i)
        {
            Drawable2D* drawable = materialDirtyDrawables_[i];
            if (!drawable->GetMaterial())
                drawable->SetMaterial(GetMaterial(drawable->GetTexture(), drawable->GetBlendMode()));
        }
        materialDirtyDrawables_.Clear();
    }

    if (orderDirty_)
    {
        Sort(drawables_.Begin(), drawables_.End(), CompareDrawable2Ds);
        orderDirty_ = false;
    }

    Camera* camera = static_cast<Camera*>(eventData[P_CAMERA].GetPtr());
    frustum_ = &camera->GetFrustum();
    if (camera->IsOrthographic() && camera->GetNode()->GetWorldDirection() == Vector3::FORWARD)
    {
        // Define bounding box with min and max points
        frustumBoundingBox_.Define(frustum_->vertices_[2], frustum_->vertices_[4]);
        frustum_ = 0;
    }

    // Check visibility
    {
        PROFILE(CheckDrawableVisibility);

        WorkQueue* queue = GetSubsystem<WorkQueue>();
        int numWorkItems = queue->GetNumThreads() + 1; // Worker threads + main thread
        int drawablesPerItem = drawables_.Size() / numWorkItems;

        PODVector<Drawable2D*>::Iterator start = drawables_.Begin();
        for (int i = 0; i < numWorkItems; ++i)
        {
            SharedPtr<WorkItem> item = queue->GetFreeItem();
            item->priority_ = M_MAX_UNSIGNED;
            item->workFunction_ = CheckDrawableVisibility;
            item->aux_ = this;

            PODVector<Drawable2D*>::Iterator end = drawables_.End();
            if (i < numWorkItems - 1 && end - start > drawablesPerItem)
                end = start + drawablesPerItem;

            item->start_ = &(*start);
            item->end_ = &(*end);
            queue->AddWorkItem(item);

            start = end;
        }

        queue->Complete(M_MAX_UNSIGNED);
    }

    vertexCount_ = 0;
    for (unsigned i = 0; i < drawables_.Size(); ++i)
    {
        if (drawables_[i]->GetVisibility())
            vertexCount_ += drawables_[i]->GetVertices().Size();
    }
    indexCount_ = vertexCount_ / 4 * 6;

    // Go through the drawables to form geometries & batches, but upload the actual vertex data later
    materials_.Clear();

    Material* material = 0;
    unsigned iStart = 0;
    unsigned iCount = 0;
    unsigned vStart = 0;
    unsigned vCount = 0;

    for (unsigned d = 0; d < drawables_.Size(); ++d)
    {
        if (!drawables_[d]->GetVisibility())
            continue;

        Material* usedMaterial = drawables_[d]->GetMaterial();
        const Vector<Vertex2D>& vertices = drawables_[d]->GetVertices();

        if (material != usedMaterial)
        {
            if (material)
            {
                AddBatch(material, iStart, iCount, vStart, vCount);
                iStart += iCount;
                iCount = 0;
                vStart += vCount;
                vCount = 0;
            }

            material = usedMaterial;
        }

        iCount += vertices.Size() / 4 * 6;
        vCount += vertices.Size();
    }

    if (material)
        AddBatch(material, iStart, iCount, vStart, vCount);

    // Now the amount of batches is known. Build the part of source batches that are sensitive to threading issues
    // (material & geometry pointers)
    unsigned count = materials_.Size();
    batches_.Resize(count);

    for (unsigned i = 0; i < count; ++i)
    {
        batches_[i].material_ = materials_[i];
        batches_[i].geometry_ = geometries_[i];
    }
}

void Renderer2D::GetDrawables(PODVector<Drawable2D*>& dest, Node* node)
{
    if (!node || !node->IsEnabled())
        return;

    const Vector<SharedPtr<Component> >& components = node->GetComponents();
    for (Vector<SharedPtr<Component> >::ConstIterator i = components.Begin(); i != components.End(); ++i)
    {
        Drawable2D* drawable = dynamic_cast<Drawable2D*>(i->Get());
        if (drawable && drawable->IsEnabled())
            dest.Push(drawable);
    }

    const Vector<SharedPtr<Node> >& children = node->GetChildren();
    for (Vector<SharedPtr<Node> >::ConstIterator i = children.Begin(); i != children.End(); ++i)
        GetDrawables(dest, i->Get());
}

Material* Renderer2D::GetMaterial(Texture2D* texture, BlendMode blendMode)
{
    HashMap<Texture2D*, HashMap<int, SharedPtr<Material> > >::Iterator t = cachedMaterials_.Find(texture);
    if (t == cachedMaterials_.End())
    {
        SharedPtr<Material> material(CreateMaterial(texture, blendMode));
        cachedMaterials_[texture][blendMode] = material;
        return material;
    }

    HashMap<int, SharedPtr<Material> >& materials = t->second_;
    HashMap<int, SharedPtr<Material> >::Iterator b = materials.Find(blendMode);
    if (b != materials.End())
        return b->second_;

    SharedPtr<Material> material(CreateMaterial(texture, blendMode));
    materials[blendMode] = material;

    return material;
}

Material* Renderer2D::CreateMaterial(Texture2D* texture, BlendMode blendMode)
{
    Material* material = new Material(context_);
    if (texture)
        material->SetName(texture->GetName() + "_" + blendModeNames[blendMode]);
    else
        material->SetName(blendModeNames[blendMode]);

    Technique* tech = new Technique(context_);
    Pass* pass = tech->CreatePass(PASS_ALPHA);
    pass->SetBlendMode(blendMode);

    pass->SetVertexShader("Urho2D");
    pass->SetPixelShader("Urho2D");

    pass->SetDepthWrite(false);

    material->SetTechnique(0, tech);
    material->SetCullMode(CULL_NONE);

    material->SetTexture(TU_DIFFUSE, texture);

    return material;
}

void Renderer2D::AddBatch(Material* material, unsigned indexStart, unsigned indexCount, unsigned vertexStart, unsigned vertexCount)
{
    if (!material || indexCount == 0 || vertexCount == 0)
        return;

    materials_.Push(SharedPtr<Material>(material));

    unsigned batchSize = materials_.Size();
    if (geometries_.Size() < batchSize)
    {
        SharedPtr<Geometry> geometry(new Geometry(context_));
        geometry->SetIndexBuffer(indexBuffer_);
        geometry->SetVertexBuffer(0, vertexBuffer_, MASK_VERTEX2D);
        geometries_.Push(geometry);
    }

    geometries_[batchSize - 1]->SetDrawRange(TRIANGLE_LIST, indexStart, indexCount, vertexStart, vertexCount, false);
}

}
<commit_msg>Do not check material in Renderer2D::CheckDrawableVisibility. [ci skip]<commit_after>//
// Copyright (c) 2008-2014 the Urho3D project.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//

#include "Precompiled.h"
#include "Camera.h"
#include "Context.h"
#include "Drawable2D.h"
#include "Geometry.h"
#include "GraphicsEvents.h"
#include "IndexBuffer.h"
#include "Log.h"
#include "Material.h"
#include "Node.h"
#include "Profiler.h"
#include "Renderer2D.h"
#include "Scene.h"
#include "Sort.h"
#include "Technique.h"
#include "Texture2D.h"
#include "VertexBuffer.h"
#include "WorkQueue.h"

#include "DebugNew.h"

namespace Urho3D
{

extern const char* blendModeNames[];

Renderer2D::Renderer2D(Context* context) :
    Drawable(context, DRAWABLE_GEOMETRY),
    indexBuffer_(new IndexBuffer(context_)),
    vertexBuffer_(new VertexBuffer(context_)),
    orderDirty_(true),
    frustum_(0),
    indexCount_(0),
    vertexCount_(0)
{
    SubscribeToEvent(E_BEGINVIEWUPDATE, HANDLER(Renderer2D, HandleBeginViewUpdate));
}

Renderer2D::~Renderer2D()
{
}

void Renderer2D::RegisterObject(Context* context)
{
    context->RegisterFactory<Renderer2D>();
}

static inline bool CompareDrawable2Ds(Drawable2D* lhs, Drawable2D* rhs)
{
    if (lhs->GetLayer() != rhs->GetLayer())
        return lhs->GetLayer() < rhs->GetLayer();

    if (lhs->GetOrderInLayer() != rhs->GetOrderInLayer())
        return lhs->GetOrderInLayer() < rhs->GetOrderInLayer();

    Material* lhsUsedMaterial = lhs->GetMaterial();
    Material* rhsUsedMaterial = rhs->GetMaterial();
    if (lhsUsedMaterial != rhsUsedMaterial)
        return lhsUsedMaterial->GetNameHash() < rhsUsedMaterial->GetNameHash();

    return lhs->GetID() < rhs->GetID();
}

void Renderer2D::ProcessRayQuery(const RayOctreeQuery& query, PODVector<RayQueryResult>& results)
{
    if (orderDirty_)
    {
        Sort(drawables_.Begin(), drawables_.End(), CompareDrawable2Ds);
        orderDirty_ = false;
    }

    unsigned resultSize = results.Size();
    for (unsigned i = drawables_.Size() - 1; i < drawables_.Size(); --i)
    {
        drawables_[i]->ProcessRayQuery(query, results);
        if (results.Size() != resultSize)
            return;
    }
}

void Renderer2D::UpdateBatches(const FrameInfo& frame)
{
    unsigned count = batches_.Size();

    // Update non-thread critical parts of the source batches
    for (unsigned i = 0; i < count; ++i)
    {
        batches_[i].distance_ = 10.0f + (count - i) * 0.001f;
        batches_[i].worldTransform_ = &Matrix3x4::IDENTITY;
    }
}

void Renderer2D::UpdateGeometry(const FrameInfo& frame)
{
    // Fill index buffer
    if (indexBuffer_->GetIndexCount() < indexCount_ || indexBuffer_->IsDataLost())
    {
        bool largeIndices = vertexCount_ > 0xffff;
        indexBuffer_->SetSize(indexCount_, largeIndices);
        void* buffer = indexBuffer_->Lock(0, indexCount_, true);
        if (buffer)
        {
            unsigned quadCount = indexCount_ / 6;
            if (largeIndices)
            {
                unsigned* dest = reinterpret_cast<unsigned*>(buffer);
                for (unsigned i = 0; i < quadCount; ++i)
                {
                    unsigned base = i * 4;
                    dest[0] = base;
                    dest[1] = base + 1;
                    dest[2] = base + 2;
                    dest[3] = base;
                    dest[4] = base + 2;
                    dest[5] = base + 3;
                    dest += 6;
                }
            }
            else
            {
                unsigned short* dest = reinterpret_cast<unsigned short*>(buffer);
                for (unsigned i = 0; i < quadCount; ++i)
                {
                    unsigned base = i * 4;
                    dest[0] = (unsigned short)(base);
                    dest[1] = (unsigned short)(base + 1);
                    dest[2] = (unsigned short)(base + 2);
                    dest[3] = (unsigned short)(base);
                    dest[4] = (unsigned short)(base + 2);
                    dest[5] = (unsigned short)(base + 3);
                    dest += 6;
                }
            }

            indexBuffer_->Unlock();
        }
        else
        {
            LOGERROR("Failed to lock index buffer");
            return;
        }
    }

    if (vertexBuffer_->GetVertexCount() < vertexCount_)
        vertexBuffer_->SetSize(vertexCount_, MASK_VERTEX2D);

    if (vertexCount_)
    {
        Vertex2D* dest = reinterpret_cast<Vertex2D*>(vertexBuffer_->Lock(0, vertexCount_, true));
        if (dest)
        {
            for (unsigned d = 0; d < drawables_.Size(); ++d)
            {
                if (!drawables_[d]->GetVisibility() || drawables_[d]->GetVertices().Empty())
                    continue;

                const Vector<Vertex2D>& vertices = drawables_[d]->GetVertices();
                for (unsigned i = 0; i < vertices.Size(); ++i)
                    dest[i] = vertices[i];
                dest += vertices.Size();
            }

            vertexBuffer_->Unlock();
        }
        else
            LOGERROR("Failed to lock vertex buffer");
    }
}

UpdateGeometryType Renderer2D::GetUpdateGeometryType()
{
    return UPDATE_MAIN_THREAD;
}

void Renderer2D::AddDrawable(Drawable2D* drawable)
{
    if (!drawable)
        return;

    drawables_.Push(drawable);
    materialDirtyDrawables_.Push(drawable);

    orderDirty_ = true;
}

void Renderer2D::RemoveDrawable(Drawable2D* drawable)
{
    if (!drawable)
        return;

    drawables_.Remove(drawable);
    materialDirtyDrawables_.Remove(drawable);
    orderDirty_ = true;
}

void Renderer2D::MarkMaterialDirty(Drawable2D* drawable)
{
    materialDirtyDrawables_.Push(drawable);
}

bool Renderer2D::CheckVisibility(Drawable2D* drawable) const
{
    const BoundingBox& box = drawable->GetWorldBoundingBox();
    if (frustum_)
        return frustum_->IsInsideFast(box) != OUTSIDE;

    return frustumBoundingBox_.IsInsideFast(box) != OUTSIDE;
}

void Renderer2D::OnWorldBoundingBoxUpdate()
{
    // Set a large dummy bounding box to ensure the renderer is rendered
    boundingBox_.Define(-M_LARGE_VALUE, M_LARGE_VALUE);
    worldBoundingBox_ = boundingBox_;
}

static void CheckDrawableVisibility(const WorkItem* item, unsigned threadIndex)
{
    Renderer2D* renderer = reinterpret_cast<Renderer2D*>(item->aux_);
    Drawable2D** start = reinterpret_cast<Drawable2D**>(item->start_);
    Drawable2D** end = reinterpret_cast<Drawable2D**>(item->end_);

    while (start != end)
    {
        Drawable2D* drawable = *start++;
        if (renderer->CheckVisibility(drawable) && drawable->GetVertices().Size())
            drawable->SetVisibility(true);
        else
            drawable->SetVisibility(false);
    }
}

void Renderer2D::HandleBeginViewUpdate(StringHash eventType, VariantMap& eventData)
{
    using namespace BeginViewUpdate;

    Scene* scene = GetScene();
    // Check that we are updating the correct scene
    if (scene != eventData[P_SCENE].GetPtr())
        return;

    PROFILE(UpdateRenderer2D);

    if (!materialDirtyDrawables_.Empty())
    {
        for (unsigned i = 0; i < materialDirtyDrawables_.Size(); ++i)
        {
            Drawable2D* drawable = materialDirtyDrawables_[i];
            if (!drawable->GetMaterial())
                drawable->SetMaterial(GetMaterial(drawable->GetTexture(), drawable->GetBlendMode()));
        }
        materialDirtyDrawables_.Clear();
    }

    if (orderDirty_)
    {
        Sort(drawables_.Begin(), drawables_.End(), CompareDrawable2Ds);
        orderDirty_ = false;
    }

    Camera* camera = static_cast<Camera*>(eventData[P_CAMERA].GetPtr());
    frustum_ = &camera->GetFrustum();
    if (camera->IsOrthographic() && camera->GetNode()->GetWorldDirection() == Vector3::FORWARD)
    {
        // Define bounding box with min and max points
        frustumBoundingBox_.Define(frustum_->vertices_[2], frustum_->vertices_[4]);
        frustum_ = 0;
    }

    // Check visibility
    {
        PROFILE(CheckDrawableVisibility);

        WorkQueue* queue = GetSubsystem<WorkQueue>();
        int numWorkItems = queue->GetNumThreads() + 1; // Worker threads + main thread
        int drawablesPerItem = drawables_.Size() / numWorkItems;

        PODVector<Drawable2D*>::Iterator start = drawables_.Begin();
        for (int i = 0; i < numWorkItems; ++i)
        {
            SharedPtr<WorkItem> item = queue->GetFreeItem();
            item->priority_ = M_MAX_UNSIGNED;
            item->workFunction_ = CheckDrawableVisibility;
            item->aux_ = this;

            PODVector<Drawable2D*>::Iterator end = drawables_.End();
            if (i < numWorkItems - 1 && end - start > drawablesPerItem)
                end = start + drawablesPerItem;

            item->start_ = &(*start);
            item->end_ = &(*end);
            queue->AddWorkItem(item);

            start = end;
        }

        queue->Complete(M_MAX_UNSIGNED);
    }

    vertexCount_ = 0;
    for (unsigned i = 0; i < drawables_.Size(); ++i)
    {
        if (drawables_[i]->GetVisibility())
            vertexCount_ += drawables_[i]->GetVertices().Size();
    }
    indexCount_ = vertexCount_ / 4 * 6;

    // Go through the drawables to form geometries & batches, but upload the actual vertex data later
    materials_.Clear();

    Material* material = 0;
    unsigned iStart = 0;
    unsigned iCount = 0;
    unsigned vStart = 0;
    unsigned vCount = 0;

    for (unsigned d = 0; d < drawables_.Size(); ++d)
    {
        if (!drawables_[d]->GetVisibility())
            continue;

        Material* usedMaterial = drawables_[d]->GetMaterial();
        const Vector<Vertex2D>& vertices = drawables_[d]->GetVertices();

        if (material != usedMaterial)
        {
            if (material)
            {
                AddBatch(material, iStart, iCount, vStart, vCount);
                iStart += iCount;
                iCount = 0;
                vStart += vCount;
                vCount = 0;
            }

            material = usedMaterial;
        }

        iCount += vertices.Size() / 4 * 6;
        vCount += vertices.Size();
    }

    if (material)
        AddBatch(material, iStart, iCount, vStart, vCount);

    // Now the amount of batches is known. Build the part of source batches that are sensitive to threading issues
    // (material & geometry pointers)
    unsigned count = materials_.Size();
    batches_.Resize(count);

    for (unsigned i = 0; i < count; ++i)
    {
        batches_[i].material_ = materials_[i];
        batches_[i].geometry_ = geometries_[i];
    }
}

void Renderer2D::GetDrawables(PODVector<Drawable2D*>& dest, Node* node)
{
    if (!node || !node->IsEnabled())
        return;

    const Vector<SharedPtr<Component> >& components = node->GetComponents();
    for (Vector<SharedPtr<Component> >::ConstIterator i = components.Begin(); i != components.End(); ++i)
    {
        Drawable2D* drawable = dynamic_cast<Drawable2D*>(i->Get());
        if (drawable && drawable->IsEnabled())
            dest.Push(drawable);
    }

    const Vector<SharedPtr<Node> >& children = node->GetChildren();
    for (Vector<SharedPtr<Node> >::ConstIterator i = children.Begin(); i != children.End(); ++i)
        GetDrawables(dest, i->Get());
}

Material* Renderer2D::GetMaterial(Texture2D* texture, BlendMode blendMode)
{
    HashMap<Texture2D*, HashMap<int, SharedPtr<Material> > >::Iterator t = cachedMaterials_.Find(texture);
    if (t == cachedMaterials_.End())
    {
        SharedPtr<Material> material(CreateMaterial(texture, blendMode));
        cachedMaterials_[texture][blendMode] = material;
        return material;
    }

    HashMap<int, SharedPtr<Material> >& materials = t->second_;
    HashMap<int, SharedPtr<Material> >::Iterator b = materials.Find(blendMode);
    if (b != materials.End())
        return b->second_;

    SharedPtr<Material> material(CreateMaterial(texture, blendMode));
    materials[blendMode] = material;

    return material;
}

Material* Renderer2D::CreateMaterial(Texture2D* texture, BlendMode blendMode)
{
    Material* material = new Material(context_);
    if (texture)
        material->SetName(texture->GetName() + "_" + blendModeNames[blendMode]);
    else
        material->SetName(blendModeNames[blendMode]);

    Technique* tech = new Technique(context_);
    Pass* pass = tech->CreatePass(PASS_ALPHA);
    pass->SetBlendMode(blendMode);

    pass->SetVertexShader("Urho2D");
    pass->SetPixelShader("Urho2D");

    pass->SetDepthWrite(false);

    material->SetTechnique(0, tech);
    material->SetCullMode(CULL_NONE);

    material->SetTexture(TU_DIFFUSE, texture);

    return material;
}

void Renderer2D::AddBatch(Material* material, unsigned indexStart, unsigned indexCount, unsigned vertexStart, unsigned vertexCount)
{
    if (!material || indexCount == 0 || vertexCount == 0)
        return;

    materials_.Push(SharedPtr<Material>(material));

    unsigned batchSize = materials_.Size();
    if (geometries_.Size() < batchSize)
    {
        SharedPtr<Geometry> geometry(new Geometry(context_));
        geometry->SetIndexBuffer(indexBuffer_);
        geometry->SetVertexBuffer(0, vertexBuffer_, MASK_VERTEX2D);
        geometries_.Push(geometry);
    }

    geometries_[batchSize - 1]->SetDrawRange(TRIANGLE_LIST, indexStart, indexCount, vertexStart, vertexCount, false);
}

}
<|endoftext|>


<commit_before>/*
Copyright 2018 creatorlxd

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "stdafx.h"
#include "Window.h"

SpaceGameEngine::Window::Window() :CurrentObject<Window>(this)
{
	m_Hwnd = NULL;
	m_IconFileName = "";
	m_WindowWidth = 0;
	m_WindowHeight = 0;
	m_WindowTitle = "";
	m_WindowPosition = m_DefaultWindowPosition;		//default value
	m_IfShowCursor = true;
	m_FPSLimit = 360;		//default value
	if (GetDefaultConfigFile().IfHaveConfigTable("Window"))
	{
		auto WindowConfig = GetDefaultConfigFile().GetConfigTable("Window");
		if (WindowConfig.IfHaveConfigValue("IconFileName"))
			m_IconFileName = WindowConfig.GetConfigValue("IconFileName").AsString();
		if (WindowConfig.IfHaveConfigValue("WindowWidth"))
			m_WindowWidth = WindowConfig.GetConfigValue("WindowWidth").AsInt();
		if (WindowConfig.IfHaveConfigValue("WindowHeight"))
			m_WindowHeight = WindowConfig.GetConfigValue("WindowHeight").AsInt();
		if (WindowConfig.IfHaveConfigValue("WindowTitle"))
			m_WindowTitle = WindowConfig.GetConfigValue("WindowTitle").AsString();
		if (WindowConfig.IfHaveConfigValue("WindowPositionX"))
			m_WindowPosition.first = WindowConfig.GetConfigValue("WindowPositionX").AsInt();
		if (WindowConfig.IfHaveConfigValue("WindowPositionY"))
			m_WindowPosition.second = WindowConfig.GetConfigValue("WindowPositionY").AsInt();
		if (WindowConfig.IfHaveConfigValue("IfShowCursor"))
			m_IfShowCursor = WindowConfig.GetConfigValue("IfShowCursor").AsBool();
		if (WindowConfig.IfHaveConfigValue("FPSLimit"))
			m_FPSLimit = WindowConfig.GetConfigValue("FPSLimit").AsInt();
	}

	ShowCursor(m_IfShowCursor);

	m_IfBegin = false;
}

SpaceGameEngine::Window::~Window()
{
	DATA_NOTIFY(Window, m_OnReleaseAction);
}

HWND SpaceGameEngine::Window::GetHwnd()
{
	return m_Hwnd;
}

DWORD SpaceGameEngine::Window::GetWindowWidth()
{
	return m_WindowWidth;
}

DWORD SpaceGameEngine::Window::GetWindowHeight()
{
	return m_WindowHeight;
}

void SpaceGameEngine::Window::ChangeIfShowCursor(bool b)
{
	if (m_IfShowCursor == b)
	{
		return;
	}
	else
	{
		m_IfShowCursor = b;
		ShowCursor(b);
	}
}

bool SpaceGameEngine::Window::GetIfShowCursor()
{
	return m_IfShowCursor;
}

void SpaceGameEngine::Window::SetCursorPosition(int x, int y)
{
	auto pos = GetWindowPosition();
	SetCursorPos(pos.first + x, pos.second + y);
}

std::pair<int, int> SpaceGameEngine::Window::GetCursorPosition()
{
	POINT p;
	GetCursorPos(&p);
	GetWindowPosition();
	return std::pair<int, int>(p.x - m_WindowPosition.first, p.y - m_WindowPosition.second);
}

void SpaceGameEngine::Window::UpdateWindowSize()
{
	RECT r;
	GetClientRect(m_Hwnd, &r);
	m_WindowWidth = abs(r.right - r.left);
	m_WindowHeight = abs(r.bottom - r.top);
}

std::pair<int, int> SpaceGameEngine::Window::GetWindowPosition()
{
	if (m_IfBegin)
	{
		RECT r;
		GetClientRect(m_Hwnd, &r);
		m_WindowPosition = std::pair<int, int>(r.left, r.top);
	}
	return m_WindowPosition;
}

void SpaceGameEngine::Window::SetWindowPosition(int x, int y)
{
	if (m_IfBegin)
	{
		RECT r;
		GetWindowRect(m_Hwnd, &r);
		SetWindowPos(m_Hwnd, HWND_TOPMOST, r.left + x - m_WindowPosition.first, r.top + y - m_WindowPosition.second, 0, 0, SWP_SHOWWINDOW | SWP_NOSIZE);
	}
	m_WindowPosition = std::make_pair(x, y);
}

void SpaceGameEngine::Window::SetWindowSize(int x, int y)
{
	if (m_IfBegin)
	{
		RECT r;
		SetRect(&r, 0, 0, x, y);
		AdjustWindowRect(&r, WS_OVERLAPPEDWINDOW, false);
		SetWindowPos(m_Hwnd, HWND_TOPMOST, 0, 0, r.right - r.left, r.bottom - r.top, SWP_SHOWWINDOW | SWP_NOMOVE);
	}
	m_WindowWidth = x;
	m_WindowHeight = y;
	if (m_IfBegin)
	{
		Resize();
	}
}

void SpaceGameEngine::Window::SetWindowTitle(const String & title)
{
	m_WindowTitle = title;
}

SpaceGameEngine::String SpaceGameEngine::Window::GetWindowTitle()
{
	return m_WindowTitle;
}

void SpaceGameEngine::Window::SetFPSLimit(unsigned int limit)
{
	m_FPSLimit = limit;
}

unsigned int SpaceGameEngine::Window::GetFPSLimit()
{
	return m_FPSLimit;
}

bool SpaceGameEngine::Window::IfBegin()
{
	return m_IfBegin;
}

SpaceGameEngine::Timer & SpaceGameEngine::Window::GetTimer()
{
	return m_Timer;
}

void SpaceGameEngine::Window::StartRun(HINSTANCE hInstance)
{
	m_Timer.Init();

	//init window
	WNDCLASSEX WndClass = { 0 };
	WndClass.cbSize = sizeof(WNDCLASSEX);
	WndClass.style = CS_HREDRAW | CS_VREDRAW;
	WndClass.lpfnWndProc = WindowProcess;
	WndClass.cbClsExtra = 0;
	WndClass.cbWndExtra = 0;
	WndClass.hInstance = hInstance;
	WndClass.hIcon = (HICON)LoadImage(NULL, StringToWString(m_IconFileName).c_str(), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_LOADFROMFILE);
	WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
	WndClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
	WndClass.lpszMenuName = NULL;
	WndClass.lpszClassName = L"SpaceGameEngineWindow";
	if (!RegisterClassEx(&WndClass))
	{
		THROW_ERROR("can not register window");
		return;
	}
	RECT r;
	SetRect(&r, m_WindowPosition.first, m_WindowPosition.second, m_WindowPosition.first + m_WindowWidth, m_WindowPosition.second + m_WindowHeight);
	AdjustWindowRect(&r, WS_OVERLAPPEDWINDOW, false);
	m_Hwnd = CreateWindow(L"SpaceGameEngineWindow", StringToWString(m_WindowTitle).c_str(), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, r.right - r.left, r.bottom - r.top, NULL, NULL, hInstance, NULL);
	MoveWindow(m_Hwnd, r.left, r.top, r.right - r.left, r.bottom - r.top, true);
	ShowWindow(m_Hwnd, SW_SHOWNORMAL);
	UpdateWindow(m_Hwnd);

	DATA_NOTIFY(Window, m_OnInitAction);
	m_IfBegin = true;
	DATA_NOTIFY(Window, m_OnStartAction);

	MSG msg = { 0 };
	while (msg.message != WM_QUIT)
	{
		if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		else
		{
			static auto time = std::chrono::steady_clock::now();
			static double time_limit = 1.0 / (double)m_FPSLimit;
			auto time_now = std::chrono::steady_clock::now();
			std::chrono::duration<double> time_span = std::chrono::duration_cast<std::chrono::duration<double>>(time_now - time);

			if (time_span.count() >= time_limit)
			{
				m_Timer.Tick();
				DATA_NOTIFY(Window, m_OnRunAction);
				time = time_now;
			}
			else
			{
				Sleep(1000 * (time_limit - time_span.count()));
			}
		}
	}
}

void SpaceGameEngine::Window::Resize()
{
	DATA_NOTIFY(Window, m_OnResizeAction);
}

LRESULT SpaceGameEngine::Window::WindowProcess(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	ASSERT(Window::GetCurrentObject(), "Must have a current window object");
	switch (message)
	{
	case WM_PAINT:
		ValidateRect(Window::GetCurrentObject()->m_Hwnd, NULL);
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	case WM_SIZE:
		Window::GetCurrentObject()->m_WindowWidth = LOWORD(lParam);
		Window::GetCurrentObject()->m_WindowHeight = HIWORD(lParam);
		if (LOWORD(lParam) != 0 && HIWORD(lParam) != 0)
			Window::GetCurrentObject()->Resize();
		break;
	default:
		return DefWindowProc(hwnd, message, wParam, lParam);
		break;
	}
	return NULL;
}
<commit_msg>fix a bug in window<commit_after>/*
Copyright 2018 creatorlxd

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "stdafx.h"
#include "Window.h"

SpaceGameEngine::Window::Window() :CurrentObject<Window>(this)
{
	m_Hwnd = NULL;
	m_IconFileName = "";
	m_WindowWidth = 0;
	m_WindowHeight = 0;
	m_WindowTitle = "";
	m_WindowPosition = m_DefaultWindowPosition;		//default value
	m_IfShowCursor = true;
	m_FPSLimit = 360;		//default value
	if (GetDefaultConfigFile().IfHaveConfigTable("Window"))
	{
		auto WindowConfig = GetDefaultConfigFile().GetConfigTable("Window");
		if (WindowConfig.IfHaveConfigValue("IconFileName"))
			m_IconFileName = WindowConfig.GetConfigValue("IconFileName").AsString();
		if (WindowConfig.IfHaveConfigValue("WindowWidth"))
			m_WindowWidth = WindowConfig.GetConfigValue("WindowWidth").AsInt();
		if (WindowConfig.IfHaveConfigValue("WindowHeight"))
			m_WindowHeight = WindowConfig.GetConfigValue("WindowHeight").AsInt();
		if (WindowConfig.IfHaveConfigValue("WindowTitle"))
			m_WindowTitle = WindowConfig.GetConfigValue("WindowTitle").AsString();
		if (WindowConfig.IfHaveConfigValue("WindowPositionX"))
			m_WindowPosition.first = WindowConfig.GetConfigValue("WindowPositionX").AsInt();
		if (WindowConfig.IfHaveConfigValue("WindowPositionY"))
			m_WindowPosition.second = WindowConfig.GetConfigValue("WindowPositionY").AsInt();
		if (WindowConfig.IfHaveConfigValue("IfShowCursor"))
			m_IfShowCursor = WindowConfig.GetConfigValue("IfShowCursor").AsBool();
		if (WindowConfig.IfHaveConfigValue("FPSLimit"))
			m_FPSLimit = WindowConfig.GetConfigValue("FPSLimit").AsInt();
	}

	ShowCursor(m_IfShowCursor);

	m_IfBegin = false;
}

SpaceGameEngine::Window::~Window()
{
	DATA_NOTIFY(Window, m_OnReleaseAction);
}

HWND SpaceGameEngine::Window::GetHwnd()
{
	return m_Hwnd;
}

DWORD SpaceGameEngine::Window::GetWindowWidth()
{
	return m_WindowWidth;
}

DWORD SpaceGameEngine::Window::GetWindowHeight()
{
	return m_WindowHeight;
}

void SpaceGameEngine::Window::ChangeIfShowCursor(bool b)
{
	if (m_IfShowCursor == b)
	{
		return;
	}
	else
	{
		m_IfShowCursor = b;
		ShowCursor(b);
	}
}

bool SpaceGameEngine::Window::GetIfShowCursor()
{
	return m_IfShowCursor;
}

void SpaceGameEngine::Window::SetCursorPosition(int x, int y)
{
	auto pos = GetWindowPosition();
	SetCursorPos(pos.first + x, pos.second + y);
}

std::pair<int, int> SpaceGameEngine::Window::GetCursorPosition()
{
	POINT p;
	GetCursorPos(&p);
	GetWindowPosition();
	return std::pair<int, int>(p.x - m_WindowPosition.first, p.y - m_WindowPosition.second);
}

void SpaceGameEngine::Window::UpdateWindowSize()
{
	RECT r;
	GetClientRect(m_Hwnd, &r);
	m_WindowWidth = abs(r.right - r.left);
	m_WindowHeight = abs(r.bottom - r.top);
}

std::pair<int, int> SpaceGameEngine::Window::GetWindowPosition()
{
	if (m_IfBegin)
	{
		RECT r;
		GetClientRect(m_Hwnd, &r);
		m_WindowPosition = std::pair<int, int>(r.left, r.top);
	}
	return m_WindowPosition;
}

void SpaceGameEngine::Window::SetWindowPosition(int x, int y)
{
	if (m_IfBegin)
	{
		RECT r;
		GetWindowRect(m_Hwnd, &r);
		SetWindowPos(m_Hwnd, HWND_TOPMOST, r.left + x - m_WindowPosition.first, r.top + y - m_WindowPosition.second, 0, 0, SWP_SHOWWINDOW | SWP_NOSIZE);
	}
	m_WindowPosition = std::make_pair(x, y);
}

void SpaceGameEngine::Window::SetWindowSize(int x, int y)
{
	if (m_IfBegin)
	{
		RECT r;
		SetRect(&r, 0, 0, x, y);
		AdjustWindowRect(&r, WS_OVERLAPPEDWINDOW, false);
		SetWindowPos(m_Hwnd, HWND_TOPMOST, 0, 0, r.right - r.left, r.bottom - r.top, SWP_SHOWWINDOW | SWP_NOMOVE);
	}
	m_WindowWidth = x;
	m_WindowHeight = y;
	if (m_IfBegin)
	{
		Resize();
	}
}

void SpaceGameEngine::Window::SetWindowTitle(const String & title)
{
	m_WindowTitle = title;
}

SpaceGameEngine::String SpaceGameEngine::Window::GetWindowTitle()
{
	return m_WindowTitle;
}

void SpaceGameEngine::Window::SetFPSLimit(unsigned int limit)
{
	m_FPSLimit = limit;
}

unsigned int SpaceGameEngine::Window::GetFPSLimit()
{
	return m_FPSLimit;
}

bool SpaceGameEngine::Window::IfBegin()
{
	return m_IfBegin;
}

SpaceGameEngine::Timer & SpaceGameEngine::Window::GetTimer()
{
	return m_Timer;
}

void SpaceGameEngine::Window::StartRun(HINSTANCE hInstance)
{
	m_Timer.Init();

	//init window
	WNDCLASSEX WndClass = { 0 };
	WndClass.cbSize = sizeof(WNDCLASSEX);
	WndClass.style = CS_HREDRAW | CS_VREDRAW;
	WndClass.lpfnWndProc = WindowProcess;
	WndClass.cbClsExtra = 0;
	WndClass.cbWndExtra = 0;
	WndClass.hInstance = hInstance;
	WndClass.hIcon = (HICON)LoadImage(NULL, StringToWString(m_IconFileName).c_str(), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_LOADFROMFILE);
	WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
	WndClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
	WndClass.lpszMenuName = NULL;
	WndClass.lpszClassName = L"SpaceGameEngineWindow";
	if (!RegisterClassEx(&WndClass))
	{
		THROW_ERROR("can not register window");
		return;
	}
	RECT r;
	SetRect(&r, m_WindowPosition.first, m_WindowPosition.second, m_WindowPosition.first + m_WindowWidth, m_WindowPosition.second + m_WindowHeight);
	AdjustWindowRect(&r, WS_OVERLAPPEDWINDOW, false);
	m_Hwnd = CreateWindow(WndClass.lpszClassName, StringToWString(m_WindowTitle).c_str(), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, r.right - r.left, r.bottom - r.top, NULL, NULL, hInstance, NULL);
	MoveWindow(m_Hwnd, r.left, r.top, r.right - r.left, r.bottom - r.top, true);
	ShowWindow(m_Hwnd, SW_SHOWNORMAL);
	UpdateWindow(m_Hwnd);

	DATA_NOTIFY(Window, m_OnInitAction);
	m_IfBegin = true;
	DATA_NOTIFY(Window, m_OnStartAction);

	MSG msg = { 0 };
	while (msg.message != WM_QUIT)
	{
		if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		else
		{
			static auto time = std::chrono::steady_clock::now();
			static double time_limit = 1.0 / (double)m_FPSLimit;
			auto time_now = std::chrono::steady_clock::now();
			std::chrono::duration<double> time_span = std::chrono::duration_cast<std::chrono::duration<double>>(time_now - time);

			if (time_span.count() >= time_limit)
			{
				m_Timer.Tick();
				DATA_NOTIFY(Window, m_OnRunAction);
				time = time_now;
			}
			else
			{
				Sleep(1000 * (time_limit - time_span.count()));
			}
		}
	}
	UnregisterClass(WndClass.lpszClassName, hInstance);
}

void SpaceGameEngine::Window::Resize()
{
	DATA_NOTIFY(Window, m_OnResizeAction);
}

LRESULT SpaceGameEngine::Window::WindowProcess(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	ASSERT(Window::GetCurrentObject(), "Must have a current window object");
	switch (message)
	{
	case WM_PAINT:
		ValidateRect(Window::GetCurrentObject()->m_Hwnd, NULL);
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	case WM_SIZE:
		Window::GetCurrentObject()->m_WindowWidth = LOWORD(lParam);
		Window::GetCurrentObject()->m_WindowHeight = HIWORD(lParam);
		if (LOWORD(lParam) != 0 && HIWORD(lParam) != 0)
			Window::GetCurrentObject()->Resize();
		break;
	default:
		return DefWindowProc(hwnd, message, wParam, lParam);
		break;
	}
	return NULL;
}
<|endoftext|>


<commit_before>#include "task.h"
#include "lua_moo.h"
#include "objectmanager.h"
#include <QDateTime>

const char		*Task::mPrepositionList[] =
{
	"with/using",
	"at/to",
	"in front of",
	"in/inside/into",
	"on top of/on/onto/upon",
	"out of/from inside/from",
	"over",
	"through",
	"under/underneath/beneath",
	"behind",
	"beside",
	"for/about",
	"is",
	"as",
	"off/off of",
	0
};

Task::Task( const QString &pCommand ) : mCommand( pCommand )
{
	mProgrammerId = OBJECT_NONE;

	mTimeStamp = QDateTime::currentMSecsSinceEpoch();

	mPlayer = OBJECT_NONE;
	mObject = OBJECT_NONE;
	mCaller = OBJECT_NONE;

	mDirectObjectId   = OBJECT_NONE;
	mIndirectObjectId = OBJECT_NONE;
}

Task::Task( const TaskEntry &pEntry )
{
	mProgrammerId = pEntry.playerid();

	mId			= pEntry.id();
	mTimeStamp	= pEntry.timestamp();
	mCommand	= pEntry.command();

	mPlayer		= pEntry.playerid();
	mObject		= OBJECT_NONE;
	mCaller		= OBJECT_NONE;

	mDirectObjectId   = OBJECT_NONE;
	mIndirectObjectId = OBJECT_NONE;
}

Task::~Task( void )
{
}

void Task::findObject( const QString &pName, QList<ObjectId> &pId ) const
{
	if( pName.isEmpty() )
	{
		return;
	}

	if( pName.startsWith( "#" ) )
	{
		bool	ok;
		int		id = pName.mid( 1 ).toInt( &ok );

		if( ok && ObjectManager::instance()->object( id ) != 0 )
		{
			pId.append( id );

			return;
		}

		return;
	}

	if( pName == "me" )
	{
		pId.append( player() );

		return;
	}

	if( pName == "here" )
	{
		Object			*Player;

		if( ( Player = ObjectManager::instance()->object( player() ) ) != 0 )
		{
			pId.append( Player->location() );
		}
	}

	// Otherwise, the server considers all of the objects whose location is either the player
	// (i.e., the objects the player is "holding", so to speak)

	Object			*Player;

	if( ( Player = ObjectManager::instance()->object( player() ) ) != 0 )
	{
		const QList<ObjectId>	&Contents = Player->contents();

		foreach( ObjectId id, Contents )
		{
			Object		*Object;

			if( ( Object = ObjectManager::instance()->object( id ) ) != 0 )
			{
				if( Object->matchName( pName ) )
				{
					pId.append( id );
				}
			}
		}

		// or the room the player is in (i.e., the objects in the same room as the player);

		// it will try to match the object string against the various names for these objects.

		Object			*Location;

		if( ( Location = ObjectManager::instance()->object( Player->location() ) ) != 0 )
		{
			if( Location->matchName( pName ) )
			{
				pId.append( Location->id() );
			}

			const QList<ObjectId>	&Contents = Location->contents();

			foreach( ObjectId id, Contents )
			{
				Object		*Object;

				if( ( Object = ObjectManager::instance()->object( id ) ) != 0 )
				{
					if( Object->matchName( pName ) )
					{
						pId.append( id );
					}
				}
			}
		}
	}
}

int Task::findPreposition( const QStringList &pWords )
{
	mPreposition.clear();

	for( int i = 0 ; i < pWords.size() && mPreposition.isEmpty() ; i++ )
	{
		const QString	CurWrd = pWords.at( i );

		for( const char **p = mPrepositionList ; *p != 0 ; p++ )
		{
			QString			s( *p );
			QStringList		PrpSet = s.split( '/' );

			if( PrpSet.contains( CurWrd ) )
			{
				mPreposition = CurWrd;

				return( i );
			}
		}
	}

	return( pWords.size() );
}

void Task::getDirectAndIndirect( const QStringList &pWords, int pPrpIdx )
{
	mDirectObjectName.clear();
	mIndirectObjectName.clear();

	for( int i = 0 ; i < pWords.size() ; i++ )
	{
		if( i < pPrpIdx )
		{
			if( !mDirectObjectName.isEmpty() )
			{
				mDirectObjectName.append( " " );
			}

			mDirectObjectName.append( pWords.at( i ) );
		}
		else if( i > pPrpIdx )
		{
			if( !mIndirectObjectName.isEmpty() )
			{
				mIndirectObjectName.append( " " );
			}

			mIndirectObjectName.append( pWords.at( i ) );
		}
	}
}
<commit_msg>Added up preposition (for pick up)<commit_after>#include "task.h"
#include "lua_moo.h"
#include "objectmanager.h"
#include <QDateTime>

const char		*Task::mPrepositionList[] =
{
	"with/using",
	"at/to",
	"in front of",
	"in/inside/into",
	"on top of/on/onto/upon",
	"out of/from inside/from",
	"over",
	"through",
	"under/underneath/beneath",
	"behind",
	"beside",
	"for/about",
	"is",
	"as",
	"off/off of",
	"up",
	0
};

Task::Task( const QString &pCommand ) : mCommand( pCommand )
{
	mProgrammerId = OBJECT_NONE;

	mTimeStamp = QDateTime::currentMSecsSinceEpoch();

	mPlayer = OBJECT_NONE;
	mObject = OBJECT_NONE;
	mCaller = OBJECT_NONE;

	mDirectObjectId   = OBJECT_NONE;
	mIndirectObjectId = OBJECT_NONE;
}

Task::Task( const TaskEntry &pEntry )
{
	mProgrammerId = pEntry.playerid();

	mId			= pEntry.id();
	mTimeStamp	= pEntry.timestamp();
	mCommand	= pEntry.command();

	mPlayer		= pEntry.playerid();
	mObject		= OBJECT_NONE;
	mCaller		= OBJECT_NONE;

	mDirectObjectId   = OBJECT_NONE;
	mIndirectObjectId = OBJECT_NONE;
}

Task::~Task( void )
{
}

void Task::findObject( const QString &pName, QList<ObjectId> &pId ) const
{
	if( pName.isEmpty() )
	{
		return;
	}

	if( pName.startsWith( "#" ) )
	{
		bool	ok;
		int		id = pName.mid( 1 ).toInt( &ok );

		if( ok && ObjectManager::instance()->object( id ) != 0 )
		{
			pId.append( id );

			return;
		}

		return;
	}

	if( pName == "me" )
	{
		pId.append( player() );

		return;
	}

	if( pName == "here" )
	{
		Object			*Player;

		if( ( Player = ObjectManager::instance()->object( player() ) ) != 0 )
		{
			pId.append( Player->location() );
		}
	}

	// Otherwise, the server considers all of the objects whose location is either the player
	// (i.e., the objects the player is "holding", so to speak)

	Object			*Player;

	if( ( Player = ObjectManager::instance()->object( player() ) ) != 0 )
	{
		const QList<ObjectId>	&Contents = Player->contents();

		foreach( ObjectId id, Contents )
		{
			Object		*Object;

			if( ( Object = ObjectManager::instance()->object( id ) ) != 0 )
			{
				if( Object->matchName( pName ) )
				{
					pId.append( id );
				}
			}
		}

		// or the room the player is in (i.e., the objects in the same room as the player);

		// it will try to match the object string against the various names for these objects.

		Object			*Location;

		if( ( Location = ObjectManager::instance()->object( Player->location() ) ) != 0 )
		{
			if( Location->matchName( pName ) )
			{
				pId.append( Location->id() );
			}

			const QList<ObjectId>	&Contents = Location->contents();

			foreach( ObjectId id, Contents )
			{
				Object		*Object;

				if( ( Object = ObjectManager::instance()->object( id ) ) != 0 )
				{
					if( Object->matchName( pName ) )
					{
						pId.append( id );
					}
				}
			}
		}
	}
}

int Task::findPreposition( const QStringList &pWords )
{
	mPreposition.clear();

	for( int i = 0 ; i < pWords.size() && mPreposition.isEmpty() ; i++ )
	{
		const QString	CurWrd = pWords.at( i );

		for( const char **p = mPrepositionList ; *p != 0 ; p++ )
		{
			QString			s( *p );
			QStringList		PrpSet = s.split( '/' );

			if( PrpSet.contains( CurWrd ) )
			{
				mPreposition = CurWrd;

				return( i );
			}
		}
	}

	return( pWords.size() );
}

void Task::getDirectAndIndirect( const QStringList &pWords, int pPrpIdx )
{
	mDirectObjectName.clear();
	mIndirectObjectName.clear();

	for( int i = 0 ; i < pWords.size() ; i++ )
	{
		if( i < pPrpIdx )
		{
			if( !mDirectObjectName.isEmpty() )
			{
				mDirectObjectName.append( " " );
			}

			mDirectObjectName.append( pWords.at( i ) );
		}
		else if( i > pPrpIdx )
		{
			if( !mIndirectObjectName.isEmpty() )
			{
				mIndirectObjectName.append( " " );
			}

			mIndirectObjectName.append( pWords.at( i ) );
		}
	}
}
<|endoftext|>