There is already a signal for this. Actually there are two. For all
primitives there is a signal when a primitive gets added
Molecule::primitiveAdded(Primitive *), a signal when a primitive gets
deleted Molecule::primitiveRemoved(Primitive *), and when you modify a
molecule you are supposed to call Molecule::update() which emits a
signal Molecule::updated() and also emits a signal
::primitiveUpdated(Primitive ) with the parameter equal to the molecule
that had ::update() called on it. As a side: when you update only one
atom you are to call Atom::update() and that emits
Molecule::primitiveUpdated(<atom that got called ::update() on>). This
means we can tell things “hey, only this single atom got updated”. The
versatility of this is that we can connect a single slot to the three
Molecule::primitive functions and conveniently…
Molecule::primitiveUpdate(Primitive *) is also emitted when the molecule
itself is updated, with the parameter of the molecule itself.
Alternatively you can connect to Molecule::updated() but this is not as
dynamic as you don’t get a pointer to the primitive itself.
However, there are a few things i’m curious about. Remember that
engines keep an internal list of the primitives they are to render. So
does the ribbon engine ALWAYS have to work on a molecule or does it work
on individual atoms or residues? Also there is a virtual function
Engine::updatePrimitive() that gets called when a primitive is updated
in the main code. So your engine only needs to reimplement this
function and booyah, you now can cache your stuff. But you would also
probably want to reimplement Engine::addPrimitive and
Engine::removePrimitive also.
Tools are a little different from engines. We need to be careful here
design wise. If there is stuff to improve performance for graphics then
it should go in the Engines. If this information needs to be available
for the tools for some reason (i don’t have a good example) then we need
to rethink our tools.
So far so good with following a Model-View-Controller architecture so we
should think about it that way.
Engines+GLWidget == View
Tools + Extensions == Controller
Molecule == Model
In this philosophy the view basically gives us a representation of the
model. The view should NOT directly interact with the model. To do so
the view relies on the controller(s) which use the view and input from
the user to modify the model. Now we could, with very little change,
make it so that Tools have a Tool::initialize(Molecule *mol) and
Tool::reset() or something like that but i’m somewhat hesitant to do
that right away because this point the Tool has access to the model
because of the GLWidget.
One thing which is bad is to save information when mouseMove /
mousePressed functions get called. This is bad:
void MyTool::mousePressed(GLWidget *widget, …)
{
m_mol = widget->molecule();
…
}
It can work but it’s a hack for a bad API. What if the GLWidget loads
a new molecule and we don’t properly clear our ‘m_mol’ pointer. Bugs
can easily crop up and they’re a pain the ass to track down. If Tools
need access to Molecule all the time (and remember, one instance of a
tool per molecule) then we should put in the initialization functions.
I should try to write more about this on the WiKi. And comments feel
free.
–
Donald
(Fri, Oct 26, 2007 at 08:57:35PM -0400) “Marcus D. Hanwell” marcus@cryos.org:
Hi,
As I have been working on the ribbon code and looking forward to adding
support for surfaces it becomes more apparent we need a signal for when the
molecule is changed. I remember Donald mentioning something about it months
ago but as far as I am aware this does not currently exist.
In order to get reasonable performance for things like ribbons and surfaces
the calculations should be done once for the molecule as it is loaded and
then cached. If the molecule is changed a signal would be emitted and the
engines/tools that need it could receive the signal and recalculate if they
are active.
This would mean any tool or extension that changes any atom or bond would need
to emit this signal. Does this seem like a reasonable approach? Are there any
alternative methodologies I should consider?
Opinions welcome.
Thanks,
Marcus
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
Avogadro-devel mailing list
Avogadro-devel@lists.sourceforge.net
avogadro-devel List Signup and Options