From b9f3c8557be186de6bf982f177d49d804f12eb61 Mon Sep 17 00:00:00 2001 From: elexis Date: Fri, 26 Jul 2019 14:47:27 +0000 Subject: [PATCH] Move CClientArea ToJSVal / FromJSVal conversion from JSI_IGUIObject (since that should be agnostic of the conversion) to CClientArea (since that defines the properties). This was SVN commit r22557. --- source/gui/GUIbase.cpp | 94 ++++++++++++++++++- source/gui/GUIbase.h | 4 + source/gui/scripting/GuiScriptConversions.cpp | 10 ++ .../gui/scripting/JSInterface_IGUIObject.cpp | 66 ++----------- 4 files changed, 114 insertions(+), 60 deletions(-) diff --git a/source/gui/GUIbase.cpp b/source/gui/GUIbase.cpp index 1f5b247c6a..e358f63983 100644 --- a/source/gui/GUIbase.cpp +++ b/source/gui/GUIbase.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2015 Wildfire Games. +/* Copyright (C) 2019 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -18,6 +18,7 @@ #include "precompiled.h" #include "GUI.h" +#include "gui/scripting/JSInterface_GUITypes.h" #include "ps/CLogger.h" @@ -136,3 +137,94 @@ bool CClientArea::SetClientArea(const CStr& Value) percent.bottom = percents[3]; return true; } + +void CClientArea::ToJSVal(JSContext* cx, JS::MutableHandleValue ret) const +{ + JSAutoRequest rq(cx); + ScriptInterface* pScriptInterface = ScriptInterface::GetScriptInterfaceAndCBData(cx)->pScriptInterface; + ret.setObjectOrNull(pScriptInterface->CreateCustomObject("GUISize")); + + if (!ret.isObject()) + { + JS_ReportError(cx, "CClientArea value is not an Object"); + return; + } + + JS::RootedObject obj(cx, &ret.toObject()); + if (!JS_InstanceOf(cx, obj, &JSI_GUISize::JSI_class, nullptr)) + { + JS_ReportError(cx, "CClientArea value is not a CClientArea class instance"); + return; + } + +#define P(x, y, z)\ + if (!pScriptInterface->SetProperty(ret, #z, x.y)) \ + { \ + JS_ReportError(cx, "Could not SetProperty '%s'", #z); \ + return; \ + } + P(pixel, left, left); + P(pixel, top, top); + P(pixel, right, right); + P(pixel, bottom, bottom); + P(percent, left, rleft); + P(percent, top, rtop); + P(percent, right, rright); + P(percent, bottom, rbottom); +#undef P +} + +bool CClientArea::FromJSVal(JSContext* cx, JS::HandleValue v) +{ + JSAutoRequest rq(cx); + ScriptInterface* pScriptInterface = ScriptInterface::GetScriptInterfaceAndCBData(cx)->pScriptInterface; + + if (v.isString()) + { + CStrW str; + if (!ScriptInterface::FromJSVal(cx, v, str)) + { + JS_ReportError(cx, "Could not read CClientArea string"); + return false; + } + + if (!SetClientArea(str.ToUTF8())) + { + JS_ReportError(cx, "Could not set SetClientArea"); + return false; + } + return true; + } + + if (!v.isObject()) + { + JS_ReportError(cx, "CClientArea value is not an String, nor Object"); + return false; + } + + JS::RootedObject obj(cx, &v.toObject()); + if (!JS_InstanceOf(cx, obj, &JSI_GUISize::JSI_class, nullptr)) + { + JS_ReportError(cx, "CClientArea value is not a CClientArea class instance"); + return false; + } + +#define P(x, y, z) \ + if (!pScriptInterface->GetProperty(v, #z, x.y))\ + {\ + JS_ReportError(cx, "CClientArea could not get object property '%s'", #z);\ + return false;\ + } + + P(pixel, left, left); + P(pixel, top, top); + P(pixel, right, right); + P(pixel, bottom, bottom); + P(percent, left, rleft); + P(percent, top, rtop); + P(percent, right, rright); + P(percent, bottom, rbottom); +#undef P + + return true; +} diff --git a/source/gui/GUIbase.h b/source/gui/GUIbase.h index 3211821913..643467b249 100644 --- a/source/gui/GUIbase.h +++ b/source/gui/GUIbase.h @@ -41,6 +41,7 @@ GUI Core, stuff that the whole GUI uses // I would like to just forward declare CSize, but it doesn't // seem to be defined anywhere in the predefined header. #include "ps/Shapes.h" +#include "scriptinterface/ScriptInterface.h" class IGUIObject; @@ -202,6 +203,9 @@ public: { return pixel == other.pixel && percent == other.percent; } + + void ToJSVal(JSContext* cx, JS::MutableHandleValue ret) const; + bool FromJSVal(JSContext* cx, JS::HandleValue v); }; diff --git a/source/gui/scripting/GuiScriptConversions.cpp b/source/gui/scripting/GuiScriptConversions.cpp index b6fd2cee5f..0dd18fbb9a 100644 --- a/source/gui/scripting/GuiScriptConversions.cpp +++ b/source/gui/scripting/GuiScriptConversions.cpp @@ -144,6 +144,16 @@ JSVAL_VECTOR(CVector2D) JSVAL_VECTOR(std::vector) JSVAL_VECTOR(CGUIString) +template<> void ScriptInterface::ToJSVal(JSContext* cx, JS::MutableHandleValue ret, const CClientArea& val) +{ + val.ToJSVal(cx, ret); +} + +template<> bool ScriptInterface::FromJSVal(JSContext* cx, JS::HandleValue v, CClientArea& out) +{ + return out.FromJSVal(cx, v); +} + template<> void ScriptInterface::ToJSVal(JSContext* cx, JS::MutableHandleValue ret, const CGUIList& val) { ToJSVal(cx, ret, val.m_Items); diff --git a/source/gui/scripting/JSInterface_IGUIObject.cpp b/source/gui/scripting/JSInterface_IGUIObject.cpp index cc7d8f611e..cde9174a9f 100644 --- a/source/gui/scripting/JSInterface_IGUIObject.cpp +++ b/source/gui/scripting/JSInterface_IGUIObject.cpp @@ -170,30 +170,9 @@ bool JSI_IGUIObject::getProperty(JSContext* cx, JS::HandleObject obj, JS::Handle case GUIST_CClientArea: { - CClientArea area; - GUI::GetSetting(e, propName, area); - - JS::RootedObject obj(cx, pScriptInterface->CreateCustomObject("GUISize")); - vp.setObject(*obj); - try - { -#define P(x, y, z) pScriptInterface->SetProperty(vp, #z, area.x.y, false, true) - P(pixel, left, left); - P(pixel, top, top); - P(pixel, right, right); - P(pixel, bottom, bottom); - P(percent, left, rleft); - P(percent, top, rtop); - P(percent, right, rright); - P(percent, bottom, rbottom); -#undef P - } - catch (PSERROR_Scripting_ConversionFailed&) - { - debug_warn(L"Error creating size object!"); - break; - } - + CClientArea value; + GUI::GetSetting(e, propName, value); + ScriptInterface::ToJSVal(cx, vp, value); break; } @@ -435,42 +414,11 @@ bool JSI_IGUIObject::setProperty(JSContext* cx, JS::HandleObject obj, JS::Handle case GUIST_CClientArea: { - if (vp.isString()) - { - std::wstring value; - if (!ScriptInterface::FromJSVal(cx, vp, value)) - return false; - - if (e->SetSetting(propName, value) != PSRETURN_OK) - { - JS_ReportError(cx, "Invalid value for setting '%s'", propName.c_str()); - return false; - } - } - else if (vp.isObject() && JS_InstanceOf(cx, vpObj, &JSI_GUISize::JSI_class, NULL)) - { - CClientArea area; - GUI::GetSetting(e, propName, area); - - ScriptInterface* pScriptInterface = ScriptInterface::GetScriptInterfaceAndCBData(cx)->pScriptInterface; -#define P(x, y, z) pScriptInterface->GetProperty(vp, #z, area.x.y) - P(pixel, left, left); - P(pixel, top, top); - P(pixel, right, right); - P(pixel, bottom, bottom); - P(percent, left, rleft); - P(percent, top, rtop); - P(percent, right, rright); - P(percent, bottom, rbottom); -#undef P - - GUI::SetSetting(e, propName, area); - } - else - { - JS_ReportError(cx, "Size only accepts strings or GUISize objects"); + CClientArea value; + if (!ScriptInterface::FromJSVal(cx, vp, value)) return false; - } + + GUI::SetSetting(e, propName, value); break; }