Ticket #3403: charts_fix.patch
File charts_fix.patch, 12.0 KB (added by , 7 years ago) |
---|
-
source/gui/scripting/GuiScriptConversions.cpp
diff --git a/source/gui/scripting/GuiScriptConversions.cpp b/source/gui/scripting/GuiScriptConversions.cpp index b2a83c1..9c2d9d2 100644
a b 17 17 18 18 #include "precompiled.h" 19 19 20 #include "scriptinterface/Script Interface.h"20 #include "scriptinterface/ScriptConversions.h" 21 21 22 22 #include "gui/IGUIObject.h" 23 23 #include "lib/external_libraries/libsdl.h" 24 24 #include "ps/Hotkey.h" 25 #include "maths/Vector2D.h" 25 26 26 27 #define SET(obj, name, value) STMT(JS::RootedValue v_(cx); AssignOrToJSVal(cx, &v_, (value)); JS_SetProperty(cx, obj, (name), v_)) 27 28 // ignore JS_SetProperty return value, because errors should be impossible … … template<> void ScriptInterface::ToJSVal<IGUIObject*>(JSContext* UNUSED(cx), JS: 121 122 else 122 123 ret.setObject(*val->GetJSObject()); 123 124 } 125 126 // define some vectors 127 VECTOR(CVector2D) 128 VECTOR(std::vector<CVector2D>) 129 -
source/gui/scripting/JSInterface_IGUIObject.cpp
diff --git a/source/gui/scripting/JSInterface_IGUIObject.cpp b/source/gui/scripting/JSInterface_IGUIObject.cpp index 471b00c..48b1890 100644
a b bool JSI_IGUIObject::getProperty(JSContext* cx, JS::HandleObject obj, JS::Handle 302 302 { 303 303 CGUISeries value; 304 304 GUI<CGUISeries>::GetSetting(e, propName, value); 305 306 JS::RootedObject obj(cx, JS_NewArrayObject(cx, JS::HandleValueArray::empty())); 307 vp.setObject(*obj); 308 309 for (u32 i = 0; i < value.m_Series.size(); ++i) 310 { 311 JS::RootedObject inner_obj(cx, JS_NewArrayObject(cx, JS::HandleValueArray::empty())); 312 for (u32 j = 0; j < value.m_Series[i].size(); ++j) 313 { 314 JS::RootedObject val(cx, JS_NewArrayObject(cx, JS::HandleValueArray::empty())); 315 316 JS::RootedValue val_x(cx), val_y(cx); 317 ScriptInterface::ToJSVal(cx, &val_x, value.m_Series[i][j].X); 318 ScriptInterface::ToJSVal(cx, &val_y, value.m_Series[i][j].Y); 319 JS_SetElement(cx, val, 0, val_x); 320 JS_SetElement(cx, val, 1, val_y); 321 322 JS_SetElement(cx, inner_obj, j, val); 323 } 324 JS_SetElement(cx, obj, i, inner_obj); 325 } 326 305 ScriptInterface::ToJSVal(cx, vp, value.m_Series); 327 306 break; 328 307 } 329 308 … … bool JSI_IGUIObject::setProperty(JSContext* cx, JS::HandleObject obj, JS::Handle 619 598 620 599 case GUIST_CGUISeries: 621 600 { 622 u32 length;623 if (!vp.isObject() || !JS_GetArrayLength(cx, vpObj, &length))624 {625 JS_ReportError(cx, "Table only accepts a GUISeries object");626 return false;627 }628 629 601 CGUISeries series; 630 series.m_Series.resize(length); 631 for (u32 i = 0; i < length; ++i) 602 if (ScriptInterface::FromJSVal(cx, vp, series.m_Series)) 603 GUI<CGUISeries>::SetSetting(e, propName, series); 604 else 632 605 { 633 JS::RootedValue data_value(cx); 634 if (!JS_GetElement(cx, vpObj, i, &data_value)) 635 { 636 JS_ReportError(cx, "Failed to get a data of series"); 637 return false; 638 } 639 640 JS::RootedObject data(cx, data_value.toObjectOrNull()); 641 u32 data_length; 642 if (!JS_GetArrayLength(cx, data, &data_length)) 643 { 644 JS_ReportError(cx, "Series only accepts a chart data"); 645 return false; 646 } 647 648 series.m_Series[i].resize(data_length); 649 for (u32 j = 0; j < data_length; ++j) 650 { 651 JS::RootedValue element_value(cx); 652 if (!JS_GetElement(cx, data, j, &element_value)) 653 { 654 JS_ReportError(cx, "Failed to get a chart data element"); 655 return false; 656 } 657 658 JS::RootedObject element(cx, element_value.toObjectOrNull()); 659 u32 element_length; 660 if (!JS_GetArrayLength(cx, element, &element_length) || element_length < 2) 661 { 662 JS_ReportError(cx, "Chart data only accepts a point"); 663 return false; 664 } 665 666 JS::RootedValue element_x(cx), element_y(cx); 667 if (!JS_GetElement(cx, element, 0, &element_x) || !JS_GetElement(cx, element, 1, &element_y)) 668 { 669 JS_ReportError(cx, "Failed to get a chart point"); 670 return false; 671 } 672 673 if (!ScriptInterface::FromJSVal(cx, element_x, series.m_Series[i][j].X) || 674 !ScriptInterface::FromJSVal(cx, element_y, series.m_Series[i][j].Y)) 675 return false; 676 } 606 JS_ReportError(cx, "Invalid value for chart series '%s'", propName.c_str()); 607 return false; 677 608 } 678 679 GUI<CGUISeries>::SetSetting(e, propName, series);680 609 break; 681 610 } 682 611 -
source/scriptinterface/ScriptConversions.cpp
diff --git a/source/scriptinterface/ScriptConversions.cpp b/source/scriptinterface/ScriptConversions.cpp index bf7e910..538c32a 100644
a b 15 15 * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>. 16 16 */ 17 17 18 #include "precompiled.h" 19 20 #include "ScriptInterface.h" 18 #include "ScriptConversions.h" 21 19 22 20 #include "graphics/Entity.h" 21 #include "maths/Vector2D.h" 23 22 #include "ps/utf16string.h" 24 #include "ps/CLogger.h"25 23 #include "ps/CStr.h" 26 #include "scriptinterface/ScriptExtraHeaders.h" // for typed arrays27 28 #define FAIL(msg) STMT(JS_ReportError(cx, msg); return false)29 30 // Implicit type conversions often hide bugs, so warn about them31 #define WARN_IF_NOT(c, v) STMT(if (!(c)) { JS_ReportWarning(cx, "Script value conversion check failed: %s (got type %s)", #c, InformalValueTypeName(v)); })32 24 33 25 // TODO: SpiderMonkey: Follow upstream progresses about JS_InformalValueTypeName in the API 34 26 // https://bugzilla.mozilla.org/show_bug.cgi?id=1285917 … … template<> void ScriptInterface::ToJSVal<CStr8>(JSContext* cx, JS::MutableHandle 376 368 } 377 369 378 370 //////////////////////////////////////////////////////////////// 379 // Compound types: 380 381 template<typename T> static void ToJSVal_vector(JSContext* cx, JS::MutableHandleValue ret, const std::vector<T>& val) 382 { 383 JSAutoRequest rq(cx); 384 JS::RootedObject obj(cx, JS_NewArrayObject(cx, 0)); 385 if (!obj) 386 { 387 ret.setUndefined(); 388 return; 389 } 390 for (u32 i = 0; i < val.size(); ++i) 391 { 392 JS::RootedValue el(cx); 393 ScriptInterface::ToJSVal<T>(cx, &el, val[i]); 394 JS_SetElement(cx, obj, i, el); 395 } 396 ret.setObject(*obj); 397 } 398 399 template<typename T> static bool FromJSVal_vector(JSContext* cx, JS::HandleValue v, std::vector<T>& out) 400 { 401 JSAutoRequest rq(cx); 402 JS::RootedObject obj(cx); 403 if (!v.isObject()) 404 FAIL("Argument must be an array"); 405 obj = &v.toObject(); 406 if (!(JS_IsArrayObject(cx, obj) || JS_IsTypedArrayObject(obj))) 407 FAIL("Argument must be an array"); 408 409 u32 length; 410 if (!JS_GetArrayLength(cx, obj, &length)) 411 FAIL("Failed to get array length"); 412 out.reserve(length); 413 for (u32 i = 0; i < length; ++i) 414 { 415 JS::RootedValue el(cx); 416 if (!JS_GetElement(cx, obj, i, &el)) 417 FAIL("Failed to read array element"); 418 T el2; 419 if (!ScriptInterface::FromJSVal<T>(cx, el, el2)) 420 return false; 421 out.push_back(el2); 422 } 423 return true; 424 } 425 371 // Compound types 426 372 // Instantiate various vector types: 427 373 428 #define VECTOR(T) \429 template<> void ScriptInterface::ToJSVal<std::vector<T> >(JSContext* cx, JS::MutableHandleValue ret, const std::vector<T>& val) \430 { \431 ToJSVal_vector(cx, ret, val); \432 } \433 template<> bool ScriptInterface::FromJSVal<std::vector<T> >(JSContext* cx, JS::HandleValue v, std::vector<T>& out) \434 { \435 return FromJSVal_vector(cx, v, out); \436 }437 438 374 VECTOR(int) 439 375 VECTOR(u32) 440 376 VECTOR(u16) … … template<> bool ScriptInterface::FromJSVal<std::vector<Entity> >(JSContext* cx, 453 389 { 454 390 return FromJSVal_vector(cx, v, out); 455 391 } 392 393 template<> void ScriptInterface::ToJSVal<CVector2D>(JSContext* cx, JS::MutableHandleValue ret, const CVector2D& val) 394 { 395 std::vector<float> vec = {val.X, val.Y}; 396 ToJSVal_vector(cx, ret, vec); 397 } 398 399 template<> bool ScriptInterface::FromJSVal<CVector2D>(JSContext* cx, JS::HandleValue v, CVector2D& out) 400 { 401 std::vector<float> vec; 402 403 if (!FromJSVal_vector(cx, v, vec)) 404 return false; 405 406 if (vec.size() != 2) 407 return false; 408 409 out.X = vec[0]; 410 out.Y = vec[1]; 411 412 return true; 413 } -
new file source/scriptinterface/ScriptConversions.h
diff --git a/source/scriptinterface/ScriptConversions.h b/source/scriptinterface/ScriptConversions.h new file mode 100644 index 0000000..d136de3
- + 1 /* Copyright (C) 2016 Wildfire Games. 2 * This file is part of 0 A.D. 3 * 4 * 0 A.D. is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * 0 A.D. is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 #ifndef INCLUDED_SCRIPTCONVERSIONS 19 #define INCLUDED_SCRIPTCONVERSIONS 20 21 #include "precompiled.h" 22 23 #include "ScriptInterface.h" 24 #include "ps/CLogger.h" 25 #include "scriptinterface/ScriptExtraHeaders.h" // for typed arrays 26 27 #define FAIL(msg) STMT(JS_ReportError(cx, msg); return false) 28 29 // Implicit type conversions often hide bugs, so warn about them 30 #define WARN_IF_NOT(c, v) STMT(if (!(c)) { JS_ReportWarning(cx, "Script value conversion check failed: %s (got type %s)", #c, InformalValueTypeName(v)); }) 31 32 template<typename T> static void ToJSVal_vector(JSContext* cx, JS::MutableHandleValue ret, const std::vector<T>& val) 33 { 34 JSAutoRequest rq(cx); 35 JS::RootedObject obj(cx, JS_NewArrayObject(cx, 0)); 36 if (!obj) 37 { 38 ret.setUndefined(); 39 return; 40 } 41 for (u32 i = 0; i < val.size(); ++i) 42 { 43 JS::RootedValue el(cx); 44 ScriptInterface::ToJSVal<T>(cx, &el, val[i]); 45 JS_SetElement(cx, obj, i, el); 46 } 47 ret.setObject(*obj); 48 } 49 50 template<typename T> static bool FromJSVal_vector(JSContext* cx, JS::HandleValue v, std::vector<T>& out) 51 { 52 JSAutoRequest rq(cx); 53 JS::RootedObject obj(cx); 54 if (!v.isObject()) 55 FAIL("Argument must be an array"); 56 obj = &v.toObject(); 57 if (!(JS_IsArrayObject(cx, obj) || JS_IsTypedArrayObject(obj))) 58 FAIL("Argument must be an array"); 59 60 u32 length; 61 if (!JS_GetArrayLength(cx, obj, &length)) 62 FAIL("Failed to get array length"); 63 out.reserve(length); 64 for (u32 i = 0; i < length; ++i) 65 { 66 JS::RootedValue el(cx); 67 if (!JS_GetElement(cx, obj, i, &el)) 68 FAIL("Failed to read array element"); 69 T el2; 70 if (!ScriptInterface::FromJSVal<T>(cx, el, el2)) 71 return false; 72 out.push_back(el2); 73 } 74 return true; 75 } 76 77 #define VECTOR(T) \ 78 template<> void ScriptInterface::ToJSVal<std::vector<T> >(JSContext* cx, JS::MutableHandleValue ret, const std::vector<T>& val) \ 79 { \ 80 ToJSVal_vector(cx, ret, val); \ 81 } \ 82 template<> bool ScriptInterface::FromJSVal<std::vector<T> >(JSContext* cx, JS::HandleValue v, std::vector<T>& out) \ 83 { \ 84 return FromJSVal_vector(cx, v, out); \ 85 } 86 87 #endif //INCLUDED_SCRIPTCONVERSIONS -
source/simulation2/scripting/EngineScriptConversions.cpp
diff --git a/source/simulation2/scripting/EngineScriptConversions.cpp b/source/simulation2/scripting/EngineScriptConversions.cpp index 5aa970c..299e2d7 100644
a b 17 17 18 18 #include "precompiled.h" 19 19 20 #include "scriptinterface/ScriptInterface.h" 21 #include "scriptinterface/ScriptExtraHeaders.h" // for typed arrays 20 #include "scriptinterface/ScriptConversions.h" 22 21 23 22 #include "maths/Fixed.h" 24 23 #include "maths/FixedVector2D.h" … … template<> void ScriptInterface::ToJSVal<Grid<u16> >(JSContext* cx, JS::MutableH 299 298 ret.setObject(*obj); 300 299 } 301 300 302 // TODO: This is copy-pasted from scriptinterface/ScriptConversions.cpp (#define VECTOR stuff), would be nice to remove the duplication 303 template<> void ScriptInterface::ToJSVal<std::vector<CFixedVector2D> >(JSContext* cx, JS::MutableHandleValue ret, const std::vector<CFixedVector2D>& val) 304 { 305 JSAutoRequest rq(cx); 306 JS::RootedObject obj(cx, JS_NewArrayObject(cx, 0)); 307 if (!obj) 308 { 309 ret.setUndefined(); 310 return; 311 } 312 for (size_t i = 0; i < val.size(); ++i) 313 { 314 JS::RootedValue el(cx); 315 ScriptInterface::ToJSVal<CFixedVector2D>(cx, &el, val[i]); 316 JS_SetElement(cx, obj, i, el); 317 } 318 ret.setObject(*obj); 319 } 301 // define vectors 302 VECTOR(CFixedVector2D)