1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
| #include <string>
#include <exception>
#include <map>
using namespace std;
class Machin
{
public:
void Hello(void);
int FaireTruc(string const &chn, int a, int b);
};
class Appel
{
public:
static const int Retour = -1;
void SetNomMethode(string nom);
void SetThisId(int id);
void SetInt(int index, int valeur);
void SetString(int index, string valeur);
string GetNomMethode() const;
int GetThisId() const;
int GetInt(int index) const;
string GetString(int index) const;
private:
//Blabla implémentation
};
class Reseau
{
public:
void AppelDistant(Appel &);
};
class MachinProxy
{
private:
Reseau& monReseau;
int monId;
public:
MachinProxy(Reseau& reseau, int id) : monReseau(reseau), monId(id) { }
void Hello(void) {
Appel appel;
appel.SetThisId(monId);
monReseau.AppelDistant(appel);
}
int FaireTruc(string const &chn, int a, int b) {
Appel appel;
appel.SetThisId(monId);
appel.SetString(0, chn);
appel.SetInt(1, a);
appel.SetInt(2, b);
monReseau.AppelDistant(appel);
return appel.GetInt(Appel::Retour);
}
};
class StubBase
{
protected:
typedef void(StubBase::*PtrFonction)(Appel &appel); //En C++11, on peut probablement utiliser std::function<void(Appel&)> à la place
virtual map<string, PtrFonction> GetMap() = 0;
private:
map<string, PtrFonction> maMap;
public:
void Initialiser() { //Doit être appelée APRÈS avoir construit l'objet complètement
maMap = GetMap();
}
void TraiterAppel(Appel& appel) {
PtrFonction ptr = maMap[appel.GetNomMethode()];
if(!ptr)
throw exception("Méthode inconnue");
(this->*ptr)(appel);
}
};
class MachinStub : public StubBase //Doit forcément être le premier et non-virtuel
{
private:
Machin& leVraiMachin;
public:
MachinStub(Machin& machin) : StubBase(), leVraiMachin(machin) { }
virtual map<string, PtrFonction> GetMap()
{
map<string, PtrFonction> ret;
ret["Hello"] = static_cast<PtrFonction>(&MachinStub::Hello); //Ça DOIT passer avec static_cast, sinon ça veut dire qu'on fait n'importe quoi.
ret["FaireTruc"] = static_cast<PtrFonction>(&MachinStub::FaireTruc);
}
private:
void Hello(Appel &appel) {
(void)appel; //Hello est une fonction void(void), rien à traiter ici
leVraiMachin.Hello();
}
void FaireTruc(Appel &appel) {
int retour = leVraiMachin.FaireTruc(appel.GetString(0), appel.GetInt(1), appel.GetInt(2));
appel.SetInt(Appel::Retour, retour);
}
}; |
Partager