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

[IMP-dev] Faking objects



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.