From f76b4e53a987a755d1b3f7b67cdb8d48e1b63ff5 Mon Sep 17 00:00:00 2001 From: Cary Sandvig Date: Sat, 28 Apr 2001 00:06:58 +0000 Subject: [PATCH] remove at least one frame of latency in Gui stuff --- panda/src/event/throw_event.I | 44 ++++++++++++++++ panda/src/event/throw_event.h | 19 +++++++ panda/src/gui/guiButton.cxx | 90 ++++++++++++++++++++------------ panda/src/gui/guiManager.I | 11 ++-- panda/src/gui/guiManager.cxx | 15 ++++-- panda/src/gui/guiManager.h | 5 +- panda/src/gui/guiRollover.cxx | 10 ++-- panda/src/tform/mouseWatcher.I | 24 +++++++++ panda/src/tform/mouseWatcher.cxx | 4 ++ panda/src/tform/mouseWatcher.h | 6 +++ 10 files changed, 182 insertions(+), 46 deletions(-) diff --git a/panda/src/event/throw_event.I b/panda/src/event/throw_event.I index 5e70a831ae..18efd11620 100644 --- a/panda/src/event/throw_event.I +++ b/panda/src/event/throw_event.I @@ -44,5 +44,49 @@ throw_event(const string &event_name, EventQueue::get_global_event_queue()->queue_event(event); } +//////////////////////////////////////////////////////////////////////////// +INLINE void +throw_event_directly(EventHandler& handler, + const CPT_Event &event) { + handler.dispatch_event(event); +} +INLINE void +throw_event_directly(EventHandler& handler, + const string &event_name) { + handler.dispatch_event(new Event(event_name)); +} + +INLINE void +throw_event_directly(EventHandler& handler, + const string &event_name, + const EventParameter &p1) { + Event *event = new Event(event_name); + event->add_parameter(p1); + handler.dispatch_event(event); +} + +INLINE void +throw_event_directly(EventHandler& handler, + const string &event_name, + const EventParameter &p1, + const EventParameter &p2) { + Event *event = new Event(event_name); + event->add_parameter(p1); + event->add_parameter(p2); + handler.dispatch_event(event); +} + +INLINE void +throw_event_directly(EventHandler& handler, + const string &event_name, + const EventParameter &p1, + const EventParameter &p2, + const EventParameter &p3) { + Event *event = new Event(event_name); + event->add_parameter(p1); + event->add_parameter(p2); + event->add_parameter(p3); + handler.dispatch_event(event); +} diff --git a/panda/src/event/throw_event.h b/panda/src/event/throw_event.h index 57f2b7bd65..40000edcf2 100644 --- a/panda/src/event/throw_event.h +++ b/panda/src/event/throw_event.h @@ -24,6 +24,25 @@ INLINE void throw_event(const string &event_name, const EventParameter &p2, const EventParameter &p3); +#include "eventHandler.h" + +INLINE void throw_event_directly(EventHandler& handler, + const CPT_Event &event); +INLINE void throw_event_directly(EventHandler& handler, + const string &event_name); +INLINE void throw_event_directly(EventHandler& handler, + const string &event_name, + const EventParameter &p1); +INLINE void throw_event_directly(EventHandler& handler, + const string &event_name, + const EventParameter &p1, + const EventParameter &p2); +INLINE void throw_event_directly(EventHandler& handler, + const string &event_name, + const EventParameter &p1, + const EventParameter &p2, + const EventParameter &p3); + #include "throw_event.I" #endif diff --git a/panda/src/gui/guiButton.cxx b/panda/src/gui/guiButton.cxx index 8d4830c78a..69733f7d8e 100644 --- a/panda/src/gui/guiButton.cxx +++ b/panda/src/gui/guiButton.cxx @@ -56,6 +56,21 @@ inline void GetExtents(GuiLabel* v, GuiLabel* w, GuiLabel* x, GuiLabel* y, } } +inline void my_throw(GuiManager* mgr, const string& name, + const EventParameter& p) { + throw_event(name, p); + if (mgr != (GuiManager*)0L) + throw_event_directly(*(mgr->get_private_handler()), name, p); +} + +inline void my_throw(GuiManager* mgr, const string& name, + const EventParameter& p1, + const EventParameter& p2) { + throw_event(name, p1, p2); + if (mgr != (GuiManager*)0L) + throw_event_directly(*(mgr->get_private_handler()), name, p1, p2); +} + static void enter_button(CPT_Event e) { const MouseWatcherRegion* rgn = DCAST(MouseWatcherRegion, e->get_parameter(0).get_ptr()); GuiButton* val = find_in_buttons_map(rgn); @@ -141,6 +156,7 @@ void GuiButton::switch_state(GuiButton::States nstate) { << ")" << endl; } _state = nstate; + const EventParameter paramthis = EventParameter(this); // deal with new state switch (_state) { case NONE: @@ -163,7 +179,7 @@ void GuiButton::switch_state(GuiButton::States nstate) { if (gui_cat->is_debug()) gui_cat->debug() << "throwing _up_event '" << _up_event << "'" << endl; #endif /* _DEBUG */ - throw_event(_up_event, EventParameter(this)); + my_throw(_mgr, _up_event, paramthis); #ifdef _DEBUG } else if (gui_cat->is_debug()) gui_cat->debug() << "_up_event is empty!" << endl; @@ -189,7 +205,7 @@ void GuiButton::switch_state(GuiButton::States nstate) { gui_cat->debug() << "throwing _up_rollover_event '" << _up_rollover_event << "'" << endl; #endif /* _DEBUG */ - throw_event(_up_rollover_event, EventParameter(this)); + my_throw(_mgr, _up_rollover_event, paramthis); #ifdef _DEBUG } else if (gui_cat->is_debug()) gui_cat->debug() << "_up_rollover_event is empty!" << endl; @@ -210,7 +226,7 @@ void GuiButton::switch_state(GuiButton::States nstate) { gui_cat->debug() << "throwing _up_event '" << _up_event << "'" << endl; #endif /* _DEBUG */ - throw_event(_up_event, EventParameter(this)); + my_throw(_mgr, _up_event, paramthis); #ifdef _DEBUG } else if (gui_cat->is_debug()) gui_cat->debug() << "_up_event is empty!" << endl; @@ -240,7 +256,7 @@ void GuiButton::switch_state(GuiButton::States nstate) { gui_cat->debug() << "throwing _down_event '" << _down_event << "'" << endl; #endif /* _DEBUG */ - throw_event(_down_event, EventParameter(this)); + my_throw(_mgr, _down_event, paramthis); #ifdef _DEBUG } else if (gui_cat->is_debug()) gui_cat->debug() << "_down_event is empty!" << endl; @@ -266,7 +282,7 @@ void GuiButton::switch_state(GuiButton::States nstate) { gui_cat->debug() << "throwing _down_rollover_event '" << _down_rollover_event << "'" << endl; #endif /* _DEBUG */ - throw_event(_down_rollover_event, EventParameter(this)); + my_throw(_mgr, _down_rollover_event, paramthis); #ifdef _DEBUG } else if (gui_cat->is_debug()) gui_cat->debug() << "_down_rollover_event is empty!" << endl; @@ -287,7 +303,7 @@ void GuiButton::switch_state(GuiButton::States nstate) { gui_cat->debug() << "throwing _down_event '" << _down_event << "'" << endl; #endif /* _DEBUG */ - throw_event(_down_event, EventParameter(this)); + my_throw(_mgr, _down_event, paramthis); #ifdef _DEBUG } else if (gui_cat->is_debug()) gui_cat->debug() << "_down_event is empty!" << endl; @@ -315,7 +331,7 @@ void GuiButton::switch_state(GuiButton::States nstate) { gui_cat->debug() << "throwing _inactive_event '" << _inactive_event << "'" << endl; #endif /* _DEBUG */ - throw_event(_inactive_event, EventParameter(this)); + my_throw(_mgr, _inactive_event, paramthis); } } _rgn->set_suppress_below(false); @@ -337,7 +353,7 @@ void GuiButton::switch_state(GuiButton::States nstate) { gui_cat->debug() << "throwing _inactive_event '" << _inactive_event << "'" << endl; #endif /* _DEBUG */ - throw_event(_inactive_event, EventParameter(this)); + my_throw(_mgr, _inactive_event, paramthis); } } _rgn->set_suppress_below(false); @@ -414,8 +430,10 @@ void GuiButton::run_button_up(void) const { if (gui_cat->is_debug()) gui_cat->debug() << "doing work" << endl; #endif /* _DEBUG */ - _eh->remove_hook(_up_event, GuiButton::behavior_up); - _eh->remove_hook(_up_rollover_event, GuiButton::behavior_up); + _mgr->get_private_handler()->remove_hook(_up_event, GuiButton::behavior_up); + _mgr->get_private_handler()->remove_hook(_up_rollover_event, + GuiButton::behavior_up); + const EventParameter paramthis = EventParameter(this); if (!_behavior_event.empty()) { if (_have_event_param) { #ifdef _DEBUG @@ -424,15 +442,15 @@ void GuiButton::run_button_up(void) const { << "' with parameter (" << _event_param << ")" << endl; #endif /* _DEBUG */ - throw_event(_behavior_event, EventParameter(this), - EventParameter(_event_param)); + const EventParameter paramparam = EventParameter(_event_param); + my_throw(_mgr, _behavior_event, paramthis, paramparam); } else { #ifdef _DEBUG if (gui_cat->is_debug()) gui_cat->debug() << "throwing behavior event '" << _behavior_event << "'" << endl; #endif /* _DEBUG */ - throw_event(_behavior_event, EventParameter(this)); + my_throw(_mgr, _behavior_event, paramthis); } } if (_behavior_functor != (GuiBehavior::BehaviorFunctor*)0L) @@ -452,8 +470,9 @@ void GuiButton::run_button_down(void) const { gui_cat->debug() << "doing work, up_event is '" << _up_event << "' '" << _up_rollover_event << "'" << endl; #endif /* _DEBUG */ - _eh->add_hook(_up_event, GuiButton::behavior_up); - _eh->add_hook(_up_rollover_event, GuiButton::behavior_up); + _mgr->get_private_handler()->add_hook(_up_event, GuiButton::behavior_up); + _mgr->get_private_handler()->add_hook(_up_rollover_event, + GuiButton::behavior_up); } GuiButton::GuiButton(const string& name, GuiLabel* up, GuiLabel* down) @@ -523,11 +542,13 @@ GuiButton::~GuiButton(void) { string name = get_name(); buttons.erase(this->_rgn.p()); if ((buttons.size() == 0) && added_hooks) { + /* _eh->remove_hook("gui-enter", enter_button); _eh->remove_hook("gui-exit" + get_name(), exit_button); _eh->remove_hook("gui-button-press", click_button_down); _eh->remove_hook("gui-button-release", click_button_up); added_hooks = false; + */ } if (_behavior_functor != (GuiBehavior::BehaviorFunctor*)0L) @@ -538,10 +559,12 @@ GuiButton::~GuiButton(void) { void GuiButton::manage(GuiManager* mgr, EventHandler& eh) { if (!added_hooks) { - eh.add_hook("gui-enter", enter_button); - eh.add_hook("gui-exit", exit_button); - eh.add_hook("gui-button-press", click_button_down); - eh.add_hook("gui-button-release", click_button_up); + mgr->get_private_handler()->add_hook("gui-enter", enter_button); + mgr->get_private_handler()->add_hook("gui-exit", exit_button); + mgr->get_private_handler()->add_hook("gui-button-press", + click_button_down); + mgr->get_private_handler()->add_hook("gui-button-release", + click_button_up); added_hooks = true; } if (_mgr == (GuiManager*)0L) { @@ -556,10 +579,12 @@ void GuiButton::manage(GuiManager* mgr, EventHandler& eh) { void GuiButton::manage(GuiManager* mgr, EventHandler& eh, Node* n) { if (!added_hooks) { - eh.add_hook("gui-enter", enter_button); - eh.add_hook("gui-exit", exit_button); - eh.add_hook("gui-button-press", click_button_down); - eh.add_hook("gui-button-release", click_button_up); + mgr->get_private_handler()->add_hook("gui-enter", enter_button); + mgr->get_private_handler()->add_hook("gui-exit", exit_button); + mgr->get_private_handler()->add_hook("gui-button-press", + click_button_down); + mgr->get_private_handler()->add_hook("gui-button-release", + click_button_up); added_hooks = true; } if (_mgr == (GuiManager*)0L) { @@ -653,20 +678,18 @@ void GuiButton::start_behavior(void) { return; if (!this->is_active()) return; - _eh->add_hook(_down_event, GuiButton::behavior_down); - _eh->add_hook(_down_rollover_event, GuiButton::behavior_down); + _mgr->get_private_handler()->add_hook(_down_event, GuiButton::behavior_down); + _mgr->get_private_handler()->add_hook(_down_rollover_event, + GuiButton::behavior_down); } void GuiButton::stop_behavior(void) { GuiBehavior::stop_behavior(); if (_mgr == (GuiManager*)0L) return; - _eh->remove_hook(_up_event, GuiButton::behavior_up); - _eh->remove_hook(_up_rollover_event, GuiButton::behavior_up); - /* - _eh->remove_hook(_down_event, GuiButton::behavior_down); - _eh->remove_hook(_down_rollover_event, GuiButton::behavior_down); - */ + _mgr->get_private_handler()->remove_hook(_up_event, GuiButton::behavior_up); + _mgr->get_private_handler()->remove_hook(_up_rollover_event, + GuiButton::behavior_up); } void GuiButton::reset_behavior(void) { @@ -674,8 +697,9 @@ void GuiButton::reset_behavior(void) { if (_mgr == (GuiManager*)0L) return; this->start_behavior(); - _eh->remove_hook(_up_event, GuiButton::behavior_up); - _eh->remove_hook(_up_rollover_event, GuiButton::behavior_up); + _mgr->get_private_handler()->remove_hook(_up_event, GuiButton::behavior_up); + _mgr->get_private_handler()->remove_hook(_up_rollover_event, + GuiButton::behavior_up); } void GuiButton::set_priority(GuiItem* i, const GuiItem::Priority p) { diff --git a/panda/src/gui/guiManager.I b/panda/src/gui/guiManager.I index cadac2213b..3203df2515 100644 --- a/panda/src/gui/guiManager.I +++ b/panda/src/gui/guiManager.I @@ -3,10 +3,9 @@ // //////////////////////////////////////////////////////////////////// -INLINE GuiManager::GuiManager(MouseWatcher* w, Node* n) : _start_draw_order(0), - _next_draw_order(0), - _root(n), - _watcher(w) { +INLINE GuiManager::GuiManager(MouseWatcher* w, Node* n, EventHandler* h) + : _start_draw_order(0), _next_draw_order(0), _root(n), _watcher(w), + _eh(h) { } INLINE int GuiManager::get_next_draw_order(void) const { @@ -30,3 +29,7 @@ INLINE int GuiManager::get_start_draw_order(void) const { INLINE void GuiManager::set_start_draw_order(int v) { this->_start_draw_order = v; } + +INLINE EventHandler* GuiManager::get_private_handler(void) const { + return _eh; +} diff --git a/panda/src/gui/guiManager.cxx b/panda/src/gui/guiManager.cxx index 9af92d97ea..c92f900749 100644 --- a/panda/src/gui/guiManager.cxx +++ b/panda/src/gui/guiManager.cxx @@ -15,6 +15,7 @@ #include #include #include +#include GuiManager::GuiMap* GuiManager::_map = (GuiManager::GuiMap*)0L; @@ -66,25 +67,27 @@ GuiManager* GuiManager::get_ptr(GraphicsWindow* w, MouseAndKeyboard* mak, << endl; } // now setup event triggers for the watcher +#ifdef _DEBUG if (has_watcher && !watcher->get_button_down_pattern().empty()) gui_cat->warning() << "overwriting existing button down pattern '" << watcher->get_button_down_pattern() << "' with 'gui-button-press'" << endl; - watcher->set_button_down_pattern("gui-button-press"); if (has_watcher && !watcher->get_button_up_pattern().empty()) gui_cat->warning() << "overwriting existing button up pattern '" << watcher->get_button_up_pattern() << "' with 'gui-button-release'" << endl; - watcher->set_button_up_pattern("gui-button-release"); if (has_watcher && !watcher->get_enter_pattern().empty()) gui_cat->warning() << "overwriting existing enter pattern '" << watcher->get_enter_pattern() << "' with 'gui-enter'" << endl; - watcher->set_enter_pattern("gui-enter"); if (has_watcher && !watcher->get_leave_pattern().empty()) gui_cat->warning() << "overwriting existing exit pattern '" << watcher->get_leave_pattern() << "' with 'gui-exit'" << endl; +#endif /* _DEBUG */ + watcher->set_button_down_pattern("gui-button-press"); + watcher->set_button_up_pattern("gui-button-release"); + watcher->set_enter_pattern("gui-enter"); watcher->set_leave_pattern("gui-exit"); if (root2d == (Node *)NULL) { @@ -116,8 +119,12 @@ GuiManager* GuiManager::get_ptr(GraphicsWindow* w, MouseAndKeyboard* mak, gui_cat->debug() << "2D layer created" << endl; } + // make an event handler for our internal events + EventHandler* eh = new EventHandler(new EventQueue()); + watcher->set_extra_handler(eh); + // now make the manager for this window - ret = new GuiManager(watcher, root2d); + ret = new GuiManager(watcher, root2d, eh); if (gui_cat->is_debug()) gui_cat->debug() << "new manager allocated (0x" << (void*)ret << ")" << endl; diff --git a/panda/src/gui/guiManager.h b/panda/src/gui/guiManager.h index 21602d481b..02a8cd1684 100644 --- a/panda/src/gui/guiManager.h +++ b/panda/src/gui/guiManager.h @@ -39,8 +39,9 @@ private: Node* _root; MouseWatcher* _watcher; + EventHandler* _eh; - INLINE GuiManager(MouseWatcher*, Node*); + INLINE GuiManager(MouseWatcher*, Node*, EventHandler*); PUBLISHED: static GuiManager* get_ptr(GraphicsWindow*, MouseAndKeyboard*, Node *root2d); @@ -63,6 +64,8 @@ PUBLISHED: bool is_sane(void) const; void sanity_check(void) const; + + INLINE EventHandler* get_private_handler(void) const; }; #include "guiManager.I" diff --git a/panda/src/gui/guiRollover.cxx b/panda/src/gui/guiRollover.cxx index 13f05f6e40..7542b89eb0 100644 --- a/panda/src/gui/guiRollover.cxx +++ b/panda/src/gui/guiRollover.cxx @@ -86,16 +86,18 @@ GuiRollover::~GuiRollover(void) { string name = get_name(); rollovers.erase(this->_rgn.p()); if ((rollovers.size() == 0) && added_hooks) { + /* _eh->remove_hook("gui-enter", enter_rollover); _eh->remove_hook("gui-exit", exit_rollover); added_hooks = false; + */ } } void GuiRollover::manage(GuiManager* mgr, EventHandler& eh) { if (!added_hooks) { - eh.add_hook("gui-enter", enter_rollover); - eh.add_hook("gui-exit", exit_rollover); + mgr->get_private_handler()->add_hook("gui-enter", enter_rollover); + mgr->get_private_handler()->add_hook("gui-exit", exit_rollover); added_hooks = true; } if (_mgr == (GuiManager*)0L) { @@ -110,8 +112,8 @@ void GuiRollover::manage(GuiManager* mgr, EventHandler& eh) { void GuiRollover::manage(GuiManager* mgr, EventHandler& eh, Node* n) { if (!added_hooks) { - eh.add_hook("gui-enter", enter_rollover); - eh.add_hook("gui-exit", exit_rollover); + mgr->get_private_handler()->add_hook("gui-enter", enter_rollover); + mgr->get_private_handler()->add_hook("gui-exit", exit_rollover); added_hooks = true; } if (_mgr == (GuiManager*)0L) { diff --git a/panda/src/tform/mouseWatcher.I b/panda/src/tform/mouseWatcher.I index e67e297c8c..8b6c97c3e6 100644 --- a/panda/src/tform/mouseWatcher.I +++ b/panda/src/tform/mouseWatcher.I @@ -263,3 +263,27 @@ INLINE void MouseWatcher:: clear_geometry() { _geometry.clear(); } + +//////////////////////////////////////////////////////////////////// +// Function: MouseWatcher::set_extra_handler +// Access: Published +// Description: As an optimization for the C++ Gui, an extra handler +// can be registered with a mouseWatcher so that events +// can be dealt with much sooner. +//////////////////////////////////////////////////////////////////// +INLINE void MouseWatcher:: +set_extra_handler(EventHandler *eh) { + _eh = eh; +} + +//////////////////////////////////////////////////////////////////// +// Function: MouseWatcher::get_extra_handler +// Access: Published +// Description: As an optimization for the C++ Gui, an extra handler +// can be registered with a mouseWatcher so that events +// can be dealt with much sooner. +//////////////////////////////////////////////////////////////////// +INLINE EventHandler* MouseWatcher:: +get_extra_handler(void) const { + return _eh; +} diff --git a/panda/src/tform/mouseWatcher.cxx b/panda/src/tform/mouseWatcher.cxx index 43ad02e702..30608f502f 100644 --- a/panda/src/tform/mouseWatcher.cxx +++ b/panda/src/tform/mouseWatcher.cxx @@ -34,6 +34,7 @@ MouseWatcher(const string &name) : DataNode(name) { _current_region = (MouseWatcherRegion *)NULL; _button_down_region = (MouseWatcherRegion *)NULL; _button_down = false; + _eh = (EventHandler*)0L; } //////////////////////////////////////////////////////////////////// @@ -233,6 +234,9 @@ throw_event_pattern(const string &pattern, const MouseWatcherRegion *region, if (!event.empty()) { throw_event(event, EventParameter(region), EventParameter(button_name)); + if (_eh != (EventHandler*)0L) + throw_event_directly(*_eh, event, EventParameter(region), + EventParameter(button_name)); } } diff --git a/panda/src/tform/mouseWatcher.h b/panda/src/tform/mouseWatcher.h index ee71129076..cb2937bf4e 100644 --- a/panda/src/tform/mouseWatcher.h +++ b/panda/src/tform/mouseWatcher.h @@ -16,6 +16,7 @@ #include #include #include +#include #include @@ -77,6 +78,9 @@ PUBLISHED: INLINE NodeRelation *get_geometry() const; INLINE void clear_geometry(); + INLINE void set_extra_handler(EventHandler *eh); + INLINE EventHandler* get_extra_handler(void) const; + public: virtual void output(ostream &out) const; virtual void write(ostream &out, int indent_level = 0) const; @@ -104,6 +108,8 @@ private: PT(NodeRelation) _geometry; + EventHandler* _eh; + //////////////////////////////////////////////////////////////////// // From parent class DataNode ////////////////////////////////////////////////////////////////////