Changeset View
Changeset View
Standalone View
Standalone View
source/gui/Scripting/JSInterface_GUIProxy_impl.h
- This file was copied from source/gui/Scripting/JSInterface_IGUIObject.cpp.
Show All 9 Lines | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||
* GNU General Public License for more details. | * GNU General Public License for more details. | ||||
* | * | ||||
* You should have received a copy of the GNU General Public License | * 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/>. | * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>. | ||||
*/ | */ | ||||
#include "precompiled.h" | // This file is included directly into actual implementation files. | ||||
#include "JSInterface_IGUIObject.h" | template <typename T> | ||||
js::Class& JSI_GUIProxy<T>::ClassDefinition() | |||||
#include "gui/CGUI.h" | { | ||||
#include "gui/CGUISetting.h" | static js::Class c = PROXY_CLASS_DEF("GUIObjectProxy", JSCLASS_HAS_PRIVATE | JSCLASS_HAS_CACHED_PROTO(JSProto_Proxy)); | ||||
#include "gui/ObjectBases/IGUIObject.h" | return c; | ||||
#include "ps/CLogger.h" | } | ||||
#include "scriptinterface/ScriptExtraHeaders.h" | |||||
#include "scriptinterface/ScriptInterface.h" | |||||
JSClass JSI_IGUIObject::JSI_class = { | |||||
"GUIObject", JSCLASS_HAS_PRIVATE, &JSI_IGUIObject::JSI_classops | |||||
}; | |||||
JSClassOps JSI_IGUIObject::JSI_classops = { | |||||
nullptr, | |||||
JSI_IGUIObject::deleteProperty, | |||||
JSI_IGUIObject::getProperty, | |||||
JSI_IGUIObject::setProperty, | |||||
nullptr, nullptr, nullptr, nullptr, | |||||
nullptr, nullptr, nullptr, nullptr | |||||
}; | |||||
JSFunctionSpec JSI_IGUIObject::JSI_methods[] = | template <typename T> | ||||
JSI_GUIProxy<T>& JSI_GUIProxy<T>::Singleton() | |||||
{ | { | ||||
JS_FN("toString", JSI_IGUIObject::toString, 0, 0), | static JSI_GUIProxy<T> s; | ||||
JS_FN("focus", JSI_IGUIObject::focus, 0, 0), | return s; | ||||
JS_FN("blur", JSI_IGUIObject::blur, 0, 0), | } | ||||
JS_FN("getComputedSize", JSI_IGUIObject::getComputedSize, 0, 0), | |||||
JS_FS_END | |||||
}; | |||||
void JSI_IGUIObject::RegisterScriptClass(ScriptInterface& scriptInterface) | namespace | ||||
{ | { | ||||
scriptInterface.DefineCustomObjectType(&JSI_class, nullptr, 0, nullptr, JSI_methods, nullptr, nullptr); | template<class OG, class R, bool (R::*funcptr)(ScriptInterface&, JS::MutableHandleValue)> | ||||
inline bool apply_to(JSContext* cx, uint argc, JS::Value* vp) | |||||
{ | |||||
JS::CallArgs args = JS::CallArgsFromVp(argc, vp); | |||||
OG* e = static_cast<OG*>(JS_GetPrivate(args.thisv().toObjectOrNull())); | |||||
if (!e) | |||||
return false; | |||||
return (static_cast<R*>(e)->*(funcptr))(*(ScriptInterface::GetScriptInterfaceAndCBData(cx)->pScriptInterface), args.rval()); | |||||
} | |||||
} | } | ||||
bool JSI_IGUIObject::getProperty(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::MutableHandleValue vp) | template <typename T> | ||||
bool JSI_GUIProxy<T>::get(JSContext* cx, JS::HandleObject proxy, JS::HandleValue UNUSED(receiver), JS::HandleId id, JS::MutableHandleValue vp) const | |||||
{ | { | ||||
ScriptInterface* pScriptInterface = ScriptInterface::GetScriptInterfaceAndCBData(cx)->pScriptInterface; | ScriptInterface* pScriptInterface = ScriptInterface::GetScriptInterfaceAndCBData(cx)->pScriptInterface; | ||||
ScriptRequest rq(*pScriptInterface); | ScriptRequest rq(*pScriptInterface); | ||||
IGUIObject* e = ScriptInterface::GetPrivate<IGUIObject>(rq, obj, &JSI_IGUIObject::JSI_class); | T* e = static_cast<T*>(JS_GetPrivate(proxy.get())); | ||||
if (!e) | if (!e) | ||||
return false; | return false; | ||||
JS::RootedValue idval(rq.cx); | JS::RootedValue idval(rq.cx); | ||||
if (!JS_IdToValue(rq.cx, id, &idval)) | if (!JS_IdToValue(rq.cx, id, &idval)) | ||||
return false; | return false; | ||||
std::string propName; | std::string propName; | ||||
if (!ScriptInterface::FromJSVal(rq, idval, propName)) | if (!ScriptInterface::FromJSVal(rq, idval, propName)) | ||||
return false; | return false; | ||||
// Skip registered functions and inherited properties | // Return function properties. Specializable. | ||||
// including JSInterfaces of derived classes | if (funcGetter(e, propName, vp)) | ||||
if (propName == "constructor" || | |||||
propName == "prototype" || | |||||
propName == "toString" || | |||||
propName == "toJSON" || | |||||
propName == "focus" || | |||||
propName == "blur" || | |||||
propName == "getTextSize" || | |||||
propName == "getComputedSize" | |||||
) | |||||
return true; | return true; | ||||
// Use onWhatever to access event handlers | // Use onWhatever to access event handlers | ||||
if (propName.substr(0, 2) == "on") | if (propName.substr(0, 2) == "on") | ||||
{ | { | ||||
CStr eventName(propName.substr(2)); | CStr eventName(propName.substr(2)); | ||||
std::map<CStr, JS::Heap<JSObject*>>::iterator it = e->m_ScriptHandlers.find(eventName); | std::map<CStr, JS::Heap<JSObject*>>::iterator it = e->m_ScriptHandlers.find(eventName); | ||||
if (it == e->m_ScriptHandlers.end()) | if (it == e->m_ScriptHandlers.end()) | ||||
Show All 33 Lines | else if (e->SettingExists(propName)) | ||||
e->m_Settings[propName]->ToJSVal(rq, vp); | e->m_Settings[propName]->ToJSVal(rq, vp); | ||||
return true; | return true; | ||||
} | } | ||||
LOGERROR("Property '%s' does not exist!", propName.c_str()); | LOGERROR("Property '%s' does not exist!", propName.c_str()); | ||||
return false; | return false; | ||||
} | } | ||||
bool JSI_IGUIObject::setProperty(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::MutableHandleValue vp, JS::ObjectOpResult& result) | |||||
{ | |||||
ScriptRequest rq(*ScriptInterface::GetScriptInterfaceAndCBData(cx)->pScriptInterface); | |||||
IGUIObject* e = ScriptInterface::GetPrivate<IGUIObject>(rq, obj, &JSI_IGUIObject::JSI_class); | template <typename T> | ||||
bool JSI_GUIProxy<T>::set(JSContext* cx, JS::HandleObject proxy, JS::HandleId id, JS::HandleValue vp, | |||||
JS::HandleValue UNUSED(receiver), JS::ObjectOpResult& result) const | |||||
{ | |||||
T* e = static_cast<T*>(JS_GetPrivate(proxy.get())); | |||||
if (!e) | if (!e) | ||||
return result.fail(JSMSG_NOT_NONNULL_OBJECT); | return result.fail(JSMSG_NOT_NONNULL_OBJECT); | ||||
ScriptRequest rq(*ScriptInterface::GetScriptInterfaceAndCBData(cx)->pScriptInterface); | |||||
JS::RootedValue idval(rq.cx); | JS::RootedValue idval(rq.cx); | ||||
if (!JS_IdToValue(rq.cx, id, &idval)) | if (!JS_IdToValue(rq.cx, id, &idval)) | ||||
return result.fail(JSMSG_NOT_NONNULL_OBJECT); | return result.fail(JSMSG_NOT_NONNULL_OBJECT); | ||||
std::string propName; | std::string propName; | ||||
if (!ScriptInterface::FromJSVal(rq, idval, propName)) | if (!ScriptInterface::FromJSVal(rq, idval, propName)) | ||||
return result.fail(JSMSG_UNDEFINED_PROP); | return result.fail(JSMSG_UNDEFINED_PROP); | ||||
if (propName == "name") | if (propName == "name") | ||||
{ | { | ||||
std::string value; | std::string value; | ||||
if (!ScriptInterface::FromJSVal(rq, vp, value)) | if (!ScriptInterface::FromJSVal(rq, vp, value)) | ||||
return result.fail(JSMSG_UNDEFINED_PROP); | return result.fail(JSMSG_UNDEFINED_PROP); | ||||
e->SetName(value); | e->SetName(value); | ||||
return result.succeed(); | return result.succeed(); | ||||
} | } | ||||
JS::RootedObject vpObj(rq.cx); | JS::RootedObject vpObj(cx); | ||||
if (vp.isObject()) | if (vp.isObject()) | ||||
vpObj = &vp.toObject(); | vpObj = &vp.toObject(); | ||||
// Use onWhatever to set event handlers | // Use onWhatever to set event handlers | ||||
if (propName.substr(0, 2) == "on") | if (propName.substr(0, 2) == "on") | ||||
{ | { | ||||
if (vp.isPrimitive() || vp.isNull() || !JS_ObjectIsFunction(rq.cx, &vp.toObject())) | if (vp.isPrimitive() || vp.isNull() || !JS_ObjectIsFunction(rq.cx, &vp.toObject())) | ||||
{ | { | ||||
Show All 9 Lines | bool JSI_GUIProxy<T>::set(JSContext* cx, JS::HandleObject proxy, JS::HandleId id, JS::HandleValue vp, | ||||
if (e->SettingExists(propName)) | if (e->SettingExists(propName)) | ||||
return e->m_Settings[propName]->FromJSVal(rq, vp, true) ? result.succeed() : result.fail(JSMSG_USER_DEFINED_ERROR); | return e->m_Settings[propName]->FromJSVal(rq, vp, true) ? result.succeed() : result.fail(JSMSG_USER_DEFINED_ERROR); | ||||
LOGERROR("Property '%s' does not exist!", propName.c_str()); | LOGERROR("Property '%s' does not exist!", propName.c_str()); | ||||
return result.fail(JSMSG_UNDEFINED_PROP); | return result.fail(JSMSG_UNDEFINED_PROP); | ||||
} | } | ||||
bool JSI_IGUIObject::deleteProperty(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::ObjectOpResult& result) | template<typename T> | ||||
bool JSI_GUIProxy<T>::delete_(JSContext* cx, JS::HandleObject proxy, JS::HandleId id, JS::ObjectOpResult& result) const | |||||
{ | { | ||||
ScriptRequest rq(*ScriptInterface::GetScriptInterfaceAndCBData(cx)->pScriptInterface); | T* e = static_cast<T*>(JS_GetPrivate(proxy.get())); | ||||
IGUIObject* e = ScriptInterface::GetPrivate<IGUIObject>(rq, obj, &JSI_IGUIObject::JSI_class); | |||||
if (!e) | if (!e) | ||||
return result.fail(JSMSG_NOT_NONNULL_OBJECT); | return result.fail(JSMSG_NOT_NONNULL_OBJECT); | ||||
ScriptRequest rq(*ScriptInterface::GetScriptInterfaceAndCBData(cx)->pScriptInterface); | |||||
JS::RootedValue idval(rq.cx); | JS::RootedValue idval(rq.cx); | ||||
if (!JS_IdToValue(rq.cx, id, &idval)) | if (!JS_IdToValue(rq.cx, id, &idval)) | ||||
return result.fail(JSMSG_NOT_NONNULL_OBJECT); | return result.fail(JSMSG_NOT_NONNULL_OBJECT); | ||||
std::string propName; | std::string propName; | ||||
if (!ScriptInterface::FromJSVal(rq, idval, propName)) | if (!ScriptInterface::FromJSVal(rq, idval, propName)) | ||||
return result.fail(JSMSG_UNDEFINED_PROP); | return result.fail(JSMSG_UNDEFINED_PROP); | ||||
// event handlers | // event handlers | ||||
if (propName.substr(0, 2) == "on") | if (propName.substr(0, 2) == "on") | ||||
{ | { | ||||
CStr eventName(propName.substr(2)); | CStr eventName(propName.substr(2)); | ||||
e->UnsetScriptHandler(eventName); | e->UnsetScriptHandler(eventName); | ||||
return result.succeed(); | return result.succeed(); | ||||
} | } | ||||
LOGERROR("Only event handlers can be deleted from GUI objects!"); | LOGERROR("Only event handlers can be deleted from GUI objects!"); | ||||
return result.fail(JSMSG_UNDEFINED_PROP); | return result.fail(JSMSG_UNDEFINED_PROP); | ||||
} | } | ||||
bool JSI_IGUIObject::toString(JSContext* cx, uint argc, JS::Value* vp) | |||||
{ | |||||
ScriptRequest rq(*ScriptInterface::GetScriptInterfaceAndCBData(cx)->pScriptInterface); | |||||
JS::CallArgs args = JS::CallArgsFromVp(argc, vp); | |||||
IGUIObject* e = ScriptInterface::GetPrivate<IGUIObject>(rq, args, &JSI_IGUIObject::JSI_class); | |||||
if (!e) | |||||
return false; | |||||
ScriptInterface::ToJSVal(rq, args.rval(), "[GUIObject: " + e->GetName() + "]"); | |||||
return true; | |||||
} | |||||
bool JSI_IGUIObject::focus(JSContext* cx, uint argc, JS::Value* vp) | |||||
{ | |||||
ScriptRequest rq(*ScriptInterface::GetScriptInterfaceAndCBData(cx)->pScriptInterface); | |||||
JS::CallArgs args = JS::CallArgsFromVp(argc, vp); | |||||
IGUIObject* e = ScriptInterface::GetPrivate<IGUIObject>(rq, args, &JSI_IGUIObject::JSI_class); | |||||
if (!e) | |||||
return false; | |||||
e->GetGUI().SetFocusedObject(e); | |||||
args.rval().setUndefined(); | |||||
return true; | |||||
} | |||||
bool JSI_IGUIObject::blur(JSContext* cx, uint argc, JS::Value* vp) | |||||
{ | |||||
ScriptRequest rq(*ScriptInterface::GetScriptInterfaceAndCBData(cx)->pScriptInterface); | |||||
JS::CallArgs args = JS::CallArgsFromVp(argc, vp); | |||||
IGUIObject* e = ScriptInterface::GetPrivate<IGUIObject>(rq, args, &JSI_IGUIObject::JSI_class); | |||||
if (!e) | |||||
return false; | |||||
e->GetGUI().SetFocusedObject(nullptr); | |||||
args.rval().setUndefined(); | |||||
return true; | |||||
} | |||||
bool JSI_IGUIObject::getComputedSize(JSContext* cx, uint argc, JS::Value* vp) | |||||
{ | |||||
ScriptRequest rq(*ScriptInterface::GetScriptInterfaceAndCBData(cx)->pScriptInterface); | |||||
JS::CallArgs args = JS::CallArgsFromVp(argc, vp); | |||||
IGUIObject* e = ScriptInterface::GetPrivate<IGUIObject>(rq, args, &JSI_IGUIObject::JSI_class); | |||||
if (!e) | |||||
return false; | |||||
e->UpdateCachedSize(); | |||||
ScriptInterface::ToJSVal(rq, args.rval(), e->m_CachedActualSize); | |||||
return true; | |||||
} |
Wildfire Games · Phabricator