00001
00002
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
#include "Object.h"
00037
#include "stringutils.h"
00038
#include "TypeFactory.h"
00039
00040
namespace PLearn {
00041
using namespace std;
00042
00043
00044
00045 void TypeFactory::register_type(
const string& type_name,
00046
const string& parent_class,
00047
NEW_OBJECT constructor,
00048
GETOPTIONLIST_METHOD getoptionlist_method,
00049
ISA_METHOD isa_method,
00050
const string& one_line_descr,
00051
const string& multi_line_help)
00052 {
00053
TypeMapEntry entry(type_name,
00054 parent_class,
00055 constructor,
00056 getoptionlist_method,
00057 isa_method,
00058 one_line_descr,
00059 multi_line_help);
00060
00061
instance().
registerType(entry);
00062 }
00063
00064 void TypeFactory::registerType(
const TypeMapEntry& entry)
00065 {
00066
type_map_.insert( pair<string,TypeMapEntry>(entry.
type_name, entry) );
00067
00068 }
00069
00070 void TypeFactory::unregisterType(
string type_name)
00071 {
00072
type_map_.erase(type_name);
00073 }
00074
00075 bool TypeFactory::isRegistered(
string type_name)
const
00076
{
00077
return type_map_.find(type_name)!=
type_map_.end();
00078 }
00079
00080 Object* TypeFactory::newObject(
string type_name)
const
00081
{
00082 TypeMap::const_iterator it =
type_map_.find(type_name);
00083
if (it ==
type_map_.end())
00084
PLERROR(
"In TypeFactory::newObject(\"%s\"): %s not registered in type map.", type_name.c_str(), type_name.c_str());
00085
if (!(*it->second.constructor))
00086
PLERROR(
"In TypeFactory::newObject(\"%s\"): %s does not have a factory constructor!", type_name.c_str(), type_name.c_str());
00087
return (*it->second.constructor)();
00088 }
00089
00090 bool TypeFactory::isAbstract(
string type_name)
const
00091
{
00092 TypeMap::const_iterator it =
type_map_.find(type_name);
00093
if (it ==
type_map_.end())
00094
PLERROR(
"In TypeFactory: %s not registered in type map.", type_name.c_str(), type_name.c_str());
00095
return it->second.constructor == 0;
00096 }
00097
00098 TypeFactory& TypeFactory::instance()
00099 {
00100
static TypeFactory instance_;
00101
return instance_;
00102 }
00103
00104
00105 void displayObjectHelp(ostream& out,
const string& classname)
00106 {
00107
const TypeMap& type_map = TypeFactory::instance().
getTypeMap();
00108 TypeMap::const_iterator it = type_map.find(classname);
00109 TypeMap::const_iterator itend = type_map.end();
00110
00111
if(it==itend)
00112
PLERROR(
"Object type %s unknown.\n"
00113
"Did you #include it, does it call the IMPLEMENT_NAME_AND_DEEPCOPY macro?\n"
00114
"and has it indeed been linked with your program?", classname.c_str());
00115
00116
const TypeMapEntry& entry = it->second;
00117
Object* obj = 0;
00118
00119 out <<
"****************************************************************** \n"
00120 <<
"** " << classname <<
"\n"
00121 <<
"****************************************************************** \n" <<
endl;
00122
00123
00124 out << entry.
one_line_descr <<
endl <<
endl;
00125 out << entry.
multi_line_help <<
endl <<
endl;
00126
00127
if(entry.
constructor)
00128 obj = (*entry.
constructor)();
00129
else
00130 out <<
"Note: " << classname <<
" is a base-class with pure virtual methods that cannot be instantiated directly.\n"
00131 <<
"(default values for build options can only be displayed for instantiable classes, \n"
00132 <<
" so you'll only see question marks here.)\n" <<
endl;
00133
00134 out <<
"****************************************************************** \n"
00135 <<
"** Build Options ** \n"
00136 <<
"** (including those inherited from parent and ancestor classes) ** \n"
00137 <<
"****************************************************************** \n" <<
endl;
00138
00139 out << classname +
"( \n";
00140
OptionList& options = (*entry.
getoptionlist_method)();
00141
00142
for( OptionList::iterator olIt = options.begin(); olIt!=options.end(); ++olIt )
00143 {
00144 OptionBase::flag_t flags = (*olIt)->flags();
00145
if(flags & OptionBase::buildoption)
00146 {
00147
string descr = (*olIt)->description();
00148
string optname = (*olIt)->optionname();
00149
string opttype = (*olIt)->optiontype();
00150
string defaultval =
"?";
00151
if(obj)
00152 {
00153 defaultval = (*olIt)->defaultval();
00154
if(defaultval==
"")
00155 defaultval = (*olIt)->writeIntoString(obj);
00156 }
00157
00158 out <<
addprefix(
"# ", opttype +
": " + descr);
00159 out << optname +
" = " + defaultval +
" ;\n\n";
00160 }
00161 }
00162 out <<
");\n\n";
00163
00164
if(obj)
00165
delete obj;
00166
00167 out <<
"****************************************************************** \n"
00168 <<
"** Subclasses of " << classname <<
" \n"
00169 <<
"** (only those that can be instantiated) \n"
00170 <<
"****************************************************************** \n" <<
endl;
00171
for(it = type_map.begin(); it!=itend; ++it)
00172 {
00173
00174
const TypeMapEntry& e = it->second;
00175
if(e.
constructor && it->first!=classname)
00176 {
00177
Object* o = (*e.
constructor)();
00178
if( (*entry.
isa_method)(o) )
00179 out << it->first <<
" ";
00180
if(o)
00181
delete o;
00182 }
00183 }
00184
00185 out <<
"\n\n------------------------------------------------------------------ \n" <<
endl;
00186
00187 }
00188
00189
00190
00191 }