forked from 0ad/0ad
Fix 768c84aa46
style, add tests.
Patch by: @bb Small fixes by: @Stan Reviewed by: @vladislavbelov Differential Revision: https://code.wildfiregames.com/D3103 This was SVN commit r24665.
This commit is contained in:
parent
4c4da81cc4
commit
3872ee43b5
4
binaries/data/mods/_test.gui/gui/common/styles.xml
Normal file
4
binaries/data/mods/_test.gui/gui/common/styles.xml
Normal file
@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<styles>
|
||||
<style name="default"/>
|
||||
</styles>
|
15
binaries/data/mods/_test.gui/gui/event/event.js
Executable file
15
binaries/data/mods/_test.gui/gui/event/event.js
Executable file
@ -0,0 +1,15 @@
|
||||
var called1 = 0;
|
||||
var called2 = 0;
|
||||
var called3 = 0;
|
||||
var called4 = 0;
|
||||
var obj1 = Engine.GetGUIObjectByName("obj1");
|
||||
var obj3 = Engine.GetGUIObjectByName("obj3");
|
||||
|
||||
obj1.onTick = () => { ++called1; };
|
||||
Engine.GetGUIObjectByName("obj2").onTick = () => {
|
||||
++called2;
|
||||
delete obj1.onTick;
|
||||
delete obj3.onTick;
|
||||
Engine.GetGUIObjectByName("obj4").onTick = () => { ++called4; };
|
||||
};
|
||||
obj3.onTick = () => { ++called3; };
|
9
binaries/data/mods/_test.gui/gui/event/event.xml
Executable file
9
binaries/data/mods/_test.gui/gui/event/event.xml
Executable file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<objects>
|
||||
<object name="obj1"/>
|
||||
<object name="obj2"/>
|
||||
<object name="obj3"/>
|
||||
<object name="obj4"/>
|
||||
|
||||
<script file="gui/event/event.js"/>
|
||||
</objects>
|
5
binaries/data/mods/_test.gui/gui/event/page_event.xml
Normal file
5
binaries/data/mods/_test.gui/gui/event/page_event.xml
Normal file
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<page>
|
||||
<include>common/styles.xml</include>
|
||||
<include>event/event.xml</include>
|
||||
</page>
|
@ -9,6 +9,7 @@
|
||||
<a:documentation/>
|
||||
<choice>
|
||||
<ref name="objects"/>
|
||||
<ref name="styles"/>
|
||||
</choice>
|
||||
</start>
|
||||
<define name="objects">
|
||||
@ -16,6 +17,7 @@
|
||||
<zeroOrMore>
|
||||
<choice>
|
||||
<ref name="script"/>
|
||||
<ref name="object"/>
|
||||
</choice>
|
||||
</zeroOrMore>
|
||||
</element>
|
||||
@ -33,4 +35,23 @@
|
||||
</interleave>
|
||||
</element>
|
||||
</define>
|
||||
<define name="object">
|
||||
<element name="object">
|
||||
<optional>
|
||||
<attribute name="name"/>
|
||||
</optional>
|
||||
</element>
|
||||
</define>
|
||||
<define name="styles">
|
||||
<element name="styles">
|
||||
<zeroOrMore>
|
||||
<ref name="style"/>
|
||||
</zeroOrMore>
|
||||
</element>
|
||||
</define>
|
||||
<define name="style">
|
||||
<element name="style">
|
||||
<attribute name="name"/>
|
||||
</element>
|
||||
</define>
|
||||
</grammar>
|
||||
|
@ -43,6 +43,7 @@
|
||||
#include "scriptinterface/ScriptInterface.h"
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
|
||||
extern int g_yres;
|
||||
@ -275,24 +276,24 @@ void CGUI::TickObjects()
|
||||
|
||||
void CGUI::SendEventToAll(const CStr& eventName)
|
||||
{
|
||||
auto it = m_EventIGUIObjects.find(eventName);
|
||||
if (it == m_EventIGUIObjects.end())
|
||||
std::unordered_map<CStr, std::vector<IGUIObject*>>::iterator it = m_EventObjects.find(eventName);
|
||||
if (it == m_EventObjects.end())
|
||||
return;
|
||||
|
||||
std::set<IGUIObject*> copy = it->second;
|
||||
for (IGUIObject* pIGUIObject : copy)
|
||||
pIGUIObject->ScriptEvent(eventName);
|
||||
std::vector<IGUIObject*> copy = it->second;
|
||||
for (IGUIObject* object : copy)
|
||||
object->ScriptEvent(eventName);
|
||||
}
|
||||
|
||||
void CGUI::SendEventToAll(const CStr& eventName, const JS::HandleValueArray& paramData)
|
||||
{
|
||||
auto it = m_EventIGUIObjects.find(eventName);
|
||||
if (it == m_EventIGUIObjects.end())
|
||||
std::unordered_map<CStr, std::vector<IGUIObject*>>::iterator it = m_EventObjects.find(eventName);
|
||||
if (it == m_EventObjects.end())
|
||||
return;
|
||||
|
||||
std::set<IGUIObject*> copy = it->second;
|
||||
for (IGUIObject* pIGUIObject : copy)
|
||||
pIGUIObject->ScriptEvent(eventName, paramData);
|
||||
std::vector<IGUIObject*> copy = it->second;
|
||||
for (IGUIObject* object : copy)
|
||||
object->ScriptEvent(eventName, paramData);
|
||||
}
|
||||
|
||||
void CGUI::Draw()
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2020 Wildfire Games.
|
||||
/* Copyright (C) 2021 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -679,9 +679,9 @@ private:
|
||||
|
||||
public:
|
||||
/**
|
||||
* Stores all the IGUIObject which listen to a given event.
|
||||
* Map from event names to object which listen to a given event.
|
||||
*/
|
||||
std::map<CStr, std::set<IGUIObject*>> m_EventIGUIObjects;
|
||||
std::unordered_map<CStr, std::vector<IGUIObject*>> m_EventObjects;
|
||||
};
|
||||
|
||||
#endif // INCLUDED_CGUI
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2020 Wildfire Games.
|
||||
/* Copyright (C) 2021 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -31,6 +31,8 @@
|
||||
#include "scriptinterface/ScriptInterface.h"
|
||||
#include "soundmanager/ISoundManager.h"
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
const CStr IGUIObject::EventNameMouseEnter = "MouseEnter";
|
||||
const CStr IGUIObject::EventNameMouseMove = "MouseMove";
|
||||
const CStr IGUIObject::EventNameMouseLeave = "MouseLeave";
|
||||
@ -347,11 +349,7 @@ void IGUIObject::SetScriptHandler(const CStr& eventName, JS::HandleObject Functi
|
||||
|
||||
m_ScriptHandlers[eventName] = JS::Heap<JSObject*>(Function);
|
||||
|
||||
auto it = m_pGUI.m_EventIGUIObjects.find(eventName);
|
||||
if (it == m_pGUI.m_EventIGUIObjects.end())
|
||||
m_pGUI.m_EventIGUIObjects.emplace(eventName, std::set<IGUIObject*>{this});
|
||||
else
|
||||
it->second.insert(this);
|
||||
m_pGUI.m_EventObjects[eventName].push_back(this);
|
||||
}
|
||||
|
||||
void IGUIObject::UnsetScriptHandler(const CStr& eventName)
|
||||
@ -365,15 +363,16 @@ void IGUIObject::UnsetScriptHandler(const CStr& eventName)
|
||||
|
||||
if (m_ScriptHandlers.empty())
|
||||
JS_RemoveExtraGCRootsTracer(m_pGUI.GetScriptInterface()->GetGeneralJSContext(), Trace, this);
|
||||
{
|
||||
auto it = m_pGUI.m_EventIGUIObjects.find(eventName);
|
||||
if (it != m_pGUI.m_EventIGUIObjects.end())
|
||||
{
|
||||
it->second.erase(this);
|
||||
if (!it->second.size())
|
||||
m_pGUI.m_EventIGUIObjects.erase(eventName);
|
||||
}
|
||||
}
|
||||
|
||||
std::unordered_map<CStr, std::vector<IGUIObject*>>::iterator it2 = m_pGUI.m_EventObjects.find(eventName);
|
||||
if (it2 == m_pGUI.m_EventObjects.end())
|
||||
return;
|
||||
|
||||
std::vector<IGUIObject*>& handlers = it2->second;
|
||||
handlers.erase(std::remove(handlers.begin(), handlers.end(), this), handlers.end());
|
||||
|
||||
if (handlers.empty())
|
||||
m_pGUI.m_EventObjects.erase(it2);
|
||||
}
|
||||
|
||||
InReaction IGUIObject::SendEvent(EGUIMessageType type, const CStr& eventName)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2020 Wildfire Games.
|
||||
/* Copyright (C) 2021 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -53,6 +53,65 @@ public:
|
||||
DeleteDirectory(DataDir()/"_testcache");
|
||||
}
|
||||
|
||||
void test_EventObject()
|
||||
{
|
||||
// Load up a test page.
|
||||
const ScriptInterface& scriptInterface = *(g_GUI->GetScriptInterface());
|
||||
ScriptRequest rq(scriptInterface);
|
||||
JS::RootedValue val(rq.cx);
|
||||
scriptInterface.CreateObject(rq, &val);
|
||||
|
||||
ScriptInterface::StructuredClone data = scriptInterface.WriteStructuredClone(JS::NullHandleValue);
|
||||
g_GUI->PushPage(L"event/page_event.xml", data, JS::UndefinedHandleValue);
|
||||
|
||||
const ScriptInterface& pageScriptInterface = *(g_GUI->GetActiveGUI()->GetScriptInterface());
|
||||
ScriptRequest prq(pageScriptInterface);
|
||||
JS::RootedValue global(prq.cx, prq.globalValue());
|
||||
|
||||
int called_value = 0;
|
||||
JS::RootedValue js_called_value(prq.cx);
|
||||
|
||||
// Ticking will call the onTick handlers of all object. The second
|
||||
// onTick is configured to disable the onTick handlers of the first and
|
||||
// third and enable the fourth. So ticking once will only call the
|
||||
// first and second object. We don't want the fourth object to be
|
||||
// called, to avoid infinite additions of objects.
|
||||
g_GUI->TickObjects();
|
||||
pageScriptInterface.GetProperty(global, "called1", &js_called_value);
|
||||
ScriptInterface::FromJSVal(prq, js_called_value, called_value);
|
||||
TS_ASSERT_EQUALS(called_value, 1);
|
||||
|
||||
pageScriptInterface.GetProperty(global, "called2", &js_called_value);
|
||||
ScriptInterface::FromJSVal(prq, js_called_value, called_value);
|
||||
TS_ASSERT_EQUALS(called_value, 1);
|
||||
|
||||
pageScriptInterface.GetProperty(global, "called3", &js_called_value);
|
||||
ScriptInterface::FromJSVal(prq, js_called_value, called_value);
|
||||
TS_ASSERT_EQUALS(called_value, 0);
|
||||
|
||||
pageScriptInterface.GetProperty(global, "called4", &js_called_value);
|
||||
ScriptInterface::FromJSVal(prq, js_called_value, called_value);
|
||||
TS_ASSERT_EQUALS(called_value, 0);
|
||||
|
||||
// Ticking again will still call the second object, but also the fourth.
|
||||
g_GUI->TickObjects();
|
||||
pageScriptInterface.GetProperty(global, "called1", &js_called_value);
|
||||
ScriptInterface::FromJSVal(prq, js_called_value, called_value);
|
||||
TS_ASSERT_EQUALS(called_value, 1);
|
||||
|
||||
pageScriptInterface.GetProperty(global, "called2", &js_called_value);
|
||||
ScriptInterface::FromJSVal(prq, js_called_value, called_value);
|
||||
TS_ASSERT_EQUALS(called_value, 2);
|
||||
|
||||
pageScriptInterface.GetProperty(global, "called3", &js_called_value);
|
||||
ScriptInterface::FromJSVal(prq, js_called_value, called_value);
|
||||
TS_ASSERT_EQUALS(called_value, 0);
|
||||
|
||||
pageScriptInterface.GetProperty(global, "called4", &js_called_value);
|
||||
ScriptInterface::FromJSVal(prq, js_called_value, called_value);
|
||||
TS_ASSERT_EQUALS(called_value, 1);
|
||||
}
|
||||
|
||||
void test_hotkeysState()
|
||||
{
|
||||
// Load up a fake test hotkey when pressing 'a'.
|
||||
|
Loading…
Reference in New Issue
Block a user