00001 // Filename: directd.h 00002 // Created by: skyler 2002.04.08 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved 00008 // 00009 // All use of this software is subject to the terms of the Panda 3d 00010 // Software license. You should have received a copy of this license 00011 // along with this source code; you will also find a current copy of 00012 // the license at http://www.panda3d.org/license.txt . 00013 // 00014 // To contact the maintainers of this program write to 00015 // panda3d@yahoogroups.com . 00016 // 00017 //////////////////////////////////////////////////////////////////// 00018 00019 #include <process.h> 00020 #include <Windows.h> 00021 #include "pandabase.h" 00022 #include "directsymbols.h" 00023 #include "queuedConnectionManager.h" 00024 #include "queuedConnectionReader.h" 00025 #include "connectionWriter.h" 00026 #include "queuedConnectionListener.h" 00027 00028 #ifdef CPPPARSER //[ 00029 // hack for interrogate 00030 typedef int intptr_t; 00031 typedef int HANDLE; 00032 #endif //] 00033 00034 00035 // Description: DirectD is a client/server app for starting panda/direct. 00036 // 00037 // Usage: 00038 // Start a directd server on each of the machines you 00039 // which to start panda on. 00040 // 00041 // Start a directd client on the controlling machine or 00042 // import ShowBaseGlobal with the xxxxx flag in your 00043 // Configrc. The client will connect each of the servers 00044 // in the xxxxx list in your Configrc. 00045 // 00046 // There are two API groups in this class, they are: 00047 // 00048 // listen_to() 00049 // client_ready() or tell_server() 00050 // wait_for_servers() 00051 // server_ready() 00052 // 00053 // and: 00054 // 00055 // connect_to() 00056 // send_command() 00057 // disconnect_from() 00058 // 00059 // The second group was from a more general implementation 00060 // of DirectD. The first group summarizes the main intents 00061 // of DirectD. 00062 // Both groups are presented in order chronologically by their 00063 // intended usage. 00064 // The first group will probably provide everthing needed for 00065 // DirectD. 00066 class EXPCL_DIRECT DirectD { 00067 PUBLISHED: 00068 DirectD(); 00069 ~DirectD(); 00070 00071 // Description: Call listen_to in the server. 00072 // port is a rendezvous port. 00073 // 00074 // backlog refers to how many connections can queue up 00075 // before you handle them. Consider setting backlog to 00076 // the count you send to wait_for_servers(); or higher. 00077 void listen_to(int port, int backlog=8); 00078 00079 // Description: Call this function from the client when 00080 // import ShowbaseGlobal is nearly finished. 00081 // cmd: a cli command that will be executed on the remote 00082 // machine. 00083 // A new connection will be created and closed. If you 00084 // want to send more than one command, you should use 00085 // connect_to(), send_command(), and disconnect_from(). 00086 int client_ready(const string& server_host, int port, const string& cmd); 00087 00088 // Description: Tell the server to do the command cmd. 00089 // cmd is one of the following: 00090 // "k[<n>]" Kill the most recent application 00091 // started with client_ready() or "!". 00092 // Or kill the nth most recent or 'a' for All. 00093 // E.g. "k", "k0", "k2", "ka". 00094 // "q" Tell the server to quit. 00095 // "!cmd" Exectue the cmd on the server (this 00096 // is a dos shell command; if you want 00097 // a bash command, include bash in the 00098 // command e.g. "!bash pwd"). When you call 00099 // client_ready(), it prefixes "!" for you. 00100 // A new connection will be created and closed. 00101 int tell_server(const string& server_host, int port, const string& cmd); 00102 00103 // Description: Call this function from the client after 00104 // calling <count> client_ready() calls. 00105 // 00106 // Call listen_to(port) prior to calling 00107 // wait_for_servers() (or better yet, prior 00108 // to calling client_ready()). 00109 // 00110 // timeout_ms defaults to two minutes. 00111 bool wait_for_servers(int count, int timeout_ms=2*60*1000); 00112 00113 // Description: Call this function from the server when 00114 // import ShowbaseGlobal is nearly finished. 00115 int server_ready(const string& client_host, int port); 00116 00117 // Description: Call connect_to from client for each server. 00118 // returns the port number of the connection (which 00119 // is different from the rendezvous port used in the 00120 // second argument). The return value can be used 00121 // for the port arguemnt in disconnect_from(). 00122 int connect_to(const string& server_host, int port); 00123 00124 // Description: This is the counterpart to connect_to(). Pass 00125 // the same server_host as for connect_to(), but pass 00126 // the return value from connect_to() for the port, 00127 // not the port passed to connect_to(). 00128 void disconnect_from(const string& server_host, int port); 00129 00130 // Description: Send the same command string to all current 00131 // connections. 00132 void send_command(const string& cmd); 00133 00134 protected: 00135 void start_app(const string& cmd); 00136 void kill_app(int index); 00137 void kill_all(); 00138 virtual void handle_command(const string& cmd); 00139 void handle_datagram(NetDatagram& datagram); 00140 void send_one_message(const string& host_name, 00141 int port, const string& message); 00142 00143 QueuedConnectionManager _cm; 00144 QueuedConnectionReader _reader; 00145 ConnectionWriter _writer; 00146 QueuedConnectionListener _listener; 00147 00148 // Start of old stuff: 00149 // This is used to switch to the original method of 00150 // starting applications. It can be used on old systems 00151 // that don't support job objects. Eventually this stuff 00152 // should be removed. 00153 bool _useOldStuff; 00154 typedef pvector< long /*intptr_t*/ > PidStack; 00155 PidStack _pids; 00156 // End of old stuff 00157 00158 typedef pset< PT(Connection) > ConnectionSet; 00159 ConnectionSet _connections; 00160 HANDLE _jobObject; 00161 bool _shutdown; 00162 00163 void check_for_new_clients(); 00164 void check_for_datagrams(); 00165 void check_for_lost_connection(); 00166 };