PICloud Dispatcher screen mode
This commit is contained in:
@@ -124,12 +124,12 @@ bool TileScrollBar::mouseEvent(PIKbdListener::MouseEvent me) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
TileList::TileList(const PIString & n): PIScreenTile(n) {
|
TileList::TileList(const PIString & n, SelectionMode sm): PIScreenTile(n) {
|
||||||
alignment = Left;
|
alignment = Left;
|
||||||
focus_flags = CanHasFocus | NextByArrowsHorizontal | NextByTab | FocusOnMouseOrWheel;
|
focus_flags = CanHasFocus | NextByArrowsHorizontal | NextByTab | FocusOnMouseOrWheel;
|
||||||
lhei = offset = cur = 0;
|
lhei = offset = cur = 0;
|
||||||
mouse_sel = false;
|
mouse_sel = false;
|
||||||
selection_mode = NoSelection;
|
selection_mode = sm;
|
||||||
scroll = new TileScrollBar();
|
scroll = new TileScrollBar();
|
||||||
scroll->size_policy = Ignore;
|
scroll->size_policy = Ignore;
|
||||||
addTile(scroll);
|
addTile(scroll);
|
||||||
|
|||||||
@@ -70,8 +70,6 @@ protected:
|
|||||||
class PIP_CONSOLE_EXPORT TileList: public PIScreenTile {
|
class PIP_CONSOLE_EXPORT TileList: public PIScreenTile {
|
||||||
PIOBJECT_SUBCLASS(TileList, PIScreenTile)
|
PIOBJECT_SUBCLASS(TileList, PIScreenTile)
|
||||||
public:
|
public:
|
||||||
TileList(const PIString & n = PIString());
|
|
||||||
virtual ~TileList() {}
|
|
||||||
enum SelectionMode {
|
enum SelectionMode {
|
||||||
NoSelection,
|
NoSelection,
|
||||||
SingleSelection,
|
SingleSelection,
|
||||||
@@ -81,6 +79,10 @@ public:
|
|||||||
SelectionChanged,
|
SelectionChanged,
|
||||||
RowPressed
|
RowPressed
|
||||||
};
|
};
|
||||||
|
|
||||||
|
TileList(const PIString & n = PIString(), SelectionMode sm = NoSelection);
|
||||||
|
virtual ~TileList() {}
|
||||||
|
|
||||||
typedef PIPair<PIString, PIScreenTypes::CellFormat> Row;
|
typedef PIPair<PIString, PIScreenTypes::CellFormat> Row;
|
||||||
PIDeque<Row> content;
|
PIDeque<Row> content;
|
||||||
PIScreenTypes::Alignment alignment;
|
PIScreenTypes::Alignment alignment;
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ set(PIP_UTILS_LIST ${PIP_UTILS_LIST} PARENT_SCOPE)
|
|||||||
file(GLOB CPPS "*.cpp")
|
file(GLOB CPPS "*.cpp")
|
||||||
file(GLOB HDRS "*.h")
|
file(GLOB HDRS "*.h")
|
||||||
add_executable(picloud ${CPPS} ${HDRS})
|
add_executable(picloud ${CPPS} ${HDRS})
|
||||||
target_link_libraries(picloud pip pip_cloud)
|
target_link_libraries(picloud pip pip_cloud pip_console)
|
||||||
if (DEFINED LIB)
|
if (DEFINED LIB)
|
||||||
install(TARGETS picloud DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
|
install(TARGETS picloud DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
|
||||||
else()
|
else()
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ public:
|
|||||||
void removeClient(DispatcherClient * c);
|
void removeClient(DispatcherClient * c);
|
||||||
PIVector<DispatcherClient*> getClients();
|
PIVector<DispatcherClient*> getClients();
|
||||||
EVENT_HANDLER0(void, printStatus);
|
EVENT_HANDLER0(void, printStatus);
|
||||||
|
const DispatcherClient * getConnection() const {return server;}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DispatcherClient * server;
|
DispatcherClient * server;
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ public:
|
|||||||
void sendData(const PIByteArray & data);
|
void sendData(const PIByteArray & data);
|
||||||
void sendDataToClient(const PIByteArray & data, uint client_id);
|
void sendDataToClient(const PIByteArray & data, uint client_id);
|
||||||
void authorise(bool ok);
|
void authorise(bool ok);
|
||||||
|
bool isAuthorised() const {return authorised;}
|
||||||
|
PICloud::TCP::Role role() const {return tcp.role();}
|
||||||
PIString address();
|
PIString address();
|
||||||
uint clientId() const {return client_id;}
|
uint clientId() const {return client_id;}
|
||||||
EVENT1(disconnectEvent, DispatcherClient *, client)
|
EVENT1(disconnectEvent, DispatcherClient *, client)
|
||||||
|
|||||||
@@ -1,16 +1,13 @@
|
|||||||
#include "dispatcherserver.h"
|
#include "dispatcherserver.h"
|
||||||
|
#include "piscreentiles.h"
|
||||||
|
|
||||||
|
|
||||||
DispatcherServer::DispatcherServer(PIEthernet::Address addr) : eth(PIEthernet::TCP_Server) {
|
DispatcherServer::DispatcherServer(PIEthernet::Address addr) : eth(PIEthernet::TCP_Server) {
|
||||||
client_gid = 0;
|
client_gid = 0;
|
||||||
eth.setParameter(PIEthernet::ReuseAddress);
|
eth.setParameter(PIEthernet::ReuseAddress);
|
||||||
|
eth.setReadAddress(addr);
|
||||||
CONNECTU(ð, newConnection, this, newConnection);
|
CONNECTU(ð, newConnection, this, newConnection);
|
||||||
eth.listen(addr, true);
|
|
||||||
piCoutObj << "server started" << addr;
|
|
||||||
CONNECTU(&status_timer, tickEvent, this, printStatus);
|
|
||||||
CONNECTU(&timeout_timer, tickEvent, this, cleanClients);
|
CONNECTU(&timeout_timer, tickEvent, this, cleanClients);
|
||||||
status_timer.start(1000);
|
|
||||||
timeout_timer.start(5000);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -20,6 +17,30 @@ DispatcherServer::~DispatcherServer() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DispatcherServer::start() {
|
||||||
|
eth.listen(true);
|
||||||
|
timeout_timer.start(5000);
|
||||||
|
piCoutObj << "server started" << eth.readAddress();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DispatcherServer::picoutStatus() {
|
||||||
|
map_mutex.lock();
|
||||||
|
piCout << PICoutManipulators::NewLine;
|
||||||
|
piCout << "Connections:";
|
||||||
|
for (auto c: clients) {
|
||||||
|
piCout << " " << c->address();
|
||||||
|
}
|
||||||
|
piCout << "Servers:";
|
||||||
|
auto it = c_servers.makeIterator();
|
||||||
|
while(it.next()){
|
||||||
|
piCout << " " << it.key();
|
||||||
|
it.value()->printStatus();
|
||||||
|
}
|
||||||
|
map_mutex.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void DispatcherServer::cleanClients() {
|
void DispatcherServer::cleanClients() {
|
||||||
PIVector<DispatcherClient*> rm;
|
PIVector<DispatcherClient*> rm;
|
||||||
map_mutex.lock();
|
map_mutex.lock();
|
||||||
@@ -40,23 +61,94 @@ void DispatcherServer::cleanClients() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DispatcherServer::printStatus() {
|
void DispatcherServer::updateConnectionsTile(TileList * tl) {
|
||||||
map_mutex.lock();
|
map_mutex.lock();
|
||||||
piCout << PICoutManipulators::NewLine;
|
tl->content.clear();
|
||||||
piCout << "Connections:";
|
|
||||||
for (auto c: clients) {
|
for (auto c: clients) {
|
||||||
piCout << " " << c->address();
|
PIString role = "Invalid";
|
||||||
|
switch (c->role()) {
|
||||||
|
case PICloud::TCP::Client : {
|
||||||
|
role = "Client";
|
||||||
|
CloudServer * cs = index_c_clients.value(c, nullptr);
|
||||||
|
if (cs) role += " \"" + cs->serverName() + "\"";
|
||||||
|
} break;
|
||||||
|
case PICloud::TCP::Server : {
|
||||||
|
role = "Server";
|
||||||
|
CloudServer * cs = index_c_servers.value(c, nullptr);
|
||||||
|
if (cs) role += " \"" + cs->serverName() + "\"";
|
||||||
|
} break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
piCout << "Servers:";
|
tl->content << TileList::Row(c->address() + " " + role, PIScreenTypes::CellFormat());
|
||||||
auto it = c_servers.makeIterator();
|
|
||||||
while(it.next()){
|
|
||||||
piCout << " " << it.key();
|
|
||||||
it.value()->printStatus();
|
|
||||||
}
|
}
|
||||||
map_mutex.unlock();
|
map_mutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DispatcherServer::updateServersTile(TileList * tl, PISet<const DispatcherClient *> servers) {
|
||||||
|
map_mutex.lock();
|
||||||
|
tl->content.clear();
|
||||||
|
auto mi = c_servers.makeIterator();
|
||||||
|
while (mi.next()) {
|
||||||
|
tl->content << TileList::Row(mi.value()->serverName() + " - " + PIString::fromNumber(mi.value()->getClients().size()), PIScreenTypes::CellFormat());
|
||||||
|
if (servers.contains(mi.value()->getConnection())) tl->selected << (tl->content.size_s() - 1);
|
||||||
|
}
|
||||||
|
map_mutex.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DispatcherServer::updateClientsTile(TileList * tl, PISet<const DispatcherClient *> servers) {
|
||||||
|
map_mutex.lock();
|
||||||
|
tl->content.clear();
|
||||||
|
auto mi = c_servers.makeIterator();
|
||||||
|
while (mi.next()) {
|
||||||
|
for (auto c : mi.value()->getClients()) {
|
||||||
|
if (servers.isEmpty() || servers.contains(mi.value()->getConnection()))
|
||||||
|
tl->content << TileList::Row(c->address(), PIScreenTypes::CellFormat());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
map_mutex.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const DispatcherClient * DispatcherServer::getConnection(int index) {
|
||||||
|
const DispatcherClient * ret = nullptr;
|
||||||
|
map_mutex.lock();
|
||||||
|
if (index >=0 && index < clients.size_s()) ret = clients[index];
|
||||||
|
map_mutex.unlock();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const DispatcherClient * DispatcherServer::getServer(int index) {
|
||||||
|
const DispatcherClient * ret = nullptr;
|
||||||
|
const DispatcherClient * tmp;
|
||||||
|
map_mutex.lock();
|
||||||
|
if (index >=0 && index < clients.size_s()) {
|
||||||
|
tmp = clients[index];
|
||||||
|
}
|
||||||
|
if (index_c_servers.contains(tmp)) ret = tmp;
|
||||||
|
map_mutex.unlock();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PISet<const DispatcherClient *> DispatcherServer::getServers(PISet<int> ids) {
|
||||||
|
PISet<const DispatcherClient *> ret;
|
||||||
|
if (ids.isEmpty()) return ret;
|
||||||
|
map_mutex.lock();
|
||||||
|
int i = 0;
|
||||||
|
auto mi = c_servers.makeIterator();
|
||||||
|
while (mi.next()) {
|
||||||
|
if (ids.contains(i)) ret << mi.value()->getConnection();
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
map_mutex.unlock();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void DispatcherServer::disconnectClient(DispatcherClient *client) {
|
void DispatcherServer::disconnectClient(DispatcherClient *client) {
|
||||||
if (!clients.contains(client)) {
|
if (!clients.contains(client)) {
|
||||||
//piCoutObj << "INVALID client" << client;
|
//piCoutObj << "INVALID client" << client;
|
||||||
|
|||||||
@@ -3,13 +3,23 @@
|
|||||||
|
|
||||||
#include "cloudserver.h"
|
#include "cloudserver.h"
|
||||||
|
|
||||||
|
class TileList;
|
||||||
|
|
||||||
|
|
||||||
class DispatcherServer: public PIObject {
|
class DispatcherServer: public PIObject {
|
||||||
PIOBJECT(DispatcherServer)
|
PIOBJECT(DispatcherServer)
|
||||||
public:
|
public:
|
||||||
DispatcherServer(PIEthernet::Address addr);
|
DispatcherServer(PIEthernet::Address addr);
|
||||||
~DispatcherServer();
|
~DispatcherServer();
|
||||||
EVENT_HANDLER0(void, printStatus);
|
void start();
|
||||||
|
|
||||||
|
void updateConnectionsTile(TileList * tl);
|
||||||
|
void updateServersTile(TileList * tl, PISet<const DispatcherClient *> servers = PISet<const DispatcherClient *>());
|
||||||
|
void updateClientsTile(TileList * tl, PISet<const DispatcherClient *> servers = PISet<const DispatcherClient *>());
|
||||||
|
const DispatcherClient * getConnection(int index);
|
||||||
|
const DispatcherClient * getServer(int index);
|
||||||
|
PISet<const DispatcherClient *> getServers(PISet<int> ids);
|
||||||
|
EVENT_HANDLER0(void, picoutStatus);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
EVENT_HANDLER1(void, newConnection, PIEthernet * , cl);
|
EVENT_HANDLER1(void, newConnection, PIEthernet * , cl);
|
||||||
@@ -22,7 +32,6 @@ private:
|
|||||||
PIMap<const DispatcherClient *, CloudServer *> index_c_servers;
|
PIMap<const DispatcherClient *, CloudServer *> index_c_servers;
|
||||||
PIMap<const DispatcherClient *, CloudServer *> index_c_clients;
|
PIMap<const DispatcherClient *, CloudServer *> index_c_clients;
|
||||||
PIVector<DispatcherClient*> rm_clients;
|
PIVector<DispatcherClient*> rm_clients;
|
||||||
PITimer status_timer;
|
|
||||||
PITimer timeout_timer;
|
PITimer timeout_timer;
|
||||||
PIMutex map_mutex;
|
PIMutex map_mutex;
|
||||||
uint client_gid;
|
uint client_gid;
|
||||||
|
|||||||
@@ -24,39 +24,98 @@
|
|||||||
|
|
||||||
using namespace PICoutManipulators;
|
using namespace PICoutManipulators;
|
||||||
|
|
||||||
PIEthernet::Address addr = PIEthernet::Address("0.0.0.0", 10101);
|
|
||||||
|
|
||||||
void usage() {
|
void usage() {
|
||||||
piCout << Bold << "PIP Cloud Dispatcher";
|
piCout << Bold << "PIP Cloud Dispatcher";
|
||||||
piCout << Cyan << "Version" << Bold << PIPVersion() << NewLine;
|
piCout << Cyan << "Version" << Bold << PIPVersion() << NewLine;
|
||||||
piCout << Green << Bold << "Usage:" << Default << "\"picloud [-h] [-i <ip>] [-p <port>]\"" << NewLine;
|
piCout << Green << Bold << "Usage:" << Default << "\"picloud [-hsv] [-i <ip>] [-p <port>]\"" << NewLine;
|
||||||
piCout << Green << Bold << "Details:";
|
piCout << Green << Bold << "Details:";
|
||||||
piCout << "-h --help " << Green << "- display this message and exit";
|
piCout << "-h --help " << Green << "- display this message and exit";
|
||||||
piCout << "-i --ip " << Green << "- listen address, default \"0.0.0.0\"";
|
piCout << "-i --ip " << Green << "- listen address, default \"0.0.0.0\"";
|
||||||
piCout << "-p --port " << Green << "- listen port, default 10101";
|
piCout << "-p --port " << Green << "- listen port, default 10101";
|
||||||
|
piCout << "-s --screen " << Green << "- start with console UI";
|
||||||
|
piCout << "-v --verbose" << Green << "- print state (--screen ignore this flag)";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int main (int argc, char * argv[]) {
|
int main (int argc, char * argv[]) {
|
||||||
PICrypt::hash("");
|
|
||||||
PICLI cli(argc, argv);
|
PICLI cli(argc, argv);
|
||||||
cli.addArgument("help");
|
cli.addArgument("help");
|
||||||
cli.addArgument("ip", true);
|
cli.addArgument("ip", true);
|
||||||
cli.addArgument("port", true);
|
cli.addArgument("port", true);
|
||||||
|
cli.addArgument("screen");
|
||||||
|
cli.addArgument("verbose");
|
||||||
|
|
||||||
if (cli.hasArgument("help")) {
|
if (cli.hasArgument("help")) {
|
||||||
usage();
|
usage();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
PITimer status_timer;
|
||||||
|
PIEthernet::Address addr = PIEthernet::Address("0.0.0.0", 10101);
|
||||||
if (cli.hasArgument("ip"))
|
if (cli.hasArgument("ip"))
|
||||||
addr.setIP(cli.argumentValue("ip"));
|
addr.setIP(cli.argumentValue("ip"));
|
||||||
if (cli.hasArgument("port"))
|
if (cli.hasArgument("port"))
|
||||||
addr.setPort(cli.argumentValue("port").toInt());
|
addr.setPort(cli.argumentValue("port").toInt());
|
||||||
DispatcherServer server(addr);
|
DispatcherServer server(addr);
|
||||||
|
if (cli.hasArgument("screen")) {
|
||||||
|
PISet<const DispatcherClient *> sel_servers;
|
||||||
|
PIScreen screen(false);
|
||||||
|
PIScreenTile maintile("PICloud Dispatcher", PIScreenTypes::Horizontal, PIScreenTypes::Expanding);
|
||||||
|
PIScreenTile tls[3];
|
||||||
|
TileList conn_tl(PIString(), TileList::MultiSelection);
|
||||||
|
TileList server_tl(PIString(), TileList::MultiSelection);
|
||||||
|
TileList client_tl(PIString(), TileList::MultiSelection);
|
||||||
|
tls[0].addTile(new TileSimple(TileSimple::Row("Connections", PIScreenTypes::CellFormat(PIScreenTypes::Default, PIScreenTypes::Default, PIScreenTypes::Inverse))));
|
||||||
|
tls[0].addTile(&conn_tl);
|
||||||
|
tls[1].addTile(new TileSimple(TileSimple::Row("Servers", PIScreenTypes::CellFormat(PIScreenTypes::Default, PIScreenTypes::Default, PIScreenTypes::Inverse))));
|
||||||
|
tls[1].addTile(&server_tl);
|
||||||
|
tls[2].addTile(new TileSimple(TileSimple::Row("Clients", PIScreenTypes::CellFormat(PIScreenTypes::Default, PIScreenTypes::Default, PIScreenTypes::Inverse))));
|
||||||
|
tls[2].addTile(&client_tl);
|
||||||
|
CONNECTL(&screen, tileEvent, ([&](PIScreenTile * t, PIScreenTypes::TileEvent e){
|
||||||
|
if (t == (PIScreenTile *)&server_tl) {
|
||||||
|
if (e.type == TileList::SelectionChanged) {
|
||||||
|
sel_servers = server.getServers(server_tl.selected);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (t == (PIScreenTile *)&conn_tl) {
|
||||||
|
if (e.type == TileList::RowPressed) {
|
||||||
|
sel_servers.clear();
|
||||||
|
server_tl.selected.clear();
|
||||||
|
const DispatcherClient * dc = server.getServer(e.data.toInt());
|
||||||
|
if (dc) sel_servers << dc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
for (auto & a : tls) {
|
||||||
|
a.children()[0]->size_policy = PIScreenTypes::Fixed;
|
||||||
|
maintile.addTile(&a);
|
||||||
|
}
|
||||||
|
CONNECTL(&status_timer, tickEvent, [&](void *, int){
|
||||||
|
screen.lock();
|
||||||
|
server.updateConnectionsTile(&conn_tl);
|
||||||
|
server.updateServersTile(&server_tl, sel_servers);
|
||||||
|
server.updateClientsTile(&client_tl, server.getServers(server_tl.selected));
|
||||||
|
screen.unlock();
|
||||||
|
});
|
||||||
|
screen.enableExitCapture(PIKbdListener::F10);
|
||||||
|
screen.rootTile()->addTile(new TileSimple(TileSimple::Row("PICloud Dispatcher " + addr.toString(), PIScreenTypes::CellFormat(PIScreenTypes::Yellow, PIScreenTypes::Default, PIScreenTypes::Bold))));
|
||||||
|
screen.rootTile()->addTile(&maintile);
|
||||||
|
screen.rootTile()->addTile(new TilePICout());
|
||||||
|
screen.start();
|
||||||
|
server.start();
|
||||||
|
status_timer.start(100);
|
||||||
|
screen.waitForFinish();
|
||||||
|
} else {
|
||||||
PIKbdListener ls;
|
PIKbdListener ls;
|
||||||
ls.enableExitCapture(PIKbdListener::F10);
|
ls.enableExitCapture(PIKbdListener::F10);
|
||||||
ls.start();
|
ls.start();
|
||||||
|
server.start();
|
||||||
|
if (cli.hasArgument("verbose")) {
|
||||||
|
CONNECTU(&status_timer, tickEvent, &server, picoutStatus);
|
||||||
|
status_timer.start(1000);
|
||||||
|
}
|
||||||
WAIT_FOR_EXIT
|
WAIT_FOR_EXIT
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user