forked from 0ad/0ad
Fix [19027] by using generic code for conversions and fixing a few other issues. Refs #3403. Reviewed by leper.
Also fix some of the warnings that jenkins showed. Differential Revision: https://code.wildfiregames.com/D24 This was SVN commit r19115.
This commit is contained in:
parent
1a038b1735
commit
2bae30c454
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2016 Wildfire Games.
|
||||
/* Copyright (C) 2017 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -38,6 +38,15 @@ CChart::~CChart()
|
||||
void CChart::HandleMessage(SGUIMessage& Message)
|
||||
{
|
||||
// TODO: implement zoom
|
||||
switch (Message.type)
|
||||
{
|
||||
case GUIM_SETTINGS_UPDATED:
|
||||
{
|
||||
UpdateSeries();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CChart::Draw()
|
||||
@ -47,16 +56,14 @@ void CChart::Draw()
|
||||
if (!GetGUI())
|
||||
return;
|
||||
|
||||
UpdateSeries();
|
||||
if (m_Series.empty())
|
||||
return;
|
||||
|
||||
const float bz = GetBufferedZ();
|
||||
CRect rect = GetChartRect();
|
||||
const float width = rect.GetWidth();
|
||||
const float height = rect.GetHeight();
|
||||
|
||||
if (m_Series.empty())
|
||||
return;
|
||||
|
||||
// Disable depth updates to prevent apparent z-fighting-related issues
|
||||
// with some drivers causing units to get drawn behind the texture.
|
||||
glDepthMask(0);
|
||||
@ -93,6 +100,7 @@ void CChart::Draw()
|
||||
continue;
|
||||
|
||||
std::vector<float> vertices;
|
||||
vertices.reserve(data.m_Points.size() * 3);
|
||||
for (const CVector2D& point : data.m_Points)
|
||||
{
|
||||
vertices.push_back(rect.left + (point.X - leftBottom.X) * scale.X);
|
||||
@ -131,10 +139,10 @@ void CChart::UpdateSeries()
|
||||
GUI<CGUIList>::GetSettingPointer(this, "series_color", pSeriesColor);
|
||||
|
||||
m_Series.clear();
|
||||
m_Series.resize(pSeries->m_Series.size());
|
||||
for (size_t i = 0; i < pSeries->m_Series.size(); ++i)
|
||||
{
|
||||
m_Series.resize(m_Series.size() + 1);
|
||||
CChartData& data = m_Series.back();
|
||||
CChartData& data = m_Series[i];
|
||||
|
||||
if (i < pSeriesColor->m_Items.size() && !GUI<int>::ParseColor(pSeriesColor->m_Items[i].GetOriginalString(), data.m_Color, 0))
|
||||
LOGWARNING("GUI: Error parsing 'series_color' (\"%s\")", utf8_from_wstring(pSeriesColor->m_Items[i].GetOriginalString()));
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2016 Wildfire Games.
|
||||
/* Copyright (C) 2017 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -29,4 +29,4 @@ public:
|
||||
std::vector<std::vector<CVector2D>> m_Series;
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif // INCLUDED_CGUISERIES
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2016 Wildfire Games.
|
||||
/* Copyright (C) 2017 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -17,11 +17,12 @@
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
#include "scriptinterface/ScriptInterface.h"
|
||||
#include "scriptinterface/ScriptConversions.h"
|
||||
|
||||
#include "gui/IGUIObject.h"
|
||||
#include "lib/external_libraries/libsdl.h"
|
||||
#include "ps/Hotkey.h"
|
||||
#include "maths/Vector2D.h"
|
||||
|
||||
#define SET(obj, name, value) STMT(JS::RootedValue v_(cx); AssignOrToJSVal(cx, &v_, (value)); JS_SetProperty(cx, obj, (name), v_))
|
||||
// ignore JS_SetProperty return value, because errors should be impossible
|
||||
@ -121,3 +122,23 @@ template<> void ScriptInterface::ToJSVal<IGUIObject*>(JSContext* UNUSED(cx), JS:
|
||||
else
|
||||
ret.setObject(*val->GetJSObject());
|
||||
}
|
||||
|
||||
template<> void ScriptInterface::ToJSVal<CGUIString>(JSContext* cx, JS::MutableHandleValue ret, const CGUIString& val)
|
||||
{
|
||||
ScriptInterface::ToJSVal(cx, ret, val.GetOriginalString());
|
||||
}
|
||||
|
||||
template<> bool ScriptInterface::FromJSVal<CGUIString>(JSContext* cx, JS::HandleValue v, CGUIString& out)
|
||||
{
|
||||
std::wstring val;
|
||||
if (!ScriptInterface::FromJSVal(cx, v, val))
|
||||
return false;
|
||||
out.SetValue(val);
|
||||
return true;
|
||||
}
|
||||
|
||||
// define some vectors
|
||||
JSVAL_VECTOR(CVector2D)
|
||||
JSVAL_VECTOR(std::vector<CVector2D>)
|
||||
JSVAL_VECTOR(CGUIString)
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2016 Wildfire Games.
|
||||
/* Copyright (C) 2017 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -284,17 +284,7 @@ bool JSI_IGUIObject::getProperty(JSContext* cx, JS::HandleObject obj, JS::Handle
|
||||
{
|
||||
CGUIList value;
|
||||
GUI<CGUIList>::GetSetting(e, propName, value);
|
||||
|
||||
JS::RootedObject obj(cx, JS_NewArrayObject(cx, JS::HandleValueArray::empty()));
|
||||
vp.setObject(*obj);
|
||||
|
||||
for (u32 i = 0; i < value.m_Items.size(); ++i)
|
||||
{
|
||||
JS::RootedValue val(cx);
|
||||
ScriptInterface::ToJSVal(cx, &val, value.m_Items[i].GetOriginalString());
|
||||
JS_SetElement(cx, obj, i, val);
|
||||
}
|
||||
|
||||
ScriptInterface::ToJSVal(cx, vp, value.m_Items);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -302,28 +292,7 @@ bool JSI_IGUIObject::getProperty(JSContext* cx, JS::HandleObject obj, JS::Handle
|
||||
{
|
||||
CGUISeries value;
|
||||
GUI<CGUISeries>::GetSetting(e, propName, value);
|
||||
|
||||
JS::RootedObject obj(cx, JS_NewArrayObject(cx, JS::HandleValueArray::empty()));
|
||||
vp.setObject(*obj);
|
||||
|
||||
for (u32 i = 0; i < value.m_Series.size(); ++i)
|
||||
{
|
||||
JS::RootedObject inner_obj(cx, JS_NewArrayObject(cx, JS::HandleValueArray::empty()));
|
||||
for (u32 j = 0; j < value.m_Series[i].size(); ++j)
|
||||
{
|
||||
JS::RootedObject val(cx, JS_NewArrayObject(cx, JS::HandleValueArray::empty()));
|
||||
|
||||
JS::RootedValue val_x(cx), val_y(cx);
|
||||
ScriptInterface::ToJSVal(cx, &val_x, value.m_Series[i][j].X);
|
||||
ScriptInterface::ToJSVal(cx, &val_y, value.m_Series[i][j].Y);
|
||||
JS_SetElement(cx, val, 0, val_x);
|
||||
JS_SetElement(cx, val, 1, val_y);
|
||||
|
||||
JS_SetElement(cx, inner_obj, j, val);
|
||||
}
|
||||
JS_SetElement(cx, obj, i, inner_obj);
|
||||
}
|
||||
|
||||
ScriptInterface::ToJSVal(cx, vp, value.m_Series);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -585,98 +554,27 @@ bool JSI_IGUIObject::setProperty(JSContext* cx, JS::HandleObject obj, JS::Handle
|
||||
|
||||
case GUIST_CGUIList:
|
||||
{
|
||||
u32 length;
|
||||
if (!vp.isObject() || !JS_GetArrayLength(cx, vpObj, &length))
|
||||
CGUIList list;
|
||||
if (ScriptInterface::FromJSVal(cx, vp, list.m_Items))
|
||||
GUI<CGUIList>::SetSetting(e, propName, list);
|
||||
else
|
||||
{
|
||||
JS_ReportError(cx, "List only accepts a GUIList object");
|
||||
JS_ReportError(cx, "Failed to get list '%s'", propName.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
CGUIList list;
|
||||
|
||||
for (u32 i = 0; i < length; ++i)
|
||||
{
|
||||
JS::RootedValue element(cx);
|
||||
if (!JS_GetElement(cx, vpObj, i, &element))
|
||||
{
|
||||
JS_ReportError(cx, "Failed to get list element");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::wstring value;
|
||||
if (!ScriptInterface::FromJSVal(cx, element, value))
|
||||
return false;
|
||||
|
||||
CGUIString str;
|
||||
str.SetValue(value);
|
||||
|
||||
list.m_Items.push_back(str);
|
||||
}
|
||||
|
||||
GUI<CGUIList>::SetSetting(e, propName, list);
|
||||
break;
|
||||
}
|
||||
|
||||
case GUIST_CGUISeries:
|
||||
{
|
||||
u32 length;
|
||||
if (!vp.isObject() || !JS_GetArrayLength(cx, vpObj, &length))
|
||||
CGUISeries series;
|
||||
if (ScriptInterface::FromJSVal(cx, vp, series.m_Series))
|
||||
GUI<CGUISeries>::SetSetting(e, propName, series);
|
||||
else
|
||||
{
|
||||
JS_ReportError(cx, "Table only accepts a GUISeries object");
|
||||
JS_ReportError(cx, "Invalid value for chart series '%s'", propName.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
CGUISeries series;
|
||||
series.m_Series.resize(length);
|
||||
for (u32 i = 0; i < length; ++i)
|
||||
{
|
||||
JS::RootedValue data_value(cx);
|
||||
if (!JS_GetElement(cx, vpObj, i, &data_value))
|
||||
{
|
||||
JS_ReportError(cx, "Failed to get a data of series");
|
||||
return false;
|
||||
}
|
||||
|
||||
JS::RootedObject data(cx, data_value.toObjectOrNull());
|
||||
u32 data_length;
|
||||
if (!JS_GetArrayLength(cx, data, &data_length))
|
||||
{
|
||||
JS_ReportError(cx, "Series only accepts a chart data");
|
||||
return false;
|
||||
}
|
||||
|
||||
series.m_Series[i].resize(data_length);
|
||||
for (u32 j = 0; j < data_length; ++j)
|
||||
{
|
||||
JS::RootedValue element_value(cx);
|
||||
if (!JS_GetElement(cx, data, j, &element_value))
|
||||
{
|
||||
JS_ReportError(cx, "Failed to get a chart data element");
|
||||
return false;
|
||||
}
|
||||
|
||||
JS::RootedObject element(cx, element_value.toObjectOrNull());
|
||||
u32 element_length;
|
||||
if (!JS_GetArrayLength(cx, element, &element_length) || element_length < 2)
|
||||
{
|
||||
JS_ReportError(cx, "Chart data only accepts a point");
|
||||
return false;
|
||||
}
|
||||
|
||||
JS::RootedValue element_x(cx), element_y(cx);
|
||||
if (!JS_GetElement(cx, element, 0, &element_x) || !JS_GetElement(cx, element, 1, &element_y))
|
||||
{
|
||||
JS_ReportError(cx, "Failed to get a chart point");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ScriptInterface::FromJSVal(cx, element_x, series.m_Series[i][j].X) ||
|
||||
!ScriptInterface::FromJSVal(cx, element_y, series.m_Series[i][j].Y))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
GUI<CGUISeries>::SetSetting(e, propName, series);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2016 Wildfire Games.
|
||||
/* Copyright (C) 2017 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -17,13 +17,12 @@
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
#include "ScriptInterface.h"
|
||||
#include "ScriptConversions.h"
|
||||
|
||||
#include "graphics/Entity.h"
|
||||
#include "maths/Vector2D.h"
|
||||
#include "ps/utf16string.h"
|
||||
#include "ps/CLogger.h"
|
||||
#include "ps/CStr.h"
|
||||
#include "scriptinterface/ScriptExtraHeaders.h" // for typed arrays
|
||||
|
||||
#define FAIL(msg) STMT(JS_ReportError(cx, msg); return false)
|
||||
|
||||
@ -376,71 +375,15 @@ template<> void ScriptInterface::ToJSVal<CStr8>(JSContext* cx, JS::MutableHandle
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// Compound types:
|
||||
|
||||
template<typename T> static void ToJSVal_vector(JSContext* cx, JS::MutableHandleValue ret, const std::vector<T>& val)
|
||||
{
|
||||
JSAutoRequest rq(cx);
|
||||
JS::RootedObject obj(cx, JS_NewArrayObject(cx, 0));
|
||||
if (!obj)
|
||||
{
|
||||
ret.setUndefined();
|
||||
return;
|
||||
}
|
||||
for (u32 i = 0; i < val.size(); ++i)
|
||||
{
|
||||
JS::RootedValue el(cx);
|
||||
ScriptInterface::ToJSVal<T>(cx, &el, val[i]);
|
||||
JS_SetElement(cx, obj, i, el);
|
||||
}
|
||||
ret.setObject(*obj);
|
||||
}
|
||||
|
||||
template<typename T> static bool FromJSVal_vector(JSContext* cx, JS::HandleValue v, std::vector<T>& out)
|
||||
{
|
||||
JSAutoRequest rq(cx);
|
||||
JS::RootedObject obj(cx);
|
||||
if (!v.isObject())
|
||||
FAIL("Argument must be an array");
|
||||
obj = &v.toObject();
|
||||
if (!(JS_IsArrayObject(cx, obj) || JS_IsTypedArrayObject(obj)))
|
||||
FAIL("Argument must be an array");
|
||||
|
||||
u32 length;
|
||||
if (!JS_GetArrayLength(cx, obj, &length))
|
||||
FAIL("Failed to get array length");
|
||||
out.reserve(length);
|
||||
for (u32 i = 0; i < length; ++i)
|
||||
{
|
||||
JS::RootedValue el(cx);
|
||||
if (!JS_GetElement(cx, obj, i, &el))
|
||||
FAIL("Failed to read array element");
|
||||
T el2;
|
||||
if (!ScriptInterface::FromJSVal<T>(cx, el, el2))
|
||||
return false;
|
||||
out.push_back(el2);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Compound types
|
||||
// Instantiate various vector types:
|
||||
|
||||
#define VECTOR(T) \
|
||||
template<> void ScriptInterface::ToJSVal<std::vector<T> >(JSContext* cx, JS::MutableHandleValue ret, const std::vector<T>& val) \
|
||||
{ \
|
||||
ToJSVal_vector(cx, ret, val); \
|
||||
} \
|
||||
template<> bool ScriptInterface::FromJSVal<std::vector<T> >(JSContext* cx, JS::HandleValue v, std::vector<T>& out) \
|
||||
{ \
|
||||
return FromJSVal_vector(cx, v, out); \
|
||||
}
|
||||
|
||||
VECTOR(int)
|
||||
VECTOR(u32)
|
||||
VECTOR(u16)
|
||||
VECTOR(std::string)
|
||||
VECTOR(std::wstring)
|
||||
VECTOR(CStr8)
|
||||
JSVAL_VECTOR(int)
|
||||
JSVAL_VECTOR(u32)
|
||||
JSVAL_VECTOR(u16)
|
||||
JSVAL_VECTOR(std::string)
|
||||
JSVAL_VECTOR(std::wstring)
|
||||
JSVAL_VECTOR(CStr8)
|
||||
|
||||
|
||||
class IComponent;
|
||||
@ -453,3 +396,25 @@ template<> bool ScriptInterface::FromJSVal<std::vector<Entity> >(JSContext* cx,
|
||||
{
|
||||
return FromJSVal_vector(cx, v, out);
|
||||
}
|
||||
|
||||
template<> void ScriptInterface::ToJSVal<CVector2D>(JSContext* cx, JS::MutableHandleValue ret, const CVector2D& val)
|
||||
{
|
||||
std::vector<float> vec = {val.X, val.Y};
|
||||
ToJSVal_vector(cx, ret, vec);
|
||||
}
|
||||
|
||||
template<> bool ScriptInterface::FromJSVal<CVector2D>(JSContext* cx, JS::HandleValue v, CVector2D& out)
|
||||
{
|
||||
std::vector<float> vec;
|
||||
|
||||
if (!FromJSVal_vector(cx, v, vec))
|
||||
return false;
|
||||
|
||||
if (vec.size() != 2)
|
||||
return false;
|
||||
|
||||
out.X = vec[0];
|
||||
out.Y = vec[1];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
89
source/scriptinterface/ScriptConversions.h
Normal file
89
source/scriptinterface/ScriptConversions.h
Normal file
@ -0,0 +1,89 @@
|
||||
/* Copyright (C) 2017 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 0 A.D. 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_SCRIPTCONVERSIONS
|
||||
#define INCLUDED_SCRIPTCONVERSIONS
|
||||
|
||||
#include "ScriptInterface.h"
|
||||
#include "scriptinterface/ScriptExtraHeaders.h" // for typed arrays
|
||||
|
||||
#include <limits>
|
||||
|
||||
template<typename T> static void ToJSVal_vector(JSContext* cx, JS::MutableHandleValue ret, const std::vector<T>& val)
|
||||
{
|
||||
JSAutoRequest rq(cx);
|
||||
JS::RootedObject obj(cx, JS_NewArrayObject(cx, 0));
|
||||
if (!obj)
|
||||
{
|
||||
ret.setUndefined();
|
||||
return;
|
||||
}
|
||||
|
||||
ENSURE(val.size() <= std::numeric_limits<u32>::max());
|
||||
for (u32 i = 0; i < val.size(); ++i)
|
||||
{
|
||||
JS::RootedValue el(cx);
|
||||
ScriptInterface::ToJSVal<T>(cx, &el, val[i]);
|
||||
JS_SetElement(cx, obj, i, el);
|
||||
}
|
||||
ret.setObject(*obj);
|
||||
}
|
||||
|
||||
#define FAIL(msg) STMT(JS_ReportError(cx, msg); return false)
|
||||
|
||||
template<typename T> static bool FromJSVal_vector(JSContext* cx, JS::HandleValue v, std::vector<T>& out)
|
||||
{
|
||||
JSAutoRequest rq(cx);
|
||||
JS::RootedObject obj(cx);
|
||||
if (!v.isObject())
|
||||
FAIL("Argument must be an array");
|
||||
|
||||
obj = &v.toObject();
|
||||
if (!(JS_IsArrayObject(cx, obj) || JS_IsTypedArrayObject(obj)))
|
||||
FAIL("Argument must be an array");
|
||||
|
||||
u32 length;
|
||||
if (!JS_GetArrayLength(cx, obj, &length))
|
||||
FAIL("Failed to get array length");
|
||||
|
||||
out.reserve(length);
|
||||
for (u32 i = 0; i < length; ++i)
|
||||
{
|
||||
JS::RootedValue el(cx);
|
||||
if (!JS_GetElement(cx, obj, i, &el))
|
||||
FAIL("Failed to read array element");
|
||||
T el2;
|
||||
if (!ScriptInterface::FromJSVal<T>(cx, el, el2))
|
||||
return false;
|
||||
out.push_back(el2);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#undef FAIL
|
||||
|
||||
#define JSVAL_VECTOR(T) \
|
||||
template<> void ScriptInterface::ToJSVal<std::vector<T> >(JSContext* cx, JS::MutableHandleValue ret, const std::vector<T>& val) \
|
||||
{ \
|
||||
ToJSVal_vector(cx, ret, val); \
|
||||
} \
|
||||
template<> bool ScriptInterface::FromJSVal<std::vector<T> >(JSContext* cx, JS::HandleValue v, std::vector<T>& out) \
|
||||
{ \
|
||||
return FromJSVal_vector(cx, v, out); \
|
||||
}
|
||||
|
||||
#endif //INCLUDED_SCRIPTCONVERSIONS
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2016 Wildfire Games.
|
||||
/* Copyright (C) 2017 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -17,8 +17,7 @@
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
#include "scriptinterface/ScriptInterface.h"
|
||||
#include "scriptinterface/ScriptExtraHeaders.h" // for typed arrays
|
||||
#include "scriptinterface/ScriptConversions.h"
|
||||
|
||||
#include "maths/Fixed.h"
|
||||
#include "maths/FixedVector2D.h"
|
||||
@ -299,21 +298,5 @@ template<> void ScriptInterface::ToJSVal<Grid<u16> >(JSContext* cx, JS::MutableH
|
||||
ret.setObject(*obj);
|
||||
}
|
||||
|
||||
// TODO: This is copy-pasted from scriptinterface/ScriptConversions.cpp (#define VECTOR stuff), would be nice to remove the duplication
|
||||
template<> void ScriptInterface::ToJSVal<std::vector<CFixedVector2D> >(JSContext* cx, JS::MutableHandleValue ret, const std::vector<CFixedVector2D>& val)
|
||||
{
|
||||
JSAutoRequest rq(cx);
|
||||
JS::RootedObject obj(cx, JS_NewArrayObject(cx, 0));
|
||||
if (!obj)
|
||||
{
|
||||
ret.setUndefined();
|
||||
return;
|
||||
}
|
||||
for (size_t i = 0; i < val.size(); ++i)
|
||||
{
|
||||
JS::RootedValue el(cx);
|
||||
ScriptInterface::ToJSVal<CFixedVector2D>(cx, &el, val[i]);
|
||||
JS_SetElement(cx, obj, i, el);
|
||||
}
|
||||
ret.setObject(*obj);
|
||||
}
|
||||
// define vectors
|
||||
JSVAL_VECTOR(CFixedVector2D)
|
||||
|
Loading…
Reference in New Issue
Block a user