00001 #ifndef GSGL_FRAMEWORK_BROKER_H
00002 #define GSGL_FRAMEWORK_BROKER_H
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include "data/data.hpp"
00038 #include "data/exception.hpp"
00039 #include "data/global.hpp"
00040 #include "data/string.hpp"
00041 #include "data/dictionary.hpp"
00042
00043 namespace gsgl
00044 {
00045
00046 namespace data
00047 {
00048
00049 class DATA_API brokered_object
00050 {
00051 mutable gsgl::string type_name;
00052 friend class broker;
00053 public:
00054 virtual const gsgl::string & get_type_name() const;
00055 };
00056
00057
00058 class config_record;
00059
00060
00061 class DATA_API broker_creator
00062 {
00063 public:
00064
00065 typedef brokered_object * (*creator_ft)(const config_record & obj_conf);
00066
00067 private:
00068 const gsgl::string type_name;
00069 const creator_ft create_func;
00070
00071 public:
00072 broker_creator(const gsgl::string & type_name, creator_ft create_func);
00073 ~broker_creator();
00074
00075 const gsgl::string & get_type_name() const { return type_name; }
00076 creator_ft get_create_func() const { return create_func; }
00077 };
00078
00079
00080
00081
00082
00083
00084
00085 class DATA_API broker
00086 : public global_register<broker_creator, gsgl::data::dictionary<broker_creator *, gsgl::string> >
00087 {
00088 broker();
00089 virtual ~broker();
00090
00091 public:
00092 bool has_object(const gsgl::string & type_name);
00093 brokered_object *create_object(const gsgl::string & type_name, const config_record & conf);
00094
00095 static broker *global_instance();
00096 };
00097
00098
00099
00100
00101 template <typename R>
00102 void global_register_resource_aux(gsgl::data::dictionary<broker_creator *, gsgl::string> & d, broker_creator *bc)
00103 {
00104 assert(bc);
00105
00106 if (d.contains_index(bc->get_type_name()))
00107 throw runtime_exception(L"%ls: already registered this object type!", bc->get_type_name().w_string());
00108 else
00109 d[bc->get_type_name()] = bc;
00110 }
00111
00112
00113 template <typename R>
00114 void global_unregister_resource_aux(gsgl::data::dictionary<broker_creator *, gsgl::string> & d, broker_creator *bc)
00115 {
00116 assert(bc);
00117
00118 if (d.contains_index(bc->get_type_name()))
00119 d.remove(bc->get_type_name());
00120 else
00121 throw internal_exception(__FILE__, __LINE__, L"Attempted to unregister an unregistered creator from the global broker.");
00122 }
00123
00124
00125 }
00126
00127 }
00128
00129
00130
00131 #define BROKER_DECLARE_CREATOR(name) static gsgl::data::brokered_object *_create_(const gsgl::data::config_record & obj_conf) { return new name(obj_conf); } static gsgl::data::broker_creator _creator_
00132
00133 #define BROKER_DEFINE_CREATOR(name) gsgl::data::broker_creator name::_creator_(gsgl::string(#name), &name::_create_)
00134
00135
00136
00137 #endif