I'm kinda new to c++ programming and I'm coding an object manager to a multiplayer game but I'm having some doubts about how to manage the client objects. The client object is composed of connected client parameters (like IP, connected time, received data etc).
In order to avoid memory fragmentation, I'm planning to allocate a object pool with the max number of client allowed. For that, I'm coding a client object manager like this:
ClientManager.h
#include "Client.h"
class ClientManager {
public:
static void init(int max); //initialize pool (allocate memory)
static void dispose(); //dispose pool (deallocate memory)
static bool add(int socketFd); //add connected client by its socket file descriptor
static bool remove(int socketFd); //remove connected client by its socket fd
static Client& get(int socketFd); //get the client object by its socket fd
private:
Client* clientList; //array of allocated clients objects
int maxClient; //max number of connected clients allowed
Note that this class will be called only the static way so there are no constructors/destructors. This class must be static because it is imperative that the client data can be read/modified between different types of objects.
The implementation will be something like:
ClientManager.cpp
void ClientManager::init(int max) {
maxClient = max;
clientList = new Client[maxClient];
}
void ClientManager::dispose() {
maxClient = 0;
delete [] clientList;
clientList = NULL;
}
bool ClientManager::add(int socketFd) {
//search pool for non-initialized object
//if(there is a non-initializes object) { initialize it with socketFd and return true}
//else return false;
}
bool ClientManager::remove(int socketFd) {
//search pool for socketFd
//if(socketFd found) { clear object (make it non-initialized) and return true}
//else return false
}
Client& ClientManager::get(int socketFd) {
//search for object position
if(pos) return clientList[pos];
else ???????
}
Now, how do I manage the object return in the get function? Is it by reference the best option? I don't want to return a pointer but if it is my last option, I can live with it. I guess I can make sure that I only get registered (initialized) object in the pool, if so is this check in the get function necessary? I don't want an assert because I want the code to be robust and not stop during runtime (I'm new to C++ so if I'm saying something wrong please correct me).
in the main program, I'm thinking in something like:
Daemon.cpp
#include "ClientManager.h"
int main(...) {
ClientManager::init(100);
while(1) {
//do server stuff
//get onConnect event (new client is connecting)
//get onDisconnect event (connected client has gone offline)
//get onDataReceived event (connected client has sent data)
}
}
void onConnect(int socketFd) {
ClientManager::add(socketFd);
}
void onDisconnect(int socketFd) {
ClientManager::remove(socketFd);
}
void onDataReceived(int socketFd) {
do_something(ClientManager::get(socketFd).data);
}
Am I doing it right? Thanks
Notes:
1) This code is on my mind and I typed it here, so I may have forgotten something.
2) The program will terminate only by being killed (I'm using linux), so the ClientManager dispose method will not be explicitly called in the main program (since it is a static class). Again, if I'm saying something wrong please tell me!
3) Sorry about my bad english :)