/Desktop/MGS-MultithreadedGameServer/TFactory.h

Vai alla documentazione di questo file.
00001 //
00002 // File: ConnectionHandler.cc
00003 // Created by: <Detro /> aka Ivan De Marino 
00004 // <detro@mandolinux.org, demarino@studenti.unina.it, demarino@na.astro.it>
00005 // Created on: Tue Nov 16 01:22:38 2004
00006 //
00007 
00008 #ifndef _TFACTORY_H_
00009 #define _TFACTORY_H_
00010 #include "TFactoryException.h"
00011 #include <dlfcn.h> // Libreria "Dynamic Lynking Loader"
00012 
00013 /** 
00014  * @class TFactory TFactory.h
00015  * Questa Classe Template ha il compito di @b Istanziare @b a @b Run-Time Classi
00016  * la cui Dichiarazione e Definizione non e' avvenuta a @b Compile-Time.
00017  * In sostanza, si parla di realizzare un sistema per la gestione
00018  * di quelli che, in gergo, si chiamano @b Plug-In: mini-programmi che
00019  * si aggiungono ad altri piu' grandi per aumentarne le funzionalita'.
00020  * 
00021  * E' una "Factory" di Classi @a Plug-In. <br>
00022  * Carica da libreria SO la definizione di una Classe che ha come 
00023  * Classe di Base il Parametro passato alla Factory: in questo modo e'
00024  * sufficiente, per realizzare classi Plug-In, che le Classi da Istanziare 
00025  * a Run-Time implementino un'interfaccia comune.
00026  * 
00027  * Per la precisione, e' anche necessario che nella libreria SO che
00028  * contiene la classe sia presente una funzione cosė definita: <br> <br>
00029  *
00030  * <code>
00031  * extern "C" <br>
00032  * <ClassName> *buildObject(void) { return new <ClassName>; } <br>
00033  * </code> <br>
00034  *
00035  * @c buildObject(void) crea effettivamente una istanza della Classe Plug-In.
00036  *
00037  * Questa soluzione permette quindi di caricare nuove Classi senza
00038  * bisogno ne di ricompilare, ne di modificare il codice. */
00039 template <class T>
00040 class TFactory {
00041    public:
00042       TFactory(const string &);
00043       ~TFactory();
00044       T build () ;
00045       void closeSo();
00046       
00047    private:
00048       /* Handler della SO caricata */
00049       void *handler;
00050       /* Puntatore alla funzione (o, meglio, al "simbolo")
00051        * ritornato da "dlsym" */
00052       T (*builder)(void);
00053       void openSo(const string &);
00054 };
00055 
00056 /**
00057  * Costruttore TFactory.
00058  * Si occupa anche di recuperare i Simboli (@c "buildObject" ) 
00059  * necessari all'istanziazione di una nuova T Class.
00060  *
00061  * @param soLibPath Path alla Libreria SO da dove caricare la definizione
00062  *    della Classe */
00063 template <class T>
00064 TFactory<T>::TFactory(const string &soLibPath) {
00065    try {
00066       /* Caricamento della SO */
00067       openSo(soLibPath);
00068       /* Casting necessario per una corretta assegnazione
00069        * della funzione al relativo puntatore */
00070       *(void **) (&builder) = dlsym(handler, "buildObject");
00071       /* Controlla che il Simbolo Cercato ("buildObject") sia
00072        * stato trovato... */
00073       if ( builder == NULL ) { // Errore nel caricamento della funzione
00074          /* ...in caso negativo, lancia un TFactoryException */
00075          string exceptionMessage("<TFactory msg> ERROR: ");
00076          exceptionMessage += dlerror();
00077          throw TFactoryException(exceptionMessage);
00078       }
00079    }
00080    catch ( TFactoryException &e ) {
00081       throw e;
00082    }
00083    cout << "<TFactory msg> Plug-In Loaded. Library-Path: "<< soLibPath << endl;
00084 }
00085 
00086 /** Distruttore TFactory */
00087 template <class T>
00088 TFactory<T>::~TFactory() {}
00089 
00090 /**
00091  * Restituisce una istanza della Classe contenuta nella SO.
00092  * L'oggetto restituito e' UP-Castato alla Classe Base "T"
00093  * (parametro del Template) 
00094  * @return Una nuova istanza di T (T = Parametro di TFactory) */
00095 template <class T>
00096 T TFactory<T>::build() {
00097    return ( (*builder)() ); // Ritorna la nuova istanza di T
00098 }
00099 
00100 /**
00101  * Carica la libreria SO.
00102  *
00103  * @param soLibPath Libreria SO da caricare */
00104 template <class T>
00105 void TFactory<T>::openSo(const string &soLibPath) {
00106    /* Apertura della Libreria SO */
00107    handler = dlopen( soLibPath.data(), RTLD_NOW);
00108    
00109    if (!handler) {
00110       string exceptionMessage("<TFactory msg> ERROR: ");
00111       exceptionMessage += dlerror();
00112       throw TFactoryException(exceptionMessage);
00113    }
00114 }
00115 
00116 /** Chiude la libreria SO */
00117 template <class T>
00118 void TFactory<T>::closeSo() {
00119    if (handler) {
00120       dlclose(handler);
00121       handler = NULL;
00122    }
00123 }
00124 
00125 #endif

Generato il Sun Nov 28 13:27:03 2004 per MGS - Multithreaded Game Server da doxygen 1.3.4