00001 /** 00002 * \file example/ExampleDecorator.h \brief Add a name to a particle. 00003 * 00004 * Copyright 2007-2010 IMP Inventors. All rights reserved. 00005 * 00006 */ 00007 00008 #ifndef IMPEXAMPLE_EXAMPLE_DECORATOR_H 00009 #define IMPEXAMPLE_EXAMPLE_DECORATOR_H 00010 00011 #include "example_config.h" 00012 00013 #include <IMP/core/core_macros.h> 00014 #include <IMP/Particle.h> 00015 #include <IMP/Model.h> 00016 #include <IMP/Decorator.h> 00017 #include <IMP/exception.h> 00018 00019 IMPEXAMPLE_BEGIN_NAMESPACE 00020 00021 //! A simple decorator which adds a name to a particle. 00022 /** A decorator adds functionality to a particle and ensures that invariants 00023 are preserved. In this case, the functionality is the setting and access 00024 of a name for the Particle and the invariant is that the name is always 00025 non-empty. 00026 00027 The source code is as follows: 00028 \include ExampleDecorator.h 00029 \include ExampleDecorator.cpp 00030 */ 00031 class IMPEXAMPLEEXPORT ExampleDecorator: public Decorator 00032 { 00033 /* Use a static variable in a static method to create the key 00034 so that it is only done once and is only done when it is first 00035 needed. Lazy initialization of keys makes \imp more efficient as 00036 Particles do not have to allocate memory for ununsed keys. 00037 */ 00038 static StringKey get_name_key(); 00039 00040 public: 00041 00042 //! Add a name to the particle 00043 /** The create function should take arguments which allow 00044 the initial state of the Decorator to be reasonable (i.e. 00045 make sure there is a non-empty name). 00046 */ 00047 static ExampleDecorator setup_particle(Particle *p, std::string name) { 00048 IMP_USAGE_CHECK(!name.empty(), "The name cannot be empty."); 00049 p->add_attribute(get_name_key(), name); 00050 ExampleDecorator ret(p); 00051 return ret; 00052 } 00053 00054 //! return true if the particle has a name 00055 static bool particle_is_instance(Particle *p) { 00056 return p->has_attribute(get_name_key()); 00057 } 00058 //! Set the name of the particle 00059 void set_name(std::string name) { 00060 IMP_USAGE_CHECK(!name.empty(), "The name cannot be empty."); 00061 get_particle()->set_value(get_name_key(), name); 00062 } 00063 00064 //! Get the name of the particle 00065 std::string get_name() const { 00066 return get_particle()->get_value(get_name_key()); 00067 } 00068 /* Declare the basic constructors and the cast function.*/ 00069 IMP_DECORATOR(ExampleDecorator, Decorator); 00070 }; 00071 00072 // Make it so the C++ operator<< can be used. 00073 IMP_OUTPUT_OPERATOR(ExampleDecorator); 00074 00075 00076 /** Define a collection of them. Also look at example.i*/ 00077 typedef Decorators<ExampleDecorator, Particles> ExampleDecorators; 00078 00079 IMPEXAMPLE_END_NAMESPACE 00080 00081 #endif /* IMPEXAMPLE_EXAMPLE_DECORATOR_H */