[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [IMP-dev] Not really faking objects



They should be called decorators, not bundles. Here is a cleaned version.

class XYZDecorator {
	static FloatKey kx_, ky_, kz_;
public:
	XYZDecorator(Particle*p): p_(p){}

	bool get_is_initialized() {
return p_->has_attribute(kx_) && p_->has_attribute(ky_) && p_- >has_attribute(kz_);
	}

static XYZDecorator::Pointer initialize(Float x=nan, Float y=nan, Float z=nan) {
		IMP_assert(!is_instance(p_));
		p_->add_attribute(kx_, x);
		p_->add_attribute(ky_, y);
		p_->add_attribute(kz_, z);
	}

	Float get_x() const {
		return p_->get_attribute(kx_);
	}

	void set_x(Float x) const {
		return p_->set_attribute(kx_, x);
	}
	// etc
};

the user calls XYZDecorator xyz(p); then p.initialize(1,2,3); if needed
p.get_x(); etc.



Daniel Russel wrote:
To elaborate further on my proposal from last night, a particle bundle would look like the following (incorporating some unrelated proposed changes)

class XYZBundle {
	static FloatKey kx_, ky_, kz_;
public:
	XYZBundle(Particle*p): p_(p){}
	static bool is_instance(Particle *p) {
return p->has_attribute(kx_) && p->has_attribute(ky_) && p- >has_attribute(kz_);
	}
	typedef std::auto_ptr<XYZBundle> Pointer;
	
	Pointer cast(Pointer *p) {
		if (!is_instance(p)) return Pointer();
		else return Pointer(new XYZBundle(p));
	}

	// either
	static XYZBundle::Pointer initialize(Particle *p) {
		p->add_attribute(kx_, 0);
		p->add_attribute(ky_, 0);
		p->add_attribute(kz_, 0);
		return Pointer(new XYZBundle(p));
	}
	// or
static XYZBundle::Pointer initialize(Particle *p, Float x, Float y, Float z) {
		p->add_attribute(kx_, x);
		p->add_attribute(ky_, y);
		p->add_attribute(kz_, z);
		return Pointer(new XYZBundle(p));
	}
	Float get_x() const {
		return p->get_attribute(kx_);
	}
	void set_x(Float x) const {
		return p->set_attribute(kx_, x);
	}
	// etc
};

The user class
XYZBundle::Pointer xyzp= XYZBundle::initialize(p) to add the right fields
or
XYZBundle::Pointer xyzp= XYZBundle::cast(p) to use.

I am a bit uncomfortable about the faking aspect of the design especially without working reference counting. Since Bundles don't need to get passed back and forth from python, we could make the reference counting work. It might be better to just allocate Bundles on the stack. This removes a memory management issue at the cost of eliminating the possibility of using a NULL pointer to signify failure. So things would have to look more like

class XYZBundle {
	static FloatKey kx_, ky_, kz_;
public:
	XYZBundle(Particle*p): p_(p){if (!is_instance(p)) p_=NULL;}

	bool get_is_valid() const {return p_ != NULL;}

	static bool is_instance(Particle *p) {
return p->has_attribute(kx_) && p->has_attribute(ky_) && p- >has_attribute(kz_);
	}

	// either
	static XYZBundle initialize(Particle *p) {
		IMP_assert(!is_instance(p));
		p->add_attribute(kx_, 0);
		p->add_attribute(ky_, 0);
		p->add_attribute(kz_, 0);
		return XYZBundle(p);
	}
	// or
static XYZBundle::Pointer initialize(Particle *p, Float x, Float y, Float z) {
		IMP_assert(!is_instance(p));
		p->add_attribute(kx_, x);
		p->add_attribute(ky_, y);
		p->add_attribute(kz_, z);
		return XYZBundle(p);
	}
	Float get_x() const {
		return p->get_attribute(kx_);
	}
	void set_x(Float x) const {
		return p->set_attribute(kx_, x);
	}
	// etc
};

the the user calls
XYZBundle xyzb(p); and xyzb.is_valid() to manipulate a Particle
and
XYZBundle xyzb= XYZBundle::initialize(p); to initialize.



_______________________________________________
IMP-dev mailing list

https://salilab.org/mailman/listinfo/imp-dev