From 2abad9649b6e05ea2e72f20492f154fac0e945ee Mon Sep 17 00:00:00 2001 From: rdb Date: Sat, 19 Mar 2016 18:46:10 +0100 Subject: [PATCH 01/16] Remove X11-specific stuff from egldisplay, instead using x11display as common base --- makepanda/makepanda.py | 6 +- panda/src/egldisplay/config_egldisplay.cxx | 35 - panda/src/egldisplay/config_egldisplay.h | 8 - panda/src/egldisplay/eglGraphicsPipe.I | 46 - panda/src/egldisplay/eglGraphicsPipe.cxx | 203 +-- panda/src/egldisplay/eglGraphicsPipe.h | 59 +- .../egldisplay/eglGraphicsStateGuardian.cxx | 5 +- panda/src/egldisplay/eglGraphicsWindow.I | 8 - panda/src/egldisplay/eglGraphicsWindow.cxx | 1355 +---------------- panda/src/egldisplay/eglGraphicsWindow.h | 58 +- 10 files changed, 19 insertions(+), 1764 deletions(-) diff --git a/makepanda/makepanda.py b/makepanda/makepanda.py index 11868cf829..575058e5ae 100755 --- a/makepanda/makepanda.py +++ b/makepanda/makepanda.py @@ -4539,8 +4539,7 @@ if (PkgSkip("EGL")==0 and PkgSkip("GLES")==0 and PkgSkip("X11")==0 and not RUNTI TargetAdd('pandagles_egldisplay_composite1.obj', opts=OPTS, input='p3egldisplay_composite1.cxx') OPTS=['DIR:panda/metalibs/pandagles', 'BUILDING:PANDAGLES', 'GLES', 'EGL'] TargetAdd('pandagles_pandagles.obj', opts=OPTS, input='pandagles.cxx') - # Uncomment this as soon as x11-specific stuff is removed from p3egldisplay - #TargetAdd('libpandagles.dll', input='p3x11display_composite1.obj') + TargetAdd('libpandagles.dll', input='p3x11display_composite1.obj') TargetAdd('libpandagles.dll', input='pandagles_pandagles.obj') TargetAdd('libpandagles.dll', input='p3glesgsg_config_glesgsg.obj') TargetAdd('libpandagles.dll', input='p3glesgsg_glesgsg.obj') @@ -4558,8 +4557,7 @@ if (PkgSkip("EGL")==0 and PkgSkip("GLES2")==0 and PkgSkip("X11")==0 and not RUNT TargetAdd('pandagles2_egldisplay_composite1.obj', opts=OPTS, input='p3egldisplay_composite1.cxx') OPTS=['DIR:panda/metalibs/pandagles2', 'BUILDING:PANDAGLES2', 'GLES2', 'EGL'] TargetAdd('pandagles2_pandagles2.obj', opts=OPTS, input='pandagles2.cxx') - # Uncomment this as soon as x11-specific stuff is removed from p3egldisplay - #TargetAdd('libpandagles2.dll', input='p3x11display_composite1.obj') + TargetAdd('libpandagles2.dll', input='p3x11display_composite1.obj') TargetAdd('libpandagles2.dll', input='pandagles2_pandagles2.obj') TargetAdd('libpandagles2.dll', input='p3gles2gsg_config_gles2gsg.obj') TargetAdd('libpandagles2.dll', input='p3gles2gsg_gles2gsg.obj') diff --git a/panda/src/egldisplay/config_egldisplay.cxx b/panda/src/egldisplay/config_egldisplay.cxx index 7277e517f8..809e73916c 100644 --- a/panda/src/egldisplay/config_egldisplay.cxx +++ b/panda/src/egldisplay/config_egldisplay.cxx @@ -26,41 +26,6 @@ ConfigureFn(config_egldisplay) { init_libegldisplay(); } -ConfigVariableString display_cfg -("display", "", - PRC_DESC("Specify the X display string for the default display. If this " - "is not specified, $DISPLAY is used.")); - -ConfigVariableBool x_error_abort -("x-error-abort", false, - PRC_DESC("Set this true to trigger and abort (and a stack trace) on receipt " - "of an error from the X window system. This can make it easier " - "to discover where these errors are generated.")); - -ConfigVariableInt x_wheel_up_button -("x-wheel-up-button", 4, - PRC_DESC("This is the mouse button index of the wheel_up event: which " - "mouse button number does the system report when the mouse wheel " - "is rolled one notch up?")); - -ConfigVariableInt x_wheel_down_button -("x-wheel-down-button", 5, - PRC_DESC("This is the mouse button index of the wheel_down event: which " - "mouse button number does the system report when the mouse wheel " - "is rolled one notch down?")); - -ConfigVariableInt x_wheel_left_button -("x-wheel-left-button", 6, - PRC_DESC("This is the mouse button index of the wheel_left event: which " - "mouse button number does the system report when one scrolls " - "to the left?")); - -ConfigVariableInt x_wheel_right_button -("x-wheel-right-button", 7, - PRC_DESC("This is the mouse button index of the wheel_right event: which " - "mouse button number does the system report when one scrolls " - "to the right?")); - /** * Initializes the library. This must be called at least once before any of * the functions or classes in this library can be used. Normally it will be diff --git a/panda/src/egldisplay/config_egldisplay.h b/panda/src/egldisplay/config_egldisplay.h index 1c403ec513..2df5bcc1f4 100644 --- a/panda/src/egldisplay/config_egldisplay.h +++ b/panda/src/egldisplay/config_egldisplay.h @@ -39,12 +39,4 @@ extern EXPCL_PANDAGLES const string get_egl_error_string(int error); #endif -extern ConfigVariableString display_cfg; -extern ConfigVariableBool x_error_abort; - -extern ConfigVariableInt x_wheel_up_button; -extern ConfigVariableInt x_wheel_down_button; -extern ConfigVariableInt x_wheel_left_button; -extern ConfigVariableInt x_wheel_right_button; - #endif diff --git a/panda/src/egldisplay/eglGraphicsPipe.I b/panda/src/egldisplay/eglGraphicsPipe.I index bec9e98a34..53d9c311af 100644 --- a/panda/src/egldisplay/eglGraphicsPipe.I +++ b/panda/src/egldisplay/eglGraphicsPipe.I @@ -10,49 +10,3 @@ * @author rdb * @date 2009-05-21 */ - -/** - * Returns a pointer to the X display associated with the pipe: the display on - * which to create the windows. - */ -INLINE X11_Display *eglGraphicsPipe:: -get_display() const { - return _display; -} - -/** - * Returns the X screen number associated with the pipe. - */ -INLINE int eglGraphicsPipe:: -get_screen() const { - return _screen; -} - -/** - * Returns the handle to the root window on the pipe's display. - */ -INLINE X11_Window eglGraphicsPipe:: -get_root() const { - return _root; -} - -/** - * Returns the input method opened for the pipe, or NULL if the input method - * could not be opened for some reason. - */ -INLINE XIM eglGraphicsPipe:: -get_im() const { - return _im; -} - -/** - * Returns an invisible Cursor suitable for assigning to windows that have the - * cursor_hidden property set. - */ -INLINE X11_Cursor eglGraphicsPipe:: -get_hidden_cursor() { - if (_hidden_cursor == None) { - make_hidden_cursor(); - } - return _hidden_cursor; -} diff --git a/panda/src/egldisplay/eglGraphicsPipe.cxx b/panda/src/egldisplay/eglGraphicsPipe.cxx index 0280b2bd7d..441fc10512 100644 --- a/panda/src/egldisplay/eglGraphicsPipe.cxx +++ b/panda/src/egldisplay/eglGraphicsPipe.cxx @@ -21,67 +21,11 @@ TypeHandle eglGraphicsPipe::_type_handle; -bool eglGraphicsPipe::_error_handlers_installed = false; -eglGraphicsPipe::ErrorHandlerFunc *eglGraphicsPipe::_prev_error_handler; -eglGraphicsPipe::IOErrorHandlerFunc *eglGraphicsPipe::_prev_io_error_handler; - -LightReMutex eglGraphicsPipe::_x_mutex; - /** * */ eglGraphicsPipe:: -eglGraphicsPipe(const string &display) { - string display_spec = display; - if (display_spec.empty()) { - display_spec = display_cfg; - } - if (display_spec.empty()) { - display_spec = ExecutionEnvironment::get_environment_variable("DISPLAY"); - } - if (display_spec.empty()) { - display_spec = ":0.0"; - } - - // The X docs say we should do this to get international character support - // from the keyboard. - setlocale(LC_ALL, ""); - - // But it's important that we use the "C" locale for numeric formatting, - // since all of the internal Panda code assumes this--we need a decimal - // point to mean a decimal point. - setlocale(LC_NUMERIC, "C"); - - _is_valid = false; - _supported_types = OT_window | OT_buffer | OT_texture_buffer; - _display = NULL; - _screen = 0; - _root = (X11_Window)NULL; - _im = (XIM)NULL; - _hidden_cursor = None; - _egl_display = NULL; - - install_error_handlers(); - - _display = XOpenDisplay(display_spec.c_str()); - if (!_display) { - egldisplay_cat.error() - << "Could not open display \"" << display_spec << "\".\n"; - return; - } - - if (!XSupportsLocale()) { - egldisplay_cat.warning() - << "X does not support locale " << setlocale(LC_ALL, NULL) << "\n"; - } - XSetLocaleModifiers(""); - - _screen = DefaultScreen(_display); - _root = RootWindow(_display, _screen); - _display_width = DisplayWidth(_display, _screen); - _display_height = DisplayHeight(_display, _screen); - _is_valid = true; - +eglGraphicsPipe(const string &display) : x11GraphicsPipe(display) { _egl_display = eglGetDisplay((NativeDisplayType) _display); if (!eglInitialize(_egl_display, NULL, NULL)) { egldisplay_cat.error() @@ -94,38 +38,6 @@ eglGraphicsPipe(const string &display) { << "Couldn't bind EGL to the OpenGL ES API: " << get_egl_error_string(eglGetError()) << "\n"; } - - // Connect to an input method for supporting international text entry. - _im = XOpenIM(_display, NULL, NULL, NULL); - if (_im == (XIM)NULL) { - egldisplay_cat.warning() - << "Couldn't open input method.\n"; - } - - // What styles does the current input method support? - /* - XIMStyles *im_supported_styles; - XGetIMValues(_im, XNQueryInputStyle, &im_supported_styles, NULL); - - for (int i = 0; i < im_supported_styles->count_styles; i++) { - XIMStyle style = im_supported_styles->supported_styles[i]; - cerr << "style " << i << ". " << hex << style << dec << "\n"; - } - - XFree(im_supported_styles); - */ - - // Get some X atom numbers. - _wm_delete_window = XInternAtom(_display, "WM_DELETE_WINDOW", false); - _net_wm_window_type = XInternAtom(_display, "_NET_WM_WINDOW_TYPE", false); - _net_wm_window_type_splash = XInternAtom(_display, "_NET_WM_WINDOW_TYPE_SPLASH", false); - _net_wm_window_type_fullscreen = XInternAtom(_display, "_NET_WM_WINDOW_TYPE_FULLSCREEN", false); - _net_wm_state = XInternAtom(_display, "_NET_WM_STATE", false); - _net_wm_state_fullscreen = XInternAtom(_display, "_NET_WM_STATE_FULLSCREEN", false); - _net_wm_state_above = XInternAtom(_display, "_NET_WM_STATE_ABOVE", false); - _net_wm_state_below = XInternAtom(_display, "_NET_WM_STATE_BELOW", false); - _net_wm_state_add = XInternAtom(_display, "_NET_WM_STATE_ADD", false); - _net_wm_state_remove = XInternAtom(_display, "_NET_WM_STATE_REMOVE", false); } /** @@ -133,13 +45,6 @@ eglGraphicsPipe(const string &display) { */ eglGraphicsPipe:: ~eglGraphicsPipe() { - release_hidden_cursor(); - if (_im) { - XCloseIM(_im); - } - if (_display) { - XCloseDisplay(_display); - } if (_egl_display) { if (!eglTerminate(_egl_display)) { egldisplay_cat.error() << "Failed to terminate EGL display: " @@ -168,26 +73,6 @@ pipe_constructor() { return new eglGraphicsPipe; } -/** - * Returns an indication of the thread in which this GraphicsPipe requires its - * window processing to be performed: typically either the app thread (e.g. - * X) or the draw thread (Windows). - */ -GraphicsPipe::PreferredWindowThread -eglGraphicsPipe::get_preferred_window_thread() const { - // Actually, since we're creating the graphics context in open_window() now, - // it appears we need to ensure the open_window() call is performed in the - // draw thread for now, even though X wants all of its calls to be single- - // threaded. - - // This means that all X windows may have to be handled by the same draw - // thread, which we didn't intend (though the global _x_mutex may allow them - // to be technically served by different threads, even though the actual X - // calls will be serialized). There might be a better way. - - return PWT_draw; -} - /** * Creates a new window on the pipe, if possible. */ @@ -318,89 +203,3 @@ make_output(const string &name, // Nothing else left to try. return NULL; } - -/** - * Called once to make an invisible Cursor for return from - * get_hidden_cursor(). - */ -void eglGraphicsPipe:: -make_hidden_cursor() { - nassertv(_hidden_cursor == None); - - unsigned int x_size, y_size; - XQueryBestCursor(_display, _root, 1, 1, &x_size, &y_size); - - Pixmap empty = XCreatePixmap(_display, _root, x_size, y_size, 1); - - XColor black; - memset(&black, 0, sizeof(black)); - - _hidden_cursor = XCreatePixmapCursor(_display, empty, empty, - &black, &black, x_size, y_size); - XFreePixmap(_display, empty); -} - -/** - * Called once to release the invisible cursor created by - * make_hidden_cursor(). - */ -void eglGraphicsPipe:: -release_hidden_cursor() { - if (_hidden_cursor != None) { - XFreeCursor(_display, _hidden_cursor); - _hidden_cursor = None; - } -} - -/** - * Installs new Xlib error handler functions if this is the first time this - * function has been called. These error handler functions will attempt to - * reduce Xlib's annoying tendency to shut down the client at the first error. - * Unfortunately, it is difficult to play nice with the client if it has - * already installed its own error handlers. - */ -void eglGraphicsPipe:: -install_error_handlers() { - if (_error_handlers_installed) { - return; - } - - _prev_error_handler = (ErrorHandlerFunc *)XSetErrorHandler(error_handler); - _prev_io_error_handler = (IOErrorHandlerFunc *)XSetIOErrorHandler(io_error_handler); - _error_handlers_installed = true; -} - -/** - * This function is installed as the error handler for a non-fatal Xlib error. - */ -int eglGraphicsPipe:: -error_handler(X11_Display *display, XErrorEvent *error) { - static const int msg_len = 80; - char msg[msg_len]; - XGetErrorText(display, error->error_code, msg, msg_len); - egldisplay_cat.error() - << msg << "\n"; - - if (x_error_abort) { - abort(); - } - - // We return to allow the application to continue running, unlike the - // default X error handler which exits. - return 0; -} - -/** - * This function is installed as the error handler for a fatal Xlib error. - */ -int eglGraphicsPipe:: -io_error_handler(X11_Display *display) { - egldisplay_cat.fatal() - << "X fatal error on display " << (void *)display << "\n"; - - // Unfortunately, we can't continue from this function, even if we promise - // never to use X again. We're supposed to terminate without returning, and - // if we do return, the caller will exit anyway. Sigh. Very poor design on - // X's part. - return 0; -} diff --git a/panda/src/egldisplay/eglGraphicsPipe.h b/panda/src/egldisplay/eglGraphicsPipe.h index 3cd9682350..aea34925e6 100644 --- a/panda/src/egldisplay/eglGraphicsPipe.h +++ b/panda/src/egldisplay/eglGraphicsPipe.h @@ -15,11 +15,7 @@ #define EGLGRAPHICSPIPE_H #include "pandabase.h" -#include "graphicsWindow.h" -#include "graphicsPipe.h" -#include "lightMutex.h" -#include "lightReMutex.h" -#include "get_x11.h" +#include "x11GraphicsPipe.h" #ifdef OPENGLES_2 #include "gles2gsg.h" @@ -46,7 +42,7 @@ class eglGraphicsWindow; * This graphics pipe represents the interface for creating OpenGL ES graphics * windows on an X-based (e.g. Unix) client. */ -class eglGraphicsPipe : public GraphicsPipe { +class eglGraphicsPipe : public x11GraphicsPipe { public: eglGraphicsPipe(const string &display = string()); virtual ~eglGraphicsPipe(); @@ -54,29 +50,6 @@ public: virtual string get_interface_name() const; static PT(GraphicsPipe) pipe_constructor(); - INLINE X11_Display *get_display() const; - INLINE int get_screen() const; - INLINE X11_Window get_root() const; - INLINE XIM get_im() const; - - INLINE X11_Cursor get_hidden_cursor(); - -public: - virtual PreferredWindowThread get_preferred_window_thread() const; - -public: - // Atom specifications. - Atom _wm_delete_window; - Atom _net_wm_window_type; - Atom _net_wm_window_type_splash; - Atom _net_wm_window_type_fullscreen; - Atom _net_wm_state; - Atom _net_wm_state_fullscreen; - Atom _net_wm_state_above; - Atom _net_wm_state_below; - Atom _net_wm_state_add; - Atom _net_wm_state_remove; - protected: virtual PT(GraphicsOutput) make_output(const string &name, const FrameBufferProperties &fb_prop, @@ -89,40 +62,16 @@ protected: bool &precertify); private: - void make_hidden_cursor(); - void release_hidden_cursor(); - - static void install_error_handlers(); - static int error_handler(X11_Display *display, XErrorEvent *error); - static int io_error_handler(X11_Display *display); - - X11_Display *_display; - int _screen; - X11_Window _root; - XIM _im; EGLDisplay _egl_display; - X11_Cursor _hidden_cursor; - - typedef int ErrorHandlerFunc(X11_Display *, XErrorEvent *); - typedef int IOErrorHandlerFunc(X11_Display *); - static bool _error_handlers_installed; - static ErrorHandlerFunc *_prev_error_handler; - static IOErrorHandlerFunc *_prev_io_error_handler; - -public: - // This Mutex protects any X library calls, which all have to be single- - // threaded. In particular, it protects eglMakeCurrent(). - static LightReMutex _x_mutex; - public: static TypeHandle get_class_type() { return _type_handle; } static void init_type() { - GraphicsPipe::init_type(); + x11GraphicsPipe::init_type(); register_type(_type_handle, "eglGraphicsPipe", - GraphicsPipe::get_class_type()); + x11GraphicsPipe::get_class_type()); } virtual TypeHandle get_type() const { return get_class_type(); diff --git a/panda/src/egldisplay/eglGraphicsStateGuardian.cxx b/panda/src/egldisplay/eglGraphicsStateGuardian.cxx index 5168bd575e..84fc303efb 100644 --- a/panda/src/egldisplay/eglGraphicsStateGuardian.cxx +++ b/panda/src/egldisplay/eglGraphicsStateGuardian.cxx @@ -257,8 +257,9 @@ reset() { // If "Mesa" is present, assume software. However, if "Mesa DRI" is found, // it's actually a Mesa-based OpenGL layer running over a hardware driver. - if (_gl_renderer.find("Mesa") != string::npos && - _gl_renderer.find("Mesa DRI") == string::npos) { + if (_gl_renderer == "Software Rasterizer" || + (_gl_renderer.find("Mesa") != string::npos && + _gl_renderer.find("Mesa DRI") == string::npos)) { // It's Mesa, therefore probably a software context. _fbprops.set_force_software(1); _fbprops.set_force_hardware(0); diff --git a/panda/src/egldisplay/eglGraphicsWindow.I b/panda/src/egldisplay/eglGraphicsWindow.I index 0f3a6bb472..54fa89ab46 100644 --- a/panda/src/egldisplay/eglGraphicsWindow.I +++ b/panda/src/egldisplay/eglGraphicsWindow.I @@ -10,11 +10,3 @@ * @author rdb * @date 2009-05-21 */ - -/** - * Returns the X11 Window handle. - */ -INLINE X11_Window eglGraphicsWindow:: -get_xwindow() const { - return _xwindow; -} diff --git a/panda/src/egldisplay/eglGraphicsWindow.cxx b/panda/src/egldisplay/eglGraphicsWindow.cxx index 7299815739..b7e7d5dccf 100644 --- a/panda/src/egldisplay/eglGraphicsWindow.cxx +++ b/panda/src/egldisplay/eglGraphicsWindow.cxx @@ -27,17 +27,8 @@ #include "nativeWindowHandle.h" #include "get_x11.h" -#include -#include - -#ifdef HAVE_LINUX_INPUT_H -#include -#endif - TypeHandle eglGraphicsWindow::_type_handle; -#define test_bit(bit, array) ((array)[(bit)/8] & (1<<((bit)&7))) - /** * */ @@ -49,31 +40,12 @@ eglGraphicsWindow(GraphicsEngine *engine, GraphicsPipe *pipe, int flags, GraphicsStateGuardian *gsg, GraphicsOutput *host) : - GraphicsWindow(engine, pipe, name, fb_prop, win_prop, flags, gsg, host) + x11GraphicsWindow(engine, pipe, name, fb_prop, win_prop, flags, gsg, host) { eglGraphicsPipe *egl_pipe; DCAST_INTO_V(egl_pipe, _pipe); - _display = egl_pipe->get_display(); - _screen = egl_pipe->get_screen(); - _xwindow = (X11_Window)NULL; - _ic = (XIC)NULL; _egl_display = egl_pipe->_egl_display; _egl_surface = 0; - _awaiting_configure = false; - _wm_delete_window = egl_pipe->_wm_delete_window; - _net_wm_window_type = egl_pipe->_net_wm_window_type; - _net_wm_window_type_splash = egl_pipe->_net_wm_window_type_splash; - _net_wm_window_type_fullscreen = egl_pipe->_net_wm_window_type_fullscreen; - _net_wm_state = egl_pipe->_net_wm_state; - _net_wm_state_fullscreen = egl_pipe->_net_wm_state_fullscreen; - _net_wm_state_above = egl_pipe->_net_wm_state_above; - _net_wm_state_below = egl_pipe->_net_wm_state_below; - _net_wm_state_add = egl_pipe->_net_wm_state_add; - _net_wm_state_remove = egl_pipe->_net_wm_state_remove; - - GraphicsWindowInputDevice device = - GraphicsWindowInputDevice::pointer_and_keyboard(this, "keyboard_mouse"); - add_input_device(device); } /** @@ -222,327 +194,6 @@ end_flip() { GraphicsWindow::end_flip(); } -/** - * Do whatever processing is necessary to ensure that the window responds to - * user events. Also, honor any requests recently made via - * request_properties() - * - * This function is called only within the window thread. - */ -void eglGraphicsWindow:: -process_events() { - LightReMutexHolder holder(eglGraphicsPipe::_x_mutex); - - GraphicsWindow::process_events(); - - if (_xwindow == (X11_Window)0) { - return; - } - - poll_raw_mice(); - - XEvent event; - XKeyEvent keyrelease_event; - bool got_keyrelease_event = false; - - while (XCheckIfEvent(_display, &event, check_event, (char *)this)) { - if (XFilterEvent(&event, None)) { - continue; - } - - if (got_keyrelease_event) { - // If a keyrelease event is immediately followed by a matching keypress - // event, that's just key repeat and we should treat the two events - // accordingly. It would be nice if X provided a way to differentiate - // between keyrepeat and explicit keypresses more generally. - got_keyrelease_event = false; - - if (event.type == KeyPress && - event.xkey.keycode == keyrelease_event.keycode && - (event.xkey.time - keyrelease_event.time <= 1)) { - // In particular, we only generate down messages for the repeated - // keys, not down-and-up messages. - handle_keystroke(event.xkey); - - // We thought about not generating the keypress event, but we need - // that repeat for backspace. Rethink later. - handle_keypress(event.xkey); - continue; - - } else { - // This keyrelease event is not immediately followed by a matching - // keypress event, so it's a genuine release. - handle_keyrelease(keyrelease_event); - } - } - - WindowProperties properties; - ButtonHandle button; - - switch (event.type) { - case ReparentNotify: - break; - - case ConfigureNotify: - _awaiting_configure = false; - if (_properties.get_fixed_size()) { - // If the window properties indicate a fixed size only, undo any - // attempt by the user to change them. In X, there doesn't appear to - // be a way to universally disallow this directly (although we do set - // the min_size and max_size to the same value, which seems to work - // for most window managers.) - WindowProperties current_props = get_properties(); - if (event.xconfigure.width != current_props.get_x_size() || - event.xconfigure.height != current_props.get_y_size()) { - XWindowChanges changes; - changes.width = current_props.get_x_size(); - changes.height = current_props.get_y_size(); - int value_mask = (CWWidth | CWHeight); - XConfigureWindow(_display, _xwindow, value_mask, &changes); - } - - } else { - // A normal window may be resized by the user at will. - properties.set_size(event.xconfigure.width, event.xconfigure.height); - system_changed_properties(properties); - } - break; - - case ButtonPress: - // This refers to the mouse buttons. - button = get_mouse_button(event.xbutton); - _input_devices[0].set_pointer_in_window(event.xbutton.x, event.xbutton.y); - _input_devices[0].button_down(button); - break; - - case ButtonRelease: - button = get_mouse_button(event.xbutton); - _input_devices[0].set_pointer_in_window(event.xbutton.x, event.xbutton.y); - _input_devices[0].button_up(button); - break; - - case MotionNotify: - _input_devices[0].set_pointer_in_window(event.xmotion.x, event.xmotion.y); - break; - - case KeyPress: - handle_keystroke(event.xkey); - handle_keypress(event.xkey); - break; - - case KeyRelease: - // The KeyRelease can't be processed immediately, because we have to - // check first if it's immediately followed by a matching KeyPress - // event. - keyrelease_event = event.xkey; - got_keyrelease_event = true; - break; - - case EnterNotify: - _input_devices[0].set_pointer_in_window(event.xcrossing.x, event.xcrossing.y); - break; - - case LeaveNotify: - _input_devices[0].set_pointer_out_of_window(); - break; - - case FocusIn: - properties.set_foreground(true); - system_changed_properties(properties); - break; - - case FocusOut: - properties.set_foreground(false); - system_changed_properties(properties); - break; - - case UnmapNotify: - properties.set_minimized(true); - system_changed_properties(properties); - break; - - case MapNotify: - properties.set_minimized(false); - system_changed_properties(properties); - - // Auto-focus the window when it is mapped. - XSetInputFocus(_display, _xwindow, RevertToPointerRoot, CurrentTime); - break; - - case ClientMessage: - if ((Atom)(event.xclient.data.l[0]) == _wm_delete_window) { - // This is a message from the window manager indicating that the user - // has requested to close the window. - string close_request_event = get_close_request_event(); - if (!close_request_event.empty()) { - // In this case, the app has indicated a desire to intercept the - // request and process it directly. - throw_event(close_request_event); - - } else { - // In this case, the default case, the app does not intend to - // service the request, so we do by closing the window. - - // TODO: don't release the gsg in the window thread. - close_window(); - properties.set_open(false); - system_changed_properties(properties); - } - } - break; - - case DestroyNotify: - // Apparently, we never get a DestroyNotify on a toplevel window. - // Instead, we rely on hints from the window manager (see above). - egldisplay_cat.info() - << "DestroyNotify\n"; - break; - - default: - egldisplay_cat.error() - << "unhandled X event type " << event.type << "\n"; - } - } - - if (got_keyrelease_event) { - // This keyrelease event is not immediately followed by a matching - // keypress event, so it's a genuine release. - handle_keyrelease(keyrelease_event); - } -} - -/** - * Applies the requested set of properties to the window, if possible, for - * instance to request a change in size or minimization status. - * - * The window properties are applied immediately, rather than waiting until - * the next frame. This implies that this method may *only* be called from - * within the window thread. - * - * The return value is true if the properties are set, false if they are - * ignored. This is mainly useful for derived classes to implement extensions - * to this function. - */ -void eglGraphicsWindow:: -set_properties_now(WindowProperties &properties) { - if (_pipe == (GraphicsPipe *)NULL) { - // If the pipe is null, we're probably closing down. - GraphicsWindow::set_properties_now(properties); - return; - } - - eglGraphicsPipe *egl_pipe; - DCAST_INTO_V(egl_pipe, _pipe); - - // Fullscreen mode is implemented with a hint to the window manager. - // However, we also implicitly set the origin to (0, 0) and the size to the - // desktop size, and request undecorated mode, in case the user has a less- - // capable window manager (or no window manager at all). - if (properties.get_fullscreen()) { - properties.set_undecorated(true); - properties.set_origin(0, 0); - properties.set_size(egl_pipe->get_display_width(), - egl_pipe->get_display_height()); - } - - GraphicsWindow::set_properties_now(properties); - if (!properties.is_any_specified()) { - // The base class has already handled this case. - return; - } - - // The window is already open; we are limited to what we can change on the - // fly. - - // We'll pass some property requests on as a window manager hint. - WindowProperties wm_properties = _properties; - wm_properties.add_properties(properties); - - // The window title may be changed by issuing another hint request. Assume - // this will be honored. - if (properties.has_title()) { - _properties.set_title(properties.get_title()); - properties.clear_title(); - } - - // Ditto for fullscreen mode. - if (properties.has_fullscreen()) { - _properties.set_fullscreen(properties.get_fullscreen()); - properties.clear_fullscreen(); - } - - // The size and position of an already-open window are changed via explicit - // X calls. These may still get intercepted by the window manager. Rather - // than changing _properties immediately, we'll wait for the ConfigureNotify - // message to come back. - XWindowChanges changes; - int value_mask = 0; - - if (properties.has_origin()) { - changes.x = properties.get_x_origin(); - changes.y = properties.get_y_origin(); - value_mask |= (CWX | CWY); - properties.clear_origin(); - } - if (properties.has_size()) { - changes.width = properties.get_x_size(); - changes.height = properties.get_y_size(); - value_mask |= (CWWidth | CWHeight); - properties.clear_size(); - } - if (properties.has_z_order()) { - // We'll send the classic stacking request through the standard interface, - // for users of primitive window managers; but we'll also send it as a - // window manager hint, for users of modern window managers. - _properties.set_z_order(properties.get_z_order()); - switch (properties.get_z_order()) { - case WindowProperties::Z_bottom: - changes.stack_mode = Below; - break; - - case WindowProperties::Z_normal: - changes.stack_mode = TopIf; - break; - - case WindowProperties::Z_top: - changes.stack_mode = Above; - break; - } - - value_mask |= (CWStackMode); - properties.clear_z_order(); - } - - if (value_mask != 0) { - XReconfigureWMWindow(_display, _xwindow, _screen, value_mask, &changes); - - // Don't draw anything until this is done reconfiguring. - _awaiting_configure = true; - } - - // We hide the cursor by setting it to an invisible pixmap. - if (properties.has_cursor_hidden()) { - _properties.set_cursor_hidden(properties.get_cursor_hidden()); - if (properties.get_cursor_hidden()) { - XDefineCursor(_display, _xwindow, egl_pipe->get_hidden_cursor()); - } else { - XDefineCursor(_display, _xwindow, None); - } - properties.clear_cursor_hidden(); - } - - if (properties.has_foreground()) { - if (properties.get_foreground()) { - XSetInputFocus(_display, _xwindow, RevertToPointerRoot, CurrentTime); - } else { - XSetInputFocus(_display, PointerRoot, RevertToPointerRoot, CurrentTime); - } - properties.clear_foreground(); - } - - set_wm_properties(wm_properties, true); -} - /** * Closes the window right now. Called from the window thread. */ @@ -606,97 +257,19 @@ open_window() { } } - XVisualInfo *visual_info = eglgsg->_visual; - if (visual_info == NULL) { + _visual_info = eglgsg->_visual; + if (_visual_info == NULL) { // No X visual for this fbconfig; how can we open the window? egldisplay_cat.error() << "No X visual: cannot open window.\n"; return false; } - Visual *visual = visual_info->visual; - int depth = visual_info->depth; - if (!_properties.has_origin()) { - _properties.set_origin(0, 0); - } - if (!_properties.has_size()) { - _properties.set_size(100, 100); - } + setup_colormap(_visual_info); - X11_Window parent_window = egl_pipe->get_root(); - WindowHandle *window_handle = _properties.get_parent_window(); - if (window_handle != NULL) { - egldisplay_cat.info() - << "Got parent_window " << *window_handle << "\n"; - WindowHandle::OSHandle *os_handle = window_handle->get_os_handle(); - if (os_handle != NULL) { - egldisplay_cat.info() - << "os_handle type " << os_handle->get_type() << "\n"; - - if (os_handle->is_of_type(NativeWindowHandle::X11Handle::get_class_type())) { - NativeWindowHandle::X11Handle *x11_handle = DCAST(NativeWindowHandle::X11Handle, os_handle); - parent_window = x11_handle->get_handle(); - } else if (os_handle->is_of_type(NativeWindowHandle::IntHandle::get_class_type())) { - NativeWindowHandle::IntHandle *int_handle = DCAST(NativeWindowHandle::IntHandle, os_handle); - parent_window = (X11_Window)int_handle->get_handle(); - } - } - } - _parent_window_handle = window_handle; - - setup_colormap(visual_info); - - _event_mask = - ButtonPressMask | ButtonReleaseMask | - KeyPressMask | KeyReleaseMask | - EnterWindowMask | LeaveWindowMask | - PointerMotionMask | - FocusChangeMask | - StructureNotifyMask; - - // Initialize window attributes - XSetWindowAttributes wa; - wa.background_pixel = XBlackPixel(_display, _screen); - wa.border_pixel = 0; - wa.colormap = _colormap; - wa.event_mask = _event_mask; - - unsigned long attrib_mask = - CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; - - _xwindow = XCreateWindow - (_display, parent_window, - _properties.get_x_origin(), _properties.get_y_origin(), - _properties.get_x_size(), _properties.get_y_size(), - 0, depth, InputOutput, visual, attrib_mask, &wa); - - if (_xwindow == (X11_Window)0) { - egldisplay_cat.error() - << "failed to create X window.\n"; + if (!x11GraphicsWindow::open_window()) { return false; } - set_wm_properties(_properties, false); - - // We don't specify any fancy properties of the XIC. It would be nicer if - // we could support fancy IM's that want preedit callbacks, etc., but that - // can wait until we have an X server that actually supports these to test - // it on. - XIM im = egl_pipe->get_im(); - _ic = NULL; - if (im) { - _ic = XCreateIC - (im, - XNInputStyle, XIMPreeditNothing | XIMStatusNothing, - (void*)NULL); - if (_ic == (XIC)NULL) { - egldisplay_cat.warning() - << "Couldn't create input context.\n"; - } - } - - if (_properties.get_cursor_hidden()) { - XDefineCursor(_display, _xwindow, egl_pipe->get_hidden_cursor()); - } _egl_surface = eglCreateWindowSurface(_egl_display, eglgsg->_fbconfig, (NativeWindowType) _xwindow, NULL); if (eglGetError() != EGL_SUCCESS) { @@ -721,923 +294,5 @@ open_window() { } _fb_properties = eglgsg->get_fb_properties(); - XMapWindow(_display, _xwindow); - - if (_properties.get_raw_mice()) { - open_raw_mice(); - } else { - if (egldisplay_cat.is_debug()) { - egldisplay_cat.debug() - << "Raw mice not requested.\n"; - } - } - - // Create a WindowHandle for ourselves - _window_handle = NativeWindowHandle::make_x11(_xwindow); - - // And tell our parent window that we're now its child. - if (_parent_window_handle != (WindowHandle *)NULL) { - _parent_window_handle->attach_child(_window_handle); - } - return true; } - -/** - * Asks the window manager to set the appropriate properties. In X, these - * properties cannot be specified directly by the application; they must be - * requested via the window manager, which may or may not choose to honor the - * request. - * - * If already_mapped is true, the window has already been mapped (manifested) - * on the display. This means we may need to use a different action in some - * cases. - */ -void eglGraphicsWindow:: -set_wm_properties(const WindowProperties &properties, bool already_mapped) { - // Name the window if there is a name - XTextProperty window_name; - XTextProperty *window_name_p = (XTextProperty *)NULL; - if (properties.has_title()) { - char *name = (char *)properties.get_title().c_str(); - if (XStringListToTextProperty(&name, 1, &window_name) != 0) { - window_name_p = &window_name; - } - } - - // The size hints request a window of a particular size andor a particular - // placement onscreen. - XSizeHints *size_hints_p = NULL; - if (properties.has_origin() || properties.has_size()) { - size_hints_p = XAllocSizeHints(); - if (size_hints_p != (XSizeHints *)NULL) { - if (properties.has_origin()) { - size_hints_p->x = properties.get_x_origin(); - size_hints_p->y = properties.get_y_origin(); - size_hints_p->flags |= USPosition; - } - if (properties.has_size()) { - size_hints_p->width = properties.get_x_size(); - size_hints_p->height = properties.get_y_size(); - size_hints_p->flags |= USSize; - - if (properties.get_fixed_size()) { - size_hints_p->min_width = properties.get_x_size(); - size_hints_p->min_height = properties.get_y_size(); - size_hints_p->max_width = properties.get_x_size(); - size_hints_p->max_height = properties.get_y_size(); - size_hints_p->flags |= (PMinSize | PMaxSize); - } - } - } - } - - // The window manager hints include requests to the window manager other - // than those specific to window geometry. - XWMHints *wm_hints_p = NULL; - wm_hints_p = XAllocWMHints(); - if (wm_hints_p != (XWMHints *)NULL) { - if (properties.has_minimized() && properties.get_minimized()) { - wm_hints_p->initial_state = IconicState; - } else { - wm_hints_p->initial_state = NormalState; - } - wm_hints_p->flags = StateHint; - } - - // Two competing window manager interfaces have evolved. One of them allows - // to set certain properties as a "type"; the other one as a "state". We'll - // try to honor both. - static const int max_type_data = 32; - PN_int32 type_data[max_type_data]; - int next_type_data = 0; - - static const int max_state_data = 32; - PN_int32 state_data[max_state_data]; - int next_state_data = 0; - - static const int max_set_data = 32; - class SetAction { - public: - inline SetAction() { } - inline SetAction(Atom state, Atom action) : _state(state), _action(action) { } - Atom _state; - Atom _action; - }; - SetAction set_data[max_set_data]; - int next_set_data = 0; - - if (properties.get_fullscreen()) { - // For a "fullscreen" request, we pass this through, hoping the window - // manager will support EWMH. - type_data[next_type_data++] = _net_wm_window_type_fullscreen; - - // We also request it as a state. - state_data[next_state_data++] = _net_wm_state_fullscreen; - set_data[next_set_data++] = SetAction(_net_wm_state_fullscreen, _net_wm_state_add); - } else { - set_data[next_set_data++] = SetAction(_net_wm_state_fullscreen, _net_wm_state_remove); - } - - // If we asked for a window without a border, there's no excellent way to - // arrange that. For users whose window managers follow the EWMH - // specification, we can ask for a "splash" screen, which is usually - // undecorated. It's not exactly right, but the spec doesn't give us an - // exactly-right option. - - // For other users, we'll totally punt and just set the window's Class to - // "Undecorated", and let the user configure hisher window manager not to - // put a border around windows of this class. - XClassHint *class_hints_p = NULL; - if (properties.get_undecorated()) { - class_hints_p = XAllocClassHint(); - class_hints_p->res_class = (char*) "Undecorated"; - - if (!properties.get_fullscreen()) { - type_data[next_type_data++] = _net_wm_window_type_splash; - } - } - - if (properties.has_z_order()) { - switch (properties.get_z_order()) { - case WindowProperties::Z_bottom: - state_data[next_state_data++] = _net_wm_state_below; - set_data[next_set_data++] = SetAction(_net_wm_state_below, _net_wm_state_add); - set_data[next_set_data++] = SetAction(_net_wm_state_above, _net_wm_state_remove); - break; - - case WindowProperties::Z_normal: - set_data[next_set_data++] = SetAction(_net_wm_state_below, _net_wm_state_remove); - set_data[next_set_data++] = SetAction(_net_wm_state_above, _net_wm_state_remove); - break; - - case WindowProperties::Z_top: - state_data[next_state_data++] = _net_wm_state_above; - set_data[next_set_data++] = SetAction(_net_wm_state_below, _net_wm_state_remove); - set_data[next_set_data++] = SetAction(_net_wm_state_above, _net_wm_state_add); - break; - } - } - - nassertv(next_type_data < max_type_data); - nassertv(next_state_data < max_state_data); - nassertv(next_set_data < max_set_data); - - XChangeProperty(_display, _xwindow, _net_wm_window_type, - XA_ATOM, 32, PropModeReplace, - (unsigned char *)type_data, next_type_data); - - // Request the state properties all at once. - XChangeProperty(_display, _xwindow, _net_wm_state, - XA_ATOM, 32, PropModeReplace, - (unsigned char *)state_data, next_state_data); - - if (already_mapped) { - // We have to request state changes differently when the window has been - // mapped. To do this, we need to send a client message to the root - // window for each change. - - eglGraphicsPipe *egl_pipe; - DCAST_INTO_V(egl_pipe, _pipe); - - for (int i = 0; i < next_set_data; ++i) { - XClientMessageEvent event; - memset(&event, 0, sizeof(event)); - - event.type = ClientMessage; - event.send_event = True; - event.display = _display; - event.window = _xwindow; - event.message_type = _net_wm_state; - event.format = 32; - event.data.l[0] = set_data[i]._action; - event.data.l[1] = set_data[i]._state; - event.data.l[2] = 0; - event.data.l[3] = 1; - - XSendEvent(_display, egl_pipe->get_root(), True, 0, (XEvent *)&event); - } - } - - XSetWMProperties(_display, _xwindow, window_name_p, window_name_p, - NULL, 0, size_hints_p, wm_hints_p, class_hints_p); - - if (size_hints_p != (XSizeHints *)NULL) { - XFree(size_hints_p); - } - if (wm_hints_p != (XWMHints *)NULL) { - XFree(wm_hints_p); - } - if (class_hints_p != (XClassHint *)NULL) { - XFree(class_hints_p); - } - - // Also, indicate to the window manager that we'd like to get a chance to - // close our windows cleanly, rather than being rudely disconnected from the - // X server if the user requests a window close. - Atom protocols[] = { - _wm_delete_window, - }; - - XSetWMProtocols(_display, _xwindow, protocols, - sizeof(protocols) / sizeof(Atom)); -} - -/** - * Allocates a colormap appropriate to the visual and stores in in the - * _colormap method. - */ -void eglGraphicsWindow:: -setup_colormap(XVisualInfo *visual) { - eglGraphicsPipe *egl_pipe; - DCAST_INTO_V(egl_pipe, _pipe); - X11_Window root_window = egl_pipe->get_root(); - - int visual_class = visual->c_class; - int rc, is_rgb; - - switch (visual_class) { - case PseudoColor: - _colormap = XCreateColormap(_display, root_window, - visual->visual, AllocAll); - break; - case TrueColor: - case DirectColor: - _colormap = XCreateColormap(_display, root_window, - visual->visual, AllocNone); - break; - case StaticColor: - case StaticGray: - case GrayScale: - _colormap = XCreateColormap(_display, root_window, - visual->visual, AllocNone); - break; - default: - egldisplay_cat.error() - << "Could not allocate a colormap for visual class " - << visual_class << ".\n"; - break; - } -} - -/** - * Adds raw mice to the _input_devices list. - */ -void eglGraphicsWindow:: -open_raw_mice() -{ -#ifdef HAVE_LINUX_INPUT_H - bool any_present = false; - bool any_mice = false; - - for (int i=0; i<64; i++) { - uint8_t evtypes[EV_MAX/8 + 1]; - ostringstream fnb; - fnb << "/dev/input/event" << i; - string fn = fnb.str(); - int fd = open(fn.c_str(), O_RDONLY | O_NONBLOCK, 0); - if (fd >= 0) { - any_present = true; - char name[256]; - char phys[256]; - char uniq[256]; - if ((ioctl(fd, EVIOCGNAME(sizeof(name)), name) < 0)|| - (ioctl(fd, EVIOCGPHYS(sizeof(phys)), phys) < 0)|| - (ioctl(fd, EVIOCGPHYS(sizeof(uniq)), uniq) < 0)|| - (ioctl(fd, EVIOCGBIT(0, EV_MAX), &evtypes) < 0)) { - close(fd); - egldisplay_cat.error() << - "Opening raw mice: ioctl failed on " << fn << "\n"; - } else { - if (test_bit(EV_REL, evtypes) || test_bit(EV_ABS, evtypes)) { - for (char *p=name; *p; p++) { - if (((*p<'a')||(*p>'z')) && ((*p<'A')||(*p>'Z')) && ((*p<'0')||(*p>'9'))) { - *p = '_'; - } - } - for (char *p=uniq; *p; p++) { - if (((*p<'a')||(*p>'z')) && ((*p<'A')||(*p>'Z')) && ((*p<'0')||(*p>'9'))) { - *p = '_'; - } - } - string full_id = ((string)name) + "." + uniq; - MouseDeviceInfo inf; - inf._fd = fd; - inf._input_device_index = _input_devices.size(); - inf._io_buffer = ""; - _mouse_device_info.push_back(inf); - GraphicsWindowInputDevice device = - GraphicsWindowInputDevice::pointer_only(this, full_id); - add_input_device(device); - egldisplay_cat.info() << "Raw mouse " << - inf._input_device_index << " detected: " << full_id << "\n"; - any_mice = true; - } else { - close(fd); - } - } - } else { - if ((errno == ENOENT)||(errno == ENOTDIR)) { - break; - } else { - any_present = true; - egldisplay_cat.error() << - "Opening raw mice: " << strerror(errno) << " " << fn << "\n"; - } - } - } - - if (!any_present) { - egldisplay_cat.error() << - "Opening raw mice: files not found: /dev/input/event*\n"; - } else if (!any_mice) { - egldisplay_cat.error() << - "Opening raw mice: no mouse devices detected in /dev/input/event*\n"; - } -#else - egldisplay_cat.error() << - "Opening raw mice: panda not compiled with raw mouse support.\n"; -#endif -} - -/** - * Reads events from the raw mouse device files. - */ -void eglGraphicsWindow:: -poll_raw_mice() -{ -#ifdef HAVE_LINUX_INPUT_H - for (int dev=0; dev<_mouse_device_info.size(); dev++) { - MouseDeviceInfo &inf = _mouse_device_info[dev]; - - // Read all bytes into buffer. - if (inf._fd >= 0) { - while (1) { - char tbuf[1024]; - int nread = read(inf._fd, tbuf, sizeof(tbuf)); - if (nread > 0) { - inf._io_buffer += string(tbuf, nread); - } else { - if ((nread < 0)&&((errno == EWOULDBLOCK) || (errno==EAGAIN))) { - break; - } - close(inf._fd); - inf._fd = -1; - break; - } - } - } - - // Process events. - int nevents = inf._io_buffer.size() / sizeof(struct input_event); - if (nevents == 0) { - continue; - } - const input_event *events = (const input_event *)(inf._io_buffer.c_str()); - GraphicsWindowInputDevice &dev = _input_devices[inf._input_device_index]; - int x = dev.get_raw_pointer().get_x(); - int y = dev.get_raw_pointer().get_y(); - for (int i=0; i= BTN_MOUSE)&&(events[i].code < BTN_MOUSE+8)) { - int btn = events[i].code - BTN_MOUSE; - dev.set_pointer_in_window(x,y); - if (events[i].value) { - dev.button_down(MouseButton::button(btn)); - } else { - dev.button_up(MouseButton::button(btn)); - } - } - } - } - inf._io_buffer.erase(0,nevents*sizeof(struct input_event)); - dev.set_pointer_in_window(x,y); - } -#endif -} - -/** - * Generates a keystroke corresponding to the indicated X KeyPress event. - */ -void eglGraphicsWindow:: -handle_keystroke(XKeyEvent &event) { - _input_devices[0].set_pointer_in_window(event.x, event.y); - - if (_ic) { - // First, get the keystroke as a wide-character sequence. - static const int buffer_size = 256; - wchar_t buffer[buffer_size]; - Status status; - int len = XwcLookupString(_ic, &event, buffer, buffer_size, NULL, - &status); - if (status == XBufferOverflow) { - egldisplay_cat.error() - << "Overflowed input buffer.\n"; - } - - // Now each of the returned wide characters represents a keystroke. - for (int i = 0; i < len; i++) { - _input_devices[0].keystroke(buffer[i]); - } - - } else { - // Without an input context, just get the ascii keypress. - ButtonHandle button = get_button(event, true); - if (button.has_ascii_equivalent()) { - _input_devices[0].keystroke(button.get_ascii_equivalent()); - } - } -} - -/** - * Generates a keypress corresponding to the indicated X KeyPress event. - */ -void eglGraphicsWindow:: -handle_keypress(XKeyEvent &event) { - _input_devices[0].set_pointer_in_window(event.x, event.y); - - // Now get the raw unshifted button. - ButtonHandle button = get_button(event, false); - if (button != ButtonHandle::none()) { - if (button == KeyboardButton::lcontrol() || button == KeyboardButton::rcontrol()) { - _input_devices[0].button_down(KeyboardButton::control()); - } - if (button == KeyboardButton::lshift() || button == KeyboardButton::rshift()) { - _input_devices[0].button_down(KeyboardButton::shift()); - } - if (button == KeyboardButton::lalt() || button == KeyboardButton::ralt()) { - _input_devices[0].button_down(KeyboardButton::alt()); - } - if (button == KeyboardButton::lmeta() || button == KeyboardButton::rmeta()) { - _input_devices[0].button_down(KeyboardButton::meta()); - } - _input_devices[0].button_down(button); - } -} - -/** - * Generates a keyrelease corresponding to the indicated X KeyRelease event. - */ -void eglGraphicsWindow:: -handle_keyrelease(XKeyEvent &event) { - _input_devices[0].set_pointer_in_window(event.x, event.y); - - // Now get the raw unshifted button. - ButtonHandle button = get_button(event, false); - if (button != ButtonHandle::none()) { - if (button == KeyboardButton::lcontrol() || button == KeyboardButton::rcontrol()) { - _input_devices[0].button_up(KeyboardButton::control()); - } - if (button == KeyboardButton::lshift() || button == KeyboardButton::rshift()) { - _input_devices[0].button_up(KeyboardButton::shift()); - } - if (button == KeyboardButton::lalt() || button == KeyboardButton::ralt()) { - _input_devices[0].button_up(KeyboardButton::alt()); - } - if (button == KeyboardButton::lmeta() || button == KeyboardButton::rmeta()) { - _input_devices[0].button_up(KeyboardButton::meta()); - } - _input_devices[0].button_up(button); - } -} - -/** - * Returns the Panda ButtonHandle corresponding to the keyboard button - * indicated by the given key event. - */ -ButtonHandle eglGraphicsWindow:: -get_button(XKeyEvent &key_event, bool allow_shift) { - KeySym key = XLookupKeysym(&key_event, 0); - - if ((key_event.state & Mod2Mask) != 0) { - // Mod2Mask corresponds to NumLock being in effect. In this case, we want - // to get the alternate keysym associated with any keypad keys. Weird - // system. - KeySym k2; - ButtonHandle button; - switch (key) { - case XK_KP_Space: - case XK_KP_Tab: - case XK_KP_Enter: - case XK_KP_F1: - case XK_KP_F2: - case XK_KP_F3: - case XK_KP_F4: - case XK_KP_Equal: - case XK_KP_Multiply: - case XK_KP_Add: - case XK_KP_Separator: - case XK_KP_Subtract: - case XK_KP_Divide: - case XK_KP_Left: - case XK_KP_Up: - case XK_KP_Right: - case XK_KP_Down: - case XK_KP_Begin: - case XK_KP_Prior: - case XK_KP_Next: - case XK_KP_Home: - case XK_KP_End: - case XK_KP_Insert: - case XK_KP_Delete: - case XK_KP_0: - case XK_KP_1: - case XK_KP_2: - case XK_KP_3: - case XK_KP_4: - case XK_KP_5: - case XK_KP_6: - case XK_KP_7: - case XK_KP_8: - case XK_KP_9: - k2 = XLookupKeysym(&key_event, 1); - button = map_button(k2); - if (button != ButtonHandle::none()) { - return button; - } - // If that didn't produce a button we know, just fall through and handle - // the normal, un-numlocked key. - break; - - default: - break; - } - } - - if (allow_shift) { - // If shift is held down, get the shifted keysym. - if ((key_event.state & ShiftMask) != 0) { - KeySym k2 = XLookupKeysym(&key_event, 1); - ButtonHandle button = map_button(k2); - if (button != ButtonHandle::none()) { - return button; - } - } - - // If caps lock is down, shift lowercase letters to uppercase. We can do - // this in just the ASCII set, because we handle international keyboards - // elsewhere (via an input context). - if ((key_event.state & (ShiftMask | LockMask)) != 0) { - if (key >= XK_a and key <= XK_z) { - key += (XK_A - XK_a); - } - } - } - - return map_button(key); -} - -/** - * Maps from a single X keysym to Panda's ButtonHandle. Called by - * get_button(), above. - */ -ButtonHandle eglGraphicsWindow:: -map_button(KeySym key) { - switch (key) { - case XK_BackSpace: - return KeyboardButton::backspace(); - case XK_Tab: - case XK_KP_Tab: - return KeyboardButton::tab(); - case XK_Return: - case XK_KP_Enter: - return KeyboardButton::enter(); - case XK_Escape: - return KeyboardButton::escape(); - case XK_KP_Space: - case XK_space: - return KeyboardButton::space(); - case XK_exclam: - return KeyboardButton::ascii_key('!'); - case XK_quotedbl: - return KeyboardButton::ascii_key('"'); - case XK_numbersign: - return KeyboardButton::ascii_key('#'); - case XK_dollar: - return KeyboardButton::ascii_key('$'); - case XK_percent: - return KeyboardButton::ascii_key('%'); - case XK_ampersand: - return KeyboardButton::ascii_key('&'); - case XK_apostrophe: // == XK_quoteright - return KeyboardButton::ascii_key('\''); - case XK_parenleft: - return KeyboardButton::ascii_key('('); - case XK_parenright: - return KeyboardButton::ascii_key(')'); - case XK_asterisk: - case XK_KP_Multiply: - return KeyboardButton::ascii_key('*'); - case XK_plus: - case XK_KP_Add: - return KeyboardButton::ascii_key('+'); - case XK_comma: - case XK_KP_Separator: - return KeyboardButton::ascii_key(','); - case XK_minus: - case XK_KP_Subtract: - return KeyboardButton::ascii_key('-'); - case XK_period: - case XK_KP_Decimal: - return KeyboardButton::ascii_key('.'); - case XK_slash: - case XK_KP_Divide: - return KeyboardButton::ascii_key('/'); - case XK_0: - case XK_KP_0: - return KeyboardButton::ascii_key('0'); - case XK_1: - case XK_KP_1: - return KeyboardButton::ascii_key('1'); - case XK_2: - case XK_KP_2: - return KeyboardButton::ascii_key('2'); - case XK_3: - case XK_KP_3: - return KeyboardButton::ascii_key('3'); - case XK_4: - case XK_KP_4: - return KeyboardButton::ascii_key('4'); - case XK_5: - case XK_KP_5: - return KeyboardButton::ascii_key('5'); - case XK_6: - case XK_KP_6: - return KeyboardButton::ascii_key('6'); - case XK_7: - case XK_KP_7: - return KeyboardButton::ascii_key('7'); - case XK_8: - case XK_KP_8: - return KeyboardButton::ascii_key('8'); - case XK_9: - case XK_KP_9: - return KeyboardButton::ascii_key('9'); - case XK_colon: - return KeyboardButton::ascii_key(':'); - case XK_semicolon: - return KeyboardButton::ascii_key(';'); - case XK_less: - return KeyboardButton::ascii_key('<'); - case XK_equal: - case XK_KP_Equal: - return KeyboardButton::ascii_key('='); - case XK_greater: - return KeyboardButton::ascii_key('>'); - case XK_question: - return KeyboardButton::ascii_key('?'); - case XK_at: - return KeyboardButton::ascii_key('@'); - case XK_A: - return KeyboardButton::ascii_key('A'); - case XK_B: - return KeyboardButton::ascii_key('B'); - case XK_C: - return KeyboardButton::ascii_key('C'); - case XK_D: - return KeyboardButton::ascii_key('D'); - case XK_E: - return KeyboardButton::ascii_key('E'); - case XK_F: - return KeyboardButton::ascii_key('F'); - case XK_G: - return KeyboardButton::ascii_key('G'); - case XK_H: - return KeyboardButton::ascii_key('H'); - case XK_I: - return KeyboardButton::ascii_key('I'); - case XK_J: - return KeyboardButton::ascii_key('J'); - case XK_K: - return KeyboardButton::ascii_key('K'); - case XK_L: - return KeyboardButton::ascii_key('L'); - case XK_M: - return KeyboardButton::ascii_key('M'); - case XK_N: - return KeyboardButton::ascii_key('N'); - case XK_O: - return KeyboardButton::ascii_key('O'); - case XK_P: - return KeyboardButton::ascii_key('P'); - case XK_Q: - return KeyboardButton::ascii_key('Q'); - case XK_R: - return KeyboardButton::ascii_key('R'); - case XK_S: - return KeyboardButton::ascii_key('S'); - case XK_T: - return KeyboardButton::ascii_key('T'); - case XK_U: - return KeyboardButton::ascii_key('U'); - case XK_V: - return KeyboardButton::ascii_key('V'); - case XK_W: - return KeyboardButton::ascii_key('W'); - case XK_X: - return KeyboardButton::ascii_key('X'); - case XK_Y: - return KeyboardButton::ascii_key('Y'); - case XK_Z: - return KeyboardButton::ascii_key('Z'); - case XK_bracketleft: - return KeyboardButton::ascii_key('['); - case XK_backslash: - return KeyboardButton::ascii_key('\\'); - case XK_bracketright: - return KeyboardButton::ascii_key(']'); - case XK_asciicircum: - return KeyboardButton::ascii_key('^'); - case XK_underscore: - return KeyboardButton::ascii_key('_'); - case XK_grave: // == XK_quoteleft - return KeyboardButton::ascii_key('`'); - case XK_a: - return KeyboardButton::ascii_key('a'); - case XK_b: - return KeyboardButton::ascii_key('b'); - case XK_c: - return KeyboardButton::ascii_key('c'); - case XK_d: - return KeyboardButton::ascii_key('d'); - case XK_e: - return KeyboardButton::ascii_key('e'); - case XK_f: - return KeyboardButton::ascii_key('f'); - case XK_g: - return KeyboardButton::ascii_key('g'); - case XK_h: - return KeyboardButton::ascii_key('h'); - case XK_i: - return KeyboardButton::ascii_key('i'); - case XK_j: - return KeyboardButton::ascii_key('j'); - case XK_k: - return KeyboardButton::ascii_key('k'); - case XK_l: - return KeyboardButton::ascii_key('l'); - case XK_m: - return KeyboardButton::ascii_key('m'); - case XK_n: - return KeyboardButton::ascii_key('n'); - case XK_o: - return KeyboardButton::ascii_key('o'); - case XK_p: - return KeyboardButton::ascii_key('p'); - case XK_q: - return KeyboardButton::ascii_key('q'); - case XK_r: - return KeyboardButton::ascii_key('r'); - case XK_s: - return KeyboardButton::ascii_key('s'); - case XK_t: - return KeyboardButton::ascii_key('t'); - case XK_u: - return KeyboardButton::ascii_key('u'); - case XK_v: - return KeyboardButton::ascii_key('v'); - case XK_w: - return KeyboardButton::ascii_key('w'); - case XK_x: - return KeyboardButton::ascii_key('x'); - case XK_y: - return KeyboardButton::ascii_key('y'); - case XK_z: - return KeyboardButton::ascii_key('z'); - case XK_braceleft: - return KeyboardButton::ascii_key('{'); - case XK_bar: - return KeyboardButton::ascii_key('|'); - case XK_braceright: - return KeyboardButton::ascii_key('}'); - case XK_asciitilde: - return KeyboardButton::ascii_key('~'); - case XK_F1: - case XK_KP_F1: - return KeyboardButton::f1(); - case XK_F2: - case XK_KP_F2: - return KeyboardButton::f2(); - case XK_F3: - case XK_KP_F3: - return KeyboardButton::f3(); - case XK_F4: - case XK_KP_F4: - return KeyboardButton::f4(); - case XK_F5: - return KeyboardButton::f5(); - case XK_F6: - return KeyboardButton::f6(); - case XK_F7: - return KeyboardButton::f7(); - case XK_F8: - return KeyboardButton::f8(); - case XK_F9: - return KeyboardButton::f9(); - case XK_F10: - return KeyboardButton::f10(); - case XK_F11: - return KeyboardButton::f11(); - case XK_F12: - return KeyboardButton::f12(); - case XK_KP_Left: - case XK_Left: - return KeyboardButton::left(); - case XK_KP_Up: - case XK_Up: - return KeyboardButton::up(); - case XK_KP_Right: - case XK_Right: - return KeyboardButton::right(); - case XK_KP_Down: - case XK_Down: - return KeyboardButton::down(); - case XK_KP_Prior: - case XK_Prior: - return KeyboardButton::page_up(); - case XK_KP_Next: - case XK_Next: - return KeyboardButton::page_down(); - case XK_KP_Home: - case XK_Home: - return KeyboardButton::home(); - case XK_KP_End: - case XK_End: - return KeyboardButton::end(); - case XK_KP_Insert: - case XK_Insert: - return KeyboardButton::insert(); - case XK_KP_Delete: - case XK_Delete: - return KeyboardButton::del(); - case XK_Num_Lock: - return KeyboardButton::num_lock(); - case XK_Scroll_Lock: - return KeyboardButton::scroll_lock(); - case XK_Print: - return KeyboardButton::print_screen(); - case XK_Pause: - return KeyboardButton::pause(); - case XK_Menu: - return KeyboardButton::menu(); - case XK_Shift_L: - return KeyboardButton::lshift(); - case XK_Shift_R: - return KeyboardButton::rshift(); - case XK_Control_L: - return KeyboardButton::lcontrol(); - case XK_Control_R: - return KeyboardButton::rcontrol(); - case XK_Alt_L: - return KeyboardButton::lalt(); - case XK_Alt_R: - return KeyboardButton::ralt(); - case XK_Meta_L: - return KeyboardButton::lmeta(); - case XK_Meta_R: - return KeyboardButton::rmeta(); - case XK_Caps_Lock: - return KeyboardButton::caps_lock(); - case XK_Shift_Lock: - return KeyboardButton::shift_lock(); - } - - return ButtonHandle::none(); -} - -/** - * Returns the Panda ButtonHandle corresponding to the mouse button indicated - * by the given button event. - */ -ButtonHandle eglGraphicsWindow:: -get_mouse_button(XButtonEvent &button_event) { - int index = button_event.button; - if (index == x_wheel_up_button) { - return MouseButton::wheel_up(); - } else if (index == x_wheel_down_button) { - return MouseButton::wheel_down(); - } else if (index == x_wheel_left_button) { - return MouseButton::wheel_left(); - } else if (index == x_wheel_right_button) { - return MouseButton::wheel_right(); - } else { - return MouseButton::button(index - 1); - } -} -/** - * This function is used as a predicate to XCheckIfEvent() to determine if the - * indicated queued X event is relevant and should be returned to this window. - */ -Bool eglGraphicsWindow:: -check_event(X11_Display *display, XEvent *event, char *arg) { - const eglGraphicsWindow *self = (eglGraphicsWindow *)arg; - - // We accept any event that is sent to our window. - return (event->xany.window == self->_xwindow); -} diff --git a/panda/src/egldisplay/eglGraphicsWindow.h b/panda/src/egldisplay/eglGraphicsWindow.h index 4a17920791..508365cc65 100644 --- a/panda/src/egldisplay/eglGraphicsWindow.h +++ b/panda/src/egldisplay/eglGraphicsWindow.h @@ -17,14 +17,12 @@ #include "pandabase.h" #include "eglGraphicsPipe.h" -#include "graphicsWindow.h" -#include "buttonHandle.h" -#include "get_x11.h" +#include "x11GraphicsWindow.h" /** * An interface to the egl system for managing GLES windows under X. */ -class eglGraphicsWindow : public GraphicsWindow { +class eglGraphicsWindow : public x11GraphicsWindow { public: eglGraphicsWindow(GraphicsEngine *engine, GraphicsPipe *pipe, const string &name, @@ -40,70 +38,22 @@ public: virtual void end_frame(FrameMode mode, Thread *current_thread); virtual void end_flip(); - virtual void process_events(); - virtual void set_properties_now(WindowProperties &properties); - - INLINE X11_Window get_xwindow() const; - protected: virtual void close_window(); virtual bool open_window(); private: - void set_wm_properties(const WindowProperties &properties, - bool already_mapped); - - void setup_colormap(XVisualInfo *visual); - void handle_keystroke(XKeyEvent &event); - void handle_keypress(XKeyEvent &event); - void handle_keyrelease(XKeyEvent &event); - - ButtonHandle get_button(XKeyEvent &key_event, bool allow_shift); - ButtonHandle map_button(KeySym key); - ButtonHandle get_mouse_button(XButtonEvent &button_event); - - static Bool check_event(X11_Display *display, XEvent *event, char *arg); - - void open_raw_mice(); - void poll_raw_mice(); - -private: - X11_Display *_display; - int _screen; - X11_Window _xwindow; - Colormap _colormap; - XIC _ic; EGLDisplay _egl_display; EGLSurface _egl_surface; - long _event_mask; - bool _awaiting_configure; - Atom _wm_delete_window; - Atom _net_wm_window_type; - Atom _net_wm_window_type_splash; - Atom _net_wm_window_type_fullscreen; - Atom _net_wm_state; - Atom _net_wm_state_fullscreen; - Atom _net_wm_state_above; - Atom _net_wm_state_below; - Atom _net_wm_state_add; - Atom _net_wm_state_remove; - - struct MouseDeviceInfo { - int _fd; - int _input_device_index; - string _io_buffer; - }; - pvector _mouse_device_info; - public: static TypeHandle get_class_type() { return _type_handle; } static void init_type() { - GraphicsWindow::init_type(); + x11GraphicsWindow::init_type(); register_type(_type_handle, "eglGraphicsWindow", - GraphicsWindow::get_class_type()); + x11GraphicsWindow::get_class_type()); } virtual TypeHandle get_type() const { return get_class_type(); From 58837c0f4a819cf0df8df19ad9ff7c49478388e5 Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 22 Mar 2016 11:31:51 +0100 Subject: [PATCH 02/16] Fix particle sample and tkinter in Python 3 --- direct/src/particles/ParticleEffect.py | 2 +- direct/src/showbase/ShowBase.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/direct/src/particles/ParticleEffect.py b/direct/src/particles/ParticleEffect.py index c645aea962..ba1c14a95f 100644 --- a/direct/src/particles/ParticleEffect.py +++ b/direct/src/particles/ParticleEffect.py @@ -204,7 +204,7 @@ class ParticleEffect(NodePath): def loadConfig(self, filename): data = vfs.readFile(filename, 1) - data = data.replace('\r', '') + data = data.replace(b'\r', b'') try: exec(data) except: diff --git a/direct/src/showbase/ShowBase.py b/direct/src/showbase/ShowBase.py index 0a3abdc07b..7d747fe42f 100644 --- a/direct/src/showbase/ShowBase.py +++ b/direct/src/showbase/ShowBase.py @@ -2904,7 +2904,7 @@ class ShowBase(DirectObject.DirectObject): # Use importlib to prevent this import from being picked up # by modulefinder when packaging an application. - tkinter = importlib.import_module('Tkinter').tkinter + tkinter = importlib.import_module('_tkinter') Pmw = importlib.import_module('Pmw') # Create a new Tk root. @@ -2938,7 +2938,7 @@ class ShowBase(DirectObject.DirectObject): # dooneevent will return 0 if there are no more events # waiting or 1 if there are still more. # DONT_WAIT tells tkinter not to block waiting for events - while tkinter.dooneevent(tkinter.ALL_EVENTS | tkinter.DONT_WAIT): + while self.tkRoot.dooneevent(tkinter.ALL_EVENTS | tkinter.DONT_WAIT): pass return task.again From 63dd1e0d2b4551c0db40a6a5230c03373ac6dad3 Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 24 Mar 2016 22:24:16 +0100 Subject: [PATCH 03/16] Fixes for ffmpeg 3.0 --- panda/src/ffmpeg/ffmpegAudioCursor.cxx | 16 ++++++++++++++++ panda/src/ffmpeg/ffmpegVideoCursor.cxx | 22 +++++++++++++++++++--- 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/panda/src/ffmpeg/ffmpegAudioCursor.cxx b/panda/src/ffmpeg/ffmpegAudioCursor.cxx index 14283fe19b..132f2ff9f9 100644 --- a/panda/src/ffmpeg/ffmpegAudioCursor.cxx +++ b/panda/src/ffmpeg/ffmpegAudioCursor.cxx @@ -203,7 +203,11 @@ cleanup() { if (_packet) { if (_packet->data) { +#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 12, 100) + av_packet_unref(_packet); +#else av_free_packet(_packet); +#endif } delete _packet; _packet = NULL; @@ -242,7 +246,11 @@ cleanup() { void FfmpegAudioCursor:: fetch_packet() { if (_packet->data) { +#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 12, 100) + av_packet_unref(_packet); +#else av_free_packet(_packet); +#endif } while (av_read_frame(_format_ctx, _packet) >= 0) { if (_packet->stream_index == _audio_index) { @@ -250,7 +258,11 @@ fetch_packet() { _packet_data = _packet->data; return; } +#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 12, 100) + av_packet_unref(_packet); +#else av_free_packet(_packet); +#endif } _packet->data = 0; _packet_size = 0; @@ -300,7 +312,11 @@ reload_buffer() { pkt.size = _packet_size; int len = avcodec_decode_audio4(_audio_ctx, _frame, &got_frame, &pkt); movies_debug("avcodec_decode_audio4 returned " << len); +#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 12, 100) + av_packet_unref(&pkt); +#else av_free_packet(&pkt); +#endif bufsize = 0; if (got_frame) { diff --git a/panda/src/ffmpeg/ffmpegVideoCursor.cxx b/panda/src/ffmpeg/ffmpegVideoCursor.cxx index ec79cd40b2..0be8024a0a 100644 --- a/panda/src/ffmpeg/ffmpegVideoCursor.cxx +++ b/panda/src/ffmpeg/ffmpegVideoCursor.cxx @@ -82,9 +82,13 @@ init_from(FfmpegVideo *source) { #ifdef HAVE_SWSCALE nassertv(_convert_ctx == NULL); - _convert_ctx = sws_getContext(_size_x, _size_y, - _video_ctx->pix_fmt, _size_x, _size_y, - PIX_FMT_BGR24, SWS_BILINEAR | SWS_PRINT_INFO, NULL, NULL, NULL); + _convert_ctx = sws_getContext(_size_x, _size_y, _video_ctx->pix_fmt, +#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(51, 74, 100) + _size_x, _size_y, AV_PIX_FMT_BGR24, +#else + _size_x, _size_y, PIX_FMT_BGR24, +#endif + SWS_BILINEAR | SWS_PRINT_INFO, NULL, NULL, NULL); #endif // HAVE_SWSCALE #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(54, 59, 100) @@ -568,7 +572,11 @@ cleanup() { if (_packet) { if (_packet->data) { +#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 12, 100) + av_packet_unref(_packet); +#else av_free_packet(_packet); +#endif } delete _packet; _packet = NULL; @@ -737,14 +745,22 @@ fetch_packet(int default_frame) { bool FfmpegVideoCursor:: do_fetch_packet(int default_frame) { if (_packet->data) { +#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 12, 100) + av_packet_unref(_packet); +#else av_free_packet(_packet); +#endif } while (av_read_frame(_format_ctx, _packet) >= 0) { if (_packet->stream_index == _video_index) { _packet_frame = _packet->dts; return false; } +#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 12, 100) + av_packet_unref(_packet); +#else av_free_packet(_packet); +#endif } _packet->data = 0; From ad350a207efbead3cfecdf15eeafe49422311145 Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 24 Mar 2016 23:55:21 +0100 Subject: [PATCH 04/16] Replace use of deprecated base.loadSfx/loadMusic with loader.loadSfx/Music --- samples/music-box/main.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/music-box/main.py b/samples/music-box/main.py index 774168f782..dd8ecf0299 100755 --- a/samples/music-box/main.py +++ b/samples/music-box/main.py @@ -41,7 +41,7 @@ class MusicBox(DirectObject): # Loading sounds is done in a similar way to loading other things # Loading the main music box song - self.musicBoxSound = base.loadMusic('music/musicbox.ogg') + self.musicBoxSound = loader.loadMusic('music/musicbox.ogg') self.musicBoxSound.setVolume(.5) # Volume is a percentage from 0 to 1 # 0 means loop forever, 1 (default) means # play once. 2 or higher means play that many times @@ -69,7 +69,7 @@ class MusicBox(DirectObject): # Loading the open/close effect # loadSFX and loadMusic are identical. They are often used for organization #(loadMusic is used for background music, loadSfx is used for other effects) - self.lidSfx = base.loadSfx('music/openclose.ogg') + self.lidSfx = loader.loadSfx('music/openclose.ogg') # The open/close file has both effects in it. Fortunatly we can use intervals # to easily define parts of a sound file to play self.lidOpenSfx = SoundInterval(self.lidSfx, duration=2, startTime=0) From ce947adf8f33a28c50c3f9083859a3f64c035601 Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 24 Mar 2016 23:56:12 +0100 Subject: [PATCH 05/16] Replace uses of "delete" with "delete[]" where appropriate --- dtool/src/dtoolutil/executionEnvironment.cxx | 3 +-- dtool/src/dtoolutil/pfstreamBuf.cxx | 2 +- panda/src/downloader/download_utils.cxx | 4 ++-- panda/src/pnmimagetypes/pnmFileTypeJPGWriter.cxx | 2 +- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/dtool/src/dtoolutil/executionEnvironment.cxx b/dtool/src/dtoolutil/executionEnvironment.cxx index a51fb7741c..b6ae2c7f71 100644 --- a/dtool/src/dtoolutil/executionEnvironment.cxx +++ b/dtool/src/dtoolutil/executionEnvironment.cxx @@ -283,7 +283,7 @@ ns_get_environment_variable(const string &var) const { if (item != NULL) { if (PyUnicode_Check(item)) { Py_ssize_t size = PyUnicode_GetSize(item); - wchar_t *data = new wchar_t[size + 1]; + wchar_t *data = (wchar_t *)alloca(sizeof(wchar_t) * (size + 1)); #if PY_MAJOR_VERSION >= 3 if (PyUnicode_AsWideChar(item, data, size) != -1) { #else @@ -292,7 +292,6 @@ ns_get_environment_variable(const string &var) const { wstring wstr (data, size); main_dir = Filename::from_os_specific_w(wstr); } - delete data; } #if PY_MAJOR_VERSION < 3 else if (PyString_Check(item)) { diff --git a/dtool/src/dtoolutil/pfstreamBuf.cxx b/dtool/src/dtoolutil/pfstreamBuf.cxx index fc0de36048..1fd59207ca 100644 --- a/dtool/src/dtoolutil/pfstreamBuf.cxx +++ b/dtool/src/dtoolutil/pfstreamBuf.cxx @@ -122,7 +122,7 @@ int PipeStreamBuf::underflow(void) { #endif /* PHAVE_IOSTREAM */ gbump(-((int)n)); } - delete buf; + delete[] buf; return ret; } diff --git a/panda/src/downloader/download_utils.cxx b/panda/src/downloader/download_utils.cxx index d1aba78fd6..be31c81cd8 100644 --- a/panda/src/downloader/download_utils.cxx +++ b/panda/src/downloader/download_utils.cxx @@ -41,7 +41,7 @@ check_crc(Filename name) { unsigned long crc = crc32(0L, Z_NULL, 0); crc = crc32(crc, (unsigned char *)buffer, buffer_length); - delete buffer; + delete[] buffer; return crc; } @@ -67,7 +67,7 @@ check_adler(Filename name) { unsigned long adler = adler32(0L, Z_NULL, 0); adler = adler32(adler, (unsigned char *)buffer, buffer_length); - delete buffer; + delete[] buffer; return adler; } diff --git a/panda/src/pnmimagetypes/pnmFileTypeJPGWriter.cxx b/panda/src/pnmimagetypes/pnmFileTypeJPGWriter.cxx index a73d1c415c..97964714fa 100644 --- a/panda/src/pnmimagetypes/pnmFileTypeJPGWriter.cxx +++ b/panda/src/pnmimagetypes/pnmFileTypeJPGWriter.cxx @@ -333,7 +333,7 @@ write_data(xel *array, xelval *) { row_pointer[0] = row; (void) jpeg_write_scanlines(&cinfo, row_pointer, 1); } - delete row; + delete[] row; /* Step 6: Finish compression */ From a9c5525dd602bb9ede3d17116483c5d60cf866f1 Mon Sep 17 00:00:00 2001 From: rdb Date: Fri, 25 Mar 2016 00:43:44 +0100 Subject: [PATCH 06/16] Compile fix for Ubuntu precise version of ffmpeg --- panda/src/ffmpeg/ffmpegVideoCursor.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/panda/src/ffmpeg/ffmpegVideoCursor.cxx b/panda/src/ffmpeg/ffmpegVideoCursor.cxx index 0be8024a0a..eb33490384 100644 --- a/panda/src/ffmpeg/ffmpegVideoCursor.cxx +++ b/panda/src/ffmpeg/ffmpegVideoCursor.cxx @@ -83,7 +83,7 @@ init_from(FfmpegVideo *source) { #ifdef HAVE_SWSCALE nassertv(_convert_ctx == NULL); _convert_ctx = sws_getContext(_size_x, _size_y, _video_ctx->pix_fmt, -#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(51, 74, 100) +#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(51, 74, 100) _size_x, _size_y, AV_PIX_FMT_BGR24, #else _size_x, _size_y, PIX_FMT_BGR24, From 2b034506fad5a64efdd3f8c6a390e061c11dda0b Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 24 Mar 2016 23:57:00 +0100 Subject: [PATCH 07/16] Backport fixes for Arch compile issues to 1.9 --- direct/src/dcparser/dcPython.h | 1 - panda/src/ffmpeg/ffmpegAudioCursor.cxx | 16 ++++++++++++++++ panda/src/ffmpeg/ffmpegVideoCursor.cxx | 22 +++++++++++++++++++--- 3 files changed, 35 insertions(+), 4 deletions(-) diff --git a/direct/src/dcparser/dcPython.h b/direct/src/dcparser/dcPython.h index d5a50baa2f..6236f8f0b6 100644 --- a/direct/src/dcparser/dcPython.h +++ b/direct/src/dcparser/dcPython.h @@ -20,7 +20,6 @@ #ifdef HAVE_PYTHON -#undef HAVE_LONG_LONG // NSPR and Python both define this. #undef _POSIX_C_SOURCE #include diff --git a/panda/src/ffmpeg/ffmpegAudioCursor.cxx b/panda/src/ffmpeg/ffmpegAudioCursor.cxx index a33db26b6f..38c3057c6f 100644 --- a/panda/src/ffmpeg/ffmpegAudioCursor.cxx +++ b/panda/src/ffmpeg/ffmpegAudioCursor.cxx @@ -210,7 +210,11 @@ cleanup() { if (_packet) { if (_packet->data) { +#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 12, 100) + av_packet_unref(_packet); +#else av_free_packet(_packet); +#endif } delete _packet; _packet = NULL; @@ -251,7 +255,11 @@ cleanup() { void FfmpegAudioCursor:: fetch_packet() { if (_packet->data) { +#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 12, 100) + av_packet_unref(_packet); +#else av_free_packet(_packet); +#endif } while (av_read_frame(_format_ctx, _packet) >= 0) { if (_packet->stream_index == _audio_index) { @@ -259,7 +267,11 @@ fetch_packet() { _packet_data = _packet->data; return; } +#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 12, 100) + av_packet_unref(_packet); +#else av_free_packet(_packet); +#endif } _packet->data = 0; _packet_size = 0; @@ -312,7 +324,11 @@ reload_buffer() { pkt.size = _packet_size; int len = avcodec_decode_audio4(_audio_ctx, _frame, &got_frame, &pkt); movies_debug("avcodec_decode_audio4 returned " << len); +#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 12, 100) + av_packet_unref(&pkt); +#else av_free_packet(&pkt); +#endif bufsize = 0; if (got_frame) { diff --git a/panda/src/ffmpeg/ffmpegVideoCursor.cxx b/panda/src/ffmpeg/ffmpegVideoCursor.cxx index 87b3b48395..45e72026c8 100644 --- a/panda/src/ffmpeg/ffmpegVideoCursor.cxx +++ b/panda/src/ffmpeg/ffmpegVideoCursor.cxx @@ -89,9 +89,13 @@ init_from(FfmpegVideo *source) { #ifdef HAVE_SWSCALE nassertv(_convert_ctx == NULL); - _convert_ctx = sws_getContext(_size_x, _size_y, - _video_ctx->pix_fmt, _size_x, _size_y, - PIX_FMT_BGR24, SWS_BILINEAR | SWS_PRINT_INFO, NULL, NULL, NULL); + _convert_ctx = sws_getContext(_size_x, _size_y, _video_ctx->pix_fmt, +#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(51, 74, 100) + _size_x, _size_y, AV_PIX_FMT_BGR24, +#else + _size_x, _size_y, PIX_FMT_BGR24, +#endif + SWS_BILINEAR | SWS_PRINT_INFO, NULL, NULL, NULL); #endif // HAVE_SWSCALE #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(54, 59, 100) @@ -622,7 +626,11 @@ cleanup() { if (_packet) { if (_packet->data) { +#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 12, 100) + av_packet_unref(_packet); +#else av_free_packet(_packet); +#endif } delete _packet; _packet = NULL; @@ -812,14 +820,22 @@ fetch_packet(int default_frame) { bool FfmpegVideoCursor:: do_fetch_packet(int default_frame) { if (_packet->data) { +#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 12, 100) + av_packet_unref(_packet); +#else av_free_packet(_packet); +#endif } while (av_read_frame(_format_ctx, _packet) >= 0) { if (_packet->stream_index == _video_index) { _packet_frame = _packet->dts; return false; } +#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 12, 100) + av_packet_unref(_packet); +#else av_free_packet(_packet); +#endif } _packet->data = 0; From d906f55ebfe7bb9600e738cd8a104d063a5b288a Mon Sep 17 00:00:00 2001 From: rdb Date: Fri, 25 Mar 2016 15:23:45 +0100 Subject: [PATCH 08/16] Fix rtdist error when using Python 3.5 --- direct/src/showutil/FreezeTool.py | 1 + 1 file changed, 1 insertion(+) diff --git a/direct/src/showutil/FreezeTool.py b/direct/src/showutil/FreezeTool.py index 04f8dc8baf..286e56ba9d 100644 --- a/direct/src/showutil/FreezeTool.py +++ b/direct/src/showutil/FreezeTool.py @@ -832,6 +832,7 @@ class Freezer: # bring in Python's startup modules. if addStartupModules: self.modules['_frozen_importlib'] = self.ModuleDef('importlib._bootstrap', implicit = True) + self.modules['_frozen_importlib_external'] = self.ModuleDef('importlib._bootstrap_external', implicit = True) for moduleName in startupModules: if moduleName not in self.modules: From 6334f2511d1df347f516afe9e6a6e6d1cabebc7c Mon Sep 17 00:00:00 2001 From: rdb Date: Fri, 25 Mar 2016 16:41:58 +0100 Subject: [PATCH 09/16] Let's not display deprecation warnings in release builds --- direct/src/directbase/DirectStart.py | 4 +++- direct/src/showbase/ShowBase.py | 6 +++--- makepanda/makepanda.py | 6 ++++-- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/direct/src/directbase/DirectStart.py b/direct/src/directbase/DirectStart.py index 6264b09486..031dc85323 100644 --- a/direct/src/directbase/DirectStart.py +++ b/direct/src/directbase/DirectStart.py @@ -1,7 +1,9 @@ """ This is a deprecated module that creates a global instance of ShowBase. """ __all__ = [] -print('Using deprecated DirectStart interface.') + +if __debug__: + print('Using deprecated DirectStart interface.') from direct.showbase import ShowBase base = ShowBase.ShowBase() diff --git a/direct/src/showbase/ShowBase.py b/direct/src/showbase/ShowBase.py index 7d747fe42f..28aa140e8e 100644 --- a/direct/src/showbase/ShowBase.py +++ b/direct/src/showbase/ShowBase.py @@ -45,7 +45,7 @@ if __debug__: import AppRunnerGlobal def legacyRun(): - builtins.base.notify.warning("run() is deprecated, use base.run() instead") + assert builtins.base.notify.warning("run() is deprecated, use base.run() instead") builtins.base.run() @atexit.register @@ -1793,14 +1793,14 @@ class ShowBase(DirectObject.DirectObject): # backwards compatibility. Please do not add code here, add # it to the loader. def loadSfx(self, name): - self.notify.warning("base.loadSfx is deprecated, use base.loader.loadSfx instead.") + assert self.notify.warning("base.loadSfx is deprecated, use base.loader.loadSfx instead.") return self.loader.loadSfx(name) # This function should only be in the loader but is here for # backwards compatibility. Please do not add code here, add # it to the loader. def loadMusic(self, name): - self.notify.warning("base.loadMusic is deprecated, use base.loader.loadMusic instead.") + assert self.notify.warning("base.loadMusic is deprecated, use base.loader.loadMusic instead.") return self.loader.loadMusic(name) def playSfx( diff --git a/makepanda/makepanda.py b/makepanda/makepanda.py index 575058e5ae..46554539d7 100755 --- a/makepanda/makepanda.py +++ b/makepanda/makepanda.py @@ -2671,7 +2671,8 @@ if not PkgSkip("PYTHON"): # Also add this file, for backward compatibility. ConditionalWriteFile(GetOutputDir() + '/panda3d/dtoolconfig.py', """ -print("Warning: panda3d.dtoolconfig is deprecated, use panda3d.interrogatedb instead.") +if __debug__: + print("Warning: panda3d.dtoolconfig is deprecated, use panda3d.interrogatedb instead.") from .interrogatedb import * """) @@ -2702,7 +2703,8 @@ if not PkgSkip("VRPN"): panda_modules_code = """ "This module is deprecated. Import from panda3d.core and other panda3d.* modules instead." -print("Warning: pandac.PandaModules is deprecated, import from panda3d.core instead") +if __debug__: + print("Warning: pandac.PandaModules is deprecated, import from panda3d.core instead") """ for module in panda_modules: From 54fa31ba1793e5bc6bea012c44904e443d20a24e Mon Sep 17 00:00:00 2001 From: rdb Date: Fri, 25 Mar 2016 17:06:50 +0100 Subject: [PATCH 10/16] StandardError -> Exception, other 2to3 changes, threaded 2to3 --- direct/src/actor/Actor.py | 2 +- direct/src/directdevices/DirectRadamec.py | 2 +- direct/src/directnotify/Notifier.py | 2 +- direct/src/directscripts/gendocs.py | 30 ++++++----- .../src/distributed/ConnectionRepository.py | 2 +- direct/src/distributed/ServerRepository.py | 2 +- .../extension_native_helpers.py | 6 ++- direct/src/fsm/FSM.py | 8 +-- direct/src/fsm/State.py | 12 ++--- direct/src/gui/DirectGuiBase.py | 19 ++++--- direct/src/gui/DirectScrollBar.py | 2 +- direct/src/gui/DirectSlider.py | 2 +- direct/src/interval/FunctionInterval.py | 6 +-- direct/src/interval/ProjectileInterval.py | 2 +- direct/src/p3d/AppRunner.py | 18 +++---- direct/src/p3d/JavaScript.py | 16 ++++-- direct/src/p3d/PackageInstaller.py | 2 +- direct/src/p3d/PackageMerger.py | 8 +-- direct/src/p3d/Packager.py | 52 +++++++++---------- direct/src/p3d/PatchMaker.py | 4 +- direct/src/p3d/SeqValue.py | 2 +- direct/src/p3d/packp3d.py | 12 ++--- direct/src/p3d/runp3d.py | 2 +- direct/src/plugin_npapi/make_osx_bundle.py | 4 +- .../src/plugin_standalone/make_osx_bundle.py | 4 +- direct/src/showbase/Audio3DManager.py | 4 +- direct/src/showbase/Loader.py | 2 +- direct/src/showbase/Messenger.py | 12 ++--- direct/src/showbase/PythonUtil.py | 18 +++---- direct/src/showbase/RandomNumGen.py | 14 ++--- direct/src/showbase/ShowBase.py | 8 +-- direct/src/showutil/FreezeTool.py | 18 ++++--- direct/src/stdpy/glob.py | 2 +- direct/src/stdpy/thread.py | 4 +- direct/src/stdpy/threading2.py | 7 ++- direct/src/task/Task.py | 6 +-- direct/src/tkpanels/FSMInspector.py | 2 +- direct/src/tkpanels/Inspector.py | 8 +-- direct/src/tkwidgets/Tree.py | 2 +- direct/src/wxwidgets/ViewPort.py | 2 +- direct/src/wxwidgets/WxPandaWindow.py | 2 +- makepanda/makepanda.py | 21 +++++++- makepanda/makepandacore.py | 30 +++++++---- 43 files changed, 211 insertions(+), 172 deletions(-) diff --git a/direct/src/actor/Actor.py b/direct/src/actor/Actor.py index cfff9860d7..74cb07937f 100644 --- a/direct/src/actor/Actor.py +++ b/direct/src/actor/Actor.py @@ -2058,7 +2058,7 @@ class Actor(DirectObject, NodePath): if otherPartName != partName and otherPartDef.truePartName == parent: joints = self.getOverlappingJoints(partName, otherPartName) if joints: - raise StandardError, 'Overlapping joints: %s and %s' % (partName, otherPartName) + raise Exception('Overlapping joints: %s and %s' % (partName, otherPartName)) def setSubpartsComplete(self, flag): diff --git a/direct/src/directdevices/DirectRadamec.py b/direct/src/directdevices/DirectRadamec.py index 65880be00f..2f9a2495f1 100644 --- a/direct/src/directdevices/DirectRadamec.py +++ b/direct/src/directdevices/DirectRadamec.py @@ -77,7 +77,7 @@ class DirectRadamec(DirectObject): maxRange = self.maxRange[chan] minRange = self.minRange[chan] except IndexError: - raise RuntimeError, "can't normalize this channel (chanel %d)" % chan + raise RuntimeError("can't normalize this channel (channel %d)" % chan) range = maxRange - minRange clampedVal = CLAMP(self.aList[chan], minRange, maxRange) return ((maxVal - minVal) * (clampedVal - minRange) / range) + minVal diff --git a/direct/src/directnotify/Notifier.py b/direct/src/directnotify/Notifier.py index a49bbf0d03..a0dcc511ad 100644 --- a/direct/src/directnotify/Notifier.py +++ b/direct/src/directnotify/Notifier.py @@ -116,7 +116,7 @@ class Notifier: return NSError # error funcs - def error(self, errorString, exception=StandardError): + def error(self, errorString, exception=Exception): """ Raise an exception with given string and optional type: Exception: error diff --git a/direct/src/directscripts/gendocs.py b/direct/src/directscripts/gendocs.py index edf402382c..7770203de4 100644 --- a/direct/src/directscripts/gendocs.py +++ b/direct/src/directscripts/gendocs.py @@ -108,7 +108,7 @@ def findFiles(dirlist, ext, ign, list): for dir in dirlist: for file in os.listdir(dir): full = dir + "/" + file - if (ign.has_key(full)==0) and (ign.has_key(file)==0): + if full not in ign and file not in ign: if (os.path.isfile(full)): if (file.endswith(ext)): list.append(full) @@ -145,7 +145,7 @@ def textToHTML(comment, sep, delsection=None): sec = sec.replace(" "," ") if (delsection != None) and (delsection.match(sec)): included[sec] = 1 - if (included.has_key(sec)==0): + if sec not in included: included[sec] = 1 total = total + sec + "
\n" return total @@ -341,14 +341,14 @@ class InterrogateDatabase: def printTree(tree, indent): spacing = " "[:indent] if isinstance(tree, types.TupleType) and isinstance(tree[0], types.IntType): - if symbol.sym_name.has_key(tree[0]): + if tree[0] in symbol.sym_name: for i in range(len(tree)): if (i==0): print spacing + "(symbol." + symbol.sym_name[tree[0]] + "," else: printTree(tree[i], indent+1) print spacing + ")," - elif token.tok_name.has_key(tree[0]): + elif tree[0] in token.tok_name: print spacing + "(token." + token.tok_name[tree[0]] + ", '" + tree[1] + "')," else: print spacing + str(tree) @@ -535,10 +535,10 @@ class ParseTreeInfo: def extract_tokens(self, str, tree): if (isinstance(tree, types.TupleType)): - if (token.tok_name.has_key(tree[0])): + if tree[0] in token.tok_name: str = str + tree[1] if (tree[1]==","): str=str+" " - elif (symbol.sym_name.has_key(tree[0])): + elif tree[0] in symbol.sym_name: for sub in tree[1:]: str = self.extract_tokens(str, sub) return str @@ -569,7 +569,7 @@ class CodeDatabase: tokzr = InterrogateTokenizer(cxx) idb = InterrogateDatabase(tokzr) for type in idb.types.values(): - if (type.flags & 8192) or (self.types.has_key(type.scopedname)==0): + if (type.flags & 8192) or type.scopedname not in self.types: self.types[type.scopedname] = type if (type.flags & 8192) and (type.atomictype == 0) and (type.scopedname.count(" ")==0) and (type.scopedname.count(":")==0): self.goodtypes[type.scopedname] = type @@ -706,7 +706,7 @@ class CodeDatabase: def getFunctionPrototype(self, fn, urlprefix, urlsuffix): func = self.funcs.get(fn) if (isinstance(func, InterrogateFunction)): - if self.formattedprotos.has_key(fn): + if fn in self.formattedprotos: proto = self.formattedprotos[fn] else: proto = func.prototype @@ -864,7 +864,7 @@ def generate(pversion, indirlist, directdirlist, docdir, header, footer, urlpref body = body + generateFunctionDocs(code, method, urlprefix, urlsuffix) body = header + body + footer writeFile(docdir + "/" + type + ".html", body) - if (CLASS_RENAME_DICT.has_key(type)): + if type in CLASS_RENAME_DICT: modtype = CLASS_RENAME_DICT[type] writeFile(docdir + "/" + modtype + ".html", body) xclasses.append(modtype) @@ -892,8 +892,10 @@ def generate(pversion, indirlist, directdirlist, docdir, header, footer, urlpref for method in code.getClassMethods(type)[:]: name = code.getFunctionName(method) prefix = name[0].upper() - if (table.has_key(prefix)==0): table[prefix] = {} - if (table[prefix].has_key(name)==0): table[prefix][name] = [] + if prefix not in table: + table[prefix] = {} + if name not in table[prefix]: + table[prefix][name] = [] table[prefix][name].append(type) index = "

List of Methods - Panda " + pversion + "

\n" @@ -971,13 +973,13 @@ def expandImports(indirlist, directdirlist, fixdirlist): print fixfile+" : "+module+" : repairing" for x in funcExports: fn = code.getFunctionName(x) - if (used.has_key(fn)): + if fn in used: result.append("from "+module+" import "+fn) for x in typeExports: - if (used.has_key(x)): + if x in used: result.append("from "+module+" import "+x) for x in varExports: - if (used.has_key(x)): + if x in used: result.append("from "+module+" import "+x) else: result.append(line) diff --git a/direct/src/distributed/ConnectionRepository.py b/direct/src/distributed/ConnectionRepository.py index 3ff327a5b4..8af690357a 100644 --- a/direct/src/distributed/ConnectionRepository.py +++ b/direct/src/distributed/ConnectionRepository.py @@ -418,7 +418,7 @@ class ConnectionRepository( if hasattr(module, symbolName): dcImports[symbolName] = getattr(module, symbolName) else: - raise StandardError, 'Symbol %s not defined in module %s.' % (symbolName, moduleName) + raise Exception('Symbol %s not defined in module %s.' % (symbolName, moduleName)) else: # "import moduleName" diff --git a/direct/src/distributed/ServerRepository.py b/direct/src/distributed/ServerRepository.py index 613b88788f..7dcd5add72 100644 --- a/direct/src/distributed/ServerRepository.py +++ b/direct/src/distributed/ServerRepository.py @@ -192,7 +192,7 @@ class ServerRepository: dcImports[symbolName] = getattr(module, symbolName) else: - raise StandardError, 'Symbol %s not defined in module %s.' % (symbolName, moduleName) + raise Exception('Symbol %s not defined in module %s.' % (symbolName, moduleName)) else: # "import moduleName" diff --git a/direct/src/extensions_native/extension_native_helpers.py b/direct/src/extensions_native/extension_native_helpers.py index c6747e7272..d248f1f193 100644 --- a/direct/src/extensions_native/extension_native_helpers.py +++ b/direct/src/extensions_native/extension_native_helpers.py @@ -11,8 +11,10 @@ def Dtool_funcToMethod(func, cls, method_name=None): The new method is accessible to any instance immediately.""" if sys.version_info < (3, 0): func.im_class = cls - func.im_func = func - func.im_self = None + func.im_func = func + func.im_self = None + func.__func__ = func + func.__self__ = None if not method_name: method_name = func.__name__ cls.DtoolClassDict[method_name] = func diff --git a/direct/src/fsm/FSM.py b/direct/src/fsm/FSM.py index 1c0465b74d..2f9967783e 100644 --- a/direct/src/fsm/FSM.py +++ b/direct/src/fsm/FSM.py @@ -190,7 +190,7 @@ class FSM(DirectObject): def getCurrentFilter(self): if not self.state: error = "FSM cannot determine current filter while in transition (%s -> %s)." % (self.oldState, self.newState) - raise AlreadyInTransition, error + raise AlreadyInTransition(error) filter = getattr(self, "filter" + self.state, None) if not filter: @@ -276,7 +276,7 @@ class FSM(DirectObject): return if not self.request(request, *args): - raise RequestDenied, "%s (from state: %s)" % (request, self.state) + raise RequestDenied("%s (from state: %s)" % (request, self.state)) finally: self.fsmLock.release() @@ -310,7 +310,7 @@ class FSM(DirectObject): self.name, request, str(args)[1:])) filter = self.getCurrentFilter() - result = filter(request, args) + result = list(filter(request, args)) if result: if isinstance(result, types.StringTypes): # If the return value is a string, it's just the name @@ -381,7 +381,7 @@ class FSM(DirectObject): # request) not listed in defaultTransitions and not # handled by an earlier filter. if request[0].isupper(): - raise RequestDenied, "%s (from state: %s)" % (request, self.state) + raise RequestDenied("%s (from state: %s)" % (request, self.state)) # In either case, we quietly ignore unhandled command # (lowercase) requests. diff --git a/direct/src/fsm/State.py b/direct/src/fsm/State.py index 3be6501002..44a17080f8 100644 --- a/direct/src/fsm/State.py +++ b/direct/src/fsm/State.py @@ -30,18 +30,18 @@ class State(DirectObject): exitFunc = state.getExitFunc() # print 'testing: ', state, enterFunc, exitFunc, oldFunction if type(enterFunc) == types.MethodType: - if (enterFunc.im_func == oldFunction): + if enterFunc.__func__ == oldFunction: # print 'found: ', enterFunc, oldFunction state.setEnterFunc(types.MethodType(newFunction, - enterFunc.im_self, - enterFunc.im_class)) + enterFunc.__self__, + enterFunc.__self__.__class__)) count += 1 if type(exitFunc) == types.MethodType: - if (exitFunc.im_func == oldFunction): + if exitFunc.__func__ == oldFunction: # print 'found: ', exitFunc, oldFunction state.setExitFunc(types.MethodType(newFunction, - exitFunc.im_self, - exitFunc.im_class)) + exitFunc.__self__, + exitFunc.__self__.__class__)) count += 1 return count diff --git a/direct/src/gui/DirectGuiBase.py b/direct/src/gui/DirectGuiBase.py index 41322bcdff..2c67136535 100644 --- a/direct/src/gui/DirectGuiBase.py +++ b/direct/src/gui/DirectGuiBase.py @@ -258,8 +258,8 @@ class DirectGuiBase(DirectObject.DirectObject): text = 'Unknown option "' else: text = 'Unknown options "' - raise KeyError, text + ', '.join(unusedOptions) + \ - '" for ' + myClass.__name__ + raise KeyError(text + ', '.join(unusedOptions) + \ + '" for ' + myClass.__name__) # Can now call post init func self.postInitialiseFunc() @@ -399,8 +399,8 @@ class DirectGuiBase(DirectObject.DirectObject): if len(componentConfigFuncs) == 0 and \ component not in self._dynamicGroups: - raise KeyError, 'Unknown option "' + option + \ - '" for ' + self.__class__.__name__ + raise KeyError('Unknown option "' + option + \ + '" for ' + self.__class__.__name__) # Add the configure method(s) (may be more than # one if this is configuring a component group) @@ -413,8 +413,8 @@ class DirectGuiBase(DirectObject.DirectObject): indirectOptions[componentConfigFunc][componentOption] \ = value else: - raise KeyError, 'Unknown option "' + option + \ - '" for ' + self.__class__.__name__ + raise KeyError('Unknown option "' + option + \ + '" for ' + self.__class__.__name__) # Call the configure methods for any components. # Pass in the dictionary of keyword/values created above @@ -468,8 +468,8 @@ class DirectGuiBase(DirectObject.DirectObject): return componentCget(componentOption) # Option not found - raise KeyError, 'Unknown option "' + option + \ - '" for ' + self.__class__.__name__ + raise KeyError('Unknown option "' + option + \ + '" for ' + self.__class__.__name__) # Allow index style refererences __getitem__ = cget @@ -481,8 +481,7 @@ class DirectGuiBase(DirectObject.DirectObject): """ # Check for invalid component name if '_' in componentName: - raise ValueError, \ - 'Component name "%s" must not contain "_"' % componentName + raise ValueError('Component name "%s" must not contain "_"' % componentName) # Get construction keywords if hasattr(self, '_constructorKeywords'): diff --git a/direct/src/gui/DirectScrollBar.py b/direct/src/gui/DirectScrollBar.py index a2a6f70ab2..acdc0a9c95 100644 --- a/direct/src/gui/DirectScrollBar.py +++ b/direct/src/gui/DirectScrollBar.py @@ -142,7 +142,7 @@ class DirectScrollBar(DirectFrame): elif self['orientation'] == DGG.VERTICAL_INVERTED: self.guiItem.setAxis(Vec3(0, 0, 1)) else: - raise ValueError, 'Invalid value for orientation: %s' % (self['orientation']) + raise ValueError('Invalid value for orientation: %s' % (self['orientation'])) def setManageButtons(self): self.guiItem.setManagePieces(self['manageButtons']) diff --git a/direct/src/gui/DirectSlider.py b/direct/src/gui/DirectSlider.py index 40737e6c9f..4fdc0588c8 100644 --- a/direct/src/gui/DirectSlider.py +++ b/direct/src/gui/DirectSlider.py @@ -111,7 +111,7 @@ class DirectSlider(DirectFrame): elif self['orientation'] == DGG.VERTICAL: self.guiItem.setAxis(Vec3(0, 0, 1)) else: - raise ValueError, 'Invalid value for orientation: %s' % (self['orientation']) + raise ValueError('Invalid value for orientation: %s' % (self['orientation'])) def destroy(self): if (hasattr(self, 'thumb')): diff --git a/direct/src/interval/FunctionInterval.py b/direct/src/interval/FunctionInterval.py index 2dc2d7686a..a730373916 100644 --- a/direct/src/interval/FunctionInterval.py +++ b/direct/src/interval/FunctionInterval.py @@ -34,11 +34,11 @@ class FunctionInterval(Interval.Interval): # print 'testing: ', ival.function, oldFunction # Note: you can only replace methods currently if type(ival.function) == types.MethodType: - if (ival.function.im_func == oldFunction): + if ival.function.__func__ == oldFunction: # print 'found: ', ival.function, oldFunction ival.function = types.MethodType(newFunction, - ival.function.im_self, - ival.function.im_class) + ival.function.__self__, + ival.function.__self__.__class__) count += 1 return count diff --git a/direct/src/interval/ProjectileInterval.py b/direct/src/interval/ProjectileInterval.py index d87253a5ad..9b8942d5ab 100755 --- a/direct/src/interval/ProjectileInterval.py +++ b/direct/src/interval/ProjectileInterval.py @@ -221,7 +221,7 @@ class ProjectileInterval(Interval): def testTrajectory(self): try: self.__calcTrajectory(*self.trajectoryArgs) - except StandardError: + except Exception: assert self.notify.error('invalid projectile parameters') return False return True diff --git a/direct/src/p3d/AppRunner.py b/direct/src/p3d/AppRunner.py index 9c6c15631a..0fd46de469 100644 --- a/direct/src/p3d/AppRunner.py +++ b/direct/src/p3d/AppRunner.py @@ -798,7 +798,7 @@ class AppRunner(DirectObject): if not host.hasContentsFile: # This is weird. How did we launch without having # this file at all? - raise OSError, message + raise OSError(message) # Just make it a warning and continue. self.notify.warning(message) @@ -819,20 +819,20 @@ class AppRunner(DirectObject): return self.addPackageInfo(name, platform, version, hostUrl, hostDir = hostDir, recurse = True) message = "Couldn't find %s %s on %s" % (name, version, hostUrl) - raise OSError, message + raise OSError(message) package.checkStatus() if not package.downloadDescFile(self.http): message = "Couldn't get desc file for %s" % (name) - raise OSError, message + raise OSError(message) if not package.downloadPackage(self.http): message = "Couldn't download %s" % (name) - raise OSError, message + raise OSError(message) if not package.installPackage(self): message = "Couldn't install %s" % (name) - raise OSError, message + raise OSError(message) if package.guiApp: self.guiApp = True @@ -877,17 +877,17 @@ class AppRunner(DirectObject): vfs = VirtualFileSystem.getGlobalPtr() if not vfs.exists(fname): - raise ArgumentError, "No such file: %s" % (p3dFilename) + raise ArgumentError("No such file: %s" % (p3dFilename)) fname.makeAbsolute() fname.setBinary() mf = Multifile() if p3dOffset == 0: if not mf.openRead(fname): - raise ArgumentError, "Not a Panda3D application: %s" % (p3dFilename) + raise ArgumentError("Not a Panda3D application: %s" % (p3dFilename)) else: if not mf.openRead(fname, p3dOffset): - raise ArgumentError, "Not a Panda3D application: %s at offset: %s" % (p3dFilename, p3dOffset) + raise ArgumentError("Not a Panda3D application: %s at offset: %s" % (p3dFilename, p3dOffset)) # Now load the p3dInfo file. self.p3dInfo = None @@ -925,7 +925,7 @@ class AppRunner(DirectObject): # The interactiveConsole flag can only be set true if the # application has allow_python_dev set. if not self.allowPythonDev and interactiveConsole: - raise StandardError, "Impossible, interactive_console set without allow_python_dev." + raise Exception("Impossible, interactive_console set without allow_python_dev.") self.interactiveConsole = interactiveConsole if self.allowPythonDev: diff --git a/direct/src/p3d/JavaScript.py b/direct/src/p3d/JavaScript.py index 3b6d295032..3208b7d7ba 100644 --- a/direct/src/p3d/JavaScript.py +++ b/direct/src/p3d/JavaScript.py @@ -13,9 +13,11 @@ class UndefinedObject: attributes, similar to None, but it is a slightly different concept in JavaScript. """ - def __nonzero__(self): + def __bool__(self): return False + __nonzero__ = __bool__ # Python 2 + def __str__(self): return "Undefined" @@ -83,16 +85,18 @@ class BrowserObject: def __str__(self): return self.toString() - def __nonzero__(self): + def __bool__(self): return True + __nonzero__ = __bool__ # Python 2 + def __call__(self, *args, **kw): needsResponse = True if 'needsResponse' in kw: needsResponse = kw['needsResponse'] del kw['needsResponse'] if kw: - raise ArgumentError, 'Keyword arguments not supported' + raise ArgumentError('Keyword arguments not supported') try: parentObj, attribName = self.__childObject @@ -242,16 +246,18 @@ class MethodWrapper: parentObj, attribName = self.__childObject return "%s.%s" % (parentObj, attribName) - def __nonzero__(self): + def __bool__(self): return True + __nonzero__ = __bool__ # Python 2 + def __call__(self, *args, **kw): needsResponse = True if 'needsResponse' in kw: needsResponse = kw['needsResponse'] del kw['needsResponse'] if kw: - raise ArgumentError, 'Keyword arguments not supported' + raise ArgumentError('Keyword arguments not supported') try: parentObj, attribName = self.__childObject diff --git a/direct/src/p3d/PackageInstaller.py b/direct/src/p3d/PackageInstaller.py index 33527ef94e..cec1e07b11 100644 --- a/direct/src/p3d/PackageInstaller.py +++ b/direct/src/p3d/PackageInstaller.py @@ -239,7 +239,7 @@ class PackageInstaller(DirectObject): downloaded. Call donePackages() to finish the list. """ if self.state != self.S_initial: - raise ValueError, 'addPackage called after donePackages' + raise ValueError('addPackage called after donePackages') host = self.appRunner.getHostWithAlt(hostUrl) pp = self.PendingPackage(packageName, version, host) diff --git a/direct/src/p3d/PackageMerger.py b/direct/src/p3d/PackageMerger.py index a00a3f7d35..9c2e1ac499 100644 --- a/direct/src/p3d/PackageMerger.py +++ b/direct/src/p3d/PackageMerger.py @@ -7,7 +7,7 @@ from panda3d.core import * import shutil import os -class PackageMergerError(StandardError): +class PackageMergerError(Exception): pass class PackageMerger: @@ -102,12 +102,12 @@ class PackageMerger: doc = TiXmlDocument(packageDescFullpath.toOsSpecific()) if not doc.LoadFile(): message = "Could not read XML file: %s" % (self.descFile.filename) - raise OSError, message + raise OSError(message) xpackage = doc.FirstChildElement('package') if not xpackage: message = "No package definition: %s" % (self.descFile.filename) - raise OSError, message + raise OSError(message) xcompressed = xpackage.FirstChildElement('compressed_archive') if xcompressed: @@ -286,7 +286,7 @@ class PackageMerger: if not self.__readContentsFile(sourceDir, packageNames): message = "Couldn't read %s" % (sourceDir) - raise PackageMergerError, message + raise PackageMergerError(message) def close(self): """ Finalizes the results of all of the previous calls to diff --git a/direct/src/p3d/Packager.py b/direct/src/p3d/Packager.py index f7d6855a90..2f1e6a36e1 100644 --- a/direct/src/p3d/Packager.py +++ b/direct/src/p3d/Packager.py @@ -26,7 +26,7 @@ from direct.directnotify.DirectNotifyGlobal import * vfs = VirtualFileSystem.getGlobalPtr() -class PackagerError(StandardError): +class PackagerError(Exception): pass class OutsideOfPackageError(PackagerError): @@ -390,7 +390,7 @@ class Packager: if not self.p3dApplication and not self.packager.allowPackages: message = 'Cannot generate packages without an installDir; use -i' - raise PackagerError, message + raise PackagerError(message) if self.ignoredDirFiles: exts = sorted(self.ignoredDirFiles.keys()) @@ -429,11 +429,11 @@ class Packager: if self.version != PandaSystem.getPackageVersionString(): message = 'mismatched Panda3D version: requested %s, but Panda3D is built as %s' % (self.version, PandaSystem.getPackageVersionString()) - raise PackagerError, message + raise PackagerError(message) if self.host != PandaSystem.getPackageHostUrl(): message = 'mismatched Panda3D host: requested %s, but Panda3D is built as %s' % (self.host, PandaSystem.getPackageHostUrl()) - raise PackagerError, message + raise PackagerError(message) if self.p3dApplication: # Default compression level for an app. @@ -554,7 +554,7 @@ class Packager: # Add the main module, if any. if not self.mainModule and self.p3dApplication: message = 'No main_module specified for application %s' % (self.packageName) - raise PackagerError, message + raise PackagerError(message) if self.mainModule: moduleName, newName = self.mainModule if newName not in self.freezer.modules: @@ -790,7 +790,7 @@ class Packager: if not self.packager.allowPackages: message = 'Cannot generate packages without an installDir; use -i' - raise PackagerError, message + raise PackagerError(message) installPath = Filename(self.packager.installDir, packageDir) # Remove any files already in the installPath. @@ -811,7 +811,7 @@ class Packager: return if len(files) != 1: - raise PackagerError, 'Multiple files in "solo" package %s' % (self.packageName) + raise PackagerError('Multiple files in "solo" package %s' % (self.packageName)) Filename(installPath, '').makeDir() @@ -1535,7 +1535,7 @@ class Packager: compressedPath = Filename(self.packager.installDir, newCompressedFilename) if not compressFile(self.packageFullpath, compressedPath, 6): message = 'Unable to write %s' % (compressedPath) - raise PackagerError, message + raise PackagerError(message) def readDescFile(self): """ Reads the existing package.xml file before rewriting @@ -1838,7 +1838,7 @@ class Packager: if parentName not in self.freezer.modules: message = 'Cannot add Python file %s; not in package' % (file.newName) if file.required or file.explicit: - raise StandardError, message + raise Exception(message) else: self.notify.warning(message) return @@ -1852,7 +1852,7 @@ class Packager: # Precompile egg files to bam's. np = self.packager.loader.loadModel(file.filename) if not np: - raise StandardError, 'Could not read egg file %s' % (file.filename) + raise Exception('Could not read egg file %s' % (file.filename)) bamName = Filename(file.newName) bamName.setExtension('bam') @@ -1862,14 +1862,14 @@ class Packager: # Load the bam file so we can massage its textures. bamFile = BamFile() if not bamFile.openRead(file.filename): - raise StandardError, 'Could not read bam file %s' % (file.filename) + raise Exception('Could not read bam file %s' % (file.filename)) if not bamFile.resolve(): - raise StandardError, 'Could not resolve bam file %s' % (file.filename) + raise Exception('Could not resolve bam file %s' % (file.filename)) node = bamFile.readNode() if not node: - raise StandardError, 'Not a model file: %s' % (file.filename) + raise Exception('Not a model file: %s' % (file.filename)) self.addNode(node, file.filename, file.newName) @@ -2703,7 +2703,7 @@ class Packager: self.allowPackages = False if not PandaSystem.getPackageVersionString() or not PandaSystem.getPackageHostUrl(): - raise PackagerError, 'This script must be run using a version of Panda3D that has been built\nfor distribution. Try using ppackage.p3d or packp3d.p3d instead.\nIf you are running this script for development purposes, you may also\nset the Config variable panda-package-host-url to the URL you expect\nto download these contents from (for instance, a file:// URL).' + raise PackagerError('This script must be run using a version of Panda3D that has been built\nfor distribution. Try using ppackage.p3d or packp3d.p3d instead.\nIf you are running this script for development purposes, you may also\nset the Config variable panda-package-host-url to the URL you expect\nto download these contents from (for instance, a file:// URL).') self.readContentsFile() @@ -2804,7 +2804,7 @@ class Packager: self.notify.info("No files added to %s" % (name)) for (lineno, stype, sname, args, kw) in statements: if stype == 'class': - raise PackagerError, 'Nested classes not allowed' + raise PackagerError('Nested classes not allowed') self.__evalFunc(sname, args, kw) package = self.endPackage() if package is not None: @@ -2812,7 +2812,7 @@ class Packager: elif packageNames is not None: # If the name is explicitly specified, this means # we should abort if the package faild to construct. - raise PackagerError, 'Failed to construct %s' % name + raise PackagerError('Failed to construct %s' % name) else: self.__evalFunc(name, args, kw) except PackagerError: @@ -2838,7 +2838,7 @@ class Packager: func(*args, **kw) except OutsideOfPackageError: message = '%s encountered outside of package definition' % (name) - raise OutsideOfPackageError, message + raise OutsideOfPackageError(message) def __expandTabs(self, line, tabWidth = 8): """ Expands tab characters in the line to 8 spaces. """ @@ -2883,10 +2883,10 @@ class Packager: value = value.strip() if parameter not in argList: message = 'Unknown parameter %s' % (parameter) - raise PackagerError, message + raise PackagerError(message) if parameter in args: message = 'Duplicate parameter %s' % (parameter) - raise PackagerError, message + raise PackagerError(message) args[parameter] = value @@ -2900,7 +2900,7 @@ class Packager: to file() etc., and close the package with endPackage(). """ if self.currentPackage: - raise PackagerError, 'unclosed endPackage %s' % (self.currentPackage.packageName) + raise PackagerError('unclosed endPackage %s' % (self.currentPackage.packageName)) package = self.Package(packageName, self) self.currentPackage = package @@ -2910,7 +2910,7 @@ class Packager: if not package.p3dApplication and not self.allowPackages: message = 'Cannot generate packages without an installDir; use -i' - raise PackagerError, message + raise PackagerError(message) def endPackage(self): @@ -2919,7 +2919,7 @@ class Packager: or None if the package failed to close (e.g. missing files). """ if not self.currentPackage: - raise PackagerError, 'unmatched endPackage' + raise PackagerError('unmatched endPackage') package = self.currentPackage package.signParams += self.signParams[:] @@ -3310,7 +3310,7 @@ class Packager: raise OutsideOfPackageError if (newName or filename) and len(moduleNames) != 1: - raise PackagerError, 'Cannot specify newName with multiple modules' + raise PackagerError('Cannot specify newName with multiple modules') if required: self.currentPackage.requiredModules += moduleNames @@ -3469,7 +3469,7 @@ class Packager: package.mainModule = None if not package.mainModule and compileToExe: message = "No main_module specified for exe %s" % (filename) - raise PackagerError, message + raise PackagerError(message) if package.mainModule: moduleName, newName = package.mainModule @@ -3641,12 +3641,12 @@ class Packager: if newName: if len(files) != 1: message = 'Cannot install multiple files on target filename %s' % (newName) - raise PackagerError, message + raise PackagerError(message) if text: if len(files) != 1: message = 'Cannot install text to multiple files' - raise PackagerError, message + raise PackagerError(message) if not newName: newName = str(filenames[0]) diff --git a/direct/src/p3d/PatchMaker.py b/direct/src/p3d/PatchMaker.py index 7055f5eb3e..485ad0d0e9 100644 --- a/direct/src/p3d/PatchMaker.py +++ b/direct/src/p3d/PatchMaker.py @@ -765,7 +765,7 @@ class PatchMaker: filename = Filename(package.currentFile.filename + '.%s.patch' % (package.patchVersion)) assert filename not in self.patchFilenames if not self.buildPatch(topPv, currentPv, package, filename): - raise StandardError, "Couldn't build patch." + raise Exception("Couldn't build patch.") def buildPatch(self, v1, v2, package, patchFilename): """ Builds a patch from PackageVersion v1 to PackageVersion @@ -780,7 +780,7 @@ class PatchMaker: compressedPathname = Filename(pathname + '.pz') compressedPathname.unlink() if not compressFile(pathname, compressedPathname, 9): - raise StandardError, "Couldn't compress patch." + raise Exception("Couldn't compress patch.") pathname.unlink() patchfile = self.Patchfile(package) diff --git a/direct/src/p3d/SeqValue.py b/direct/src/p3d/SeqValue.py index c146944dfa..d41cfd250b 100644 --- a/direct/src/p3d/SeqValue.py +++ b/direct/src/p3d/SeqValue.py @@ -26,7 +26,7 @@ class SeqValue: elif isinstance(value, types.StringTypes): self.setFromString(value) else: - raise TypeError, 'Invalid sequence type: %s' % (value,) + raise TypeError('Invalid sequence type: %s' % (value,)) def setFromTuple(self, value): """ Sets the seq from the indicated tuple of integers. """ diff --git a/direct/src/p3d/packp3d.py b/direct/src/p3d/packp3d.py index e1cebf2137..a33a49e2d4 100755 --- a/direct/src/p3d/packp3d.py +++ b/direct/src/p3d/packp3d.py @@ -107,7 +107,7 @@ from panda3d.core import * # Temp hack for debugging. #from direct.p3d.AppRunner import dummyAppRunner; dummyAppRunner() -class ArgumentError(StandardError): +class ArgumentError(Exception): pass def makePackedApp(args): @@ -167,13 +167,13 @@ def makePackedApp(args): sys.exit(0) if not appFilename: - raise ArgumentError, "No target app specified. Use:\n %s -o app.p3d\nUse -h to get more usage information." % (os.path.split(sys.argv[0])[1]) + raise ArgumentError("No target app specified. Use:\n %s -o app.p3d\nUse -h to get more usage information." % (os.path.split(sys.argv[0])[1])) if args: - raise ArgumentError, "Extra arguments on command line." + raise ArgumentError("Extra arguments on command line.") if appFilename.getExtension() != 'p3d': - raise ArgumentError, 'Application filename must end in ".p3d".' + raise ArgumentError('Application filename must end in ".p3d".') appDir = Filename(appFilename.getDirname()) if not appDir: @@ -188,9 +188,9 @@ def makePackedApp(args): if not main.exists(): main = glob.glob(os.path.join(root.toOsSpecific(), '*.py')) if len(main) == 0: - raise ArgumentError, 'No Python files in root directory.' + raise ArgumentError('No Python files in root directory.') elif len(main) > 1: - raise ArgumentError, 'Multiple Python files in root directory; specify the main application with -m "main".' + raise ArgumentError('Multiple Python files in root directory; specify the main application with -m "main".') main = Filename.fromOsSpecific(os.path.split(main[0])[1]) main.makeAbsolute(root) diff --git a/direct/src/p3d/runp3d.py b/direct/src/p3d/runp3d.py index e561e73a0f..167f8d0d2f 100644 --- a/direct/src/p3d/runp3d.py +++ b/direct/src/p3d/runp3d.py @@ -46,7 +46,7 @@ def parseSysArgs(): sys.exit(1) if not args or not args[0]: - raise ArgumentError, "No Panda app specified. Use:\nrunp3d.py app.p3d" + raise ArgumentError("No Panda app specified. Use:\nrunp3d.py app.p3d") arg0 = args[0] p3dFilename = Filename.fromOsSpecific(arg0) diff --git a/direct/src/plugin_npapi/make_osx_bundle.py b/direct/src/plugin_npapi/make_osx_bundle.py index 8d83b35310..e4b9f365a6 100755 --- a/direct/src/plugin_npapi/make_osx_bundle.py +++ b/direct/src/plugin_npapi/make_osx_bundle.py @@ -33,7 +33,7 @@ def makeBundle(startDir): path.appendPath(os.environ['DYLD_LIBRARY_PATH']) nppanda3d = path.findFile('nppanda3d') if not nppanda3d: - raise StandardError, "Couldn't find nppanda3d on path." + raise Exception("Couldn't find nppanda3d on path.") # Generate the bundle directory structure rootFilename = Filename(fstartDir, 'bundle') @@ -54,7 +54,7 @@ def makeBundle(startDir): resourceFilename.toOsSpecific(), Filename(fstartDir, "nppanda3d.r").toOsSpecific())) if not resourceFilename.exists(): - raise IOError, 'Unable to run Rez' + raise IOError('Unable to run Rez') # Copy in Info.plist and the compiled executable. shutil.copyfile(Filename(fstartDir, "nppanda3d.plist").toOsSpecific(), plistFilename.toOsSpecific()) diff --git a/direct/src/plugin_standalone/make_osx_bundle.py b/direct/src/plugin_standalone/make_osx_bundle.py index 20807f6974..2fe846a3c3 100755 --- a/direct/src/plugin_standalone/make_osx_bundle.py +++ b/direct/src/plugin_standalone/make_osx_bundle.py @@ -32,7 +32,7 @@ def makeBundle(startDir): path.appendPath(os.defpath) panda3d_mac = path.findFile('panda3d_mac') if not panda3d_mac: - raise StandardError, "Couldn't find panda3d_mac on path." + raise Exception("Couldn't find panda3d_mac on path.") # Construct a search path to look for the images. search = DSearchPath() @@ -53,7 +53,7 @@ def makeBundle(startDir): # Now find the icon file on the above search path. icons = search.findFile('panda3d.icns') if not icons: - raise StandardError, "Couldn't find panda3d.icns on model-path." + raise Exception("Couldn't find panda3d.icns on model-path.") # Generate the bundle directory structure rootFilename = Filename(fstartDir) diff --git a/direct/src/showbase/Audio3DManager.py b/direct/src/showbase/Audio3DManager.py index 270a7e56c4..5a4fdc295b 100644 --- a/direct/src/showbase/Audio3DManager.py +++ b/direct/src/showbase/Audio3DManager.py @@ -123,7 +123,7 @@ class Audio3DManager: Default: VBase3(0, 0, 0) """ if not isinstance(velocity, VBase3): - raise TypeError, "Invalid argument 1, expected " + raise TypeError("Invalid argument 1, expected ") self.vel_dict[sound]=velocity def setSoundVelocityAuto(self, sound): @@ -156,7 +156,7 @@ class Audio3DManager: Default: VBase3(0, 0, 0) """ if not isinstance(velocity, VBase3): - raise TypeError, "Invalid argument 0, expected " + raise TypeError("Invalid argument 0, expected ") self.listener_vel=velocity def setListenerVelocityAuto(self): diff --git a/direct/src/showbase/Loader.py b/direct/src/showbase/Loader.py index 94bc5d4e14..9521df23ef 100644 --- a/direct/src/showbase/Loader.py +++ b/direct/src/showbase/Loader.py @@ -324,7 +324,7 @@ class Loader(DirectObject): nodeList[i] = nodeList[i].node() # From here on, we deal with a list of (filename, node) pairs. - modelList = zip(modelList, nodeList) + modelList = list(zip(modelList, nodeList)) if callback is None: # We got no callback, so it's a synchronous save. diff --git a/direct/src/showbase/Messenger.py b/direct/src/showbase/Messenger.py index aba83d7d3a..e9f9241646 100644 --- a/direct/src/showbase/Messenger.py +++ b/direct/src/showbase/Messenger.py @@ -132,7 +132,7 @@ class Messenger: # Make sure extraArgs is a list or tuple if not (isinstance(extraArgs, list) or isinstance(extraArgs, tuple) or isinstance(extraArgs, set)): - raise TypeError, "A list is required as extraArgs argument" + raise TypeError("A list is required as extraArgs argument") self.lock.acquire() try: @@ -442,7 +442,7 @@ class Messenger: object, params = objectEntry method = params[0] if (type(method) == types.MethodType): - function = method.im_func + function = method.__func__ else: function = method #print ('function: ' + repr(function) + '\n' + @@ -451,7 +451,7 @@ class Messenger: # 'newFunction: ' + repr(newFunction) + '\n') if (function == oldMethod): newMethod = types.MethodType( - newFunction, method.im_self, method.im_class) + newFunction, method.__self__, method.__self__.__class__) params[0] = newMethod # Found it retrun true retFlag += 1 @@ -560,8 +560,8 @@ class Messenger: return string version of class.method or method. """ if (type(method) == types.MethodType): - functionName = method.im_class.__name__ + '.' + \ - method.im_func.__name__ + functionName = method.__self__.__class__.__name__ + '.' + \ + method.__func__.__name__ else: if hasattr(method, "__name__"): functionName = method.__name__ @@ -629,7 +629,7 @@ class Messenger: if (type(function) == types.MethodType): str = (str + '\t' + 'Method: ' + repr(function) + '\n\t' + - 'Function: ' + repr(function.im_func) + '\n') + 'Function: ' + repr(function.__func__) + '\n') else: str = (str + '\t' + 'Function: ' + repr(function) + '\n') diff --git a/direct/src/showbase/PythonUtil.py b/direct/src/showbase/PythonUtil.py index 3e8e8aa581..e1750cf21f 100644 --- a/direct/src/showbase/PythonUtil.py +++ b/direct/src/showbase/PythonUtil.py @@ -660,7 +660,7 @@ if __debug__: def profileDecorator(f): def _profiled(*args, **kArgs): - name = '(%s) %s from %s' % (category, f.func_name, f.__module__) + name = '(%s) %s from %s' % (category, f.__name__, f.__module__) # showbase might not be loaded yet, so don't use # base.config. Instead, query the ConfigVariableBool. @@ -1265,12 +1265,12 @@ class Enum: invalidChars = invalidChars.replace('_','') invalidFirstChars = invalidChars+string.digits if item[0] in invalidFirstChars: - raise SyntaxError, ("Enum '%s' contains invalid first char" % + raise SyntaxError("Enum '%s' contains invalid first char" % item) if not disjoint(item, invalidChars): for char in item: if char in invalidChars: - raise SyntaxError, ( + raise SyntaxError( "Enum\n'%s'\ncontains illegal char '%s'" % (item, char)) return 1 @@ -2070,7 +2070,7 @@ def report(types = [], prefix = '', xform = None, notifyFunc = None, dConfigPara rArgs = '(' + reduce(str.__add__,rArgs)[:-2] + ')' - outStr = '%s%s' % (f.func_name, rArgs) + outStr = '%s%s' % (f.__name__, rArgs) # Insert prefix place holder, if needed if prefixes: @@ -2127,9 +2127,9 @@ def report(types = [], prefix = '', xform = None, notifyFunc = None, dConfigPara pass return rVal - wrap.func_name = f.func_name - wrap.func_dict = f.func_dict - wrap.func_doc = f.func_doc + wrap.__name__ = f.__name__ + wrap.__dict__ = f.__dict__ + wrap.__doc__ = f.__doc__ wrap.__module__ = f.__module__ return wrap return decorator @@ -2179,7 +2179,7 @@ if __debug__: return f(*args, **kArgs) except Exception, e: try: - s = '%s(' % f.func_name + s = '%s(' % f.__name__ for arg in args: s += '%s, ' % arg for key, value in kArgs.items(): @@ -2193,7 +2193,7 @@ if __debug__: exceptionLoggedNotify.info(s) except: exceptionLoggedNotify.info( - '%s: ERROR IN PRINTING' % f.func_name) + '%s: ERROR IN PRINTING' % f.__name__) raise _exceptionLogged.__doc__ = f.__doc__ return _exceptionLogged diff --git a/direct/src/showbase/RandomNumGen.py b/direct/src/showbase/RandomNumGen.py index 0b6df19d2b..da95bbabee 100644 --- a/direct/src/showbase/RandomNumGen.py +++ b/direct/src/showbase/RandomNumGen.py @@ -96,30 +96,30 @@ class RandomNumGen: # common case while still doing adequate error checking istart = int(start) if istart != start: - raise ValueError, "non-integer arg 1 for randrange()" + raise ValueError("non-integer arg 1 for randrange()") if stop is None: if istart > 0: return self.__rand(istart) - raise ValueError, "empty range for randrange()" + raise ValueError("empty range for randrange()") istop = int(stop) if istop != stop: - raise ValueError, "non-integer stop for randrange()" + raise ValueError("non-integer stop for randrange()") if step == 1: if istart < istop: return istart + self.__rand(istop - istart) - raise ValueError, "empty range for randrange()" + raise ValueError("empty range for randrange()") istep = int(step) if istep != step: - raise ValueError, "non-integer step for randrange()" + raise ValueError("non-integer step for randrange()") if istep > 0: n = (istop - istart + istep - 1) / istep elif istep < 0: n = (istop - istart + istep + 1) / istep else: - raise ValueError, "zero step for randrange()" + raise ValueError("zero step for randrange()") if n <= 0: - raise ValueError, "empty range for randrange()" + raise ValueError("empty range for randrange()") return istart + istep*int(self.__rand(n)) def randint(self, a, b): diff --git a/direct/src/showbase/ShowBase.py b/direct/src/showbase/ShowBase.py index 28aa140e8e..f9f8068683 100644 --- a/direct/src/showbase/ShowBase.py +++ b/direct/src/showbase/ShowBase.py @@ -338,7 +338,7 @@ class ShowBase(DirectObject.DirectObject): # Make sure we're not making more than one ShowBase. if hasattr(builtins, 'base'): - raise StandardError, "Attempt to spawn multiple ShowBase instances!" + raise Exception("Attempt to spawn multiple ShowBase instances!") # DO NOT ADD TO THIS LIST. We're trying to phase out the use of # built-in variables by ShowBase. Use a Global module if necessary. @@ -695,7 +695,7 @@ class ShowBase(DirectObject.DirectObject): if requireWindow: # Unless require-window is set to false, it is an # error not to open a window. - raise StandardError, 'Could not open window.' + raise Exception('Could not open window.') else: self.notify.info("Successfully opened window of type %s (%s)" % ( win.getType(), win.getPipe().getInterfaceName())) @@ -2519,7 +2519,7 @@ class ShowBase(DirectObject.DirectObject): rig = NodePath(namePrefix) buffer = source.makeCubeMap(namePrefix, size, rig, cameraMask, 1) if buffer == None: - raise StandardError, "Could not make cube map." + raise Exception("Could not make cube map.") # Set the near and far planes from the default lens. lens = rig.find('**/+Camera').node().getLens() @@ -2589,7 +2589,7 @@ class ShowBase(DirectObject.DirectObject): buffer = toSphere.makeCubeMap(namePrefix, size, rig, cameraMask, 0) if buffer == None: self.graphicsEngine.removeWindow(toSphere) - raise StandardError, "Could not make cube map." + raise Exception("Could not make cube map.") # Set the near and far planes from the default lens. lens = rig.find('**/+Camera').node().getLens() diff --git a/direct/src/showutil/FreezeTool.py b/direct/src/showutil/FreezeTool.py index 286e56ba9d..9862e1c764 100644 --- a/direct/src/showutil/FreezeTool.py +++ b/direct/src/showutil/FreezeTool.py @@ -171,7 +171,7 @@ class CompilationEnvironment: } print >> sys.stderr, compile if os.system(compile) != 0: - raise StandardError, 'failed to compile %s.' % basename + raise Exception('failed to compile %s.' % basename) link = self.linkExe % { 'python' : self.Python, @@ -186,7 +186,7 @@ class CompilationEnvironment: } print >> sys.stderr, link if os.system(link) != 0: - raise StandardError, 'failed to link %s.' % basename + raise Exception('failed to link %s.' % basename) def compileDll(self, filename, basename): compile = self.compileObj % { @@ -203,7 +203,7 @@ class CompilationEnvironment: } print >> sys.stderr, compile if os.system(compile) != 0: - raise StandardError, 'failed to compile %s.' % basename + raise Exception('failed to compile %s.' % basename) link = self.linkDll % { 'python' : self.Python, @@ -219,7 +219,7 @@ class CompilationEnvironment: } print >> sys.stderr, link if os.system(link) != 0: - raise StandardError, 'failed to link %s.' % basename + raise Exception('failed to link %s.' % basename) # The code from frozenmain.c in the Python source repository. frozenMainCode = """ @@ -1207,7 +1207,7 @@ class Freezer: Filename(mfname).unlink() multifile = Multifile() if not multifile.openReadWrite(mfname): - raise StandardError + raise Exception self.addToMultifile(multifile) @@ -1284,7 +1284,7 @@ class Freezer: # We must have a __main__ module to make an exe file. if not self.__writingModule('__main__'): message = "Can't generate an executable without a __main__ module." - raise StandardError, message + raise Exception(message) filename = basename + self.sourceExtension @@ -1407,9 +1407,11 @@ class PandaModuleFinder(modulefinder.ModuleFinder): return (None, name, ('', '', imp.PY_FROZEN)) message = "DLL loader cannot find %s." % (name) - raise ImportError, message + raise ImportError(message) + + def load_module(self, fqname, fp, pathname, file_info): + suffix, mode, type = file_info - def load_module(self, fqname, fp, pathname, (suffix, mode, type)): if type == imp.PY_FROZEN: # It's a frozen module. co, isPackage = p3extend_frozen.get_frozen_module_code(pathname) diff --git a/direct/src/stdpy/glob.py b/direct/src/stdpy/glob.py index 3d1cce60f4..6f825a4561 100755 --- a/direct/src/stdpy/glob.py +++ b/direct/src/stdpy/glob.py @@ -61,7 +61,7 @@ def glob1(dirname, pattern): except os.error: return [] if pattern[0] != '.': - names = filter(lambda x: x[0] != '.', names) + names = [x for x in names if x[0] != '.'] return fnmatch.filter(names, pattern) def glob0(dirname, basename): diff --git a/direct/src/stdpy/thread.py b/direct/src/stdpy/thread.py index f8291488d1..ccbc141b5b 100644 --- a/direct/src/stdpy/thread.py +++ b/direct/src/stdpy/thread.py @@ -21,7 +21,7 @@ from panda3d import core forceYield = core.Thread.forceYield considerYield = core.Thread.considerYield -class error(StandardError): +class error(Exception): pass class LockType: @@ -54,7 +54,7 @@ class LockType: self.__lock.acquire() try: if not self.__locked: - raise error, 'Releasing unheld lock.' + raise error('Releasing unheld lock.') self.__locked = False self.__cvar.notify() diff --git a/direct/src/stdpy/threading2.py b/direct/src/stdpy/threading2.py index d03ac01c3c..b9df97ca97 100644 --- a/direct/src/stdpy/threading2.py +++ b/direct/src/stdpy/threading2.py @@ -139,10 +139,9 @@ class _RLock(_Verbose): # Internal methods used by condition variables - def _acquire_restore(self, (count, owner)): + def _acquire_restore(self, state): self.__block.acquire() - self.__count = count - self.__owner = owner + self.__count, self.__owner = state if __debug__: self._note("%s._acquire_restore()", self) @@ -334,7 +333,7 @@ class _BoundedSemaphore(_Semaphore): def release(self): if self._Semaphore__value >= self._initial_value: - raise ValueError, "Semaphore released too many times" + raise ValueError("Semaphore released too many times") return _Semaphore.release(self) diff --git a/direct/src/task/Task.py b/direct/src/task/Task.py index 5d4a831f32..bce3b127e1 100644 --- a/direct/src/task/Task.py +++ b/direct/src/task/Task.py @@ -571,13 +571,13 @@ class TaskManager: method = task.getFunction() if (type(method) == types.MethodType): - function = method.im_func + function = method.__func__ else: function = method if (function == oldMethod): newMethod = types.MethodType(newFunction, - method.im_self, - method.im_class) + method.__self__, + method.__self__.__class__) task.setFunction(newMethod) # Found a match return 1 diff --git a/direct/src/tkpanels/FSMInspector.py b/direct/src/tkpanels/FSMInspector.py index 398cd1583f..f6c5cc258e 100644 --- a/direct/src/tkpanels/FSMInspector.py +++ b/direct/src/tkpanels/FSMInspector.py @@ -151,7 +151,7 @@ class FSMInspector(AppShell): toCenter, self.computePoint(toState.radius, angle - DELTA)) - return newFromPt + newToPt + return list(newFromPt) + list(newToPt) def computePoint(self, radius, angle): x = radius * math.cos(angle) diff --git a/direct/src/tkpanels/Inspector.py b/direct/src/tkpanels/Inspector.py index 47d3b4f6a6..98e4378e30 100644 --- a/direct/src/tkpanels/Inspector.py +++ b/direct/src/tkpanels/Inspector.py @@ -166,7 +166,7 @@ class FunctionInspector(Inspector): class InstanceMethodInspector(Inspector): def title(self): - return str(self.object.im_class) + "." + self.object.__name__ + "()" + return str(self.object.__self__.__class__) + "." + self.object.__name__ + "()" class CodeInspector(Inspector): def title(self): @@ -391,10 +391,10 @@ class InspectorWindow: #Private def selectedIndex(self): - indicies = map(int, self.listWidget.curselection()) - if len(indicies) == 0: + indices = list(map(int, self.listWidget.curselection())) + if len(indices) == 0: return None - partNumber = indicies[0] + partNumber = indices[0] return partNumber def inspectorForSelectedPart(self): diff --git a/direct/src/tkwidgets/Tree.py b/direct/src/tkwidgets/Tree.py index 7e864aaad3..88d3918386 100644 --- a/direct/src/tkwidgets/Tree.py +++ b/direct/src/tkwidgets/Tree.py @@ -27,7 +27,7 @@ from panda3d.core import * # Initialize icon directory ICONDIR = ConfigVariableSearchPath('model-path').findFile(Filename('icons')).toOsSpecific() if not os.path.isdir(ICONDIR): - raise RuntimeError, "can't find DIRECT icon directory (%s)" % repr(ICONDIR) + raise RuntimeError("can't find DIRECT icon directory (%s)" % repr(ICONDIR)) class TreeNode: diff --git a/direct/src/wxwidgets/ViewPort.py b/direct/src/wxwidgets/ViewPort.py index b0d03d88c9..19ed102330 100755 --- a/direct/src/wxwidgets/ViewPort.py +++ b/direct/src/wxwidgets/ViewPort.py @@ -171,7 +171,7 @@ class Viewport(WxPandaWindow, DirectObject): if vpType == VPFRONT: return Viewport.makeFront(parent) if vpType == VPTOP: return Viewport.makeTop(parent) if vpType == VPPERSPECTIVE: return Viewport.makePerspective(parent) - raise TypeError, "Unknown viewport type: %s" % vpType + raise TypeError("Unknown viewport type: %s" % vpType) @staticmethod def makeOrthographic(parent, name, campos): diff --git a/direct/src/wxwidgets/WxPandaWindow.py b/direct/src/wxwidgets/WxPandaWindow.py index 6d4ccd335b..79a4ebc68d 100644 --- a/direct/src/wxwidgets/WxPandaWindow.py +++ b/direct/src/wxwidgets/WxPandaWindow.py @@ -172,7 +172,7 @@ else: break if pipe.getInterfaceName() != 'OpenGL': - raise StandardError, "Couldn't get an OpenGL pipe." + raise Exception("Couldn't get an OpenGL pipe.") self.win = base.openWindow(callbackWindowDict = callbackWindowDict, pipe = pipe, gsg = gsg, type = 'onscreen') self.hasCapture = False diff --git a/makepanda/makepanda.py b/makepanda/makepanda.py index 46554539d7..71845db7b8 100755 --- a/makepanda/makepanda.py +++ b/makepanda/makepanda.py @@ -2621,7 +2621,26 @@ CreatePandaVersionFiles() ########################################################################################## if (PkgSkip("DIRECT")==0): - CopyPythonTree(GetOutputDir() + '/direct', 'direct/src', lib2to3_fixers=['all']) + fixers = [ + 'apply', + 'callable', + 'dict', + 'except', + 'execfile', + 'import', + 'imports', + 'long', + 'metaclass', + 'next', + 'numliterals', + 'print', + 'types', + 'unicode', + 'xrange', + 'xreadlines', + ] + + CopyPythonTree(GetOutputDir() + '/direct', 'direct/src', lib2to3_fixers=fixers, threads=THREADCOUNT) ConditionalWriteFile(GetOutputDir() + '/direct/__init__.py', "") # This file used to be copied, but would nowadays cause conflicts. diff --git a/makepanda/makepandacore.py b/makepanda/makepandacore.py index f395693c3f..05b6053053 100644 --- a/makepanda/makepandacore.py +++ b/makepanda/makepandacore.py @@ -2640,18 +2640,25 @@ def CopyTree(dstdir, srcdir, omitVCS=True): if omitVCS: DeleteVCS(dstdir) -def CopyPythonTree(dstdir, srcdir, lib2to3_fixers=[]): +def CopyPythonTree(dstdir, srcdir, lib2to3_fixers=[], threads=0): if (not os.path.isdir(dstdir)): os.mkdir(dstdir) lib2to3 = None + lib2to3_args = ['-w', '-n', '--no-diffs'] + if len(lib2to3_fixers) > 0 and sys.version_info >= (3, 0): from lib2to3.main import main as lib2to3 - lib2to3_args = ['-w', '-n', '--no-diffs', '-x', 'buffer', '-x', 'idioms', '-x', 'set_literal', '-x', 'ws_comma'] - if lib2to3_fixers != ['all']: + + if lib2to3_fixers == ['all']: + lib2to3_args += ['-x', 'buffer', '-x', 'idioms', '-x', 'set_literal', '-x', 'ws_comma'] + else: for fixer in lib2to3_fixers: lib2to3_args += ['-f', fixer] + if threads: + lib2to3_args += ['-j', str(threads)] + exclude_files = set(VCS_FILES) exclude_files.add('panda3d.py') @@ -2667,20 +2674,23 @@ def CopyPythonTree(dstdir, srcdir, lib2to3_fixers=[]): if ext == '.py' and not entry.endswith('-extensions.py'): refactor.append((dstpth, srcpth)) + lib2to3_args.append(dstpth) else: JustBuilt([dstpth], [srcpth]) elif entry not in VCS_DIRS: - CopyPythonTree(dstpth, srcpth, lib2to3_fixers) + CopyPythonTree(dstpth, srcpth, lib2to3_fixers, threads=threads) - for dstpth, srcpth in refactor: - if lib2to3 is not None: - ret = lib2to3("lib2to3.fixes", lib2to3_args + [dstpth]) - if ret != 0: + if refactor and lib2to3 is not None: + ret = lib2to3("lib2to3.fixes", lib2to3_args) + + if ret != 0: + for dstpth, srcpth in refactor: os.remove(dstpth) exit("Error in lib2to3.") - JustBuilt([dstpth], [srcpth]) - + else: + for dstpth, srcpth in refactor: + JustBuilt([dstpth], [srcpth]) ######################################################################## ## From 82ab126ea70d5acde0a60d33b971a8a448df8963 Mon Sep 17 00:00:00 2001 From: rdb Date: Fri, 25 Mar 2016 17:33:30 +0100 Subject: [PATCH 11/16] Add support for glLogicOp via LogicOpAttrib / NodePath::set_logic_op --- .../glstuff/glGraphicsStateGuardian_src.cxx | 40 ++++ .../src/glstuff/glGraphicsStateGuardian_src.h | 3 + panda/src/pgraph/config_pgraph.cxx | 3 + panda/src/pgraph/logicOpAttrib.I | 29 +++ panda/src/pgraph/logicOpAttrib.cxx | 205 ++++++++++++++++++ panda/src/pgraph/logicOpAttrib.h | 112 ++++++++++ panda/src/pgraph/nodePath.cxx | 56 +++++ panda/src/pgraph/nodePath.h | 134 +++++++----- panda/src/pgraph/p3pgraph_composite3.cxx | 1 + panda/src/pgraph/renderAttribRegistry.h | 2 +- 10 files changed, 533 insertions(+), 52 deletions(-) create mode 100644 panda/src/pgraph/logicOpAttrib.I create mode 100644 panda/src/pgraph/logicOpAttrib.cxx create mode 100644 panda/src/pgraph/logicOpAttrib.h diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index d308af9aa8..ad15b7d210 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -56,6 +56,7 @@ #include "depthWriteAttrib.h" #include "fogAttrib.h" #include "lightAttrib.h" +#include "logicOpAttrib.h" #include "materialAttrib.h" #include "rescaleNormalAttrib.h" #include "scissorAttrib.h" @@ -475,6 +476,7 @@ reset() { _inv_state_mask.clear_bit(TransparencyAttrib::get_class_slot()); _inv_state_mask.clear_bit(ColorWriteAttrib::get_class_slot()); _inv_state_mask.clear_bit(ColorBlendAttrib::get_class_slot()); + _inv_state_mask.clear_bit(LogicOpAttrib::get_class_slot()); _inv_state_mask.clear_bit(TextureAttrib::get_class_slot()); _inv_state_mask.clear_bit(TexGenAttrib::get_class_slot()); _inv_state_mask.clear_bit(TexMatrixAttrib::get_class_slot()); @@ -6631,6 +6633,34 @@ do_issue_material() { } #endif // SUPPORT_FIXED_FUNCTION +/** + * Issues the logic operation attribute to the GL. + */ +#if !defined(OPENGLES) || defined(OPENGLES_1) +void CLP(GraphicsStateGuardian):: +do_issue_logic_op() { + const LogicOpAttrib *target_logic_op; + _target_rs->get_attrib_def(target_logic_op); + + if (target_logic_op->get_operation() != LogicOpAttrib::O_none) { + glEnable(GL_COLOR_LOGIC_OP); + glLogicOp(GL_CLEAR - 1 + (int)target_logic_op->get_operation()); + + if (GLCAT.is_spam()) { + GLCAT.spam() << "glEnable(GL_COLOR_LOGIC_OP)\n"; + GLCAT.spam() << "glLogicOp(" << target_logic_op->get_operation() << ")\n"; + } + } else { + glDisable(GL_COLOR_LOGIC_OP); + glLogicOp(GL_COPY); + + if (GLCAT.is_spam()) { + GLCAT.spam() << "glDisable(GL_COLOR_LOGIC_OP)\n"; + } + } +} +#endif + /** * */ @@ -9660,6 +9690,16 @@ set_state_and_transform(const RenderState *target, } #endif +#if !defined(OPENGLES) || defined(OPENGLES_1) + int logic_op_slot = LogicOpAttrib::get_class_slot(); + if (_target_rs->get_attrib(logic_op_slot) != _state_rs->get_attrib(logic_op_slot) || + !_state_mask.get_bit(logic_op_slot)) { + // PStatGPUTimer timer(this, _draw_set_state_logic_op_pcollector); + do_issue_logic_op(); + _state_mask.set_bit(logic_op_slot); + } +#endif + int transparency_slot = TransparencyAttrib::get_class_slot(); int color_write_slot = ColorWriteAttrib::get_class_slot(); int color_blend_slot = ColorBlendAttrib::get_class_slot(); diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.h b/panda/src/glstuff/glGraphicsStateGuardian_src.h index 9d73f69130..5a1ded8644 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.h +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.h @@ -405,6 +405,9 @@ protected: void do_issue_material(); #endif void do_issue_texture(); +#if !defined(OPENGLES) || defined(OPENGLES_1) + void do_issue_logic_op(); +#endif void do_issue_blending(); #ifdef SUPPORT_FIXED_FUNCTION void do_issue_tex_gen(); diff --git a/panda/src/pgraph/config_pgraph.cxx b/panda/src/pgraph/config_pgraph.cxx index d5427a659f..10b9fb04d3 100644 --- a/panda/src/pgraph/config_pgraph.cxx +++ b/panda/src/pgraph/config_pgraph.cxx @@ -50,6 +50,7 @@ #include "loaderFileType.h" #include "loaderFileTypeBam.h" #include "loaderFileTypeRegistry.h" +#include "logicOpAttrib.h" #include "materialAttrib.h" #include "modelFlattenRequest.h" #include "modelLoadRequest.h" @@ -419,6 +420,7 @@ init_libpgraph() { Loader::init_type(); LoaderFileType::init_type(); LoaderFileTypeBam::init_type(); + LogicOpAttrib::init_type(); MaterialAttrib::init_type(); ModelFlattenRequest::init_type(); ModelLoadRequest::init_type(); @@ -483,6 +485,7 @@ init_libpgraph() { LensNode::register_with_read_factory(); LightAttrib::register_with_read_factory(); LightRampAttrib::register_with_read_factory(); + LogicOpAttrib::register_with_read_factory(); MaterialAttrib::register_with_read_factory(); ModelNode::register_with_read_factory(); ModelRoot::register_with_read_factory(); diff --git a/panda/src/pgraph/logicOpAttrib.I b/panda/src/pgraph/logicOpAttrib.I new file mode 100644 index 0000000000..189769a3e6 --- /dev/null +++ b/panda/src/pgraph/logicOpAttrib.I @@ -0,0 +1,29 @@ +/** + * PANDA 3D SOFTWARE + * Copyright (c) Carnegie Mellon University. All rights reserved. + * + * All use of this software is subject to the terms of the revised BSD + * license. You should have received a copy of this license along + * with this source code in a file named "LICENSE." + * + * @file logicOpAttrib.I + * @author rdb + * @date 2016-03-24 + */ + +/** + * Use LogicOpAttrib::make() to construct a new LogicOpAttrib object. + */ +INLINE LogicOpAttrib:: +LogicOpAttrib(LogicOpAttrib::Operation op) : + _op(op) +{ +} + +/** + * Returns the logic operation specified by this attribute. + */ +INLINE LogicOpAttrib::Operation LogicOpAttrib:: +get_operation() const { + return _op; +} diff --git a/panda/src/pgraph/logicOpAttrib.cxx b/panda/src/pgraph/logicOpAttrib.cxx new file mode 100644 index 0000000000..b632bb1b45 --- /dev/null +++ b/panda/src/pgraph/logicOpAttrib.cxx @@ -0,0 +1,205 @@ +/** + * PANDA 3D SOFTWARE + * Copyright (c) Carnegie Mellon University. All rights reserved. + * + * All use of this software is subject to the terms of the revised BSD + * license. You should have received a copy of this license along + * with this source code in a file named "LICENSE." + * + * @file logicOpAttrib.I + * @author rdb + * @date 2016-03-24 + */ + +#include "logicOpAttrib.h" +#include "graphicsStateGuardianBase.h" +#include "dcast.h" +#include "bamReader.h" +#include "bamWriter.h" +#include "datagram.h" +#include "datagramIterator.h" + +TypeHandle LogicOpAttrib::_type_handle; +int LogicOpAttrib::_attrib_slot; + +/** + * Constructs a new LogicOpAttrib object that disables special-effect + * blending, allowing normal transparency to be used instead. + */ +CPT(RenderAttrib) LogicOpAttrib:: +make_off() { + return RenderAttribRegistry::quick_get_global_ptr()->get_slot_default(_attrib_slot); +} + +/** + * Constructs a new LogicOpAttrib object with the given logic operation. + */ +CPT(RenderAttrib) LogicOpAttrib:: +make(LogicOpAttrib::Operation op) { + LogicOpAttrib *attrib = new LogicOpAttrib(op); + return return_new(attrib); +} + +/** + * Returns a RenderAttrib that corresponds to whatever the standard default + * properties for render attributes of this type ought to be. + */ +CPT(RenderAttrib) LogicOpAttrib:: +make_default() { + return RenderAttribRegistry::quick_get_global_ptr()->get_slot_default(_attrib_slot); +} + +/** + * + */ +void LogicOpAttrib:: +output(ostream &out) const { + out << get_type() << ":" << get_operation(); +} + +/** + * Intended to be overridden by derived LogicOpAttrib types to return a + * unique number indicating whether this LogicOpAttrib is equivalent to the + * other one. + * + * This should return 0 if the two LogicOpAttrib objects are equivalent, a + * number less than zero if this one should be sorted before the other one, + * and a number greater than zero otherwise. + * + * This will only be called with two LogicOpAttrib objects whose get_type() + * functions return the same. + */ +int LogicOpAttrib:: +compare_to_impl(const RenderAttrib *other) const { + const LogicOpAttrib *la = (const LogicOpAttrib *)other; + return (int)_op - (int)la->_op; +} + +/** + * Intended to be overridden by derived RenderAttrib types to return a unique + * hash for these particular properties. RenderAttribs that compare the same + * with compare_to_impl(), above, should return the same hash; RenderAttribs + * that compare differently should return a different hash. + */ +size_t LogicOpAttrib:: +get_hash_impl() const { + size_t hash = 0; + hash = int_hash::add_hash(hash, (int)_op); + return hash; +} + +/** + * + */ +CPT(RenderAttrib) LogicOpAttrib:: +get_auto_shader_attrib_impl(const RenderState *state) const { + return RenderAttribRegistry::quick_get_global_ptr()->get_slot_default(_attrib_slot); +} + +/** + * Tells the BamReader how to create objects of type LogicOpAttrib. + */ +void LogicOpAttrib:: +register_with_read_factory() { + BamReader::get_factory()->register_factory(get_class_type(), make_from_bam); +} + +/** + * Writes the contents of this object to the datagram for shipping out to a + * Bam file. + */ +void LogicOpAttrib:: +write_datagram(BamWriter *manager, Datagram &dg) { + RenderAttrib::write_datagram(manager, dg); + + dg.add_uint8(_op); +} + +/** + * This function is called by the BamReader's factory when a new object of + * type LogicOpAttrib is encountered in the Bam file. It should create the + * LogicOpAttrib and extract its information from the file. + */ +TypedWritable *LogicOpAttrib:: +make_from_bam(const FactoryParams ¶ms) { + LogicOpAttrib *attrib = new LogicOpAttrib(O_none); + DatagramIterator scan; + BamReader *manager; + + parse_params(params, scan, manager); + attrib->fillin(scan, manager); + + return attrib; +} + +/** + * This internal function is called by make_from_bam to read in all of the + * relevant data from the BamFile for the new LogicOpAttrib. + */ +void LogicOpAttrib:: +fillin(DatagramIterator &scan, BamReader *manager) { + RenderAttrib::fillin(scan, manager); + + _op = (Operation)scan.get_uint8(); +} + +/** + * + */ +ostream & +operator << (ostream &out, LogicOpAttrib::Operation op) { + switch (op) { + case LogicOpAttrib::O_none: + return out << "none"; + + case LogicOpAttrib::O_clear: + return out << "clear"; + + case LogicOpAttrib::O_and: + return out << "and"; + + case LogicOpAttrib::O_and_reverse: + return out << "and_reverse"; + + case LogicOpAttrib::O_copy: + return out << "copy"; + + case LogicOpAttrib::O_and_inverted: + return out << "and_inverted"; + + case LogicOpAttrib::O_noop: + return out << "noop"; + + case LogicOpAttrib::O_xor: + return out << "xor"; + + case LogicOpAttrib::O_or: + return out << "or"; + + case LogicOpAttrib::O_nor: + return out << "nor"; + + case LogicOpAttrib::O_equivalent: + return out << "equivalent"; + + case LogicOpAttrib::O_invert: + return out << "invert"; + + case LogicOpAttrib::O_or_reverse: + return out << "or_reverse"; + + case LogicOpAttrib::O_copy_inverted: + return out << "copy_inverted"; + + case LogicOpAttrib::O_or_inverted: + return out << "or_inverted"; + + case LogicOpAttrib::O_nand: + return out << "nand"; + + case LogicOpAttrib::O_set: + return out << "set"; + } + + return out << "**invalid LogicOpAttrib::Operation(" << (int)op << ")**"; +} diff --git a/panda/src/pgraph/logicOpAttrib.h b/panda/src/pgraph/logicOpAttrib.h new file mode 100644 index 0000000000..988836f8d1 --- /dev/null +++ b/panda/src/pgraph/logicOpAttrib.h @@ -0,0 +1,112 @@ +/** + * PANDA 3D SOFTWARE + * Copyright (c) Carnegie Mellon University. All rights reserved. + * + * All use of this software is subject to the terms of the revised BSD + * license. You should have received a copy of this license along + * with this source code in a file named "LICENSE." + * + * @file logicOpAttrib.I + * @author rdb + * @date 2016-03-24 + */ + +#ifndef LOGICOPATTRIB_H +#define LOGICOPATTRIB_H + +#include "pandabase.h" +#include "luse.h" +#include "renderAttrib.h" + +class FactoryParams; + +/** + * If enabled, specifies that a custom logical operation be performed instead + * of any color blending. Setting it to a value other than M_none will cause + * color blending to be disabled and the given logic operation to be performed. + */ +class EXPCL_PANDA_PGRAPH LogicOpAttrib : public RenderAttrib { +PUBLISHED: + enum Operation { + O_none, // LogicOp disabled, regular blending occurs. + O_clear, // Clears framebuffer value. + O_and, + O_and_reverse, + O_copy, // Writes the incoming color to the framebuffer. + O_and_inverted, + O_noop, // Leaves the framebuffer value unaltered. + O_xor, + O_or, + O_nor, + O_equivalent, + O_invert, + O_or_reverse, + O_copy_inverted, + O_or_inverted, + O_nand, + O_set, // Sets all the bits in the framebuffer to 1. + }; + +private: + INLINE LogicOpAttrib(Operation op); + +PUBLISHED: + static CPT(RenderAttrib) make_off(); + static CPT(RenderAttrib) make(Operation op); + static CPT(RenderAttrib) make_default(); + + INLINE Operation get_operation() const; + MAKE_PROPERTY(operation, get_operation); + +public: + virtual void output(ostream &out) const; + +protected: + virtual int compare_to_impl(const RenderAttrib *other) const; + virtual size_t get_hash_impl() const; + virtual CPT(RenderAttrib) get_auto_shader_attrib_impl(const RenderState *state) const; + +private: + Operation _op; + +PUBLISHED: + static int get_class_slot() { + return _attrib_slot; + } + virtual int get_slot() const { + return get_class_slot(); + } + +public: + static void register_with_read_factory(); + virtual void write_datagram(BamWriter *manager, Datagram &dg); + +protected: + static TypedWritable *make_from_bam(const FactoryParams ¶ms); + void fillin(DatagramIterator &scan, BamReader *manager); + +public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type() { + RenderAttrib::init_type(); + register_type(_type_handle, "LogicOpAttrib", + RenderAttrib::get_class_type()); + _attrib_slot = register_slot(_type_handle, 100, new LogicOpAttrib(O_none)); + } + virtual TypeHandle get_type() const { + return get_class_type(); + } + virtual TypeHandle force_init_type() {init_type(); return get_class_type();} + +private: + static TypeHandle _type_handle; + static int _attrib_slot; +}; + +EXPCL_PANDA_PGRAPH ostream &operator << (ostream &out, LogicOpAttrib::Operation op); + +#include "logicOpAttrib.I" + +#endif diff --git a/panda/src/pgraph/nodePath.cxx b/panda/src/pgraph/nodePath.cxx index c6bfff127c..de0cf7c4fb 100644 --- a/panda/src/pgraph/nodePath.cxx +++ b/panda/src/pgraph/nodePath.cxx @@ -4832,6 +4832,62 @@ get_transparency() const { return TransparencyAttrib::M_none; } +/** + * Specifically sets or disables a logical operation on this particular node. + * If no other nodes override, this will cause geometry to be rendered without + * color blending but instead using the given logical operator. + */ +void NodePath:: +set_logic_op(LogicOpAttrib::Operation op, int priority) { + nassertv_always(!is_empty()); + + node()->set_attrib(LogicOpAttrib::make(op), priority); +} + +/** + * Completely removes any logical operation that may have been set on this + * node via set_logic_op(). The geometry at this level and below will + * subsequently be rendered using standard color blending. + */ +void NodePath:: +clear_logic_op() { + nassertv_always(!is_empty()); + node()->clear_attrib(LogicOpAttrib::get_class_slot()); +} + +/** + * Returns true if a logical operation has been explicitly set on this + * particular node via set_logic_op(). If this returns true, then + * get_logic_op() may be called to determine whether a logical operation has + * been explicitly disabled for this node or set to particular operation. + */ +bool NodePath:: +has_logic_op() const { + nassertr_always(!is_empty(), false); + return node()->has_attrib(LogicOpAttrib::get_class_slot()); +} + +/** + * Returns the logical operation that has been specifically set on this node + * via set_logic_op(), or O_none if standard color blending has been + * specifically set, or if nothing has been specifically set. See also + * has_logic_op(). This does not necessarily imply that the geometry will + * or will not be rendered with the given logical operation, as there may be + * other nodes that override. + */ +LogicOpAttrib::Operation NodePath:: +get_logic_op() const { + nassertr_always(!is_empty(), LogicOpAttrib::O_none); + const RenderAttrib *attrib = + node()->get_attrib(LogicOpAttrib::get_class_slot()); + if (attrib != (const RenderAttrib *)NULL) { + const LogicOpAttrib *ta = DCAST(LogicOpAttrib, attrib); + return ta->get_operation(); + } + + return LogicOpAttrib::O_none; +} + /** * Specifies the antialiasing type that should be applied at this node and * below. See AntialiasAttrib. diff --git a/panda/src/pgraph/nodePath.h b/panda/src/pgraph/nodePath.h index 729bcf37f3..4f39aa28bb 100644 --- a/panda/src/pgraph/nodePath.h +++ b/panda/src/pgraph/nodePath.h @@ -26,6 +26,7 @@ #include "transformState.h" #include "renderModeAttrib.h" #include "transparencyAttrib.h" +#include "logicOpAttrib.h" #include "nodePathComponent.h" #include "pointerTo.h" #include "referenceCount.h" @@ -62,57 +63,83 @@ class SamplerState; class Shader; class ShaderInput; -/* - * A NodePath is the fundamental unit of high-level interaction with the scene - * graph. It encapsulates the complete path down to a node from some other - * node, usually the root of the scene graph. This is used to resolve - * ambiguities associated with instancing. NodePath also contains a number of - * handy high-level methods for common scene-graph manipulations, such as - * reparenting, and common state changes, such as repositioning. There are - * also a number of NodePath methods for finding nodes deep within the tree by - * name or by type. These take a path string, which at its simplest consists - * of a series of node names separated by slashes, like a directory pathname. - * Each component of the path string may optionally consist of one of the - * following special names, instead of a node name: * -- matches - * exactly one node, with any name. ** -- matches any sequence of - * zero or more nodes. +typename -- matches any node that is or derives from - * the given type. -typename -- matches any node that is the given type - * exactly. =tag -- matches any node that has the indicated tag. - * =tag=value -- matches any node whose tag matches the indicated value. - * Furthermore, a node name may itself contain standard filename globbing - * characters, like *, ?, and [a-z], that will be accepted as a partial match. - * (In fact, the '*' special name may be seen as just a special case of this.) - * The globbing characters may not be used with the typename matches or with - * tag matches, but they may be used to match a tag's value in the =tag=value - * syntax. The special characters "@@", appearing at the beginning of a node - * name, indicate a stashed node. Normally, stashed nodes are not returned by - * a find (but see the special flags, below), but a stashed node may be found - * if it is explicitly named with its leading @@ characters. By extension, - * "@@*" may be used to identify any stashed node. Examples: "roomgraph" will - * look for a node named "graph", which is a child of an unnamed node, which - * is a child of a node named "room", which is a child of the starting path. - * "**red*" will look for any node anywhere in the tree (below the starting - * path) with a name that begins with "red". "**+PartBundleNode**head" will - * look for a node named "head", somewhere below a PartBundleNode anywhere in - * the tree. The search is always potentially ambiguous, even if the special - * wildcard operators are not used, because there may be multiple nodes in the - * tree with the same name. In general, in the case of an ambiguity, the - * shortest path is preferred; when a method (such as extend_by) must choose - * only only one of several possible paths, it will choose the shortest - * available; on the other hand, when a method (such as find_all_matches) is - * to return all of the matching paths, it will sort them so that the shortest - * paths appear first in the output. Special flags. The entire string may - * optionally be followed by the ";" character, followed by one or more of the - * following special control flags, with no intervening spaces or punctuation: - * -h Do not return hidden nodes. +h Do return hidden nodes. -s Do - * not return stashed nodes unless explicitly referenced with @@. +s Return - * stashed nodes even without any explicit @@ characters. -i Node name - * comparisons are not case insensitive: case must match exactly. +i Node - * name comparisons are case insensitive: case is not important. This affects - * matches against the node name only; node type and tag strings are always - * case sensitive. The default flags are +h-s-i. - */ - +// +// A NodePath is the fundamental unit of high-level interaction with the scene +// graph. It encapsulates the complete path down to a node from some other +// node, usually the root of the scene graph. This is used to resolve +// ambiguities associated with instancing. +// +// NodePath also contains a number of handy high-level methods for common +// scene-graph manipulations, such as reparenting, and common state changes, +// such as repositioning. +// +// There are also a number of NodePath methods for finding nodes deep within +// the tree by name or by type. These take a path string, which at its +// simplest consists of a series of node names separated by slashes, like a +// directory pathname. +// +// Each component of the path string may optionally consist of one of the +// following special names, instead of a node name: +// +// * -- matches exactly one node, with any name. +// ** -- matches any sequence of zero or more nodes. +// +typename -- matches any node that is or derives from the given type. +// -typename -- matches any node that is the given type exactly. +// =tag -- matches any node that has the indicated tag. +// =tag=value -- matches any node whose tag matches the indicated value. +// +// Furthermore, a node name may itself contain standard filename globbing +// characters, like *, ?, and [a-z], that will be accepted as a partial match. +// (In fact, the '*' special name may be seen as just a special case of this.) +// The globbing characters may not be used with the typename matches or with +// tag matches, but they may be used to match a tag's value in the =tag=value +// syntax. +// +// The special characters "@@", appearing at the beginning of a node name, +// indicate a stashed node. Normally, stashed nodes are not returned by a +// find (but see the special flags, below), but a stashed node may be found if +// it is explicitly named with its leading @@ characters. By extension, "@@*" +// may be used to identify any stashed node. +// +// Examples: +// +// "room//graph" will look for a node named "graph", which is a child of an +// unnamed node, which is a child of a node named "room", which is a child of +// the starting path. +// +// "**/red*" will look for any node anywhere in the tree (below the starting +// path) with a name that begins with "red". +// +// "**/+PartBundleNode/**/head" will look for a node named "head", somewhere +// below a PartBundleNode anywhere in the tree. +// +// +// The search is always potentially ambiguous, even if the special wildcard +// operators are not used, because there may be multiple nodes in the tree +// with the same name. In general, in the case of an ambiguity, the shortest +// path is preferred; when a method (such as extend_by) must choose only only +// one of several possible paths, it will choose the shortest available; on +// the other hand, when a method (such as find_all_matches) is to return all +// of the matching paths, it will sort them so that the shortest paths appear +// first in the output. +// +// +// Special flags. The entire string may optionally be followed by the ";" +// character, followed by one or more of the following special control flags, +// with no intervening spaces or punctuation: +// +// -h Do not return hidden nodes. +// +h Do return hidden nodes. +// -s Do not return stashed nodes unless explicitly referenced with @@. +// +s Return stashed nodes even without any explicit @@ characters. +// -i Node name comparisons are not case insensitive: case must match +// exactly. +// +i Node name comparisons are case insensitive: case is not important. +// This affects matches against the node name only; node type and tag +// strings are always case sensitive. +// +// The default flags are +h-s-i. +// /** * NodePath is the fundamental system for disambiguating instances, and also @@ -786,6 +813,11 @@ PUBLISHED: bool has_transparency() const; TransparencyAttrib::Mode get_transparency() const; + void set_logic_op(LogicOpAttrib::Operation op, int priority = 0); + void clear_logic_op(); + bool has_logic_op() const; + LogicOpAttrib::Operation get_logic_op() const; + void set_antialias(unsigned short mode, int priority = 0); void clear_antialias(); bool has_antialias() const; diff --git a/panda/src/pgraph/p3pgraph_composite3.cxx b/panda/src/pgraph/p3pgraph_composite3.cxx index 5b88a55d2f..18be4cb35e 100644 --- a/panda/src/pgraph/p3pgraph_composite3.cxx +++ b/panda/src/pgraph/p3pgraph_composite3.cxx @@ -7,6 +7,7 @@ #include "loaderFileType.cxx" #include "loaderFileTypeBam.cxx" #include "loaderFileTypeRegistry.cxx" +#include "logicOpAttrib.cxx" #include "materialAttrib.cxx" #include "materialCollection.cxx" #include "modelFlattenRequest.cxx" diff --git a/panda/src/pgraph/renderAttribRegistry.h b/panda/src/pgraph/renderAttribRegistry.h index 9858192332..59194fd278 100644 --- a/panda/src/pgraph/renderAttribRegistry.h +++ b/panda/src/pgraph/renderAttribRegistry.h @@ -47,7 +47,7 @@ public: // Raise this number whenever we add a new attrib. This used to be // determined at runtime, but it's better to have it as a constexpr. - static const int _max_slots = 29; + static const int _max_slots = 32; int register_slot(TypeHandle type_handle, int sort, RenderAttrib *default_attrib); From 8badce2fdbec88ee52bc9ed60c41a2856363e857 Mon Sep 17 00:00:00 2001 From: rdb Date: Sat, 26 Mar 2016 12:03:45 +0100 Subject: [PATCH 12/16] pfreeze now supports Python 3 --- direct/src/showutil/FreezeTool.py | 71 ++++++++++++++++++++++++++++++- 1 file changed, 69 insertions(+), 2 deletions(-) diff --git a/direct/src/showutil/FreezeTool.py b/direct/src/showutil/FreezeTool.py index 9862e1c764..ad99f8c629 100644 --- a/direct/src/showutil/FreezeTool.py +++ b/direct/src/showutil/FreezeTool.py @@ -227,6 +227,10 @@ frozenMainCode = """ #include "Python.h" +#if PY_MAJOR_VERSION >= 3 +#include +#endif + #ifdef MS_WINDOWS extern void PyWinFreeze_ExeInit(void); extern void PyWinFreeze_ExeTerm(void); @@ -239,10 +243,27 @@ int Py_FrozenMain(int argc, char **argv) { char *p; - int n, sts; + int n, sts = 1; int inspect = 0; int unbuffered = 0; +#if PY_MAJOR_VERSION >= 3 + int i; + char *oldloc = NULL; + wchar_t **argv_copy = NULL; + /* We need a second copies, as Python might modify the first one. */ + wchar_t **argv_copy2 = NULL; + + if (argc > 0) { + argv_copy = PyMem_RawMalloc(sizeof(wchar_t*) * argc); + argv_copy2 = PyMem_RawMalloc(sizeof(wchar_t*) * argc); + if (!argv_copy || !argv_copy2) { + fprintf(stderr, \"out of memory\\n\"); + goto error; + } + } +#endif + Py_FrozenFlag = 1; /* Suppress errors from getpath.c */ if ((p = Py_GETENV("PYTHONINSPECT")) && *p != '\\0') @@ -256,10 +277,41 @@ Py_FrozenMain(int argc, char **argv) setbuf(stderr, (char *)NULL); } +#if PY_MAJOR_VERSION >= 3 + oldloc = _PyMem_RawStrdup(setlocale(LC_ALL, NULL)); + if (!oldloc) { + fprintf(stderr, \"out of memory\\n\"); + goto error; + } + + setlocale(LC_ALL, \"\"); + for (i = 0; i < argc; i++) { + argv_copy[i] = Py_DecodeLocale(argv[i], NULL); + argv_copy2[i] = argv_copy[i]; + if (!argv_copy[i]) { + fprintf(stderr, \"Unable to decode the command line argument #%i\\n\", + i + 1); + argc = i; + goto error; + } + } + setlocale(LC_ALL, oldloc); + PyMem_RawFree(oldloc); + oldloc = NULL; +#endif + #ifdef MS_WINDOWS PyInitFrozenExtensions(); #endif /* MS_WINDOWS */ - Py_SetProgramName(argv[0]); + + if (argc >= 1) { +#if PY_MAJOR_VERSION >= 3 + Py_SetProgramName(argv_copy[0]); +#else + Py_SetProgramName(argv[0]); +#endif + } + Py_Initialize(); #ifdef MS_WINDOWS PyWinFreeze_ExeInit(); @@ -269,7 +321,11 @@ Py_FrozenMain(int argc, char **argv) fprintf(stderr, "Python %s\\n%s\\n", Py_GetVersion(), Py_GetCopyright()); +#if PY_MAJOR_VERSION >= 3 + PySys_SetArgv(argc, argv_copy); +#else PySys_SetArgv(argc, argv); +#endif n = PyImport_ImportFrozenModule("__main__"); if (n == 0) @@ -288,6 +344,17 @@ Py_FrozenMain(int argc, char **argv) PyWinFreeze_ExeTerm(); #endif Py_Finalize(); + +error: +#if PY_MAJOR_VERSION >= 3 + PyMem_RawFree(argv_copy); + if (argv_copy2) { + for (i = 0; i < argc; i++) + PyMem_RawFree(argv_copy2[i]); + PyMem_RawFree(argv_copy2); + } + PyMem_RawFree(oldloc); +#endif return sts; } """ From 56606f9b1bea8b9f435280bbea659845f06d15a1 Mon Sep 17 00:00:00 2001 From: Mitchell Stokes Date: Sun, 27 Mar 2016 11:49:10 -0700 Subject: [PATCH 13/16] Handle Python 2 vs Python 3 stdlib differences when building the morepy package See PEP3108 for more details on stdlib differences. --- direct/src/p3d/panda3d.pdef | 98 +++++++++++++++++++++++-------------- 1 file changed, 60 insertions(+), 38 deletions(-) diff --git a/direct/src/p3d/panda3d.pdef b/direct/src/p3d/panda3d.pdef index 58695f9e8f..4c6588622f 100644 --- a/direct/src/p3d/panda3d.pdef +++ b/direct/src/p3d/panda3d.pdef @@ -1,3 +1,4 @@ +import sys from panda3d.core import Filename, PandaSystem, getModelPath # This file defines a number of standard "packages" that correspond to @@ -140,60 +141,81 @@ class morepy(package): config(display_name = "Python standard library") require('panda3d') - module('string', 're', 'struct', 'difflib', 'StringIO', - 'cStringIO', 'StringIO', 'textwrap', 'codecs', - 'unicodedata', 'stringprep', 'fpformat', 'datetime', + module('string', 're', 'struct', 'difflib', 'StringIO', 'StringIO', + 'textwrap', 'codecs', 'unicodedata', 'stringprep', 'datetime', 'calendar', 'collections', 'heapq', 'bisect', 'array', - 'sets', 'sched', 'mutex', 'queue', 'weakref', 'UserDict', - 'UserList', 'UserString', 'types', 'new', 'copy', 'pprint', - 'repr', 'numbers', 'math', 'cmath', 'decimal', 'fractions', + 'sched', 'queue', 'weakref', 'types', 'copy', 'pprint', + 'numbers', 'math', 'cmath', 'decimal', 'fractions', 'random', 'itertools', 'functools', 'operator', 'os.path', - 'fileinput', 'stat', 'statvfs', 'filecmp', 'tempfile', - 'glob', 'fnmatch', 'linecache', 'shutil', 'dircache', - 'macpath', 'pickle', 'cPickle', 'copy_reg', 'shelve', - 'marshal', 'anydbm', 'whichdb', 'dbm', 'gdbm', 'dbhash', - 'bsddb', 'dumbdbm', 'zlib', 'gzip', 'bz2', 'zipfile', - 'tarfile', 'csv', 'ConfigParser', 'robotparser', 'netrc', - 'xdrlib', 'plistlib', 'hashlib', 'hmac', 'md5', 'sha', 'os', + 'fileinput', 'filecmp', 'tempfile', 'glob', 'fnmatch', 'linecache', + 'shutil', 'macpath', 'pickle', 'shelve', 'marshal', 'bsddb', 'zlib', + 'gzip', 'bz2', 'zipfile', 'tarfile', 'csv', 'netrc', + 'xdrlib', 'plistlib', 'hashlib', 'hmac', 'os', 'time', 'optparse', 'getopt', 'logging', 'logging.*') module('getpass', 'curses', 'curses.textpad', 'curses.wrapper', 'curses.ascii', 'curses.panel', 'platform', 'errno', - 'ctypes', 'select', 'threading', 'thread', - 'dummy_threading', 'dummy_thread', 'multiprocessing', - 'mmap', 'readline', 'rlcompleter', 'subprocess', 'socket', - 'ssl', 'signal', 'popen2', 'asyncore', 'asynchat', 'email', - 'json', 'mailcap', 'mailbox', 'mhlib', 'mimetools', - 'mimetypes', 'MimeWriter', 'mimify', 'multifile', 'rfc822', - 'base64', 'binhex', 'binascii', 'quopri', 'uu', - 'HTMLParser', 'sgmllib', 'htmllib', 'htmlentitydefs', - 'xml.parsers.expat', 'xml.dom', 'xml.dom.minidom', + 'ctypes', 'select', 'threading', 'dummy_threading', 'dummy_thread', + 'multiprocessing', 'mmap', 'readline', 'rlcompleter', 'subprocess', + 'socket', 'ssl', 'signal', 'asyncore', 'asynchat', 'email', 'json', + 'mailcap', 'mailbox', 'mimetypes', 'base64', 'binhex', 'binascii', + 'quopri', 'uu', 'xml.parsers.expat', 'xml.dom', 'xml.dom.minidom', 'xml.dom.pulldom', 'xml.sax', 'xml.sax.handler', 'xml.sax.saxutils', 'xml.sax.xmlreader', 'xml.etree.ElementTree', 'webbrowser', 'cgi', 'cgitb') - module('wsgiref', 'urllib', 'urllib2', 'httplib', 'ftplib', - 'poplib', 'imaplib', 'nntplib', 'smtplib', 'smtpd', - 'telnetlib', 'uuid', 'urlparse', 'SocketServer', - 'BaseHTTPServer', 'SimpleHTTPServer', 'CGIHTTPServer', - 'cookielib', 'Cookie', 'xmlrpclib', 'SimpleXMLRPCServer', - 'DocXMLRPCServer', 'audioop', 'imageop', 'aifc', 'sunau', + module('wsgiref', 'ftplib', 'poplib', 'imaplib', 'nntplib', 'smtplib', + 'smtpd', 'telnetlib', 'uuid', 'audioop', 'aifc', 'sunau', 'wave', 'chunk', 'colorsys', 'imghdr', 'sndhdr', 'ossaudiodev', 'gettext', 'locale', 'cmd', 'shlex', 'pydoc', 'doctest', 'unittest', 'test', - 'test.test_support', 'bdb', 'pdb', 'hotshot', 'timeit', - 'trace', 'sys', '__builtin__') + 'bdb', 'pdb', 'hotshot', 'timeit', 'trace', 'sys', '__builtin__') module('future_builtins', 'warnings', 'contextlib', 'abc', 'atexit', 'traceback', '__future__', 'gc', 'inspect', - 'site', 'user', 'fpectl', 'code', 'codeop', 'rexec', - 'Bastion', 'imp', 'imputil', 'zipimport', 'pkgutil', + 'site', 'fpectl', 'code', 'codeop', 'zipimport', 'pkgutil', 'modulefinder', 'runpy', 'parser', 'symtable', 'symbol', 'token', 'keyword', 'tokenize', 'tabnanny', 'pyclbr', 'py_compile', 'compileall', 'dis', 'pickletools', - 'distutils', 'formatter', 'msilib', 'msvcrt', '_winreg', - 'winsound', 'posix', 'pwd', 'spwd', 'grp', 'crypt', 'dl', - 'termios', 'tty', 'pty', 'fcntl', 'pipes', 'posixfile', - 'resource', 'nis', 'syslog', 'commands', 'ic', 'MacOS', - 'macostools', 'findertools', 'EasyDialogs', 'FrameWork', - 'autoGIL', 'ColorPicker', 'ast') + 'distutils', 'msilib', 'msvcrt', 'winsound', 'posix', 'pwd', 'spwd', + 'grp', 'crypt', 'termios', 'tty', 'pty', 'fcntl', 'pipes', + 'resource', 'nis', 'syslog', 'ast') + + # Handle module name differences between Python 2 and Python 3 (see PEP3108) + if sys.version_info[0] < 3: + # Deprecated modules that were removed in Python 3 + module('posixfile', 'rfc822', 'mimetools','MimeWriter', 'mimify', + 'multifile', 'sets', 'md5', 'sha', 'imp', 'formatter') + # Mac-specific modules that were removed + module('autoGIL', 'ColorPicker', 'EasyDialogs', 'findertools', + 'FrameWork', 'ic', 'MacOS', 'macostools') + # Removed because they were hardly used + module('imputil', 'mutex', 'user', 'new') + # Removed because they were obsolete + module('Bastion', 'rexec', 'commands', 'dircache', 'dl', 'fpformat', + 'htmllib', 'imageop', 'mhlib', 'popen2', 'sgmllib', 'stat', + 'statvfs', 'thread', 'UserDict', 'UserList', 'UserString') + # Renamed to fix PEP8 violations + module('_winreg', 'ConfigParser', 'copy_reg', 'SocketServer') + # C and Python implementations of the same interface were merged + module('cPickle', 'cStringIO') + # Renamed because of poorly chosen names + module('repr', 'test.test_support') + # Modules that got grouped under packages + module('anydbm', 'whichdb', 'dbm', 'dumbdbm', 'gdbm', 'dbhash') + module('HTMLParser', 'htmlentitydefs') + module('BaseHTTPServer', 'SimpleHTTPServer', 'cookielib', 'Cookie', + 'CGIHTTPServer', 'httplib') + module('urllib', 'urllib2', 'urlparse', 'robotparser') + module('xmlrpclib', 'SimpleXMLRPCServer', 'DocXMLRPCServer') + else: + # Renamed to fix PEP8 violations + module('winreg', 'configparser', 'copyreg', 'socketserver') + # Renamed because of poorly chosen names + module('reprlib', 'test.support') + # Modules that got grouped under packages + module('dbm') + module('html') + module('http') + module('urllib') + module('xmlrpc') # To add the multitude of standard Python string encodings. module('encodings', 'encodings.*') From 23bf9ea5c73006a7b561fa2d83af4f568ac54ae6 Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 28 Mar 2016 22:31:50 +0200 Subject: [PATCH 14/16] The direct tree is now valid Python 2 *and* 3 --- direct/src/actor/Actor.py | 196 ++++++------ direct/src/actor/DistributedActor.py | 2 +- direct/src/cluster/ClusterClient.py | 18 +- direct/src/cluster/ClusterConfig.py | 2 +- direct/src/cluster/ClusterServer.py | 4 +- direct/src/controls/BattleWalker.py | 6 +- direct/src/controls/GhostWalker.py | 2 +- direct/src/controls/ObserverWalker.py | 2 +- direct/src/controls/PhysicsWalker.py | 4 +- direct/src/controls/TwoDWalker.py | 2 +- direct/src/directbase/ThreeUpStart.py | 2 +- direct/src/directdevices/DirectFastrak.py | 2 +- direct/src/directdevices/DirectJoybox.py | 2 +- direct/src/directdevices/DirectRadamec.py | 2 +- direct/src/directnotify/DirectNotify.py | 8 +- direct/src/directnotify/DirectNotifyGlobal.py | 2 +- direct/src/directnotify/LoggerGlobal.py | 2 +- direct/src/directnotify/Notifier.py | 4 +- direct/src/directnotify/RotatingLog.py | 7 +- direct/src/directscripts/eggcacher.py | 10 +- direct/src/directscripts/extract_docs.py | 80 ++--- direct/src/directscripts/gendocs.py | 52 ++-- direct/src/directscripts/packpanda.py | 56 ++-- direct/src/directtools/DirectCameraControl.py | 12 +- direct/src/directtools/DirectGeometry.py | 18 +- direct/src/directtools/DirectGlobals.py | 4 +- direct/src/directtools/DirectGrid.py | 4 +- direct/src/directtools/DirectLights.py | 2 +- direct/src/directtools/DirectManipulation.py | 13 +- direct/src/directtools/DirectSelection.py | 12 +- direct/src/directtools/DirectSession.py | 33 ++- direct/src/directtools/DirectUtil.py | 2 +- direct/src/directutil/DeltaProfiler.py | 4 +- .../directutil/DistributedLargeBlobSender.py | 2 +- .../DistributedLargeBlobSenderAI.py | 2 +- direct/src/directutil/MemoryLeakHelpers.py | 2 +- direct/src/directutil/Mopath.py | 12 +- direct/src/directutil/Verify.py | 6 +- direct/src/distributed/AsyncRequest.py | 8 +- direct/src/distributed/CRCache.py | 2 +- direct/src/distributed/CRDataCache.py | 4 +- direct/src/distributed/ClientRepository.py | 12 +- .../src/distributed/ClientRepositoryBase.py | 28 +- .../src/distributed/ConnectionRepository.py | 9 +- direct/src/distributed/DistributedCamera.py | 12 +- .../distributed/DistributedCartesianGrid.py | 2 +- .../distributed/DistributedCartesianGridAI.py | 4 +- direct/src/distributed/DistributedNode.py | 11 +- direct/src/distributed/DistributedNodeAI.py | 8 +- direct/src/distributed/DistributedNodeUD.py | 4 +- direct/src/distributed/DistributedObject.py | 33 ++- direct/src/distributed/DistributedObjectAI.py | 34 ++- .../src/distributed/DistributedObjectBase.py | 13 +- .../distributed/DistributedObjectGlobalAI.py | 2 +- .../distributed/DistributedObjectGlobalUD.py | 2 +- direct/src/distributed/DistributedObjectOV.py | 22 +- direct/src/distributed/DistributedObjectUD.py | 26 +- .../src/distributed/DistributedSmoothNode.py | 6 +- .../distributed/DistributedSmoothNodeAI.py | 4 +- .../distributed/DistributedSmoothNodeBase.py | 2 +- direct/src/distributed/DoCollectionManager.py | 28 +- direct/src/distributed/DoInterestManager.py | 52 ++-- direct/src/distributed/GridChild.py | 2 +- direct/src/distributed/NetMessenger.py | 8 +- direct/src/distributed/OldClientRepository.py | 4 +- direct/src/distributed/ParentMgr.py | 4 +- direct/src/distributed/ServerRepository.py | 14 +- direct/src/distributed/TimeManagerAI.py | 2 +- direct/src/doc/howto.adjust | 5 +- .../extensions_native/CInterval_extensions.py | 35 ++- .../extensions_native/NodePath_extensions.py | 4 +- .../extension_native_helpers.py | 3 +- direct/src/filter/CommonFilters.py | 2 +- direct/src/fsm/ClassicFSM.py | 17 +- direct/src/fsm/FSM.py | 10 +- direct/src/fsm/FourState.py | 6 +- direct/src/fsm/FourStateAI.py | 6 +- direct/src/fsm/SampleFSM.py | 41 ++- direct/src/fsm/State.py | 4 +- direct/src/fsm/StateData.py | 1 - direct/src/fsm/StatePush.py | 11 +- direct/src/gui/DirectButton.py | 6 +- direct/src/gui/DirectCheckBox.py | 2 +- direct/src/gui/DirectCheckButton.py | 6 +- direct/src/gui/DirectDialog.py | 18 +- direct/src/gui/DirectEntry.py | 38 +-- direct/src/gui/DirectEntryScroll.py | 8 +- direct/src/gui/DirectFrame.py | 28 +- direct/src/gui/DirectGui.py | 38 +-- direct/src/gui/DirectGuiBase.py | 45 ++- direct/src/gui/DirectGuiTest.py | 18 +- direct/src/gui/DirectLabel.py | 2 +- direct/src/gui/DirectOptionMenu.py | 14 +- direct/src/gui/DirectRadioButton.py | 8 +- direct/src/gui/DirectScrollBar.py | 8 +- direct/src/gui/DirectScrolledFrame.py | 8 +- direct/src/gui/DirectScrolledList.py | 15 +- direct/src/gui/DirectSlider.py | 8 +- direct/src/gui/DirectWaitBar.py | 6 +- direct/src/gui/OnscreenGeom.py | 36 +-- direct/src/gui/OnscreenImage.py | 40 +-- direct/src/gui/OnscreenText.py | 29 +- direct/src/interval/ActorInterval.py | 2 +- direct/src/interval/AnimControlInterval.py | 2 +- direct/src/interval/FunctionInterval.py | 2 +- direct/src/interval/IndirectInterval.py | 4 +- direct/src/interval/Interval.py | 35 ++- direct/src/interval/IntervalGlobal.py | 24 +- direct/src/interval/IntervalTest.py | 18 +- direct/src/interval/LerpInterval.py | 16 +- direct/src/interval/MetaInterval.py | 55 ++-- direct/src/interval/MopathInterval.py | 2 +- direct/src/interval/ParticleInterval.py | 2 +- direct/src/interval/ProjectileInterval.py | 2 +- direct/src/interval/ProjectileIntervalTest.py | 2 +- direct/src/interval/SoundInterval.py | 2 +- direct/src/interval/TestInterval.py | 2 +- direct/src/leveleditor/ActionMgr.py | 50 ++-- direct/src/leveleditor/AnimControlUI.py | 10 +- direct/src/leveleditor/AnimMgr.py | 2 +- direct/src/leveleditor/AnimMgrBase.py | 16 +- direct/src/leveleditor/CurveAnimUI.py | 10 +- direct/src/leveleditor/CurveEditor.py | 4 +- direct/src/leveleditor/FileMgr.py | 9 +- direct/src/leveleditor/GraphEditorUI.py | 11 +- direct/src/leveleditor/HotKeyUI.py | 6 +- direct/src/leveleditor/LayerEditorUI.py | 8 +- direct/src/leveleditor/LevelEditor.py | 14 +- direct/src/leveleditor/LevelEditorBase.py | 8 +- direct/src/leveleditor/LevelEditorStart.py | 2 +- direct/src/leveleditor/LevelEditorUI.py | 2 +- direct/src/leveleditor/LevelEditorUIBase.py | 26 +- direct/src/leveleditor/LevelLoader.py | 4 +- direct/src/leveleditor/LevelLoaderBase.py | 2 +- direct/src/leveleditor/MayaConverter.py | 6 +- direct/src/leveleditor/ObjectHandler.py | 2 +- direct/src/leveleditor/ObjectMgr.py | 2 +- direct/src/leveleditor/ObjectMgrBase.py | 19 +- direct/src/leveleditor/ObjectPalette.py | 2 +- direct/src/leveleditor/ObjectPaletteBase.py | 8 +- direct/src/leveleditor/ObjectPaletteUI.py | 4 +- direct/src/leveleditor/ObjectPropertyUI.py | 8 +- direct/src/leveleditor/PaletteTreeCtrl.py | 6 +- direct/src/leveleditor/ProtoObjs.py | 4 +- direct/src/leveleditor/ProtoObjsUI.py | 5 +- direct/src/leveleditor/ProtoPalette.py | 2 +- direct/src/leveleditor/ProtoPaletteBase.py | 16 +- direct/src/leveleditor/ProtoPaletteUI.py | 7 +- direct/src/leveleditor/SceneGraphUI.py | 2 +- direct/src/leveleditor/SceneGraphUIBase.py | 11 +- direct/src/motiontrail/MotionTrail.py | 16 +- direct/src/p3d/AppRunner.py | 6 +- direct/src/p3d/DeploymentTools.py | 223 +++++++------- direct/src/p3d/HostInfo.py | 8 +- direct/src/p3d/JavaScript.py | 14 +- direct/src/p3d/PackageMerger.py | 2 +- direct/src/p3d/Packager.py | 37 +-- direct/src/p3d/PatchMaker.py | 12 +- direct/src/p3d/SeqValue.py | 10 +- direct/src/p3d/packp3d.py | 11 +- direct/src/p3d/panda3d.pdef | 25 +- direct/src/p3d/pdeploy.py | 68 ++--- direct/src/p3d/pmerge.py | 13 +- direct/src/p3d/ppatcher.py | 11 +- direct/src/p3d/runp3d.py | 12 +- direct/src/p3d/thirdparty.pdef | 22 +- direct/src/particles/GlobalForceGroup.py | 2 +- direct/src/particles/ParticleEffect.py | 20 +- direct/src/particles/ParticleTest.py | 6 +- direct/src/particles/Particles.py | 14 +- .../particles/SpriteParticleRendererExt.py | 12 +- direct/src/plugin_installer/make_installer.py | 53 ++-- direct/src/plugin_installer/make_xpi.py | 4 +- direct/src/plugin_npapi/make_osx_bundle.py | 10 +- .../src/plugin_standalone/make_osx_bundle.py | 12 +- direct/src/showbase/Audio3DManager.py | 10 +- direct/src/showbase/BulletinBoard.py | 2 +- direct/src/showbase/BulletinBoardGlobal.py | 2 +- direct/src/showbase/ContainerLeakDetector.py | 105 ++++--- direct/src/showbase/ContainerReport.py | 24 +- direct/src/showbase/CountedResource.py | 58 ++-- direct/src/showbase/DirectObject.py | 6 +- direct/src/showbase/DistancePhasedNode.py | 6 +- direct/src/showbase/EventManager.py | 2 +- direct/src/showbase/EventManagerGlobal.py | 2 +- direct/src/showbase/ExceptionVarDump.py | 9 +- direct/src/showbase/Factory.py | 2 +- direct/src/showbase/FindCtaPaths.py | 8 +- direct/src/showbase/Finder.py | 21 +- direct/src/showbase/GarbageReport.py | 36 ++- direct/src/showbase/Job.py | 6 +- direct/src/showbase/JobManager.py | 10 +- direct/src/showbase/JobManagerGlobal.py | 2 +- direct/src/showbase/LeakDetectors.py | 24 +- direct/src/showbase/Loader.py | 18 +- direct/src/showbase/Messenger.py | 48 +-- direct/src/showbase/MessengerGlobal.py | 2 +- direct/src/showbase/MessengerLeakDetector.py | 12 +- direct/src/showbase/ObjectPool.py | 38 +-- direct/src/showbase/ObjectReport.py | 12 +- direct/src/showbase/OnScreenDebug.py | 9 +- direct/src/showbase/PhasedObject.py | 18 +- direct/src/showbase/ProfileSession.py | 55 ++-- direct/src/showbase/PythonUtil.py | 279 +++++++++--------- direct/src/showbase/RandomNumGen.py | 12 +- direct/src/showbase/ReferrerSearch.py | 62 ++-- direct/src/showbase/ShadowPlacer.py | 2 +- direct/src/showbase/ShowBase.py | 35 ++- direct/src/showbase/ShowBaseGlobal.py | 10 +- direct/src/showbase/ThreeUpShow.py | 2 +- direct/src/showbase/TkGlobal.py | 6 +- direct/src/showbase/VFSImporter.py | 7 +- direct/src/showbase/VerboseImport.py | 4 +- direct/src/showbase/pandaSqueezeTool.py | 24 +- direct/src/showbase/pandaSqueezer.py | 12 +- direct/src/showutil/Effects.py | 2 +- direct/src/showutil/FreezeTool.py | 52 ++-- direct/src/showutil/Rope.py | 6 +- direct/src/showutil/TexMemWatcher.py | 2 +- direct/src/showutil/pfreeze.py | 9 +- direct/src/stdpy/file.py | 10 +- direct/src/stdpy/glob.py | 2 +- direct/src/stdpy/pickle.py | 2 +- direct/src/stdpy/thread.py | 2 +- direct/src/stdpy/threading.py | 5 +- direct/src/stdpy/threading2.py | 17 +- direct/src/task/FrameProfiler.py | 20 +- direct/src/task/Task.py | 58 ++-- direct/src/task/TaskManagerGlobal.py | 2 +- direct/src/task/TaskProfiler.py | 6 +- direct/src/task/Timer.py | 2 +- direct/src/tkpanels/AnimPanel.py | 19 +- direct/src/tkpanels/DirectSessionPanel.py | 9 +- direct/src/tkpanels/FSMInspector.py | 50 ++-- direct/src/tkpanels/Inspector.py | 9 +- direct/src/tkpanels/MopathRecorder.py | 46 +-- direct/src/tkpanels/NotifyPanel.py | 2 +- direct/src/tkpanels/ParticlePanel.py | 39 +-- direct/src/tkpanels/Placer.py | 13 +- direct/src/tkpanels/TaskManagerPanel.py | 13 +- direct/src/tkwidgets/AppShell.py | 28 +- direct/src/tkwidgets/Dial.py | 11 +- direct/src/tkwidgets/EntryScale.py | 38 +-- direct/src/tkwidgets/Floater.py | 11 +- direct/src/tkwidgets/MemoryExplorer.py | 3 +- direct/src/tkwidgets/ProgressBar.py | 2 +- direct/src/tkwidgets/SceneGraphExplorer.py | 3 +- direct/src/tkwidgets/Slider.py | 22 +- direct/src/tkwidgets/Tree.py | 9 +- direct/src/tkwidgets/Valuator.py | 41 +-- direct/src/tkwidgets/VectorWidgets.py | 21 +- .../src/tkwidgets/WidgetPropertiesDialog.py | 31 +- direct/src/wxwidgets/ViewPort.py | 2 +- direct/src/wxwidgets/WxPandaShell.py | 4 +- direct/src/wxwidgets/WxPandaStart.py | 2 +- makepanda/makepanda.py | 21 +- 256 files changed, 2108 insertions(+), 2104 deletions(-) diff --git a/direct/src/actor/Actor.py b/direct/src/actor/Actor.py index 74cb07937f..29db4290bd 100644 --- a/direct/src/actor/Actor.py +++ b/direct/src/actor/Actor.py @@ -6,7 +6,7 @@ from panda3d.core import * from panda3d.core import Loader as PandaLoader from direct.showbase.DirectObject import DirectObject from direct.directnotify import DirectNotifyGlobal -import types + class Actor(DirectObject, NodePath): """ @@ -239,30 +239,30 @@ class Actor(DirectObject, NodePath): # models{}{}, anims{}{} = multi-part actor w/ LOD # # make sure we have models - if (models): + if models: # do we have a dictionary of models? - if (type(models)==type({})): + if type(models) == dict: # if this is a dictionary of dictionaries - if (type(models[models.keys()[0]]) == type({})): + if type(models[next(iter(models))]) == dict: # then it must be a multipart actor w/LOD self.setLODNode(node = lodNode) # preserve numerical order for lod's # this will make it easier to set ranges - sortedKeys = models.keys() + sortedKeys = list(models.keys()) sortedKeys.sort() for lodName in sortedKeys: # make a node under the LOD switch # for each lod (just because!) self.addLOD(str(lodName)) # iterate over both dicts - for modelName in models[lodName].keys(): + for modelName in models[lodName]: self.loadModel(models[lodName][modelName], modelName, lodName, copy = copy, okMissing = okMissing) # then if there is a dictionary of dictionaries of anims - elif (type(anims[anims.keys()[0]])==type({})): + elif type(anims[next(iter(anims))]) == dict: # then this is a multipart actor w/o LOD - for partName in models.keys(): + for partName in models: # pass in each part self.loadModel(models[partName], partName, copy = copy, okMissing = okMissing) @@ -270,7 +270,7 @@ class Actor(DirectObject, NodePath): # it is a single part actor w/LOD self.setLODNode(node = lodNode) # preserve order of LOD's - sortedKeys = models.keys() + sortedKeys = list(models.keys()) sortedKeys.sort() for lodName in sortedKeys: self.addLOD(str(lodName)) @@ -283,28 +283,28 @@ class Actor(DirectObject, NodePath): # load anims # make sure the actor has animations - if (anims): - if (len(anims) >= 1): + if anims: + if len(anims) >= 1: # if so, does it have a dictionary of dictionaries? - if (type(anims[anims.keys()[0]])==type({})): + if type(anims[next(iter(anims))]) == dict: # are the models a dict of dicts too? - if (type(models)==type({})): - if (type(models[models.keys()[0]]) == type({})): + if type(models) == dict: + if type(models[next(iter(models))]) == dict: # then we have a multi-part w/ LOD - sortedKeys = models.keys() + sortedKeys = list(models.keys()) sortedKeys.sort() for lodName in sortedKeys: # iterate over both dicts - for partName in anims.keys(): + for partName in anims: self.loadAnims( anims[partName], partName, lodName) else: # then it must be multi-part w/o LOD - for partName in anims.keys(): + for partName in anims: self.loadAnims(anims[partName], partName) - elif (type(models)==type({})): + elif type(models) == dict: # then we have single-part w/ LOD - sortedKeys = models.keys() + sortedKeys = list(models.keys()) sortedKeys.sort() for lodName in sortedKeys: self.loadAnims(anims, lodName=lodName) @@ -431,11 +431,10 @@ class Actor(DirectObject, NodePath): part.outputValue(lineStream) value = lineStream.getLine() - print ' ' * indentLevel, part.getName(), value + print(' '.join((' ' * indentLevel, part.getName(), value))) - for i in range(part.getNumChildren()): - self.__doListJoints(indentLevel + 2, part.getChild(i), - isIncluded, subset) + for child in part.getChildren(): + self.__doListJoints(indentLevel + 2, child, isIncluded, subset) def getActorInfo(self): @@ -449,14 +448,14 @@ class Actor(DirectObject, NodePath): lodName = self.__sortedLODNames[0] partInfo = [] - for partName in partDict.keys(): + for partName in partDict: subpartDef = self.__subpartDict.get(partName, Actor.SubpartDef(partName)) partBundleDict = self.__partBundleDict.get(lodName) partDef = partBundleDict.get(subpartDef.truePartName) partBundle = partDef.getBundle() animDict = partDict[partName] animInfo = [] - for animName in animDict.keys(): + for animName in animDict: file = animDict[animName].filename animControl = animDict[animName].animControl animInfo.append([animName, file, animControl]) @@ -478,17 +477,17 @@ class Actor(DirectObject, NodePath): Pretty print actor's details """ for lodName, lodInfo in self.getActorInfo(): - print 'LOD:', lodName + print('LOD: %s' % lodName) for partName, bundle, animInfo in lodInfo: - print ' Part:', partName - print ' Bundle:', repr(bundle) + print(' Part: %s' % partName) + print(' Bundle: %r' % bundle) for animName, file, animControl in animInfo: - print ' Anim:', animName - print ' File:', file + print(' Anim: %s' % animName) + print(' File: %s' % file) if animControl == None: - print ' (not loaded)' + print(' (not loaded)') else: - print (' NumFrames: %d PlayRate: %0.2f' % + print(' NumFrames: %d PlayRate: %0.2f' % (animControl.getNumFrames(), animControl.getPlayRate())) @@ -568,7 +567,7 @@ class Actor(DirectObject, NodePath): def __updateSortedLODNames(self): # Cache the sorted LOD names so we don't have to grab them # and sort them every time somebody asks for the list - self.__sortedLODNames = self.__partBundleDict.keys() + self.__sortedLODNames = list(self.__partBundleDict.keys()) # Reverse sort the doing a string->int def sortKey(x): if not str(x).isdigit(): @@ -604,8 +603,8 @@ class Actor(DirectObject, NodePath): """ partNames = [] if self.__partBundleDict: - partNames = self.__partBundleDict.values()[0].keys() - return partNames + self.__subpartDict.keys() + partNames = list(next(iter(self.__partBundleDict.values())).keys()) + return partNames + list(self.__subpartDict.keys()) def getGeomNode(self): """ @@ -646,33 +645,33 @@ class Actor(DirectObject, NodePath): """ # make sure we don't call this twice in a row # and pollute the the switches dictionary -## sortedKeys = self.switches.keys() +## sortedKeys = list(self.switches.keys()) ## sortedKeys.sort() child = self.__LODNode.find(str(lodName)) index = self.__LODNode.node().findChild(child.node()) self.__LODNode.node().forceSwitch(index) def printLOD(self): -## sortedKeys = self.switches.keys() +## sortedKeys = list(self.switches.keys()) ## sortedKeys.sort() sortedKeys = self.__sortedLODNames for eachLod in sortedKeys: - print "python switches for %s: in: %d, out %d" % (eachLod, + print("python switches for %s: in: %d, out %d" % (eachLod, self.switches[eachLod][0], - self.switches[eachLod][1]) + self.switches[eachLod][1])) switchNum = self.__LODNode.node().getNumSwitches() for eachSwitch in range(0, switchNum): - print "c++ switches for %d: in: %d, out: %d" % (eachSwitch, + print("c++ switches for %d: in: %d, out: %d" % (eachSwitch, self.__LODNode.node().getIn(eachSwitch), - self.__LODNode.node().getOut(eachSwitch)) + self.__LODNode.node().getOut(eachSwitch))) def resetLOD(self): """ Restore all switch distance info (usually after a useLOD call)""" self.__LODNode.node().clearForceSwitch() -## sortedKeys = self.switches.keys() +## sortedKeys = list(self.switches.keys()) ## sortedKeys.sort() ## for eachLod in sortedKeys: ## index = sortedKeys.index(eachLod) @@ -699,7 +698,7 @@ class Actor(DirectObject, NodePath): # save the switch distance info self.switches[lodName] = [inDist, outDist] # add the switch distance info -## sortedKeys = self.switches.keys() +## sortedKeys = list(self.switches.keys()) ## sortedKeys.sort() self.__LODNode.node().setSwitch(self.getLODIndex(lodName), inDist, outDist) @@ -798,7 +797,7 @@ class Actor(DirectObject, NodePath): lodName = lodNames[lod] if partName == None: partBundleDict = self.__partBundleDict[lodName] - partNames = partBundleDict.keys() + partNames = list(partBundleDict.keys()) else: partNames = [partName] @@ -822,7 +821,7 @@ class Actor(DirectObject, NodePath): If no part specified, return anim durations of first part. NOTE: returns info only for an arbitrary LOD """ - lodName = self.__animControlDict.keys()[0] + lodName = next(iter(self.__animControlDict)) controls = self.getAnimControls(animName, partName) if len(controls) == 0: return None @@ -834,7 +833,7 @@ class Actor(DirectObject, NodePath): Return frame rate of given anim name and given part, unmodified by any play rate in effect. """ - lodName = self.__animControlDict.keys()[0] + lodName = next(iter(self.__animControlDict)) controls = self.getAnimControls(animName, partName) if len(controls) == 0: return None @@ -850,7 +849,7 @@ class Actor(DirectObject, NodePath): """ if self.__animControlDict: # use the first lod - lodName = self.__animControlDict.keys()[0] + lodName = next(iter(self.__animControlDict)) controls = self.getAnimControls(animName, partName) if controls: return controls[0].getPlayRate() @@ -877,7 +876,7 @@ class Actor(DirectObject, NodePath): If no part specified, return anim duration of first part. NOTE: returns info for arbitrary LOD """ - lodName = self.__animControlDict.keys()[0] + lodName = next(iter(self.__animControlDict)) controls = self.getAnimControls(animName, partName) if len(controls) == 0: return None @@ -890,7 +889,7 @@ class Actor(DirectObject, NodePath): return ((toFrame+1)-fromFrame) / animControl.getFrameRate() def getNumFrames(self, animName=None, partName=None): - lodName = self.__animControlDict.keys()[0] + lodName = next(iter(self.__animControlDict)) controls = self.getAnimControls(animName, partName) if len(controls) == 0: return None @@ -908,12 +907,12 @@ class Actor(DirectObject, NodePath): specified return current anim of an arbitrary part in dictionary. NOTE: only returns info for an arbitrary LOD """ - if len(self.__animControlDict.items()) == 0: + if len(self.__animControlDict) == 0: return - lodName, animControlDict = self.__animControlDict.items()[0] + lodName, animControlDict = next(iter(self.__animControlDict.items())) if partName == None: - partName, animDict = animControlDict.items()[0] + partName, animDict = next(iter(animControlDict.items())) else: animDict = animControlDict.get(partName) if animDict == None: @@ -936,9 +935,9 @@ class Actor(DirectObject, NodePath): actor. If part not specified return current anim of first part in dictionary. NOTE: only returns info for an arbitrary LOD """ - lodName, animControlDict = self.__animControlDict.items()[0] + lodName, animControlDict = next(iter(self.__animControlDict.items())) if partName == None: - partName, animDict = animControlDict.items()[0] + partName, animDict = next(iter(animControlDict.items())) else: animDict = animControlDict.get(partName) if animDict == None: @@ -1420,17 +1419,15 @@ class Actor(DirectObject, NodePath): if mode > 0: # Use the 'fixed' bin instead of reordering the scene # graph. - numFrontParts = frontParts.getNumPaths() - for partNum in range(0, numFrontParts): - frontParts[partNum].setBin('fixed', mode) + for part in frontParts: + part.setBin('fixed', mode) return if mode == -2: # Turn off depth test/write on the frontParts. - numFrontParts = frontParts.getNumPaths() - for partNum in range(0, numFrontParts): - frontParts[partNum].setDepthWrite(0) - frontParts[partNum].setDepthTest(0) + for part in frontParts: + part.setDepthWrite(0) + part.setDepthTest(0) # Find the back part. backPart = root.find("**/" + backPartName) @@ -1457,12 +1454,8 @@ class Actor(DirectObject, NodePath): char = partData.partBundleNP char.node().update() geomNodes = char.findAllMatches("**/+GeomNode") - numGeomNodes = geomNodes.getNumPaths() - for nodeNum in xrange(numGeomNodes): - thisGeomNode = geomNodes.getPath(nodeNum) - numGeoms = thisGeomNode.node().getNumGeoms() - for geomNum in xrange(numGeoms): - thisGeom = thisGeomNode.node().getGeom(geomNum) + for thisGeomNode in geomNodes: + for thisGeom in thisGeomNode.node().getGeoms(): thisGeom.markBoundsStale() thisGeomNode.node().markInternalBoundsStale() else: @@ -1473,12 +1466,8 @@ class Actor(DirectObject, NodePath): char = partData.partBundleNP char.node().update() geomNodes = char.findAllMatches("**/+GeomNode") - numGeomNodes = geomNodes.getNumPaths() - for nodeNum in xrange(numGeomNodes): - thisGeomNode = geomNodes.getPath(nodeNum) - numGeoms = thisGeomNode.node().getNumGeoms() - for geomNum in xrange(numGeoms): - thisGeom = thisGeomNode.node().getGeom(geomNum) + for thisGeomNode in geomNodes: + for thisGeom in thisGeomNode.node().getGeoms(): thisGeom.markBoundsStale() thisGeomNode.node().markInternalBoundsStale() @@ -1494,19 +1483,14 @@ class Actor(DirectObject, NodePath): # update all characters first charNodes = part.findAllMatches("**/+Character") - numCharNodes = charNodes.getNumPaths() - for charNum in range(0, numCharNodes): - (charNodes.getPath(charNum)).node().update() + for charNode in charNodes: + charNode.node().update() # for each geomNode, iterate through all geoms and force update # of bounding spheres by marking current bounds as stale geomNodes = part.findAllMatches("**/+GeomNode") - numGeomNodes = geomNodes.getNumPaths() - for nodeNum in range(0, numGeomNodes): - thisGeomNode = geomNodes.getPath(nodeNum) - numGeoms = thisGeomNode.node().getNumGeoms() - for geomNum in range(0, numGeoms): - thisGeom = thisGeomNode.node().getGeom(geomNum) + for nodeNum, thisGeomNode in enumerate(geomNodes): + for geomNum, thisGeom in enumerate(thisGeomNode.node().getGeoms()): thisGeom.markBoundsStale() assert Actor.notify.debug("fixing bounds for node %s, geom %s" % \ (nodeNum, geomNum)) @@ -1517,20 +1501,18 @@ class Actor(DirectObject, NodePath): Show the bounds of all actor geoms """ geomNodes = self.__geomNode.findAllMatches("**/+GeomNode") - numGeomNodes = geomNodes.getNumPaths() - for nodeNum in range(0, numGeomNodes): - geomNodes.getPath(nodeNum).showBounds() + for node in geomNodes: + node.showBounds() def hideAllBounds(self): """ Hide the bounds of all actor geoms """ geomNodes = self.__geomNode.findAllMatches("**/+GeomNode") - numGeomNodes = geomNodes.getNumPaths() - for nodeNum in range(0, numGeomNodes): - geomNodes.getPath(nodeNum).hideBounds() + for node in geomNodes: + node.hideBounds() # actions @@ -1698,7 +1680,7 @@ class Actor(DirectObject, NodePath): if self.mergeLODBundles: lodName = 'common' elif self.switches: - lodName = str(self.switches.keys()[0]) + lodName = str(next(iter(self.switches))) else: lodName = 'lodRoot' @@ -1723,7 +1705,7 @@ class Actor(DirectObject, NodePath): lodName = 'common' elif not lodName: if self.switches: - lodName = str(self.switches.keys()[0]) + lodName = str(next(iter(self.switches))) else: lodName = 'lodRoot' @@ -1777,7 +1759,7 @@ class Actor(DirectObject, NodePath): # If we have the __subpartsComplete flag, and no partName # is specified, it really means to play the animation on # all subparts, not on the overall Actor. - partName = self.__subpartDict.keys() + partName = list(self.__subpartDict.keys()) controls = [] # build list of lodNames and corresponding animControlDicts @@ -1805,7 +1787,7 @@ class Actor(DirectObject, NodePath): else: # Get exactly the named part or parts. - if isinstance(partName, types.StringTypes): + if isinstance(partName, str): partNameList = [partName] else: partNameList = partName @@ -1835,7 +1817,7 @@ class Actor(DirectObject, NodePath): controls.append(anim.animControl) else: # get the named animation(s) only. - if isinstance(animName, types.StringTypes): + if isinstance(animName, str): # A single animName animNameList = [animName] else: @@ -2107,7 +2089,7 @@ class Actor(DirectObject, NodePath): if lodName: partNames = self.__partBundleDict[lodName].keys() else: - partNames = self.__partBundleDict.values()[0].keys() + partNames = next(iter(self.__partBundleDict.values())).keys() for partName in partNames: subJoints = set() @@ -2133,9 +2115,9 @@ class Actor(DirectObject, NodePath): lodNames = ['common'] elif lodName == 'all': reload = False - lodNames = self.switches.keys() + lodNames = list(self.switches.keys()) lodNames.sort() - for i in range(0,len(lodNames)): + for i in range(0, len(lodNames)): lodNames[i] = str(lodNames[i]) else: lodNames = [lodName] @@ -2256,20 +2238,20 @@ class Actor(DirectObject, NodePath): assert Actor.notify.debug("in unloadAnims: %s, part: %s, lod: %s" % (anims, partName, lodName)) - if lodName == None or self.mergeLODBundles: + if lodName is None or self.mergeLODBundles: lodNames = self.__animControlDict.keys() else: lodNames = [lodName] - if (partName == None): + if partName is None: if len(lodNames) > 0: - partNames = self.__animControlDict[lodNames[0]].keys() + partNames = self.__animControlDict[next(iter(lodNames))].keys() else: partNames = [] else: partNames = [partName] - if (anims==None): + if anims is None: for lodName in lodNames: for partName in partNames: for animDef in self.__animControlDict[lodName][partName].values(): @@ -2400,7 +2382,7 @@ class Actor(DirectObject, NodePath): Copy the part bundle dictionary from another actor as this instance's own. NOTE: this method does not actually copy geometry """ - for lodName in other.__partBundleDict.keys(): + for lodName in other.__partBundleDict: # find the lod Asad if lodName == 'lodRoot': partLod = self @@ -2445,11 +2427,11 @@ class Actor(DirectObject, NodePath): assert(other.mergeLODBundles == self.mergeLODBundles) - for lodName in other.__animControlDict.keys(): + for lodName in other.__animControlDict: self.__animControlDict[lodName] = {} - for partName in other.__animControlDict[lodName].keys(): + for partName in other.__animControlDict[lodName]: self.__animControlDict[lodName][partName] = {} - for animName in other.__animControlDict[lodName][partName].keys(): + for animName in other.__animControlDict[lodName][partName]: anim = other.__animControlDict[lodName][partName][animName] anim = anim.makeCopy() self.__animControlDict[lodName][partName][animName] = anim @@ -2512,13 +2494,13 @@ class Actor(DirectObject, NodePath): def printAnimBlends(self, animName=None, partName=None, lodName=None): for lodName, animList in self.getAnimBlends(animName, partName, lodName): - print 'LOD %s:' % (lodName) + print('LOD %s:' % (lodName)) for animName, blendList in animList: list = [] for partName, effect in blendList: list.append('%s:%.3f' % (partName, effect)) - print ' %s: %s' % (animName, ', '.join(list)) + print(' %s: %s' % (animName, ', '.join(list))) def osdAnimBlends(self, animName=None, partName=None, lodName=None): if not onScreenDebug.enabled: @@ -2565,5 +2547,5 @@ class Actor(DirectObject, NodePath): def renamePartBundles(self, partName, newBundleName): subpartDef = self.__subpartDict.get(partName, Actor.SubpartDef(partName)) for partBundleDict in self.__partBundleDict.values(): - partDef=partBundleDict.get(subpartDef.truePartName) + partDef = partBundleDict.get(subpartDef.truePartName) partDef.getBundle().setName(newBundleName) diff --git a/direct/src/actor/DistributedActor.py b/direct/src/actor/DistributedActor.py index 2e991d2043..c46a8863c4 100644 --- a/direct/src/actor/DistributedActor.py +++ b/direct/src/actor/DistributedActor.py @@ -4,7 +4,7 @@ __all__ = ['DistributedActor'] from direct.distributed import DistributedNode -import Actor +from . import Actor class DistributedActor(DistributedNode.DistributedNode, Actor.Actor): def __init__(self, cr): diff --git a/direct/src/cluster/ClusterClient.py b/direct/src/cluster/ClusterClient.py index f238aca91d..873b03d4ea 100644 --- a/direct/src/cluster/ClusterClient.py +++ b/direct/src/cluster/ClusterClient.py @@ -1,8 +1,8 @@ """ClusterClient: Master for mutli-piping or PC clusters. """ from panda3d.core import * -from ClusterMsgs import * -from ClusterConfig import * +from .ClusterMsgs import * +from .ClusterConfig import * from direct.directnotify import DirectNotifyGlobal from direct.showbase import DirectObject from direct.task import Task @@ -44,10 +44,10 @@ class ClusterClient(DirectObject.DirectObject): self.daemon.tellServer(serverConfig.serverName, serverConfig.serverDaemonPort, serverCommand) - print 'Begin waitForServers' + print('Begin waitForServers') if not self.daemon.waitForServers(len(configList)): - print 'Cluster Client, no response from servers' - print 'End waitForServers' + print('Cluster Client, no response from servers') + print('End waitForServers') self.qcm=QueuedConnectionManager() self.serverList = [] self.serverQueues = [] @@ -262,9 +262,8 @@ class ClusterClient(DirectObject.DirectObject): def getNodePathFindCmd(self, nodePath): - import string pathString = repr(nodePath) - index = string.find(pathString, '/') + index = pathString.find('/') if index != -1: rootName = pathString[:index] searchString = pathString[index+1:] @@ -273,9 +272,8 @@ class ClusterClient(DirectObject.DirectObject): return rootName def getNodePathName(self, nodePath): - import string pathString = repr(nodePath) - index = string.find(pathString, '/') + index = pathString.find('/') if index != -1: name = pathString[index+1:] return name @@ -409,7 +407,7 @@ class ClusterClientSync(ClusterClient): #I probably don't need this self.waitForSwap = 0 self.ready = 0 - print "creating synced client" + print("creating synced client") self.startSwapCoordinatorTask() def startSwapCoordinatorTask(self): diff --git a/direct/src/cluster/ClusterConfig.py b/direct/src/cluster/ClusterConfig.py index 6cf71dcaab..73e4ebf2b6 100644 --- a/direct/src/cluster/ClusterConfig.py +++ b/direct/src/cluster/ClusterConfig.py @@ -1,5 +1,5 @@ -from ClusterClient import * +from .ClusterClient import * # A dictionary of information for various cluster configurations. # Dictionary is keyed on cluster-config string diff --git a/direct/src/cluster/ClusterServer.py b/direct/src/cluster/ClusterServer.py index 4ec78b0841..511dc84cef 100644 --- a/direct/src/cluster/ClusterServer.py +++ b/direct/src/cluster/ClusterServer.py @@ -1,5 +1,5 @@ from panda3d.core import * -from ClusterMsgs import * +from .ClusterMsgs import * from direct.distributed.MsgTypes import * from direct.directnotify import DirectNotifyGlobal from direct.showbase import DirectObject @@ -246,7 +246,7 @@ class ClusterServer(DirectObject.DirectObject): if (type == CLUSTER_NONE): pass elif (type == CLUSTER_EXIT): - print 'GOT EXIT' + print('GOT EXIT') import sys sys.exit() elif (type == CLUSTER_CAM_OFFSET): diff --git a/direct/src/controls/BattleWalker.py b/direct/src/controls/BattleWalker.py index 8b6e634e25..a26beb4103 100755 --- a/direct/src/controls/BattleWalker.py +++ b/direct/src/controls/BattleWalker.py @@ -2,7 +2,7 @@ from direct.showbase.InputStateGlobal import inputState from direct.task.Task import Task from pandac.PandaModules import * -import GravityWalker +from . import GravityWalker BattleStrafe = 0 @@ -166,7 +166,7 @@ class BattleWalker(GravityWalker.GravityWalker): # Should fSlide be renamed slideButton? self.slideSpeed=.15*(turnLeft and -self.avatarControlForwardSpeed or turnRight and self.avatarControlForwardSpeed) - print 'slideSpeed: ', self.slideSpeed + print('slideSpeed: %s' % self.slideSpeed) self.rotationSpeed=0 self.speed=0 @@ -233,7 +233,7 @@ class BattleWalker(GravityWalker.GravityWalker): if self.moving: distance = dt * self.speed slideDistance = dt * self.slideSpeed - print 'slideDistance: ', slideDistance + print('slideDistance: %s' % slideDistance) rotation = dt * self.rotationSpeed # Take a step in the direction of our previous heading. diff --git a/direct/src/controls/GhostWalker.py b/direct/src/controls/GhostWalker.py index 8dd36f2450..4badbf7258 100755 --- a/direct/src/controls/GhostWalker.py +++ b/direct/src/controls/GhostWalker.py @@ -15,7 +15,7 @@ animations based on walker events. """ from direct.directnotify import DirectNotifyGlobal -import NonPhysicsWalker +from . import NonPhysicsWalker class GhostWalker(NonPhysicsWalker.NonPhysicsWalker): diff --git a/direct/src/controls/ObserverWalker.py b/direct/src/controls/ObserverWalker.py index efc9c4b0f9..f93e0e3325 100755 --- a/direct/src/controls/ObserverWalker.py +++ b/direct/src/controls/ObserverWalker.py @@ -16,7 +16,7 @@ animations based on walker events. from panda3d.core import * from direct.directnotify import DirectNotifyGlobal -import NonPhysicsWalker +from . import NonPhysicsWalker class ObserverWalker(NonPhysicsWalker.NonPhysicsWalker): notify = DirectNotifyGlobal.directNotify.newCategory("ObserverWalker") diff --git a/direct/src/controls/PhysicsWalker.py b/direct/src/controls/PhysicsWalker.py index b0a0cdfcb8..fc6fe1ca70 100755 --- a/direct/src/controls/PhysicsWalker.py +++ b/direct/src/controls/PhysicsWalker.py @@ -324,7 +324,7 @@ class PhysicsWalker(DirectObject.DirectObject): indicator.instanceTo(contactIndicatorNode) self.physContactIndicator=contactIndicatorNode else: - print "failed load of physics indicator" + print("failed load of physics indicator") def avatarPhysicsIndicator(self, task): #assert self.debugPrint("avatarPhysicsIndicator()") @@ -710,7 +710,7 @@ class PhysicsWalker(DirectObject.DirectObject): def setPriorParentVector(self): assert self.debugPrint("doDeltaPos()") - print "self.__oldDt", self.__oldDt, "self.__oldPosDelta", self.__oldPosDelta + print("self.__oldDt %s self.__oldPosDelta %s" % (self.__oldDt, self.__oldPosDelta)) if __debug__: onScreenDebug.add("__oldDt", "% 10.4f"%self.__oldDt) onScreenDebug.add("self.__oldPosDelta", diff --git a/direct/src/controls/TwoDWalker.py b/direct/src/controls/TwoDWalker.py index d80f90bf4d..b99f6db11b 100644 --- a/direct/src/controls/TwoDWalker.py +++ b/direct/src/controls/TwoDWalker.py @@ -2,7 +2,7 @@ TwoDWalker.py is for controling the avatars in a 2D Scroller game environment. """ -from GravityWalker import * +from .GravityWalker import * from panda3d.core import ConfigVariableBool diff --git a/direct/src/directbase/ThreeUpStart.py b/direct/src/directbase/ThreeUpStart.py index 3d1784408f..b0a78fcef9 100644 --- a/direct/src/directbase/ThreeUpStart.py +++ b/direct/src/directbase/ThreeUpStart.py @@ -1,5 +1,5 @@ -print 'ThreeUpStart: Starting up environment.' +print('ThreeUpStart: Starting up environment.') from pandac.PandaModules import * diff --git a/direct/src/directdevices/DirectFastrak.py b/direct/src/directdevices/DirectFastrak.py index 4f046329a0..c6e30bd8fc 100644 --- a/direct/src/directdevices/DirectFastrak.py +++ b/direct/src/directdevices/DirectFastrak.py @@ -1,7 +1,7 @@ """ Class used to create and control radamec device """ from math import * from direct.showbase.DirectObject import DirectObject -from DirectDeviceManager import * +from .DirectDeviceManager import * from direct.directnotify import DirectNotifyGlobal diff --git a/direct/src/directdevices/DirectJoybox.py b/direct/src/directdevices/DirectJoybox.py index 7376154947..60c4c4211b 100644 --- a/direct/src/directdevices/DirectJoybox.py +++ b/direct/src/directdevices/DirectJoybox.py @@ -1,6 +1,6 @@ """ Class used to create and control joybox device """ from direct.showbase.DirectObject import DirectObject -from DirectDeviceManager import * +from .DirectDeviceManager import * from direct.directtools.DirectUtil import * from direct.gui import OnscreenText from direct.task import Task diff --git a/direct/src/directdevices/DirectRadamec.py b/direct/src/directdevices/DirectRadamec.py index 2f9a2495f1..2aa7b1933c 100644 --- a/direct/src/directdevices/DirectRadamec.py +++ b/direct/src/directdevices/DirectRadamec.py @@ -1,7 +1,7 @@ """ Class used to create and control radamec device """ from math import * from direct.showbase.DirectObject import DirectObject -from DirectDeviceManager import * +from .DirectDeviceManager import * from direct.directnotify import DirectNotifyGlobal diff --git a/direct/src/directnotify/DirectNotify.py b/direct/src/directnotify/DirectNotify.py index 96f79f57a3..14a712bd40 100644 --- a/direct/src/directnotify/DirectNotify.py +++ b/direct/src/directnotify/DirectNotify.py @@ -2,8 +2,8 @@ DirectNotify module: this module contains the DirectNotify class """ -import Notifier -import Logger +from . import Notifier +from . import Logger class DirectNotify: """ @@ -35,7 +35,7 @@ class DirectNotify: """ Return list of category dictionary keys """ - return (self.__categories.keys()) + return list(self.__categories.keys()) def getCategory(self, categoryName): """getCategory(self, string) @@ -97,7 +97,7 @@ class DirectNotify: category.setInfo(1) category.setDebug(1) else: - print ("DirectNotify: unknown notify level: " + str(level) + print("DirectNotify: unknown notify level: " + str(level) + " for category: " + str(categoryName)) diff --git a/direct/src/directnotify/DirectNotifyGlobal.py b/direct/src/directnotify/DirectNotifyGlobal.py index 353b3d48f7..e25ddb11ad 100644 --- a/direct/src/directnotify/DirectNotifyGlobal.py +++ b/direct/src/directnotify/DirectNotifyGlobal.py @@ -2,7 +2,7 @@ __all__ = ['directNotify', 'giveNotify'] -import DirectNotify +from . import DirectNotify directNotify = DirectNotify.DirectNotify() giveNotify = directNotify.giveNotify diff --git a/direct/src/directnotify/LoggerGlobal.py b/direct/src/directnotify/LoggerGlobal.py index 87a89e446d..610a009a8f 100644 --- a/direct/src/directnotify/LoggerGlobal.py +++ b/direct/src/directnotify/LoggerGlobal.py @@ -1,5 +1,5 @@ """instantiate global Logger object""" -import Logger +from . import Logger defaultLogger = Logger.Logger() diff --git a/direct/src/directnotify/Notifier.py b/direct/src/directnotify/Notifier.py index a0dcc511ad..35a916f8b3 100644 --- a/direct/src/directnotify/Notifier.py +++ b/direct/src/directnotify/Notifier.py @@ -2,7 +2,7 @@ Notifier module: contains methods for handling information output for the programmer/user """ -from LoggerGlobal import defaultLogger +from .LoggerGlobal import defaultLogger from direct.showbase import PythonUtil from panda3d.core import ConfigVariableBool, NotifyCategory, StreamWriter, Notify import time @@ -237,7 +237,7 @@ class Notifier: if self.streamWriter: self.streamWriter.write(string + '\n') else: - print >> sys.stderr, string + sys.stderr.write(string + '\n') def debugStateCall(self, obj=None, fsmMemberName='fsm', secondaryFsm='secondaryFSM'): diff --git a/direct/src/directnotify/RotatingLog.py b/direct/src/directnotify/RotatingLog.py index caf7bbd527..e663da67ac 100755 --- a/direct/src/directnotify/RotatingLog.py +++ b/direct/src/directnotify/RotatingLog.py @@ -91,7 +91,7 @@ class RotatingLog: self.timeLimit=time.time()+self.timeInterval else: # We'll keep writing to the old file, if available. - print "RotatingLog error: Unable to open new log file \"%s\"."%(path,) + print("RotatingLog error: Unable to open new log file \"%s\"." % (path,)) def write(self, data): """ @@ -115,8 +115,9 @@ class RotatingLog: def isatty(self): return self.file.isatty() - def next(self): - return self.file.next() + def __next__(self): + return next(self.file) + next = __next__ def read(self, size): return self.file.read(size) diff --git a/direct/src/directscripts/eggcacher.py b/direct/src/directscripts/eggcacher.py index ea2f653876..ebef394890 100644 --- a/direct/src/directscripts/eggcacher.py +++ b/direct/src/directscripts/eggcacher.py @@ -19,8 +19,8 @@ class EggCacher: self.pandaloader = Loader() self.loaderopts = LoaderOptions(LoaderOptions.LF_no_ram_cache) if (self.bamcache.getActive() == 0): - print "The model cache is not currently active." - print "You must set a model-cache-dir in your config file." + print("The model cache is not currently active.") + print("You must set a model-cache-dir in your config file.") sys.exit(1) self.parseArgs(args) files = self.scanPaths(self.paths) @@ -39,13 +39,13 @@ class EggCacher: else: break if (len(args) < 1): - print "Usage: eggcacher options file-or-directory" + print("Usage: eggcacher options file-or-directory") sys.exit(1) self.paths = args def scanPath(self, eggs, path): if (os.path.exists(path)==0): - print "No such file or directory: "+path + print("No such file or directory: " + path) return if (os.path.isdir(path)): for f in os.listdir(path): @@ -78,7 +78,7 @@ class EggCacher: percent = (progress * 100) / total report = path if (self.concise): report = os.path.basename(report) - print "Preprocessing Models %2d%% %s" % (percent, report) + print("Preprocessing Models %2d%% %s" % (percent, report)) sys.stdout.flush() if (cached) and (cached.hasData()==0): self.pandaloader.loadSync(fn, self.loaderopts) diff --git a/direct/src/directscripts/extract_docs.py b/direct/src/directscripts/extract_docs.py index 8e291f95ae..b6ad69e946 100644 --- a/direct/src/directscripts/extract_docs.py +++ b/direct/src/directscripts/extract_docs.py @@ -5,6 +5,8 @@ You need to run this before invoking Doxyfile.python. It requires a valid makepanda installation with interrogatedb .in files in the lib/pandac/input directory. """ +from __future__ import print_function + __all__ = [] import os @@ -156,61 +158,61 @@ def translated_type_name(type, scoped=True): def processElement(handle, element): if interrogate_element_has_comment(element): - print >>handle, comment(interrogate_element_comment(element)) + print(comment(interrogate_element_comment(element)), file=handle) - print >>handle, translated_type_name(interrogate_element_type(element)), - print >>handle, interrogate_element_name(element) + ';' + print(translated_type_name(interrogate_element_type(element)), end=' ', file=handle) + print(interrogate_element_name(element) + ';', file=handle) def processFunction(handle, function, isConstructor = False): - for i_wrapper in xrange(interrogate_function_number_of_python_wrappers(function)): + for i_wrapper in range(interrogate_function_number_of_python_wrappers(function)): wrapper = interrogate_function_python_wrapper(function, i_wrapper) if interrogate_wrapper_has_comment(wrapper): - print >>handle, block_comment(interrogate_wrapper_comment(wrapper)) + print(block_comment(interrogate_wrapper_comment(wrapper)), file=handle) if not isConstructor: if interrogate_function_is_method(function): if not interrogate_wrapper_number_of_parameters(wrapper) > 0 or not interrogate_wrapper_parameter_is_this(wrapper, 0): - print >>handle, "static", + print("static", end=' ', file=handle) if interrogate_wrapper_has_return_value(wrapper): - print >>handle, translated_type_name(interrogate_wrapper_return_type(wrapper)), + print(translated_type_name(interrogate_wrapper_return_type(wrapper)), end=' ', file=handle) else: pass#print >>handle, "void", - print >>handle, translateFunctionName(interrogate_function_name(function)) + "(", + print(translateFunctionName(interrogate_function_name(function)) + "(", end=' ', file=handle) else: - print >>handle, "__init__(", + print("__init__(", end=' ', file=handle) first = True for i_param in range(interrogate_wrapper_number_of_parameters(wrapper)): if not interrogate_wrapper_parameter_is_this(wrapper, i_param): if not first: - print >>handle, ",", - print >>handle, translated_type_name(interrogate_wrapper_parameter_type(wrapper, i_param)), + print(",", end=' ', file=handle) + print(translated_type_name(interrogate_wrapper_parameter_type(wrapper, i_param)), end=' ', file=handle) if interrogate_wrapper_parameter_has_name(wrapper, i_param): - print >>handle, interrogate_wrapper_parameter_name(wrapper, i_param), + print(interrogate_wrapper_parameter_name(wrapper, i_param), end=' ', file=handle) first = False - print >>handle, ");" + print(");", file=handle) def processType(handle, type): typename = translated_type_name(type, scoped=False) derivations = [ translated_type_name(interrogate_type_get_derivation(type, n)) for n in range(interrogate_type_number_of_derivations(type)) ] if interrogate_type_has_comment(type): - print >>handle, block_comment(interrogate_type_comment(type)) + print(block_comment(interrogate_type_comment(type)), file=handle) if interrogate_type_is_enum(type): - print >>handle, "enum %s {" % typename + print("enum %s {" % typename, file=handle) for i_value in range(interrogate_type_number_of_enum_values(type)): docstring = comment(interrogate_type_enum_value_comment(type, i_value)) if docstring: - print >>handle, docstring - print >>handle, interrogate_type_enum_value_name(type, i_value), "=", interrogate_type_enum_value(type, i_value), "," + print(docstring, file=handle) + print(interrogate_type_enum_value_name(type, i_value), "=", interrogate_type_enum_value(type, i_value), ",", file=handle) elif interrogate_type_is_typedef(type): wrapped_type = translated_type_name(interrogate_type_wrapped_type(type)) - print >>handle, "typedef %s %s;" % (wrapped_type, typename) + print("typedef %s %s;" % (wrapped_type, typename), file=handle) return else: if interrogate_type_is_struct(type): @@ -220,39 +222,39 @@ def processType(handle, type): elif interrogate_type_is_union(type): classtype = "union" else: - print "I don't know what type %s is" % interrogate_type_true_name(type) + print("I don't know what type %s is" % interrogate_type_true_name(type)) return if len(derivations) > 0: - print >>handle, "%s %s : public %s {" % (classtype, typename, ", public ".join(derivations)) + print("%s %s : public %s {" % (classtype, typename, ", public ".join(derivations)), file=handle) else: - print >>handle, "%s %s {" % (classtype, typename) - print >>handle, "public:" + print("%s %s {" % (classtype, typename), file=handle) + print("public:", file=handle) - for i_ntype in xrange(interrogate_type_number_of_nested_types(type)): + for i_ntype in range(interrogate_type_number_of_nested_types(type)): processType(handle, interrogate_type_get_nested_type(type, i_ntype)) - for i_method in xrange(interrogate_type_number_of_constructors(type)): + for i_method in range(interrogate_type_number_of_constructors(type)): processFunction(handle, interrogate_type_get_constructor(type, i_method), True) - for i_method in xrange(interrogate_type_number_of_methods(type)): + for i_method in range(interrogate_type_number_of_methods(type)): processFunction(handle, interrogate_type_get_method(type, i_method)) - for i_method in xrange(interrogate_type_number_of_make_seqs(type)): - print >>handle, "list", translateFunctionName(interrogate_make_seq_seq_name(interrogate_type_get_make_seq(type, i_method))), "();" + for i_method in range(interrogate_type_number_of_make_seqs(type)): + print("list", translateFunctionName(interrogate_make_seq_seq_name(interrogate_type_get_make_seq(type, i_method))), "();", file=handle) - for i_element in xrange(interrogate_type_number_of_elements(type)): + for i_element in range(interrogate_type_number_of_elements(type)): processElement(handle, interrogate_type_get_element(type, i_element)) - print >>handle, "};" + print("};", file=handle) def processModule(handle, package): - print >>handle, "namespace %s {" % package + print("namespace %s {" % package, file=handle) if package != "core": - print >>handle, "using namespace core;" + print("using namespace core;", file=handle) - for i_type in xrange(interrogate_number_of_global_types()): + for i_type in range(interrogate_number_of_global_types()): type = interrogate_get_global_type(i_type) if interrogate_type_has_module_name(type): @@ -260,9 +262,9 @@ def processModule(handle, package): if "panda3d." + package == module_name: processType(handle, type) else: - print "Type %s has no module name" % typename + print("Type %s has no module name" % typename) - for i_func in xrange(interrogate_number_of_global_functions()): + for i_func in range(interrogate_number_of_global_functions()): func = interrogate_get_global_function(i_func) if interrogate_function_has_module_name(func): @@ -270,16 +272,16 @@ def processModule(handle, package): if "panda3d." + package == module_name: processFunction(handle, func) else: - print "Type %s has no module name" % typename + print("Type %s has no module name" % typename) - print >>handle, "}" + print("}", file=handle) if __name__ == "__main__": handle = open("pandadoc.hpp", "w") - print >>handle, comment("Panda3D modules that are implemented in C++.") - print >>handle, "namespace panda3d {" + print(comment("Panda3D modules that are implemented in C++."), file=handle) + print("namespace panda3d {", file=handle) # Determine the path to the interrogatedb files interrogate_add_search_directory(os.path.join(os.path.dirname(pandac.__file__), "..", "..", "etc")) @@ -295,5 +297,5 @@ if __name__ == "__main__": processModule(handle, module_name) - print >>handle, "}" + print("}", file=handle) handle.close() diff --git a/direct/src/directscripts/gendocs.py b/direct/src/directscripts/gendocs.py index 7770203de4..6bb83c9567 100644 --- a/direct/src/directscripts/gendocs.py +++ b/direct/src/directscripts/gendocs.py @@ -48,7 +48,7 @@ # ######################################################################## -import os, sys, parser, symbol, token, types, re +import os, sys, parser, symbol, token, re ######################################################################## # @@ -103,7 +103,7 @@ def writeFileLines(wfile, lines): sys.exit("Cannot write "+wfile) def findFiles(dirlist, ext, ign, list): - if isinstance(dirlist, types.StringTypes): + if isinstance(dirlist, str): dirlist = [dirlist] for dir in dirlist: for file in os.listdir(dir): @@ -195,8 +195,8 @@ class InterrogateTokenizer: neg = 1 self.pos += 1 if (self.data[self.pos].isdigit()==0): - print "File position "+str(self.pos) - print "Text: "+self.data[self.pos:self.pos+50] + print("File position " + str(self.pos)) + print("Text: " + self.data[self.pos:self.pos+50]) sys.exit("Syntax error in interrogate file format 0") value = 0 while (self.data[self.pos].isdigit()): @@ -340,20 +340,20 @@ class InterrogateDatabase: def printTree(tree, indent): spacing = " "[:indent] - if isinstance(tree, types.TupleType) and isinstance(tree[0], types.IntType): + if isinstance(tree, tuple) and isinstance(tree[0], int): if tree[0] in symbol.sym_name: for i in range(len(tree)): if (i==0): - print spacing + "(symbol." + symbol.sym_name[tree[0]] + "," + print(spacing + "(symbol." + symbol.sym_name[tree[0]] + ",") else: printTree(tree[i], indent+1) - print spacing + ")," + print(spacing + "),") elif tree[0] in token.tok_name: - print spacing + "(token." + token.tok_name[tree[0]] + ", '" + tree[1] + "')," + print(spacing + "(token." + token.tok_name[tree[0]] + ", '" + tree[1] + "'),") else: - print spacing + str(tree) + print(spacing + str(tree)) else: - print spacing + str(tree) + print(spacing + str(tree)) COMPOUND_STMT_PATTERN = ( @@ -447,7 +447,7 @@ class ParseTreeInfo: self.function_info = {} self.assign_info = {} self.derivs = {} - if isinstance(tree, types.StringType): + if isinstance(tree, str): try: tree = parser.suite(tree+"\n").totuple() if (tree): @@ -455,8 +455,8 @@ class ParseTreeInfo: if found: self.docstring = vars["docstring"] except: - print "CAUTION --- Parse failed: "+name - if isinstance(tree, types.TupleType): + print("CAUTION --- Parse failed: " + name) + if isinstance(tree, tuple): self.extract_info(tree) def match(self, pattern, data, vars=None): @@ -480,10 +480,10 @@ class ParseTreeInfo: """ if vars is None: vars = {} - if type(pattern) is types.ListType: # 'variables' are ['varname'] + if type(pattern) is list: # 'variables' are ['varname'] vars[pattern[0]] = data return 1, vars - if type(pattern) is not types.TupleType: + if type(pattern) is not tuple: return (pattern == data), vars if len(data) != len(pattern): return 0, vars @@ -534,7 +534,7 @@ class ParseTreeInfo: classinfo.derivs[vars["classname"]] = 1 def extract_tokens(self, str, tree): - if (isinstance(tree, types.TupleType)): + if (isinstance(tree, tuple)): if tree[0] in token.tok_name: str = str + tree[1] if (tree[1]==","): str=str+" " @@ -564,7 +564,7 @@ class CodeDatabase: self.varExports = {} self.globalfn = [] self.formattedprotos = {} - print "Reading C++ source files" + print("Reading C++ source files") for cxx in cxxlist: tokzr = InterrogateTokenizer(cxx) idb = InterrogateDatabase(tokzr) @@ -583,7 +583,7 @@ class CodeDatabase: self.funcExports.setdefault("pandac.PandaModules", []).append(func.pyname) else: self.funcs[type.scopedname+"."+func.pyname] = func - print "Reading Python sources files" + print("Reading Python sources files") for py in pylist: pyinf = ParseTreeInfo(readFile(py), py, py) mod = pathToModule(py) @@ -602,7 +602,7 @@ class CodeDatabase: self.varExports.setdefault(mod, []).append(var) def getClassList(self): - return self.goodtypes.keys() + return list(self.goodtypes.keys()) def getGlobalFunctionList(self): return self.globalfn @@ -625,7 +625,7 @@ class CodeDatabase: parents.append(basetype.scopedname) return parents elif (isinstance(type, ParseTreeInfo)): - return type.derivs.keys() + return list(type.derivs.keys()) else: return [] @@ -767,7 +767,7 @@ CLASS_RENAME_DICT = { ######################################################################## def makeCodeDatabase(indirlist, directdirlist): - if isinstance(directdirlist, types.StringTypes): + if isinstance(directdirlist, str): directdirlist = [directdirlist] ignore = {} ignore["__init__.py"] = 1 @@ -820,7 +820,7 @@ def generate(pversion, indirlist, directdirlist, docdir, header, footer, urlpref classes = code.getClassList()[:] classes.sort(None, str.lower) xclasses = classes[:] - print "Generating HTML pages" + print("Generating HTML pages") for type in classes: body = "

" + type + "

\n" comment = code.getClassComment(type) @@ -900,14 +900,14 @@ def generate(pversion, indirlist, directdirlist, docdir, header, footer, urlpref index = "

List of Methods - Panda " + pversion + "

\n" - prefixes = table.keys() + prefixes = list(table.keys()) prefixes.sort(None, str.lower) for prefix in prefixes: index = index + linkTo("#"+prefix, prefix) + " " index = index + "

" for prefix in prefixes: index = index + '' + "\n" - names = table[prefix].keys() + names = list(table[prefix].keys()) names.sort(None, str.lower) for name in names: line = '' + name + ":
    \n" @@ -968,9 +968,9 @@ def expandImports(indirlist, directdirlist, fixdirlist): varExports = code.getVarExports(module) if (len(typeExports)+len(funcExports)+len(varExports)==0): result.append(line) - print fixfile+" : "+module+" : no exports" + print(fixfile + " : " + module + " : no exports") else: - print fixfile+" : "+module+" : repairing" + print(fixfile + " : " + module + " : repairing") for x in funcExports: fn = code.getFunctionName(x) if fn in used: diff --git a/direct/src/directscripts/packpanda.py b/direct/src/directscripts/packpanda.py index 1868b0f1cb..b8dec72610 100755 --- a/direct/src/directscripts/packpanda.py +++ b/direct/src/directscripts/packpanda.py @@ -13,7 +13,7 @@ # ############################################################################## -import sys, os, getopt, string, shutil, py_compile, subprocess +import sys, os, getopt, shutil, py_compile, subprocess OPTIONLIST = [ ("dir", 1, "Name of directory containing game"), @@ -27,14 +27,14 @@ OPTIONLIST = [ ] def ParseFailure(): - print "" - print "packpanda usage:" - print "" + print("") + print("packpanda usage:") + print("") for (opt, hasval, explanation) in OPTIONLIST: if (hasval): - print " --%-10s %s"%(opt+" x", explanation) + print(" --%-10s %s"%(opt+" x", explanation)) else: - print " --%-10s %s"%(opt+" ", explanation) + print(" --%-10s %s"%(opt+" ", explanation)) sys.exit(1) def ParseOptions(args): @@ -75,7 +75,7 @@ for dir in sys.path: PANDA=os.path.abspath(dir) if (PANDA is None): sys.exit("Cannot locate the panda root directory in the python path (cannot locate directory containing direct and pandac).") -print "PANDA located at "+PANDA +print("PANDA located at "+PANDA) if (os.path.exists(os.path.join(PANDA,"..","makepanda","makepanda.py"))) and (sys.platform != "win32" or os.path.exists(os.path.join(PANDA,"..","thirdparty","win-nsis","makensis.exe"))): PSOURCE=os.path.abspath(os.path.join(PANDA,"..")) @@ -95,7 +95,7 @@ else: VER=OPTIONS["version"] DIR=OPTIONS["dir"] if (DIR==""): - print "You must specify the --dir option." + print("You must specify the --dir option.") ParseFailure() DIR=os.path.abspath(DIR) MYDIR=os.path.abspath(os.getcwd()) @@ -123,21 +123,21 @@ else: MAIN="main.py" def PrintFileStatus(label, file): if (os.path.exists(file)): - print "%-15s: %s"%(label, file) + print("%-15s: %s"%(label, file)) else: - print "%-15s: %s (MISSING)"%(label, file) + print("%-15s: %s (MISSING)"%(label, file)) PrintFileStatus("Dir", DIR) -print "%-15s: %s"%("Name", NAME) -print "%-15s: %s"%("Start Menu", SMDIRECTORY) +print("%-15s: %s"%("Name", NAME)) +print("%-15s: %s"%("Start Menu", SMDIRECTORY)) PrintFileStatus("Main", os.path.join(DIR, MAIN)) if (sys.platform == "win32"): PrintFileStatus("Icon", ICON) PrintFileStatus("Bitmap", BITMAP) PrintFileStatus("License", LICENSE) -print "%-15s: %s"%("Output", OUTFILE) +print("%-15s: %s"%("Output", OUTFILE)) if (sys.platform == "win32"): - print "%-15s: %s"%("Install Dir", INSTALLDIR) + print("%-15s: %s"%("Install Dir", INSTALLDIR)) if (os.path.isdir(DIR)==0): sys.exit("Difficulty reading "+DIR+". Cannot continue.") @@ -181,8 +181,8 @@ if (sys.platform == "win32"): else: TMPGAME=os.path.join(TMPDIR,"usr","share","games",BASENAME,"game") TMPETC=os.path.join(TMPDIR,"usr","share","games",BASENAME,"etc") -print "" -print "Copying the game to "+TMPDIR+"..." +print("") +print("Copying the game to "+TMPDIR+"...") if (os.path.exists(TMPDIR)): try: shutil.rmtree(TMPDIR) except: sys.exit("Cannot delete "+TMPDIR) @@ -247,7 +247,7 @@ def egg2bam(file,bam): present = os.path.exists(bam) if (present): bam = "packpanda-TMP.bam"; cmd = 'egg2bam -noabs -ps rel -pd . "'+file+'" -o "'+bam+'"' - print "Executing: "+cmd + print("Executing: "+cmd) if (sys.platform == "win32"): res = os.spawnl(os.P_WAIT, EGG2BAM, cmd) else: @@ -257,7 +257,7 @@ def egg2bam(file,bam): os.unlink(bam) def py2pyc(file): - print "Compiling python "+file + print("Compiling python "+file) pyc = file[:-3]+'.pyc' pyo = file[:-3]+'.pyo' if (os.path.exists(pyc)): os.unlink(pyc) @@ -284,24 +284,24 @@ def CompileFiles(file): CompileFiles(os.path.join(file, x)) def DeleteFiles(file): - base = string.lower(os.path.basename(file)) + base = os.path.basename(file).lower() if (os.path.isdir(file)): for pattern in OPTIONS["rmdir"]: - if (string.lower(pattern) == base): - print "Deleting "+file + if pattern.lower() == base: + print("Deleting "+file) shutil.rmtree(file) return for x in os.listdir(file): DeleteFiles(os.path.join(file, x)) else: for ext in OPTIONS["rmext"]: - if (base[-(len(ext)+1):] == string.lower("."+ext)): - print "Deleting "+file + if base[-(len(ext) + 1):] == ("." + ext).lower(): + print("Deleting "+file) os.unlink(file) return -print "" -print "Compiling BAM and PYC files..." +print("") +print("Compiling BAM and PYC files...") os.chdir(TMPGAME) CompileFiles(".") DeleteFiles(".") @@ -371,9 +371,9 @@ if (sys.platform == "win32"): CMD=CMD+'/DPPICON="'+PPICON+'" ' CMD=CMD+'"'+PSOURCE+'\\direct\\directscripts\\packpanda.nsi"' - print "" - print CMD - print "packing..." + print("") + print(CMD) + print("packing...") subprocess.call(CMD) else: os.chdir(MYDIR) diff --git a/direct/src/directtools/DirectCameraControl.py b/direct/src/directtools/DirectCameraControl.py index e3fbe6c8b7..2913260c57 100644 --- a/direct/src/directtools/DirectCameraControl.py +++ b/direct/src/directtools/DirectCameraControl.py @@ -1,8 +1,8 @@ from direct.showbase.DirectObject import DirectObject -from DirectUtil import * -from DirectGeometry import * -from DirectGlobals import * -from DirectSelection import SelectionRay +from .DirectUtil import * +from .DirectGeometry import * +from .DirectGlobals import * +from .DirectSelection import SelectionRay from direct.interval.IntervalGlobal import Sequence, Func from direct.directnotify import DirectNotifyGlobal from direct.task import Task @@ -233,13 +233,13 @@ class DirectCameraControl(DirectObject): self.updateCoaMarkerSize() def mouseFlyStartTopWin(self): - print "Moving mouse 2 in new window" + print("Moving mouse 2 in new window") #altIsDown = base.getAlt() #if altIsDown: # print "Alt is down" def mouseFlyStopTopWin(self): - print "Stopping mouse 2 in new window" + print("Stopping mouse 2 in new window") def spawnXZTranslateOrHPanYZoom(self): # Kill any existing tasks diff --git a/direct/src/directtools/DirectGeometry.py b/direct/src/directtools/DirectGeometry.py index 9c748e57b3..2c69a8d8d5 100644 --- a/direct/src/directtools/DirectGeometry.py +++ b/direct/src/directtools/DirectGeometry.py @@ -1,7 +1,7 @@ from panda3d.core import * -from DirectGlobals import * -from DirectUtil import * +from .DirectGlobals import * +from .DirectUtil import * import math class LineNodePath(NodePath): @@ -28,10 +28,10 @@ class LineNodePath(NodePath): ls.setColor(colorVec) def moveTo(self, *_args): - apply(self.lineSegs.moveTo, _args) + self.lineSegs.moveTo(*_args) def drawTo(self, *_args): - apply(self.lineSegs.drawTo, _args) + self.lineSegs.drawTo(*_args) def create(self, frameAccurate = 0): self.lineSegs.create(self.lineNode, frameAccurate) @@ -47,13 +47,13 @@ class LineNodePath(NodePath): self.lineSegs.setThickness(thickness) def setColor(self, *_args): - apply(self.lineSegs.setColor, _args) + self.lineSegs.setColor(*_args) def setVertex(self, *_args): - apply(self.lineSegs.setVertex, _args) + self.lineSegs.setVertex(*_args) def setVertexColor(self, vertex, *_args): - apply(self.lineSegs.setVertexColor, (vertex,) + _args) + self.lineSegs.setVertexColor(*(vertex,) + _args) def getCurrentPosition(self): return self.lineSegs.getCurrentPosition() @@ -119,9 +119,9 @@ class LineNodePath(NodePath): Given a list of lists of points, draw a separate line for each list """ for pointList in lineList: - apply(self.moveTo, pointList[0]) + self.moveTo(*pointList[0]) for point in pointList[1:]: - apply(self.drawTo, point) + self.drawTo(*point) ## ## Given a point in space, and a direction, find the point of intersection diff --git a/direct/src/directtools/DirectGlobals.py b/direct/src/directtools/DirectGlobals.py index 372d16839f..9d10a3f691 100644 --- a/direct/src/directtools/DirectGlobals.py +++ b/direct/src/directtools/DirectGlobals.py @@ -51,12 +51,12 @@ LE_CAM_MASKS = {'persp':LE_PERSP_CAM_MASK, 'top':LE_TOP_CAM_MASK} def LE_showInAllCam(nodePath): - for camName in LE_CAM_MASKS.keys(): + for camName in LE_CAM_MASKS: nodePath.show(LE_CAM_MASKS[camName]) def LE_showInOneCam(nodePath, thisCamName): LE_showInAllCam(nodePath) - for camName in LE_CAM_MASKS.keys(): + for camName in LE_CAM_MASKS: if camName != thisCamName: nodePath.hide(LE_CAM_MASKS[camName]) diff --git a/direct/src/directtools/DirectGrid.py b/direct/src/directtools/DirectGrid.py index e7e67823a3..80d8280ec0 100644 --- a/direct/src/directtools/DirectGrid.py +++ b/direct/src/directtools/DirectGrid.py @@ -1,8 +1,8 @@ from panda3d.core import * from direct.showbase.DirectObject import DirectObject -from DirectUtil import * -from DirectGeometry import * +from .DirectUtil import * +from .DirectGeometry import * class DirectGrid(NodePath, DirectObject): def __init__(self,gridSize=100.0,gridSpacing=5.0,planeColor=(0.5,0.5,0.5,0.5),parent = None): diff --git a/direct/src/directtools/DirectLights.py b/direct/src/directtools/DirectLights.py index 1797351032..f20f08aca7 100644 --- a/direct/src/directtools/DirectLights.py +++ b/direct/src/directtools/DirectLights.py @@ -78,7 +78,7 @@ class DirectLights(NodePath): light.setColor(VBase4(1)) light.setLens(PerspectiveLens()) else: - print 'Invalid light type' + print('Invalid light type') return None # Add the new light directLight = DirectLight(light, self) diff --git a/direct/src/directtools/DirectManipulation.py b/direct/src/directtools/DirectManipulation.py index ad9a1c0e51..3ebc697400 100644 --- a/direct/src/directtools/DirectManipulation.py +++ b/direct/src/directtools/DirectManipulation.py @@ -1,10 +1,9 @@ from direct.showbase.DirectObject import DirectObject -from DirectGlobals import * -from DirectUtil import * -from DirectGeometry import * -from DirectSelection import SelectionRay +from .DirectGlobals import * +from .DirectUtil import * +from .DirectGeometry import * +from .DirectSelection import SelectionRay from direct.task import Task -import types from copy import deepcopy class DirectManipulationControl(DirectObject): @@ -1207,7 +1206,7 @@ class ObjectHandles(NodePath, DirectObject): self.reparentTo(hidden) def enableHandles(self, handles): - if type(handles) == types.ListType: + if type(handles) == list: for handle in handles: self.enableHandle(handle) elif handles == 'x': @@ -1256,7 +1255,7 @@ class ObjectHandles(NodePath, DirectObject): self.zScaleGroup.reparentTo(self.zHandles) def disableHandles(self, handles): - if type(handles) == types.ListType: + if type(handles) == list: for handle in handles: self.disableHandle(handle) elif handles == 'x': diff --git a/direct/src/directtools/DirectSelection.py b/direct/src/directtools/DirectSelection.py index 2b2373ce26..ef14fb429b 100644 --- a/direct/src/directtools/DirectSelection.py +++ b/direct/src/directtools/DirectSelection.py @@ -1,7 +1,7 @@ from direct.showbase.DirectObject import DirectObject -from DirectGlobals import * -from DirectUtil import * -from DirectGeometry import * +from .DirectGlobals import * +from .DirectUtil import * +from .DirectGeometry import * COA_ORIGIN = 0 COA_CENTER = 1 @@ -68,7 +68,7 @@ class SelectedNodePaths(DirectObject): """ Select the specified node path. Multiselect as required """ # Do nothing if nothing selected if not nodePath: - print 'Nothing selected!!' + print('Nothing selected!!') return None # Reset selected objects and highlight if multiSelect is false @@ -160,7 +160,7 @@ class SelectedNodePaths(DirectObject): return None def getDeselectedAsList(self): - return self.deselectedDict.values()[:] + return list(self.deselectedDict.values()) def getDeselectedDict(self, id): """ @@ -260,7 +260,7 @@ class SelectedNodePaths(DirectObject): return self.getDeselectedDict(id) def getNumSelected(self): - return len(self.selectedDict.keys()) + return len(self.selectedDict) class DirectBoundingBox: diff --git a/direct/src/directtools/DirectSession.py b/direct/src/directtools/DirectSession.py index 2fb18b5806..96f8bdb610 100644 --- a/direct/src/directtools/DirectSession.py +++ b/direct/src/directtools/DirectSession.py @@ -1,27 +1,25 @@ import math -import types -import string +import sys from panda3d.core import * -from DirectUtil import * +from .DirectUtil import * from direct.showbase.DirectObject import DirectObject from direct.task import Task -from DirectGlobals import DIRECT_NO_MOD -from DirectCameraControl import DirectCameraControl -from DirectManipulation import DirectManipulationControl -from DirectSelection import SelectionRay, COA_ORIGIN, SelectedNodePaths -from DirectGrid import DirectGrid +from .DirectGlobals import DIRECT_NO_MOD +from .DirectCameraControl import DirectCameraControl +from .DirectManipulation import DirectManipulationControl +from .DirectSelection import SelectionRay, COA_ORIGIN, SelectedNodePaths +from .DirectGrid import DirectGrid #from DirectGeometry import * -from DirectLights import DirectLights +from .DirectLights import DirectLights from direct.cluster.ClusterClient import createClusterClient, DummyClusterClient from direct.cluster.ClusterServer import ClusterServer ## from direct.tkpanels import Placer ## from direct.tkwidgets import Slider ## from direct.tkwidgets import SceneGraphExplorer from direct.gui import OnscreenText -from direct.showbase import Loader from direct.interval.IntervalGlobal import * class DirectSession(DirectObject): @@ -115,7 +113,7 @@ class DirectSession(DirectObject): if fastrak: from direct.directdevices import DirectFastrak # parse string into format device:N where N is the sensor name - fastrak = string.split(fastrak) + fastrak = fastrak.split() for i in range(len(fastrak))[1:]: self.fastrak.append(DirectFastrak.DirectFastrak(fastrak[0] + ':' + fastrak[i])) @@ -556,12 +554,12 @@ class DirectSession(DirectObject): input = input[:-7] # Deal with keyboard and mouse input - if input in self.hotKeyMap.keys(): + if input in self.hotKeyMap: keyDesc = self.hotKeyMap[input] messenger.send(keyDesc[1]) - elif input in self.speicalKeyMap.keys(): + elif input in self.speicalKeyMap: messenger.send(self.speicalKeyMap[input]) - elif input in self.directOnlyKeyMap.keys(): + elif input in self.directOnlyKeyMap: if self.fIgnoreDirectOnlyKeyMap: return keyDesc = self.directOnlyKeyMap[input] @@ -808,7 +806,7 @@ class DirectSession(DirectObject): def isNotCycle(self, nodePath, parent): if nodePath == parent: - print 'DIRECT.reparent: Invalid parent' + print('DIRECT.reparent: Invalid parent') return 0 elif parent.hasParent(): return self.isNotCycle(nodePath, parent.getParent()) @@ -944,7 +942,10 @@ class DirectSession(DirectObject): def getAndSetName(self, nodePath): """ Prompt user for new node path name """ - from tkSimpleDialog import askstring + if sys.version_info >= (3, 0): + from tkinter.simpledialog import askstring + else: + from tkSimpleDialog import askstring newName = askstring('Node Path: ' + nodePath.getName(), 'Enter new name:') if newName: diff --git a/direct/src/directtools/DirectUtil.py b/direct/src/directtools/DirectUtil.py index 224b069b9d..9919f841b2 100644 --- a/direct/src/directtools/DirectUtil.py +++ b/direct/src/directtools/DirectUtil.py @@ -1,5 +1,5 @@ -from DirectGlobals import * +from .DirectGlobals import * # Routines to adjust values def ROUND_TO(value, divisor): diff --git a/direct/src/directutil/DeltaProfiler.py b/direct/src/directutil/DeltaProfiler.py index 8e2612fd1c..2c51c699be 100755 --- a/direct/src/directutil/DeltaProfiler.py +++ b/direct/src/directutil/DeltaProfiler.py @@ -16,11 +16,11 @@ class DeltaProfiler: def printDeltaTime(self, label): if self.active: deltaTime=time()-self.priorTime - print "%s DeltaTime %-25s to %-25s: %3.5f"%( + print("%s DeltaTime %-25s to %-25s: %3.5f"%( self.name, self.priorLabel, label, - deltaTime) + deltaTime)) self.priorLabel=label # The printing time is not included in the timing. # This is intentional. diff --git a/direct/src/directutil/DistributedLargeBlobSender.py b/direct/src/directutil/DistributedLargeBlobSender.py index ae521369c2..39748a13a2 100755 --- a/direct/src/directutil/DistributedLargeBlobSender.py +++ b/direct/src/directutil/DistributedLargeBlobSender.py @@ -2,7 +2,7 @@ from direct.distributed import DistributedObject from direct.directnotify import DirectNotifyGlobal -import LargeBlobSenderConsts +from . import LargeBlobSenderConsts class DistributedLargeBlobSender(DistributedObject.DistributedObject): """DistributedLargeBlobSender: for sending large chunks of data through diff --git a/direct/src/directutil/DistributedLargeBlobSenderAI.py b/direct/src/directutil/DistributedLargeBlobSenderAI.py index b679a5f714..648599731d 100755 --- a/direct/src/directutil/DistributedLargeBlobSenderAI.py +++ b/direct/src/directutil/DistributedLargeBlobSenderAI.py @@ -2,7 +2,7 @@ from direct.distributed import DistributedObjectAI from direct.directnotify import DirectNotifyGlobal -import LargeBlobSenderConsts +from . import LargeBlobSenderConsts class DistributedLargeBlobSenderAI(DistributedObjectAI.DistributedObjectAI): """DistributedLargeBlobSenderAI: for sending large chunks of data through diff --git a/direct/src/directutil/MemoryLeakHelpers.py b/direct/src/directutil/MemoryLeakHelpers.py index 4607d05e16..950e7fd9b1 100755 --- a/direct/src/directutil/MemoryLeakHelpers.py +++ b/direct/src/directutil/MemoryLeakHelpers.py @@ -11,7 +11,7 @@ import gc gc.set_debug(gc.DEBUG_LEAK) gc.collect() -print gc.garbage +print(gc.garbage) # Inside DistributedObjectAI, you can uncomment the __del__ function to # see when your objects are being deleted (or not) diff --git a/direct/src/directutil/Mopath.py b/direct/src/directutil/Mopath.py index 07d7dd63b2..05e437d34d 100644 --- a/direct/src/directutil/Mopath.py +++ b/direct/src/directutil/Mopath.py @@ -29,7 +29,7 @@ class Mopath(DirectObject): elif isinstance( objectToLoad, str ): self.loadFile( objectToLoad ) elif objectToLoad is not None: - print "Mopath: Unable to load object '%s', objectToLoad must be a file name string or a NodePath" % objectToLoad + print("Mopath: Unable to load object '%s', objectToLoad must be a file name string or a NodePath" % objectToLoad) def getMaxT(self): return self.maxT * self.timeScale @@ -40,7 +40,7 @@ class Mopath(DirectObject): self.loadNodePath(nodePath) nodePath.removeNode() else: - print 'Mopath: no data in file: %s' % filename + print('Mopath: no data in file: %s' % filename) def loadNodePath(self, nodePath, fReset = 1): @@ -55,7 +55,7 @@ class Mopath(DirectObject): elif (self.hprNurbsCurve != None): self.maxT = self.hprNurbsCurve.getMaxT() else: - print 'Mopath: no valid curves in nodePath: %s' % nodePath + print('Mopath: no valid curves in nodePath: %s' % nodePath) def reset(self): @@ -77,7 +77,7 @@ class Mopath(DirectObject): if (self.xyzNurbsCurve == None): self.xyzNurbsCurve = node else: - print 'Mopath: got a PCT_NONE curve and an XYZ Curve in nodePath: %s' % nodePath + print('Mopath: got a PCT_NONE curve and an XYZ Curve in nodePath: %s' % nodePath) elif (node.getCurveType() == PCTT): self.tNurbsCurve.append(node) else: @@ -106,7 +106,7 @@ class Mopath(DirectObject): def goTo(self, node, time): if (self.xyzNurbsCurve == None) and (self.hprNurbsCurve == None): - print 'Mopath: Mopath has no curves' + print('Mopath: Mopath has no curves') return time /= self.timeScale self.playbackTime = self.calcTime(CLAMP(time, 0.0, self.maxT)) @@ -145,7 +145,7 @@ class Mopath(DirectObject): def play(self, node, time = 0.0, loop = 0): if (self.xyzNurbsCurve == None) and (self.hprNurbsCurve == None): - print 'Mopath: Mopath has no curves' + print('Mopath: Mopath has no curves') return self.node = node self.loop = loop diff --git a/direct/src/directutil/Verify.py b/direct/src/directutil/Verify.py index 8a1f41acb5..ce23b1daa9 100755 --- a/direct/src/directutil/Verify.py +++ b/direct/src/directutil/Verify.py @@ -52,11 +52,11 @@ def verify(assertion): wish to have the assertion checked, even in release (-O) code. """ if not assertion: - print "\n\nverify failed:" + print("\n\nverify failed:") import sys - print " File \"%s\", line %d"%( + print(" File \"%s\", line %d"%( sys._getframe(1).f_code.co_filename, - sys._getframe(1).f_lineno) + sys._getframe(1).f_lineno)) if wantVerifyPdb: import pdb pdb.set_trace() diff --git a/direct/src/distributed/AsyncRequest.py b/direct/src/distributed/AsyncRequest.py index dc3c6bf4d6..1d30259a6e 100755 --- a/direct/src/distributed/AsyncRequest.py +++ b/direct/src/distributed/AsyncRequest.py @@ -1,7 +1,7 @@ #from otp.ai.AIBaseGlobal import * from direct.directnotify import DirectNotifyGlobal from direct.showbase.DirectObject import DirectObject -from ConnectionRepository import * +from .ConnectionRepository import * from panda3d.core import ConfigVariableDouble, ConfigVariableInt, ConfigVariableBool ASYNC_REQUEST_DEFAULT_TIMEOUT_IN_SECONDS = 8.0 @@ -251,9 +251,9 @@ class AsyncRequest(DirectObject): if __debug__: if _breakOnTimeout: if hasattr(self, "avatarId"): - print "\n\nself.avatarId =", self.avatarId - print "\nself.neededObjects =", self.neededObjects - print "\ntimed out after %s seconds.\n\n"%(task.delayTime,) + print("\n\nself.avatarId =", self.avatarId) + print("\nself.neededObjects =", self.neededObjects) + print("\ntimed out after %s seconds.\n\n"%(task.delayTime,)) import pdb; pdb.set_trace() self.delete() return Task.done diff --git a/direct/src/distributed/CRCache.py b/direct/src/distributed/CRCache.py index 2c3d966778..b256c4f13e 100644 --- a/direct/src/distributed/CRCache.py +++ b/direct/src/distributed/CRCache.py @@ -1,7 +1,7 @@ """CRCache module: contains the CRCache class""" from direct.directnotify import DirectNotifyGlobal -import DistributedObject +from . import DistributedObject class CRCache: notify = DirectNotifyGlobal.directNotify.newCategory("CRCache") diff --git a/direct/src/distributed/CRDataCache.py b/direct/src/distributed/CRDataCache.py index afc86abaa1..85036544de 100755 --- a/direct/src/distributed/CRDataCache.py +++ b/direct/src/distributed/CRDataCache.py @@ -23,7 +23,7 @@ class CRDataCache: # cache is full, throw out a random doId's data if self._junkIndex >= len(self._doId2name2data): self._junkIndex = 0 - junkDoId = self._doId2name2data.keys()[self._junkIndex] + junkDoId = list(self._doId2name2data.keys())[self._junkIndex] self._junkIndex += 1 for name in self._doId2name2data[junkDoId]: self._doId2name2data[junkDoId][name].flush() @@ -96,7 +96,7 @@ if __debug__: assert 'testCachedData2' in data assert data['testCachedData'].foo == 34 assert data['testCachedData2'].bar == 45 - for cd in data.itervalues(): + for cd in data.values(): cd.flush() del data dc._checkMemLeaks() diff --git a/direct/src/distributed/ClientRepository.py b/direct/src/distributed/ClientRepository.py index a22c5b404c..b3745c1355 100644 --- a/direct/src/distributed/ClientRepository.py +++ b/direct/src/distributed/ClientRepository.py @@ -1,12 +1,12 @@ """ClientRepository module: contains the ClientRepository class""" -from ClientRepositoryBase import ClientRepositoryBase +from .ClientRepositoryBase import ClientRepositoryBase from direct.directnotify import DirectNotifyGlobal -from MsgTypesCMU import * -from PyDatagram import PyDatagram -from PyDatagramIterator import PyDatagramIterator +from .MsgTypesCMU import * +from .PyDatagram import PyDatagram +from .PyDatagramIterator import PyDatagramIterator from panda3d.core import UniqueIdAllocator -import types + class ClientRepository(ClientRepositoryBase): """ @@ -305,7 +305,7 @@ class ClientRepository(ClientRepositoryBase): def handleDatagram(self, di): if self.notify.getDebug(): - print "ClientRepository received datagram:" + print("ClientRepository received datagram:") di.getDatagram().dumpHex(ostream) msgType = self.getMsgType() diff --git a/direct/src/distributed/ClientRepositoryBase.py b/direct/src/distributed/ClientRepositoryBase.py index 9f60eaac98..9836f0fd0b 100644 --- a/direct/src/distributed/ClientRepositoryBase.py +++ b/direct/src/distributed/ClientRepositoryBase.py @@ -1,18 +1,16 @@ from pandac.PandaModules import * -from MsgTypes import * +from .MsgTypes import * from direct.task import Task from direct.directnotify import DirectNotifyGlobal -import CRCache +from . import CRCache from direct.distributed.CRDataCache import CRDataCache from direct.distributed.ConnectionRepository import ConnectionRepository from direct.showbase import PythonUtil -import ParentMgr -import RelatedObjectMgr +from . import ParentMgr +from . import RelatedObjectMgr import time -from ClockDelta import * -from PyDatagram import PyDatagram -from PyDatagramIterator import PyDatagramIterator -import types +from .ClockDelta import * + class ClientRepositoryBase(ConnectionRepository): """ @@ -190,7 +188,7 @@ class ClientRepositoryBase(ConnectionRepository): for dg, di in updates: # non-DC updates that need to be played back in-order are # stored as (msgType, (dg, di)) - if type(di) is types.TupleType: + if type(di) is tuple: msgType = dg dg, di = di self.replayDeferredGenerate(msgType, (dg, di)) @@ -264,7 +262,7 @@ class ClientRepositoryBase(ConnectionRepository): distObj.setLocation(parentId, zoneId) distObj.updateRequiredFields(dclass, di) # updateRequiredFields calls announceGenerate - print "New DO:%s, dclass:%s"%(doId, dclass.getName()) + print("New DO:%s, dclass:%s"%(doId, dclass.getName())) return distObj def generateWithRequiredOtherFields(self, dclass, doId, di, @@ -602,8 +600,8 @@ class ClientRepositoryBase(ConnectionRepository): del self._delayDeletedDOs[key] def printDelayDeletes(self): - print 'DelayDeletes:' - print '=============' - for obj in self._delayDeletedDOs.itervalues(): - print '%s\t%s (%s)\tdelayDeletes=%s' % ( - obj.doId, safeRepr(obj), itype(obj), obj.getDelayDeleteNames()) + print('DelayDeletes:') + print('=============') + for obj in self._delayDeletedDOs.values(): + print('%s\t%s (%s)\tdelayDeletes=%s' % ( + obj.doId, safeRepr(obj), itype(obj), obj.getDelayDeleteNames())) diff --git a/direct/src/distributed/ConnectionRepository.py b/direct/src/distributed/ConnectionRepository.py index 8af690357a..deda5ab5c6 100644 --- a/direct/src/distributed/ConnectionRepository.py +++ b/direct/src/distributed/ConnectionRepository.py @@ -4,15 +4,12 @@ from direct.directnotify.DirectNotifyGlobal import directNotify from direct.distributed.DoInterestManager import DoInterestManager from direct.distributed.DoCollectionManager import DoCollectionManager from direct.showbase import GarbageReport -from PyDatagram import PyDatagram -from PyDatagramIterator import PyDatagramIterator +from .PyDatagramIterator import PyDatagramIterator import types -import imp import gc - class ConnectionRepository( DoInterestManager, DoCollectionManager, CConnectionRepository): """ @@ -248,7 +245,7 @@ class ConnectionRepository( self.dclassesByNumber = {} self.hashVal = 0 - if isinstance(dcFileNames, types.StringTypes): + if isinstance(dcFileNames, str): # If we were given a single string, make it a list. dcFileNames = [dcFileNames] @@ -514,7 +511,7 @@ class ConnectionRepository( if failureCallback: failureCallback(0, '', *failureArgs) else: - print "uh oh, we aren't using one of the tri-state CM variables" + print("uh oh, we aren't using one of the tri-state CM variables") failureCallback(0, '', *failureArgs) def disconnect(self): diff --git a/direct/src/distributed/DistributedCamera.py b/direct/src/distributed/DistributedCamera.py index 7ea07d91bb..297a24bf98 100755 --- a/direct/src/distributed/DistributedCamera.py +++ b/direct/src/distributed/DistributedCamera.py @@ -148,8 +148,8 @@ class Fixture(NodePath, FSM): # if added to the dc definition of the Fixture struct and # saved out to the Camera file. lodNodes = render.findAllMatches('**/+LODNode') - for i in xrange(0,lodNodes.getNumPaths()): - lodNodes[i].node().forceSwitch(lodNodes[i].node().getHighestSwitch()) + for lodNode in lodNodes: + lodNode.node().forceSwitch(lodNode.node().getHighestSwitch()) def exitUsing(self): @@ -183,13 +183,13 @@ class DistributedCamera(DistributedObject): def __str__(self): out = '' - for fixture in self.fixtures.itervalues(): + for fixture in self.fixtures.values(): out = '%s\n%s' % (out, fixture) return out[1:] def pack(self): out = '' - for fixture in self.fixtures.itervalues(): + for fixture in self.fixtures.values(): out = '%s\n%s' % (out, fixture.pack()) return out[1:] @@ -198,7 +198,7 @@ class DistributedCamera(DistributedObject): self.parent = None - for fixture in self.fixtures.itervalues(): + for fixture in self.fixtures.values(): fixture.cleanup() fixture.detachNode() self.fixtures = {} @@ -215,7 +215,7 @@ class DistributedCamera(DistributedObject): else: self.parent = self.cr.getDo(doId) - for fix in self.fixtures.itervalues(): + for fix in self.fixtures.values(): fix.reparentTo(self.parent) def getCamParent(self): diff --git a/direct/src/distributed/DistributedCartesianGrid.py b/direct/src/distributed/DistributedCartesianGrid.py index 80d0bafc4e..8c156af9d1 100755 --- a/direct/src/distributed/DistributedCartesianGrid.py +++ b/direct/src/distributed/DistributedCartesianGrid.py @@ -15,7 +15,7 @@ if __debug__: from direct.directtools.DirectGeometry import * from direct.showbase.PythonUtil import randFloat -from CartesianGridBase import CartesianGridBase +from .CartesianGridBase import CartesianGridBase # increase this number if you want to visualize the grid lines # above water level diff --git a/direct/src/distributed/DistributedCartesianGridAI.py b/direct/src/distributed/DistributedCartesianGridAI.py index e9f3b53816..3b830b8028 100755 --- a/direct/src/distributed/DistributedCartesianGridAI.py +++ b/direct/src/distributed/DistributedCartesianGridAI.py @@ -2,8 +2,8 @@ from pandac.PandaModules import * from direct.directnotify.DirectNotifyGlobal import directNotify from direct.task import Task -from DistributedNodeAI import DistributedNodeAI -from CartesianGridBase import CartesianGridBase +from .DistributedNodeAI import DistributedNodeAI +from .CartesianGridBase import CartesianGridBase class DistributedCartesianGridAI(DistributedNodeAI, CartesianGridBase): notify = directNotify.newCategory("DistributedCartesianGridAI") diff --git a/direct/src/distributed/DistributedNode.py b/direct/src/distributed/DistributedNode.py index 590a58eeb4..1b0c3412dc 100644 --- a/direct/src/distributed/DistributedNode.py +++ b/direct/src/distributed/DistributedNode.py @@ -1,10 +1,9 @@ """DistributedNode module: contains the DistributedNode class""" from panda3d.core import NodePath -from direct.task import Task -import GridParent -import DistributedObject -import types +from . import GridParent +from . import DistributedObject + class DistributedNode(DistributedObject.DistributedObject, NodePath): """Distributed Node class:""" @@ -77,7 +76,7 @@ class DistributedNode(DistributedObject.DistributedObject, NodePath): ### setParent ### def b_setParent(self, parentToken): - if type(parentToken) == types.StringType: + if type(parentToken) == str: self.setParentStr(parentToken) else: self.setParent(parentToken) @@ -85,7 +84,7 @@ class DistributedNode(DistributedObject.DistributedObject, NodePath): self.d_setParent(parentToken) def d_setParent(self, parentToken): - if type(parentToken) == types.StringType: + if type(parentToken) == str: self.sendUpdate("setParentStr", [parentToken]) else: self.sendUpdate("setParent", [parentToken]) diff --git a/direct/src/distributed/DistributedNodeAI.py b/direct/src/distributed/DistributedNodeAI.py index e48fb3e70b..3d30e8d707 100644 --- a/direct/src/distributed/DistributedNodeAI.py +++ b/direct/src/distributed/DistributedNodeAI.py @@ -1,7 +1,7 @@ from pandac.PandaModules import NodePath -import DistributedObjectAI -import GridParent -import types +from . import DistributedObjectAI +from . import GridParent + class DistributedNodeAI(DistributedObjectAI.DistributedObjectAI, NodePath): def __init__(self, air, name=None): @@ -47,7 +47,7 @@ class DistributedNodeAI(DistributedObjectAI.DistributedObjectAI, NodePath): ### setParent ### def b_setParent(self, parentToken): - if type(parentToken) == types.StringType: + if type(parentToken) == str: self.setParentStr(parentToken) else: self.setParent(parentToken) diff --git a/direct/src/distributed/DistributedNodeUD.py b/direct/src/distributed/DistributedNodeUD.py index 1924a03420..21d6a2dbbb 100755 --- a/direct/src/distributed/DistributedNodeUD.py +++ b/direct/src/distributed/DistributedNodeUD.py @@ -1,5 +1,5 @@ #from otp.ai.AIBaseGlobal import * -from DistributedObjectUD import DistributedObjectUD +from .DistributedObjectUD import DistributedObjectUD class DistributedNodeUD(DistributedObjectUD): def __init__(self, air, name=None): @@ -13,7 +13,7 @@ class DistributedNodeUD(DistributedObjectUD): name = self.__class__.__name__ def b_setParent(self, parentToken): - if type(parentToken) == types.StringType: + if type(parentToken) == str: self.setParentStr(parentToken) else: self.setParent(parentToken) diff --git a/direct/src/distributed/DistributedObject.py b/direct/src/distributed/DistributedObject.py index cfd25fda23..0ed3e90a54 100644 --- a/direct/src/distributed/DistributedObject.py +++ b/direct/src/distributed/DistributedObject.py @@ -1,6 +1,7 @@ """DistributedObject module: contains the DistributedObject class""" -from pandac.PandaModules import * +from panda3d.core import * +from panda3d.direct import * from direct.directnotify.DirectNotifyGlobal import directNotify from direct.distributed.DistributedObjectBase import DistributedObjectBase from direct.showbase.PythonUtil import StackTrace @@ -80,14 +81,11 @@ class DistributedObject(DistributedObjectBase): and conditionally show generated, disabled, neverDisable, or cachable" """ - spaces=' '*(indent+2) + spaces = ' ' * (indent + 2) try: - print "%s%s:"%( - ' '*indent, self.__class__.__name__) - print "%sfrom DistributedObject doId:%s, parent:%s, zone:%s"%( - spaces, - self.doId, self.parentId, self.zoneId), - flags=[] + print("%s%s:" % (' ' * indent, self.__class__.__name__)) + + flags = [] if self.activeState == ESGenerated: flags.append("generated") if self.activeState < ESGenerating: @@ -96,10 +94,15 @@ class DistributedObject(DistributedObjectBase): flags.append("neverDisable") if self.cacheable: flags.append("cacheable") + + flagStr = "" if len(flags): - print "(%s)"%(" ".join(flags),), - print - except Exception, e: print "%serror printing status"%(spaces,), e + flagStr = " (%s)" % (" ".join(flags)) + + print("%sfrom DistributedObject doId:%s, parent:%s, zone:%s%s" % ( + spaces, self.doId, self.parentId, self.zoneId, flagStr)) + except Exception as e: + print("%serror printing status %s" % (spaces, e)) def getAutoInterests(self): # returns the sub-zones under this object that are automatically @@ -123,7 +126,7 @@ class DistributedObject(DistributedObjectBase): p = DCPacker() p.setUnpackData(field.getDefaultValue()) len = p.rawUnpackUint16()/4 - for i in xrange(len): + for i in range(len): zone = int(p.rawUnpackUint32()) autoInterests.add(zone) autoInterests.update(autoInterests) @@ -247,7 +250,7 @@ class DistributedObject(DistributedObjectBase): # we are going to crash, output the destroyDo stacktrace self.notify.warning('self.cr is none in _deactivateDO %d' % self.doId) if hasattr(self, 'destroyDoStackTrace'): - print self.destroyDoStackTrace + print(self.destroyDoStackTrace) self.__callbacks = {} self.cr.closeAutoInterests(self) self.setLocation(0,0) @@ -260,7 +263,7 @@ class DistributedObject(DistributedObjectBase): # check for leftover cached data that was not retrieved or flushed by this object # this will catch typos in the data name in calls to get/setCachedData if hasattr(self, '_cachedData'): - for name, cachedData in self._cachedData.iteritems(): + for name, cachedData in self._cachedData.items(): self.notify.warning('flushing unretrieved cached data: %s' % name) cachedData.flush() del self._cachedData @@ -398,7 +401,7 @@ class DistributedObject(DistributedObjectBase): def getCurrentContexts(self): # Returns a list of the currently outstanding contexts created # by getCallbackContext(). - return self.__callbacks.keys() + return list(self.__callbacks.keys()) def getCallback(self, context): # Returns the callback that was passed in to the previous diff --git a/direct/src/distributed/DistributedObjectAI.py b/direct/src/distributed/DistributedObjectAI.py index 18985e42e1..efe5cd02bf 100644 --- a/direct/src/distributed/DistributedObjectAI.py +++ b/direct/src/distributed/DistributedObjectAI.py @@ -3,7 +3,8 @@ from direct.directnotify.DirectNotifyGlobal import directNotify from direct.distributed.DistributedObjectBase import DistributedObjectBase from direct.showbase import PythonUtil -from pandac.PandaModules import * +from panda3d.core import * +from panda3d.direct import * #from PyDatagram import PyDatagram #from PyDatagramIterator import PyDatagramIterator @@ -56,25 +57,26 @@ class DistributedObjectAI(DistributedObjectBase): def status(self, indent=0): """ print out doId(parentId, zoneId) className - and conditionally show generated, disabled, neverDisable, - or cachable + and conditionally show generated or deleted """ - spaces=' '*(indent+2) + spaces = ' ' * (indent + 2) try: - print "%s%s:"%( - ' '*indent, self.__class__.__name__) - print "%sfrom DistributedObject doId:%s, parent:%s, zone:%s"%( - spaces, - self.doId, self.parentId, self.zoneId), - flags=[] + print("%s%s:" % (' ' * indent, self.__class__.__name__)) + + flags = [] if self.__generated: flags.append("generated") if self.air == None: flags.append("deleted") + + flagStr = "" if len(flags): - print "(%s)"%(" ".join(flags),), - print - except Exception, e: print "%serror printing status"%(spaces,), e + flagStr = " (%s)" % (" ".join(flags)) + + print("%sfrom DistributedObject doId:%s, parent:%s, zone:%s%s" % ( + spaces, self.doId, self.parentId, self.zoneId, flagStr)) + except Exception as e: + print("%serror printing status %s" % (spaces, e)) def getDeleteEvent(self): # this is sent just before we get deleted @@ -347,16 +349,16 @@ class DistributedObjectAI(DistributedObjectBase): self.air.sendUpdate(self, fieldName, args) def GetPuppetConnectionChannel(self, doId): - return doId + (1L << 32) + return doId + (1 << 32) def GetAccountConnectionChannel(self, doId): - return doId + (3L << 32) + return doId + (3 << 32) def GetAccountIDFromChannelCode(self, channel): return channel >> 32 def GetAvatarIDFromChannelCode(self, channel): - return channel & 0xffffffffL + return channel & 0xffffffff def sendUpdateToAvatarId(self, avId, fieldName, args): assert self.notify.debugStateCall(self) diff --git a/direct/src/distributed/DistributedObjectBase.py b/direct/src/distributed/DistributedObjectBase.py index 70a7c567ca..e105e4c891 100755 --- a/direct/src/distributed/DistributedObjectBase.py +++ b/direct/src/distributed/DistributedObjectBase.py @@ -22,14 +22,13 @@ class DistributedObjectBase(DirectObject): """ print out "doId(parentId, zoneId) className" """ - spaces=' '*(indent+2) + spaces = ' ' * (indent + 2) try: - print "%s%s:"%( - ' '*indent, self.__class__.__name__) - print "%sfrom DistributedObject doId:%s, parent:%s, zone:%s"%( - spaces, - self.doId, self.parentId, self.zoneId), - except Exception, e: print "%serror printing status"%(spaces,), e + print("%s%s:" % (' ' * indent, self.__class__.__name__)) + print("%sfrom DistributedObject doId:%s, parent:%s, zone:%s" % ( + spaces, self.doId, self.parentId, self.zoneId)) + except Exception as e: + print("%serror printing status %s" % (spaces, e)) def getLocation(self): try: diff --git a/direct/src/distributed/DistributedObjectGlobalAI.py b/direct/src/distributed/DistributedObjectGlobalAI.py index 10b80be712..28ce8d2c7d 100755 --- a/direct/src/distributed/DistributedObjectGlobalAI.py +++ b/direct/src/distributed/DistributedObjectGlobalAI.py @@ -1,5 +1,5 @@ -from DistributedObjectAI import DistributedObjectAI +from .DistributedObjectAI import DistributedObjectAI from direct.directnotify.DirectNotifyGlobal import directNotify diff --git a/direct/src/distributed/DistributedObjectGlobalUD.py b/direct/src/distributed/DistributedObjectGlobalUD.py index 191c60c685..ce51d8421c 100755 --- a/direct/src/distributed/DistributedObjectGlobalUD.py +++ b/direct/src/distributed/DistributedObjectGlobalUD.py @@ -1,6 +1,6 @@ -from DistributedObjectUD import DistributedObjectUD +from .DistributedObjectUD import DistributedObjectUD from direct.directnotify.DirectNotifyGlobal import directNotify import sys diff --git a/direct/src/distributed/DistributedObjectOV.py b/direct/src/distributed/DistributedObjectOV.py index ef3c12dd62..52ed2d13be 100755 --- a/direct/src/distributed/DistributedObjectOV.py +++ b/direct/src/distributed/DistributedObjectOV.py @@ -40,22 +40,24 @@ class DistributedObjectOV(DistributedObjectBase): print out "doId(parentId, zoneId) className" and conditionally show generated, disabled """ - spaces=' '*(indent+2) + spaces = ' ' * (indent + 2) try: - print "%s%s:"%( - ' '*indent, self.__class__.__name__) - print "%sfrom DistributedObjectOV doId:%s, parent:%s, zone:%s"%( - spaces, - self.doId, self.parentId, self.zoneId), - flags=[] + print("%s%s:" % (' ' * indent, self.__class__.__name__)) + + flags = [] if self.activeState == ESGenerated: flags.append("generated") if self.activeState < ESGenerating: flags.append("disabled") + + flagStr = "" if len(flags): - print "(%s)"%(" ".join(flags),), - print - except Exception, e: print "%serror printing status"%(spaces,), e + flagStr = " (%s)" % (" ".join(flags)) + + print("%sfrom DistributedObjectOV doId:%s, parent:%s, zone:%s%s" % ( + spaces, self.doId, self.parentId, self.zoneId, flagStr)) + except Exception as e: + print("%serror printing status %s" % (spaces, e)) def getDelayDeleteCount(self): diff --git a/direct/src/distributed/DistributedObjectUD.py b/direct/src/distributed/DistributedObjectUD.py index 7642cd222b..4309ad7d80 100755 --- a/direct/src/distributed/DistributedObjectUD.py +++ b/direct/src/distributed/DistributedObjectUD.py @@ -54,24 +54,26 @@ class DistributedObjectUD(DistributedObjectBase): def status(self, indent=0): """ print out doId(parentId, zoneId) className - and conditionally show generated, disabled, neverDisable, - or cachable + and conditionally show generated or deleted """ spaces = ' ' * (indent + 2) try: - print "%s%s:" % (' ' * indent, self.__class__.__name__) - print ("%sfrom " - "DistributedObject doId:%s, parent:%s, zone:%s" % - (spaces, self.doId, self.parentId, self.zoneId)), + print("%s%s:" % (' ' * indent, self.__class__.__name__)) + flags = [] if self.__generated: flags.append("generated") if self.air == None: flags.append("deleted") + + flagStr = "" if len(flags): - print "(%s)" % (" ".join(flags),), - print - except Exception, e: print "%serror printing status" % (spaces,), e + flagStr = " (%s)" % (" ".join(flags)) + + print("%sfrom DistributedObject doId:%s, parent:%s, zone:%s%s" % ( + spaces, self.doId, self.parentId, self.zoneId, flagStr)) + except Exception as e: + print("%serror printing status %s" % (spaces, e)) def getDeleteEvent(self): # this is sent just before we get deleted @@ -267,16 +269,16 @@ class DistributedObjectUD(DistributedObjectBase): self.air.sendUpdate(self, fieldName, args) def GetPuppetConnectionChannel(self, doId): - return doId + (1L << 32) + return doId + (1 << 32) def GetAccountConnectionChannel(self, doId): - return doId + (3L << 32) + return doId + (3 << 32) def GetAccountIDFromChannelCode(self, channel): return channel >> 32 def GetAvatarIDFromChannelCode(self, channel): - return channel & 0xffffffffL + return channel & 0xffffffff def sendUpdateToAvatarId(self, avId, fieldName, args): assert self.notify.debugStateCall(self) diff --git a/direct/src/distributed/DistributedSmoothNode.py b/direct/src/distributed/DistributedSmoothNode.py index 34ad0ae52b..cdc2dc034e 100644 --- a/direct/src/distributed/DistributedSmoothNode.py +++ b/direct/src/distributed/DistributedSmoothNode.py @@ -1,9 +1,9 @@ """DistributedSmoothNode module: contains the DistributedSmoothNode class""" from pandac.PandaModules import * -from ClockDelta import * -import DistributedNode -import DistributedSmoothNodeBase +from .ClockDelta import * +from . import DistributedNode +from . import DistributedSmoothNodeBase from direct.task.Task import cont # This number defines our tolerance for out-of-sync telemetry packets. diff --git a/direct/src/distributed/DistributedSmoothNodeAI.py b/direct/src/distributed/DistributedSmoothNodeAI.py index 968a7ccfa4..fe8ec19b1c 100755 --- a/direct/src/distributed/DistributedSmoothNodeAI.py +++ b/direct/src/distributed/DistributedSmoothNodeAI.py @@ -1,5 +1,5 @@ -import DistributedNodeAI -import DistributedSmoothNodeBase +from . import DistributedNodeAI +from . import DistributedSmoothNodeBase class DistributedSmoothNodeAI(DistributedNodeAI.DistributedNodeAI, DistributedSmoothNodeBase.DistributedSmoothNodeBase): diff --git a/direct/src/distributed/DistributedSmoothNodeBase.py b/direct/src/distributed/DistributedSmoothNodeBase.py index faeda49115..8f7d1c31e4 100755 --- a/direct/src/distributed/DistributedSmoothNodeBase.py +++ b/direct/src/distributed/DistributedSmoothNodeBase.py @@ -1,6 +1,6 @@ """DistributedSmoothNodeBase module: contains the DistributedSmoothNodeBase class""" -from ClockDelta import * +from .ClockDelta import * from direct.task import Task from direct.showbase.PythonUtil import randFloat, Enum from panda3d.direct import CDistributedSmoothNodeBase diff --git a/direct/src/distributed/DoCollectionManager.py b/direct/src/distributed/DoCollectionManager.py index 691e84f75a..16bf345f4e 100755 --- a/direct/src/distributed/DoCollectionManager.py +++ b/direct/src/distributed/DoCollectionManager.py @@ -117,29 +117,29 @@ class DoCollectionManager: return 1 def dosByDistance(self): - objs = self.doId2do.values() + objs = list(self.doId2do.values()) objs.sort(cmp=self._compareDistance) return objs def doByDistance(self): objs = self.dosByDistance() for obj in objs: - print '%s\t%s\t%s' % (obj.doId, self._getDistanceFromLA(obj), - obj.dclass.getName()) + print('%s\t%s\t%s' % (obj.doId, self._getDistanceFromLA(obj), + obj.dclass.getName())) if __debug__: def printObjects(self): format="%10s %10s %10s %30s %20s" title=format%("parentId", "zoneId", "doId", "dclass", "name") - print title - print '-'*len(title) + print(title) + print('-'*len(title)) for distObj in self.doId2do.values(): - print format%( + print(format%( distObj.__dict__.get("parentId"), distObj.__dict__.get("zoneId"), distObj.__dict__.get("doId"), distObj.dclass.getName(), - distObj.__dict__.get("name")) + distObj.__dict__.get("name"))) def _printObjects(self, table): class2count = {} @@ -148,14 +148,14 @@ class DoCollectionManager: class2count.setdefault(className, 0) class2count[className] += 1 count2classes = invertDictLossless(class2count) - counts = count2classes.keys() + counts = list(count2classes.keys()) counts.sort() counts.reverse() for count in counts: count2classes[count].sort() for name in count2classes[count]: - print '%s %s' % (count, name) - print '' + print('%s %s' % (count, name)) + print('') def _returnObjects(self, table): class2count = {} @@ -165,7 +165,7 @@ class DoCollectionManager: class2count.setdefault(className, 0) class2count[className] += 1 count2classes = invertDictLossless(class2count) - counts = count2classes.keys() + counts = list(count2classes.keys()) counts.sort() counts.reverse() for count in counts: @@ -189,12 +189,12 @@ class DoCollectionManager: def printObjectCount(self): # print object counts by distributed object type - print '==== OBJECT COUNT ====' + print('==== OBJECT COUNT ====') if self.hasOwnerView(): - print '== doId2do' + print('== doId2do') self._printObjects(self.getDoTable(ownerView=False)) if self.hasOwnerView(): - print '== doId2ownerView' + print('== doId2ownerView') self._printObjects(self.getDoTable(ownerView=True)) def getDoList(self, parentId, zoneId=None, classType=None): diff --git a/direct/src/distributed/DoInterestManager.py b/direct/src/distributed/DoInterestManager.py index ed72de562c..a81000a788 100755 --- a/direct/src/distributed/DoInterestManager.py +++ b/direct/src/distributed/DoInterestManager.py @@ -8,10 +8,10 @@ p.s. A great deal of this code is just code moved from ClientRepository.py. """ from pandac.PandaModules import * -from MsgTypes import * +from .MsgTypes import * from direct.showbase.PythonUtil import * from direct.showbase import DirectObject -from PyDatagram import PyDatagram +from .PyDatagram import PyDatagram from direct.directnotify.DirectNotifyGlobal import directNotify import types from direct.showbase.PythonUtil import report @@ -184,8 +184,8 @@ class DoInterestManager(DirectObject.DirectObject): DoInterestManager._interests[handle] = InterestState( description, InterestState.StateActive, contextId, event, parentId, zoneIdList, self._completeEventCount) if self.__verbose(): - print 'CR::INTEREST.addInterest(handle=%s, parentId=%s, zoneIdList=%s, description=%s, event=%s)' % ( - handle, parentId, zoneIdList, description, event) + print('CR::INTEREST.addInterest(handle=%s, parentId=%s, zoneIdList=%s, description=%s, event=%s)' % ( + handle, parentId, zoneIdList, description, event)) self._sendAddInterest(handle, contextId, parentId, zoneIdList, description) if event: messenger.send(self._getAddInterestEvent(), [event]) @@ -218,8 +218,8 @@ class DoInterestManager(DirectObject.DirectObject): DoInterestManager._interests[handle] = InterestState( description, InterestState.StateActive, 0, None, parentId, zoneIdList, self._completeEventCount, True) if self.__verbose(): - print 'CR::INTEREST.addInterest(handle=%s, parentId=%s, zoneIdList=%s, description=%s)' % ( - handle, parentId, zoneIdList, description) + print('CR::INTEREST.addInterest(handle=%s, parentId=%s, zoneIdList=%s, description=%s)' % ( + handle, parentId, zoneIdList, description)) assert self.printInterestsIfDebug() return InterestHandle(handle) @@ -266,8 +266,8 @@ class DoInterestManager(DirectObject.DirectObject): if not event: self._considerRemoveInterest(handle) if self.__verbose(): - print 'CR::INTEREST.removeInterest(handle=%s, event=%s)' % ( - handle, event) + print('CR::INTEREST.removeInterest(handle=%s, event=%s)' % ( + handle, event)) else: DoInterestManager.notify.warning( "removeInterest: handle not found: %s" % (handle)) @@ -302,7 +302,7 @@ class DoInterestManager(DirectObject.DirectObject): intState.state = InterestState.StatePendingDel self._considerRemoveInterest(handle) if self.__verbose(): - print 'CR::INTEREST.removeAutoInterest(handle=%s)' % (handle) + print('CR::INTEREST.removeAutoInterest(handle=%s)' % (handle)) else: DoInterestManager.notify.warning( "removeInterest: handle not found: %s" % (handle)) @@ -357,8 +357,8 @@ class DoInterestManager(DirectObject.DirectObject): DoInterestManager._interests[handle].addEvent(event) if self.__verbose(): - print 'CR::INTEREST.alterInterest(handle=%s, parentId=%s, zoneIdList=%s, description=%s, event=%s)' % ( - handle, parentId, zoneIdList, description, event) + print('CR::INTEREST.alterInterest(handle=%s, parentId=%s, zoneIdList=%s, description=%s, event=%s)' % ( + handle, parentId, zoneIdList, description, event)) self._sendAddInterest(handle, contextId, parentId, zoneIdList, description, action='modify') exists = True assert self.printInterestsIfDebug() @@ -445,24 +445,24 @@ class DoInterestManager(DirectObject.DirectObject): DoInterestManager._debug_maxDescriptionLen, len(description)) def printInterestHistory(self): - print "***************** Interest History *************" + print("***************** Interest History *************") format = '%9s %' + str(DoInterestManager._debug_maxDescriptionLen) + 's %6s %6s %9s %s' - print format % ( + print(format % ( "Action", "Description", "Handle", "Context", "ParentId", - "ZoneIdList") + "ZoneIdList")) for i in DoInterestManager._debug_interestHistory: - print format % tuple(i) - print "Note: interests with a Context of 0 do not get" \ - " done/finished notices." + print(format % tuple(i)) + print("Note: interests with a Context of 0 do not get" \ + " done/finished notices.") def printInterestSets(self): - print "******************* Interest Sets **************" + print("******************* Interest Sets **************") format = '%6s %' + str(DoInterestManager._debug_maxDescriptionLen) + 's %11s %11s %8s %8s %8s' - print format % ( + print(format % ( "Handle", "Description", "ParentId", "ZoneIdList", "State", "Context", - "Event") + "Event")) for id, state in DoInterestManager._interests.items(): if len(state.events) == 0: event = '' @@ -470,11 +470,11 @@ class DoInterestManager(DirectObject.DirectObject): event = state.events[0] else: event = state.events - print format % (id, state.desc, + print(format % (id, state.desc, state.parentId, state.zoneIdList, state.state, state.context, - event) - print "************************************************" + event)) + print("************************************************") def printInterests(self): self.printInterestHistory() @@ -492,7 +492,7 @@ class DoInterestManager(DirectObject.DirectObject): """ assert DoInterestManager.notify.debugCall() if __debug__: - if isinstance(zoneIdList, types.ListType): + if isinstance(zoneIdList, list): zoneIdList.sort() if action is None: action = 'add' @@ -507,7 +507,7 @@ class DoInterestManager(DirectObject.DirectObject): datagram.addUint16(handle) datagram.addUint32(contextId) datagram.addUint32(parentId) - if isinstance(zoneIdList, types.ListType): + if isinstance(zoneIdList, list): vzl = list(zoneIdList) vzl.sort() uniqueElements(vzl) @@ -585,7 +585,7 @@ class DoInterestManager(DirectObject.DirectObject): handle = di.getUint16() contextId = di.getUint32() if self.__verbose(): - print 'CR::INTEREST.interestDone(handle=%s)' % handle + print('CR::INTEREST.interestDone(handle=%s)' % handle) DoInterestManager.notify.debug( "handleInterestDoneMessage--> Received handle %s, context %s" % ( handle, contextId)) diff --git a/direct/src/distributed/GridChild.py b/direct/src/distributed/GridChild.py index 78b35f8c67..462c4d841e 100755 --- a/direct/src/distributed/GridChild.py +++ b/direct/src/distributed/GridChild.py @@ -106,7 +106,7 @@ class GridChild: self._gridInterests[gridDoId] = [None,zoneId] def getGridInterestIds(self): - return self._gridInterests.keys() + return list(self._gridInterests.keys()) def getGridInterestZoneId(self,gridDoId): return self._gridInterests.get(gridDoId,[None,None])[1] diff --git a/direct/src/distributed/NetMessenger.py b/direct/src/distributed/NetMessenger.py index 0d24e2a1ff..03c666d2ea 100755 --- a/direct/src/distributed/NetMessenger.py +++ b/direct/src/distributed/NetMessenger.py @@ -1,10 +1,14 @@ -from cPickle import dumps, loads - from direct.directnotify import DirectNotifyGlobal from direct.distributed.PyDatagram import PyDatagram from direct.showbase.Messenger import Messenger +import sys +if sys.version_info >= (3, 0): + from pickle import dumps, loads +else: + from cPickle import dumps, loads + # Messages do not need to be in the MESSAGE_TYPES list. # This is just an optimization. If the message is found diff --git a/direct/src/distributed/OldClientRepository.py b/direct/src/distributed/OldClientRepository.py index 2e996cc5df..daeb4af628 100644 --- a/direct/src/distributed/OldClientRepository.py +++ b/direct/src/distributed/OldClientRepository.py @@ -1,6 +1,6 @@ """OldClientRepository module: contains the OldClientRepository class""" -from ClientRepositoryBase import * +from .ClientRepositoryBase import * class OldClientRepository(ClientRepositoryBase): """ @@ -126,7 +126,7 @@ class OldClientRepository(ClientRepositoryBase): def handleDatagram(self, di): if self.notify.getDebug(): - print "ClientRepository received datagram:" + print("ClientRepository received datagram:") di.getDatagram().dumpHex(ostream) msgType = self.getMsgType() diff --git a/direct/src/distributed/ParentMgr.py b/direct/src/distributed/ParentMgr.py index 434c3cbd64..6e52b1097b 100644 --- a/direct/src/distributed/ParentMgr.py +++ b/direct/src/distributed/ParentMgr.py @@ -2,7 +2,7 @@ from direct.directnotify import DirectNotifyGlobal from direct.showbase.PythonUtil import isDefaultValue -import types + class ParentMgr: # This is now used on the AI as well. @@ -90,7 +90,7 @@ class ParentMgr: if isDefaultValue(token): self.notify.error('parent token (for %s) cannot be a default value (%s)' % (repr(parent), token)) - if type(token) is types.IntType: + if type(token) is int: if token > 0xFFFFFFFF: self.notify.error('parent token %s (for %s) is out of uint32 range' % (token, repr(parent))) diff --git a/direct/src/distributed/ServerRepository.py b/direct/src/distributed/ServerRepository.py index 7dcd5add72..11cec06ac3 100644 --- a/direct/src/distributed/ServerRepository.py +++ b/direct/src/distributed/ServerRepository.py @@ -5,9 +5,7 @@ from direct.distributed.MsgTypesCMU import * from direct.task import Task from direct.directnotify import DirectNotifyGlobal from direct.distributed.PyDatagram import PyDatagram -from direct.distributed.PyDatagramIterator import PyDatagramIterator -import time -import types + class ServerRepository: @@ -153,7 +151,7 @@ class ServerRepository: for client in flush: client.connection.flush() - return task.again + return Task.again def setTcpHeaderSize(self, headerSize): """Sets the header size of TCP packets. At the present, legal @@ -299,7 +297,7 @@ class ServerRepository: retVal = self.qcl.getNewConnection(rendezvous, netAddress, newConnection) if not retVal: - return task.cont + return Task.cont # Crazy dereferencing newConnection = newConnection.p() @@ -321,13 +319,13 @@ class ServerRepository: self.lastConnection = newConnection self.sendDoIdRange(client) - return task.cont + return Task.cont def readerPollUntilEmpty(self, task): """ continuously polls for new messages on the server """ while self.readerPollOnce(): pass - return task.cont + return Task.cont def readerPollOnce(self): """ checks for available messages to the server """ @@ -691,7 +689,7 @@ class ServerRepository: for client in self.clientsByConnection.values(): if not self.qcr.isConnectionOk(client.connection): self.handleClientDisconnect(client) - return task.cont + return Task.cont def sendToZoneExcept(self, zoneId, datagram, exceptionList): """sends a message to everyone who has interest in the diff --git a/direct/src/distributed/TimeManagerAI.py b/direct/src/distributed/TimeManagerAI.py index a9aed1222e..c912394326 100644 --- a/direct/src/distributed/TimeManagerAI.py +++ b/direct/src/distributed/TimeManagerAI.py @@ -18,6 +18,6 @@ class TimeManagerAI(DistributedObjectAI.DistributedObjectAI): """ timestamp = globalClockDelta.getRealNetworkTime(bits=32) requesterId = self.air.getAvatarIdFromSender() - print "requestServerTime from %s" % (requesterId) + print("requestServerTime from %s" % (requesterId)) self.sendUpdateToAvatarId(requesterId, "serverTime", [context, timestamp]) diff --git a/direct/src/doc/howto.adjust b/direct/src/doc/howto.adjust index 5862e708a2..cf6925ad2f 100644 --- a/direct/src/doc/howto.adjust +++ b/direct/src/doc/howto.adjust @@ -52,7 +52,10 @@ of the slider to change settings. Click on: You can pack multiple sliders into a single panel: -from Tkinter import * +if sys.version_info >= (3, 0): + from tkinter import * +else: + from Tkinter import * def func1(x): print '1:', x diff --git a/direct/src/extensions_native/CInterval_extensions.py b/direct/src/extensions_native/CInterval_extensions.py index eb82fc50f3..9ed7ff48a0 100644 --- a/direct/src/extensions_native/CInterval_extensions.py +++ b/direct/src/extensions_native/CInterval_extensions.py @@ -63,14 +63,17 @@ def popupControls(self, tl = None): import math # Don't use a regular import, to prevent ModuleFinder from picking # it up as a dependency when building a .p3d package. - import importlib + import importlib, sys EntryScale = importlib.import_module('direct.tkwidgets.EntryScale') - Tkinter = importlib.import_module('Tkinter') + if sys.version_info >= (3, 0): + tkinter = importlib.import_module('tkinter') + else: + tkinter = importlib.import_module('Tkinter') if tl == None: - tl = Tkinter.Toplevel() + tl = tkinter.Toplevel() tl.title('Interval Controls') - outerFrame = Tkinter.Frame(tl) + outerFrame = tkinter.Frame(tl) def entryScaleCommand(t, s=self): s.setT(t) s.pause() @@ -79,8 +82,8 @@ def popupControls(self, tl = None): min = 0, max = math.floor(self.getDuration() * 100) / 100, command = entryScaleCommand) es.set(self.getT(), fCommand = 0) - es.pack(expand = 1, fill = Tkinter.X) - bf = Tkinter.Frame(outerFrame) + es.pack(expand = 1, fill = tkinter.X) + bf = tkinter.Frame(outerFrame) # Jump to start and end def toStart(s=self, es=es): s.setT(0.0) @@ -88,23 +91,23 @@ def popupControls(self, tl = None): def toEnd(s=self): s.setT(s.getDuration()) s.pause() - jumpToStart = Tkinter.Button(bf, text = '<<', command = toStart) + jumpToStart = tkinter.Button(bf, text = '<<', command = toStart) # Stop/play buttons def doPlay(s=self, es=es): s.resume(es.get()) - stop = Tkinter.Button(bf, text = 'Stop', + stop = tkinter.Button(bf, text = 'Stop', command = lambda s=self: s.pause()) - play = Tkinter.Button( + play = tkinter.Button( bf, text = 'Play', command = doPlay) - jumpToEnd = Tkinter.Button(bf, text = '>>', command = toEnd) - jumpToStart.pack(side = Tkinter.LEFT, expand = 1, fill = Tkinter.X) - play.pack(side = Tkinter.LEFT, expand = 1, fill = Tkinter.X) - stop.pack(side = Tkinter.LEFT, expand = 1, fill = Tkinter.X) - jumpToEnd.pack(side = Tkinter.LEFT, expand = 1, fill = Tkinter.X) - bf.pack(expand = 1, fill = Tkinter.X) - outerFrame.pack(expand = 1, fill = Tkinter.X) + jumpToEnd = tkinter.Button(bf, text = '>>', command = toEnd) + jumpToStart.pack(side = tkinter.LEFT, expand = 1, fill = tkinter.X) + play.pack(side = tkinter.LEFT, expand = 1, fill = tkinter.X) + stop.pack(side = tkinter.LEFT, expand = 1, fill = tkinter.X) + jumpToEnd.pack(side = tkinter.LEFT, expand = 1, fill = tkinter.X) + bf.pack(expand = 1, fill = tkinter.X) + outerFrame.pack(expand = 1, fill = tkinter.X) # Add function to update slider during setT calls def update(t, es=es): es.set(t, fCommand = 0) diff --git a/direct/src/extensions_native/NodePath_extensions.py b/direct/src/extensions_native/NodePath_extensions.py index 7383ae1e06..4c388becf7 100644 --- a/direct/src/extensions_native/NodePath_extensions.py +++ b/direct/src/extensions_native/NodePath_extensions.py @@ -690,7 +690,7 @@ def subdivideCollisions(self, numSolidsInLeaves): # this CollisionNode doesn't need to be split continue solids = [] - for i in xrange(numSolids): + for i in range(numSolids): solids.append(node.getSolid(i)) # recursively subdivide the solids into a spatial binary tree solidTree = self.r_subdivideCollisions(solids, numSolidsInLeaves) @@ -743,7 +743,7 @@ def r_subdivideCollisions(self, solids, numSolidsInLeaves): midY += maxExtent if extentZ < (maxExtent * .75) or extentZ > (maxExtent * 1.25): midZ += maxExtent - for i in xrange(len(solids)): + for i in range(len(solids)): origin = origins[i] x = origin.getX(); y = origin.getY(); z = origin.getZ() if x < midX: diff --git a/direct/src/extensions_native/extension_native_helpers.py b/direct/src/extensions_native/extension_native_helpers.py index d248f1f193..e9648e7440 100644 --- a/direct/src/extensions_native/extension_native_helpers.py +++ b/direct/src/extensions_native/extension_native_helpers.py @@ -1,7 +1,6 @@ -### Tools __all__ = ["Dtool_ObjectToDict", "Dtool_funcToMethod"] -import imp, sys, os +import sys def Dtool_ObjectToDict(cls, name, obj): cls.DtoolClassDict[name] = obj diff --git a/direct/src/filter/CommonFilters.py b/direct/src/filter/CommonFilters.py index c861561066..9cfe72d987 100644 --- a/direct/src/filter/CommonFilters.py +++ b/direct/src/filter/CommonFilters.py @@ -15,7 +15,7 @@ clunky approach. - Josh """ -from FilterManager import FilterManager +from .FilterManager import FilterManager from panda3d.core import LVecBase4, LPoint2 from panda3d.core import Filename from panda3d.core import AuxBitplaneAttrib diff --git a/direct/src/fsm/ClassicFSM.py b/direct/src/fsm/ClassicFSM.py index a0d6045c5f..847cf290db 100644 --- a/direct/src/fsm/ClassicFSM.py +++ b/direct/src/fsm/ClassicFSM.py @@ -10,18 +10,15 @@ existing code. New code should use the FSM module instead. from direct.directnotify.DirectNotifyGlobal import directNotify from direct.showbase.DirectObject import DirectObject -import types import weakref if __debug__: - _debugFsms={} + _debugFsms = {} def printDebugFsmList(): global _debugFsms - keys=_debugFsms.keys() - keys.sort() - for k in keys: - print k, _debugFsms[k]() - __builtins__['debugFsmList']=printDebugFsmList + for k in sorted(_debugFsms.keys()): + print("%s %s" % (k, _debugFsms[k]())) + __builtins__['debugFsmList'] = printDebugFsmList class ClassicFSM(DirectObject): """ @@ -123,7 +120,7 @@ class ClassicFSM(DirectObject): self.__name = name def getStates(self): - return self.__states.values() + return list(self.__states.values()) def setStates(self, states): """setStates(self, State[])""" @@ -251,7 +248,7 @@ class ClassicFSM(DirectObject): (self.__name)) self.__currentState = self.__initialState - if isinstance(aStateName, types.StringType): + if isinstance(aStateName, str): aState = self.getStateNamed(aStateName) else: # Allow the caller to pass in a state in itself, not just @@ -342,7 +339,7 @@ class ClassicFSM(DirectObject): (self.__name)) self.__currentState = self.__initialState - if isinstance(aStateName, types.StringType): + if isinstance(aStateName, str): aState = self.getStateNamed(aStateName) else: # Allow the caller to pass in a state in itself, not just diff --git a/direct/src/fsm/FSM.py b/direct/src/fsm/FSM.py index 2f9967783e..a62bede3f0 100644 --- a/direct/src/fsm/FSM.py +++ b/direct/src/fsm/FSM.py @@ -9,7 +9,7 @@ from direct.showbase.DirectObject import DirectObject from direct.directnotify import DirectNotifyGlobal from direct.showbase import PythonUtil from direct.stdpy.threading import RLock -import types + class FSMException(Exception): pass @@ -238,7 +238,7 @@ class FSM(DirectObject): self.fsmLock.acquire() try: - assert isinstance(request, types.StringTypes) + assert isinstance(request, str) self.notify.debug("%s.forceTransition(%s, %s" % ( self.name, request, str(args)[1:])) @@ -266,7 +266,7 @@ class FSM(DirectObject): self.fsmLock.acquire() try: - assert isinstance(request, types.StringTypes) + assert isinstance(request, str) self.notify.debug("%s.demand(%s, %s" % ( self.name, request, str(args)[1:])) if not self.state: @@ -305,14 +305,14 @@ class FSM(DirectObject): self.fsmLock.acquire() try: - assert isinstance(request, types.StringTypes) + assert isinstance(request, str) self.notify.debug("%s.request(%s, %s" % ( self.name, request, str(args)[1:])) filter = self.getCurrentFilter() result = list(filter(request, args)) if result: - if isinstance(result, types.StringTypes): + if isinstance(result, str): # If the return value is a string, it's just the name # of the state. Wrap it in a tuple for consistency. result = (result,) + args diff --git a/direct/src/fsm/FourState.py b/direct/src/fsm/FourState.py index 790439e901..df653825f9 100755 --- a/direct/src/fsm/FourState.py +++ b/direct/src/fsm/FourState.py @@ -6,8 +6,8 @@ __all__ = ['FourState'] from direct.directnotify import DirectNotifyGlobal #import DistributedObject -import ClassicFSM -import State +from . import ClassicFSM +from . import State class FourState: @@ -122,7 +122,7 @@ class FourState: } self.stateIndex = 0 self.fsm = ClassicFSM.ClassicFSM('FourState', - self.states.values(), + list(self.states.values()), # Initial State names[0], # Final State diff --git a/direct/src/fsm/FourStateAI.py b/direct/src/fsm/FourStateAI.py index 814d8f057a..6f5ff8d966 100755 --- a/direct/src/fsm/FourStateAI.py +++ b/direct/src/fsm/FourStateAI.py @@ -6,8 +6,8 @@ __all__ = ['FourStateAI'] from direct.directnotify import DirectNotifyGlobal #import DistributedObjectAI -import ClassicFSM -import State +from . import ClassicFSM +from . import State from direct.task import Task @@ -128,7 +128,7 @@ class FourStateAI: [names[1]]), } self.fsm = ClassicFSM.ClassicFSM('FourState', - self.states.values(), + list(self.states.values()), # Initial State names[0], # Final State diff --git a/direct/src/fsm/SampleFSM.py b/direct/src/fsm/SampleFSM.py index b3b6fa88ed..9db513afa2 100644 --- a/direct/src/fsm/SampleFSM.py +++ b/direct/src/fsm/SampleFSM.py @@ -2,9 +2,8 @@ __all__ = ['ClassicStyle', 'NewStyle', 'ToonEyes'] -import FSM +from . import FSM from direct.task import Task -import string class ClassicStyle(FSM.FSM): @@ -19,61 +18,61 @@ class ClassicStyle(FSM.FSM): } def enterRed(self): - print "enterRed(self, '%s', '%s')" % (self.oldState, self.newState) + print("enterRed(self, '%s', '%s')" % (self.oldState, self.newState)) def exitRed(self): - print "exitRed(self, '%s', '%s')" % (self.oldState, self.newState) + print("exitRed(self, '%s', '%s')" % (self.oldState, self.newState)) def enterYellow(self): - print "enterYellow(self, '%s', '%s')" % (self.oldState, self.newState) + print("enterYellow(self, '%s', '%s')" % (self.oldState, self.newState)) def exitYellow(self): - print "exitYellow(self, '%s', '%s')" % (self.oldState, self.newState) + print("exitYellow(self, '%s', '%s')" % (self.oldState, self.newState)) def enterGreen(self): - print "enterGreen(self, '%s', '%s')" % (self.oldState, self.newState) + print("enterGreen(self, '%s', '%s')" % (self.oldState, self.newState)) def exitGreen(self): - print "exitGreen(self, '%s', '%s')" % (self.oldState, self.newState) + print("exitGreen(self, '%s', '%s')" % (self.oldState, self.newState)) class NewStyle(FSM.FSM): def enterRed(self): - print "enterRed(self, '%s', '%s')" % (self.oldState, self.newState) + print("enterRed(self, '%s', '%s')" % (self.oldState, self.newState)) def filterRed(self, request, args): - print "filterRed(self, '%s', %s)" % (request, args) + print("filterRed(self, '%s', %s)" % (request, args)) if request == 'advance': return 'Green' return self.defaultFilter(request, args) def exitRed(self): - print "exitRed(self, '%s', '%s')" % (self.oldState, self.newState) + print("exitRed(self, '%s', '%s')" % (self.oldState, self.newState)) def enterYellow(self): - print "enterYellow(self, '%s', '%s')" % (self.oldState, self.newState) + print("enterYellow(self, '%s', '%s')" % (self.oldState, self.newState)) def filterYellow(self, request, args): - print "filterYellow(self, '%s', %s)" % (request, args) + print("filterYellow(self, '%s', %s)" % (request, args)) if request == 'advance': return 'Red' return self.defaultFilter(request, args) def exitYellow(self): - print "exitYellow(self, '%s', '%s')" % (self.oldState, self.newState) + print("exitYellow(self, '%s', '%s')" % (self.oldState, self.newState)) def enterGreen(self): - print "enterGreen(self, '%s', '%s')" % (self.oldState, self.newState) + print("enterGreen(self, '%s', '%s')" % (self.oldState, self.newState)) def filterGreen(self, request, args): - print "filterGreen(self, '%s', %s)" % (request, args) + print("filterGreen(self, '%s', %s)" % (request, args)) if request == 'advance': return 'Yellow' return self.defaultFilter(request, args) def exitGreen(self): - print "exitGreen(self, '%s', '%s')" % (self.oldState, self.newState) + print("exitGreen(self, '%s', '%s')" % (self.oldState, self.newState)) class ToonEyes(FSM.FSM): @@ -88,14 +87,14 @@ class ToonEyes(FSM.FSM): def defaultFilter(self, request, args): # The default filter accepts any direct state request (these # start with a capital letter). - if request[0] in string.uppercase: + if request[0].isupper(): return request # Unexpected command requests are quietly ignored. return None def enterOpen(self): - print "swap in eyes open model" + print("swap in eyes open model") def filterOpen(self, request, args): if request == 'blink': @@ -109,7 +108,7 @@ class ToonEyes(FSM.FSM): return Task.done def enterClosed(self): - print "swap in eyes closed model" + print("swap in eyes closed model") def filterClosed(self, request, args): if request == 'unblink': @@ -117,7 +116,7 @@ class ToonEyes(FSM.FSM): return self.defaultFilter(request, args) def enterSurprised(self): - print "swap in eyes surprised model" + print("swap in eyes surprised model") def enterOff(self): taskMgr.remove(self.__unblinkName) diff --git a/direct/src/fsm/State.py b/direct/src/fsm/State.py index 44a17080f8..3842b0844b 100644 --- a/direct/src/fsm/State.py +++ b/direct/src/fsm/State.py @@ -199,7 +199,7 @@ class State(DirectObject): self.__enterChildren(argList) if (self.__enterFunc != None): - apply(self.__enterFunc, argList) + self.__enterFunc(*argList) def exit(self, argList=[]): """ @@ -210,7 +210,7 @@ class State(DirectObject): # call exit function if it exists if (self.__exitFunc != None): - apply(self.__exitFunc, argList) + self.__exitFunc(*argList) def __str__(self): return "State: name = %s, enter = %s, exit = %s, trans = %s, children = %s" %\ diff --git a/direct/src/fsm/StateData.py b/direct/src/fsm/StateData.py index 82ce729d93..9223d3c12c 100644 --- a/direct/src/fsm/StateData.py +++ b/direct/src/fsm/StateData.py @@ -5,7 +5,6 @@ __all__ = ['StateData'] from direct.directnotify.DirectNotifyGlobal import directNotify from direct.showbase.DirectObject import DirectObject -from direct.directnotify import DirectNotifyGlobal class StateData(DirectObject): """ diff --git a/direct/src/fsm/StatePush.py b/direct/src/fsm/StatePush.py index 0d30a8c3f8..fe0f496158 100755 --- a/direct/src/fsm/StatePush.py +++ b/direct/src/fsm/StatePush.py @@ -16,8 +16,8 @@ class PushesStateChanges: def destroy(self): if len(self._subscribers) != 0: - raise '%s object still has subscribers in destroy(): %s' % ( - self.__class__.__name__, self._subscribers) + raise Exception('%s object still has subscribers in destroy(): %s' % ( + self.__class__.__name__, self._subscribers)) del self._subscribers del self._value @@ -154,7 +154,7 @@ class ReceivesMultipleStateChanges: self._source2key = {} def destroy(self): - keys = self._key2source.keys() + keys = list(self._key2source.keys()) for key in keys: self._unsubscribe(key) del self._key2source @@ -202,15 +202,14 @@ class FunctionCall(ReceivesMultipleStateChanges, PushesStateChanges): # the value of arguments that push state self._bakedArgs = [] self._bakedKargs = {} - for i in xrange(len(self._args)): + for i, arg in enumerate(self._args): key = i - arg = self._args[i] if isinstance(arg, PushesStateChanges): self._bakedArgs.append(arg.getState()) self._subscribeTo(arg, key) else: self._bakedArgs.append(self._args[i]) - for key, arg in self._kArgs.iteritems(): + for key, arg in self._kArgs.items(): if isinstance(arg, PushesStateChanges): self._bakedKargs[key] = arg.getState() self._subscribeTo(arg, key) diff --git a/direct/src/gui/DirectButton.py b/direct/src/gui/DirectButton.py index f5dcee7413..87077d20a0 100644 --- a/direct/src/gui/DirectButton.py +++ b/direct/src/gui/DirectButton.py @@ -3,8 +3,8 @@ __all__ = ['DirectButton'] from panda3d.core import * -import DirectGuiGlobals as DGG -from DirectFrame import * +from . import DirectGuiGlobals as DGG +from .DirectFrame import * class DirectButton(DirectFrame): """ @@ -100,7 +100,7 @@ class DirectButton(DirectFrame): def commandFunc(self, event): if self['command']: # Pass any extra args to command - apply(self['command'], self['extraArgs']) + self['command'](*self['extraArgs']) def setClickSound(self): clickSound = self['clickSound'] diff --git a/direct/src/gui/DirectCheckBox.py b/direct/src/gui/DirectCheckBox.py index e0e2f8dc24..26b561edaf 100755 --- a/direct/src/gui/DirectCheckBox.py +++ b/direct/src/gui/DirectCheckBox.py @@ -55,5 +55,5 @@ class DirectCheckBox(DirectButton): if self['command']: # Pass any extra args to command - apply(self['command'], [self['isChecked']] + self['extraArgs']) + self['command'](*[self['isChecked']] + self['extraArgs']) diff --git a/direct/src/gui/DirectCheckButton.py b/direct/src/gui/DirectCheckButton.py index 5212031600..3df28a0730 100644 --- a/direct/src/gui/DirectCheckButton.py +++ b/direct/src/gui/DirectCheckButton.py @@ -3,8 +3,8 @@ __all__ = ['DirectCheckButton'] from panda3d.core import * -from DirectButton import * -from DirectLabel import * +from .DirectButton import * +from .DirectLabel import * class DirectCheckButton(DirectButton): """ @@ -169,7 +169,7 @@ class DirectCheckButton(DirectButton): if self['command']: # Pass any extra args to command - apply(self['command'], [self['indicatorValue']] + self['extraArgs']) + self['command'](*[self['indicatorValue']] + self['extraArgs']) def setIndicatorValue(self): self.component('indicator').guiItem.setState(self['indicatorValue']) diff --git a/direct/src/gui/DirectDialog.py b/direct/src/gui/DirectDialog.py index b1d245b1b1..039092c511 100644 --- a/direct/src/gui/DirectDialog.py +++ b/direct/src/gui/DirectDialog.py @@ -3,9 +3,9 @@ __all__ = ['findDialog', 'cleanupDialog', 'DirectDialog', 'OkDialog', 'OkCancelDialog', 'YesNoDialog', 'YesNoCancelDialog', 'RetryCancelDialog'] from panda3d.core import * -import DirectGuiGlobals as DGG -from DirectFrame import * -from DirectButton import * +from . import DirectGuiGlobals as DGG +from .DirectFrame import * +from .DirectButton import * import types def findDialog(uniqueName): @@ -186,8 +186,8 @@ class DirectDialog(DirectFrame): bindList = zip(self.buttonList, self['buttonHotKeyList'], self['buttonValueList']) for button, hotKey, value in bindList: - if ((type(hotKey) == types.ListType) or - (type(hotKey) == types.TupleType)): + if ((type(hotKey) == list) or + (type(hotKey) == tuple)): for key in hotKey: button.bind('press-' + key + '-', self.buttonCommand, extraArgs = [value]) @@ -274,12 +274,12 @@ class DirectDialog(DirectFrame): scale = self['button_scale'] # Can either be a Vec3 or a tuple of 3 values if (isinstance(scale, Vec3) or - (type(scale) == types.ListType) or - (type(scale) == types.TupleType)): + (type(scale) == list) or + (type(scale) == tuple)): sx = scale[0] sz = scale[2] - elif ((type(scale) == types.IntType) or - (type(scale) == types.FloatType)): + elif ((type(scale) == int) or + (type(scale) == float)): sx = sz = scale else: sx = sz = 1 diff --git a/direct/src/gui/DirectEntry.py b/direct/src/gui/DirectEntry.py index ceddf741f7..45733b7c35 100644 --- a/direct/src/gui/DirectEntry.py +++ b/direct/src/gui/DirectEntry.py @@ -3,10 +3,10 @@ __all__ = ['DirectEntry'] from panda3d.core import * -import DirectGuiGlobals as DGG -from DirectFrame import * -from OnscreenText import OnscreenText -import string,types +from . import DirectGuiGlobals as DGG +from .DirectFrame import * +from .OnscreenText import OnscreenText +import sys # import this to make sure it gets pulled into the publish import encodings.utf_8 from direct.showbase.DirectObject import DirectObject @@ -181,12 +181,12 @@ class DirectEntry(DirectFrame): def commandFunc(self, event): if self['command']: # Pass any extra args to command - apply(self['command'], [self.get()] + self['extraArgs']) + self['command'](*[self.get()] + self['extraArgs']) def failedCommandFunc(self, event): if self['failedCommand']: # Pass any extra args - apply(self['failedCommand'], [self.get()] + self['failedExtraArgs']) + self['failedCommand'](*[self.get()] + self['failedExtraArgs']) def autoCapitalizeFunc(self): if self['autoCapitalize']: @@ -198,7 +198,7 @@ class DirectEntry(DirectFrame): def focusInCommandFunc(self): if self['focusInCommand']: - apply(self['focusInCommand'], self['focusInExtraArgs']) + self['focusInCommand'](*self['focusInExtraArgs']) if self['autoCapitalize']: self.accept(self.guiItem.getTypeEvent(), self._handleTyping) self.accept(self.guiItem.getEraseEvent(), self._handleErasing) @@ -216,14 +216,13 @@ class DirectEntry(DirectFrame): wordSoFar = '' # track whether the previous character was part of a word or not wasNonWordChar = True - for i in xrange(len(name)): - character = name[i] + for i, character in enumerate(name): # test to see if we are between words # - Count characters that can't be capitalized as a break between words # This assumes that string.lower and string.upper will return different # values for all unicode letters. # - Don't count apostrophes as a break between words - if ((string.lower(character) == string.upper(character)) and (character != "'")): + if character.lower() == character.upper() and character != "'": # we are between words wordSoFar = '' wasNonWordChar = True @@ -232,7 +231,7 @@ class DirectEntry(DirectFrame): if wasNonWordChar: # first letter of a word, capitalize it unconditionally; capitalize = True - elif (character == string.upper(character) and + elif (character == character.upper() and len(self.autoCapitalizeAllowPrefixes) and wordSoFar in self.autoCapitalizeAllowPrefixes): # first letter after one of the prefixes, allow it to be capitalized @@ -243,9 +242,9 @@ class DirectEntry(DirectFrame): capitalize = True if capitalize: # allow this letter to remain capitalized - character = string.upper(character) + character = character.upper() else: - character = string.lower(character) + character = character.lower() wordSoFar += character wasNonWordChar = False capName += character @@ -253,7 +252,7 @@ class DirectEntry(DirectFrame): def focusOutCommandFunc(self): if self['focusOutCommand']: - apply(self['focusOutCommand'], self['focusOutExtraArgs']) + self['focusOutCommand'](*self['focusOutExtraArgs']) if self['autoCapitalize']: self.ignore(self.guiItem.getTypeEvent()) self.ignore(self.guiItem.getEraseEvent()) @@ -263,11 +262,16 @@ class DirectEntry(DirectFrame): does not change the current cursor position. Also see enterText(). """ - self.unicodeText = isinstance(text, types.UnicodeType) - if self.unicodeText: + if sys.version_info >= (3, 0): + assert not isinstance(text, bytes) + self.unicodeText = True self.guiItem.setWtext(text) else: - self.guiItem.setText(text) + self.unicodeText = isinstance(text, unicode) + if self.unicodeText: + self.guiItem.setWtext(text) + else: + self.guiItem.setText(text) def get(self, plain = False): """ Returns the text currently showing in the typable region. diff --git a/direct/src/gui/DirectEntryScroll.py b/direct/src/gui/DirectEntryScroll.py index 3fe1599b1b..0cd7c3ea21 100644 --- a/direct/src/gui/DirectEntryScroll.py +++ b/direct/src/gui/DirectEntryScroll.py @@ -1,10 +1,10 @@ __all__ = ['DirectEntryScroll'] from panda3d.core import * -import DirectGuiGlobals as DGG -from DirectScrolledFrame import * -from DirectFrame import * -from DirectEntry import * +from . import DirectGuiGlobals as DGG +from .DirectScrolledFrame import * +from .DirectFrame import * +from .DirectEntry import * class DirectEntryScroll(DirectFrame): def __init__(self, entry, parent = None, **kw): diff --git a/direct/src/gui/DirectFrame.py b/direct/src/gui/DirectFrame.py index 2f5ed61241..9db60f727b 100644 --- a/direct/src/gui/DirectFrame.py +++ b/direct/src/gui/DirectFrame.py @@ -3,11 +3,17 @@ __all__ = ['DirectFrame'] from panda3d.core import * -import DirectGuiGlobals as DGG -from DirectGuiBase import * -from OnscreenImage import OnscreenImage -from OnscreenGeom import OnscreenGeom -import types +from . import DirectGuiGlobals as DGG +from .DirectGuiBase import * +from .OnscreenImage import OnscreenImage +from .OnscreenGeom import OnscreenGeom +import sys + +if sys.version_info >= (3, 0): + stringTypes = (str,) +else: + stringTypes = (str, unicode) + class DirectFrame(DirectGuiWidget): DefDynGroups = ('text', 'geom', 'image') @@ -54,7 +60,7 @@ class DirectFrame(DirectGuiWidget): # Determine if user passed in single string or a sequence if self['text'] == None: textList = (None,) * self['numStates'] - elif isinstance(self['text'], types.StringTypes): + elif isinstance(self['text'], stringTypes): # If just passing in a single string, make a tuple out of it textList = (self['text'],) * self['numStates'] else: @@ -80,7 +86,7 @@ class DirectFrame(DirectGuiWidget): if text == None: return else: - from OnscreenText import OnscreenText + from .OnscreenText import OnscreenText self.createcomponent( component, (), 'text', OnscreenText, @@ -97,7 +103,7 @@ class DirectFrame(DirectGuiWidget): # Passed in None geomList = (None,) * self['numStates'] elif isinstance(geom, NodePath) or \ - isinstance(geom, types.StringTypes): + isinstance(geom, stringTypes): # Passed in a single node path, make a tuple out of it geomList = (geom,) * self['numStates'] else: @@ -139,14 +145,14 @@ class DirectFrame(DirectGuiWidget): imageList = (None,) * self['numStates'] elif isinstance(arg, NodePath) or \ isinstance(arg, Texture) or \ - isinstance(arg, types.StringTypes): + isinstance(arg, stringTypes): # Passed in a single node path, make a tuple out of it imageList = (arg,) * self['numStates'] else: # Otherwise, hope that the user has passed in a tuple/list if ((len(arg) == 2) and - isinstance(arg[0], types.StringTypes) and - isinstance(arg[1], types.StringTypes)): + isinstance(arg[0], stringTypes) and + isinstance(arg[1], stringTypes)): # Its a model/node pair of strings imageList = (arg,) * self['numStates'] else: diff --git a/direct/src/gui/DirectGui.py b/direct/src/gui/DirectGui.py index 1d3c0636de..e0a59abb82 100644 --- a/direct/src/gui/DirectGui.py +++ b/direct/src/gui/DirectGui.py @@ -1,9 +1,9 @@ -"""Undocumented Module""" +""" Imports all of the DirectGUI classes. """ -import DirectGuiGlobals as DGG -from OnscreenText import * -from OnscreenGeom import * -from OnscreenImage import * +from . import DirectGuiGlobals as DGG +from .OnscreenText import * +from .OnscreenGeom import * +from .OnscreenImage import * # MPG DirectStart should call this? # Set up default font @@ -12,17 +12,17 @@ from OnscreenImage import * # PGItem.getTextNode().setFont(defaultFont) # Direct Gui Classes -from DirectFrame import * -from DirectButton import * -from DirectEntry import * -from DirectEntryScroll import * -from DirectLabel import * -from DirectScrolledList import * -from DirectDialog import * -from DirectWaitBar import * -from DirectSlider import * -from DirectScrollBar import * -from DirectScrolledFrame import * -from DirectCheckButton import * -from DirectOptionMenu import * -from DirectRadioButton import * +from .DirectFrame import * +from .DirectButton import * +from .DirectEntry import * +from .DirectEntryScroll import * +from .DirectLabel import * +from .DirectScrolledList import * +from .DirectDialog import * +from .DirectWaitBar import * +from .DirectSlider import * +from .DirectScrollBar import * +from .DirectScrolledFrame import * +from .DirectCheckButton import * +from .DirectOptionMenu import * +from .DirectRadioButton import * diff --git a/direct/src/gui/DirectGuiBase.py b/direct/src/gui/DirectGuiBase.py index 2c67136535..633b9615c0 100644 --- a/direct/src/gui/DirectGuiBase.py +++ b/direct/src/gui/DirectGuiBase.py @@ -5,14 +5,13 @@ __all__ = ['DirectGuiBase', 'DirectGuiWidget'] from panda3d.core import * from panda3d.direct import get_config_showbase -import DirectGuiGlobals as DGG -from OnscreenText import * -from OnscreenGeom import * -from OnscreenImage import * +from . import DirectGuiGlobals as DGG +from .OnscreenText import * +from .OnscreenGeom import * +from .OnscreenImage import * from direct.directtools.DirectUtil import ROUND_TO from direct.showbase import DirectObject from direct.task import Task -import types guiObjectCollector = PStatCollector("Client::GuiObjects") @@ -243,7 +242,7 @@ class DirectGuiBase(DirectObject.DirectObject): # Now check if anything is left over unusedOptions = [] keywords = self._constructorKeywords - for name in keywords.keys(): + for name in keywords: used = keywords[name][1] if not used: # This keyword argument has not been used. If it @@ -350,8 +349,8 @@ class DirectGuiBase(DirectObject.DirectObject): # This is one of the options of this gui item. # Check it is an initialisation option. if optionInfo[option][FUNCTION] is DGG.INITOPT: - print 'Cannot configure initialisation option "' \ - + option + '" for ' + self.__class__.__name__ + print('Cannot configure initialisation option "' \ + + option + '" for ' + self.__class__.__name__) break #raise KeyError, \ # 'Cannot configure initialisation option "' \ @@ -506,7 +505,7 @@ class DirectGuiBase(DirectObject.DirectObject): # with corresponding keys beginning with *component*. alias = alias + '_' aliasLen = len(alias) - for option in keywords.keys(): + for option in keywords: if len(option) > aliasLen and option[:aliasLen] == alias: newkey = component + '_' + option[aliasLen:] keywords[newkey] = keywords[option] @@ -519,7 +518,7 @@ class DirectGuiBase(DirectObject.DirectObject): # First, walk through the option list looking for arguments # than refer to this component's group. - for option in keywords.keys(): + for option in keywords: # Check if this keyword argument refers to the group # of this component. If so, add this to the options # to use when constructing the widget. Mark the @@ -538,7 +537,7 @@ class DirectGuiBase(DirectObject.DirectObject): # specific than the group arguments, above; we walk through # the list afterwards so they will override. - for option in keywords.keys(): + for option in keywords: if len(option) > nameLen and option[:nameLen] == componentPrefix: # The keyword argument refers to this component, so add # this to the options to use when constructing the widget. @@ -550,7 +549,7 @@ class DirectGuiBase(DirectObject.DirectObject): if widgetClass is None: return None # Get arguments for widget constructor - if len(widgetArgs) == 1 and type(widgetArgs[0]) == types.TupleType: + if len(widgetArgs) == 1 and type(widgetArgs[0]) == tuple: # Arguments to the constructor can be specified as either # multiple trailing arguments to createcomponent() or as a # single tuple argument. @@ -600,7 +599,7 @@ class DirectGuiBase(DirectObject.DirectObject): def components(self): # Return a list of all components. - names = self.__componentInfo.keys() + names = list(self.__componentInfo.keys()) names.sort() return names @@ -631,8 +630,8 @@ class DirectGuiBase(DirectObject.DirectObject): gEvent = event + self.guiId if get_config_showbase().GetBool('debug-directgui-msgs', False): from direct.showbase.PythonUtil import StackTrace - print gEvent - print StackTrace() + print(gEvent) + print(StackTrace()) self.accept(gEvent, command, extraArgs = extraArgs) def unbind(self, event): @@ -944,7 +943,7 @@ class DirectGuiWidget(DirectGuiBase, NodePath): # Convert None, and string arguments if relief == None: relief = PGFrameStyle.TNone - elif isinstance(relief, types.StringTypes): + elif isinstance(relief, str): # Convert string to frame style int relief = DGG.FrameStyleDict[relief] # Set style @@ -969,8 +968,8 @@ class DirectGuiWidget(DirectGuiBase, NodePath): def setFrameColor(self): # this might be a single color or a list of colors colors = self['frameColor'] - if type(colors[0]) == types.IntType or \ - type(colors[0]) == types.FloatType: + if type(colors[0]) == int or \ + type(colors[0]) == float: colors = (colors,) for i in range(self['numStates']): if i >= len(colors): @@ -985,14 +984,14 @@ class DirectGuiWidget(DirectGuiBase, NodePath): textures = self['frameTexture'] if textures == None or \ isinstance(textures, Texture) or \ - isinstance(textures, types.StringTypes): + isinstance(textures, str): textures = (textures,) * self['numStates'] for i in range(self['numStates']): if i >= len(textures): texture = textures[-1] else: texture = textures[i] - if isinstance(texture, types.StringTypes): + if isinstance(texture, str): texture = loader.loadTexture(texture) if texture: self.frameStyle[i].setTexture(texture) @@ -1057,9 +1056,9 @@ class DirectGuiWidget(DirectGuiBase, NodePath): def printConfig(self, indent = 0): space = ' ' * indent - print space + self.guiId, '-', self.__class__.__name__ - print space + 'Pos: %s' % tuple(self.getPos()) - print space + 'Scale: %s' % tuple(self.getScale()) + print('%s%s - %s' % (space, self.guiId, self.__class__.__name__)) + print('%sPos: %s' % (space, tuple(self.getPos()))) + print('%sScale: %s' % (space, tuple(self.getScale()))) # Print out children info for child in self.getChildren(): messenger.send(DGG.PRINT + child.getName(), [indent + 2]) diff --git a/direct/src/gui/DirectGuiTest.py b/direct/src/gui/DirectGuiTest.py index 6172aef04d..c68c705b0e 100644 --- a/direct/src/gui/DirectGuiTest.py +++ b/direct/src/gui/DirectGuiTest.py @@ -5,8 +5,8 @@ __all__ = [] if __name__ == "__main__": from direct.showbase.ShowBase import ShowBase - import DirectGuiGlobals - from DirectGui import * + from . import DirectGuiGlobals + from .DirectGui import * #from whrandom import * from random import * @@ -18,7 +18,7 @@ if __name__ == "__main__": # Here we specify the button's command def dummyCmd(index): - print 'Button %d POW!!!!' % index + print('Button %d POW!!!!' % index) # Define some commands to bind to enter, exit and click events def shrink(db): @@ -94,7 +94,7 @@ if __name__ == "__main__": # DIRECT ENTRY EXAMPLE def printEntryText(text): - print 'Text:', text + print('Text: %s' % (text)) # Here we create an entry, and specify everything up front # CALL de1.get() and de1.set('new text') to get and set entry contents @@ -110,7 +110,7 @@ if __name__ == "__main__": # DIRECT DIALOG EXAMPLE def printDialogValue(value): - print 'Value:', value + print('Value: %s' % (value)) simpleDialog = YesNoDialog(text = 'Simple', command = printDialogValue) @@ -136,9 +136,9 @@ if __name__ == "__main__": # NOTE: There are some utility functions which help you get size # of a direct gui widget. These can be used to position and scale an # image after you've created the entry. scale = (width/2, 1, height/2) - print 'BOUNDS:', de1.getBounds() - print 'WIDTH:', de1.getWidth() - print 'HEIGHT:', de1.getHeight() - print 'CENTER:', de1.getCenter() + print('BOUNDS: %s' % de1.getBounds()) + print('WIDTH: %s' % de1.getWidth()) + print('HEIGHT: %s' % de1.getHeight()) + print('CENTER: %s' % (de1.getCenter(),)) base.run() diff --git a/direct/src/gui/DirectLabel.py b/direct/src/gui/DirectLabel.py index 6dd31c6096..5cb2932900 100644 --- a/direct/src/gui/DirectLabel.py +++ b/direct/src/gui/DirectLabel.py @@ -3,7 +3,7 @@ __all__ = ['DirectLabel'] from panda3d.core import * -from DirectFrame import * +from .DirectFrame import * class DirectLabel(DirectFrame): """ diff --git a/direct/src/gui/DirectOptionMenu.py b/direct/src/gui/DirectOptionMenu.py index 7dfc758fee..e2432a5512 100644 --- a/direct/src/gui/DirectOptionMenu.py +++ b/direct/src/gui/DirectOptionMenu.py @@ -2,13 +2,11 @@ __all__ = ['DirectOptionMenu'] -import types - from panda3d.core import * -import DirectGuiGlobals as DGG -from DirectButton import * -from DirectLabel import * -from DirectFrame import * +from . import DirectGuiGlobals as DGG +from .DirectButton import * +from .DirectLabel import * +from .DirectFrame import * class DirectOptionMenu(DirectButton): """ @@ -252,7 +250,7 @@ class DirectOptionMenu(DirectButton): def index(self, index): intIndex = None - if isinstance(index, types.IntType): + if isinstance(index, int): intIndex = index elif index in self['items']: i = 0 @@ -272,7 +270,7 @@ class DirectOptionMenu(DirectButton): self['text'] = item if fCommand and self['command']: # Pass any extra args to command - apply(self['command'], [item] + self['extraArgs']) + self['command'](*[item] + self['extraArgs']) def get(self): """ Get currently selected item """ diff --git a/direct/src/gui/DirectRadioButton.py b/direct/src/gui/DirectRadioButton.py index 2b0f0473e4..8044e81295 100755 --- a/direct/src/gui/DirectRadioButton.py +++ b/direct/src/gui/DirectRadioButton.py @@ -3,9 +3,9 @@ __all__ = ['DirectRadioButton'] from panda3d.core import * -import DirectGuiGlobals as DGG -from DirectButton import * -from DirectLabel import * +from . import DirectGuiGlobals as DGG +from .DirectButton import * +from .DirectLabel import * class DirectRadioButton(DirectButton): """ @@ -205,7 +205,7 @@ class DirectRadioButton(DirectButton): if self['command']: # Pass any extra args to command - apply(self['command'], self['extraArgs']) + self['command'](*self['extraArgs']) def setOthers(self, others): self['others'] = others diff --git a/direct/src/gui/DirectScrollBar.py b/direct/src/gui/DirectScrollBar.py index acdc0a9c95..8493547e0d 100644 --- a/direct/src/gui/DirectScrollBar.py +++ b/direct/src/gui/DirectScrollBar.py @@ -3,9 +3,9 @@ __all__ = ['DirectScrollBar'] from panda3d.core import * -import DirectGuiGlobals as DGG -from DirectFrame import * -from DirectButton import * +from . import DirectGuiGlobals as DGG +from .DirectFrame import * +from .DirectButton import * """ import DirectScrollBar @@ -164,5 +164,5 @@ class DirectScrollBar(DirectFrame): self._optionInfo['value'][DGG._OPT_VALUE] = self.guiItem.getValue() if self['command']: - apply(self['command'], self['extraArgs']) + self['command'](*self['extraArgs']) diff --git a/direct/src/gui/DirectScrolledFrame.py b/direct/src/gui/DirectScrolledFrame.py index 325582ef52..6a7be7cabf 100644 --- a/direct/src/gui/DirectScrolledFrame.py +++ b/direct/src/gui/DirectScrolledFrame.py @@ -3,9 +3,9 @@ __all__ = ['DirectScrolledFrame'] from panda3d.core import * -import DirectGuiGlobals as DGG -from DirectFrame import * -from DirectScrollBar import * +from . import DirectGuiGlobals as DGG +from .DirectFrame import * +from .DirectScrollBar import * """ import DirectScrolledFrame @@ -87,7 +87,7 @@ class DirectScrolledFrame(DirectFrame): def commandFunc(self): if self['command']: - apply(self['command'], self['extraArgs']) + self['command'](*self['extraArgs']) def destroy(self): # Destroy children of the canvas diff --git a/direct/src/gui/DirectScrolledList.py b/direct/src/gui/DirectScrolledList.py index 3bd5c9fd07..79c1661f7e 100644 --- a/direct/src/gui/DirectScrolledList.py +++ b/direct/src/gui/DirectScrolledList.py @@ -3,11 +3,11 @@ __all__ = ['DirectScrolledListItem', 'DirectScrolledList'] from panda3d.core import * -import DirectGuiGlobals as DGG +from . import DirectGuiGlobals as DGG from direct.directnotify import DirectNotifyGlobal from direct.task.Task import Task -from DirectFrame import * -from DirectButton import * +from .DirectFrame import * +from .DirectButton import * import types @@ -39,7 +39,7 @@ class DirectScrolledListItem(DirectButton): def select(self): assert self.notify.debugStateCall(self) - apply(self.nextCommand, self.nextCommandExtraArgs) + self.nextCommand(*self.nextCommandExtraArgs) self.parent.selectListItem(self) @@ -251,7 +251,7 @@ class DirectScrolledList(DirectFrame): if item.__class__.__name__ == 'str': if self['itemMakeFunction']: # If there is a function to create the item - item = apply(self['itemMakeFunction'], (item, i, self['itemMakeExtraArgs'])) + item = self['itemMakeFunction'](item, i, self['itemMakeExtraArgs']) else: item = DirectFrame(text = item, text_align = self['itemsAlign'], @@ -269,7 +269,7 @@ class DirectScrolledList(DirectFrame): if self['command']: # Pass any extra args to command - apply(self['command'], self['extraArgs']) + self['command'](*self['extraArgs']) return ret def makeAllItems(self): @@ -283,8 +283,7 @@ class DirectScrolledList(DirectFrame): if item.__class__.__name__ == 'str': if self['itemMakeFunction']: # If there is a function to create the item - item = apply(self['itemMakeFunction'], - (item, i, self['itemMakeExtraArgs'])) + item = self['itemMakeFunction'](item, i, self['itemMakeExtraArgs']) else: item = DirectFrame(text = item, text_align = self['itemsAlign'], diff --git a/direct/src/gui/DirectSlider.py b/direct/src/gui/DirectSlider.py index 4fdc0588c8..73f5410e49 100644 --- a/direct/src/gui/DirectSlider.py +++ b/direct/src/gui/DirectSlider.py @@ -3,9 +3,9 @@ __all__ = ['DirectSlider'] from panda3d.core import * -import DirectGuiGlobals as DGG -from DirectFrame import * -from DirectButton import * +from . import DirectGuiGlobals as DGG +from .DirectFrame import * +from .DirectButton import * """ import DirectSlider @@ -124,4 +124,4 @@ class DirectSlider(DirectFrame): self._optionInfo['value'][DGG._OPT_VALUE] = self.guiItem.getValue() if self['command']: - apply(self['command'], self['extraArgs']) + self['command'](*self['extraArgs']) diff --git a/direct/src/gui/DirectWaitBar.py b/direct/src/gui/DirectWaitBar.py index ac4509987d..149540e5d5 100644 --- a/direct/src/gui/DirectWaitBar.py +++ b/direct/src/gui/DirectWaitBar.py @@ -3,8 +3,8 @@ __all__ = ['DirectWaitBar'] from panda3d.core import * -import DirectGuiGlobals as DGG -from DirectFrame import * +from . import DirectGuiGlobals as DGG +from .DirectFrame import * import types """ @@ -93,7 +93,7 @@ class DirectWaitBar(DirectFrame): """Updates the bar texture, which you can set using bar['barTexture'].""" # this must be a single texture (or a string). texture = self['barTexture'] - if isinstance(texture, types.StringTypes): + if isinstance(texture, str): texture = loader.loadTexture(texture) if texture: self.barStyle.setTexture(texture) diff --git a/direct/src/gui/OnscreenGeom.py b/direct/src/gui/OnscreenGeom.py index faf020a2d1..ac4f93a418 100644 --- a/direct/src/gui/OnscreenGeom.py +++ b/direct/src/gui/OnscreenGeom.py @@ -4,7 +4,7 @@ __all__ = ['OnscreenGeom'] from panda3d.core import * from direct.showbase.DirectObject import DirectObject -import types + class OnscreenGeom(DirectObject, NodePath): def __init__(self, geom = None, @@ -49,25 +49,25 @@ class OnscreenGeom(DirectObject, NodePath): # Adjust pose # Set pos - if (isinstance(pos, types.TupleType) or - isinstance(pos, types.ListType)): - apply(self.setPos, pos) + if (isinstance(pos, tuple) or + isinstance(pos, list)): + self.setPos(*pos) elif isinstance(pos, VBase3): self.setPos(pos) # Hpr - if (isinstance(hpr, types.TupleType) or - isinstance(hpr, types.ListType)): - apply(self.setHpr, hpr) + if (isinstance(hpr, tuple) or + isinstance(hpr, list)): + self.setHpr(*hpr) elif isinstance(hpr, VBase3): self.setPos(hpr) # Scale - if (isinstance(scale, types.TupleType) or - isinstance(scale, types.ListType)): - apply(self.setScale, scale) + if (isinstance(scale, tuple) or + isinstance(scale, list)): + self.setScale(*scale) elif isinstance(scale, VBase3): self.setPos(scale) - elif (isinstance(scale, types.FloatType) or - isinstance(scale, types.IntType)): + elif (isinstance(scale, float) or + isinstance(scale, int)): self.setScale(scale) def setGeom(self, geom, @@ -93,7 +93,7 @@ class OnscreenGeom(DirectObject, NodePath): # Assign geometry if isinstance(geom, NodePath): self.assign(geom.copyTo(parent, sort)) - elif isinstance(geom, types.StringTypes): + elif isinstance(geom, str): self.assign(loader.loadModel(geom)) self.reparentTo(parent, sort) @@ -116,17 +116,17 @@ class OnscreenGeom(DirectObject, NodePath): if (((setter == self.setPos) or (setter == self.setHpr) or (setter == self.setScale)) and - (isinstance(value, types.TupleType) or - isinstance(value, types.ListType))): - apply(setter, value) + (isinstance(value, tuple) or + isinstance(value, list))): + setter(*value) else: setter(value) except AttributeError: - print 'OnscreenText.configure: invalid option:', option + print('OnscreenText.configure: invalid option: %s' % option) # Allow index style references def __setitem__(self, key, value): - apply(self.configure, (), {key: value}) + self.configure(*(), **{key: value}) def cget(self, option): # Get current configuration setting. diff --git a/direct/src/gui/OnscreenImage.py b/direct/src/gui/OnscreenImage.py index 7f4579886d..a99d4bf0ff 100644 --- a/direct/src/gui/OnscreenImage.py +++ b/direct/src/gui/OnscreenImage.py @@ -4,7 +4,7 @@ __all__ = ['OnscreenImage'] from panda3d.core import * from direct.showbase.DirectObject import DirectObject -import types + class OnscreenImage(DirectObject, NodePath): def __init__(self, image = None, @@ -49,25 +49,25 @@ class OnscreenImage(DirectObject, NodePath): # Adjust pose # Set pos - if (isinstance(pos, types.TupleType) or - isinstance(pos, types.ListType)): - apply(self.setPos, pos) + if (isinstance(pos, tuple) or + isinstance(pos, list)): + self.setPos(*pos) elif isinstance(pos, VBase3): self.setPos(pos) # Hpr - if (isinstance(hpr, types.TupleType) or - isinstance(hpr, types.ListType)): - apply(self.setHpr, hpr) + if (isinstance(hpr, tuple) or + isinstance(hpr, list)): + self.setHpr(*hpr) elif isinstance(hpr, VBase3): self.setHpr(hpr) # Scale - if (isinstance(scale, types.TupleType) or - isinstance(scale, types.ListType)): - apply(self.setScale, scale) + if (isinstance(scale, tuple) or + isinstance(scale, list)): + self.setScale(*scale) elif isinstance(scale, VBase3): self.setScale(scale) - elif (isinstance(scale, types.FloatType) or - isinstance(scale, types.IntType)): + elif (isinstance(scale, float) or + isinstance(scale, int)): self.setScale(scale) # Set color @@ -95,7 +95,7 @@ class OnscreenImage(DirectObject, NodePath): # Assign geometry if isinstance(image, NodePath): self.assign(image.copyTo(parent, sort)) - elif isinstance(image, types.StringTypes) or \ + elif isinstance(image, str) or \ isinstance(image, Texture): if isinstance(image, Texture): # It's a Texture @@ -115,9 +115,9 @@ class OnscreenImage(DirectObject, NodePath): if node: self.assign(node.copyTo(parent, sort)) else: - print 'OnscreenImage: node %s not found' % image[1] + print('OnscreenImage: node %s not found' % image[1]) else: - print 'OnscreenImage: model %s not found' % image[0] + print('OnscreenImage: model %s not found' % image[0]) if transform and not self.isEmpty(): self.setTransform(transform) @@ -133,17 +133,17 @@ class OnscreenImage(DirectObject, NodePath): if (((setter == self.setPos) or (setter == self.setHpr) or (setter == self.setScale)) and - (isinstance(value, types.TupleType) or - isinstance(value, types.ListType))): - apply(setter, value) + (isinstance(value, tuple) or + isinstance(value, list))): + setter(*value) else: setter(value) except AttributeError: - print 'OnscreenImage.configure: invalid option:', option + print('OnscreenImage.configure: invalid option: %s' % option) # Allow index style references def __setitem__(self, key, value): - apply(self.configure, (), {key: value}) + self.configure(*(), **{key: value}) def cget(self, option): # Get current configuration setting. diff --git a/direct/src/gui/OnscreenText.py b/direct/src/gui/OnscreenText.py index 9fbea1a3a6..03beac702b 100644 --- a/direct/src/gui/OnscreenText.py +++ b/direct/src/gui/OnscreenText.py @@ -3,9 +3,9 @@ __all__ = ['OnscreenText', 'Plain', 'ScreenTitle', 'ScreenPrompt', 'NameConfirm', 'BlackOnWhite'] from panda3d.core import * -import DirectGuiGlobals as DGG +from . import DirectGuiGlobals as DGG from direct.showbase.DirectObject import DirectObject -import types +import sys ## These are the styles of text we might commonly see. They set the ## overall appearance of the text according to one of a number of @@ -152,7 +152,7 @@ class OnscreenText(DirectObject, NodePath): else: raise ValueError - if not isinstance(scale, types.TupleType): + if not isinstance(scale, tuple): # If the scale is already a tuple, it's a 2-d (x, y) scale. # Otherwise, it's a uniform scale--make it a tuple. scale = (scale, scale) @@ -263,15 +263,24 @@ class OnscreenText(DirectObject, NodePath): self.textNode.clearText() def setText(self, text): - self.unicodeText = isinstance(text, types.UnicodeType) + if sys.version_info >= (3, 0): + assert not isinstance(text, bytes) + self.unicodeText = True + else: + self.unicodeText = isinstance(text, unicode) + if self.unicodeText: self.textNode.setWtext(text) else: self.textNode.setText(text) def appendText(self, text): - if isinstance(text, types.UnicodeType): - self.unicodeText = 1 + if sys.version_info >= (3, 0): + assert not isinstance(text, bytes) + self.unicodeText = True + else: + self.unicodeText = isinstance(text, unicode) + if self.unicodeText: self.textNode.appendWtext(text) else: @@ -322,7 +331,7 @@ class OnscreenText(DirectObject, NodePath): """ if sy == None: - if isinstance(sx, types.TupleType): + if isinstance(sx, tuple): self.__scale = sx else: self.__scale = (sx, sx) @@ -413,7 +422,7 @@ class OnscreenText(DirectObject, NodePath): def configure(self, option=None, **kw): # These is for compatibility with DirectGui functions if not self.mayChange: - print 'OnscreenText.configure: mayChange == 0' + print('OnscreenText.configure: mayChange == 0') return for option, value in kw.items(): # Use option string to access setter function @@ -424,11 +433,11 @@ class OnscreenText(DirectObject, NodePath): else: setter(value) except AttributeError: - print 'OnscreenText.configure: invalid option:', option + print('OnscreenText.configure: invalid option: %s' % option) # Allow index style references def __setitem__(self, key, value): - apply(self.configure, (), {key: value}) + self.configure(*(), **{key: value}) def cget(self, option): # Get current configuration setting. diff --git a/direct/src/interval/ActorInterval.py b/direct/src/interval/ActorInterval.py index ae26c4cde4..5d8b557ae6 100644 --- a/direct/src/interval/ActorInterval.py +++ b/direct/src/interval/ActorInterval.py @@ -5,7 +5,7 @@ __all__ = ['ActorInterval', 'LerpAnimInterval'] from panda3d.core import * from panda3d.direct import * from direct.directnotify.DirectNotifyGlobal import * -import Interval +from . import Interval import math class ActorInterval(Interval.Interval): diff --git a/direct/src/interval/AnimControlInterval.py b/direct/src/interval/AnimControlInterval.py index 57494b145b..4223e69f08 100755 --- a/direct/src/interval/AnimControlInterval.py +++ b/direct/src/interval/AnimControlInterval.py @@ -5,7 +5,7 @@ __all__ = ['AnimControlInterval'] from panda3d.core import * from panda3d.direct import * from direct.directnotify.DirectNotifyGlobal import * -import Interval +from . import Interval import math class AnimControlInterval(Interval.Interval): diff --git a/direct/src/interval/FunctionInterval.py b/direct/src/interval/FunctionInterval.py index a730373916..8f84ca9df8 100644 --- a/direct/src/interval/FunctionInterval.py +++ b/direct/src/interval/FunctionInterval.py @@ -6,7 +6,7 @@ from panda3d.core import * from panda3d.direct import * from direct.showbase.MessengerGlobal import * from direct.directnotify.DirectNotifyGlobal import directNotify -import Interval +from . import Interval ############################################################# diff --git a/direct/src/interval/IndirectInterval.py b/direct/src/interval/IndirectInterval.py index 991265273e..a0adf30a82 100644 --- a/direct/src/interval/IndirectInterval.py +++ b/direct/src/interval/IndirectInterval.py @@ -5,8 +5,8 @@ __all__ = ['IndirectInterval'] from panda3d.core import * from panda3d.direct import * from direct.directnotify.DirectNotifyGlobal import * -import Interval -import LerpBlendHelpers +from . import Interval +from . import LerpBlendHelpers class IndirectInterval(Interval.Interval): """ diff --git a/direct/src/interval/Interval.py b/direct/src/interval/Interval.py index 75eb336694..21a79f016a 100644 --- a/direct/src/interval/Interval.py +++ b/direct/src/interval/Interval.py @@ -452,14 +452,17 @@ class Interval(DirectObject): """ # Don't use a regular import, to prevent ModuleFinder from picking # it up as a dependency when building a .p3d package. - import importlib + import importlib, sys EntryScale = importlib.import_module('direct.tkwidgets.EntryScale') - Tkinter = importlib.import_module('Tkinter') + if sys.version_info >= (3, 0): + tkinter = importlib.import_module('tkinter') + else: + tkinter = importlib.import_module('Tkinter') if tl == None: - tl = Tkinter.Toplevel() + tl = tkinter.Toplevel() tl.title('Interval Controls') - outerFrame = Tkinter.Frame(tl) + outerFrame = tkinter.Frame(tl) def entryScaleCommand(t, s=self): s.setT(t) s.pause() @@ -468,8 +471,8 @@ class Interval(DirectObject): min = 0, max = math.floor(self.getDuration() * 100) / 100, command = entryScaleCommand) es.set(self.getT(), fCommand = 0) - es.pack(expand = 1, fill = Tkinter.X) - bf = Tkinter.Frame(outerFrame) + es.pack(expand = 1, fill = tkinter.X) + bf = tkinter.Frame(outerFrame) # Jump to start and end def toStart(s=self, es=es): s.clearToInitial() @@ -479,23 +482,23 @@ class Interval(DirectObject): s.setT(s.getDuration()) es.set(s.getDuration(), fCommand = 0) s.pause() - jumpToStart = Tkinter.Button(bf, text = '<<', command = toStart) + jumpToStart = tkinter.Button(bf, text = '<<', command = toStart) # Stop/play buttons def doPlay(s=self, es=es): s.resume(es.get()) - stop = Tkinter.Button(bf, text = 'Stop', + stop = tkinter.Button(bf, text = 'Stop', command = lambda s=self: s.pause()) - play = Tkinter.Button( + play = tkinter.Button( bf, text = 'Play', command = doPlay) - jumpToEnd = Tkinter.Button(bf, text = '>>', command = toEnd) - jumpToStart.pack(side = Tkinter.LEFT, expand = 1, fill = Tkinter.X) - play.pack(side = Tkinter.LEFT, expand = 1, fill = Tkinter.X) - stop.pack(side = Tkinter.LEFT, expand = 1, fill = Tkinter.X) - jumpToEnd.pack(side = Tkinter.LEFT, expand = 1, fill = Tkinter.X) - bf.pack(expand = 1, fill = Tkinter.X) - outerFrame.pack(expand = 1, fill = Tkinter.X) + jumpToEnd = tkinter.Button(bf, text = '>>', command = toEnd) + jumpToStart.pack(side = tkinter.LEFT, expand = 1, fill = tkinter.X) + play.pack(side = tkinter.LEFT, expand = 1, fill = tkinter.X) + stop.pack(side = tkinter.LEFT, expand = 1, fill = tkinter.X) + jumpToEnd.pack(side = tkinter.LEFT, expand = 1, fill = tkinter.X) + bf.pack(expand = 1, fill = tkinter.X) + outerFrame.pack(expand = 1, fill = tkinter.X) # Add function to update slider during setT calls def update(t, es=es): es.set(t, fCommand = 0) diff --git a/direct/src/interval/IntervalGlobal.py b/direct/src/interval/IntervalGlobal.py index d1589d268d..903f92d14f 100644 --- a/direct/src/interval/IntervalGlobal.py +++ b/direct/src/interval/IntervalGlobal.py @@ -4,23 +4,23 @@ # since the purpose of this module is to add up the contributions # of a number of other modules. -from Interval import * -from ActorInterval import * -from FunctionInterval import * -from LerpInterval import * -from IndirectInterval import * -from MopathInterval import * +from .Interval import * +from .ActorInterval import * +from .FunctionInterval import * +from .LerpInterval import * +from .IndirectInterval import * +from .MopathInterval import * try: import panda3d.physics ##Some people may have the particle system compiled out if hasattr( panda3d.physics, 'ParticleSystem' ): - from ParticleInterval import * + from .ParticleInterval import * if __debug__: - from TestInterval import * + from .TestInterval import * except ImportError: pass -from SoundInterval import * -from ProjectileInterval import * -from MetaInterval import * -from IntervalManager import * +from .SoundInterval import * +from .ProjectileInterval import * +from .MetaInterval import * +from .IntervalManager import * from panda3d.direct import WaitInterval diff --git a/direct/src/interval/IntervalTest.py b/direct/src/interval/IntervalTest.py index 4bbfc9db57..fce7e0f755 100644 --- a/direct/src/interval/IntervalTest.py +++ b/direct/src/interval/IntervalTest.py @@ -6,7 +6,7 @@ __all__ = [] if __name__ == "__main__": from direct.showbase.ShowBase import ShowBase from panda3d.core import * - from IntervalGlobal import * + from .IntervalGlobal import * from direct.actor.Actor import * from direct.directutil import Mopath @@ -72,7 +72,7 @@ if __name__ == "__main__": waterEventTrack.setIntervalStartTime('water-is-done', eventTime) def handleWaterDone(): - print 'water is done' + print('water is done') # Interval can handle its own event messenger.accept('water-is-done', waterDone, handleWaterDone) @@ -92,7 +92,7 @@ if __name__ == "__main__": i2 = FunctionInterval(lambda: base.transitions.fadeIn()) def caughtIt(): - print 'Caught here-is-an-event' + print('Caught here-is-an-event') class DummyAcceptor(DirectObject): pass @@ -106,7 +106,7 @@ if __name__ == "__main__": # Using a function def printDone(): - print 'done' + print('done') i6 = FunctionInterval(printDone) @@ -139,25 +139,25 @@ if __name__ == "__main__": def printStart(): global startTime startTime = globalClock.getFrameTime() - print 'Start' + print('Start') def printPreviousStart(): global startTime currTime = globalClock.getFrameTime() - print 'PREVIOUS_END %0.2f' % (currTime - startTime) + print('PREVIOUS_END %0.2f' % (currTime - startTime)) def printPreviousEnd(): global startTime currTime = globalClock.getFrameTime() - print 'PREVIOUS_END %0.2f' % (currTime - startTime) + print('PREVIOUS_END %0.2f' % (currTime - startTime)) def printTrackStart(): global startTime currTime = globalClock.getFrameTime() - print 'TRACK_START %0.2f' % (currTime - startTime) + print('TRACK_START %0.2f' % (currTime - startTime)) def printArguments(a, b, c): - print 'My args were %d, %d, %d' % (a, b, c) + print('My args were %d, %d, %d' % (a, b, c)) i1 = FunctionInterval(printStart) # Just to take time diff --git a/direct/src/interval/LerpInterval.py b/direct/src/interval/LerpInterval.py index 06271fc061..24435ae084 100644 --- a/direct/src/interval/LerpInterval.py +++ b/direct/src/interval/LerpInterval.py @@ -15,8 +15,8 @@ __all__ = [ from panda3d.core import * from panda3d.direct import * from direct.directnotify.DirectNotifyGlobal import * -import Interval -import LerpBlendHelpers +from . import Interval +from . import LerpBlendHelpers # # Most of the intervals defined in this module--the group up here at @@ -774,17 +774,17 @@ class LerpFunctionNoStateInterval(Interval.Interval): if (t >= self.duration): # Set to end value if (t > self.duration): - print "after end" + print("after end") #apply(self.function, [self.toData] + self.extraArgs) elif self.duration == 0.0: # Zero duration, just use endpoint - apply(self.function, [self.toData] + self.extraArgs) + self.function(*[self.toData] + self.extraArgs) else: # In the middle of the lerp, compute appropriate blended value bt = self.blendType(t/self.duration) data = (self.fromData * (1 - bt)) + (self.toData * bt) # Evaluate function - apply(self.function, [data] + self.extraArgs) + self.function(*[data] + self.extraArgs) # Print debug information # assert self.notify.debug('updateFunc() - %s: t = %f' % (self.name, t)) @@ -841,16 +841,16 @@ class LerpFunctionInterval(Interval.Interval): #print "doing priv step",t if (t >= self.duration): # Set to end value - apply(self.function, [self.toData] + self.extraArgs) + self.function(*[self.toData] + self.extraArgs) elif self.duration == 0.0: # Zero duration, just use endpoint - apply(self.function, [self.toData] + self.extraArgs) + self.function(*[self.toData] + self.extraArgs) else: # In the middle of the lerp, compute appropriate blended value bt = self.blendType(t/self.duration) data = (self.fromData * (1 - bt)) + (self.toData * bt) # Evaluate function - apply(self.function, [data] + self.extraArgs) + self.function(*[data] + self.extraArgs) # Print debug information # assert self.notify.debug('updateFunc() - %s: t = %f' % (self.name, t)) diff --git a/direct/src/interval/MetaInterval.py b/direct/src/interval/MetaInterval.py index 7ec7967662..d7b23afdeb 100644 --- a/direct/src/interval/MetaInterval.py +++ b/direct/src/interval/MetaInterval.py @@ -5,10 +5,9 @@ __all__ = ['MetaInterval', 'Sequence', 'Parallel', 'ParallelEndTogether', 'Track from panda3d.core import * from panda3d.direct import * from direct.directnotify.DirectNotifyGlobal import * -from IntervalManager import ivalMgr -import Interval +from .IntervalManager import ivalMgr +from . import Interval from direct.task.Task import TaskManager -import types #if __debug__: # import direct.showbase.PythonUtil as PythonUtil @@ -32,7 +31,7 @@ class MetaInterval(CMetaInterval): # "create interval", 1, 10) name = None - #if len(ivals) == 2 and isinstance(ivals[1], types.StringType): + #if len(ivals) == 2 and isinstance(ivals[1], str): # # If the second parameter is a string, it's the name. # name = ivals[1] # ivals = ivals[0] @@ -69,7 +68,7 @@ class MetaInterval(CMetaInterval): del kw['duration'] if kw: - self.notify.error("Unexpected keyword parameters: %s" % (kw.keys())) + self.notify.error("Unexpected keyword parameters: %s" % (list(kw.keys()))) # We must allow the old style: Track([ival0, ival1, ...]) as # well as the new style: Track(ival0, ival1, ...) @@ -80,8 +79,8 @@ class MetaInterval(CMetaInterval): # bug, since it will go away when we eventually remove support # for the old interface. #if len(ivals) == 1 and \ - # (isinstance(ivals[0], types.TupleType) or \ - # isinstance(ivals[0], types.ListType)): + # (isinstance(ivals[0], tuple) or \ + # isinstance(ivals[0], list)): # self.ivals = ivals[0] #else: @@ -121,7 +120,7 @@ class MetaInterval(CMetaInterval): def append(self, ival): # Appends a single interval to the list so far. - if isinstance(self.ivals, types.TupleType): + if isinstance(self.ivals, tuple): self.ivals = list(self.ivals) self.ivals.append(ival) self.__ivalsDirty = 1 @@ -141,7 +140,7 @@ class MetaInterval(CMetaInterval): def insert(self, index, ival): # Inserts the given interval into the middle of the list. - if isinstance(self.ivals, types.TupleType): + if isinstance(self.ivals, tuple): self.ivals = list(self.ivals) self.ivals.insert(index, ival) self.__ivalsDirty = 1 @@ -150,7 +149,7 @@ class MetaInterval(CMetaInterval): def pop(self, index = None): # Returns element index (or the last element) and removes it # from the list. - if isinstance(self.ivals, types.TupleType): + if isinstance(self.ivals, tuple): self.ivals = list(self.ivals) self.__ivalsDirty = 1 if index == None: @@ -160,21 +159,21 @@ class MetaInterval(CMetaInterval): def remove(self, ival): # Removes the indicated interval from the list. - if isinstance(self.ivals, types.TupleType): + if isinstance(self.ivals, tuple): self.ivals = list(self.ivals) self.ivals.remove(ival) self.__ivalsDirty = 1 def reverse(self): # Reverses the order of the intervals. - if isinstance(self.ivals, types.TupleType): + if isinstance(self.ivals, tuple): self.ivals = list(self.ivals) self.ivals.reverse() self.__ivalsDirty = 1 def sort(self, cmpfunc = None): # Sorts the intervals. (?) - if isinstance(self.ivals, types.TupleType): + if isinstance(self.ivals, tuple): self.ivals = list(self.ivals) self.__ivalsDirty = 1 if cmpfunc == None: @@ -189,38 +188,38 @@ class MetaInterval(CMetaInterval): return self.ivals[index] def __setitem__(self, index, value): - if isinstance(self.ivals, types.TupleType): + if isinstance(self.ivals, tuple): self.ivals = list(self.ivals) self.ivals[index] = value self.__ivalsDirty = 1 assert self.validateComponent(value) def __delitem__(self, index): - if isinstance(self.ivals, types.TupleType): + if isinstance(self.ivals, tuple): self.ivals = list(self.ivals) del self.ivals[index] self.__ivalsDirty = 1 def __getslice__(self, i, j): - if isinstance(self.ivals, types.TupleType): + if isinstance(self.ivals, tuple): self.ivals = list(self.ivals) return self.__class__(self.ivals[i: j]) def __setslice__(self, i, j, s): - if isinstance(self.ivals, types.TupleType): + if isinstance(self.ivals, tuple): self.ivals = list(self.ivals) self.ivals[i: j] = s self.__ivalsDirty = 1 assert self.validateComponents(s) def __delslice__(self, i, j): - if isinstance(self.ivals, types.TupleType): + if isinstance(self.ivals, tuple): self.ivals = list(self.ivals) del self.ivals[i: j] self.__ivalsDirty = 1 def __iadd__(self, other): - if isinstance(self.ivals, types.TupleType): + if isinstance(self.ivals, tuple): self.ivals = list(self.ivals) if isinstance(other, MetaInterval): assert self.__class__ == other.__class__ @@ -283,8 +282,8 @@ class MetaInterval(CMetaInterval): # is TRACK_START. self.pushLevel(name, relTime, relTo) for tuple in list: - if isinstance(tuple, types.TupleType) or \ - isinstance(tuple, types.ListType): + if isinstance(tuple, tuple) or \ + isinstance(tuple, list): relTime = tuple[0] ival = tuple[1] if len(tuple) >= 3: @@ -497,10 +496,10 @@ class MetaInterval(CMetaInterval): ival = None except: if ival != None: - print "Exception occurred while processing %s of %s:" % (ival.getName(), self.getName()) + print("Exception occurred while processing %s of %s:" % (ival.getName(), self.getName())) else: - print "Exception occurred while processing %s:" % (self.getName()) - print self + print("Exception occurred while processing %s:" % (self.getName())) + print(self) raise def privDoEvent(self, t, event): @@ -601,8 +600,8 @@ class Track(MetaInterval): # this is the same as asking that the component is itself an # Interval. - if not (isinstance(tuple, types.TupleType) or \ - isinstance(tuple, types.ListType)): + if not (isinstance(tuple, tuple) or \ + isinstance(tuple, list)): # It's not a tuple. return 0 @@ -613,8 +612,8 @@ class Track(MetaInterval): else: relTo = TRACK_START - if not (isinstance(relTime, types.FloatType) or \ - isinstance(relTime, types.IntType)): + if not (isinstance(relTime, float) or \ + isinstance(relTime, int)): # First parameter is not a number. return 0 if not MetaInterval.validateComponent(self, ival): diff --git a/direct/src/interval/MopathInterval.py b/direct/src/interval/MopathInterval.py index 0764b1bc12..83ea995caa 100644 --- a/direct/src/interval/MopathInterval.py +++ b/direct/src/interval/MopathInterval.py @@ -2,7 +2,7 @@ __all__ = ['MopathInterval'] -import LerpInterval +from . import LerpInterval from panda3d.core import * from panda3d.direct import * from direct.directnotify.DirectNotifyGlobal import * diff --git a/direct/src/interval/ParticleInterval.py b/direct/src/interval/ParticleInterval.py index 3682904fce..c373af7542 100644 --- a/direct/src/interval/ParticleInterval.py +++ b/direct/src/interval/ParticleInterval.py @@ -9,7 +9,7 @@ Contains the ParticleInterval class from panda3d.core import * from panda3d.direct import * from direct.directnotify.DirectNotifyGlobal import directNotify -from Interval import Interval +from .Interval import Interval class ParticleInterval(Interval): diff --git a/direct/src/interval/ProjectileInterval.py b/direct/src/interval/ProjectileInterval.py index 9b8942d5ab..a1b5d70014 100755 --- a/direct/src/interval/ProjectileInterval.py +++ b/direct/src/interval/ProjectileInterval.py @@ -5,7 +5,7 @@ __all__ = ['ProjectileInterval'] from panda3d.core import * from panda3d.direct import * from direct.directnotify.DirectNotifyGlobal import * -from Interval import Interval +from .Interval import Interval from direct.showbase import PythonUtil class ProjectileInterval(Interval): diff --git a/direct/src/interval/ProjectileIntervalTest.py b/direct/src/interval/ProjectileIntervalTest.py index 7e0b080d5a..bd747be382 100755 --- a/direct/src/interval/ProjectileIntervalTest.py +++ b/direct/src/interval/ProjectileIntervalTest.py @@ -4,7 +4,7 @@ __all__ = ['doTest'] from panda3d.core import * from panda3d.direct import * -from IntervalGlobal import * +from .IntervalGlobal import * def doTest(): smiley = loader.loadModel('models/misc/smiley') diff --git a/direct/src/interval/SoundInterval.py b/direct/src/interval/SoundInterval.py index ca38af297a..5927d14703 100644 --- a/direct/src/interval/SoundInterval.py +++ b/direct/src/interval/SoundInterval.py @@ -5,7 +5,7 @@ __all__ = ['SoundInterval'] from panda3d.core import * from panda3d.direct import * from direct.directnotify.DirectNotifyGlobal import * -import Interval +from . import Interval import random class SoundInterval(Interval.Interval): diff --git a/direct/src/interval/TestInterval.py b/direct/src/interval/TestInterval.py index 444ad20aaf..82a04b604e 100755 --- a/direct/src/interval/TestInterval.py +++ b/direct/src/interval/TestInterval.py @@ -9,7 +9,7 @@ Contains the ParticleInterval class from panda3d.core import * from panda3d.direct import * from direct.directnotify.DirectNotifyGlobal import directNotify -from Interval import Interval +from .Interval import Interval class TestInterval(Interval): diff --git a/direct/src/leveleditor/ActionMgr.py b/direct/src/leveleditor/ActionMgr.py index 041f6b4cf2..29d9ba3742 100755 --- a/direct/src/leveleditor/ActionMgr.py +++ b/direct/src/leveleditor/ActionMgr.py @@ -1,5 +1,5 @@ from pandac.PandaModules import * -import ObjectGlobals as OG +from . import ObjectGlobals as OG class ActionMgr: def __init__(self): @@ -22,7 +22,7 @@ class ActionMgr: def undo(self): if len(self.undoList) < 1: - print 'No more undo' + print('No more undo') else: action = self.undoList.pop() self.redoList.append(action) @@ -30,7 +30,7 @@ class ActionMgr: def redo(self): if len(self.redoList) < 1: - print 'No more redo' + print('No more redo') else: action = self.redoList.pop() self.undoList.append(action) @@ -70,7 +70,7 @@ class ActionBase(Functor): pass def undo(self): - print "undo method is not defined for this action" + print("undo method is not defined for this action") class ActionAddNewObj(ActionBase): """ Action class for adding new object """ @@ -88,16 +88,16 @@ class ActionAddNewObj(ActionBase): def redo(self): if self.uid is None: - print "Can't redo this add" + print("Can't redo this add") else: self.result = self._do__call__(uid=self.uid) return self.result def undo(self): if self.result is None: - print "Can't undo this add" + print("Can't undo this add") else: - print "Undo: addNewObject" + print("Undo: addNewObject") if self.uid: obj = self.editor.objectMgr.findObjectById(self.uid) else: @@ -109,7 +109,7 @@ class ActionAddNewObj(ActionBase): base.direct.removeNodePath(obj[OG.OBJ_NP]) self.result = None else: - print "Can't undo this add" + print("Can't undo this add") class ActionDeleteObj(ActionBase): """ Action class for deleting object """ @@ -150,11 +150,11 @@ class ActionDeleteObj(ActionBase): saveObjStatus(np, False) def undo(self): - if len(self.hierarchy.keys()) == 0 or\ - len(self.objInfos.keys()) == 0: - print "Can't undo this deletion" + if len(self.hierarchy) == 0 or\ + len(self.objInfos) == 0: + print("Can't undo this deletion") else: - print "Undo: deleteObject" + print("Undo: deleteObject") def restoreObject(uid, parentNP): obj = self.objInfos[uid] objDef = obj[OG.OBJ_DEF] @@ -169,8 +169,8 @@ class ActionDeleteObj(ActionBase): self.editor.objectMgr.updateObjectProperties(objNP, objProp) objNP.setMat(self.objTransforms[uid]) - while (len(self.hierarchy.keys()) > 0): - for uid in self.hierarchy.keys(): + while len(self.hierarchy) > 0: + for uid in self.hierarchy: if self.hierarchy[uid] is None: parentNP = None restoreObject(uid, parentNP) @@ -230,11 +230,11 @@ class ActionDeleteObjById(ActionBase): saveObjStatus(self.uid, True) def undo(self): - if len(self.hierarchy.keys()) == 0 or\ - len(self.objInfos.keys()) == 0: - print "Can't undo this deletion" + if len(self.hierarchy) == 0 or\ + len(self.objInfos) == 0: + print("Can't undo this deletion") else: - print "Undo: deleteObjectById" + print("Undo: deleteObjectById") def restoreObject(uid, parentNP): obj = self.objInfos[uid] objDef = obj[OG.OBJ_DEF] @@ -249,8 +249,8 @@ class ActionDeleteObjById(ActionBase): self.editor.objectMgr.updateObjectProperties(objNP, objProp) objNP.setMat(self.objTransforms[uid]) - while (len(self.hierarchy.keys()) > 0): - for uid in self.hierarchy.keys(): + while len(self.hierarchy) > 0: + for uid in self.hierarchy: if self.hierarchy[uid] is None: parentNP = None restoreObject(uid, parentNP) @@ -298,7 +298,7 @@ class ActionSelectObj(ActionBase): self.selectedUIDs.append(uid) def undo(self): - print "Undo : selectObject" + print("Undo : selectObject") base.direct.deselectAllCB() for uid in self.selectedUIDs: obj = self.editor.objectMgr.findObjectById(uid) @@ -332,9 +332,9 @@ class ActionTransformObj(ActionBase): def undo(self): if self.origMat is None: - print "Can't undo this transform" + print("Can't undo this transform") else: - print "Undo: transformObject" + print("Undo: transformObject") obj = self.editor.objectMgr.findObjectById(self.uid) if obj: obj[OG.OBJ_NP].setMat(self.origMat) @@ -360,7 +360,7 @@ class ActionDeselectAll(ActionBase): self.selectedUIDs.append(uid) def undo(self): - print "Undo : deselectAll" + print("Undo : deselectAll") base.direct.deselectAllCB() for uid in self.selectedUIDs: obj = self.editor.objectMgr.findObjectById(uid) @@ -391,7 +391,7 @@ class ActionUpdateObjectProp(ActionBase): return self.result def undo(self): - print "Undo : updateObjectProp" + print("Undo : updateObjectProp") if self.oldVal: self.obj[OG.OBJ_PROP][self.propName] = self.oldVal if self.undoFunc: diff --git a/direct/src/leveleditor/AnimControlUI.py b/direct/src/leveleditor/AnimControlUI.py index 71cf4168cf..2137da5c35 100755 --- a/direct/src/leveleditor/AnimControlUI.py +++ b/direct/src/leveleditor/AnimControlUI.py @@ -3,11 +3,9 @@ """ from direct.interval.IntervalGlobal import * from direct.actor.Actor import * -from panda3d.core import VBase3,VBase4 -import ObjectGlobals as OG -import AnimGlobals as AG +from . import ObjectGlobals as OG -import os,wx, time +import os, wx from wx.lib.embeddedimage import PyEmbeddedImage #---------------------------------------------------------------------- @@ -895,13 +893,13 @@ class AnimControlUI(wx.Dialog): del self.keys[i] break - for j in self.editor.animMgr.keyFramesInfo.keys(): + for j in list(self.editor.animMgr.keyFramesInfo.keys()): for k in range(0,len(self.editor.animMgr.keyFramesInfo[j])): if self.curFrame == self.editor.animMgr.keyFramesInfo[j][k][0]: del self.editor.animMgr.keyFramesInfo[j][k] break - for l in self.editor.animMgr.keyFramesInfo.keys(): + for l in list(self.editor.animMgr.keyFramesInfo.keys()): if len(self.editor.animMgr.keyFramesInfo[l]) == 0: del self.editor.animMgr.keyFramesInfo[l] diff --git a/direct/src/leveleditor/AnimMgr.py b/direct/src/leveleditor/AnimMgr.py index 6be3aa58f6..f57766f791 100755 --- a/direct/src/leveleditor/AnimMgr.py +++ b/direct/src/leveleditor/AnimMgr.py @@ -1,7 +1,7 @@ """ Defines AnimMgr """ -from AnimMgrBase import * +from .AnimMgrBase import * class AnimMgr(AnimMgrBase): """ Animation will create, manage, update animations in the scene """ diff --git a/direct/src/leveleditor/AnimMgrBase.py b/direct/src/leveleditor/AnimMgrBase.py index ecc0a55ae3..09cf49f73c 100755 --- a/direct/src/leveleditor/AnimMgrBase.py +++ b/direct/src/leveleditor/AnimMgrBase.py @@ -2,12 +2,12 @@ Defines AnimMgrBase """ -import os, wx, math +import os, math from direct.interval.IntervalGlobal import * -from panda3d.core import VBase3,VBase4 -import ObjectGlobals as OG -import AnimGlobals as AG +from panda3d.core import VBase3 +from . import ObjectGlobals as OG +from . import AnimGlobals as AG class AnimMgrBase: """ AnimMgr will create, manage, update animations in the scene """ @@ -47,7 +47,7 @@ class AnimMgrBase: def generateKeyFrames(self): #generate keyFrame list self.keyFrames = [] - for property in self.keyFramesInfo.keys(): + for property in list(self.keyFramesInfo.keys()): for frameInfo in self.keyFramesInfo[property]: frame = frameInfo[AG.FRAME] exist = False @@ -80,7 +80,7 @@ class AnimMgrBase: return def removeAnimInfo(self, uid): - for property in self.keyFramesInfo.keys(): + for property in list(self.keyFramesInfo.keys()): if property[AG.UID] == uid: del self.keyFramesInfo[property] self.generateKeyFrames() @@ -141,7 +141,7 @@ class AnimMgrBase: #generate key frame animation for normal property self.editor.objectMgr.findNodes(render) for node in self.editor.objectMgr.Nodes: - for property in self.keyFramesInfo.keys(): + for property in list(self.keyFramesInfo.keys()): if property[AG.UID] == node[OG.OBJ_UID] and property[AG.PROP_NAME] != 'X' and property[AG.PROP_NAME] != 'Y' and property[AG.PROP_NAME] != 'Z': mysequence = Sequence(name = node[OG.OBJ_UID]) keyFramesInfo = self.keyFramesInfo[property] @@ -166,7 +166,7 @@ class AnimMgrBase: #generate key frame animation for the property which is controled by animation curve self.editor.objectMgr.findNodes(render) for node in self.editor.objectMgr.Nodes: - for property in self.keyFramesInfo.keys(): + for property in list(self.keyFramesInfo.keys()): if property[AG.UID] == node[OG.OBJ_UID]: if property[AG.PROP_NAME] == 'X' or property[AG.PROP_NAME] == 'Y' or property[AG.PROP_NAME] == 'Z': mysequence = Sequence(name = node[OG.OBJ_UID]) diff --git a/direct/src/leveleditor/CurveAnimUI.py b/direct/src/leveleditor/CurveAnimUI.py index b779b2c615..ca99d1eca4 100755 --- a/direct/src/leveleditor/CurveAnimUI.py +++ b/direct/src/leveleditor/CurveAnimUI.py @@ -1,12 +1,12 @@ """ This is the GUI for the Curve Animation """ -import os, wx, time +import wx from direct.interval.IntervalGlobal import * from direct.actor.Actor import * -from direct.showutil.Rope import Rope -import ObjectGlobals as OG +from . import ObjectGlobals as OG + class CurveAnimUI(wx.Dialog): """ @@ -129,8 +129,8 @@ class CurveAnimUI(wx.Dialog): return hasKey = False - for key in self.editor.animMgr.curveAnimation.keys(): - if key == (self.nodePath[OG.OBJ_UID],self.curve[OG.OBJ_UID]): + for key in self.editor.animMgr.curveAnimation: + if key == (self.nodePath[OG.OBJ_UID], self.curve[OG.OBJ_UID]): dlg = wx.MessageDialog(None, 'Already have the animation for this object attach to this curve.', 'NOTICE', wx.OK ) dlg.ShowModal() dlg.Destroy() diff --git a/direct/src/leveleditor/CurveEditor.py b/direct/src/leveleditor/CurveEditor.py index bc1d907c22..b1acc04525 100755 --- a/direct/src/leveleditor/CurveEditor.py +++ b/direct/src/leveleditor/CurveEditor.py @@ -7,9 +7,9 @@ from direct.wxwidgets.WxPandaShell import * from direct.showbase.DirectObject import * from direct.directtools.DirectSelection import SelectionRay from direct.showutil.Rope import Rope -from ActionMgr import * +from .ActionMgr import * from direct.task import Task -import ObjectGlobals as OG + class CurveEditor(DirectObject): """ CurveEditor will create and edit the curve """ diff --git a/direct/src/leveleditor/FileMgr.py b/direct/src/leveleditor/FileMgr.py index c1b39fda98..a0b00d1a04 100755 --- a/direct/src/leveleditor/FileMgr.py +++ b/direct/src/leveleditor/FileMgr.py @@ -1,11 +1,6 @@ import os import imp -from ObjectMgr import ObjectMgr -from ObjectHandler import ObjectHandler -from ObjectPalette import ObjectPalette -from ProtoPalette import ProtoPalette -import ObjectGlobals as OG class FileMgr: """ To handle data file """ @@ -40,7 +35,7 @@ class FileMgr: self.editor.updateStatusReadout('Sucessfully saved to %s'%fileName) self.editor.fNeedToSave = False except IOError: - print 'failed to save %s'%fileName + print('failed to save %s'%fileName) if f: f.close() @@ -54,4 +49,4 @@ class FileMgr: self.editor.updateStatusReadout('Sucessfully opened file %s'%fileName) self.editor.fNeedToSave = False except: - print 'failed to load %s'%fileName + print('failed to load %s'%fileName) diff --git a/direct/src/leveleditor/GraphEditorUI.py b/direct/src/leveleditor/GraphEditorUI.py index 5e69cf6710..908fde08da 100755 --- a/direct/src/leveleditor/GraphEditorUI.py +++ b/direct/src/leveleditor/GraphEditorUI.py @@ -1,12 +1,11 @@ """ Defines Graph Editor """ -import os,wx +import wx import math -import cPickle as pickle -from PaletteTreeCtrl import * -import ObjectGlobals as OG -import AnimGlobals as AG +from .PaletteTreeCtrl import * +from . import ObjectGlobals as OG +from . import AnimGlobals as AG from wx.lib.embeddedimage import PyEmbeddedImage property = [ @@ -131,7 +130,7 @@ class GraphEditorWindow(wx.Window): if self._mainDialog.editor.animMgr.keyFramesInfo != {}: self.keyFramesInfo = self._mainDialog.editor.animMgr.keyFramesInfo - for key in self.keyFramesInfo.keys(): + for key in self.keyFramesInfo: if key == (self.object[OG.OBJ_UID], 'X'): for i in range(len(self.keyFramesInfo[key])): item = self.keyFramesInfo[key][i] diff --git a/direct/src/leveleditor/HotKeyUI.py b/direct/src/leveleditor/HotKeyUI.py index 8c8b442824..8cde68b0eb 100755 --- a/direct/src/leveleditor/HotKeyUI.py +++ b/direct/src/leveleditor/HotKeyUI.py @@ -89,8 +89,8 @@ class EditHotKeyDialog(wx.Dialog): newKeyStr = specialKey if newKeyStr != self.currKey: - if newKeyStr in base.direct.hotKeyMap.keys(): - print 'a hotkey is to be overridden with', newKeyStr + if newKeyStr in list(base.direct.hotKeyMap.keys()): + print('a hotkey is to be overridden with %s' % newKeyStr) oldKeyDesc = base.direct.hotKeyMap[newKeyStr] msg = 'The hotkey is already assigned to %s\n'%oldKeyDesc[0] +\ 'Do you want to override this?' @@ -116,7 +116,7 @@ class HotKeyPanel(ScrolledPanel): def updateUI(self): vbox = wx.BoxSizer(wx.VERTICAL) - keys = base.direct.hotKeyMap.keys() + keys = list(base.direct.hotKeyMap.keys()) keys.sort() for key in keys: keyDesc = base.direct.hotKeyMap[key] diff --git a/direct/src/leveleditor/LayerEditorUI.py b/direct/src/leveleditor/LayerEditorUI.py index 442d85d576..d77f8779bb 100644 --- a/direct/src/leveleditor/LayerEditorUI.py +++ b/direct/src/leveleditor/LayerEditorUI.py @@ -2,11 +2,9 @@ Defines Layer UI """ import wx -import sys -import cPickle as pickle from pandac.PandaModules import * -import ObjectGlobals as OG +from . import ObjectGlobals as OG class LayerEditorUI(wx.Panel): def __init__(self, parent, editor): @@ -160,7 +158,7 @@ class LayerEditorUI(wx.Panel): self.llist.SetItemState(index, wx.LIST_STATE_FOCUSED, wx.LIST_STATE_FOCUSED) def removeObjData(self, objUID): - layersDataDictKeys = self.layersDataDict.keys() + layersDataDictKeys = list(self.layersDataDict.keys()) for i in range(len(layersDataDictKeys)): layersData = self.layersDataDict[layersDataDictKeys[i]] for j in range(len(layersData)): @@ -247,7 +245,7 @@ class LayerEditorUI(wx.Panel): self.saveData.append(" ui.layerEditorUI.reset()") for index in range(self.llist.GetItemCount()): self.saveData.append(" ui.layerEditorUI.addLayerEntry('%s', %s )"%(self.llist.GetItemText(index), self.llist.GetItemData(index))) - layersDataDictKeys = self.layersDataDict.keys() + layersDataDictKeys = list(self.layersDataDict.keys()) for i in range(len(layersDataDictKeys)): layerData = self.layersDataDict[layersDataDictKeys[i]] for j in range(len(layerData)): diff --git a/direct/src/leveleditor/LevelEditor.py b/direct/src/leveleditor/LevelEditor.py index 43fd87f473..c1322c455d 100644 --- a/direct/src/leveleditor/LevelEditor.py +++ b/direct/src/leveleditor/LevelEditor.py @@ -5,13 +5,13 @@ LevelEditor, ObjectHandler, ObjectPalette should be rewritten to be game specific. """ -from LevelEditorUI import * -from LevelEditorBase import * -from ObjectMgr import * -from AnimMgr import * -from ObjectHandler import * -from ObjectPalette import * -from ProtoPalette import * +from .LevelEditorUI import * +from .LevelEditorBase import * +from .ObjectMgr import * +from .AnimMgr import * +from .ObjectHandler import * +from .ObjectPalette import * +from .ProtoPalette import * class LevelEditor(LevelEditorBase): """ Class for Panda3D LevelEditor """ diff --git a/direct/src/leveleditor/LevelEditorBase.py b/direct/src/leveleditor/LevelEditorBase.py index 68bcea9ec8..ad351a7e39 100755 --- a/direct/src/leveleditor/LevelEditorBase.py +++ b/direct/src/leveleditor/LevelEditorBase.py @@ -9,10 +9,10 @@ from direct.showbase.DirectObject import * from direct.directtools.DirectUtil import * from direct.gui.DirectGui import * -from CurveEditor import * -from FileMgr import * -from ActionMgr import * -from MayaConverter import * +from .CurveEditor import * +from .FileMgr import * +from .ActionMgr import * +from .MayaConverter import * class LevelEditorBase(DirectObject): """ Base Class for Panda3D LevelEditor """ diff --git a/direct/src/leveleditor/LevelEditorStart.py b/direct/src/leveleditor/LevelEditorStart.py index e9bccd920a..4ec577106c 100644 --- a/direct/src/leveleditor/LevelEditorStart.py +++ b/direct/src/leveleditor/LevelEditorStart.py @@ -1,4 +1,4 @@ -import LevelEditor +from . import LevelEditor if __name__ == '__main__': base.le = LevelEditor.LevelEditor() diff --git a/direct/src/leveleditor/LevelEditorUI.py b/direct/src/leveleditor/LevelEditorUI.py index 574c957239..9fec2d28d8 100755 --- a/direct/src/leveleditor/LevelEditorUI.py +++ b/direct/src/leveleditor/LevelEditorUI.py @@ -1,4 +1,4 @@ -from LevelEditorUIBase import * +from .LevelEditorUIBase import * class LevelEditorUI(LevelEditorUIBase): """ Class for Panda3D LevelEditor """ diff --git a/direct/src/leveleditor/LevelEditorUIBase.py b/direct/src/leveleditor/LevelEditorUIBase.py index 7b46e3eb02..f457f838d6 100755 --- a/direct/src/leveleditor/LevelEditorUIBase.py +++ b/direct/src/leveleditor/LevelEditorUIBase.py @@ -7,16 +7,16 @@ from direct.wxwidgets.WxPandaShell import * from direct.directtools.DirectSelection import SelectionRay #from ViewPort import * -from ObjectPaletteUI import * -from ObjectPropertyUI import * -from SceneGraphUI import * -from LayerEditorUI import * -from HotKeyUI import * -from ProtoPaletteUI import * -from ActionMgr import * -from AnimControlUI import * -from CurveAnimUI import * -from GraphEditorUI import * +from .ObjectPaletteUI import * +from .ObjectPropertyUI import * +from .SceneGraphUI import * +from .LayerEditorUI import * +from .HotKeyUI import * +from .ProtoPaletteUI import * +from .ActionMgr import * +from .AnimControlUI import * +from .CurveAnimUI import * +from .GraphEditorUI import * class PandaTextDropTarget(wx.TextDropTarget): def __init__(self, editor, view): @@ -32,7 +32,7 @@ class PandaTextDropTarget(wx.TextDropTarget): action = ActionAddNewObj(self.editor, text, parent=parentNPRef[0]) self.editor.actionMgr.push(action) newobj = action() - print newobj + print(newobj) if newobj is None: return @@ -584,12 +584,12 @@ class LevelEditorUIBase(WxPandaShell): def replaceObject(self, evt, all=False): currObj = self.editor.objectMgr.findObjectByNodePath(base.direct.selected.last) if currObj is None: - print 'No valid object is selected for replacement' + print('No valid object is selected for replacement') return targetType = self.editor.ui.objectPaletteUI.getSelected() if targetType is None: - print 'No valid target type is selected for replacement' + print('No valid target type is selected for replacement') return if all: diff --git a/direct/src/leveleditor/LevelLoader.py b/direct/src/leveleditor/LevelLoader.py index 77824aaa37..79f4a6644c 100755 --- a/direct/src/leveleditor/LevelLoader.py +++ b/direct/src/leveleditor/LevelLoader.py @@ -16,8 +16,8 @@ from direct.leveleditor.LevelLoaderBase import LevelLoaderBase from direct.leveleditor.ObjectMgr import ObjectMgr from direct.leveleditor.ProtoPalette import ProtoPalette from direct.leveleditor import ObjectGlobals as OG -from ObjectHandler import ObjectHandler -from ObjectPalette import ObjectPalette +from .ObjectHandler import ObjectHandler +from .ObjectPalette import ObjectPalette class LevelLoader(LevelLoaderBase): def __init__(self): diff --git a/direct/src/leveleditor/LevelLoaderBase.py b/direct/src/leveleditor/LevelLoaderBase.py index c5b9c6b907..1e3489e96b 100755 --- a/direct/src/leveleditor/LevelLoaderBase.py +++ b/direct/src/leveleditor/LevelLoaderBase.py @@ -33,5 +33,5 @@ class LevelLoaderBase: module = imp.load_module(fileName, file, pathname, description) return True except: - print 'failed to load %s'%fileName + print('failed to load %s'%fileName) return None diff --git a/direct/src/leveleditor/MayaConverter.py b/direct/src/leveleditor/MayaConverter.py index cf13b1259d..6c1feb4db1 100755 --- a/direct/src/leveleditor/MayaConverter.py +++ b/direct/src/leveleditor/MayaConverter.py @@ -1,6 +1,6 @@ from direct.wxwidgets.WxAppShell import * -import os, re, shutil -import ObjectGlobals as OG +import os +from . import ObjectGlobals as OG CLOSE_STDIN = "" @@ -30,7 +30,7 @@ class Process: #some platforms (like Windows) will send some small number #of bytes per .write() call (sometimes 2 in the case of #Windows). - self.b.extend([input[i:i+512] for i in xrange(0, len(input), 512)]) + self.b.extend([input[i:i+512] for i in range(0, len(input), 512)]) input = self.b.pop(0) self.process._stdin_.write(input) if hasattr(self.process._stdin_, "LastWrite"): diff --git a/direct/src/leveleditor/ObjectHandler.py b/direct/src/leveleditor/ObjectHandler.py index e51bf2b8fb..b93fc82ddb 100755 --- a/direct/src/leveleditor/ObjectHandler.py +++ b/direct/src/leveleditor/ObjectHandler.py @@ -7,7 +7,7 @@ to be game specific. from direct.actor import Actor -import ObjectGlobals as OG +from . import ObjectGlobals as OG class ObjectHandler: """ ObjectHandler will create and update objects """ diff --git a/direct/src/leveleditor/ObjectMgr.py b/direct/src/leveleditor/ObjectMgr.py index d3219dde70..d80f8d4439 100755 --- a/direct/src/leveleditor/ObjectMgr.py +++ b/direct/src/leveleditor/ObjectMgr.py @@ -1,7 +1,7 @@ """ Defines ObjectMgr """ -from ObjectMgrBase import * +from .ObjectMgrBase import * class ObjectMgr(ObjectMgrBase): """ ObjectMgr will create, manage, update objects in the scene """ diff --git a/direct/src/leveleditor/ObjectMgrBase.py b/direct/src/leveleditor/ObjectMgrBase.py index bb16f47e4d..3a65d6a998 100755 --- a/direct/src/leveleditor/ObjectMgrBase.py +++ b/direct/src/leveleditor/ObjectMgrBase.py @@ -2,14 +2,13 @@ Defines ObjectMgrBase """ -import os, time, wx, types, copy +import os, time, copy from direct.task import Task from direct.actor.Actor import Actor from pandac.PandaModules import * -from ActionMgr import * -import ObjectGlobals as OG -from ObjectPaletteBase import ObjectGen +from .ActionMgr import * +from . import ObjectGlobals as OG # python wrapper around a panda.NodePath object class PythonNodePath(NodePath): @@ -41,14 +40,14 @@ class ObjectMgrBase: def reset(self): base.direct.deselectAllCB() - for id in self.objects.keys(): + for id in list(self.objects.keys()): try: self.objects[id][OG.OBJ_NP].removeNode() except: pass del self.objects[id] - for np in self.npIndex.keys(): + for np in list(self.npIndex.keys()): del self.npIndex[np] self.objects = {} @@ -179,13 +178,13 @@ class ObjectMgrBase: funcName = objDef.createFunction[OG.FUNC_NAME] funcArgs = copy.deepcopy(objDef.createFunction[OG.FUNC_ARGS]) - for pair in funcArgs.items(): + for pair in list(funcArgs.items()): if pair[1] == OG.ARG_NAME: funcArgs[pair[0]] = nameStr elif pair[1] == OG.ARG_PARENT: funcArgs[pair[0]] = parent - if type(funcName) == types.StringType: + if type(funcName) == str: if funcName.startswith('.'): # when it's using default objectHandler if self.editor: @@ -512,7 +511,7 @@ class ObjectMgrBase: else: newobjModel = loader.loadModel(model, okMissing=True) if newobjModel is None: - print "Can't load model %s"%model + print("Can't load model %s"%model) return self.flatten(newobjModel, model, objDef, uid) newobj = PythonNodePath(newobjModel) @@ -683,7 +682,7 @@ class ObjectMgrBase: kwargs[key] = funcArgs[key] undoKwargs[key] = funcArgs[key] - if type(funcName) == types.StringType: + if type(funcName) == str: if funcName.startswith('.'): if self.editor: func = Functor(getattr(self.editor, "objectHandler%s"%funcName), **kwargs) diff --git a/direct/src/leveleditor/ObjectPalette.py b/direct/src/leveleditor/ObjectPalette.py index 4b08ad1360..ff254cbb9c 100755 --- a/direct/src/leveleditor/ObjectPalette.py +++ b/direct/src/leveleditor/ObjectPalette.py @@ -14,7 +14,7 @@ Then you need implement ObjectPalette class inheriting ObjectPaletteBase, and in the populate function you can define ObjectPalette tree structure. """ -from ObjectPaletteBase import * +from .ObjectPaletteBase import * class ObjectProp(ObjectBase): def __init__(self, *args, **kw): diff --git a/direct/src/leveleditor/ObjectPaletteBase.py b/direct/src/leveleditor/ObjectPaletteBase.py index 1946926c89..5bbfe38e50 100755 --- a/direct/src/leveleditor/ObjectPaletteBase.py +++ b/direct/src/leveleditor/ObjectPaletteBase.py @@ -1,5 +1,5 @@ import copy -import ObjectGlobals as OG +from . import ObjectGlobals as OG class ObjectGen: """ Base class for obj definitions """ @@ -82,7 +82,7 @@ class ObjectPaletteBase: def deleteStruct(self, name, deleteItems): try: item = self.data.pop(name) - for key in self.dataStruct.keys(): + for key in list(self.dataStruct.keys()): if self.dataStruct[key] == name: node = self.deleteStruct(key, deleteItems) if node is not None: @@ -98,7 +98,7 @@ class ObjectPaletteBase: node = self.deleteStruct(name, deleteItems) if node is not None: deleteItems[name] = node - for key in deleteItems.keys(): + for key in list(deleteItems.keys()): item = self.dataStruct.pop(key) except: return @@ -126,7 +126,7 @@ class ObjectPaletteBase: if newName == "": return False try: - for key in self.dataStruct.keys(): + for key in list(self.dataStruct.keys()): if self.dataStruct[key] == oldName: self.dataStruct[key] = newName diff --git a/direct/src/leveleditor/ObjectPaletteUI.py b/direct/src/leveleditor/ObjectPaletteUI.py index 4c9fa92d3d..bf84e3d492 100755 --- a/direct/src/leveleditor/ObjectPaletteUI.py +++ b/direct/src/leveleditor/ObjectPaletteUI.py @@ -2,8 +2,8 @@ Defines ObjectPalette tree UI """ import wx -import cPickle as pickle -from PaletteTreeCtrl import * +from .PaletteTreeCtrl import * + class ObjectPaletteUI(wx.Panel): def __init__(self, parent, editor): diff --git a/direct/src/leveleditor/ObjectPropertyUI.py b/direct/src/leveleditor/ObjectPropertyUI.py index 0be0910523..08adb8b784 100755 --- a/direct/src/leveleditor/ObjectPropertyUI.py +++ b/direct/src/leveleditor/ObjectPropertyUI.py @@ -10,8 +10,8 @@ from wx.lib.scrolledpanel import ScrolledPanel from wx.lib.agw.cubecolourdialog import * from direct.wxwidgets.WxSlider import * from pandac.PandaModules import * -import ObjectGlobals as OG -import AnimGlobals as AG +from . import ObjectGlobals as OG +from . import AnimGlobals as AG #---------------------------------------------------------------------- Key = PyEmbeddedImage( @@ -495,14 +495,14 @@ class ObjectPropertyUI(ScrolledPanel): sizer = wx.BoxSizer(wx.VERTICAL) propNames = objDef.orderedProperties[:] - for key in objDef.properties.keys(): + for key in list(objDef.properties.keys()): if key not in propNames: propNames.append(key) for key in propNames: # handling properties mask propMask = BitMask32() - for modeKey in objDef.propertiesMask.keys(): + for modeKey in list(objDef.propertiesMask.keys()): if key in objDef.propertiesMask[modeKey]: propMask |= modeKey diff --git a/direct/src/leveleditor/PaletteTreeCtrl.py b/direct/src/leveleditor/PaletteTreeCtrl.py index f774f0dac5..c4a5d46fce 100644 --- a/direct/src/leveleditor/PaletteTreeCtrl.py +++ b/direct/src/leveleditor/PaletteTreeCtrl.py @@ -2,8 +2,8 @@ Defines Palette tree control """ import wx -import cPickle as pickle -from ObjectPaletteBase import * +from .ObjectPaletteBase import * + class PaletteTreeCtrl(wx.TreeCtrl): def __init__(self, parent, treeStyle, rootName): @@ -155,7 +155,7 @@ class PaletteTreeCtrl(wx.TreeCtrl): if item != self.GetRootItem(): # prevent dragging root item text = self.GetItemText(item) - print "Starting drag'n'drop with %s..." % repr(text) + print("Starting drag'n'drop with %s..." % repr(text)) tdo = wx.TextDataObject(text) tds = wx.DropSource(self) diff --git a/direct/src/leveleditor/ProtoObjs.py b/direct/src/leveleditor/ProtoObjs.py index a1bc137a3e..a8e2c7bd34 100755 --- a/direct/src/leveleditor/ProtoObjs.py +++ b/direct/src/leveleditor/ProtoObjs.py @@ -3,7 +3,7 @@ Palette for Prototyping """ import os import imp -import types + class ProtoObjs: def __init__(self, name): @@ -19,7 +19,7 @@ class ProtoObjs: module = imp.load_module(moduleName, file, pathname, description) self.data = module.protoData except: - print "%s doesn't exist"%(self.name) + print("%s doesn't exist"%(self.name)) return def saveProtoData(self, f): diff --git a/direct/src/leveleditor/ProtoObjsUI.py b/direct/src/leveleditor/ProtoObjsUI.py index 67fb60f4b9..63222e3a2d 100755 --- a/direct/src/leveleditor/ProtoObjsUI.py +++ b/direct/src/leveleditor/ProtoObjsUI.py @@ -3,10 +3,9 @@ Defines ProtoObjs List UI """ import wx import os -import cPickle as pickl from pandac.PandaModules import * -from ProtoObjs import * +from .ProtoObjs import * class ProtoDropTarget(wx.PyDropTarget): """Implements drop target functionality to receive files, bitmaps and text""" @@ -73,7 +72,7 @@ class ProtoObjsUI(wx.Panel): self.SetDropTarget(ProtoDropTarget(self)) def populate(self): - for key in self.protoObjs.data.keys(): + for key in list(self.protoObjs.data.keys()): self.add(self.protoObjs.data[key]) # All subclasses should implement this method diff --git a/direct/src/leveleditor/ProtoPalette.py b/direct/src/leveleditor/ProtoPalette.py index b796e712fa..0f8aacee3b 100755 --- a/direct/src/leveleditor/ProtoPalette.py +++ b/direct/src/leveleditor/ProtoPalette.py @@ -2,7 +2,7 @@ Palette for Prototyping """ -from ProtoPaletteBase import * +from .ProtoPaletteBase import * class ProtoPalette(ProtoPaletteBase): def __init__(self): diff --git a/direct/src/leveleditor/ProtoPaletteBase.py b/direct/src/leveleditor/ProtoPaletteBase.py index 3c0c5bdd1c..9d9aa3775f 100755 --- a/direct/src/leveleditor/ProtoPaletteBase.py +++ b/direct/src/leveleditor/ProtoPaletteBase.py @@ -1,11 +1,9 @@ """ Palette for Prototyping """ -import os import imp -import types -from ObjectPaletteBase import * +from .ObjectPaletteBase import * class ProtoPaletteBase(ObjectPaletteBase): def __init__(self): @@ -14,9 +12,9 @@ class ProtoPaletteBase(ObjectPaletteBase): assert self.dirname def addItems(self): - if type(protoData) == types.DictType: - for key in protoData.keys(): - if type(protoData[key]) == types.DictType: + if type(protoData) == dict: + for key in list(protoData.keys()): + if type(protoData[key]) == dict: self.add(key, parent) self.addItems(protoData[key], key) else: @@ -30,7 +28,7 @@ class ProtoPaletteBase(ObjectPaletteBase): self.data = module.protoData self.dataStruct = module.protoDataStruct except: - print "protoPaletteData doesn't exist" + print("protoPaletteData doesn't exist") return #self.addItems() @@ -39,14 +37,14 @@ class ProtoPaletteBase(ObjectPaletteBase): if not f: return - for key in self.dataStruct.keys(): + for key in list(self.dataStruct.keys()): f.write("\t'%s':'%s',\n"%(key, self.dataStruct[key])) def saveProtoData(self, f): if not f: return - for key in self.data.keys(): + for key in list(self.data.keys()): if isinstance(self.data[key], ObjectBase): f.write("\t'%s':ObjectBase(name='%s', model='%s', anims=%s, actor=%s),\n"%(key, self.data[key].name, self.data[key].model, self.data[key].anims, self.data[key].actor)) else: diff --git a/direct/src/leveleditor/ProtoPaletteUI.py b/direct/src/leveleditor/ProtoPaletteUI.py index 7c19e85754..d9f047b55f 100755 --- a/direct/src/leveleditor/ProtoPaletteUI.py +++ b/direct/src/leveleditor/ProtoPaletteUI.py @@ -3,9 +3,8 @@ Defines ProtoPalette tree UI """ import wx import os -import cPickle as pickl from pandac.PandaModules import * -from PaletteTreeCtrl import * +from .PaletteTreeCtrl import * class UniversalDropTarget(wx.PyDropTarget): """Implements drop target functionality to receive files, bitmaps and text""" @@ -89,7 +88,7 @@ class ProtoPaletteUI(wx.Panel): self.SetDropTarget(UniversalDropTarget(self.editor)) def populate(self): - dataStructKeys = self.palette.dataStruct.keys()[:] + dataStructKeys = list(self.palette.dataStruct.keys()) self.tree.addTreeNodes(self.tree.GetRootItem(), self.palette.rootName, self.palette.dataStruct, dataStructKeys) def OnBeginLabelEdit(self, event): @@ -199,7 +198,7 @@ class ProtoPaletteUI(wx.Panel): if self.opSort == self.opSortAlpha: return cmp(data1, data2) else: - items = self.palette.data.keys()[:] + items = list(self.palette.data.keys()) index1 = items.index(data1) index2 = items.index(data2) return cmp(index1, index2) diff --git a/direct/src/leveleditor/SceneGraphUI.py b/direct/src/leveleditor/SceneGraphUI.py index 0a6ca41b69..f3c99e617b 100755 --- a/direct/src/leveleditor/SceneGraphUI.py +++ b/direct/src/leveleditor/SceneGraphUI.py @@ -1,7 +1,7 @@ """ Defines Scene Graph tree UI """ -from SceneGraphUIBase import * +from .SceneGraphUIBase import * class SceneGraphUI(SceneGraphUIBase): def __init__(self, parent, editor): diff --git a/direct/src/leveleditor/SceneGraphUIBase.py b/direct/src/leveleditor/SceneGraphUIBase.py index b8c4bc9b7e..c98cf8505c 100755 --- a/direct/src/leveleditor/SceneGraphUIBase.py +++ b/direct/src/leveleditor/SceneGraphUIBase.py @@ -2,20 +2,19 @@ Defines Scene Graph tree UI Base """ import wx -import cPickle as pickle from pandac.PandaModules import * -from ActionMgr import * +from .ActionMgr import * -import ObjectGlobals as OG +from . import ObjectGlobals as OG class SceneGraphUIDropTarget(wx.TextDropTarget): def __init__(self, editor): - print "in SceneGraphUIDropTarget::init..." + print("in SceneGraphUIDropTarget::init...") wx.TextDropTarget.__init__(self) self.editor = editor def OnDropText(self, x, y, text): - print "in SceneGraphUIDropTarget::OnDropText..." + print("in SceneGraphUIDropTarget::OnDropText...") self.editor.ui.sceneGraphUI.changeHierarchy(text, x, y) class SceneGraphUIBase(wx.Panel): @@ -299,7 +298,7 @@ class SceneGraphUIBase(wx.Panel): if item != self.tree.GetRootItem(): # prevent dragging root item text = self.tree.GetItemText(item) - print "Starting SceneGraphUI drag'n'drop with %s..." % repr(text) + print("Starting SceneGraphUI drag'n'drop with %s..." % repr(text)) tdo = wx.TextDataObject(text) tds = wx.DropSource(self.tree) diff --git a/direct/src/motiontrail/MotionTrail.py b/direct/src/motiontrail/MotionTrail.py index f678b34c7e..db891548ac 100644 --- a/direct/src/motiontrail/MotionTrail.py +++ b/direct/src/motiontrail/MotionTrail.py @@ -11,14 +11,14 @@ def remove_task ( ): if (MotionTrail.task_added): total_motion_trails = len (MotionTrail.motion_trail_list) - if (total_motion_trails > 0): - print "warning:", total_motion_trails, "motion trails still exist when motion trail task is removed" + if total_motion_trails > 0: + print("warning: %d motion trails still exist when motion trail task is removed" % (total_motion_trails)) MotionTrail.motion_trail_list = [ ] taskMgr.remove (MotionTrail.motion_trail_task_name) - print "MotionTrail task removed" + print("MotionTrail task removed") MotionTrail.task_added = False return @@ -149,10 +149,10 @@ class MotionTrail(NodePath, DirectObject): def print_matrix (self, matrix): separator = ' ' - print matrix.getCell (0, 0), separator, matrix.getCell (0, 1), separator, matrix.getCell (0, 2), separator, matrix.getCell (0, 3) - print matrix.getCell (1, 0), separator, matrix.getCell (1, 1), separator, matrix.getCell (1, 2), separator, matrix.getCell (1, 3) - print matrix.getCell (2, 0), separator, matrix.getCell (2, 1), separator, matrix.getCell (2, 2), separator, matrix.getCell (2, 3) - print matrix.getCell (3, 0), separator, matrix.getCell (3, 1), separator, matrix.getCell (3, 2), separator, matrix.getCell (3, 3) + print(matrix.getCell (0, 0), separator, matrix.getCell (0, 1), separator, matrix.getCell (0, 2), separator, matrix.getCell (0, 3)) + print(matrix.getCell (1, 0), separator, matrix.getCell (1, 1), separator, matrix.getCell (1, 2), separator, matrix.getCell (1, 3)) + print(matrix.getCell (2, 0), separator, matrix.getCell (2, 1), separator, matrix.getCell (2, 2), separator, matrix.getCell (2, 3)) + print(matrix.getCell (3, 0), separator, matrix.getCell (3, 1), separator, matrix.getCell (3, 2), separator, matrix.getCell (3, 3)) def motion_trail_task (self, task): @@ -379,8 +379,8 @@ class MotionTrail(NodePath, DirectObject): elapsed_time = current_time - self.fade_start_time if (elapsed_time < 0.0): + print("elapsed_time < 0: %f" % (elapsed_time)) elapsed_time = 0.0 - print "elapsed_time < 0", elapsed_time if (elapsed_time < self.fade_time): color_scale = (1.0 - (elapsed_time / self.fade_time)) * color_scale diff --git a/direct/src/p3d/AppRunner.py b/direct/src/p3d/AppRunner.py index 0fd46de469..4a59e20de6 100644 --- a/direct/src/p3d/AppRunner.py +++ b/direct/src/p3d/AppRunner.py @@ -13,7 +13,11 @@ __all__ = ["AppRunner", "dummyAppRunner", "ArgumentError"] import sys import os -import __builtin__ as builtins + +if sys.version_info >= (3, 0): + import builtins +else: + import __builtin__ as builtins from direct.showbase import VFSImporter from direct.showbase.DirectObject import DirectObject diff --git a/direct/src/p3d/DeploymentTools.py b/direct/src/p3d/DeploymentTools.py index 8d03fd94bc..5d63e0e6f5 100644 --- a/direct/src/p3d/DeploymentTools.py +++ b/direct/src/p3d/DeploymentTools.py @@ -5,7 +5,7 @@ to build for as many platforms as possible. """ __all__ = ["Standalone", "Installer"] import os, sys, subprocess, tarfile, shutil, time, zipfile, socket, getpass, struct -import gzip +import gzip, plistlib from io import BytesIO, TextIOWrapper from direct.directnotify.DirectNotifyGlobal import * from direct.showbase.AppRunnerGlobal import appRunner @@ -22,6 +22,9 @@ try: except ImportError: pwd = None +if sys.version_info >= (3, 0): + xrange = range + # Make sure this matches with the magic in p3dEmbedMain.cxx. P3DEMBED_MAGIC = 0xFF3D3D00 @@ -758,20 +761,20 @@ class Installer: desktopFile.setText() desktopFile.makeDir() desktop = open(desktopFile.toOsSpecific(), 'w') - print >>desktop, "[Desktop Entry]" - print >>desktop, "Name=%s" % self.fullname - print >>desktop, "Exec=%s" % self.shortname.lower() + desktop.write("[Desktop Entry]\n") + desktop.write("Name=%s\n" % self.fullname) + desktop.write("Exec=%s\n" % self.shortname.lower()) if iconFile is not None: - print >>desktop, "Icon=%s" % iconFile.getBasename() + desktop.write("Icon=%s\n" % iconFile.getBasename()) # Set the "Terminal" option based on whether or not a console env is requested cEnv = self.standalone.tokens.get("console_environment", "") if cEnv == "" or int(cEnv) == 0: - print >>desktop, "Terminal=false" + desktop.write("Terminal=false\n") else: - print >>desktop, "Terminal=true" + desktop.write("Terminal=true\n") - print >>desktop, "Type=Application" + desktop.write("Type=Application\n") desktop.close() if self.includeRequires or self.extracts: @@ -942,45 +945,25 @@ class Installer: Installer.notify.info("Generating %s.icns..." % self.shortname) hasIcon = self.icon.makeICNS(Filename(hostDir, "%s.icns" % self.shortname)) - # Create the application plist file. - # Although it might make more sense to use Python's plistlib module here, - # it is not available on non-OSX systems before Python 2.6. - plist = open(Filename(output, "Contents/Info.plist").toOsSpecific(), "w") - print >>plist, '' - print >>plist, '' - print >>plist, '' - print >>plist, '' - print >>plist, '\tCFBundleDevelopmentRegion' - print >>plist, '\tEnglish' - print >>plist, '\tCFBundleDisplayName' - print >>plist, '\t%s' % self.fullname - print >>plist, '\tCFBundleExecutable' - print >>plist, '\t%s' % exefile.getBasename() + # Create the application plist file using Python's plistlib module. + plist = { + 'CFBundleDevelopmentRegion': 'English', + 'CFBundleDisplayName': self.fullname, + 'CFBundleExecutable': exefile.getBasename(), + 'CFBundleIdentifier': '%s.%s' % (self.author, self.shortname), + 'CFBundleInfoDictionaryVersion': '6.0', + 'CFBundleName': self.shortname, + 'CFBundlePackageType': 'APPL', + 'CFBundleShortVersionString': self.version, + 'CFBundleVersion': self.version, + 'LSHasLocalizedDisplayName': False, + 'NSAppleScriptEnabled': False, + 'NSPrincipalClass': 'NSApplication', + } if hasIcon: - print >>plist, '\tCFBundleIconFile' - print >>plist, '\t%s.icns' % self.shortname - print >>plist, '\tCFBundleIdentifier' - print >>plist, '\t%s.%s' % (self.authorid, self.shortname) - print >>plist, '\tCFBundleInfoDictionaryVersion' - print >>plist, '\t6.0' - print >>plist, '\tCFBundleName' - print >>plist, '\t%s' % self.shortname - print >>plist, '\tCFBundlePackageType' - print >>plist, '\tAPPL' - print >>plist, '\tCFBundleShortVersionString' - print >>plist, '\t%s' % self.version - print >>plist, '\tCFBundleVersion' - print >>plist, '\t%s' % self.version - print >>plist, '\tLSHasLocalizedDisplayName' - print >>plist, '\t' - print >>plist, '\tNSAppleScriptEnabled' - print >>plist, '\t' - print >>plist, '\tNSPrincipalClass' - print >>plist, '\tNSApplication' - print >>plist, '' - print >>plist, '' - plist.close() + plist['CFBundleIconFile'] = self.shortname + '.icns' + plistlib.writePlist(plist, Filename(output, "Contents/Info.plist").toOsSpecific()) return output def buildPKG(self, output, platform): @@ -1221,73 +1204,73 @@ class Installer: nsi = open(nsifile.toOsSpecific(), "w") # Some global info - print >>nsi, 'Name "%s"' % self.fullname - print >>nsi, 'OutFile "%s"' % output.toOsSpecific() + nsi.write('Name "%s"\n' % self.fullname) + nsi.write('OutFile "%s"\n' % output.toOsSpecific()) if platform == 'win_amd64': - print >>nsi, 'InstallDir "$PROGRAMFILES64\\%s"' % self.fullname + nsi.write('InstallDir "$PROGRAMFILES64\\%s"\n' % self.fullname) else: - print >>nsi, 'InstallDir "$PROGRAMFILES\\%s"' % self.fullname - print >>nsi, 'SetCompress auto' - print >>nsi, 'SetCompressor lzma' - print >>nsi, 'ShowInstDetails nevershow' - print >>nsi, 'ShowUninstDetails nevershow' - print >>nsi, 'InstType "Typical"' + nsi.write('InstallDir "$PROGRAMFILES\\%s"\n' % self.fullname) + nsi.write('SetCompress auto\n') + nsi.write('SetCompressor lzma\n') + nsi.write('ShowInstDetails nevershow\n') + nsi.write('ShowUninstDetails nevershow\n') + nsi.write('InstType "Typical"\n') # Tell Vista that we require admin rights - print >>nsi, 'RequestExecutionLevel admin' - print >>nsi + nsi.write('RequestExecutionLevel admin\n') + nsi.write('\n') if self.offerRun: - print >>nsi, 'Function launch' - print >>nsi, ' ExecShell "open" "$INSTDIR\\%s.exe"' % self.shortname - print >>nsi, 'FunctionEnd' - print >>nsi + nsi.write('Function launch\n') + nsi.write(' ExecShell "open" "$INSTDIR\\%s.exe"\n' % self.shortname) + nsi.write('FunctionEnd\n') + nsi.write('\n') if self.offerDesktopShortcut: - print >>nsi, 'Function desktopshortcut' + nsi.write('Function desktopshortcut\n') if icofile is None: - print >>nsi, ' CreateShortcut "$DESKTOP\\%s.lnk" "$INSTDIR\\%s.exe"' % (self.fullname, self.shortname) + nsi.write(' CreateShortcut "$DESKTOP\\%s.lnk" "$INSTDIR\\%s.exe"\n' % (self.fullname, self.shortname)) else: - print >>nsi, ' CreateShortcut "$DESKTOP\\%s.lnk" "$INSTDIR\\%s.exe" "" "$INSTDIR\\%s.ico"' % (self.fullname, self.shortname, self.shortname) - print >>nsi, 'FunctionEnd' - print >>nsi + nsi.write(' CreateShortcut "$DESKTOP\\%s.lnk" "$INSTDIR\\%s.exe" "" "$INSTDIR\\%s.ico"\n' % (self.fullname, self.shortname, self.shortname)) + nsi.write('FunctionEnd\n') + nsi.write('\n') - print >>nsi, '!include "MUI2.nsh"' - print >>nsi, '!define MUI_ABORTWARNING' + nsi.write('!include "MUI2.nsh"\n') + nsi.write('!define MUI_ABORTWARNING\n') if self.offerRun: - print >>nsi, '!define MUI_FINISHPAGE_RUN' - print >>nsi, '!define MUI_FINISHPAGE_RUN_NOTCHECKED' - print >>nsi, '!define MUI_FINISHPAGE_RUN_FUNCTION launch' - print >>nsi, '!define MUI_FINISHPAGE_RUN_TEXT "Run %s"' % self.fullname + nsi.write('!define MUI_FINISHPAGE_RUN\n') + nsi.write('!define MUI_FINISHPAGE_RUN_NOTCHECKED\n') + nsi.write('!define MUI_FINISHPAGE_RUN_FUNCTION launch\n') + nsi.write('!define MUI_FINISHPAGE_RUN_TEXT "Run %s"\n' % self.fullname) if self.offerDesktopShortcut: - print >>nsi, '!define MUI_FINISHPAGE_SHOWREADME ""' - print >>nsi, '!define MUI_FINISHPAGE_SHOWREADME_NOTCHECKED' - print >>nsi, '!define MUI_FINISHPAGE_SHOWREADME_TEXT "Create Desktop Shortcut"' - print >>nsi, '!define MUI_FINISHPAGE_SHOWREADME_FUNCTION desktopshortcut' - print >>nsi - print >>nsi, 'Var StartMenuFolder' - print >>nsi, '!insertmacro MUI_PAGE_WELCOME' + nsi.write('!define MUI_FINISHPAGE_SHOWREADME ""\n') + nsi.write('!define MUI_FINISHPAGE_SHOWREADME_NOTCHECKED\n') + nsi.write('!define MUI_FINISHPAGE_SHOWREADME_TEXT "Create Desktop Shortcut"\n') + nsi.write('!define MUI_FINISHPAGE_SHOWREADME_FUNCTION desktopshortcut\n') + nsi.write('\n') + nsi.write('Var StartMenuFolder\n') + nsi.write('!insertmacro MUI_PAGE_WELCOME\n') if not self.licensefile.empty(): abs = Filename(self.licensefile) abs.makeAbsolute() - print >>nsi, '!insertmacro MUI_PAGE_LICENSE "%s"' % abs.toOsSpecific() - print >>nsi, '!insertmacro MUI_PAGE_DIRECTORY' - print >>nsi, '!insertmacro MUI_PAGE_STARTMENU Application $StartMenuFolder' - print >>nsi, '!insertmacro MUI_PAGE_INSTFILES' - print >>nsi, '!insertmacro MUI_PAGE_FINISH' - print >>nsi, '!insertmacro MUI_UNPAGE_WELCOME' - print >>nsi, '!insertmacro MUI_UNPAGE_CONFIRM' - print >>nsi, '!insertmacro MUI_UNPAGE_INSTFILES' - print >>nsi, '!insertmacro MUI_UNPAGE_FINISH' - print >>nsi, '!insertmacro MUI_LANGUAGE "English"' + nsi.write('!insertmacro MUI_PAGE_LICENSE "%s"\n' % abs.toOsSpecific()) + nsi.write('!insertmacro MUI_PAGE_DIRECTORY\n') + nsi.write('!insertmacro MUI_PAGE_STARTMENU Application $StartMenuFolder\n') + nsi.write('!insertmacro MUI_PAGE_INSTFILES\n') + nsi.write('!insertmacro MUI_PAGE_FINISH\n') + nsi.write('!insertmacro MUI_UNPAGE_WELCOME\n') + nsi.write('!insertmacro MUI_UNPAGE_CONFIRM\n') + nsi.write('!insertmacro MUI_UNPAGE_INSTFILES\n') + nsi.write('!insertmacro MUI_UNPAGE_FINISH\n') + nsi.write('!insertmacro MUI_LANGUAGE "English"\n') # This section defines the installer. - print >>nsi, 'Section "" SecCore' - print >>nsi, ' SetOutPath "$INSTDIR"' - print >>nsi, ' File "%s"' % exefile.toOsSpecific() + nsi.write('Section "" SecCore\n') + nsi.write(' SetOutPath "$INSTDIR"\n') + nsi.write(' File "%s"\n' % exefile.toOsSpecific()) if icofile is not None: - print >>nsi, ' File "%s"' % icofile.toOsSpecific() + nsi.write(' File "%s"\n' % icofile.toOsSpecific()) for f in extrafiles: - print >>nsi, ' File "%s"' % f.toOsSpecific() + nsi.write(' File "%s"\n' % f.toOsSpecific()) curdir = "" for root, dirs, files in self.os_walk(hostDir.toOsSpecific()): for name in files: @@ -1297,39 +1280,39 @@ class Installer: file.makeRelativeTo(hostDir) outdir = file.getDirname().replace('/', '\\') if curdir != outdir: - print >>nsi, ' SetOutPath "$INSTDIR\\%s"' % outdir + nsi.write(' SetOutPath "$INSTDIR\\%s"\n' % outdir) curdir = outdir - print >>nsi, ' File "%s"' % (basefile.toOsSpecific()) - print >>nsi, ' SetOutPath "$INSTDIR"' - print >>nsi, ' WriteUninstaller "$INSTDIR\\Uninstall.exe"' - print >>nsi, ' ; Start menu items' - print >>nsi, ' !insertmacro MUI_STARTMENU_WRITE_BEGIN Application' - print >>nsi, ' CreateDirectory "$SMPROGRAMS\\$StartMenuFolder"' + nsi.write(' File "%s"\n' % (basefile.toOsSpecific())) + nsi.write(' SetOutPath "$INSTDIR"\n') + nsi.write(' WriteUninstaller "$INSTDIR\\Uninstall.exe"\n') + nsi.write(' ; Start menu items\n') + nsi.write(' !insertmacro MUI_STARTMENU_WRITE_BEGIN Application\n') + nsi.write(' CreateDirectory "$SMPROGRAMS\\$StartMenuFolder"\n') if icofile is None: - print >>nsi, ' CreateShortCut "$SMPROGRAMS\\$StartMenuFolder\\%s.lnk" "$INSTDIR\\%s.exe"' % (self.fullname, self.shortname) + nsi.write(' CreateShortCut "$SMPROGRAMS\\$StartMenuFolder\\%s.lnk" "$INSTDIR\\%s.exe"\n' % (self.fullname, self.shortname)) else: - print >>nsi, ' CreateShortCut "$SMPROGRAMS\\$StartMenuFolder\\%s.lnk" "$INSTDIR\\%s.exe" "" "$INSTDIR\\%s.ico"' % (self.fullname, self.shortname, self.shortname) - print >>nsi, ' CreateShortCut "$SMPROGRAMS\\$StartMenuFolder\\Uninstall.lnk" "$INSTDIR\\Uninstall.exe"' - print >>nsi, ' !insertmacro MUI_STARTMENU_WRITE_END' - print >>nsi, 'SectionEnd' + nsi.write(' CreateShortCut "$SMPROGRAMS\\$StartMenuFolder\\%s.lnk" "$INSTDIR\\%s.exe" "" "$INSTDIR\\%s.ico"\n' % (self.fullname, self.shortname, self.shortname)) + nsi.write(' CreateShortCut "$SMPROGRAMS\\$StartMenuFolder\\Uninstall.lnk" "$INSTDIR\\Uninstall.exe"\n') + nsi.write(' !insertmacro MUI_STARTMENU_WRITE_END\n') + nsi.write('SectionEnd\n') # This section defines the uninstaller. - print >>nsi, 'Section Uninstall' - print >>nsi, ' Delete "$INSTDIR\\%s.exe"' % self.shortname + nsi.write('Section Uninstall\n') + nsi.write(' Delete "$INSTDIR\\%s.exe"\n' % self.shortname) if icofile is not None: - print >>nsi, ' Delete "$INSTDIR\\%s.ico"' % self.shortname + nsi.write(' Delete "$INSTDIR\\%s.ico"\n' % self.shortname) for f in extrafiles: - print >>nsi, ' Delete "%s"' % f.getBasename() - print >>nsi, ' Delete "$INSTDIR\\Uninstall.exe"' - print >>nsi, ' RMDir /r "$INSTDIR"' - print >>nsi, ' ; Desktop icon' - print >>nsi, ' Delete "$DESKTOP\\%s.lnk"' % self.fullname - print >>nsi, ' ; Start menu items' - print >>nsi, ' !insertmacro MUI_STARTMENU_GETFOLDER Application $StartMenuFolder' - print >>nsi, ' Delete "$SMPROGRAMS\\$StartMenuFolder\\%s.lnk"' % self.fullname - print >>nsi, ' Delete "$SMPROGRAMS\\$StartMenuFolder\\Uninstall.lnk"' - print >>nsi, ' RMDir "$SMPROGRAMS\\$StartMenuFolder"' - print >>nsi, 'SectionEnd' + nsi.write(' Delete "%s"\n' % f.getBasename()) + nsi.write(' Delete "$INSTDIR\\Uninstall.exe"\n') + nsi.write(' RMDir /r "$INSTDIR"\n') + nsi.write(' ; Desktop icon\n') + nsi.write(' Delete "$DESKTOP\\%s.lnk"\n' % self.fullname) + nsi.write(' ; Start menu items\n') + nsi.write(' !insertmacro MUI_STARTMENU_GETFOLDER Application $StartMenuFolder\n') + nsi.write(' Delete "$SMPROGRAMS\\$StartMenuFolder\\%s.lnk"\n' % self.fullname) + nsi.write(' Delete "$SMPROGRAMS\\$StartMenuFolder\\Uninstall.lnk"\n') + nsi.write(' RMDir "$SMPROGRAMS\\$StartMenuFolder"\n') + nsi.write('SectionEnd\n') nsi.close() cmd = [makensis] @@ -1339,7 +1322,7 @@ class Installer: else: cmd.append("-" + o) cmd.append(nsifile.toOsSpecific()) - print cmd + print(cmd) try: retcode = subprocess.call(cmd, shell = False) if retcode != 0: diff --git a/direct/src/p3d/HostInfo.py b/direct/src/p3d/HostInfo.py index d97a39ea8e..4e5efdcd3e 100644 --- a/direct/src/p3d/HostInfo.py +++ b/direct/src/p3d/HostInfo.py @@ -244,10 +244,10 @@ class HostInfo: # if we get here there may be some bigger problem. Just # give the generic "big problem" message. launcher.setPandaErrorCode(6) - except NameError,e: + except NameError as e: # no launcher pass - except AttributeError, e: + except AttributeError as e: self.notify.warning("%s" % (str(e),)) pass return False @@ -653,8 +653,8 @@ class HostInfo: packages = packages[:] - for key, platforms in self.packages.items(): - for platform, package in platforms.items(): + for key, platforms in list(self.packages.items()): + for platform, package in list(platforms.items()): if package in packages: self.__deletePackageFiles(package) del platforms[platform] diff --git a/direct/src/p3d/JavaScript.py b/direct/src/p3d/JavaScript.py index 3208b7d7ba..b59deb1aa2 100644 --- a/direct/src/p3d/JavaScript.py +++ b/direct/src/p3d/JavaScript.py @@ -4,8 +4,6 @@ code that runs in a browser via the web plugin. """ __all__ = ["UndefinedObject", "Undefined", "ConcreteStruct", "BrowserObject", "MethodWrapper"] -import types - class UndefinedObject: """ This is a special object that is returned by the browser to represent an "undefined" or "void" value, typically the value for @@ -42,7 +40,7 @@ class ConcreteStruct: returns all properties of the object. You can override this to restrict the set of properties that are uploaded. """ - return self.__dict__.items() + return list(self.__dict__.items()) class BrowserObject: """ This class provides the Python wrapper around some object that @@ -109,7 +107,7 @@ class BrowserObject: # problems. needsResponse = False - if parentObj is self.__runner.dom and attribName == 'eval' and len(args) == 1 and isinstance(args[0], types.StringTypes): + if parentObj is self.__runner.dom and attribName == 'eval' and len(args) == 1 and isinstance(args[0], str): # As another special hack, we make dom.eval() a # special case, and map it directly into an eval() # call. If the string begins with 'void ', we further @@ -207,7 +205,7 @@ class BrowserObject: # for numeric keys so we can properly support Python's # iterators, but we return KeyError for string keys to # emulate mapping objects. - if isinstance(key, types.StringTypes): + if isinstance(key, str): raise KeyError(key) else: raise IndexError(key) @@ -219,7 +217,7 @@ class BrowserObject: propertyName = str(key), value = value) if not result: - if isinstance(key, types.StringTypes): + if isinstance(key, str): raise KeyError(key) else: raise IndexError(key) @@ -228,7 +226,7 @@ class BrowserObject: result = self.__runner.scriptRequest('del_property', self, propertyName = str(key)) if not result: - if isinstance(key, types.StringTypes): + if isinstance(key, str): raise KeyError(key) else: raise IndexError(key) @@ -269,7 +267,7 @@ class MethodWrapper: # problems. needsResponse = False - if parentObj is self.__runner.dom and attribName == 'eval' and len(args) == 1 and isinstance(args[0], types.StringTypes): + if parentObj is self.__runner.dom and attribName == 'eval' and len(args) == 1 and isinstance(args[0], str): # As another special hack, we make dom.eval() a # special case, and map it directly into an eval() # call. If the string begins with 'void ', we further diff --git a/direct/src/p3d/PackageMerger.py b/direct/src/p3d/PackageMerger.py index 9c2e1ac499..a22d8f5f2d 100644 --- a/direct/src/p3d/PackageMerger.py +++ b/direct/src/p3d/PackageMerger.py @@ -207,7 +207,7 @@ class PackageMerger: xcontents.SetAttribute('max_age', str(self.maxAge)) self.contentsSeq.storeXml(xcontents) - contents = self.contents.items() + contents = list(self.contents.items()) contents.sort() for key, pe in contents: xpackage = pe.makeXml() diff --git a/direct/src/p3d/Packager.py b/direct/src/p3d/Packager.py index 2f1e6a36e1..b46cda30b7 100644 --- a/direct/src/p3d/Packager.py +++ b/direct/src/p3d/Packager.py @@ -11,8 +11,6 @@ from panda3d.core import * import sys import os import glob -import string -import types import struct import subprocess import copy @@ -574,7 +572,7 @@ class Packager: # But first, make sure that all required modules are present. missing = [] - moduleDict = dict(self.freezer.getModuleDefs()).keys() + moduleDict = dict(self.freezer.getModuleDefs()) for module in self.requiredModules: if module not in moduleDict: missing.append(module) @@ -1228,7 +1226,7 @@ class Packager: filenames = [] for line in lines: - if line[0] not in string.whitespace: + if not line[0].isspace(): continue line = line.strip() s = line.find(' (compatibility') @@ -1659,9 +1657,9 @@ class Packager: xconfig = TiXmlElement('config') for variable, value in self.configs.items(): - if isinstance(value, types.UnicodeType): + if sys.version_info < (3, 0) and isinstance(value, unicode): xconfig.SetAttribute(variable, value.encode('utf-8')) - elif isinstance(value, types.BooleanType): + elif isinstance(value, bool): # True or False must be encoded as 1 or 0. xconfig.SetAttribute(variable, str(int(value))) else: @@ -2190,7 +2188,7 @@ class Packager: if package not in self.requires: self.requires.append(package) - for lowerName in package.targetFilenames.keys(): + for lowerName in package.targetFilenames: ext = Filename(lowerName).getExtension() if ext not in self.packager.nonuniqueExtensions: self.skipFilenames[lowerName] = True @@ -2726,7 +2724,7 @@ class Packager: packageNames.append(package.packageName) if packageNames: - from PatchMaker import PatchMaker + from .PatchMaker import PatchMaker pm = PatchMaker(self.installDir) pm.buildPatches(packageNames = packageNames) @@ -2759,7 +2757,7 @@ class Packager: # By convention, the existence of a method of this class named # do_foo(self) is sufficient to define a pdef method call # foo(). - for methodName in self.__class__.__dict__.keys(): + for methodName in list(self.__class__.__dict__.keys()): if methodName.startswith('do_'): name = methodName[3:] c = func_closure(name) @@ -3147,14 +3145,14 @@ class Packager: while p < len(version): # Scan to the first digit. w = '' - while p < len(version) and version[p] not in string.digits: + while p < len(version) and not version[p].isdigit(): w += version[p] p += 1 words.append(w) # Scan to the end of the string of digits. w = '' - while p < len(version) and version[p] in string.digits: + while p < len(version) and version[p].isdigit(): w += version[p] p += 1 if w: @@ -3233,7 +3231,7 @@ class Packager: if not self.currentPackage: raise OutsideOfPackageError - for keyword, value in kw.items(): + for keyword, value in list(kw.items()): self.currentPackage.configs[keyword] = value def do_require(self, *args, **kw): @@ -3917,17 +3915,10 @@ class metaclass_def(type): return type.__new__(self, name, bases, dict) -class class_p3d: - __metaclass__ = metaclass_def - pass - -class class_package: - __metaclass__ = metaclass_def - pass - -class class_solo: - __metaclass__ = metaclass_def - pass +# Define these dynamically to stay compatible with Python 2 and 3. +class_p3d = metaclass_def(str('class_p3d'), (), {}) +class_package = metaclass_def(str('class_package'), (), {}) +class_solo = metaclass_def(str('class_solo'), (), {}) class func_closure: diff --git a/direct/src/p3d/PatchMaker.py b/direct/src/p3d/PatchMaker.py index 485ad0d0e9..b48ad80f24 100644 --- a/direct/src/p3d/PatchMaker.py +++ b/direct/src/p3d/PatchMaker.py @@ -180,7 +180,7 @@ class PatchMaker: result = Filename.temporary('', 'patch_') p = Patchfile() if not p.apply(patchFilename, origFile, result): - print "Internal patching failed: %s" % (patchFilename) + print("Internal patching failed: %s" % (patchFilename)) return None return result @@ -345,7 +345,7 @@ class PatchMaker: packageDescFullpath = Filename(self.patchMaker.installDir, self.packageDesc) self.doc = TiXmlDocument(packageDescFullpath.toOsSpecific()) if not self.doc.LoadFile(): - print "Couldn't read %s" % (packageDescFullpath) + print("Couldn't read %s" % (packageDescFullpath)) return False xpackage = self.doc.FirstChildElement('package') @@ -537,7 +537,7 @@ class PatchMaker: packageSeq.storeXml(xpackage, 'seq') doc.SaveFile() else: - print "Couldn't read %s" % (importDescFullpath) + print("Couldn't read %s" % (importDescFullpath)) if self.contentsDocPackage: # Now that we've rewritten the xml file, we have to @@ -633,7 +633,7 @@ class PatchMaker: doc = TiXmlDocument(contentsFilename.toOsSpecific()) if not doc.LoadFile(): # Couldn't read file. - print "couldn't read %s" % (contentsFilename) + print("couldn't read %s" % (contentsFilename)) return False xcontents = doc.FirstChildElement('contents') @@ -740,7 +740,7 @@ class PatchMaker: remainingNames.remove(package.packageName) if remainingNames: - print "Unknown packages: %s" % (remainingNames,) + print("Unknown packages: %s" % (remainingNames,)) def processAllPackages(self): """ Walks through the list of packages, and builds missing @@ -803,7 +803,7 @@ class PatchMaker: # No original version to patch from. return False - print "Building patch from %s to %s" % (printOrigName, printNewName) + print("Building patch from %s to %s" % (printOrigName, printNewName)) patchFilename.unlink() p = Patchfile() # The C++ class if p.build(origFilename, newFilename, patchFilename): diff --git a/direct/src/p3d/SeqValue.py b/direct/src/p3d/SeqValue.py index d41cfd250b..68b655bce3 100644 --- a/direct/src/p3d/SeqValue.py +++ b/direct/src/p3d/SeqValue.py @@ -1,7 +1,5 @@ __all__ = ["SeqValue"] -import types - class SeqValue: """ This represents a sequence value read from a contents.xml @@ -21,22 +19,22 @@ class SeqValue: def set(self, value): """ Sets the seq from the indicated value of unspecified type. """ - if isinstance(value, types.TupleType): + if isinstance(value, tuple): self.setFromTuple(value) - elif isinstance(value, types.StringTypes): + elif isinstance(value, str): self.setFromString(value) else: raise TypeError('Invalid sequence type: %s' % (value,)) def setFromTuple(self, value): """ Sets the seq from the indicated tuple of integers. """ - assert isinstance(value, types.TupleType) + assert isinstance(value, tuple) self.value = value def setFromString(self, value): """ Sets the seq from the indicated string of dot-separated integers. Raises ValueError on error. """ - assert isinstance(value, types.StringTypes) + assert isinstance(value, str) self.value = () if value: diff --git a/direct/src/p3d/packp3d.py b/direct/src/p3d/packp3d.py index a33a49e2d4..dee4fa2656 100755 --- a/direct/src/p3d/packp3d.py +++ b/direct/src/p3d/packp3d.py @@ -100,7 +100,6 @@ import sys import os import getopt import glob -import direct from direct.p3d import Packager from panda3d.core import * @@ -159,11 +158,11 @@ def makePackedApp(args): elif option == '-D': allowPythonDev = True elif option == '-h': - print usageText % ( + print(usageText % ( PandaSystem.getPackageVersionString(), PandaSystem.getPackageHostUrl(), os.path.split(sys.argv[0])[1], - '%s.%s' % (sys.version_info[0], sys.version_info[1])) + '%s.%s' % (sys.version_info[0], sys.version_info[1]))) sys.exit(0) if not appFilename: @@ -228,13 +227,13 @@ def makePackedApp(args): except Packager.PackagerError: # Just print the error message and exit gracefully. inst = sys.exc_info()[1] - print inst.args[0] + print(inst.args[0]) sys.exit(1) try: makePackedApp(sys.argv[1:]) -except ArgumentError, e: - print e.args[0] +except ArgumentError as e: + print(e.args[0]) sys.exit(1) # An explicit call to exit() is required to exit the program, when diff --git a/direct/src/p3d/panda3d.pdef b/direct/src/p3d/panda3d.pdef index 4c6588622f..59e53cb39b 100644 --- a/direct/src/p3d/panda3d.pdef +++ b/direct/src/p3d/panda3d.pdef @@ -97,12 +97,16 @@ class panda3d(package): excludeModule('wx', 'direct.showbase.WxGlobal') - excludeModule('Tkinter', 'Pmw', + excludeModule('Tkinter', 'tkinter', 'Pmw', 'tkinter.simpledialog', 'direct.showbase.TkGlobal', 'direct.tkpanels', 'direct.tkwidgets', 'tkCommonDialog', 'tkMessageBox', 'tkSimpleDialog') - excludeModule('MySQLdb', '_mysql') + excludeModule('MySQLdb', 'MySQLdb.connections', 'MySQLdb.constants', + 'MySQLdb.converters', '_mysql') + + # Some code in distributed conditionally imports these. + excludeModule('otp.ai', 'otp.ai.AIZoneData') # Most of the core Panda3D DLL's will be included implicitly due to # being referenced by the above Python code. Here we name a few more @@ -141,14 +145,14 @@ class morepy(package): config(display_name = "Python standard library") require('panda3d') - module('string', 're', 'struct', 'difflib', 'StringIO', 'StringIO', + module('string', 're', 'struct', 'difflib', 'textwrap', 'codecs', 'unicodedata', 'stringprep', 'datetime', 'calendar', 'collections', 'heapq', 'bisect', 'array', 'sched', 'queue', 'weakref', 'types', 'copy', 'pprint', 'numbers', 'math', 'cmath', 'decimal', 'fractions', 'random', 'itertools', 'functools', 'operator', 'os.path', 'fileinput', 'filecmp', 'tempfile', 'glob', 'fnmatch', 'linecache', - 'shutil', 'macpath', 'pickle', 'shelve', 'marshal', 'bsddb', 'zlib', + 'shutil', 'macpath', 'pickle', 'shelve', 'marshal', 'zlib', 'gzip', 'bz2', 'zipfile', 'tarfile', 'csv', 'netrc', 'xdrlib', 'plistlib', 'hashlib', 'hmac', 'os', 'time', 'optparse', 'getopt', 'logging', 'logging.*') @@ -167,8 +171,8 @@ class morepy(package): 'wave', 'chunk', 'colorsys', 'imghdr', 'sndhdr', 'ossaudiodev', 'gettext', 'locale', 'cmd', 'shlex', 'pydoc', 'doctest', 'unittest', 'test', - 'bdb', 'pdb', 'hotshot', 'timeit', 'trace', 'sys', '__builtin__') - module('future_builtins', 'warnings', 'contextlib', 'abc', + 'bdb', 'pdb', 'timeit', 'trace', 'sys') + module('warnings', 'contextlib', 'abc', 'atexit', 'traceback', '__future__', 'gc', 'inspect', 'site', 'fpectl', 'code', 'codeop', 'zipimport', 'pkgutil', 'modulefinder', 'runpy', 'parser', 'symtable', 'symbol', @@ -191,13 +195,14 @@ class morepy(package): # Removed because they were obsolete module('Bastion', 'rexec', 'commands', 'dircache', 'dl', 'fpformat', 'htmllib', 'imageop', 'mhlib', 'popen2', 'sgmllib', 'stat', - 'statvfs', 'thread', 'UserDict', 'UserList', 'UserString') + 'statvfs', 'thread', 'UserDict', 'UserList', 'UserString', + 'future_builtins', 'hotshot', 'bsddb') # Renamed to fix PEP8 violations module('_winreg', 'ConfigParser', 'copy_reg', 'SocketServer') # C and Python implementations of the same interface were merged - module('cPickle', 'cStringIO') + module('cPickle', 'cStringIO', 'StringIO') # Renamed because of poorly chosen names - module('repr', 'test.test_support') + module('repr', 'test.test_support', '__builtins__') # Modules that got grouped under packages module('anydbm', 'whichdb', 'dbm', 'dumbdbm', 'gdbm', 'dbhash') module('HTMLParser', 'htmlentitydefs') @@ -209,7 +214,7 @@ class morepy(package): # Renamed to fix PEP8 violations module('winreg', 'configparser', 'copyreg', 'socketserver') # Renamed because of poorly chosen names - module('reprlib', 'test.support') + module('reprlib', 'test.support', 'builtins') # Modules that got grouped under packages module('dbm') module('html') diff --git a/direct/src/p3d/pdeploy.py b/direct/src/p3d/pdeploy.py index 0b0a77f834..f98d10b65d 100644 --- a/direct/src/p3d/pdeploy.py +++ b/direct/src/p3d/pdeploy.py @@ -151,8 +151,8 @@ from panda3d.core import Filename, PandaSystem def usage(code, msg = ''): if not msg: - print >> sys.stderr, usageText % {'prog' : os.path.split(sys.argv[0])[1]} - print >> sys.stderr, msg + sys.stderr.write(usageText % {'prog' : os.path.split(sys.argv[0])[1]}) + sys.stderr.write(msg + '\n') sys.exit(code) shortname = "" @@ -173,7 +173,7 @@ omitDefaultCheckboxes = False try: opts, args = getopt.getopt(sys.argv[1:], 'n:N:v:o:t:P:csOl:L:a:A:e:i:h') -except getopt.error, msg: +except getopt.error as msg: usage(1, msg or 'Invalid option') for opt, arg in opts: @@ -213,7 +213,7 @@ for opt, arg in opts: usage(0) else: msg = 'illegal option: ' + flag - print msg + print(msg) sys.exit(1, msg) if not args or len(args) != 2: @@ -223,32 +223,32 @@ if not args or len(args) != 2: appFilename = Filename.fromOsSpecific(args[0]) if appFilename.getExtension().lower() != 'p3d': - print 'Application filename must end in ".p3d".' + print('Application filename must end in ".p3d".') sys.exit(1) deploy_mode = args[1].lower() if not appFilename.exists(): - print 'Application filename does not exist!' + print('Application filename does not exist!') sys.exit(1) if shortname == '': shortname = appFilename.getBasenameWoExtension() if shortname.lower() != shortname or ' ' in shortname: - print '\nProvided short name should be lowercase, and may not contain spaces!\n' + print('\nProvided short name should be lowercase, and may not contain spaces!\n') if version == '' and deploy_mode == 'installer': - print '\nA version number is required in "installer" mode.\n' + print('\nA version number is required in "installer" mode.\n') sys.exit(1) if not outputDir: - print '\nYou must name the output directory with the -o parameter.\n' + print('\nYou must name the output directory with the -o parameter.\n') sys.exit(1) if not outputDir.exists(): - print '\nThe specified output directory does not exist!\n' + print('\nThe specified output directory does not exist!\n') sys.exit(1) elif not outputDir.isDirectory(): - print '\nThe specified output directory is a file!\n' + print('\nThe specified output directory is a file!\n') sys.exit(1) if deploy_mode == 'standalone': @@ -287,8 +287,8 @@ elif deploy_mode == 'installer': if authoremail: i.authoremail = authoremail if not authorname or not authoremail or not authorid: - print "Using author \"%s\" <%s> with ID %s" % \ - (i.authorname, i.authoremail, i.authorid) + print("Using author \"%s\" <%s> with ID %s" % \ + (i.authorname, i.authoremail, i.authorid)) # Add the supplied icon images if len(iconFiles) > 0: @@ -296,7 +296,7 @@ elif deploy_mode == 'installer': i.icon = Icon() for iconFile in iconFiles: if not i.icon.addImage(iconFile): - print '\nFailed to add icon image "%s"!\n' % iconFile + print('\nFailed to add icon image "%s"!\n' % iconFile) failed = True if failed: sys.exit(1) @@ -323,32 +323,32 @@ elif deploy_mode == 'html': if "data" not in tokens: tokens["data"] = appFilename.getBasename() - print "Creating %s.html..." % shortname + print("Creating %s.html..." % shortname) html = open(Filename(outputDir, shortname + ".html").toOsSpecific(), "w") - print >>html, "" - print >>html, "" - print >>html, " " - print >>html, " %s" % fullname - print >>html, " " + html.write("\n") + html.write("\n") + html.write(" \n") + html.write(" %s\n" % fullname) + html.write(" \n") if authorname: - print >>html, " " % authorname.replace('"', '\\"') - print >>html, " " - print >>html, " " - print >>html, " \n" % authorname.replace('"', '\\"')) + html.write(" \n") + html.write(" \n") + html.write(" >html, "%s=\"%s\"" % (key, value.replace('"', '\\"')), + html.write(" %s=\"%s\"" % (key, value.replace('"', '\\"'))) if "width" not in tokens: - print >>html, "width=\"%s\"" % w, + html.write(" width=\"%s\"" % w) if "height" not in tokens: - print >>html, "height=\"%s\"" % h, - print >>html, "type=\"application/x-panda3d\">" - print >>html, " " % (w, h) + html.write(" height=\"%s\"" % h) + html.write(" type=\"application/x-panda3d\">") + html.write(" \n" % (w, h)) for key, value in tokens.items(): - print >>html, " " % (key, value.replace('"', '\\"')) - print >>html, " " - print >>html, " " - print >>html, " " - print >>html, "" + html.write(" \n" % (key, value.replace('"', '\\"'))) + html.write(" \n") + html.write(" \n") + html.write(" \n") + html.write("\n") html.close() else: usage(1, 'Invalid deployment mode!') diff --git a/direct/src/p3d/pmerge.py b/direct/src/p3d/pmerge.py index 2b290eb044..99492df35b 100755 --- a/direct/src/p3d/pmerge.py +++ b/direct/src/p3d/pmerge.py @@ -40,6 +40,7 @@ Options: -h Display this help + """ import sys @@ -47,16 +48,16 @@ import getopt import os from direct.p3d import PackageMerger -from panda3d.core import * +from panda3d.core import Filename def usage(code, msg = ''): - print >> sys.stderr, usageText % {'prog' : os.path.split(sys.argv[0])[1]} - print >> sys.stderr, msg + sys.stderr.write(usageText % {'prog' : os.path.split(sys.argv[0])[1]}) + sys.stderr.write(msg + '\n') sys.exit(code) try: opts, args = getopt.getopt(sys.argv[1:], 'i:p:h') -except getopt.error, msg: +except getopt.error as msg: usage(1, msg) installDir = None @@ -70,7 +71,7 @@ for opt, arg in opts: elif opt == '-h': usage(0) else: - print 'illegal option: ' + arg + print('illegal option: ' + arg) sys.exit(1) if not packageNames: @@ -96,7 +97,7 @@ try: except PackageMerger.PackageMergerError: # Just print the error message and exit gracefully. inst = sys.exc_info()[1] - print inst.args[0] + print(inst.args[0]) sys.exit(1) diff --git a/direct/src/p3d/ppatcher.py b/direct/src/p3d/ppatcher.py index 440e22cb61..69e9689622 100755 --- a/direct/src/p3d/ppatcher.py +++ b/direct/src/p3d/ppatcher.py @@ -53,6 +53,7 @@ Options: -h Display this help + """ import sys @@ -60,16 +61,16 @@ import getopt import os from direct.p3d.PatchMaker import PatchMaker -from panda3d.core import * +from panda3d.core import Filename def usage(code, msg = ''): - print >> sys.stderr, usageText % {'prog' : os.path.split(sys.argv[0])[1]} - print >> sys.stderr, msg + sys.stderr.write(usageText % {'prog' : os.path.split(sys.argv[0])[1]}) + sys.stderr.write(msg + '\n') sys.exit(code) try: opts, args = getopt.getopt(sys.argv[1:], 'i:h') -except getopt.error, msg: +except getopt.error as msg: usage(1, msg) installDir = None @@ -80,7 +81,7 @@ for opt, arg in opts: elif opt == '-h': usage(0) else: - print 'illegal option: ' + arg + print('illegal option: ' + arg) sys.exit(1) packageNames = args diff --git a/direct/src/p3d/runp3d.py b/direct/src/p3d/runp3d.py index 167f8d0d2f..2ab457bc3c 100644 --- a/direct/src/p3d/runp3d.py +++ b/direct/src/p3d/runp3d.py @@ -26,7 +26,7 @@ See pack3d.p3d for an application that generates these p3d files. import sys import getopt -from AppRunner import AppRunner, ArgumentError +from .AppRunner import AppRunner, ArgumentError from direct.task.TaskManagerGlobal import taskMgr from panda3d.core import Filename @@ -42,7 +42,7 @@ def parseSysArgs(): for option, value in opts: if option == '-h': - print __doc__ + print(__doc__) sys.exit(1) if not args or not args[0]: @@ -62,8 +62,8 @@ def runPackedApp(pathname): try: runner.setP3DFilename(pathname, tokens = [], argv = [], instanceId = 0, interactiveConsole = False) - except ArgumentError, e: - print e.args[0] + except ArgumentError as e: + print(e.args[0]) sys.exit(1) if __name__ == '__main__': @@ -73,7 +73,7 @@ if __name__ == '__main__': argv = parseSysArgs() runner.setP3DFilename(argv[0], tokens = [], argv = argv, instanceId = 0, interactiveConsole = False) - except ArgumentError, e: - print e.args[0] + except ArgumentError as e: + print(e.args[0]) sys.exit(1) taskMgr.run() diff --git a/direct/src/p3d/thirdparty.pdef b/direct/src/p3d/thirdparty.pdef index bc72b39eb7..bc001e427d 100644 --- a/direct/src/p3d/thirdparty.pdef +++ b/direct/src/p3d/thirdparty.pdef @@ -32,16 +32,28 @@ class tk(package): #config(gui_app = True) require('panda3d') - module('Tkinter', '_tkinter', required = True) - module('Tkconstants', 'Tkdnd', 'Tix', 'ScrolledText', 'turtle', - 'tkColorChooser', 'tkCommonDialog', 'tkFileDialog', - 'tkFont', 'tkMessageBox', 'tkSimpleDialog') + if sys.version_info >= (3, 0): + module('tkinter', '_tkinter', required = True) + module('tkinter.colorchooser', 'tkinter.commondialog', + 'tkinter.constants', 'tkinter.dialog', 'tkinter.dnd', + 'tkinter.filedialog', 'tkinter.font', 'tkinter.messagebox', + 'tkinter.scrolledtext', 'tkinter.simpledialog', 'tkinter.tix', + 'tkinter.ttk') + else: + module('Tkinter', '_tkinter', required = True) + module('Tkconstants', 'Tkdnd', 'Tix', 'ScrolledText', 'turtle', + 'tkColorChooser', 'tkCommonDialog', 'tkFileDialog', + 'tkFont', 'tkMessageBox', 'tkSimpleDialog') + module('direct.showbase.TkGlobal', 'direct.tkpanels', 'direct.tkwidgets') try: - from Tkinter import Tcl + if sys.version_info >= (3, 0): + from tkinter import Tcl + else: + from Tkinter import Tcl tcl = Tcl() dir = Filename.fromOsSpecific(tcl.eval("info library")) ver = tcl.eval("info tclversion") diff --git a/direct/src/particles/GlobalForceGroup.py b/direct/src/particles/GlobalForceGroup.py index c371b74acf..c3ba10b98c 100644 --- a/direct/src/particles/GlobalForceGroup.py +++ b/direct/src/particles/GlobalForceGroup.py @@ -1,4 +1,4 @@ -import ForceGroup +from . import ForceGroup class GlobalForceGroup(ForceGroup.ForceGroup): diff --git a/direct/src/particles/ParticleEffect.py b/direct/src/particles/ParticleEffect.py index ba1c14a95f..c58b7b4d46 100644 --- a/direct/src/particles/ParticleEffect.py +++ b/direct/src/particles/ParticleEffect.py @@ -98,7 +98,7 @@ class ParticleEffect(NodePath): self.addForce(forceGroup[i]) def addForce(self, force): - for p in self.particlesDict.values(): + for p in list(self.particlesDict.values()): p.addForce(force) def removeForceGroup(self, forceGroup): @@ -111,11 +111,11 @@ class ParticleEffect(NodePath): self.forceGroupDict.pop(forceGroup.getName(), None) def removeForce(self, force): - for p in self.particlesDict.values(): + for p in list(self.particlesDict.values()): p.removeForce(force) def removeAllForces(self): - for fg in self.forceGroupDict.values(): + for fg in list(self.forceGroupDict.values()): self.removeForceGroup(fg) def addParticles(self, particles): @@ -123,7 +123,7 @@ class ParticleEffect(NodePath): self.particlesDict[particles.getName()] = particles # Associate all forces in all force groups with the particles - for fg in self.forceGroupDict.values(): + for fg in list(self.forceGroupDict.values()): for i in range(len(fg)): particles.addForce(fg[i]) @@ -135,16 +135,16 @@ class ParticleEffect(NodePath): self.particlesDict.pop(particles.getName(), None) # Remove all forces from the particles - for fg in self.forceGroupDict.values(): + for fg in list(self.forceGroupDict.values()): for f in fg: particles.removeForce(f) def removeAllParticles(self): - for p in self.particlesDict.values(): + for p in list(self.particlesDict.values()): self.removeParticles(p) def getParticlesList(self): - return self.particlesDict.values() + return list(self.particlesDict.values()) def getParticlesNamed(self, name): return self.particlesDict.get(name, None) @@ -153,7 +153,7 @@ class ParticleEffect(NodePath): return self.particlesDict def getForceGroupList(self): - return self.forceGroupDict.values() + return list(self.forceGroupDict.values()) def getForceGroupNamed(self, name): return self.forceGroupDict.get(name, None) @@ -182,7 +182,7 @@ class ParticleEffect(NodePath): # Save all the particles to file num = 0 - for p in self.particlesDict.values(): + for p in list(self.particlesDict.values()): target = 'p%d' % num num = num + 1 f.write(target + ' = Particles.Particles(\'%s\')\n' % p.getName()) @@ -191,7 +191,7 @@ class ParticleEffect(NodePath): # Save all the forces to file num = 0 - for fg in self.forceGroupDict.values(): + for fg in list(self.forceGroupDict.values()): target = 'f%d' % num num = num + 1 f.write(target + ' = ForceGroup.ForceGroup(\'%s\')\n' % \ diff --git a/direct/src/particles/ParticleTest.py b/direct/src/particles/ParticleTest.py index 7399417b52..780ea4edc5 100644 --- a/direct/src/particles/ParticleTest.py +++ b/direct/src/particles/ParticleTest.py @@ -4,10 +4,10 @@ if __name__ == "__main__": from panda3d.physics import LinearVectorForce from panda3d.core import Vec3 - import ParticleEffect + from . import ParticleEffect from direct.tkpanels import ParticlePanel - import Particles - import ForceGroup + from . import Particles + from . import ForceGroup # Showbase base.enableParticles() diff --git a/direct/src/particles/Particles.py b/direct/src/particles/Particles.py index ee82ffc81b..6ed19af896 100644 --- a/direct/src/particles/Particles.py +++ b/direct/src/particles/Particles.py @@ -23,7 +23,7 @@ from panda3d.physics import SphereSurfaceEmitter from panda3d.physics import SphereVolumeEmitter from panda3d.physics import TangentRingEmitter -import SpriteParticleRendererExt +from . import SpriteParticleRendererExt from direct.directnotify.DirectNotifyGlobal import directNotify import sys @@ -108,7 +108,7 @@ class Particles(ParticleSystem): elif (type == "OrientedParticleFactory"): self.factory = OrientedParticleFactory() else: - print "unknown factory type: %s" % type + print("unknown factory type: %s" % type) return None self.factory.setLifespanBase(0.5) ParticleSystem.setFactory(self, self.factory) @@ -139,7 +139,7 @@ class Particles(ParticleSystem): self.renderer = SpriteParticleRendererExt.SpriteParticleRendererExt() # self.renderer.setTextureFromFile() else: - print "unknown renderer type: %s" % type + print("unknown renderer type: %s" % type) return None ParticleSystem.setRenderer(self, self.renderer) @@ -171,7 +171,7 @@ class Particles(ParticleSystem): elif (type == "TangentRingEmitter"): self.emitter = TangentRingEmitter() else: - print "unknown emitter type: %s" % type + print("unknown emitter type: %s" % type) return None ParticleSystem.setEmitter(self, self.emitter) @@ -568,9 +568,9 @@ class Particles(ParticleSystem): self.factory.getLifespanBase()+self.factory.getLifespanSpread()] birthRateRange = [self.getBirthRate()] * 3 - print 'Litter Ranges: ',litterRange - print 'LifeSpan Ranges: ',lifespanRange - print 'BirthRate Ranges: ',birthRateRange + print('Litter Ranges: %s' % litterRange) + print('LifeSpan Ranges: %s' % lifespanRange) + print('BirthRate Ranges: %s' % birthRateRange) return dict(zip(('min','median','max'),[l*s/b for l,s,b in zip(litterRange,lifespanRange,birthRateRange)])) diff --git a/direct/src/particles/SpriteParticleRendererExt.py b/direct/src/particles/SpriteParticleRendererExt.py index 5a929b2dbc..f73b61e350 100644 --- a/direct/src/particles/SpriteParticleRendererExt.py +++ b/direct/src/particles/SpriteParticleRendererExt.py @@ -37,7 +37,7 @@ class SpriteParticleRendererExt(SpriteParticleRenderer): self.setSourceTextureName(fileName) return True else: - print "Couldn't find rendererSpriteTexture file: %s" % fileName + print("Couldn't find rendererSpriteTexture file: %s" % fileName) return False def addTextureFromFile(self, fileName = None): @@ -52,7 +52,7 @@ class SpriteParticleRendererExt(SpriteParticleRenderer): self.addTexture(t, t.getYSize()) return True else: - print "Couldn't find rendererSpriteTexture file: %s" % fileName + print("Couldn't find rendererSpriteTexture file: %s" % fileName) return False def getSourceFileName(self): @@ -86,12 +86,12 @@ class SpriteParticleRendererExt(SpriteParticleRenderer): # Load model and get texture m = loader.loadModel(modelName) if (m == None): - print "SpriteParticleRendererExt: Couldn't find model: %s!" % modelName + print("SpriteParticleRendererExt: Couldn't find model: %s!" % modelName) return False np = m.find(nodeName) if np.isEmpty(): - print "SpriteParticleRendererExt: Couldn't find node: %s!" % nodeName + print("SpriteParticleRendererExt: Couldn't find node: %s!" % nodeName) m.removeNode() return False @@ -113,12 +113,12 @@ class SpriteParticleRendererExt(SpriteParticleRenderer): # Load model and get texture m = loader.loadModel(modelName) if (m == None): - print "SpriteParticleRendererExt: Couldn't find model: %s!" % modelName + print("SpriteParticleRendererExt: Couldn't find model: %s!" % modelName) return False np = m.find(nodeName) if np.isEmpty(): - print "SpriteParticleRendererExt: Couldn't find node: %s!" % nodeName + print("SpriteParticleRendererExt: Couldn't find node: %s!" % nodeName) m.removeNode() return False diff --git a/direct/src/plugin_installer/make_installer.py b/direct/src/plugin_installer/make_installer.py index 0d0f12b0dc..9410f4fb90 100755 --- a/direct/src/plugin_installer/make_installer.py +++ b/direct/src/plugin_installer/make_installer.py @@ -298,7 +298,7 @@ def getDllVersion(filename): tempfile = 'tversion.txt' tempdata = open(tempfile, 'w+') cmd = 'cscript //nologo "%s" "%s"' % (versionInfo, filename) - print cmd + print(cmd) result = subprocess.call(cmd, stdout = tempdata) if result: sys.exit(result) @@ -326,18 +326,18 @@ def makeCabFile(ocx, pluginDependencies): infFile = 'temp.inf' inf = open(infFile, 'w') - print >> inf, '[Add.Code]\n%s=%s\n%s=%s' % (infFile, infFile, ocx, ocx) + info.write('[Add.Code]\n%s=%s\n%s=%s\n' % (infFile, infFile, ocx, ocx)) dependencies = pluginDependencies[ocx] for filename in dependencies: - print >> inf, '%s=%s' % (filename, filename) - print >> inf, '\n[%s]\nfile=thiscab' % (infFile) - print >> inf, '\n[%s]\nfile=thiscab\nclsid={924B4927-D3BA-41EA-9F7E-8A89194AB3AC}\nRegisterServer=yes\nFileVersion=%s' % (ocx, getDllVersion(ocxFullpath)) + inf.write('%s=%s\n' % (filename, filename)) + inf.write('\n[%s]\nfile=thiscab\n' % (infFile)) + inf.write('\n[%s]\nfile=thiscab\nclsid={924B4927-D3BA-41EA-9F7E-8A89194AB3AC}\nRegisterServer=yes\nFileVersion=%s\n' % (ocx, getDllVersion(ocxFullpath))) fullpaths = [] for filename in dependencies: fullpath = findExecutable(filename) fullpaths.append(fullpath) - print >> inf, '\n[%s]\nfile=thiscab\nDestDir=11\nRegisterServer=yes\nFileVersion=%s' % (filename, getDllVersion(fullpath)) + inf.write('\n[%s]\nfile=thiscab\nDestDir=11\nRegisterServer=yes\nFileVersion=%s\n' % (filename, getDllVersion(fullpath))) inf.close() # Now process the inf file with cabarc. @@ -350,20 +350,20 @@ def makeCabFile(ocx, pluginDependencies): for fullpath in fullpaths: cmd += ' "%s"' % (fullpath) cmd += ' "%s" %s' % (ocxFullpath, infFile) - print cmd + print(cmd) result = subprocess.call(cmd) if result: sys.exit(result) if not os.path.exists(cabFilename): - print "Couldn't generate %s" % (cabFilename) + print("Couldn't generate %s" % (cabFilename)) sys.exit(1) - print "Successfully generated %s" % (cabFilename) + print("Successfully generated %s" % (cabFilename)) if options.spc and options.pvk: # Now we have to sign the cab file. cmd = '"%s" -spc "%s" -k "%s" "%s"' % (signcode, options.spc, options.pvk, cabFilename) - print cmd + print(cmd) result = subprocess.call(cmd) if result: sys.exit(result) @@ -502,8 +502,8 @@ def makeInstaller(): CMD += ' -i "%s"' % (infoFilename) CMD += ' -d "%s"' % (descriptionFilename) - print "" - print CMD + print("") + print(CMD) # Don't check the exit status of packagemaker; it's not always # reliable. @@ -518,7 +518,7 @@ def makeInstaller(): shutil.rmtree(tmpresdir) if not os.path.exists(pkgname): - print "Unable to create %s." % (pkgname) + print("Unable to create %s." % (pkgname)) sys.exit(1) # Pack the .pkg into a .dmg @@ -530,8 +530,8 @@ def makeInstaller(): tmpdmg = tempfile.mktemp('', 'p3d-setup') + ".dmg" CMD = 'hdiutil create "%s" -srcfolder "%s"' % (tmpdmg, tmproot) - print "" - print CMD + print("") + print(CMD) result = subprocess.call(CMD, shell = True) if result: sys.exit(result) @@ -541,8 +541,8 @@ def makeInstaller(): if os.path.exists("p3d-setup.dmg"): os.remove("p3d-setup.dmg") CMD = 'hdiutil convert "%s" -format UDBZ -o "p3d-setup.dmg"' % tmpdmg - print "" - print CMD + print("") + print(CMD) result = subprocess.call(CMD, shell = True) if result: sys.exit(result) @@ -569,13 +569,12 @@ def makeInstaller(): if options.regview: CMD += '/DREGVIEW=%s ' % (options.regview) - dependencies = dependentFiles.items() - for i in range(len(dependencies)): - CMD += '/DDEP%s="%s" ' % (i, dependencies[i][0]) - CMD += '/DDEP%sP="%s" ' % (i, dependencies[i][1]) - dependencies = pluginDependencies[npapi] - for i in range(len(dependencies)): - CMD += '/DNPAPI_DEP%s="%s" ' % (i, dependencies[i]) + for i, dep in enumerate(dependentFiles.items()): + CMD += '/DDEP%s="%s" ' % (i, dep[0]) + CMD += '/DDEP%sP="%s" ' % (i, dep[1]) + + for i, dep in enumerate(pluginDependencies[npapi]): + CMD += '/DNPAPI_DEP%s="%s" ' % (i, dep) if options.start: CMD += '/DADD_START_MENU ' @@ -588,9 +587,9 @@ def makeInstaller(): CMD += '"' + this_dir + '\\p3d_installer.nsi"' - print "" - print CMD - print "packing..." + print("") + print(CMD) + print("packing...") result = subprocess.call(CMD) if result: sys.exit(result) diff --git a/direct/src/plugin_installer/make_xpi.py b/direct/src/plugin_installer/make_xpi.py index 185a6cdfd4..7cd02fd908 100755 --- a/direct/src/plugin_installer/make_xpi.py +++ b/direct/src/plugin_installer/make_xpi.py @@ -123,10 +123,10 @@ def makeXpiFile(): version files. """ if not options.host_url: - print "Cannot generate xpi file without --host-url." + print("Cannot generate xpi file without --host-url.") sys.exit(1) - print "Generating xpi file" + print("Generating xpi file") root = options.plugin_root if os.path.isdir(os.path.join(root, 'plugin')): root = os.path.join(root, 'plugin') diff --git a/direct/src/plugin_npapi/make_osx_bundle.py b/direct/src/plugin_npapi/make_osx_bundle.py index e4b9f365a6..ce7a102b06 100755 --- a/direct/src/plugin_npapi/make_osx_bundle.py +++ b/direct/src/plugin_npapi/make_osx_bundle.py @@ -15,11 +15,11 @@ import glob import shutil import direct -from pandac.PandaModules import Filename, DSearchPath +from panda3d.core import Filename, DSearchPath def usage(code, msg = ''): - print >> sys.stderr, __doc__ - print >> sys.stderr, msg + sys.stderr.write(__doc__) + sys.stderr.write(msg + '\n') sys.exit(code) def makeBundle(startDir): @@ -62,7 +62,7 @@ def makeBundle(startDir): # All done! bundleFilename.touch() - print bundleFilename.toOsSpecific() + print(bundleFilename.toOsSpecific()) def buildDmg(startDir): fstartDir = Filename.fromOsSpecific(startDir) @@ -79,7 +79,7 @@ def buildDmg(startDir): if __name__ == '__main__': try: opts, args = getopt.getopt(sys.argv[1:], 'h') - except getopt.error, msg: + except getopt.error as msg: usage(1, msg) for opt, arg in opts: diff --git a/direct/src/plugin_standalone/make_osx_bundle.py b/direct/src/plugin_standalone/make_osx_bundle.py index 2fe846a3c3..c88ce5ecf7 100755 --- a/direct/src/plugin_standalone/make_osx_bundle.py +++ b/direct/src/plugin_standalone/make_osx_bundle.py @@ -15,11 +15,11 @@ import glob import shutil import direct -from pandac.PandaModules import Filename, DSearchPath, getModelPath, ExecutionEnvironment +from panda3d.core import Filename, DSearchPath, getModelPath, ExecutionEnvironment def usage(code, msg = ''): - print >> sys.stderr, __doc__ - print >> sys.stderr, msg + sys.stderr.write(__doc__) + sys.stderr.write(msg + '\n') sys.exit(code) def makeBundle(startDir): @@ -71,18 +71,18 @@ def makeBundle(startDir): # Copy in Info.plist, the icon file, and the compiled executable. shutil.copyfile(Filename(fstartDir, "panda3d_mac.plist").toOsSpecific(), plistFilename.toOsSpecific()) shutil.copyfile(icons.toOsSpecific(), iconFilename.toOsSpecific()) - print panda3d_mac, exeFilename + print('%s %s' % (panda3d_mac, exeFilename)) shutil.copyfile(panda3d_mac.toOsSpecific(), exeFilename.toOsSpecific()) os.chmod(exeFilename.toOsSpecific(), 0o755) # All done! bundleFilename.touch() - print bundleFilename.toOsSpecific() + print(bundleFilename.toOsSpecific()) if __name__ == '__main__': try: opts, args = getopt.getopt(sys.argv[1:], 'h') - except getopt.error, msg: + except getopt.error as msg: usage(1, msg) for opt, arg in opts: diff --git a/direct/src/showbase/Audio3DManager.py b/direct/src/showbase/Audio3DManager.py index 5a4fdc295b..e9cdb59eb8 100644 --- a/direct/src/showbase/Audio3DManager.py +++ b/direct/src/showbase/Audio3DManager.py @@ -144,7 +144,7 @@ class Audio3DManager: if (vel!=None): return vel else: - for known_object in self.sound_dict.keys(): + for known_object in list(self.sound_dict.keys()): if self.sound_dict[known_object].count(sound): return known_object.getPosDelta(self.root)/globalClock.getDt() return VBase3(0, 0, 0) @@ -185,7 +185,7 @@ class Audio3DManager: """ # sound is an AudioSound # object is any Panda object with coordinates - for known_object in self.sound_dict.keys(): + for known_object in list(self.sound_dict.keys()): if self.sound_dict[known_object].count(sound): # This sound is already attached to something #return 0 @@ -207,7 +207,7 @@ class Audio3DManager: """ sound will no longer have it's 3D position updated """ - for known_object in self.sound_dict.keys(): + for known_object in list(self.sound_dict.keys()): if self.sound_dict[known_object].count(sound): self.sound_dict[known_object].remove(sound) if len(self.sound_dict[known_object]) == 0: @@ -258,7 +258,7 @@ class Audio3DManager: if self.audio_manager.getActive()==0: return Task.cont - for known_object in self.sound_dict.keys(): + for known_object in list(self.sound_dict.keys()): tracked_sound = 0 while tracked_sound < len(self.sound_dict[known_object]): sound = self.sound_dict[known_object][tracked_sound] @@ -285,7 +285,7 @@ class Audio3DManager: """ taskMgr.remove("Audio3DManager-updateTask") self.detachListener() - for object in self.sound_dict.keys(): + for object in list(self.sound_dict.keys()): for sound in self.sound_dict[object]: self.detachSound(sound) diff --git a/direct/src/showbase/BulletinBoard.py b/direct/src/showbase/BulletinBoard.py index 52265a1334..c46eb0ff0e 100755 --- a/direct/src/showbase/BulletinBoard.py +++ b/direct/src/showbase/BulletinBoard.py @@ -53,7 +53,7 @@ class BulletinBoard: def __repr__(self): str = 'Bulletin Board Contents\n' str += '=======================' - keys = self._dict.keys() + keys = list(self._dict.keys()) keys.sort() for postName in keys: str += '\n%s: %s' % (postName, self._dict[postName]) diff --git a/direct/src/showbase/BulletinBoardGlobal.py b/direct/src/showbase/BulletinBoardGlobal.py index 7bbf494574..dd750d9a22 100755 --- a/direct/src/showbase/BulletinBoardGlobal.py +++ b/direct/src/showbase/BulletinBoardGlobal.py @@ -2,6 +2,6 @@ __all__ = ['bulletinBoard'] -import BulletinBoard +from . import BulletinBoard bulletinBoard = BulletinBoard.BulletinBoard() diff --git a/direct/src/showbase/ContainerLeakDetector.py b/direct/src/showbase/ContainerLeakDetector.py index 580656d65e..abfe5cf99e 100755 --- a/direct/src/showbase/ContainerLeakDetector.py +++ b/direct/src/showbase/ContainerLeakDetector.py @@ -2,7 +2,29 @@ from direct.directnotify.DirectNotifyGlobal import directNotify from direct.showbase.PythonUtil import makeFlywheelGen from direct.showbase.PythonUtil import itype, serialNum, safeRepr, fastRepr from direct.showbase.Job import Job -import types, weakref, random, __builtin__ +import types, weakref, random, sys + +if sys.version_info >= (3, 0): + import builtins as __builtin__ + + intTypes = (int,) + deadEndTypes = (bool, types.BuiltinFunctionType, + types.BuiltinMethodType, complex, + float, int, + type(None), type(NotImplemented), + type, types.CodeType, types.FunctionType, + bytes, str, tuple) +else: + import __builtin__ + + intTypes = (int, long) + deadEndTypes = (types.BooleanType, types.BuiltinFunctionType, + types.BuiltinMethodType, types.ComplexType, + types.FloatType, types.IntType, types.LongType, + types.NoneType, types.NotImplementedType, + types.TypeType, types.CodeType, types.FunctionType, + types.StringType, types.UnicodeType, types.TupleType) + def _createContainerLeak(): def leakContainer(task=None): @@ -17,7 +39,7 @@ def _createContainerLeak(): base.leakContainer[(LeakKey(),)] = {} # test the non-weakref object reference handling if random.random() < .01: - key = random.choice(base.leakContainer.keys()) + key = random.choice(list(base.leakContainer.keys())) ContainerLeakDetector.notify.debug( 'removing reference to leakContainer key %s so it will be garbage-collected' % safeRepr(key)) del base.leakContainer[key] @@ -82,7 +104,7 @@ class Indirection: # store a weakref to the key self.dictKey = weakref.ref(dictKey) self._isWeakRef = True - except TypeError, e: + except TypeError as e: ContainerLeakDetector.notify.debug('could not weakref dict key %s' % keyRepr) self.dictKey = dictKey self._isWeakRef = False @@ -163,7 +185,7 @@ class ObjectRef: # make sure we're not storing a reference to the actual object, # that could cause a memory leak - assert type(objId) in (types.IntType, types.LongType) + assert type(objId) in intTypes # prevent cycles (i.e. base.loader.base.loader) assert not self.goesThrough(objId=objId) @@ -184,7 +206,7 @@ class ObjectRef: def goesThroughGen(self, obj=None, objId=None): if obj is None: - assert type(objId) in (types.IntType, types.LongType) + assert type(objId) in intTypes else: objId = id(obj) o = None @@ -238,11 +260,11 @@ class ObjectRef: evalStr = '%s.%s' % (bis, evalStr) try: container = eval(evalStr) - except NameError, ne: + except NameError as ne: return None - except AttributeError, ae: + except AttributeError as ae: return None - except KeyError, ke: + except KeyError as ke: return None return container @@ -290,7 +312,7 @@ class ObjectRef: indirections = self._indirections for indirection in indirections: indirection.acquire() - for i in xrange(len(indirections)): + for i in range(len(indirections)): yield None if i > 0: prevIndirection = indirections[i-1] @@ -394,19 +416,14 @@ class FindContainers(Job): return 1 def _isDeadEnd(self, obj, objName=None): - if type(obj) in (types.BooleanType, types.BuiltinFunctionType, - types.BuiltinMethodType, types.ComplexType, - types.FloatType, types.IntType, types.LongType, - types.NoneType, types.NotImplementedType, - types.TypeType, types.CodeType, types.FunctionType, - types.StringType, types.UnicodeType, - types.TupleType): + if type(obj) in deadEndTypes: return True + # if it's an internal object, ignore it if id(obj) in ContainerLeakDetector.PrivateIds: return True # prevent crashes in objects that define __cmp__ and don't handle strings - if type(objName) == types.StringType and objName in ('im_self', 'im_class'): + if type(objName) == str and objName in ('im_self', 'im_class'): return True try: className = obj.__class__.__name__ @@ -440,7 +457,7 @@ class FindContainers(Job): objId = id(obj) if objId in self._id2discoveredStartRef: existingRef = self._id2discoveredStartRef[objId] - if type(existingRef) not in (types.IntType, types.LongType): + if type(existingRef) not in intTypes: if (existingRef.getNumIndirections() >= ref.getNumIndirections()): # the ref that we already have is more concise than the new ref @@ -471,7 +488,7 @@ class FindContainers(Job): if curObjRef is None: # choose an object to start a traversal from try: - startRefWorkingList = workingListSelector.next() + startRefWorkingList = next(workingListSelector) except StopIteration: # do relative # of traversals on each set based on how many refs it contains baseLen = len(self._baseStartRefWorkingList.source) @@ -488,7 +505,7 @@ class FindContainers(Job): while True: yield None try: - curObjRef = startRefWorkingList.refGen.next() + curObjRef = next(startRefWorkingList.refGen) break except StopIteration: # we've run out of refs, grab a new set @@ -498,7 +515,7 @@ class FindContainers(Job): # make a generator that yields containers a # of times that is # proportional to their length for fw in makeFlywheelGen( - startRefWorkingList.source.values(), + list(startRefWorkingList.source.values()), countFunc=lambda x: self.getStartObjAffinity(x), scale=.05): yield None @@ -509,7 +526,7 @@ class FindContainers(Job): continue # do we need to go look up the object in _id2ref? sometimes we do that # to avoid storing multiple redundant refs to a single item - if type(curObjRef) in (types.IntType, types.LongType): + if type(curObjRef) in intTypes: startId = curObjRef curObjRef = None try: @@ -560,10 +577,10 @@ class FindContainers(Job): curObjRef = objRef continue - if type(curObj) is types.DictType: + if type(curObj) is dict: key = None attr = None - keys = curObj.keys() + keys = list(curObj.keys()) # we will continue traversing the object graph via one key of the dict, # choose it at random without taking a big chunk of CPU time numKeysLeft = len(keys) + 1 @@ -572,7 +589,7 @@ class FindContainers(Job): numKeysLeft -= 1 try: attr = curObj[key] - except KeyError, e: + except KeyError as e: # this is OK because we are yielding during the iteration self.notify.debug('could not index into %s with key %s' % ( parentObjRef, safeRepr(key))) @@ -617,7 +634,7 @@ class FindContainers(Job): while 1: yield None try: - attr = itr.next() + attr = next(itr) except: # some custom classes don't do well when iterated attr = None @@ -651,13 +668,13 @@ class FindContainers(Job): if curObjRef is None and random.randrange(numAttrsLeft) == 0: curObjRef = objRef del attr - except StopIteration, e: + except StopIteration as e: pass del itr continue - except Exception, e: - print 'FindContainers job caught exception: %s' % e + except Exception as e: + print('FindContainers job caught exception: %s' % e) if __dev__: raise yield Job.Done @@ -693,7 +710,7 @@ class CheckContainers(Job): for result in self._leakDetector.getContainerByIdGen(objId): yield None container = result - except Exception, e: + except Exception as e: # this container no longer exists if self.notify.getDebug(): for contName in self._leakDetector.getContainerNameByIdGen(objId): @@ -714,7 +731,7 @@ class CheckContainers(Job): continue try: cLen = len(container) - except Exception, e: + except Exception as e: # this container no longer exists if self.notify.getDebug(): for contName in self._leakDetector.getContainerNameByIdGen(objId): @@ -800,8 +817,8 @@ class CheckContainers(Job): if config.GetBool('pdb-on-leak-detect', 0): import pdb;pdb.set_trace() pass - except Exception, e: - print 'CheckContainers job caught exception: %s' % e + except Exception as e: + print('CheckContainers job caught exception: %s' % e) if __dev__: raise yield Job.Done @@ -855,9 +872,9 @@ class FPTObjsOfType(Job): except: pass else: - print 'GPTC(' + self._otn + '):' + self.getJobName() + ': ' + ptc - except Exception, e: - print 'FPTObjsOfType job caught exception: %s' % e + print('GPTC(' + self._otn + '):' + self.getJobName() + ': ' + ptc) + except Exception as e: + print('FPTObjsOfType job caught exception: %s' % e) if __dev__: raise yield Job.Done @@ -909,9 +926,9 @@ class FPTObjsNamed(Job): except: pass else: - print 'GPTCN(' + self._on + '):' + self.getJobName() + ': ' + ptc - except Exception, e: - print 'FPTObjsNamed job caught exception: %s' % e + print('GPTCN(' + self._on + '):' + self.getJobName() + ': ' + ptc) + except Exception as e: + print('FPTObjsNamed job caught exception: %s' % e) if __dev__: raise yield Job.Done @@ -950,7 +967,7 @@ class PruneObjectRefs(Job): # reference is invalid, remove it self._leakDetector.removeContainerById(id) _id2baseStartRef = self._leakDetector._findContainersJob._id2baseStartRef - ids = _id2baseStartRef.keys() + ids = list(_id2baseStartRef.keys()) for id in ids: yield None try: @@ -960,7 +977,7 @@ class PruneObjectRefs(Job): # reference is invalid, remove it del _id2baseStartRef[id] _id2discoveredStartRef = self._leakDetector._findContainersJob._id2discoveredStartRef - ids = _id2discoveredStartRef.keys() + ids = list(_id2discoveredStartRef.keys()) for id in ids: yield None try: @@ -969,8 +986,8 @@ class PruneObjectRefs(Job): except: # reference is invalid, remove it del _id2discoveredStartRef[id] - except Exception, e: - print 'PruneObjectRefs job caught exception: %s' % e + except Exception as e: + print('PruneObjectRefs job caught exception: %s' % e) if __dev__: raise yield Job.Done @@ -1058,7 +1075,7 @@ class ContainerLeakDetector(Job): return 'pruneLeakingContainerRefs-%s' % self._serialNum def getContainerIds(self): - return self._id2ref.keys() + return list(self._id2ref.keys()) def getContainerByIdGen(self, id, **kwArgs): # return a generator to look up a container diff --git a/direct/src/showbase/ContainerReport.py b/direct/src/showbase/ContainerReport.py index fd80977f92..753e72e84c 100755 --- a/direct/src/showbase/ContainerReport.py +++ b/direct/src/showbase/ContainerReport.py @@ -95,18 +95,18 @@ class ContainerReport(Job): self._id2pathStr[id(child)] = str(self._id2pathStr[id(parentObj)]) continue - if type(parentObj) is types.DictType: + if type(parentObj) is dict: key = None attr = None - keys = parentObj.keys() + keys = list(parentObj.keys()) try: keys.sort() - except TypeError, e: + except TypeError as e: self.notify.warning('non-sortable dict keys: %s: %s' % (self._id2pathStr[id(parentObj)], repr(e))) for key in keys: try: attr = parentObj[key] - except KeyError, e: + except KeyError as e: self.notify.warning('could not index into %s with key %s' % (self._id2pathStr[id(parentObj)], key)) if id(attr) not in self._visitedIds: @@ -134,7 +134,7 @@ class ContainerReport(Job): index = 0 while 1: try: - attr = itr.next() + attr = next(itr) except: # some custom classes don't do well when iterated attr = None @@ -146,7 +146,7 @@ class ContainerReport(Job): self._id2pathStr[id(attr)] = self._id2pathStr[id(parentObj)] + '[%s]' % index index += 1 del attr - except StopIteration, e: + except StopIteration as e: pass del itr continue @@ -213,11 +213,11 @@ class ContainerReport(Job): if type not in self._type2id2len: return len2ids = invertDictLossless(self._type2id2len[type]) - lengths = len2ids.keys() + lengths = list(len2ids.keys()) lengths.sort() lengths.reverse() - print '=====' - print '===== %s' % type + print('=====') + print('===== %s' % type) count = 0 stop = False for l in lengths: @@ -232,13 +232,13 @@ class ContainerReport(Job): yield None pathStrList.sort() for pathstr in pathStrList: - print '%s: %s' % (l, pathstr) + print('%s: %s' % (l, pathstr)) if limit is not None and count >= limit: return def _output(self, **kArgs): - print "===== ContainerReport: \'%s\' =====" % (self._name,) - initialTypes = (types.DictType, types.ListType, types.TupleType) + print("===== ContainerReport: \'%s\' =====" % (self._name,)) + initialTypes = (dict, list, tuple) for type in initialTypes: for i in self._outputType(type, **kArgs): yield None diff --git a/direct/src/showbase/CountedResource.py b/direct/src/showbase/CountedResource.py index 1a89c663ff..62a25d28b2 100755 --- a/direct/src/showbase/CountedResource.py +++ b/direct/src/showbase/CountedResource.py @@ -97,13 +97,13 @@ if __debug__ and __name__ == '__main__': # Now acquire the resource this class is # managing. - print '-- Acquire Mouse' + print('-- Acquire Mouse') @classmethod def release(cls): # First, release the resource this class is # managing. - print '-- Release Mouse' + print('-- Release Mouse') # The call to the super-class's release() is # not necessary at the moment, but may be in @@ -128,11 +128,11 @@ if __debug__ and __name__ == '__main__': @classmethod def acquire(cls): super(CursorResource, cls).acquire() - print '-- Acquire Cursor' + print('-- Acquire Cursor') @classmethod def release(cls): - print '-- Release Cursor' + print('-- Release Cursor') super(CursorResource, cls).release() @@ -159,70 +159,70 @@ if __debug__ and __name__ == '__main__': @classmethod def acquire(cls): super(InvalidResource, cls).acquire() - print '-- Acquire Invalid' + print('-- Acquire Invalid') @classmethod def release(cls): - print '-- Release Invalid' + print('-- Release Invalid') super(InvalidResource, cls).release() - print '\nAllocate Mouse' + print('\nAllocate Mouse') m = MouseResource() - print 'Free up Mouse' + print('Free up Mouse') del m - print '\nAllocate Cursor' + print('\nAllocate Cursor') c = CursorResource() - print 'Free up Cursor' + print('Free up Cursor') del c - print '\nAllocate Mouse then Cursor' + print('\nAllocate Mouse then Cursor') m = MouseResource() c = CursorResource() - print 'Free up Cursor' + print('Free up Cursor') del c - print 'Free up Mouse' + print('Free up Mouse') del m - print '\nAllocate Mouse then Cursor' + print('\nAllocate Mouse then Cursor') m = MouseResource() c = CursorResource() - print 'Free up Mouse' + print('Free up Mouse') del m - print 'Free up Cursor' + print('Free up Cursor') del c - print '\nAllocate Cursor then Mouse' + print('\nAllocate Cursor then Mouse') c = CursorResource() m = MouseResource() - print 'Free up Mouse' + print('Free up Mouse') del m - print 'Free up Cursor' + print('Free up Cursor') del c - print '\nAllocate Cursor then Mouse' + print('\nAllocate Cursor then Mouse') c = CursorResource() m = MouseResource() - print 'Free up Cursor' + print('Free up Cursor') del c # example of an invalid subclass try: - print '\nAllocate Invalid' + print('\nAllocate Invalid') i = InvalidResource() - print 'Free up Invalid' - except AssertionError,e: - print e - print + print('Free up Invalid') + except AssertionError as e: + print(e) + print('') - print 'Free up Mouse' + print('Free up Mouse') del m def demoFunc(): - print '\nAllocate Cursor within function' + print('\nAllocate Cursor within function') c = CursorResource() - print 'Cursor will be freed on function exit' + print('Cursor will be freed on function exit') demoFunc() diff --git a/direct/src/showbase/DirectObject.py b/direct/src/showbase/DirectObject.py index f881d65b5a..22d846bc3e 100644 --- a/direct/src/showbase/DirectObject.py +++ b/direct/src/showbase/DirectObject.py @@ -4,7 +4,7 @@ __all__ = ['DirectObject'] from direct.directnotify.DirectNotifyGlobal import directNotify -from MessengerGlobal import messenger +from .MessengerGlobal import messenger class DirectObject: """ @@ -60,7 +60,7 @@ class DirectObject: if type(taskOrName) == type(''): # we must use a copy, since task.remove will modify self._taskList if hasattr(self, '_taskList'): - taskListValues = self._taskList.values() + taskListValues = list(self._taskList.values()) for task in taskListValues: if task.name == taskOrName: task.remove() @@ -69,7 +69,7 @@ class DirectObject: def removeAllTasks(self): if hasattr(self,'_taskList'): - for task in self._taskList.values(): + for task in list(self._taskList.values()): task.remove() def _addTask(self, task): diff --git a/direct/src/showbase/DistancePhasedNode.py b/direct/src/showbase/DistancePhasedNode.py index b94e31d028..dae96991af 100755 --- a/direct/src/showbase/DistancePhasedNode.py +++ b/direct/src/showbase/DistancePhasedNode.py @@ -1,7 +1,7 @@ from direct.showbase.DirectObject import DirectObject from direct.directnotify.DirectNotifyGlobal import directNotify from panda3d.core import * -from PhasedObject import PhasedObject +from .PhasedObject import PhasedObject class DistancePhasedNode(PhasedObject, DirectObject, NodePath): """ @@ -84,7 +84,7 @@ class DistancePhasedNode(PhasedObject, DirectObject, NodePath): fromCollideNode = None): NodePath.__init__(self, name) self.phaseParamMap = phaseParamMap - self.phaseParamList = sorted(phaseParamMap.items(), + self.phaseParamList = sorted(list(phaseParamMap.items()), key = lambda x: x[1], reverse = True) PhasedObject.__init__(self, @@ -269,7 +269,7 @@ class BufferedDistancePhasedNode(DistancePhasedNode): def __init__(self, name, bufferParamMap = {}, autoCleanup = True, enterPrefix = 'enter', exitPrefix = 'exit', phaseCollideMask = BitMask32.allOn(), fromCollideNode = None): self.bufferParamMap = bufferParamMap - self.bufferParamList = sorted(bufferParamMap.items(), + self.bufferParamList = sorted(list(bufferParamMap.items()), key = lambda x: x[1], reverse = True) diff --git a/direct/src/showbase/EventManager.py b/direct/src/showbase/EventManager.py index 2d57b9e49b..35616f6002 100644 --- a/direct/src/showbase/EventManager.py +++ b/direct/src/showbase/EventManager.py @@ -3,7 +3,7 @@ __all__ = ['EventManager'] -from MessengerGlobal import * +from .MessengerGlobal import * from direct.directnotify.DirectNotifyGlobal import * from direct.task.TaskManagerGlobal import taskMgr from panda3d.core import PStatCollector, EventQueue, EventHandler diff --git a/direct/src/showbase/EventManagerGlobal.py b/direct/src/showbase/EventManagerGlobal.py index 175008ccdb..9e7000ed51 100644 --- a/direct/src/showbase/EventManagerGlobal.py +++ b/direct/src/showbase/EventManagerGlobal.py @@ -2,6 +2,6 @@ __all__ = ['eventMgr'] -import EventManager +from . import EventManager eventMgr = EventManager.EventManager() diff --git a/direct/src/showbase/ExceptionVarDump.py b/direct/src/showbase/ExceptionVarDump.py index f07161d1f7..82060a7d24 100755 --- a/direct/src/showbase/ExceptionVarDump.py +++ b/direct/src/showbase/ExceptionVarDump.py @@ -3,7 +3,6 @@ __all__ = ["install"] from direct.directnotify.DirectNotifyGlobal import directNotify from direct.showbase.PythonUtil import fastRepr import sys -import types import traceback notify = directNotify.newCategory("ExceptionVarDump") @@ -22,7 +21,7 @@ def _varDump__init__(self, *args, **kArgs): while True: try: frame = sys._getframe(f) - except ValueError, e: + except ValueError as e: break else: f += 1 @@ -111,7 +110,7 @@ def _excepthookDumpVars(eType, eValue, tb): if name in codeNames: name2obj[name] = obj # show them in alphabetical order - names = name2obj.keys() + names = list(name2obj.keys()) names.sort() # push them in reverse order so they'll be popped in the correct order names.reverse() @@ -125,7 +124,7 @@ def _excepthookDumpVars(eType, eValue, tb): name, obj, traversedIds = stateStack.pop() #notify.info('%s, %s, %s' % (name, fastRepr(obj), traversedIds)) r = fastRepr(obj, maxLen=10) - if type(r) is types.StringType: + if type(r) is str: r = r.replace('\n', '\\n') s += '\n %s = %s' % (name, r) # if we've already traversed through this object, don't traverse through it again @@ -145,7 +144,7 @@ def _excepthookDumpVars(eType, eValue, tb): attrName2obj[attrName] = attr if len(attrName2obj): # show them in alphabetical order - attrNames = attrName2obj.keys() + attrNames = list(attrName2obj.keys()) attrNames.sort() # push them in reverse order so they'll be popped in the correct order attrNames.reverse() diff --git a/direct/src/showbase/Factory.py b/direct/src/showbase/Factory.py index fcf9301976..bff33dd931 100755 --- a/direct/src/showbase/Factory.py +++ b/direct/src/showbase/Factory.py @@ -25,7 +25,7 @@ class Factory: (type, self._type2ctor[type], ctor)) self._type2ctor[type] = ctor def _registerTypes(self, type2ctor): - for type, ctor in type2ctor.items(): + for type, ctor in list(type2ctor.items()): self._registerType(type, ctor) def nullCtor(self, *args, **kwArgs): diff --git a/direct/src/showbase/FindCtaPaths.py b/direct/src/showbase/FindCtaPaths.py index 74d63b9617..a530778715 100755 --- a/direct/src/showbase/FindCtaPaths.py +++ b/direct/src/showbase/FindCtaPaths.py @@ -51,7 +51,7 @@ def getPaths(): # these will all be siblings, so we filter out duplicate # parent directories. - print 'Appending to sys.path based on $CTPROJS:' + print('Appending to sys.path based on $CTPROJS:') # First, get the list of packages, then reverse the list to # put it in ctattach order. (The reversal may not matter too @@ -69,14 +69,14 @@ def getPaths(): for package in packages: tree = os.getenv(package) if not tree: - print " CTPROJS contains %s, but $%s is not defined." % (package, package) + print(" CTPROJS contains %s, but $%s is not defined." % (package, package)) sys.exit(1) tree = deCygwinify(tree) parent, base = os.path.split(tree) if base != package.lower(): - print " Warning: $%s refers to a directory named %s (instead of %s)" % (package, base, package.lower()) + print(" Warning: $%s refers to a directory named %s (instead of %s)" % (package, base, package.lower())) if parent not in parents: parents.append(parent) @@ -94,7 +94,7 @@ def getPaths(): # Now the result goes onto sys.path. for parent in parents: - print " %s" % (parent) + print(" %s" % (parent)) if parent not in sys.path: sys.path.append(parent) diff --git a/direct/src/showbase/Finder.py b/direct/src/showbase/Finder.py index b3b2031633..f7c619da91 100644 --- a/direct/src/showbase/Finder.py +++ b/direct/src/showbase/Finder.py @@ -31,8 +31,7 @@ def findClass(className): def rebindClass(filename): file = open(filename, 'r') lines = file.readlines() - for i in xrange(len(lines)): - line = lines[i] + for line in lines: if (line[0:6] == 'class '): # Chop off the "class " syntax and strip extra whitespace classHeader = line[6:].strip() @@ -46,12 +45,12 @@ def rebindClass(filename): if colonLoc > 0: className = classHeader[:colonLoc] else: - print 'error: className not found' + print('error: className not found') # Remove that temp file file.close() os.remove(filename) return - print 'Rebinding class name: ' + className + print('Rebinding class name: ' + className) break # Try to find the original class with this class name @@ -68,7 +67,7 @@ def rebindClass(filename): realClass, realNameSpace = res # Now execute that class def in this namespace - execfile(filename, realNameSpace) + exec(compile(open(filename).read(), filename, 'exec'), realNameSpace) # That execfile should have created a new class obj in that namespace tmpClass = realNameSpace[className] @@ -157,7 +156,7 @@ def replaceMessengerFunc(replaceFuncList): for oldFunc, funcName, newFunc in replaceFuncList: res = messenger.replaceMethod(oldFunc, newFunc) if res: - print ('replaced %s messenger function(s): %s' % (res, funcName)) + print('replaced %s messenger function(s): %s' % (res, funcName)) def replaceTaskMgrFunc(replaceFuncList): try: @@ -166,7 +165,7 @@ def replaceTaskMgrFunc(replaceFuncList): return for oldFunc, funcName, newFunc in replaceFuncList: if taskMgr.replaceMethod(oldFunc, newFunc): - print ('replaced taskMgr function: %s' % funcName) + print('replaced taskMgr function: %s' % funcName) def replaceStateFunc(replaceFuncList): if not sys.modules.get('base.direct.fsm.State'): @@ -175,7 +174,7 @@ def replaceStateFunc(replaceFuncList): for oldFunc, funcName, newFunc in replaceFuncList: res = State.replaceMethod(oldFunc, newFunc) if res: - print ('replaced %s FSM transition function(s): %s' % (res, funcName)) + print('replaced %s FSM transition function(s): %s' % (res, funcName)) def replaceCRFunc(replaceFuncList): try: @@ -188,7 +187,7 @@ def replaceCRFunc(replaceFuncList): return for oldFunc, funcName, newFunc in replaceFuncList: if base.cr.replaceMethod(oldFunc, newFunc): - print ('replaced DistributedObject function: %s' % funcName) + print('replaced DistributedObject function: %s' % funcName) def replaceAIRFunc(replaceFuncList): try: @@ -197,7 +196,7 @@ def replaceAIRFunc(replaceFuncList): return for oldFunc, funcName, newFunc in replaceFuncList: if simbase.air.replaceMethod(oldFunc, newFunc): - print ('replaced DistributedObject function: %s' % funcName) + print('replaced DistributedObject function: %s' % funcName) def replaceIvalFunc(replaceFuncList): # Make sure we have imported IntervalManager and thus created @@ -208,4 +207,4 @@ def replaceIvalFunc(replaceFuncList): for oldFunc, funcName, newFunc in replaceFuncList: res = FunctionInterval.replaceMethod(oldFunc, newFunc) if res: - print ('replaced %s interval function(s): %s' % (res, funcName)) + print('replaced %s interval function(s): %s' % (res, funcName)) diff --git a/direct/src/showbase/GarbageReport.py b/direct/src/showbase/GarbageReport.py index 72c46b4a0e..db91df0c47 100755 --- a/direct/src/showbase/GarbageReport.py +++ b/direct/src/showbase/GarbageReport.py @@ -8,9 +8,13 @@ from direct.showbase.PythonUtil import AlphabetCounter from direct.showbase.Job import Job import gc import types +import sys GarbageCycleCountAnnounceEvent = 'announceGarbageCycleDesc2num' +if sys.version_info >= (3, 0): + xrange = range + class FakeObject: pass @@ -173,7 +177,7 @@ class GarbageReport(Job): if hasattr(self.garbage[i], '_garbageInfo') and callable(self.garbage[i]._garbageInfo): try: info = self.garbage[i]._garbageInfo() - except Exception, e: + except Exception as e: info = str(e) self._id2garbageInfo[id(self.garbage[i])] = info yield None @@ -211,7 +215,7 @@ class GarbageReport(Job): startIndex = 0 # + 1 to include a reference back to the first object endIndex = numObjs + 1 - if type(objs[-1]) is types.InstanceType and type(objs[0]) is types.DictType: + if type(objs[-1]) is types.InstanceType and type(objs[0]) is dict: startIndex -= 1 endIndex -= 1 @@ -227,7 +231,7 @@ class GarbageReport(Job): # skip past the instance dict and get the member obj numToSkip += 1 member = objs[index+2] - for key, value in obj.__dict__.iteritems(): + for key, value in obj.__dict__.items(): if value is member: break yield None @@ -235,11 +239,11 @@ class GarbageReport(Job): key = '' cycleBySyntax += '%s' % key objAlreadyRepresented = True - elif type(obj) is types.DictType: + elif type(obj) is dict: cycleBySyntax += '{' # get object referred to by dict val = objs[index+1] - for key, value in obj.iteritems(): + for key, value in obj.items(): if value is val: break yield None @@ -247,10 +251,10 @@ class GarbageReport(Job): key = '' cycleBySyntax += '%s}' % fastRepr(key) objAlreadyRepresented = True - elif type(obj) in (types.TupleType, types.ListType): + elif type(obj) in (tuple, list): brackets = { - types.TupleType: '()', - types.ListType: '[]', + tuple: '()', + list: '[]', }[type(obj)] # get object being referenced by container nextObj = objs[index+1] @@ -508,16 +512,16 @@ class GarbageReport(Job): candidateCycle, curId, numDelInstances, resumeIndex = stateStack.pop() if self.notify.getDebug(): if self._args.delOnly: - print 'restart: %s root=%s cur=%s numDelInstances=%s resume=%s' % ( - candidateCycle, rootId, curId, numDelInstances, resumeIndex) + print('restart: %s root=%s cur=%s numDelInstances=%s resume=%s' % ( + candidateCycle, rootId, curId, numDelInstances, resumeIndex)) else: - print 'restart: %s root=%s cur=%s resume=%s' % ( - candidateCycle, rootId, curId, resumeIndex) + print('restart: %s root=%s cur=%s resume=%s' % ( + candidateCycle, rootId, curId, resumeIndex)) for index in xrange(resumeIndex, len(self.referentsByNumber[curId])): yield None refId = self.referentsByNumber[curId][index] if self.notify.getDebug(): - print ' : %s -> %s' % (curId, refId) + print(' : %s -> %s' % (curId, refId)) if refId == rootId: # we found a cycle! mark it down and move on to the next refId normCandidateCycle = self._getNormalizedCycle(candidateCycle) @@ -527,7 +531,7 @@ class GarbageReport(Job): # cleaned up by Python if (not self._args.delOnly) or numDelInstances >= 1: if self.notify.getDebug(): - print ' FOUND: ', normCandidateCycle + [normCandidateCycle[0],] + print(' FOUND: ', normCandidateCycle + [normCandidateCycle[0],]) cycles.append(normCandidateCycle + [normCandidateCycle[0],]) uniqueCycleSets.add(normCandidateCycleTuple) elif refId in candidateCycle: @@ -562,9 +566,9 @@ def checkForGarbageLeaks(): numGarbage = len(gc.garbage) if (numGarbage > 0 and config.GetBool('auto-garbage-logging', 0)): if (numGarbage != _CFGLGlobals.LastNumGarbage): - print + print("") gr = GarbageReport('found garbage', threaded=False, collect=False) - print + print("") _CFGLGlobals.LastNumGarbage = numGarbage _CFGLGlobals.LastNumCycles = gr.getNumCycles() messenger.send(GarbageCycleCountAnnounceEvent, [gr.getDesc2numDict()]) diff --git a/direct/src/showbase/Job.py b/direct/src/showbase/Job.py index 4eb511d9a8..02407b29c4 100755 --- a/direct/src/showbase/Job.py +++ b/direct/src/showbase/Job.py @@ -44,7 +44,7 @@ class Job(DirectObject): # # when done, yield Job.Done # - raise "don't call down" + raise NotImplementedError("don't call down") def getPriority(self): return self._priority @@ -112,14 +112,14 @@ if __debug__: # __dev__ not yet available at this point while True: while self._accum < 100: self._accum += 1 - print 'counter = %s, accum = %s' % (self._counter, self._accum) + print('counter = %s, accum = %s' % (self._counter, self._accum)) yield None self._accum = 0 self._counter += 1 if self._counter >= 100: - print 'Job.Done' + print('Job.Done') self.printingEnd() yield Job.Done else: diff --git a/direct/src/showbase/JobManager.py b/direct/src/showbase/JobManager.py index 3474b42f18..0c2ab09bbf 100755 --- a/direct/src/showbase/JobManager.py +++ b/direct/src/showbase/JobManager.py @@ -106,7 +106,7 @@ class JobManager: job.resume() while True: try: - result = gen.next() + result = next(gen) except StopIteration: # Job didn't yield Job.Done, it ran off the end and returned # treat it as if it returned Job.Done @@ -137,7 +137,7 @@ class JobManager: def _getSortedPriorities(self): # returns all job priorities in ascending order - priorities = self._pri2jobId2job.keys() + priorities = list(self._pri2jobId2job.keys()) priorities.sort() return priorities @@ -152,11 +152,11 @@ class JobManager: if self._jobIdGenerator is None: # round-robin the jobs, giving high-priority jobs more timeslices self._jobIdGenerator = flywheel( - self._jobId2timeslices.keys(), + list(self._jobId2timeslices.keys()), countFunc = lambda jobId: self._jobId2timeslices[jobId]) try: # grab the next jobId in the sequence - jobId = self._jobIdGenerator.next() + jobId = next(self._jobIdGenerator) except StopIteration: self._jobIdGenerator = None continue @@ -181,7 +181,7 @@ class JobManager: job.resume() while globalClock.getRealTime() < endT: try: - result = gen.next() + result = next(gen) except StopIteration: # Job didn't yield Job.Done, it ran off the end and returned # treat it as if it returned Job.Done diff --git a/direct/src/showbase/JobManagerGlobal.py b/direct/src/showbase/JobManagerGlobal.py index c5f591715d..767f4ce342 100755 --- a/direct/src/showbase/JobManagerGlobal.py +++ b/direct/src/showbase/JobManagerGlobal.py @@ -1,5 +1,5 @@ __all__ = ['jobMgr'] -import JobManager +from . import JobManager jobMgr = JobManager.JobManager() diff --git a/direct/src/showbase/LeakDetectors.py b/direct/src/showbase/LeakDetectors.py index 92bc944fc8..1124d1301d 100755 --- a/direct/src/showbase/LeakDetectors.py +++ b/direct/src/showbase/LeakDetectors.py @@ -3,14 +3,20 @@ from pandac.PandaModules import * from direct.showbase.DirectObject import DirectObject from direct.showbase.Job import Job -import __builtin__, gc +import gc, sys + +if sys.version_info >= (3, 0): + import builtins +else: + import __builtin__ as builtins + class LeakDetector: def __init__(self): # put this object just under __builtins__ where the # ContainerLeakDetector will find it quickly - if not hasattr(__builtin__, "leakDetectors"): - __builtin__.leakDetectors = {} + if not hasattr(builtins, "leakDetectors"): + builtins.leakDetectors = {} self._leakDetectorsKey = self.getLeakDetectorKey() if __dev__: assert self._leakDetectorsKey not in leakDetectors @@ -52,7 +58,7 @@ class ObjectTypesLeakDetector(LeakDetector): self._thisLdGen = 0 def destroy(self): - for ld in self._type2ld.itervalues(): + for ld in self._type2ld.values(): ld.destroy() LeakDetector.destroy(self) @@ -133,7 +139,7 @@ class CppMemoryUsage(LeakDetector): class TaskLeakDetectorBase: def _getTaskNamePattern(self, taskName): # get a generic string pattern from a task name by removing numeric characters - for i in xrange(10): + for i in (0, 1, 2, 3, 4, 5, 6, 7, 8, 9): taskName = taskName.replace('%s' % i, '') return taskName @@ -165,7 +171,7 @@ class TaskLeakDetector(LeakDetector, TaskLeakDetectorBase): self._taskName2collector = {} def destroy(self): - for taskName, collector in self._taskName2collector.iteritems(): + for taskName, collector in self._taskName2collector.items(): collector.destroy() del self._taskName2collector LeakDetector.destroy(self) @@ -189,7 +195,7 @@ class TaskLeakDetector(LeakDetector, TaskLeakDetectorBase): class MessageLeakDetectorBase: def _getMessageNamePattern(self, msgName): # get a generic string pattern from a message name by removing numeric characters - for i in xrange(10): + for i in (0, 1, 2, 3, 4, 5, 6, 7, 8, 9): msgName = msgName.replace('%s' % i, '') return msgName @@ -266,7 +272,7 @@ class MessageTypesLeakDetector(LeakDetector, MessageLeakDetectorBase): if self._createJob: self._createJob.destroy() self._createJob = None - for msgName, detector in self._msgName2detector.iteritems(): + for msgName, detector in self._msgName2detector.items(): detector.destroy() del self._msgName2detector LeakDetector.destroy(self) @@ -342,7 +348,7 @@ class MessageListenerTypesLeakDetector(LeakDetector): if self._createJob: self._createJob.destroy() self._createJob = None - for typeName, detector in self._typeName2detector.iteritems(): + for typeName, detector in self._typeName2detector.items(): detector.destroy() del self._typeName2detector LeakDetector.destroy(self) diff --git a/direct/src/showbase/Loader.py b/direct/src/showbase/Loader.py index 9521df23ef..5aca6c4042 100644 --- a/direct/src/showbase/Loader.py +++ b/direct/src/showbase/Loader.py @@ -6,7 +6,6 @@ from panda3d.core import * from panda3d.core import Loader as PandaLoader from direct.directnotify.DirectNotifyGlobal import * from direct.showbase.DirectObject import DirectObject -import types # You can specify a phaseChecker callback to check # a modelPath to see if it is being loaded in the correct @@ -139,8 +138,7 @@ class Loader(DirectObject): if allowInstance: loaderOptions.setFlags(loaderOptions.getFlags() | LoaderOptions.LFAllowInstance) - if isinstance(modelPath, types.StringTypes) or \ - isinstance(modelPath, Filename): + if not isinstance(modelPath, (tuple, list, set)): # We were given a single model pathname. modelList = [modelPath] if phaseChecker: @@ -270,8 +268,7 @@ class Loader(DirectObject): # Maybe we were given a node modelNode = model - elif isinstance(model, types.StringTypes) or \ - isinstance(model, Filename): + elif isinstance(model, (str, Filename)): # If we were given a filename, we have to ask the loader # to resolve it for us. options = LoaderOptions(LoaderOptions.LFSearch | LoaderOptions.LFNoDiskCache | LoaderOptions.LFCacheOnly) @@ -284,7 +281,7 @@ class Loader(DirectObject): assert Loader.notify.debug("%s resolves to %s" % (model, modelNode.getFullpath())) else: - raise 'Invalid parameter to unloadModel: %s' % (model) + raise TypeError('Invalid parameter to unloadModel: %s' % (model)) assert Loader.notify.debug("Unloading model: %s" % (modelNode.getFullpath())) ModelPool.releaseModel(modelNode) @@ -301,8 +298,7 @@ class Loader(DirectObject): else: loaderOptions = LoaderOptions(loaderOptions) - if isinstance(modelPath, types.StringTypes) or \ - isinstance(modelPath, Filename): + if not isinstance(modelPath, (tuple, list, set)): # We were given a single model pathname. modelList = [modelPath] nodeList = [node] @@ -795,14 +791,10 @@ class Loader(DirectObject): just as in loadModel(); otherwise, the loading happens before loadSound() returns.""" - if isinstance(soundPath, types.StringTypes) or \ - isinstance(soundPath, Filename): + if not isinstance(soundPath, (MovieAudio, tuple, list, set)): # We were given a single sound pathname. soundList = [soundPath] gotList = False - elif isinstance(soundPath, MovieAudio): - soundList = [soundPath] - gotList = False else: # Assume we were given a list of sound pathnames. soundList = soundPath diff --git a/direct/src/showbase/Messenger.py b/direct/src/showbase/Messenger.py index e9f9241646..20c02ce17a 100644 --- a/direct/src/showbase/Messenger.py +++ b/direct/src/showbase/Messenger.py @@ -3,7 +3,7 @@ __all__ = ['Messenger'] -from PythonUtil import * +from .PythonUtil import * from direct.directnotify import DirectNotifyGlobal import types @@ -87,7 +87,7 @@ class Messenger: self.lock.acquire() try: objs = [] - for refCount, obj in self._id2object.itervalues(): + for refCount, obj in self._id2object.values(): objs.append(obj) return objs finally: @@ -97,7 +97,7 @@ class Messenger: return len(self.__callbacks.get(event, {})) def _getEvents(self): - return self.__callbacks.keys() + return list(self.__callbacks.keys()) def _releaseObject(self, object): # assumes lock is held. @@ -214,7 +214,7 @@ class Messenger: # Get the list of events this object is listening to eventDict = self.__objectEvents.get(id) if eventDict: - for event in eventDict.keys(): + for event in list(eventDict.keys()): # Find the dictionary of all the objects accepting this event acceptorDict = self.__callbacks.get(event) # If this object is there, delete it from the dictionary @@ -240,7 +240,7 @@ class Messenger: # Get the list of events this object is listening to eventDict = self.__objectEvents.get(id) if eventDict: - return eventDict.keys() + return list(eventDict.keys()) return [] finally: self.lock.release() @@ -307,7 +307,7 @@ class Messenger: if not acceptorDict: if __debug__: if foundWatch: - print "Messenger: \"%s\" was sent, but no function in Python listened."%(event,) + print("Messenger: \"%s\" was sent, but no function in Python listened."%(event,)) return if taskChain: @@ -357,7 +357,7 @@ class Messenger: return task.done def __dispatch(self, acceptorDict, event, sentArgs, foundWatch): - for id in acceptorDict.keys(): + for id in list(acceptorDict.keys()): # We have to make this apparently redundant check, because # it is possible that one object removes its own hooks # in response to a handler called by a previous object. @@ -389,10 +389,10 @@ class Messenger: if __debug__: if foundWatch: - print "Messenger: \"%s\" --> %s%s"%( + print("Messenger: \"%s\" --> %s%s"%( event, self.__methodRepr(method), - tuple(extraArgs + sentArgs)) + tuple(extraArgs + sentArgs))) #print "Messenger: \"%s\" --> %s%s"%( # event, @@ -428,7 +428,7 @@ class Messenger: return (len(self.__callbacks) == 0) def getEvents(self): - return self.__callbacks.keys() + return list(self.__callbacks.keys()) def replaceMethod(self, oldMethod, newFunction): """ @@ -436,9 +436,9 @@ class Messenger: you redefine functions with Control-c-Control-v """ retFlag = 0 - for entry in self.__callbacks.items(): + for entry in list(self.__callbacks.items()): event, objectDict = entry - for objectEntry in objectDict.items(): + for objectEntry in list(objectDict.items()): object, params = objectEntry method = params[0] if (type(method) == types.MethodType): @@ -462,8 +462,8 @@ class Messenger: isVerbose = 1 - Messenger.notify.getDebug() Messenger.notify.setDebug(isVerbose) if isVerbose: - print "Verbose mode true. quiet list = %s"%( - self.quieting.keys(),) + print("Verbose mode true. quiet list = %s"%( + list(self.quieting.keys()),)) if __debug__: def watch(self, needle): @@ -527,11 +527,11 @@ class Messenger: return a matching event (needle) if found (in haystack). This is primarily a debugging tool. """ - keys = self.__callbacks.keys() + keys = list(self.__callbacks.keys()) keys.sort() for event in keys: if repr(event).find(needle) >= 0: - print self.__eventRepr(event), + print(self.__eventRepr(event)) return {event: self.__callbacks[event]} def findAll(self, needle, limit=None): @@ -541,11 +541,11 @@ class Messenger: This is primarily a debugging tool. """ matches = {} - keys = self.__callbacks.keys() + keys = list(self.__callbacks.keys()) keys.sort() for event in keys: if repr(event).find(needle) >= 0: - print self.__eventRepr(event), + print(self.__eventRepr(event)) matches[event] = self.__callbacks[event] # if the limit is not None, decrement and # check for break: @@ -575,7 +575,7 @@ class Messenger: """ str = event.ljust(32) + '\t' acceptorDict = self.__callbacks[event] - for key, (method, extraArgs, persistent) in acceptorDict.items(): + for key, (method, extraArgs, persistent) in list(acceptorDict.items()): str = str + self.__methodRepr(method) + ' ' str = str + '\n' return str @@ -585,16 +585,16 @@ class Messenger: Compact version of event, acceptor pairs """ str = "The messenger is currently handling:\n" + "="*64 + "\n" - keys = self.__callbacks.keys() + keys = list(self.__callbacks.keys()) keys.sort() for event in keys: str += self.__eventRepr(event) # Print out the object: event dictionary too str += "="*64 + "\n" - for key, eventDict in self.__objectEvents.items(): + for key, eventDict in list(self.__objectEvents.items()): object = self._getObject(key) str += "%s:\n" % repr(object) - for event in eventDict.keys(): + for event in list(eventDict.keys()): str += " %s\n" % repr(event) str += "="*64 + "\n" + "End of messenger info.\n" @@ -607,12 +607,12 @@ class Messenger: import types str = 'Messenger\n' str = str + '='*50 + '\n' - keys = self.__callbacks.keys() + keys = list(self.__callbacks.keys()) keys.sort() for event in keys: acceptorDict = self.__callbacks[event] str = str + 'Event: ' + event + '\n' - for key in acceptorDict.keys(): + for key in list(acceptorDict.keys()): function, extraArgs, persistent = acceptorDict[key] object = self._getObject(key) if (type(object) == types.InstanceType): diff --git a/direct/src/showbase/MessengerGlobal.py b/direct/src/showbase/MessengerGlobal.py index 38ef00539d..f5a534c0d1 100644 --- a/direct/src/showbase/MessengerGlobal.py +++ b/direct/src/showbase/MessengerGlobal.py @@ -2,6 +2,6 @@ __all__ = ['messenger'] -import Messenger +from . import Messenger messenger = Messenger.Messenger() diff --git a/direct/src/showbase/MessengerLeakDetector.py b/direct/src/showbase/MessengerLeakDetector.py index 50ac0c2a8c..08cbe0778f 100755 --- a/direct/src/showbase/MessengerLeakDetector.py +++ b/direct/src/showbase/MessengerLeakDetector.py @@ -1,7 +1,13 @@ from direct.directnotify.DirectNotifyGlobal import directNotify from direct.showbase.DirectObject import DirectObject from direct.showbase.Job import Job -import gc, __builtin__ +import gc, sys + +if sys.version_info >= (3, 0): + import builtins +else: + import __builtin__ as builtins + class MessengerLeakObject(DirectObject): def __init__(self): @@ -27,7 +33,7 @@ class MessengerLeakDetector(Job): # if an object is attached to one of these, it's attached to builtin # this cuts down on the amount of searching that needs to be done builtinIds = set() - builtinIds.add(id(__builtin__.__dict__)) + builtinIds.add(id(builtins.__dict__)) try: builtinIds.add(id(base)) builtinIds.add(id(base.cr)) @@ -49,7 +55,7 @@ class MessengerLeakDetector(Job): while True: yield None - objects = messenger._Messenger__objectEvents.keys() + objects = list(messenger._Messenger__objectEvents.keys()) assert self.notify.debug('%s objects in the messenger' % len(objects)) for object in objects: yield None diff --git a/direct/src/showbase/ObjectPool.py b/direct/src/showbase/ObjectPool.py index 506a7e2ba5..4b0c0a0731 100755 --- a/direct/src/showbase/ObjectPool.py +++ b/direct/src/showbase/ObjectPool.py @@ -12,14 +12,14 @@ class Diff: self.lost=lost self.gained=gained def printOut(self, full=False): - print 'lost %s objects, gained %s objects' % (len(self.lost), len(self.gained)) - print '\n\nself.lost\n' - print self.lost.typeFreqStr() - print '\n\nself.gained\n' - print self.gained.typeFreqStr() + print('lost %s objects, gained %s objects' % (len(self.lost), len(self.gained))) + print('\n\nself.lost\n') + print(self.lost.typeFreqStr()) + print('\n\nself.gained\n') + print(self.gained.typeFreqStr()) if full: self.gained.printObjsByType() - print '\n\nGAINED-OBJECT REFERRERS\n' + print('\n\nGAINED-OBJECT REFERRERS\n') self.gained.printReferrers(1) class ObjectPool: @@ -53,14 +53,14 @@ class ObjectPool: del self._count2types def getTypes(self): - return self._type2objs.keys() + return list(self._type2objs.keys()) def getObjsOfType(self, type): return self._type2objs.get(type, []) def printObjsOfType(self, type): for obj in self._type2objs.get(type, []): - print repr(obj) + print(repr(obj)) def diff(self, other): """print difference between this pool and 'other' pool""" @@ -97,8 +97,8 @@ class ObjectPool: return s def printObjsByType(self): - print 'Object Pool: Objects By Type' - print '\n============================' + print('Object Pool: Objects By Type') + print('\n============================') counts = list(set(self._count2types.keys())) counts.sort() # print types with the smallest number of instances first, in case @@ -107,8 +107,8 @@ class ObjectPool: for count in counts: types = makeList(self._count2types[count]) for typ in types: - print 'TYPE: %s, %s objects' % (repr(typ), len(self._type2objs[typ])) - print getNumberedTypedSortedString(self._type2objs[typ]) + print('TYPE: %s, %s objects' % (repr(typ), len(self._type2objs[typ]))) + print(getNumberedTypedSortedString(self._type2objs[typ])) def containerLenStr(self): s = 'Object Pool: Container Lengths' @@ -127,17 +127,17 @@ class ObjectPool: for count in counts: types = makeList(self._count2types[count]) for typ in types: - print '\n\nTYPE: %s' % repr(typ) - for i in xrange(min(numEach,len(self._type2objs[typ]))): + print('\n\nTYPE: %s' % repr(typ)) + for i in range(min(numEach, len(self._type2objs[typ]))): obj = self._type2objs[typ][i] - print '\nOBJ: %s\n' % safeRepr(obj) + print('\nOBJ: %s\n' % safeRepr(obj)) referrers = gc.get_referrers(obj) - print '%s REFERRERS:\n' % len(referrers) + print('%s REFERRERS:\n' % len(referrers)) if len(referrers): - print getNumberedTypedString(referrers, maxLen=80, - numPrefix='REF') + print(getNumberedTypedString(referrers, maxLen=80, + numPrefix='REF')) else: - print '' + print('') def __len__(self): return len(self._objs) diff --git a/direct/src/showbase/ObjectReport.py b/direct/src/showbase/ObjectReport.py index 084557f4b1..b860932d2d 100755 --- a/direct/src/showbase/ObjectReport.py +++ b/direct/src/showbase/ObjectReport.py @@ -7,7 +7,11 @@ from direct.showbase import DirectObject, ObjectPool, GarbageReport from direct.showbase.PythonUtil import makeList, Sync import gc import sys -import __builtin__ + +if sys.version_info >= (3, 0): + import builtins +else: + import __builtin__ as builtins """ >>> from direct.showbase import ObjectReport @@ -134,7 +138,7 @@ class ObjectReport: gc_objects = gc.get_objects() # use get_referents to find everything else objects = gc_objects - objects.append(__builtin__.__dict__) + objects.append(builtins.__dict__) nextObjList = gc_objects found = set() found.add(id(objects)) @@ -160,7 +164,7 @@ class ObjectReport: else: objs = [] stateStack = Stack() - root = __builtins__ + root = builtins objIds = set([id(root)]) stateStack.push((root, None, 0)) while True: @@ -183,7 +187,7 @@ class ObjectReport: adjacents = newObjs if len(adjacents) == 0: print 'DEAD END' - for i in xrange(resumeIndex, len(adjacents)): + for i in range(resumeIndex, len(adjacents)): adj = adjacents[i] stateStack.push((obj, adjacents, i+1)) stateStack.push((adj, None, 0)) diff --git a/direct/src/showbase/OnScreenDebug.py b/direct/src/showbase/OnScreenDebug.py index 7dd70a2912..ba24b0637a 100755 --- a/direct/src/showbase/OnScreenDebug.py +++ b/direct/src/showbase/OnScreenDebug.py @@ -4,7 +4,6 @@ __all__ = ['OnScreenDebug'] from panda3d.core import * -import types from direct.gui import OnscreenText from direct.directtools import DirectUtil @@ -36,7 +35,7 @@ class OnScreenDebug: font = loader.loadFont(fontPath) if not font.isValid(): - print "failed to load OnScreenDebug font", fontPath + print("failed to load OnScreenDebug font %s" % fontPath) font = TextNode.getDefaultFont() self.onScreenText = OnscreenText.OnscreenText( pos = (-1.0, 0.9), fg=fgColor, bg=bgColor, @@ -51,7 +50,7 @@ class OnScreenDebug: if not self.onScreenText: self.load() self.onScreenText.clearText() - entries = self.data.items() + entries = list(self.data.items()) entries.sort() for k, v in entries: if v[0] == self.frame: @@ -64,7 +63,7 @@ class OnScreenDebug: #isNew = "was" isNew = "~" value = v[1] - if type(value) == types.FloatType: + if type(value) == float: value = "% 10.4f"%(value,) # else: other types will be converted to str by the "%s" self.onScreenText.appendText("%20s %s %-44s\n"%(k, isNew, value)) @@ -88,7 +87,7 @@ class OnScreenDebug: def removeAllWithPrefix(self, prefix): toRemove = [] - for key in self.data.keys(): + for key in list(self.data.keys()): if len(key) >= len(prefix): if key[:len(prefix)] == prefix: toRemove.append(key) diff --git a/direct/src/showbase/PhasedObject.py b/direct/src/showbase/PhasedObject.py index 43c43c4b53..4a6dad1481 100755 --- a/direct/src/showbase/PhasedObject.py +++ b/direct/src/showbase/PhasedObject.py @@ -37,7 +37,7 @@ class PhasedObject: self.aliasPhaseMap = {} self.__phasing = False - for alias,phase in aliasMap.items(): + for alias,phase in list(aliasMap.items()): self.setAlias(phase, alias) def __repr__(self): @@ -168,26 +168,26 @@ if __debug__: self.setPhase('Away') def loadPhaseAway(self): - print 'loading Away' + print('loading Away') def unloadPhaseAway(self): - print 'unloading Away' + print('unloading Away') def loadPhaseFar(self): - print 'loading Far' + print('loading Far') def unloadPhaseFar(self): - print 'unloading Far' + print('unloading Far') def loadPhaseNear(self): - print 'loading Near' + print('loading Near') def unloadPhaseNear(self): - print 'unloading Near' + print('unloading Near') def loadPhaseAt(self): - print 'loading At' + print('loading At') def unloadPhaseAt(self): - print 'unloading At' + print('unloading At') diff --git a/direct/src/showbase/ProfileSession.py b/direct/src/showbase/ProfileSession.py index 0d7c7bd8c2..3470f0dc9e 100755 --- a/direct/src/showbase/ProfileSession.py +++ b/direct/src/showbase/ProfileSession.py @@ -1,11 +1,18 @@ +from __future__ import print_function from panda3d.core import TrueClock from direct.directnotify.DirectNotifyGlobal import directNotify from direct.showbase.PythonUtil import ( StdoutCapture, _installProfileCustomFuncs,_removeProfileCustomFuncs, _getProfileResultFileInfo, _setProfileResultsFileInfo) -import __builtin__ import profile import pstats +import sys + +if sys.version_info >= (3, 0): + import builtins +else: + import __builtin__ as builtins + class PercentStats(pstats.Stats): # prints more useful output when sampled durations are shorter than a millisecond @@ -22,27 +29,27 @@ class PercentStats(pstats.Stats): def print_stats(self, *amount): for filename in self.files: - print filename - if self.files: print + print(filename) + if self.files: print() indent = ' ' * 8 for func in self.top_level: - print indent, func_get_function_name(func) + print(indent, func_get_function_name(func)) - print indent, self.total_calls, "function calls", + print(indent, self.total_calls, "function calls", end=' ') if self.total_calls != self.prim_calls: - print "(%d primitive calls)" % self.prim_calls, + print("(%d primitive calls)" % self.prim_calls, end=' ') # DCR #print "in %.3f CPU seconds" % self.total_tt - print "in %s CPU milliseconds" % (self.total_tt * 1000.) + print("in %s CPU milliseconds" % (self.total_tt * 1000.)) if self._totalTime != self.total_tt: - print indent, 'percentages are of %s CPU milliseconds' % (self._totalTime * 1000) - print + print(indent, 'percentages are of %s CPU milliseconds' % (self._totalTime * 1000)) + print() width, list = self.get_print_list(amount) if list: self.print_title() for func in list: self.print_line(func) - print + print() # DCR #print return self @@ -64,20 +71,20 @@ class PercentStats(pstats.Stats): f8 = self.f8 if nc != cc: c = c + '/' + str(cc) - print c.rjust(9), - print f8(tt), + print(c.rjust(9), end=' ') + print(f8(tt), end=' ') if nc == 0: - print ' '*8, + print(' '*8, end=' ') else: - print f8(tt/nc), - print f8(ct), + print(f8(tt/nc), end=' ') + print(f8(ct), end=' ') if cc == 0: - print ' '*8, + print(' '*8, end=' ') else: - print f8(ct/cc), + print(f8(ct/cc), end=' ') # DCR #print func_std_string(func) - print PercentStats.func_std_string(func) + print(PercentStats.func_std_string(func)) class ProfileSession: # class that encapsulates a profile of a single callable using Python's standard @@ -155,7 +162,7 @@ class ProfileSession: self._reset() # if we're already profiling, just run the func and don't profile - if 'globalProfileSessionFunc' in __builtin__.__dict__: + if 'globalProfileSessionFunc' in builtins.__dict__: self.notify.warning('could not profile %s' % self._func) result = self._func() if self._duration is None: @@ -163,8 +170,8 @@ class ProfileSession: else: # put the function in the global namespace so that profile can find it assert hasattr(self._func, '__call__') - __builtin__.globalProfileSessionFunc = self._func - __builtin__.globalProfileSessionResult = [None] + builtins.globalProfileSessionFunc = self._func + builtins.globalProfileSessionResult = [None] # set up the RAM file self._filenames.append(self._getNextFilename()) @@ -197,7 +204,7 @@ class ProfileSession: # calculate the duration (this is dependent on the internal Python profile data format. # see profile.py and pstats.py, this was copied from pstats.Stats.strip_dirs) maxTime = 0. - for cc, nc, tt, ct, callers in profData[1].itervalues(): + for cc, nc, tt, ct, callers in profData[1].values(): if ct > maxTime: maxTime = ct self._duration = maxTime @@ -206,8 +213,8 @@ class ProfileSession: # clean up the globals result = globalProfileSessionResult[0] - del __builtin__.__dict__['globalProfileSessionFunc'] - del __builtin__.__dict__['globalProfileSessionResult'] + del builtins.__dict__['globalProfileSessionFunc'] + del builtins.__dict__['globalProfileSessionResult'] self._successfulProfiles += 1 diff --git a/direct/src/showbase/PythonUtil.py b/direct/src/showbase/PythonUtil.py index e1750cf21f..c433384859 100644 --- a/direct/src/showbase/PythonUtil.py +++ b/direct/src/showbase/PythonUtil.py @@ -11,7 +11,7 @@ __all__ = ['indent', 'boolEqual', 'lineupPos', 'formatElapsedSeconds', 'solveQuadratic', 'findPythonModule', 'mostDerivedLast', 'weightedChoice', 'randFloat', 'normalDistrib', -'weightedRand', 'randUint31', 'randInt32', 'randUint32', +'weightedRand', 'randUint31', 'randInt32', 'SerialNumGen', 'serialNum', 'uniqueName', 'Enum', 'Singleton', 'SingletonError', 'printListEnum', 'safeRepr', 'fastRepr', 'isDefaultValue', @@ -33,19 +33,24 @@ if __debug__: 'getProfileResultString', 'printStack', 'printReverseStack'] import types -import string import math import os import sys import random import time -import __builtin__ import importlib __report_indent = 3 from panda3d.core import ConfigVariableBool +if sys.version_info >= (3, 0): + import builtins + xrange = range +else: + import __builtin__ as builtins + + """ # with one integer positional arg, this uses about 4/5 of the memory of the Functor class below def Functor(function, *args, **kArgs): @@ -93,7 +98,7 @@ class Functor: except: argStr = 'bad repr: %s' % arg.__class__ s += ', %s' % argStr - for karg, value in self._kargs.items(): + for karg, value in list(self._kargs.items()): s += ', %s=%s' % (karg, repr(value)) s += ')' return s @@ -220,13 +225,13 @@ if __debug__: return r def printStack(): - print StackTrace(start=1).compact() + print(StackTrace(start=1).compact()) return True def printReverseStack(): - print StackTrace(start=1).reverseCompact() + print(StackTrace(start=1).reverseCompact()) return True def printVerboseStack(): - print StackTrace(start=1) + print(StackTrace(start=1)) return True #----------------------------------------------------------------------------- @@ -273,7 +278,7 @@ if __debug__: return traceFunctionCall(sys._getframe(2)) def printThisCall(): - print traceFunctionCall(sys._getframe(1)) + print(traceFunctionCall(sys._getframe(1))) return 1 # to allow "assert printThisCall()" # Magic numbers: These are the bit masks in func_code.co_flags that @@ -284,7 +289,7 @@ _KEY_DICT = 8 def doc(obj): if (isinstance(obj, types.MethodType)) or \ (isinstance(obj, types.FunctionType)): - print obj.__doc__ + print(obj.__doc__) def adjust(command = None, dim = 1, parent = None, **kw): """ @@ -312,15 +317,15 @@ def adjust(command = None, dim = 1, parent = None, **kw): Valuator = importlib.import_module('direct.tkwidgets.Valuator') # Set command if specified if command: - kw['command'] = lambda x: apply(command, x) + kw['command'] = lambda x: command(*x) if parent is None: kw['title'] = command.__name__ kw['dim'] = dim # Create toplevel if needed if not parent: - vg = apply(Valuator.ValuatorGroupPanel, (parent,), kw) + vg = Valuator.ValuatorGroupPanel(parent, **kw) else: - vg = apply(Valuator.ValuatorGroup, (parent,), kw) + vg = Valuator.ValuatorGroup(parent, **kw) vg.pack(expand = 1, fill = 'x') return vg @@ -378,18 +383,18 @@ def sameElements(a, b): def makeList(x): """returns x, converted to a list""" - if type(x) is types.ListType: + if type(x) is list: return x - elif type(x) is types.TupleType: + elif type(x) is tuple: return list(x) else: return [x,] def makeTuple(x): """returns x, converted to a tuple""" - if type(x) is types.ListType: + if type(x) is list: return tuple(x) - elif type(x) is types.TupleType: + elif type(x) is tuple: return x else: return (x,) @@ -429,7 +434,7 @@ def invertDict(D, lossy=False): n = {} for key, value in D.items(): if not lossy and value in n: - raise 'duplicate key in invertDict: %s' % value + raise Exception('duplicate key in invertDict: %s' % value) n[value] = key return n @@ -587,7 +592,7 @@ class StdoutPassthrough(StdoutCapture): # constant profile defaults if __debug__: - from StringIO import StringIO + from io import StringIO PyUtilProfileDefaultFilename = 'profiledata' PyUtilProfileDefaultLines = 80 @@ -604,29 +609,29 @@ if __debug__: def profileFunc(callback, name, terse, log=True): global _ProfileResultStr - if 'globalProfileFunc' in __builtin__.__dict__: + if 'globalProfileFunc' in builtins.__dict__: # rats. Python profiler is not re-entrant... base.notify.warning( 'PythonUtil.profileStart(%s): aborted, already profiling %s' #'\nStack Trace:\n%s' - % (name, __builtin__.globalProfileFunc, + % (name, builtins.globalProfileFunc, #StackTrace() )) return - __builtin__.globalProfileFunc = callback - __builtin__.globalProfileResult = [None] + builtins.globalProfileFunc = callback + builtins.globalProfileResult = [None] prefix = '***** START PROFILE: %s *****' % name if log: - print prefix + print(prefix) startProfile(cmd='globalProfileResult[0]=globalProfileFunc()', callInfo=(not terse), silent=not log) suffix = '***** END PROFILE: %s *****' % name if log: - print suffix + print(suffix) else: _ProfileResultStr = '%s\n%s\n%s' % (prefix, _ProfileResultStr, suffix) result = globalProfileResult[0] - del __builtin__.__dict__['globalProfileFunc'] - del __builtin__.__dict__['globalProfileResult'] + del builtins.__dict__['globalProfileFunc'] + del builtins.__dict__['globalProfileResult'] return result def profiled(category=None, terse=False): @@ -641,7 +646,7 @@ if __debug__: want-profile-particles 1 """ - assert type(category) in (types.StringType, types.NoneType), "must provide a category name for @profiled" + assert type(category) in (str, type(None)), "must provide a category name for @profiled" # allow profiling in published versions """ @@ -720,8 +725,8 @@ if __debug__: assert filename not in profileFilenames profileFilenames.add(filename) profileFilenameList.push(filename) - movedOpenFuncs.append(__builtin__.open) - __builtin__.open = _profileOpen + movedOpenFuncs.append(builtins.open) + builtins.open = _profileOpen movedDumpFuncs.append(marshal.dump) marshal.dump = _profileMarshalDump movedLoadFuncs.append(marshal.load) @@ -746,7 +751,7 @@ if __debug__: assert profileFilenameList.top() == filename marshal.load = movedLoadFuncs.pop() marshal.dump = movedDumpFuncs.pop() - __builtin__.open = movedOpenFuncs.pop() + builtins.open = movedOpenFuncs.pop() profileFilenames.remove(filename) profileFilenameList.pop() profileFilename2file.pop(filename, None) @@ -763,10 +768,10 @@ if __debug__: # # def func(self=self): # self.load() - # import __builtin__ - # __builtin__.func = func + # import builtins + # builtins.func = func # PythonUtil.startProfile(cmd='func()', filename='profileData') - # del __builtin__.func + # del builtins.func # def _profileWithoutGarbageLeak(cmd, filename): # The profile module isn't necessarily installed on every Python @@ -1162,8 +1167,8 @@ def weightedRand(valDict, rng=random.random): -Weights need not add up to any particular value. -The actual selection will be returned. """ - selections = valDict.keys() - weights = valDict.values() + selections = list(valDict.keys()) + weights = list(valDict.values()) totalWeight = 0 for weight in weights: @@ -1195,11 +1200,6 @@ def randInt32(rng=random.random): i *= -1 return i -def randUint32(rng=random.random): - """returns a random integer in [0..2^32). - rng must return float in [0..1]""" - return long(rng() * 0xFFFFFFFFL) - class SerialNumGen: """generates serial numbers""" def __init__(self, start=None): @@ -1228,15 +1228,16 @@ def uniqueName(name): class EnumIter: def __init__(self, enum): - self._values = enum._stringTable.keys() + self._values = list(enum._stringTable.keys()) self._index = 0 def __iter__(self): return self - def next(self): + def __next__(self): if self._index >= len(self._values): raise StopIteration self._index += 1 return self._values[self._index-1] + next = __next__ class Enum: """Pass in list of strings or string of comma-separated strings. @@ -1258,6 +1259,8 @@ class Enum: """ if __debug__: + import string + # chars that cannot appear within an item string. InvalidChars = string.whitespace def _checkValidIdentifier(item): @@ -1389,7 +1392,7 @@ def printListEnumGen(l): n //= 10 format = '%0' + '%s' % digits + 'i:%s' for i in range(len(l)): - print format % (i, l[i]) + print(format % (i, l[i])) yield None def printListEnum(l): @@ -1461,10 +1464,10 @@ def fastRepr(obj, maxLen=200, strFactor=10, _visitedIds=None): _visitedIds = set() if id(obj) in _visitedIds: return '' % itype(obj) - if type(obj) in (types.TupleType, types.ListType): + if type(obj) in (tuple, list): s = '' - s += {types.TupleType: '(', - types.ListType: '[',}[type(obj)] + s += {tuple: '(', + list: '[',}[type(obj)] if maxLen is not None and len(obj) > maxLen: o = obj[:maxLen] ellips = '...' @@ -1477,16 +1480,16 @@ def fastRepr(obj, maxLen=200, strFactor=10, _visitedIds=None): s += ', ' _visitedIds.remove(id(obj)) s += ellips - s += {types.TupleType: ')', - types.ListType: ']',}[type(obj)] + s += {tuple: ')', + list: ']',}[type(obj)] return s - elif type(obj) is types.DictType: + elif type(obj) is dict: s = '{' if maxLen is not None and len(obj) > maxLen: - o = obj.keys()[:maxLen] + o = list(obj.keys())[:maxLen] ellips = '...' else: - o = obj.keys() + o = list(obj.keys()) ellips = '' _visitedIds.add(id(obj)) for key in o: @@ -1497,7 +1500,7 @@ def fastRepr(obj, maxLen=200, strFactor=10, _visitedIds=None): s += ellips s += '}' return s - elif type(obj) is types.StringType: + elif type(obj) is str: if maxLen is not None: maxLen *= strFactor if maxLen is not None and len(obj) > maxLen: @@ -1515,14 +1518,14 @@ def fastRepr(obj, maxLen=200, strFactor=10, _visitedIds=None): def convertTree(objTree, idList): newTree = {} - for key in objTree.keys(): + for key in list(objTree.keys()): obj = (idList[key],) newTree[obj] = {} r_convertTree(objTree[key], newTree[obj], idList) return newTree def r_convertTree(oldTree, newTree, idList): - for key in oldTree.keys(): + for key in list(oldTree.keys()): obj = idList.get(key) if(not obj): @@ -1535,14 +1538,14 @@ def r_convertTree(oldTree, newTree, idList): def pretty_print(tree): for name in tree.keys(): - print name + print(name) r_pretty_print(tree[name], 0) def r_pretty_print(tree, num): num+=1 for name in tree.keys(): - print " "*num,name + print(" "*num,name) r_pretty_print(tree[name],num) @@ -1568,13 +1571,13 @@ def appendStr(obj, st): class ScratchPad: """empty class to stick values onto""" def __init__(self, **kArgs): - for key, value in kArgs.iteritems(): + for key, value in kArgs.items(): setattr(self, key, value) self._keys = set(kArgs.keys()) def add(self, **kArgs): - for key, value in kArgs.iteritems(): + for key, value in kArgs.items(): setattr(self, key, value) - self._keys.update(kArgs.keys()) + self._keys.update(list(kArgs.keys())) def destroy(self): for key in self._keys: delattr(self, key) @@ -1639,10 +1642,10 @@ def deeptype(obj, maxLen=100, _visitedIds=None): if id(obj) in _visitedIds: return '' % itype(obj) t = type(obj) - if t in (types.TupleType, types.ListType): + if t in (tuple, list): s = '' - s += {types.TupleType: '(', - types.ListType: '[',}[type(obj)] + s += {tuple: '(', + list: '[',}[type(obj)] if maxLen is not None and len(obj) > maxLen: o = obj[:maxLen] ellips = '...' @@ -1655,16 +1658,16 @@ def deeptype(obj, maxLen=100, _visitedIds=None): s += ', ' _visitedIds.remove(id(obj)) s += ellips - s += {types.TupleType: ')', - types.ListType: ']',}[type(obj)] + s += {tuple: ')', + list: ']',}[type(obj)] return s - elif type(obj) is types.DictType: + elif type(obj) is dict: s = '{' if maxLen is not None and len(obj) > maxLen: - o = obj.keys()[:maxLen] + o = list(obj.keys())[:maxLen] ellips = '...' else: - o = obj.keys() + o = list(obj.keys()) ellips = '' _visitedIds.add(id(obj)) for key in o: @@ -1745,7 +1748,7 @@ def printNumberedTyped(items, maxLen=5000): if len(objStr) > maxLen: snip = '' objStr = '%s%s' % (objStr[:(maxLen-len(snip))], snip) - print format % (i, itype(items[i]), objStr) + print(format % (i, itype(items[i]), objStr)) def printNumberedTypesGen(items, maxLen=5000): digits = 0 @@ -1756,7 +1759,7 @@ def printNumberedTypesGen(items, maxLen=5000): digits = digits format = '%0' + '%s' % digits + 'i:%s' for i in xrange(len(items)): - print format % (i, itype(items[i])) + print(format % (i, itype(items[i]))) yield None def printNumberedTypes(items, maxLen=5000): @@ -2048,7 +2051,7 @@ def report(types = [], prefix = '', xform = None, notifyFunc = None, dConfigPara pass pass - except NameError,e: + except NameError as e: return decorator globalClockDelta = importlib.import_module("direct.distributed.ClockDelta").globalClockDelta @@ -2101,18 +2104,18 @@ def report(types = [], prefix = '', xform = None, notifyFunc = None, dConfigPara if notifyFunc: notifyFunc(outStr % (prefix,)) else: - print indent(outStr % (prefix,)) + print(indent(outStr % (prefix,))) else: if notifyFunc: notifyFunc(outStr) else: - print indent(outStr) + print(indent(outStr)) if 'interests' in types: base.cr.printInterestSets() if 'stackTrace' in types: - print StackTrace() + print(StackTrace()) global __report_indent rVal = None @@ -2122,7 +2125,7 @@ def report(types = [], prefix = '', xform = None, notifyFunc = None, dConfigPara finally: __report_indent -= 1 if rVal is not None: - print indent(' -> '+repr(rVal)) + print(indent(' -> '+repr(rVal))) pass pass return rVal @@ -2177,12 +2180,12 @@ if __debug__: def _exceptionLogged(*args, **kArgs): try: return f(*args, **kArgs) - except Exception, e: + except Exception as e: try: s = '%s(' % f.__name__ for arg in args: s += '%s, ' % arg - for key, value in kArgs.items(): + for key, value in list(kArgs.items()): s += '%s=%s, ' % (key, value) if len(args) or len(kArgs): s = s[:-2] @@ -2235,7 +2238,7 @@ def makeFlywheelGen(objects, countList=None, countFunc=None, scale=None): def flywheel(index2objectAndCount): # generator to produce a sequence whose elements appear a specific number of times while len(index2objectAndCount): - keyList = index2objectAndCount.keys() + keyList = list(index2objectAndCount.keys()) for key in keyList: if index2objectAndCount[key][1] > 0: yield index2objectAndCount[key][0] @@ -2322,7 +2325,7 @@ if __debug__: st=globalClock.getRealTime() f(*args,**kArgs) s=globalClock.getRealTime()-st - print "Function %s.%s took %s seconds"%(f.__module__, f.__name__,s) + print("Function %s.%s took %s seconds"%(f.__module__, f.__name__,s)) else: import profile as prof, pstats @@ -2355,7 +2358,7 @@ def getTotalAnnounceTime(): def getAnnounceGenerateTime(stat): val=0 stats=stat.stats - for i in stats.keys(): + for i in list(stats.keys()): if(i[2]=="announceGenerate"): newVal=stats[i][3] if(newVal>val): @@ -2418,9 +2421,9 @@ class MiniLogSentry: del self.log def logBlock(id, msg): - print '<< LOGBLOCK(%03d)' % id - print str(msg) - print '/LOGBLOCK(%03d) >>' % id + print('<< LOGBLOCK(%03d)' % id) + print(str(msg)) + print('/LOGBLOCK(%03d) >>' % id) class HierarchyException(Exception): JOSWILSO = 0 @@ -2592,9 +2595,6 @@ def endSuperLog(): superLogFile.close() superLogFile = None -def isInteger(n): - return type(n) in (types.IntType, types.LongType) - def configIsToday(configName): # TODO: replace usage of strptime with something else # returns true if config string is a valid representation of today's date @@ -2660,68 +2660,53 @@ if __debug__ and __name__ == '__main__': assert unescapeHtmlString('as%32df') == 'as2df' assert unescapeHtmlString('asdf%32') == 'asdf2' -def unicodeUtf8(s): - # * -> Unicode UTF-8 - if type(s) is types.UnicodeType: - return s - else: - return unicode(str(s), 'utf-8') - -def encodedUtf8(s): - # * -> 8-bit-encoded UTF-8 - return unicodeUtf8(s).encode('utf-8') - -import __builtin__ -__builtin__.Functor = Functor -__builtin__.Stack = Stack -__builtin__.Queue = Queue -__builtin__.Enum = Enum -__builtin__.SerialNumGen = SerialNumGen -__builtin__.SerialMaskedGen = SerialMaskedGen -__builtin__.ScratchPad = ScratchPad -__builtin__.uniqueName = uniqueName -__builtin__.serialNum = serialNum +builtins.Functor = Functor +builtins.Stack = Stack +builtins.Queue = Queue +builtins.Enum = Enum +builtins.SerialNumGen = SerialNumGen +builtins.SerialMaskedGen = SerialMaskedGen +builtins.ScratchPad = ScratchPad +builtins.uniqueName = uniqueName +builtins.serialNum = serialNum if __debug__: - __builtin__.profiled = profiled - __builtin__.exceptionLogged = exceptionLogged -__builtin__.itype = itype -__builtin__.appendStr = appendStr -__builtin__.bound = bound -__builtin__.clamp = clamp -__builtin__.lerp = lerp -__builtin__.makeList = makeList -__builtin__.makeTuple = makeTuple + builtins.profiled = profiled + builtins.exceptionLogged = exceptionLogged +builtins.itype = itype +builtins.appendStr = appendStr +builtins.bound = bound +builtins.clamp = clamp +builtins.lerp = lerp +builtins.makeList = makeList +builtins.makeTuple = makeTuple if __debug__: - __builtin__.printStack = printStack - __builtin__.printReverseStack = printReverseStack - __builtin__.printVerboseStack = printVerboseStack -__builtin__.DelayedCall = DelayedCall -__builtin__.DelayedFunctor = DelayedFunctor -__builtin__.FrameDelayedCall = FrameDelayedCall -__builtin__.SubframeCall = SubframeCall -__builtin__.invertDict = invertDict -__builtin__.invertDictLossless = invertDictLossless -__builtin__.getBase = getBase -__builtin__.getRepository = getRepository -__builtin__.safeRepr = safeRepr -__builtin__.fastRepr = fastRepr -__builtin__.nullGen = nullGen -__builtin__.flywheel = flywheel -__builtin__.loopGen = loopGen + builtins.printStack = printStack + builtins.printReverseStack = printReverseStack + builtins.printVerboseStack = printVerboseStack +builtins.DelayedCall = DelayedCall +builtins.DelayedFunctor = DelayedFunctor +builtins.FrameDelayedCall = FrameDelayedCall +builtins.SubframeCall = SubframeCall +builtins.invertDict = invertDict +builtins.invertDictLossless = invertDictLossless +builtins.getBase = getBase +builtins.getRepository = getRepository +builtins.safeRepr = safeRepr +builtins.fastRepr = fastRepr +builtins.nullGen = nullGen +builtins.flywheel = flywheel +builtins.loopGen = loopGen if __debug__: - __builtin__.StackTrace = StackTrace -__builtin__.report = report -__builtin__.pstatcollect = pstatcollect -__builtin__.MiniLog = MiniLog -__builtin__.MiniLogSentry = MiniLogSentry -__builtin__.logBlock = logBlock -__builtin__.HierarchyException = HierarchyException -__builtin__.deeptype = deeptype -__builtin__.Default = Default -__builtin__.isInteger = isInteger -__builtin__.configIsToday = configIsToday -__builtin__.typeName = typeName -__builtin__.safeTypeName = safeTypeName -__builtin__.histogramDict = histogramDict -__builtin__.unicodeUtf8 = unicodeUtf8 -__builtin__.encodedUtf8 = encodedUtf8 + builtins.StackTrace = StackTrace +builtins.report = report +builtins.pstatcollect = pstatcollect +builtins.MiniLog = MiniLog +builtins.MiniLogSentry = MiniLogSentry +builtins.logBlock = logBlock +builtins.HierarchyException = HierarchyException +builtins.deeptype = deeptype +builtins.Default = Default +builtins.configIsToday = configIsToday +builtins.typeName = typeName +builtins.safeTypeName = safeTypeName +builtins.histogramDict = histogramDict diff --git a/direct/src/showbase/RandomNumGen.py b/direct/src/showbase/RandomNumGen.py index da95bbabee..df37f1cd17 100644 --- a/direct/src/showbase/RandomNumGen.py +++ b/direct/src/showbase/RandomNumGen.py @@ -23,7 +23,7 @@ class RandomNumGen: if isinstance(seed, RandomNumGen): # seed this rng with the other rng rng = seed - seed = rng.randint(0, 1L << 16) + seed = rng.randint(0, 1 << 16) self.notify.debug("seed: " + str(seed)) seed = int(seed) @@ -70,11 +70,7 @@ class RandomNumGen: assert N >= 0 assert N <= 0x7fffffff - # the cast to 'long' prevents python from importing warnings.py, - # presumably to warn that the multiplication result is too - # large for an int and is implicitly being returned as a long. - # import of warnings.py was taking a few seconds - return int((self.__rng.getUint31() * long(N)) >> 31) + return int((self.__rng.getUint31() * N) >> 31) def choice(self, seq): """returns a random element from seq""" @@ -82,7 +78,7 @@ class RandomNumGen: def shuffle(self, x): """randomly shuffles x in-place""" - for i in xrange(len(x)-1, 0, -1): + for i in range(len(x) - 1, 0, -1): # pick an element in x[:i+1] with which to exchange x[i] j = int(self.__rand(i+1)) x[i], x[j] = x[j], x[i] @@ -134,4 +130,4 @@ class RandomNumGen: # synchronicity is critical def random(self): """returns random float in [0.0, 1.0)""" - return float(self.__rng.getUint31()) / float(1L << 31) + return float(self.__rng.getUint31()) / float(1 << 31) diff --git a/direct/src/showbase/ReferrerSearch.py b/direct/src/showbase/ReferrerSearch.py index 06272f5d05..1015c1973b 100755 --- a/direct/src/showbase/ReferrerSearch.py +++ b/direct/src/showbase/ReferrerSearch.py @@ -34,7 +34,7 @@ class ReferrerSearch(Job): self.info = safeReprNotify.getInfo() safeReprNotify.setInfo(0) - print 'RefPath(%s): Beginning ReferrerSearch for %s' %(self._id, fastRepr(self.obj)) + print('RefPath(%s): Beginning ReferrerSearch for %s' %(self._id, fastRepr(self.obj))) self.visited = set() for x in self.stepGenerator(0, [self.obj]): @@ -45,7 +45,7 @@ class ReferrerSearch(Job): pass def finished(self): - print 'RefPath(%s): Finished ReferrerSearch for %s' %(self._id, fastRepr(self.obj)) + print('RefPath(%s): Finished ReferrerSearch for %s' %(self._id, fastRepr(self.obj))) self.obj = None safeReprNotify = _getSafeReprNotify() @@ -53,7 +53,7 @@ class ReferrerSearch(Job): pass def __del__(self): - print 'ReferrerSearch garbage collected' + print('ReferrerSearch garbage collected') def truncateAtNewLine(self, s): if s.find('\n') == -1: @@ -68,13 +68,13 @@ class ReferrerSearch(Job): def myrepr(self, referrer, refersTo): pre = '' if (isinstance(referrer, dict)): - for k,v in referrer.iteritems(): + for k,v in referrer.items(): if v is refersTo: pre = self.truncateAtNewLine(fastRepr(k)) + ']-> ' break elif (isinstance(referrer, (list, tuple))): - for x in xrange(len(referrer)): - if referrer[x] is refersTo: + for x, ref in enumerate(referrer): + if ref is refersTo: pre = '%s]-> ' % (x) break @@ -114,7 +114,7 @@ class ReferrerSearch(Job): if not (ref is path or \ inspect.isframe(ref) or \ (isinstance(ref, dict) and \ - ref.keys() == locals().keys()) or \ + list(ref.keys()) == list(locals().keys())) or \ ref is self.__dict__ or \ id(ref) in self.visited) ] @@ -163,7 +163,7 @@ class ReferrerSearch(Job): # The referrer is this call frame inspect.isframe(ref) or \ # The referrer is the locals() dictionary (closure) - (isinstance(ref, dict) and ref.keys() == locals().keys()) or \ + (isinstance(ref, dict) and list(ref.keys()) == list(locals().keys())) or \ # We found the reference on self ref is self.__dict__ or \ # We've already seen this referrer @@ -192,8 +192,8 @@ class ReferrerSearch(Job): def printStats(self, path): path = list(reversed(path)) path.insert(0,0) - print 'RefPath(%s) - Stats - visited(%s) | found(%s) | depth(%s) | CurrentPath(%s)' % \ - (self._id, len(self.visited), self.found, self.depth, ''.join(self.myrepr(path[x], path[x+1]) for x in xrange(len(path)-1))) + print('RefPath(%s) - Stats - visited(%s) | found(%s) | depth(%s) | CurrentPath(%s)' % \ + (self._id, len(self.visited), self.found, self.depth, ''.join(self.myrepr(path[x], path[x+1]) for x in range(len(path) - 1)))) pass def isAtRoot(self, at, path): @@ -205,10 +205,10 @@ class ReferrerSearch(Job): sys.stdout.write("RefPath(%s): Circular: " % self._id) path = list(reversed(path)) path.insert(0,0) - for x in xrange(len(path)-1): + for x in range(len(path) - 1): sys.stdout.write(self.myrepr(path[x], path[x+1])) pass - print + print("") return True @@ -218,80 +218,80 @@ class ReferrerSearch(Job): sys.stdout.write("RefPath(%s): __builtins__-> " % self._id) path = list(reversed(path)) path.insert(0,0) - for x in xrange(len(path)-1): + for x in range(len(path) - 1): sys.stdout.write(self.myrepr(path[x], path[x+1])) pass - print + print("") return True # any module scope if inspect.ismodule(at): sys.stdout.write("RefPath(%s): Module(%s)-> " % (self._id, at.__name__)) path = list(reversed(path)) - for x in xrange(len(path)-1): + for x in range(len(path) - 1): sys.stdout.write(self.myrepr(path[x], path[x+1])) pass - print + print("") return True # any class scope if inspect.isclass(at): sys.stdout.write("RefPath(%s): Class(%s)-> " % (self._id, at.__name__)) path = list(reversed(path)) - for x in xrange(len(path)-1): + for x in range(len(path) - 1): sys.stdout.write(self.myrepr(path[x], path[x+1])) pass - print + print("") return True # simbase if at is simbase: sys.stdout.write("RefPath(%s): simbase-> " % self._id) path = list(reversed(path)) - for x in xrange(len(path)-1): + for x in range(len(path) - 1): sys.stdout.write(self.myrepr(path[x], path[x+1])) pass - print + print("") return True # simbase.air if at is simbase.air: sys.stdout.write("RefPath(%s): simbase.air-> " % self._id) path = list(reversed(path)) - for x in xrange(len(path)-1): + for x in range(len(path) - 1): sys.stdout.write(self.myrepr(path[x], path[x+1])) pass - print + print("") return True # messenger if at is messenger: sys.stdout.write("RefPath(%s): messenger-> " % self._id) path = list(reversed(path)) - for x in xrange(len(path)-1): + for x in range(len(path) - 1): sys.stdout.write(self.myrepr(path[x], path[x+1])) pass - print + print("") return True # taskMgr if at is taskMgr: sys.stdout.write("RefPath(%s): taskMgr-> " % self._id) path = list(reversed(path)) - for x in xrange(len(path)-1): + for x in range(len(path) - 1): sys.stdout.write(self.myrepr(path[x], path[x+1])) pass - print + print("") return True # world if hasattr(simbase.air, 'mainWorld') and at is simbase.air.mainWorld: sys.stdout.write("RefPath(%s): mainWorld-> " % self._id) path = list(reversed(path)) - for x in xrange(len(path)-1): + for x in range(len(path) - 1): sys.stdout.write(self.myrepr(path[x], path[x+1])) pass - print + print("") return True pass @@ -304,14 +304,14 @@ class ReferrerSearch(Job): sys.stdout.write("RefPath(%s): ManyRefs(%s)[%s]-> " % (self._id, len(referrers), fastRepr(at))) path = list(reversed(path)) path.insert(0,0) - for x in xrange(len(path)-1): + for x in range(len(path) - 1): sys.stdout.write(self.myrepr(path[x], path[x+1])) pass - print + print("") return True else: sys.stdout.write("RefPath(%s): ManyRefsAllowed(%s)[%s]-> " % (self._id, len(referrers), fastRepr(at, maxLen = 1, strFactor = 30))) - print + print("") pass pass return False diff --git a/direct/src/showbase/ShadowPlacer.py b/direct/src/showbase/ShadowPlacer.py index b05bc3e8eb..b0563d007c 100755 --- a/direct/src/showbase/ShadowPlacer.py +++ b/direct/src/showbase/ShadowPlacer.py @@ -13,7 +13,7 @@ the its parent node. from direct.controls.ControlManager import CollisionHandlerRayStart from direct.directnotify import DirectNotifyGlobal from pandac.PandaModules import * -import DirectObject +from . import DirectObject class ShadowPlacer(DirectObject.DirectObject): notify = DirectNotifyGlobal.directNotify.newCategory("ShadowPlacer") diff --git a/direct/src/showbase/ShowBase.py b/direct/src/showbase/ShowBase.py index f9f8068683..80368ab175 100644 --- a/direct/src/showbase/ShowBase.py +++ b/direct/src/showbase/ShowBase.py @@ -17,32 +17,35 @@ from panda3d.direct import storeAccessibilityShortcutKeys, allowAccessibilitySho from direct.extensions_native import NodePath_extensions # This needs to be available early for DirectGUI imports -import __builtin__ as builtins +import sys +if sys.version_info >= (3, 0): + import builtins +else: + import __builtin__ as builtins builtins.config = get_config_showbase() from direct.directnotify.DirectNotifyGlobal import directNotify, giveNotify -from MessengerGlobal import messenger -from BulletinBoardGlobal import bulletinBoard +from .MessengerGlobal import messenger +from .BulletinBoardGlobal import bulletinBoard from direct.task.TaskManagerGlobal import taskMgr -from JobManagerGlobal import jobMgr -from EventManagerGlobal import eventMgr +from .JobManagerGlobal import jobMgr +from .EventManagerGlobal import eventMgr #from PythonUtil import * from direct.interval import IntervalManager from direct.showbase.BufferViewer import BufferViewer from direct.task import Task -import sys -import Loader +from . import Loader import time import atexit import importlib from direct.showbase import ExceptionVarDump -import DirectObject -import SfxPlayer +from . import DirectObject +from . import SfxPlayer if __debug__: from direct.showbase import GarbageReport from direct.directutil import DeltaProfiler - import OnScreenDebug -import AppRunnerGlobal + from . import OnScreenDebug +from . import AppRunnerGlobal def legacyRun(): assert builtins.base.notify.warning("run() is deprecated, use base.run() instead") @@ -402,7 +405,7 @@ class ShowBase(DirectObject.DirectObject): self.accept('window-event', self.windowEvent) # Transition effects (fade, iris, etc) - import Transitions + from . import Transitions self.transitions = Transitions.Transitions(self.loader) if self.win: @@ -478,12 +481,12 @@ class ShowBase(DirectObject.DirectObject): add stuff to this. """ if self.config.GetBool('want-env-debug-info', 0): - print "\n\nEnvironment Debug Info {" - print "* model path:" - print getModelPath() + print("\n\nEnvironment Debug Info {") + print("* model path:") + print(getModelPath()) #print "* dna path:" #print getDnaPath() - print "}" + print("}") def destroy(self): """ Call this function to destroy the ShowBase and stop all diff --git a/direct/src/showbase/ShowBaseGlobal.py b/direct/src/showbase/ShowBaseGlobal.py index 451f411f15..0781b06f0e 100644 --- a/direct/src/showbase/ShowBaseGlobal.py +++ b/direct/src/showbase/ShowBaseGlobal.py @@ -2,7 +2,7 @@ __all__ = [] -from ShowBase import * +from .ShowBase import * # Create the showbase instance # This should be created by the game specific "start" file @@ -20,8 +20,12 @@ def inspect(anObject): Inspector = importlib.import_module('direct.tkpanels.Inspector') return Inspector.inspect(anObject) -import __builtin__ -__builtin__.inspect = inspect +if sys.version_info >= (3, 0): + import builtins +else: + import __builtin__ as builtins +builtins.inspect = inspect + # this also appears in AIBaseGlobal if (not __debug__) and __dev__: notify = directNotify.newCategory('ShowBaseGlobal') diff --git a/direct/src/showbase/ThreeUpShow.py b/direct/src/showbase/ThreeUpShow.py index 5d32153ede..6449033c50 100644 --- a/direct/src/showbase/ThreeUpShow.py +++ b/direct/src/showbase/ThreeUpShow.py @@ -3,7 +3,7 @@ __all__ = ['ThreeUpShow'] -import ShowBase +from . import ShowBase class ThreeUpShow(ShowBase.ShowBase): def __init__(self): diff --git a/direct/src/showbase/TkGlobal.py b/direct/src/showbase/TkGlobal.py index 1fdb89ac1a..bfdeb9b48f 100644 --- a/direct/src/showbase/TkGlobal.py +++ b/direct/src/showbase/TkGlobal.py @@ -1,8 +1,12 @@ """ This module is now vestigial. """ -from Tkinter import * import sys, Pmw +if sys.version_info >= (3, 0): + from tkinter import * +else: + from Tkinter import * + # This is required by the ihooks.py module used by Squeeze (used by # pandaSqueezer.py) so that Pmw initializes properly if '_Pmw' in sys.modules: diff --git a/direct/src/showbase/VFSImporter.py b/direct/src/showbase/VFSImporter.py index eb2b7bd7d4..807b931ab0 100644 --- a/direct/src/showbase/VFSImporter.py +++ b/direct/src/showbase/VFSImporter.py @@ -6,7 +6,6 @@ import sys import marshal import imp import types -import __builtin__ # The sharedPackages dictionary lists all of the "shared packages", # special Python packages that automatically span multiple directories @@ -305,7 +304,7 @@ class VFSLoader: if source and source[-1] != '\n': source = source + '\n' - code = __builtin__.compile(source, filename.toOsSpecific(), 'exec') + code = compile(source, filename.toOsSpecific(), 'exec') # try to cache the compiled code pycFilename = Filename(filename) @@ -449,7 +448,7 @@ class VFSSharedLoader: mod = loader.load_module(fullname, loadingShared = True) except ImportError: etype, evalue, etraceback = sys.exc_info() - print "%s on %s: %s" % (etype.__name__, fullname, evalue) + print("%s on %s: %s" % (etype.__name__, fullname, evalue)) if not message: message = '%s: %s' % (fullname, evalue) continue @@ -509,7 +508,7 @@ def reloadSharedPackage(mod): # Also force any child packages to become shared packages, if # they aren't already. - for basename, child in mod.__dict__.items(): + for basename, child in list(mod.__dict__.items()): if isinstance(child, types.ModuleType): childname = child.__name__ if childname == fullname + '.' + basename and \ diff --git a/direct/src/showbase/VerboseImport.py b/direct/src/showbase/VerboseImport.py index a8e2ef7317..56efc33b23 100644 --- a/direct/src/showbase/VerboseImport.py +++ b/direct/src/showbase/VerboseImport.py @@ -19,13 +19,13 @@ def newimport(*args, **kw): name = args[0] # Only print the name if we have not imported this before if name not in sys.modules: - print (" "*indentLevel + "import " + args[0]) + print((" "*indentLevel + "import " + args[0])) fPrint = 1 indentLevel += 1 result = oldimport(*args, **kw) indentLevel -= 1 if fPrint: - print (" "*indentLevel + "DONE: import " + args[0]) + print((" "*indentLevel + "DONE: import " + args[0])) return result # Replace the builtin import with our new import diff --git a/direct/src/showbase/pandaSqueezeTool.py b/direct/src/showbase/pandaSqueezeTool.py index fd87135930..e19d660c22 100755 --- a/direct/src/showbase/pandaSqueezeTool.py +++ b/direct/src/showbase/pandaSqueezeTool.py @@ -52,15 +52,14 @@ __all__ = ['usage', 'Squeezer', 'Loader', 'boot', 'open', 'explode', 'getloader' VERSION = "1.6/98-05-04" MAGIC = "[PANDASQUEEZE]" -import base64, imp, marshal, os, string, sys +import base64, imp, marshal, os, sys # -------------------------------------------------------------------- # usage def usage(): - print - print "SQUEEZE", VERSION, "(c) 1997-1998 by Secret Labs AB" - print """\ + print("\nSQUEEZE", VERSION, "(c) 1997-1998 by Secret Labs AB") + print("""\ Convert a Python application to a compressed module package. Usage: squeeze [-1ux] -o app [-b start] modules... [-d files...] @@ -87,7 +86,7 @@ StringIO file object). The -x option can be used with -d to create a self-extracting archive, instead of a package. When the resulting script is executed, the data files are extracted. Omit the -b option in this case. -""" +""") sys.exit(1) @@ -199,9 +198,9 @@ def boot(name, fp, size, offset = 0): loaderopen = """ def open(name): - import StringIO + from io import StringIO try: - return StringIO.StringIO(data["+"+name]) + return StringIO(data["+"+name]) except KeyError: raise IOError, (0, "no such file") """ @@ -268,12 +267,12 @@ def squeeze(app, start, filelist, outputDir): try: fp = open(bootstrap) s = fp.readline() - string.index(s, MAGIC) + s.index(MAGIC) except IOError: pass except ValueError: - print bootstrap, "was not created by squeeze. You have to manually" - print "remove the file to proceed." + print("%s was not created by squeeze. You have to manually" % (bootstrap)) + print("remove the file to proceed.") sys.exit(1) # @@ -298,7 +297,7 @@ def squeeze(app, start, filelist, outputDir): loaderlen = len(loader) magic = repr(imp.get_magic()) - version = string.split(sys.version)[0] + version = sys.version.split()[0] # # generate script and package files @@ -372,5 +371,4 @@ exec "from %(start)s import *" dummy, rawbytes = sq.getstatus() - print "squeezed", rawbytes, "to", bytes, "bytes", - print "(%d%%)" % (bytes * 100 / rawbytes) + print("squeezed %s to %s (%d%%)" % (rawbytes, bytes, bytes * 100 / rawbytes)) diff --git a/direct/src/showbase/pandaSqueezer.py b/direct/src/showbase/pandaSqueezer.py index 707bafc204..84beee7813 100644 --- a/direct/src/showbase/pandaSqueezer.py +++ b/direct/src/showbase/pandaSqueezer.py @@ -5,18 +5,18 @@ __all__ = [] import os import sys import getopt -import pandaSqueezeTool +from . import pandaSqueezeTool # Assumption: We will be squeezing the files from the current directory or the -d directory. if __name__ == "__main__": try: opts, pargs = getopt.getopt(sys.argv[1:], 'Od:') - except Exception, e: + except Exception as e: # User passed in a bad option, print the error and the help, then exit - print e - print 'Usage: pass in -O for optimized' - print ' pass in -d directory' + print(e) + print('Usage: pass in -O for optimized') + print(' pass in -d directory') sys.exit() fOptimized = 0 @@ -25,7 +25,7 @@ if __name__ == "__main__": flag, value = opt if (flag == '-O'): fOptimized = 1 - print 'Squeezing pyo files' + print('Squeezing pyo files') elif (flag == '-d'): os.chdir(value) diff --git a/direct/src/showutil/Effects.py b/direct/src/showutil/Effects.py index effaa426c6..d98223711b 100644 --- a/direct/src/showutil/Effects.py +++ b/direct/src/showutil/Effects.py @@ -105,7 +105,7 @@ def createBounce(nodeObj, numBounces, startValues, totalTime, amplitude, newVec3 = Vec3(startValues) newVec3.setCell(index, currBounceVal) - print "### newVec3 = ", newVec3 + print("### newVec3 = %s" % newVec3) # create the right type of lerp if ((bounceType == SX_BOUNCE) or (bounceType == SY_BOUNCE) or diff --git a/direct/src/showutil/FreezeTool.py b/direct/src/showutil/FreezeTool.py index ad99f8c629..89016e274d 100644 --- a/direct/src/showutil/FreezeTool.py +++ b/direct/src/showutil/FreezeTool.py @@ -7,8 +7,7 @@ import os import marshal import imp import platform -import types -from StringIO import StringIO +from io import StringIO from distutils.sysconfig import PREFIX, get_python_inc, get_python_version, get_config_var # Temporary (?) try..except to protect against unbuilt p3extend_frozen. @@ -97,7 +96,7 @@ class CompilationEnvironment: elif (Filename('/c/Program Files/Microsoft Visual Studio .NET 2003/Vc7').exists()): self.MSVC = Filename('/c/Program Files/Microsoft Visual Studio .NET 2003/Vc7').toOsSpecific() else: - print 'Could not locate Microsoft Visual C++ Compiler! Try running from the Visual Studio Command Prompt.' + print('Could not locate Microsoft Visual C++ Compiler! Try running from the Visual Studio Command Prompt.') sys.exit(1) if ('WindowsSdkDir' in os.environ): @@ -107,7 +106,7 @@ class CompilationEnvironment: elif (os.path.exists(os.path.join(self.MSVC, 'PlatformSDK'))): self.PSDK = os.path.join(self.MSVC, 'PlatformSDK') else: - print 'Could not locate the Microsoft Windows Platform SDK! Try running from the Visual Studio Command Prompt.' + print('Could not locate the Microsoft Windows Platform SDK! Try running from the Visual Studio Command Prompt.') sys.exit(1) # We need to use the correct compiler setting for debug vs. release builds. @@ -169,7 +168,7 @@ class CompilationEnvironment: 'filename' : filename, 'basename' : basename, } - print >> sys.stderr, compile + sys.stderr.write(compile + '\n') if os.system(compile) != 0: raise Exception('failed to compile %s.' % basename) @@ -184,7 +183,7 @@ class CompilationEnvironment: 'filename' : filename, 'basename' : basename, } - print >> sys.stderr, link + sys.stderr.write(link + '\n') if os.system(link) != 0: raise Exception('failed to link %s.' % basename) @@ -201,7 +200,7 @@ class CompilationEnvironment: 'filename' : filename, 'basename' : basename, } - print >> sys.stderr, compile + sys.stderr.write(compile + '\n') if os.system(compile) != 0: raise Exception('failed to compile %s.' % basename) @@ -217,7 +216,7 @@ class CompilationEnvironment: 'basename' : basename, 'dllext' : self.dllext, } - print >> sys.stderr, link + sys.stderr.write(link + '\n') if os.system(link) != 0: raise Exception('failed to link %s.' % basename) @@ -547,14 +546,15 @@ int PyInitFrozenExtensions() """ okMissing = [ + '__main__', '_dummy_threading', 'Carbon', 'Carbon.Files', 'Carbon.Folder', 'Carbon.Folders', 'HouseGlobals', 'Carbon.File', 'MacOS', '_emx_link', 'ce', 'mac', 'org.python.core', 'os.path', 'os2', 'posix', 'pwd', 'readline', 'riscos', 'riscosenviron', - 'riscospath', 'dbm', 'fcntl', 'win32api', 'usercustomize', - '_winreg', 'ctypes', 'ctypes.wintypes', 'nt','msvcrt', - 'EasyDialogs', 'SOCKS', 'ic', 'rourl2path', 'termios', + 'riscospath', 'dbm', 'fcntl', 'win32api', 'win32pipe', 'usercustomize', + '_winreg', 'winreg', 'ctypes', 'ctypes.wintypes', 'nt','msvcrt', + 'EasyDialogs', 'SOCKS', 'ic', 'rourl2path', 'termios', 'vms_lib', 'OverrideFrom23._Res', 'email', 'email.Utils', 'email.Generator', - 'email.Iterators', '_subprocess', 'gestalt', + 'email.Iterators', '_subprocess', 'gestalt', 'java.lang', 'direct.extensions_native.extensions_darwin', ] @@ -570,7 +570,7 @@ class Freezer: # The file on disk it was loaded from, if any. self.filename = filename - if isinstance(filename, types.StringTypes): + if filename is not None and not isinstance(filename, Filename): self.filename = Filename(filename) # True if the module was found via the modulefinder. @@ -681,7 +681,7 @@ class Freezer: # Actually, make sure we know how to find all of the # already-imported modules. (Some of them might do their own # special path mangling.) - for moduleName, module in sys.modules.items(): + for moduleName, module in list(sys.modules.items()): if module and hasattr(module, '__path__'): path = getattr(module, '__path__') if path: @@ -694,7 +694,7 @@ class Freezer: constructor, but it may be called at any point during processing. """ - for key, value in freezer.modules.items(): + for key, value in list(freezer.modules.items()): self.previousModules[key] = value self.modules[key] = value @@ -737,7 +737,7 @@ class Freezer: try: module = __import__(moduleName) except: - print "couldn't import %s" % (moduleName) + print("couldn't import %s" % (moduleName)) module = None if module != None: @@ -776,7 +776,7 @@ class Freezer: try: module = __import__(moduleName) except: - print "couldn't import %s" % (moduleName) + print("couldn't import %s" % (moduleName)) module = None if module != None: @@ -911,7 +911,7 @@ class Freezer: # Walk through the list in sorted order, so we reach parents # before children. - names = self.modules.items() + names = list(self.modules.items()) names.sort() excludeDict = {} @@ -936,7 +936,7 @@ class Freezer: else: includes.append(mdef) - self.mf = PandaModuleFinder(excludes = excludeDict.keys()) + self.mf = PandaModuleFinder(excludes = list(excludeDict.keys())) # Attempt to import the explicit modules into the modulefinder. @@ -952,7 +952,7 @@ class Freezer: try: self.__loadModule(mdef) except ImportError: - print "Unknown module: %s" % (mdef.moduleName) + print("Unknown module: %s" % (mdef.moduleName)) # Also attempt to import any implicit modules. If any of # these fail to import, we don't really care. @@ -967,7 +967,7 @@ class Freezer: pass # Now, any new modules we found get added to the export list. - for origName in self.mf.modules.keys(): + for origName in list(self.mf.modules.keys()): if origName not in origToNewName: self.modules[origName] = self.ModuleDef(origName, implicit = True) @@ -996,7 +996,7 @@ class Freezer: if missing: missing.sort() - print "There are some missing modules: %r" % missing + print("There are some missing modules: %r" % missing) def __sortModuleKey(self, mdef): """ A sort key function to sort a list of mdef's into order, @@ -1072,7 +1072,7 @@ class Freezer: moduleNames = [] - for newName, mdef in self.modules.items(): + for newName, mdef in list(self.modules.items()): if mdef.guess: # Not really a module. pass @@ -1092,7 +1092,7 @@ class Freezer: moduleDefs = [] - for newName, mdef in self.modules.items(): + for newName, mdef in list(self.modules.items()): prev = self.previousModules.get(newName, None) if not mdef.exclude: # Include this module (even if a previous pass @@ -1118,7 +1118,7 @@ class Freezer: # actual filename we put in there is meaningful only for stack # traces, so we'll just use the module name. replace_paths = [] - for moduleName, module in self.mf.modules.items(): + for moduleName, module in list(self.mf.modules.items()): if module.__code__: origPathname = module.__code__.co_filename replace_paths.append((origPathname, moduleName)) @@ -1126,7 +1126,7 @@ class Freezer: # Now that we have built up the replacement mapping, go back # through and actually replace the paths. - for moduleName, module in self.mf.modules.items(): + for moduleName, module in list(self.mf.modules.items()): if module.__code__: co = self.mf.replace_paths_in_code(module.__code__) module.__code__ = co; diff --git a/direct/src/showutil/Rope.py b/direct/src/showutil/Rope.py index 1e65411684..1c3af011d6 100644 --- a/direct/src/showutil/Rope.py +++ b/direct/src/showutil/Rope.py @@ -1,5 +1,5 @@ from panda3d.core import * -import types + class Rope(NodePath): """ @@ -96,7 +96,7 @@ class Rope(NodePath): for i in range(numVerts): v = self.verts[i] - if isinstance(v, types.TupleType): + if isinstance(v, tuple): nodePath, point = v color = defaultColor thickness = defaultThickness @@ -106,7 +106,7 @@ class Rope(NodePath): color = v.get('color', defaultColor) thickness = v.get('thickness', defaultThickness) - if isinstance(point, types.TupleType): + if isinstance(point, tuple): if (len(point) >= 4): self.curve.setVertex(i, VBase4(point[0], point[1], point[2], point[3])) else: diff --git a/direct/src/showutil/TexMemWatcher.py b/direct/src/showutil/TexMemWatcher.py index d4d91ae1d3..843395d58d 100644 --- a/direct/src/showutil/TexMemWatcher.py +++ b/direct/src/showutil/TexMemWatcher.py @@ -729,7 +729,7 @@ class TexMemWatcher(DirectObject): # Sort the regions from largest to smallest to maximize # packing effectiveness. - texRecords = self.texRecordsByTex.values() + texRecords = list(self.texRecordsByTex.values()) texRecords.sort(key = lambda tr: (tr.tw, tr.th), reverse = True) for tr in texRecords: diff --git a/direct/src/showutil/pfreeze.py b/direct/src/showutil/pfreeze.py index 5bcc3c41ee..8676251026 100755 --- a/direct/src/showutil/pfreeze.py +++ b/direct/src/showutil/pfreeze.py @@ -53,8 +53,9 @@ import os from direct.showutil import FreezeTool def usage(code, msg = ''): - print >> sys.stderr, __doc__ - print >> sys.stderr, msg + if __doc__: + sys.stderr.write(__doc__ + '\n') + sys.stderr.write(msg + '\n') sys.exit(code) # We're not protecting the next part under a __name__ == __main__ @@ -67,7 +68,7 @@ addStartupModules = False try: opts, args = getopt.getopt(sys.argv[1:], 'o:i:x:p:sh') -except getopt.error, msg: +except getopt.error as msg: usage(1, msg) for opt, arg in opts: @@ -87,7 +88,7 @@ for opt, arg in opts: elif opt == '-h': usage(0) else: - print 'illegal option: ' + flag + print('illegal option: ' + flag) sys.exit(1) if not basename: diff --git a/direct/src/stdpy/file.py b/direct/src/stdpy/file.py index d6ef48cd9e..222739612a 100644 --- a/direct/src/stdpy/file.py +++ b/direct/src/stdpy/file.py @@ -26,6 +26,12 @@ if sys.version_info < (3, 0): FileExistsError = IOError PermissionError = IOError + unicodeType = unicode + strType = str +else: + unicodeType = str + strType = () + def open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True): if sys.version_info >= (3, 0): @@ -70,11 +76,11 @@ def open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, # We can also "open" a VirtualFile object for reading. vfile = file filename = vfile.getFilename() - elif isinstance(file, unicode): + elif isinstance(file, unicodeType): # If a raw string is given, assume it's an os-specific # filename. filename = core.Filename.fromOsSpecificW(file) - elif isinstance(file, str): + elif isinstance(file, strType): filename = core.Filename.fromOsSpecific(file) else: # If a Filename is given, make a writable copy anyway. diff --git a/direct/src/stdpy/glob.py b/direct/src/stdpy/glob.py index 6f825a4561..28eee2cb6e 100755 --- a/direct/src/stdpy/glob.py +++ b/direct/src/stdpy/glob.py @@ -53,7 +53,7 @@ def iglob(pathname): def glob1(dirname, pattern): if not dirname: dirname = os.curdir - if isinstance(pattern, unicode) and not isinstance(dirname, unicode): + if sys.version_info < (3, 0) and isinstance(pattern, unicode) and not isinstance(dirname, unicode): dirname = unicode(dirname, sys.getfilesystemencoding() or sys.getdefaultencoding()) try: diff --git a/direct/src/stdpy/pickle.py b/direct/src/stdpy/pickle.py index ae46f3967b..57e7c2521c 100644 --- a/direct/src/stdpy/pickle.py +++ b/direct/src/stdpy/pickle.py @@ -139,7 +139,7 @@ class Unpickler(pickle.Unpickler): try: from cStringIO import StringIO except ImportError: - from StringIO import StringIO + from io import StringIO def dump(obj, file, protocol=None): Pickler(file, protocol).dump(obj) diff --git a/direct/src/stdpy/thread.py b/direct/src/stdpy/thread.py index ccbc141b5b..d10a47fb54 100644 --- a/direct/src/stdpy/thread.py +++ b/direct/src/stdpy/thread.py @@ -240,7 +240,7 @@ class _local(object): # Delete this key from all threads. _threadsLock.acquire() try: - for thread, locals, wrapper in _threads.values(): + for thread, locals, wrapper in list(_threads.values()): try: del locals[i] except KeyError: diff --git a/direct/src/stdpy/threading.py b/direct/src/stdpy/threading.py index 3fa576e712..4c0ce1e8fb 100644 --- a/direct/src/stdpy/threading.py +++ b/direct/src/stdpy/threading.py @@ -21,7 +21,6 @@ easier to use and understand. It is permissible to mix-and-match both threading and threading2 within the same application. """ -import direct from panda3d import core from direct.stdpy import thread as _thread import sys as _sys @@ -380,7 +379,7 @@ def enumerate(): tlist = [] _thread._threadsLock.acquire() try: - for thread, locals, wrapper in _thread._threads.values(): + for thread, locals, wrapper in list(_thread._threads.values()): if wrapper and thread.isStarted(): tlist.append(wrapper) return tlist @@ -484,7 +483,7 @@ if __debug__: def run(self): while self.count > 0: item = self.queue.get() - print item + print(item) self.count = self.count - 1 NP = 3 diff --git a/direct/src/stdpy/threading2.py b/direct/src/stdpy/threading2.py index b9df97ca97..9beee770c0 100644 --- a/direct/src/stdpy/threading2.py +++ b/direct/src/stdpy/threading2.py @@ -480,19 +480,16 @@ class Thread(_Verbose): # Lib/traceback.py) exc_type, exc_value, exc_tb = self.__exc_info() try: - print>>self.__stderr, ( - "Exception in thread " + self.getName() + - " (most likely raised during interpreter shutdown):") - print>>self.__stderr, ( - "Traceback (most recent call last):") + self.__stderr.write("Exception in thread " + self.getName() + + " (most likely raised during interpreter shutdown):\n") + self.__stderr.write("Traceback (most recent call last):\n") while exc_tb: - print>>self.__stderr, ( - ' File "%s", line %s, in %s' % + self.__stderr.write(' File "%s", line %s, in %s\n' % (exc_tb.tb_frame.f_code.co_filename, exc_tb.tb_lineno, exc_tb.tb_frame.f_code.co_name)) exc_tb = exc_tb.tb_next - print>>self.__stderr, ("%s: %s" % (exc_type, exc_value)) + self.__stderr.write("%s: %s\n" % (exc_type, exc_value)) # Make sure that exc_tb gets deleted since it is a memory # hog; deleting everything else is just for thoroughness finally: @@ -710,7 +707,7 @@ def activeCount(): def enumerate(): _active_limbo_lock.acquire() - active = _active.values() + _limbo.values() + active = list(_active.values()) + list(_limbo.values()) _active_limbo_lock.release() return active @@ -794,7 +791,7 @@ if __debug__: def run(self): while self.count > 0: item = self.queue.get() - print item + print(item) self.count = self.count - 1 NP = 3 diff --git a/direct/src/task/FrameProfiler.py b/direct/src/task/FrameProfiler.py index b524dbf1c1..4207937d1c 100755 --- a/direct/src/task/FrameProfiler.py +++ b/direct/src/task/FrameProfiler.py @@ -35,15 +35,15 @@ class FrameProfiler: 24 * FrameProfiler.Minute, ] for t in self._logSchedule: - assert isInteger(t) + #assert isInteger(t) # make sure the period is evenly divisible into each element of the log schedule assert (t % self._period) == 0 # make sure each element of the schedule is evenly divisible into each subsequent element - for i in xrange(len(self._logSchedule)): + for i in range(len(self._logSchedule)): e = self._logSchedule[i] - for j in xrange(i, len(self._logSchedule)): + for j in range(i, len(self._logSchedule)): assert (self._logSchedule[j] % e) == 0 - assert isInteger(self._period) + #assert isInteger(self._period) self._enableFC = FunctionCall(self._setEnabled, taskMgr.getProfileFramesSV()) self._enableFC.pushCurrentState() @@ -66,13 +66,13 @@ class FrameProfiler: else: self._task.remove() del self._task - for session in self._period2aggregateProfile.itervalues: + for session in self._period2aggregateProfile.values(): session.release() del self._period2aggregateProfile - for task in self._id2task.itervalues(): + for task in self._id2task.values(): task.remove() del self._id2task - for session in self._id2session.itervalues(): + for session in self._id2session.values(): session.release() del self._id2session self.notify.info('frame profiler stopped') @@ -84,7 +84,7 @@ class FrameProfiler: def _scheduleNextProfile(self): self._profileCounter += 1 self._timeElapsed = self._profileCounter * self._period - assert isInteger(self._timeElapsed) + #assert isInteger(self._timeElapsed) time = self._startTime + self._timeElapsed # vary the actual delay between profiles by a random amount to prevent interaction @@ -121,7 +121,7 @@ class FrameProfiler: else: gen = self._doAnalysisGen(sessionId) task._generator = gen - result = gen.next() + result = next(gen) if result == Task.done: del task._generator return result @@ -150,7 +150,7 @@ class FrameProfiler: # log profiles when it's time, and aggregate them upwards into the # next-longer profile - for pi in xrange(len(self._logSchedule)): + for pi in range(len(self._logSchedule)): period = self._logSchedule[pi] if (self._timeElapsed % period) == 0: if period in p2ap: diff --git a/direct/src/task/Task.py b/direct/src/task/Task.py index bce3b127e1..e12b64078d 100644 --- a/direct/src/task/Task.py +++ b/direct/src/task/Task.py @@ -42,21 +42,21 @@ def print_exc_plus(): f = f.f_back stack.reverse() traceback.print_exc() - print "Locals by frame, innermost last" + print("Locals by frame, innermost last") for frame in stack: - print - print "Frame %s in %s at line %s" % (frame.f_code.co_name, + print("") + print("Frame %s in %s at line %s" % (frame.f_code.co_name, frame.f_code.co_filename, - frame.f_lineno) - for key, value in frame.f_locals.items(): - print "\t%20s = " % key, + frame.f_lineno)) + for key, value in list(frame.f_locals.items()): #We have to be careful not to cause a new error in our error #printer! Calling str() on an unknown object could cause an #error we don't want. try: - print value + valueStr = str(value) except: - print "" + valueStr = "" + print("\t%20s = %s" % (key, valueStr)) # For historical purposes, we remap the C++-defined enumeration to # these Python names, and define them both at the module level, here, @@ -153,7 +153,7 @@ class TaskManager: clock = property(lambda self: self.mgr.getClock(), setClock) def invokeDefaultHandler(self, signalNumber, stackFrame): - print '*** allowing mid-frame keyboard interrupt.' + print('*** allowing mid-frame keyboard interrupt.') # Restore default interrupt handler if signal: signal.signal(signal.SIGINT, signal.default_int_handler) @@ -164,9 +164,9 @@ class TaskManager: self.fKeyboardInterrupt = 1 self.interruptCount += 1 if self.interruptCount == 1: - print '* interrupt by keyboard' + print('* interrupt by keyboard') elif self.interruptCount == 2: - print '** waiting for end of frame before interrupting...' + print('** waiting for end of frame before interrupting...') # The user must really want to interrupt this process # Next time around invoke the default handler signal.signal(signal.SIGINT, self.invokeDefaultHandler) @@ -397,7 +397,7 @@ class TaskManager: 'Task %s does not accept arguments.' % (repr(task))) if name is not None: - assert isinstance(name, types.StringTypes), 'Name must be a string type' + assert isinstance(name, str), 'Name must be a string type' task.setName(name) assert task.hasName() @@ -431,12 +431,12 @@ class TaskManager: all tasks with the indicated name are removed. Returns the number of tasks removed. """ - if isinstance(taskOrName, types.StringTypes): + if isinstance(taskOrName, str): tasks = self.mgr.findTasks(taskOrName) return self.mgr.remove(tasks) elif isinstance(taskOrName, AsyncTask): return self.mgr.remove(taskOrName) - elif isinstance(taskOrName, types.ListType): + elif isinstance(taskOrName, list): for task in taskOrName: self.remove(task) else: @@ -520,7 +520,7 @@ class TaskManager: except SystemExit: self.stop() raise - except IOError, ioError: + except IOError as ioError: code, message = self._unpackIOError(ioError) # Since upgrading to Python 2.4.1, pausing the execution # often gives this IOError during the sleep function: @@ -532,7 +532,7 @@ class TaskManager: self.stop() else: raise - except Exception, e: + except Exception as e: if self.extendedExceptions: self.stop() print_exc_plus() @@ -615,7 +615,7 @@ class TaskManager: self._frameProfileQueue.push((num, session, callback)) def _doProfiledFrames(self, numFrames): - for i in xrange(numFrames): + for i in range(numFrames): result = self.step() return result @@ -1261,22 +1261,22 @@ if __debug__: return task.done obj = TestClass() startRefCount = sys.getrefcount(obj) - print 'sys.getrefcount(obj): %s' % sys.getrefcount(obj) - print '** addTask' + print('sys.getrefcount(obj): %s' % sys.getrefcount(obj)) + print('** addTask') t = obj.addTask(obj.doTask, 'test') - print 'sys.getrefcount(obj): %s' % sys.getrefcount(obj) - print 'task.getRefCount(): %s' % t.getRefCount() - print '** removeTask' + print('sys.getrefcount(obj): %s' % sys.getrefcount(obj)) + print('task.getRefCount(): %s' % t.getRefCount()) + print('** removeTask') obj.removeTask('test') - print 'sys.getrefcount(obj): %s' % sys.getrefcount(obj) - print 'task.getRefCount(): %s' % t.getRefCount() - print '** step' + print('sys.getrefcount(obj): %s' % sys.getrefcount(obj)) + print('task.getRefCount(): %s' % t.getRefCount()) + print('** step') taskMgr.step() taskMgr.step() taskMgr.step() - print 'sys.getrefcount(obj): %s' % sys.getrefcount(obj) - print 'task.getRefCount(): %s' % t.getRefCount() - print '** task release' + print('sys.getrefcount(obj): %s' % sys.getrefcount(obj)) + print('task.getRefCount(): %s' % t.getRefCount()) + print('** task release') t = None - print 'sys.getrefcount(obj): %s' % sys.getrefcount(obj) + print('sys.getrefcount(obj): %s' % sys.getrefcount(obj)) assert sys.getrefcount(obj) == startRefCount diff --git a/direct/src/task/TaskManagerGlobal.py b/direct/src/task/TaskManagerGlobal.py index 4c95232c4d..60587d7a4f 100644 --- a/direct/src/task/TaskManagerGlobal.py +++ b/direct/src/task/TaskManagerGlobal.py @@ -2,6 +2,6 @@ __all__ = ['taskMgr'] -import Task +from . import Task taskMgr = Task.TaskManager() diff --git a/direct/src/task/TaskProfiler.py b/direct/src/task/TaskProfiler.py index ceb83b2e15..e099f82905 100755 --- a/direct/src/task/TaskProfiler.py +++ b/direct/src/task/TaskProfiler.py @@ -100,7 +100,7 @@ class TaskProfiler: if taskMgr.getProfileTasks(): self._setEnabled(False) self._enableFC.destroy() - for tracker in self._namePrefix2tracker.itervalues(): + for tracker in self._namePrefix2tracker.values(): tracker.destroy() del self._namePrefix2tracker del self._task @@ -119,7 +119,7 @@ class TaskProfiler: def logProfiles(self, name=None): if name: name = name.lower() - for namePrefix, tracker in self._namePrefix2tracker.iteritems(): + for namePrefix, tracker in self._namePrefix2tracker.items(): if (name and (name not in namePrefix.lower())): continue tracker.log() @@ -128,7 +128,7 @@ class TaskProfiler: if name: name = name.lower() # flush stored task profiles - for namePrefix, tracker in self._namePrefix2tracker.iteritems(): + for namePrefix, tracker in self._namePrefix2tracker.items(): if (name and (name not in namePrefix.lower())): continue tracker.flush() diff --git a/direct/src/task/Timer.py b/direct/src/task/Timer.py index fb773a7c42..be7957183c 100644 --- a/direct/src/task/Timer.py +++ b/direct/src/task/Timer.py @@ -2,7 +2,7 @@ __all__ = ['Timer'] -import Task +from . import Task class Timer: id = 0 diff --git a/direct/src/tkpanels/AnimPanel.py b/direct/src/tkpanels/AnimPanel.py index c48320efab..8cee51e1a6 100644 --- a/direct/src/tkpanels/AnimPanel.py +++ b/direct/src/tkpanels/AnimPanel.py @@ -9,11 +9,15 @@ __all__ = ['AnimPanel', 'ActorControl'] # Import Tkinter, Pmw, and the floater code from this directory tree. from direct.tkwidgets.AppShell import * from direct.showbase.TkGlobal import * -from tkSimpleDialog import askfloat -from Tkinter import * -import Pmw, string, types +import Pmw, sys from direct.task import Task +if sys.version_info >= (3, 0): + from tkinter.simpledialog import askfloat +else: + from tkSimpleDialog import askfloat + + FRAMES = 0 SECONDS = 1 @@ -28,8 +32,7 @@ class AnimPanel(AppShell): def __init__(self, aList = [], parent = None, session = None, **kw): INITOPT = Pmw.INITOPT - if ((type(aList) == types.ListType) or - (type(aList) == types.TupleType)): + if isinstance(aList, (list, tuple)): kw['actorList'] = aList else: kw['actorList'] = [aList] @@ -201,7 +204,7 @@ class AnimPanel(AppShell): self.actorControlList = [] for actor in self['actorList']: anims = actor.getAnimNames() - print "actor animnames: %s"%anims + print("actor animnames: %s"%anims) topAnims = [] if 'neutral' in anims: i = anims.index('neutral') @@ -518,7 +521,7 @@ class ActorControl(Pmw.MegaWidget): if (self.fps == None): # there was probably a problem loading the # active animation, set default anim properties - print "unable to get animation fps, zeroing out animation info" + print("unable to get animation fps, zeroing out animation info") self.fps = 24 self.duration = 0 self.maxFrame = 0 @@ -624,7 +627,7 @@ class ActorControl(Pmw.MegaWidget): def goTo(self, t): # Convert scale value to float - t = string.atof(t) + t = float(t) # Now convert t to seconds for offset calculations if self.unitsVar.get() == FRAMES: t = t / self.fps diff --git a/direct/src/tkpanels/DirectSessionPanel.py b/direct/src/tkpanels/DirectSessionPanel.py index 54a515895d..65a262eda3 100644 --- a/direct/src/tkpanels/DirectSessionPanel.py +++ b/direct/src/tkpanels/DirectSessionPanel.py @@ -5,15 +5,14 @@ __all__ = ['DirectSessionPanel'] # Import Tkinter, Pmw, and the dial code from direct.showbase.TkGlobal import * from direct.tkwidgets.AppShell import * -from Tkinter import * from panda3d.core import * -import Pmw, string +import Pmw from direct.tkwidgets import Dial from direct.tkwidgets import Floater from direct.tkwidgets import Slider from direct.tkwidgets import VectorWidgets from direct.tkwidgets import SceneGraphExplorer -from TaskManagerPanel import TaskManagerWidget +from .TaskManagerPanel import TaskManagerWidget from direct.tkwidgets import MemoryExplorer """ @@ -744,8 +743,8 @@ class DirectSessionPanel(AppShell): color[2]/255.0) def selectDisplayRegionNamed(self, name): - if (string.find(name, 'Display Region ') >= 0): - drIndex = string.atoi(name[-1:]) + if name.find('Display Region ') >= 0: + drIndex = int(name[-1:]) self.activeDisplayRegion = base.direct.drList[drIndex] else: self.activeDisplayRegion = None diff --git a/direct/src/tkpanels/FSMInspector.py b/direct/src/tkpanels/FSMInspector.py index f6c5cc258e..14b307b300 100644 --- a/direct/src/tkpanels/FSMInspector.py +++ b/direct/src/tkpanels/FSMInspector.py @@ -4,9 +4,13 @@ __all__ = ['FSMInspector', 'StateInspector'] from direct.tkwidgets.AppShell import * from direct.showbase.TkGlobal import * -from tkSimpleDialog import askstring -from Tkinter import * -import Pmw, math, operator +import Pmw, math, operator, sys + +if sys.version_info >= (3, 0): + from tkinter.simpledialog import askstring +else: + from tkSimpleDialog import askstring + DELTA = (5.0 / 360.) * 2.0 * math.pi @@ -115,14 +119,14 @@ class FSMInspector(AppShell): self._canvas.itemconfigure('labels', font = ('MS Sans Serif', size)) def setMarkerSize(self, size): - for key in self.stateInspectorDict.keys(): + for key in self.stateInspectorDict: self.stateInspectorDict[key].setRadius(size) self.drawConnections() def drawConnections(self, event = None): # Get rid of existing arrows self._canvas.delete('arrow') - for key in self.stateInspectorDict.keys(): + for key in self.stateInspectorDict: si = self.stateInspectorDict[key] state = si.state if state.getTransitions(): @@ -236,7 +240,7 @@ class FSMInspector(AppShell): self.setGridSize(self._gridSize) def setGridSize(self, size): - for key in self.stateInspectorDict.keys(): + for key in self.stateInspectorDict: self.stateInspectorDict[key].setGridSize(size) def popupGridDialog(self): @@ -253,29 +257,27 @@ class FSMInspector(AppShell): def printLayout(self): dict = self.stateInspectorDict - keys = dict.keys() - keys.sort - print "ClassicFSM.ClassicFSM('%s', [" % self.name + keys = list(dict.keys()) + keys.sort() + print("ClassicFSM.ClassicFSM('%s', [" % self.name) for key in keys[:-1]: si = dict[key] center = si.center() - print " State.State('%s'," % si.state.getName() - print " %s," % si.state.getEnterFunc().__name__ - print " %s," % si.state.getExitFunc().__name__ - print " %s," % si.state.getTransitions() - print " inspectorPos = ", - print "[%.1f, %.1f])," % (center[0], center[1]) + print(" State.State('%s'," % si.state.getName()) + print(" %s," % si.state.getEnterFunc().__name__) + print(" %s," % si.state.getExitFunc().__name__) + print(" %s," % si.state.getTransitions()) + print(" inspectorPos = [%.1f, %.1f])," % (center[0], center[1])) for key in keys[-1:]: si = dict[key] center = si.center() - print " State.State('%s'," % si.state.getName() - print " %s," % si.state.getEnterFunc().__name__ - print " %s," % si.state.getExitFunc().__name__ - print " %s," % si.state.getTransitions() - print " inspectorPos = ", - print "[%.1f, %.1f])]," % (center[0], center[1]) - print " '%s'," % self.fsm.getInitialState().getName() - print " '%s')" % self.fsm.getFinalState().getName() + print(" State.State('%s'," % si.state.getName()) + print(" %s," % si.state.getEnterFunc().__name__) + print(" %s," % si.state.getExitFunc().__name__) + print(" %s," % si.state.getTransitions()) + print(" inspectorPos = [%.1f, %.1f])]," % (center[0], center[1])) + print(" '%s'," % self.fsm.getInitialState().getName()) + print(" '%s')" % self.fsm.getFinalState().getName()) def toggleBalloon(self): if self.toggleBalloonVar.get(): @@ -434,7 +436,7 @@ class StateInspector(Pmw.MegaArchetype): self.fsm.request(self.getName()) def inspectSubMachine(self): - print 'inspect ' + self.tag + ' subMachine' + print('inspect ' + self.tag + ' subMachine') for childFSM in self.state.getChildren(): FSMInspector(childFSM) diff --git a/direct/src/tkpanels/Inspector.py b/direct/src/tkpanels/Inspector.py index 98e4378e30..4480332699 100644 --- a/direct/src/tkpanels/Inspector.py +++ b/direct/src/tkpanels/Inspector.py @@ -8,7 +8,6 @@ so that I can just type: inspect(anObject) any time.""" __all__ = ['inspect', 'inspectorFor', 'Inspector', 'ModuleInspector', 'ClassInspector', 'InstanceInspector', 'FunctionInspector', 'InstanceMethodInspector', 'CodeInspector', 'ComplexInspector', 'DictionaryInspector', 'SequenceInspector', 'SliceInspector', 'InspectorWindow'] from direct.showbase.TkGlobal import * -from Tkinter import * import Pmw ### public API @@ -26,7 +25,7 @@ def inspectorFor(anObject): if typeName in _InspectorMap: inspectorName = _InspectorMap[typeName] else: - print("Can't find an inspector for " + typeName) + print(("Can't find an inspector for " + typeName)) inspectorName = 'Inspector' inspector = globals()[inspectorName](anObject) return inspector @@ -147,7 +146,7 @@ class ModuleInspector(Inspector): class ClassInspector(Inspector): def namedParts(self): - return ['__bases__'] + self.object.__dict__.keys() + return ['__bases__'] + list(self.object.__dict__.keys()) def title(self): return self.object.__name__ + ' Class' @@ -184,7 +183,7 @@ class DictionaryInspector(Inspector): def initializePartsList(self): Inspector.initializePartsList(self) - keys = self.object.keys() + keys = list(self.object.keys()) keys.sort() for each in keys: self._partsList.append(each) @@ -422,7 +421,7 @@ class InspectorWindow: ('Place', NodePath.place), ('Set Color', NodePath.rgbPanel)]) elif isinstance(part, ClassicFSM.ClassicFSM): - import FSMInspector + from . import FSMInspector popupMenu = self.createPopupMenu( part, [('Inspect ClassicFSM', FSMInspector.FSMInspector)]) diff --git a/direct/src/tkpanels/MopathRecorder.py b/direct/src/tkpanels/MopathRecorder.py index 3e7bc3e0c5..e829ce233f 100644 --- a/direct/src/tkpanels/MopathRecorder.py +++ b/direct/src/tkpanels/MopathRecorder.py @@ -11,15 +11,18 @@ from direct.directtools.DirectGlobals import * from direct.directtools.DirectUtil import * from direct.directtools.DirectGeometry import * from direct.directtools.DirectSelection import * -from tkFileDialog import * -from Tkinter import * -import Pmw, os, string +import Pmw, os, sys from direct.tkwidgets import Dial from direct.tkwidgets import Floater from direct.tkwidgets import Slider from direct.tkwidgets import EntryScale from direct.tkwidgets import VectorWidgets -import __builtin__ + +if sys.version_info >= (3, 0): + from tkinter.filedialog import * +else: + from tkFileDialog import * + PRF_UTILITIES = [ 'lambda: base.direct.camera.lookAt(render)', @@ -347,7 +350,7 @@ class MopathRecorder(AppShell, DirectObject): self.speedEntry.bind( '', lambda e = None, s = self: s.setSpeedScale( - string.atof(s.speedVar.get()))) + float(s.speedVar.get()))) self.speedEntry.pack(side = LEFT, expand = 0) frame.pack(fill = X, expand = 1) @@ -662,7 +665,7 @@ class MopathRecorder(AppShell, DirectObject): marker if subnode selected """ taskMgr.remove(self.name + '-curveEditTask') - print nodePath.id() + print(nodePath.getKey()) if nodePath.id() in self.playbackMarkerIds: base.direct.select(self.playbackMarker) elif nodePath.id() in self.tangentMarkerIds: @@ -1105,7 +1108,7 @@ class MopathRecorder(AppShell, DirectObject): def computeCurves(self): # Check to make sure curve fitters have points if (self.curveFitter.getNumSamples() == 0): - print 'MopathRecorder.computeCurves: Must define curve first' + print('MopathRecorder.computeCurves: Must define curve first') return # Create curves # XYZ @@ -1351,7 +1354,7 @@ class MopathRecorder(AppShell, DirectObject): def desampleCurve(self): if (self.curveFitter.getNumSamples() == 0): - print 'MopathRecorder.desampleCurve: Must define curve first' + print('MopathRecorder.desampleCurve: Must define curve first') return # NOTE: This is destructive, points will be deleted from curve fitter self.curveFitter.desample(self.desampleFrequency) @@ -1365,7 +1368,7 @@ class MopathRecorder(AppShell, DirectObject): def sampleCurve(self, fCompute = 1): if self.curveCollection == None: - print 'MopathRecorder.sampleCurve: Must define curve first' + print('MopathRecorder.sampleCurve: Must define curve first') return # Reset curve fitters self.curveFitter.reset() @@ -1580,7 +1583,7 @@ class MopathRecorder(AppShell, DirectObject): def cropCurve(self): if self.pointSet == None: - print 'Empty Point Set' + print('Empty Point Set') return # Keep handle on old points oldPoints = self.pointSet @@ -1623,8 +1626,8 @@ class MopathRecorder(AppShell, DirectObject): else: path = '.' if not os.path.isdir(path): - print 'MopathRecorder Info: Empty Model Path!' - print 'Using current directory' + print('MopathRecorder Info: Empty Model Path!') + print('Using current directory') path = '.' mopathFilename = askopenfilename( defaultextension = '.egg', @@ -1662,8 +1665,8 @@ class MopathRecorder(AppShell, DirectObject): else: path = '.' if not os.path.isdir(path): - print 'MopathRecorder Info: Empty Model Path!' - print 'Using current directory' + print('MopathRecorder Info: Empty Model Path!') + print('Using current directory') path = '.' mopathFilename = asksaveasfilename( defaultextension = '.egg', @@ -1760,7 +1763,7 @@ class MopathRecorder(AppShell, DirectObject): kw['min'] = min kw['maxVelocity'] = maxVelocity kw['resolution'] = resolution - widget = apply(Floater.Floater, (parent,), kw) + widget = Floater.Floater(parent, **kw) # Do this after the widget so command isn't called on creation widget['command'] = command widget.pack(fill = X) @@ -1771,7 +1774,7 @@ class MopathRecorder(AppShell, DirectObject): def createAngleDial(self, parent, category, text, balloonHelp, command = None, **kw): kw['text'] = text - widget = apply(Dial.AngleDial, (parent,), kw) + widget = Dial.AngleDial(parent, **kw) # Do this after the widget so command isn't called on creation widget['command'] = command widget.pack(fill = X) @@ -1789,7 +1792,7 @@ class MopathRecorder(AppShell, DirectObject): kw['resolution'] = resolution #widget = apply(EntryScale.EntryScale, (parent,), kw) from direct.tkwidgets import Slider - widget = apply(Slider.Slider, (parent,), kw) + widget = Slider.Slider(parent, **kw) # Do this after the widget so command isn't called on creation widget['command'] = command widget.pack(side = side, fill = fill, expand = expand) @@ -1805,7 +1808,7 @@ class MopathRecorder(AppShell, DirectObject): kw['min'] = min kw['max'] = max kw['resolution'] = resolution - widget = apply(EntryScale.EntryScale, (parent,), kw) + widget = EntryScale.EntryScale(parent, **kw) # Do this after the widget so command isn't called on creation widget['command'] = command widget.pack(side = side, fill = fill, expand = expand) @@ -1817,7 +1820,7 @@ class MopathRecorder(AppShell, DirectObject): command = None, **kw): # Set label's text kw['text'] = text - widget = apply(VectorWidgets.Vector2Entry, (parent,), kw) + widget = VectorWidgets.Vector2Entry(parent, **kw) # Do this after the widget so command isn't called on creation widget['command'] = command widget.pack(fill = X) @@ -1829,7 +1832,7 @@ class MopathRecorder(AppShell, DirectObject): command = None, **kw): # Set label's text kw['text'] = text - widget = apply(VectorWidgets.Vector3Entry, (parent,), kw) + widget = VectorWidgets.Vector3Entry(parent, **kw) # Do this after the widget so command isn't called on creation widget['command'] = command widget.pack(fill = X) @@ -1841,7 +1844,7 @@ class MopathRecorder(AppShell, DirectObject): command = None, **kw): # Set label's text kw['text'] = text - widget = apply(VectorWidgets.ColorEntry, (parent,), kw) + widget = VectorWidgets.ColorEntry(parent, **kw) # Do this after the widget so command isn't called on creation widget['command'] = command widget.pack(fill = X) @@ -1913,4 +1916,3 @@ class MopathRecorder(AppShell, DirectObject): self.cCam = self.cCamera.attachNewNode(self.cCamNode) self.cDr.setCamera(self.cCam) - diff --git a/direct/src/tkpanels/NotifyPanel.py b/direct/src/tkpanels/NotifyPanel.py index f1b8a0720b..9712903f7a 100644 --- a/direct/src/tkpanels/NotifyPanel.py +++ b/direct/src/tkpanels/NotifyPanel.py @@ -131,7 +131,7 @@ class NotifyPanel: def _getPandaCategoriesAsList(self, pc, list): import types for item in pc: - if type(item) == types.ListType: + if type(item) == list: self._getPandaCategoriesAsList(item, list) else: list.append(item) diff --git a/direct/src/tkpanels/ParticlePanel.py b/direct/src/tkpanels/ParticlePanel.py index f07e9c4102..b712d7c7fb 100644 --- a/direct/src/tkpanels/ParticlePanel.py +++ b/direct/src/tkpanels/ParticlePanel.py @@ -5,8 +5,6 @@ __all__ = ['ParticlePanel'] # Import Tkinter, Pmw, and the floater code from this directory tree. from direct.tkwidgets.AppShell import * from direct.showbase.TkGlobal import * -from tkFileDialog import * -from tkSimpleDialog import askstring from direct.tkwidgets import Dial from direct.tkwidgets import Floater from direct.tkwidgets import Slider @@ -15,8 +13,14 @@ from direct.tkpanels import Placer from direct.particles import ForceGroup from direct.particles import Particles from direct.particles import ParticleEffect -from Tkinter import * -import Pmw, os +import Pmw, os, sys + +if sys.version_info >= (3, 0): + from tkinter.filedialog import * + from tkinter.simpledialog import askstring +else: + from tkFileDialog import * + from tkSimpleDialog import askstring from panda3d.core import * from panda3d.physics import * @@ -67,7 +71,7 @@ class ParticlePanel(AppShell): self.initialiseoptions(ParticlePanel) # Update panel values to reflect particle effect's state - self.selectEffectNamed(self.effectsDict.keys()[0]) + self.selectEffectNamed(next(iter(self.effectsDict))) # Make sure labels/menus reflect current state self.updateMenusAndLabels() # Make sure there is a page for each forceGroup objects @@ -976,7 +980,7 @@ class ParticlePanel(AppShell): kw['min'] = min kw['resolution'] = resolution kw['numDigits'] = numDigits - widget = apply(Floater.Floater, (parent,), kw) + widget = Floater.Floater(parent, **kw) # Do this after the widget so command isn't called on creation widget['command'] = command widget.pack(fill = X) @@ -988,7 +992,7 @@ class ParticlePanel(AppShell): command = None, **kw): kw['text'] = text kw['style'] = 'mini' - widget = apply(Dial.AngleDial, (parent,), kw) + widget = Dial.AngleDial(parent, **kw) # Do this after the widget so command isn't called on creation widget['command'] = command widget.pack(fill = X) @@ -1003,7 +1007,7 @@ class ParticlePanel(AppShell): kw['min'] = min kw['max'] = max kw['resolution'] = resolution - widget = apply(Slider.Slider, (parent,), kw) + widget = Slider.Slider(parent, **kw) # Do this after the widget so command isn't called on creation widget['command'] = command widget.pack(fill = X) @@ -1015,7 +1019,7 @@ class ParticlePanel(AppShell): command = None, **kw): # Set label's text kw['text'] = text - widget = apply(VectorWidgets.Vector2Entry, (parent,), kw) + widget = VectorWidgets.Vector2Entry(parent, **kw) # Do this after the widget so command isn't called on creation widget['command'] = command widget.pack(fill = X) @@ -1027,7 +1031,7 @@ class ParticlePanel(AppShell): command = None, **kw): # Set label's text kw['text'] = text - widget = apply(VectorWidgets.Vector3Entry, (parent,), kw) + widget = VectorWidgets.Vector3Entry(parent, **kw) # Do this after the widget so command isn't called on creation widget['command'] = command widget.pack(fill = X) @@ -1039,7 +1043,7 @@ class ParticlePanel(AppShell): command = None, **kw): # Set label's text kw['text'] = text - widget = apply(VectorWidgets.ColorEntry, (parent,), kw) + widget = VectorWidgets.ColorEntry(parent, **kw) # Do this after the widget so command isn't called on creation widget['command'] = command widget.pack(fill = X) @@ -1111,8 +1115,7 @@ class ParticlePanel(AppShell): self.effectsLabelMenu.delete(5, 'end') self.effectsLabelMenu.add_separator() # Add in a checkbutton for each effect (to toggle on/off) - keys = self.effectsDict.keys() - keys.sort() + keys = sorted(self.effectsDict.keys()) for name in keys: effect = self.effectsDict[name] self.effectsLabelMenu.add_command( @@ -1194,7 +1197,7 @@ class ParticlePanel(AppShell): self.mainNotebook.selectpage('System') self.updateInfo('System') else: - print 'ParticlePanel: No effect named ' + name + print('ParticlePanel: No effect named ' + name) def toggleEffect(self, effect, var): if var.get(): @@ -1250,8 +1253,8 @@ class ParticlePanel(AppShell): else: path = '.' if not os.path.isdir(path): - print 'ParticlePanel Warning: Invalid default DNA directory!' - print 'Using current directory' + print('ParticlePanel Warning: Invalid default DNA directory!') + print('Using current directory') path = '.' particleFilename = askopenfilename( defaultextension = '.ptf', @@ -1278,8 +1281,8 @@ class ParticlePanel(AppShell): else: path = '.' if not os.path.isdir(path): - print 'ParticlePanel Warning: Invalid default DNA directory!' - print 'Using current directory' + print('ParticlePanel Warning: Invalid default DNA directory!') + print('Using current directory') path = '.' particleFilename = asksaveasfilename( defaultextension = '.ptf', diff --git a/direct/src/tkpanels/Placer.py b/direct/src/tkpanels/Placer.py index 9b52343bf7..8cda08310b 100644 --- a/direct/src/tkpanels/Placer.py +++ b/direct/src/tkpanels/Placer.py @@ -9,7 +9,6 @@ from direct.tkwidgets.AppShell import * from direct.tkwidgets import Dial from direct.tkwidgets import Floater from direct.directtools.DirectGlobals import ZERO_VEC, UNIT_VEC -from Tkinter import * import Pmw """ @@ -770,12 +769,12 @@ class Placer(AppShell): posString = '%.2f, %.2f, %.2f' % (pos[0], pos[1], pos[2]) hprString = '%.2f, %.2f, %.2f' % (hpr[0], hpr[1], hpr[2]) scaleString = '%.2f, %.2f, %.2f' % (scale[0], scale[1], scale[2]) - print 'NodePath: %s' % name - print 'Pos: %s' % posString - print 'Hpr: %s' % hprString - print 'Scale: %s' % scaleString - print ('%s.setPosHprScale(%s, %s, %s)' % - (name, posString, hprString, scaleString)) + print('NodePath: %s' % name) + print('Pos: %s' % posString) + print('Hpr: %s' % hprString) + print('Scale: %s' % scaleString) + print(('%s.setPosHprScale(%s, %s, %s)' % + (name, posString, hprString, scaleString))) def onDestroy(self, event): # Remove hooks diff --git a/direct/src/tkpanels/TaskManagerPanel.py b/direct/src/tkpanels/TaskManagerPanel.py index 8030f06c2a..1283044b59 100644 --- a/direct/src/tkpanels/TaskManagerPanel.py +++ b/direct/src/tkpanels/TaskManagerPanel.py @@ -3,9 +3,16 @@ __all__ = ['TaskManagerPanel', 'TaskManagerWidget'] from direct.tkwidgets.AppShell import * -from Tkinter import * from direct.showbase.DirectObject import DirectObject -import Pmw +import Pmw, sys + +if sys.version_info >= (3, 0): + from tkinter import * + from tkinter.messagebox import askokcancel +else: + from Tkinter import * + from tkMessageBox import askokcancel + class TaskManagerPanel(AppShell): # Override class variables here @@ -188,7 +195,6 @@ class TaskManagerWidget(DirectObject): (name == 'tkLoop') or (name == 'eventManager') or (name == 'igLoop')): - from tkMessageBox import askokcancel ok = askokcancel('TaskManagerControls', 'Remove: %s?' % name, parent = self.parent, @@ -205,7 +211,6 @@ class TaskManagerWidget(DirectObject): (name == 'tkLoop') or (name == 'eventManager') or (name == 'igLoop')): - from tkMessageBox import askokcancel ok = askokcancel('TaskManagerControls', 'Remove tasks named: %s?' % name, parent = self.parent, diff --git a/direct/src/tkwidgets/AppShell.py b/direct/src/tkwidgets/AppShell.py index 67a7e6b794..6c5d930976 100644 --- a/direct/src/tkwidgets/AppShell.py +++ b/direct/src/tkwidgets/AppShell.py @@ -9,15 +9,19 @@ __all__ = ['AppShell'] from direct.showbase.DirectObject import DirectObject from direct.showbase.TkGlobal import * -from tkFileDialog import * -from Tkinter import * -import Pmw -import Dial -import Floater -import Slider -import EntryScale -import VectorWidgets -import ProgressBar +import Pmw, sys +from . import Dial +from . import Floater +from . import Slider +from . import EntryScale +from . import VectorWidgets +from . import ProgressBar + +if sys.version_info >= (3, 0): + from tkinter.filedialog import * +else: + from tkFileDialog import * + """ TO FIX: @@ -318,7 +322,7 @@ class AppShell(Pmw.MegaWidget, DirectObject): # Update kw to reflect user inputs kw['text'] = text # Create widget - widget = apply(widgetClass, (parent,), kw) + widget = widgetClass(parent, **kw) # Do this after so command isn't called on widget creation widget['command'] = command # Pack widget @@ -475,7 +479,7 @@ class AppShell(Pmw.MegaWidget, DirectObject): kw['menu_tearoff'] = menu_tearoff kw['menubutton_textvariable'] = variable # Create widget - widget = apply(Pmw.OptionMenu, (parent,), kw) + widget = Pmw.OptionMenu(parent, **kw) # Do this after so command isn't called on widget creation widget['command'] = command # Pack widget @@ -502,7 +506,7 @@ class AppShell(Pmw.MegaWidget, DirectObject): kw['scrolledlist_items'] = items kw['entryfield_entry_state'] = state # Create widget - widget = apply(Pmw.ComboBox, (parent,), kw) + widget = Pmw.ComboBox(parent, **kw) # Bind selection command widget['selectioncommand'] = command # Select first item if it exists diff --git a/direct/src/tkwidgets/Dial.py b/direct/src/tkwidgets/Dial.py index 13a3cc8472..5b10cdb95a 100644 --- a/direct/src/tkwidgets/Dial.py +++ b/direct/src/tkwidgets/Dial.py @@ -6,10 +6,9 @@ Dial Class: Velocity style controller for floating point values with __all__ = ['Dial', 'AngleDial', 'DialWidget'] from direct.showbase.TkGlobal import * -from Tkinter import * -from Valuator import Valuator, VALUATOR_MINI, VALUATOR_FULL +from .Valuator import Valuator, VALUATOR_MINI, VALUATOR_FULL from direct.task import Task -import math, string, operator, Pmw +import math, operator, Pmw TWO_PI = 2.0 * math.pi ONEPOINTFIVE_PI = 1.5 * math.pi @@ -258,7 +257,7 @@ class DialWidget(Pmw.MegaWidget): value = self['base'] + ((value - self['base']) % self['delta']) # Send command if any if fCommand and (self['command'] != None): - apply(self['command'], [value] + self['commandData']) + self['command'](*[value] + self['commandData']) # Record value self.value = value @@ -411,12 +410,12 @@ class DialWidget(Pmw.MegaWidget): def _onButtonPress(self, *args): """ User redefinable callback executed on button press """ if self['preCallback']: - apply(self['preCallback'], self['callbackData']) + self['preCallback'](*self['callbackData']) def _onButtonRelease(self, *args): """ User redefinable callback executed on button release """ if self['postCallback']: - apply(self['postCallback'], self['callbackData']) + self['postCallback'](*self['callbackData']) if __name__ == '__main__': diff --git a/direct/src/tkwidgets/EntryScale.py b/direct/src/tkwidgets/EntryScale.py index e4c8a96a60..c9685fcf6c 100644 --- a/direct/src/tkwidgets/EntryScale.py +++ b/direct/src/tkwidgets/EntryScale.py @@ -5,10 +5,14 @@ EntryScale Class: Scale with a label, and a linked and validated entry __all__ = ['EntryScale', 'EntryScaleGroup'] from direct.showbase.TkGlobal import * -from Tkinter import * -import string, Pmw -import tkColorChooser -from tkSimpleDialog import * +import Pmw, sys + +if sys.version_info >= (3, 0): + from tkinter.simpledialog import * + from tkinter.colorchooser import askcolor +else: + from tkSimpleDialog import * + from tkColorChooser import askcolor """ Change Min/Max buttons to labels, add highlight binding @@ -204,7 +208,7 @@ class EntryScale(Pmw.MegaWidget): if not self.fScaleCommand: return # convert scale val to float - self.set(string.atof(strVal)) + self.set(float(strVal)) """ # Update entry to reflect formatted value self.entryValue.set(self.entryFormat % self.value) @@ -215,10 +219,10 @@ class EntryScale(Pmw.MegaWidget): def _entryCommand(self, event = None): try: - val = string.atof(self.entryValue.get()) - apply(self.onReturn, self['callbackData']) + val = float(self.entryValue.get()) + self.onReturn(*self['callbackData']) self.set(val) - apply(self.onReturnRelease, self['callbackData']) + self.onReturnRelease(*self['callbackData']) except ValueError: pass @@ -266,7 +270,7 @@ class EntryScale(Pmw.MegaWidget): def __onPress(self, event): # First execute onpress callback if self['preCallback']: - apply(self['preCallback'], self['callbackData']) + self['preCallback'](*self['callbackData']) # Now enable slider command self.fScaleCommand = 1 @@ -279,7 +283,7 @@ class EntryScale(Pmw.MegaWidget): self.fScaleCommand = 0 # First execute onpress callback if self['postCallback']: - apply(self['postCallback'], self['callbackData']) + self['postCallback'](*self['callbackData']) def onRelease(self, *args): """ User redefinable callback executed on button release """ @@ -417,7 +421,7 @@ class EntryScaleGroup(Pmw.MegaToplevel): def __onReturn(self, esg): # Execute onReturn callback - apply(self.onReturn, esg.get()) + self.onReturn(*esg.get()) def onReturn(self, *args): """ User redefinable callback executed on button press """ @@ -425,7 +429,7 @@ class EntryScaleGroup(Pmw.MegaToplevel): def __onReturnRelease(self, esg): # Execute onReturnRelease callback - apply(self.onReturnRelease, esg.get()) + self.onReturnRelease(*esg.get()) def onReturnRelease(self, *args): """ User redefinable callback executed on button press """ @@ -434,7 +438,7 @@ class EntryScaleGroup(Pmw.MegaToplevel): def __onPress(self, esg): # Execute onPress callback if self['preCallback']: - apply(self['preCallback'], esg.get()) + self['preCallback'](*esg.get()) def onPress(self, *args): """ User redefinable callback executed on button press """ @@ -443,7 +447,7 @@ class EntryScaleGroup(Pmw.MegaToplevel): def __onRelease(self, esg): # Execute onRelease callback if self['postCallback']: - apply(self['postCallback'], esg.get()) + self['postCallback'](*esg.get()) def onRelease(self, *args): """ User redefinable callback executed on button release """ @@ -492,7 +496,7 @@ def rgbPanel(nodePath, callback = None): # System color picker def popupColorPicker(esg = esg): # Can pass in current color with: color = (255, 0, 0) - color = tkColorChooser.askcolor( + color = askcolor( parent = esg.interior(), # Initialize it to current color initialcolor = tuple(esg.get()[:3]))[0] @@ -502,7 +506,7 @@ def rgbPanel(nodePath, callback = None): command = popupColorPicker) def printToLog(nodePath=nodePath): c=nodePath.getColor() - print "Vec4(%.3f, %.3f, %.3f, %.3f)"%(c[0], c[1], c[2], c[3]) + print("Vec4(%.3f, %.3f, %.3f, %.3f)"%(c[0], c[1], c[2], c[3])) menu.insert_command(index = 5, label = 'Print to log', command = printToLog) @@ -520,7 +524,7 @@ if __name__ == '__main__': # Dummy command def printVal(val): - print val + print(val) # Create and pack a EntryScale megawidget. mega1 = EntryScale(root, command = printVal) diff --git a/direct/src/tkwidgets/Floater.py b/direct/src/tkwidgets/Floater.py index 655b7728be..d8a1b83534 100644 --- a/direct/src/tkwidgets/Floater.py +++ b/direct/src/tkwidgets/Floater.py @@ -6,8 +6,7 @@ Floater Class: Velocity style controller for floating point values with __all__ = ['Floater', 'FloaterWidget', 'FloaterGroup'] from direct.showbase.TkGlobal import * -from Tkinter import * -from Valuator import Valuator, VALUATOR_MINI, VALUATOR_FULL +from .Valuator import Valuator, VALUATOR_MINI, VALUATOR_FULL from direct.task import Task import math, Pmw @@ -123,7 +122,7 @@ class FloaterWidget(Pmw.MegaWidget): """ # Send command if any if fCommand and (self['command'] != None): - apply(self['command'], [value] + self['commandData']) + self['command'](*[value] + self['commandData']) # Record value self.value = value @@ -145,7 +144,7 @@ class FloaterWidget(Pmw.MegaWidget): # Exectute user redefinable callback function (if any) self['relief'] = SUNKEN if self['preCallback']: - apply(self['preCallback'], self['callbackData']) + self['preCallback'](*self['callbackData']) self.velocitySF = 0.0 self.updateTask = taskMgr.add(self.updateFloaterTask, 'updateFloater') @@ -183,7 +182,7 @@ class FloaterWidget(Pmw.MegaWidget): self.velocitySF = 0.0 # Execute user redefinable callback function (if any) if self['postCallback']: - apply(self['postCallback'], self['callbackData']) + self['postCallback'](*self['callbackData']) self['relief'] = RAISED def setNumDigits(self): @@ -336,7 +335,7 @@ if __name__ == '__main__': # Dummy command def printVal(val): - print val + print(val) # Create and pack a Floater megawidget. mega1 = Floater(root, command = printVal) diff --git a/direct/src/tkwidgets/MemoryExplorer.py b/direct/src/tkwidgets/MemoryExplorer.py index 325e95b74d..62e74a6202 100755 --- a/direct/src/tkwidgets/MemoryExplorer.py +++ b/direct/src/tkwidgets/MemoryExplorer.py @@ -1,7 +1,6 @@ from direct.showbase.DirectObject import DirectObject from direct.showbase.TkGlobal import * -from Tkinter import * -from Tree import * +from .Tree import * import Pmw #-------------------------------------------------------------------------- diff --git a/direct/src/tkwidgets/ProgressBar.py b/direct/src/tkwidgets/ProgressBar.py index d9ed5d3824..81b1d480b3 100644 --- a/direct/src/tkwidgets/ProgressBar.py +++ b/direct/src/tkwidgets/ProgressBar.py @@ -5,7 +5,7 @@ A basic widget for showing the progress being made in a task. __all__ = ['ProgressBar'] from direct.showbase.TkGlobal import * -from Tkinter import * + class ProgressBar: def __init__(self, master=None, orientation="horizontal", diff --git a/direct/src/tkwidgets/SceneGraphExplorer.py b/direct/src/tkwidgets/SceneGraphExplorer.py index 2c5c965056..7e39dbeac1 100644 --- a/direct/src/tkwidgets/SceneGraphExplorer.py +++ b/direct/src/tkwidgets/SceneGraphExplorer.py @@ -4,8 +4,7 @@ __all__ = ['SceneGraphExplorer', 'SceneGraphExplorerItem', 'explore'] from direct.showbase.DirectObject import DirectObject from direct.showbase.TkGlobal import * -from Tkinter import * -from Tree import * +from .Tree import * import Pmw # changing these strings requires changing DirectSession.py SGE_ strs too! diff --git a/direct/src/tkwidgets/Slider.py b/direct/src/tkwidgets/Slider.py index f2d9bb1246..ceb36287d3 100644 --- a/direct/src/tkwidgets/Slider.py +++ b/direct/src/tkwidgets/Slider.py @@ -6,9 +6,7 @@ Slider Class: Velocity style controller for floating point values with __all__ = ['Slider', 'SliderWidget', 'rgbPanel'] from direct.showbase.TkGlobal import * -from Tkinter import * -from Valuator import Valuator, rgbPanel, VALUATOR_MINI, VALUATOR_FULL -import string +from .Valuator import Valuator, rgbPanel, VALUATOR_MINI, VALUATOR_FULL import Pmw class Slider(Valuator): @@ -282,7 +280,7 @@ class SliderWidget(Pmw.MegaWidget): """ # Send command if any if fCommand and (self['command'] != None): - apply(self['command'], [value] + self['commandData']) + self['command'](*[value] + self['commandData']) # Record value self.value = value @@ -322,11 +320,11 @@ class SliderWidget(Pmw.MegaWidget): # Find screen space position of bottom/center of arrow button x = (self._arrowBtn.winfo_rootx() + self._arrowBtn.winfo_width()/2.0 - self.interior()['bd']) -# string.atoi(self.interior()['bd'])) +# int(self.interior()['bd'])) y = self._arrowBtn.winfo_rooty() + self._arrowBtn.winfo_height() # Popup border width bd = self._popup['bd'] -# bd = string.atoi(self._popup['bd']) +# bd = int(self._popup['bd']) # Get width of label minW = self._minLabel.winfo_width() # Width of canvas to adjust for @@ -378,7 +376,7 @@ class SliderWidget(Pmw.MegaWidget): self._fPressInside = 1 self._fUpdate = 1 if self['preCallback']: - apply(self['preCallback'], self['callbackData']) + self['preCallback'](*self['callbackData']) self._updateValue(event) else: self._fPressInside = 0 @@ -391,24 +389,24 @@ class SliderWidget(Pmw.MegaWidget): if canvasY > 0: self._fUpdate = 1 if self['preCallback']: - apply(self['preCallback'], self['callbackData']) + self['preCallback'](*self['callbackData']) self._unpostOnNextRelease() elif self._fUpdate: self._updateValue(event) def _scaleBtnPress(self, event): if self['preCallback']: - apply(self['preCallback'], self['callbackData']) + self['preCallback'](*self['callbackData']) def _scaleBtnRelease(self, event): # Do post callback if any if self['postCallback']: - apply(self['postCallback'], self['callbackData']) + self['postCallback'](*self['callbackData']) def _widgetBtnRelease(self, event): # Do post callback if any if self._fUpdate and self['postCallback']: - apply(self['postCallback'], self['callbackData']) + self['postCallback'](*self['callbackData']) if (self._fUnpost or (not (self._firstPress or self._fPressInside))): self._unpostSlider() @@ -460,7 +458,7 @@ class SliderWidget(Pmw.MegaWidget): self._widget['command'] = self._scaleCommand def _scaleCommand(self, val): - self.set(string.atof(val)) + self.set(float(val)) # Methods to modify floater characteristics def setMin(self): diff --git a/direct/src/tkwidgets/Tree.py b/direct/src/tkwidgets/Tree.py index 88d3918386..e3e49b925f 100644 --- a/direct/src/tkwidgets/Tree.py +++ b/direct/src/tkwidgets/Tree.py @@ -21,7 +21,6 @@ __all__ = ['TreeNode', 'TreeItem'] import os from direct.showbase.TkGlobal import * -from Tkinter import * from panda3d.core import * # Initialize icon directory @@ -233,7 +232,7 @@ class TreeNode: self.kidKeys.append(key) # Remove unused children - for key in self.children.keys(): + for key in list(self.children.keys()): if key not in self.kidKeys: del(self.children[key]) @@ -304,14 +303,14 @@ class TreeNode: if self.fModeChildrenTag: if self.childrenTag: showThisItem = False - for tagKey in self.childrenTag.keys(): + for tagKey in list(self.childrenTag.keys()): if item.nodePath.hasTag(tagKey): showThisItem = self.childrenTag[tagKey] if not showThisItem: self.kidKeys.remove(key) # Remove unused children - for key in self.children.keys(): + for key in list(self.children.keys()): if key not in self.kidKeys: del(self.children[key]) cx = x+20 @@ -437,7 +436,7 @@ class TreeNode: if self.fModeChildrenTag: if self.childrenTag: showThisItem = False - for tagKey in self.childrenTag.keys(): + for tagKey in list(self.childrenTag.keys()): if self.item.nodePath.hasTag(tagKey): showThisItem = self.childrenTag[tagKey] if not showThisItem: diff --git a/direct/src/tkwidgets/Valuator.py b/direct/src/tkwidgets/Valuator.py index 652640a8cf..8b88d98680 100644 --- a/direct/src/tkwidgets/Valuator.py +++ b/direct/src/tkwidgets/Valuator.py @@ -4,12 +4,15 @@ __all__ = ['Valuator', 'ValuatorGroup', 'ValuatorGroupPanel'] from direct.showbase.DirectObject import * from direct.showbase.TkGlobal import * -from Tkinter import * -import tkColorChooser -import WidgetPropertiesDialog -import string, Pmw +from . import WidgetPropertiesDialog +import Pmw from direct.directtools.DirectUtil import getTkColorString +if sys.version_info >= (3, 0): + from tkinter.colorchooser import askcolor +else: + from tkColorChooser import askcolor + VALUATOR_MINI = 'mini' VALUATOR_FULL = 'full' @@ -204,7 +207,7 @@ class Valuator(Pmw.MegaWidget): self._valuator.updateIndicator(value) # Execute command if required if fCommand and self.fInit and (self['command'] is not None): - apply(self['command'], [value] + self['commandData']) + self['command'](*[value] + self['commandData']) # Record adjusted value self.adjustedValue = value # Once initialization is finished, allow commands to execute @@ -228,7 +231,7 @@ class Valuator(Pmw.MegaWidget): # Reset background self._entry.configure(background = self._entryBackground) # Get new value and check validity - newValue = string.atof(input) + newValue = float(input) # If OK, execute preCallback if one defined self._preCallback() # Call set to update valuator @@ -259,12 +262,12 @@ class Valuator(Pmw.MegaWidget): # Callback functions def _preCallback(self): if self['preCallback']: - apply(self['preCallback'], self['callbackData']) + self['preCallback'](*self['callbackData']) def _postCallback(self): # Exectute post callback if one defined if self['postCallback']: - apply(self['postCallback'], self['callbackData']) + self['postCallback'](*self['callbackData']) def setState(self): """ Enable/disable widget """ @@ -391,16 +394,16 @@ class ValuatorGroup(Pmw.MegaWidget): # Add a group alias so you can configure the valuators via: # fg.configure(Valuator_XXX = YYY) if self['type'] == DIAL: - import Dial + from . import Dial valuatorType = Dial.Dial elif self['type'] == ANGLEDIAL: - import Dial + from . import Dial valuatorType = Dial.AngleDial elif self['type'] == SLIDER: - import Slider + from . import Slider valuatorType = Slider.Slider else: - import Floater + from . import Floater valuatorType = Floater.Floater f = self.createcomponent( 'valuator%d' % index, (), 'valuator', valuatorType, @@ -459,12 +462,12 @@ class ValuatorGroup(Pmw.MegaWidget): def _preCallback(self, valGroup): # Execute pre callback if self['preCallback']: - apply(self['preCallback'], valGroup.get()) + self['preCallback'](*valGroup.get()) def _postCallback(self, valGroup): # Execute post callback if self['postCallback']: - apply(self['postCallback'], valGroup.get()) + self['postCallback'](*valGroup.get()) def __len__(self): return self['dim'] @@ -607,7 +610,7 @@ def rgbPanel(nodePath, callback = None, style = 'mini'): def popupColorPicker(): # Can pass in current color with: color = (255, 0, 0) - color = tkColorChooser.askcolor( + color = askcolor( parent = vgp.interior(), # Initialize it to current color initialcolor = tuple(vgp.get()[:3]))[0] @@ -616,7 +619,7 @@ def rgbPanel(nodePath, callback = None, style = 'mini'): def printToLog(): c=nodePath.getColor() - print "Vec4(%.3f, %.3f, %.3f, %.3f)"%(c[0], c[1], c[2], c[3]) + print("Vec4(%.3f, %.3f, %.3f, %.3f)"%(c[0], c[1], c[2], c[3])) # Check init color if nodePath.hasColor(): @@ -689,7 +692,7 @@ def lightRGBPanel(light, style = 'mini'): # Color picker for lights def popupColorPicker(): # Can pass in current color with: color = (255, 0, 0) - color = tkColorChooser.askcolor( + color = askcolor( parent = vgp.interior(), # Initialize it to current color initialcolor = tuple(vgp.get()[:3]))[0] @@ -698,8 +701,8 @@ def lightRGBPanel(light, style = 'mini'): def printToLog(): n = light.getName() c=light.getColor() - print n + (".setColor(Vec4(%.3f, %.3f, %.3f, %.3f))" % - (c[0], c[1], c[2], c[3])) + print(n + (".setColor(Vec4(%.3f, %.3f, %.3f, %.3f))" % + (c[0], c[1], c[2], c[3]))) # Check init color initColor = light.getColor() * 255.0 # Create entry scale group diff --git a/direct/src/tkwidgets/VectorWidgets.py b/direct/src/tkwidgets/VectorWidgets.py index 8fa64d31d9..1edfa951dd 100644 --- a/direct/src/tkwidgets/VectorWidgets.py +++ b/direct/src/tkwidgets/VectorWidgets.py @@ -3,14 +3,15 @@ __all__ = ['VectorEntry', 'Vector2Entry', 'Vector3Entry', 'Vector4Entry', 'ColorEntry'] from direct.showbase.TkGlobal import * -from Tkinter import * -import Valuator -import Floater -import Slider -import string -import tkColorChooser -import types +from . import Valuator import Pmw +import sys + +if sys.version_info >= (3, 0): + from tkinter.colorchooser import askcolor +else: + from tkColorChooser import askcolor + class VectorEntry(Pmw.MegaWidget): def __init__(self, parent = None, **kw): @@ -176,7 +177,7 @@ class VectorEntry(Pmw.MegaWidget): return self._value[index] def set(self, value, fCommand = 1): - if type(value) in (types.FloatType, types.IntType, types.LongType): + if type(value) in (float, int): value = [value] * self['dim'] for i in range(self['dim']): self._value[i] = value[i] @@ -192,7 +193,7 @@ class VectorEntry(Pmw.MegaWidget): entryVar = self.variableList[index] # Did we get a valid float? try: - newVal = string.atof(entryVar.get()) + newVal = float(entryVar.get()) except ValueError: return @@ -330,7 +331,7 @@ class ColorEntry(VectorEntry): def popupColorPicker(self): # Can pass in current color with: color = (255, 0, 0) - color = tkColorChooser.askcolor( + color = askcolor( parent = self.interior(), # Initialize it to current color initialcolor = tuple(self.get()[:3]))[0] diff --git a/direct/src/tkwidgets/WidgetPropertiesDialog.py b/direct/src/tkwidgets/WidgetPropertiesDialog.py index 6418d89c0a..0693a885d1 100644 --- a/direct/src/tkwidgets/WidgetPropertiesDialog.py +++ b/direct/src/tkwidgets/WidgetPropertiesDialog.py @@ -3,8 +3,7 @@ __all__ = ['WidgetPropertiesDialog'] from direct.showbase.TkGlobal import * -from Tkinter import * -import types, string, Pmw +import Pmw, sys """ TODO: @@ -28,12 +27,16 @@ class WidgetPropertiesDialog(Toplevel): self.propertyDict = propertyDict self.propertyList = propertyList if self.propertyList is None: - self.propertyList = self.propertyDict.keys() + self.propertyList = list(self.propertyDict.keys()) self.propertyList.sort() # Use default parent if none specified if not parent: - import Tkinter - parent = Tkinter._default_root + if sys.version_info >= (3, 0): + import tkinter + parent = tkinter._default_root + else: + import Tkinter + parent = Tkinter._default_root # Create toplevel window Toplevel.__init__(self, parent) self.transient(parent) @@ -172,8 +175,8 @@ class WidgetPropertiesDialog(Toplevel): box.pack() def realOrNone(self, val): - val = string.lower(val) - if string.find('none', val) != -1: + val = val.lower() + if 'none'.find(val) != -1: if val == 'none': return Pmw.OK else: @@ -181,8 +184,8 @@ class WidgetPropertiesDialog(Toplevel): return Pmw.realvalidator(val) def intOrNone(self, val): - val = string.lower(val) - if string.find('none', val) != -1: + val = val.lower() + if 'none'.find(val) != -1: if val == 'none': return Pmw.OK else: @@ -204,22 +207,22 @@ class WidgetPropertiesDialog(Toplevel): self.destroy() def validateChanges(self): - for property in self.modifiedDict.keys(): + for property in self.modifiedDict: tuple = self.modifiedDict[property] widget = tuple[0] entry = tuple[1] type = tuple[2] fNone = tuple[3] value = entry.get() - lValue = string.lower(value) - if (string.find('none', lValue) != -1): + lValue = value.lower() + if 'none'.find(lValue) != -1: if fNone and (lValue == 'none'): widget[property] = None else: if type == 'real': - value = string.atof(value) + value = float(value) elif type == 'integer': - value = string.atoi(value) + value = int(value) widget[property] = value def apply(self): diff --git a/direct/src/wxwidgets/ViewPort.py b/direct/src/wxwidgets/ViewPort.py index 19ed102330..57d7d4fc13 100755 --- a/direct/src/wxwidgets/ViewPort.py +++ b/direct/src/wxwidgets/ViewPort.py @@ -12,7 +12,7 @@ from direct.showbase.DirectObject import DirectObject from direct.directtools.DirectGrid import DirectGrid from direct.showbase.ShowBase import WindowControls from direct.directtools.DirectGlobals import * -from WxPandaWindow import WxPandaWindow +from .WxPandaWindow import WxPandaWindow from panda3d.core import OrthographicLens, Point3, Plane, CollisionPlane, CollisionNode, NodePath import wx diff --git a/direct/src/wxwidgets/WxPandaShell.py b/direct/src/wxwidgets/WxPandaShell.py index 128eea64b4..cae5fb9332 100755 --- a/direct/src/wxwidgets/WxPandaShell.py +++ b/direct/src/wxwidgets/WxPandaShell.py @@ -10,8 +10,8 @@ try: except NameError: base = ShowBase(False, windowType = 'none') -from WxAppShell import * -from ViewPort import * +from .WxAppShell import * +from .ViewPort import * ID_FOUR_VIEW = 401 ID_TOP_VIEW = 402 diff --git a/direct/src/wxwidgets/WxPandaStart.py b/direct/src/wxwidgets/WxPandaStart.py index 015181144b..80cd385bf1 100755 --- a/direct/src/wxwidgets/WxPandaStart.py +++ b/direct/src/wxwidgets/WxPandaStart.py @@ -1,3 +1,3 @@ -from WxPandaShell import * +from .WxPandaShell import * base.app = WxPandaShell() diff --git a/makepanda/makepanda.py b/makepanda/makepanda.py index 71845db7b8..4dae961c0d 100755 --- a/makepanda/makepanda.py +++ b/makepanda/makepanda.py @@ -2621,26 +2621,7 @@ CreatePandaVersionFiles() ########################################################################################## if (PkgSkip("DIRECT")==0): - fixers = [ - 'apply', - 'callable', - 'dict', - 'except', - 'execfile', - 'import', - 'imports', - 'long', - 'metaclass', - 'next', - 'numliterals', - 'print', - 'types', - 'unicode', - 'xrange', - 'xreadlines', - ] - - CopyPythonTree(GetOutputDir() + '/direct', 'direct/src', lib2to3_fixers=fixers, threads=THREADCOUNT) + CopyPythonTree(GetOutputDir() + '/direct', 'direct/src', threads=THREADCOUNT) ConditionalWriteFile(GetOutputDir() + '/direct/__init__.py', "") # This file used to be copied, but would nowadays cause conflicts. From 245d1241c98022aaa9b517f93fff84d921fa2457 Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 28 Mar 2016 22:36:31 +0200 Subject: [PATCH 15/16] Restore assign() for vector classes --- panda/src/linmath/lvecBase2_src.h | 6 +++++- panda/src/linmath/lvecBase3_src.h | 5 +++++ panda/src/linmath/lvecBase4_src.h | 5 +++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/panda/src/linmath/lvecBase2_src.h b/panda/src/linmath/lvecBase2_src.h index e4c1c8a905..0167855c65 100644 --- a/panda/src/linmath/lvecBase2_src.h +++ b/panda/src/linmath/lvecBase2_src.h @@ -33,9 +33,13 @@ PUBLISHED: INLINE_LINMATH FLOATNAME(LVecBase2)() DEFAULT_CTOR; INLINE_LINMATH FLOATNAME(LVecBase2)(FLOATTYPE fill_value); INLINE_LINMATH FLOATNAME(LVecBase2)(FLOATTYPE x, FLOATTYPE y); - ALLOC_DELETED_CHAIN(FLOATNAME(LVecBase2)); +#ifdef CPPPARSER + FLOATNAME(LVecBase2) &operator = (const FLOATNAME(LVecBase2) ©) = default; + FLOATNAME(LVecBase2) &operator = (FLOATTYPE fill_value) = default; +#endif + INLINE_LINMATH static const FLOATNAME(LVecBase2) &zero(); INLINE_LINMATH static const FLOATNAME(LVecBase2) &unit_x(); INLINE_LINMATH static const FLOATNAME(LVecBase2) &unit_y(); diff --git a/panda/src/linmath/lvecBase3_src.h b/panda/src/linmath/lvecBase3_src.h index c1879231b1..fdc39c7819 100644 --- a/panda/src/linmath/lvecBase3_src.h +++ b/panda/src/linmath/lvecBase3_src.h @@ -36,6 +36,11 @@ PUBLISHED: INLINE_LINMATH FLOATNAME(LVecBase3)(const FLOATNAME(LVecBase2) ©, FLOATTYPE z); ALLOC_DELETED_CHAIN(FLOATNAME(LVecBase3)); +#ifdef CPPPARSER + FLOATNAME(LVecBase3) &operator = (const FLOATNAME(LVecBase3) ©) = default; + FLOATNAME(LVecBase3) &operator = (FLOATTYPE fill_value) = default; +#endif + INLINE_LINMATH static const FLOATNAME(LVecBase3) &zero(); INLINE_LINMATH static const FLOATNAME(LVecBase3) &unit_x(); INLINE_LINMATH static const FLOATNAME(LVecBase3) &unit_y(); diff --git a/panda/src/linmath/lvecBase4_src.h b/panda/src/linmath/lvecBase4_src.h index 21afc8b182..1d4a16e961 100644 --- a/panda/src/linmath/lvecBase4_src.h +++ b/panda/src/linmath/lvecBase4_src.h @@ -45,6 +45,11 @@ PUBLISHED: INLINE_LINMATH FLOATNAME(LVecBase4)(const FLOATNAME(LVector3) &vector); ALLOC_DELETED_CHAIN(FLOATNAME(LVecBase4)); +#ifdef CPPPARSER + FLOATNAME(LVecBase4) &operator = (const FLOATNAME(LVecBase4) ©) = default; + FLOATNAME(LVecBase4) &operator = (FLOATTYPE fill_value) = default; +#endif + INLINE_LINMATH static const FLOATNAME(LVecBase4) &zero(); INLINE_LINMATH static const FLOATNAME(LVecBase4) &unit_x(); INLINE_LINMATH static const FLOATNAME(LVecBase4) &unit_y(); From 516e88c8fce44657f47f9a55fbe9600be9c1309c Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 28 Mar 2016 23:20:26 +0200 Subject: [PATCH 16/16] Fix to unbreak travis test script --- direct/src/showbase/PythonUtil.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/direct/src/showbase/PythonUtil.py b/direct/src/showbase/PythonUtil.py index c433384859..ebf8bce63f 100644 --- a/direct/src/showbase/PythonUtil.py +++ b/direct/src/showbase/PythonUtil.py @@ -1259,13 +1259,11 @@ class Enum: """ if __debug__: - import string - # chars that cannot appear within an item string. - InvalidChars = string.whitespace def _checkValidIdentifier(item): - invalidChars = string.whitespace+string.punctuation - invalidChars = invalidChars.replace('_','') + import string + invalidChars = string.whitespace + string.punctuation + invalidChars = invalidChars.replace('_', '') invalidFirstChars = invalidChars+string.digits if item[0] in invalidFirstChars: raise SyntaxError("Enum '%s' contains invalid first char" %