mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-01-07 04:00:37 -06:00
distinguish between local and remote scripting
This commit is contained in:
@@ -67,6 +67,7 @@ public:
|
||||
void addKeyframe(const network::datamessagestructures::CameraKeyframe &kf);
|
||||
void clearKeyframes();
|
||||
|
||||
void bindKeyLocal(Key key, KeyModifier modifier, std::string lua);
|
||||
void bindKey(Key key, KeyModifier modifier, std::string lua);
|
||||
void lockControls();
|
||||
void unlockControls();
|
||||
@@ -109,7 +110,7 @@ private:
|
||||
|
||||
bool _cameraUpdatedFromScript = false;
|
||||
|
||||
std::multimap<KeyWithModifier, std::string > _keyLua;
|
||||
std::multimap<KeyWithModifier, std::pair<std::string, bool>> _keyLua;
|
||||
|
||||
std::unique_ptr<InputState> _inputState;
|
||||
Camera* _camera;
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#define LUACONSOLE_H
|
||||
|
||||
#include <openspace/scripting/scriptengine.h>
|
||||
#include <openspace/network/parallelconnection.h>
|
||||
|
||||
#include <openspace/util/keys.h>
|
||||
|
||||
@@ -50,12 +51,16 @@ public:
|
||||
|
||||
bool isVisible() const;
|
||||
void setVisible(bool visible);
|
||||
void toggleVisibility();
|
||||
bool isRemoteScripting() const;
|
||||
void setRemoteScripting(bool remoteScripting);
|
||||
|
||||
void toggleMode();
|
||||
|
||||
static scripting::LuaLibrary luaLibrary();
|
||||
|
||||
|
||||
private:
|
||||
void parallelConnectionChanged(const network::Status& status);
|
||||
void addToCommand(std::string c);
|
||||
std::string UnicodeToUTF8(unsigned int codepoint);
|
||||
|
||||
@@ -73,6 +78,7 @@ private:
|
||||
} _autoCompleteInfo;
|
||||
|
||||
bool _isVisible;
|
||||
bool _remoteScripting;
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -33,6 +33,9 @@
|
||||
//glm includes
|
||||
#include <glm/gtx/quaternion.hpp>
|
||||
|
||||
//ghoul includes
|
||||
#include <ghoul/designpattern/event.h>
|
||||
|
||||
//std includes
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@@ -59,16 +62,24 @@ typedef int _SOCKET;
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
|
||||
namespace openspace{
|
||||
namespace openspace {
|
||||
|
||||
namespace network{
|
||||
namespace network {
|
||||
|
||||
enum class Status : uint32_t {
|
||||
Disconnected = 0,
|
||||
ClientWithoutHost,
|
||||
ClientWithHost,
|
||||
Host
|
||||
};
|
||||
|
||||
enum class MessageType : uint32_t {
|
||||
Authentication = 0,
|
||||
Data,
|
||||
HostInformation,
|
||||
ConnectionStatus,
|
||||
HostshipRequest,
|
||||
HostshipResignation
|
||||
HostshipResignation,
|
||||
NConnections
|
||||
};
|
||||
|
||||
struct Message {
|
||||
@@ -106,9 +117,13 @@ namespace openspace{
|
||||
void setAddress(const std::string &address);
|
||||
|
||||
void setName(const std::string& name);
|
||||
|
||||
|
||||
bool isAuthenticated();
|
||||
|
||||
bool isHost();
|
||||
|
||||
|
||||
const std::string& hostName();
|
||||
|
||||
void requestHostship(const std::string &password);
|
||||
|
||||
void resignHostship();
|
||||
@@ -133,7 +148,15 @@ namespace openspace{
|
||||
* interaction
|
||||
*/
|
||||
static scripting::LuaLibrary luaLibrary();
|
||||
|
||||
Status status();
|
||||
|
||||
size_t nConnections();
|
||||
|
||||
std::shared_ptr<ghoul::Event<>> connectionEvent();
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
@@ -162,7 +185,10 @@ namespace openspace{
|
||||
|
||||
void dataMessageReceived(const std::vector<char>& messageContent);
|
||||
|
||||
void hostInfoMessageReceived(const std::vector<char>& messageContent);
|
||||
void connectionStatusMessageReceived(const std::vector<char>& messageContent);
|
||||
|
||||
void nConnectionsMessageReceived(const std::vector<char>& messageContent);
|
||||
|
||||
|
||||
void broadcast();
|
||||
|
||||
@@ -171,26 +197,37 @@ namespace openspace{
|
||||
void sendFunc();
|
||||
|
||||
void threadManagement();
|
||||
|
||||
void setStatus(Status status);
|
||||
|
||||
void setHostName(const std::string& hostName);
|
||||
|
||||
void setNConnections(size_t nConnections);
|
||||
|
||||
std::string scriptFromPropertyAndValue(const std::string property, const std::string value);
|
||||
//std::string scriptFromPropertyAndValue(const std::string property, const std::string value);
|
||||
|
||||
uint32_t _passCode;
|
||||
std::string _port;
|
||||
std::string _address;
|
||||
std::string _name;
|
||||
|
||||
_SOCKET _clientSocket;
|
||||
std::unique_ptr<std::thread> _connectionThread;
|
||||
std::unique_ptr<std::thread> _broadcastThread;
|
||||
std::unique_ptr<std::thread> _sendThread;
|
||||
std::unique_ptr<std::thread> _listenThread;
|
||||
std::unique_ptr<std::thread> _handlerThread;
|
||||
std::atomic<bool> _isHost;
|
||||
|
||||
std::atomic<bool> _isConnected;
|
||||
std::atomic<bool> _isRunning;
|
||||
std::atomic<bool> _tryConnect;
|
||||
std::atomic<bool> _disconnect;
|
||||
std::atomic<bool> _initializationTimejumpRequired;
|
||||
|
||||
std::atomic<size_t> _nConnections;
|
||||
std::atomic<Status> _status;
|
||||
std::string _hostName;
|
||||
|
||||
std::condition_variable _disconnectCondition;
|
||||
std::mutex _disconnectMutex;
|
||||
|
||||
@@ -206,6 +243,8 @@ namespace openspace{
|
||||
std::atomic<bool> _latestTimeKeyframeValid;
|
||||
std::map<std::string, std::string> _currentState;
|
||||
std::mutex _currentStateMutex;
|
||||
|
||||
std::shared_ptr<ghoul::Event<>> _connectionEvent;
|
||||
};
|
||||
} // namespace network
|
||||
|
||||
|
||||
@@ -37,9 +37,8 @@ namespace scripting {
|
||||
struct LuaLibrary {
|
||||
/**
|
||||
* This structure represents a Lua function with its #name, #function pointer
|
||||
* #argumentText describing the arguments this function takes, the #helpText
|
||||
* describing the function, and whether it should be shared in a parallel
|
||||
* connection (#parallelShared)
|
||||
* #argumentText describing the arguments this function takes, and the the #helpText
|
||||
* describing the function.
|
||||
*/
|
||||
struct Function {
|
||||
/// The name of the function
|
||||
@@ -50,9 +49,6 @@ struct LuaLibrary {
|
||||
std::string argumentText;
|
||||
/// A help text describing what the function does/
|
||||
std::string helpText;
|
||||
/// If <code>true</code>, this function will be shared with other parallel
|
||||
/// connections
|
||||
bool parallelShared;
|
||||
};
|
||||
/// The name of the library
|
||||
std::string name;
|
||||
|
||||
@@ -49,6 +49,7 @@ namespace scripting {
|
||||
*/
|
||||
class ScriptEngine {
|
||||
public:
|
||||
using RemoteScripting = ghoul::Boolean;
|
||||
/**
|
||||
* Initializes the internal Lua state and registers a common set of library functions
|
||||
* \throw LuaRuntimeException If the creation of the new Lua state fails
|
||||
@@ -81,7 +82,7 @@ public:
|
||||
|
||||
void preSynchronization();
|
||||
|
||||
void queueScript(const std::string &script);
|
||||
void queueScript(const std::string &script, RemoteScripting remoteScripting);
|
||||
|
||||
void setLogFile(const std::string& filename, const std::string& type);
|
||||
|
||||
@@ -90,9 +91,9 @@ public:
|
||||
std::vector<std::string> allLuaFunctions() const;
|
||||
|
||||
//parallel functions
|
||||
bool parseLibraryAndFunctionNames(std::string &library, std::string &function, const std::string &script);
|
||||
bool shouldScriptBeSent(const std::string &library, const std::string &function);
|
||||
void cacheScript(const std::string &library, const std::string &function, const std::string &script);
|
||||
//bool parseLibraryAndFunctionNames(std::string &library, std::string &function, const std::string &script);
|
||||
//bool shouldScriptBeSent(const std::string &library, const std::string &function);
|
||||
//void cacheScript(const std::string &library, const std::string &function, const std::string &script);
|
||||
|
||||
private:
|
||||
|
||||
@@ -109,13 +110,13 @@ private:
|
||||
|
||||
//sync variables
|
||||
std::mutex _mutex;
|
||||
std::vector<std::string> _queuedScripts;
|
||||
std::vector<std::pair<std::string, bool>> _queuedScripts;
|
||||
std::vector<std::string> _receivedScripts;
|
||||
std::string _currentSyncedScript;
|
||||
|
||||
//parallel variables
|
||||
std::map<std::string, std::map<std::string, std::string>> _cachedScripts;
|
||||
std::mutex _cachedScriptsMutex;
|
||||
//std::map<std::string, std::map<std::string, std::string>> _cachedScripts;
|
||||
//std::mutex _cachedScriptsMutex;
|
||||
|
||||
//logging variables
|
||||
bool _logFileExists = false;
|
||||
|
||||
@@ -155,7 +155,7 @@ void addScreenSpaceRenderable(std::string texturePath) {
|
||||
std::string luaTable =
|
||||
"{Type = 'ScreenSpaceImage', TexturePath = '" + absPath(texturePath) + "' }";
|
||||
std::string script = "openspace.registerScreenSpaceRenderable(" + luaTable + ");";
|
||||
OsEng.scriptEngine().queueScript(script);
|
||||
OsEng.scriptEngine().queueScript(script, openspace::scripting::ScriptEngine::RemoteScripting::Yes);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
@@ -453,22 +453,26 @@ void GUI::render() {
|
||||
|
||||
if (toSun) {
|
||||
OsEng.scriptEngine().queueScript(
|
||||
"openspace.setPropertyValue('Interaction.coordinateSystem', 'Sun');"
|
||||
"openspace.setPropertyValue('Interaction.coordinateSystem', 'Sun');",
|
||||
scripting::ScriptEngine::RemoteScripting::Yes
|
||||
);
|
||||
}
|
||||
if (toPluto) {
|
||||
OsEng.scriptEngine().queueScript(
|
||||
"openspace.setPropertyValue('Interaction.coordinateSystem', 'Pluto');"
|
||||
"openspace.setPropertyValue('Interaction.coordinateSystem', 'Pluto');",
|
||||
scripting::ScriptEngine::RemoteScripting::Yes
|
||||
);
|
||||
}
|
||||
if (toJupiter) {
|
||||
OsEng.scriptEngine().queueScript(
|
||||
"openspace.setPropertyValue('Interaction.coordinateSystem', 'Jupiter');"
|
||||
"openspace.setPropertyValue('Interaction.coordinateSystem', 'Jupiter');",
|
||||
scripting::ScriptEngine::RemoteScripting::Yes
|
||||
);
|
||||
}
|
||||
if (to67P) {
|
||||
OsEng.scriptEngine().queueScript(
|
||||
"openspace.setPropertyValue('Interaction.coordinateSystem', '67P');"
|
||||
"openspace.setPropertyValue('Interaction.coordinateSystem', '67P');",
|
||||
scripting::ScriptEngine::RemoteScripting::Yes
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -65,7 +65,8 @@ void GuiOriginComponent::render() {
|
||||
if (hasChanged) {
|
||||
OsEng.scriptEngine().queueScript(
|
||||
"openspace.setPropertyValue('Interaction.origin', '" +
|
||||
nodes[currentPosition]->name() + "');"
|
||||
nodes[currentPosition]->name() + "');",
|
||||
scripting::ScriptEngine::RemoteScripting::Yes
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,7 +38,8 @@ void GuiTimeComponent::render() {
|
||||
bool changed = ImGui::SliderFloat("Delta Time", &deltaTime, -5000.f, 5000.f);
|
||||
if (changed) {
|
||||
OsEng.scriptEngine().queueScript(
|
||||
"openspace.time.setDeltaTime(" + std::to_string(deltaTime) + ")"
|
||||
"openspace.time.setDeltaTime(" + std::to_string(deltaTime) + ")",
|
||||
scripting::ScriptEngine::RemoteScripting::Yes
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ void renderTooltip(Property* prop) {
|
||||
void executeScript(const std::string& id, const std::string& value) {
|
||||
std::string script =
|
||||
"openspace.setPropertyValueSingle('" + id + "', " + value + ");";
|
||||
OsEng.scriptEngine().queueScript(script);
|
||||
OsEng.scriptEngine().queueScript(script, scripting::ScriptEngine::RemoteScripting::Yes);
|
||||
}
|
||||
|
||||
void renderBoolProperty(Property* prop, const std::string& ownerName) {
|
||||
|
||||
@@ -15,10 +15,14 @@ openspace.bindKey("q", helper.renderable.toggle('SunMarker'))
|
||||
openspace.bindKey("e", helper.renderable.toggle('EarthMarker'))
|
||||
openspace.bindKey("x", helper.renderable.toggle('Constellation Bounds'))
|
||||
|
||||
openspace.bindKey("c", "openspace.parallel.setAddress('130.236.142.51');openspace.parallel.setPassword('newhorizons-20150714');openspace.parallel.connect();")
|
||||
--openspace.bindKey("c", "openspace.parallel.setAddress('130.236.142.51');openspace.parallel.setPassword('newhorizons-20150714');openspace.parallel.connect();")
|
||||
|
||||
openspace.bindKey("h", "openspace.iswa.setBaseUrl('https://iswa-demo-server.herokuapp.com/')");
|
||||
--openspace.bindKey("h", "openspace.iswa.setBaseUrl('https://iswa-demo-server.herokuapp.com/')");
|
||||
openspace.bindKey("g", "openspace.iswa.setBaseUrl('http://128.183.168.116:3000/')");
|
||||
openspace.bindKey("l", "openspace.iswa.setBaseUrl('http://localhost:3000/')");
|
||||
|
||||
openspace.bindKey("v", "openspace.time.setTime('2015-03-15T02:00:00.00')");
|
||||
openspace.bindKey("v", "openspace.time.setTime('2015-03-15T02:00:00.00')");
|
||||
|
||||
openspace.bindKeyLocal("h", "openspace.parallel.setAddress('127.0.0.2');openspace.parallel.setPort('25001');openspace.parallel.setPassword('test');openspace.parallel.connect();openspace.parallel.requestHostship('test');")
|
||||
openspace.bindKeyLocal("c", "openspace.parallel.setAddress('127.0.0.3');openspace.parallel.setPort('25001');openspace.parallel.setPassword('test');openspace.parallel.connect();")
|
||||
openspace.bindKeyLocal("d", "openspace.parallel.setAddress('127.0.0.4');openspace.parallel.setPort('25001');openspace.parallel.setPassword('test');openspace.parallel.connect();")
|
||||
@@ -17,10 +17,12 @@ openspace.bindKey("s", "openspace.setPropertyValue('Interaction.origin', 'Rosett
|
||||
|
||||
-- openspace.bindKey("F5", "openspace.setPropertyValue('Interaction.coordinateSystem', 'Sun'); openspace.printInfo('Changing Viewpoint to Sun');");
|
||||
openspace.bindKey("F6", "openspace.setPropertyValue('Interaction.coordinateSystem', '67P'); openspace.printInfo('Changing Viewpoint to 67P');");
|
||||
openspace.bindKey("F7", "openspace.time.setTime('2014-08-15T03:05:18.101')");
|
||||
openspace.bindKey("F8", "openspace.setPropertyValue('67P.renderable.ProjectionComponent.clearAllProjections', true);");
|
||||
|
||||
openspace.bindKey("i", helper.renderable.toggle('ImagePlaneRosetta'))
|
||||
openspace.bindKey("q", helper.renderable.toggle('SunMarker'))
|
||||
openspace.bindKey("e", helper.renderable.toggle('EarthMarker'))
|
||||
|
||||
openspace.bindKey("c", "openspace.parallel.setAddress('130.236.142.51');openspace.parallel.setPassword('newhorizons-20150714');openspace.parallel.connect();")
|
||||
openspace.bindKeyLocal("h", "openspace.parallel.setAddress('127.0.0.1');openspace.parallel.setPort('25001');openspace.parallel.setPassword('test');openspace.parallel.connect();openspace.parallel.requestHostship('test');")
|
||||
openspace.bindKeyLocal("c", "openspace.parallel.setAddress('127.0.0.1');openspace.parallel.setPort('25001');openspace.parallel.setPassword('test');openspace.parallel.connect();")
|
||||
|
||||
@@ -7,24 +7,24 @@ helper.property = {}
|
||||
-- Function that sets the most common key bindings that are common to most (all?)
|
||||
-- scenes
|
||||
helper.setCommonKeys = function()
|
||||
openspace.bindKey("F1", "openspace.gui.toggle()")
|
||||
openspace.bindKey("F2", "openspace.setPerformanceMeasurement(true)")
|
||||
openspace.bindKey("F3", "openspace.setPerformanceMeasurement(false)")
|
||||
openspace.bindKeyLocal("F1", "openspace.gui.toggle()")
|
||||
openspace.bindKeyLocal("F2", "openspace.setPerformanceMeasurement(true)")
|
||||
openspace.bindKeyLocal("F3", "openspace.setPerformanceMeasurement(false)")
|
||||
|
||||
openspace.bindKey("t", "openspace.toggleFrametimeType(1)")
|
||||
openspace.bindKey("Shift+t", "openspace.toggleFrametimeType(0)")
|
||||
openspace.bindKeyLocal("t", "openspace.toggleFrametimeType(1)")
|
||||
openspace.bindKeyLocal("Shift+t", "openspace.toggleFrametimeType(0)")
|
||||
|
||||
openspace.bindKey("ESC", "openspace.toggleShutdown()")
|
||||
openspace.bindKeyLocal("ESC", "openspace.toggleShutdown()")
|
||||
|
||||
openspace.bindKey("PRINT_SCREEN", "openspace.takeScreenshot()")
|
||||
openspace.bindKeyLocal("PRINT_SCREEN", "openspace.takeScreenshot()")
|
||||
openspace.bindKey("SPACE", "openspace.time.togglePause()")
|
||||
|
||||
openspace.bindKey("COMMA", "openspace.setRenderer('Framebuffer');")
|
||||
openspace.bindKey("PERIOD", "openspace.setRenderer('ABuffer');")
|
||||
|
||||
|
||||
openspace.bindKey("f", helper.property.invert('Interaction.rotationalFriction'))
|
||||
openspace.bindKey("Shift+f", helper.property.invert('Interaction.zoomFriction'))
|
||||
openspace.bindKeyLocal("f", helper.property.invert('Interaction.rotationalFriction'))
|
||||
openspace.bindKeyLocal("Shift+f", helper.property.invert('Interaction.zoomFriction'))
|
||||
|
||||
openspace.bindKey("w", "openspace.toggleFade(3)")
|
||||
end
|
||||
|
||||
@@ -556,6 +556,7 @@ void OpenSpaceEngine::runScripts(const ghoul::Dictionary& scripts) {
|
||||
|
||||
//@JK
|
||||
//temporary solution to ensure that startup scripts may be syncrhonized over parallel connection
|
||||
/*
|
||||
std::ifstream scriptFile;
|
||||
scriptFile.open(absoluteScriptPath.c_str());
|
||||
std::string line;
|
||||
@@ -569,7 +570,7 @@ void OpenSpaceEngine::runScripts(const ghoul::Dictionary& scripts) {
|
||||
_engine->scriptEngine().cacheScript(lib, func, line);
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
@@ -858,14 +859,13 @@ void OpenSpaceEngine::keyboardCallback(Key key, KeyModifier mod, KeyAction actio
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (key == _console->commandInputButton() && (action == KeyAction::Press || action == KeyAction::Repeat))
|
||||
_console->toggleVisibility();
|
||||
|
||||
if (!_console->isVisible()) {
|
||||
if (key == _console->commandInputButton()) {
|
||||
if (action == KeyAction::Press) {
|
||||
_console->toggleMode();
|
||||
}
|
||||
} else if (!_console->isVisible()) {
|
||||
_interactionHandler->keyboardCallback(key, mod, action);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
_console->keyboardCallback(key, mod, action);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -269,8 +269,10 @@ void InteractionHandler::keyboardCallback(Key key, KeyModifier modifier, KeyActi
|
||||
// iterate over key bindings
|
||||
auto ret = _keyLua.equal_range({ key, modifier });
|
||||
for (auto it = ret.first; it != ret.second; ++it) {
|
||||
//OsEng.scriptEngine()->runScript(it->second);
|
||||
OsEng.scriptEngine().queueScript(it->second);
|
||||
OsEng.scriptEngine().queueScript(it->second.first,
|
||||
it->second.second ?
|
||||
scripting::ScriptEngine::RemoteScripting::Yes :
|
||||
scripting::ScriptEngine::RemoteScripting::No);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -378,12 +380,20 @@ void InteractionHandler::resetKeyBindings() {
|
||||
_keyLua.clear();
|
||||
}
|
||||
|
||||
void InteractionHandler::bindKeyLocal(Key key, KeyModifier modifier, std::string lua) {
|
||||
_keyLua.insert({
|
||||
{ key, modifier },
|
||||
std::make_pair(lua, false)
|
||||
});
|
||||
}
|
||||
|
||||
void InteractionHandler::bindKey(Key key, KeyModifier modifier, std::string lua) {
|
||||
_keyLua.insert({
|
||||
{ key, modifier },
|
||||
lua
|
||||
std::make_pair(lua, true)
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
void InteractionHandler::writeKeyboardDocumentation(const std::string& type, const std::string& file)
|
||||
{
|
||||
@@ -391,8 +401,14 @@ void InteractionHandler::writeKeyboardDocumentation(const std::string& type, con
|
||||
std::ofstream f(absPath(file));
|
||||
|
||||
for (const auto& p : _keyLua) {
|
||||
std::string remoteScriptingInfo;
|
||||
bool remoteScripting = p.second.second;
|
||||
|
||||
if (!remoteScripting) {
|
||||
remoteScriptingInfo = " (LOCAL)";
|
||||
}
|
||||
f << std::to_string(p.first) << ": " <<
|
||||
p.second << std::endl;
|
||||
p.second.first << remoteScriptingInfo << std::endl;
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -417,7 +433,14 @@ scripting::LuaLibrary InteractionHandler::luaLibrary() {
|
||||
"bindKey",
|
||||
&luascriptfunctions::bindKey,
|
||||
"string, string",
|
||||
"Binds a key by name to a lua string command"
|
||||
"Binds a key by name to a lua string command to execute both locally "
|
||||
"and to broadcast to clients if this is the host of a parallel session"
|
||||
},
|
||||
{
|
||||
"bindKeyLocal",
|
||||
&luascriptfunctions::bindKeyLocal,
|
||||
"string, string",
|
||||
"Binds a key by name to a lua string command to execute only locally"
|
||||
},
|
||||
{
|
||||
"setInteractionMode",
|
||||
|
||||
@@ -60,7 +60,9 @@ int setOrigin(lua_State* L) {
|
||||
/**
|
||||
* \ingroup LuaScripts
|
||||
* bindKey():
|
||||
* Binds a key to Lua command
|
||||
* Binds a key to Lua command to both execute locally
|
||||
* and broadcast to all clients if this node is hosting
|
||||
* a parallel connection.
|
||||
*/
|
||||
int bindKey(lua_State* L) {
|
||||
using ghoul::lua::luaTypeToString;
|
||||
@@ -93,6 +95,42 @@ int bindKey(lua_State* L) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \ingroup LuaScripts
|
||||
* bindKey():
|
||||
* Binds a key to Lua command to execute only locally
|
||||
*/
|
||||
int bindKeyLocal(lua_State* L) {
|
||||
using ghoul::lua::luaTypeToString;
|
||||
|
||||
int nArguments = lua_gettop(L);
|
||||
if (nArguments != 2)
|
||||
return luaL_error(L, "Expected %i arguments, got %i", 2, nArguments);
|
||||
|
||||
|
||||
std::string key = luaL_checkstring(L, -2);
|
||||
std::string command = luaL_checkstring(L, -1);
|
||||
|
||||
if (command.empty())
|
||||
return luaL_error(L, "Command string is empty");
|
||||
|
||||
openspace::KeyWithModifier iKey = openspace::stringToKey(key);
|
||||
|
||||
if (iKey.key == openspace::Key::Unknown) {
|
||||
LERRORC("lua.bindKey", "Could not find key '" << key << "'");
|
||||
return 0;
|
||||
}
|
||||
|
||||
OsEng.interactionHandler().bindKeyLocal(
|
||||
iKey.key,
|
||||
iKey.modifier,
|
||||
command
|
||||
);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \ingroup LuaScripts
|
||||
* clearKeys():
|
||||
@@ -176,120 +214,7 @@ int resetCameraDirection(lua_State* L) {
|
||||
OsEng.interactionHandler().resetCameraDirection();
|
||||
}
|
||||
|
||||
#ifdef USE_OLD_INTERACTIONHANDLER
|
||||
|
||||
/**
|
||||
* \ingroup LuaScripts
|
||||
* dt(bool):
|
||||
* Get current frame time
|
||||
*/
|
||||
int dt(lua_State* L) {
|
||||
/*
|
||||
int nArguments = lua_gettop(L);
|
||||
if (nArguments != 0)
|
||||
return luaL_error(L, "Expected %i arguments, got %i", 0, nArguments);
|
||||
|
||||
lua_pushnumber(L,OsEng.interactionHandler().deltaTime());
|
||||
*/return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* \ingroup LuaScripts
|
||||
* distance(double, double):
|
||||
* Change distance to origin
|
||||
*/
|
||||
int distance(lua_State* L) {
|
||||
/*
|
||||
int nArguments = lua_gettop(L);
|
||||
if (nArguments != 2)
|
||||
return luaL_error(L, "Expected %i arguments, got %i", 2, nArguments);
|
||||
|
||||
double d1 = luaL_checknumber(L, -2);
|
||||
double d2 = luaL_checknumber(L, -1);
|
||||
PowerScaledScalar dist(static_cast<float>(d1), static_cast<float>(d2));
|
||||
OsEng.interactionHandler().distanceDelta(dist);
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \ingroup LuaScripts
|
||||
* setInteractionSensitivity(double):
|
||||
* Changes the global interaction sensitivity to the passed value
|
||||
*/
|
||||
int setInteractionSensitivity(lua_State* L) {
|
||||
int nArguments = lua_gettop(L);
|
||||
if (nArguments != 1)
|
||||
return luaL_error(L, "Expected %i arguments, got %i", 1, nArguments);
|
||||
|
||||
float sensitivity = static_cast<float>(luaL_checknumber(L, -1));
|
||||
//OsEng.interactionHandler().setInteractionSensitivity(sensitivity);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \ingroup LuaScripts
|
||||
* interactionSensitivity():
|
||||
* Returns the current, global interaction sensitivity
|
||||
*/
|
||||
int interactionSensitivity(lua_State* L) {
|
||||
//float sensitivity = OsEng.interactionHandler().interactionSensitivity();
|
||||
//lua_pushnumber(L, sensitivity);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* \ingroup LuaScripts
|
||||
* setInvertRoll(bool):
|
||||
* Determines if the roll movement is inverted
|
||||
*/
|
||||
int setInvertRoll(lua_State* L) {
|
||||
int nArguments = lua_gettop(L);
|
||||
if (nArguments != 1)
|
||||
return luaL_error(L, "Expected %i arguments, got %i", 1, nArguments);
|
||||
|
||||
bool invert = lua_toboolean(L, -1) == 1;
|
||||
//OsEng.interactionHandler().setInvertRoll(invert);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \ingroup LuaScripts
|
||||
* invertRoll():
|
||||
* Returns the current setting for inversion of roll movement
|
||||
*/
|
||||
int invertRoll(lua_State* L) {
|
||||
//bool invert = OsEng.interactionHandler().invertRoll();
|
||||
//lua_pushboolean(L, invert);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* \ingroup LuaScripts
|
||||
* setInvertRotation(bool):
|
||||
* Determines if the rotation movement is inverted
|
||||
*/
|
||||
int setInvertRotation(lua_State* L) {
|
||||
int nArguments = lua_gettop(L);
|
||||
if (nArguments != 1)
|
||||
return luaL_error(L, "Expected %i arguments, got %i", 1, nArguments);
|
||||
|
||||
bool invert = lua_toboolean(L, -1) == 1;
|
||||
//OsEng.interactionHandler().setInvertRotation(invert);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \ingroup LuaScripts
|
||||
* invertRotation():
|
||||
* Returns the current setting for inversion of rotation movement
|
||||
*/
|
||||
int invertRotation(lua_State* L) {
|
||||
//bool invert = OsEng.interactionHandler().invertRotation();
|
||||
//lua_pushboolean(L, invert);
|
||||
return 1;
|
||||
}
|
||||
#endif USE_OLD_INTERACTIONHANDLER
|
||||
} // namespace luascriptfunctions
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -58,6 +58,7 @@ LuaConsole::LuaConsole()
|
||||
, _filename("")
|
||||
, _autoCompleteInfo({NoAutoComplete, false, ""})
|
||||
, _isVisible(false)
|
||||
, _remoteScripting(true)
|
||||
{
|
||||
// _commands.push_back("");
|
||||
// _activeCommand = _commands.size() - 1;
|
||||
@@ -89,6 +90,13 @@ void LuaConsole::initialize() {
|
||||
}
|
||||
_commands.push_back("");
|
||||
_activeCommand = _commands.size() - 1;
|
||||
|
||||
OsEng.parallelConnection().connectionEvent()->subscribe("luaConsole",
|
||||
"statusChanged", [this]() {
|
||||
network::Status status = OsEng.parallelConnection().status();
|
||||
parallelConnectionChanged(status);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
void LuaConsole::deinitialize() {
|
||||
@@ -102,6 +110,8 @@ void LuaConsole::deinitialize() {
|
||||
file.write(s.c_str(), length);
|
||||
}
|
||||
}
|
||||
|
||||
OsEng.parallelConnection().connectionEvent()->unsubscribe("luaConsole");
|
||||
}
|
||||
|
||||
void LuaConsole::keyboardCallback(Key key, KeyModifier modifier, KeyAction action) {
|
||||
@@ -169,7 +179,8 @@ void LuaConsole::keyboardCallback(Key key, KeyModifier modifier, KeyAction actio
|
||||
else {
|
||||
std::string cmd = _commands.at(_activeCommand);
|
||||
if (cmd != "") {
|
||||
OsEng.scriptEngine().queueScript(cmd);
|
||||
OsEng.scriptEngine().queueScript(cmd,
|
||||
_remoteScripting ? scripting::ScriptEngine::RemoteScripting::Yes : scripting::ScriptEngine::RemoteScripting::No);
|
||||
|
||||
// Only add the current command to the history if it hasn't been
|
||||
// executed before. We don't want two of the same commands in a row
|
||||
@@ -309,13 +320,28 @@ void LuaConsole::render() {
|
||||
startY = startY - font_size * 15.0f * 2.0f;
|
||||
|
||||
const glm::vec4 red(1, 0, 0, 1);
|
||||
const glm::vec4 lightBlue(0.4, 0.4, 1, 1);
|
||||
const glm::vec4 green(0, 1, 0, 1);
|
||||
const glm::vec4 white(1, 1, 1, 1);
|
||||
std::shared_ptr<ghoul::fontrendering::Font> font = OsEng.fontManager().font("Mono", font_size);
|
||||
|
||||
using ghoul::fontrendering::RenderFont;
|
||||
|
||||
RenderFont(*font, glm::vec2(15.f, startY), red, "$");
|
||||
if (_remoteScripting) {
|
||||
int nClients = OsEng.parallelConnection().nConnections() - 1;
|
||||
if (nClients == 1) {
|
||||
RenderFont(*font, glm::vec2(15.f, startY + 20.0f), red, "Broadcasting script to 1 client");
|
||||
} else {
|
||||
RenderFont(*font, glm::vec2(15.f, startY + 20.0f), red, ("Broadcasting script to " + std::to_string(nClients) + " clients").c_str());
|
||||
}
|
||||
RenderFont(*font, glm::vec2(15.f, startY), red, "$");
|
||||
}
|
||||
else {
|
||||
if (OsEng.parallelConnection().isHost()) {
|
||||
RenderFont(*font, glm::vec2(15.f, startY + 20.0f), lightBlue, "Local script execution");
|
||||
}
|
||||
RenderFont(*font, glm::vec2(15.f, startY), lightBlue, "$");
|
||||
}
|
||||
RenderFont(*font, glm::vec2(15.f + font_size, startY), white, "%s", _commands.at(_activeCommand).c_str());
|
||||
|
||||
size_t n = std::count(_commands.at(_activeCommand).begin(), _commands.at(_activeCommand).begin() + _inputPosition, '\n');
|
||||
@@ -390,10 +416,24 @@ void LuaConsole::setVisible(bool visible) {
|
||||
_isVisible = visible;
|
||||
}
|
||||
|
||||
void LuaConsole::toggleVisibility() {
|
||||
_isVisible = !_isVisible;
|
||||
void LuaConsole::toggleMode() {
|
||||
if (_isVisible) {
|
||||
if (_remoteScripting) {
|
||||
_remoteScripting = false;
|
||||
} else {
|
||||
_isVisible = false;
|
||||
}
|
||||
} else {
|
||||
_remoteScripting = OsEng.parallelConnection().isHost();
|
||||
_isVisible = true;
|
||||
}
|
||||
}
|
||||
|
||||
void LuaConsole::parallelConnectionChanged(const network::Status& status) {
|
||||
_remoteScripting = status == network::Status::Host;
|
||||
}
|
||||
|
||||
|
||||
scripting::LuaLibrary LuaConsole::luaLibrary() {
|
||||
return {
|
||||
"console",
|
||||
|
||||
@@ -64,7 +64,7 @@ int toggle(lua_State* L) {
|
||||
if (nArguments != 0)
|
||||
return luaL_error(L, "Expected %i arguments, got %i", 0, nArguments);
|
||||
|
||||
OsEng.console().toggleVisibility();
|
||||
OsEng.console().toggleMode();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -67,7 +67,7 @@ bool NetworkEngine::handleMessage(const std::string& message) {
|
||||
{
|
||||
std::string script = message.substr(1);
|
||||
//LINFO("Received Lua Script: '" << script << "'");
|
||||
OsEng.scriptEngine().queueScript(script);
|
||||
OsEng.scriptEngine().queueScript(script, scripting::ScriptEngine::RemoteScripting::No);
|
||||
return true;
|
||||
}
|
||||
case MessageTypeExternalControlConnected:
|
||||
|
||||
@@ -84,14 +84,16 @@ ParallelConnection::ParallelConnection()
|
||||
, _listenThread(nullptr)
|
||||
, _handlerThread(nullptr)
|
||||
, _isRunning(true)
|
||||
, _isHost(false)
|
||||
, _nConnections(0)
|
||||
, _status(Status::Disconnected)
|
||||
, _hostName("")
|
||||
, _isConnected(false)
|
||||
, _tryConnect(false)
|
||||
, _disconnect(false)
|
||||
, _latestTimeKeyframeValid(false)
|
||||
, _initializationTimejumpRequired(false)
|
||||
{
|
||||
//create handler thread
|
||||
_connectionEvent = std::make_shared<ghoul::Event<>>();
|
||||
_handlerThread = std::make_unique<std::thread>(&ParallelConnection::threadManagement, this);
|
||||
}
|
||||
|
||||
@@ -174,7 +176,7 @@ void ParallelConnection::disconnect(){
|
||||
_isConnected.store(false);
|
||||
|
||||
//tell broadcast thread to stop broadcasting (we're no longer host)
|
||||
_isHost.store(false);
|
||||
setStatus(Status::Disconnected);
|
||||
|
||||
//join connection thread and delete it
|
||||
if(_connectionThread != nullptr){
|
||||
@@ -320,8 +322,14 @@ void ParallelConnection::establishConnection(addrinfo *info){
|
||||
//we no longer need to try to establish connection
|
||||
_tryConnect.store(false);
|
||||
|
||||
_sendBufferMutex.lock();
|
||||
_sendBuffer.clear();
|
||||
_sendBufferMutex.unlock();
|
||||
|
||||
//send authentication
|
||||
sendAuthentication();
|
||||
} else {
|
||||
LINFO("Connection attempt failed.");
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
@@ -380,8 +388,11 @@ void ParallelConnection::handleMessage(const Message& message) {
|
||||
case MessageType::Data:
|
||||
dataMessageReceived(message.content);
|
||||
break;
|
||||
case MessageType::HostInformation:
|
||||
hostInfoMessageReceived(message.content);
|
||||
case MessageType::ConnectionStatus:
|
||||
connectionStatusMessageReceived(message.content);
|
||||
break;
|
||||
case MessageType::NConnections:
|
||||
nConnectionsMessageReceived(message.content);
|
||||
break;
|
||||
default:
|
||||
//unknown message type
|
||||
@@ -475,7 +486,7 @@ void ParallelConnection::dataMessageReceived(const std::vector<char>& messageCon
|
||||
uint32_t type = *(reinterpret_cast<const uint32_t*>(messageContent.data()));
|
||||
std::vector<char> buffer(messageContent.begin() + sizeof(uint32_t), messageContent.end());
|
||||
|
||||
switch(type){
|
||||
switch(static_cast<network::datamessagestructures::Type>(type)) {
|
||||
case network::datamessagestructures::Type::CameraData: {
|
||||
network::datamessagestructures::CameraKeyframe kf(buffer);
|
||||
OsEng.interactionHandler().addKeyframe(kf);
|
||||
@@ -522,7 +533,7 @@ void ParallelConnection::dataMessageReceived(const std::vector<char>& messageCon
|
||||
case network::datamessagestructures::Type::ScriptData: {
|
||||
network::datamessagestructures::ScriptMessage sm;
|
||||
sm.deserialize(buffer);
|
||||
OsEng.scriptEngine().queueScript(sm._script);
|
||||
OsEng.scriptEngine().queueScript(sm._script, scripting::ScriptEngine::RemoteScripting::No);
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -562,8 +573,13 @@ void ParallelConnection::sendFunc(){
|
||||
std::unique_lock<std::mutex> unqlock(_sendBufferMutex);
|
||||
_sendCondition.wait(unqlock);
|
||||
|
||||
if (_disconnect) {
|
||||
break;
|
||||
}
|
||||
|
||||
while (!_sendBuffer.empty()) {
|
||||
const Message& message = _sendBuffer.front();
|
||||
Message message = _sendBuffer.front();
|
||||
unqlock.unlock();
|
||||
std::vector<char> header;
|
||||
|
||||
//insert header into buffer
|
||||
@@ -594,65 +610,79 @@ void ParallelConnection::sendFunc(){
|
||||
signalDisconnect();
|
||||
}
|
||||
|
||||
unqlock.lock();
|
||||
_sendBuffer.erase(_sendBuffer.begin());
|
||||
}
|
||||
}
|
||||
}
|
||||
std::lock_guard<std::mutex> sendLock(_sendBufferMutex);
|
||||
_sendBuffer.clear();
|
||||
|
||||
}
|
||||
|
||||
void ParallelConnection::hostInfoMessageReceived(const std::vector<char>& message){
|
||||
if (message.size() < 1) {
|
||||
LERROR("Malformed host info message.");
|
||||
void ParallelConnection::connectionStatusMessageReceived(const std::vector<char>& message) {
|
||||
if (message.size() < 2 * sizeof(uint32_t)) {
|
||||
LERROR("Malformed connection status message.");
|
||||
return;
|
||||
}
|
||||
char hostInfo = message[0];
|
||||
size_t pointer = 0;
|
||||
uint32_t statusIn = *(reinterpret_cast<const uint32_t*>(&message[pointer]));
|
||||
network::Status status = static_cast<network::Status>(statusIn);
|
||||
pointer += sizeof(uint32_t);
|
||||
|
||||
size_t hostNameSize = *(reinterpret_cast<const uint32_t*>(&message[pointer]));
|
||||
pointer += sizeof(uint32_t);
|
||||
|
||||
if (hostNameSize > message.size() - pointer) {
|
||||
LERROR("Malformed connection status message.");
|
||||
return;
|
||||
}
|
||||
|
||||
std::string hostName = "";
|
||||
if (hostNameSize > 0) {
|
||||
hostName = std::string(&message[pointer], hostNameSize);
|
||||
}
|
||||
pointer += hostNameSize;
|
||||
|
||||
if (hostInfo == 1) { // assigned as host
|
||||
if (_isHost.load()) {
|
||||
//we're already host, do nothing (dummy check)
|
||||
return;
|
||||
}
|
||||
_isHost.store(true);
|
||||
if (status > Status::Host) {
|
||||
LERROR("Invalid status.");
|
||||
return;
|
||||
}
|
||||
|
||||
//start broadcasting
|
||||
if (status == _status) {
|
||||
//status remains unchanged.
|
||||
return;
|
||||
}
|
||||
|
||||
setStatus(status);
|
||||
setHostName(hostName);
|
||||
|
||||
if (status == Status::Host) { // assigned as host
|
||||
_broadcastThread = std::make_unique<std::thread>(&ParallelConnection::broadcast, this);
|
||||
|
||||
} else { // assigned as client
|
||||
if (!_isHost.load()) {
|
||||
//we're already a client, do nothing (dummy check)
|
||||
return;
|
||||
}
|
||||
|
||||
//stop broadcast loop
|
||||
_isHost.store(false);
|
||||
|
||||
|
||||
// delete broadcasting thread
|
||||
// (the thread is allowed to terminate once the status is set to non-host.)
|
||||
if (_broadcastThread != nullptr) {
|
||||
_broadcastThread->join();
|
||||
_broadcastThread = nullptr;
|
||||
}
|
||||
OsEng.interactionHandler().clearKeyframes();
|
||||
|
||||
|
||||
//clear buffered any keyframes
|
||||
|
||||
|
||||
//request init package from the host
|
||||
//int size = headerSize();
|
||||
//std::vector<char> buffer;
|
||||
//buffer.reserve(size);
|
||||
|
||||
//write header
|
||||
//writeHeader(buffer, MessageTypes::InitializationRequest);
|
||||
|
||||
//send message
|
||||
//std::cout << "host info queue" << std::endl;
|
||||
//queueMessage(MessageTypes::InitializationRequest, buffer);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void ParallelConnection::nConnectionsMessageReceived(const std::vector<char>& message) {
|
||||
if (message.size() < sizeof(uint32_t)) {
|
||||
LERROR("Malformed host info message.");
|
||||
return;
|
||||
}
|
||||
uint32_t nConnections = *(reinterpret_cast<const uint32_t*>(&message[0]));
|
||||
setNConnections(nConnections);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//void ParallelConnection::initializationRequestMessageReceived(const std::vector<char>& message){
|
||||
/*
|
||||
//get current state as scripts
|
||||
@@ -742,8 +772,10 @@ void ParallelConnection::listenCommunication() {
|
||||
|
||||
//if enough data was received
|
||||
if (nBytesRead <= 0) {
|
||||
LERROR("Error " << _ERRNO << " detected in connection when reading header, disconnecting!");
|
||||
signalDisconnect();
|
||||
if (!_disconnect) {
|
||||
LERROR("Error " << _ERRNO << " detected in connection when reading header, disconnecting!");
|
||||
signalDisconnect();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -773,8 +805,10 @@ void ParallelConnection::listenCommunication() {
|
||||
nBytesRead = receiveData(_clientSocket, messageBuffer, messageSize, 0);
|
||||
|
||||
if (nBytesRead <= 0) {
|
||||
LERROR("Error " << _ERRNO << " detected in connection when reading message, disconnecting!");
|
||||
signalDisconnect();
|
||||
if (!_disconnect) {
|
||||
LERROR("Error " << _ERRNO << " detected in connection when reading message, disconnecting!");
|
||||
signalDisconnect();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -816,10 +850,7 @@ void ParallelConnection::setName(const std::string& name){
|
||||
_name = name;
|
||||
}
|
||||
|
||||
bool ParallelConnection::isHost(){
|
||||
return _isHost.load();
|
||||
}
|
||||
|
||||
|
||||
void ParallelConnection::requestHostship(const std::string &password){
|
||||
std::vector<char> buffer;
|
||||
uint32_t passcode = hash(password);
|
||||
@@ -863,7 +894,7 @@ bool ParallelConnection::initNetworkAPI(){
|
||||
}
|
||||
|
||||
void ParallelConnection::sendScript(const std::string& script) {
|
||||
if (!_isHost) return;
|
||||
if (!isHost()) return;
|
||||
|
||||
network::datamessagestructures::ScriptMessage sm;
|
||||
sm._script = script;
|
||||
@@ -886,7 +917,7 @@ void ParallelConnection::preSynchronization(){
|
||||
//std::cout << "start." << std::endl;
|
||||
|
||||
//if we're the host
|
||||
if(_isHost){
|
||||
//if(_isHost){
|
||||
/*
|
||||
//get current time parameters and create a keyframe
|
||||
network::datamessagestructures::TimeKeyframe tf;
|
||||
@@ -925,8 +956,8 @@ void ParallelConnection::preSynchronization(){
|
||||
|
||||
std::cout << "host 7." << std::endl;
|
||||
*/
|
||||
}
|
||||
else{
|
||||
//}
|
||||
//else{
|
||||
/*
|
||||
//if we're not the host and we have a valid keyframe (one that hasnt been used before)
|
||||
if(_latestTimeKeyframeValid.load()){
|
||||
@@ -951,7 +982,7 @@ void ParallelConnection::preSynchronization(){
|
||||
|
||||
}
|
||||
*/
|
||||
}
|
||||
//}
|
||||
|
||||
//std::cout << "stop." << std::endl;
|
||||
}
|
||||
@@ -1012,10 +1043,47 @@ void ParallelConnection::preSynchronization(){
|
||||
|
||||
//}
|
||||
|
||||
void ParallelConnection::setStatus(Status status) {
|
||||
if (_status != status) {
|
||||
_status = status;
|
||||
_connectionEvent->publish("statusChanged");
|
||||
}
|
||||
}
|
||||
|
||||
Status ParallelConnection::status() {
|
||||
return _status;
|
||||
}
|
||||
|
||||
void ParallelConnection::setNConnections(size_t nConnections) {
|
||||
if (_nConnections != nConnections) {
|
||||
_nConnections = nConnections;
|
||||
_connectionEvent->publish("nConnectionsChanged");
|
||||
}
|
||||
}
|
||||
|
||||
size_t ParallelConnection::nConnections() {
|
||||
return _nConnections;
|
||||
}
|
||||
|
||||
bool ParallelConnection::isHost() {
|
||||
return _status == Status::Host;
|
||||
}
|
||||
|
||||
void ParallelConnection::setHostName(const std::string& hostName) {
|
||||
if (_hostName != hostName) {
|
||||
_hostName = hostName;
|
||||
_connectionEvent->publish("hostNameChanged");
|
||||
}
|
||||
}
|
||||
|
||||
const std::string& ParallelConnection::hostName() {
|
||||
return _hostName;
|
||||
}
|
||||
|
||||
void ParallelConnection::broadcast(){
|
||||
|
||||
//while we're still connected and we're the host
|
||||
while (_isConnected && _isHost) {
|
||||
while (_isConnected && isHost()) {
|
||||
//create a keyframe with current position and orientation of camera
|
||||
network::datamessagestructures::CameraKeyframe kf;
|
||||
kf._position = OsEng.interactionHandler().camera()->positionVec3();
|
||||
@@ -1054,6 +1122,11 @@ uint32_t ParallelConnection::hash(const std::string &val) {
|
||||
|
||||
return hashVal;
|
||||
};
|
||||
|
||||
|
||||
std::shared_ptr<ghoul::Event<>> ParallelConnection::connectionEvent() {
|
||||
return _connectionEvent;
|
||||
}
|
||||
|
||||
scripting::LuaLibrary ParallelConnection::luaLibrary() {
|
||||
return {
|
||||
|
||||
@@ -763,23 +763,20 @@ scripting::LuaLibrary RenderEngine::luaLibrary() {
|
||||
"toggleFade",
|
||||
&luascriptfunctions::toggleFade,
|
||||
"number",
|
||||
"Toggles fading in or out",
|
||||
true
|
||||
"Toggles fading in or out"
|
||||
},
|
||||
{
|
||||
"fadeIn",
|
||||
&luascriptfunctions::fadeIn,
|
||||
"number",
|
||||
"",
|
||||
true
|
||||
""
|
||||
},
|
||||
//also temporary @JK
|
||||
{
|
||||
"fadeOut",
|
||||
&luascriptfunctions::fadeOut,
|
||||
"number",
|
||||
"",
|
||||
true
|
||||
""
|
||||
},
|
||||
{
|
||||
"registerScreenSpaceRenderable",
|
||||
@@ -1334,6 +1331,45 @@ void RenderEngine::renderInformation() {
|
||||
break;
|
||||
}
|
||||
|
||||
network::Status status = OsEng.parallelConnection().status();
|
||||
size_t nConnections = OsEng.parallelConnection().nConnections();
|
||||
const std::string& hostName = OsEng.parallelConnection().hostName();
|
||||
|
||||
std::string connectionInfo = "";
|
||||
int nClients = nConnections;
|
||||
if (status == network::Status::Host) {
|
||||
nClients--;
|
||||
if (nClients == 1) {
|
||||
connectionInfo = "Hosting session with 1 client";
|
||||
} else {
|
||||
connectionInfo = "Hosting session with " + std::to_string(nClients) + " clients";
|
||||
}
|
||||
} else if (status == network::Status::ClientWithHost) {
|
||||
nClients--;
|
||||
connectionInfo = "Session hosted by '" + hostName + "'";
|
||||
} else if (status == network::Status::ClientWithoutHost) {
|
||||
connectionInfo = "Host is disconnected";
|
||||
}
|
||||
|
||||
if (status == network::Status::ClientWithHost || status == network::Status::ClientWithoutHost) {
|
||||
connectionInfo += "\n";
|
||||
if (nClients > 2) {
|
||||
connectionInfo += "You and " + std::to_string(nClients - 1) + " more clients are tuned in";
|
||||
} else if (nClients == 2) {
|
||||
connectionInfo += "You and " + std::to_string(nClients - 1) + " more client are tuned in";
|
||||
} else if (nClients == 1) {
|
||||
connectionInfo += "You are the only client";
|
||||
}
|
||||
}
|
||||
|
||||
if (connectionInfo != "") {
|
||||
RenderFontCr(*_fontInfo,
|
||||
penPosition,
|
||||
connectionInfo.c_str()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
#ifdef OPENSPACE_MODULE_NEWHORIZONS_ENABLED
|
||||
bool hasNewHorizons = scene()->sceneGraphNode("NewHorizons");
|
||||
double currentTime = Time::ref().currentTime();
|
||||
|
||||
@@ -137,7 +137,7 @@ ScreenSpaceRenderable::ScreenSpaceRenderable(const ghoul::Dictionary& dictionary
|
||||
_delete.onChange([this](){
|
||||
std::string script =
|
||||
"openspace.unregisterScreenSpaceRenderable('" + name() + "');";
|
||||
OsEng.scriptEngine().queueScript(script);
|
||||
OsEng.scriptEngine().queueScript(script, scripting::ScriptEngine::RemoteScripting::Yes);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -467,7 +467,6 @@ scripting::LuaLibrary Scene::luaLibrary() {
|
||||
"Sets a property identified by the URI in "
|
||||
"the first argument. The second argument can be any type, but it has to "
|
||||
"match the type that the property expects.",
|
||||
true
|
||||
},
|
||||
{
|
||||
"getPropertyValue",
|
||||
|
||||
@@ -156,16 +156,7 @@ bool ScriptEngine::runScript(const std::string& script) {
|
||||
LERRORC(e.component, e.message);
|
||||
return false;
|
||||
}
|
||||
|
||||
// if we're currently hosting the parallel session, find out if script should be synchronized.
|
||||
if (OsEng.parallelConnection().isHost()) {
|
||||
std::string lib, func;
|
||||
if (parseLibraryAndFunctionNames(lib, func, script) && shouldScriptBeSent(lib, func)){
|
||||
OsEng.parallelConnection().sendScript(script);
|
||||
// cacheScript(lib, func, script);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -194,7 +185,7 @@ bool ScriptEngine::runScriptFile(const std::string& filename) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ScriptEngine::shouldScriptBeSent(const std::string& library, const std::string& function) {
|
||||
/*bool ScriptEngine::shouldScriptBeSent(const std::string& library, const std::string& function) {
|
||||
std::set<LuaLibrary>::const_iterator libit;
|
||||
for (libit = _registeredLibraries.cbegin();
|
||||
libit != _registeredLibraries.cend();
|
||||
@@ -219,9 +210,9 @@ bool ScriptEngine::shouldScriptBeSent(const std::string& library, const std::str
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}*/
|
||||
|
||||
void ScriptEngine::cacheScript(const std::string &library, const std::string &function, const std::string &script){
|
||||
/*void ScriptEngine::cacheScript(const std::string &library, const std::string &function, const std::string &script){
|
||||
_cachedScriptsMutex.lock();
|
||||
_cachedScripts[library][function] = script;
|
||||
_cachedScriptsMutex.unlock();
|
||||
@@ -246,8 +237,9 @@ std::vector<std::string> ScriptEngine::cachedScripts(){
|
||||
_cachedScriptsMutex.unlock();
|
||||
|
||||
return retVal;
|
||||
}
|
||||
}*/
|
||||
|
||||
/*
|
||||
bool ScriptEngine::parseLibraryAndFunctionNames(std::string &library, std::string &function, const std::string &script){
|
||||
|
||||
//"deconstruct the script to find library and function name
|
||||
@@ -289,7 +281,7 @@ bool ScriptEngine::parseLibraryAndFunctionNames(std::string &library, std::strin
|
||||
//if we found a function all is good
|
||||
return !function.empty();
|
||||
}
|
||||
|
||||
*/
|
||||
bool ScriptEngine::isLibraryNameAllowed(lua_State* state, const std::string& name) {
|
||||
bool result = false;
|
||||
lua_getglobal(state, _openspaceLibraryName.c_str());
|
||||
@@ -665,23 +657,30 @@ void ScriptEngine::preSynchronization() {
|
||||
_mutex.lock();
|
||||
|
||||
if (!_queuedScripts.empty()){
|
||||
_currentSyncedScript = _queuedScripts.back();
|
||||
_queuedScripts.pop_back();
|
||||
_currentSyncedScript = _queuedScripts.back().first;
|
||||
bool remoteScripting = _queuedScripts.back().second;
|
||||
|
||||
|
||||
//Not really a received script but the master also needs to run the script...
|
||||
_receivedScripts.push_back(_currentSyncedScript);
|
||||
_queuedScripts.pop_back();
|
||||
|
||||
if (OsEng.parallelConnection().isHost() && remoteScripting) {
|
||||
OsEng.parallelConnection().sendScript(_currentSyncedScript);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
_mutex.unlock();
|
||||
}
|
||||
|
||||
void ScriptEngine::queueScript(const std::string &script){
|
||||
void ScriptEngine::queueScript(const std::string &script, ScriptEngine::RemoteScripting remoteScripting){
|
||||
if (script.empty())
|
||||
return;
|
||||
|
||||
_mutex.lock();
|
||||
|
||||
_queuedScripts.insert(_queuedScripts.begin(), script);
|
||||
_queuedScripts.insert(_queuedScripts.begin(), std::make_pair(script, remoteScripting));
|
||||
|
||||
_mutex.unlock();
|
||||
}
|
||||
|
||||
@@ -249,8 +249,7 @@ scripting::LuaLibrary Time::luaLibrary() {
|
||||
&luascriptfunctions::time_setDeltaTime,
|
||||
"number",
|
||||
"Sets the amount of simulation time that happens "
|
||||
"in one second of real time",
|
||||
true
|
||||
"in one second of real time"
|
||||
},
|
||||
{
|
||||
"deltaTime",
|
||||
@@ -263,16 +262,14 @@ scripting::LuaLibrary Time::luaLibrary() {
|
||||
"setPause",
|
||||
&luascriptfunctions::time_setPause,
|
||||
"bool",
|
||||
"Pauses the simulation time or restores the delta time",
|
||||
true
|
||||
"Pauses the simulation time or restores the delta time"
|
||||
},
|
||||
{
|
||||
"togglePause",
|
||||
&luascriptfunctions::time_togglePause,
|
||||
"",
|
||||
"Toggles the pause function, i.e. temporarily setting the delta time to 0"
|
||||
" and restoring it afterwards",
|
||||
true
|
||||
" and restoring it afterwards"
|
||||
},
|
||||
{
|
||||
"setTime",
|
||||
@@ -281,8 +278,7 @@ scripting::LuaLibrary Time::luaLibrary() {
|
||||
"Sets the current simulation time to the "
|
||||
"specified value. If the parameter is a number, the value is the number "
|
||||
"of seconds past the J2000 epoch. If it is a string, it has to be a "
|
||||
"valid ISO 8601 date string (YYYY-MM-DDTHH:MN:SS)",
|
||||
true
|
||||
"valid ISO 8601 date string (YYYY-MM-DDTHH:MN:SS)"
|
||||
},
|
||||
{
|
||||
"currentTime",
|
||||
|
||||
Reference in New Issue
Block a user