Skip to content

Commit

Permalink
Gloom|GloomEd: Set up IPC between editor and viewer using UDP
Browse files Browse the repository at this point in the history
  • Loading branch information
skyjake committed Sep 1, 2019
1 parent 916a450 commit a1a241c
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 13 deletions.
30 changes: 27 additions & 3 deletions doomsday/apps/gloom/src/gloomapp.cpp
Expand Up @@ -25,18 +25,24 @@

#include <doomsday/DataBundle>

#include <de/Beacon>
#include <de/DisplayMode>
#include <de/FileSystem>
#include <de/PackageLoader>
#include <de/ScriptSystem>

#include <c_plus/datagram.h>

using namespace de;
using namespace gloom;

static const duint16 COMMAND_PORT = 14666;

DE_PIMPL(GloomApp)
{
ImageBank images;
// std::unique_ptr<EditorWindow> editWin;
cplus::ref<iDatagram> commandSocket;
Beacon beacon{{COMMAND_PORT, COMMAND_PORT + 4}};
std::unique_ptr<AppWindowSystem> winSys;
std::unique_ptr<AudioSystem> audioSys;
std::unique_ptr<GloomWorld> world;
Expand All @@ -46,12 +52,30 @@ DE_PIMPL(GloomApp)
// We will be accessing data bundles (WADs).
static DataBundle::Interpreter intrpDataBundle;
FileSystem::get().addInterpreter(intrpDataBundle);

// GloomEd will tell us what to do via the command socket.
commandSocket.reset(new_Datagram());
for (int attempt = 0; attempt < 12; ++attempt)
{
if (open_Datagram(commandSocket, duint16(COMMAND_PORT + 4 + attempt)))
{
LOG_NET_NOTE("Listening to commands on port %u") << port_Datagram(commandSocket);
break;
}
}
if (!isOpen_Datagram(commandSocket))
{
throw Error("GloomApp::GloomApp",
"Failed to open socket for listening to commands from GloomEd");
}

beacon.setMessage(Stringf("GloomApp: port=%u", port_Datagram(commandSocket)));
beacon.start();
}

~Impl()
{
// Windows will be closed; OpenGL context will be gone.
// Deinitalize everything.
// Windows will be closed; OpenGL context will be gone. Deinitialize everything.
if (winSys->mainExists())
{
winSys->main().glActivate();
Expand Down
92 changes: 82 additions & 10 deletions doomsday/apps/gloomed/src/main.cpp
Expand Up @@ -18,35 +18,94 @@

#include "editorwindow.h"
#include "utils.h"
#include <de/App>
#include <de/Beacon>
#include <de/CommandLine>
#include <de/EventLoop>
#include <de/Loop>
#include <de/Info>
#include <QApplication>
#include <QMessageBox>
#include <QTimer>

using namespace de;

static iProcess *gloomProc = nullptr;
static const duint16 COMMAND_PORT = 14666;

struct GloomCommander : DE_OBSERVES(Beacon, Discovery)
{
cplus::ref<iProcess> proc;
Beacon beacon{{COMMAND_PORT, COMMAND_PORT + 4}};
Address address;

GloomCommander()
{
beacon.audienceForDiscovery() += this;
}

void beaconFoundHost(const Address &host, const Block &message) override
{
qDebug("GloomEd beacon found:%s [%s]", host.asText().c_str(), message.c_str());
if (message.beginsWith(DE_STR("GloomApp:")))
{
const Info msg(message.mid(9));
const duint16 commandPort = duint16(msg.root().keyValue("port").text.toInt());
qDebug("Viewer command port: %u", commandPort);

beacon.stop();
address = host;
}
}
};
static GloomCommander *gloomCommander;

static bool launchGloom()
{
if (gloomProc)
if (gloomCommander)
{
// Is it still running?
if (isRunning_Process(gloomProc))
if (gloomCommander->proc && isRunning_Process(gloomCommander->proc))
{
return true;
}
iRelease(gloomProc);
gloomProc = nullptr;
}
else
{
gloomCommander = new GloomCommander;
}

gloomCommander->beacon.discover(0.0, 0.5);

CommandLine cmd;
#if defined (MACOSX)
cmd << convert(qApp->applicationDirPath() + "/../../../Gloom.app/Contents/MacOS/Gloom");
#endif
gloomProc = cmd.executeProcess();
return gloomProc != nullptr;
gloomCommander->proc.reset(cmd.executeProcess());
return bool(gloomCommander->proc);
}

struct EmbeddedApp : public App
{
EventLoop deEventLoop{EventLoop::Manual};
Loop deLoop;

EmbeddedApp(const StringList &args) : App(args)
{}

NativePath appDataPath() const
{
return NativePath::homePath() / unixHomeFolderName();
}

void processEvents()
{
// Manually handle events and loop iteration callbacks.
deLoop.iterate();
deEventLoop.processQueuedEvents();
fflush(stdout);
fflush(stderr);
}
};

int main(int argc, char **argv)
{
QApplication app(argc, argv);
Expand All @@ -58,7 +117,7 @@ int main(int argc, char **argv)

EditorWindow win;

QObject::connect(&win.editor(), &Editor::buildMapRequested, [&app, &win]() {
QObject::connect(&win.editor(), &Editor::buildMapRequested, &win, [&win, &app]() {
try
{
// Export/update the map package.
Expand All @@ -80,5 +139,18 @@ int main(int argc, char **argv)
});

win.showNormal();
return app.exec();

/* We are not running a de::App, but some classes assume that the Loop/EventLoop are
* available and active. Use a QTimer to continually check for events and perform
* loop iteration.
*/
EmbeddedApp deApp(makeList(argc, argv));
deApp.initSubsystems(App::DisablePersistentData | App::DisablePlugins);
QTimer deTimer;
QObject::connect(&deTimer, &QTimer::timeout, [&deApp]() { deApp.processEvents(); });
deTimer.start(100);

int rc = app.exec();
delete gloomCommander;
return rc;
}

0 comments on commit a1a241c

Please sign in to comment.