Browse Source

remove at least one frame of latency in Gui stuff

Cary Sandvig 24 years ago
parent
commit
f76b4e53a9

+ 44 - 0
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);
+}

+ 19 - 0
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

+ 57 - 33
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) {

+ 7 - 4
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;
+}

+ 11 - 4
panda/src/gui/guiManager.cxx

@@ -15,6 +15,7 @@
 #include <lightTransition.h>
 #include <frustum.h>
 #include <orthoProjection.h>
+#include <eventQueue.h>
 
 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;

+ 4 - 1
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"

+ 6 - 4
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) {

+ 24 - 0
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;
+}

+ 4 - 0
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));
   }
 }
 

+ 6 - 0
panda/src/tform/mouseWatcher.h

@@ -16,6 +16,7 @@
 #include <luse.h>
 #include <nodeRelation.h>
 #include <pointerTo.h>
+#include <eventHandler.h>
 
 #include <set>
 
@@ -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
 ////////////////////////////////////////////////////////////////////