You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdegames/libksirtet/lib/mp_interface.h

248 lines
7.4 KiB

#ifndef MP_INTERFACE_H
#define MP_INTERFACE_H
#include <tqwidget.h>
#include <tqvaluelist.h>
#include <tqptrlist.h>
#include "mp_board.h"
#include "mp_option.h"
class TQHBoxLayout;
class Local;
class ConnectionData;
class RemoteHostData;
class KeyData;
class KeyCollection;
class KKeyDialog;
class KAction;
struct ActionData {
const char *label, *name;
const char *slot, *slotRelease; // if slotRelease!=0
// : use keyPress/ReleaseEvent mecanism
};
/**
* This structure contains information about the game
* configuration.
*/
typedef struct {
/** The game version id used for identification (e.g. "4").
* You should change this id when the game is made incompatible
* with previous version. (changes in data for example).
*/
const char *gameId;
/** Maximum number of local players. */
uint maxNbLocalPlayers;
/** Interval (in msec.) between data exchange. */
uint interval;
/** If there are built-in artificial intelligences that can play. */
bool AIAllowed;
/** Slot for player/AI additional configuration. These must be SLOTs which
* take an "int" as parameter. It must open a setting
* dialog for the corresponding local player/computer and save the
* new settings in the config file. It should probably create a group
* with the given number in its name.
* If such a pointer is set to 0 : it means there is no perticular
* setting.
*/
const char *humanSettingSlot, *AISettingSlot;
} MPGameInfo;
/**
* The MPInterface class is useful for multiplayers game
* management. Each game is represented by a class you have inherited
* from the @ref MPBoard class.
*
* Multiplayers games can take place with several (humans or eventually
* AIs) players on the same computer (they use the same keyboard and have
* each a @ref MPBoard widget on the screen) or/and network players.
*
* This class is intended to do all the hard work of sending/receiving data
* between the players and to send the keyboard events to the right
* @ref MPBoard. So multiplayers game should be completely transparent
* from your point of view.
*
* Note : The data exchange is done in background with a timer calling at given
* intervals the read/write methods. Obviously this kind of things can be done
* easily with threads but I have no experience with thread programming
* and not all people have thread libraries and a thread-safe system.
*/
class MPInterface : public TQWidget
{
Q_OBJECT
public:
/** Constructor which takes a MPGameInfo struct as parameter.
*/
MPInterface(const MPGameInfo &gameInfo,
uint nbActions, const ActionData *data,
TQWidget *parent = 0, const char *name = 0);
virtual ~MPInterface();
public slots:
/** Create a single player game for a human being.
* Call @ref stop if a game is already created. */
void singleHuman() { specialLocalGame(1, 0); }
/** Create a local game opposing two human beings.
* Call @ref stop if a game is already created. */
void humanVsHuman() { specialLocalGame(2, 0); }
/** Create a local game opposing a human with an AI.
* Call @ref stop if a game is already created. */
void humanVsComputer() { specialLocalGame(1, 1); }
/** Open a dialog to create a multiplayer game.
* Call @ref stop if a game is already created. */
void dialog();
public:
virtual void addKeys(KKeyDialog &);
void saveKeys();
/** Called when a new game is created. At this point
* the number of players is known. */
virtual void init() {}
/** Called just before a new game is created (called by
* singleHuman, humanVsHuman, humanVsComputer and dialog). */
virtual void stop() {}
/** Called when the start button of the netmeeting is pressed. */
virtual void start() {}
/**
* Set keys configuration for the given number of human players.
* The size of the array is the number of defined actions.
*/
void setDefaultKeycodes(uint nbHumans, uint human, const int *keycodes);
/**
* @return the total number of players.
* (If called from client : return the number of local boards).
*/
uint nbPlayers() const;
/**
* @return true if the interface is the server.
*/
bool server() const { return _server; }
/** @return the player name.
Do not call from client !
*/
TQString playerName(uint i) const;
/**
* Create a new @ref MPBoard.
*
* @param i is the game index that goes from 0 to the number of
* local players : it can be used to retrieve configuration settings.
*/
virtual MPBoard *newBoard(uint i) = 0;
/**
* This method must read data from each client with method
* @ref readingStream, do the needed treatement
* (for instance which players has lost, which data to be resent, ...) and
* then write the useful data to each client with method
* @ref writingStream.
*
* NB: this method is also called for single player games but
* you probably only want to check for game over condition (it depends
* on game implementation that you really return data to the board).
*/
virtual void treatData() = 0;
/** @return the reading stream for board #i.
* Do not call from client !
*/
TQDataStream &readingStream(uint i) const;
/** @return the writing stream for board #i.
*/
TQDataStream &writingStream(uint i) const;
/**
* Read data sent from server to clients "MultiplayersInterface"
* (this data is not addressed to boards).
* These are meta data that are not directly used in game.
* It can be used to display "game over" infos for all
* local games.
* NB: the use of this method is optional.
*/
virtual void dataFromServer(TQDataStream &) {}
/** Used by the server to write meta data to clients.
* NB: the use of this method is optional.
* Do not call from client !
*/
TQDataStream &dataToClientsStream() const;
/** Write immediately data to clients and local boards.
* It is unlike the normal exchange which is driven
* by the timer of the server. Be aware of possible
* interactions.
*/
void immediateWrite();
/**
* This method should be overload if an option widget is used in the
* the "netmeeting" dialog). By default a
* null pointer is returned and so no option widget is shown.
* The option widget must be inherited from the @ref MPOptionWidget class.
*/
virtual MPOptionWidget *newOptionWidget() const { return 0; }
/** Called when a network error occurred or when a host gets disconnected.
* The default implementation displays a message and calls singleHumans()
* ie it stops the current game. By overloading this method, it is
* possible to continue the game at this point with the remaining players.
*/
virtual void hostDisconnected(uint i, const TQString &msg);
protected:
void paintEvent(TQPaintEvent *);
void keyPressEvent(TQKeyEvent *);
void keyReleaseEvent(TQKeyEvent *);
private slots:
void enableKeys(bool enable);
void singleHumanSlot();
public:
class Data {
public:
Data() {}
MPBoard *ptr;
int humanIndex;
TQString name;
};
private:
Local *internal;
const MPGameInfo gameInfo;
TQValueList<Data> boards;
uint nbLocalHumans;
TQHBoxLayout *hbl;
bool _server, disconnected;
KeyData *_keyData;
TQMemArray<KeyCollection *> _keyCol;
void createServerGame(const TQPtrList<RemoteHostData> &);
void createClientGame(const RemoteHostData &);
void createLocalGame(const ConnectionData &);
void specialLocalGame(uint nbHumans, uint nbComputers);
void clear();
void initKeys(uint nbHumans);
};
#endif // MP_INTERFACE_H