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;
|
||||
focus_flags = CanHasFocus | NextByArrowsHorizontal | NextByTab | FocusOnMouseOrWheel;
|
||||
lhei = offset = cur = 0;
|
||||
mouse_sel = false;
|
||||
selection_mode = NoSelection;
|
||||
selection_mode = sm;
|
||||
scroll = new TileScrollBar();
|
||||
scroll->size_policy = Ignore;
|
||||
addTile(scroll);
|
||||
|
||||
@@ -70,8 +70,6 @@ protected:
|
||||
class PIP_CONSOLE_EXPORT TileList: public PIScreenTile {
|
||||
PIOBJECT_SUBCLASS(TileList, PIScreenTile)
|
||||
public:
|
||||
TileList(const PIString & n = PIString());
|
||||
virtual ~TileList() {}
|
||||
enum SelectionMode {
|
||||
NoSelection,
|
||||
SingleSelection,
|
||||
@@ -81,6 +79,10 @@ public:
|
||||
SelectionChanged,
|
||||
RowPressed
|
||||
};
|
||||
|
||||
TileList(const PIString & n = PIString(), SelectionMode sm = NoSelection);
|
||||
virtual ~TileList() {}
|
||||
|
||||
typedef PIPair<PIString, PIScreenTypes::CellFormat> Row;
|
||||
PIDeque<Row> content;
|
||||
PIScreenTypes::Alignment alignment;
|
||||
|
||||
@@ -3,7 +3,7 @@ set(PIP_UTILS_LIST ${PIP_UTILS_LIST} PARENT_SCOPE)
|
||||
file(GLOB CPPS "*.cpp")
|
||||
file(GLOB HDRS "*.h")
|
||||
add_executable(picloud ${CPPS} ${HDRS})
|
||||
target_link_libraries(picloud pip pip_cloud)
|
||||
target_link_libraries(picloud pip pip_cloud pip_console)
|
||||
if (DEFINED LIB)
|
||||
install(TARGETS picloud DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
|
||||
else()
|
||||
|
||||
@@ -14,6 +14,7 @@ public:
|
||||
void removeClient(DispatcherClient * c);
|
||||
PIVector<DispatcherClient*> getClients();
|
||||
EVENT_HANDLER0(void, printStatus);
|
||||
const DispatcherClient * getConnection() const {return server;}
|
||||
|
||||
private:
|
||||
DispatcherClient * server;
|
||||
|
||||
@@ -18,6 +18,8 @@ public:
|
||||
void sendData(const PIByteArray & data);
|
||||
void sendDataToClient(const PIByteArray & data, uint client_id);
|
||||
void authorise(bool ok);
|
||||
bool isAuthorised() const {return authorised;}
|
||||
PICloud::TCP::Role role() const {return tcp.role();}
|
||||
PIString address();
|
||||
uint clientId() const {return client_id;}
|
||||
EVENT1(disconnectEvent, DispatcherClient *, client)
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
#include "dispatcherserver.h"
|
||||
#include "piscreentiles.h"
|
||||
|
||||
|
||||
DispatcherServer::DispatcherServer(PIEthernet::Address addr) : eth(PIEthernet::TCP_Server) {
|
||||
client_gid = 0;
|
||||
eth.setParameter(PIEthernet::ReuseAddress);
|
||||
eth.setReadAddress(addr);
|
||||
CONNECTU(ð, newConnection, this, newConnection);
|
||||
eth.listen(addr, true);
|
||||
piCoutObj << "server started" << addr;
|
||||
CONNECTU(&status_timer, tickEvent, this, printStatus);
|
||||
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() {
|
||||
PIVector<DispatcherClient*> rm;
|
||||
map_mutex.lock();
|
||||
@@ -40,23 +61,94 @@ void DispatcherServer::cleanClients() {
|
||||
}
|
||||
|
||||
|
||||
void DispatcherServer::printStatus() {
|
||||
void DispatcherServer::updateConnectionsTile(TileList * tl) {
|
||||
map_mutex.lock();
|
||||
piCout << PICoutManipulators::NewLine;
|
||||
piCout << "Connections:";
|
||||
tl->content.clear();
|
||||
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:";
|
||||
auto it = c_servers.makeIterator();
|
||||
while(it.next()){
|
||||
piCout << " " << it.key();
|
||||
it.value()->printStatus();
|
||||
tl->content << TileList::Row(c->address() + " " + role, PIScreenTypes::CellFormat());
|
||||
}
|
||||
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) {
|
||||
if (!clients.contains(client)) {
|
||||
//piCoutObj << "INVALID client" << client;
|
||||
|
||||
@@ -3,13 +3,23 @@
|
||||
|
||||
#include "cloudserver.h"
|
||||
|
||||
class TileList;
|
||||
|
||||
|
||||
class DispatcherServer: public PIObject {
|
||||
PIOBJECT(DispatcherServer)
|
||||
public:
|
||||
DispatcherServer(PIEthernet::Address addr);
|
||||
~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:
|
||||
EVENT_HANDLER1(void, newConnection, PIEthernet * , cl);
|
||||
@@ -22,7 +32,6 @@ private:
|
||||
PIMap<const DispatcherClient *, CloudServer *> index_c_servers;
|
||||
PIMap<const DispatcherClient *, CloudServer *> index_c_clients;
|
||||
PIVector<DispatcherClient*> rm_clients;
|
||||
PITimer status_timer;
|
||||
PITimer timeout_timer;
|
||||
PIMutex map_mutex;
|
||||
uint client_gid;
|
||||
|
||||
@@ -24,39 +24,98 @@
|
||||
|
||||
using namespace PICoutManipulators;
|
||||
|
||||
PIEthernet::Address addr = PIEthernet::Address("0.0.0.0", 10101);
|
||||
|
||||
void usage() {
|
||||
piCout << Bold << "PIP Cloud Dispatcher";
|
||||
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 << "-h --help " << Green << "- display this message and exit";
|
||||
piCout << "-i --ip " << Green << "- listen address, default \"0.0.0.0\"";
|
||||
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[]) {
|
||||
PICrypt::hash("");
|
||||
PICLI cli(argc, argv);
|
||||
cli.addArgument("help");
|
||||
cli.addArgument("ip", true);
|
||||
cli.addArgument("port", true);
|
||||
cli.addArgument("screen");
|
||||
cli.addArgument("verbose");
|
||||
|
||||
if (cli.hasArgument("help")) {
|
||||
usage();
|
||||
return 0;
|
||||
}
|
||||
PITimer status_timer;
|
||||
PIEthernet::Address addr = PIEthernet::Address("0.0.0.0", 10101);
|
||||
if (cli.hasArgument("ip"))
|
||||
addr.setIP(cli.argumentValue("ip"));
|
||||
if (cli.hasArgument("port"))
|
||||
addr.setPort(cli.argumentValue("port").toInt());
|
||||
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;
|
||||
ls.enableExitCapture(PIKbdListener::F10);
|
||||
ls.start();
|
||||
server.start();
|
||||
if (cli.hasArgument("verbose")) {
|
||||
CONNECTU(&status_timer, tickEvent, &server, picoutStatus);
|
||||
status_timer.start(1000);
|
||||
}
|
||||
WAIT_FOR_EXIT
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user