Browse Source

*** empty log message ***

Dave Schuyler 24 years ago
parent
commit
cc8191fb07

+ 9 - 6
direct/src/directd/Sources.pp

@@ -2,18 +2,21 @@
 // This package presently only builds on Windows.
 // This package presently only builds on Windows.
 #define DIRECTORY_IF_WINDOWS yes
 #define DIRECTORY_IF_WINDOWS yes
 
 
-//#define LOCAL_LIBS \
-//    directbase
+#define LOCAL_LIBS \
+    directbase
 #define OTHER_LIBS \
 #define OTHER_LIBS \
     net:c linmath:c putil:c express:c panda:m pandaexpress:m dtoolconfig dtool
     net:c linmath:c putil:c express:c panda:m pandaexpress:m dtoolconfig dtool
 #define WIN_SYS_LIBS $[WIN_SYS_LIBS] user32.lib //advapi32.lib
 #define WIN_SYS_LIBS $[WIN_SYS_LIBS] user32.lib //advapi32.lib
 
 
-//#define C++FLAGS -DWITHIN_PANDA
-
-#begin bin_target
+#begin lib_target
   #define TARGET directd
   #define TARGET directd
 
 
   #define SOURCES \
   #define SOURCES \
     directd.h directd.cxx
     directd.h directd.cxx
+  
+  #define INSTALL_HEADERS \
+    directd.h
+
+  #define IGATESCAN directd.h
 
 
-#end bin_target
+#end lib_target

+ 233 - 183
direct/src/directd/directd.cxx

@@ -26,9 +26,9 @@
 //#include "pandabase.h"
 //#include "pandabase.h"
 
 
 //#include "queuedConnectionManager.h"
 //#include "queuedConnectionManager.h"
-#include "queuedConnectionListener.h"
-#include "queuedConnectionReader.h"
-#include "connectionWriter.h"
+//#include "queuedConnectionListener.h"
+//#include "queuedConnectionReader.h"
+//#include "connectionWriter.h"
 #include "netAddress.h"
 #include "netAddress.h"
 #include "connection.h"
 #include "connection.h"
 #include "datagramIterator.h"
 #include "datagramIterator.h"
@@ -104,7 +104,8 @@ namespace {
   }
   }
 
 
   /*
   /*
-      returns process id.
+      Start an application with the command line cmd.
+      returns the process id of the new process/application.
   */
   */
   DWORD
   DWORD
   StartApp(const string& cmd) {
   StartApp(const string& cmd) {
@@ -132,11 +133,76 @@ namespace {
 DirectD::DirectD() :
 DirectD::DirectD() :
     _host_name("localhost"),
     _host_name("localhost"),
     _port(8001), _app_pid(0),
     _port(8001), _app_pid(0),
-    _controller(false), _verbose(false) {
+    _reader(&_cm, 1), _writer(&_cm, 1), _listener(&_cm, 0),
+    _verbose(false), _shutdown(false) {
 }
 }
 
 
 DirectD::~DirectD() {
 DirectD::~DirectD() {
+  // Close all the connections:
+  ConnectionSet::iterator ci;
+  for (ci = _connections.begin(); ci != _connections.end(); ++ci) {
+    _cm.close_connection((*ci));
+  }
+  _connections.clear();
+}
+
+
+
+DirectDServer::DirectDServer() {
+}
+
+DirectDServer::~DirectDServer() {
+}
+
+
+
+DirectDClient::DirectDClient() {
+}
+
+DirectDClient::~DirectDClient() {
+}
 
 
+void
+DirectDClient::handle_command(const string& cmd) {
+  if (_verbose) {
+    cerr<<"command: "<<cmd<<endl;
+  }
+}
+
+
+#if 0 //[
+void 
+DirectD::add_server(const string& server_host, int port) {
+  string* s = new String(server_host);
+  _servers.push_back(pair<const string*, int>(&s, port));
+}
+
+// Description: free memory and earse all elements from _servers.
+void
+DirectD::clear_server_list() {
+  ServerList::const_iterator i = _servers.begin();
+  for (; i!=_servers.end(); ++i) {
+    string* name=(*i).first;
+    delete name;
+  }
+  _servers.clear();
+}
+
+int 
+DirectD::connect() {
+  ServerList::const_iterator i = _servers;
+  for (; i!=_servers.end(); ++i) {
+    string* name=(*i).first;
+    int port=(*i).second;
+    cerr<<"connecting to "<<name<<" "<<port<<endl;
+  }
+  return 0;
+}
+#endif //]
+
+int 
+DirectD::tell_client_the_server_is_ready(const string& client_host, int port) {
+  return 0;
 }
 }
 
 
 void
 void
@@ -173,226 +239,210 @@ DirectD::kill_app() {
 }
 }
 
 
 void
 void
-DirectD::spawn_background_server() {
-  stringstream ss;
-  ss<<"directd -s "<<_host_name.c_str()<<" "<<_port;
-  DWORD serverPID = StartApp(ss.str());
+DirectD::send_command(const string& cmd) {
+  NetDatagram datagram;
+  datagram.add_string(cmd);
+  // Send the datagram.
+  ConnectionSet::iterator ci;
+  for (ci = _connections.begin(); ci != _connections.end(); ++ci) {
+    _writer.send(datagram, (*ci));
+  }
 }
 }
 
 
 void
 void
-DirectD::run_server() {
-  if (_verbose) cerr<<"server"<<endl;
-
-  PT(Connection) rendezvous = _cm.open_TCP_server_rendezvous(_port, 5);
-
-  if (rendezvous.is_null()) {
-    nout << "Cannot grab port " << _port << ".\n";
-    exit(1);
-  }
-
-  if (_verbose) nout << "Listening for connections on port " << _port << "\n";
-
-  QueuedConnectionListener listener(&_cm, 0);
-  listener.add_connection(rendezvous);
-
-  typedef pset< PT(Connection) > Clients;
-  Clients clients;
-
-  QueuedConnectionReader reader(&_cm, 1);
-  ConnectionWriter writer(&_cm, 1);
-
-  bool shutdown = false;
-  while (!shutdown) {
-    // Check for new clients.
-    while (listener.new_connection_available()) {
-      PT(Connection) rv;
-      NetAddress address;
-      PT(Connection) new_connection;
-      if (listener.get_new_connection(rv, address, new_connection)) {
-        if (_verbose) nout << "Got connection from " << address << "\n";
-        reader.add_connection(new_connection);
-        clients.insert(new_connection);
-      }
+DirectD::cli_command(const string& cmd) {
+  cerr<<"command "<<cmd<<endl;
+  if (cmd[0]=='!') {
+    // ...connect to host.
+    cerr<<"Local command "<<flush;
+    string code;
+    cin >> code;
+    string host;
+    cin >> host;
+    int port;
+    cin >> port;
+    cerr<<"connect ("<<code<<") to "<<host<<" port "<<port<<endl;
+    connect_to(host, port);
+  } else {
+    send_command(cmd);
+    if (cmd[0] == 'q' && cmd.size()==1) {
+      // ...user entered quit command.
+      exit(0);
     }
     }
+  }
+}
 
 
-    // Check for reset clients.
-    while (_cm.reset_connection_available()) {
-      PT(Connection) connection;
-      if (_cm.get_reset_connection(connection)) {
-        if (_verbose) {
-          nout << "Lost connection from "
-               << connection->get_address() << "\n";
-        }
-        clients.erase(connection);
-        _cm.close_connection(connection);
-      }
-    }
+void
+DirectD::handle_datagram(NetDatagram& datagram){
+  DatagramIterator di(datagram);
+  string cmd=di.get_string();
+  handle_command(cmd);
+}
 
 
-    // Process all available datagrams.
-    while (reader.data_available()) {
-      NetDatagram datagram;
-      if (reader.get_data(datagram)) {
-        if (_verbose) {
-          nout << "Got datagram " /*<< datagram <<*/ "from "
-               << datagram.get_address() << ", sending to "
-               << clients.size() << " clients.\n";
-          if (_verbose) datagram.dump_hex(nout);
-        }
-        DatagramIterator di(datagram);
-        string cmd=di.get_string();
-        if (_verbose) {
-          cerr<<"server: "<<cmd<<endl;
-        }
-        if (cmd[0]=='q' && cmd.size()==1) {
-          shutdown=true;
-        }
-
-        Clients::iterator ci;
-        for (ci = clients.begin(); ci != clients.end(); ++ci) {
-          writer.send(datagram, (*ci));
-        }
-
-        if (datagram.get_length() <= 1) {
-          // An empty datagram, shut down the server:
-          shutdown = true;
-        }
+void
+DirectD::handle_command(const string& cmd) {
+  if (_verbose) {
+    cerr<<"command: "<<cmd<<endl;
+  }
+  if (cmd.size()==1) {
+    switch (cmd[0]) {
+    case 's': {
+      string c;
+      read_command(c);
+      start_app(c);
       }
       }
+      break;
+    case 'k':
+      kill_app();
+      break;
+    case 'q':
+      _shutdown=true;
+      break;
+    default:
+      cerr<<"unknown command: "<<cmd<<endl;
     }
     }
-
-    // Yield the timeslice before we poll again.
-    PR_Sleep(PR_MillisecondsToInterval(100));
+  } else {
+    start_app(cmd);
   }
   }
 }
 }
 
 
 void
 void
-DirectD::run_client() {
-  if (!_controller) {
-    cerr<<"client"<<endl;
+DirectD::read_command(string& cmd) {
+  try {
+    ifstream f;
+    f.open("directdCommand", ios::in | ios::binary);
+    stringstream ss;
+    const buf_size=512;
+    char buf[buf_size];
+    f.getline(buf, buf_size);
+    if (f.gcount() > 0) {
+      cmd = buf;
+      cerr<<"read_command "<<cmd<<endl;
+    }
+    f.close();
+  catch (...) {
+    // This could be bad, I suppose.  But we're going to throw out
+    // and exceptions that happen during the above read.
+    cerr<<"DirectD::read_command() exception."<<endl;
   }
   }
+}
 
 
+void
+DirectD::connect_to(const string& host_name, int port) {
   NetAddress host;
   NetAddress host;
-  if (!host.set_host(_host_name, _port)) {
-    nout << "Unknown host: " << _host_name << "\n";
+  if (!host.set_host(host_name, port)) {
+    nout << "Unknown host: " << host_name << "\n";
   }
   }
 
 
-  PT(Connection) c = _cm.open_TCP_client_connection(host, 5000);
-
+  const int timeout_ms=5000;
+  PT(Connection) c = _cm.open_TCP_client_connection(host, timeout_ms);
   if (c.is_null()) {
   if (c.is_null()) {
     nout << "No connection.\n";
     nout << "No connection.\n";
     exit(1);
     exit(1);
   }
   }
 
 
-  nout << "Successfully opened TCP connection to " << _host_name
+  nout << "Successfully opened TCP connection to " << host_name
        << " on port "
        << " on port "
        << c->get_address().get_port() << " and IP "
        << c->get_address().get_port() << " and IP "
        << c->get_address() << "\n";
        << c->get_address() << "\n";
 
 
-  QueuedConnectionReader reader(&_cm, 0);
-  reader.add_connection(c);
-  ConnectionWriter writer(&_cm, 0);
-
-  bool lost_connection = false;
-
-  while (!cin.fail() && !lost_connection) {
-    NetDatagram datagram;
-    if (_controller) {
-      cout << "directd send: " << flush;
-      string d;
-      cin >> d;
-      datagram.add_string(d);
-      // Send the datagram.
-      writer.send(datagram, c);
-      if (d[0] == 'q' && d.size()==1) {
-        // ...user entered quit command.
-        _cm.close_connection(c);
-        return;
-      }
-    }
+  _reader.add_connection(c);
+  _connections.insert(c);
+}
 
 
-    // Check for a lost connection.
-    while (_cm.reset_connection_available()) {
-      PT(Connection) connection;
-      if (_cm.get_reset_connection(connection)) {
-        nout << "Lost connection from "
-             << connection->get_address() << "\n";
-        _cm.close_connection(connection);
-        if (connection == c) {
-          lost_connection = true;
-        }
-      }
+void
+DirectD::check_for_lost_connection() {
+  while (_cm.reset_connection_available()) {
+    PT(Connection) c;
+    if (_cm.get_reset_connection(c)) {
+      nout<<"Lost connection from "<<c->get_address()<<endl;
+      _connections.erase(c);
+      _cm.close_connection(c);
     }
     }
+  }
+}
 
 
-    // Now poll for new datagrams on the socket.
-    while (reader.data_available()) {
-      if (reader.get_data(datagram)) {
-        nout << "Got datagram " /*<< datagram*/ << "from "
-             << datagram.get_address() << "\n";
+void
+DirectD::check_for_datagrams(){
+  // Process all available datagrams.
+  while (_reader.data_available()) {
+    NetDatagram datagram;
+    if (_reader.get_data(datagram)) {
+      if (_verbose) {
+        nout << "Got datagram " /*<< datagram <<*/ "from "
+             << datagram.get_address() << endl;
         datagram.dump_hex(nout);
         datagram.dump_hex(nout);
-        if (!_controller) {
-          DatagramIterator di(datagram);
-          string cmd=di.get_string();
-          cerr<<"cmd="<<cmd<<endl;
-          switch (cmd[0]) {
-          case 's':
-            start_app("calc");
-            break;
-          case 'k':
-            kill_app();
-            break;
-          default:
-            cerr<<"unknown command: "<<cmd<<endl;
-          }
-        }
       }
       }
+      handle_datagram(datagram);
     }
     }
   }
   }
-  nout << "Exiting\n";
 }
 }
 
 
 void
 void
-DirectD::run_controller() {
-  cerr<<"controller"<<endl;
-  _controller=true;
-  run_client();
+DirectD::spawn_background_server() {
+  stringstream ss;
+  ss<<"directd -s "<<_host_name.c_str()<<" "<<_port;
+  DWORD serverPID = StartApp(ss.str());
 }
 }
 
 
-
-int
-main(int argc, char *argv[]) {
-  if (argc > 1 && strcmp(argv[1], "--help")==0) {
-    cerr<<"directd [-c <host>] <port>\n"
-    "    -c        run as client (else run as server).\n"
-    "    host      e.g. localhost\n"
-    "    port      default 8001\n";
-    return 1;
+void
+DirectD::listen_to(int port) {
+  const backlog=8;
+  PT(Connection) rendezvous = _cm.open_TCP_server_rendezvous(_port, backlog);
+  if (rendezvous.is_null()) {
+    nout << "Cannot grab port " << _port << ".\n";
+    exit(1);
   }
   }
+  if (_verbose) nout << "Listening for connections on port " << _port << "\n";
+  _listener.add_connection(rendezvous);
+}
 
 
-  cerr<<"directd"<<endl;
-  DirectD directd;
-  if (argc >= 3) {
-    string host=argv[argc-2];
-    directd.set_host_name(host);
-  }
-  char run_as=' ';
-  if (argc > 1) {
-    directd.set_port(atoi(argv[argc-1]));
-    if (strlen(argv[1]) > 1 && argv[1][0] == '-') {
-      run_as=argv[1][1];
+void
+DirectD::check_for_new_clients() {
+  while (_listener.new_connection_available()) {
+    PT(Connection) rv;
+    NetAddress address;
+    PT(Connection) new_connection;
+    if (_listener.get_new_connection(rv, address, new_connection)) {
+      if (_verbose) nout << "Got connection from " << address << "\n";
+      _reader.add_connection(new_connection);
+      _connections.insert(new_connection);
     }
     }
   }
   }
-  switch (run_as) {
-  case 's':
-    directd.run_server();
-    break;
-  case 'c':
-    directd.run_client();
-    break;
-  default:
-    directd.spawn_background_server();
-    PR_Sleep(PR_MillisecondsToInterval(1000));
-    directd.run_controller();
-    break;
+}
+
+void
+DirectD::run_server() {
+  if (_verbose) cerr<<"server"<<endl;
+  
+  listen_to(_port);
+
+  while (1) {
+    check_for_new_clients();
+    check_for_lost_connection();
+    check_for_datagrams();
+
+    // Yield the timeslice before we poll again.
+    PR_Sleep(PR_MillisecondsToInterval(200));
+  }
+}
+
+void
+DirectD::run_client() {
+  if (_verbose) {
+    cerr<<"client"<<endl;
   }
   }
   
   
-  return 0;
+  connect_to(_host_name, _port);
+
+  while (!cin.fail() && _connections.size()!=0) {
+    cout << "directd send: " << flush;
+    string d;
+    cin >> d;
+    cli_command(d);
+
+    check_for_lost_connection();
+    check_for_datagrams();
+  }
+  nout << "Exiting\n";
 }
 }

+ 90 - 4
direct/src/directd/directd.h

@@ -17,38 +17,124 @@
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 
 
 
 
+
+
+
+// This is a work in progress, if  you have any questions, ask skyler.
+
+
+
+
+
+
 #include <process.h>
 #include <process.h>
 #include <Windows.h>
 #include <Windows.h>
 #include "pandabase.h"
 #include "pandabase.h"
+#include "directsymbols.h"
 #include "queuedConnectionManager.h"
 #include "queuedConnectionManager.h"
+#include "queuedConnectionReader.h"
+#include "connectionWriter.h"
+#include "queuedConnectionListener.h"
 
 
+#ifdef CPPPARSER //[
+// hack for interrogate
+typedef int intptr_t;
+#endif //]
 
 
-class DirectD {
-public:
+
+/*
+    DirectD is a client/server app for starting panda/direct.
+    
+    Usage:
+    DirectD is both the client and the server, what it does depends on
+    which command line argumenta are given at startup.
+    
+    Start a directd server on each of the machines you which to start
+    panda on.
+    
+    Start a directd client on the controlling machine or import
+    ShowBaseGlobal with the xxxxx flag in your Configrc.  The client 
+    will connact each of the servers in the xxxxx list in your Configrc.
+*/
+class EXPCL_DIRECT DirectD {
+PUBLISHED:
   DirectD();
   DirectD();
   ~DirectD();
   ~DirectD();
   
   
+  // Description: Call connect_to from client for each server.
+  void connect_to(const string& server_host, int port);
+  
+  // Description: Call listen_to in the server.
+  //              port is a rendezvous port.
+  void listen_to(int port);
+  
+  // Description: 
+  ////void disconnect() {
+  
+  // process command string.
+  void send_command(const string& cmd);
+
+  // Description: This function is overly named, but that's what it does.
+  //              Call this function from the server when import ShowbaseGlobal is
+  //              nearly finished.
+  int tell_client_the_server_is_ready(const string& client_host, int port);
+
+public:
   void set_host_name(const string& host_name);
   void set_host_name(const string& host_name);
   void set_port(int port);
   void set_port(int port);
   void spawn_background_server();
   void spawn_background_server();
   
   
   void run_server();
   void run_server();
   void run_client();
   void run_client();
-  void run_controller();
   
   
   void send_start_app(const string& cmd);
   void send_start_app(const string& cmd);
   void start_app(const string& cmd);
   void start_app(const string& cmd);
   
   
   void send_kill_app(const string& pid);
   void send_kill_app(const string& pid);
   void kill_app();
   void kill_app();
+  
+  void cli_command(const string& cmd);
+  void handle_command(const string& cmd);
+  
+  void handle_datagram(NetDatagram& datagram);
 
 
 protected:
 protected:
   QueuedConnectionManager _cm;
   QueuedConnectionManager _cm;
+  QueuedConnectionReader _reader;
+  ConnectionWriter _writer;
+  QueuedConnectionListener _listener;
+
   string _host_name;
   string _host_name;
   int _port;
   int _port;
   intptr_t _app_pid;
   intptr_t _app_pid;
-  bool _controller;
+  #if 0 //[
+  typedef pvector<pair<const string*, int> > ServerList;
+  ServerList _servers;
+  #endif //]
+  typedef pset< PT(Connection) > ConnectionSet;
+  ConnectionSet _connections;
+
   bool _verbose;
   bool _verbose;
+  bool _shutdown;
+  
+  void check_for_new_clients();
+  void check_for_datagrams();
+  void check_for_lost_connection();
+  
+  void read_command(string& cmd);
+};
+
+class EXPCL_DIRECT DirectDServer: public DirectD {
+public:
+  DirectDServer();
+  ~DirectDServer();
 };
 };
 
 
+class EXPCL_DIRECT DirectDClient: public DirectD {
+public:
+  DirectDClient();
+  ~DirectDClient();
+
+  void handle_command(const string& cmd);
+};
 
 

+ 19 - 0
direct/src/directdServer/Sources.pp

@@ -0,0 +1,19 @@
+
+// This package presently only builds on Windows.
+#define DIRECTORY_IF_WINDOWS yes
+
+//#define LOCAL_LIBS \
+//    directbase
+#define OTHER_LIBS \
+    net:c linmath:c putil:c express:c panda:m pandaexpress:m dtoolconfig dtool
+#define WIN_SYS_LIBS $[WIN_SYS_LIBS] user32.lib //advapi32.lib
+
+#begin bin_target
+  #define TARGET directdServer
+  #define LOCAL_LIBS directd
+  #define OTHER_LIBS $[OTHER_LIBS] pystub
+
+  #define SOURCES \
+    directdServer.cxx
+
+#end bin_target

+ 56 - 0
direct/src/directdServer/directdServer.cxx

@@ -0,0 +1,56 @@
+// Filename: directd.cxx
+// Created by:  skyler 2002.04.08
+// Based on test_tcp_*.* by drose.
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://www.panda3d.org/license.txt .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#include "directd.h"
+
+int
+main(int argc, char *argv[]) {
+  if (argc > 1 && strcmp(argv[1], "--help")==0) {
+    cerr<<"directd [-c <host>] <port>\n"
+    "    -c        run as client (else run as server).\n"
+    "    host      e.g. localhost\n"
+    "    port      default 8001\n";
+    return 1;
+  }
+
+  cerr<<"directd"<<endl;
+  DirectD directd;
+  if (argc >= 3) {
+    string host=argv[argc-2];
+    directd.set_host_name(host);
+  }
+  char run_as=' ';
+  if (argc > 1) {
+    directd.set_port(atoi(argv[argc-1]));
+    if (strlen(argv[1]) > 1 && argv[1][0] == '-') {
+      run_as=argv[1][1];
+    }
+  }
+  switch (run_as) {
+  case 's':
+    directd.run_server();
+    break;
+  case 'c':
+  default:
+    directd.run_client();
+    break;
+  }
+  
+  return 0;
+}