Changeset 59f1bc for src/documentation/constructs/qt-gui.dox
- Timestamp:
- Feb 14, 2016, 12:34:29 PM (9 years ago)
- Branches:
- Action_Thermostats, Add_AtomRandomPerturbation, Add_FitFragmentPartialChargesAction, Add_RotateAroundBondAction, Add_SelectAtomByNameAction, Added_ParseSaveFragmentResults, AddingActions_SaveParseParticleParameters, Adding_Graph_to_ChangeBondActions, Adding_MD_integration_tests, Adding_ParticleName_to_Atom, Adding_StructOpt_integration_tests, AtomFragments, Automaking_mpqc_open, AutomationFragmentation_failures, Candidate_v1.5.4, Candidate_v1.6.0, Candidate_v1.6.1, ChangeBugEmailaddress, ChangingTestPorts, ChemicalSpaceEvaluator, CombiningParticlePotentialParsing, Combining_Subpackages, Debian_Package_split, Debian_package_split_molecuildergui_only, Disabling_MemDebug, Docu_Python_wait, EmpiricalPotential_contain_HomologyGraph, EmpiricalPotential_contain_HomologyGraph_documentation, Enable_parallel_make_install, Enhance_userguide, Enhanced_StructuralOptimization, Enhanced_StructuralOptimization_continued, Example_ManyWaysToTranslateAtom, Exclude_Hydrogens_annealWithBondGraph, FitPartialCharges_GlobalError, Fix_BoundInBox_CenterInBox_MoleculeActions, Fix_ChargeSampling_PBC, Fix_ChronosMutex, Fix_FitPartialCharges, Fix_FitPotential_needs_atomicnumbers, Fix_ForceAnnealing, Fix_IndependentFragmentGrids, Fix_ParseParticles, Fix_ParseParticles_split_forward_backward_Actions, Fix_PopActions, Fix_QtFragmentList_sorted_selection, Fix_Restrictedkeyset_FragmentMolecule, Fix_StatusMsg, Fix_StepWorldTime_single_argument, Fix_Verbose_Codepatterns, Fix_fitting_potentials, Fixes, ForceAnnealing_goodresults, ForceAnnealing_oldresults, ForceAnnealing_tocheck, ForceAnnealing_with_BondGraph, ForceAnnealing_with_BondGraph_continued, ForceAnnealing_with_BondGraph_continued_betteresults, ForceAnnealing_with_BondGraph_contraction-expansion, FragmentAction_writes_AtomFragments, FragmentMolecule_checks_bonddegrees, GeometryObjects, Gui_Fixes, Gui_displays_atomic_force_velocity, ImplicitCharges, IndependentFragmentGrids, IndependentFragmentGrids_IndividualZeroInstances, IndependentFragmentGrids_IntegrationTest, IndependentFragmentGrids_Sole_NN_Calculation, JobMarket_RobustOnKillsSegFaults, JobMarket_StableWorkerPool, JobMarket_unresolvable_hostname_fix, MoreRobust_FragmentAutomation, ODR_violation_mpqc_open, PartialCharges_OrthogonalSummation, PdbParser_setsAtomName, PythonUI_with_named_parameters, QtGui_reactivate_TimeChanged_changes, Recreated_GuiChecks, Rewrite_FitPartialCharges, RotateToPrincipalAxisSystem_UndoRedo, SaturateAtoms_findBestMatching, SaturateAtoms_singleDegree, StoppableMakroAction, Subpackage_CodePatterns, Subpackage_JobMarket, Subpackage_LinearAlgebra, Subpackage_levmar, Subpackage_mpqc_open, Subpackage_vmg, Switchable_LogView, ThirdParty_MPQC_rebuilt_buildsystem, TrajectoryDependenant_MaxOrder, TremoloParser_IncreasedPrecision, TremoloParser_MultipleTimesteps, TremoloParser_setsAtomName, Ubuntu_1604_changes, stable
- Children:
- 23221f
- Parents:
- 03e69e
- git-author:
- Frederik Heber <heber@…> (01/06/16 08:36:58)
- git-committer:
- Frederik Heber <heber@…> (02/14/16 12:34:29)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/documentation/constructs/qt-gui.dox
r03e69e r59f1bc 59 59 * there is a QTimer that only updates an object in regular intervals, or 60 60 * because of asynchronous threads. Elsewhen, the slot callback for a 61 * certain signal is called directly. For all of these cases we have to61 * certain signal is called directly. All of these cases we have to 62 62 * accommodate. This is especially problematic with the instantiation and 63 * destruction of objects .63 * destruction of objects that represent atoms and molecules in the World. 64 64 * 65 65 * A clarifying example: Imagine an atom is constructed, the AtomObserver … … 70 70 * 71 71 * The only possible way out is to duplicate information. This is the usual 72 * way how to deal withenvironments with multiple threads. I.e. all the72 * way how to proceed in environments with multiple threads. I.e. all the 73 73 * information that the GUI representants of information inside the World 74 74 * needs to be doubled such that when the original information is destroyed 75 * the representant can still be accessed as long as needed. 75 * the representant can still be accessed as long as needed. Here, we use 76 * the ObservedValue construct of CodePatterns. 76 77 * 77 78 * \subsection qt-gui-general-observedvalue Observed Value … … 100 101 * pieces of information that require more computing resources within the 101 102 * updater. Also, the Cacheable's information can only be obtained as long 102 * as the source of information is still alive. 103 * 104 * Both concepts can be used in threaded environments as mutexed are used to 103 * as the source of information is still alive. However, so far Cacheable's 104 * content is marked invalid when an update signal has been received and 105 * update itself only on request, which is no longer possible when the object 106 * to represent is gone. 107 * 108 * Both concepts can be used in threaded environments as mutexes are used to 105 109 * protect read and write accesses. 106 110 * 107 * \subsection qt-gui-general-signalslot Observer/Observable and Signal/Slot 108 * 109 * In the following we refer to Observer/Observable as "O/O" and to Signal/Slot 110 * as "S/S". 111 * 112 * One thing we need to do is to translate between update() or 113 * recieveNotification() calls from an Observable and subsequent signal/slot 114 * calls. The general idea is to use these ObservedValues as translation 115 * points for small pieces of information and Cacheables for larger pieces. 116 * 117 * However, we need more of these translation points: 118 * -# GLWorldView checks for 119 * -# World's MoleculeInserted 120 * -# World's SelectionChanged 121 * -# WorldTime's TimeChanged 122 * -# each molecule's AtomInserted and AtomRemoved 123 * -# AtomObservable's AtomChanged. 124 * -# ShapeRegistry's ShapedAdded, ShapeRemoved, and SelectionChanged 125 * -# GLMoleculeObject_molecule checks for 126 * -# molecule's AtomInserted, AtomRemoved, AtomMoved, IndexChanged 127 * -# World's SelectionChanged 128 * 111 * \subsection qt-gui-general-observedinstance The observed instance board 112 * 113 * The setup is then as follows: We have two distinct realms, the World (with 114 * atoms and molecules) on the one side and the QtGUI (with visual 115 * representations of atoms and molecules) on the other side. 116 * 117 * There is an interface between this world such that the destruction of an 118 * atom does not directly invalidate its visual representation. This interface 119 * between the two realms is contained in the class QtObservedInstanceBoard, 120 * which is a singleton and is similar to the World instance in the World realm 121 * for the QtGui realm. 122 * 123 * All properties, e.g. the position of an element, relevant to the QtGUI are 124 * duplicated as ObservedValues. Properties associated to the same instance in 125 * the World, e.g. the same atom, are combined into a QtObservedAtom instance, 126 * and similarly QtObservedMolecule for molecule. All of these observed 127 * instances are placed into ObservedValuesContainer which are contained in 128 * the interface QtObservedInstanceBoard. 129 * 130 * The sequence of events is then as follows (here exemplified with an atom): 131 * -# an atom is created (World::createAtom()), the World notifies about it 132 * via its World::AtomInserted channel. 133 * -# QtObservedInstanceBoard is signOn()ed to this channel and instantiates 134 * a new QtObservedAtom which is placed into its respective 135 * ObservedValuesContainer. 136 * -# on instantiation of QtObservedAtom a vector of specific ObservedValues is 137 * created, one for each property (position, element, bond count, ...). 138 * Each signOn()s to the respective atom's channel. Also the QtObservedAtom 139 * signOn()s to each of these channels as it converts these notifications 140 * into Qt signals (and the updated value can be accessed via getters from 141 * the QtObservedAtom instance). The QtObservedInstanceBoard is notified 142 * of this with the instance being marked as connected. 143 * -# when the atom is destroyed (World::destroyAtom()), being an Observable 144 * it will call subjectKilled() on all its channels. The 145 * ObservedValue_wCallback announces this subjectKilled() via the callback 146 * function which notifies QtObservedAtom. Once all subjectKilled(), for 147 * each observed value and for QtObservedAtom itself, have been received, 148 * the QtObservedInstanceBoard is notified by the instance now being 149 * marked as disconnected and ready for erase. 150 * -# then the QtObservedInstanceBoard removes the instance from its 151 * ObservedValuesContainer. 152 * 153 * Note however that the instance is a shared_ptr and will continue to exist 154 * and therefore its getters will still deliver the last piece of information 155 * before the atom was destroyed until all shared_ptrs are released. Hence, 156 * the QtGui may safely continue using the pointer. 157 * 158 * As new observed instances may come in immediately having the same id and 159 * as it is difficult to keep track who got its observed instance already 160 * and who not, a soft fail is required. I.e. of the QtObservedInstanceBoard 161 * returns an empty shared_ptr this means that the object -- despite any 162 * received (and probably delayed) signal -- has been destroyed and should 163 * not be displayed, updated by, ... whatsoever. 164 * 165 * \subsection qt-gui-general-signalslot Details on the slot connections 166 * 167 * Qt's event system does not guarantee that events are always processed in 168 * the order they are emitted. This is because connections can be defined 169 * as direct or queued (or both with auto). Direct connections will always 170 * be executed as direct function calls, i.e. immediately. Queued connections 171 * however are inserted into Qt's event queue and may even get processed by 172 * a different thread. 173 * 174 * We have to take care of this. 175 * 176 * Basically what we do in QtObservedInstanceBoard and the observed instances 177 * of type QtObservedAtom and QtObservedMolecule is that we translate between 178 * the Observer/Observable (O/O) system of CodePatterns with its callback 179 * functions and the event system of Qt with its Signal/Slot (S/S). 180 * 181 * That is in the recieveNotification() functions many "emit()"s can be found. 182 * 183 * Furthermore, signals are used in a specific way to ensure synchronicity. 184 * This is only a problem with the visual representation as we there find a 185 * a nested problem: First molecules, then atoms belonging to a certain 186 * molecule. This enforces a certain sequence of events and thus of signals. 187 * 188 * \subsubsection qt-gui-general-signalslot-glworldscene Details on GLWorldScene 189 * 190 * The central place for all events is the GLWorldScene instance. There 191 * signals from QtObservedInstanceBoard for insertion and removal of both atoms 192 * and molecules are caught. Insertion of molecules is dealt with directly, 193 * we sign on to the inserted&removed channels for its atoms, then we emit 194 * a queued signal to actually instantiate the GLMoleculeObject_molecule. 195 * 196 * Until its instantiation we store incoming signals in the 197 * GLWorldScene::MoleculeMissedStateMap, protected by a mutex to enforce atomic 198 * access. After it has been instantiated (and all stored signals have been 199 * processed), they are relayed onto the specific instance. However, we do not 200 * do this via emits but by directly using Qt's invokeMethod() which allows 201 * to trigger queued events. This way it is done in a likewise manner whether 202 * it has been a stored or live signal that was received. 203 * 204 * \subsubsection qt-gui-general-signalslot-other Details on other signals 205 * 206 * All other signals that only change the property of a visual representation, 207 * e.g. the element of an atom, is directly processed by, in this case, the 208 * GLMoleculeObject_atom connected to QtObservedAtom. 209 . * 129 210 * \section qt-gui-qt3d Qt3D and the way to get atoms and bonds displayed 130 211 * … … 146 227 * of an element-specific color at the atom's position. The atom relies 147 228 * on its representants to be contain all required information but it 148 * is also signOn() to the atom itself whose O/O are translated to S/S149 * for processing whenever desired.229 * is also signOn() to the QtObservedAtom itself whose O/O are translated to 230 * S/S for processing whenever desired. 150 231 * 151 232 * Next comes the GLMoleculeObject_bond which displays a cylinder between … … 158 239 * 159 240 * Parallel to these are GLMoleculeObject_shape which display the surface 160 * of a selected shape. A shape in general does not change after instant ation,241 * of a selected shape. A shape in general does not change after instantiation, 161 242 * hence the shape lives with the information it gets on instantiation till 162 243 * it dies. … … 168 249 * molecules. The molecule also needs ObservedValues for its bounding box 169 250 * (used to show when it's selected), the index, the selection status, 170 * and the list of atom ids. As Cacheable we use the tesselation structure.251 * and the list of atom ids. 171 252 * 172 253 * \section qt-gui-cases Sample cases … … 270 351 * they automatically clear the info box. 271 352 * 272 * \date 201 5-07-15353 * \date 2016-01-08 273 354 */
Note:
See TracChangeset
for help on using the changeset viewer.