#include "GenericDataNodes.h" //////////////////////////////////////////////////////////////////// // GenericDataNode //////////////////////////////////////////////////////////////////// DataNodeLink *GenericDataNode::find(DataNodeListener *listener, int msgId, GenericDataNode *&node, std::string const &name, DataNodeArgument args, GenericDataNodeConstructor constructor) { DataNodeManager *const manager = DataNodeManager::getDefault(); if (DataNode *prev = manager->findDataNode(name)) { // Strange. All of my alert types were failing here. I changed the // build script to build Alert.C before the other alert classes, and it // starting working again! node = dynamic_cast< GenericDataNode * >(prev); } else { node = constructor(args); manager->registerNode(name, node); } return node->createLink(listener, msgId); } //////////////////////////////////////////////////////////////////// // GenericDataNodeFactory //////////////////////////////////////////////////////////////////// std::string GenericDataNodeFactory::asString() const { // Should this be cached? These objects should be immutable. // THE PREFIX F IS RESERVED HERE. return 'F' + quoteString(_constructorName) + _args.asString(); } DataNodeArgument GenericDataNodeFactory::replace (std::string const &name, DataNodeArgument const &value) const { DataNodeArgument newArgs = _args.replace(name, value); if (newArgs) { return new GenericDataNodeFactory(_constructor, _constructorName, newArgs); } else { // No change so return null. return newArgs; } } DataNodeLink *GenericDataNodeFactory::find(DataNodeListener *listener, int msgId, GenericDataNode *&node ) const { return GenericDataNode::find(listener, msgId, node, asString(), _args, _constructor); } static std::map< std::string, DataNodeArgument > namedFactories; DataNodeArgument GenericDataNodeFactory::findFactory(std::string const &name, bool noComplain) { DataNodeArgument result = getPropertyDefault(namedFactories, name); assert(noComplain || result); return result; } void GenericDataNodeFactory::storeFactory(std::string const &name, DataNodeArgument const &factory) { // This must be a factory. Because of the use of smart pointers, we can't // enforce that at compile time. The smart pointers are very useful, and // are worth the loss of compile time type checking in this case. The // compiler automatically throws an exception if factory is not of the // right type. factory.getValue< GenericDataNodeFactory >(); // I can't imagine any good reason for reusing a key. Almost certainly this // is a bug. This is probably a result of "clone disease" but it could be // from someone not being very specific or creative and trying to use a key // which already exists. assert(!namedFactories.count(name)); namedFactories[name] = factory; } DataNodeLink *GenericDataNodeFactory::replaceAndFind (DataNodeArgument const &factory, DataNodeListener *listener, int msgId, GenericDataNode *&node, std::string const &name, DataNodeArgument const &value) { return factory.replace(name, value).getValue< GenericDataNodeFactory >() .find(listener, msgId, node); }