Simplify GUI/simulation interface
This was SVN commit r7286.
This commit is contained in:
parent
953fb41c82
commit
3f1dfce41b
@ -3,16 +3,21 @@ var g_Selection = {}; // { id: 1, id: 1, ... } for each selected entity ID 'id'
|
||||
var g_ActiveSelectionColour = { r:1, g:1, b:1, a:1 };
|
||||
var g_InactiveSelectionColour = { r:0, g:0, b:0, a:0 };
|
||||
|
||||
function setHighlight(ent, colour)
|
||||
{
|
||||
Engine.GuiInterfaceCall("SetSelectionHighlight", { "entity":ent, "colour":colour });
|
||||
}
|
||||
|
||||
function toggleEntitySelection(ent)
|
||||
{
|
||||
if (g_Selection[ent])
|
||||
{
|
||||
Engine.SetEntitySelectionHighlight(ent, g_InactiveSelectionColour);
|
||||
setHighlight(ent, g_InactiveSelectionColour);
|
||||
delete g_Selection[ent];
|
||||
}
|
||||
else
|
||||
{
|
||||
Engine.SetEntitySelectionHighlight(ent, g_ActiveSelectionColour);
|
||||
setHighlight(ent, g_ActiveSelectionColour);
|
||||
g_Selection[ent] = 1;
|
||||
}
|
||||
}
|
||||
@ -23,7 +28,7 @@ function addEntitySelection(ents)
|
||||
{
|
||||
if (!g_Selection[ent])
|
||||
{
|
||||
Engine.SetEntitySelectionHighlight(ent, g_ActiveSelectionColour);
|
||||
setHighlight(ent, g_ActiveSelectionColour);
|
||||
g_Selection[ent] = 1;
|
||||
}
|
||||
}
|
||||
@ -32,7 +37,7 @@ function addEntitySelection(ents)
|
||||
function resetEntitySelection()
|
||||
{
|
||||
for (var ent in g_Selection)
|
||||
Engine.SetEntitySelectionHighlight(ent, g_InactiveSelectionColour);
|
||||
setHighlight(ent, g_InactiveSelectionColour);
|
||||
|
||||
g_Selection = {};
|
||||
}
|
||||
|
@ -13,12 +13,12 @@ function onSimulationUpdate()
|
||||
function updateDebug()
|
||||
{
|
||||
var debug = getGUIObjectByName("debug");
|
||||
var simState = Engine.GetSimulationState();
|
||||
var simState = Engine.GuiInterfaceCall("GetSimulationState");
|
||||
var text = "Simulation:\n" + uneval(simState);
|
||||
text += "\n\n";
|
||||
for (var ent in g_Selection)
|
||||
{
|
||||
text += "Entity "+ent+":\n" + uneval(Engine.GetEntityState(ent)) + "\n";
|
||||
text += "Entity "+ent+":\n" + uneval(Engine.GuiInterfaceCall("GetEntityState", ent)) + "\n";
|
||||
}
|
||||
debug.caption = text;
|
||||
}
|
||||
@ -28,7 +28,7 @@ function updateBuildButton()
|
||||
var selection = getEntitySelection();
|
||||
if (selection.length)
|
||||
{
|
||||
var entity = Engine.GetEntityState(selection[0]);
|
||||
var entity = Engine.GuiInterfaceCall("GetEntityState", selection[0]);
|
||||
if (entity.buildEntities && entity.buildEntities.length)
|
||||
{
|
||||
var ent = entity.buildEntities[0];
|
||||
|
@ -45,13 +45,13 @@ GuiInterface.prototype.GetEntityState = function(player, ent)
|
||||
return ret;
|
||||
};
|
||||
|
||||
GuiInterface.prototype.SetSelectionHighlight = function(ent, colour)
|
||||
GuiInterface.prototype.SetSelectionHighlight = function(player, cmd)
|
||||
{
|
||||
var cmpSelectable = Engine.QueryInterface(ent, IID_Selectable);
|
||||
cmpSelectable.SetSelectionHighlight(colour);
|
||||
var cmpSelectable = Engine.QueryInterface(cmd.entity, IID_Selectable);
|
||||
cmpSelectable.SetSelectionHighlight(cmd.colour);
|
||||
};
|
||||
|
||||
GuiInterface.prototype.SetBuildingPlacementPreview = function(cmd)
|
||||
GuiInterface.prototype.SetBuildingPlacementPreview = function(player, cmd)
|
||||
{
|
||||
if (!this.placementEntity || this.placementEntity[0] != cmd.template)
|
||||
{
|
||||
@ -78,10 +78,22 @@ GuiInterface.prototype.SetBuildingPlacementPreview = function(cmd)
|
||||
}
|
||||
};
|
||||
|
||||
GuiInterface.prototype.ScriptCall = function(name, args)
|
||||
// List the GuiInterface functions that can be safely called by GUI scripts.
|
||||
// (GUI scripts are non-deterministic and untrusted, so these functions must be
|
||||
// appropriately careful. They are called with a first argument "player", which is
|
||||
// trusted and indicates the player associated with the current client; no data should
|
||||
// be returned unless this player is meant to be able to see it.)
|
||||
var exposedFunctions = {
|
||||
"GetSimulationState": 1,
|
||||
"GetEntityState": 1,
|
||||
"SetSelectionHighlight": 1,
|
||||
"SetBuildingPlacementPreview": 1
|
||||
};
|
||||
|
||||
GuiInterface.prototype.ScriptCall = function(player, name, args)
|
||||
{
|
||||
if (name == "SetBuildingPlacementPreview")
|
||||
this.SetBuildingPlacementPreview(args);
|
||||
if (exposedFunctions[name])
|
||||
return this[name](player, args);
|
||||
else
|
||||
throw new Error("Invalid GuiInterface Call name \""+name+"\"");
|
||||
};
|
||||
|
@ -108,44 +108,6 @@ static jsval CloneValueBetweenContexts(JSContext* cxFrom, JSContext* cxTo, jsval
|
||||
return JSVAL_VOID;
|
||||
}
|
||||
|
||||
CScriptVal GetSimulationState(void* cbdata)
|
||||
{
|
||||
CGUIManager* guiManager = static_cast<CGUIManager*> (cbdata);
|
||||
|
||||
if (!g_UseSimulation2 || !g_Game)
|
||||
return JSVAL_VOID;
|
||||
CSimulation2* sim = g_Game->GetSimulation2();
|
||||
debug_assert(sim);
|
||||
CmpPtr<ICmpGuiInterface> gui(*sim, SYSTEM_ENTITY);
|
||||
if (gui.null())
|
||||
return JSVAL_VOID;
|
||||
|
||||
int player = -1;
|
||||
if (g_Game && g_Game->GetLocalPlayer())
|
||||
player = g_Game->GetLocalPlayer()->GetPlayerID();
|
||||
|
||||
return CloneValueBetweenContexts(sim->GetScriptInterface().GetContext(), guiManager->GetScriptInterface().GetContext(), gui->GetSimulationState(player).get());
|
||||
}
|
||||
|
||||
CScriptVal GetEntityState(void* cbdata, entity_id_t ent)
|
||||
{
|
||||
CGUIManager* guiManager = static_cast<CGUIManager*> (cbdata);
|
||||
|
||||
if (!g_UseSimulation2 || !g_Game)
|
||||
return JSVAL_VOID;
|
||||
CSimulation2* sim = g_Game->GetSimulation2();
|
||||
debug_assert(sim);
|
||||
CmpPtr<ICmpGuiInterface> gui(*sim, SYSTEM_ENTITY);
|
||||
if (gui.null())
|
||||
return JSVAL_VOID;
|
||||
|
||||
int player = -1;
|
||||
if (g_Game && g_Game->GetLocalPlayer())
|
||||
player = g_Game->GetLocalPlayer()->GetPlayerID();
|
||||
|
||||
return CloneValueBetweenContexts(sim->GetScriptInterface().GetContext(), guiManager->GetScriptInterface().GetContext(), gui->GetEntityState(player, ent).get());
|
||||
}
|
||||
|
||||
CScriptVal GuiInterfaceCall(void* cbdata, std::string name, CScriptVal data)
|
||||
{
|
||||
CGUIManager* guiManager = static_cast<CGUIManager*> (cbdata);
|
||||
@ -158,27 +120,16 @@ CScriptVal GuiInterfaceCall(void* cbdata, std::string name, CScriptVal data)
|
||||
if (gui.null())
|
||||
return JSVAL_VOID;
|
||||
|
||||
int player = -1;
|
||||
if (g_Game && g_Game->GetLocalPlayer())
|
||||
player = g_Game->GetLocalPlayer()->GetPlayerID();
|
||||
|
||||
JSContext* cxGui = guiManager->GetScriptInterface().GetContext();
|
||||
JSContext* cxSim = sim->GetScriptInterface().GetContext();
|
||||
CScriptVal ret = gui->ScriptCall(name, CloneValueBetweenContexts(cxGui, cxSim, data.get()));
|
||||
CScriptVal ret = gui->ScriptCall(player, name, CloneValueBetweenContexts(cxGui, cxSim, data.get()));
|
||||
return CloneValueBetweenContexts(cxSim, cxGui, ret.get());
|
||||
}
|
||||
|
||||
void SetEntitySelectionHighlight(void* UNUSED(cbdata), entity_id_t ent, CColor color)
|
||||
{
|
||||
if (!g_UseSimulation2 || !g_Game)
|
||||
return;
|
||||
CSimulation2* sim = g_Game->GetSimulation2();
|
||||
debug_assert(sim);
|
||||
CmpPtr<ICmpGuiInterface> gui(*sim, SYSTEM_ENTITY);
|
||||
if (gui.null())
|
||||
return;
|
||||
|
||||
// TODO: stop duplicating all this prolog code
|
||||
|
||||
gui->SetSelectionHighlight(ent, color);
|
||||
}
|
||||
|
||||
void PostNetworkCommand(void* cbdata, CScriptVal cmd)
|
||||
{
|
||||
CGUIManager* guiManager = static_cast<CGUIManager*> (cbdata);
|
||||
@ -226,9 +177,6 @@ void GuiScriptingInit(ScriptInterface& scriptInterface)
|
||||
|
||||
// Simulation<->GUI interface functions:
|
||||
scriptInterface.RegisterFunction<bool, &IsNewSimulation>("IsNewSimulation");
|
||||
scriptInterface.RegisterFunction<CScriptVal, &GetSimulationState>("GetSimulationState");
|
||||
scriptInterface.RegisterFunction<CScriptVal, entity_id_t, &GetEntityState>("GetEntityState");
|
||||
scriptInterface.RegisterFunction<void, entity_id_t, CColor, &SetEntitySelectionHighlight>("SetEntitySelectionHighlight");
|
||||
scriptInterface.RegisterFunction<CScriptVal, std::string, CScriptVal, &GuiInterfaceCall>("GuiInterfaceCall");
|
||||
|
||||
scriptInterface.RegisterFunction<void, CScriptVal, &PostNetworkCommand>("PostNetworkCommand");
|
||||
|
@ -104,6 +104,12 @@ public:
|
||||
template<typename T0, typename T1, typename R>
|
||||
bool CallFunction(jsval val, const char* name, const T0& a0, const T1& a1, R& ret);
|
||||
|
||||
/**
|
||||
* Call the named property on the given object, with return type R and 3 arguments
|
||||
*/
|
||||
template<typename T0, typename T1, typename T2, typename R>
|
||||
bool CallFunction(jsval val, const char* name, const T0& a0, const T1& a1, const T2& a2, R& ret);
|
||||
|
||||
jsval GetGlobalObject();
|
||||
|
||||
/**
|
||||
@ -273,6 +279,21 @@ bool ScriptInterface::CallFunction(jsval val, const char* name, const T0& a0, co
|
||||
return FromJSVal(GetContext(), jsRet, ret);
|
||||
}
|
||||
|
||||
template<typename T0, typename T1, typename T2, typename R>
|
||||
bool ScriptInterface::CallFunction(jsval val, const char* name, const T0& a0, const T1& a1, const T2& a2, R& ret)
|
||||
{
|
||||
LOCAL_ROOT_SCOPE;
|
||||
jsval jsRet;
|
||||
std::vector<jsval> argv;
|
||||
argv.push_back(ToJSVal(GetContext(), a0));
|
||||
argv.push_back(ToJSVal(GetContext(), a1));
|
||||
argv.push_back(ToJSVal(GetContext(), a2));
|
||||
bool ok = CallFunction_(val, name, argv, jsRet);
|
||||
if (!ok)
|
||||
return false;
|
||||
return FromJSVal(GetContext(), jsRet, ret);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool ScriptInterface::SetGlobal(const char* name, const T& value, bool replace)
|
||||
{
|
||||
|
@ -30,25 +30,9 @@ class CCmpGuiInterfaceScripted : public ICmpGuiInterface
|
||||
public:
|
||||
DEFAULT_SCRIPT_WRAPPER(GuiInterfaceScripted)
|
||||
|
||||
virtual CScriptVal GetSimulationState(int player)
|
||||
virtual CScriptVal ScriptCall(int player, std::string cmd, CScriptVal data)
|
||||
{
|
||||
return m_Script.Call<CScriptVal> ("GetSimulationState", player);
|
||||
}
|
||||
|
||||
virtual CScriptVal GetEntityState(int player, entity_id_t ent)
|
||||
{
|
||||
return m_Script.Call<CScriptVal> ("GetEntityState", player, ent);
|
||||
}
|
||||
|
||||
virtual void SetSelectionHighlight(entity_id_t ent, const CColor& color)
|
||||
{
|
||||
m_Script.Call<CScriptVal> ("SetSelectionHighlight", ent, color);
|
||||
// ignore return value
|
||||
}
|
||||
|
||||
virtual CScriptVal ScriptCall(std::string name, CScriptVal data)
|
||||
{
|
||||
return m_Script.Call<CScriptVal> ("ScriptCall", name, data);
|
||||
return m_Script.Call<CScriptVal> ("ScriptCall", player, cmd, data);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -25,14 +25,10 @@ struct CColor;
|
||||
class ICmpGuiInterface : public IComponent
|
||||
{
|
||||
public:
|
||||
virtual CScriptVal GetSimulationState(int player) = 0;
|
||||
virtual CScriptVal GetEntityState(int player, entity_id_t ent) = 0;
|
||||
virtual void SetSelectionHighlight(entity_id_t ent, const CColor& color) = 0;
|
||||
|
||||
/**
|
||||
* Generic call function, for use by GUI scripts to talk to the GuiInterface script.
|
||||
*/
|
||||
virtual CScriptVal ScriptCall(std::string name, CScriptVal data) = 0;
|
||||
virtual CScriptVal ScriptCall(int player, std::string cmd, CScriptVal data) = 0;
|
||||
// TODO: some of the earlier functions should just use ScriptCall.
|
||||
|
||||
DECLARE_INTERFACE_TYPE(GuiInterface)
|
||||
|
Loading…
Reference in New Issue
Block a user