source: branches/species/PARSIMONY/ap_main_type.hxx

Last change on this file was 19654, checked in by westram, 5 weeks ago
  • reintegrates 'macros' into 'trunk'
    • improves program termination (#867)
      • introduces MacroExitor classes
        • handles confirmation (to quit)
        • waits for macros to finish, then exits w/o confirmation
        • provides specialized termination for different programs via derived classes
          • has been implemented for "normal" arb and merge-tool.
      • introduces ARB_disconnect_from_db
        • generalizes code to terminate all interconnections between GUI, database and macro-ability
        • allow to install atdisconnect-callbacks
          • usable by modules operating on a database; allow to inform module that database will vanish.
        • now used by all arb applications to disconnect from all their database(s), except the properties.
    • fixes some broken behavior
      • merge-tool
        • crashed when quitting via macro
        • wrong restarts, if originally started with arguments,
      • importer
        • failed to record/playback macros
        • crashed in modules operating on the temporary import database
      • database browser
        • crashed on disappearing database
  • adds: log:branches/macros@19620:19653
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 5.5 KB
Line 
1// ================================================================ //
2//                                                                  //
3//   File      : ap_main_type.hxx                                   //
4//   Purpose   :                                                    //
5//                                                                  //
6//   Institute of Microbiology (Technical University Munich)        //
7//   http://www.arb-home.de/                                        //
8//                                                                  //
9// ================================================================ //
10
11#ifndef AP_MAIN_TYPE_HXX
12#define AP_MAIN_TYPE_HXX
13
14#ifndef AP_BUFFER_HXX
15#include "AP_buffer.hxx"
16#endif
17#ifndef PARS_DTREE_HXX
18#include "pars_dtree.hxx"
19#endif
20
21class UserFrame {
22    Level frameLevel;
23    // @@@ store more information here (e.g. comment, parsimony value, timestamp)
24public:
25    UserFrame(Level level) : frameLevel(level) {}
26    Level get_level() const { return frameLevel; }
27};
28
29typedef AP_STACK<UserFrame> UserFrameStack;
30
31class AP_main : virtual Noncopyable {
32    NodeStack             *currFrame;
33    FrameStack             frames;
34    UserFrameStack         user_frames;
35    Level                  frameLevel;
36    AWT_graphic_parsimony *agt;       // provides access to tree!
37    StackFrameData        *frameData; // saved/restored by remember/revert
38    GBDATA                *gb_main;
39
40    void push_nodes_changed_since(Level wanted_frameLevel);
41    void rollback_to(Level wanted_frameLevel);
42
43public:
44    AP_main()
45        : currFrame(NULp),
46          frameLevel(0),
47          agt(NULp),
48          frameData(NULp),
49          gb_main(NULp)
50    {}
51    ~AP_main() {
52        if (gb_main) GB_close(gb_main);
53        ap_assert(!frameData);
54        delete currFrame;
55    }
56
57    void set_tree_root(AWT_graphic_parsimony *agt_);
58    AWT_graphic_parsimony *get_graphic_tree() { return agt; }
59    AP_pars_root *get_tree_root() const { return agt->get_tree_root(); }
60
61    DEFINE_READ_ACCESSORS(AP_tree_nlen*, get_root_node, agt->get_root_node());
62
63    GBDATA *get_gb_main() const {
64        ap_assert(gb_main); // you need to call open() before you can use get_gb_main()
65        return gb_main;
66    }
67    const char *get_aliname() const;
68    size_t get_user_push_counter() const { return user_frames.count_elements(); }
69    Level get_frameLevel() const { return frameLevel; }
70
71    GB_ERROR open(const char *db_server);
72    void disconnect_from_db(AW_root *aw_root);
73
74    bool push_node(AP_tree_nlen *node, AP_STACK_MODE);
75
76    void remember_user_state();
77    void revert_user_state();
78    // @@@ add accept_user_state (#632)
79
80    void remember();
81    void revert();
82    void accept();
83    void accept_all() { while (currFrame) accept(); }
84
85#if defined(UNIT_TESTS)
86    void remember_whole_tree(); // dont use in production
87#endif
88
89    void accept_if(bool cond) { if (cond) accept(); else revert(); }
90    void revert_if(bool cond) { accept_if(!cond); }
91
92    bool remember_and_rollback_to(Level wanted_frameLevel) {
93        if (wanted_frameLevel>=frameLevel) {
94            return false;
95        }
96        remember();
97        push_nodes_changed_since(wanted_frameLevel);
98        rollback_to(wanted_frameLevel);
99        return true;
100    }
101    bool remember_and_rollback_to_previous() {
102        /*! tree is modified into the same (or equiv) state as it would be done by calling pop(),
103         * but the current state is pushed onto the stack.
104         * Calling pop() afterwards will undo this operation.
105         */
106        return remember_and_rollback_to(frameLevel-1);
107    }
108
109#if defined(PROVIDE_PRINT)
110    void print(std::ostream& out);
111    void print2file(const char *file_in_ARBHOME);
112    void dump2file(const char *name) {
113        static int counter = 0;
114
115        if (counter == 0) {
116            system("rm $ARBHOME/[0-9][0-9]_*.log");
117        }
118
119        char *numbered_name = GBS_global_string_copy("%02i_%s.log", ++counter, name);
120        print2file(numbered_name);
121        free(numbered_name);
122    }
123
124#endif
125
126#if defined(ASSERTION_USED) || defined(UNIT_TESTS)
127    Validity revert_will_produce_valid_tree() {
128        ASSERT_VALID_TREE(get_root_node());
129        ASSERT_RESULT(bool, true, remember_and_rollback_to_previous()); // otherwise stack is empty
130        Validity valid(tree_is_valid(get_root_node(), false));
131        revert();                                                       // undo remember_and_rollback_to_previous
132        ASSERT_VALID_TREE(get_root_node());
133        return valid;
134    }
135    Validity all_available_reverts_will_produce_valid_trees() {
136        ASSERT_VALID_TREE(get_root_node());
137        Level pops_avail = get_frameLevel();
138        Validity valid;
139        for (Level rollback = 1; rollback<=pops_avail && valid; ++rollback) {
140            Level wanted_level = pops_avail-rollback;
141            ASSERT_RESULT(bool, true, remember_and_rollback_to(wanted_level)); // otherwise stack is empty
142
143            // dump2file(GBS_global_string("after_remember_and_rollback_to_%lu", wanted_level));
144            valid = Validity(tree_is_valid(get_root_node(), false));
145
146            revert(); // undo remember_and_rollback_to
147            // dump2file("after_pop_to_undo__remember_and_rollback_to");
148
149            ASSERT_VALID_TREE(get_root_node());
150        }
151        return valid;
152    }
153#endif
154
155    inline AP_tree_nlen *makeNode(AP_pars_root *proot);
156    inline AP_tree_edge *makeEdge(AP_tree_nlen *n1, AP_tree_nlen *n2);
157    inline void destroyNode(AP_tree_nlen *node);
158    inline void destroyEdge(AP_tree_edge *edge);
159};
160
161#else
162#error ap_main_type.hxx included twice
163#endif // AP_MAIN_TYPE_HXX
Note: See TracBrowser for help on using the repository browser.