minor restructure of close_window(), etc.

This commit is contained in:
David Rose 2001-07-18 16:16:48 +00:00
parent e3c0904c88
commit 8090dda677
13 changed files with 240 additions and 115 deletions

View File

@ -20,7 +20,7 @@
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::set_render_traverser
// Access: Public
// Access: Published
// Description: Sets the traverser that will be used to render the
// scene graph. If this is unset, nothing will be
// rendered.
@ -32,7 +32,7 @@ set_render_traverser(RenderTraverser *rt) {
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::get_render_traverser
// Access: Public
// Access: Published
// Description: Returns the traverser that will be used to render the
// scene graph.
////////////////////////////////////////////////////////////////////
@ -41,6 +41,18 @@ get_render_traverser() const {
return _render_traverser;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::is_closed
// Access: Public
// Description: Returns true if the window associated with this GSG
// has been closed, and hence the resources associated
// with this GSG have been freed.
////////////////////////////////////////////////////////////////////
INLINE bool GraphicsStateGuardian::
is_closed() const {
return (_win == (GraphicsWindow *)NULL);
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::get_state
// Access: Public

View File

@ -733,6 +733,19 @@ unmark_prepared_geom_node(GeomNodeContext *gnc) {
return removed;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::close_gsg
// Access: Protected, Virtual
// Description: This is called by the associated GraphicsWindow when
// close_window() is called. It should null out the
// _win pointer and possibly free any open resources
// associated with the GSG.
////////////////////////////////////////////////////////////////////
void GraphicsStateGuardian::
close_gsg() {
_win = (GraphicsWindow *)NULL;
}
#ifdef DO_PSTATS
////////////////////////////////////////////////////////////////////

View File

@ -84,6 +84,8 @@ PUBLISHED:
void clear_attribute(TypeHandle type);
public:
INLINE bool is_closed() const;
virtual TextureContext *prepare_texture(Texture *tex);
virtual void apply_texture(TextureContext *tc);
virtual void release_texture(TextureContext *tc);
@ -165,6 +167,8 @@ protected:
bool mark_prepared_geom_node(GeomNodeContext *gnc);
bool unmark_prepared_geom_node(GeomNodeContext *gnc);
virtual void close_gsg();
#ifdef DO_PSTATS
// These functions are used to update the active texture memory
// usage record (and other frame-based measurements) in Pstats.
@ -300,7 +304,8 @@ public:
private:
static TypeHandle _type_handle;
friend class GraphicsPipe;
friend class GraphicsPipe;
friend class GraphicsWindow;
};
#include "graphicsStateGuardian.I"

View File

@ -20,7 +20,7 @@
////////////////////////////////////////////////////////////////////
// Function: GraphicsWindow::get_properties
// Access: Public
// Access: Published
// Description: Returns the full Properties structure that describes
// the window.
////////////////////////////////////////////////////////////////////
@ -31,7 +31,7 @@ get_properties() const {
////////////////////////////////////////////////////////////////////
// Function: GraphicsWindow::get_width
// Access: Public
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE int GraphicsWindow::
@ -41,7 +41,7 @@ get_width() const {
////////////////////////////////////////////////////////////////////
// Function: GraphicsWindow::get_height
// Access: Public
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE int GraphicsWindow::
@ -51,7 +51,7 @@ get_height() const {
////////////////////////////////////////////////////////////////////
// Function: GraphicsWindow::get_xorg
// Access: Public
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE int GraphicsWindow::
@ -61,7 +61,7 @@ get_xorg() const {
////////////////////////////////////////////////////////////////////
// Function: GraphicsWindow::get_yorg
// Access: Public
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE int GraphicsWindow::
@ -71,19 +71,24 @@ get_yorg() const {
////////////////////////////////////////////////////////////////////
// Function: GraphicsWindow::get_gsg
// Access: Public
// Access: Published
// Description: Returns the GSG that is associated with this window.
// There is a one-to-one association between windows and
// GSG's.
//
// It is invalid to call this if the window has been
// closed; that is, if is_closed() returns true. In
// this case the GSG has been closed as well.
////////////////////////////////////////////////////////////////////
INLINE GraphicsStateGuardian *GraphicsWindow::
get_gsg() const {
nassertr(!is_closed(), NULL);
return _gsg;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsWindow::get_pipe
// Access: Public
// Access: Published
// Description: Returns the GraphicsPipe that this window is
// associated with. It is possible that the
// GraphicsPipe might have been deleted while an
@ -97,99 +102,35 @@ get_pipe() const {
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsWindow::get_num_input_devices
// Access: Public
// Description: Returns the number of separate input devices
// associated with the window. Typically, a window will
// have exactly one input device: the keyboard/mouse
// pair. However, some windows may have no input
// devices, and others may add additional devices, for
// instance for a joystick.
// Function: GraphicsWindow::close_window
// Access: Published
// Description: Closes the window and frees all resources associated
// with it, including the GSG. The window may not be
// opened again.
////////////////////////////////////////////////////////////////////
INLINE int GraphicsWindow::
get_num_input_devices() const {
return _input_devices.size();
INLINE void GraphicsWindow::
close_window() {
if (!is_closed()) {
do_close_window();
release_gsg();
}
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsWindow::get_input_device_name
// Access: Public
// Description: Returns the name of the nth input device.
////////////////////////////////////////////////////////////////////
INLINE string GraphicsWindow::
get_input_device_name(int device) const {
nassertr(device >= 0 && device < (int)_input_devices.size(), "");
return _input_devices[device].get_name();
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsWindow::has_pointer
// Access: Public
// Description: Returns true if the nth input device has a
// screen-space pointer (for instance, a mouse), false
// otherwise.
// Function: GraphicsWindow::is_closed
// Access: Published
// Description: Returns true if close_window() has been called on
// this window, false otherwise. If the window has been
// closed, most of its interface is no longer valid.
////////////////////////////////////////////////////////////////////
INLINE bool GraphicsWindow::
has_pointer(int device) const {
nassertr(device >= 0 && device < (int)_input_devices.size(), false);
return _input_devices[device].has_pointer();
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsWindow::has_keyboard
// Access: Public
// Description: Returns true if the nth input device has a keyboard,
// false otherwise.
////////////////////////////////////////////////////////////////////
INLINE bool GraphicsWindow::
has_keyboard(int device) const {
nassertr(device >= 0 && device < (int)_input_devices.size(), false);
return _input_devices[device].has_keyboard();
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsWindow::get_mouse_data
// Access: Public
// Description: Returns the MouseData associated with the nth input
// device.
////////////////////////////////////////////////////////////////////
INLINE const MouseData &GraphicsWindow::
get_mouse_data(int device) const {
nassertr(device >= 0 && device < (int)_input_devices.size(),
*(new MouseData));
return _input_devices[device].get_mouse_data();
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsWindow::has_button_event
// Access: Public
// Description: Returns true if the indicated device has a pending
// button event (a mouse button or keyboard button
// down/up), false otherwise. If this returns true, the
// particular event may be extracted via
// get_button_event().
////////////////////////////////////////////////////////////////////
INLINE bool GraphicsWindow::
has_button_event(int device) const {
nassertr(device >= 0 && device < (int)_input_devices.size(), false);
return _input_devices[device].has_button_event();
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsWindow::get_button_event
// Access: Public
// Description: Assuming a previous call to has_button_event()
// returned true, this returns the pending button event.
////////////////////////////////////////////////////////////////////
INLINE ButtonEvent GraphicsWindow::
get_button_event(int device) {
nassertr(has_button_event(device), ButtonEvent());
return _input_devices[device].get_button_event();
is_closed() const {
return (_gsg == (GraphicsStateGuardian *)NULL);
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsWindow::set_frame_number
// Access: Public
// Access: Published
// Description: Sets the current frame number of the window. This
// affects the frame numbers written for %f in a RIB or
// image filename template. The frame number is
@ -203,7 +144,7 @@ set_frame_number(const int f) {
////////////////////////////////////////////////////////////////////
// Function: GraphicsWindow::get_frame_number
// Access: Public
// Access: Published
// Description: Returns the current frame number of the window. See
// set_frame_number().
////////////////////////////////////////////////////////////////////
@ -256,3 +197,94 @@ call_idle_callback() {
}
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsWindow::get_num_input_devices
// Access: Published
// Description: Returns the number of separate input devices
// associated with the window. Typically, a window will
// have exactly one input device: the keyboard/mouse
// pair. However, some windows may have no input
// devices, and others may add additional devices, for
// instance for a joystick.
////////////////////////////////////////////////////////////////////
INLINE int GraphicsWindow::
get_num_input_devices() const {
return _input_devices.size();
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsWindow::get_input_device_name
// Access: Published
// Description: Returns the name of the nth input device.
////////////////////////////////////////////////////////////////////
INLINE string GraphicsWindow::
get_input_device_name(int device) const {
nassertr(device >= 0 && device < (int)_input_devices.size(), "");
return _input_devices[device].get_name();
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsWindow::has_pointer
// Access: Published
// Description: Returns true if the nth input device has a
// screen-space pointer (for instance, a mouse), false
// otherwise.
////////////////////////////////////////////////////////////////////
INLINE bool GraphicsWindow::
has_pointer(int device) const {
nassertr(device >= 0 && device < (int)_input_devices.size(), false);
return _input_devices[device].has_pointer();
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsWindow::has_keyboard
// Access: Published
// Description: Returns true if the nth input device has a keyboard,
// false otherwise.
////////////////////////////////////////////////////////////////////
INLINE bool GraphicsWindow::
has_keyboard(int device) const {
nassertr(device >= 0 && device < (int)_input_devices.size(), false);
return _input_devices[device].has_keyboard();
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsWindow::get_mouse_data
// Access: Published
// Description: Returns the MouseData associated with the nth input
// device.
////////////////////////////////////////////////////////////////////
INLINE const MouseData &GraphicsWindow::
get_mouse_data(int device) const {
nassertr(device >= 0 && device < (int)_input_devices.size(),
*(new MouseData));
return _input_devices[device].get_mouse_data();
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsWindow::has_button_event
// Access: Published
// Description: Returns true if the indicated device has a pending
// button event (a mouse button or keyboard button
// down/up), false otherwise. If this returns true, the
// particular event may be extracted via
// get_button_event().
////////////////////////////////////////////////////////////////////
INLINE bool GraphicsWindow::
has_button_event(int device) const {
nassertr(device >= 0 && device < (int)_input_devices.size(), false);
return _input_devices[device].has_button_event();
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsWindow::get_button_event
// Access: Published
// Description: Assuming a previous call to has_button_event()
// returned true, this returns the pending button event.
////////////////////////////////////////////////////////////////////
INLINE ButtonEvent GraphicsWindow::
get_button_event(int device) {
nassertr(has_button_event(device), ButtonEvent());
return _input_devices[device].get_button_event();
}

View File

@ -184,11 +184,22 @@ operator=(const GraphicsWindow&) {
////////////////////////////////////////////////////////////////////
// Function: GraphicsWindow::Destructor
// Access: Public
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
GraphicsWindow::
~GraphicsWindow() {
// First, call close_window(). This tells our GSG to let go of its
// pointer to us, and also eventually calls do_close_window().
// However, do_close_window() is a virtual function that might be
// extended in a derived class, but we don't have any derived
// virtual functions by the time the destructor is called.
// Therefore, if a derived class has redefined do_close_window(), it
// should also call close_window() in its own destructor.
close_window();
// We don't have to destruct our child channels explicitly, since
// they are all reference-counted and will go away when their
// pointers do. However, we do need to zero out their pointers to
@ -514,6 +525,47 @@ make_gsg() {
nassertv(_gsg != (GraphicsStateGuardian *)NULL);
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsWindow::release_gsg
// Access: Protected
// Description: Releases the current GSG pointer, if it is currently
// held. This invalidates the window and marks it
// closed; it should not be called unless the code to
// close the window is also called.
////////////////////////////////////////////////////////////////////
void GraphicsWindow::
release_gsg() {
if (_gsg != (GraphicsStateGuardian *)NULL) {
// First, we save the GSG pointer and then NULL it out. That way,
// if the GSG happens to call close_window() while it is closing
// itself, it won't be recursive (because we'll already be marked
// closed).
PT(GraphicsStateGuardian) gsg = _gsg;
_gsg.clear();
// Now we tell the GSG it's time to sleep.
gsg->close_gsg();
}
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsWindow::do_close_window
// Access: Protected, Virtual
// Description: An internal function to release whatever system
// resources are held by the window and actually close
// it. This is called by close_window().
//
// If a derived class redefines this function, it should
// also arrange to call close_window() (or its
// equivalent) from its own destructor, since we cannot
// call a virtual function from this destructor.
////////////////////////////////////////////////////////////////////
void GraphicsWindow::
do_close_window() {
display_cat.info()
<< "Closing " << get_type() << "\n";
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsWindow::get_factory
// Access: Public, Static

View File

@ -113,14 +113,14 @@ PUBLISHED:
INLINE int get_yorg() const;
INLINE GraphicsStateGuardian *get_gsg() const;
INLINE GraphicsPipe *get_pipe() const;
INLINE void close_window();
INLINE bool is_closed() const;
INLINE void set_frame_number(const int);
INLINE int get_frame_number() const;
virtual void close_window(int exit_status) {return;}; //release windowing system resources
public:
virtual void resized(const int, const int);
@ -179,6 +179,8 @@ public:
protected:
void make_gsg();
void release_gsg();
virtual void do_close_window();
typedef vector_GraphicsWindowInputDevice InputDevices;
InputDevices _input_devices;

View File

@ -431,11 +431,11 @@ void event_esc(CPT_Event ev) {
#endif
if(ev->get_name()=="q") {
// if app ever exits using exit() without close_window, hopefully this will work
framework_cat.debug() << "Testing unsafe, no close_window(), direct exit() of framework\n";
// if app ever exits using exit() without close_window, hopefully this will work
framework_cat.debug() << "Testing unsafe, no close_window(), direct exit() of framework\n";
} else {
main_win->close_window(0);
framework_cat.debug() << "Exiting framework\n";
main_win->close_window();
framework_cat.debug() << "Exiting framework\n";
}
main_win = NULL;

View File

@ -1768,9 +1768,9 @@ release_texture(TextureContext *tc) {
GLTextureContext *gtc = DCAST(GLTextureContext, tc);
Texture *tex = tc->_texture;
HGLRC curcxt=wglGetCurrentContext();
if(curcxt!=NULL)
glDeleteTextures(1, &gtc->_index);
if (!is_closed()) {
glDeleteTextures(1, &gtc->_index);
}
gtc->_index = 0;
bool erased = unmark_prepared_texture(gtc);

View File

@ -1155,10 +1155,14 @@ void glxGraphicsWindow::process_event(XEvent event)
handle_mouse_motion(event.xcrossing.x, event.xcrossing.y);
}
break;
case DestroyNotify:
close_window();
break;
case UnmapNotify:
case VisibilityNotify:
case ClientMessage:
case DestroyNotify:
case CirculateNotify:
case CreateNotify:
case GravityNotify:

View File

@ -178,6 +178,7 @@ void wdxGraphicsWindow::DestroyMe(bool bAtExitFnCalled) {
_dxgsg->dx_cleanup(_props._fullscreen, bAtExitFnCalled);
_dxgsg=NULL;
}
release_gsg();
if(_hdc!=NULL) {
ReleaseDC(_mwindow,_hdc);
@ -195,7 +196,8 @@ void wdxGraphicsWindow::DestroyMe(bool bAtExitFnCalled) {
}
}
void wdxGraphicsWindow::close_window(int exit_status) {
void wdxGraphicsWindow::do_close_window() {
GraphicsWindow::do_close_window();
DestroyMe(false);
}
@ -205,7 +207,7 @@ void wdxGraphicsWindow::close_window(int exit_status) {
// Description:
////////////////////////////////////////////////////////////////////
wdxGraphicsWindow::~wdxGraphicsWindow(void) {
DestroyMe(false);
close_window();
}
void DestroyAllWindows(bool bAtExitFnCalled) {
@ -262,7 +264,7 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
break;
case WM_CLOSE:
DestroyMe(false);
close_window();
// BUGBUG: right now there is no way to tell the panda app the graphics window is invalid or
// has been closed by the user, to prevent further methods from being called on the window.

View File

@ -115,7 +115,7 @@ public:
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
void DestroyMe(bool bAtExitFnCalled);
virtual void close_window(int exit_status);
virtual void do_close_window();
private:
static TypeHandle _type_handle;

View File

@ -96,7 +96,7 @@ void wglGraphicsWindow::DestroyMe(bool bAtExitFnCalled) {
report_errors();
// implicitly calls gsg destructors which release GL objects (textures, display lists, etc)
_gsg = NULL;
release_gsg();
HGLRC curcxt=wglGetCurrentContext();
if(curcxt!=NULL)
@ -134,7 +134,8 @@ void wglGraphicsWindow::DestroyMe(bool bAtExitFnCalled) {
}
}
void wglGraphicsWindow::close_window(int exit_status) {
void wglGraphicsWindow::do_close_window() {
GraphicsWindow::do_close_window();
DestroyMe(false);
}
@ -144,7 +145,7 @@ void wglGraphicsWindow::close_window(int exit_status) {
// Description:
////////////////////////////////////////////////////////////////////
wglGraphicsWindow::~wglGraphicsWindow(void) {
DestroyMe(false);
close_window();
}
void DestroyAllWindows(bool bAtExitFnCalled) {
@ -1330,7 +1331,7 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
break;
case WM_CLOSE:
DestroyMe(false);
close_window();
// BUGBUG: right now there is no way to tell the panda app the graphics window is invalid or
// has been closed by the user, to prevent further methods from being called on the window.

View File

@ -143,7 +143,9 @@ public:
LONG WINAPI window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
ButtonHandle lookup_key(WPARAM wparam) const;
void DestroyMe(bool bAtExitFnCalled);
virtual void close_window(int exit_status);
protected:
virtual void do_close_window();
private:
static TypeHandle _type_handle;