From 389b24e69522f986296817818f2f2ab1803fc1bb Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 13 Mar 2023 10:36:55 +0100 Subject: [PATCH 01/84] windisplay: Fix issues switching fullscreen while maximized Fixes #1469 --- panda/src/windisplay/winGraphicsWindow.cxx | 79 +++++++++++++++------- panda/src/windisplay/winGraphicsWindow.h | 2 + 2 files changed, 55 insertions(+), 26 deletions(-) diff --git a/panda/src/windisplay/winGraphicsWindow.cxx b/panda/src/windisplay/winGraphicsWindow.cxx index 1ca0425273..7878484a79 100644 --- a/panda/src/windisplay/winGraphicsWindow.cxx +++ b/panda/src/windisplay/winGraphicsWindow.cxx @@ -283,15 +283,34 @@ process_events() { */ void WinGraphicsWindow:: set_properties_now(WindowProperties &properties) { - if (properties.has_fullscreen() && !properties.get_fullscreen() && - is_fullscreen()) { - if (do_windowed_switch()) { - _properties.set_fullscreen(false); - properties.clear_fullscreen(); - } else { - windisplay_cat.warning() - << "Switching to windowed mode failed!\n"; + if (properties.has_fullscreen()) { + if (!properties.get_fullscreen() && is_fullscreen()) { + if (do_windowed_switch()) { + _properties.set_fullscreen(false); + } else { + windisplay_cat.warning() + << "Switching to windowed mode failed!\n"; + } } + else if (properties.get_fullscreen() && !is_fullscreen()) { + int x_size; + int y_size; + if (properties.has_size()) { + x_size = properties.get_x_size(); + y_size = properties.get_y_size(); + } else { + x_size = _properties.get_x_size(); + y_size = _properties.get_y_size(); + } + if (do_fullscreen_switch(x_size, y_size)) { + _properties.set_fullscreen(true); + properties.clear_size(); + } else { + windisplay_cat.warning() + << "Switching to fullscreen mode failed!\n"; + } + } + properties.clear_fullscreen(); } GraphicsWindow::set_properties_now(properties); @@ -917,8 +936,8 @@ do_fullscreen_resize(int x_size, int y_size) { * Called in the set_properties_now function to switch to fullscreen. */ bool WinGraphicsWindow:: -do_fullscreen_switch() { - if (!do_fullscreen_enable()) { +do_fullscreen_switch(int x_size, int y_size) { + if (!do_fullscreen_enable(x_size, y_size)) { // Couldn't get fullscreen. return false; } @@ -928,17 +947,21 @@ do_fullscreen_switch() { DWORD window_style = make_style(props); SetWindowLong(_hWnd, GWL_STYLE, window_style); - WINDOW_METRICS metrics; - bool has_origin; - if (!calculate_metrics(true, window_style, metrics, has_origin)){ - return false; - } - - SetWindowPos(_hWnd, HWND_NOTOPMOST, 0, 0, metrics.width, metrics.height, + SetWindowPos(_hWnd, HWND_NOTOPMOST, 0, 0, x_size, y_size, SWP_FRAMECHANGED | SWP_SHOWWINDOW); + + handle_reshape(); return true; } +/** + * Called in the set_properties_now function to switch to fullscreen. + */ +bool WinGraphicsWindow:: +do_fullscreen_switch() { + return do_fullscreen_switch(_properties.get_x_size(), _properties.get_y_size()); +} + /** * Called in the set_properties_now function to switch to windowed mode. */ @@ -1188,8 +1211,8 @@ open_graphic_window() { // somehow, but I need the window's black background to cover up the desktop // during the mode change. - if (fullscreen){ - if (!do_fullscreen_enable()){ + if (fullscreen) { + if (!do_fullscreen_enable()) { return false; } } @@ -1202,7 +1225,7 @@ open_graphic_window() { * Not to confuse with do_fullscreen_switch(). */ bool WinGraphicsWindow:: -do_fullscreen_enable() { +do_fullscreen_enable(int x_size, int y_size) { HWND hDesktopWindow = GetDesktopWindow(); HDC scrnDC = GetDC(hDesktopWindow); @@ -1212,8 +1235,8 @@ do_fullscreen_enable() { // GetDeviceCaps(scrnDC, VERTRES); ReleaseDC(hDesktopWindow, scrnDC); - DWORD dwWidth = _properties.get_x_size(); - DWORD dwHeight = _properties.get_y_size(); + DWORD dwWidth = x_size; + DWORD dwHeight = y_size; DWORD dwFullScreenBitDepth = cur_bitdepth; DEVMODE dm; @@ -1241,12 +1264,16 @@ do_fullscreen_enable() { } _fullscreen_display_mode = dm; - - _properties.set_origin(0, 0); - _properties.set_size(dwWidth, dwHeight); - return true; +} +/** + * This is a low-level function that just puts Windows in fullscreen mode. + * Not to confuse with do_fullscreen_switch(). + */ +bool WinGraphicsWindow:: +do_fullscreen_enable() { + return do_fullscreen_enable(_properties.get_x_size(), _properties.get_y_size()); } /** diff --git a/panda/src/windisplay/winGraphicsWindow.h b/panda/src/windisplay/winGraphicsWindow.h index 083508087b..a0416a873f 100644 --- a/panda/src/windisplay/winGraphicsWindow.h +++ b/panda/src/windisplay/winGraphicsWindow.h @@ -111,8 +111,10 @@ protected: virtual void handle_reshape(); virtual bool do_fullscreen_resize(int x_size, int y_size); + bool do_fullscreen_switch(int x_size, int y_size); virtual bool do_fullscreen_switch(); virtual bool do_windowed_switch(); + bool do_fullscreen_enable(int x_size, int y_size); virtual bool do_fullscreen_enable(); virtual bool do_fullscreen_disable(); From 21d7a83bfc1215c38827b003ac53f1abdf68f76f Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 29 Mar 2023 16:33:33 +0200 Subject: [PATCH 02/84] egldisplay: Fix GL_INVALID_OPERATION with headless pbuffer --- panda/src/egldisplay/eglGraphicsBuffer.cxx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/panda/src/egldisplay/eglGraphicsBuffer.cxx b/panda/src/egldisplay/eglGraphicsBuffer.cxx index 2cfbff83b4..e1293fd52e 100644 --- a/panda/src/egldisplay/eglGraphicsBuffer.cxx +++ b/panda/src/egldisplay/eglGraphicsBuffer.cxx @@ -38,9 +38,10 @@ eglGraphicsBuffer(GraphicsEngine *engine, GraphicsPipe *pipe, DCAST_INTO_V(egl_pipe, _pipe); _pbuffer = EGL_NO_SURFACE; - // Since the pbuffer never gets flipped, we get screenshots from the same - // buffer we draw into. - _screenshot_buffer_type = _draw_buffer_type; + // EGL pbuffers only have a back buffer (see 2.2.2 in spec), and it is never + // flipped (eglSwapBuffers is a no-op). + _draw_buffer_type = RenderBuffer::T_back; + _screenshot_buffer_type = RenderBuffer::T_back; } /** From f5d5340ad314cf36ed4426292beeffb4aa53cf73 Mon Sep 17 00:00:00 2001 From: rdb Date: Sat, 8 Apr 2023 10:37:13 +0200 Subject: [PATCH 03/84] egldisplay: make pbuffers resizeable --- panda/src/egldisplay/eglGraphicsBuffer.cxx | 24 ++++++++++++++++++++++ panda/src/egldisplay/eglGraphicsBuffer.h | 2 ++ panda/src/egldisplay/eglGraphicsPipe.cxx | 1 - 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/panda/src/egldisplay/eglGraphicsBuffer.cxx b/panda/src/egldisplay/eglGraphicsBuffer.cxx index e1293fd52e..a71f562611 100644 --- a/panda/src/egldisplay/eglGraphicsBuffer.cxx +++ b/panda/src/egldisplay/eglGraphicsBuffer.cxx @@ -120,6 +120,30 @@ end_frame(FrameMode mode, Thread *current_thread) { } } +/** + * + */ +void eglGraphicsBuffer:: +set_size(int x, int y) { + nassertv_always(_gsg != nullptr); + + if (_size.get_x() != x || _size.get_y() != y) { + eglDestroySurface(_egl_display, _pbuffer); + + int attrib_list[] = { + EGL_WIDTH, x, + EGL_HEIGHT, y, + EGL_NONE + }; + + eglGraphicsStateGuardian *eglgsg; + DCAST_INTO_V(eglgsg, _gsg); + _pbuffer = eglCreatePbufferSurface(eglgsg->_egl_display, eglgsg->_fbconfig, attrib_list); + } + + set_size_and_recalc(x, y); +} + /** * Closes the buffer right now. Called from the window thread. */ diff --git a/panda/src/egldisplay/eglGraphicsBuffer.h b/panda/src/egldisplay/eglGraphicsBuffer.h index 68697ef94c..60be353e47 100644 --- a/panda/src/egldisplay/eglGraphicsBuffer.h +++ b/panda/src/egldisplay/eglGraphicsBuffer.h @@ -36,6 +36,8 @@ public: virtual bool begin_frame(FrameMode mode, Thread *current_thread); virtual void end_frame(FrameMode mode, Thread *current_thread); + virtual void set_size(int x, int y); + protected: virtual void close_buffer(); virtual bool open_buffer(); diff --git a/panda/src/egldisplay/eglGraphicsPipe.cxx b/panda/src/egldisplay/eglGraphicsPipe.cxx index 6d4a58adc5..4df78c1028 100644 --- a/panda/src/egldisplay/eglGraphicsPipe.cxx +++ b/panda/src/egldisplay/eglGraphicsPipe.cxx @@ -323,7 +323,6 @@ make_output(const std::string &name, if (retry == 2) { if (((flags&BF_require_parasite)!=0)|| ((flags&BF_require_window)!=0)|| - ((flags&BF_resizeable)!=0)|| ((flags&BF_size_track_host)!=0)) { return nullptr; } From 87b46a61ed2ee417aac7270233a158e10a2bc20e Mon Sep 17 00:00:00 2001 From: rdb Date: Fri, 5 May 2023 10:45:26 +0200 Subject: [PATCH 04/84] display: minor doc fix and code cleanup --- panda/src/display/graphicsOutput.cxx | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/panda/src/display/graphicsOutput.cxx b/panda/src/display/graphicsOutput.cxx index 63d21476c0..9b6c93c49a 100644 --- a/panda/src/display/graphicsOutput.cxx +++ b/panda/src/display/graphicsOutput.cxx @@ -1113,8 +1113,9 @@ clear_pipe() { /** * Changes the x_size and y_size, then recalculates structures that depend on - * size. The recalculation currently includes: - compute_pixels on all the - * graphics regions. - updating the texture card, if one is present. + * size. The recalculation currently includes: + * - compute_pixels on all the graphics regions. + * - updating the texture card, if one is present. */ void GraphicsOutput:: set_size_and_recalc(int x, int y) { @@ -1126,11 +1127,8 @@ set_size_and_recalc(int x, int y) { int fb_x_size = get_fb_x_size(); int fb_y_size = get_fb_y_size(); - TotalDisplayRegions::iterator dri; - for (dri = _total_display_regions.begin(); - dri != _total_display_regions.end(); - ++dri) { - (*dri)->compute_pixels_all_stages(fb_x_size, fb_y_size); + for (DisplayRegion *dr : _total_display_regions) { + dr->compute_pixels_all_stages(fb_x_size, fb_y_size); } if (_texture_card != nullptr && _texture_card->get_num_geoms() > 0) { From eb82dbc7656075c466ce02ee8ffb7a8929173c09 Mon Sep 17 00:00:00 2001 From: rdb Date: Fri, 5 May 2023 10:47:14 +0200 Subject: [PATCH 05/84] putil: Accept bytes in DatagramOutputFile::write_header() --- panda/src/putil/datagramOutputFile.cxx | 16 ++++++++++++++++ panda/src/putil/datagramOutputFile.h | 1 + 2 files changed, 17 insertions(+) diff --git a/panda/src/putil/datagramOutputFile.cxx b/panda/src/putil/datagramOutputFile.cxx index 407e1adfec..6d285a7f3e 100644 --- a/panda/src/putil/datagramOutputFile.cxx +++ b/panda/src/putil/datagramOutputFile.cxx @@ -86,6 +86,22 @@ close() { _error = false; } +/** + * Writes a sequence of bytes to the beginning of the datagram file. This may + * be called any number of times after the file has been opened and before the + * first datagram is written. It may not be called once the first datagram is + * written. + */ +bool DatagramOutputFile:: +write_header(const vector_uchar &header) { + nassertr(_out != nullptr, false); + nassertr(!_wrote_first_datagram, false); + + _out->write((const char *)&header[0], header.size()); + thread_consider_yield(); + return !_out->fail(); +} + /** * Writes a sequence of bytes to the beginning of the datagram file. This may * be called any number of times after the file has been opened and before the diff --git a/panda/src/putil/datagramOutputFile.h b/panda/src/putil/datagramOutputFile.h index 17402850b0..fbc88e0bcd 100644 --- a/panda/src/putil/datagramOutputFile.h +++ b/panda/src/putil/datagramOutputFile.h @@ -38,6 +38,7 @@ PUBLISHED: void close(); + bool write_header(const vector_uchar &header); bool write_header(const std::string &header); virtual bool put_datagram(const Datagram &data); virtual bool copy_datagram(SubfileInfo &result, const Filename &filename); From 86804b3ed1c31841cd198091cd3f5688a0028e3e Mon Sep 17 00:00:00 2001 From: rdb Date: Fri, 5 May 2023 10:48:04 +0200 Subject: [PATCH 06/84] putil: Fix a faulty docstring in BamReader --- panda/src/putil/bamReader.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/panda/src/putil/bamReader.cxx b/panda/src/putil/bamReader.cxx index 2c9f0958ea..6c6d6e7b4f 100644 --- a/panda/src/putil/bamReader.cxx +++ b/panda/src/putil/bamReader.cxx @@ -315,7 +315,7 @@ read_object(TypedWritable *&ptr, ReferenceCount *&ref_ptr) { * time to call it. * * This must be called at least once after reading a particular object via - * get_object() in order to validate that object. + * read_object() in order to validate that object. * * The return value is true if all objects have been resolved, or false if * some objects are still outstanding (in which case you will need to call From 749e297a027dffda4c413ae24e8f9a19cc185e11 Mon Sep 17 00:00:00 2001 From: rdb Date: Fri, 5 May 2023 10:51:24 +0200 Subject: [PATCH 07/84] putil: Add file_version property to BamWriter (mirroring BamReader) --- panda/src/putil/bamWriter.h | 4 +++ panda/src/putil/bamWriter_ext.cxx | 28 +++++++++++++++++ panda/src/putil/bamWriter_ext.h | 37 +++++++++++++++++++++++ panda/src/putil/p3putil_ext_composite.cxx | 1 + 4 files changed, 70 insertions(+) create mode 100644 panda/src/putil/bamWriter_ext.cxx create mode 100644 panda/src/putil/bamWriter_ext.h diff --git a/panda/src/putil/bamWriter.h b/panda/src/putil/bamWriter.h index 780104b61c..be07d80411 100644 --- a/panda/src/putil/bamWriter.h +++ b/panda/src/putil/bamWriter.h @@ -87,9 +87,13 @@ PUBLISHED: INLINE TypedWritable *get_root_node() const; INLINE void set_root_node(TypedWritable *root_node); +public: + EXTENSION(PyObject *get_file_version() const); + PUBLISHED: MAKE_PROPERTY(target, get_target, set_target); MAKE_PROPERTY(filename, get_filename); + MAKE_PROPERTY(file_version, get_file_version); MAKE_PROPERTY(file_endian, get_file_endian); MAKE_PROPERTY(file_stdfloat_double, get_file_stdfloat_double); MAKE_PROPERTY(file_texture_mode, get_file_texture_mode); diff --git a/panda/src/putil/bamWriter_ext.cxx b/panda/src/putil/bamWriter_ext.cxx new file mode 100644 index 0000000000..ea5b451eb6 --- /dev/null +++ b/panda/src/putil/bamWriter_ext.cxx @@ -0,0 +1,28 @@ +/** + * 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 bamWriter_ext.cxx + * @author rdb + * @date 2023-05-03 + */ + +#include "bamWriter_ext.h" +#include "config_putil.h" + +#ifdef HAVE_PYTHON + +/** + * Returns the version number of the Bam file currently being written. + */ +PyObject *Extension:: +get_file_version() const { + return Py_BuildValue("(ii)", _this->get_file_major_ver(), + _this->get_file_minor_ver()); +} + +#endif diff --git a/panda/src/putil/bamWriter_ext.h b/panda/src/putil/bamWriter_ext.h new file mode 100644 index 0000000000..1f0b3eefb1 --- /dev/null +++ b/panda/src/putil/bamWriter_ext.h @@ -0,0 +1,37 @@ +/** + * 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 bamWriter_ext.h + * @author rdb + * @date 2023-05-01 + */ + +#ifndef BAMWRITER_EXT_H +#define BAMWRITER_EXT_H + +#include "dtoolbase.h" + +#ifdef HAVE_PYTHON + +#include "extension.h" +#include "bamWriter.h" +#include "py_panda.h" + +/** + * This class defines the extension methods for BamWriter, which are called + * instead of any C++ methods with the same prototype. + */ +template<> +class Extension : public ExtensionBase { +public: + PyObject *get_file_version() const; +}; + +#endif // HAVE_PYTHON + +#endif // BAMWRITER_EXT_H diff --git a/panda/src/putil/p3putil_ext_composite.cxx b/panda/src/putil/p3putil_ext_composite.cxx index 6306661a7f..abb9df3b73 100644 --- a/panda/src/putil/p3putil_ext_composite.cxx +++ b/panda/src/putil/p3putil_ext_composite.cxx @@ -1,4 +1,5 @@ #include "bamReader_ext.cxx" +#include "bamWriter_ext.cxx" #include "bitArray_ext.cxx" #include "paramPyObject.cxx" #include "pythonCallbackObject.cxx" From 45fbfab094ab68ca4f130f7a496f65fbe7273fa0 Mon Sep 17 00:00:00 2001 From: rdb Date: Fri, 5 May 2023 10:52:46 +0200 Subject: [PATCH 08/84] pgraph: Add file_version property to BamFile (like BamReader/Writer) --- panda/src/pgraph/bamFile.h | 4 +++ panda/src/pgraph/bamFile_ext.cxx | 28 ++++++++++++++++ panda/src/pgraph/bamFile_ext.h | 37 +++++++++++++++++++++ panda/src/pgraph/p3pgraph_ext_composite.cxx | 1 + 4 files changed, 70 insertions(+) create mode 100644 panda/src/pgraph/bamFile_ext.cxx create mode 100644 panda/src/pgraph/bamFile_ext.h diff --git a/panda/src/pgraph/bamFile.h b/panda/src/pgraph/bamFile.h index a244ab3fa3..32793e512e 100644 --- a/panda/src/pgraph/bamFile.h +++ b/panda/src/pgraph/bamFile.h @@ -74,7 +74,11 @@ PUBLISHED: BamReader *get_reader(); BamWriter *get_writer(); +public: + EXTENSION(PyObject *get_file_version() const); + PUBLISHED: + MAKE_PROPERTY(file_version, get_file_version); MAKE_PROPERTY(file_endian, get_file_endian); MAKE_PROPERTY(file_stdfloat_double, get_file_stdfloat_double); diff --git a/panda/src/pgraph/bamFile_ext.cxx b/panda/src/pgraph/bamFile_ext.cxx new file mode 100644 index 0000000000..6c5cd04e1a --- /dev/null +++ b/panda/src/pgraph/bamFile_ext.cxx @@ -0,0 +1,28 @@ +/** + * 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 bamFile_ext.cxx + * @author rdb + * @date 2023-05-03 + */ + +#include "bamFile_ext.h" +#include "bamWriter_ext.h" + +#ifdef HAVE_PYTHON + +/** + * Returns the version number of the Bam file currently being written. + */ +PyObject *Extension:: +get_file_version() const { + return Py_BuildValue("(ii)", _this->get_file_major_ver(), + _this->get_file_minor_ver()); +} + +#endif diff --git a/panda/src/pgraph/bamFile_ext.h b/panda/src/pgraph/bamFile_ext.h new file mode 100644 index 0000000000..7a6408d531 --- /dev/null +++ b/panda/src/pgraph/bamFile_ext.h @@ -0,0 +1,37 @@ +/** + * 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 bamFile_ext.h + * @author rdb + * @date 2023-05-03 + */ + +#ifndef BAMFILE_EXT_H +#define BAMFILE_EXT_H + +#include "dtoolbase.h" + +#ifdef HAVE_PYTHON + +#include "extension.h" +#include "bamFile.h" +#include "py_panda.h" + +/** + * This class defines the extension methods for BamFile, which are called + * instead of any C++ methods with the same prototype. + */ +template<> +class Extension : public ExtensionBase { +public: + PyObject *get_file_version() const; +}; + +#endif // HAVE_PYTHON + +#endif // BAMFILE_EXT_H diff --git a/panda/src/pgraph/p3pgraph_ext_composite.cxx b/panda/src/pgraph/p3pgraph_ext_composite.cxx index 37b9012c76..493636ccda 100644 --- a/panda/src/pgraph/p3pgraph_ext_composite.cxx +++ b/panda/src/pgraph/p3pgraph_ext_composite.cxx @@ -1,3 +1,4 @@ +#include "bamFile_ext.cxx" #include "loaderFileTypeRegistry_ext.cxx" #include "nodePath_ext.cxx" #include "nodePathCollection_ext.cxx" From 5d833c988aaace97b5460ed1bb2d4c53c3c9bf27 Mon Sep 17 00:00:00 2001 From: rdb Date: Fri, 5 May 2023 10:55:06 +0200 Subject: [PATCH 09/84] interrogate: Support explicit `cls` parameter for static methods --- dtool/src/interrogate/functionRemap.cxx | 20 ++++++++++++++----- dtool/src/interrogate/functionRemap.h | 1 + .../interfaceMakerPythonNative.cxx | 9 ++++++++- 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/dtool/src/interrogate/functionRemap.cxx b/dtool/src/interrogate/functionRemap.cxx index 2e984c652b..f4fc81ddbe 100644 --- a/dtool/src/interrogate/functionRemap.cxx +++ b/dtool/src/interrogate/functionRemap.cxx @@ -479,6 +479,10 @@ get_call_str(const string &container, const vector_string &pexprs) const { call << separator << "self"; separator = ", "; } + if (_flags & F_explicit_cls) { + call << separator << "cls"; + separator = ", "; + } size_t pn = _first_true_parameter; size_t num_parameters = pexprs.size(); @@ -807,14 +811,20 @@ setup_properties(const InterrogateFunction &ifunc, InterfaceMaker *interface_mak first_param = 1; } - if (_parameters.size() > first_param && _parameters[first_param]._name == "self" && + if (_parameters.size() > first_param && TypeManager::is_pointer_to_PyObject(_parameters[first_param]._remap->get_orig_type())) { // Here's a special case. If the first parameter of a nonstatic method // is a PyObject * called "self", then we will automatically fill it in - // from the this pointer, and remove it from the generated parameter - // list. - _parameters.erase(_parameters.begin() + first_param); - _flags |= F_explicit_self; + // from the this pointer, and remove it from the generated parameter list. + // For static methods, we offer "cls" instead, containing the type object. + if (_parameters[first_param]._name == "self") { + _parameters.erase(_parameters.begin() + first_param); + _flags |= F_explicit_self; + } + else if (!_has_this && _parameters[first_param]._name == "cls") { + _parameters.erase(_parameters.begin() + first_param); + _flags |= F_explicit_cls; + } } if (_parameters.size() == first_param) { diff --git a/dtool/src/interrogate/functionRemap.h b/dtool/src/interrogate/functionRemap.h index 61ce48bcb6..87c6b0a523 100644 --- a/dtool/src/interrogate/functionRemap.h +++ b/dtool/src/interrogate/functionRemap.h @@ -101,6 +101,7 @@ public: F_divide_float = 0x2000, F_hash = 0x4000, F_explicit_args = 0x8000, + F_explicit_cls =0x10000, }; typedef std::vector Parameters; diff --git a/dtool/src/interrogate/interfaceMakerPythonNative.cxx b/dtool/src/interrogate/interfaceMakerPythonNative.cxx index cc184c7efa..e1bf72eb93 100644 --- a/dtool/src/interrogate/interfaceMakerPythonNative.cxx +++ b/dtool/src/interrogate/interfaceMakerPythonNative.cxx @@ -1669,7 +1669,11 @@ write_module_class(ostream &out, Object *obj) { } if (!func->_has_this) { - flags += " | METH_STATIC"; + if (func->_flags & FunctionRemap::F_explicit_cls) { + flags += " | METH_CLASS"; + } else { + flags += " | METH_STATIC"; + } // Skip adding this entry if we also have a property with the same name. // In that case, we will use a Dtool_StaticProperty to disambiguate @@ -3527,6 +3531,9 @@ write_function_for_top(ostream &out, InterfaceMaker::Object *obj, InterfaceMaker if (func->_has_this) { prototype += "self"; } + else if (func->_flags & FunctionRemap::F_explicit_cls) { + prototype += "cls"; + } switch (func->_args_type) { case AT_keyword_args: From cc74efa79ab64b5d41c887a7222250f61e84cdc3 Mon Sep 17 00:00:00 2001 From: max Date: Fri, 5 May 2023 11:08:17 +0200 Subject: [PATCH 10/84] Fix assorted instances of leftover Python 3 syntax Closes #1490 --- contrib/src/panda3dtoolsgui/Panda3DToolsGUI.py | 6 +++--- panda/src/iphone/ipfreeze.py | 6 +++--- panda/src/iphone/provision.py | 2 +- panda/src/testbed/test_native_net1.py | 12 ++++++------ panda/src/testbed/test_native_net2.py | 6 +++--- panda/src/testbed/test_native_net3.py | 4 ++-- 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/contrib/src/panda3dtoolsgui/Panda3DToolsGUI.py b/contrib/src/panda3dtoolsgui/Panda3DToolsGUI.py index 0c8b3f3ccd..331081016b 100644 --- a/contrib/src/panda3dtoolsgui/Panda3DToolsGUI.py +++ b/contrib/src/panda3dtoolsgui/Panda3DToolsGUI.py @@ -1905,7 +1905,7 @@ class main(wx.Frame): self.txaExtraLines.append(line) txafile.close() except: - print "Error opening .txa file!" + print("Error opening .txa file!") self.palettize_saveTxaTxt.SetValue(os.path.join(dirname + os.sep , filename)) dlg.Destroy() @@ -2705,7 +2705,7 @@ class main(wx.Frame): selectedItemIndex = int(self.batchTree.GetItemText(selectedItemId).split()[0])-1 batchItem = self.batchList[selectedItemIndex] - print '\n'+self.BuildCommand(batchItem) + print('\n'+self.BuildCommand(batchItem)) if (batchItem['cmd'].count('maya2egg')): # Display Maya2Egg Tool Panel @@ -2840,7 +2840,7 @@ class main(wx.Frame): self.txaExtraLines.append(line) txafile.close() except: - print "Error opening .txa file!" + print("Error opening .txa file!") self.batchItemNameTxt.SetValue(batchItem['label']) diff --git a/panda/src/iphone/ipfreeze.py b/panda/src/iphone/ipfreeze.py index d7fe343a15..8762b95b63 100755 --- a/panda/src/iphone/ipfreeze.py +++ b/panda/src/iphone/ipfreeze.py @@ -17,8 +17,8 @@ import os from direct.dist import FreezeTool def usage(code, msg = ''): - print >> sys.stderr, __doc__ - print >> sys.stderr, msg + print(__doc__, file=sys.stderr) + print(msg, file=sys.stderr) sys.exit(code) if __name__ == '__main__': @@ -30,7 +30,7 @@ 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/panda/src/iphone/provision.py b/panda/src/iphone/provision.py index 47a445d3cc..ffdefc6fa0 100755 --- a/panda/src/iphone/provision.py +++ b/panda/src/iphone/provision.py @@ -34,7 +34,7 @@ command = 'env CODESIGN_ALLOCATE="/Developer/Platforms/iPhoneOS.platform/Develop 'xcent' : xcent, } -print command +print(command) result = os.system(command) if result != 0: raise StandardError diff --git a/panda/src/testbed/test_native_net1.py b/panda/src/testbed/test_native_net1.py index 0e4738e8ad..dd96973b16 100644 --- a/panda/src/testbed/test_native_net1.py +++ b/panda/src/testbed/test_native_net1.py @@ -11,7 +11,7 @@ SocketIP.InitNetworkDriver(); addr = SocketAddress() addr.setHost("127.0.0.1",8080) -print addr.getIpPort() +print(addr.getIpPort()) inbound = SocketTCPListen() @@ -23,16 +23,16 @@ while 1 == 1: source = SocketAddress() if inbound.GetIncomingConnection(newsession,source) : #newsession.SetNonBlocking(); - print source.getIpPort() + print(source.getIpPort()) newsession.SendData("Hello From the Listener\n\r"); s = newsession.RecvData(10); - print s - print newsession.GetLastError() + print(s) + print(newsession.GetLastError()) if newsession.ErrorIsWouldBlocking(newsession.GetLastError()) : - print "Reading Would Block" + print("Reading Would Block") else: - print "Not A Blocking Error" + print("Not A Blocking Error") newsession.SendData("GoodBy From the Listener\n\r"); newsession.Close(); diff --git a/panda/src/testbed/test_native_net2.py b/panda/src/testbed/test_native_net2.py index 44c197911b..002b223f53 100644 --- a/panda/src/testbed/test_native_net2.py +++ b/panda/src/testbed/test_native_net2.py @@ -15,7 +15,7 @@ SocketIP.InitNetworkDriver(); addr = SocketAddress() addr.setHost("127.0.0.1",6666) -print addr.getIpPort() +print(addr.getIpPort()) MyConection = BufferedDatagramConnection(0,4096000,4096000,102400); #help(BufferedDatagramConnection) @@ -42,8 +42,8 @@ dg1.addUint16(54321) while 1==1: for x in range(200000): if not MyConection.SendMessage(dg1): - print "Error Sending Message" + print("Error Sending Message") MyConection.Flush(); time.sleep(1) - print "loop" + print("loop") diff --git a/panda/src/testbed/test_native_net3.py b/panda/src/testbed/test_native_net3.py index dff516eb60..d1d9486ee6 100644 --- a/panda/src/testbed/test_native_net3.py +++ b/panda/src/testbed/test_native_net3.py @@ -15,7 +15,7 @@ SocketIP.InitNetworkDriver(); addr = SocketAddress() addr.setHost("127.0.0.1",6666) -print addr.getIpPort() +print(addr.getIpPort()) MyConection = BufferedDatagramConnection(0,4096000,4096000,102400); #help(BufferedDatagramConnection) @@ -47,4 +47,4 @@ while 1==1: MyConection.Flush(); time.sleep(1) - print "loop" + print("loop") From c958919037d80455e6b64bbb62b1bb2ace97a020 Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 8 May 2023 10:32:50 +0200 Subject: [PATCH 11/84] Make API documentation for Filename and VirtualFileSystem clearer Mention specifically that Filename methods act on the physical disk whereas VirtualFileSystem methods act on the VFS Fixes #1493 [skip ci] --- dtool/src/dtoolutil/filename.cxx | 25 +++++++++++++++++-------- dtool/src/dtoolutil/filename.h | 5 +++++ panda/src/express/virtualFileSystem.I | 11 ++++++----- 3 files changed, 28 insertions(+), 13 deletions(-) diff --git a/dtool/src/dtoolutil/filename.cxx b/dtool/src/dtoolutil/filename.cxx index da5657dd9d..7d3ce1693f 100644 --- a/dtool/src/dtoolutil/filename.cxx +++ b/dtool/src/dtoolutil/filename.cxx @@ -1259,9 +1259,12 @@ to_os_long_name() const { } /** - * Returns true if the filename exists on the disk, false otherwise. If the - * type is indicated to be executable, this also tests that the file has + * Returns true if the filename exists on the physical disk, false otherwise. + * If the type is indicated to be executable, this also tests that the file has * execute permission. + * + * @see VirtualFileSystem::exists() for checking whether the filename exists in + * the virtual file system. */ bool Filename:: exists() const { @@ -1290,8 +1293,11 @@ exists() const { } /** - * Returns true if the filename exists and is the name of a regular file (i.e. - * not a directory or device), false otherwise. + * Returns true if the filename exists on the physical disk and is the name of + * a regular file (i.e. not a directory or device), false otherwise. + * + * @see VirtualFileSystem::is_regular_file() for checking whether the filename + * exists and is a regular file in the virtual file system. */ bool Filename:: is_regular_file() const { @@ -1320,8 +1326,8 @@ is_regular_file() const { } /** - * Returns true if the filename exists and is either a directory or a regular - * file that can be written to, or false otherwise. + * Returns true if the filename exists on the physical disk and is either a + * directory or a regular file that can be written to, or false otherwise. */ bool Filename:: is_writable() const { @@ -1352,8 +1358,11 @@ is_writable() const { } /** - * Returns true if the filename exists and is a directory name, false - * otherwise. + * Returns true if the filename exists on the physical disk and is a directory + * name, false otherwise. + * + * @see VirtualFileSystem::is_directory() for checking whether the filename + * exists as a directory in the virtual file system. */ bool Filename:: is_directory() const { diff --git a/dtool/src/dtoolutil/filename.h b/dtool/src/dtoolutil/filename.h index 99d94af5a6..35d18044f1 100644 --- a/dtool/src/dtoolutil/filename.h +++ b/dtool/src/dtoolutil/filename.h @@ -35,6 +35,11 @@ class DSearchPath; * convention, and it knows how to perform basic OS-specific I/O, like testing * for file existence and searching a searchpath, as well as the best way to * open an fstream for reading or writing. + * + * Note that the methods of Filename that interact with the filesystem (such + * as exists(), open_read(), etc.) directly interface with the operating system + * and are not aware of Panda's virtual file system. To interact with the VFS, + * use the methods on VirtualFileSystem instead. */ class EXPCL_DTOOL_DTOOLUTIL Filename { PUBLISHED: diff --git a/panda/src/express/virtualFileSystem.I b/panda/src/express/virtualFileSystem.I index b74b9edbee..713b992147 100644 --- a/panda/src/express/virtualFileSystem.I +++ b/panda/src/express/virtualFileSystem.I @@ -12,7 +12,8 @@ */ /** - * Convenience function; returns true if the named file exists. + * Convenience function; returns true if the named file exists in the virtual + * file system hierarchy. */ INLINE bool VirtualFileSystem:: exists(const Filename &filename) const { @@ -20,8 +21,8 @@ exists(const Filename &filename) const { } /** - * Convenience function; returns true if the named file exists and is a - * directory. + * Convenience function; returns true if the named file exists as a directory in + * the virtual file system hierarchy. */ INLINE bool VirtualFileSystem:: is_directory(const Filename &filename) const { @@ -30,8 +31,8 @@ is_directory(const Filename &filename) const { } /** - * Convenience function; returns true if the named file exists and is a - * regular file. + * Convenience function; returns true if the named file exists as a regular file + * in the virtual file system hierarchy. */ INLINE bool VirtualFileSystem:: is_regular_file(const Filename &filename) const { From 4b276826b66bb5c8c5fd3fbab1ee8a590d95e595 Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 8 May 2023 11:20:54 +0200 Subject: [PATCH 12/84] workflow: Update GitHub CI runner OS versions --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 78f845c5e3..72795cdd0a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,12 +6,12 @@ jobs: if: "!contains(github.event.head_commit.message, '[skip ci]') && !contains(github.event.head_commit.message, '[ci skip]')" strategy: matrix: - os: [ubuntu-18.04, windows-2019, macOS-10.15] + os: [ubuntu-20.04, windows-2019, macOS-11] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v1 - name: Install dependencies (Ubuntu) - if: matrix.os == 'ubuntu-18.04' + if: matrix.os == 'ubuntu-20.04' run: | sudo apt-get update sudo apt-get install build-essential bison flex libfreetype6-dev libgl1-mesa-dev libjpeg-dev libode-dev libopenal-dev libpng-dev libssl-dev libvorbis-dev libx11-dev libxcursor-dev libxrandr-dev nvidia-cg-toolkit zlib1g-dev From 3f76f4aa7018ca7e7fe0726abfdcca8c6c840481 Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 8 May 2023 18:18:42 +0200 Subject: [PATCH 13/84] dist: Strip out delvewheel patch from packaged Python code Fixes #1492 --- direct/src/dist/FreezeTool.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/direct/src/dist/FreezeTool.py b/direct/src/dist/FreezeTool.py index 04dad43c7d..2361c7f16d 100644 --- a/direct/src/dist/FreezeTool.py +++ b/direct/src/dist/FreezeTool.py @@ -2495,6 +2495,21 @@ class PandaModuleFinder(modulefinder.ModuleFinder): else: code = fp.read() + # Strip out delvewheel patch (see GitHub issue #1492) + if isinstance(code, bytes): + # Don't look for \n at the end, it may also be \r\n + start_marker = b'# start delvewheel patch' + end_marker = b'# end delvewheel patch' + else: + start_marker = '# start delvewheel patch' + end_marker = '# end delvewheel patch' + + start = code.find(start_marker) + while start >= 0: + end = code.find(end_marker, start) + len(end_marker) + code = code[:start] + code[end:] + start = code.find(start_marker) + code += b'\n' if isinstance(code, bytes) else '\n' if sys.version_info >= (3, 2): co = compile(code, pathname, 'exec', optimize=self.optimize) From 1072e6bf1a32b7dc32a8c2fce54ded81c09af7c2 Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 8 May 2023 18:24:41 +0200 Subject: [PATCH 14/84] dist: Show better error message when targeting outdated platform This occurs if someone explicitly mentions eg. manylinux1 in their platforms list and then updates to Python 3.10 --- direct/src/dist/commands.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/direct/src/dist/commands.py b/direct/src/dist/commands.py index 2619cac2ad..a37f043849 100644 --- a/direct/src/dist/commands.py +++ b/direct/src/dist/commands.py @@ -551,7 +551,20 @@ class build_apps(setuptools.Command): for index in self.pypi_extra_indexes: pip_args += ['--extra-index-url', index] - subprocess.check_call([sys.executable, '-m', 'pip'] + pip_args) + try: + subprocess.check_call([sys.executable, '-m', 'pip'] + pip_args) + except: + # Display a more helpful message for these common issues. + if platform.startswith('manylinux2010_') and sys.version_info >= (3, 11): + new_platform = platform.replace('manylinux2010_', 'manylinux2014_') + self.announce('This error likely occurs because {} is not a supported target as of Python 3.11.\nChange the target platform to {} instead.'.format(platform, new_platform), distutils.log.ERROR) + elif platform.startswith('manylinux1_') and sys.version_info >= (3, 10): + new_platform = platform.replace('manylinux1_', 'manylinux2014_') + self.announce('This error likely occurs because {} is not a supported target as of Python 3.10.\nChange the target platform to {} instead.'.format(platform, new_platform), distutils.log.ERROR) + elif platform.startswith('macosx_10_6_') and sys.version_info >= (3, 8): + new_platform = platform.replace('macosx_10_6_', 'macosx_10_9_') + self.announce('This error likely occurs because {} is not a supported target as of Python 3.8.\nChange the target platform to {} instead.'.format(platform, new_platform), distutils.log.ERROR) + raise # Return a list of paths to the downloaded whls return [ From e5824367193f619fe9206dba97ba9abfde97e740 Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 8 May 2023 19:48:57 +0200 Subject: [PATCH 15/84] dist: Fix bdist_apps regression as of 88d27aa31c1eeb7d48cc468ed23a4ed18a8922f9 --- direct/src/dist/commands.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/direct/src/dist/commands.py b/direct/src/dist/commands.py index cbbfe4c204..4213db21fa 100644 --- a/direct/src/dist/commands.py +++ b/direct/src/dist/commands.py @@ -1689,6 +1689,8 @@ class bdist_apps(setuptools.Command): setattr(self, opt, None) def finalize_options(self): + import pkg_resources + # We need to massage the inputs a bit in case they came from a # setup.cfg file. self.installers = { From 3df594a6dd351bbfa08ca4d84cc8b61f1d72e8a7 Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 8 May 2023 19:50:14 +0200 Subject: [PATCH 16/84] dist: Add hidden import for shapely [skip ci] --- direct/src/dist/FreezeTool.py | 1 + 1 file changed, 1 insertion(+) diff --git a/direct/src/dist/FreezeTool.py b/direct/src/dist/FreezeTool.py index 2361c7f16d..3cfdafe1e9 100644 --- a/direct/src/dist/FreezeTool.py +++ b/direct/src/dist/FreezeTool.py @@ -96,6 +96,7 @@ hiddenImports = { 'scipy.special._ufuncs': ['scipy.special._ufuncs_cxx'], 'scipy.stats._stats': ['scipy.special.cython_special'], 'setuptools.monkey': ['setuptools.msvc'], + 'shapely._geometry_helpers': ['shapely._geos'], } if sys.version_info >= (3,): From 600fa45d6ee3947dee348cc96cb54a4c898cacb9 Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 8 May 2023 19:58:58 +0200 Subject: [PATCH 17/84] CMake: Fix typo in CMAKE_CXX_FLAGS variable on MSVC --- dtool/CompilerFlags.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dtool/CompilerFlags.cmake b/dtool/CompilerFlags.cmake index 0b6945878e..e3820ae652 100644 --- a/dtool/CompilerFlags.cmake +++ b/dtool/CompilerFlags.cmake @@ -101,7 +101,7 @@ endif() # Set warning levels if(MSVC) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W3") - set(CMAKE_CCXX_FLAGS "${CMAKE_CXX_FLAGS} /W3") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W3") else() set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall") From 75abee73e224b82c0869da3460284d48e891b5d0 Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 8 May 2023 19:59:50 +0200 Subject: [PATCH 18/84] CMake: Disable FMOD Ex on macOS There's no version of FMOD Ex that isn't linked against libstdc++.6.dylib, which is no longer available in the SDKs --- dtool/Package.cmake | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dtool/Package.cmake b/dtool/Package.cmake index 10e653f6d4..0a0fb8ea39 100644 --- a/dtool/Package.cmake +++ b/dtool/Package.cmake @@ -518,7 +518,9 @@ package_status(OPUS "Opus") # # FMOD Ex -find_package(FMODEx QUIET) +if(NOT APPLE) + find_package(FMODEx QUIET) +endif() package_option(FMODEx "This enables support for the FMOD Ex sound library, From 96b2f3a4d59c3c503d73a808f8656c81c7ad06df Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 8 May 2023 20:00:39 +0200 Subject: [PATCH 19/84] CMake: Split out Objective-C++ flags on macOS to fix crash This now requires CMake 3.16 This is a similar fix as 987f2f036b7d5b0e02a7ed8a2ff0f1029ae0d048 but for CMake --- CMakeLists.txt | 8 ++++++++ dtool/CompilerFlags.cmake | 15 +++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5249ac8b57..1d1ced66a4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,6 +24,9 @@ endif() # Set defaults for macOS, must be before project(). if(APPLE) + # Needed for enable_language(OBJCXX) + cmake_minimum_required(VERSION 3.16) + set(CMAKE_OSX_DEPLOYMENT_TARGET "10.9" CACHE STRING "Minimum macOS version to target") set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++") @@ -46,6 +49,11 @@ project(Panda3D VERSION ${_version}) unset(_version) unset(_s) +if(APPLE) + # Allows separating out C++ flags from ObjC++ flags + enable_language(OBJCXX) +endif() + # Determine the possible build types. Must be *after* calling project(). set(_configs Standard Release RelWithDebInfo Debug MinSizeRel) if(CMAKE_CXX_COMPILER_ID MATCHES "(AppleClang|Clang|GCC)") diff --git a/dtool/CompilerFlags.cmake b/dtool/CompilerFlags.cmake index e3820ae652..48f931387f 100644 --- a/dtool/CompilerFlags.cmake +++ b/dtool/CompilerFlags.cmake @@ -16,6 +16,7 @@ if(MSVC) else() set(CMAKE_C_FLAGS_STANDARD "-O3") set(CMAKE_CXX_FLAGS_STANDARD "-O3") + set(CMAKE_OBJCXX_FLAGS_STANDARD "-O3") endif() set(CMAKE_SHARED_LINKER_FLAGS_STANDARD "") set(CMAKE_MODULE_LINKER_FLAGS_STANDARD "") @@ -27,6 +28,8 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "(AppleClang|Clang)") "${CMAKE_C_FLAGS_DEBUG} -fprofile-instr-generate -fcoverage-mapping") set(CMAKE_CXX_FLAGS_COVERAGE "${CMAKE_CXX_FLAGS_DEBUG} -fprofile-instr-generate -fcoverage-mapping") + set(CMAKE_OBJCXX_FLAGS_COVERAGE + "${CMAKE_OBJCXX_FLAGS_DEBUG} -fprofile-instr-generate -fcoverage-mapping") set(CMAKE_SHARED_LINKER_FLAGS_COVERAGE "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} -fprofile-instr-generate") @@ -106,6 +109,9 @@ if(MSVC) else() set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall") + if(APPLE) + set(CMAKE_OBJCXX_FLAGS "${CMAKE_OBJCXX_FLAGS} -Wall") + endif() endif() @@ -133,6 +139,14 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "(GNU|Clang)") set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} ${release_flags}") set(CMAKE_CXX_FLAGS_STANDARD "${CMAKE_CXX_FLAGS_STANDARD} ${standard_flags}") + if(APPLE) + set(CMAKE_OBJCXX_FLAGS "${CMAKE_OBJCXX_FLAGS} ${global_flags}") + set(CMAKE_OBJCXX_FLAGS_RELEASE "${CMAKE_OBJCXX_FLAGS_RELEASE} ${global_flags}") + set(CMAKE_OBJCXX_FLAGS_RELWITHDEBINFO "${CMAKE_OBJCXX_FLAGS_RELWITHDEBINFO} ${global_flags}") + set(CMAKE_OBJCXX_FLAGS_MINSIZEREL "${CMAKE_OBJCXX_FLAGS_MINSIZEREL} ${global_flags}") + set(CMAKE_OBJCXX_FLAGS_STANDARD "${CMAKE_OBJCXX_FLAGS_STANDARD} ${global_flags}") + endif() + if(MSVC) # Clang behaving as MSVC set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-command-line-argument") @@ -151,6 +165,7 @@ endif() # and stops us from identifying cases where ENABLE_EXPORTS is needed. set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "") set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "") +set(CMAKE_SHARED_LIBRARY_LINK_OBJCXX_FLAGS "") # As long as we're figuring out compiler flags, figure out the flags for # turning C++ exception support on and off From dee48cc20113c0fe0ba4a88e21f7c7780c782bcc Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 8 May 2023 20:01:22 +0200 Subject: [PATCH 20/84] CMake: Fix error linking OpenAL as framework --- panda/src/audiotraits/CMakeLists.txt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/panda/src/audiotraits/CMakeLists.txt b/panda/src/audiotraits/CMakeLists.txt index 419bc66a88..cd58f3277d 100644 --- a/panda/src/audiotraits/CMakeLists.txt +++ b/panda/src/audiotraits/CMakeLists.txt @@ -58,7 +58,13 @@ if(HAVE_OPENAL) composite_sources(p3openal_audio P3OPENAL_SOURCES) add_library(p3openal_audio ${MODULE_TYPE} ${P3OPENAL_HEADERS} ${P3OPENAL_SOURCES}) set_target_properties(p3openal_audio PROPERTIES DEFINE_SYMBOL BUILDING_OPENAL_AUDIO) - target_link_libraries(p3openal_audio panda PKG::OPENAL) + target_link_libraries(p3openal_audio panda) + + if(HAVE_OPENAL_FRAMEWORK) + target_link_libraries(p3openal_audio "-framework OpenAL") + else() + target_link_libraries(p3openal_audio PKG::OPENAL) + endif() if(CMAKE_CXX_COMPILER_ID MATCHES "^(GNU|Clang)$") # When statically linking OpenAL, keep its symbols private to this module. From 6acfdb737bc2d491fed8b1ca2d1be42b520bbb87 Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 8 May 2023 20:02:07 +0200 Subject: [PATCH 21/84] workflow: Update CMake builder to macOS 11 --- .github/workflows/ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8c42f64d74..1fc6e969ff 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,7 +40,7 @@ jobs: eigen: NO - profile: macos-eigen-coverage-unity-xcode - os: macOS-10.15 + os: macOS-11 config: Coverage unity: YES generator: Xcode @@ -50,7 +50,7 @@ jobs: eigen: YES - profile: macos-nometa-standard-makefile - os: macOS-10.15 + os: macOS-11 config: Standard unity: NO generator: Unix Makefiles @@ -87,7 +87,7 @@ jobs: fetch-depth: 10 - name: Self-destruct makepanda - run: python makepanda/selfdestruct.py --yes + run: python3 makepanda/selfdestruct.py --yes - name: Install dependencies (macOS) if: runner.os == 'macOS' From d126ec71f72ad300688ae9a8cc51a5149d879fe3 Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 9 May 2023 09:16:17 +0200 Subject: [PATCH 22/84] PythonUtil: Add SerialMaskedGen to `__all__` Fixes #1496 --- direct/src/showbase/PythonUtil.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/direct/src/showbase/PythonUtil.py b/direct/src/showbase/PythonUtil.py index c460dbe73d..370a67d408 100644 --- a/direct/src/showbase/PythonUtil.py +++ b/direct/src/showbase/PythonUtil.py @@ -11,7 +11,7 @@ __all__ = [ 'boolEqual', 'lineupPos', 'formatElapsedSeconds', 'solveQuadratic', 'findPythonModule', 'mostDerivedLast', 'clampScalar', 'weightedChoice', 'randFloat', 'normalDistrib', 'weightedRand', 'randUint31', 'randInt32', - 'SerialNumGen', 'serialNum', 'uniqueName', 'Singleton', + 'SerialNumGen', 'SerialMaskedGen', 'serialNum', 'uniqueName', 'Singleton', 'SingletonError', 'printListEnum', 'safeRepr', 'fastRepr', 'isDefaultValue', 'ScratchPad', 'Sync', 'itype', 'getNumberedTypedString', 'getNumberedTypedSortedString', 'printNumberedTyped', 'DelayedCall', From 7fb9942fc34c41047e53feeaac33ad508b9dc0c3 Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 16 May 2023 18:14:57 +0200 Subject: [PATCH 23/84] tinydisplay: Fix crash on window close on macOS Fixes #1485 --- panda/src/tinydisplay/tinyCocoaGraphicsWindow.mm | 1 + 1 file changed, 1 insertion(+) diff --git a/panda/src/tinydisplay/tinyCocoaGraphicsWindow.mm b/panda/src/tinydisplay/tinyCocoaGraphicsWindow.mm index 0bb43c4eb8..38c08e88f7 100644 --- a/panda/src/tinydisplay/tinyCocoaGraphicsWindow.mm +++ b/panda/src/tinydisplay/tinyCocoaGraphicsWindow.mm @@ -173,6 +173,7 @@ close_window() { CFRelease(swap_buffer._data_provider); ZB_close(swap_buffer._frame_buffer); } + _swap_chain.clear(); CocoaGraphicsWindow::close_window(); } From d2e93cc185ff9990e40c0da124250364d3cc2cd1 Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 25 May 2023 13:55:22 +0200 Subject: [PATCH 24/84] gobj: Fix post_load_store_cache field being uninitialized on cycle This is randomly causing textures to be downloaded, which can be a significant performance drain --- panda/src/gobj/texture.cxx | 1 + 1 file changed, 1 insertion(+) diff --git a/panda/src/gobj/texture.cxx b/panda/src/gobj/texture.cxx index 7edced0507..99c5d10c02 100644 --- a/panda/src/gobj/texture.cxx +++ b/panda/src/gobj/texture.cxx @@ -10711,6 +10711,7 @@ Texture::CData:: CData(const Texture::CData ©) { _num_mipmap_levels_read = 0; _render_to_texture = copy._render_to_texture; + _post_load_store_cache = copy._post_load_store_cache; do_assign(©); From b79d8efce69ec409e51b43736979d5afa95db233 Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 25 May 2023 14:11:51 +0200 Subject: [PATCH 25/84] Don't use RTTI features when building with `-fno-rtti` This should make it possible to use `-fno-rtti` in a C++ application even when Panda has been compiled with RTTI enabled. --- panda/src/express/nodeReferenceCount.I | 2 +- panda/src/express/referenceCount.I | 2 +- panda/src/putil/copyOnWriteObject.I | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/panda/src/express/nodeReferenceCount.I b/panda/src/express/nodeReferenceCount.I index d87bc982d8..66a8be1cea 100644 --- a/panda/src/express/nodeReferenceCount.I +++ b/panda/src/express/nodeReferenceCount.I @@ -213,7 +213,7 @@ NodeRefCountObj(const Base ©) : Base(copy) { template void NodeRefCountObj:: init_type() { -#if defined(HAVE_RTTI) && !defined(__EDG__) +#if defined(HAVE_RTTI) && !defined(__EDG__) && (!defined(__GNUC__) || defined(__GXX_RTTI)) // If we have RTTI, we can determine the name of the base type. std::string base_name = typeid(Base).name(); #else diff --git a/panda/src/express/referenceCount.I b/panda/src/express/referenceCount.I index f4d71b1117..870362ff14 100644 --- a/panda/src/express/referenceCount.I +++ b/panda/src/express/referenceCount.I @@ -424,7 +424,7 @@ RefCountObj(const Base ©) : Base(copy) { template void RefCountObj:: init_type() { -#if defined(HAVE_RTTI) && !defined(__EDG__) +#if defined(HAVE_RTTI) && !defined(__EDG__) && (!defined(__GNUC__) || defined(__GXX_RTTI)) // If we have RTTI, we can determine the name of the base type. std::string base_name = typeid(Base).name(); #else diff --git a/panda/src/putil/copyOnWriteObject.I b/panda/src/putil/copyOnWriteObject.I index bcf326d87c..a6afee7163 100644 --- a/panda/src/putil/copyOnWriteObject.I +++ b/panda/src/putil/copyOnWriteObject.I @@ -128,7 +128,7 @@ make_cow_copy() { template void CopyOnWriteObj:: init_type() { -#if defined(HAVE_RTTI) && !defined(__EDG__) +#if defined(HAVE_RTTI) && !defined(__EDG__) && (!defined(__GNUC__) || defined(__GXX_RTTI)) // If we have RTTI, we can determine the name of the base type. std::string base_name = typeid(Base).name(); #else @@ -188,7 +188,7 @@ make_cow_copy() { template void CopyOnWriteObj1:: init_type() { -#if defined(HAVE_RTTI) && !defined(__EDG__) +#if defined(HAVE_RTTI) && !defined(__EDG__) && (!defined(__GNUC__) || defined(__GXX_RTTI)) // If we have RTTI, we can determine the name of the base type. std::string base_name = typeid(Base).name(); #else From d4d4aefbce08335b8afb13109a7001263a874763 Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 8 Jun 2023 13:45:52 +0200 Subject: [PATCH 26/84] makepackage: Force creating .dmg as HFS+ for 10.9 compatibility Fixes #1502 [skip ci] --- makepanda/makepackage.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/makepanda/makepackage.py b/makepanda/makepackage.py index 4e0a459488..f57fc873e3 100755 --- a/makepanda/makepackage.py +++ b/makepanda/makepackage.py @@ -832,7 +832,7 @@ def MakeInstallerOSX(version, runtime=False, python_versions=[], installdir=None dist.write('\n') dist.close() - oscmd('hdiutil create Panda3D-rw.dmg -volname "Panda3D SDK %s" -srcfolder dstroot/Panda3D' % (version)) + oscmd('hdiutil create Panda3D-rw.dmg -fs HFS+ -volname "Panda3D SDK %s" -srcfolder dstroot/Panda3D' % (version)) oscmd('hdiutil convert Panda3D-rw.dmg -format UDBZ -o %s' % (dmg_name)) oscmd('rm -f Panda3D-rw.dmg') From 94ebd7c953eb7ab048d3fd239374d6d4d7284a97 Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 12 Jun 2023 09:54:25 +0200 Subject: [PATCH 27/84] pstats: Fix exception when `__module__` is a descriptor This comes up when using metaclasses Fixes #1505 --- panda/src/pstatclient/pStatClient_ext.cxx | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/panda/src/pstatclient/pStatClient_ext.cxx b/panda/src/pstatclient/pStatClient_ext.cxx index db4b573c26..684ac1db2a 100644 --- a/panda/src/pstatclient/pStatClient_ext.cxx +++ b/panda/src/pstatclient/pStatClient_ext.cxx @@ -181,10 +181,23 @@ make_c_function_collector(PyCFunctionObject *meth) { } else { // If there's no module name, we need to get it from __module__. PyObject *py_mod_name = cls->tp_dict ? PyDict_GetItemString(cls->tp_dict, "__module__") : nullptr; - const char *mod_name; + const char *mod_name = nullptr; if (py_mod_name != nullptr) { - mod_name = PyUnicode_AsUTF8(py_mod_name); - } else { + if (PyUnicode_Check(py_mod_name)) { + mod_name = PyUnicode_AsUTF8(py_mod_name); + } else { + // Might be a descriptor. + py_mod_name = PyObject_GetAttrString(meth->m_self, "__module__"); + if (py_mod_name != nullptr) { + if (PyUnicode_Check(py_mod_name)) { + mod_name = PyUnicode_AsUTF8(py_mod_name); + } + Py_DECREF(py_mod_name); + } + else PyErr_Clear(); + } + } + if (mod_name == nullptr) { // Is it a built-in, like int or dict? PyObject *builtins = PyEval_GetBuiltins(); if (PyDict_GetItemString(builtins, cls->tp_name) == (PyObject *)cls) { From 07f9f9d89722a82234e0d111e61b7ff98e88e2db Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 13 Jun 2023 13:46:37 +0200 Subject: [PATCH 28/84] (multiview) texture preparation changes: Multiview textures are now handled as a single texture context instead of as one texture context per view. This should be marginally more efficient, but more importantly, it paves the way for implementing multiview textures as subviews of an array texture down the line, which paves the way for hardware-accelerated stereo rendering (where the left and right views get rendered simultaneously to different layers of an array texture). The difference between a multiview texture done this way and an array texture is that the views of a multiview texture will still be treated as individual textures from the shader's point of view, only the views will be sharing the same storage on the GPU. This can be done by using a feature offered by graphics APIs that is (serendipitously) also called "texture views", where it's possible to create multiple texture objects that point to layer ranges of a bigger array texture. That part has not yet been done as doing this in OpenGL will be a little tricky due to texture views being an optional feature (so both paths would need to be implemented), but texture views are native in Vulkan (and D3D10+ for that matter), so doing this now allows me to implement multiview textures natively on the Vulkan end right from the start, and OpenGL can follow later if desired. Furthermore, this commit includes: - OpenGL: Overhaul texture creation and binding - OpenGL: Change how reloading a texture with mipmaps works - OpenGL: Use DSA in a couple of places - OpenGL ES: Add support for buffer textures - OpenGL: Remove support for bindless textures for now; this was never implemented in a very useful way, not used to my knowledge, and it is better to re-implement it later after the new shader pipeline lands - DirectX9: All views of a texture are uploaded at the same time - TinyDisplay: Support multiview textures natively (consecutive storage in memory) - General: Per-page texture update tracking is working properly now for multiview textures --- panda/src/display/graphicsStateGuardian.cxx | 2 +- panda/src/display/graphicsStateGuardian.h | 2 +- panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx | 39 +- panda/src/dxgsg9/dxGraphicsStateGuardian9.h | 4 +- panda/src/dxgsg9/dxShaderContext9.cxx | 4 +- panda/src/dxgsg9/dxTextureContext9.I | 17 +- panda/src/dxgsg9/dxTextureContext9.cxx | 750 +++++++------- panda/src/dxgsg9/dxTextureContext9.h | 19 +- panda/src/dxgsg9/wdxGraphicsBuffer9.cxx | 24 +- panda/src/gles2gsg/gles2gsg.h | 17 + panda/src/glstuff/glCgShaderContext_src.cxx | 52 +- panda/src/glstuff/glGeomMunger_src.cxx | 2 +- panda/src/glstuff/glGraphicsBuffer_src.cxx | 87 +- panda/src/glstuff/glGraphicsBuffer_src.h | 2 +- .../glstuff/glGraphicsStateGuardian_src.cxx | 933 ++++++++++-------- .../src/glstuff/glGraphicsStateGuardian_src.h | 22 +- panda/src/glstuff/glShaderContext_src.cxx | 145 +-- panda/src/glstuff/glShaderContext_src.h | 3 - panda/src/glstuff/glTextureContext_src.I | 40 +- panda/src/glstuff/glTextureContext_src.cxx | 130 +-- panda/src/glstuff/glTextureContext_src.h | 29 +- panda/src/glstuff/glmisc_src.cxx | 10 - panda/src/glstuff/glmisc_src.h | 1 - panda/src/gobj/preparedGraphicsObjects.cxx | 20 +- panda/src/gobj/preparedGraphicsObjects.h | 2 +- panda/src/gobj/texture.cxx | 236 ++--- panda/src/gobj/texture.h | 10 +- panda/src/gobj/textureContext.I | 20 +- panda/src/gobj/textureContext.h | 4 +- panda/src/gsgbase/graphicsStateGuardianBase.h | 2 +- .../tinydisplay/tinyGraphicsStateGuardian.cxx | 249 ++--- .../tinydisplay/tinyGraphicsStateGuardian.h | 18 +- panda/src/tinydisplay/tinyTextureContext.I | 6 +- panda/src/tinydisplay/tinyTextureContext.cxx | 8 + panda/src/tinydisplay/tinyTextureContext.h | 2 +- panda/src/tinydisplay/zbuffer.h | 2 +- panda/src/tinydisplay/zgl.h | 7 +- panda/src/wgldisplay/wglGraphicsBuffer.cxx | 4 +- 38 files changed, 1567 insertions(+), 1357 deletions(-) diff --git a/panda/src/display/graphicsStateGuardian.cxx b/panda/src/display/graphicsStateGuardian.cxx index 795579fbc9..00672f6dbc 100644 --- a/panda/src/display/graphicsStateGuardian.cxx +++ b/panda/src/display/graphicsStateGuardian.cxx @@ -548,7 +548,7 @@ get_scene() const { * call Texture::prepare(). */ TextureContext *GraphicsStateGuardian:: -prepare_texture(Texture *, int view) { +prepare_texture(Texture *) { return nullptr; } diff --git a/panda/src/display/graphicsStateGuardian.h b/panda/src/display/graphicsStateGuardian.h index 61797f954e..78869cabd6 100644 --- a/panda/src/display/graphicsStateGuardian.h +++ b/panda/src/display/graphicsStateGuardian.h @@ -289,7 +289,7 @@ PUBLISHED: MAKE_PROPERTY(scene, get_scene, set_scene); public: - virtual TextureContext *prepare_texture(Texture *tex, int view); + virtual TextureContext *prepare_texture(Texture *tex); virtual bool update_texture(TextureContext *tc, bool force); virtual void release_texture(TextureContext *tc); virtual void release_textures(const pvector &contexts); diff --git a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx index 28c8e50281..90bd610455 100644 --- a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx +++ b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx @@ -189,8 +189,8 @@ DXGraphicsStateGuardian9:: * call Texture::prepare(). */ TextureContext *DXGraphicsStateGuardian9:: -prepare_texture(Texture *tex, int view) { - DXTextureContext9 *dtc = new DXTextureContext9(_prepared_objects, tex, view); +prepare_texture(Texture *tex) { + DXTextureContext9 *dtc = new DXTextureContext9(_prepared_objects, tex); if (!get_supports_compressed_texture_format(tex->get_ram_image_compression())) { dxgsg9_cat.error() @@ -206,7 +206,7 @@ prepare_texture(Texture *tex, int view) { * stage. */ void DXGraphicsStateGuardian9:: -apply_texture(int i, TextureContext *tc, const SamplerState &sampler) { +apply_texture(int i, TextureContext *tc, int view, const SamplerState &sampler) { if (tc == nullptr) { // The texture wasn't bound properly or something, so ensure texturing is // disabled and just return. @@ -296,7 +296,7 @@ apply_texture(int i, TextureContext *tc, const SamplerState &sampler) { float lod_bias = sampler.get_lod_bias(); set_sampler_state(i, D3DSAMP_MIPMAPLODBIAS, *(DWORD*)&lod_bias); - _d3d_device->SetTexture(i, dtc->get_d3d_texture()); + _d3d_device->SetTexture(i, dtc->get_d3d_texture(view)); } /** @@ -384,20 +384,10 @@ release_texture(TextureContext *tc) { */ bool DXGraphicsStateGuardian9:: extract_texture_data(Texture *tex) { - bool success = true; - - int num_views = tex->get_num_views(); - for (int view = 0; view < num_views; ++view) { - TextureContext *tc = tex->prepare_now(view, get_prepared_objects(), this); - nassertr(tc != nullptr, false); - DXTextureContext9 *dtc = DCAST(DXTextureContext9, tc); - - if (!dtc->extract_texture_data(*_screen)) { - success = false; - } - } - - return success; + TextureContext *tc = tex->prepare_now(get_prepared_objects(), this); + nassertr(tc != nullptr, false); + DXTextureContext9 *dtc = DCAST(DXTextureContext9, tc); + return dtc->extract_texture_data(*_screen); } /** @@ -1851,7 +1841,7 @@ framebuffer_copy_to_texture(Texture *tex, int view, int z, // must use a render target type texture for StretchRect tex->set_render_to_texture(true); - TextureContext *tc = tex->prepare_now(view, get_prepared_objects(), this); + TextureContext *tc = tex->prepare_now(get_prepared_objects(), this); if (tc == nullptr) { return false; } @@ -1868,10 +1858,11 @@ framebuffer_copy_to_texture(Texture *tex, int view, int z, // for now. return do_framebuffer_copy_to_ram(tex, view, z, dr, rb, true); } - nassertr(dtc->get_d3d_2d_texture() != nullptr, false); + IDirect3DTexture9 *d3d_2d_texture = dtc->get_d3d_2d_texture(view); + nassertr(d3d_2d_texture != nullptr, false); IDirect3DSurface9 *tex_level_0; - hr = dtc->get_d3d_2d_texture()->GetSurfaceLevel(0, &tex_level_0); + hr = d3d_2d_texture->GetSurfaceLevel(0, &tex_level_0); if (FAILED(hr)) { dxgsg9_cat.error() << "GetSurfaceLev failed in copy_texture" << D3DERRORSTRING(hr); return false; @@ -1896,7 +1887,7 @@ framebuffer_copy_to_texture(Texture *tex, int view, int z, << "Unable to re-create texture " << *dtc->get_texture() << endl; return false; } - hr = dtc->get_d3d_2d_texture()->GetSurfaceLevel(0, &tex_level_0); + hr = d3d_2d_texture->GetSurfaceLevel(0, &tex_level_0); if (FAILED(hr)) { dxgsg9_cat.error() << "GetSurfaceLev failed in copy_texture" << D3DERRORSTRING(hr); return false; @@ -3663,8 +3654,8 @@ update_standard_texture_bindings() { // We always reissue every stage in DX, just in case the texcoord index or // texgen mode or some other property has changed. int view = get_current_tex_view_offset() + stage->get_tex_view_offset(); - TextureContext *tc = texture->prepare_now(view, _prepared_objects, this); - apply_texture(si, tc, sampler); + TextureContext *tc = texture->prepare_now(_prepared_objects, this); + apply_texture(si, tc, view, sampler); set_texture_blend_mode(si, stage); int texcoord_dimensions = 2; diff --git a/panda/src/dxgsg9/dxGraphicsStateGuardian9.h b/panda/src/dxgsg9/dxGraphicsStateGuardian9.h index 01fa8cf981..995dbc2442 100644 --- a/panda/src/dxgsg9/dxGraphicsStateGuardian9.h +++ b/panda/src/dxgsg9/dxGraphicsStateGuardian9.h @@ -63,8 +63,8 @@ public: calc_fb_properties(DWORD cformat, DWORD dformat, DWORD multisampletype, DWORD multisamplequality); - virtual TextureContext *prepare_texture(Texture *tex, int view); - void apply_texture(int i, TextureContext *tc, const SamplerState &sampler); + virtual TextureContext *prepare_texture(Texture *tex); + void apply_texture(int i, TextureContext *tc, int view, const SamplerState &sampler); virtual bool update_texture(TextureContext *tc, bool force); bool upload_texture(DXTextureContext9 *dtc, bool force); virtual void release_texture(TextureContext *tc); diff --git a/panda/src/dxgsg9/dxShaderContext9.cxx b/panda/src/dxgsg9/dxShaderContext9.cxx index 53a4b6bac9..a4f3f7e24a 100644 --- a/panda/src/dxgsg9/dxShaderContext9.cxx +++ b/panda/src/dxgsg9/dxShaderContext9.cxx @@ -730,13 +730,13 @@ update_shader_texture_bindings(DXShaderContext9 *prev, GSG *gsg) { continue; } - TextureContext *tc = tex->prepare_now(view, gsg->_prepared_objects, gsg); + TextureContext *tc = tex->prepare_now(gsg->_prepared_objects, gsg); if (tc == nullptr) { continue; } int texunit = cgGetParameterResourceIndex(p); - gsg->apply_texture(texunit, tc, sampler); + gsg->apply_texture(texunit, tc, view, sampler); } } #endif diff --git a/panda/src/dxgsg9/dxTextureContext9.I b/panda/src/dxgsg9/dxTextureContext9.I index 6dbfea34a0..22a9d2443a 100644 --- a/panda/src/dxgsg9/dxTextureContext9.I +++ b/panda/src/dxgsg9/dxTextureContext9.I @@ -24,8 +24,9 @@ has_mipmaps() const { * texture it is. */ INLINE IDirect3DBaseTexture9 *DXTextureContext9:: -get_d3d_texture() const { - return _d3d_texture; +get_d3d_texture(int view) const { + view = (std::max)((std::min)(view, (int)_d3d_textures.size() - 1), 0); + return _d3d_textures[view]; } /** @@ -33,8 +34,8 @@ get_d3d_texture() const { * 1-d or 2-d texture. */ INLINE IDirect3DTexture9 *DXTextureContext9:: -get_d3d_2d_texture() const { - return _d3d_2d_texture; +get_d3d_2d_texture(int view) const { + return (IDirect3DTexture9 *)get_d3d_texture(view); } /** @@ -42,8 +43,8 @@ get_d3d_2d_texture() const { * 3-d texture. */ INLINE IDirect3DVolumeTexture9 *DXTextureContext9:: -get_d3d_volume_texture() const { - return _d3d_volume_texture; +get_d3d_volume_texture(int view) const { + return (IDirect3DVolumeTexture9 *)get_d3d_texture(view); } /** @@ -51,6 +52,6 @@ get_d3d_volume_texture() const { * cube map texture. */ INLINE IDirect3DCubeTexture9 *DXTextureContext9:: -get_d3d_cube_texture() const { - return _d3d_cube_texture; +get_d3d_cube_texture(int view) const { + return (IDirect3DCubeTexture9 *)get_d3d_texture(view); } diff --git a/panda/src/dxgsg9/dxTextureContext9.cxx b/panda/src/dxgsg9/dxTextureContext9.cxx index aedf120669..e8522f4167 100644 --- a/panda/src/dxgsg9/dxTextureContext9.cxx +++ b/panda/src/dxgsg9/dxTextureContext9.cxx @@ -36,18 +36,14 @@ static const DWORD g_LowByteMask = 0x000000FF; * */ DXTextureContext9:: -DXTextureContext9(PreparedGraphicsObjects *pgo, Texture *tex, int view) : - TextureContext(pgo, tex, view) { +DXTextureContext9(PreparedGraphicsObjects *pgo, Texture *tex) : + TextureContext(pgo, tex) { if (dxgsg9_cat.is_spam()) { dxgsg9_cat.spam() << "Creating DX texture [" << tex->get_name() << "], minfilter(" << tex->get_minfilter() << "), magfilter(" << tex->get_magfilter() << "), anisodeg(" << tex->get_anisotropic_degree() << ")\n"; } - _d3d_texture = nullptr; - _d3d_2d_texture = nullptr; - _d3d_volume_texture = nullptr; - _d3d_cube_texture = nullptr; _has_mipmaps = false; _is_render_target = false; _managed = -1; @@ -101,7 +97,7 @@ bool DXTextureContext9:: create_texture(DXScreenData &scrn) { // check if the texture has already been created - if (_d3d_2d_texture || _d3d_cube_texture || _d3d_volume_texture) { + if (!_d3d_textures.empty()) { // texture already created, no need to create return true; } @@ -146,21 +142,22 @@ create_texture(DXScreenData &scrn) { } } - switch (tex->get_texture_type()) { - case Texture::TT_1d_texture: - case Texture::TT_2d_texture: - case Texture::TT_cube_map: - // no compression for render target textures, or very small textures - if (!tex->get_render_to_texture() && - orig_width >= 4 && orig_height >= 4) { - if (texture_wants_compressed){ - compress_texture = true; - } + Texture::TextureType texture_type = tex->get_texture_type(); + switch (texture_type) { + case Texture::TT_1d_texture: + case Texture::TT_2d_texture: + case Texture::TT_cube_map: + // no compression for render target textures, or very small textures + if (!tex->get_render_to_texture() && orig_width >= 4 && orig_height >= 4) { + if (texture_wants_compressed){ + compress_texture = true; } - break; - case Texture::TT_3d_texture: - // compression of 3d textures not supported by all video chips - break; + } + break; + + case Texture::TT_3d_texture: + // compression of 3d textures not supported by all video chips + break; } if (texture_stored_compressed && !compress_texture) { @@ -259,7 +256,7 @@ create_texture(DXScreenData &scrn) { DWORD filter_caps; - switch (tex->get_texture_type()) { + switch (texture_type) { case Texture::TT_1d_texture: case Texture::TT_2d_texture: filter_caps = scrn._d3dcaps.TextureFilterCaps; @@ -353,7 +350,7 @@ create_texture(DXScreenData &scrn) { if (orig_width != target_width || orig_height != target_height || orig_depth != target_depth) { - if (tex->get_texture_type() == Texture::TT_3d_texture) { + if (texture_type == Texture::TT_3d_texture) { dxgsg9_cat.info() << "Reducing size of " << tex->get_name() << " from " << orig_width << "x" << orig_height << "x" << orig_depth @@ -970,17 +967,18 @@ create_texture(DXScreenData &scrn) { << "D3D create_texture ( ) unknown texture format\n"; } - int data_size; - data_size = target_width * target_height * target_depth; + int num_views = tex->get_num_views(); + + size_t data_size = target_width * target_height * target_depth; if (_has_mipmaps) { - data_size = (int) ((PN_stdfloat) data_size * 1.3333333); + data_size += data_size / 3; } - data_size = (int) ((PN_stdfloat) data_size * bytes_per_texel); - if (tex->get_texture_type() == Texture::TT_cube_map) { + data_size *= bytes_per_texel; + if (texture_type == Texture::TT_cube_map) { data_size *= 6; } - update_data_size_bytes(data_size); + update_data_size_bytes((size_t)data_size * (size_t)num_views); int attempts; @@ -991,14 +989,14 @@ create_texture(DXScreenData &scrn) { << " reported available.\n"; dxgsg9_cat.debug() << " size is " << target_width << " w * " << target_height << " h * " - << target_depth << " d"; + << target_depth << " d * " << num_views << " v"; if (_has_mipmaps) { dxgsg9_cat.debug(false) << " * 1.3333333 mipmaps"; } dxgsg9_cat.debug(false) << " * " << bytes_per_texel << " bpt"; - if (tex->get_texture_type() == Texture::TT_cube_map) { + if (texture_type == Texture::TT_cube_map) { dxgsg9_cat.debug(false) << " * 6 faces"; } @@ -1006,45 +1004,55 @@ create_texture(DXScreenData &scrn) { << "\n"; } - attempts = 0; - do - { - switch (tex->get_texture_type()) { - case Texture::TT_1d_texture: - case Texture::TT_2d_texture: - hr = scrn._d3d_device->CreateTexture - (target_width, target_height, mip_level_count, usage, - target_pixel_format, pool, &_d3d_2d_texture, nullptr); - _d3d_texture = _d3d_2d_texture; - break; + for (int view = 0; view < num_views; ++view) { + IDirect3DBaseTexture9 *d3d_texture = nullptr; + IDirect3DTexture9 *d3d_2d_texture; + IDirect3DVolumeTexture9 *d3d_volume_texture; + IDirect3DCubeTexture9 *d3d_cube_texture; - case Texture::TT_3d_texture: - hr = scrn._d3d_device->CreateVolumeTexture - (target_width, target_height, target_depth, mip_level_count, usage, - target_pixel_format, pool, &_d3d_volume_texture, nullptr); - _d3d_texture = _d3d_volume_texture; - break; + attempts = 0; + do { + switch (texture_type) { + case Texture::TT_1d_texture: + case Texture::TT_2d_texture: + hr = scrn._d3d_device->CreateTexture + (target_width, target_height, mip_level_count, usage, + target_pixel_format, pool, &d3d_2d_texture, nullptr); + d3d_texture = d3d_2d_texture; + break; - case Texture::TT_cube_map: - hr = scrn._d3d_device->CreateCubeTexture - (target_width, mip_level_count, usage, - target_pixel_format, pool, &_d3d_cube_texture, nullptr); - _d3d_texture = _d3d_cube_texture; + case Texture::TT_3d_texture: + hr = scrn._d3d_device->CreateVolumeTexture + (target_width, target_height, target_depth, mip_level_count, usage, + target_pixel_format, pool, &d3d_volume_texture, nullptr); + d3d_texture = d3d_volume_texture; + break; - target_height = target_width; - break; + case Texture::TT_cube_map: + hr = scrn._d3d_device->CreateCubeTexture + (target_width, mip_level_count, usage, + target_pixel_format, pool, &d3d_cube_texture, nullptr); + d3d_texture = d3d_cube_texture; + + target_height = target_width; + break; + } + + attempts++; + } + while (scrn._dxgsg9->check_dx_allocation(hr, data_size, attempts)); + + if (FAILED(hr)) { + dxgsg9_cat.error() + << "D3D create_texture failed!" << D3DERRORSTRING(hr); + dxgsg9_cat.error() + << " width = " << target_width << " height = " << target_height + << " target_pixel_format = " << target_pixel_format << "\n"; + + goto error_exit; } - attempts++; - } while (scrn._dxgsg9 -> check_dx_allocation (hr, data_size, attempts)); - - if (FAILED(hr)) { - dxgsg9_cat.error() - << "D3D create_texture failed!" << D3DERRORSTRING(hr); - dxgsg9_cat.error() - << " width = " << target_width << " height = " << target_height << " target_pixel_format = " << target_pixel_format << "\n"; - - goto error_exit; + _d3d_textures.push_back(d3d_texture); } if (DEBUG_TEXTURES && dxgsg9_cat.is_debug()) { @@ -1088,12 +1096,11 @@ create_texture(DXScreenData &scrn) { return true; - error_exit: - - RELEASE(_d3d_texture, dxgsg9, "texture", RELEASE_ONCE); - _d3d_2d_texture = nullptr; - _d3d_volume_texture = nullptr; - _d3d_cube_texture = nullptr; +error_exit: + for (IDirect3DBaseTexture9 *d3d_texture : _d3d_textures) { + RELEASE(d3d_texture, dxgsg9, "texture", RELEASE_ONCE); + } + _d3d_textures.clear(); return false; } @@ -1121,18 +1128,20 @@ create_simple_texture(DXScreenData &scrn) { int data_size = target_width * target_height * 4; + IDirect3DTexture9 *d3d_2d_texture = nullptr; hr = scrn._d3d_device->CreateTexture (target_width, target_height, mip_level_count, usage, - target_pixel_format, pool, &_d3d_2d_texture, nullptr); - _d3d_texture = _d3d_2d_texture; + target_pixel_format, pool, &d3d_2d_texture, nullptr); if (FAILED(hr)) { dxgsg9_cat.error() << "D3D create_simple_texture failed!" << D3DERRORSTRING(hr); dxgsg9_cat.error() - << " width = " << target_width << " height = " << target_height << " target_pixel_format = " << target_pixel_format << "\n"; + << " width = " << target_width << " height = " << target_height + << " target_pixel_format = " << target_pixel_format << "\n"; goto error_exit; } + _d3d_textures.push_back(d3d_2d_texture); if (DEBUG_TEXTURES && dxgsg9_cat.is_debug()) { dxgsg9_cat.debug() @@ -1144,10 +1153,10 @@ create_simple_texture(DXScreenData &scrn) { CPTA_uchar image = get_texture()->get_simple_ram_image(); hr = -1; - // hr = fill_d3d_texture_pixels(scrn); + // hr = fill_d3d_texture_pixels(view, scrn); IDirect3DSurface9 *surface = nullptr; - _d3d_2d_texture->GetSurfaceLevel(0, &surface); + d3d_2d_texture->GetSurfaceLevel(0, &surface); RECT source_size; source_size.left = source_size.top = 0; @@ -1176,11 +1185,11 @@ create_simple_texture(DXScreenData &scrn) { mark_loaded(); return true; - error_exit: - RELEASE(_d3d_texture, dxgsg9, "texture", RELEASE_ONCE); - _d3d_2d_texture = nullptr; - _d3d_volume_texture = nullptr; - _d3d_cube_texture = nullptr; +error_exit: + for (IDirect3DBaseTexture9 *d3d_texture : _d3d_textures) { + RELEASE(d3d_texture, dxgsg9, "texture", RELEASE_ONCE); + } + _d3d_textures.clear(); return false; } @@ -1189,16 +1198,15 @@ create_simple_texture(DXScreenData &scrn) { */ void DXTextureContext9:: delete_texture() { - - if (_d3d_texture == nullptr) { + if (_d3d_textures.empty()) { // don't bother printing the msg below, since we already released it. return; } - RELEASE(_d3d_texture, dxgsg9, "texture", RELEASE_ONCE); - _d3d_2d_texture = nullptr; - _d3d_volume_texture = nullptr; - _d3d_cube_texture = nullptr; + for (IDirect3DBaseTexture9 *d3d_texture : _d3d_textures) { + RELEASE(d3d_texture, dxgsg9, "texture", RELEASE_ONCE); + } + _d3d_textures.clear(); } /** @@ -1219,10 +1227,13 @@ extract_texture_data(DXScreenData &screen) { << "\n"; return state; } - nassertr(IS_VALID_PTR(_d3d_2d_texture), false); + nassertr(!_d3d_textures.empty(), false); + + //FIXME: support for multiview textures + IDirect3DTexture9 *d3d_2d_texture = get_d3d_2d_texture(0); D3DSURFACE_DESC desc; - hr = _d3d_2d_texture->GetLevelDesc(0, &desc); + hr = d3d_2d_texture->GetLevelDesc(0, &desc); if (FAILED(hr)) { dxgsg9_cat.error() << "Texture::GetLevelDesc() failed!" << D3DERRORSTRING(hr); @@ -1299,11 +1310,12 @@ extract_texture_data(DXScreenData &screen) { return state; } - int num_levels = _d3d_2d_texture->GetLevelCount(); + int num_levels = d3d_2d_texture->GetLevelCount(); tex->set_x_size(desc.Width); tex->set_y_size(desc.Height); tex->set_z_size(1); + tex->set_num_views(1); tex->set_component_type(Texture::T_unsigned_byte); tex->set_format(format); tex->clear_ram_image(); @@ -1315,7 +1327,7 @@ extract_texture_data(DXScreenData &screen) { source_surface = 0; destination_surface = 0; - hr = _d3d_2d_texture -> GetSurfaceLevel (0, &source_surface); + hr = d3d_2d_texture->GetSurfaceLevel(0, &source_surface); if (hr == D3D_OK) { D3DPOOL pool; @@ -1389,7 +1401,7 @@ extract_texture_data(DXScreenData &screen) { else { for (int n = 0; n < num_levels; ++n) { D3DLOCKED_RECT rect; - hr = _d3d_2d_texture->LockRect(n, &rect, nullptr, D3DLOCK_READONLY); + hr = d3d_2d_texture->LockRect(n, &rect, nullptr, D3DLOCK_READONLY); if (FAILED(hr)) { dxgsg9_cat.error() << "Texture::LockRect() failed! level = " << n << " " << D3DERRORSTRING(hr); @@ -1428,7 +1440,7 @@ extract_texture_data(DXScreenData &screen) { memcpy(image.p(), rect.pBits, size); } - _d3d_2d_texture->UnlockRect(n); + d3d_2d_texture->UnlockRect(n); if (n == 0) { tex->set_ram_image(image, compression); } else { @@ -1741,62 +1753,49 @@ static UINT calculate_row_byte_length (int width, int num_color_channels, D3DFOR * with texture data. Takes care of all necessary conversions and error * handling. */ -HRESULT DXTextureContext9::fill_d3d_texture_mipmap_pixels(int mip_level, int depth_index, D3DFORMAT source_format) -{ +HRESULT DXTextureContext9:: +fill_d3d_texture_mipmap_pixels(int mip_level, int depth_index, D3DFORMAT source_format) { // This whole function was refactored out of fill_d3d_texture_pixels to make // the code more readable and to avoid code duplication. - IDirect3DSurface9 *mip_surface = nullptr; - bool using_temp_buffer = false; HRESULT hr = E_FAIL; CPTA_uchar image = get_texture()->get_ram_mipmap_image(mip_level); - BYTE *pixels = (BYTE*) image.p(); - DWORD width = (DWORD) get_texture()->get_expected_mipmap_x_size(mip_level); - DWORD height = (DWORD) get_texture()->get_expected_mipmap_y_size(mip_level); + DWORD width = (DWORD)get_texture()->get_expected_mipmap_x_size(mip_level); + DWORD height = (DWORD)get_texture()->get_expected_mipmap_y_size(mip_level); + DWORD num_color_channels = get_texture()->get_num_components(); int component_width = get_texture()->get_component_width(); size_t page_size = get_texture()->get_expected_ram_mipmap_page_size(mip_level); size_t view_size; + size_t view_stride; vector_uchar clear_data; + BYTE *image_pixels; if (page_size > 0) { if (image.is_null()) { // Make an image, filled with the texture's clear color. image = get_texture()->make_ram_mipmap_image(mip_level); nassertr(!image.is_null(), E_FAIL); - pixels = (BYTE *)image.p(); } - view_size = image.size(); - pixels += view_size * get_view(); - pixels += page_size * depth_index; + image_pixels = (BYTE *)image.p(); + view_size = get_texture()->get_ram_mipmap_view_size(mip_level); + view_stride = view_size; + image_pixels += page_size * depth_index; } else { // This is a 0x0 texture, which gets loaded as though it were 1x1. width = 1; height = 1; clear_data = get_texture()->get_clear_data(); - pixels = clear_data.data(); + image_pixels = clear_data.data(); view_size = clear_data.size(); + view_stride = 0; } - - if (get_texture()->get_texture_type() == Texture::TT_cube_map) { - nassertr(IS_VALID_PTR(_d3d_cube_texture), E_FAIL); - hr = _d3d_cube_texture->GetCubeMapSurface((D3DCUBEMAP_FACES)depth_index, mip_level, &mip_surface); - } else { - nassertr(IS_VALID_PTR(_d3d_2d_texture), E_FAIL); - hr = _d3d_2d_texture->GetSurfaceLevel(mip_level, &mip_surface); - } - - if (FAILED(hr)) { - dxgsg9_cat.error() - << "FillDDTextureMipmapPixels failed for " << get_texture()->get_name() - << ", GetSurfaceLevel failed" << D3DERRORSTRING(hr); - return E_FAIL; - } + nassertr(IS_VALID_PTR(image_pixels), E_FAIL); RECT source_size; source_size.left = source_size.top = 0; source_size.right = width; source_size.bottom = height; - UINT source_row_byte_length = calculate_row_byte_length(width, get_texture()->get_num_components(), source_format); + UINT source_row_byte_length = calculate_row_byte_length(width, num_color_channels, source_format); DWORD mip_filter; // need filtering if size changes, (also if bitdepth reduced (need @@ -1807,87 +1806,128 @@ HRESULT DXTextureContext9::fill_d3d_texture_mipmap_pixels(int mip_level, int dep mip_filter |= D3DX_FILTER_SRGB; } - // D3DXLoadSurfaceFromMemory will load black luminance and we want full - // white, so convert to explicit luminance-alpha format - if (_d3d_format == D3DFMT_A8) { - // alloc buffer for explicit D3DFMT_A8L8 - USHORT *temp_buffer = new USHORT[width * height]; + // Preallocate temporary buffer for conversion + BYTE *temp_buffer = nullptr; + if (source_format == D3DFMT_A8 || component_width != 1) { + int num_pixels = width * height; + if (source_format == D3DFMT_A8) { + num_pixels *= 2; + source_format = D3DFMT_A8L8; + source_row_byte_length *= 2; + } else { + num_pixels *= num_color_channels; + } + temp_buffer = new BYTE[num_pixels]; if (!IS_VALID_PTR(temp_buffer)) { dxgsg9_cat.error() - << "FillDDTextureMipmapPixels couldnt alloc mem for temp pixbuf!\n"; - goto exit_FillMipmapSurf; + << "FillDDSurfaceTexturePixels couldnt alloc mem for temp pixbuf!\n"; + return E_FAIL; } - using_temp_buffer = true; - - USHORT *out_pixels = temp_buffer; - BYTE *source_pixels = pixels + component_width - 1; - for (UINT y = 0; y < height; y++) { - for (UINT x = 0; x < width; x++, source_pixels += component_width, out_pixels++) { - // add full white, which is our interpretation of alpha-only (similar - // to default adding full opaque alpha 0xFF to RGB-only textures) - *out_pixels = ((*source_pixels) << 8 ) | 0xFF; - } - } - - source_format = D3DFMT_A8L8; - source_row_byte_length = width * sizeof(USHORT); - pixels = (BYTE*)temp_buffer; - } - else if (component_width != 1) { - // Convert from 16-bit per channel (or larger) format down to 8-bit per - // channel. This throws away precision in the original image, but dx8 - // doesn't support high-precision images anyway. - - int num_components = get_texture()->get_num_components(); - int num_pixels = width * height * num_components; - BYTE *temp_buffer = new BYTE[num_pixels]; - if (!IS_VALID_PTR(temp_buffer)) { - dxgsg9_cat.error() << "FillDDTextureMipmapPixels couldnt alloc mem for temp pixbuf!\n"; - goto exit_FillMipmapSurf; - } - using_temp_buffer = true; - - BYTE *source_pixels = pixels + component_width - 1; - for (int i = 0; i < num_pixels; i++) { - temp_buffer[i] = *source_pixels; - source_pixels += component_width; - } - pixels = (BYTE*)temp_buffer; } // filtering may be done here if texture if targetsize != origsize + int num_views = (int)_d3d_textures.size(); + #ifdef DO_PSTATS - GraphicsStateGuardian::_data_transferred_pcollector.add_level(source_row_byte_length * height); + GraphicsStateGuardian::_data_transferred_pcollector.add_level(source_row_byte_length * height * num_views); #endif - if (source_format == D3DFMT_ATI1 || source_format == D3DFMT_ATI2) { - // These formats are not supported by D3DXLoadSurfaceFromMemory. - D3DLOCKED_RECT rect; - _d3d_2d_texture->LockRect(mip_level, &rect, 0, D3DLOCK_DISCARD); - unsigned char *dest = (unsigned char *)rect.pBits; - memcpy(dest, pixels, view_size); + for (int view = 0; view < num_views; ++view) { + BYTE *pixels = image_pixels; + image_pixels += view_stride; - _d3d_2d_texture->UnlockRect(mip_level); + if (source_format == D3DFMT_ATI1 || source_format == D3DFMT_ATI2) { + // These formats are not supported by D3DXLoadSurfaceFromMemory. + D3DLOCKED_RECT rect; - } else { - hr = D3DXLoadSurfaceFromMemory - (mip_surface, nullptr, nullptr, (LPCVOID)pixels, - source_format, source_row_byte_length, nullptr, - &source_size, mip_filter, (D3DCOLOR)0x0); - if (FAILED(hr)) { - dxgsg9_cat.error() - << "FillDDTextureMipmapPixels failed for " << get_texture()->get_name() - << ", mip_level " << mip_level - << ", D3DXLoadSurfFromMem failed" << D3DERRORSTRING(hr); + if (get_texture()->get_texture_type() == Texture::TT_cube_map) { + IDirect3DCubeTexture9 *d3d_cube_texture = get_d3d_cube_texture(view); + nassertr(IS_VALID_PTR(d3d_cube_texture), E_FAIL); + d3d_cube_texture->LockRect((D3DCUBEMAP_FACES)depth_index, mip_level, &rect, 0, D3DLOCK_DISCARD); + + unsigned char *dest = (unsigned char *)rect.pBits; + memcpy(dest, pixels, view_size); + + d3d_cube_texture->UnlockRect((D3DCUBEMAP_FACES)depth_index, mip_level); + } else { + IDirect3DTexture9 *d3d_2d_texture = get_d3d_2d_texture(view); + nassertr(IS_VALID_PTR(d3d_2d_texture), E_FAIL); + d3d_2d_texture->LockRect(mip_level, &rect, 0, D3DLOCK_DISCARD); + + unsigned char *dest = (unsigned char *)rect.pBits; + memcpy(dest, pixels, view_size); + + d3d_2d_texture->UnlockRect(mip_level); + } + } + else { + if (_d3d_format == D3DFMT_A8 && source_format == D3DFMT_A8L8) { + USHORT *out_pixels = (USHORT *)temp_buffer; + BYTE *source_pixels = pixels + component_width - 1; + for (UINT y = 0; y < height; y++) { + for (UINT x = 0; x < width; x++, source_pixels += component_width, out_pixels++) { + // add full white, which is our interpretation of alpha-only + // (similar to default adding full opaque alpha 0xFF to RGB-only + // textures) + *out_pixels = ((*source_pixels) << 8) | 0xFF; + } + } + pixels = (BYTE *)temp_buffer; + } + else if (component_width != 1) { + // Convert from 16-bit per channel (or larger) format down to 8-bit per + // channel. This throws away precision in the original image, but dx8 + // doesn't support high-precision images anyway. + + int num_components = get_texture()->get_num_components(); + int num_pixels = width * height * num_components; + + BYTE *source_pixels = pixels + component_width - 1; + for (int i = 0; i < num_pixels; i++) { + temp_buffer[i] = *source_pixels; + source_pixels += component_width; + } + pixels = (BYTE *)temp_buffer; + } + + IDirect3DSurface9 *mip_surface = nullptr; + if (get_texture()->get_texture_type() == Texture::TT_cube_map) { + IDirect3DCubeTexture9 *d3d_cube_texture = get_d3d_cube_texture(view); + nassertr(IS_VALID_PTR(d3d_cube_texture), E_FAIL); + hr = d3d_cube_texture->GetCubeMapSurface((D3DCUBEMAP_FACES)depth_index, mip_level, &mip_surface); + } else { + IDirect3DTexture9 *d3d_2d_texture = get_d3d_2d_texture(view); + nassertr(IS_VALID_PTR(d3d_2d_texture), E_FAIL); + hr = d3d_2d_texture->GetSurfaceLevel(mip_level, &mip_surface); + } + + if (FAILED(hr)) { + dxgsg9_cat.error() + << "FillDDTextureMipmapPixels failed for " << get_texture()->get_name() + << ", view " << view << ", mip_level " << mip_level + << ", GetSurfaceLevel failed" << D3DERRORSTRING(hr); + return E_FAIL; + } + + hr = D3DXLoadSurfaceFromMemory + (mip_surface, nullptr, nullptr, (LPCVOID)pixels, + source_format, source_row_byte_length, nullptr, + &source_size, mip_filter, (D3DCOLOR)0x0); + if (FAILED(hr)) { + dxgsg9_cat.error() + << "FillDDTextureMipmapPixels failed for " << get_texture()->get_name() + << ", view " << view << ", mip_level " << mip_level + << ", D3DXLoadSurfFromMem failed" << D3DERRORSTRING(hr); + } + + RELEASE(mip_surface, dxgsg9, "FillDDTextureMipmapPixels MipSurface texture ptr", RELEASE_ONCE); } } -exit_FillMipmapSurf: - if (using_temp_buffer) { - SAFE_DELETE_ARRAY(pixels); + if (temp_buffer != nullptr) { + delete[] temp_buffer; } - RELEASE(mip_surface, dxgsg9, "FillDDTextureMipmapPixels MipSurface texture ptr", RELEASE_ONCE); return hr; } @@ -1899,7 +1939,8 @@ fill_d3d_texture_pixels(DXScreenData &scrn, bool compress_texture) { IDirect3DDevice9 *device = scrn._d3d_device; Texture *tex = get_texture(); nassertr(IS_VALID_PTR(tex), E_FAIL); - if (tex->get_texture_type() == Texture::TT_3d_texture) { + Texture::TextureType texture_type = tex->get_texture_type(); + if (texture_type == Texture::TT_3d_texture) { return fill_d3d_volume_texture_pixels(scrn); } @@ -1924,14 +1965,15 @@ fill_d3d_texture_pixels(DXScreenData &scrn, bool compress_texture) { if (image.is_null()) { // The texture doesn't have an image to load. That's ok; it might be a // texture we've rendered to by frame buffer operations or something. - if (tex->get_render_to_texture()) { + if (tex->get_render_to_texture() && texture_type != Texture::TT_cube_map) { HRESULT result; - if (_d3d_2d_texture) { + for (int view = 0; view < (int)_d3d_textures.size(); ++view) { + IDirect3DTexture9 *d3d_2d_texture = get_d3d_2d_texture(view); + // clear render to texture IDirect3DSurface9 *surface; - - result = _d3d_2d_texture -> GetSurfaceLevel (0, &surface); + result = d3d_2d_texture->GetSurfaceLevel(0, &surface); if (result == D3D_OK) { D3DSURFACE_DESC surface_description; @@ -1981,7 +2023,6 @@ fill_d3d_texture_pixels(DXScreenData &scrn, bool compress_texture) { } } //nassertr(IS_VALID_PTR((BYTE*)image.p()), E_FAIL); - nassertr(IS_VALID_PTR(_d3d_texture), E_FAIL); PStatTimer timer(GraphicsStateGuardian::_load_texture_pcollector); @@ -2017,6 +2058,7 @@ fill_d3d_texture_pixels(DXScreenData &scrn, bool compress_texture) { break; } + int num_views = (int)_d3d_textures.size(); for (unsigned int di = 0; di < orig_depth; di++) { // fill top level mipmap @@ -2028,7 +2070,7 @@ fill_d3d_texture_pixels(DXScreenData &scrn, bool compress_texture) { if (_has_mipmaps) { // if we have pre-calculated mipmap levels, use them, otherwise generate // on the fly - int miplevel_count = _d3d_texture->GetLevelCount(); + int miplevel_count = _d3d_textures[0]->GetLevelCount(); if (miplevel_count <= tex->get_num_loadable_ram_mipmap_images()) { if (dxgsg9_cat.is_debug()) { dxgsg9_cat.debug() @@ -2041,45 +2083,51 @@ fill_d3d_texture_pixels(DXScreenData &scrn, bool compress_texture) { return hr; // error message was already output in fill_d3d_texture_mipmap_pixels } } + + return D3D_OK; } else { // mipmaps need to be generated, either use autogen or d3dx functions + for (int view = 0; view < num_views; ++view) { + IDirect3DBaseTexture9 *d3d_texture = get_d3d_texture(view); + nassertr(IS_VALID_PTR(d3d_texture), E_FAIL); - if (_managed == false && scrn._supports_automatic_mipmap_generation) { - if (false) - { - // hr = _d3d_texture -> SetAutoGenFilterType - // (D3DTEXF_PYRAMIDALQUAD); hr = _d3d_texture -> - // SetAutoGenFilterType (D3DTEXF_GAUSSIANQUAD); hr = _d3d_texture - // -> SetAutoGenFilterType (D3DTEXF_ANISOTROPIC); - hr = _d3d_texture -> SetAutoGenFilterType (D3DTEXF_LINEAR); - if (FAILED(hr)) { - dxgsg9_cat.error() << "SetAutoGenFilterType failed " << D3DERRORSTRING(hr); + if (_managed == false && scrn._supports_automatic_mipmap_generation) { + if (false) { + IDirect3DBaseTexture9 *d3d_texture = get_d3d_texture(view); + nassertr(IS_VALID_PTR(d3d_texture), E_FAIL); + //hr = d3d_texture->SetAutoGenFilterType(D3DTEXF_PYRAMIDALQUAD); + //hr = d3d_texture->SetAutoGenFilterType(D3DTEXF_GAUSSIANQUAD); + //hr = d3d_texture->SetAutoGenFilterType(D3DTEXF_ANISOTROPIC); + hr = d3d_texture->SetAutoGenFilterType(D3DTEXF_LINEAR); + if (FAILED(hr)) { + dxgsg9_cat.error() << "SetAutoGenFilterType failed " << D3DERRORSTRING(hr); + } + + d3d_texture->GenerateMipSubLevels(); + } + } + else { + DWORD mip_filter_flags; + if (!dx_use_triangle_mipgen_filter) { + mip_filter_flags = D3DX_FILTER_BOX; + } else { + mip_filter_flags = D3DX_FILTER_TRIANGLE; } - _d3d_texture -> GenerateMipSubLevels ( ); - } - } - else { - DWORD mip_filter_flags; - if (!dx_use_triangle_mipgen_filter) { - mip_filter_flags = D3DX_FILTER_BOX; - } else { - mip_filter_flags = D3DX_FILTER_TRIANGLE; - } + if (Texture::is_srgb(tex->get_format())) { + mip_filter_flags |= D3DX_FILTER_SRGB; + } - if (Texture::is_srgb(tex->get_format())) { - mip_filter_flags |= D3DX_FILTER_SRGB; - } + // mip_filter_flags |= D3DX_FILTER_DITHER; + hr = D3DXFilterTexture(d3d_texture, nullptr, 0, mip_filter_flags); - // mip_filter_flags |= D3DX_FILTER_DITHER; - hr = D3DXFilterTexture(_d3d_texture, nullptr, 0, - mip_filter_flags); - - if (FAILED(hr)) { - dxgsg9_cat.error() - << "FillDDSurfaceTexturePixels failed for " << tex->get_name() - << ", D3DXFilterTex failed" << D3DERRORSTRING(hr); + if (FAILED(hr)) { + dxgsg9_cat.error() + << "FillDDSurfaceTexturePixels failed for " << tex->get_name() + << " view " << view << ", D3DXFilterTex failed" + << D3DERRORSTRING(hr); + } } } } @@ -2126,159 +2174,167 @@ fill_d3d_volume_texture_pixels(DXScreenData &scrn) { PStatTimer timer(GraphicsStateGuardian::_load_texture_pcollector); - nassertr(IS_VALID_PTR(_d3d_texture), E_FAIL); + nassertr(!_d3d_textures.empty(), E_FAIL); nassertr(tex->get_texture_type() == Texture::TT_3d_texture, E_FAIL); - DWORD orig_width = (DWORD) tex->get_x_size(); - DWORD orig_height = (DWORD) tex->get_y_size(); - DWORD orig_depth = (DWORD) tex->get_z_size(); + DWORD orig_width = (DWORD)tex->get_x_size(); + DWORD orig_height = (DWORD)tex->get_y_size(); + DWORD orig_depth = (DWORD)tex->get_z_size(); DWORD num_color_channels = tex->get_num_components(); - D3DFORMAT source_format = _d3d_format; - BYTE *image_pixels = (BYTE*)image.p(); int component_width = tex->get_component_width(); - nassertr(IS_VALID_PTR(image_pixels), E_FAIL); - - size_t view_size = tex->get_ram_mipmap_view_size(0); - image_pixels += view_size * get_view(); - - IDirect3DVolume9 *mip_level_0 = nullptr; - bool using_temp_buffer = false; - BYTE *pixels = image_pixels; - - nassertr(IS_VALID_PTR(_d3d_volume_texture), E_FAIL); - hr = _d3d_volume_texture->GetVolumeLevel(0, &mip_level_0); - - if (FAILED(hr)) { - dxgsg9_cat.error() - << "FillDDSurfaceTexturePixels failed for " << tex->get_name() - << ", GetSurfaceLevel failed" << D3DERRORSTRING(hr); - return E_FAIL; - } - - D3DBOX source_size; - source_size.Left = source_size.Top = source_size.Front = 0; - source_size.Right = orig_width; - source_size.Bottom = orig_height; - source_size.Back = orig_depth; - + D3DFORMAT source_format = _d3d_format; UINT source_row_byte_length = orig_width * num_color_channels; UINT source_page_byte_length = orig_height * source_row_byte_length; - DWORD level_0_filter, mip_filter_flags; - using_temp_buffer = false; - - // need filtering if size changes, (also if bitdepth reduced (need - // dithering)??) - level_0_filter = D3DX_FILTER_LINEAR ; //| D3DX_FILTER_DITHER; //dithering looks ugly on i810 for 4444 textures - - if (Texture::is_srgb(tex->get_format())) { - level_0_filter |= D3DX_FILTER_SRGB; - } - - // D3DXLoadSurfaceFromMemory will load black luminance and we want full - // white, so convert to explicit luminance-alpha format - if (_d3d_format == D3DFMT_A8) { - // alloc buffer for explicit D3DFMT_A8L8 - USHORT *temp_buffer = new USHORT[orig_width * orig_height * orig_depth]; + // Preallocate temporary buffer for conversion + BYTE *temp_buffer = nullptr; + if (_d3d_format == D3DFMT_A8 || component_width != 1) { + int num_pixels = orig_width * orig_height * orig_depth; + if (_d3d_format == D3DFMT_A8) { + num_pixels *= 2; + source_format = D3DFMT_A8L8; + source_row_byte_length *= 2; + source_page_byte_length *= 2; + } else { + num_pixels *= num_color_channels; + } + temp_buffer = new BYTE[num_pixels]; if (!IS_VALID_PTR(temp_buffer)) { dxgsg9_cat.error() << "FillDDSurfaceTexturePixels couldnt alloc mem for temp pixbuf!\n"; - goto exit_FillDDSurf; + return E_FAIL; } - using_temp_buffer = true; - - USHORT *out_pixels = temp_buffer; - BYTE *source_pixels = pixels + component_width - 1; - for (UINT z = 0; z < orig_depth; z++) { - for (UINT y = 0; y < orig_height; y++) { - for (UINT x = 0; - x < orig_width; - x++, source_pixels += component_width, out_pixels++) { - // add full white, which is our interpretation of alpha-only - // (similar to default adding full opaque alpha 0xFF to RGB-only - // textures) - *out_pixels = ((*source_pixels) << 8 ) | 0xFF; - } - } - } - - source_format = D3DFMT_A8L8; - source_row_byte_length = orig_width * sizeof(USHORT); - source_page_byte_length = orig_height * source_row_byte_length; - pixels = (BYTE*)temp_buffer; - - } else if (component_width != 1) { - // Convert from 16-bit per channel (or larger) format down to 8-bit per - // channel. This throws away precision in the original image, but dx8 - // doesn't support high-precision images anyway. - - int num_components = tex->get_num_components(); - int num_pixels = orig_width * orig_height * orig_depth * num_components; - BYTE *temp_buffer = new BYTE[num_pixels]; - if (!IS_VALID_PTR(temp_buffer)) { - dxgsg9_cat.error() << "FillDDSurfaceTexturePixels couldnt alloc mem for temp pixbuf!\n"; - goto exit_FillDDSurf; - } - using_temp_buffer = true; - - BYTE *source_pixels = pixels + component_width - 1; - for (int i = 0; i < num_pixels; i++) { - temp_buffer[i] = *source_pixels; - source_pixels += component_width; - } - pixels = (BYTE*)temp_buffer; } + BYTE *image_pixels = (BYTE *)image.p(); + nassertr(IS_VALID_PTR(image_pixels), E_FAIL); + + size_t view_size = tex->get_ram_mipmap_view_size(0); + int num_views = (int)_d3d_textures.size(); - // filtering may be done here if texture if targetsize != origsize #ifdef DO_PSTATS - GraphicsStateGuardian::_data_transferred_pcollector.add_level(source_page_byte_length * orig_depth); + GraphicsStateGuardian::_data_transferred_pcollector.add_level(source_page_byte_length * orig_depth * num_views); #endif - hr = D3DXLoadVolumeFromMemory - (mip_level_0, nullptr, nullptr, (LPCVOID)pixels, - source_format, source_row_byte_length, source_page_byte_length, - nullptr, - &source_size, level_0_filter, (D3DCOLOR)0x0); - if (FAILED(hr)) { - dxgsg9_cat.error() - << "FillDDSurfaceTexturePixels failed for " << tex->get_name() - << ", D3DXLoadVolumeFromMem failed" << D3DERRORSTRING(hr); - goto exit_FillDDSurf; - } - if (_has_mipmaps) { - if (!dx_use_triangle_mipgen_filter) { - mip_filter_flags = D3DX_FILTER_BOX; - } else { - mip_filter_flags = D3DX_FILTER_TRIANGLE; - } + bool success = true; - if (Texture::is_srgb(tex->get_format())) { - mip_filter_flags |= D3DX_FILTER_SRGB; - } + for (int view = 0; view < num_views; ++view) { + IDirect3DVolumeTexture9 *d3d_volume_texture = get_d3d_volume_texture(view); + nassertr(IS_VALID_PTR(d3d_volume_texture), E_FAIL); - // mip_filter_flags| = D3DX_FILTER_DITHER; + IDirect3DVolume9 *mip_level_0 = nullptr; + BYTE *pixels = image_pixels; + image_pixels += view_size; - hr = D3DXFilterTexture(_d3d_texture, nullptr, 0, - mip_filter_flags); + hr = d3d_volume_texture->GetVolumeLevel(0, &mip_level_0); if (FAILED(hr)) { dxgsg9_cat.error() << "FillDDSurfaceTexturePixels failed for " << tex->get_name() - << ", D3DXFilterTex failed" << D3DERRORSTRING(hr); - goto exit_FillDDSurf; + << ", GetSurfaceLevel failed" << D3DERRORSTRING(hr); + success = false; + continue; } + + D3DBOX source_size; + source_size.Left = source_size.Top = source_size.Front = 0; + source_size.Right = orig_width; + source_size.Bottom = orig_height; + source_size.Back = orig_depth; + + DWORD level_0_filter, mip_filter_flags; + + // need filtering if size changes, (also if bitdepth reduced (need + // dithering)??) + level_0_filter = D3DX_FILTER_LINEAR ; //| D3DX_FILTER_DITHER; //dithering looks ugly on i810 for 4444 textures + + if (Texture::is_srgb(tex->get_format())) { + level_0_filter |= D3DX_FILTER_SRGB; + } + + // D3DXLoadSurfaceFromMemory will load black luminance and we want full + // white, so convert to explicit luminance-alpha format + if (_d3d_format == D3DFMT_A8 && source_format == D3DFMT_A8L8) { + USHORT *out_pixels = (USHORT *)temp_buffer; + BYTE *source_pixels = pixels + component_width - 1; + for (UINT z = 0; z < orig_depth; z++) { + for (UINT y = 0; y < orig_height; y++) { + for (UINT x = 0; + x < orig_width; + x++, source_pixels += component_width, out_pixels++) { + // add full white, which is our interpretation of alpha-only + // (similar to default adding full opaque alpha 0xFF to RGB-only + // textures) + *out_pixels = ((*source_pixels) << 8) | 0xFF; + } + } + } + + pixels = (BYTE *)temp_buffer; + } + else if (component_width != 1) { + // Convert from 16-bit per channel (or larger) format down to 8-bit per + // channel. This throws away precision in the original image, but dx8 + // doesn't support high-precision images anyway. + + int num_components = tex->get_num_components(); + int num_pixels = orig_width * orig_height * orig_depth * num_components; + + BYTE *source_pixels = pixels + component_width - 1; + for (int i = 0; i < num_pixels; i++) { + temp_buffer[i] = *source_pixels; + source_pixels += component_width; + } + pixels = (BYTE *)temp_buffer; + } + + // filtering may be done here if texture if targetsize != origsize + hr = D3DXLoadVolumeFromMemory + (mip_level_0, nullptr, nullptr, (LPCVOID)pixels, + source_format, source_row_byte_length, source_page_byte_length, + nullptr, + &source_size, level_0_filter, (D3DCOLOR)0x0); + if (FAILED(hr)) { + dxgsg9_cat.error() + << "FillDDSurfaceTexturePixels failed for " << tex->get_name() + << " view " << view << ", D3DXLoadVolumeFromMem failed" << D3DERRORSTRING(hr); + success = false; + continue; + } + + if (_has_mipmaps) { + if (!dx_use_triangle_mipgen_filter) { + mip_filter_flags = D3DX_FILTER_BOX; + } else { + mip_filter_flags = D3DX_FILTER_TRIANGLE; + } + + if (Texture::is_srgb(tex->get_format())) { + mip_filter_flags |= D3DX_FILTER_SRGB; + } + + // mip_filter_flags| = D3DX_FILTER_DITHER; + + hr = D3DXFilterTexture(d3d_volume_texture, nullptr, 0, mip_filter_flags); + if (FAILED(hr)) { + dxgsg9_cat.error() + << "FillDDSurfaceTexturePixels failed for " << tex->get_name() + << " view " << view << ", D3DXFilterTex failed" << D3DERRORSTRING(hr); + success = false; + continue; + } + } + + RELEASE(mip_level_0, dxgsg9, "FillDDSurf MipLev0 texture ptr", RELEASE_ONCE); } - exit_FillDDSurf: - if (using_temp_buffer) { - SAFE_DELETE_ARRAY(pixels); + if (temp_buffer != nullptr) { + delete[] temp_buffer; } - RELEASE(mip_level_0, dxgsg9, "FillDDSurf MipLev0 texture ptr", RELEASE_ONCE); - return hr; + + return success ? D3D_OK : E_FAIL; } - /** * Returns the largest power of 2 less than or equal to value. */ diff --git a/panda/src/dxgsg9/dxTextureContext9.h b/panda/src/dxgsg9/dxTextureContext9.h index 53558d39f0..a8cd2db0bb 100644 --- a/panda/src/dxgsg9/dxTextureContext9.h +++ b/panda/src/dxgsg9/dxTextureContext9.h @@ -17,13 +17,14 @@ #include "dxgsg9base.h" #include "texture.h" #include "textureContext.h" +#include "small_vector.h" /** * */ class EXPCL_PANDADX DXTextureContext9 : public TextureContext { public: - DXTextureContext9(PreparedGraphicsObjects *pgo, Texture *tex, int view); + DXTextureContext9(PreparedGraphicsObjects *pgo, Texture *tex); virtual ~DXTextureContext9(); virtual void evict_lru(); @@ -34,10 +35,10 @@ public: bool extract_texture_data(DXScreenData &scrn); INLINE bool has_mipmaps() const; - INLINE IDirect3DBaseTexture9 *get_d3d_texture() const; - INLINE IDirect3DTexture9 *get_d3d_2d_texture() const; - INLINE IDirect3DVolumeTexture9 *get_d3d_volume_texture() const; - INLINE IDirect3DCubeTexture9 *get_d3d_cube_texture() const; + INLINE IDirect3DBaseTexture9 *get_d3d_texture(int view) const; + INLINE IDirect3DTexture9 *get_d3d_2d_texture(int view) const; + INLINE IDirect3DVolumeTexture9 *get_d3d_volume_texture(int view) const; + INLINE IDirect3DCubeTexture9 *get_d3d_cube_texture(int view) const; static HRESULT d3d_surface_to_texture(RECT &source_rect, IDirect3DSurface9 *d3d_surface, @@ -54,10 +55,10 @@ private: private: D3DFORMAT _d3d_format; // the 'D3DFORMAT' the Panda TextureBuffer fmt corresponds to - IDirect3DBaseTexture9 *_d3d_texture; - IDirect3DTexture9 *_d3d_2d_texture; - IDirect3DVolumeTexture9 *_d3d_volume_texture; - IDirect3DCubeTexture9 *_d3d_cube_texture; + small_vector _d3d_textures; + //IDirect3DTexture9 *_d3d_2d_texture; + //IDirect3DVolumeTexture9 *_d3d_volume_texture; + //IDirect3DCubeTexture9 *_d3d_cube_texture; int _managed; diff --git a/panda/src/dxgsg9/wdxGraphicsBuffer9.cxx b/panda/src/dxgsg9/wdxGraphicsBuffer9.cxx index 86a8c9ee41..c09916fded 100644 --- a/panda/src/dxgsg9/wdxGraphicsBuffer9.cxx +++ b/panda/src/dxgsg9/wdxGraphicsBuffer9.cxx @@ -364,7 +364,7 @@ rebuild_bitplanes() { // color_tex->set_format(Texture::F_rgba); color_ctx = DCAST(DXTextureContext9, - color_tex->prepare_now(0, _gsg->get_prepared_objects(), _gsg)); + color_tex->prepare_now(_gsg->get_prepared_objects(), _gsg)); if (color_ctx) { if (!color_ctx->create_texture(*_dxgsg->_screen)) { @@ -373,7 +373,7 @@ rebuild_bitplanes() { return false; } if (color_tex->get_texture_type() == Texture::TT_2d_texture) { - color_d3d_tex = color_ctx->_d3d_2d_texture; + color_d3d_tex = color_ctx->get_d3d_2d_texture(0); nassertr(color_d3d_tex != 0, false); hr = color_d3d_tex -> GetSurfaceLevel(0, &color_surf); if (!SUCCEEDED(hr)) { @@ -381,7 +381,7 @@ rebuild_bitplanes() { } } if (color_tex->get_texture_type() == Texture::TT_cube_map) { - color_cube = color_ctx->_d3d_cube_texture; + color_cube = color_ctx->get_d3d_cube_texture(0); nassertr(color_cube != 0, false); if (_cube_map_index >= 0 && _cube_map_index < 6) { @@ -443,7 +443,7 @@ rebuild_bitplanes() { depth_tex->set_format(Texture::F_depth_stencil); depth_ctx = DCAST(DXTextureContext9, - depth_tex->prepare_now(0, _gsg->get_prepared_objects(), _gsg)); + depth_tex->prepare_now(_gsg->get_prepared_objects(), _gsg)); if (depth_ctx) { if (!depth_ctx->create_texture(*_dxgsg->_screen)) { dxgsg9_cat.error() @@ -451,7 +451,7 @@ rebuild_bitplanes() { return false; } if (depth_tex->get_texture_type() == Texture::TT_2d_texture) { - depth_d3d_tex = depth_ctx->_d3d_2d_texture; + depth_d3d_tex = depth_ctx->get_d3d_2d_texture(0); nassertr(depth_d3d_tex != 0, false); hr = depth_d3d_tex -> GetSurfaceLevel(0, &depth_surf); if (!SUCCEEDED(hr)) { @@ -459,7 +459,7 @@ rebuild_bitplanes() { } } if (depth_tex->get_texture_type() == Texture::TT_cube_map) { - depth_cube = depth_ctx->_d3d_cube_texture; + depth_cube = depth_ctx->get_d3d_cube_texture(0); nassertr(depth_cube != 0, false); hr = depth_cube -> GetCubeMapSurface ((D3DCUBEMAP_FACES) _cube_map_index, 0, &depth_surf); if (!SUCCEEDED(hr)) { @@ -518,7 +518,7 @@ rebuild_bitplanes() { IDirect3DSurface9 *color_surf = 0; IDirect3DCubeTexture9 *color_cube = 0; - color_ctx = DCAST(DXTextureContext9, tex->prepare_now(0, _gsg->get_prepared_objects(), _gsg)); + color_ctx = DCAST(DXTextureContext9, tex->prepare_now(_gsg->get_prepared_objects(), _gsg)); if (color_ctx) { if (!color_ctx->create_texture(*_dxgsg->_screen)) { dxgsg9_cat.error() @@ -526,7 +526,7 @@ rebuild_bitplanes() { return false; } if (tex->get_texture_type() == Texture::TT_2d_texture) { - color_d3d_tex = color_ctx->_d3d_2d_texture; + color_d3d_tex = color_ctx->get_d3d_2d_texture(0); nassertr(color_d3d_tex != 0, false); hr = color_d3d_tex -> GetSurfaceLevel(0, &color_surf); @@ -613,8 +613,8 @@ select_target_tex_page(int page) { if (color_tex) { color_ctx = DCAST(DXTextureContext9, - color_tex->prepare_now(0, _gsg->get_prepared_objects(), _gsg)); - color_cube = color_ctx->_d3d_cube_texture; + color_tex->prepare_now(_gsg->get_prepared_objects(), _gsg)); + color_cube = color_ctx->get_d3d_cube_texture(0); if (color_cube && _cube_map_index >= 0 && _cube_map_index < 6) { hr = color_cube -> GetCubeMapSurface ((D3DCUBEMAP_FACES) _cube_map_index, 0, &color_surf); if (!SUCCEEDED(hr)) { @@ -657,7 +657,7 @@ select_target_tex_page(int page) { IDirect3DSurface9 *color_surf = 0; IDirect3DCubeTexture9 *color_cube = 0; - color_ctx = DCAST(DXTextureContext9, tex->prepare_now(0, _gsg->get_prepared_objects(), _gsg)); + color_ctx = DCAST(DXTextureContext9, tex->prepare_now(_gsg->get_prepared_objects(), _gsg)); if (color_ctx) { if (tex->get_texture_type() == Texture::TT_cube_map) { @@ -665,7 +665,7 @@ select_target_tex_page(int page) { printf ("CUBEMAP i = %d, RenderTexturePlane = %d, _cube_map_index %d \n", i, plane, _cube_map_index); } - color_cube = color_ctx->_d3d_cube_texture; + color_cube = color_ctx->get_d3d_cube_texture(0); if (color_cube && _cube_map_index >= 0 && _cube_map_index < 6) { hr = color_cube -> GetCubeMapSurface ((D3DCUBEMAP_FACES) _cube_map_index, 0, &color_surf); if (!SUCCEEDED(hr)) { diff --git a/panda/src/gles2gsg/gles2gsg.h b/panda/src/gles2gsg/gles2gsg.h index db422f2163..967f341703 100644 --- a/panda/src/gles2gsg/gles2gsg.h +++ b/panda/src/gles2gsg/gles2gsg.h @@ -151,6 +151,8 @@ typedef char GLchar; #define GL_COLOR 0x1800 #define GL_DEPTH 0x1801 #define GL_STENCIL 0x1802 +#define GL_GREEN 0x1904 +#define GL_BLUE 0x1905 #define GL_RGB10_A2 0x8059 #define GL_TEXTURE_WRAP_R 0x8072 #define GL_TEXTURE_MIN_LOD 0x813A @@ -203,6 +205,7 @@ typedef char GLchar; #define GL_FLOAT_MAT4x3 0x8B6A #define GL_TEXTURE_2D_ARRAY 0x8C1A #define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D +#define GL_TEXTURE_BUFFER 0x8C2A #define GL_R11F_G11F_B10F 0x8C3A #define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B #define GL_RGB9_E5 0x8C3D @@ -228,6 +231,7 @@ typedef char GLchar; #define GL_RGB_INTEGER 0x8D98 #define GL_RGBA_INTEGER 0x8D99 #define GL_SAMPLER_2D_ARRAY 0x8DC1 +#define GL_SAMPLER_BUFFER 0x8DC2 #define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4 #define GL_SAMPLER_CUBE_SHADOW 0x8DC5 #define GL_UNSIGNED_INT_VEC2 0x8DC6 @@ -237,24 +241,37 @@ typedef char GLchar; #define GL_INT_SAMPLER_3D 0x8DCB #define GL_INT_SAMPLER_CUBE 0x8DCC #define GL_INT_SAMPLER_2D_ARRAY 0x8DCF +#define GL_INT_SAMPLER_BUFFER 0x8DD0 #define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2 #define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3 #define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4 #define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7 +#define GL_UNSIGNED_INT_SAMPLER_BUFFER 0x8DD8 #define GL_MAX_IMAGE_UNITS 0x8F38 #define GL_TEXTURE_CUBE_MAP_ARRAY 0x9009 +#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY 0x900A +#define GL_SAMPLER_CUBE_MAP_ARRAY 0x900C +#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW 0x900D +#define GL_INT_SAMPLER_CUBE_MAP_ARRAY 0x900E +#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY 0x900F #define GL_IMAGE_2D 0x904D #define GL_IMAGE_3D 0x904E #define GL_IMAGE_CUBE 0x9050 +#define GL_IMAGE_BUFFER 0x9051 #define GL_IMAGE_2D_ARRAY 0x9053 +#define GL_IMAGE_CUBE_MAP_ARRAY 0x9054 #define GL_INT_IMAGE_2D 0x9058 #define GL_INT_IMAGE_3D 0x9059 #define GL_INT_IMAGE_CUBE 0x905B +#define GL_INT_IMAGE_BUFFER 0x905C #define GL_INT_IMAGE_2D_ARRAY 0x905E +#define GL_INT_IMAGE_CUBE_MAP_ARRAY 0x905F #define GL_UNSIGNED_INT_IMAGE_2D 0x9063 #define GL_UNSIGNED_INT_IMAGE_3D 0x9064 #define GL_UNSIGNED_INT_IMAGE_CUBE 0x9066 +#define GL_UNSIGNED_INT_IMAGE_BUFFER 0x9067 #define GL_UNSIGNED_INT_IMAGE_2D_ARRAY 0x9069 +#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY 0x906A #define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117 #define GL_UNSIGNALED 0x9118 #define GL_SIGNALED 0x9119 diff --git a/panda/src/glstuff/glCgShaderContext_src.cxx b/panda/src/glstuff/glCgShaderContext_src.cxx index b4d38ff8e9..edf23b0658 100644 --- a/panda/src/glstuff/glCgShaderContext_src.cxx +++ b/panda/src/glstuff/glCgShaderContext_src.cxx @@ -1054,26 +1054,38 @@ disable_shader_texture_bindings() { return; } - for (int i = 0; i < (int)_shader->_tex_spec.size(); ++i) { - CGparameter p = _cg_parameter_map[_shader->_tex_spec[i]._id._seqno]; - if (p == 0) continue; + if (_glgsg->_supports_dsa) { + // The DSA extension has a single call for unbinding all targets for a + // given texture unit. + for (int i = 0; i < (int)_shader->_tex_spec.size(); ++i) { + CGparameter p = _cg_parameter_map[_shader->_tex_spec[i]._id._seqno]; + if (p == 0) continue; - int texunit = cgGetParameterResourceIndex(p); - _glgsg->set_active_texture_stage(texunit); + int texunit = cgGetParameterResourceIndex(p); + _glgsg->_glBindTextureUnit(texunit, 0); + } + } else { + for (int i = 0; i < (int)_shader->_tex_spec.size(); ++i) { + CGparameter p = _cg_parameter_map[_shader->_tex_spec[i]._id._seqno]; + if (p == 0) continue; - glBindTexture(GL_TEXTURE_1D, 0); - glBindTexture(GL_TEXTURE_2D, 0); - if (_glgsg->_supports_3d_texture) { - glBindTexture(GL_TEXTURE_3D, 0); + int texunit = cgGetParameterResourceIndex(p); + _glgsg->set_active_texture_stage(texunit); + + glBindTexture(GL_TEXTURE_1D, 0); + glBindTexture(GL_TEXTURE_2D, 0); + if (_glgsg->_supports_3d_texture) { + glBindTexture(GL_TEXTURE_3D, 0); + } + if (_glgsg->_supports_2d_texture_array) { + glBindTexture(GL_TEXTURE_2D_ARRAY_EXT, 0); + } + if (_glgsg->_supports_cube_map) { + glBindTexture(GL_TEXTURE_CUBE_MAP, 0); + } + // This is probably faster - but maybe not as safe? + // cgGLDisableTextureParameter(p); } - if (_glgsg->_supports_2d_texture_array) { - glBindTexture(GL_TEXTURE_2D_ARRAY_EXT, 0); - } - if (_glgsg->_supports_cube_map) { - glBindTexture(GL_TEXTURE_CUBE_MAP, 0); - } - // This is probably faster - but maybe not as safe? - // cgGLDisableTextureParameter(p); } cg_report_errors(); @@ -1132,7 +1144,7 @@ update_shader_texture_bindings(ShaderContext *prev) { _glgsg->set_active_texture_stage(texunit); - TextureContext *tc = tex->prepare_now(view, _glgsg->_prepared_objects, _glgsg); + TextureContext *tc = tex->prepare_now(_glgsg->_prepared_objects, _glgsg); if (tc == nullptr) { continue; } @@ -1148,8 +1160,8 @@ update_shader_texture_bindings(ShaderContext *prev) { } CLP(TextureContext) *gtc = (CLP(TextureContext) *)tc; - _glgsg->apply_texture(gtc); - _glgsg->apply_sampler(texunit, sampler, gtc); + _glgsg->apply_texture(gtc, view); + _glgsg->apply_sampler(texunit, sampler, gtc, view); } cg_report_errors(); diff --git a/panda/src/glstuff/glGeomMunger_src.cxx b/panda/src/glstuff/glGeomMunger_src.cxx index f6bf36da4a..ac1ae02496 100644 --- a/panda/src/glstuff/glGeomMunger_src.cxx +++ b/panda/src/glstuff/glGeomMunger_src.cxx @@ -274,7 +274,7 @@ munge_format_impl(const GeomVertexFormat *orig, column_alignment = texcoord_type->get_column_alignment(); num_values = texcoord_type->get_num_values(); } - if (start + num_values * sizeof(PN_stdfloat) > glgsg->get_max_vertex_attrib_stride()) { + if (start + num_values * sizeof(PN_stdfloat) > (size_t)glgsg->get_max_vertex_attrib_stride()) { // We are exceeding the limit for stride reported by the driver. // Start a new array. new_format->insert_array(insert_at++, new_array_format); diff --git a/panda/src/glstuff/glGraphicsBuffer_src.cxx b/panda/src/glstuff/glGraphicsBuffer_src.cxx index c3c6dd0fb4..0a26277ea9 100644 --- a/panda/src/glstuff/glGraphicsBuffer_src.cxx +++ b/panda/src/glstuff/glGraphicsBuffer_src.cxx @@ -268,11 +268,8 @@ begin_frame(FrameMode mode, Thread *current_thread) { if (gl_enable_memory_barriers && _fbo_multisample == 0) { CLP(GraphicsStateGuardian) *glgsg = (CLP(GraphicsStateGuardian) *)_gsg.p(); - TextureContexts::iterator it; - for (it = _texture_contexts.begin(); it != _texture_contexts.end(); ++it) { - CLP(TextureContext) *gtc = *it; - - if (gtc != nullptr && gtc->needs_barrier(GL_FRAMEBUFFER_BARRIER_BIT)) { + for (CLP(TextureContext) *gtc : _texture_contexts) { + if (gtc->needs_barrier(GL_FRAMEBUFFER_BARRIER_BIT)) { glgsg->issue_memory_barrier(GL_FRAMEBUFFER_BARRIER_BIT); // If we've done it for one, we've done it for all. break; @@ -478,6 +475,12 @@ rebuild_bitplanes() { // Assign the texture to this slot. attach[plane] = tex; + + if (plane == RTP_color && _fb_properties.is_stereo()) { + if (tex->get_num_views() < 2) { + tex->set_num_views(2); + } + } } } @@ -581,7 +584,9 @@ rebuild_bitplanes() { // The second tex view has already been initialized, so bind it // straight away. if (attach[RTP_color] != nullptr) { - attach_tex(layer, 1, attach[RTP_color], next++); + CLP(TextureContext) *gtc = _texture_contexts.back(); + nassertv(gtc->get_texture() == attach[RTP_color]); + attach_tex(next++, gtc, 1, layer); } else { // XXX hack: I needed a slot to use, and we don't currently use // RTP_stencil and it's treated as a color attachment below, so this @@ -776,7 +781,15 @@ bind_slot(int layer, bool rb_resize, Texture **attach, RenderTexturePlane slot, _fb_properties.setup_color_texture(tex); } - GLenum target = glgsg->get_texture_target(tex->get_texture_type()); + TextureContext *tc = tex->prepare_now(glgsg->get_prepared_objects(), glgsg); + nassertv(tc != nullptr); + CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tc); + + glgsg->update_texture(gtc, true); + gtc->set_active(true); + _texture_contexts.push_back(gtc); + + GLenum target = gtc->_target; if (target == GL_TEXTURE_CUBE_MAP) { target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + layer; } @@ -793,7 +806,7 @@ bind_slot(int layer, bool rb_resize, Texture **attach, RenderTexturePlane slot, _rb[RTP_depth_stencil] = 0; } - attach_tex(layer, 0, tex, GL_DEPTH_ATTACHMENT_EXT); + attach_tex(GL_DEPTH_ATTACHMENT_EXT, gtc, 0, layer); #ifndef OPENGLES GLint depth_size = 0; @@ -806,7 +819,7 @@ bind_slot(int layer, bool rb_resize, Texture **attach, RenderTexturePlane slot, GLCAT.debug() << "Binding texture " << *tex << " to stencil attachment.\n"; } - attach_tex(layer, 0, tex, GL_STENCIL_ATTACHMENT_EXT); + attach_tex(GL_STENCIL_ATTACHMENT_EXT, gtc, 0, layer); #ifndef OPENGLES GLint stencil_size = 0; @@ -820,7 +833,7 @@ bind_slot(int layer, bool rb_resize, Texture **attach, RenderTexturePlane slot, GLCAT.debug() << "Binding texture " << *tex << " to color attachment.\n"; } - attach_tex(layer, 0, tex, attachpoint); + attach_tex(attachpoint, gtc, 0, layer); #ifndef OPENGLES if (attachpoint == GL_COLOR_ATTACHMENT0_EXT) { @@ -1344,30 +1357,22 @@ bind_slot_multisample(bool rb_resize, Texture **attach, RenderTexturePlane slot, * This function attaches the given texture to the given attachment point. */ void CLP(GraphicsBuffer):: -attach_tex(int layer, int view, Texture *attach, GLenum attachpoint) { +attach_tex(GLenum attachpoint, CLP(TextureContext) *gtc, int view, int layer) { + // We should have created the right number of views ahead of time. + nassertv(view < gtc->_num_views); + CLP(GraphicsStateGuardian) *glgsg = (CLP(GraphicsStateGuardian) *)_gsg.p(); - if (view >= attach->get_num_views()) { - attach->set_num_views(view + 1); - } - - // Create the OpenGL texture object. - TextureContext *tc = attach->prepare_now(view, glgsg->get_prepared_objects(), glgsg); - nassertv(tc != nullptr); - CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tc); - - glgsg->update_texture(gtc, true); - gtc->set_active(true); - _texture_contexts.push_back(gtc); - // It seems that binding the texture is necessary before binding to a // framebuffer attachment. - glgsg->apply_texture(gtc); + glgsg->apply_texture(gtc, view); + + GLuint index = gtc->get_view_index(view); #if !defined(OPENGLES) && defined(SUPPORT_FIXED_FUNCTION) if (glgsg->has_fixed_function_pipeline()) { GLclampf priority = 1.0f; - glPrioritizeTextures(1, >c->_index, &priority); + glPrioritizeTextures(1, &index, &priority); } #endif @@ -1375,31 +1380,29 @@ attach_tex(int layer, int view, Texture *attach, GLenum attachpoint) { if (_rb_size_z != 1) { // Bind all of the layers of the texture. nassertv(glgsg->_glFramebufferTexture != nullptr); - glgsg->_glFramebufferTexture(GL_FRAMEBUFFER_EXT, attachpoint, - gtc->_index, 0); + glgsg->_glFramebufferTexture(GL_FRAMEBUFFER_EXT, attachpoint, index, 0); return; } #endif - GLenum target = glgsg->get_texture_target(attach->get_texture_type()); - if (target == GL_TEXTURE_CUBE_MAP) { - target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + layer; - } - + GLenum target = gtc->_target; switch (target) { #ifndef OPENGLES_1 case GL_TEXTURE_3D: glgsg->_glFramebufferTexture3D(GL_FRAMEBUFFER_EXT, attachpoint, - target, gtc->_index, 0, layer); + target, index, 0, layer); break; case GL_TEXTURE_2D_ARRAY: glgsg->_glFramebufferTextureLayer(GL_FRAMEBUFFER_EXT, attachpoint, - gtc->_index, 0, layer); + index, 0, layer); break; #endif + case GL_TEXTURE_CUBE_MAP: + target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + layer; + // fall through default: glgsg->_glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, attachpoint, - target, gtc->_index, 0); + target, index, 0); } } @@ -1419,10 +1422,7 @@ generate_mipmaps() { // PStatGPUTimer timer(glgsg, _generate_mipmap_pcollector); - pvector::iterator it; - for (it = _texture_contexts.begin(); it != _texture_contexts.end(); ++it) { - CLP(TextureContext) *gtc = *it; - + for (CLP(TextureContext) *gtc : _texture_contexts) { if (gtc->_generate_mipmaps) { glgsg->generate_mipmaps(gtc); } @@ -1954,11 +1954,8 @@ resolve_multisamples() { if (gl_enable_memory_barriers) { // Issue memory barriers as necessary to make sure that the texture memory // is synchronized before we blit to it. - pvector::iterator it; - for (it = _texture_contexts.begin(); it != _texture_contexts.end(); ++it) { - CLP(TextureContext) *gtc = *it; - - if (gtc != nullptr && gtc->needs_barrier(GL_FRAMEBUFFER_BARRIER_BIT)) { + for (CLP(TextureContext) *gtc : _texture_contexts) { + if (gtc->needs_barrier(GL_FRAMEBUFFER_BARRIER_BIT)) { glgsg->issue_memory_barrier(GL_FRAMEBUFFER_BARRIER_BIT); // If we've done it for one, we've done it for all. break; diff --git a/panda/src/glstuff/glGraphicsBuffer_src.h b/panda/src/glstuff/glGraphicsBuffer_src.h index dfd4a92e94..83c58ba45b 100644 --- a/panda/src/glstuff/glGraphicsBuffer_src.h +++ b/panda/src/glstuff/glGraphicsBuffer_src.h @@ -92,7 +92,7 @@ protected: RenderTexturePlane plane, GLenum attachpoint); void bind_slot_multisample(bool rb_resize, Texture **attach, RenderTexturePlane plane, GLenum attachpoint); - void attach_tex(int layer, int view, Texture *attach, GLenum attachpoint); + void attach_tex(GLenum attachpoint, CLP(TextureContext) *gtc, int view, int layer); bool check_fbo(); void generate_mipmaps(); void rebuild_bitplanes(); diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index e9ea3f1ae6..9242c584e8 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -1201,6 +1201,15 @@ reset() { _glTexBuffer = (PFNGLTEXBUFFERPROC)get_extension_func("glTexBufferARB"); _supports_buffer_texture = true; } +#elif !defined(OPENGLES_1) + if (is_at_least_gles_version(3, 2)) { + _glTexBuffer = (PFNGLTEXBUFFERPROC)get_extension_func("glTexBuffer"); + _supports_buffer_texture = (_glTexBuffer != nullptr); + } + else if (has_extension("GL_OES_texture_buffer")) { + _glTexBuffer = (PFNGLTEXBUFFERPROC)get_extension_func("glTexBufferOES"); + _supports_buffer_texture = (_glTexBuffer != nullptr); + } #endif #ifdef OPENGLES @@ -2562,8 +2571,18 @@ reset() { #ifndef OPENGLES if (is_at_least_gl_version(4, 5) || has_extension("GL_ARB_direct_state_access")) { + _glCreateTextures = (PFNGLCREATETEXTURESPROC) + get_extension_func("glCreateTextures"); + _glTextureStorage2D = (PFNGLTEXTURESTORAGE2DPROC) + get_extension_func("glTextureStorage2D"); + _glTextureSubImage2D = (PFNGLTEXTURESUBIMAGE2DPROC) + get_extension_func("glTextureSubImage2D"); + _glTextureParameteri = (PFNGLTEXTUREPARAMETERIPROC) + get_extension_func("glTextureParameteri"); _glGenerateTextureMipmap = (PFNGLGENERATETEXTUREMIPMAPPROC) get_extension_func("glGenerateTextureMipmap"); + _glBindTextureUnit = (PFNGLBINDTEXTUREUNITPROC) + get_extension_func("glBindTextureUnit"); _supports_dsa = true; } else { @@ -6243,7 +6262,7 @@ issue_memory_barrier(GLbitfield barriers) { * call Texture::prepare(). */ TextureContext *CLP(GraphicsStateGuardian):: -prepare_texture(Texture *tex, int view) { +prepare_texture(Texture *tex) { PStatGPUTimer timer(this, _prepare_texture_pcollector); report_my_gl_errors(); @@ -6295,8 +6314,12 @@ prepare_texture(Texture *tex, int view) { break; } - CLP(TextureContext) *gtc = new CLP(TextureContext)(this, _prepared_objects, tex, view); - gtc->_target = get_texture_target(texture_type); + CLP(TextureContext) *gtc = new CLP(TextureContext)(this, _prepared_objects, tex); + + // Make sure we have an index so that get_native_id() will already work. + GLenum target = get_texture_target(texture_type); + gtc->reset_data(target, 1); + report_my_gl_errors(); return gtc; @@ -6317,17 +6340,18 @@ update_texture(TextureContext *tc, bool force) { CLP(TextureContext) *gtc; DCAST_INTO_R(gtc, tc, false); + Texture *tex = tc->get_texture(); + GLenum target = get_texture_target(tex->get_texture_type()); + if (gtc->_target != target) { + // The target has changed. That means we have to re-bind a new texture + // object. + gtc->reset_data(target, tex->get_num_views()); + } + if (gtc->was_image_modified() || !gtc->_has_storage) { PStatGPUTimer timer(this, _texture_update_pcollector); // If the texture image was modified, reload the texture. - apply_texture(gtc); - - Texture *tex = tc->get_texture(); - if (gtc->was_properties_modified()) { - specify_texture(gtc, tex->get_default_sampler()); - } - bool okflag = upload_texture(gtc, force, tex->uses_mipmaps()); if (!okflag) { GLCAT.error() @@ -6335,16 +6359,29 @@ update_texture(TextureContext *tc, bool force) { return false; } - } else if (gtc->was_properties_modified()) { + if (gtc->was_properties_modified()) { + for (int view = 0; view < gtc->_num_views; ++view) { + apply_texture(gtc, view); + specify_texture(gtc, tex->get_default_sampler()); + } + } + } + else if (gtc->was_properties_modified()) { PStatGPUTimer timer(this, _texture_update_pcollector); // If only the properties have been modified, we don't necessarily need to // reload the texture. - apply_texture(gtc); + bool needs_reload = false; + for (int view = 0; view < gtc->_num_views; ++view) { + apply_texture(gtc, view); - Texture *tex = tc->get_texture(); - if (specify_texture(gtc, tex->get_default_sampler())) { - // Actually, looks like the texture *does* need to be reloaded. + if (specify_texture(gtc, tex->get_default_sampler())) { + // Actually, looks like the texture *does* need to be reloaded. + needs_reload = true; + } + } + + if (needs_reload) { gtc->mark_needs_reload(); bool okflag = upload_texture(gtc, force, tex->uses_mipmaps()); if (!okflag) { @@ -6352,8 +6389,8 @@ update_texture(TextureContext *tc, bool force) { << "Could not load " << *tex << "\n"; return false; } - - } else { + } + else { // The texture didn't need reloading, but mark it fully updated now. gtc->mark_loaded(); } @@ -6381,12 +6418,7 @@ release_texture(TextureContext *tc) { _textures_needing_framebuffer_barrier.erase(gtc); #endif - glDeleteTextures(1, >c->_index); - - if (gtc->_buffer != 0) { - _glDeleteBuffers(1, >c->_buffer); - } - + gtc->set_num_views(0); delete gtc; } @@ -6401,8 +6433,6 @@ release_textures(const pvector &contexts) { return; } - GLuint *indices = (GLuint *)alloca(sizeof(GLuint) * contexts.size() * 2); - GLuint *buffers = indices + contexts.size(); size_t num_indices = 0; size_t num_buffers = 0; @@ -6416,15 +6446,33 @@ release_textures(const pvector &contexts) { _textures_needing_framebuffer_barrier.erase(gtc); #endif - indices[num_indices++] = gtc->_index; - - if (gtc->_buffer != 0) { - buffers[num_buffers++] = gtc->_buffer; + num_indices += gtc->_num_views; + if (gtc->_buffers != nullptr) { + num_buffers += gtc->_num_views; } + } + + GLuint *indices = (GLuint *)alloca(sizeof(GLuint) * num_indices); + GLuint *buffers = (GLuint *)alloca(sizeof(GLuint) * num_buffers); + num_indices = 0; + num_buffers = 0; + + for (TextureContext *tc : contexts) { + CLP(TextureContext) *gtc = (CLP(TextureContext) *)tc; + + for (int view = 0; view < gtc->_num_views; ++view) { + indices[num_indices++] = gtc->_indices[view]; + + if (gtc->_buffers != nullptr) { + buffers[num_buffers++] = gtc->_buffers[view]; + } + } + gtc->_num_views = 0; delete gtc; } + glDeleteTextures(num_indices, indices); if (num_buffers > 0) { @@ -6446,17 +6494,45 @@ extract_texture_data(Texture *tex) { // Make sure the error stack is cleared out before we begin. report_my_gl_errors(); + TextureContext *tc = tex->prepare_now(get_prepared_objects(), this); + nassertr(tc != nullptr, false); + CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tc); + + GLenum target = gtc->_target; + int num_views = tex->get_num_views(); for (int view = 0; view < num_views; ++view) { - TextureContext *tc = tex->prepare_now(view, get_prepared_objects(), this); - nassertr(tc != nullptr, false); - CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tc); + GLuint index = gtc->get_view_index(view); + glBindTexture(target, index); + if (GLCAT.is_spam()) { + GLCAT.spam() + << "glBindTexture(0x" << hex << target << dec << ", " << index << "): " + << *tex << " view " << view << "\n"; + } - if (!do_extract_texture_data(gtc)) { +#ifndef OPENGLES_1 + if (target == GL_TEXTURE_BUFFER) { + _glBindBuffer(GL_TEXTURE_BUFFER, gtc->get_view_buffer(view)); + } +#endif + + if (!do_extract_texture_data(gtc, view)) { success = false; } } + glBindTexture(target, 0); + if (GLCAT.is_spam()) { + GLCAT.spam() + << "glBindTexture(0x" << hex << target << dec << ", 0)\n"; + } + +#ifndef OPENGLES_1 + if (target == GL_TEXTURE_BUFFER) { + _glBindBuffer(GL_TEXTURE_BUFFER, 0); + } +#endif + return success; } @@ -7642,27 +7718,44 @@ framebuffer_copy_to_texture(Texture *tex, int view, int z, } } - TextureContext *tc = tex->prepare_now(view, get_prepared_objects(), this); + TextureContext *tc = tex->prepare_now(get_prepared_objects(), this); nassertr(tc != nullptr, false); CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tc); - apply_texture(gtc); + GLenum target = get_texture_target(tex->get_texture_type()); + if (gtc->_target != target) { + gtc->reset_data(target, view + 1); + } + else if (view >= gtc->_num_views) { + gtc->set_num_views(view + 1); + } + + apply_texture(gtc, view); bool needs_reload = specify_texture(gtc, tex->get_default_sampler()); - GLenum target = get_texture_target(tex->get_texture_type()); GLint internal_format = get_internal_image_format(tex); int width = tex->get_x_size(); int height = tex->get_y_size(); int depth = tex->get_z_size(); bool uses_mipmaps = tex->uses_mipmaps() && !gl_ignore_mipmaps; + int num_levels = 1; + bool can_generate = _supports_generate_mipmap; +#if defined(OPENGLES) && !defined(OPENGLES_1) + // OpenGL ES doesn't support generating mipmaps for sRGB textures, so we + // have to disable mipmaps, unless we have a special extension. + if (internal_format == GL_SRGB8 || internal_format == GL_SRGB8_ALPHA8) { + can_generate = has_extension("GL_NV_generate_mipmap_sRGB"); + } +#endif if (uses_mipmaps) { - if (_supports_generate_mipmap) { + if (can_generate) { #ifndef OPENGLES_2 if (_glGenerateMipmap == nullptr) { glTexParameteri(target, GL_GENERATE_MIPMAP, true); } #endif + num_levels = tex->get_expected_num_mipmap_levels(); } else { // If we can't auto-generate mipmaps, do without mipmaps. glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); @@ -7687,21 +7780,23 @@ framebuffer_copy_to_texture(Texture *tex, int view, int z, if (!gtc->_has_storage || internal_format != gtc->_internal_format || - uses_mipmaps != gtc->_uses_mipmaps || width != gtc->_width || height != gtc->_height || - depth != gtc->_depth) { + depth != gtc->_depth || + (gtc->_immutable && num_levels > gtc->_num_levels)) { // If the texture properties have changed, we need to reload the image. new_image = true; } if (new_image && gtc->_immutable) { - gtc->reset_data(); - glBindTexture(target, gtc->_index); + gtc->reset_data(target, view + 1); + GLuint index = gtc->get_view_index(view); + glBindTexture(target, index); if (GLCAT.is_spam()) { GLCAT.spam() - << "glBindTexture(0x" << hex << target << dec << ", " << gtc->_index << "): " << *tex << "\n"; + << "glBindTexture(0x" << hex << target << dec << ", " << index << "): " + << *tex << " view " << view << "\n"; } } @@ -7743,12 +7838,12 @@ framebuffer_copy_to_texture(Texture *tex, int view, int z, } gtc->_has_storage = true; - gtc->_simple_loaded = false; - gtc->_uses_mipmaps = uses_mipmaps; gtc->_internal_format = internal_format; gtc->_width = width; gtc->_height = height; gtc->_depth = depth; + gtc->_num_levels = num_levels; + gtc->_may_reload_with_mipmaps = !uses_mipmaps && can_generate; gtc->mark_loaded(); gtc->enqueue_lru(&_prepared_objects->_graphics_memory_lru); @@ -10019,7 +10114,7 @@ get_texture_target(Texture::TextureType texture_type) const { return GL_NONE; case Texture::TT_buffer_texture: -#ifndef OPENGLES +#ifndef OPENGLES_1 if (_supports_buffer_texture) { return GL_TEXTURE_BUFFER; } @@ -10445,7 +10540,7 @@ get_external_image_format(Texture *tex) const { return GL_DEPTH_COMPONENT; case Texture::F_depth_stencil: return _supports_depth_stencil ? GL_DEPTH_STENCIL : GL_DEPTH_COMPONENT; -#ifndef OPENGLES +#ifndef OPENGLES_1 case Texture::F_red: case Texture::F_r16: case Texture::F_r32: @@ -12690,7 +12785,7 @@ update_standard_texture_bindings() { #endif // OPENGLES int view = get_current_tex_view_offset() + stage->get_tex_view_offset(); - TextureContext *tc = texture->prepare_now(view, _prepared_objects, this); + TextureContext *tc = texture->prepare_now(_prepared_objects, this); if (tc == nullptr) { // Something wrong with this texture; skip it. continue; @@ -12716,8 +12811,8 @@ update_standard_texture_bindings() { } // Don't DCAST(); we already did the verification in update_texture. CLP(TextureContext) *gtc = (CLP(TextureContext) *)tc; - apply_texture(gtc); - apply_sampler(i, _target_texture->get_on_sampler(stage), gtc); + apply_texture(gtc, view); + apply_sampler(i, _target_texture->get_on_sampler(stage), gtc, view); if (stage->involves_color_scale() && _color_scale_enabled) { LColor color = stage->get_color(); @@ -12868,8 +12963,22 @@ update_standard_texture_bindings() { */ void CLP(GraphicsStateGuardian):: apply_white_texture(GLuint unit) { - set_active_texture_stage(unit); - glBindTexture(GL_TEXTURE_2D, get_white_texture()); +#ifndef OPENGLES + if (_supports_dsa) { + _glBindTextureUnit(unit, get_white_texture()); + } else +#endif + { + set_active_texture_stage(unit); + + GLuint index = get_white_texture(); + glBindTexture(GL_TEXTURE_2D, index); + + if (GLCAT.is_spam()) { + GLCAT.spam() + << "glBindTexture(GL_TEXTURE_2D, " << index << "): all-white texture\n"; + } + } // Also apply the default sampler, if there's a chance we'd applied anything // else. @@ -12886,7 +12995,24 @@ apply_white_texture(GLuint unit) { */ GLuint CLP(GraphicsStateGuardian):: get_white_texture() { - if (_white_texture == 0) { + if (_white_texture != 0) { + return _white_texture; + } + + const unsigned char data[] = {0xff, 0xff, 0xff, 0xff}; + +#ifndef OPENGLES + if (_supports_dsa && _supports_tex_storage) { + _glCreateTextures(GL_TEXTURE_2D, 1, &_white_texture); + _glTextureParameteri(_white_texture, GL_TEXTURE_WRAP_S, GL_REPEAT); + _glTextureParameteri(_white_texture, GL_TEXTURE_WRAP_T, GL_REPEAT); + _glTextureParameteri(_white_texture, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + _glTextureParameteri(_white_texture, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + _glTextureStorage2D(_white_texture, 1, GL_RGBA8, 1, 1); + _glTextureSubImage2D(_white_texture, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, data); + } else +#endif + { glGenTextures(1, &_white_texture); glBindTexture(GL_TEXTURE_2D, _white_texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); @@ -12894,7 +13020,6 @@ get_white_texture() { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - unsigned char data[] = {0xff, 0xff, 0xff, 0xff}; glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); } @@ -12928,8 +13053,7 @@ update_show_usage_texture_bindings(int show_stage_index) { Texture *texture = _target_texture->get_on_texture(stage); nassertv(texture != nullptr); - int view = get_current_tex_view_offset() + stage->get_tex_view_offset(); - TextureContext *tc = texture->prepare_now(view, _prepared_objects, this); + TextureContext *tc = texture->prepare_now(_prepared_objects, this); if (tc == nullptr) { // Something wrong with this texture; skip it. break; @@ -13423,18 +13547,13 @@ do_issue_tex_gen() { */ bool CLP(GraphicsStateGuardian):: specify_texture(CLP(TextureContext) *gtc, const SamplerState &sampler) { -#ifndef OPENGLES - nassertr(gtc->_handle == 0 /* can't modify tex with active handle */, false); -#endif - Texture *tex = gtc->get_texture(); - - GLenum target = get_texture_target(tex->get_texture_type()); + GLenum target = gtc->_target; if (target == GL_NONE) { // Unsupported target (e.g. 3-d texturing on GL 1.1). return false; } -#ifndef OPENGLES +#ifndef OPENGLES_1 if (target == GL_TEXTURE_BUFFER) { // Buffer textures may not receive texture parameters. return false; @@ -13550,9 +13669,8 @@ specify_texture(CLP(TextureContext) *gtc, const SamplerState &sampler) { report_my_gl_errors(); - if (uses_mipmaps && !gtc->_uses_mipmaps) { - // Suddenly we require mipmaps. This means the texture may need - // reloading. + if (uses_mipmaps && gtc->_may_reload_with_mipmaps) { + // Suddenly we require mipmaps, which means the texture may need reloading. return true; } @@ -13562,26 +13680,26 @@ specify_texture(CLP(TextureContext) *gtc, const SamplerState &sampler) { /** * Updates OpenGL with the current information for this texture, and makes it * the current texture available for rendering. + * + * The texture needs to have valid storage, call update_texture() first. */ bool CLP(GraphicsStateGuardian):: -apply_texture(CLP(TextureContext) *gtc) { +apply_texture(CLP(TextureContext) *gtc, int view) { gtc->set_active(true); - GLenum target = get_texture_target(gtc->get_texture()->get_texture_type()); + + GLenum target = gtc->_target; + assert(target != GL_NONE); // REMOVE ME if (target == GL_NONE) { return false; } - if (gtc->_target != target) { - // The target has changed. That means we have to re-bind a new texture - // object. - gtc->reset_data(); - gtc->_target = target; - } - - glBindTexture(target, gtc->_index); + GLuint index = gtc->get_view_index(view); + glBindTexture(target, index); if (GLCAT.is_spam()) { + Texture *tex = gtc->get_texture(); GLCAT.spam() - << "glBindTexture(0x" << hex << target << dec << ", " << gtc->_index << "): " << *gtc->get_texture() << "\n"; + << "glBindTexture(GL_TEXTURE_2D, " << index << "): " << *tex + << " view " << view << "\n"; } report_my_gl_errors(); @@ -13597,7 +13715,7 @@ apply_texture(CLP(TextureContext) *gtc) { * applied to the given texture context instead. */ bool CLP(GraphicsStateGuardian):: -apply_sampler(GLuint unit, const SamplerState &sampler, CLP(TextureContext) *gtc) { +apply_sampler(GLuint unit, const SamplerState &sampler, CLP(TextureContext) *gtc, int view) { #ifndef OPENGLES_1 if (_supports_sampler_objects) { // We support sampler objects. Prepare the sampler object and bind it to @@ -13622,19 +13740,18 @@ apply_sampler(GLuint unit, const SamplerState &sampler, CLP(TextureContext) *gtc // change the texture parameters if they don't match. if (gtc->_active_sampler != sampler) { set_active_texture_stage(unit); - apply_texture(gtc); + apply_texture(gtc, view); specify_texture(gtc, sampler); } } - if (sampler.uses_mipmaps() && !gtc->_uses_mipmaps && !gtc->_simple_loaded && !gl_ignore_mipmaps) { + if (sampler.uses_mipmaps() && gtc->_may_reload_with_mipmaps) { // The texture wasn't created with mipmaps, but we are trying to sample it // with mipmaps. We will need to reload it. GLCAT.info() << "reloading texture " << gtc->get_texture()->get_name() << " with mipmaps\n"; - apply_texture(gtc); gtc->mark_needs_reload(); bool okflag = upload_texture(gtc, false, true); if (!okflag) { @@ -13642,6 +13759,8 @@ apply_sampler(GLuint unit, const SamplerState &sampler, CLP(TextureContext) *gtc << "Could not load " << *gtc->get_texture() << "\n"; return false; } + // Make sure that the correct view is bound again after upload_texture. + apply_texture(gtc, view); } report_my_gl_errors(); @@ -13651,6 +13770,8 @@ apply_sampler(GLuint unit, const SamplerState &sampler, CLP(TextureContext) *gtc /** * Uploads the entire texture image to OpenGL, including all pages. * + * It does not need to be currently bound. + * * The return value is true if successful, or false if the texture has no * image. */ @@ -13700,12 +13821,6 @@ upload_texture(CLP(TextureContext) *gtc, bool force, bool uses_mipmaps) { } } - int mipmap_bias = 0; - - int width = tex->get_x_size(); - int height = tex->get_y_size(); - int depth = tex->get_z_size(); - // If we'll use immutable texture storage, we have to pick a sized image // format. bool force_sized = (gl_immutable_texture_storage && _supports_tex_storage) || @@ -13789,6 +13904,7 @@ upload_texture(CLP(TextureContext) *gtc, bool force, bool uses_mipmaps) { // instead; of course, the user doesn't always know ahead of time what the // hardware limits are. + int mipmap_bias = 0; if ((max_dimension_x > 0 && max_dimension_y > 0 && max_dimension_z > 0) && image_compression == Texture::CM_off) { while (tex->get_expected_mipmap_x_size(mipmap_bias) > max_dimension_x || @@ -13808,18 +13924,18 @@ upload_texture(CLP(TextureContext) *gtc, bool force, bool uses_mipmaps) { } } } + } - width = tex->get_expected_mipmap_x_size(mipmap_bias); - height = tex->get_expected_mipmap_y_size(mipmap_bias); - depth = tex->get_expected_mipmap_z_size(mipmap_bias); + int width = tex->get_expected_mipmap_x_size(mipmap_bias); + int height = tex->get_expected_mipmap_y_size(mipmap_bias); + int depth = tex->get_expected_mipmap_z_size(mipmap_bias); - if (mipmap_bias != 0) { - GLCAT.info() - << "Reducing image " << tex->get_name() - << " from " << tex->get_x_size() << " x " << tex->get_y_size() - << " x " << tex->get_z_size() << " to " - << width << " x " << height << " x " << depth << "\n"; - } + if (mipmap_bias != 0) { + GLCAT.info() + << "Reducing image " << tex->get_name() + << " from " << tex->get_x_size() << " x " << tex->get_y_size() + << " x " << tex->get_z_size() << " to " + << width << " x " << height << " x " << depth << "\n"; } if (image_compression != Texture::CM_off) { @@ -13843,68 +13959,30 @@ upload_texture(CLP(TextureContext) *gtc, bool force, bool uses_mipmaps) { glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - GLenum target = get_texture_target(texture_type); - uses_mipmaps = (uses_mipmaps && !gl_ignore_mipmaps) || gl_force_mipmaps; -#ifndef OPENGLES - if (target == GL_TEXTURE_BUFFER) { - // Buffer textures may not have mipmaps. - uses_mipmaps = false; - } -#endif // OPENGLES - bool needs_reload = false; if (!gtc->_has_storage || - gtc->_uses_mipmaps != uses_mipmaps || gtc->_internal_format != internal_format || gtc->_width != width || gtc->_height != height || gtc->_depth != depth) { // We need to reload a new GL Texture object. needs_reload = true; - - if (_use_object_labels) { - // This seems like a good time to assign a label for the debug messages. - const string &name = tex->get_name(); - _glObjectLabel(GL_TEXTURE, gtc->_index, name.size(), name.data()); - } } - if (needs_reload && gtc->_immutable) { - GLCAT.info() << "Attempt to modify texture with immutable storage, recreating texture.\n"; - gtc->reset_data(); - glBindTexture(target, gtc->_index); - - if (GLCAT.is_spam()) { - GLCAT.spam() - << "glBindTexture(0x" << hex << target << dec << ", " << gtc->_index << "): " << *tex << "\n"; - } + // Figure out whether mipmaps will be generated by the GPU or by Panda (or + // not at all), and how many mipmap levels should be created. + uses_mipmaps = (uses_mipmaps && !gl_ignore_mipmaps) || gl_force_mipmaps; + int num_levels = 1; + if (texture_type == Texture::TT_buffer_texture || + (width == 1 && height == 1 && depth == 1)) { + // Buffer textures, or 1x1x1 textures, never have mipmaps. + gtc->_num_levels = 1; + gtc->_generate_mipmaps = false; + gtc->_may_reload_with_mipmaps = false; } - -#ifndef OPENGLES - if (target == GL_TEXTURE_BUFFER) { - // Buffer textures don't support mipmappping. + else if (needs_reload || (uses_mipmaps && gtc->_num_levels <= 1)) { gtc->_generate_mipmaps = false; - - if (gtc->_buffer == 0) { - // The buffer object wasn't created yet. - _glGenBuffers(1, >c->_buffer); - _glBindBuffer(GL_TEXTURE_BUFFER, gtc->_buffer); - _glTexBuffer(GL_TEXTURE_BUFFER, internal_format, gtc->_buffer); - needs_reload = true; - } else { - _glBindBuffer(GL_TEXTURE_BUFFER, gtc->_buffer); - if (gtc->_internal_format != internal_format) { - _glTexBuffer(GL_TEXTURE_BUFFER, internal_format, gtc->_buffer); - } - } - } else -#endif // !OPENGLES - if (needs_reload) { - // Figure out whether mipmaps will be generated by the GPU or by Panda (or - // not at all), and how many mipmap levels should be created. - gtc->_generate_mipmaps = false; - int num_levels = 1; - CPTA_uchar image = tex->get_ram_mipmap_image(mipmap_bias); + gtc->_may_reload_with_mipmaps = false; bool can_generate = _supports_generate_mipmap; #if defined(OPENGLES) && !defined(OPENGLES_1) @@ -13918,17 +13996,16 @@ upload_texture(CLP(TextureContext) *gtc, bool force, bool uses_mipmaps) { if (image.is_null()) { // We don't even have a RAM image, so we have no choice but to let // mipmaps be generated on the GPU. - if (uses_mipmaps) { - if (can_generate) { + if (can_generate) { + if (uses_mipmaps) { num_levels = tex->get_expected_num_mipmap_levels() - mipmap_bias; gtc->_generate_mipmaps = true; - } else { - // If it can't, do without mipmaps. - num_levels = 1; - glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + } + else if (!gl_ignore_mipmaps) { + // If someone asks for mipmaps, we can generate them. + gtc->_may_reload_with_mipmaps = true; } } - } else { if (uses_mipmaps) { num_levels = tex->get_num_ram_mipmap_images() - mipmap_bias; @@ -13953,11 +14030,202 @@ upload_texture(CLP(TextureContext) *gtc, bool force, bool uses_mipmaps) { gtc->_generate_mipmaps = true; } else { // If it can't, do without mipmaps. - glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + uses_mipmaps = false; num_levels = 1; } } } + else if (!gl_ignore_mipmaps) { + // We don't yet know whether this might succeed, so we will try if + // someone asks for it. + gtc->_may_reload_with_mipmaps = true; + } + } + if (num_levels > gtc->_num_levels) { + // Always need to reallocate storage when we're adding new mipmap levels. + needs_reload = true; + } + } + else { + // Maybe we need to generate mipmaps on the CPU. + num_levels = gtc->_num_levels; + if (!image.is_null() && uses_mipmaps) { + if (tex->get_num_ram_mipmap_images() - mipmap_bias <= 1) { + // No RAM mipmap levels available. Should we generate some? + if (!_supports_generate_mipmap || !driver_generate_mipmaps || + image_compression != Texture::CM_off) { + // Yes, the GL can't or won't generate them, so we need to. Note + // that some drivers (nVidia) will *corrupt memory* if you ask them + // to generate mipmaps for a pre-compressed texture. + tex->generate_ram_mipmap_images(); + } + } + } + } + + int num_views = tex->get_num_views(); + if (needs_reload) { + if (gtc->_immutable) { + GLCAT.info() + << "Attempt to modify texture with immutable storage, recreating texture.\n"; + gtc->reset_data(gtc->_target, num_views); + } + else if (_supports_tex_storage && gl_immutable_texture_storage) { + gtc->_immutable = true; + } + } + +#ifndef OPENGLES_1 + if (needs_reload || !image.is_null()) { + // Make sure that any incoherent writes to this texture have been synced. + if (gtc->needs_barrier(GL_TEXTURE_UPDATE_BARRIER_BIT)) { + issue_memory_barrier(GL_TEXTURE_UPDATE_BARRIER_BIT); + } + } +#endif + + // Make sure we have a GL texture name for every view of the texture. + int old_num_views = gtc->_num_views; + if (old_num_views != num_views) { + gtc->set_num_views(num_views); + } + + // For a buffer texture, make sure we've created the buffer indices. + if (texture_type == Texture::TT_buffer_texture) { + nassertr(gtc->_buffers != nullptr, false); + } + + bool extract_success = false; + if (tex->get_post_load_store_cache()) { + extract_success = true; + } + + bool success = true; + for (int view = 0; view < num_views; ++view) { + if (upload_texture_image(gtc, view, needs_reload || view >= old_num_views, + mipmap_bias, num_levels, + internal_format, external_format, + component_type, image_compression)) { + gtc->_has_storage = true; + gtc->_internal_format = internal_format; + gtc->_width = width; + gtc->_height = height; + gtc->_depth = depth; + gtc->_num_levels = num_levels; + + if (extract_success) { + // The next call assumes the texture is still bound. + if (!do_extract_texture_data(gtc, view)) { + extract_success = false; + } + } + } + else { + success = false; + } + } + + report_my_gl_errors(); + + if (success) { + if (needs_reload) { + gtc->update_data_size_bytes(get_texture_memory_size(gtc)); + } + + nassertr(gtc->_has_storage, false); + + if (extract_success) { + tex->set_post_load_store_cache(false); + // OK, get the RAM image, and save it in a BamCache record. + if (tex->has_ram_image()) { + BamCache *cache = BamCache::get_global_ptr(); + PT(BamCacheRecord) record = cache->lookup(tex->get_fullpath(), "txo"); + if (record != nullptr) { + record->set_data(tex, tex); + cache->store(record); + } + } + } + + GraphicsEngine *engine = get_engine(); + nassertr(engine != nullptr, false); + engine->texture_uploaded(tex); + gtc->mark_loaded(); + + return true; + } + + return false; +} + +/** + * Loads a texture image, or one page of a cube map image, from system RAM to + * texture memory. + */ +bool CLP(GraphicsStateGuardian):: +upload_texture_image(CLP(TextureContext) *gtc, int view, bool needs_reload, + int mipmap_bias, int num_levels, GLint internal_format, + GLint external_format, GLenum component_type, + Texture::CompressionMode image_compression) { + // Make sure the error stack is cleared out before we begin. + clear_my_gl_errors(); + + if (image_compression != Texture::CM_off && !_supports_compressed_texture) { + return false; + } + + GLenum target = gtc->_target; + if (target == GL_NONE) { + // Unsupported target (e.g. 3-d texturing on GL 1.1). + return false; + } + + Texture *tex = gtc->get_texture(); + nassertr(tex != nullptr, false); + Texture::TextureType texture_type = tex->get_texture_type(); + + GLuint index = gtc->get_view_index(view); + glBindTexture(target, index); + + if (GLCAT.is_spam()) { + GLCAT.spam() + << "glBindTexture(0x" << hex << target << dec << ", " << index << "): " + << *tex << " view " << view << "\n"; + } + + if (_use_object_labels && needs_reload) { + // This seems like a good time to assign a label for the debug messages. + const string &name = tex->get_name(); + if (gtc->_num_views == 1) { + _glObjectLabel(GL_TEXTURE, index, name.size(), name.data()); + } else { + // Add a suffix for a multiview texture. + char *buffer = (char *)alloca(name.size() + 32); + int size = sprintf(buffer, "%s#%d", name.c_str(), view); + _glObjectLabel(GL_TEXTURE, index, size, buffer); + } + } + + CPTA_uchar image = tex->get_ram_mipmap_image(mipmap_bias); + int width = tex->get_expected_mipmap_x_size(mipmap_bias); + int height = tex->get_expected_mipmap_y_size(mipmap_bias); + int depth = tex->get_expected_mipmap_z_size(mipmap_bias); + +#ifndef OPENGLES_1 + if (target == GL_TEXTURE_BUFFER) { + GLuint buffer = gtc->get_view_buffer(view); + nassertr(buffer != 0, false); + _glBindBuffer(GL_TEXTURE_BUFFER, buffer); + if (needs_reload) { + _glTexBuffer(GL_TEXTURE_BUFFER, internal_format, buffer); + } + } else +#endif // !OPENGLES + if (needs_reload) { + if (num_levels <= 1) { + // If we have no mipmaps, tell OpenGL this before we upload the texture + // images, to give it a hint not to expect them. + glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); } if (_supports_texture_max_level) { @@ -14011,12 +14279,12 @@ upload_texture(CLP(TextureContext) *gtc, bool force, bool uses_mipmaps) { // using glTexImage to load all of the individual images one by one later, // but we are not allowed to change the texture size or number of mipmap // levels after this point. - if (gl_immutable_texture_storage && _supports_tex_storage && !gtc->_has_storage) { + if (gtc->_immutable) { if (GLCAT.is_debug()) { GLCAT.debug() - << "allocating storage for texture " << tex->get_name() << ", " << width - << " x " << height << " x " << depth << ", mipmaps " << num_levels - << ", uses_mipmaps = " << uses_mipmaps << "\n"; + << "allocating storage for texture " << tex->get_name() << ", " + << width << " x " << height << " x " << depth << ", mipmaps " + << num_levels << "\n"; } switch (texture_type) { @@ -14039,179 +14307,46 @@ upload_texture(CLP(TextureContext) *gtc, bool force, bool uses_mipmaps) { break; } - gtc->_has_storage = true; - gtc->_simple_loaded = false; - gtc->_immutable = true; - gtc->_uses_mipmaps = uses_mipmaps; - gtc->_internal_format = internal_format; - gtc->_width = width; - gtc->_height = height; - gtc->_depth = depth; - gtc->update_data_size_bytes(get_texture_memory_size(gtc)); - needs_reload = false; } - } else { - // Maybe we need to generate mipmaps on the CPU. - if (!image.is_null() && uses_mipmaps) { - if (tex->get_num_ram_mipmap_images() - mipmap_bias <= 1) { - // No RAM mipmap levels available. Should we generate some? - if (!_supports_generate_mipmap || !driver_generate_mipmaps || - image_compression != Texture::CM_off) { - // Yes, the GL can't or won't generate them, so we need to. Note - // that some drivers (nVidia) will *corrupt memory* if you ask them - // to generate mipmaps for a pre-compressed texture. - tex->generate_ram_mipmap_images(); - } - } - } - } - - bool success = upload_texture_image - (gtc, needs_reload, uses_mipmaps, mipmap_bias, target, - internal_format, external_format, component_type, image_compression); - - if (gtc->_generate_mipmaps && _glGenerateMipmap != nullptr && - !image.is_null()) { - // We uploaded an image; we may need to generate mipmaps. - if (GLCAT.is_debug()) { - GLCAT.debug() - << "generating mipmaps for texture " << tex->get_name() << ", " - << width << " x " << height << " x " << depth - << ", uses_mipmaps = " << uses_mipmaps << "\n"; - } - _glGenerateMipmap(target); - } - - maybe_gl_finish(); - - if (success) { - if (needs_reload) { - gtc->_has_storage = true; - gtc->_simple_loaded = false; - gtc->_uses_mipmaps = uses_mipmaps; - gtc->_internal_format = internal_format; - gtc->_width = width; - gtc->_height = height; - gtc->_depth = depth; - - gtc->update_data_size_bytes(get_texture_memory_size(gtc)); - } - - nassertr(gtc->_has_storage, false); - - if (tex->get_post_load_store_cache()) { - tex->set_post_load_store_cache(false); - // OK, get the RAM image, and save it in a BamCache record. - if (do_extract_texture_data(gtc)) { - if (tex->has_ram_image()) { - BamCache *cache = BamCache::get_global_ptr(); - PT(BamCacheRecord) record = cache->lookup(tex->get_fullpath(), "txo"); - if (record != nullptr) { - record->set_data(tex, tex); - cache->store(record); - } - } - } - } - - GraphicsEngine *engine = get_engine(); - nassertr(engine != nullptr, false); - engine->texture_uploaded(tex); - gtc->mark_loaded(); - - report_my_gl_errors(); - return true; - } - - report_my_gl_errors(); - return false; -} - -/** - * Loads a texture image, or one page of a cube map image, from system RAM to - * texture memory. - */ -bool CLP(GraphicsStateGuardian):: -upload_texture_image(CLP(TextureContext) *gtc, bool needs_reload, - bool uses_mipmaps, int mipmap_bias, - GLenum texture_target, - GLint internal_format, - GLint external_format, GLenum component_type, - Texture::CompressionMode image_compression) { - // Make sure the error stack is cleared out before we begin. - clear_my_gl_errors(); - - if (texture_target == GL_NONE) { - // Unsupported target (e.g. 3-d texturing on GL 1.1). - return false; - } - if (image_compression != Texture::CM_off && !_supports_compressed_texture) { - return false; - } - - Texture *tex = gtc->get_texture(); - nassertr(tex != nullptr, false); - - CPTA_uchar image = tex->get_ram_mipmap_image(mipmap_bias); - int width = tex->get_expected_mipmap_x_size(mipmap_bias); - int height = tex->get_expected_mipmap_y_size(mipmap_bias); - int depth = tex->get_expected_mipmap_z_size(mipmap_bias); - - // Determine the number of images to upload. - int num_levels = mipmap_bias + 1; - if (uses_mipmaps) { - num_levels = tex->get_expected_num_mipmap_levels(); } + // How many mipmap levels do we have available to upload? int num_ram_mipmap_levels = 0; if (!image.is_null()) { - if (uses_mipmaps) { - num_ram_mipmap_levels = tex->get_num_ram_mipmap_images(); - } else { - num_ram_mipmap_levels = 1; - } + num_ram_mipmap_levels = std::min(num_levels, tex->get_num_ram_mipmap_images() - mipmap_bias); } -#ifndef OPENGLES_1 - if (needs_reload || num_ram_mipmap_levels > 0) { - // Make sure that any incoherent writes to this texture have been synced. - if (gtc->needs_barrier(GL_TEXTURE_UPDATE_BARRIER_BIT)) { - issue_memory_barrier(GL_TEXTURE_UPDATE_BARRIER_BIT); - } - } -#endif - if (!needs_reload) { // Try to subload the image over the existing GL Texture object, possibly // saving on texture memory fragmentation. if (GLCAT.is_debug()) { - SparseArray pages = gtc->get_image_modified_pages(0); + SparseArray pages = gtc->get_view_modified_pages(view, 0); if (num_ram_mipmap_levels == 0) { if (tex->has_clear_color()) { GLCAT.debug() - << "clearing texture " << tex->get_name() << ", " + << "clearing texture " << tex->get_name() << " view " << view << ", " << width << " x " << height << " x " << depth << ", pages " << pages - << ", uses_mipmaps = " << uses_mipmaps << ", clear_color = " + << ", mipmaps " << num_levels << ", clear_color = " << tex->get_clear_color() << "\n"; } else { GLCAT.debug() << "not loading NULL image for texture " << tex->get_name() - << ", " << width << " x " << height << " x " << depth - << ", pages " << pages << ", uses_mipmaps = " << uses_mipmaps << "\n"; + << " view " << view << ", " << width << " x " << height << " x " << depth + << ", pages " << pages << ", mipmaps = " << num_levels << "\n"; } } else { GLCAT.debug() - << "updating image data of texture " << tex->get_name() - << ", " << width << " x " << height << " x " << depth + << "updating image data of texture " << tex->get_name() << " view " + << view << ", " << width << " x " << height << " x " << depth << ", pages " << pages << ", mipmaps " << num_ram_mipmap_levels - << ", uses_mipmaps = " << uses_mipmaps << "\n"; + << " / " << num_levels << "\n"; } } - for (int n = mipmap_bias; n < num_levels; ++n) { - SparseArray pages = gtc->get_image_modified_pages(n); + for (int n = mipmap_bias; n < num_levels + mipmap_bias; ++n) { + SparseArray pages = gtc->get_view_modified_pages(view, n); // we grab the mipmap pointer first, if it is NULL we grab the normal // mipmap image pointer which is a PTA_uchar @@ -14220,7 +14355,7 @@ upload_texture_image(CLP(TextureContext) *gtc, bool needs_reload, if (image_ptr == nullptr) { ptimage = tex->get_ram_mipmap_image(n); if (ptimage.is_null()) { - if (n < num_ram_mipmap_levels) { + if (n - mipmap_bias < num_ram_mipmap_levels) { // We were told we'd have this many RAM mipmap images, but we // don't. Raise a warning. GLCAT.warning() @@ -14233,20 +14368,20 @@ upload_texture_image(CLP(TextureContext) *gtc, bool needs_reload, // The texture has a clear color, so we should fill this mipmap // level to a solid color. #ifndef OPENGLES - if (texture_target != GL_TEXTURE_BUFFER) { + if (target != GL_TEXTURE_BUFFER) { if (_supports_clear_texture) { // We can do that with the convenient glClearTexImage // function. vector_uchar clear_data = tex->get_clear_data(); if (pages.has_all_of(0, depth)) { - _glClearTexImage(gtc->_index, n - mipmap_bias, external_format, + _glClearTexImage(index, n - mipmap_bias, external_format, component_type, (void *)&clear_data[0]); } else for (size_t sri = 0; sri < pages.get_num_subranges(); ++sri) { int begin = pages.get_subrange_begin(sri); int num_pages = pages.get_subrange_end(sri) - begin; - _glClearTexSubImage(gtc->_index, n - mipmap_bias, 0, 0, begin, + _glClearTexSubImage(index, n - mipmap_bias, 0, 0, begin, width, height, num_pages, external_format, component_type, (void *)&clear_data[0]); } @@ -14282,7 +14417,7 @@ upload_texture_image(CLP(TextureContext) *gtc, bool needs_reload, if (image_ptr != nullptr) { const unsigned char *orig_image_ptr = image_ptr; size_t view_size = tex->get_ram_mipmap_view_size(n); - image_ptr += view_size * gtc->get_view(); + image_ptr += view_size * view; nassertr(image_ptr >= orig_image_ptr && image_ptr + view_size <= orig_image_ptr + tex->get_ram_mipmap_image_size(n), false); if (image_compression == Texture::CM_off) { @@ -14299,7 +14434,7 @@ upload_texture_image(CLP(TextureContext) *gtc, bool needs_reload, #ifdef DO_PSTATS _data_transferred_pcollector.add_level(page_size * pages.get_num_on_bits()); #endif - switch (texture_target) { + switch (target) { #ifndef OPENGLES_1 case GL_TEXTURE_3D: if (_supports_3d_texture) { @@ -14309,11 +14444,11 @@ upload_texture_image(CLP(TextureContext) *gtc, bool needs_reload, const unsigned char *page_ptr = image_ptr + page_size * begin; if (image_compression == Texture::CM_off) { - _glTexSubImage3D(texture_target, n - mipmap_bias, + _glTexSubImage3D(target, n - mipmap_bias, 0, 0, begin, width, height, num_pages, external_format, component_type, page_ptr); } else { - _glCompressedTexSubImage3D(texture_target, n - mipmap_bias, + _glCompressedTexSubImage3D(target, n - mipmap_bias, 0, 0, begin, width, height, num_pages, external_format, page_size * num_pages, page_ptr); @@ -14329,10 +14464,10 @@ upload_texture_image(CLP(TextureContext) *gtc, bool needs_reload, #ifndef OPENGLES case GL_TEXTURE_1D: if (image_compression == Texture::CM_off) { - glTexSubImage1D(texture_target, n - mipmap_bias, 0, width, + glTexSubImage1D(target, n - mipmap_bias, 0, width, external_format, component_type, image_ptr); } else { - _glCompressedTexSubImage1D(texture_target, n - mipmap_bias, 0, width, + _glCompressedTexSubImage1D(target, n - mipmap_bias, 0, width, external_format, page_size, image_ptr); } break; @@ -14348,11 +14483,11 @@ upload_texture_image(CLP(TextureContext) *gtc, bool needs_reload, const unsigned char *page_ptr = image_ptr + page_size * begin; if (image_compression == Texture::CM_off) { - _glTexSubImage3D(texture_target, n - mipmap_bias, + _glTexSubImage3D(target, n - mipmap_bias, 0, 0, begin, width, height, num_pages, external_format, component_type, page_ptr); } else { - _glCompressedTexSubImage3D(texture_target, n - mipmap_bias, + _glCompressedTexSubImage3D(target, n - mipmap_bias, 0, 0, begin, width, height, num_pages, external_format, page_size * num_pages, page_ptr); @@ -14365,7 +14500,7 @@ upload_texture_image(CLP(TextureContext) *gtc, bool needs_reload, break; #endif // OPENGLES_1 -#ifndef OPENGLES +#ifndef OPENGLES_1 case GL_TEXTURE_BUFFER: if (_supports_buffer_texture) { _glBufferSubData(GL_TEXTURE_BUFFER, 0, page_size, image_ptr); @@ -14411,10 +14546,10 @@ upload_texture_image(CLP(TextureContext) *gtc, bool needs_reload, // TexSubImage2D doesn't accept a row-stride parameter. height = tex->get_y_size() - tex->get_pad_y_size(); } - glTexSubImage2D(texture_target, n - mipmap_bias, 0, 0, width, height, + glTexSubImage2D(target, n - mipmap_bias, 0, 0, width, height, external_format, component_type, image_ptr); } else { - _glCompressedTexSubImage2D(texture_target, n - mipmap_bias, 0, 0, width, height, + _glCompressedTexSubImage2D(target, n - mipmap_bias, 0, 0, width, height, external_format, page_size, image_ptr); } break; @@ -14438,9 +14573,9 @@ upload_texture_image(CLP(TextureContext) *gtc, bool needs_reload, // Load the image up from scratch, creating a new GL Texture object. if (GLCAT.is_debug()) { GLCAT.debug() - << "loading new texture object for " << tex->get_name() << ", " << width - << " x " << height << " x " << depth << ", mipmaps " - << num_ram_mipmap_levels << ", uses_mipmaps = " << uses_mipmaps << "\n"; + << "loading new texture object for " << tex->get_name() << " view " + << view << ", " << width << " x " << height << " x " << depth + << ", mipmaps " << num_ram_mipmap_levels << " / " << num_levels << "\n"; } // If there is immutable storage, this is impossible to do, and we should @@ -14462,13 +14597,13 @@ upload_texture_image(CLP(TextureContext) *gtc, bool needs_reload, } } - for (int n = mipmap_bias; n < num_levels; ++n) { + for (int n = mipmap_bias; n < num_levels + mipmap_bias; ++n) { const unsigned char *image_ptr = (unsigned char*)tex->get_ram_mipmap_pointer(n); CPTA_uchar ptimage; if (image_ptr == nullptr) { ptimage = tex->get_ram_mipmap_image(n); if (ptimage.is_null()) { - if (n < num_ram_mipmap_levels) { + if (n - mipmap_bias < num_ram_mipmap_levels) { // We were told we'd have this many RAM mipmap images, but we // don't. Raise a warning. GLCAT.warning() @@ -14476,7 +14611,7 @@ upload_texture_image(CLP(TextureContext) *gtc, bool needs_reload, << "\n"; if (_supports_texture_max_level) { // Tell the GL we have no more mipmaps for it to use. - glTexParameteri(texture_target, GL_TEXTURE_MAX_LEVEL, n - mipmap_bias); + glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, n - mipmap_bias); } break; } @@ -14486,12 +14621,12 @@ upload_texture_image(CLP(TextureContext) *gtc, bool needs_reload, // fill it in with the correct clear color, which we can then // upload. ptimage = tex->make_ram_mipmap_image(n); - - } else if (image_compression != Texture::CM_off) { + } + else if (image_compression != Texture::CM_off) { // We can't upload a NULL compressed texture. if (_supports_texture_max_level) { // Tell the GL we have no more mipmaps for it to use. - glTexParameteri(texture_target, GL_TEXTURE_MAX_LEVEL, n - mipmap_bias); + glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, n - mipmap_bias); } break; } @@ -14503,7 +14638,7 @@ upload_texture_image(CLP(TextureContext) *gtc, bool needs_reload, size_t view_size = tex->get_ram_mipmap_view_size(n); if (image_ptr != nullptr) { const unsigned char *orig_image_ptr = image_ptr; - image_ptr += view_size * gtc->get_view(); + image_ptr += view_size * view; nassertr(image_ptr >= orig_image_ptr && image_ptr + view_size <= orig_image_ptr + tex->get_ram_mipmap_image_size(n), false); if (image_compression == Texture::CM_off) { @@ -14523,14 +14658,14 @@ upload_texture_image(CLP(TextureContext) *gtc, bool needs_reload, #ifdef DO_PSTATS _data_transferred_pcollector.add_level(view_size); #endif - switch (texture_target) { + switch (target) { #ifndef OPENGLES // 1-d textures not supported by OpenGL ES. Fall through. case GL_TEXTURE_1D: if (image_compression == Texture::CM_off) { - glTexImage1D(texture_target, n - mipmap_bias, internal_format, + glTexImage1D(target, n - mipmap_bias, internal_format, width, 0, external_format, component_type, image_ptr); } else { - _glCompressedTexImage1D(texture_target, n - mipmap_bias, external_format, + _glCompressedTexImage1D(target, n - mipmap_bias, external_format, width, 0, view_size, image_ptr); } break; @@ -14540,11 +14675,11 @@ upload_texture_image(CLP(TextureContext) *gtc, bool needs_reload, case GL_TEXTURE_3D: if (_supports_3d_texture) { if (image_compression == Texture::CM_off) { - _glTexImage3D(texture_target, n - mipmap_bias, internal_format, + _glTexImage3D(target, n - mipmap_bias, internal_format, width, height, depth, 0, external_format, component_type, image_ptr); } else { - _glCompressedTexImage3D(texture_target, n - mipmap_bias, external_format, + _glCompressedTexImage3D(target, n - mipmap_bias, external_format, width, height, depth, 0, view_size, image_ptr); } } else { @@ -14559,11 +14694,11 @@ upload_texture_image(CLP(TextureContext) *gtc, bool needs_reload, case GL_TEXTURE_CUBE_MAP_ARRAY: if (_supports_2d_texture_array) { if (image_compression == Texture::CM_off) { - _glTexImage3D(texture_target, n - mipmap_bias, internal_format, + _glTexImage3D(target, n - mipmap_bias, internal_format, width, height, depth, 0, external_format, component_type, image_ptr); } else { - _glCompressedTexImage3D(texture_target, n - mipmap_bias, external_format, + _glCompressedTexImage3D(target, n - mipmap_bias, external_format, width, height, depth, 0, view_size, image_ptr); } } else { @@ -14571,9 +14706,7 @@ upload_texture_image(CLP(TextureContext) *gtc, bool needs_reload, return false; } break; -#endif // OPENGLES_1 -#ifndef OPENGLES case GL_TEXTURE_BUFFER: if (_supports_buffer_texture) { _glBufferData(GL_TEXTURE_BUFFER, view_size, image_ptr, @@ -14583,7 +14716,7 @@ upload_texture_image(CLP(TextureContext) *gtc, bool needs_reload, return false; } break; -#endif // OPENGLES +#endif // OPENGLES_1 case GL_TEXTURE_CUBE_MAP: if (_supports_cube_map) { @@ -14612,11 +14745,11 @@ upload_texture_image(CLP(TextureContext) *gtc, bool needs_reload, default: if (image_compression == Texture::CM_off) { - glTexImage2D(texture_target, n - mipmap_bias, internal_format, + glTexImage2D(target, n - mipmap_bias, internal_format, width, height, 0, external_format, component_type, image_ptr); } else { - _glCompressedTexImage2D(texture_target, n - mipmap_bias, external_format, + _glCompressedTexImage2D(target, n - mipmap_bias, external_format, width, height, 0, view_size, image_ptr); } } @@ -14634,6 +14767,17 @@ upload_texture_image(CLP(TextureContext) *gtc, bool needs_reload, } } + if (gtc->_generate_mipmaps && _glGenerateMipmap != nullptr && !image.is_null()) { + // We uploaded an image; we may need to generate mipmaps. + if (GLCAT.is_debug()) { + GLCAT.debug() + << "generating mipmaps for texture " << tex->get_name() << " view " + << view << ", " << width << " x " << height << " x " << depth + << ", mipmaps = " << num_levels << "\n"; + } + _glGenerateMipmap(target); + } + report_my_gl_errors(); return true; @@ -14644,10 +14788,18 @@ upload_texture_image(CLP(TextureContext) *gtc, bool needs_reload, */ void CLP(GraphicsStateGuardian):: generate_mipmaps(CLP(TextureContext) *gtc) { + gtc->set_active(true); + + if (gtc->_num_levels <= 1) { + return; + } + #ifndef OPENGLES if (_supports_dsa) { // OpenGL 4.5 offers an easy way to do this without binding. - _glGenerateTextureMipmap(gtc->_index); + for (int view = 0; view < gtc->_num_views; ++view) { + _glGenerateTextureMipmap(gtc->_indices[view]); + } return; } #endif @@ -14655,9 +14807,20 @@ generate_mipmaps(CLP(TextureContext) *gtc) { if (_glGenerateMipmap != nullptr) { _state_texture = 0; update_texture(gtc, true); - apply_texture(gtc); - _glGenerateMipmap(gtc->_target); - glBindTexture(gtc->_target, 0); + + GLenum target = gtc->_target; + for (int view = 0; view < gtc->_num_views; ++view) { + glBindTexture(target, gtc->_indices[view]); + _glGenerateMipmap(target); + } + glBindTexture(target, 0); + + if (GLCAT.is_spam()) { + GLCAT.spam() + << "glBindTexture(0x" << hex << target << dec << ", 0)\n"; + } + + report_my_gl_errors(); } } @@ -14675,6 +14838,15 @@ upload_simple_texture(CLP(TextureContext) *gtc) { Texture *tex = gtc->get_texture(); nassertr(tex != nullptr, false); + gtc->set_num_views(1); + GLuint index = gtc->get_view_index(0); + glBindTexture(GL_TEXTURE_2D, index); + + if (GLCAT.is_spam()) { + GLCAT.spam() + << "glBindTexture(GL_TEXTURE_2D, " << index << "): " << *tex << " simple\n"; + } + #ifdef OPENGLES GLenum internal_format = GL_BGRA; #else @@ -14711,7 +14883,7 @@ upload_simple_texture(CLP(TextureContext) *gtc) { } // Turn off mipmaps for the simple texture. - if (tex->uses_mipmaps() && _supports_texture_max_level) { + if (_supports_texture_max_level) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); } @@ -14727,13 +14899,13 @@ upload_simple_texture(CLP(TextureContext) *gtc) { external_format, component_type, image_ptr); gtc->_has_storage = true; - gtc->_simple_loaded = true; gtc->_immutable = false; - gtc->_uses_mipmaps = false; gtc->_internal_format = internal_format; gtc->_width = width; gtc->_height = height; gtc->_depth = 1; + gtc->_num_levels = 1; + gtc->_may_reload_with_mipmaps = false; gtc->update_data_size_bytes(width * height * 4); gtc->mark_loaded(); @@ -14783,7 +14955,7 @@ get_texture_memory_size(CLP(TextureContext) *gtc) { // Try to get the compressed size. GLint image_size; glGetTexLevelParameteriv(page_target, 0, - GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &image_size); + GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &image_size); GLenum error_code = gl_get_error(); if (error_code != GL_NO_ERROR) { @@ -14834,11 +15006,14 @@ get_texture_memory_size(CLP(TextureContext) *gtc) { #endif // OPENGLES size_t result = num_bytes * width * height * depth * scale; - if (gtc->_uses_mipmaps) { - result = (result * 4) / 3; + for (int n = 1; n < gtc->_num_levels; ++n) { + width = max(1, width << 1); + height = max(1, height << 1); + depth = max(1, depth << 1); + result += num_bytes * width * height * depth * scale; } - return result; + return result * gtc->_num_views; } /** @@ -14858,9 +15033,10 @@ check_nonresident_texture(BufferContextChain &chain) { size_t ti = 0; BufferContext *node = chain.get_first(); while (node != nullptr) { + // For now, we just check whether the first view is resident. CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), node); gtc_list[ti] = gtc; - texture_list[ti] = gtc->_index; + texture_list[ti] = gtc->get_view_index(0); node = node->get_next(); ++ti; } @@ -14884,9 +15060,11 @@ check_nonresident_texture(BufferContextChain &chain) { /** * The internal implementation of extract_texture_data(), given an already- * created TextureContext. + * + * Assumes that the texture is already bound. */ bool CLP(GraphicsStateGuardian):: -do_extract_texture_data(CLP(TextureContext) *gtc) { +do_extract_texture_data(CLP(TextureContext) *gtc, int view) { report_my_gl_errors(); GLenum target = gtc->_target; @@ -14903,18 +15081,6 @@ do_extract_texture_data(CLP(TextureContext) *gtc) { Texture *tex = gtc->get_texture(); - glBindTexture(target, gtc->_index); - if (GLCAT.is_spam()) { - GLCAT.spam() - << "glBindTexture(0x" << hex << target << dec << ", " << gtc->_index << "): " << *tex << "\n"; - } - -#ifndef OPENGLES - if (target == GL_TEXTURE_BUFFER) { - _glBindBuffer(GL_TEXTURE_BUFFER, gtc->_buffer); - } -#endif - GLint wrap_u, wrap_v, wrap_w; GLint minfilter, magfilter; @@ -14922,7 +15088,7 @@ do_extract_texture_data(CLP(TextureContext) *gtc) { GLfloat border_color[4]; #endif -#ifdef OPENGLES +#ifdef OPENGLES_1 if (true) { #else if (target != GL_TEXTURE_BUFFER) { @@ -15466,7 +15632,7 @@ do_extract_texture_data(CLP(TextureContext) *gtc) { tex->set_component_type(type); tex->set_format(format); -#ifdef OPENGLES +#ifdef OPENGLES_1 if (true) { #else if (target != GL_TEXTURE_BUFFER) { @@ -15500,29 +15666,20 @@ do_extract_texture_data(CLP(TextureContext) *gtc) { // existing content. PTA_uchar ram_image = tex->modify_ram_image(); nassertr(ram_image.size() == image.size() * num_views, false); - memcpy(ram_image.p() + image.size() * gtc->get_view(), image.p(), image.size()); + memcpy(ram_image.p() + image.size() * view, image.p(), image.size()); } - if (gtc->_uses_mipmaps) { - // Also get the mipmap levels. - GLint num_expected_levels = tex->get_expected_num_mipmap_levels(); - GLint highest_level = num_expected_levels; - - if (_supports_texture_max_level) { - glGetTexParameteriv(target, GL_TEXTURE_MAX_LEVEL, &highest_level); - highest_level = min(highest_level, num_expected_levels); + // Also get the mipmap levels. + for (int n = 1; n < gtc->_num_levels; ++n) { + if (!extract_texture_image(image, page_size, tex, target, page_target, + type, compression, n)) { + return false; } - for (int n = 1; n <= highest_level; ++n) { - if (!extract_texture_image(image, page_size, tex, target, page_target, - type, compression, n)) { - return false; - } - if (num_views == 1) { - tex->set_ram_mipmap_image(n, image, page_size); - } else { - PTA_uchar ram_mipmap_image = tex->modify_ram_mipmap_image(n); - memcpy(ram_mipmap_image.p() + image.size() * gtc->get_view(), image.p(), image.size()); - } + if (num_views == 1) { + tex->set_ram_mipmap_image(n, image, page_size); + } else { + PTA_uchar ram_mipmap_image = tex->modify_ram_mipmap_image(n); + memcpy(ram_mipmap_image.p() + image.size() * view, image.p(), image.size()); } } @@ -15583,7 +15740,7 @@ extract_texture_image(PTA_uchar &image, size_t &page_size, } } -#ifndef OPENGLES +#ifndef OPENGLES_1 } else if (target == GL_TEXTURE_BUFFER) { // In the case of a buffer texture, we need to get it from the buffer. image = PTA_uchar::empty_array(tex->get_expected_ram_mipmap_view_size(n)); diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.h b/panda/src/glstuff/glGraphicsStateGuardian_src.h index 92db648eb1..dc44c68d61 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.h +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.h @@ -143,6 +143,7 @@ typedef void (APIENTRYP PFNGLGENVERTEXARRAYSPROC) (GLsizei n, GLuint *arrays); typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEPROC) (GLenum modeRGB, GLenum modeAlpha); typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); typedef GLboolean (APIENTRYP PFNGLUNMAPBUFFERPROC) (GLenum target); +typedef void (APIENTRYP PFNGLTEXBUFFERPROC) (GLenum target, GLenum internalformat, GLuint buffer); #ifndef OPENGLES_1 // GLSL shader functions @@ -343,7 +344,7 @@ public: void issue_memory_barrier(GLbitfield barrier); #endif - virtual TextureContext *prepare_texture(Texture *tex, int view); + virtual TextureContext *prepare_texture(Texture *tex); virtual bool update_texture(TextureContext *tc, bool force); virtual void release_texture(TextureContext *tc); virtual void release_textures(const pvector &contexts); @@ -632,12 +633,12 @@ protected: #endif // NDEBUG bool specify_texture(CLP(TextureContext) *gtc, const SamplerState &sampler); - bool apply_texture(CLP(TextureContext) *gtc); - bool apply_sampler(GLuint unit, const SamplerState &sampler, CLP(TextureContext) *gtc); + bool apply_texture(CLP(TextureContext) *gtc, int view); + bool apply_sampler(GLuint unit, const SamplerState &sampler, + CLP(TextureContext) *gtc, int view); bool upload_texture(CLP(TextureContext) *gtc, bool force, bool uses_mipmaps); - bool upload_texture_image(CLP(TextureContext) *gtc, bool needs_reload, - bool uses_mipmaps, int mipmap_bias, - GLenum texture_target, + bool upload_texture_image(CLP(TextureContext) *gtc, int view, + bool needs_reload, int mipmap_bias, int num_levels, GLint internal_format, GLint external_format, GLenum component_type, Texture::CompressionMode image_compression); @@ -646,7 +647,7 @@ protected: size_t get_texture_memory_size(CLP(TextureContext) *gtc); void check_nonresident_texture(BufferContextChain &chain); - bool do_extract_texture_data(CLP(TextureContext) *gtc); + bool do_extract_texture_data(CLP(TextureContext) *gtc, int view); bool extract_texture_image(PTA_uchar &image, size_t &page_size, Texture *tex, GLenum target, GLenum page_target, Texture::ComponentType type, @@ -833,7 +834,7 @@ public: PFNGLTEXSTORAGE2DPROC _glTexStorage2D; PFNGLTEXSTORAGE3DPROC _glTexStorage3D; -#ifndef OPENGLES +#ifndef OPENGLES_1 PFNGLTEXBUFFERPROC _glTexBuffer; #endif @@ -967,7 +968,12 @@ public: #ifndef OPENGLES bool _supports_dsa; + PFNGLCREATETEXTURESPROC _glCreateTextures; + PFNGLTEXTURESTORAGE2DPROC _glTextureStorage2D; + PFNGLTEXTURESUBIMAGE2DPROC _glTextureSubImage2D; + PFNGLTEXTUREPARAMETERIPROC _glTextureParameteri; PFNGLGENERATETEXTUREMIPMAPPROC _glGenerateTextureMipmap; + PFNGLBINDTEXTUREUNITPROC _glBindTextureUnit; #endif #ifndef OPENGLES_1 diff --git a/panda/src/glstuff/glShaderContext_src.cxx b/panda/src/glstuff/glShaderContext_src.cxx index 077e9e1d79..c3af8f63fa 100644 --- a/panda/src/glstuff/glShaderContext_src.cxx +++ b/panda/src/glstuff/glShaderContext_src.cxx @@ -1461,6 +1461,15 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { if (param_size == 1) { // A single uniform (not an array, or an array of size 1). switch (param_type) { +#ifndef OPENGLES + case GL_INT_SAMPLER_1D: + case GL_INT_SAMPLER_1D_ARRAY: + case GL_UNSIGNED_INT_SAMPLER_1D: + case GL_UNSIGNED_INT_SAMPLER_1D_ARRAY: + case GL_SAMPLER_1D: + case GL_SAMPLER_1D_ARRAY: + case GL_SAMPLER_1D_SHADOW: +#endif case GL_INT_SAMPLER_2D: case GL_INT_SAMPLER_3D: case GL_INT_SAMPLER_2D_ARRAY: @@ -1472,22 +1481,13 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { case GL_SAMPLER_CUBE_SHADOW: case GL_SAMPLER_2D_ARRAY: case GL_SAMPLER_2D_ARRAY_SHADOW: -#ifndef OPENGLES - case GL_INT_SAMPLER_1D: - case GL_INT_SAMPLER_1D_ARRAY: case GL_INT_SAMPLER_BUFFER: case GL_INT_SAMPLER_CUBE_MAP_ARRAY: - case GL_UNSIGNED_INT_SAMPLER_1D: - case GL_UNSIGNED_INT_SAMPLER_1D_ARRAY: case GL_UNSIGNED_INT_SAMPLER_BUFFER: case GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY: - case GL_SAMPLER_1D: - case GL_SAMPLER_1D_ARRAY: - case GL_SAMPLER_1D_SHADOW: case GL_SAMPLER_BUFFER: case GL_SAMPLER_CUBE_MAP_ARRAY: case GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW: -#endif // !OPENGLES case GL_SAMPLER_2D: case GL_SAMPLER_2D_SHADOW: case GL_SAMPLER_3D: @@ -1679,18 +1679,22 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { case GL_UNSIGNED_INT_IMAGE_2D_ARRAY: #ifndef OPENGLES case GL_IMAGE_1D: + case GL_INT_IMAGE_1D: + case GL_UNSIGNED_INT_IMAGE_1D: +#endif case GL_IMAGE_CUBE_MAP_ARRAY: case GL_IMAGE_BUFFER: - case GL_INT_IMAGE_1D: case GL_INT_IMAGE_CUBE_MAP_ARRAY: case GL_INT_IMAGE_BUFFER: - case GL_UNSIGNED_INT_IMAGE_1D: case GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY: case GL_UNSIGNED_INT_IMAGE_BUFFER: -#endif // This won't really change at runtime, so we might as well bind once // and then forget about it. + // Note that OpenGL ES doesn't support changing this at runtime, so we + // rely on the shader using a layout declaration. +#ifndef OPENGLES _glgsg->_glUniform1i(p, _glsl_img_inputs.size()); +#endif { ImageInput input; input._name = InternalName::make(param_name); @@ -1881,7 +1885,6 @@ get_sampler_texture_type(int &out, GLenum param_type) { return false; } -#ifndef OPENGLES case GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW: if (!_glgsg->_supports_shadow_filter) { GLCAT.error() @@ -1913,7 +1916,6 @@ get_sampler_texture_type(int &out, GLenum param_type) { << "GLSL shader uses buffer texture, which is unsupported by the driver.\n"; return false; } -#endif // !OPENGLES default: GLCAT.error() @@ -2598,57 +2600,26 @@ disable_shader_texture_bindings() { DO_PSTATS_STUFF(_glgsg->_texture_state_pcollector.add_level(1)); - for (size_t i = 0; i < _shader->_tex_spec.size(); ++i) { #ifndef OPENGLES - // Check if bindless was used, if so, there's nothing to unbind. - if (_glgsg->_supports_bindless_texture) { - GLint p = _shader->_tex_spec[i]._id._seqno; + if (_glgsg->_supports_multi_bind) { + _glgsg->_glBindTextures(0, _shader->_tex_spec.size(), nullptr); + } + else if (_glgsg->_supports_dsa) { + for (size_t i = 0; i < _shader->_tex_spec.size(); ++i) { + _glgsg->_glBindTextureUnit(i, 0); + } + } + else +#endif + { + for (size_t i = 0; i < _shader->_tex_spec.size(); ++i) { + _glgsg->set_active_texture_stage(i); - if (_glsl_uniform_handles.count(p) > 0) { - continue; + GLenum target = _glgsg->get_texture_target((Texture::TextureType)_shader->_tex_spec[i]._desired_type); + if (target != GL_NONE) { + glBindTexture(target, 0); } } - - if (_glgsg->_supports_multi_bind) { - // There are non-bindless textures to unbind, and we're lazy, so let's - // go and unbind everything after this point using one multi-bind call, - // and then break out of the loop. - _glgsg->_glBindTextures(i, _shader->_tex_spec.size() - i, nullptr); - break; - } -#endif - - _glgsg->set_active_texture_stage(i); - - switch (_shader->_tex_spec[i]._desired_type) { - case Texture::TT_1d_texture: -#ifndef OPENGLES - glBindTexture(GL_TEXTURE_1D, 0); -#endif - break; - - case Texture::TT_2d_texture: - glBindTexture(GL_TEXTURE_2D, 0); - break; - - case Texture::TT_3d_texture: - glBindTexture(GL_TEXTURE_3D, 0); - break; - - case Texture::TT_2d_texture_array: - glBindTexture(GL_TEXTURE_2D_ARRAY, 0); - break; - - case Texture::TT_cube_map: - glBindTexture(GL_TEXTURE_CUBE_MAP, 0); - break; - - case Texture::TT_buffer_texture: -#ifndef OPENGLES - glBindTexture(GL_TEXTURE_BUFFER, 0); -#endif - break; - } } // Now unbind all the image units. Not sure if we *have* to do this. @@ -2738,14 +2709,14 @@ update_shader_texture_bindings(ShaderContext *prev) { CLP(TextureContext) *gtc; if (tex != nullptr) { - int view = _glgsg->get_current_tex_view_offset(); - - gtc = DCAST(CLP(TextureContext), tex->prepare_now(view, _glgsg->_prepared_objects, _glgsg)); + gtc = DCAST(CLP(TextureContext), tex->prepare_now(_glgsg->_prepared_objects, _glgsg)); if (gtc != nullptr) { input._gtc = gtc; _glgsg->update_texture(gtc, true); - gl_tex = gtc->_index; + + int view = _glgsg->get_current_tex_view_offset(); + gl_tex = gtc->get_view_index(view); #ifndef OPENGLES if (gtc->needs_barrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT)) { @@ -2880,7 +2851,7 @@ update_shader_texture_bindings(ShaderContext *prev) { // enabled. } - CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tex->prepare_now(view, _glgsg->_prepared_objects, _glgsg)); + CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tex->prepare_now(_glgsg->_prepared_objects, _glgsg)); if (gtc == nullptr) { if (multi_bind) { textures[i] = 0; @@ -2890,49 +2861,13 @@ update_shader_texture_bindings(ShaderContext *prev) { } #ifndef OPENGLES - GLint p = spec._id._seqno; - // If it was recently written to, we will have to issue a memory barrier // soon. if (gtc->needs_barrier(GL_TEXTURE_FETCH_BARRIER_BIT)) { barriers |= GL_TEXTURE_FETCH_BARRIER_BIT; } - - // Try bindless texturing first, if supported. - if (gl_use_bindless_texture && _glgsg->_supports_bindless_texture) { - // We demand the real texture, since we won't be able to change the - // texture properties after this point. - if (multi_bind) { - textures[i] = 0; - samplers[i] = 0; - } - if (!_glgsg->update_texture(gtc, true)) { - continue; - } - - GLuint64 handle = gtc->get_handle(); - if (handle != 0) { - gtc->make_handle_resident(); - gtc->set_active(true); - - // Check if we have already specified this texture handle. If so, no - // need to call glUniformHandle again. - pmap::const_iterator it; - it = _glsl_uniform_handles.find(p); - if (it != _glsl_uniform_handles.end() && it->second == handle) { - // Already specified. - continue; - } else { - _glgsg->_glUniformHandleui64(p, handle); - _glsl_uniform_handles[p] = handle; - } - continue; - } - } #endif - // Bindless texturing wasn't supported or didn't work, so let's just bind - // the texture normally. // Note that simple RAM images are always 2-D for now, so to avoid errors, // we must load the real texture if this is not for a sampler2D. bool force = (spec._desired_type != Texture::TT_2d_texture); @@ -2943,7 +2878,7 @@ update_shader_texture_bindings(ShaderContext *prev) { textures[i] = 0; } else { gtc->set_active(true); - textures[i] = gtc->_index; + textures[i] = gtc->get_view_index(view); } SamplerContext *sc = sampler.prepare_now(_glgsg->get_prepared_objects(), _glgsg); @@ -2962,8 +2897,8 @@ update_shader_texture_bindings(ShaderContext *prev) { if (!_glgsg->update_texture(gtc, force)) { continue; } - _glgsg->apply_texture(gtc); - _glgsg->apply_sampler(i, sampler, gtc); + _glgsg->apply_texture(gtc, view); + _glgsg->apply_sampler(i, sampler, gtc, view); } } diff --git a/panda/src/glstuff/glShaderContext_src.h b/panda/src/glstuff/glShaderContext_src.h index 493da7681d..878941c114 100644 --- a/panda/src/glstuff/glShaderContext_src.h +++ b/panda/src/glstuff/glShaderContext_src.h @@ -93,9 +93,6 @@ private: GLsizei _slider_table_size; GLint _frame_number_loc; GLint _frame_number; -#ifndef OPENGLES - pmap _glsl_uniform_handles; -#endif #ifndef OPENGLES struct StorageBlock { diff --git a/panda/src/glstuff/glTextureContext_src.I b/panda/src/glstuff/glTextureContext_src.I index 51db7538ba..bde6a4d977 100644 --- a/panda/src/glstuff/glTextureContext_src.I +++ b/panda/src/glstuff/glTextureContext_src.I @@ -16,26 +16,46 @@ */ INLINE CLP(TextureContext):: CLP(TextureContext)(CLP(GraphicsStateGuardian) *glgsg, - PreparedGraphicsObjects *pgo, Texture *tex, int view) : - TextureContext(pgo, tex, view) + PreparedGraphicsObjects *pgo, Texture *tex) : + TextureContext(pgo, tex), + _num_views(0) { _glgsg = glgsg; - glGenTextures(1, &_index); - _buffer = 0; + _index = 0; + _indices = &_index; + + _buffer = 0; + _buffers = nullptr; -#ifndef OPENGLES - _handle = 0; - _handle_resident = false; -#endif _has_storage = false; - _simple_loaded = false; _immutable = false; - _uses_mipmaps = false; + _may_reload_with_mipmaps = false; _generate_mipmaps = false; _internal_format = 0; _width = 0; _height = 0; _depth = 0; + _num_levels = 0; _target = GL_NONE; } + +/** + * Returns the index for the given view of the texture. + */ +INLINE GLuint CLP(TextureContext):: +get_view_index(int view) const { + return _indices[std::min(std::max(view, 0), _num_views - 1)]; +} + +/** + * Returns the buffer index for the given view of the texture. + */ +INLINE GLuint CLP(TextureContext):: +get_view_buffer(int view) const { + if (_buffers != nullptr) { + return _buffers[std::min(std::max(view, 0), _num_views - 1)]; + } else { + return 0; + } +} diff --git a/panda/src/glstuff/glTextureContext_src.cxx b/panda/src/glstuff/glTextureContext_src.cxx index 37bad3ae3a..7572ef8a4f 100644 --- a/panda/src/glstuff/glTextureContext_src.cxx +++ b/panda/src/glstuff/glTextureContext_src.cxx @@ -37,53 +37,29 @@ void CLP(TextureContext):: evict_lru() { dequeue_lru(); -#ifndef OPENGLES - if (_handle != 0) { - if (_handle_resident) { - _glgsg->_glMakeTextureHandleNonResident(_handle); - } - _handle_resident = false; - } else -#endif - { - reset_data(); - } - + reset_data(_target); update_data_size_bytes(0); mark_unloaded(); } /** * Resets the texture object to a new one so a new GL texture object can be - * uploaded. + * uploaded. This call also allows the texture target to be changed. */ void CLP(TextureContext):: -reset_data() { -#ifndef OPENGLES - if (_handle != 0 && _handle_resident) { - _glgsg->_glMakeTextureHandleNonResident(_handle); - } -#endif - +reset_data(GLenum target, int num_views) { // Free the texture resources. - glDeleteTextures(1, &_index); + set_num_views(0); - if (_buffer != 0) { - _glgsg->_glDeleteBuffers(1, &_buffer); - _buffer = 0; - } + _target = target; // We still need a valid index number, though, in case we want to re-load // the texture later. - glGenTextures(1, &_index); + set_num_views(num_views); -#ifndef OPENGLES - _handle = 0; - _handle_resident = false; -#endif _has_storage = false; - _simple_loaded = false; _immutable = false; + _may_reload_with_mipmaps = false; #ifndef OPENGLES_1 // Mark the texture as coherent. @@ -118,41 +94,77 @@ get_native_buffer_id() const { } /** - * + * Changes the number of views in the texture. */ -#ifndef OPENGLES void CLP(TextureContext):: -make_handle_resident() { - if (_handle != 0) { - if (!_handle_resident) { - _glgsg->_glMakeTextureHandleResident(_handle); - _handle_resident = true; +set_num_views(int num_views) { + if (_num_views > num_views) { + glDeleteTextures(_num_views - num_views, _indices + _num_views); + + if (_buffers != nullptr) { + _glgsg->_glDeleteBuffers(_num_views - num_views, _buffers + num_views); } - set_resident(true); - } -} + + if (num_views <= 1) { + _index = _indices[0]; + if (_indices != &_index) { + delete[] _indices; + _indices = &_index; + } + +#ifndef OPENGLES_1 + if (_buffers != nullptr) { + _buffer = _buffers[0]; + if (_buffers != &_buffer) { + delete[] _buffers; + _buffers = &_buffer; + } + if (num_views == 0) { + _buffers = nullptr; + } + } #endif - -/** - * Returns a handle for this texture. Once this has been created, the texture - * data may still be updated, but its properties may not. - */ -#ifndef OPENGLES -INLINE GLuint64 CLP(TextureContext):: -get_handle() { - return 0; - if (!_glgsg->_supports_bindless_texture) { - return false; + } } + else if (_num_views == 0 && num_views == 1) { + glGenTextures(1, &_index); + _indices = &_index; - if (_handle == 0) { - _handle = _glgsg->_glGetTextureHandle(_index); - } - - _immutable = true; - return _handle; -} +#ifndef OPENGLES_1 + if (_target == GL_TEXTURE_BUFFER) { + _glgsg->_glGenBuffers(1, &_buffer); + _buffers = &_buffer; + } #endif + } + else if (_num_views < num_views) { + GLuint *new_indices = new GLuint[num_views]; + memcpy(new_indices, _indices, sizeof(GLuint) * _num_views); + glGenTextures(num_views - _num_views, new_indices + _num_views); + if (_indices != &_index) { + delete[] _indices; + } + _indices = new_indices; + +#ifndef OPENGLES_1 + if (_target == GL_TEXTURE_BUFFER) { + GLuint *new_buffers = new GLuint[num_views]; + if (_buffers != nullptr) { + memcpy(new_buffers, _buffers, sizeof(GLuint) * _num_views); + _glgsg->_glGenBuffers(num_views - _num_views, new_buffers + _num_views); + if (_buffers != &_buffer) { + delete[] _buffers; + } + } else { + _glgsg->_glGenBuffers(num_views, new_buffers); + } + _buffers = new_buffers; + } +#endif + } + + _num_views = num_views; +} #ifndef OPENGLES_1 /** diff --git a/panda/src/glstuff/glTextureContext_src.h b/panda/src/glstuff/glTextureContext_src.h index 41a89cb32b..c424488471 100644 --- a/panda/src/glstuff/glTextureContext_src.h +++ b/panda/src/glstuff/glTextureContext_src.h @@ -25,21 +25,20 @@ class CLP(SamplerContext); class EXPCL_GL CLP(TextureContext) : public TextureContext { public: INLINE CLP(TextureContext)(CLP(GraphicsStateGuardian) *glgsg, - PreparedGraphicsObjects *pgo, - Texture *tex, int view); + PreparedGraphicsObjects *pgo, Texture *tex); ALLOC_DELETED_CHAIN(CLP(TextureContext)); virtual ~CLP(TextureContext)(); virtual void evict_lru(); - void reset_data(); + void reset_data(GLenum target, int num_views = 1); virtual uint64_t get_native_id() const; virtual uint64_t get_native_buffer_id() const; -#ifndef OPENGLES - void make_handle_resident(); - GLuint64 get_handle(); -#endif + void set_num_views(int num_views); + + INLINE GLuint get_view_index(int view) const; + INLINE GLuint get_view_buffer(int view) const; #ifdef OPENGLES_1 static constexpr bool needs_barrier(GLbitfield barrier) { return false; }; @@ -48,30 +47,32 @@ public: void mark_incoherent(bool wrote); #endif +private: // This is the GL "name" of the texture object. GLuint _index; // This is only used for buffer textures. GLuint _buffer; -#ifndef OPENGLES - // This is the bindless "handle" to the texture object. - GLuint64 _handle; - bool _handle_resident; -#endif +public: + // Multiview textures have multiple of the above. For a single-view texture, + // these are simply pointers to the above fields. + int _num_views; + GLuint *_indices; + GLuint *_buffers; // These are the parameters that we specified with the last glTexImage2D() // or glTexStorage2D() call. If none of these have changed, we can reload // the texture image with a glTexSubImage2D(). bool _has_storage; - bool _simple_loaded; bool _immutable; - bool _uses_mipmaps; + bool _may_reload_with_mipmaps; bool _generate_mipmaps; GLint _internal_format; GLsizei _width; GLsizei _height; GLsizei _depth; + int _num_levels; GLenum _target; SamplerState _active_sampler; diff --git a/panda/src/glstuff/glmisc_src.cxx b/panda/src/glstuff/glmisc_src.cxx index 2d6db9f654..f223ef266e 100644 --- a/panda/src/glstuff/glmisc_src.cxx +++ b/panda/src/glstuff/glmisc_src.cxx @@ -250,16 +250,6 @@ ConfigVariableBool gl_immutable_texture_storage "for each texture. This improves runtime performance, but " "changing the size or type of a texture will be slower.")); -ConfigVariableBool gl_use_bindless_texture - ("gl-use-bindless-texture", false, - PRC_DESC("Set this to let Panda use OpenGL's bindless texture " - "extension for all textures passed to shaders, for improved " - "performance. This is an experimental feature and comes " - "with a few caveats; for one, it requires that all sampler " - "uniforms have a layout(bindless_sampler) qualifier, and " - "it also requires that the texture properties are not " - "modified after the texture handle has been initialized.")); - ConfigVariableBool gl_enable_memory_barriers ("gl-enable-memory-barriers", true, PRC_DESC("If this is set, Panda will make sure that every write " diff --git a/panda/src/glstuff/glmisc_src.h b/panda/src/glstuff/glmisc_src.h index cb387d81e3..6568c1b2ef 100644 --- a/panda/src/glstuff/glmisc_src.h +++ b/panda/src/glstuff/glmisc_src.h @@ -74,7 +74,6 @@ extern ConfigVariableBool gl_cube_map_seamless; extern ConfigVariableBool gl_dump_compiled_shaders; extern ConfigVariableBool gl_validate_shaders; extern ConfigVariableBool gl_immutable_texture_storage; -extern ConfigVariableBool gl_use_bindless_texture; extern ConfigVariableBool gl_enable_memory_barriers; extern ConfigVariableBool gl_vertex_array_objects; extern ConfigVariableBool gl_fixed_vertex_attrib_locations; diff --git a/panda/src/gobj/preparedGraphicsObjects.cxx b/panda/src/gobj/preparedGraphicsObjects.cxx index 93a5f5c655..b76b052476 100644 --- a/panda/src/gobj/preparedGraphicsObjects.cxx +++ b/panda/src/gobj/preparedGraphicsObjects.cxx @@ -242,7 +242,7 @@ void PreparedGraphicsObjects:: release_texture(TextureContext *tc) { ReMutexHolder holder(_lock); - tc->get_texture()->clear_prepared(tc->get_view(), this); + tc->get_texture()->clear_prepared(this); // We have to set the Texture pointer to NULL at this point, since the // Texture itself might destruct at any time after it has been released. @@ -275,7 +275,7 @@ release_all_textures() { int num_textures = (int)_prepared_textures.size() + (int)_enqueued_textures.size(); for (TextureContext *tc : _prepared_textures) { - tc->get_texture()->clear_prepared(tc->get_view(), this); + tc->get_texture()->clear_prepared(this); tc->_object = nullptr; _released_textures.push_back(tc); @@ -332,13 +332,13 @@ get_num_prepared_textures() const { * the TextureContext will be deleted. */ TextureContext *PreparedGraphicsObjects:: -prepare_texture_now(Texture *tex, int view, GraphicsStateGuardianBase *gsg) { +prepare_texture_now(Texture *tex, GraphicsStateGuardianBase *gsg) { ReMutexHolder holder(_lock); // Ask the GSG to create a brand new TextureContext. There might be several // GSG's sharing the same set of textures; if so, it doesn't matter which of // them creates the context (since they're all shared anyway). - TextureContext *tc = gsg->prepare_texture(tex, view); + TextureContext *tc = gsg->prepare_texture(tex); if (tc != nullptr) { bool prepared = _prepared_textures.insert(tc).second; @@ -1513,13 +1513,11 @@ begin_frame(GraphicsStateGuardianBase *gsg, Thread *current_thread) { qti != _enqueued_textures.end(); ++qti) { Texture *tex = qti->first; - for (int view = 0; view < tex->get_num_views(); ++view) { - TextureContext *tc = tex->prepare_now(view, this, gsg); - if (tc != nullptr) { - gsg->update_texture(tc, true); - if (view == 0 && qti->second != nullptr) { - qti->second->set_result(tc); - } + TextureContext *tc = tex->prepare_now(this, gsg); + if (tc != nullptr) { + gsg->update_texture(tc, true); + if (qti->second != nullptr) { + qti->second->set_result(tc); } } } diff --git a/panda/src/gobj/preparedGraphicsObjects.h b/panda/src/gobj/preparedGraphicsObjects.h index 6e117733c1..fac1ab630d 100644 --- a/panda/src/gobj/preparedGraphicsObjects.h +++ b/panda/src/gobj/preparedGraphicsObjects.h @@ -82,7 +82,7 @@ PUBLISHED: int get_num_queued_textures() const; int get_num_prepared_textures() const; - TextureContext *prepare_texture_now(Texture *tex, int view, + TextureContext *prepare_texture_now(Texture *tex, GraphicsStateGuardianBase *gsg); void enqueue_sampler(const SamplerState &sampler); diff --git a/panda/src/gobj/texture.cxx b/panda/src/gobj/texture.cxx index 27adaa3e27..59ddcdc61e 100644 --- a/panda/src/gobj/texture.cxx +++ b/panda/src/gobj/texture.cxx @@ -1513,6 +1513,39 @@ get_image_modified_pages(UpdateSeq since, int n) const { return result; } + if (n > 0 && cdata->_texture_type == Texture::TT_3d_texture) { + // Don't bother handling this special case, just consider all mipmap pages + // modified. + result.set_range(0, do_get_expected_mipmap_num_pages(cdata, n)); + return result; + } + + size_t num_pages = cdata->_z_size * cdata->_num_views; + for (const ModifiedPageRange &range : cdata->_modified_pages) { + if (range._z_begin >= num_pages) { + break; + } + if (since < range._modified) { + result.set_range(range._z_begin, std::min(range._z_end, num_pages) - range._z_begin); + } + } + + return result; +} + +/** + * Like get_image_modified_pages, but returns the result for a particular view. + */ +SparseArray Texture:: +get_view_modified_pages(UpdateSeq since, int view, int n) const { + CDReader cdata(_cycler); + + SparseArray result; + if (since == cdata->_image_modified) { + // Early-out since no range is more recent than _image_modified. + return result; + } + if (n > 0 && cdata->_texture_type == Texture::TT_3d_texture) { // Don't bother handling this special case, just consider all mipmap pages // modified. @@ -1520,12 +1553,17 @@ get_image_modified_pages(UpdateSeq since, int n) const { return result; } + size_t offset = cdata->_z_size * view; for (const ModifiedPageRange &range : cdata->_modified_pages) { - if (range._z_begin >= cdata->_z_size) { + if (range._z_end <= offset) { + continue; + } + if (range._z_begin >= offset + (size_t)cdata->_z_size) { break; } if (since < range._modified) { - result.set_range(range._z_begin, std::min(range._z_end, (size_t)cdata->_z_size) - range._z_begin); + size_t begin = std::max(range._z_begin, offset) - offset; + result.set_range(begin, std::min(range._z_end - offset, (size_t)cdata->_z_size) - begin); } } @@ -1553,9 +1591,9 @@ prepare(PreparedGraphicsObjects *prepared_objects) { bool Texture:: is_prepared(PreparedGraphicsObjects *prepared_objects) const { MutexHolder holder(_lock); - PreparedViews::const_iterator pvi; - pvi = _prepared_views.find(prepared_objects); - if (pvi != _prepared_views.end()) { + Contexts::const_iterator ci; + ci = _contexts.find(prepared_objects); + if (ci != _contexts.end()) { return true; } return prepared_objects->is_texture_queued(this); @@ -1569,24 +1607,11 @@ is_prepared(PreparedGraphicsObjects *prepared_objects) const { bool Texture:: was_image_modified(PreparedGraphicsObjects *prepared_objects) const { MutexHolder holder(_lock); - CDReader cdata(_cycler); - - PreparedViews::const_iterator pvi; - pvi = _prepared_views.find(prepared_objects); - if (pvi != _prepared_views.end()) { - const Contexts &contexts = (*pvi).second; - for (int view = 0; view < cdata->_num_views; ++view) { - Contexts::const_iterator ci; - ci = contexts.find(view); - if (ci == contexts.end()) { - return true; - } - TextureContext *tc = (*ci).second; - if (tc->was_image_modified()) { - return true; - } - } - return false; + Contexts::const_iterator ci; + ci = _contexts.find(prepared_objects); + if (ci != _contexts.end()) { + TextureContext *tc = (*ci).second; + return tc->was_image_modified(); } return true; } @@ -1601,24 +1626,13 @@ was_image_modified(PreparedGraphicsObjects *prepared_objects) const { size_t Texture:: get_data_size_bytes(PreparedGraphicsObjects *prepared_objects) const { MutexHolder holder(_lock); - CDReader cdata(_cycler); - - PreparedViews::const_iterator pvi; - size_t total_size = 0; - pvi = _prepared_views.find(prepared_objects); - if (pvi != _prepared_views.end()) { - const Contexts &contexts = (*pvi).second; - for (int view = 0; view < cdata->_num_views; ++view) { - Contexts::const_iterator ci; - ci = contexts.find(view); - if (ci != contexts.end()) { - TextureContext *tc = (*ci).second; - total_size += tc->get_data_size_bytes(); - } - } + Contexts::const_iterator ci; + ci = _contexts.find(prepared_objects); + if (ci != _contexts.end()) { + TextureContext *tc = (*ci).second; + return tc->get_data_size_bytes(); } - - return total_size; + return 0; } /** @@ -1628,24 +1642,13 @@ get_data_size_bytes(PreparedGraphicsObjects *prepared_objects) const { bool Texture:: get_active(PreparedGraphicsObjects *prepared_objects) const { MutexHolder holder(_lock); - CDReader cdata(_cycler); - - PreparedViews::const_iterator pvi; - pvi = _prepared_views.find(prepared_objects); - if (pvi != _prepared_views.end()) { - const Contexts &contexts = (*pvi).second; - for (int view = 0; view < cdata->_num_views; ++view) { - Contexts::const_iterator ci; - ci = contexts.find(view); - if (ci != contexts.end()) { - TextureContext *tc = (*ci).second; - if (tc->get_active()) { - return true; - } - } - } + Contexts::const_iterator ci; + ci = _contexts.find(prepared_objects); + if (ci != _contexts.end()) { + TextureContext *tc = (*ci).second; + return tc->get_active(); } - return false; + return 0; } /** @@ -1655,24 +1658,13 @@ get_active(PreparedGraphicsObjects *prepared_objects) const { bool Texture:: get_resident(PreparedGraphicsObjects *prepared_objects) const { MutexHolder holder(_lock); - CDReader cdata(_cycler); - - PreparedViews::const_iterator pvi; - pvi = _prepared_views.find(prepared_objects); - if (pvi != _prepared_views.end()) { - const Contexts &contexts = (*pvi).second; - for (int view = 0; view < cdata->_num_views; ++view) { - Contexts::const_iterator ci; - ci = contexts.find(view); - if (ci != contexts.end()) { - TextureContext *tc = (*ci).second; - if (tc->get_resident()) { - return true; - } - } - } + Contexts::const_iterator ci; + ci = _contexts.find(prepared_objects); + if (ci != _contexts.end()) { + TextureContext *tc = (*ci).second; + return tc->get_resident(); } - return false; + return 0; } /** @@ -1681,20 +1673,15 @@ get_resident(PreparedGraphicsObjects *prepared_objects) const { */ bool Texture:: release(PreparedGraphicsObjects *prepared_objects) { - MutexHolder holder(_lock); - PreparedViews::iterator pvi; - pvi = _prepared_views.find(prepared_objects); - if (pvi != _prepared_views.end()) { - Contexts temp; - temp.swap((*pvi).second); - Contexts::iterator ci; - for (ci = temp.begin(); ci != temp.end(); ++ci) { - TextureContext *tc = (*ci).second; - if (tc != nullptr) { - prepared_objects->release_texture(tc); - } + Contexts::iterator ci; + ci = _contexts.find(prepared_objects); + if (ci != _contexts.end()) { + TextureContext *tc = (*ci).second; + if (tc != nullptr) { + prepared_objects->release_texture(tc); + } else { + _contexts.erase(ci); } - _prepared_views.erase(pvi); } // Maybe it wasn't prepared yet, but it's about to be. @@ -1709,25 +1696,19 @@ int Texture:: release_all() { MutexHolder holder(_lock); - // We have to traverse a copy of the _prepared_views list, because the + // We have to traverse a copy of the _contexts list, because the // PreparedGraphicsObjects object will call clear_prepared() in response to // each release_texture(), and we don't want to be modifying the - // _prepared_views list while we're traversing it. - PreparedViews temp; - temp.swap(_prepared_views); - int num_freed = (int)temp.size(); + // _contexts list while we're traversing it. + Contexts temp = _contexts; + int num_freed = (int)_contexts.size(); - PreparedViews::iterator pvi; - for (pvi = temp.begin(); pvi != temp.end(); ++pvi) { - PreparedGraphicsObjects *prepared_objects = (*pvi).first; - Contexts temp; - temp.swap((*pvi).second); - Contexts::iterator ci; - for (ci = temp.begin(); ci != temp.end(); ++ci) { - TextureContext *tc = (*ci).second; - if (tc != nullptr) { - prepared_objects->release_texture(tc); - } + Contexts::const_iterator ci; + for (ci = temp.begin(); ci != temp.end(); ++ci) { + PreparedGraphicsObjects *prepared_objects = (*ci).first; + TextureContext *tc = (*ci).second; + if (tc != nullptr) { + prepared_objects->release_texture(tc); } } @@ -2088,29 +2069,31 @@ set_orig_file_size(int x, int y, int z) { * be rendered. */ TextureContext *Texture:: -prepare_now(int view, - PreparedGraphicsObjects *prepared_objects, +prepare_now(PreparedGraphicsObjects *prepared_objects, GraphicsStateGuardianBase *gsg) { MutexHolder holder(_lock); - CDReader cdata(_cycler); - // Don't exceed the actual number of views. - view = max(min(view, cdata->_num_views - 1), 0); - - // Get the list of PreparedGraphicsObjects for this view. - Contexts &contexts = _prepared_views[prepared_objects]; - Contexts::const_iterator pvi; - pvi = contexts.find(view); - if (pvi != contexts.end()) { - return (*pvi).second; + Contexts::const_iterator ci; + ci = _contexts.find(prepared_objects); + if (ci != _contexts.end()) { + return (*ci).second; } - TextureContext *tc = prepared_objects->prepare_texture_now(this, view, gsg); - contexts[view] = tc; + TextureContext *tc = prepared_objects->prepare_texture_now(this, gsg); + _contexts[prepared_objects] = tc; return tc; } +/** + * @deprecated See prepare_now() without a view parameter. + */ +TextureContext *Texture:: +prepare_now(int view, PreparedGraphicsObjects *prepared_objects, + GraphicsStateGuardianBase *gsg) { + return prepare_now(prepared_objects, gsg); +} + /** * Returns the smallest power of 2 greater than or equal to value. */ @@ -9277,20 +9260,11 @@ read_dds_level_bc5(Texture *tex, CData *cdata, const DDSHeader &header, int n, i * never be called by user code. */ void Texture:: -clear_prepared(int view, PreparedGraphicsObjects *prepared_objects) { - PreparedViews::iterator pvi; - pvi = _prepared_views.find(prepared_objects); - if (pvi != _prepared_views.end()) { - Contexts &contexts = (*pvi).second; - Contexts::iterator ci; - ci = contexts.find(view); - if (ci != contexts.end()) { - contexts.erase(ci); - } - - if (contexts.empty()) { - _prepared_views.erase(pvi); - } +clear_prepared(PreparedGraphicsObjects *prepared_objects) { + Contexts::iterator ci; + ci = _contexts.find(prepared_objects); + if (ci != _contexts.end()) { + _contexts.erase(ci); } } diff --git a/panda/src/gobj/texture.h b/panda/src/gobj/texture.h index d1e3b1ecb4..f6ec5eb1f2 100644 --- a/panda/src/gobj/texture.h +++ b/panda/src/gobj/texture.h @@ -528,6 +528,7 @@ PUBLISHED: MAKE_PROPERTY(image_modified, get_image_modified); SparseArray get_image_modified_pages(UpdateSeq since, int n = 0) const; + SparseArray get_view_modified_pages(UpdateSeq since, int view, int n = 0) const; INLINE bool has_auto_texture_scale() const; INLINE AutoTextureScale get_auto_texture_scale() const; @@ -597,6 +598,8 @@ PUBLISHED: MAKE_PROPERTY(post_load_store_cache, get_post_load_store_cache, set_post_load_store_cache); + TextureContext *prepare_now(PreparedGraphicsObjects *prepared_objects, + GraphicsStateGuardianBase *gsg); TextureContext *prepare_now(int view, PreparedGraphicsObjects *prepared_objects, GraphicsStateGuardianBase *gsg); @@ -859,7 +862,7 @@ private: const DDSHeader &header, int n, std::istream &in); - void clear_prepared(int view, PreparedGraphicsObjects *prepared_objects); + void clear_prepared(PreparedGraphicsObjects *prepared_objects); static void consider_downgrade(PNMImage &pnmimage, int num_channels, const std::string &name); @@ -1066,9 +1069,8 @@ protected: // conversely keeps a list (a set) of all the Textures that have been // prepared there. When either destructs, it removes itself from the // other's list. - typedef pmap Contexts; - typedef pmap PreparedViews; - PreparedViews _prepared_views; + typedef pmap Contexts; + Contexts _contexts; // It is common, when using normal maps, specular maps, gloss maps, and // such, to use a file naming convention where the filenames of the special diff --git a/panda/src/gobj/textureContext.I b/panda/src/gobj/textureContext.I index c7994a4bbc..f65caa239a 100644 --- a/panda/src/gobj/textureContext.I +++ b/panda/src/gobj/textureContext.I @@ -15,10 +15,9 @@ * */ INLINE TextureContext:: -TextureContext(PreparedGraphicsObjects *pgo, Texture *tex, int view) : +TextureContext(PreparedGraphicsObjects *pgo, Texture *tex) : BufferContext(&pgo->_texture_residency, tex), - AdaptiveLruPage(0), - _view(view) + AdaptiveLruPage(0) { } @@ -31,15 +30,13 @@ get_texture() const { } /** - * Returns the specific view of a multiview texture this context represents. - * In the usual case, with a non-multiview texture, this will be 0. + * @deprecated since 1.11.0: always returns 0. */ INLINE int TextureContext:: get_view() const { - return _view; + return 0; } - /** * Returns true if the texture properties or image have been modified since * the last time mark_loaded() was called. @@ -103,6 +100,15 @@ get_image_modified_pages(int n) const { return get_texture()->get_image_modified_pages(_image_modified, n); } +/** + * Returns a SparseArray indicating which pages of the texture have been + * modified since the last call to mark_loaded(). + */ +INLINE SparseArray TextureContext:: +get_view_modified_pages(int view, int n) const { + return get_texture()->get_view_modified_pages(_image_modified, view, n); +} + /** * Should be called (usually by a derived class) when the on-card size of this * object has changed. diff --git a/panda/src/gobj/textureContext.h b/panda/src/gobj/textureContext.h index de828781e2..765509ec65 100644 --- a/panda/src/gobj/textureContext.h +++ b/panda/src/gobj/textureContext.h @@ -32,7 +32,7 @@ */ class EXPCL_PANDA_GOBJ TextureContext : public BufferContext, public AdaptiveLruPage { public: - INLINE TextureContext(PreparedGraphicsObjects *pgo, Texture *tex, int view); + INLINE TextureContext(PreparedGraphicsObjects *pgo, Texture *tex); PUBLISHED: INLINE Texture *get_texture() const; @@ -49,6 +49,7 @@ PUBLISHED: INLINE UpdateSeq get_image_modified() const; INLINE SparseArray get_image_modified_pages(int n = 0) const; + INLINE SparseArray get_view_modified_pages(int view, int n = 0) const; public: INLINE void update_data_size_bytes(size_t new_data_size_bytes); @@ -60,7 +61,6 @@ public: virtual void write(std::ostream &out, int indent_level) const; private: - int _view; UpdateSeq _properties_modified; UpdateSeq _image_modified; diff --git a/panda/src/gsgbase/graphicsStateGuardianBase.h b/panda/src/gsgbase/graphicsStateGuardianBase.h index e2da6cc2d6..80d31f5c3c 100644 --- a/panda/src/gsgbase/graphicsStateGuardianBase.h +++ b/panda/src/gsgbase/graphicsStateGuardianBase.h @@ -147,7 +147,7 @@ public: virtual PreparedGraphicsObjects *get_prepared_objects()=0; #endif - virtual TextureContext *prepare_texture(Texture *tex, int view)=0; + virtual TextureContext *prepare_texture(Texture *tex)=0; virtual bool update_texture(TextureContext *tc, bool force)=0; virtual void release_texture(TextureContext *tc)=0; virtual void release_textures(const pvector &contexts)=0; diff --git a/panda/src/tinydisplay/tinyGraphicsStateGuardian.cxx b/panda/src/tinydisplay/tinyGraphicsStateGuardian.cxx index 17b7ac24d4..5e723cece8 100644 --- a/panda/src/tinydisplay/tinyGraphicsStateGuardian.cxx +++ b/panda/src/tinydisplay/tinyGraphicsStateGuardian.cxx @@ -1354,12 +1354,12 @@ framebuffer_copy_to_texture(Texture *tex, int view, int z, tex->setup_2d_texture(w, h, Texture::T_unsigned_byte, Texture::F_rgba); - TextureContext *tc = tex->prepare_now(view, get_prepared_objects(), this); + TextureContext *tc = tex->prepare_now(get_prepared_objects(), this); nassertr(tc != nullptr, false); TinyTextureContext *gtc = DCAST(TinyTextureContext, tc); GLTexture *gltex = >c->_gltex; - if (!setup_gltex(gltex, tex->get_x_size(), tex->get_y_size(), 1)) { + if (!setup_gltex(gltex, tex->get_x_size(), tex->get_y_size(), tex->get_num_views(), 1)) { return false; } LColor border_color = tex->get_border_color(); @@ -1369,7 +1369,7 @@ framebuffer_copy_to_texture(Texture *tex, int view, int z, gltex->border_color.v[2] = border_color[2]; gltex->border_color.v[3] = border_color[3]; - PIXEL *ip = gltex->levels[0].pixmap + gltex->xsize * gltex->ysize; + PIXEL *ip = gltex->views[view].levels[0].pixmap + gltex->xsize * gltex->ysize; PIXEL *fo = _c->zb->pbuf + xo + yo * _c->zb->linesize / PSZB; for (int y = 0; y < gltex->ysize; ++y) { ip -= gltex->xsize; @@ -1602,7 +1602,7 @@ set_state_and_transform(const RenderState *target, * call Texture::prepare(). */ TextureContext *TinyGraphicsStateGuardian:: -prepare_texture(Texture *tex, int view) { +prepare_texture(Texture *tex) { switch (tex->get_texture_type()) { case Texture::TT_1d_texture: case Texture::TT_2d_texture: @@ -1629,7 +1629,7 @@ prepare_texture(Texture *tex, int view) { } */ - TinyTextureContext *gtc = new TinyTextureContext(_prepared_objects, tex, view); + TinyTextureContext *gtc = new TinyTextureContext(_prepared_objects, tex); return gtc; } @@ -1652,7 +1652,7 @@ update_texture(TextureContext *tc, bool force) { GLTexture *gltex = >c->_gltex; - if (gtc->was_image_modified() || gltex->num_levels == 0) { + if (gtc->was_image_modified() || gltex->num_views == 0 || gltex->num_levels == 0) { // If the texture image was modified, reload the texture. Texture *tex = gtc->get_texture(); bool okflag = upload_texture(gtc, force, tex->uses_mipmaps()); @@ -1678,7 +1678,7 @@ update_texture(TextureContext *tc, bool force) { * (and if get_incomplete_render() is true). */ bool TinyGraphicsStateGuardian:: -update_texture(TextureContext *tc, bool force, int stage_index, bool uses_mipmaps) { +update_texture(TextureContext *tc, int view, bool force, int stage_index, bool uses_mipmaps) { if (!update_texture(tc, force)) { return false; } @@ -1699,8 +1699,15 @@ update_texture(TextureContext *tc, bool force, int stage_index, bool uses_mipmap _c->current_textures[stage_index] = gltex; + if (view < 0) { + view = 0; + } + if (view >= gltex->num_views) { + view = gltex->num_views - 1; + } + ZTextureDef *texture_def = &_c->zb->current_textures[stage_index]; - texture_def->levels = gltex->levels; + texture_def->levels = gltex->views[view].levels; texture_def->s_max = gltex->s_max; texture_def->t_max = gltex->t_max; @@ -2155,7 +2162,7 @@ do_issue_texture() { nassertv(texture != nullptr); int view = get_current_tex_view_offset() + stage->get_tex_view_offset(); - TextureContext *tc = texture->prepare_now(view, _prepared_objects, this); + TextureContext *tc = texture->prepare_now(_prepared_objects, this); if (tc == nullptr) { // Something wrong with this texture; skip it. return; @@ -2165,7 +2172,7 @@ do_issue_texture() { const SamplerState &sampler = _target_texture->get_on_sampler(stage); // Then, turn on the current texture mode. - if (!update_texture(tc, false, si, sampler.uses_mipmaps())) { + if (!update_texture(tc, view, false, si, sampler.uses_mipmaps())) { return; } @@ -2418,7 +2425,7 @@ upload_texture(TinyTextureContext *gtc, bool force, bool uses_mipmaps) { << num_levels << ", uses_mipmaps = " << uses_mipmaps << "\n"; } - if (!setup_gltex(gltex, tex->get_x_size(), tex->get_y_size(), num_levels)) { + if (!setup_gltex(gltex, tex->get_x_size(), tex->get_y_size(), tex->get_num_views(), num_levels)) { return false; } LColor border_color = tex->get_border_color(); @@ -2432,78 +2439,80 @@ upload_texture(TinyTextureContext *gtc, bool force, bool uses_mipmaps) { int xsize = gltex->xsize; int ysize = gltex->ysize; - for (int level = 0; level < gltex->num_levels; ++level) { - ZTextureLevel *dest = &gltex->levels[level]; + for (int view = 0; view < gltex->num_views; ++view) { + for (int level = 0; level < gltex->num_levels; ++level) { + ZTextureLevel *dest = &gltex->views[view].levels[level]; - if (tex->has_ram_mipmap_image(level)) { - switch (tex->get_format()) { - case Texture::F_rgb: - case Texture::F_rgb5: - case Texture::F_rgb8: - case Texture::F_rgb12: - case Texture::F_rgb332: - copy_rgb_image(dest, xsize, ysize, gtc, level); - break; + if (tex->has_ram_mipmap_image(level)) { + switch (tex->get_format()) { + case Texture::F_rgb: + case Texture::F_rgb5: + case Texture::F_rgb8: + case Texture::F_rgb12: + case Texture::F_rgb332: + copy_rgb_image(dest, xsize, ysize, gtc, view, level); + break; - case Texture::F_rgba: - case Texture::F_rgbm: - case Texture::F_rgba4: - case Texture::F_rgba5: - case Texture::F_rgba8: - case Texture::F_rgba12: - case Texture::F_rgba16: - case Texture::F_rgba32: - copy_rgba_image(dest, xsize, ysize, gtc, level); - break; + case Texture::F_rgba: + case Texture::F_rgbm: + case Texture::F_rgba4: + case Texture::F_rgba5: + case Texture::F_rgba8: + case Texture::F_rgba12: + case Texture::F_rgba16: + case Texture::F_rgba32: + copy_rgba_image(dest, xsize, ysize, gtc, view, level); + break; - case Texture::F_luminance: - copy_lum_image(dest, xsize, ysize, gtc, level); - break; + case Texture::F_luminance: + copy_lum_image(dest, xsize, ysize, gtc, view, level); + break; - case Texture::F_red: - copy_one_channel_image(dest, xsize, ysize, gtc, level, 0); - break; + case Texture::F_red: + copy_one_channel_image(dest, xsize, ysize, gtc, view, level, 0); + break; - case Texture::F_green: - copy_one_channel_image(dest, xsize, ysize, gtc, level, 1); - break; + case Texture::F_green: + copy_one_channel_image(dest, xsize, ysize, gtc, view, level, 1); + break; - case Texture::F_blue: - copy_one_channel_image(dest, xsize, ysize, gtc, level, 2); - break; + case Texture::F_blue: + copy_one_channel_image(dest, xsize, ysize, gtc, view, level, 2); + break; - case Texture::F_alpha: - copy_alpha_image(dest, xsize, ysize, gtc, level); - break; + case Texture::F_alpha: + copy_alpha_image(dest, xsize, ysize, gtc, view, level); + break; - case Texture::F_luminance_alphamask: - case Texture::F_luminance_alpha: - copy_la_image(dest, xsize, ysize, gtc, level); - break; + case Texture::F_luminance_alphamask: + case Texture::F_luminance_alpha: + copy_la_image(dest, xsize, ysize, gtc, view, level); + break; - default: - tinydisplay_cat.error() - << "Unsupported texture format " - << tex->get_format() << "!\n"; - return false; - } - } else { - // Fill the mipmap with a solid color. - LColor scaled = tex->get_clear_color().fmin(LColor(1)).fmax(LColor::zero()); - scaled *= 255; - unsigned int clear = RGBA8_TO_PIXEL((int)scaled[0], (int)scaled[1], - (int)scaled[2], (int)scaled[3]); - unsigned int *dpix = (unsigned int *)dest->pixmap; - int pixel_count = xsize * ysize; - while (pixel_count-- > 0) { - *dpix = clear; - ++dpix; + default: + tinydisplay_cat.error() + << "Unsupported texture format " + << tex->get_format() << "!\n"; + return false; + } + } else { + // Fill the mipmap with a solid color. + LColor scaled = tex->get_clear_color().fmin(LColor(1)).fmax(LColor::zero()); + scaled *= 255; + unsigned int clear = RGBA8_TO_PIXEL((int)scaled[0], (int)scaled[1], + (int)scaled[2], (int)scaled[3]); + unsigned int *dpix = (unsigned int *)dest->pixmap; + int pixel_count = xsize * ysize; + while (pixel_count-- > 0) { + *dpix = clear; + ++dpix; + } } + + bytecount += xsize * ysize * 4; + xsize = max(xsize >> 1, 1); + ysize = max(ysize >> 1, 1); } - - bytecount += xsize * ysize * 4; - xsize = max(xsize >> 1, 1); - ysize = max(ysize >> 1, 1); } gtc->update_data_size_bytes(bytecount); @@ -2545,7 +2554,7 @@ upload_simple_texture(TinyTextureContext *gtc) { << "loading simple image for " << tex->get_name() << "\n"; } - if (!setup_gltex(gltex, width, height, 1)) { + if (!setup_gltex(gltex, width, height, 1, 1)) { return false; } LColor border_color = tex->get_border_color(); @@ -2555,7 +2564,7 @@ upload_simple_texture(TinyTextureContext *gtc) { gltex->border_color.v[2] = border_color[2]; gltex->border_color.v[3] = border_color[3]; - ZTextureLevel *dest = &gltex->levels[0]; + ZTextureLevel *dest = &gltex->views[0].levels[0]; memcpy(dest->pixmap, image_ptr, image_size); gtc->mark_loaded(); @@ -2569,7 +2578,7 @@ upload_simple_texture(TinyTextureContext *gtc) { * texture is a valid size, false otherwise. */ bool TinyGraphicsStateGuardian:: -setup_gltex(GLTexture *gltex, int x_size, int y_size, int num_levels) { +setup_gltex(GLTexture *gltex, int x_size, int y_size, int num_views, int num_levels) { if (x_size == 0 || y_size == 0) { // A texture without pixels gets turned into a 1x1 texture. x_size = 1; @@ -2588,6 +2597,7 @@ setup_gltex(GLTexture *gltex, int x_size, int y_size, int num_levels) { return false; } + num_views = max(num_views, 1); num_levels = min(num_levels, MAX_MIPMAP_LEVELS); gltex->xsize = x_size; @@ -2601,7 +2611,7 @@ setup_gltex(GLTexture *gltex, int x_size, int y_size, int num_levels) { // We allocate one big buffer, large enough to include all the mipmap // levels, and index into that buffer for each level. This cuts down on the // number of individual alloc calls we have to make for each texture. - int total_bytecount = 0; + int view_size = 0; // Count up the total bytes required for all mipmap levels. { @@ -2609,12 +2619,14 @@ setup_gltex(GLTexture *gltex, int x_size, int y_size, int num_levels) { int y = y_size; for (int level = 0; level < num_levels; ++level) { int bytecount = x * y * 4; - total_bytecount += bytecount; + view_size += bytecount; x = max((x >> 1), 1); y = max((y >> 1), 1); } } + int total_bytecount = view_size * num_views; + if (gltex->total_bytecount != total_bytecount) { if (gltex->allocated_buffer != nullptr) { TinyTextureContext::get_class_type().deallocate_array(gltex->allocated_buffer); @@ -2623,37 +2635,48 @@ setup_gltex(GLTexture *gltex, int x_size, int y_size, int num_levels) { gltex->total_bytecount = total_bytecount; } + if (num_views != gltex->num_views) { + if (gltex->views != nullptr) { + TinyTextureContext::get_class_type().deallocate_array(gltex->views); + } + + gltex->views = (ZTextureView *)TinyTextureContext::get_class_type().allocate_array(sizeof(ZTextureView) * num_views); + gltex->num_views = num_views; + } + char *next_buffer = (char *)gltex->allocated_buffer; char *end_of_buffer = next_buffer + total_bytecount; - int level = 0; - ZTextureLevel *dest = nullptr; - while (level < num_levels) { - dest = &gltex->levels[level]; - int bytecount = x_size * y_size * 4; - dest->pixmap = (PIXEL *)next_buffer; - next_buffer += bytecount; - nassertr(next_buffer <= end_of_buffer, false); + for (int view = 0; view < num_views; ++view) { + int level = 0; + ZTextureLevel *dest = nullptr; + while (level < num_levels) { + dest = &gltex->views[view].levels[level]; + int bytecount = x_size * y_size * 4; + dest->pixmap = (PIXEL *)next_buffer; + next_buffer += bytecount; + nassertr(next_buffer <= end_of_buffer, false); - dest->s_mask = ((1 << (s_bits + ZB_POINT_ST_FRAC_BITS)) - (1 << ZB_POINT_ST_FRAC_BITS)) << level; - dest->t_mask = ((1 << (t_bits + ZB_POINT_ST_FRAC_BITS)) - (1 << ZB_POINT_ST_FRAC_BITS)) << level; - dest->s_shift = (ZB_POINT_ST_FRAC_BITS + level); - dest->t_shift = (ZB_POINT_ST_FRAC_BITS - s_bits + level); + dest->s_mask = ((1 << (s_bits + ZB_POINT_ST_FRAC_BITS)) - (1 << ZB_POINT_ST_FRAC_BITS)) << level; + dest->t_mask = ((1 << (t_bits + ZB_POINT_ST_FRAC_BITS)) - (1 << ZB_POINT_ST_FRAC_BITS)) << level; + dest->s_shift = (ZB_POINT_ST_FRAC_BITS + level); + dest->t_shift = (ZB_POINT_ST_FRAC_BITS - s_bits + level); - x_size = max((x_size >> 1), 1); - y_size = max((y_size >> 1), 1); - s_bits = max(s_bits - 1, 0); - t_bits = max(t_bits - 1, 0); + x_size = max((x_size >> 1), 1); + y_size = max((y_size >> 1), 1); + s_bits = max(s_bits - 1, 0); + t_bits = max(t_bits - 1, 0); - ++level; - } + ++level; + } - // Fill out the remaining mipmap arrays with copies of the last level, so we - // don't have to be concerned with running off the end of this array while - // scanning out triangles. - while (level < MAX_MIPMAP_LEVELS) { - gltex->levels[level] = *dest; - ++level; + // Fill out the remaining mipmap arrays with copies of the last level, so we + // don't have to be concerned with running off the end of this array while + // scanning out triangles. + while (level < MAX_MIPMAP_LEVELS) { + gltex->views[view].levels[level] = *dest; + ++level; + } } return true; @@ -2682,7 +2705,7 @@ get_tex_shift(int orig_size) { * indicated ZTexture pixmap. */ void TinyGraphicsStateGuardian:: -copy_lum_image(ZTextureLevel *dest, int xsize, int ysize, TinyTextureContext *gtc, int level) { +copy_lum_image(ZTextureLevel *dest, int xsize, int ysize, TinyTextureContext *gtc, int view, int level) { Texture *tex = gtc->get_texture(); nassertv(tex->get_num_components() == 1); nassertv(tex->get_expected_mipmap_x_size(level) == xsize && @@ -2692,7 +2715,7 @@ copy_lum_image(ZTextureLevel *dest, int xsize, int ysize, TinyTextureContext *gt nassertv(!src_image.is_null()); const unsigned char *src = src_image.p(); size_t view_size = tex->get_ram_mipmap_view_size(level); - src += view_size * gtc->get_view(); + src += view_size * view; // Component width, and offset to the high-order byte. int cw = tex->get_component_width(); @@ -2720,7 +2743,7 @@ copy_lum_image(ZTextureLevel *dest, int xsize, int ysize, TinyTextureContext *gt * indicated ZTexture pixmap. */ void TinyGraphicsStateGuardian:: -copy_alpha_image(ZTextureLevel *dest, int xsize, int ysize, TinyTextureContext *gtc, int level) { +copy_alpha_image(ZTextureLevel *dest, int xsize, int ysize, TinyTextureContext *gtc, int view, int level) { Texture *tex = gtc->get_texture(); nassertv(tex->get_num_components() == 1); @@ -2728,7 +2751,7 @@ copy_alpha_image(ZTextureLevel *dest, int xsize, int ysize, TinyTextureContext * nassertv(!src_image.is_null()); const unsigned char *src = src_image.p(); size_t view_size = tex->get_ram_mipmap_view_size(level); - src += view_size * gtc->get_view(); + src += view_size * view; // Component width, and offset to the high-order byte. int cw = tex->get_component_width(); @@ -2756,7 +2779,7 @@ copy_alpha_image(ZTextureLevel *dest, int xsize, int ysize, TinyTextureContext * * green, or blue) from the texture into the indicated ZTexture pixmap. */ void TinyGraphicsStateGuardian:: -copy_one_channel_image(ZTextureLevel *dest, int xsize, int ysize, TinyTextureContext *gtc, int level, int channel) { +copy_one_channel_image(ZTextureLevel *dest, int xsize, int ysize, TinyTextureContext *gtc, int view, int level, int channel) { Texture *tex = gtc->get_texture(); nassertv(tex->get_num_components() == 1); @@ -2764,7 +2787,7 @@ copy_one_channel_image(ZTextureLevel *dest, int xsize, int ysize, TinyTextureCon nassertv(!src_image.is_null()); const unsigned char *src = src_image.p(); size_t view_size = tex->get_ram_mipmap_view_size(level); - src += view_size * gtc->get_view(); + src += view_size * view; // Component width, and offset to the high-order byte. int cw = tex->get_component_width(); @@ -2821,7 +2844,7 @@ copy_one_channel_image(ZTextureLevel *dest, int xsize, int ysize, TinyTextureCon * into the indicated ZTexture pixmap. */ void TinyGraphicsStateGuardian:: -copy_la_image(ZTextureLevel *dest, int xsize, int ysize, TinyTextureContext *gtc, int level) { +copy_la_image(ZTextureLevel *dest, int xsize, int ysize, TinyTextureContext *gtc, int view, int level) { Texture *tex = gtc->get_texture(); nassertv(tex->get_num_components() == 2); @@ -2829,7 +2852,7 @@ copy_la_image(ZTextureLevel *dest, int xsize, int ysize, TinyTextureContext *gtc nassertv(!src_image.is_null()); const unsigned char *src = src_image.p(); size_t view_size = tex->get_ram_mipmap_view_size(level); - src += view_size * gtc->get_view(); + src += view_size * view; // Component width, and offset to the high-order byte. int cw = tex->get_component_width(); @@ -2858,7 +2881,7 @@ copy_la_image(ZTextureLevel *dest, int xsize, int ysize, TinyTextureContext *gtc * indicated ZTexture pixmap. */ void TinyGraphicsStateGuardian:: -copy_rgb_image(ZTextureLevel *dest, int xsize, int ysize, TinyTextureContext *gtc, int level) { +copy_rgb_image(ZTextureLevel *dest, int xsize, int ysize, TinyTextureContext *gtc, int view, int level) { Texture *tex = gtc->get_texture(); nassertv(tex->get_num_components() == 3); @@ -2866,7 +2889,7 @@ copy_rgb_image(ZTextureLevel *dest, int xsize, int ysize, TinyTextureContext *gt nassertv(!src_image.is_null()); const unsigned char *src = src_image.p(); size_t view_size = tex->get_ram_mipmap_view_size(level); - src += view_size * gtc->get_view(); + src += view_size * view; // Component width, and offset to the high-order byte. int cw = tex->get_component_width(); @@ -2895,7 +2918,7 @@ copy_rgb_image(ZTextureLevel *dest, int xsize, int ysize, TinyTextureContext *gt * indicated ZTexture pixmap. */ void TinyGraphicsStateGuardian:: -copy_rgba_image(ZTextureLevel *dest, int xsize, int ysize, TinyTextureContext *gtc, int level) { +copy_rgba_image(ZTextureLevel *dest, int xsize, int ysize, TinyTextureContext *gtc, int view, int level) { Texture *tex = gtc->get_texture(); nassertv(tex->get_num_components() == 4); @@ -2903,7 +2926,7 @@ copy_rgba_image(ZTextureLevel *dest, int xsize, int ysize, TinyTextureContext *g nassertv(!src_image.is_null()); const unsigned char *src = src_image.p(); size_t view_size = tex->get_ram_mipmap_view_size(level); - src += view_size * gtc->get_view(); + src += view_size * view; // Component width, and offset to the high-order byte. int cw = tex->get_component_width(); diff --git a/panda/src/tinydisplay/tinyGraphicsStateGuardian.h b/panda/src/tinydisplay/tinyGraphicsStateGuardian.h index 5f569fc1c5..3a7d3374c0 100644 --- a/panda/src/tinydisplay/tinyGraphicsStateGuardian.h +++ b/panda/src/tinydisplay/tinyGraphicsStateGuardian.h @@ -84,9 +84,9 @@ public: virtual void set_state_and_transform(const RenderState *state, const TransformState *transform); - virtual TextureContext *prepare_texture(Texture *tex, int view); + virtual TextureContext *prepare_texture(Texture *tex); virtual bool update_texture(TextureContext *tc, bool force); - bool update_texture(TextureContext *tc, bool force, int stage_index, bool uses_mipmaps); + bool update_texture(TextureContext *tc, int view, bool force, int stage_index, bool uses_mipmaps); virtual void release_texture(TextureContext *tc); virtual void do_issue_light(); @@ -112,15 +112,15 @@ private: bool apply_texture(TextureContext *tc); bool upload_texture(TinyTextureContext *gtc, bool force, bool uses_mipmaps); bool upload_simple_texture(TinyTextureContext *gtc); - bool setup_gltex(GLTexture *gltex, int x_size, int y_size, int num_levels); + bool setup_gltex(GLTexture *gltex, int x_size, int y_size, int num_views, int num_levels); int get_tex_shift(int orig_size); - static void copy_lum_image(ZTextureLevel *dest, int xsize, int ysize, TinyTextureContext *gtc, int level); - static void copy_alpha_image(ZTextureLevel *dest, int xsize, int ysize, TinyTextureContext *gtc, int level); - static void copy_one_channel_image(ZTextureLevel *dest, int xsize, int ysize, TinyTextureContext *gtc, int level, int channel); - static void copy_la_image(ZTextureLevel *dest, int xsize, int ysize, TinyTextureContext *gtc, int level); - static void copy_rgb_image(ZTextureLevel *dest, int xsize, int ysize, TinyTextureContext *gtc, int level); - static void copy_rgba_image(ZTextureLevel *dest, int xsize, int ysize, TinyTextureContext *gtc, int level); + static void copy_lum_image(ZTextureLevel *dest, int xsize, int ysize, TinyTextureContext *gtc, int view, int level); + static void copy_alpha_image(ZTextureLevel *dest, int xsize, int ysize, TinyTextureContext *gtc, int view, int level); + static void copy_one_channel_image(ZTextureLevel *dest, int xsize, int ysize, TinyTextureContext *gtc, int view, int level, int channel); + static void copy_la_image(ZTextureLevel *dest, int xsize, int ysize, TinyTextureContext *gtc, int view, int level); + static void copy_rgb_image(ZTextureLevel *dest, int xsize, int ysize, TinyTextureContext *gtc, int view, int level); + static void copy_rgba_image(ZTextureLevel *dest, int xsize, int ysize, TinyTextureContext *gtc, int view, int level); void setup_material(GLMaterial *gl_material, const Material *material); void do_auto_rescale_normal(); diff --git a/panda/src/tinydisplay/tinyTextureContext.I b/panda/src/tinydisplay/tinyTextureContext.I index 348c748228..f14097ebf9 100644 --- a/panda/src/tinydisplay/tinyTextureContext.I +++ b/panda/src/tinydisplay/tinyTextureContext.I @@ -15,9 +15,11 @@ * */ INLINE TinyTextureContext:: -TinyTextureContext(PreparedGraphicsObjects *pgo, Texture *tex, int view) : - TextureContext(pgo, tex, view) +TinyTextureContext(PreparedGraphicsObjects *pgo, Texture *tex) : + TextureContext(pgo, tex) { + _gltex.views = nullptr; + _gltex.num_views = 0; _gltex.num_levels = 0; _gltex.allocated_buffer = nullptr; _gltex.total_bytecount = 0; diff --git a/panda/src/tinydisplay/tinyTextureContext.cxx b/panda/src/tinydisplay/tinyTextureContext.cxx index d0207a1379..66fd8e4b3e 100644 --- a/panda/src/tinydisplay/tinyTextureContext.cxx +++ b/panda/src/tinydisplay/tinyTextureContext.cxx @@ -31,6 +31,14 @@ TinyTextureContext:: } else { nassertv(gltex->num_levels == 0); } + if (gltex->views != nullptr) { + nassertv(gltex->num_views != 0); + get_class_type().deallocate_array(gltex->views); + gltex->views = nullptr; + gltex->num_views = 0; + } else { + nassertv(gltex->num_views == 0); + } } /** diff --git a/panda/src/tinydisplay/tinyTextureContext.h b/panda/src/tinydisplay/tinyTextureContext.h index d321ae4ab8..6cb760c653 100644 --- a/panda/src/tinydisplay/tinyTextureContext.h +++ b/panda/src/tinydisplay/tinyTextureContext.h @@ -24,7 +24,7 @@ */ class EXPCL_TINYDISPLAY TinyTextureContext : public TextureContext { public: - INLINE TinyTextureContext(PreparedGraphicsObjects *pgo, Texture *tex, int view); + INLINE TinyTextureContext(PreparedGraphicsObjects *pgo, Texture *tex); ALLOC_DELETED_CHAIN(TinyTextureContext); ~TinyTextureContext(); diff --git a/panda/src/tinydisplay/zbuffer.h b/panda/src/tinydisplay/zbuffer.h index ced08b5e31..622de5372e 100644 --- a/panda/src/tinydisplay/zbuffer.h +++ b/panda/src/tinydisplay/zbuffer.h @@ -252,7 +252,7 @@ int texcoord_mirror_once(int coord, int max_coord); /* linesize is in BYTES */ void ZB_copyFrameBuffer(const ZBuffer *zb,void *buf,int linesize); void ZB_copyFrameBufferNoAlpha(const ZBuffer *zb,void *buf,int linesize); -void ZB_zoomFrameBuffer(ZBuffer *dest, int dest_xmin, int dest_ymin, +void ZB_zoomFrameBuffer(ZBuffer *dest, int dest_xmin, int dest_ymin, int dest_xsize, int dest_ysize, const ZBuffer *source, int source_xmin, int source_ymin, int source_xsize, int source_ysize); diff --git a/panda/src/tinydisplay/zgl.h b/panda/src/tinydisplay/zgl.h index c18cafa8b7..749c200b03 100644 --- a/panda/src/tinydisplay/zgl.h +++ b/panda/src/tinydisplay/zgl.h @@ -119,9 +119,14 @@ typedef struct GLVertex { /* textures */ +typedef struct ZTextureView { + ZTextureLevel levels[MAX_MIPMAP_LEVELS]; +} ZTextureView; + /* The combination of all mipmap levels: one complete texture. */ typedef struct GLTexture { - ZTextureLevel levels[MAX_MIPMAP_LEVELS]; + ZTextureView *views; + int num_views; int num_levels; int xsize, ysize; int s_max, t_max; diff --git a/panda/src/wgldisplay/wglGraphicsBuffer.cxx b/panda/src/wgldisplay/wglGraphicsBuffer.cxx index 207fa7eeaf..61edb9643c 100644 --- a/panda/src/wgldisplay/wglGraphicsBuffer.cxx +++ b/panda/src/wgldisplay/wglGraphicsBuffer.cxx @@ -170,7 +170,7 @@ bind_texture_to_pbuffer() { tex->set_format(Texture::F_rgb); } } - TextureContext *tc = tex->prepare_now(0, _gsg->get_prepared_objects(), _gsg); + TextureContext *tc = tex->prepare_now(_gsg->get_prepared_objects(), _gsg); nassertv(tc != nullptr); CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tc); GLenum target = wglgsg->get_texture_target(tex->get_texture_type()); @@ -180,7 +180,7 @@ bind_texture_to_pbuffer() { cdataw->_textures[tex_index]._rtm_mode = RTM_copy_texture; return; } - GLP(BindTexture)(target, gtc->_index); + GLP(BindTexture)(target, gtc->get_view_index(0)); if (_fb_properties.is_single_buffered()) { wglgsg->_wglBindTexImageARB(_pbuffer, WGL_FRONT_LEFT_ARB); } else { From 787e14fade981427d1bfd00a9decb5a1a7a5b597 Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 19 Jul 2023 11:10:49 +0200 Subject: [PATCH 29/84] egg2pg: Fix infinite recursion when `` used with `` Fixes #1515 --- panda/src/egg2pg/eggLoader.cxx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/panda/src/egg2pg/eggLoader.cxx b/panda/src/egg2pg/eggLoader.cxx index ac69a976a2..b1beac16d9 100644 --- a/panda/src/egg2pg/eggLoader.cxx +++ b/panda/src/egg2pg/eggLoader.cxx @@ -2982,7 +2982,8 @@ make_collision_plane(EggGroup *egg_group, CollisionNode *cnode, cnode->add_solid(csplane); return; } - } else if ((*ci)->is_of_type(EggCompositePrimitive::get_class_type())) { + } else if ((*ci)->is_of_type(EggCompositePrimitive::get_class_type()) && + !(*ci)->is_of_type(EggLine::get_class_type())) { EggCompositePrimitive *comp = DCAST(EggCompositePrimitive, *ci); PT(EggGroup) temp_group = new EggGroup; if (comp->triangulate_into(temp_group)) { From 52c704f79dee0f2ced37a46ea0fd479be41bf02f Mon Sep 17 00:00:00 2001 From: rdb Date: Fri, 21 Jul 2023 19:42:07 +0200 Subject: [PATCH 30/84] Update BACKERS.md [skip ci] --- BACKERS.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/BACKERS.md b/BACKERS.md index aeee271a44..960141998c 100644 --- a/BACKERS.md +++ b/BACKERS.md @@ -17,6 +17,8 @@ This is a list of all the people who are contributing financially to Panda3D. I * Max Voss * Hawkheart * Veronica +* Cody Sevier +* Marek Alexa ## Enthusiasts @@ -28,6 +30,7 @@ This is a list of all the people who are contributing financially to Panda3D. I * SureBet * Gyedo Jeon * GameDev JONI +* Max Rodriguez ## Backers From f5827963a3ac4c84187fbef6f671bc0f12787a97 Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 26 Jul 2023 19:17:07 +0200 Subject: [PATCH 31/84] pgraph: Refactor RenderAttrib return_new code a little bit - Allows the compiler to devirtualize the get_hash_impl call, in theory - Reduces the overhead of checking the configuration variables every time in return_new - Avoids recalculating the hash on calling get_unique --- panda/src/pgraph/config_pgraph.cxx | 4 +- panda/src/pgraph/config_pgraph.h | 4 +- panda/src/pgraph/renderAttrib.I | 47 +++++++++++++++++++++++- panda/src/pgraph/renderAttrib.cxx | 59 ++++++++---------------------- panda/src/pgraph/renderAttrib.h | 10 +++-- panda/src/pgraph/renderState.cxx | 6 +-- 6 files changed, 75 insertions(+), 55 deletions(-) diff --git a/panda/src/pgraph/config_pgraph.cxx b/panda/src/pgraph/config_pgraph.cxx index 7b175f15d0..c736829d39 100644 --- a/panda/src/pgraph/config_pgraph.cxx +++ b/panda/src/pgraph/config_pgraph.cxx @@ -214,7 +214,7 @@ ConfigVariableBool transform_cache "transforms, but imposes some overhead for maintaining the " "cache itself.")); -ConfigVariableBool state_cache +ALIGN_16BYTE ConfigVariableBool state_cache ("state-cache", true, PRC_DESC("Set this true to enable the cache of RenderState objects, " "similar to the TransformState cache controlled via " @@ -236,7 +236,7 @@ ConfigVariableBool uniquify_states "including the need to check for a composition cycle in " "the cache. It is highly recommended to keep this on.")); -ConfigVariableBool uniquify_attribs +ALIGN_16BYTE ConfigVariableBool uniquify_attribs ("uniquify-attribs", true, PRC_DESC("Set this true to ensure that equivalent RenderAttribs " "are pointerwise equal. This may improve caching performance, " diff --git a/panda/src/pgraph/config_pgraph.h b/panda/src/pgraph/config_pgraph.h index 0cba3cf971..97ff9682c2 100644 --- a/panda/src/pgraph/config_pgraph.h +++ b/panda/src/pgraph/config_pgraph.h @@ -46,10 +46,10 @@ extern ConfigVariableBool auto_break_cycles; extern EXPCL_PANDA_PGRAPH ConfigVariableBool garbage_collect_states; extern ConfigVariableDouble garbage_collect_states_rate; extern ConfigVariableBool transform_cache; -extern ConfigVariableBool state_cache; +extern ALIGN_16BYTE EXPCL_PANDA_PGRAPH ConfigVariableBool state_cache; extern ConfigVariableBool uniquify_transforms; extern EXPCL_PANDA_PGRAPH ConfigVariableBool uniquify_states; -extern ConfigVariableBool uniquify_attribs; +extern ALIGN_16BYTE EXPCL_PANDA_PGRAPH ConfigVariableBool uniquify_attribs; extern ConfigVariableBool retransform_sprites; extern ConfigVariableBool depth_offset_decals; extern ConfigVariableInt max_collect_vertices; diff --git a/panda/src/pgraph/renderAttrib.I b/panda/src/pgraph/renderAttrib.I index 5df0d0774e..e92d16bd3b 100644 --- a/panda/src/pgraph/renderAttrib.I +++ b/panda/src/pgraph/renderAttrib.I @@ -79,7 +79,11 @@ get_hash() const { */ INLINE CPT(RenderAttrib) RenderAttrib:: get_unique() const { - return return_unique((RenderAttrib *)this); + if (state_cache) { + return do_uniquify(this); + } else { + return this; + } } /** @@ -93,6 +97,47 @@ calc_hash() { _hash = int_hash::add_hash(hash, get_type().get_index()); } +/** + * This function is used by derived RenderAttrib types to share a common + * RenderAttrib pointer for all equivalent RenderAttrib objects. + * + * This is different from return_unique() in that it does not actually + * guarantee a unique pointer, unless uniquify-attribs is set. + */ +INLINE CPT(RenderAttrib) RenderAttrib:: +return_new(RenderAttrib *attrib) { + nassertr(attrib != nullptr, attrib); + attrib->calc_hash(); + + if (_uniquify_attribs) { + return do_uniquify(attrib); + } else { + return attrib; + } +} + +/** + * This function is used by derived RenderAttrib types to share a common + * RenderAttrib pointer for all equivalent RenderAttrib objects. + * + * The make() function of the derived type should create a new RenderAttrib + * and pass it through return_new(), which will either save the pointer and + * return it unchanged (if this is the first similar such object) or delete it + * and return an equivalent pointer (if there was already a similar object + * saved). + */ +INLINE CPT(RenderAttrib) RenderAttrib:: +return_unique(RenderAttrib *attrib) { + nassertr(attrib != nullptr, attrib); + attrib->calc_hash(); + + if (state_cache) { + return do_uniquify(attrib); + } else { + return attrib; + } +} + /** * Adds the indicated TypeHandle to the registry, if it is not there already, * and returns a unique slot number. See RenderAttribRegistry. diff --git a/panda/src/pgraph/renderAttrib.cxx b/panda/src/pgraph/renderAttrib.cxx index 62a2d0c38b..0992dcb79c 100644 --- a/panda/src/pgraph/renderAttrib.cxx +++ b/panda/src/pgraph/renderAttrib.cxx @@ -14,7 +14,6 @@ #include "renderAttrib.h" #include "bamReader.h" #include "indent.h" -#include "config_pgraph.h" #include "lightReMutexHolder.h" #include "pStatTimer.h" @@ -22,6 +21,7 @@ using std::ostream; LightReMutex *RenderAttrib::_attribs_lock = nullptr; RenderAttrib::Attribs RenderAttrib::_attribs; +bool RenderAttrib::_uniquify_attribs = false; TypeHandle RenderAttrib::_type_handle; size_t RenderAttrib::_garbage_index = 0; @@ -180,6 +180,10 @@ list_attribs(ostream &out) { */ int RenderAttrib:: garbage_collect() { + // This gets called periodically, so use this opportunity to reload the value + // from the Config.prc file. + _uniquify_attribs = uniquify_attribs && state_cache; + if (!garbage_collect_states) { return 0; } @@ -305,54 +309,15 @@ validate_attribs() { } /** - * This function is used by derived RenderAttrib types to share a common - * RenderAttrib pointer for all equivalent RenderAttrib objects. - * - * This is different from return_unique() in that it does not actually - * guarantee a unique pointer, unless uniquify-attribs is set. + * Private implementation of return_new, return_unique, and get_unique. */ CPT(RenderAttrib) RenderAttrib:: -return_new(RenderAttrib *attrib) { - nassertr(attrib != nullptr, attrib); - if (!uniquify_attribs) { - attrib->calc_hash(); - return attrib; - } - - return return_unique(attrib); -} - -/** - * This function is used by derived RenderAttrib types to share a common - * RenderAttrib pointer for all equivalent RenderAttrib objects. - * - * The make() function of the derived type should create a new RenderAttrib - * and pass it through return_new(), which will either save the pointer and - * return it unchanged (if this is the first similar such object) or delete it - * and return an equivalent pointer (if there was already a similar object - * saved). - */ -CPT(RenderAttrib) RenderAttrib:: -return_unique(RenderAttrib *attrib) { - nassertr(attrib != nullptr, attrib); - - attrib->calc_hash(); - - if (!state_cache) { - return attrib; - } - -#ifndef NDEBUG - if (paranoid_const) { - nassertr(validate_attribs(), attrib); - } -#endif - +do_uniquify(const RenderAttrib *attrib) { LightReMutexHolder holder(*_attribs_lock); if (attrib->_saved_entry != -1) { - // This attrib is already in the cache. nassertr(_attribs.find(attrib) - // == attrib->_saved_entry, attrib); + // This attrib is already in the cache. + //nassertr(_attribs.find(attrib) == attrib->_saved_entry, attrib); return attrib; } @@ -503,6 +468,12 @@ release_new() { */ void RenderAttrib:: init_attribs() { + // These are copied here so that we can be sure that they are constructed. + ALIGN_16BYTE ConfigVariableBool uniquify_attribs("uniquify-attribs", true); + ALIGN_16BYTE ConfigVariableBool state_cache("state-cache", true); + + _uniquify_attribs = uniquify_attribs && state_cache; + // TODO: we should have a global Panda mutex to allow us to safely create // _attribs_lock without a startup race condition. For the meantime, this // is OK because we guarantee that this method is called at static init diff --git a/panda/src/pgraph/renderAttrib.h b/panda/src/pgraph/renderAttrib.h index d9e9262429..a287c95f57 100644 --- a/panda/src/pgraph/renderAttrib.h +++ b/panda/src/pgraph/renderAttrib.h @@ -16,6 +16,7 @@ #include "pandabase.h" +#include "config_pgraph.h" #include "typedWritableReferenceCount.h" #include "renderAttribRegistry.h" #include "pointerTo.h" @@ -161,8 +162,9 @@ PUBLISHED: protected: INLINE void calc_hash(); - static CPT(RenderAttrib) return_new(RenderAttrib *attrib); - static CPT(RenderAttrib) return_unique(RenderAttrib *attrib); + INLINE static CPT(RenderAttrib) return_new(RenderAttrib *attrib); + INLINE static CPT(RenderAttrib) return_unique(RenderAttrib *attrib); + static CPT(RenderAttrib) do_uniquify(const RenderAttrib *attrib); virtual int compare_to_impl(const RenderAttrib *other) const; virtual size_t get_hash_impl() const; virtual CPT(RenderAttrib) compose_impl(const RenderAttrib *other) const; @@ -184,8 +186,9 @@ private: static LightReMutex *_attribs_lock; typedef SimpleHashMap > Attribs; static Attribs _attribs; + static bool _uniquify_attribs; - int _saved_entry; + mutable int _saved_entry; size_t _hash; // This keeps track of our current position through the garbage collection @@ -195,6 +198,7 @@ private: static PStatCollector _garbage_collect_pcollector; friend class RenderAttribRegistry; + friend class RenderState; public: virtual void write_datagram(BamWriter *manager, Datagram &dg); diff --git a/panda/src/pgraph/renderState.cxx b/panda/src/pgraph/renderState.cxx index da9d1bca97..235075cb1d 100644 --- a/panda/src/pgraph/renderState.cxx +++ b/panda/src/pgraph/renderState.cxx @@ -1287,8 +1287,8 @@ return_unique(RenderState *state) { LightReMutexHolder holder(*_states_lock); if (state->_saved_entry != -1) { - // This state is already in the cache. nassertr(_states.find(state) == - // state->_saved_entry, pt_state); + // This state is already in the cache. + //nassertr(_states.find(state) == state->_saved_entry, pt_state); return state; } @@ -1300,7 +1300,7 @@ return_unique(RenderState *state) { while (slot >= 0) { Attribute &attrib = state->_attributes[slot]; nassertd(attrib._attrib != nullptr) continue; - attrib._attrib = attrib._attrib->get_unique(); + attrib._attrib = RenderAttrib::do_uniquify(attrib._attrib); mask.clear_bit(slot); slot = mask.get_lowest_on_bit(); } From 71ee57bc923bcbbcc7350d9f74bf68d5c54239de Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 26 Jul 2023 19:33:43 +0200 Subject: [PATCH 32/84] linmath: Unroll LVecBase4 less-than operator implementation --- panda/src/linmath/lvecBase4_src.I | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/panda/src/linmath/lvecBase4_src.I b/panda/src/linmath/lvecBase4_src.I index 4c861b2ab9..08ecb90281 100644 --- a/panda/src/linmath/lvecBase4_src.I +++ b/panda/src/linmath/lvecBase4_src.I @@ -428,7 +428,34 @@ project(const FLOATNAME(LVecBase4) &onto) const { INLINE_LINMATH bool FLOATNAME(LVecBase4):: operator < (const FLOATNAME(LVecBase4) &other) const { TAU_PROFILE("bool LVecBase4::operator <(const LVecBase4 &)", " ", TAU_USER); - return (compare_to(other) < 0); +#ifdef FLOATTYPE_IS_INT + if (_v(0) != other._v(0)) { + return _v(0) < other._v(0); + } + if (_v(1) != other._v(1)) { + return _v(1) < other._v(1); + } + if (_v(2) != other._v(2)) { + return _v(2) < other._v(2); + } + if (_v(3) != other._v(3)) { + return _v(3) < other._v(3); + } +#else + if (!IS_THRESHOLD_COMPEQ(_v(0), other._v(0), NEARLY_ZERO(FLOATTYPE))) { + return _v(0) < other._v(0); + } + if (!IS_THRESHOLD_COMPEQ(_v(1), other._v(1), NEARLY_ZERO(FLOATTYPE))) { + return _v(1) < other._v(1); + } + if (!IS_THRESHOLD_COMPEQ(_v(2), other._v(2), NEARLY_ZERO(FLOATTYPE))) { + return _v(2) < other._v(2); + } + if (!IS_THRESHOLD_COMPEQ(_v(3), other._v(3), NEARLY_ZERO(FLOATTYPE))) { + return _v(3) < other._v(3); + } +#endif + return false; } /** From 115a716a7dd30a82ed3c3691210388c3f11d4a8c Mon Sep 17 00:00:00 2001 From: rdb Date: Sat, 13 May 2023 11:16:32 +0200 Subject: [PATCH 33/84] Implement support for custom TypedWritable subclasses in Python Fixes #1495 --- dtool/src/dtoolbase/dtoolbase.h | 1 + dtool/src/dtoolbase/typeHandle.cxx | 18 +- dtool/src/dtoolbase/typeHandle.h | 3 +- dtool/src/dtoolbase/typeHandle_ext.cxx | 21 +- dtool/src/dtoolbase/typeRegistry.cxx | 5 +- dtool/src/dtoolbase/typeRegistry.h | 7 +- dtool/src/dtoolbase/typeRegistryNode.I | 19 +- dtool/src/dtoolbase/typeRegistryNode.cxx | 34 ++- dtool/src/dtoolbase/typeRegistryNode.h | 11 +- .../interfaceMakerPythonNative.cxx | 58 +++-- .../interrogate/interfaceMakerPythonNative.h | 1 + dtool/src/interrogatedb/dtool_super_base.cxx | 2 +- dtool/src/interrogatedb/py_panda.I | 32 ++- dtool/src/interrogatedb/py_panda.cxx | 14 +- dtool/src/interrogatedb/py_panda.h | 2 +- panda/src/pgraph/bamFile.h | 4 + panda/src/pgraph/bamFile_ext.cxx | 20 +- panda/src/pgraph/bamFile_ext.h | 2 + panda/src/putil/bamReader.h | 4 + panda/src/putil/bamReader_ext.cxx | 80 ++++++- panda/src/putil/bamReader_ext.h | 2 + panda/src/putil/typedWritable.h | 5 +- panda/src/putil/typedWritable_ext.cxx | 205 ++++++++++++++++++ panda/src/putil/typedWritable_ext.h | 2 + tests/putil/test_custom_writable.py | 53 +++++ 25 files changed, 536 insertions(+), 69 deletions(-) create mode 100644 tests/putil/test_custom_writable.py diff --git a/dtool/src/dtoolbase/dtoolbase.h b/dtool/src/dtoolbase/dtoolbase.h index d72662e081..bebb3d665a 100644 --- a/dtool/src/dtoolbase/dtoolbase.h +++ b/dtool/src/dtoolbase/dtoolbase.h @@ -130,6 +130,7 @@ // flag to link in Python, we'll just excerpt the forward declaration of // PyObject. typedef struct _object PyObject; +typedef struct _typeobject PyTypeObject; #ifndef HAVE_EIGEN // If we don't have the Eigen library, don't define LINMATH_ALIGN. diff --git a/dtool/src/dtoolbase/typeHandle.cxx b/dtool/src/dtoolbase/typeHandle.cxx index 4cde03258e..740627361c 100644 --- a/dtool/src/dtoolbase/typeHandle.cxx +++ b/dtool/src/dtoolbase/typeHandle.cxx @@ -155,7 +155,7 @@ deallocate_array(void *ptr) { /** * Returns the internal void pointer that is stored for interrogate's benefit. */ -PyObject *TypeHandle:: +PyTypeObject *TypeHandle:: get_python_type() const { TypeRegistryNode *rnode = TypeRegistry::ptr()->look_up(*this, nullptr); if (rnode != nullptr) { @@ -164,6 +164,22 @@ get_python_type() const { return nullptr; } } + +/** + * Returns a Python wrapper object corresponding to the given C++ pointer. + */ +PyObject *TypeHandle:: +wrap_python(void *ptr, PyTypeObject *cast_from) const { + if (ptr == nullptr) { + return nullptr; + } + TypeRegistryNode *rnode = TypeRegistry::ptr()->look_up(*this, nullptr); + if (rnode != nullptr) { + return rnode->wrap_python(ptr, cast_from); + } else { + return nullptr; + } +} #endif std::ostream & diff --git a/dtool/src/dtoolbase/typeHandle.h b/dtool/src/dtoolbase/typeHandle.h index 39bcac543f..c759526ad9 100644 --- a/dtool/src/dtoolbase/typeHandle.h +++ b/dtool/src/dtoolbase/typeHandle.h @@ -140,7 +140,8 @@ PUBLISHED: public: #ifdef HAVE_PYTHON - PyObject *get_python_type() const; + PyTypeObject *get_python_type() const; + PyObject *wrap_python(void *ptr, PyTypeObject *cast_from = nullptr) const; #endif // HAVE_PYTHON void *allocate_array(size_t size) RETURNS_ALIGNED(MEMORY_HOOK_ALIGNMENT); diff --git a/dtool/src/dtoolbase/typeHandle_ext.cxx b/dtool/src/dtoolbase/typeHandle_ext.cxx index cefe62e154..5e0d80f2a8 100644 --- a/dtool/src/dtoolbase/typeHandle_ext.cxx +++ b/dtool/src/dtoolbase/typeHandle_ext.cxx @@ -46,7 +46,26 @@ __reduce__() const { // If we have a Python binding registered for it, that's the preferred method, // since it ensures that the appropriate module gets loaded by pickle. - PyObject *py_type = _this->get_python_type(); + PyTypeObject *py_type = _this->get_python_type(); + if (py_type != nullptr && py_type->tp_dict != nullptr) { + // Look for a get_class_type method, if it returns this handle. + PyObject *func = PyDict_GetItemString(py_type->tp_dict, "get_class_type"); + if (func != nullptr && PyCallable_Check(func)) { + PyObject *result = PyObject_CallNoArgs(func); + TypeHandle *result_handle = nullptr; + if (result == nullptr) { + // Never mind. + PyErr_Clear(); + } + else if (DtoolInstance_GetPointer(result, result_handle, Dtool_TypeHandle) && + *result_handle == *_this) { + // It returned the correct result, so we can use this. + return Py_BuildValue("O()", func); + } + } + } + + // Fall back to TypeHandle::make(), if would produce the correct result. if (py_type != nullptr && *_this == ((Dtool_PyTypedObject *)py_type)->_type) { PyObject *func = PyObject_GetAttrString((PyObject *)&Dtool_TypeHandle, "make"); return Py_BuildValue("N(O)", func, py_type); diff --git a/dtool/src/dtoolbase/typeRegistry.cxx b/dtool/src/dtoolbase/typeRegistry.cxx index 2b731abf39..dc60264f37 100644 --- a/dtool/src/dtoolbase/typeRegistry.cxx +++ b/dtool/src/dtoolbase/typeRegistry.cxx @@ -213,12 +213,13 @@ record_alternate_name(TypeHandle type, const string &name) { * of interrogate, which expects this to contain a Dtool_PyTypedObject. */ void TypeRegistry:: -record_python_type(TypeHandle type, PyObject *python_type) { +record_python_type(TypeHandle type, PyTypeObject *cls, PythonWrapFunc *wrap_func) { _lock.lock(); TypeRegistryNode *rnode = look_up(type, nullptr); if (rnode != nullptr) { - rnode->_python_type = python_type; + rnode->_python_type = cls; + rnode->_python_wrap_func = wrap_func; } _lock.unlock(); diff --git a/dtool/src/dtoolbase/typeRegistry.h b/dtool/src/dtoolbase/typeRegistry.h index c5dafef6a5..bc506eaad6 100644 --- a/dtool/src/dtoolbase/typeRegistry.h +++ b/dtool/src/dtoolbase/typeRegistry.h @@ -40,13 +40,18 @@ public: // convenience function, defined in register_type.h. bool register_type(TypeHandle &type_handle, const std::string &name); +#ifdef HAVE_PYTHON + typedef PyObject *PythonWrapFunc(void *ptr, PyTypeObject *cast_from); +#endif + PUBLISHED: TypeHandle register_dynamic_type(const std::string &name); void record_derivation(TypeHandle child, TypeHandle parent); void record_alternate_name(TypeHandle type, const std::string &name); #ifdef HAVE_PYTHON - void record_python_type(TypeHandle type, PyObject *python_type); + void record_python_type(TypeHandle type, PyTypeObject *cls, + PythonWrapFunc *wrap_func); #endif TypeHandle find_type(const std::string &name) const; diff --git a/dtool/src/dtoolbase/typeRegistryNode.I b/dtool/src/dtoolbase/typeRegistryNode.I index 1556e63847..5d3c06ac55 100644 --- a/dtool/src/dtoolbase/typeRegistryNode.I +++ b/dtool/src/dtoolbase/typeRegistryNode.I @@ -14,7 +14,7 @@ /** * Returns the Python type object associated with this node. */ -INLINE PyObject *TypeRegistryNode:: +INLINE PyTypeObject *TypeRegistryNode:: get_python_type() const { if (_python_type != nullptr || _parent_classes.empty()) { return _python_type; @@ -24,6 +24,23 @@ get_python_type() const { } } +/** + * Returns a Python wrapper object corresponding to the given C++ pointer. + */ +INLINE PyObject *TypeRegistryNode:: +wrap_python(void *ptr, PyTypeObject *cast_from) const { + if (_python_wrap_func != nullptr) { + return _python_wrap_func(ptr, cast_from); + } + else if (_parent_classes.empty()) { + return nullptr; + } + else { + // Recurse through parent classes. + return r_wrap_python(ptr, cast_from); + } +} + /** * */ diff --git a/dtool/src/dtoolbase/typeRegistryNode.cxx b/dtool/src/dtoolbase/typeRegistryNode.cxx index 291a6ec95a..0aabc97de1 100644 --- a/dtool/src/dtoolbase/typeRegistryNode.cxx +++ b/dtool/src/dtoolbase/typeRegistryNode.cxx @@ -311,16 +311,14 @@ r_build_subtrees(TypeRegistryNode *top, int bit_count, * Recurses through the parent nodes to find the best Python type object to * represent objects of this type. */ -PyObject *TypeRegistryNode:: +PyTypeObject *TypeRegistryNode:: r_get_python_type() const { - Classes::const_iterator ni; - for (ni = _parent_classes.begin(); ni != _parent_classes.end(); ++ni) { - const TypeRegistryNode *parent = *ni; + for (const TypeRegistryNode *parent : _parent_classes) { if (parent->_python_type != nullptr) { return parent->_python_type; - - } else if (!parent->_parent_classes.empty()) { - PyObject *py_type = parent->r_get_python_type(); + } + else if (!parent->_parent_classes.empty()) { + PyTypeObject *py_type = parent->r_get_python_type(); if (py_type != nullptr) { return py_type; } @@ -330,6 +328,28 @@ r_get_python_type() const { return nullptr; } +/** + * Creates a Python wrapper object to represent the given C++ pointer, which + * must be exactly of the correct type, unless cast_from is set to one of its + * base classes, in which case it will be cast appropriately. + */ +PyObject *TypeRegistryNode:: +r_wrap_python(void *ptr, PyTypeObject *cast_from) const { + for (const TypeRegistryNode *parent : _parent_classes) { + if (parent->_python_wrap_func != nullptr) { + return parent->_python_wrap_func(ptr, cast_from); + } + else if (!parent->_parent_classes.empty()) { + PyObject *wrapper = parent->r_wrap_python(ptr, cast_from); + if (wrapper != nullptr) { + return wrapper; + } + } + } + + return nullptr; +} + /** * A recursive function to double-check the result of is_derived_from(). This * is the slow, examine-the-whole-graph approach, as opposed to the clever and diff --git a/dtool/src/dtoolbase/typeRegistryNode.h b/dtool/src/dtoolbase/typeRegistryNode.h index 6ff2275103..6a6e0833a4 100644 --- a/dtool/src/dtoolbase/typeRegistryNode.h +++ b/dtool/src/dtoolbase/typeRegistryNode.h @@ -30,6 +30,8 @@ */ class EXPCL_DTOOL_DTOOLBASE TypeRegistryNode { public: + typedef PyObject *PythonWrapFunc(void *ptr, PyTypeObject *cast_from); + TypeRegistryNode(TypeHandle handle, const std::string &name, TypeHandle &ref); static bool is_derived_from(const TypeRegistryNode *child, @@ -38,7 +40,8 @@ public: static TypeHandle get_parent_towards(const TypeRegistryNode *child, const TypeRegistryNode *base); - INLINE PyObject *get_python_type() const; + INLINE PyTypeObject *get_python_type() const; + INLINE PyObject *wrap_python(void *ptr, PyTypeObject *cast_from) const; void clear_subtree(); void define_subtree(); @@ -49,7 +52,8 @@ public: typedef std::vector Classes; Classes _parent_classes; Classes _child_classes; - PyObject *_python_type = nullptr; + PyTypeObject *_python_type = nullptr; + PythonWrapFunc *_python_wrap_func = nullptr; patomic _memory_usage[TypeHandle::MC_limit]; @@ -81,7 +85,8 @@ private: void r_build_subtrees(TypeRegistryNode *top, int bit_count, SubtreeMaskType bits); - PyObject *r_get_python_type() const; + PyTypeObject *r_get_python_type() const; + PyObject *r_wrap_python(void *ptr, PyTypeObject *cast_from) const; static bool check_derived_from(const TypeRegistryNode *child, const TypeRegistryNode *base); diff --git a/dtool/src/interrogate/interfaceMakerPythonNative.cxx b/dtool/src/interrogate/interfaceMakerPythonNative.cxx index b55026b2da..6958e8a5e6 100644 --- a/dtool/src/interrogate/interfaceMakerPythonNative.cxx +++ b/dtool/src/interrogate/interfaceMakerPythonNative.cxx @@ -115,6 +115,7 @@ RenameSet methodRenameDictionary[] = { { "__deepcopy__" , "__deepcopy__", 0 }, { "__getstate__" , "__getstate__", 0 }, { "__setstate__" , "__setstate__", 0 }, + { "__new__" , "__new__", 0 }, { "print" , "Cprint", 0 }, { "CInterval.set_t", "_priv__cSetT", 0 }, { nullptr, nullptr, -1 } @@ -664,6 +665,12 @@ get_slotted_function_def(Object *obj, Function *func, FunctionRemap *remap, return true; } + if (method_name == "__new__") { + def._answer_location = "tp_new"; + def._wrapper_type = WT_new; + return true; + } + if (remap->_type == FunctionRemap::T_typecast_method) { // A typecast operator. Check for a supported low-level typecast type. if (TypeManager::is_bool(remap->_return_type->get_orig_type())) { @@ -1106,10 +1113,14 @@ write_class_details(ostream &out, Object *obj) { out << " */\n"; // First write out all the wrapper functions for the methods. + bool have_new = false; for (Function *func : obj->_methods) { if (func) { // Write the definition of the generic wrapper function for this // function. + if (func->_ifunc.get_name() == "__new__") { + have_new = true; + } write_function_for_top(out, obj, func); } } @@ -1128,10 +1139,16 @@ write_class_details(ostream &out, Object *obj) { if (obj->_constructors.size() == 0) { // We still need to write a dummy constructor to prevent inheriting the // constructor from a base class. - out << fname << " {\n" - " Dtool_Raise_TypeError(\"cannot init abstract class\");\n" - " return -1;\n" - "}\n\n"; + if (have_new) { + out << fname << " {\n" + " return 0;\n" + "}\n\n"; + } else { + out << fname << " {\n" + " Dtool_Raise_TypeError(\"cannot init abstract class\");\n" + " return -1;\n" + "}\n\n"; + } } CPPType *cpptype = TypeManager::resolve_type(obj->_itype._cpptype); @@ -1221,18 +1238,17 @@ write_class_details(ostream &out, Object *obj) { out << " return nullptr;\n"; out << "}\n\n"; - out << "static Dtool_PyInstDef *Dtool_Wrap_" << ClassName << "(void *from_this, Dtool_PyTypedObject *from_type) {\n"; - out << " if (from_this == nullptr || from_type == nullptr) {\n"; - out << " return nullptr;\n"; - out << " }\n"; + //NB. This may be called with nullptr in either argument and should produce + // a valid wrapper object even with a null pointer. + out << "static PyObject *Dtool_Wrap_" << ClassName << "(void *from_this, PyTypeObject *from_type) {\n"; out << " " << cClassName << " *to_this;\n"; - out << " if (from_type == &Dtool_" << ClassName << ") {\n"; + out << " if (from_type == nullptr || from_type == &Dtool_" << ClassName << "._PyType) {\n"; out << " to_this = (" << cClassName << "*)from_this;\n"; out << " }\n"; for (di = details.begin(); di != details.end(); di++) { if (di->second._can_downcast && di->second._is_legal_py_class) { - out << " else if (from_type == Dtool_Ptr_" << make_safe_name(di->second._to_class_name) << ") {\n"; - out << " " << di->second._to_class_name << "* other_this = (" << di->second._to_class_name << "*)from_this;\n" ; + out << " else if (from_type == (PyTypeObject *)Dtool_Ptr_" << make_safe_name(di->second._to_class_name) << ") {\n"; + out << " " << di->second._to_class_name << " *other_this = (" << di->second._to_class_name << " *)from_this;\n" ; out << " to_this = (" << cClassName << "*)other_this;\n"; out << " }\n"; } @@ -1247,7 +1263,7 @@ write_class_details(ostream &out, Object *obj) { out << " self->_ptr_to_object = to_this;\n"; out << " self->_memory_rules = false;\n"; out << " self->_is_const = false;\n"; - out << " return self;\n"; + out << " return (PyObject *)self;\n"; out << "}\n\n"; } } @@ -1405,8 +1421,9 @@ write_module_support(ostream &out, ostream *out_h, InterrogateModuleDef *def) { out << " TypeHandle handle = " << type->get_local_name(&parser) << "::get_class_type();\n"; out << " Dtool_" << safe_name << "._type = handle;\n"; - out << " registry->record_python_type(handle, " - "(PyObject *)&Dtool_" << safe_name << ");\n"; + out << " registry->record_python_type(handle," + " &Dtool_" << safe_name << "._PyType," + " Dtool_Wrap_" << safe_name << ");\n"; out << " }\n"; } else { if (IsPandaTypedObject(type->as_struct_type())) { @@ -2624,6 +2641,17 @@ write_module_class(ostream &out, Object *obj) { } break; + case WT_new: + { + string fname = "static PyObject *" + def._wrapper_name + "(PyTypeObject *cls, PyObject *args, PyObject *kwds)\n"; + + std::vector remaps; + remaps.insert(remaps.end(), def._remaps.begin(), def._remaps.end()); + string expected_params; + write_function_for_name(out, obj, remaps, fname, expected_params, true, AT_keyword_args, RF_pyobject | RF_err_null); + } + break; + case WT_none: // Nothing special about the wrapper function: just write it normally. string fname = "static PyObject *" + def._wrapper_name + "(PyObject *self, PyObject *args, PyObject *kwds)\n"; @@ -3229,7 +3257,7 @@ write_module_class(ostream &out, Object *obj) { // allocfunc tp_alloc; out << " PyType_GenericAlloc,\n"; // newfunc tp_new; - out << " Dtool_new_" << ClassName << ",\n"; + write_function_slot(out, 4, slots, "tp_new", "Dtool_new_" + ClassName); // freefunc tp_free; if (obj->_protocol_types & Object::PT_python_gc) { out << " PyObject_GC_Del,\n"; diff --git a/dtool/src/interrogate/interfaceMakerPythonNative.h b/dtool/src/interrogate/interfaceMakerPythonNative.h index 86eb24471e..348d855d01 100644 --- a/dtool/src/interrogate/interfaceMakerPythonNative.h +++ b/dtool/src/interrogate/interfaceMakerPythonNative.h @@ -82,6 +82,7 @@ private: WT_traverse, WT_compare, WT_hash, + WT_new, }; // This enum is passed to the wrapper generation functions to indicate what diff --git a/dtool/src/interrogatedb/dtool_super_base.cxx b/dtool/src/interrogatedb/dtool_super_base.cxx index 1af473e142..0992edb08f 100644 --- a/dtool/src/interrogatedb/dtool_super_base.cxx +++ b/dtool/src/interrogatedb/dtool_super_base.cxx @@ -43,7 +43,7 @@ static void *Dtool_UpcastInterface_DTOOL_SUPER_BASE(PyObject *self, Dtool_PyType return nullptr; } -static Dtool_PyInstDef *Dtool_Wrap_DTOOL_SUPER_BASE(void *from_this, Dtool_PyTypedObject *from_type) { +static PyObject *Dtool_Wrap_DTOOL_SUPER_BASE(void *from_this, PyTypeObject *from_type) { return nullptr; } diff --git a/dtool/src/interrogatedb/py_panda.I b/dtool/src/interrogatedb/py_panda.I index d6b95efe35..9434d64617 100644 --- a/dtool/src/interrogatedb/py_panda.I +++ b/dtool/src/interrogatedb/py_panda.I @@ -122,30 +122,38 @@ INLINE long Dtool_EnumValue_AsLong(PyObject *value) { */ template INLINE PyObject * DTool_CreatePyInstance(const T *obj, bool memory_rules) { - Dtool_PyTypedObject *known_class = (Dtool_PyTypedObject *)get_type_handle(T).get_python_type(); - nassertr(known_class != nullptr, nullptr); - return DTool_CreatePyInstance((void*) obj, *known_class, memory_rules, true); + Dtool_PyInstDef *self = (Dtool_PyInstDef *)get_type_handle(T).wrap_python(obj); + nassertr(self != nullptr, nullptr); + self->_memory_rules = memory_rules; + self->_is_const = true; + return (PyObject *)self; } template INLINE PyObject * DTool_CreatePyInstance(T *obj, bool memory_rules) { - Dtool_PyTypedObject *known_class = (Dtool_PyTypedObject *)get_type_handle(T).get_python_type(); - nassertr(known_class != nullptr, nullptr); - return DTool_CreatePyInstance((void*) obj, *known_class, memory_rules, false); + Dtool_PyInstDef *self = (Dtool_PyInstDef *)get_type_handle(T).wrap_python(obj); + nassertr(self != nullptr, nullptr); + self->_memory_rules = memory_rules; + self->_is_const = false; + return (PyObject *)self; } template INLINE PyObject * DTool_CreatePyInstanceTyped(const T *obj, bool memory_rules) { - Dtool_PyTypedObject *known_class = (Dtool_PyTypedObject *)get_type_handle(T).get_python_type(); - nassertr(known_class != nullptr, nullptr); - return DTool_CreatePyInstanceTyped((void*) obj, *known_class, memory_rules, true, obj->get_type().get_index()); + Dtool_PyInstDef *self = (Dtool_PyInstDef *)get_type_handle(T).wrap_python(obj); + nassertr(self != nullptr, nullptr); + self->_memory_rules = memory_rules; + self->_is_const = true; + return (PyObject *)self; } template INLINE PyObject * DTool_CreatePyInstanceTyped(T *obj, bool memory_rules) { - Dtool_PyTypedObject *known_class = (Dtool_PyTypedObject *)get_type_handle(T).get_python_type(); - nassertr(known_class != nullptr, nullptr); - return DTool_CreatePyInstanceTyped((void*) obj, *known_class, memory_rules, false, obj->get_type().get_index()); + Dtool_PyInstDef *self = (Dtool_PyInstDef *)get_type_handle(T).wrap_python(obj); + nassertr(self != nullptr, nullptr); + self->_memory_rules = memory_rules; + self->_is_const = false; + return (PyObject *)self; } /** diff --git a/dtool/src/interrogatedb/py_panda.cxx b/dtool/src/interrogatedb/py_panda.cxx index 3f5e748a94..71572d7b78 100644 --- a/dtool/src/interrogatedb/py_panda.cxx +++ b/dtool/src/interrogatedb/py_panda.cxx @@ -454,15 +454,11 @@ PyObject *DTool_CreatePyInstanceTyped(void *local_this_in, Dtool_PyTypedObject & // IF the class is possibly a run time typed object if (type_index > 0) { // get best fit class... - Dtool_PyTypedObject *target_class = (Dtool_PyTypedObject *)TypeHandle::from_index(type_index).get_python_type(); - if (target_class != nullptr) { - // cast to the type... - Dtool_PyInstDef *self = target_class->_Dtool_WrapInterface(local_this_in, &known_class_type); - if (self != nullptr) { - self->_memory_rules = memory_rules; - self->_is_const = is_const; - return (PyObject *)self; - } + Dtool_PyInstDef *self = (Dtool_PyInstDef *)TypeHandle::from_index(type_index).wrap_python(local_this_in, &known_class_type._PyType); + if (self != nullptr) { + self->_memory_rules = memory_rules; + self->_is_const = is_const; + return (PyObject *)self; } } diff --git a/dtool/src/interrogatedb/py_panda.h b/dtool/src/interrogatedb/py_panda.h index c647bfded2..1c6bd4ae00 100644 --- a/dtool/src/interrogatedb/py_panda.h +++ b/dtool/src/interrogatedb/py_panda.h @@ -41,7 +41,7 @@ struct Dtool_PyTypedObject; // used to stamp dtool instance.. #define PY_PANDA_SIGNATURE 0xbeaf typedef void *(*UpcastFunction)(PyObject *,Dtool_PyTypedObject *); -typedef Dtool_PyInstDef *(*WrapFunction)(void *, Dtool_PyTypedObject *); +typedef PyObject *(*WrapFunction)(void *, PyTypeObject *); typedef void *(*CoerceFunction)(PyObject *, void *); typedef void (*ModuleClassInitFunction)(PyObject *module); diff --git a/panda/src/pgraph/bamFile.h b/panda/src/pgraph/bamFile.h index 32793e512e..62a7ea93e7 100644 --- a/panda/src/pgraph/bamFile.h +++ b/panda/src/pgraph/bamFile.h @@ -47,7 +47,11 @@ PUBLISHED: bool open_read(std::istream &in, const std::string &bam_filename = "stream", bool report_errors = true); +#if defined(CPPPARSER) && defined(HAVE_PYTHON) + EXTENSION(PyObject *read_object()); +#else TypedWritable *read_object(); +#endif bool is_eof() const; bool resolve(); diff --git a/panda/src/pgraph/bamFile_ext.cxx b/panda/src/pgraph/bamFile_ext.cxx index 6c5cd04e1a..b7c723b0f9 100644 --- a/panda/src/pgraph/bamFile_ext.cxx +++ b/panda/src/pgraph/bamFile_ext.cxx @@ -12,10 +12,28 @@ */ #include "bamFile_ext.h" -#include "bamWriter_ext.h" +#include "bamReader_ext.h" #ifdef HAVE_PYTHON +#ifndef CPPPARSER +extern Dtool_PyTypedObject Dtool_TypedWritable; +#endif // CPPPARSER + +/** + * Reads an object from the BamFile. + */ +PyObject *Extension:: +read_object() { + BamReader *reader = _this->get_reader(); + if (reader == nullptr) { + PyErr_SetString(PyExc_ValueError, "BamFile not open for reading"); + return nullptr; + } + + return invoke_extension(reader).read_object(); +} + /** * Returns the version number of the Bam file currently being written. */ diff --git a/panda/src/pgraph/bamFile_ext.h b/panda/src/pgraph/bamFile_ext.h index 7a6408d531..67ee95aff8 100644 --- a/panda/src/pgraph/bamFile_ext.h +++ b/panda/src/pgraph/bamFile_ext.h @@ -29,6 +29,8 @@ template<> class Extension : public ExtensionBase { public: + PyObject *read_object(); + PyObject *get_file_version() const; }; diff --git a/panda/src/putil/bamReader.h b/panda/src/putil/bamReader.h index 05ded8bcff..3742c6aba1 100644 --- a/panda/src/putil/bamReader.h +++ b/panda/src/putil/bamReader.h @@ -132,8 +132,12 @@ PUBLISHED: INLINE const LoaderOptions &get_loader_options() const; INLINE void set_loader_options(const LoaderOptions &options); +#if defined(CPPPARSER) && defined(HAVE_PYTHON) + EXTENSION(PyObject *read_object()); +#else BLOCKING TypedWritable *read_object(); BLOCKING bool read_object(TypedWritable *&ptr, ReferenceCount *&ref_ptr); +#endif INLINE bool is_eof() const; bool resolve(); diff --git a/panda/src/putil/bamReader_ext.cxx b/panda/src/putil/bamReader_ext.cxx index 99ec982d74..fce150f92c 100644 --- a/panda/src/putil/bamReader_ext.cxx +++ b/panda/src/putil/bamReader_ext.cxx @@ -53,24 +53,20 @@ static TypedWritable *factory_callback(const FactoryParams ¶ms){ if (result == nullptr) { util_cat.error() - << "Exception occurred in Python factory function\n"; - - } else if (result == Py_None) { + << "Exception occurred in Python factory function:\n"; + PyErr_Print(); + } + else if (result == Py_None) { util_cat.error() << "Python factory function returned None\n"; Py_DECREF(result); result = nullptr; } -#if defined(HAVE_THREADS) && !defined(SIMPLE_THREADS) - PyGILState_Release(gstate); -#endif + void *object = nullptr; // Unwrap the returned TypedWritable object. - if (result == nullptr) { - return nullptr; - } else { - void *object = nullptr; + if (result != nullptr) { Dtool_Call_ExtractThisPointer(result, Dtool_TypedWritable, &object); TypedWritable *ptr = (TypedWritable *)object; @@ -88,9 +84,69 @@ static TypedWritable *factory_callback(const FactoryParams ¶ms){ } Py_DECREF(result); } - - return (TypedWritable *)object; + else if (DtoolInstance_TYPE(result) == &Dtool_TypedWritable && + Py_TYPE(result) != &Dtool_TypedWritable._PyType) { + // It is a custom subclass of TypedWritable, so we have to keep it + // alive, and decrement it in finalize(), see typedWritable_ext.cxx. + manager->register_finalize(ptr); + } + else { + // Otherwise, we just decrement the Python reference count, but making + // sure that the C++ object is not getting deleted (yet) by this. + bool mem_rules = false; + std::swap(mem_rules, ((Dtool_PyInstDef *)result)->_memory_rules); + Py_DECREF(result); + std::swap(mem_rules, ((Dtool_PyInstDef *)result)->_memory_rules); + } } + +#if defined(HAVE_THREADS) && !defined(SIMPLE_THREADS) + PyGILState_Release(gstate); +#endif + + return (TypedWritable *)object; +} + +/** + * Reads an object from the BamReader. + */ +PyObject *Extension:: +read_object() { + TypedWritable *ptr; + ReferenceCount *ref_ptr; + +#if defined(HAVE_THREADS) && !defined(SIMPLE_THREADS) + PyThreadState *_save; + Py_UNBLOCK_THREADS +#endif + + bool success = _this->read_object(ptr, ref_ptr); + +#if defined(HAVE_THREADS) && !defined(SIMPLE_THREADS) + Py_BLOCK_THREADS +#endif + + if (!success) { + if (_this->is_eof()) { + PyErr_SetNone(PyExc_EOFError); + return nullptr; + } + return nullptr; + } + + if (ptr == nullptr) { + Py_INCREF(Py_None); + return Py_None; + } + + if (ref_ptr != nullptr) { + ref_ptr->ref(); + } + + // Note that, unlike the regular bindings, we take ownership of the object + // here even if it's not inheriting from ReferenceCount. + return DTool_CreatePyInstanceTyped((void *)ptr, Dtool_TypedWritable, + true, false, ptr->get_type_index()); } /** diff --git a/panda/src/putil/bamReader_ext.h b/panda/src/putil/bamReader_ext.h index d7905c617f..3b17186a8d 100644 --- a/panda/src/putil/bamReader_ext.h +++ b/panda/src/putil/bamReader_ext.h @@ -29,6 +29,8 @@ template<> class Extension : public ExtensionBase { public: + PyObject *read_object(); + PyObject *get_file_version() const; static void register_factory(TypeHandle handle, PyObject *func); diff --git a/panda/src/putil/typedWritable.h b/panda/src/putil/typedWritable.h index 94d7c996d0..a97d3812b1 100644 --- a/panda/src/putil/typedWritable.h +++ b/panda/src/putil/typedWritable.h @@ -33,6 +33,9 @@ class ReferenceCount; * See also TypedObject for detailed instructions. */ class EXPCL_PANDA_PUTIL TypedWritable : public TypedObject { +PUBLISHED: + EXTENSION(static PyObject *__new__(PyTypeObject *cls)); + public: static TypedWritable* const Null; @@ -42,13 +45,13 @@ public: virtual ~TypedWritable(); - virtual void write_datagram(BamWriter *manager, Datagram &dg); virtual void update_bam_nested(BamWriter *manager); virtual int complete_pointers(TypedWritable **p_list, BamReader *manager); virtual bool require_fully_complete() const; PUBLISHED: + virtual void write_datagram(BamWriter *manager, Datagram &dg); virtual void fillin(DatagramIterator &scan, BamReader *manager); public: diff --git a/panda/src/putil/typedWritable_ext.cxx b/panda/src/putil/typedWritable_ext.cxx index f6d7d140fe..501a07a600 100644 --- a/panda/src/putil/typedWritable_ext.cxx +++ b/panda/src/putil/typedWritable_ext.cxx @@ -16,11 +16,216 @@ #ifdef HAVE_PYTHON #include "bamWriter.h" +#include "config_putil.h" #ifndef CPPPARSER +extern Dtool_PyTypedObject Dtool_BamReader; extern Dtool_PyTypedObject Dtool_BamWriter; +extern Dtool_PyTypedObject Dtool_Datagram; +extern Dtool_PyTypedObject Dtool_DatagramIterator; +extern Dtool_PyTypedObject Dtool_TypedObject; +extern Dtool_PyTypedObject Dtool_TypedWritable; +extern Dtool_PyTypedObject Dtool_TypeHandle; #endif // CPPPARSER +/** + * Class that upcalls to the parent class when write_datagram is called. + */ +class TypedWritableProxy : public TypedWritable { +public: + ~TypedWritableProxy() { + } + + virtual void write_datagram(BamWriter *manager, Datagram &dg) override { + // The derived method may call back to the TypedWritable implementation, + // which would end up back here. Detect and prevent this. + thread_local TypedWritableProxy *recursion_protect = nullptr; + if (recursion_protect == this) { + TypedWritable::write_datagram(manager, dg); + return; + } + + // We don't know where this might be invoked, so we have to be on the safe + // side and ensure that the GIL is being held. +#if defined(HAVE_THREADS) && !defined(SIMPLE_THREADS) + PyGILState_STATE gstate = PyGILState_Ensure(); +#endif + + TypedWritableProxy *prev_recursion_protect = this; + std::swap(recursion_protect, prev_recursion_protect); + + PyObject *py_manager = DTool_CreatePyInstance(manager, Dtool_BamWriter, false, false); + PyObject *py_dg = DTool_CreatePyInstance(&dg, Dtool_Datagram, false, false); + + PyObject *result = PyObject_CallMethod(_self, "write_datagram", "NN", py_manager, py_dg); + if (result != nullptr) { + Py_DECREF(result); + } else { + util_cat.error() + << "Exception occurred in Python write_datagram function:\n"; + PyErr_Print(); + } + + std::swap(recursion_protect, prev_recursion_protect); + +#if defined(HAVE_THREADS) && !defined(SIMPLE_THREADS) + PyGILState_Release(gstate); +#endif + } + + virtual void fillin(DatagramIterator &scan, BamReader *manager) override { + // The derived method may call back to the TypedWritable implementation, + // which would end up back here. Detect and prevent this. + thread_local TypedWritableProxy *recursion_protect = nullptr; + if (recursion_protect == this) { + TypedWritable::fillin(scan, manager); + return; + } + + // We don't know where this might be invoked, so we have to be on the safe + // side and ensure that the GIL is being held. +#if defined(HAVE_THREADS) && !defined(SIMPLE_THREADS) + PyGILState_STATE gstate = PyGILState_Ensure(); +#endif + + TypedWritableProxy *prev_recursion_protect = this; + std::swap(recursion_protect, prev_recursion_protect); + + PyObject *py_scan = DTool_CreatePyInstance(&scan, Dtool_DatagramIterator, false, false); + PyObject *py_manager = DTool_CreatePyInstance(manager, Dtool_BamReader, false, false); + + PyObject *result = PyObject_CallMethod(_self, "fillin", "NN", py_scan, py_manager); + if (result != nullptr) { + Py_DECREF(result); + } else { + util_cat.error() + << "Exception occurred in Python fillin function:\n"; + PyErr_Print(); + } + + std::swap(recursion_protect, prev_recursion_protect); + +#if defined(HAVE_THREADS) && !defined(SIMPLE_THREADS) + PyGILState_Release(gstate); +#endif + } + + virtual void finalize(BamReader *manager) override { + // If nobody stored the object after calling read_object(), this will cause + // this object to be deleted. + Py_DECREF(_self); + } + + virtual TypeHandle get_type() const override { + return _type; + } + + virtual TypeHandle force_init_type() override { + return _type; + } + +public: + PyObject *_self; + TypeHandle _type; +}; + +/** + * Returns a wrapper object for a TypedWritable subclass. + */ +static PyObject * +wrap_typed_writable(void *from_this, PyTypeObject *from_type) { + nassertr(from_this != nullptr, nullptr); + nassertr(from_type != nullptr, nullptr); + + TypedWritableProxy *to_this; + if (from_type == &Dtool_TypedWritable._PyType) { + to_this = (TypedWritableProxy *)(TypedWritable *)from_this; + } + else if (from_type == (PyTypeObject *)&Dtool_TypedObject._PyType) { + to_this = (TypedWritableProxy *)(TypedObject *)from_this; + } + else { + return nullptr; + } + + nassertr(to_this->_self != nullptr, nullptr); + Py_INCREF(to_this->_self); + return to_this->_self; +} + +/** + * Registers a Python type recursively, towards the TypedWritable base. + * Returns a TypeHandle if it inherited from TypedWritable, 0 otherwise. + */ +static TypeHandle +register_python_type(TypeRegistry *registry, PyTypeObject *cls) { + TypeHandle handle = TypeHandle::none(); + + if (cls->tp_bases != nullptr) { + Py_ssize_t count = PyTuple_GET_SIZE(cls->tp_bases); + for (Py_ssize_t i = 0; i < count; ++i) { + PyObject *base = PyTuple_GET_ITEM(cls->tp_bases, count); + TypeHandle base_handle = register_python_type(registry, (PyTypeObject *)base); + if (base_handle != TypeHandle::none()) { + if (handle == TypeHandle::none()) { + handle = registry->register_dynamic_type(cls->tp_name); + } + registry->record_derivation(handle, base_handle); + return handle; + } + } + } + + return handle; +} + +/** + * This is called when a TypedWritable is instantiated directly. + */ +PyObject *Extension:: +__new__(PyTypeObject *cls) { + if (cls == (PyTypeObject *)&Dtool_TypedWritable) { + return Dtool_Raise_TypeError("cannot init abstract class"); + } + + PyObject *self = cls->tp_alloc(cls, 0); + ((Dtool_PyInstDef *)self)->_signature = PY_PANDA_SIGNATURE; + ((Dtool_PyInstDef *)self)->_My_Type = &Dtool_TypedWritable; + + // We expect the user to override this method. + PyObject *class_type = PyObject_CallMethod((PyObject *)cls, "get_class_type", nullptr); + if (class_type == nullptr) { + return nullptr; + } + + // Check that it returned a TypeHandle, and that it is actually different + // from the one on the base class (which might mean that the user didn't + // actually define a custom get_class_type() method). + TypeHandle *handle = nullptr; + if (!DtoolInstance_GetPointer(class_type, handle, Dtool_TypeHandle) || + *handle == TypedWritable::get_class_type() || + *handle == TypedObject::get_class_type() || + !handle->is_derived_from(TypedWritable::get_class_type())) { + Dtool_Raise_TypeError("get_class_type() must be overridden to return a unique TypeHandle that indicates derivation from TypedWritable"); + return nullptr; + } + + // Make sure that the bindings know how to obtain a wrapper for this type. + TypeRegistry *registry = TypeRegistry::ptr(); + registry->record_python_type(*handle, cls, &wrap_typed_writable); + Py_INCREF(cls); + + // Note that we don't increment the reference count here, because that would + // create a memory leak. The TypedWritableProxy gets deleted when the Python + // object reaches a reference count of 0. + TypedWritableProxy *proxy = new TypedWritableProxy; + proxy->_self = self; + proxy->_type = *handle; + + DTool_PyInit_Finalize(self, (void *)proxy, &Dtool_TypedWritable, true, false); + return self; +} + /** * This special Python method is implement to provide support for the pickle * module. diff --git a/panda/src/putil/typedWritable_ext.h b/panda/src/putil/typedWritable_ext.h index 3d745ffb3e..9b095d7fa9 100644 --- a/panda/src/putil/typedWritable_ext.h +++ b/panda/src/putil/typedWritable_ext.h @@ -29,6 +29,8 @@ template<> class Extension : public ExtensionBase { public: + static PyObject *__new__(PyTypeObject *cls); + PyObject *__reduce__(PyObject *self) const; PyObject *__reduce_persist__(PyObject *self, PyObject *pickler) const; diff --git a/tests/putil/test_custom_writable.py b/tests/putil/test_custom_writable.py new file mode 100644 index 0000000000..202c12320c --- /dev/null +++ b/tests/putil/test_custom_writable.py @@ -0,0 +1,53 @@ +from panda3d.core import TypeRegistry, TypedWritable +from panda3d.core import DatagramBuffer, BamReader, BamWriter +import sys + + +class CustomObject(TypedWritable): + def __init__(self): + self.field = 0 + + def get_class_type(): + registry = TypeRegistry.ptr() + handle = registry.register_dynamic_type("CustomObject") + registry.record_derivation(handle, TypedWritable) + return handle + + def write_datagram(self, writer, dg): + dg.add_uint8(self.field) + + def fillin(self, scan, reader): + self.field = scan.get_uint8() + + @staticmethod + def make_from_bam(scan, reader): + obj = CustomObject() + obj.fillin(scan, reader) + return obj + + +BamReader.register_factory(CustomObject.get_class_type(), CustomObject.make_from_bam) + + +def test_typed_writable_subclass(): + obj = CustomObject() + obj.field = 123 + assert obj.get_type() == CustomObject.get_class_type() + assert obj.type == CustomObject.get_class_type() + + buf = DatagramBuffer() + + writer = BamWriter(buf) + writer.init() + writer.write_object(obj) + del writer + + reader = BamReader(buf) + reader.init() + obj = reader.read_object() + assert sys.getrefcount(obj) == 3 + reader.resolve() + del reader + assert sys.getrefcount(obj) == 2 + + assert obj.field == 123 From f0a4e61fd92afe025f243feedbbec09f1a4bef0f Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 26 Jul 2023 20:02:49 +0200 Subject: [PATCH 34/84] Revert "general: Add headers explaining the renamed config_*.h" This reverts commit 47f7d3f29733bdcbc39ece033006f7f9f2d3857b. These header files have been deprecated for years and can be safely removed now. --- makepanda/makepanda.py | 2 -- panda/src/pstatclient/config_pstats.h | 2 -- panda/src/putil/config_util.h | 2 -- 3 files changed, 6 deletions(-) delete mode 100644 panda/src/pstatclient/config_pstats.h delete mode 100644 panda/src/putil/config_util.h diff --git a/makepanda/makepanda.py b/makepanda/makepanda.py index d62789bd38..3ee9778097 100755 --- a/makepanda/makepanda.py +++ b/makepanda/makepanda.py @@ -3711,7 +3711,6 @@ TargetAdd('p3putil_composite2.obj', opts=OPTS, input='p3putil_composite2.cxx') OPTS=['DIR:panda/src/putil', 'ZLIB'] IGATEFILES=GetDirectoryContents('panda/src/putil', ["*.h", "*_composite*.cxx"]) IGATEFILES.remove("test_bam.h") -IGATEFILES.remove("config_util.h") TargetAdd('libp3putil.in', opts=OPTS, input=IGATEFILES) TargetAdd('libp3putil.in', opts=['IMOD:panda3d.core', 'ILIB:libp3putil', 'SRCDIR:panda/src/putil']) PyTargetAdd('p3putil_ext_composite.obj', opts=OPTS, input='p3putil_ext_composite.cxx') @@ -3822,7 +3821,6 @@ TargetAdd('p3pstatclient_composite2.obj', opts=OPTS, input='p3pstatclient_compos OPTS=['DIR:panda/src/pstatclient'] IGATEFILES=GetDirectoryContents('panda/src/pstatclient', ["*.h", "*_composite*.cxx"]) -IGATEFILES.remove("config_pstats.h") TargetAdd('libp3pstatclient.in', opts=OPTS, input=IGATEFILES) TargetAdd('libp3pstatclient.in', opts=['IMOD:panda3d.core', 'ILIB:libp3pstatclient', 'SRCDIR:panda/src/pstatclient']) PyTargetAdd('p3pstatclient_pStatClient_ext.obj', opts=OPTS, input='pStatClient_ext.cxx') diff --git a/panda/src/pstatclient/config_pstats.h b/panda/src/pstatclient/config_pstats.h deleted file mode 100644 index 84f42df553..0000000000 --- a/panda/src/pstatclient/config_pstats.h +++ /dev/null @@ -1,2 +0,0 @@ -// This file to remain during the whole 1.10.x cycle; remove after that. -#error config_pstats.h has been renamed to config_pstatclient.h - please update your project. diff --git a/panda/src/putil/config_util.h b/panda/src/putil/config_util.h deleted file mode 100644 index 6886f3257d..0000000000 --- a/panda/src/putil/config_util.h +++ /dev/null @@ -1,2 +0,0 @@ -// This file to remain during the whole 1.10.x cycle; remove after that. -#error config_util.h has been renamed to config_putil.h - please update your project. From cc49825e00ff0e5d549b5d6fc2f4adf5a7ef3139 Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 27 Jul 2023 08:40:52 +0200 Subject: [PATCH 35/84] pgraph: Mark all sub-classes of RenderAttrib as `final` --- panda/src/pgraph/alphaTestAttrib.h | 2 +- panda/src/pgraph/antialiasAttrib.h | 2 +- panda/src/pgraph/audioVolumeAttrib.h | 2 +- panda/src/pgraph/auxBitplaneAttrib.h | 2 +- panda/src/pgraph/clipPlaneAttrib.h | 2 +- panda/src/pgraph/colorAttrib.h | 2 +- panda/src/pgraph/colorBlendAttrib.h | 2 +- panda/src/pgraph/colorScaleAttrib.h | 2 +- panda/src/pgraph/colorWriteAttrib.h | 2 +- panda/src/pgraph/cullBinAttrib.h | 2 +- panda/src/pgraph/cullFaceAttrib.h | 2 +- panda/src/pgraph/depthBiasAttrib.h | 2 +- panda/src/pgraph/depthOffsetAttrib.h | 2 +- panda/src/pgraph/depthTestAttrib.h | 2 +- panda/src/pgraph/depthWriteAttrib.h | 2 +- panda/src/pgraph/fogAttrib.h | 2 +- panda/src/pgraph/lightAttrib.h | 2 +- panda/src/pgraph/lightRampAttrib.h | 2 +- panda/src/pgraph/logicOpAttrib.h | 2 +- panda/src/pgraph/materialAttrib.h | 2 +- panda/src/pgraph/renderModeAttrib.h | 2 +- panda/src/pgraph/rescaleNormalAttrib.h | 2 +- panda/src/pgraph/scissorAttrib.h | 2 +- panda/src/pgraph/shadeModelAttrib.h | 2 +- panda/src/pgraph/shaderAttrib.h | 2 +- panda/src/pgraph/stencilAttrib.h | 2 +- panda/src/pgraph/texGenAttrib.h | 2 +- panda/src/pgraph/texMatrixAttrib.h | 2 +- panda/src/pgraph/textureAttrib.h | 2 +- panda/src/pgraph/transparencyAttrib.h | 2 +- 30 files changed, 30 insertions(+), 30 deletions(-) diff --git a/panda/src/pgraph/alphaTestAttrib.h b/panda/src/pgraph/alphaTestAttrib.h index 96225fe902..6f460f4874 100644 --- a/panda/src/pgraph/alphaTestAttrib.h +++ b/panda/src/pgraph/alphaTestAttrib.h @@ -23,7 +23,7 @@ class FactoryParams; * Enables or disables writing of pixel to framebuffer based on its alpha * value relative to a reference alpha value */ -class EXPCL_PANDA_PGRAPH AlphaTestAttrib : public RenderAttrib { +class EXPCL_PANDA_PGRAPH AlphaTestAttrib final : public RenderAttrib { private: INLINE AlphaTestAttrib(PandaCompareFunc mode = M_always, PN_stdfloat reference_alpha = 1.0f); diff --git a/panda/src/pgraph/antialiasAttrib.h b/panda/src/pgraph/antialiasAttrib.h index 454210516d..af468c9ed5 100644 --- a/panda/src/pgraph/antialiasAttrib.h +++ b/panda/src/pgraph/antialiasAttrib.h @@ -24,7 +24,7 @@ class FactoryParams; * Specifies whether or how to enable antialiasing, if supported by the * backend renderer. */ -class EXPCL_PANDA_PGRAPH AntialiasAttrib : public RenderAttrib { +class EXPCL_PANDA_PGRAPH AntialiasAttrib final : public RenderAttrib { PUBLISHED: enum Mode { M_none = 0x0000, diff --git a/panda/src/pgraph/audioVolumeAttrib.h b/panda/src/pgraph/audioVolumeAttrib.h index 564db9748e..6aae277aee 100644 --- a/panda/src/pgraph/audioVolumeAttrib.h +++ b/panda/src/pgraph/audioVolumeAttrib.h @@ -24,7 +24,7 @@ class FactoryParams; /** * Applies a scale to audio volume for positional sounds in the scene graph. */ -class EXPCL_PANDA_PGRAPH AudioVolumeAttrib : public RenderAttrib { +class EXPCL_PANDA_PGRAPH AudioVolumeAttrib final : public RenderAttrib { protected: AudioVolumeAttrib(bool off, PN_stdfloat volume); INLINE AudioVolumeAttrib(const AudioVolumeAttrib ©); diff --git a/panda/src/pgraph/auxBitplaneAttrib.h b/panda/src/pgraph/auxBitplaneAttrib.h index 6283b09587..4d29e44413 100644 --- a/panda/src/pgraph/auxBitplaneAttrib.h +++ b/panda/src/pgraph/auxBitplaneAttrib.h @@ -46,7 +46,7 @@ class FactoryParams; * Otherwise, it has no effect. * */ -class EXPCL_PANDA_PGRAPH AuxBitplaneAttrib : public RenderAttrib { +class EXPCL_PANDA_PGRAPH AuxBitplaneAttrib final : public RenderAttrib { private: INLINE AuxBitplaneAttrib(int outputs); diff --git a/panda/src/pgraph/clipPlaneAttrib.h b/panda/src/pgraph/clipPlaneAttrib.h index 511ea34b01..14a3f90606 100644 --- a/panda/src/pgraph/clipPlaneAttrib.h +++ b/panda/src/pgraph/clipPlaneAttrib.h @@ -28,7 +28,7 @@ * ClipPlaneAttrib can either add planes or remove planes from the total set * of clipping planes in effect. */ -class EXPCL_PANDA_PGRAPH ClipPlaneAttrib : public RenderAttrib { +class EXPCL_PANDA_PGRAPH ClipPlaneAttrib final : public RenderAttrib { private: INLINE ClipPlaneAttrib(); INLINE ClipPlaneAttrib(const ClipPlaneAttrib ©); diff --git a/panda/src/pgraph/colorAttrib.h b/panda/src/pgraph/colorAttrib.h index b652233a62..872d1686eb 100644 --- a/panda/src/pgraph/colorAttrib.h +++ b/panda/src/pgraph/colorAttrib.h @@ -24,7 +24,7 @@ class FactoryParams; /** * Indicates what color should be applied to renderable geometry. */ -class EXPCL_PANDA_PGRAPH ColorAttrib : public RenderAttrib { +class EXPCL_PANDA_PGRAPH ColorAttrib final : public RenderAttrib { PUBLISHED: enum Type { T_vertex, T_flat, T_off diff --git a/panda/src/pgraph/colorBlendAttrib.h b/panda/src/pgraph/colorBlendAttrib.h index 87b680425f..4aefea44eb 100644 --- a/panda/src/pgraph/colorBlendAttrib.h +++ b/panda/src/pgraph/colorBlendAttrib.h @@ -24,7 +24,7 @@ class FactoryParams; * This specifies how colors are blended into the frame buffer, for special * effects. This overrides transparency if transparency is also specified. */ -class EXPCL_PANDA_PGRAPH ColorBlendAttrib : public RenderAttrib { +class EXPCL_PANDA_PGRAPH ColorBlendAttrib final : public RenderAttrib { PUBLISHED: enum Mode { M_none, // Blending is disabled diff --git a/panda/src/pgraph/colorScaleAttrib.h b/panda/src/pgraph/colorScaleAttrib.h index 918bbe9874..1b75f6ca14 100644 --- a/panda/src/pgraph/colorScaleAttrib.h +++ b/panda/src/pgraph/colorScaleAttrib.h @@ -24,7 +24,7 @@ class FactoryParams; /** * Applies a scale to colors in the scene graph and on vertices. */ -class EXPCL_PANDA_PGRAPH ColorScaleAttrib : public RenderAttrib { +class EXPCL_PANDA_PGRAPH ColorScaleAttrib final : public RenderAttrib { protected: ColorScaleAttrib(bool off, const LVecBase4 &scale); INLINE ColorScaleAttrib(const ColorScaleAttrib ©); diff --git a/panda/src/pgraph/colorWriteAttrib.h b/panda/src/pgraph/colorWriteAttrib.h index 02d4fd2ca9..381f65c33a 100644 --- a/panda/src/pgraph/colorWriteAttrib.h +++ b/panda/src/pgraph/colorWriteAttrib.h @@ -25,7 +25,7 @@ class FactoryParams; * for certain special effects in which it is important to write to the depth * buffer without affecting the color buffer. */ -class EXPCL_PANDA_PGRAPH ColorWriteAttrib : public RenderAttrib { +class EXPCL_PANDA_PGRAPH ColorWriteAttrib final : public RenderAttrib { PUBLISHED: enum Channels { // By coincidence, these bits are the same as those for diff --git a/panda/src/pgraph/cullBinAttrib.h b/panda/src/pgraph/cullBinAttrib.h index 1104f21af7..c9767c3938 100644 --- a/panda/src/pgraph/cullBinAttrib.h +++ b/panda/src/pgraph/cullBinAttrib.h @@ -24,7 +24,7 @@ class FactoryParams; * Assigns geometry to a particular bin by name. The bins must be created * separately via the CullBinManager interface. */ -class EXPCL_PANDA_PGRAPH CullBinAttrib : public RenderAttrib { +class EXPCL_PANDA_PGRAPH CullBinAttrib final : public RenderAttrib { private: INLINE CullBinAttrib(); diff --git a/panda/src/pgraph/cullFaceAttrib.h b/panda/src/pgraph/cullFaceAttrib.h index def2216976..1a93f19638 100644 --- a/panda/src/pgraph/cullFaceAttrib.h +++ b/panda/src/pgraph/cullFaceAttrib.h @@ -23,7 +23,7 @@ class FactoryParams; /** * Indicates which faces should be culled based on their vertex ordering. */ -class EXPCL_PANDA_PGRAPH CullFaceAttrib : public RenderAttrib { +class EXPCL_PANDA_PGRAPH CullFaceAttrib final : public RenderAttrib { PUBLISHED: enum Mode { M_cull_none, // Cull no polygons diff --git a/panda/src/pgraph/depthBiasAttrib.h b/panda/src/pgraph/depthBiasAttrib.h index fea972bd81..1a20b85846 100644 --- a/panda/src/pgraph/depthBiasAttrib.h +++ b/panda/src/pgraph/depthBiasAttrib.h @@ -40,7 +40,7 @@ class FactoryParams; * * @since 1.11.0 */ -class EXPCL_PANDA_PGRAPH DepthBiasAttrib : public RenderAttrib { +class EXPCL_PANDA_PGRAPH DepthBiasAttrib final : public RenderAttrib { private: INLINE DepthBiasAttrib(PN_stdfloat slope_factor, PN_stdfloat constant_factor, PN_stdfloat clamp = 0); diff --git a/panda/src/pgraph/depthOffsetAttrib.h b/panda/src/pgraph/depthOffsetAttrib.h index 6f868cec88..aa1739e72a 100644 --- a/panda/src/pgraph/depthOffsetAttrib.h +++ b/panda/src/pgraph/depthOffsetAttrib.h @@ -49,7 +49,7 @@ class FactoryParams; * * @deprecated See DepthBiasAttrib and DisplayRegion::set_depth_range() instead. */ -class EXPCL_PANDA_PGRAPH DepthOffsetAttrib : public RenderAttrib { +class EXPCL_PANDA_PGRAPH DepthOffsetAttrib final : public RenderAttrib { private: INLINE DepthOffsetAttrib(int offset, PN_stdfloat min_value, PN_stdfloat max_value); diff --git a/panda/src/pgraph/depthTestAttrib.h b/panda/src/pgraph/depthTestAttrib.h index f4d6c52352..6e148383e7 100644 --- a/panda/src/pgraph/depthTestAttrib.h +++ b/panda/src/pgraph/depthTestAttrib.h @@ -23,7 +23,7 @@ class FactoryParams; /** * Enables or disables writing to the depth buffer. */ -class EXPCL_PANDA_PGRAPH DepthTestAttrib : public RenderAttrib { +class EXPCL_PANDA_PGRAPH DepthTestAttrib final : public RenderAttrib { private: INLINE DepthTestAttrib(PandaCompareFunc mode = M_less); diff --git a/panda/src/pgraph/depthWriteAttrib.h b/panda/src/pgraph/depthWriteAttrib.h index 50e31e764d..bb02b4336c 100644 --- a/panda/src/pgraph/depthWriteAttrib.h +++ b/panda/src/pgraph/depthWriteAttrib.h @@ -23,7 +23,7 @@ class FactoryParams; /** * Enables or disables writing to the depth buffer. */ -class EXPCL_PANDA_PGRAPH DepthWriteAttrib : public RenderAttrib { +class EXPCL_PANDA_PGRAPH DepthWriteAttrib final : public RenderAttrib { PUBLISHED: enum Mode { M_off, diff --git a/panda/src/pgraph/fogAttrib.h b/panda/src/pgraph/fogAttrib.h index 8dac86fd6a..e513aacf0c 100644 --- a/panda/src/pgraph/fogAttrib.h +++ b/panda/src/pgraph/fogAttrib.h @@ -22,7 +22,7 @@ /** * Applies a Fog to the geometry at and below this node. */ -class EXPCL_PANDA_PGRAPH FogAttrib : public RenderAttrib { +class EXPCL_PANDA_PGRAPH FogAttrib final : public RenderAttrib { private: INLINE FogAttrib(); diff --git a/panda/src/pgraph/lightAttrib.h b/panda/src/pgraph/lightAttrib.h index 361a4a6c1e..963fffa49a 100644 --- a/panda/src/pgraph/lightAttrib.h +++ b/panda/src/pgraph/lightAttrib.h @@ -27,7 +27,7 @@ * geometry at this level and below. A LightAttrib can either add lights or * remove lights from the total set of "on" lights. */ -class EXPCL_PANDA_PGRAPH LightAttrib : public RenderAttrib { +class EXPCL_PANDA_PGRAPH LightAttrib final : public RenderAttrib { protected: INLINE LightAttrib(); LightAttrib(const LightAttrib ©); diff --git a/panda/src/pgraph/lightRampAttrib.h b/panda/src/pgraph/lightRampAttrib.h index d6859676bf..12b3711892 100644 --- a/panda/src/pgraph/lightRampAttrib.h +++ b/panda/src/pgraph/lightRampAttrib.h @@ -25,7 +25,7 @@ class FactoryParams; * a kind of light ramp. So is HDR tone mapping. So is cartoon shading. See * the constructors for an explanation of each kind of ramp. */ -class EXPCL_PANDA_PGRAPH LightRampAttrib : public RenderAttrib { +class EXPCL_PANDA_PGRAPH LightRampAttrib final : public RenderAttrib { private: INLINE LightRampAttrib(); diff --git a/panda/src/pgraph/logicOpAttrib.h b/panda/src/pgraph/logicOpAttrib.h index 7d6b0f5b6e..86bf48b530 100644 --- a/panda/src/pgraph/logicOpAttrib.h +++ b/panda/src/pgraph/logicOpAttrib.h @@ -27,7 +27,7 @@ class FactoryParams; * * @since 1.10.0 */ -class EXPCL_PANDA_PGRAPH LogicOpAttrib : public RenderAttrib { +class EXPCL_PANDA_PGRAPH LogicOpAttrib final : public RenderAttrib { PUBLISHED: enum Operation { O_none, // LogicOp disabled, regular blending occurs. diff --git a/panda/src/pgraph/materialAttrib.h b/panda/src/pgraph/materialAttrib.h index 0e65498d70..9b2aa718eb 100644 --- a/panda/src/pgraph/materialAttrib.h +++ b/panda/src/pgraph/materialAttrib.h @@ -24,7 +24,7 @@ * material is used primarily to control lighting effects, and isn't necessary * (or useful) in the absence of lighting. */ -class EXPCL_PANDA_PGRAPH MaterialAttrib : public RenderAttrib { +class EXPCL_PANDA_PGRAPH MaterialAttrib final : public RenderAttrib { private: INLINE MaterialAttrib(); diff --git a/panda/src/pgraph/renderModeAttrib.h b/panda/src/pgraph/renderModeAttrib.h index 9684ee5176..3a1d993efc 100644 --- a/panda/src/pgraph/renderModeAttrib.h +++ b/panda/src/pgraph/renderModeAttrib.h @@ -24,7 +24,7 @@ class FactoryParams; /** * Specifies how polygons are to be drawn. */ -class EXPCL_PANDA_PGRAPH RenderModeAttrib : public RenderAttrib { +class EXPCL_PANDA_PGRAPH RenderModeAttrib final : public RenderAttrib { PUBLISHED: enum Mode { M_unchanged, diff --git a/panda/src/pgraph/rescaleNormalAttrib.h b/panda/src/pgraph/rescaleNormalAttrib.h index 7f87219285..d3a7df3d1c 100644 --- a/panda/src/pgraph/rescaleNormalAttrib.h +++ b/panda/src/pgraph/rescaleNormalAttrib.h @@ -23,7 +23,7 @@ class FactoryParams; /** * Specifies how polygons are to be drawn. */ -class EXPCL_PANDA_PGRAPH RescaleNormalAttrib : public RenderAttrib { +class EXPCL_PANDA_PGRAPH RescaleNormalAttrib final : public RenderAttrib { PUBLISHED: enum Mode { // No adjustments are made to normals. diff --git a/panda/src/pgraph/scissorAttrib.h b/panda/src/pgraph/scissorAttrib.h index c7c3ff3c4e..6c2c872672 100644 --- a/panda/src/pgraph/scissorAttrib.h +++ b/panda/src/pgraph/scissorAttrib.h @@ -33,7 +33,7 @@ class FactoryParams; * See ScissorEffect if you wish to define a region relative to 2-D or 3-D * coordinates in the scene graph, with culling. */ -class EXPCL_PANDA_PGRAPH ScissorAttrib : public RenderAttrib { +class EXPCL_PANDA_PGRAPH ScissorAttrib final : public RenderAttrib { private: ScissorAttrib(const LVecBase4 &frame); diff --git a/panda/src/pgraph/shadeModelAttrib.h b/panda/src/pgraph/shadeModelAttrib.h index c5e0819141..40add922c2 100644 --- a/panda/src/pgraph/shadeModelAttrib.h +++ b/panda/src/pgraph/shadeModelAttrib.h @@ -24,7 +24,7 @@ class FactoryParams; * Specifies whether flat shading (per-polygon) or smooth shading (per-vertex) * is in effect. */ -class EXPCL_PANDA_PGRAPH ShadeModelAttrib : public RenderAttrib { +class EXPCL_PANDA_PGRAPH ShadeModelAttrib final : public RenderAttrib { PUBLISHED: enum Mode { M_flat, diff --git a/panda/src/pgraph/shaderAttrib.h b/panda/src/pgraph/shaderAttrib.h index 6552fdf385..cdc8a9b65f 100644 --- a/panda/src/pgraph/shaderAttrib.h +++ b/panda/src/pgraph/shaderAttrib.h @@ -36,7 +36,7 @@ /** * */ -class EXPCL_PANDA_PGRAPH ShaderAttrib: public RenderAttrib { +class EXPCL_PANDA_PGRAPH ShaderAttrib final : public RenderAttrib { private: INLINE ShaderAttrib(); INLINE ShaderAttrib(const ShaderAttrib ©); diff --git a/panda/src/pgraph/stencilAttrib.h b/panda/src/pgraph/stencilAttrib.h index ffc205179c..df28be5dfb 100644 --- a/panda/src/pgraph/stencilAttrib.h +++ b/panda/src/pgraph/stencilAttrib.h @@ -25,7 +25,7 @@ class FactoryParams; * make or make_2_sided. To determine if two sided stencil is supported, call * the function GraphicsStateGuardian:: get_supports_two_sided_stencil. */ -class EXPCL_PANDA_PGRAPH StencilAttrib : public RenderAttrib { +class EXPCL_PANDA_PGRAPH StencilAttrib final : public RenderAttrib { private: StencilAttrib(); diff --git a/panda/src/pgraph/texGenAttrib.h b/panda/src/pgraph/texGenAttrib.h index 0bd9e463e8..3966dbb8cf 100644 --- a/panda/src/pgraph/texGenAttrib.h +++ b/panda/src/pgraph/texGenAttrib.h @@ -29,7 +29,7 @@ * refraction maps, for instance to make shiny surfaces, as well as other * special effects such as projective texturing. */ -class EXPCL_PANDA_PGRAPH TexGenAttrib : public RenderAttrib { +class EXPCL_PANDA_PGRAPH TexGenAttrib final : public RenderAttrib { PUBLISHED: // We inherit the definition of our Mode enumerated type from RenderAttrib. // Normally, Mode would be defined here, but we define it in the base class diff --git a/panda/src/pgraph/texMatrixAttrib.h b/panda/src/pgraph/texMatrixAttrib.h index 28034a5afa..4fbfec4db8 100644 --- a/panda/src/pgraph/texMatrixAttrib.h +++ b/panda/src/pgraph/texMatrixAttrib.h @@ -27,7 +27,7 @@ class FactoryParams; /** * Applies a transform matrix to UV's before they are rendered. */ -class EXPCL_PANDA_PGRAPH TexMatrixAttrib : public RenderAttrib { +class EXPCL_PANDA_PGRAPH TexMatrixAttrib final : public RenderAttrib { protected: INLINE TexMatrixAttrib(); INLINE TexMatrixAttrib(const TexMatrixAttrib ©); diff --git a/panda/src/pgraph/textureAttrib.h b/panda/src/pgraph/textureAttrib.h index 48c61fa86f..5625237bb2 100644 --- a/panda/src/pgraph/textureAttrib.h +++ b/panda/src/pgraph/textureAttrib.h @@ -29,7 +29,7 @@ * Indicates the set of TextureStages and their associated Textures that * should be applied to (or removed from) a node. */ -class EXPCL_PANDA_PGRAPH TextureAttrib : public RenderAttrib { +class EXPCL_PANDA_PGRAPH TextureAttrib final : public RenderAttrib { protected: INLINE TextureAttrib(); INLINE TextureAttrib(const TextureAttrib ©); diff --git a/panda/src/pgraph/transparencyAttrib.h b/panda/src/pgraph/transparencyAttrib.h index 4021697596..a888c70f68 100644 --- a/panda/src/pgraph/transparencyAttrib.h +++ b/panda/src/pgraph/transparencyAttrib.h @@ -28,7 +28,7 @@ class FactoryParams; * effect unless you actually want it to be at least partially transparent * (and it has alpha components less than 1). */ -class EXPCL_PANDA_PGRAPH TransparencyAttrib : public RenderAttrib { +class EXPCL_PANDA_PGRAPH TransparencyAttrib final : public RenderAttrib { PUBLISHED: enum Mode { // The first two should be specifically 0 and 1, for historical reasons From 3c9aea1ee129c519b82625507e7f031c453f0dbf Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 2 Aug 2023 07:51:46 +0200 Subject: [PATCH 36/84] text: Fix missing epvector.h include in textAssembler.h --- panda/src/text/textAssembler.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/panda/src/text/textAssembler.h b/panda/src/text/textAssembler.h index 2cbede0d10..20f9b2c1e5 100644 --- a/panda/src/text/textAssembler.h +++ b/panda/src/text/textAssembler.h @@ -25,7 +25,7 @@ #include "textPropertiesManager.h" #include "textEncoder.h" #include "geomVertexRewriter.h" - +#include "epvector.h" #include "pmap.h" typedef struct hb_buffer_t hb_buffer_t; From 9fd39e1aef94f47ddf5296051fd32fd6ece67168 Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 2 Aug 2023 07:56:24 +0200 Subject: [PATCH 37/84] Add .idea to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 0b40b42f79..8dada724d7 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,7 @@ vgcore.* *.save.1 *.sublime-workspace .vscode/ +.idea/ # Temporary build files /_vfsimporter.* From 262bde3082eefad93581bdfee098e8fe9197e1fd Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 2 Aug 2023 08:08:25 +0200 Subject: [PATCH 38/84] grutil: Add clear_color method to CardMaker --- panda/src/grutil/cardMaker.I | 9 +++++++++ panda/src/grutil/cardMaker.h | 1 + 2 files changed, 10 insertions(+) diff --git a/panda/src/grutil/cardMaker.I b/panda/src/grutil/cardMaker.I index b960808ca0..2f8a17a7dc 100644 --- a/panda/src/grutil/cardMaker.I +++ b/panda/src/grutil/cardMaker.I @@ -101,6 +101,15 @@ set_color(const LVecBase4 &color) { _has_color = true; } +/** + * Unsets the color of the card. + */ +INLINE void CardMaker:: +clear_color() { + _has_color = false; + _color.set(1.0f, 1.0f, 1.0f, 1.0f); +} + /** * Sets the flag indicating whether vertices will be generated with normals or * not. Normals are required if you intend to enable lighting on the card, diff --git a/panda/src/grutil/cardMaker.h b/panda/src/grutil/cardMaker.h index 426fc2d5c5..0ac90f2316 100644 --- a/panda/src/grutil/cardMaker.h +++ b/panda/src/grutil/cardMaker.h @@ -49,6 +49,7 @@ PUBLISHED: INLINE void set_color(PN_stdfloat r, PN_stdfloat g, PN_stdfloat b, PN_stdfloat a); INLINE void set_color(const LColor &color); + INLINE void clear_color(); INLINE void set_has_normals(bool flag); From b6c427f2b4141b7e2700dd6d6716c17a9c6de544 Mon Sep 17 00:00:00 2001 From: Max Rodriguez Date: Thu, 22 Jun 2023 14:43:35 -0700 Subject: [PATCH 39/84] putil: Deprecated MouseData alias for PointerData Co-authored-by: rdb Closes #1513 --- panda/src/cocoadisplay/cocoaGraphicsWindow.mm | 4 +-- panda/src/display/graphicsWindow.cxx | 8 +++--- panda/src/display/graphicsWindow.h | 4 +-- panda/src/display/mouseAndKeyboard.cxx | 2 +- panda/src/putil/CMakeLists.txt | 2 +- panda/src/putil/mouseData.h | 27 ------------------- panda/src/tform/driveInterface.cxx | 2 +- panda/src/tform/mouseInterfaceNode.cxx | 2 +- panda/src/tform/mouseWatcher.cxx | 2 +- panda/src/tform/trackball.cxx | 2 +- panda/src/windisplay/winGraphicsWindow.cxx | 8 +++--- panda/src/windisplay/winGraphicsWindow.h | 2 +- panda/src/x11display/x11GraphicsWindow.cxx | 8 +++--- panda/src/x11display/x11GraphicsWindow.h | 2 +- 14 files changed, 24 insertions(+), 51 deletions(-) delete mode 100644 panda/src/putil/mouseData.h diff --git a/panda/src/cocoadisplay/cocoaGraphicsWindow.mm b/panda/src/cocoadisplay/cocoaGraphicsWindow.mm index 0a5bde1f1d..1b6cca2638 100644 --- a/panda/src/cocoadisplay/cocoaGraphicsWindow.mm +++ b/panda/src/cocoadisplay/cocoaGraphicsWindow.mm @@ -127,7 +127,7 @@ CocoaGraphicsWindow:: bool CocoaGraphicsWindow:: move_pointer(int device, int x, int y) { // Hack! Will go away when we have floating-point mouse pos. - MouseData md = get_pointer(device); + PointerData md = get_pointer(device); if (md.get_x() == x && md.get_y() == y) { return true; } @@ -1713,7 +1713,7 @@ handle_mouse_moved_event(bool in_window, double x, double y, bool absolute) { } else { // We received deltas, so add it to the current mouse position. - MouseData md = _input->get_pointer(); + PointerData md = _input->get_pointer(); nx = md.get_x() + x; ny = md.get_y() + y; } diff --git a/panda/src/display/graphicsWindow.cxx b/panda/src/display/graphicsWindow.cxx index e81a1a944d..377da09f04 100644 --- a/panda/src/display/graphicsWindow.cxx +++ b/panda/src/display/graphicsWindow.cxx @@ -355,16 +355,16 @@ disable_pointer_mode(int device) { }*/ /** - * Returns the MouseData associated with the nth input device's pointer. + * Returns the PointerData associated with the nth input device's pointer. * Using this to access raw mice (with an index other than 0) is deprecated, * see the InputDeviceManager interface instead. */ -MouseData GraphicsWindow:: +PointerData GraphicsWindow:: get_pointer(int device) const { - MouseData result; + PointerData result; { LightMutexHolder holder(_input_lock); - nassertr(device >= 0 && device < (int)_input_devices.size(), MouseData()); + nassertr(device >= 0 && device < (int)_input_devices.size(), PointerData()); result = ((const GraphicsWindowInputDevice *)_input_devices[device].p())->get_pointer(); } return result; diff --git a/panda/src/display/graphicsWindow.h b/panda/src/display/graphicsWindow.h index 3cc18007ab..33fb4174d7 100644 --- a/panda/src/display/graphicsWindow.h +++ b/panda/src/display/graphicsWindow.h @@ -21,7 +21,7 @@ #include "graphicsWindowProc.h" #include "graphicsWindowProcCallbackData.h" #include "windowProperties.h" -#include "mouseData.h" +#include "pointerData.h" #include "modifierButtons.h" #include "buttonEvent.h" #include "keyboardButton.h" @@ -97,7 +97,7 @@ PUBLISHED: /*void enable_pointer_mode(int device, double speed); void disable_pointer_mode(int device);*/ - virtual MouseData get_pointer(int device) const; + virtual PointerData get_pointer(int device) const; virtual bool move_pointer(int device, int x, int y); virtual void close_ime(); diff --git a/panda/src/display/mouseAndKeyboard.cxx b/panda/src/display/mouseAndKeyboard.cxx index b1eb49027d..6d014ddbdb 100644 --- a/panda/src/display/mouseAndKeyboard.cxx +++ b/panda/src/display/mouseAndKeyboard.cxx @@ -12,7 +12,7 @@ */ #include "mouseAndKeyboard.h" -#include "mouseData.h" +#include "pointerData.h" #include "buttonHandle.h" #include "buttonEvent.h" #include "dataNodeTransmit.h" diff --git a/panda/src/putil/CMakeLists.txt b/panda/src/putil/CMakeLists.txt index 6f63c5d490..eb312f845a 100644 --- a/panda/src/putil/CMakeLists.txt +++ b/panda/src/putil/CMakeLists.txt @@ -48,7 +48,7 @@ set(P3PUTIL_HEADERS load_prc_file.h loaderOptions.I loaderOptions.h modifierButtons.I modifierButtons.h - mouseButton.h mouseData.h + mouseButton.h nameUniquifier.I nameUniquifier.h nodeCachedReferenceCount.h nodeCachedReferenceCount.I paramValue.I paramValue.h diff --git a/panda/src/putil/mouseData.h b/panda/src/putil/mouseData.h deleted file mode 100644 index 2747c26061..0000000000 --- a/panda/src/putil/mouseData.h +++ /dev/null @@ -1,27 +0,0 @@ -/** - * 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 mouseData.h - * @author rdb - * @date 2018-09-24 - */ - -#ifndef MOUSEDATA_H -#define MOUSEDATA_H - -#include "pointerData.h" - -BEGIN_PUBLISH -/** - * Deprecated alias for PointerData. - */ -typedef PointerData MouseData; - -END_PUBLISH - -#endif diff --git a/panda/src/tform/driveInterface.cxx b/panda/src/tform/driveInterface.cxx index eb3433c557..22a23135f5 100644 --- a/panda/src/tform/driveInterface.cxx +++ b/panda/src/tform/driveInterface.cxx @@ -16,7 +16,7 @@ #include "compose_matrix.h" #include "mouseAndKeyboard.h" -#include "mouseData.h" +#include "pointerData.h" #include "clockObject.h" #include "modifierButtons.h" #include "keyboardButton.h" diff --git a/panda/src/tform/mouseInterfaceNode.cxx b/panda/src/tform/mouseInterfaceNode.cxx index 63c6c6cf87..f9c2547539 100644 --- a/panda/src/tform/mouseInterfaceNode.cxx +++ b/panda/src/tform/mouseInterfaceNode.cxx @@ -15,7 +15,7 @@ #include "buttonEvent.h" #include "buttonEventList.h" #include "dataNodeTransmit.h" -#include "mouseData.h" +#include "pointerData.h" TypeHandle MouseInterfaceNode::_type_handle; diff --git a/panda/src/tform/mouseWatcher.cxx b/panda/src/tform/mouseWatcher.cxx index 7674f2642d..8a3cba522d 100644 --- a/panda/src/tform/mouseWatcher.cxx +++ b/panda/src/tform/mouseWatcher.cxx @@ -16,7 +16,7 @@ #include "dataGraphTraverser.h" #include "mouseWatcherParameter.h" #include "mouseAndKeyboard.h" -#include "mouseData.h" +#include "pointerData.h" #include "buttonEventList.h" #include "mouseButton.h" #include "throw_event.h" diff --git a/panda/src/tform/trackball.cxx b/panda/src/tform/trackball.cxx index b56e1d47fe..eee58bc13f 100644 --- a/panda/src/tform/trackball.cxx +++ b/panda/src/tform/trackball.cxx @@ -16,7 +16,7 @@ #include "buttonEventList.h" #include "dataNodeTransmit.h" #include "compose_matrix.h" -#include "mouseData.h" +#include "pointerData.h" #include "modifierButtons.h" #include "linmath_events.h" #include "mouseButton.h" diff --git a/panda/src/windisplay/winGraphicsWindow.cxx b/panda/src/windisplay/winGraphicsWindow.cxx index 5aceb2b54b..224ef26b4e 100644 --- a/panda/src/windisplay/winGraphicsWindow.cxx +++ b/panda/src/windisplay/winGraphicsWindow.cxx @@ -125,14 +125,14 @@ WinGraphicsWindow:: } /** - * Returns the MouseData associated with the nth input device's pointer. + * Returns the PointerData associated with the nth input device's pointer. */ -MouseData WinGraphicsWindow:: +PointerData WinGraphicsWindow:: get_pointer(int device) const { - MouseData result; + PointerData result; { LightMutexHolder holder(_input_lock); - nassertr(device >= 0 && device < (int)_input_devices.size(), MouseData()); + nassertr(device >= 0 && device < (int)_input_devices.size(), PointerData()); result = ((const GraphicsWindowInputDevice *)_input_devices[device].p())->get_pointer(); diff --git a/panda/src/windisplay/winGraphicsWindow.h b/panda/src/windisplay/winGraphicsWindow.h index 1dd857e6a6..9ce69d87a1 100644 --- a/panda/src/windisplay/winGraphicsWindow.h +++ b/panda/src/windisplay/winGraphicsWindow.h @@ -72,7 +72,7 @@ public: GraphicsOutput *host); virtual ~WinGraphicsWindow(); - virtual MouseData get_pointer(int device) const; + virtual PointerData get_pointer(int device) const; virtual bool move_pointer(int device, int x, int y); virtual void close_ime(); diff --git a/panda/src/x11display/x11GraphicsWindow.cxx b/panda/src/x11display/x11GraphicsWindow.cxx index 9d0b161101..3fc30c5692 100644 --- a/panda/src/x11display/x11GraphicsWindow.cxx +++ b/panda/src/x11display/x11GraphicsWindow.cxx @@ -136,16 +136,16 @@ x11GraphicsWindow:: } /** - * Returns the MouseData associated with the nth input device's pointer. This + * Returns the PointerData associated with the nth input device's pointer. This * is deprecated; use get_pointer_device().get_pointer() instead, or for raw * mice, use the InputDeviceManager interface. */ -MouseData x11GraphicsWindow:: +PointerData x11GraphicsWindow:: get_pointer(int device) const { - MouseData result; + PointerData result; { LightMutexHolder holder(_input_lock); - nassertr(device >= 0 && device < (int)_input_devices.size(), MouseData()); + nassertr(device >= 0 && device < (int)_input_devices.size(), PointerData()); result = ((const GraphicsWindowInputDevice *)_input_devices[device].p())->get_pointer(); diff --git a/panda/src/x11display/x11GraphicsWindow.h b/panda/src/x11display/x11GraphicsWindow.h index 1bb20e181e..e147f907a5 100644 --- a/panda/src/x11display/x11GraphicsWindow.h +++ b/panda/src/x11display/x11GraphicsWindow.h @@ -34,7 +34,7 @@ public: GraphicsOutput *host); virtual ~x11GraphicsWindow(); - virtual MouseData get_pointer(int device) const; + virtual PointerData get_pointer(int device) const; virtual bool move_pointer(int device, int x, int y); virtual void clear(Thread *current_thread); From ea845478052c4af6aa7e8a1ac28aac8bfea5e53f Mon Sep 17 00:00:00 2001 From: WMOkiishi Date: Wed, 2 Aug 2023 08:17:24 +0200 Subject: [PATCH 40/84] general: Mark many constructors as `explicit` Closes #1514 Fixes #1431 --- dtool/src/prc/configVariableBool.h | 12 ++++-- dtool/src/prc/configVariableDouble.h | 14 ++++--- dtool/src/prc/configVariableFilename.h | 6 ++- dtool/src/prc/configVariableInt.h | 14 ++++--- dtool/src/prc/configVariableInt64.h | 14 ++++--- dtool/src/prc/configVariableList.h | 6 +-- dtool/src/prc/configVariableSearchPath.h | 22 +++++------ dtool/src/prc/configVariableString.h | 8 ++-- panda/src/bullet/bulletContactCallbackData.h | 8 ++-- panda/src/bullet/bulletTickCallbackData.h | 2 +- panda/src/chan/animChannelScalarTable.h | 2 +- panda/src/device/inputDeviceNode.h | 2 +- panda/src/downloader/httpEntityTag.h | 2 +- panda/src/gobj/geomVertexArrayFormat.h | 40 ++++++++++---------- panda/src/gobj/geomVertexReader.h | 20 +++++----- panda/src/gobj/geomVertexRewriter.h | 12 +++--- panda/src/gobj/geomVertexWriter.h | 18 ++++----- panda/src/gobj/paramTexture.h | 4 +- panda/src/gobj/transformBlend.h | 20 +++++----- panda/src/linmath/configVariableColor.h | 16 ++++---- panda/src/linmath/lmatrix4_src.h | 3 +- panda/src/linmath/lorientation_src.h | 6 +-- panda/src/linmath/lpoint3_src.h | 2 +- panda/src/linmath/lpoint4_src.h | 2 +- panda/src/linmath/lquaternion_src.h | 2 +- panda/src/linmath/lrotation_src.h | 8 ++-- panda/src/linmath/lvector3_src.h | 2 +- panda/src/linmath/lvector4_src.h | 2 +- panda/src/mathutil/boundingHexahedron.h | 12 +++--- panda/src/movies/movieVideo.h | 2 +- panda/src/movies/userDataAudio.h | 2 +- panda/src/ode/odeAMotorJoint.h | 4 +- panda/src/ode/odeBallJoint.h | 4 +- panda/src/ode/odeBody.h | 2 +- panda/src/ode/odeBoxGeom.h | 4 +- panda/src/ode/odeCappedCylinderGeom.h | 4 +- panda/src/ode/odeContactJoint.h | 4 +- panda/src/ode/odeCylinderGeom.h | 4 +- panda/src/ode/odeFixedJoint.h | 4 +- panda/src/ode/odeHinge2Joint.h | 4 +- panda/src/ode/odeHingeJoint.h | 4 +- panda/src/ode/odeLMotorJoint.h | 4 +- panda/src/ode/odeNullJoint.h | 4 +- panda/src/ode/odePlane2dJoint.h | 4 +- panda/src/ode/odePlaneGeom.h | 4 +- panda/src/ode/odeQuadTreeSpace.h | 14 +++---- panda/src/ode/odeRayGeom.h | 2 +- panda/src/ode/odeSliderJoint.h | 4 +- panda/src/ode/odeSphereGeom.h | 2 +- panda/src/ode/odeUniversalJoint.h | 4 +- panda/src/pgraphnodes/spotlight.h | 2 +- panda/src/physics/angularEulerIntegrator.cxx | 2 +- panda/src/pnmimage/pnmImageHeader.h | 6 +-- panda/src/text/dynamicTextFont.h | 2 +- 54 files changed, 197 insertions(+), 180 deletions(-) diff --git a/dtool/src/prc/configVariableBool.h b/dtool/src/prc/configVariableBool.h index 94ba8853bd..c6ea2194e6 100644 --- a/dtool/src/prc/configVariableBool.h +++ b/dtool/src/prc/configVariableBool.h @@ -23,10 +23,14 @@ class EXPCL_DTOOL_PRC ConfigVariableBool : public ConfigVariable { PUBLISHED: INLINE explicit ConfigVariableBool(const std::string &name); - INLINE ConfigVariableBool(const std::string &name, bool default_value, - const std::string &description = std::string(), int flags = 0); - INLINE ConfigVariableBool(const std::string &name, const std::string &default_value, - const std::string &description = std::string(), int flags = 0); + INLINE explicit ConfigVariableBool(const std::string &name, + bool default_value, + const std::string &description = std::string(), + int flags = 0); + INLINE explicit ConfigVariableBool(const std::string &name, + const std::string &default_value, + const std::string &description = std::string(), + int flags = 0); INLINE void operator = (bool value); ALWAYS_INLINE operator bool () const; diff --git a/dtool/src/prc/configVariableDouble.h b/dtool/src/prc/configVariableDouble.h index 6244ae8f15..258560c714 100644 --- a/dtool/src/prc/configVariableDouble.h +++ b/dtool/src/prc/configVariableDouble.h @@ -24,12 +24,14 @@ class EXPCL_DTOOL_PRC ConfigVariableDouble : public ConfigVariable { PUBLISHED: INLINE explicit ConfigVariableDouble(const std::string &name); - INLINE ConfigVariableDouble(const std::string &name, double default_value, - const std::string &description = std::string(), - int flags = 0); - INLINE ConfigVariableDouble(const std::string &name, const std::string &default_value, - const std::string &description = std::string(), - int flags = 0); + INLINE explicit ConfigVariableDouble(const std::string &name, + double default_value, + const std::string &description = std::string(), + int flags = 0); + INLINE explicit ConfigVariableDouble(const std::string &name, + const std::string &default_value, + const std::string &description = std::string(), + int flags = 0); INLINE void operator = (double value); INLINE operator double () const; diff --git a/dtool/src/prc/configVariableFilename.h b/dtool/src/prc/configVariableFilename.h index 1427b589f3..18ea1ddb8a 100644 --- a/dtool/src/prc/configVariableFilename.h +++ b/dtool/src/prc/configVariableFilename.h @@ -27,8 +27,10 @@ class EXPCL_DTOOL_PRC ConfigVariableFilename : public ConfigVariable { PUBLISHED: INLINE explicit ConfigVariableFilename(const std::string &name); - INLINE ConfigVariableFilename(const std::string &name, const Filename &default_value, - const std::string &description = std::string(), int flags = 0); + INLINE explicit ConfigVariableFilename(const std::string &name, + const Filename &default_value, + const std::string &description = std::string(), + int flags = 0); INLINE void operator = (const Filename &value); INLINE operator const Filename &() const; diff --git a/dtool/src/prc/configVariableInt.h b/dtool/src/prc/configVariableInt.h index 2183032ce6..5dd569a468 100644 --- a/dtool/src/prc/configVariableInt.h +++ b/dtool/src/prc/configVariableInt.h @@ -24,12 +24,14 @@ class EXPCL_DTOOL_PRC ConfigVariableInt : public ConfigVariable { PUBLISHED: INLINE explicit ConfigVariableInt(const std::string &name); - INLINE ConfigVariableInt(const std::string &name, int default_value, - const std::string &description = std::string(), - int flags = 0); - INLINE ConfigVariableInt(const std::string &name, const std::string &default_value, - const std::string &description = std::string(), - int flags = 0); + INLINE explicit ConfigVariableInt(const std::string &name, + int default_value, + const std::string &description = std::string(), + int flags = 0); + INLINE explicit ConfigVariableInt(const std::string &name, + const std::string &default_value, + const std::string &description = std::string(), + int flags = 0); INLINE void operator = (int value); INLINE operator int () const; diff --git a/dtool/src/prc/configVariableInt64.h b/dtool/src/prc/configVariableInt64.h index a85876ba1d..16a685ee3d 100644 --- a/dtool/src/prc/configVariableInt64.h +++ b/dtool/src/prc/configVariableInt64.h @@ -25,12 +25,14 @@ class EXPCL_DTOOL_PRC ConfigVariableInt64 : public ConfigVariable { PUBLISHED: INLINE explicit ConfigVariableInt64(const std::string &name); - INLINE ConfigVariableInt64(const std::string &name, int64_t default_value, - const std::string &description = std::string(), - int flags = 0); - INLINE ConfigVariableInt64(const std::string &name, const std::string &default_value, - const std::string &description = std::string(), - int flags = 0); + INLINE explicit ConfigVariableInt64(const std::string &name, + int64_t default_value, + const std::string &description = std::string(), + int flags = 0); + INLINE explicit ConfigVariableInt64(const std::string &name, + const std::string &default_value, + const std::string &description = std::string(), + int flags = 0); INLINE void operator = (int64_t value); INLINE operator int64_t () const; diff --git a/dtool/src/prc/configVariableList.h b/dtool/src/prc/configVariableList.h index 188b33c5fb..c0128af374 100644 --- a/dtool/src/prc/configVariableList.h +++ b/dtool/src/prc/configVariableList.h @@ -30,9 +30,9 @@ */ class EXPCL_DTOOL_PRC ConfigVariableList : public ConfigVariableBase { PUBLISHED: - INLINE ConfigVariableList(const std::string &name, - const std::string &description = std::string(), - int flags = 0); + INLINE explicit ConfigVariableList(const std::string &name, + const std::string &description = std::string(), + int flags = 0); INLINE ~ConfigVariableList(); INLINE size_t get_num_values() const; diff --git a/dtool/src/prc/configVariableSearchPath.h b/dtool/src/prc/configVariableSearchPath.h index ca575c078a..dd55c6af26 100644 --- a/dtool/src/prc/configVariableSearchPath.h +++ b/dtool/src/prc/configVariableSearchPath.h @@ -35,17 +35,17 @@ */ class EXPCL_DTOOL_PRC ConfigVariableSearchPath : public ConfigVariableBase { PUBLISHED: - INLINE ConfigVariableSearchPath(const std::string &name, - const std::string &description = std::string(), - int flags = 0); - INLINE ConfigVariableSearchPath(const std::string &name, - const DSearchPath &default_value, - const std::string &description, - int flags = 0); - INLINE ConfigVariableSearchPath(const std::string &name, - const std::string &default_value, - const std::string &description, - int flags = 0); + INLINE explicit ConfigVariableSearchPath(const std::string &name, + const std::string &description = std::string(), + int flags = 0); + INLINE explicit ConfigVariableSearchPath(const std::string &name, + const DSearchPath &default_value, + const std::string &description, + int flags = 0); + INLINE explicit ConfigVariableSearchPath(const std::string &name, + const std::string &default_value, + const std::string &description, + int flags = 0); INLINE ~ConfigVariableSearchPath(); INLINE operator DSearchPath () const; diff --git a/dtool/src/prc/configVariableString.h b/dtool/src/prc/configVariableString.h index cb5249e6cf..1eb0c45fab 100644 --- a/dtool/src/prc/configVariableString.h +++ b/dtool/src/prc/configVariableString.h @@ -22,9 +22,11 @@ */ class EXPCL_DTOOL_PRC ConfigVariableString : public ConfigVariable { PUBLISHED: - INLINE ConfigVariableString(const std::string &name); - INLINE ConfigVariableString(const std::string &name, const std::string &default_value, - const std::string &description = std::string(), int flags = 0); + INLINE explicit ConfigVariableString(const std::string &name); + INLINE explicit ConfigVariableString(const std::string &name, + const std::string &default_value, + const std::string &description = std::string(), + int flags = 0); INLINE void operator = (const std::string &value); INLINE operator const std::string & () const; diff --git a/panda/src/bullet/bulletContactCallbackData.h b/panda/src/bullet/bulletContactCallbackData.h index 9ed17b8e1c..a1d14250c4 100644 --- a/panda/src/bullet/bulletContactCallbackData.h +++ b/panda/src/bullet/bulletContactCallbackData.h @@ -28,10 +28,10 @@ class EXPCL_PANDABULLET BulletContactCallbackData : public CallbackData { PUBLISHED: - INLINE BulletContactCallbackData(BulletManifoldPoint &mp, - PandaNode *node0, PandaNode *node1, - int id0, int id1, - int index0, int index1); + INLINE explicit BulletContactCallbackData(BulletManifoldPoint &mp, + PandaNode *node0, PandaNode *node1, + int id0, int id1, + int index0, int index1); INLINE BulletManifoldPoint &get_manifold() const; INLINE PandaNode *get_node0() const; diff --git a/panda/src/bullet/bulletTickCallbackData.h b/panda/src/bullet/bulletTickCallbackData.h index cb6014f6dd..6e9af63d9d 100644 --- a/panda/src/bullet/bulletTickCallbackData.h +++ b/panda/src/bullet/bulletTickCallbackData.h @@ -26,7 +26,7 @@ class EXPCL_PANDABULLET BulletTickCallbackData : public CallbackData { PUBLISHED: - INLINE BulletTickCallbackData(btScalar timestep); + INLINE explicit BulletTickCallbackData(btScalar timestep); INLINE PN_stdfloat get_timestep() const; diff --git a/panda/src/chan/animChannelScalarTable.h b/panda/src/chan/animChannelScalarTable.h index db92167f56..f9c626fc26 100644 --- a/panda/src/chan/animChannelScalarTable.h +++ b/panda/src/chan/animChannelScalarTable.h @@ -31,7 +31,7 @@ protected: AnimChannelScalarTable(AnimGroup *parent, const AnimChannelScalarTable ©); PUBLISHED: - AnimChannelScalarTable(AnimGroup *parent, const std::string &name); + explicit AnimChannelScalarTable(AnimGroup *parent, const std::string &name); public: virtual bool has_changed(int last_frame, double last_frac, diff --git a/panda/src/device/inputDeviceNode.h b/panda/src/device/inputDeviceNode.h index 7fad39e5ea..f2d5659781 100644 --- a/panda/src/device/inputDeviceNode.h +++ b/panda/src/device/inputDeviceNode.h @@ -28,7 +28,7 @@ */ class EXPCL_PANDA_DEVICE InputDeviceNode : public DataNode { PUBLISHED: - InputDeviceNode(InputDevice *device, const std::string &name); + explicit InputDeviceNode(InputDevice *device, const std::string &name); public: void set_device(InputDevice *device); diff --git a/panda/src/downloader/httpEntityTag.h b/panda/src/downloader/httpEntityTag.h index 7388b8621f..07b8a0196b 100644 --- a/panda/src/downloader/httpEntityTag.h +++ b/panda/src/downloader/httpEntityTag.h @@ -25,7 +25,7 @@ class EXPCL_PANDA_DOWNLOADER HTTPEntityTag { PUBLISHED: INLINE HTTPEntityTag(); HTTPEntityTag(const std::string &text); - INLINE HTTPEntityTag(bool weak, const std::string &tag); + INLINE explicit HTTPEntityTag(bool weak, const std::string &tag); INLINE HTTPEntityTag(const HTTPEntityTag ©); INLINE void operator = (const HTTPEntityTag ©); diff --git a/panda/src/gobj/geomVertexArrayFormat.h b/panda/src/gobj/geomVertexArrayFormat.h index 4c92abfe44..26eff8f21f 100644 --- a/panda/src/gobj/geomVertexArrayFormat.h +++ b/panda/src/gobj/geomVertexArrayFormat.h @@ -48,26 +48,26 @@ class EXPCL_PANDA_GOBJ GeomVertexArrayFormat final : public TypedWritableReferen PUBLISHED: GeomVertexArrayFormat(); GeomVertexArrayFormat(const GeomVertexArrayFormat ©); - GeomVertexArrayFormat(CPT_InternalName name0, int num_components0, - NumericType numeric_type0, Contents contents0); - GeomVertexArrayFormat(CPT_InternalName name0, int num_components0, - NumericType numeric_type0, Contents contents0, - CPT_InternalName name1, int num_components1, - NumericType numeric_type1, Contents contents1); - GeomVertexArrayFormat(CPT_InternalName name0, int num_components0, - NumericType numeric_type0, Contents contents0, - CPT_InternalName name1, int num_components1, - NumericType numeric_type1, Contents contents1, - CPT_InternalName name2, int num_components2, - NumericType numeric_type2, Contents contents2); - GeomVertexArrayFormat(CPT_InternalName name0, int num_components0, - NumericType numeric_type0, Contents contents0, - CPT_InternalName name1, int num_components1, - NumericType numeric_type1, Contents contents1, - CPT_InternalName name2, int num_components2, - NumericType numeric_type2, Contents contents2, - CPT_InternalName name3, int num_components3, - NumericType numeric_type3, Contents contents3); + explicit GeomVertexArrayFormat(CPT_InternalName name0, int num_components0, + NumericType numeric_type0, Contents contents0); + explicit GeomVertexArrayFormat(CPT_InternalName name0, int num_components0, + NumericType numeric_type0, Contents contents0, + CPT_InternalName name1, int num_components1, + NumericType numeric_type1, Contents contents1); + explicit GeomVertexArrayFormat(CPT_InternalName name0, int num_components0, + NumericType numeric_type0, Contents contents0, + CPT_InternalName name1, int num_components1, + NumericType numeric_type1, Contents contents1, + CPT_InternalName name2, int num_components2, + NumericType numeric_type2, Contents contents2); + explicit GeomVertexArrayFormat(CPT_InternalName name0, int num_components0, + NumericType numeric_type0, Contents contents0, + CPT_InternalName name1, int num_components1, + NumericType numeric_type1, Contents contents1, + CPT_InternalName name2, int num_components2, + NumericType numeric_type2, Contents contents2, + CPT_InternalName name3, int num_components3, + NumericType numeric_type3, Contents contents3); void operator = (const GeomVertexArrayFormat ©); ~GeomVertexArrayFormat(); diff --git a/panda/src/gobj/geomVertexReader.h b/panda/src/gobj/geomVertexReader.h index a56d00f3ba..699d62b1a4 100644 --- a/panda/src/gobj/geomVertexReader.h +++ b/panda/src/gobj/geomVertexReader.h @@ -46,22 +46,22 @@ */ class EXPCL_PANDA_GOBJ GeomVertexReader : public GeomEnums { PUBLISHED: - INLINE GeomVertexReader(Thread *current_thread = Thread::get_current_thread()); + INLINE explicit GeomVertexReader(Thread *current_thread = Thread::get_current_thread()); INLINE GeomVertexReader(CPT(GeomVertexData) vertex_data, Thread *current_thread = Thread::get_current_thread()); - INLINE GeomVertexReader(CPT(GeomVertexData) vertex_data, - CPT_InternalName name, - Thread *current_thread = Thread::get_current_thread()); + INLINE explicit GeomVertexReader(CPT(GeomVertexData) vertex_data, + CPT_InternalName name, + Thread *current_thread = Thread::get_current_thread()); INLINE GeomVertexReader(CPT(GeomVertexArrayData) array_data, Thread *current_thread = Thread::get_current_thread()); - INLINE GeomVertexReader(CPT(GeomVertexArrayData) array_data, - int column, - Thread *current_thread = Thread::get_current_thread()); + INLINE explicit GeomVertexReader(CPT(GeomVertexArrayData) array_data, + int column, + Thread *current_thread = Thread::get_current_thread()); public: - INLINE GeomVertexReader(const GeomVertexDataPipelineReader *data_reader, - const InternalName *name, - bool force = true); + INLINE explicit GeomVertexReader(const GeomVertexDataPipelineReader *data_reader, + const InternalName *name, + bool force = true); PUBLISHED: INLINE GeomVertexReader(const GeomVertexReader ©); diff --git a/panda/src/gobj/geomVertexRewriter.h b/panda/src/gobj/geomVertexRewriter.h index 2ed1699522..2bddbb91d7 100644 --- a/panda/src/gobj/geomVertexRewriter.h +++ b/panda/src/gobj/geomVertexRewriter.h @@ -32,14 +32,14 @@ */ class EXPCL_PANDA_GOBJ GeomVertexRewriter : public GeomVertexWriter, public GeomVertexReader { PUBLISHED: - INLINE GeomVertexRewriter(Thread *current_thread = Thread::get_current_thread()); + INLINE explicit GeomVertexRewriter(Thread *current_thread = Thread::get_current_thread()); INLINE GeomVertexRewriter(GeomVertexData *vertex_data, Thread *current_thread = Thread::get_current_thread()); - INLINE GeomVertexRewriter(GeomVertexData *vertex_data, - CPT_InternalName name, - Thread *current_thread = Thread::get_current_thread()); + INLINE explicit GeomVertexRewriter(GeomVertexData *vertex_data, + CPT_InternalName name, + Thread *current_thread = Thread::get_current_thread()); INLINE GeomVertexRewriter(GeomVertexArrayData *array_data, Thread *current_thread = Thread::get_current_thread()); - INLINE GeomVertexRewriter(GeomVertexArrayData *array_data, - int column, Thread *current_thread = Thread::get_current_thread()); + INLINE explicit GeomVertexRewriter(GeomVertexArrayData *array_data, + int column, Thread *current_thread = Thread::get_current_thread()); INLINE GeomVertexRewriter(const GeomVertexRewriter ©); INLINE void operator = (const GeomVertexRewriter ©); INLINE ~GeomVertexRewriter(); diff --git a/panda/src/gobj/geomVertexWriter.h b/panda/src/gobj/geomVertexWriter.h index b0fab4609e..8347f1c325 100644 --- a/panda/src/gobj/geomVertexWriter.h +++ b/panda/src/gobj/geomVertexWriter.h @@ -54,21 +54,21 @@ */ class EXPCL_PANDA_GOBJ GeomVertexWriter : public GeomEnums { PUBLISHED: - INLINE GeomVertexWriter(Thread *current_thread = Thread::get_current_thread()); + INLINE explicit GeomVertexWriter(Thread *current_thread = Thread::get_current_thread()); INLINE GeomVertexWriter(PT(GeomVertexData) vertex_data, Thread *current_thread = Thread::get_current_thread()); - INLINE GeomVertexWriter(PT(GeomVertexData) vertex_data, - CPT_InternalName name, - Thread *current_thread = Thread::get_current_thread()); + INLINE explicit GeomVertexWriter(PT(GeomVertexData) vertex_data, + CPT_InternalName name, + Thread *current_thread = Thread::get_current_thread()); INLINE GeomVertexWriter(PT(GeomVertexArrayData) array_data, Thread *current_thread = Thread::get_current_thread()); - INLINE GeomVertexWriter(PT(GeomVertexArrayData) array_data, - int column, - Thread *current_thread = Thread::get_current_thread()); + INLINE explicit GeomVertexWriter(PT(GeomVertexArrayData) array_data, + int column, + Thread *current_thread = Thread::get_current_thread()); public: - INLINE GeomVertexWriter(GeomVertexDataPipelineWriter *data_writer, - const InternalName *name); + INLINE explicit GeomVertexWriter(GeomVertexDataPipelineWriter *data_writer, + const InternalName *name); PUBLISHED: INLINE GeomVertexWriter(const GeomVertexWriter ©); diff --git a/panda/src/gobj/paramTexture.h b/panda/src/gobj/paramTexture.h index fb9b2a5a81..cec521d2a7 100644 --- a/panda/src/gobj/paramTexture.h +++ b/panda/src/gobj/paramTexture.h @@ -28,7 +28,7 @@ protected: INLINE ParamTextureSampler() {}; PUBLISHED: - INLINE ParamTextureSampler(Texture *tex, const SamplerState &sampler); + INLINE explicit ParamTextureSampler(Texture *tex, const SamplerState &sampler); INLINE virtual TypeHandle get_value_type() const; INLINE Texture *get_texture() const; @@ -89,7 +89,7 @@ protected: }; PUBLISHED: - INLINE ParamTextureImage(Texture *tex, bool read, bool write, int z=-1, int n=0); + INLINE explicit ParamTextureImage(Texture *tex, bool read, bool write, int z=-1, int n=0); INLINE virtual TypeHandle get_value_type() const; diff --git a/panda/src/gobj/transformBlend.h b/panda/src/gobj/transformBlend.h index 3adcb73128..e52e896c92 100644 --- a/panda/src/gobj/transformBlend.h +++ b/panda/src/gobj/transformBlend.h @@ -32,16 +32,16 @@ class EXPCL_PANDA_GOBJ TransformBlend { PUBLISHED: INLINE TransformBlend(); - INLINE TransformBlend(const VertexTransform *transform0, PN_stdfloat weight0); - INLINE TransformBlend(const VertexTransform *transform0, PN_stdfloat weight0, - const VertexTransform *transform1, PN_stdfloat weight1); - INLINE TransformBlend(const VertexTransform *transform0, PN_stdfloat weight0, - const VertexTransform *transform1, PN_stdfloat weight1, - const VertexTransform *transform2, PN_stdfloat weight2); - INLINE TransformBlend(const VertexTransform *transform0, PN_stdfloat weight0, - const VertexTransform *transform1, PN_stdfloat weight1, - const VertexTransform *transform2, PN_stdfloat weight2, - const VertexTransform *transform3, PN_stdfloat weight3); + INLINE explicit TransformBlend(const VertexTransform *transform0, PN_stdfloat weight0); + INLINE explicit TransformBlend(const VertexTransform *transform0, PN_stdfloat weight0, + const VertexTransform *transform1, PN_stdfloat weight1); + INLINE explicit TransformBlend(const VertexTransform *transform0, PN_stdfloat weight0, + const VertexTransform *transform1, PN_stdfloat weight1, + const VertexTransform *transform2, PN_stdfloat weight2); + INLINE explicit TransformBlend(const VertexTransform *transform0, PN_stdfloat weight0, + const VertexTransform *transform1, PN_stdfloat weight1, + const VertexTransform *transform2, PN_stdfloat weight2, + const VertexTransform *transform3, PN_stdfloat weight3); INLINE TransformBlend(const TransformBlend ©); INLINE void operator = (const TransformBlend ©); INLINE ~TransformBlend(); diff --git a/panda/src/linmath/configVariableColor.h b/panda/src/linmath/configVariableColor.h index fba5330e26..a37f9b3955 100644 --- a/panda/src/linmath/configVariableColor.h +++ b/panda/src/linmath/configVariableColor.h @@ -34,13 +34,15 @@ */ class EXPCL_PANDA_LINMATH ConfigVariableColor : public ConfigVariable { PUBLISHED: - INLINE ConfigVariableColor(const std::string &name); - INLINE ConfigVariableColor(const std::string &name, const LColor &default_value, - const std::string &description = std::string(), - int flags = 0); - INLINE ConfigVariableColor(const std::string &name, const std::string &default_value, - const std::string &description = std::string(), - int flags = 0); + INLINE explicit ConfigVariableColor(const std::string &name); + INLINE explicit ConfigVariableColor(const std::string &name, + const LColor &default_value, + const std::string &description = std::string(), + int flags = 0); + INLINE explicit ConfigVariableColor(const std::string &name, + const std::string &default_value, + const std::string &description = std::string(), + int flags = 0); INLINE void operator = (const LColor &value); INLINE operator const LColor & () const; diff --git a/panda/src/linmath/lmatrix4_src.h b/panda/src/linmath/lmatrix4_src.h index 6dd07a9fbe..cb2fe2ec43 100644 --- a/panda/src/linmath/lmatrix4_src.h +++ b/panda/src/linmath/lmatrix4_src.h @@ -72,7 +72,8 @@ PUBLISHED: // Construct a 4x4 matrix given a 3x3 rotation matrix and an optional // translation component. INLINE_LINMATH FLOATNAME(LMatrix4)(const FLOATNAME(LMatrix3) &upper3); - INLINE_LINMATH FLOATNAME(LMatrix4)(const FLOATNAME(LMatrix3) &upper3,const FLOATNAME(LVecBase3) &trans); + INLINE_LINMATH explicit FLOATNAME(LMatrix4)(const FLOATNAME(LMatrix3) &upper3, + const FLOATNAME(LVecBase3) &trans); INLINE_LINMATH void fill(FLOATTYPE fill_value); INLINE_LINMATH void set(FLOATTYPE e00, FLOATTYPE e01, FLOATTYPE e02, FLOATTYPE e03, diff --git a/panda/src/linmath/lorientation_src.h b/panda/src/linmath/lorientation_src.h index 88921b8552..f40bdca93d 100644 --- a/panda/src/linmath/lorientation_src.h +++ b/panda/src/linmath/lorientation_src.h @@ -21,9 +21,9 @@ PUBLISHED: INLINE_LINMATH FLOATNAME(LOrientation)(); INLINE_LINMATH FLOATNAME(LOrientation)(const FLOATNAME(LQuaternion) &c); INLINE_LINMATH FLOATNAME(LOrientation)(FLOATTYPE r, FLOATTYPE i, FLOATTYPE j, FLOATTYPE k); - INLINE_LINMATH FLOATNAME(LOrientation)(const FLOATNAME(LVector3) &point_at, FLOATTYPE twist); - INLINE_LINMATH FLOATNAME(LOrientation)(const FLOATNAME(LMatrix3) &m); - INLINE_LINMATH FLOATNAME(LOrientation)(const FLOATNAME(LMatrix4) &m); + INLINE_LINMATH explicit FLOATNAME(LOrientation)(const FLOATNAME(LVector3) &point_at, FLOATTYPE twist); + INLINE_LINMATH explicit FLOATNAME(LOrientation)(const FLOATNAME(LMatrix3) &m); + INLINE_LINMATH explicit FLOATNAME(LOrientation)(const FLOATNAME(LMatrix4) &m); INLINE_LINMATH FLOATNAME(LOrientation) operator * (const FLOATNAME(LRotation) &other) const; diff --git a/panda/src/linmath/lpoint3_src.h b/panda/src/linmath/lpoint3_src.h index b321a3ba35..81ba79a644 100644 --- a/panda/src/linmath/lpoint3_src.h +++ b/panda/src/linmath/lpoint3_src.h @@ -24,7 +24,7 @@ PUBLISHED: INLINE_LINMATH FLOATNAME(LPoint3)(const FLOATNAME(LVecBase3) ©); INLINE_LINMATH FLOATNAME(LPoint3)(FLOATTYPE fill_value); INLINE_LINMATH FLOATNAME(LPoint3)(FLOATTYPE x, FLOATTYPE y, FLOATTYPE z); - INLINE_LINMATH FLOATNAME(LPoint3)(const FLOATNAME(LVecBase2) ©, FLOATTYPE z); + INLINE_LINMATH explicit FLOATNAME(LPoint3)(const FLOATNAME(LVecBase2) ©, FLOATTYPE z); PY_EXTENSION(INLINE_LINMATH PyObject *__getattr__(PyObject *self, const std::string &attr_name) const); PY_EXTENSION(INLINE_LINMATH int __setattr__(PyObject *self, const std::string &attr_name, PyObject *assign)); diff --git a/panda/src/linmath/lpoint4_src.h b/panda/src/linmath/lpoint4_src.h index 59184f7447..2593a9245f 100644 --- a/panda/src/linmath/lpoint4_src.h +++ b/panda/src/linmath/lpoint4_src.h @@ -20,7 +20,7 @@ PUBLISHED: INLINE_LINMATH FLOATNAME(LPoint4)(const FLOATNAME(LVecBase4) ©); INLINE_LINMATH FLOATNAME(LPoint4)(FLOATTYPE fill_value); INLINE_LINMATH FLOATNAME(LPoint4)(FLOATTYPE x, FLOATTYPE y, FLOATTYPE z, FLOATTYPE w); - INLINE_LINMATH FLOATNAME(LPoint4)(const FLOATNAME(LVecBase3) ©, FLOATTYPE w); + INLINE_LINMATH explicit FLOATNAME(LPoint4)(const FLOATNAME(LVecBase3) ©, FLOATTYPE w); PY_EXTENSION(INLINE_LINMATH PyObject *__getattr__(PyObject *self, const std::string &attr_name) const); PY_EXTENSION(INLINE_LINMATH int __setattr__(PyObject *self, const std::string &attr_name, PyObject *assign)); diff --git a/panda/src/linmath/lquaternion_src.h b/panda/src/linmath/lquaternion_src.h index 52bbc6fff7..43cd605101 100644 --- a/panda/src/linmath/lquaternion_src.h +++ b/panda/src/linmath/lquaternion_src.h @@ -18,7 +18,7 @@ class EXPCL_PANDA_LINMATH FLOATNAME(LQuaternion) : public FLOATNAME(LVecBase4) { PUBLISHED: INLINE_LINMATH FLOATNAME(LQuaternion)(); INLINE_LINMATH FLOATNAME(LQuaternion)(const FLOATNAME(LVecBase4) ©); - INLINE_LINMATH FLOATNAME(LQuaternion)(FLOATTYPE r, const FLOATNAME(LVecBase3) ©); + INLINE_LINMATH explicit FLOATNAME(LQuaternion)(FLOATTYPE r, const FLOATNAME(LVecBase3) ©); INLINE_LINMATH FLOATNAME(LQuaternion)(FLOATTYPE r, FLOATTYPE i, FLOATTYPE j, FLOATTYPE k); static FLOATNAME(LQuaternion) pure_imaginary(const FLOATNAME(LVector3) &v); diff --git a/panda/src/linmath/lrotation_src.h b/panda/src/linmath/lrotation_src.h index 4c844b98a1..7cf7f349d8 100644 --- a/panda/src/linmath/lrotation_src.h +++ b/panda/src/linmath/lrotation_src.h @@ -20,10 +20,10 @@ PUBLISHED: INLINE_LINMATH FLOATNAME(LRotation)(const FLOATNAME(LQuaternion) &c); INLINE_LINMATH FLOATNAME(LRotation)(const FLOATNAME(LVecBase4) ©); INLINE_LINMATH FLOATNAME(LRotation)(FLOATTYPE r, FLOATTYPE i, FLOATTYPE j, FLOATTYPE k); - INLINE_LINMATH FLOATNAME(LRotation)(const FLOATNAME(LVector3) &axis, FLOATTYPE angle); - INLINE_LINMATH FLOATNAME(LRotation)(const FLOATNAME(LMatrix3) &m); - INLINE_LINMATH FLOATNAME(LRotation)(const FLOATNAME(LMatrix4) &m); - INLINE_LINMATH FLOATNAME(LRotation)(FLOATTYPE h, FLOATTYPE p, FLOATTYPE r); + INLINE_LINMATH explicit FLOATNAME(LRotation)(const FLOATNAME(LVector3) &axis, FLOATTYPE angle); + INLINE_LINMATH explicit FLOATNAME(LRotation)(const FLOATNAME(LMatrix3) &m); + INLINE_LINMATH explicit FLOATNAME(LRotation)(const FLOATNAME(LMatrix4) &m); + INLINE_LINMATH explicit FLOATNAME(LRotation)(FLOATTYPE h, FLOATTYPE p, FLOATTYPE r); INLINE_LINMATH FLOATNAME(LRotation) operator * (FLOATTYPE scalar) const; INLINE_LINMATH FLOATNAME(LRotation) operator / (FLOATTYPE scalar) const; diff --git a/panda/src/linmath/lvector3_src.h b/panda/src/linmath/lvector3_src.h index cb8b54c315..2217384573 100644 --- a/panda/src/linmath/lvector3_src.h +++ b/panda/src/linmath/lvector3_src.h @@ -24,7 +24,7 @@ PUBLISHED: INLINE_LINMATH FLOATNAME(LVector3)(const FLOATNAME(LVecBase3) ©); INLINE_LINMATH FLOATNAME(LVector3)(FLOATTYPE fill_value); INLINE_LINMATH FLOATNAME(LVector3)(FLOATTYPE x, FLOATTYPE y, FLOATTYPE z); - INLINE_LINMATH FLOATNAME(LVector3)(const FLOATNAME(LVecBase2) ©, FLOATTYPE z); + INLINE_LINMATH explicit FLOATNAME(LVector3)(const FLOATNAME(LVecBase2) ©, FLOATTYPE z); PY_EXTENSION(INLINE_LINMATH PyObject *__getattr__(PyObject *self, const std::string &attr_name) const); PY_EXTENSION(INLINE_LINMATH int __setattr__(PyObject *self, const std::string &attr_name, PyObject *assign)); diff --git a/panda/src/linmath/lvector4_src.h b/panda/src/linmath/lvector4_src.h index a022d438a0..fe0733ded3 100644 --- a/panda/src/linmath/lvector4_src.h +++ b/panda/src/linmath/lvector4_src.h @@ -20,7 +20,7 @@ PUBLISHED: INLINE_LINMATH FLOATNAME(LVector4)(const FLOATNAME(LVecBase4) ©); INLINE_LINMATH FLOATNAME(LVector4)(FLOATTYPE fill_value); INLINE_LINMATH FLOATNAME(LVector4)(FLOATTYPE x, FLOATTYPE y, FLOATTYPE z, FLOATTYPE w); - INLINE_LINMATH FLOATNAME(LVector4)(const FLOATNAME(LVecBase3) ©, FLOATTYPE w); + INLINE_LINMATH explicit FLOATNAME(LVector4)(const FLOATNAME(LVecBase3) ©, FLOATTYPE w); PY_EXTENSION(INLINE_LINMATH PyObject *__getattr__(PyObject *self, const std::string &attr_name) const); PY_EXTENSION(INLINE_LINMATH int __setattr__(PyObject *self, const std::string &attr_name, PyObject *assign)); diff --git a/panda/src/mathutil/boundingHexahedron.h b/panda/src/mathutil/boundingHexahedron.h index 8b899001d2..349e57e6db 100644 --- a/panda/src/mathutil/boundingHexahedron.h +++ b/panda/src/mathutil/boundingHexahedron.h @@ -34,12 +34,12 @@ public: INLINE_MATHUTIL BoundingHexahedron(); PUBLISHED: - BoundingHexahedron(const LFrustum &frustum, bool is_ortho, - CoordinateSystem cs = CS_default); - BoundingHexahedron(const LPoint3 &fll, const LPoint3 &flr, - const LPoint3 &fur, const LPoint3 &ful, - const LPoint3 &nll, const LPoint3 &nlr, - const LPoint3 &nur, const LPoint3 &nul); + explicit BoundingHexahedron(const LFrustum &frustum, bool is_ortho, + CoordinateSystem cs = CS_default); + explicit BoundingHexahedron(const LPoint3 &fll, const LPoint3 &flr, + const LPoint3 &fur, const LPoint3 &ful, + const LPoint3 &nll, const LPoint3 &nlr, + const LPoint3 &nur, const LPoint3 &nul); public: ALLOC_DELETED_CHAIN(BoundingHexahedron); diff --git a/panda/src/movies/movieVideo.h b/panda/src/movies/movieVideo.h index 1e7da6288e..5b2ae0b464 100644 --- a/panda/src/movies/movieVideo.h +++ b/panda/src/movies/movieVideo.h @@ -37,7 +37,7 @@ class BamReader; */ class EXPCL_PANDA_MOVIES MovieVideo : public TypedWritableReferenceCount, public Namable { PUBLISHED: - MovieVideo(const std::string &name = "Blank Video"); + explicit MovieVideo(const std::string &name = "Blank Video"); virtual ~MovieVideo(); virtual PT(MovieVideoCursor) open(); static PT(MovieVideo) get(const Filename &name); diff --git a/panda/src/movies/userDataAudio.h b/panda/src/movies/userDataAudio.h index b0b6e3bfbc..e0cddde842 100644 --- a/panda/src/movies/userDataAudio.h +++ b/panda/src/movies/userDataAudio.h @@ -31,7 +31,7 @@ class UserDataAudioCursor; class EXPCL_PANDA_MOVIES UserDataAudio : public MovieAudio { PUBLISHED: - UserDataAudio(int rate, int channels, bool remove_after_read=true); + explicit UserDataAudio(int rate, int channels, bool remove_after_read=true); virtual ~UserDataAudio(); virtual PT(MovieAudioCursor) open(); diff --git a/panda/src/ode/odeAMotorJoint.h b/panda/src/ode/odeAMotorJoint.h index c12b48524e..d6726cb5db 100644 --- a/panda/src/ode/odeAMotorJoint.h +++ b/panda/src/ode/odeAMotorJoint.h @@ -33,8 +33,8 @@ public: OdeAMotorJoint(dJointID id); PUBLISHED: - OdeAMotorJoint(OdeWorld &world); - OdeAMotorJoint(OdeWorld &world, OdeJointGroup &joint_group); + explicit OdeAMotorJoint(OdeWorld &world); + explicit OdeAMotorJoint(OdeWorld &world, OdeJointGroup &joint_group); virtual ~OdeAMotorJoint(); INLINE void set_num_axes(int num); diff --git a/panda/src/ode/odeBallJoint.h b/panda/src/ode/odeBallJoint.h index 480a815531..979be8f3b5 100644 --- a/panda/src/ode/odeBallJoint.h +++ b/panda/src/ode/odeBallJoint.h @@ -33,8 +33,8 @@ public: OdeBallJoint(dJointID id); PUBLISHED: - OdeBallJoint(OdeWorld &world); - OdeBallJoint(OdeWorld &world, OdeJointGroup &joint_group); + explicit OdeBallJoint(OdeWorld &world); + explicit OdeBallJoint(OdeWorld &world, OdeJointGroup &joint_group); virtual ~OdeBallJoint(); INLINE void set_anchor(dReal x, dReal y, dReal z); diff --git a/panda/src/ode/odeBody.h b/panda/src/ode/odeBody.h index 3861fdb393..a03ef3f039 100644 --- a/panda/src/ode/odeBody.h +++ b/panda/src/ode/odeBody.h @@ -38,7 +38,7 @@ public: OdeBody(dBodyID id); PUBLISHED: - OdeBody(OdeWorld &world); + explicit OdeBody(OdeWorld &world); virtual ~OdeBody(); void destroy(); INLINE bool is_empty() const; diff --git a/panda/src/ode/odeBoxGeom.h b/panda/src/ode/odeBoxGeom.h index eadf84e534..53f62b5496 100644 --- a/panda/src/ode/odeBoxGeom.h +++ b/panda/src/ode/odeBoxGeom.h @@ -32,8 +32,8 @@ public: PUBLISHED: OdeBoxGeom(dReal lx, dReal ly, dReal lz); - OdeBoxGeom(OdeSpace &space, dReal lx, dReal ly, dReal lz); - OdeBoxGeom(OdeSpace &space, const LVecBase3f &size); + explicit OdeBoxGeom(OdeSpace &space, dReal lx, dReal ly, dReal lz); + explicit OdeBoxGeom(OdeSpace &space, const LVecBase3f &size); virtual ~OdeBoxGeom(); INLINE void set_lengths(dReal lx, dReal ly, dReal lz); diff --git a/panda/src/ode/odeCappedCylinderGeom.h b/panda/src/ode/odeCappedCylinderGeom.h index f48385ef7e..58c4098131 100644 --- a/panda/src/ode/odeCappedCylinderGeom.h +++ b/panda/src/ode/odeCappedCylinderGeom.h @@ -31,8 +31,8 @@ public: OdeCappedCylinderGeom(dGeomID id); PUBLISHED: - OdeCappedCylinderGeom(dReal radius, dReal length); - OdeCappedCylinderGeom(OdeSpace &space, dReal radius, dReal length); + explicit OdeCappedCylinderGeom(dReal radius, dReal length); + explicit OdeCappedCylinderGeom(OdeSpace &space, dReal radius, dReal length); virtual ~OdeCappedCylinderGeom(); INLINE void set_params(dReal radius, dReal length); diff --git a/panda/src/ode/odeContactJoint.h b/panda/src/ode/odeContactJoint.h index e31abb12ac..1f62f59a14 100644 --- a/panda/src/ode/odeContactJoint.h +++ b/panda/src/ode/odeContactJoint.h @@ -34,8 +34,8 @@ public: OdeContactJoint(dJointID id); PUBLISHED: - OdeContactJoint(OdeWorld &world, const OdeContact &contact); - OdeContactJoint(OdeWorld &world, OdeJointGroup &joint_group, const OdeContact &contact); + explicit OdeContactJoint(OdeWorld &world, const OdeContact &contact); + explicit OdeContactJoint(OdeWorld &world, OdeJointGroup &joint_group, const OdeContact &contact); virtual ~OdeContactJoint(); public: diff --git a/panda/src/ode/odeCylinderGeom.h b/panda/src/ode/odeCylinderGeom.h index 3c23a02336..bd5f9deae4 100644 --- a/panda/src/ode/odeCylinderGeom.h +++ b/panda/src/ode/odeCylinderGeom.h @@ -31,8 +31,8 @@ public: OdeCylinderGeom(dGeomID id); PUBLISHED: - OdeCylinderGeom(dReal radius, dReal length); - OdeCylinderGeom(OdeSpace &space, dReal radius, dReal length); + explicit OdeCylinderGeom(dReal radius, dReal length); + explicit OdeCylinderGeom(OdeSpace &space, dReal radius, dReal length); virtual ~OdeCylinderGeom(); INLINE void set_params(dReal radius, dReal length); diff --git a/panda/src/ode/odeFixedJoint.h b/panda/src/ode/odeFixedJoint.h index de4f8a90da..c48b57fdaf 100644 --- a/panda/src/ode/odeFixedJoint.h +++ b/panda/src/ode/odeFixedJoint.h @@ -33,8 +33,8 @@ public: OdeFixedJoint(dJointID id); PUBLISHED: - OdeFixedJoint(OdeWorld &world); - OdeFixedJoint(OdeWorld &world, OdeJointGroup &joint_group); + explicit OdeFixedJoint(OdeWorld &world); + explicit OdeFixedJoint(OdeWorld &world, OdeJointGroup &joint_group); virtual ~OdeFixedJoint(); INLINE void set(); diff --git a/panda/src/ode/odeHinge2Joint.h b/panda/src/ode/odeHinge2Joint.h index 96606f9292..74388a93fb 100644 --- a/panda/src/ode/odeHinge2Joint.h +++ b/panda/src/ode/odeHinge2Joint.h @@ -32,8 +32,8 @@ public: OdeHinge2Joint(dJointID id); PUBLISHED: - OdeHinge2Joint(OdeWorld &world, OdeJointGroup &joint_group); - OdeHinge2Joint(OdeWorld &world); + explicit OdeHinge2Joint(OdeWorld &world, OdeJointGroup &joint_group); + explicit OdeHinge2Joint(OdeWorld &world); virtual ~OdeHinge2Joint(); INLINE void set_anchor(dReal x, dReal y, dReal z); diff --git a/panda/src/ode/odeHingeJoint.h b/panda/src/ode/odeHingeJoint.h index 3c3c02b039..1799c34f80 100644 --- a/panda/src/ode/odeHingeJoint.h +++ b/panda/src/ode/odeHingeJoint.h @@ -32,8 +32,8 @@ public: OdeHingeJoint(dJointID id); PUBLISHED: - OdeHingeJoint(OdeWorld &world); - OdeHingeJoint(OdeWorld &world, OdeJointGroup &joint_group); + explicit OdeHingeJoint(OdeWorld &world); + explicit OdeHingeJoint(OdeWorld &world, OdeJointGroup &joint_group); virtual ~OdeHingeJoint(); INLINE void set_anchor(dReal x, dReal y, dReal z); diff --git a/panda/src/ode/odeLMotorJoint.h b/panda/src/ode/odeLMotorJoint.h index d79d20d34d..ea1065dba2 100644 --- a/panda/src/ode/odeLMotorJoint.h +++ b/panda/src/ode/odeLMotorJoint.h @@ -32,8 +32,8 @@ public: OdeLMotorJoint(dJointID id); PUBLISHED: - OdeLMotorJoint(OdeWorld &world); - OdeLMotorJoint(OdeWorld &world, OdeJointGroup &joint_group); + explicit OdeLMotorJoint(OdeWorld &world); + explicit OdeLMotorJoint(OdeWorld &world, OdeJointGroup &joint_group); virtual ~OdeLMotorJoint(); INLINE void set_num_axes(int num); diff --git a/panda/src/ode/odeNullJoint.h b/panda/src/ode/odeNullJoint.h index 1dbbf030c3..5ea67dcf80 100644 --- a/panda/src/ode/odeNullJoint.h +++ b/panda/src/ode/odeNullJoint.h @@ -33,8 +33,8 @@ public: OdeNullJoint(dJointID id); PUBLISHED: - OdeNullJoint(OdeWorld &world); - OdeNullJoint(OdeWorld &world, OdeJointGroup &joint_group); + explicit OdeNullJoint(OdeWorld &world); + explicit OdeNullJoint(OdeWorld &world, OdeJointGroup &joint_group); virtual ~OdeNullJoint(); public: diff --git a/panda/src/ode/odePlane2dJoint.h b/panda/src/ode/odePlane2dJoint.h index a1b36588b3..0ce51ee9a4 100644 --- a/panda/src/ode/odePlane2dJoint.h +++ b/panda/src/ode/odePlane2dJoint.h @@ -32,8 +32,8 @@ public: OdePlane2dJoint(dJointID id); PUBLISHED: - OdePlane2dJoint(OdeWorld &world); - OdePlane2dJoint(OdeWorld &world, OdeJointGroup &joint_group); + explicit OdePlane2dJoint(OdeWorld &world); + explicit OdePlane2dJoint(OdeWorld &world, OdeJointGroup &joint_group); virtual ~OdePlane2dJoint(); INLINE void set_x_param(int parameter, dReal value); diff --git a/panda/src/ode/odePlaneGeom.h b/panda/src/ode/odePlaneGeom.h index 9a3da02258..110e75d25b 100644 --- a/panda/src/ode/odePlaneGeom.h +++ b/panda/src/ode/odePlaneGeom.h @@ -32,8 +32,8 @@ public: PUBLISHED: OdePlaneGeom(dReal a, dReal b, dReal c, dReal d); OdePlaneGeom(const LVecBase4f ¶ms); - OdePlaneGeom(OdeSpace &space, dReal a, dReal b, dReal c, dReal d); - OdePlaneGeom(OdeSpace &space, const LVecBase4f ¶ms); + explicit OdePlaneGeom(OdeSpace &space, dReal a, dReal b, dReal c, dReal d); + explicit OdePlaneGeom(OdeSpace &space, const LVecBase4f ¶ms); virtual ~OdePlaneGeom(); INLINE void set_params(dReal a, dReal b, dReal c, dReal d); diff --git a/panda/src/ode/odeQuadTreeSpace.h b/panda/src/ode/odeQuadTreeSpace.h index d88e8a832b..973f1fa8fc 100644 --- a/panda/src/ode/odeQuadTreeSpace.h +++ b/panda/src/ode/odeQuadTreeSpace.h @@ -32,13 +32,13 @@ public: OdeQuadTreeSpace(dSpaceID id); PUBLISHED: - OdeQuadTreeSpace(const LPoint3f ¢er, - const LVecBase3f &extents, - const int depth); - OdeQuadTreeSpace(OdeSpace &space, - const LPoint3f ¢er, - const LVecBase3f &extents, - const int depth); + explicit OdeQuadTreeSpace(const LPoint3f ¢er, + const LVecBase3f &extents, + const int depth); + explicit OdeQuadTreeSpace(OdeSpace &space, + const LPoint3f ¢er, + const LVecBase3f &extents, + const int depth); virtual ~OdeQuadTreeSpace(); public: diff --git a/panda/src/ode/odeRayGeom.h b/panda/src/ode/odeRayGeom.h index 9f366320a7..712f0e8440 100644 --- a/panda/src/ode/odeRayGeom.h +++ b/panda/src/ode/odeRayGeom.h @@ -31,7 +31,7 @@ public: PUBLISHED: OdeRayGeom(dReal length); - OdeRayGeom(OdeSpace &space, dReal length); + explicit OdeRayGeom(OdeSpace &space, dReal length); virtual ~OdeRayGeom(); INLINE void set_length(dReal length); diff --git a/panda/src/ode/odeSliderJoint.h b/panda/src/ode/odeSliderJoint.h index 981ec33a80..fbf335cb5f 100644 --- a/panda/src/ode/odeSliderJoint.h +++ b/panda/src/ode/odeSliderJoint.h @@ -32,8 +32,8 @@ public: OdeSliderJoint(dJointID id); PUBLISHED: - OdeSliderJoint(OdeWorld &world); - OdeSliderJoint(OdeWorld &world, OdeJointGroup &joint_group); + explicit OdeSliderJoint(OdeWorld &world); + explicit OdeSliderJoint(OdeWorld &world, OdeJointGroup &joint_group); virtual ~OdeSliderJoint(); INLINE void set_axis(dReal x, dReal y, dReal z); diff --git a/panda/src/ode/odeSphereGeom.h b/panda/src/ode/odeSphereGeom.h index 33ee3a8e3f..f17d6c476e 100644 --- a/panda/src/ode/odeSphereGeom.h +++ b/panda/src/ode/odeSphereGeom.h @@ -31,7 +31,7 @@ public: PUBLISHED: OdeSphereGeom(dReal radius); - OdeSphereGeom(OdeSpace &space, dReal radius); + explicit OdeSphereGeom(OdeSpace &space, dReal radius); OdeSphereGeom(OdeGeom &geom); virtual ~OdeSphereGeom(); diff --git a/panda/src/ode/odeUniversalJoint.h b/panda/src/ode/odeUniversalJoint.h index 00d2cd6c2a..a8ec774b7f 100644 --- a/panda/src/ode/odeUniversalJoint.h +++ b/panda/src/ode/odeUniversalJoint.h @@ -34,8 +34,8 @@ public: OdeUniversalJoint(dJointID id); PUBLISHED: - OdeUniversalJoint(OdeWorld &world); - OdeUniversalJoint(OdeWorld &world, OdeJointGroup &joint_group); + explicit OdeUniversalJoint(OdeWorld &world); + explicit OdeUniversalJoint(OdeWorld &world, OdeJointGroup &joint_group); virtual ~OdeUniversalJoint(); INLINE void set_anchor(dReal x, dReal y, dReal z); diff --git a/panda/src/pgraphnodes/spotlight.h b/panda/src/pgraphnodes/spotlight.h index a529f1479e..b548b92e8b 100644 --- a/panda/src/pgraphnodes/spotlight.h +++ b/panda/src/pgraphnodes/spotlight.h @@ -31,7 +31,7 @@ */ class EXPCL_PANDA_PGRAPHNODES Spotlight : public LightLensNode { PUBLISHED: - Spotlight(const std::string &name); + explicit Spotlight(const std::string &name); protected: Spotlight(const Spotlight ©); diff --git a/panda/src/physics/angularEulerIntegrator.cxx b/panda/src/physics/angularEulerIntegrator.cxx index 642c2c6b8b..daf9a7ce69 100644 --- a/panda/src/physics/angularEulerIntegrator.cxx +++ b/panda/src/physics/angularEulerIntegrator.cxx @@ -103,7 +103,7 @@ child_integrate(Physical *physical, // apply the accumulated torque vector to the object's inertial tensor. // this matrix represents how much force the object 'wants' applied to it // in any direction, among other things. - accum_quat = current_object->get_inertial_tensor() * accum_quat; + accum_quat = LRotation(current_object->get_inertial_tensor()) * accum_quat; // derive this into the angular velocity vector. LRotation rot_quat = current_object->get_rotation(); diff --git a/panda/src/pnmimage/pnmImageHeader.h b/panda/src/pnmimage/pnmImageHeader.h index 6e21ddca98..ce2a624aa5 100644 --- a/panda/src/pnmimage/pnmImageHeader.h +++ b/panda/src/pnmimage/pnmImageHeader.h @@ -118,12 +118,12 @@ PUBLISHED: INLINE PixelSpec() = default; PUBLISHED: - INLINE PixelSpec(xelval gray_value); - INLINE PixelSpec(xelval gray_value, xelval alpha); + INLINE explicit PixelSpec(xelval gray_value); + INLINE explicit PixelSpec(xelval gray_value, xelval alpha); INLINE PixelSpec(xelval red, xelval green, xelval blue); INLINE PixelSpec(xelval red, xelval green, xelval blue, xelval alpha); INLINE PixelSpec(const xel &rgb); - INLINE PixelSpec(const xel &rgb, xelval alpha); + INLINE explicit PixelSpec(const xel &rgb, xelval alpha); INLINE bool operator < (const PixelSpec &other) const; INLINE bool operator == (const PixelSpec &other) const; diff --git a/panda/src/text/dynamicTextFont.h b/panda/src/text/dynamicTextFont.h index d2643cffb1..0b0eedf719 100644 --- a/panda/src/text/dynamicTextFont.h +++ b/panda/src/text/dynamicTextFont.h @@ -41,7 +41,7 @@ typedef struct hb_font_t hb_font_t; class EXPCL_PANDA_TEXT DynamicTextFont : public TextFont, public FreetypeFont { PUBLISHED: DynamicTextFont(const Filename &font_filename, int face_index = 0); - DynamicTextFont(const char *font_data, int data_length, int face_index); + explicit DynamicTextFont(const char *font_data, int data_length, int face_index); DynamicTextFont(const DynamicTextFont ©); virtual ~DynamicTextFont(); From 70cdbae24747fb8504db53e4fa60bb3fbe2ef0e1 Mon Sep 17 00:00:00 2001 From: Max Rodriguez Date: Wed, 2 Aug 2023 08:20:25 +0200 Subject: [PATCH 41/84] framework: Create aspect2d child nodes & update on win resize Closes #1510 Fixes #1508 --- panda/src/framework/windowFramework.I | 96 +++++++++++++++++++++++++ panda/src/framework/windowFramework.cxx | 60 +++++++++++++++- panda/src/framework/windowFramework.h | 18 +++++ 3 files changed, 172 insertions(+), 2 deletions(-) diff --git a/panda/src/framework/windowFramework.I b/panda/src/framework/windowFramework.I index 5fa4caafe8..2cc805758c 100644 --- a/panda/src/framework/windowFramework.I +++ b/panda/src/framework/windowFramework.I @@ -75,6 +75,102 @@ get_display_region_3d() const { return _display_region_3d; } +/** + * Returns the child node of aspect_2d which is positioned + * on the top center of the screen. + */ +INLINE NodePath WindowFramework:: +get_a2d_top_center() { + if (_aspect_2d.is_empty()) { + get_aspect_2d(); + } + return _a2d_top_center; +} + +/** + * Returns the child node of aspect_2d which is positioned + * on the bottom center of the screen. + */ +INLINE NodePath WindowFramework:: +get_a2d_bottom_center() { + if (_aspect_2d.is_empty()) { + get_aspect_2d(); + } + return _a2d_bottom_center; +} + +/** + * Returns the child node of aspect_2d which is positioned + * on the left center of the screen. + */ +INLINE NodePath WindowFramework:: +get_a2d_left_center() { + if (_aspect_2d.is_empty()) { + get_aspect_2d(); + } + return _a2d_left_center; +} + +/** + * Returns the child node of aspect_2d which is positioned + * on the right center of the screen. + */ +INLINE NodePath WindowFramework:: +get_a2d_right_center() { + if (_aspect_2d.is_empty()) { + get_aspect_2d(); + } + return _a2d_right_center; +} + +/** + * Returns the child node of aspect_2d which is positioned + * on the top left of the screen. + */ +INLINE NodePath WindowFramework:: +get_a2d_top_left() { + if (_aspect_2d.is_empty()) { + get_aspect_2d(); + } + return _a2d_top_left; +} + +/** + * Returns the child node of aspect_2d which is positioned + * on the top right of the screen. + */ +INLINE NodePath WindowFramework:: +get_a2d_top_right() { + if (_aspect_2d.is_empty()) { + get_aspect_2d(); + } + return _a2d_top_right; +} + +/** + * Returns the child node of aspect_2d which is positioned + * on the bottom left of the screen. + */ +INLINE NodePath WindowFramework:: +get_a2d_bottom_left() { + if (_aspect_2d.is_empty()) { + get_aspect_2d(); + } + return _a2d_bottom_left; +} + +/** + * Returns the child node of aspect_2d which is positioned + * on the bottom right of the screen. + */ +INLINE NodePath WindowFramework:: +get_a2d_bottom_right() { + if (_aspect_2d.is_empty()) { + get_aspect_2d(); + } + return _a2d_bottom_right; +} + /** * Returns the current state of the anim_controls flag. */ diff --git a/panda/src/framework/windowFramework.cxx b/panda/src/framework/windowFramework.cxx index c2fd0f6582..f28c05f3d7 100644 --- a/panda/src/framework/windowFramework.cxx +++ b/panda/src/framework/windowFramework.cxx @@ -323,6 +323,31 @@ get_aspect_2d() { } _aspect_2d.set_scale(1.0f / this_aspect_ratio, 1.0f, 1.0f); + + // Create child nodes of aspect_2d anchored to edges/corners of the window. + _a2d_top_center = _aspect_2d.attach_new_node("a2dTopCenter"); + _a2d_bottom_center = _aspect_2d.attach_new_node("a2dBottomCenter"); + _a2d_left_center = _aspect_2d.attach_new_node("a2dLeftCenter"); + _a2d_right_center = _aspect_2d.attach_new_node("a2dRightCenter"); + _a2d_top_left = _aspect_2d.attach_new_node("a2dTopLeft"); + _a2d_top_right = _aspect_2d.attach_new_node("a2dTopRight"); + _a2d_bottom_left = _aspect_2d.attach_new_node("a2dBottomLeft"); + _a2d_bottom_right = _aspect_2d.attach_new_node("a2dBottomRight"); + + PN_stdfloat a2d_top = 1.0f; + PN_stdfloat a2d_bottom = -1.0f; + PN_stdfloat a2d_left = this_aspect_ratio * -1.0f; + PN_stdfloat a2d_right = this_aspect_ratio; + + // Position nodes to their corresponding places + _a2d_top_center.set_pos(0.0f, 0.0f, a2d_top); + _a2d_bottom_center.set_pos(0.0f, 0.0f, a2d_bottom); + _a2d_left_center.set_pos(a2d_left, 0.0f, 0.0f); + _a2d_right_center.set_pos(a2d_right, 0.0f, 0.0f); + _a2d_top_left.set_pos(a2d_left, 0.0f, a2d_top); + _a2d_top_right.set_pos(a2d_right, 0.0f, a2d_top); + _a2d_bottom_left.set_pos(a2d_left, 0.0f, a2d_bottom); + _a2d_bottom_right.set_pos(a2d_right, 0.0f, a2d_bottom); } return _aspect_2d; @@ -794,7 +819,7 @@ set_anim_controls(bool enable) { /** * Reevaluates the dimensions of the window, presumably after the window has * been resized by the user or some other force. Adjusts the render film - * size, aspect2d scale (aspect ratio) and the dimensionsas of pixel_2d + * size, aspect2d scale (aspect ratio) and the dimensions of pixel_2d * according to the new window shape, or new config setting. */ void WindowFramework:: @@ -816,7 +841,38 @@ adjust_dimensions() { } if (!_aspect_2d.is_empty()) { - _aspect_2d.set_scale(1.0f / this_aspect_ratio, 1.0f, 1.0f); + PN_stdfloat a2d_top; + PN_stdfloat a2d_bottom; + PN_stdfloat a2d_left; + PN_stdfloat a2d_right; + + if (this_aspect_ratio < 1) { + // If the window is TALL, lets expand the top and bottom + _aspect_2d.set_scale(1.0f, this_aspect_ratio, this_aspect_ratio); + + a2d_top = 1.0f / this_aspect_ratio; + a2d_bottom = -1.0f / this_aspect_ratio; + a2d_left = -1.0f; + a2d_right = 1.0f; + } else { + // If the window is WIDE, lets expand the left and right + _aspect_2d.set_scale(1.0f / this_aspect_ratio, 1.0f, 1.0f); + + a2d_top = 1.0f; + a2d_bottom = -1.0f; + a2d_left = this_aspect_ratio * -1.0f; + a2d_right = this_aspect_ratio; + } + + // Adjust aspect_2d child nodes to new aspect ratio + _a2d_top_center.set_pos(0.0f, 0.0f, a2d_top); + _a2d_bottom_center.set_pos(0.0f, 0.0f, a2d_bottom); + _a2d_left_center.set_pos(a2d_left, 0.0f, 0.0f); + _a2d_right_center.set_pos(a2d_right, 0.0f, 0.0f); + _a2d_top_left.set_pos(a2d_left, 0.0f, a2d_top); + _a2d_top_right.set_pos(a2d_right, 0.0f, a2d_top); + _a2d_bottom_left.set_pos(a2d_left, 0.0f, a2d_bottom); + _a2d_bottom_right.set_pos(a2d_right, 0.0f, a2d_bottom); } if (!_pixel_2d.is_empty()) { diff --git a/panda/src/framework/windowFramework.h b/panda/src/framework/windowFramework.h index 2308cb1ff8..84f7e163c7 100644 --- a/panda/src/framework/windowFramework.h +++ b/panda/src/framework/windowFramework.h @@ -84,6 +84,15 @@ public: NodePath get_mouse(); NodePath get_button_thrower(); + INLINE NodePath get_a2d_top_center(); + INLINE NodePath get_a2d_bottom_center(); + INLINE NodePath get_a2d_left_center(); + INLINE NodePath get_a2d_right_center(); + INLINE NodePath get_a2d_top_left(); + INLINE NodePath get_a2d_top_right(); + INLINE NodePath get_a2d_bottom_left(); + INLINE NodePath get_a2d_bottom_right(); + void enable_keyboard(); void setup_trackball(); void center_trackball(const NodePath &object); @@ -175,6 +184,15 @@ private: NodePath _aspect_2d; NodePath _pixel_2d; + NodePath _a2d_top_center; + NodePath _a2d_bottom_center; + NodePath _a2d_left_center; + NodePath _a2d_right_center; + NodePath _a2d_top_left; + NodePath _a2d_top_right; + NodePath _a2d_bottom_left; + NodePath _a2d_bottom_right; + AnimControlCollection _anim_controls; bool _anim_controls_enabled; int _anim_index; From d1f4212acdc01b5ceda8edc03fe70b273c3a02da Mon Sep 17 00:00:00 2001 From: WMOkiishi Date: Fri, 17 Mar 2023 17:33:45 -0600 Subject: [PATCH 42/84] direct: Utilize the built-in `sorted` function Closes #1479 --- direct/src/actor/Actor.py | 23 ++++++------------- direct/src/cluster/ClusterClient.py | 9 +++----- direct/src/cluster/ClusterServer.py | 10 +++----- direct/src/directtools/DirectLights.py | 4 +--- direct/src/dist/FreezeTool.py | 5 +--- direct/src/dist/commands.py | 8 ++----- direct/src/distributed/DoCollectionManager.py | 10 ++------ direct/src/distributed/DoInterestManager.py | 3 +-- direct/src/gui/DirectGuiBase.py | 4 +--- direct/src/leveleditor/HotKeyUI.py | 4 +--- direct/src/showbase/BulletinBoard.py | 4 +--- direct/src/showbase/ContainerReport.py | 10 +++----- direct/src/showbase/ExceptionVarDump.py | 17 ++++---------- direct/src/showbase/GarbageReport.py | 3 +-- direct/src/showbase/JobManager.py | 4 +--- direct/src/showbase/Messenger.py | 16 ++++--------- direct/src/showbase/ObjectPool.py | 14 +++-------- direct/src/showbase/OnScreenDebug.py | 4 +--- direct/src/showutil/TexMemWatcher.py | 4 ++-- direct/src/tkpanels/FSMInspector.py | 3 +-- direct/src/tkpanels/Inspector.py | 8 ++----- direct/src/tkpanels/ParticlePanel.py | 8 ++----- direct/src/tkpanels/TaskManagerPanel.py | 4 +--- .../src/tkwidgets/WidgetPropertiesDialog.py | 3 +-- 24 files changed, 49 insertions(+), 133 deletions(-) diff --git a/direct/src/actor/Actor.py b/direct/src/actor/Actor.py index c9e8b8b8b3..263ac8803a 100644 --- a/direct/src/actor/Actor.py +++ b/direct/src/actor/Actor.py @@ -280,9 +280,7 @@ class Actor(DirectObject, NodePath): self.setLODNode(node = lodNode) # preserve numerical order for lod's # this will make it easier to set ranges - sortedKeys = list(models.keys()) - sortedKeys.sort() - for lodName in sortedKeys: + for lodName in sorted(models): # make a node under the LOD switch # for each lod (just because!) self.addLOD(str(lodName)) @@ -302,9 +300,7 @@ class Actor(DirectObject, NodePath): # it is a single part actor w/LOD self.setLODNode(node = lodNode) # preserve order of LOD's - sortedKeys = list(models.keys()) - sortedKeys.sort() - for lodName in sortedKeys: + for lodName in sorted(models): self.addLOD(str(lodName)) # pass in dictionary of parts self.loadModel(models[lodName], lodName=lodName, @@ -323,9 +319,7 @@ class Actor(DirectObject, NodePath): if isinstance(models, dict): if isinstance(models[next(iter(models))], dict): # then we have a multi-part w/ LOD - sortedKeys = list(models.keys()) - sortedKeys.sort() - for lodName in sortedKeys: + for lodName in sorted(models): # iterate over both dicts for partName in anims: self.loadAnims( @@ -336,9 +330,7 @@ class Actor(DirectObject, NodePath): self.loadAnims(anims[partName], partName) elif isinstance(models, dict): # then we have single-part w/ LOD - sortedKeys = list(models.keys()) - sortedKeys.sort() - for lodName in sortedKeys: + for lodName in sorted(models): self.loadAnims(anims, lodName=lodName) else: # else it is single-part w/o LOD @@ -603,9 +595,6 @@ class Actor(DirectObject, NodePath): return bundles 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 = list(self.__partBundleDict.keys()) # Reverse sort the doing a string->int def sortKey(x): if not str(x).isdigit(): @@ -622,7 +611,9 @@ class Actor(DirectObject, NodePath): else: return int(x) - self.__sortedLODNames.sort(key=sortKey, reverse=True) + # 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 = sorted(self.__partBundleDict, key=sortKey, reverse=True) def getLODNames(self): """ diff --git a/direct/src/cluster/ClusterClient.py b/direct/src/cluster/ClusterClient.py index fac896f1e4..e5c0b7ba6a 100644 --- a/direct/src/cluster/ClusterClient.py +++ b/direct/src/cluster/ClusterClient.py @@ -169,12 +169,9 @@ class ClusterClient(DirectObject.DirectObject): self.serverList[server].sendNamedMovementDone() def redoSortedPriorities(self): - self.sortedControlMappings = [] - for key in self.controlMappings: - self.sortedControlMappings.append([self.controlPriorities[key], - key]) - - self.sortedControlMappings.sort() + self.sortedControlMappings = sorted( + [self.controlPriorities[key], key] for key in self.controlMappings + ) def moveObject(self, nodePath, object, serverList, offset, hasColor = True): self.notify.debug('moving object '+object) diff --git a/direct/src/cluster/ClusterServer.py b/direct/src/cluster/ClusterServer.py index ba707f17dd..5d62146cc1 100644 --- a/direct/src/cluster/ClusterServer.py +++ b/direct/src/cluster/ClusterServer.py @@ -137,13 +137,9 @@ class ClusterServer(DirectObject.DirectObject): self.objectMappings.pop(name) def redoSortedPriorities(self): - - self.sortedControlMappings = [] - for key in self.objectMappings: - self.sortedControlMappings.append([self.controlPriorities[key], - key]) - - self.sortedControlMappings.sort() + self.sortedControlMappings = sorted( + [self.controlPriorities[key], key] for key in self.objectMappings + ) def addControlMapping(self, objectName, controlledName, offset = None, priority = 0): diff --git a/direct/src/directtools/DirectLights.py b/direct/src/directtools/DirectLights.py index 5fe757d688..a96e3d971e 100644 --- a/direct/src/directtools/DirectLights.py +++ b/direct/src/directtools/DirectLights.py @@ -66,9 +66,7 @@ class DirectLights(NodePath): def getNameList(self): # Return a sorted list of all lights in the light dict - nameList = [x.getName() for x in self.lightDict.values()] - nameList.sort() - return nameList + return sorted(x.getName() for x in self.lightDict.values()) def create(self, ltype): ltype = ltype.lower() diff --git a/direct/src/dist/FreezeTool.py b/direct/src/dist/FreezeTool.py index 4bf6dca3ac..84189ac77c 100644 --- a/direct/src/dist/FreezeTool.py +++ b/direct/src/dist/FreezeTool.py @@ -1146,15 +1146,12 @@ class Freezer: # Walk through the list in sorted order, so we reach parents # before children. - names = list(self.modules.items()) - names.sort() - excludeDict = {} implicitParentDict = {} includes = [] autoIncludes = [] origToNewName = {} - for newName, mdef in names: + for newName, mdef in sorted(self.modules.items()): moduleName = mdef.moduleName origToNewName[moduleName] = newName if mdef.implicit and '.' in newName: diff --git a/direct/src/dist/commands.py b/direct/src/dist/commands.py index 6036c6abcc..5410199307 100644 --- a/direct/src/dist/commands.py +++ b/direct/src/dist/commands.py @@ -859,16 +859,12 @@ class build_apps(setuptools.Command): libdir = os.path.dirname(dtool_fn.to_os_specific()) etcdir = os.path.join(libdir, '..', 'etc') - etcfiles = os.listdir(etcdir) - etcfiles.sort(reverse=True) - for fn in etcfiles: + for fn in sorted(os.listdir(etcdir), reverse=True): if fn.lower().endswith('.prc'): with open(os.path.join(etcdir, fn)) as f: prcstring += f.read() else: - etcfiles = [i for i in p3dwhl.namelist() if i.endswith('.prc')] - etcfiles.sort(reverse=True) - for fn in etcfiles: + for fn in sorted((i for i in p3dwhl.namelist() if i.endswith('.prc')), reverse=True): with p3dwhl.open(fn) as f: prcstring += f.read().decode('utf8') diff --git a/direct/src/distributed/DoCollectionManager.py b/direct/src/distributed/DoCollectionManager.py index 21eeb10751..cd022015bf 100755 --- a/direct/src/distributed/DoCollectionManager.py +++ b/direct/src/distributed/DoCollectionManager.py @@ -149,10 +149,7 @@ class DoCollectionManager: class2count.setdefault(className, 0) class2count[className] += 1 count2classes = invertDictLossless(class2count) - counts = list(count2classes.keys()) - counts.sort() - counts.reverse() - for count in counts: + for count in sorted(count2classes, reverse=True): count2classes[count].sort() for name in count2classes[count]: print('%s %s' % (count, name)) @@ -166,10 +163,7 @@ class DoCollectionManager: class2count.setdefault(className, 0) class2count[className] += 1 count2classes = invertDictLossless(class2count) - counts = list(count2classes.keys()) - counts.sort() - counts.reverse() - for count in counts: + for count in sorted(count2classes, reverse=True): count2classes[count].sort() for name in count2classes[count]: # print '%s %s' % (count, name) diff --git a/direct/src/distributed/DoInterestManager.py b/direct/src/distributed/DoInterestManager.py index 0297847966..251e0b91a1 100755 --- a/direct/src/distributed/DoInterestManager.py +++ b/direct/src/distributed/DoInterestManager.py @@ -512,8 +512,7 @@ class DoInterestManager(DirectObject.DirectObject): datagram = PyDatagram() # Add message type if isinstance(zoneIdList, list): - vzl = list(zoneIdList) - vzl.sort() + vzl = sorted(zoneIdList) uniqueElements(vzl) datagram.addUint16(CLIENT_ADD_INTEREST_MULTIPLE) datagram.addUint32(contextId) diff --git a/direct/src/gui/DirectGuiBase.py b/direct/src/gui/DirectGuiBase.py index fa2721f688..24424855d0 100644 --- a/direct/src/gui/DirectGuiBase.py +++ b/direct/src/gui/DirectGuiBase.py @@ -616,9 +616,7 @@ class DirectGuiBase(DirectObject.DirectObject): def components(self): # Return a list of all components. - names = list(self.__componentInfo.keys()) - names.sort() - return names + return sorted(self.__componentInfo) def hascomponent(self, component): return component in self.__componentInfo diff --git a/direct/src/leveleditor/HotKeyUI.py b/direct/src/leveleditor/HotKeyUI.py index 8cde68b0eb..2c56a065aa 100755 --- a/direct/src/leveleditor/HotKeyUI.py +++ b/direct/src/leveleditor/HotKeyUI.py @@ -116,9 +116,7 @@ class HotKeyPanel(ScrolledPanel): def updateUI(self): vbox = wx.BoxSizer(wx.VERTICAL) - keys = list(base.direct.hotKeyMap.keys()) - keys.sort() - for key in keys: + for key in sorted(base.direct.hotKeyMap): keyDesc = base.direct.hotKeyMap[key] itemPanel = wx.Panel(self) sizer = wx.BoxSizer(wx.HORIZONTAL) diff --git a/direct/src/showbase/BulletinBoard.py b/direct/src/showbase/BulletinBoard.py index 9478b68bfa..96b809157c 100755 --- a/direct/src/showbase/BulletinBoard.py +++ b/direct/src/showbase/BulletinBoard.py @@ -55,8 +55,6 @@ class BulletinBoard: def __repr__(self): str = 'Bulletin Board Contents\n' str += '=======================' - keys = list(self._dict.keys()) - keys.sort() - for postName in keys: + for postName in sorted(self._dict): str += '\n%s: %s' % (postName, self._dict[postName]) return str diff --git a/direct/src/showbase/ContainerReport.py b/direct/src/showbase/ContainerReport.py index 6075d55062..6ceca73d07 100755 --- a/direct/src/showbase/ContainerReport.py +++ b/direct/src/showbase/ContainerReport.py @@ -228,14 +228,11 @@ class ContainerReport(Job): if type not in self._type2id2len: return len2ids = invertDictLossless(self._type2id2len[type]) - lengths = list(len2ids.keys()) - lengths.sort() - lengths.reverse() print('=====') print('===== %s' % type) count = 0 stop = False - for l in lengths: + for l in sorted(len2ids, reverse=True): #len2ids[l].sort() pathStrList = list() for id in len2ids[l]: @@ -257,9 +254,8 @@ class ContainerReport(Job): for type in initialTypes: for i in self._outputType(type, **kArgs): yield None - otherTypes = list(set(self._type2id2len.keys()).difference(set(initialTypes))) - otherTypes.sort(key=lambda obj: obj.__name__) - for type in otherTypes: + otherTypes = set(self._type2id2len).difference(initialTypes) + for type in sorted(otherTypes, key=lambda obj: obj.__name__): for i in self._outputType(type, **kArgs): yield None diff --git a/direct/src/showbase/ExceptionVarDump.py b/direct/src/showbase/ExceptionVarDump.py index b1ccf266a8..b2cc73f68a 100755 --- a/direct/src/showbase/ExceptionVarDump.py +++ b/direct/src/showbase/ExceptionVarDump.py @@ -116,15 +116,10 @@ def _excepthookDumpVars(eType, eValue, tb): for name, obj in frame.f_locals.items(): if name in codeNames: name2obj[name] = obj - # show them in alphabetical order - names = list(name2obj.keys()) - names.sort() - # push them in reverse order so they'll be popped in the correct order - names.reverse() traversedIds = set() - - for name in names: + # push them in reverse alphabetical order so they'll be popped in the correct order + for name in sorted(name2obj, reverse=True): stateStack.push([name, name2obj[name], traversedIds]) while len(stateStack) > 0: @@ -150,14 +145,10 @@ def _excepthookDumpVars(eType, eValue, tb): continue attrName2obj[attrName] = attr if len(attrName2obj) > 0: - # show them in alphabetical order - attrNames = list(attrName2obj.keys()) - attrNames.sort() - # push them in reverse order so they'll be popped in the correct order - attrNames.reverse() ids = set(traversedIds) ids.add(id(obj)) - for attrName in attrNames: + # push them in reverse alphabetical order so they'll be popped in the correct order + for attrName in sorted(attrName2obj, reverse=True): obj = attrName2obj[attrName] stateStack.push(['%s.%s' % (name, attrName), obj, ids]) diff --git a/direct/src/showbase/GarbageReport.py b/direct/src/showbase/GarbageReport.py index fd101bc6c2..ca3d02b36a 100644 --- a/direct/src/showbase/GarbageReport.py +++ b/direct/src/showbase/GarbageReport.py @@ -294,8 +294,7 @@ class GarbageReport(Job): if self._args.fullReport: garbageIndices = range(self.numGarbage) else: - garbageIndices = list(self.cycleIds) - garbageIndices.sort() + garbageIndices = sorted(self.cycleIds) numGarbage = len(garbageIndices) # log each individual item with a number in front of it diff --git a/direct/src/showbase/JobManager.py b/direct/src/showbase/JobManager.py index 68bcbd0e32..e6f034f08c 100755 --- a/direct/src/showbase/JobManager.py +++ b/direct/src/showbase/JobManager.py @@ -141,9 +141,7 @@ class JobManager: def _getSortedPriorities(self): # returns all job priorities in ascending order - priorities = list(self._pri2jobId2job.keys()) - priorities.sort() - return priorities + return sorted(self._pri2jobId2job) def _process(self, task=None): if self._useOverflowTime is None: diff --git a/direct/src/showbase/Messenger.py b/direct/src/showbase/Messenger.py index 0a7e38e82b..e6ef2153c2 100644 --- a/direct/src/showbase/Messenger.py +++ b/direct/src/showbase/Messenger.py @@ -540,9 +540,7 @@ class Messenger: return a matching event (needle) if found (in haystack). This is primarily a debugging tool. """ - keys = list(self.__callbacks.keys()) - keys.sort() - for event in keys: + for event in sorted(self.__callbacks): if repr(event).find(needle) >= 0: return {event: self.__callbacks[event]} @@ -553,9 +551,7 @@ class Messenger: This is primarily a debugging tool. """ matches = {} - keys = list(self.__callbacks.keys()) - keys.sort() - for event in keys: + for event in sorted(self.__callbacks): if repr(event).find(needle) >= 0: matches[event] = self.__callbacks[event] # if the limit is not None, decrement and @@ -596,9 +592,7 @@ class Messenger: Compact version of event, acceptor pairs """ str = "The messenger is currently handling:\n" + "="*64 + "\n" - keys = list(self.__callbacks.keys()) - keys.sort() - for event in keys: + for event in sorted(self.__callbacks): str += self.__eventRepr(event) # Print out the object: event dictionary too str += "="*64 + "\n" @@ -617,9 +611,7 @@ class Messenger: """ str = 'Messenger\n' str = str + '='*50 + '\n' - keys = list(self.__callbacks.keys()) - keys.sort() - for event in keys: + for event in sorted(self.__callbacks): acceptorDict = self.__callbacks[event] str = str + 'Event: ' + event + '\n' for key in list(acceptorDict.keys()): diff --git a/direct/src/showbase/ObjectPool.py b/direct/src/showbase/ObjectPool.py index 125fb7f326..e895d0f8a5 100755 --- a/direct/src/showbase/ObjectPool.py +++ b/direct/src/showbase/ObjectPool.py @@ -90,10 +90,7 @@ class ObjectPool: def typeFreqStr(self): s = 'Object Pool: Type Frequencies' s += '\n=============================' - counts = list(set(self._count2types.keys())) - counts.sort() - counts.reverse() - for count in counts: + for count in sorted(self._count2types, reverse=True): types = makeList(self._count2types[count]) for typ in types: s += '\n%s\t%s' % (count, typ) @@ -102,12 +99,10 @@ class ObjectPool: def printObjsByType(self): 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 # there's a large group that waits a long time before printing #counts.reverse() - for count in counts: + for count in sorted(self._count2types): types = makeList(self._count2types[count]) for typ in types: print('TYPE: %s, %s objects' % (repr(typ), len(self._type2objs[typ]))) @@ -115,10 +110,7 @@ class ObjectPool: def printReferrers(self, numEach=3): """referrers of the first few of each type of object""" - counts = list(set(self._count2types.keys())) - counts.sort() - counts.reverse() - for count in counts: + for count in sorted(self._count2types, reverse=True): types = makeList(self._count2types[count]) for typ in types: print('\n\nTYPE: %s' % repr(typ)) diff --git a/direct/src/showbase/OnScreenDebug.py b/direct/src/showbase/OnScreenDebug.py index 7483d3c9f1..0d690e3806 100755 --- a/direct/src/showbase/OnScreenDebug.py +++ b/direct/src/showbase/OnScreenDebug.py @@ -57,9 +57,7 @@ class OnScreenDebug: if not self.onScreenText: self.load() self.onScreenText.clearText() - entries = list(self.data.items()) - entries.sort() - for k, v in entries: + for k, v in sorted(self.data.items()): if v[0] == self.frame: # It was updated this frame (key equals value): #isNew = " is" diff --git a/direct/src/showutil/TexMemWatcher.py b/direct/src/showutil/TexMemWatcher.py index 5418f1c6ba..3135c76b05 100644 --- a/direct/src/showutil/TexMemWatcher.py +++ b/direct/src/showutil/TexMemWatcher.py @@ -756,8 +756,8 @@ class TexMemWatcher(DirectObject): # Sort the regions from largest to smallest to maximize # packing effectiveness. - texRecords = list(self.texRecordsByTex.values()) - texRecords.sort(key = lambda tr: (tr.tw, tr.th), reverse = True) + texRecords = sorted(self.texRecordsByTex.values(), + key=lambda tr: (tr.tw, tr.th), reverse=True) for tr in texRecords: self.placeTexture(tr) diff --git a/direct/src/tkpanels/FSMInspector.py b/direct/src/tkpanels/FSMInspector.py index 12049542fa..f3b20aa258 100644 --- a/direct/src/tkpanels/FSMInspector.py +++ b/direct/src/tkpanels/FSMInspector.py @@ -358,8 +358,7 @@ class FSMInspector(AppShell): def printLayout(self): dict = self.stateInspectorDict - keys = list(dict.keys()) - keys.sort() + keys = sorted(dict) print("ClassicFSM.ClassicFSM('%s', [" % self.name) for key in keys[:-1]: si = dict[key] diff --git a/direct/src/tkpanels/Inspector.py b/direct/src/tkpanels/Inspector.py index 592e670cea..15cc04dc46 100644 --- a/direct/src/tkpanels/Inspector.py +++ b/direct/src/tkpanels/Inspector.py @@ -95,9 +95,7 @@ class Inspector: def initializePartsList(self): self._partsList = [] - keys = self.namedParts() - keys.sort() - for each in keys: + for each in sorted(self.namedParts()): self._partsList.append(each) #if not callable(getattr(self.object, each)): # self._partsList.append(each) @@ -202,9 +200,7 @@ class DictionaryInspector(Inspector): def initializePartsList(self): Inspector.initializePartsList(self) - keys = list(self.object.keys()) - keys.sort() - for each in keys: + for each in sorted(self.object): self._partsList.append(each) def partNumber(self, partNumber): diff --git a/direct/src/tkpanels/ParticlePanel.py b/direct/src/tkpanels/ParticlePanel.py index aeebb9cd25..7408497ac2 100644 --- a/direct/src/tkpanels/ParticlePanel.py +++ b/direct/src/tkpanels/ParticlePanel.py @@ -1174,9 +1174,7 @@ class ParticlePanel(AppShell): self.particlesLabelMenu.add_separator() # Add in a checkbutton for each effect (to toggle on/off) particles = self.particleEffect.getParticlesList() - names = [x.getName() for x in particles] - names.sort() - for name in names: + for name in sorted(x.getName() for x in particles): particle = self.particleEffect.getParticlesNamed(name) self.particlesLabelMenu.add_command( label = name, @@ -1199,9 +1197,7 @@ class ParticlePanel(AppShell): self.forceGroupLabelMenu.add_separator() # Add in a checkbutton for each effect (to toggle on/off) forceGroupList = self.particleEffect.getForceGroupList() - names = [x.getName() for x in forceGroupList] - names.sort() - for name in names: + for name in sorted(x.getName() for x in forceGroupList): force = self.particleEffect.getForceGroupNamed(name) self.forceGroupLabelMenu.add_command( label = name, diff --git a/direct/src/tkpanels/TaskManagerPanel.py b/direct/src/tkpanels/TaskManagerPanel.py index 3f974c1fb2..ce1da584d6 100644 --- a/direct/src/tkpanels/TaskManagerPanel.py +++ b/direct/src/tkpanels/TaskManagerPanel.py @@ -151,10 +151,8 @@ class TaskManagerWidget(DirectObject): # Get a list of task names taskNames = [] self.__taskDict = {} - tasks = self.taskMgr.getTasks() - tasks.sort(key = lambda t: t.getName()) count = 0 - for task in tasks: + for task in sorted(self.taskMgr.getTasks(), key=lambda t: t.getName()): taskNames.append(task.getName()) self.__taskDict[count] = task count += 1 diff --git a/direct/src/tkwidgets/WidgetPropertiesDialog.py b/direct/src/tkwidgets/WidgetPropertiesDialog.py index 92d48b4d9f..31fa2a9038 100644 --- a/direct/src/tkwidgets/WidgetPropertiesDialog.py +++ b/direct/src/tkwidgets/WidgetPropertiesDialog.py @@ -21,8 +21,7 @@ class WidgetPropertiesDialog(tk.Toplevel): self.propertyDict = propertyDict self.propertyList = propertyList if self.propertyList is None: - self.propertyList = list(self.propertyDict.keys()) - self.propertyList.sort() + self.propertyList = sorted(self.propertyDict) # Use default parent if none specified if not parent: parent = tk._default_root From f7f3179a89a622c9c7e64a7bfcd4675ae8bbc115 Mon Sep 17 00:00:00 2001 From: WMOkiishi Date: Wed, 2 Aug 2023 08:24:44 +0200 Subject: [PATCH 43/84] Move test code from across `direct` to proper test modules Closes #1480 --- .github/workflows/ci.yml | 20 +- direct/src/distributed/CRDataCache.py | 38 -- direct/src/fsm/StatePush.py | 155 +----- direct/src/physics/__init__.py | 0 direct/src/showbase/CountedResource.py | 144 ----- direct/src/showbase/DistancePhasedNode.py | 28 - direct/src/showbase/PythonUtil.py | 47 -- direct/src/stdpy/threading.py | 105 ---- direct/src/stdpy/threading2.py | 89 --- direct/src/task/Task.py | 526 ------------------ direct/src/tkpanels/ParticlePanel.py | 18 - direct/src/tkpanels/Placer.py | 8 - direct/src/tkwidgets/AppShell.py | 4 - direct/src/tkwidgets/Dial.py | 15 - direct/src/tkwidgets/EntryScale.py | 42 -- direct/src/tkwidgets/Floater.py | 39 -- direct/src/tkwidgets/VectorWidgets.py | 14 - requirements-test.txt | 4 + tests/{display => }/conftest.py | 23 + tests/distributed/test_CRDataCache.py | 42 ++ tests/fsm/test_StatePush.py | 144 +++++ .../gui/test_DirectGui.py | 22 +- .../particles/test_particle.py | 20 +- .../particles/test_particle_floor.py | 8 +- .../FallTest.py => tests/physics/test_fall.py | 15 +- .../physics/test_rotation.py | 15 +- tests/showbase/test_CountedResource.py | 145 +++++ tests/showbase/test_DistancePhasedNode.py | 30 + tests/showbase/test_PythonUtil.py | 43 ++ tests/stdpy/test_threading.py | 103 ++++ tests/stdpy/test_threading2.py | 84 +++ tests/task/test_Task.py | 518 +++++++++++++++++ tests/task/test_task_arg.py | 4 +- .../TaskTester.py => tests/task/test_tasks.py | 10 +- tests/test_imports.py | 7 - tests/tkpanels/test_ParticlePanel.py | 11 + tests/tkpanels/test_Placer.py | 12 + tests/tkwidgets/test_AppShell.py | 7 + tests/tkwidgets/test_Dial.py | 19 + tests/tkwidgets/test_EntryScale.py | 44 ++ tests/tkwidgets/test_Floater.py | 41 ++ tests/tkwidgets/test_VectorWidgets.py | 17 + 42 files changed, 1336 insertions(+), 1344 deletions(-) delete mode 100644 direct/src/physics/__init__.py create mode 100644 requirements-test.txt rename tests/{display => }/conftest.py (77%) create mode 100644 tests/distributed/test_CRDataCache.py create mode 100644 tests/fsm/test_StatePush.py rename direct/src/gui/DirectGuiTest.py => tests/gui/test_DirectGui.py (92%) rename direct/src/particles/ParticleTest.py => tests/particles/test_particle.py (54%) rename direct/src/particles/ParticleFloorTest.py => tests/particles/test_particle_floor.py (93%) mode change 100755 => 100644 rename direct/src/physics/FallTest.py => tests/physics/test_fall.py (92%) rename direct/src/physics/RotationTest.py => tests/physics/test_rotation.py (92%) create mode 100644 tests/showbase/test_CountedResource.py create mode 100644 tests/showbase/test_DistancePhasedNode.py create mode 100644 tests/stdpy/test_threading2.py create mode 100644 tests/task/test_Task.py rename direct/src/task/TaskTester.py => tests/task/test_tasks.py (82%) mode change 100755 => 100644 create mode 100644 tests/tkpanels/test_ParticlePanel.py create mode 100644 tests/tkpanels/test_Placer.py create mode 100644 tests/tkwidgets/test_AppShell.py create mode 100644 tests/tkwidgets/test_Dial.py create mode 100644 tests/tkwidgets/test_EntryScale.py create mode 100644 tests/tkwidgets/test_Floater.py create mode 100644 tests/tkwidgets/test_VectorWidgets.py diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1fc6e969ff..bfddcd515e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -207,7 +207,7 @@ jobs: PYTHONPATH: ${{ matrix.config }} run: | PYTHON_EXECUTABLE=$(grep 'Python_EXECUTABLE:' CMakeCache.txt | sed 's/.*=//') - $PYTHON_EXECUTABLE -m pip install pytest pytest-cov + $PYTHON_EXECUTABLE -m pip install -r ../requirements-test.txt export COVERAGE_FILE=.coverage.$RANDOM LLVM_PROFILE_FILE=$PWD/pid-%p.profraw $PYTHON_EXECUTABLE -m pytest ../tests --cov=. # END B @@ -239,7 +239,7 @@ jobs: PYTHONPATH: ${{ matrix.config }} run: | PYTHON_EXECUTABLE=$(grep 'Python_EXECUTABLE:' CMakeCache.txt | sed 's/.*=//') - $PYTHON_EXECUTABLE -m pip install pytest pytest-cov + $PYTHON_EXECUTABLE -m pip install -r ../requirements-test.txt export COVERAGE_FILE=.coverage.$RANDOM LLVM_PROFILE_FILE=$PWD/pid-%p.profraw $PYTHON_EXECUTABLE -m pytest ../tests --cov=. # END B @@ -271,7 +271,7 @@ jobs: PYTHONPATH: ${{ matrix.config }} run: | PYTHON_EXECUTABLE=$(grep 'Python_EXECUTABLE:' CMakeCache.txt | sed 's/.*=//') - $PYTHON_EXECUTABLE -m pip install pytest pytest-cov + $PYTHON_EXECUTABLE -m pip install -r ../requirements-test.txt export COVERAGE_FILE=.coverage.$RANDOM LLVM_PROFILE_FILE=$PWD/pid-%p.profraw $PYTHON_EXECUTABLE -m pytest ../tests --cov=. # END B @@ -303,7 +303,7 @@ jobs: PYTHONPATH: ${{ matrix.config }} run: | PYTHON_EXECUTABLE=$(grep 'Python_EXECUTABLE:' CMakeCache.txt | sed 's/.*=//') - $PYTHON_EXECUTABLE -m pip install pytest pytest-cov + $PYTHON_EXECUTABLE -m pip install -r ../requirements-test.txt export COVERAGE_FILE=.coverage.$RANDOM LLVM_PROFILE_FILE=$PWD/pid-%p.profraw $PYTHON_EXECUTABLE -m pytest ../tests --cov=. # END B @@ -335,7 +335,7 @@ jobs: PYTHONPATH: ${{ matrix.config }} run: | PYTHON_EXECUTABLE=$(grep 'Python_EXECUTABLE:' CMakeCache.txt | sed 's/.*=//') - $PYTHON_EXECUTABLE -m pip install pytest pytest-cov + $PYTHON_EXECUTABLE -m pip install -r ../requirements-test.txt export COVERAGE_FILE=.coverage.$RANDOM LLVM_PROFILE_FILE=$PWD/pid-%p.profraw $PYTHON_EXECUTABLE -m pytest ../tests --cov=. # END B @@ -398,7 +398,7 @@ jobs: - name: Test Python 3.11 shell: bash run: | - python -m pip install pytest + python -m pip install -r requirements-test.txt PYTHONPATH=built LD_LIBRARY_PATH=built/lib DYLD_LIBRARY_PATH=built/lib python -m pytest - name: Set up Python 3.10 @@ -412,7 +412,7 @@ jobs: - name: Test Python 3.10 shell: bash run: | - python -m pip install pytest + python -m pip install -r requirements-test.txt PYTHONPATH=built LD_LIBRARY_PATH=built/lib DYLD_LIBRARY_PATH=built/lib python -m pytest - name: Set up Python 3.9 @@ -426,7 +426,7 @@ jobs: - name: Test Python 3.9 shell: bash run: | - python -m pip install pytest + python -m pip install -r requirements-test.txt PYTHONPATH=built LD_LIBRARY_PATH=built/lib DYLD_LIBRARY_PATH=built/lib python -m pytest - name: Set up Python 3.8 @@ -440,7 +440,7 @@ jobs: - name: Test Python 3.8 shell: bash run: | - python -m pip install pytest + python -m pip install -r requirements-test.txt PYTHONPATH=built LD_LIBRARY_PATH=built/lib DYLD_LIBRARY_PATH=built/lib python -m pytest - name: Set up Python 3.7 @@ -454,7 +454,7 @@ jobs: - name: Test Python 3.7 shell: bash run: | - python -m pip install pytest + python -m pip install -r requirements-test.txt PYTHONPATH=built LD_LIBRARY_PATH=built/lib DYLD_LIBRARY_PATH=built/lib python -m pytest - name: Make installer diff --git a/direct/src/distributed/CRDataCache.py b/direct/src/distributed/CRDataCache.py index 43c87a015b..e6806cf9c3 100755 --- a/direct/src/distributed/CRDataCache.py +++ b/direct/src/distributed/CRDataCache.py @@ -76,41 +76,3 @@ if __debug__: def flush(self): CachedDOData.flush(self) self._flushed = True - - dc = CRDataCache() - dc._startMemLeakCheck() - - cd = CachedDOData() - cd.foo = 34 - dc.setCachedData(1, 'testCachedData', cd) - del cd - cd = CachedDOData() - cd.bar = 45 - dc.setCachedData(1, 'testCachedData2', cd) - del cd - assert dc.hasCachedData(1) - assert dc.hasCachedData(1) - assert not dc.hasCachedData(2) - # data is dict of dataName->data - data = dc.popCachedData(1) - assert len(data) == 2 - assert 'testCachedData' in data - assert 'testCachedData2' in data - assert data['testCachedData'].foo == 34 - assert data['testCachedData2'].bar == 45 - for cd in data.values(): - cd.flush() - del data - dc._checkMemLeaks() - - cd = CachedDOData() - cd.bar = 1234 - dc.setCachedData(43, 'testCachedData2', cd) - del cd - assert dc.hasCachedData(43) - dc.flush() - dc._checkMemLeaks() - - dc._stopMemLeakCheck() - dc.destroy() - del dc diff --git a/direct/src/fsm/StatePush.py b/direct/src/fsm/StatePush.py index 5c93aebd8e..21bed7e299 100755 --- a/direct/src/fsm/StatePush.py +++ b/direct/src/fsm/StatePush.py @@ -46,11 +46,6 @@ class PushesStateChanges: for subscriber in self._subscribers: subscriber._recvStatePush(self) -if __debug__: - psc = PushesStateChanges(0) - assert psc.getState() == 0 - psc.destroy() - del psc class ReceivesStateChanges: # base class for objects that subscribe to state changes from PushesStateChanges objects @@ -83,10 +78,6 @@ class ReceivesStateChanges: def _recvStatePush(self, source): pass -if __debug__: - rsc = ReceivesStateChanges(None) - rsc.destroy() - del rsc class StateVar(PushesStateChanges): # coder-friendly object that allows values to be set on it and pushes those values @@ -97,13 +88,6 @@ class StateVar(PushesStateChanges): def get(self): return PushesStateChanges.getState(self) -if __debug__: - sv = StateVar(0) - assert sv.get() == 0 - sv.set(1) - assert sv.get() == 1 - sv.destroy() - del sv class StateChangeNode(PushesStateChanges, ReceivesStateChanges): # base class that can be used to create a state-change notification chain @@ -120,31 +104,6 @@ class StateChangeNode(PushesStateChanges, ReceivesStateChanges): # got a state push, apply new state to self self._handlePotentialStateChange(source._value) -if __debug__: - sv = StateVar(0) - assert sv.get() == 0 - scn = StateChangeNode(sv) - assert scn.getState() == 0 - sv.set(1) - assert sv.get() == 1 - assert scn.getState() == 1 - scn2 = StateChangeNode(scn) - assert scn2.getState() == 1 - sv.set(2) - assert scn2.getState() == 2 - scn3 = StateChangeNode(scn) - assert scn3.getState() == 2 - sv.set(3) - assert scn2.getState() == 3 - assert scn3.getState() == 3 - scn3.destroy() - scn2.destroy() - scn.destroy() - sv.destroy() - del scn3 - del scn2 - del scn - del sv class ReceivesMultipleStateChanges: # base class for objects that subscribe to state changes from multiple PushesStateChanges @@ -179,15 +138,6 @@ class ReceivesMultipleStateChanges: def _recvMultiStatePush(self, key, source): pass -if __debug__: - rsc = ReceivesMultipleStateChanges() - sv = StateVar(0) - sv2 = StateVar('b') - rsc._subscribeTo(sv, 'a') - rsc._subscribeTo(sv2, 2) - rsc._unsubscribe('a') - rsc.destroy() - del rsc class FunctionCall(ReceivesMultipleStateChanges, PushesStateChanges): # calls func with provided args whenever arguments' state changes @@ -249,47 +199,6 @@ class FunctionCall(ReceivesMultipleStateChanges, PushesStateChanges): self._func(*self._bakedArgs, **self._bakedKargs) PushesStateChanges._handleStateChange(self) -if __debug__: - l = [] - def handler1(value, l=l): - l.append(value) - assert not l - sv = StateVar(0) - fc = FunctionCall(handler1, sv) - assert not l - fc.pushCurrentState() - assert l == [0,] - sv.set(1) - assert l == [0,1,] - sv.set(2) - assert l == [0,1,2,] - fc.destroy() - sv.destroy() - del fc - del sv - del handler1 - del l - - l = [] - def handler2(value, kDummy=None, kValue=None, l=l): - l.append((value, kValue)) - assert not l - sv = StateVar(0) - ksv = StateVar('a') - fc = FunctionCall(handler2, sv, kValue=ksv) - assert not l - fc.pushCurrentState() - assert l == [(0,'a',),] - sv.set(1) - assert l == [(0,'a'),(1,'a'),] - ksv.set('b') - assert l == [(0,'a'),(1,'a'),(1,'b'),] - fc.destroy() - sv.destroy() - del fc - del sv - del handler2 - del l class EnterExit(StateChangeNode): # call enterFunc when our state becomes true, exitFunc when it becomes false @@ -314,33 +223,6 @@ class EnterExit(StateChangeNode): self._exitFunc() StateChangeNode._handleStateChange(self) -if __debug__: - l = [] - def enter(l=l): - l.append(1) - def exit(l=l): - l.append(0) - sv = StateVar(0) - ee = EnterExit(sv, enter, exit) - sv.set(0) - assert not l - sv.set(1) - assert l == [1,] - sv.set(2) - assert l == [1,] - sv.set(0) - assert l == [1,0,] - sv.set(True) - assert l == [1,0,1,] - sv.set(False) - assert l == [1,0,1,0,] - ee.destroy() - sv.destroy() - del ee - del sv - del enter - del exit - del l class Pulse(PushesStateChanges): # changes state to True then immediately to False whenever sendPulse is called @@ -351,25 +233,6 @@ class Pulse(PushesStateChanges): self._handlePotentialStateChange(True) self._handlePotentialStateChange(False) -if __debug__: - l = [] - def handler(value, l=l): - l.append(value) - p = Pulse() - fc = FunctionCall(handler, p) - assert not l - fc.pushCurrentState() - assert l == [False, ] - p.sendPulse() - assert l == [False, True, False, ] - p.sendPulse() - assert l == [False, True, False, True, False, ] - fc.destroy() - p.destroy() - del fc - del p - del l - del handler class EventPulse(Pulse, DirectObject): # sends a True-False "pulse" whenever a specific messenger message is sent @@ -381,6 +244,7 @@ class EventPulse(Pulse, DirectObject): self.ignoreAll() Pulse.destroy(self) + class EventArgument(PushesStateChanges, DirectObject): # tracks a particular argument to a particular messenger event def __init__(self, event, index=0): @@ -396,6 +260,7 @@ class EventArgument(PushesStateChanges, DirectObject): def _handleEvent(self, *args): self._handlePotentialStateChange(args[self._index]) + class AttrSetter(StateChangeNode): def __init__(self, source, object, attrName): self._object = object @@ -406,19 +271,3 @@ class AttrSetter(StateChangeNode): def _handleStateChange(self): setattr(self._object, self._attrName, self._value) StateChangeNode._handleStateChange(self) - -if __debug__: - from direct.showbase.PythonUtil import ScratchPad - o = ScratchPad() - svar = StateVar(0) - aset = AttrSetter(svar, o, 'testAttr') - assert hasattr(o, 'testAttr') - assert o.testAttr == 0 - svar.set('red') - assert o.testAttr == 'red' - aset.destroy() - svar.destroy() - o.destroy() - del aset - del svar - del o diff --git a/direct/src/physics/__init__.py b/direct/src/physics/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/direct/src/showbase/CountedResource.py b/direct/src/showbase/CountedResource.py index a1463470e8..45b76ad31c 100755 --- a/direct/src/showbase/CountedResource.py +++ b/direct/src/showbase/CountedResource.py @@ -81,147 +81,3 @@ class CountedResource(object): def __del__(self): self.decrementCounter() - - -if __debug__ and __name__ == '__main__': - class MouseResource(CountedResource): - """ - A simple class to demonstrate the acquisition of a resource. - """ - @classmethod - def acquire(cls): - # The call to the super-class's acquire() is - # not necessary at the moment, but may be in - # the future, so do it now for good measure. - super(MouseResource, cls).acquire() - - # Now acquire the resource this class is - # managing. - print('-- Acquire Mouse') - - @classmethod - def release(cls): - # First, release the resource this class is - # managing. - print('-- Release Mouse') - - # The call to the super-class's release() is - # not necessary at the moment, but may be in - # the future, so do it now for good measure. - super(MouseResource, cls).release() - - - def __init__(self): - super(MouseResource, self).__init__() - - def __del__(self): - super(MouseResource, self).__del__() - - class CursorResource(CountedResource): - """ - A class to demonstrate how to implement a dependent - resource. Notice how this class also inherits from - CountedResource. Instead of subclassing MouseCounter, - we will just acquire it in our __init__() and release - it in our __del__(). - """ - @classmethod - def acquire(cls): - super(CursorResource, cls).acquire() - print('-- Acquire Cursor') - - @classmethod - def release(cls): - print('-- Release Cursor') - - super(CursorResource, cls).release() - - def __init__(self): - # The required resource references should - # be stored on 'self' since we want to - # release it when the object is deleted. - self.__mouseResource = MouseResource() - - # Call the super-classes __init__() - # after all required resources are - # referenced. - super(CursorResource, self).__init__() - - def __del__(self): - # Free up the most dependent resource - # first, the one this class is managing. - super(CursorResource, self).__del__() - - # Now unlink any required resources. - del self.__mouseResource - - class InvalidResource(MouseResource): - @classmethod - def acquire(cls): - super(InvalidResource, cls).acquire() - print('-- Acquire Invalid') - - @classmethod - def release(cls): - print('-- Release Invalid') - super(InvalidResource, cls).release() - - print('\nAllocate Mouse') - m = MouseResource() - print('Free up Mouse') - del m - - print('\nAllocate Cursor') - c = CursorResource() - print('Free up Cursor') - del c - - print('\nAllocate Mouse then Cursor') - m = MouseResource() - c = CursorResource() - print('Free up Cursor') - del c - print('Free up Mouse') - del m - - print('\nAllocate Mouse then Cursor') - m = MouseResource() - c = CursorResource() - print('Free up Mouse') - del m - print('Free up Cursor') - del c - - print('\nAllocate Cursor then Mouse') - c = CursorResource() - m = MouseResource() - print('Free up Mouse') - del m - print('Free up Cursor') - del c - - print('\nAllocate Cursor then Mouse') - c = CursorResource() - m = MouseResource() - print('Free up Cursor') - del c - - # example of an invalid subclass - try: - print('\nAllocate Invalid') - i = InvalidResource() - print('Free up Invalid') - except AssertionError as e: - print(e) - print('') - - print('Free up Mouse') - del m - - def demoFunc(): - print('\nAllocate Cursor within function') - c = CursorResource() - - print('Cursor will be freed on function exit') - - demoFunc() diff --git a/direct/src/showbase/DistancePhasedNode.py b/direct/src/showbase/DistancePhasedNode.py index 8ca2b3c12c..0f0a426e99 100755 --- a/direct/src/showbase/DistancePhasedNode.py +++ b/direct/src/showbase/DistancePhasedNode.py @@ -327,31 +327,3 @@ class BufferedDistancePhasedNode(DistancePhasedNode): for x,sphere in enumerate(self._colSpheres[phase+1:]): sphere.node().modifySolid(0).setRadius(self.bufferParamList[x+phase+1][1][0]) sphere.node().markInternalBoundsStale() - - -if __debug__ and 0: - cSphere = CollisionSphere(0, 0, 0, 0.1) - cNode = CollisionNode('camCol') - cNode.addSolid(cSphere) - cNodePath = NodePath(cNode) - cNodePath.reparentTo(base.cam) - # cNodePath.show() - # cNodePath.setPos(25,0,0) - - base.cTrav = CollisionTraverser() - - eventHandler = CollisionHandlerEvent() - eventHandler.addInPattern('enter%in') - eventHandler.addOutPattern('exit%in') - - # messenger.toggleVerbose() - base.cTrav.addCollider(cNodePath, eventHandler) - - p = BufferedDistancePhasedNode('p', {'At': (10, 20), 'Near': (100, 200), 'Far': (1000, 1020)}, - autoCleanup=False, - fromCollideNode=cNodePath, - ) - - p.reparentTo(render) - p._DistancePhasedNode__oneTimeCollide() - base.eventMgr.doEvents() diff --git a/direct/src/showbase/PythonUtil.py b/direct/src/showbase/PythonUtil.py index 370a67d408..7ca1b36fe1 100644 --- a/direct/src/showbase/PythonUtil.py +++ b/direct/src/showbase/PythonUtil.py @@ -2458,18 +2458,6 @@ def formatTimeCompact(seconds): return result -if __debug__ and __name__ == '__main__': - ftc = formatTimeCompact - assert ftc(0) == '0s' - assert ftc(1) == '1s' - assert ftc(60) == '1m0s' - assert ftc(64) == '1m4s' - assert ftc(60*60) == '1h0m0s' - assert ftc(24*60*60) == '1d0h0m0s' - assert ftc(24*60*60 + 2*60*60 + 34*60 + 12) == '1d2h34m12s' - del ftc - - def formatTimeExact(seconds): # like formatTimeCompact but leaves off '0 seconds', '0 minutes' etc. for # times that are e.g. 1 hour, 3 days etc. @@ -2496,19 +2484,6 @@ def formatTimeExact(seconds): return result -if __debug__ and __name__ == '__main__': - fte = formatTimeExact - assert fte(0) == '0s' - assert fte(1) == '1s' - assert fte(2) == '2s' - assert fte(61) == '1m1s' - assert fte(60) == '1m' - assert fte(60*60) == '1h' - assert fte(24*60*60) == '1d' - assert fte((24*60*60) + (2 * 60)) == '1d0h2m' - del fte - - class AlphabetCounter: # object that produces 'A', 'B', 'C', ... 'AA', 'AB', etc. def __init__(self): @@ -2540,28 +2515,6 @@ class AlphabetCounter: __next__ = next -if __debug__ and __name__ == '__main__': - def testAlphabetCounter(): - tempList = [] - ac = AlphabetCounter() - for i in range(26*3): - tempList.append(ac.next()) - assert tempList == [ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', - 'AA','AB','AC','AD','AE','AF','AG','AH','AI','AJ','AK','AL','AM','AN','AO','AP','AQ','AR','AS','AT','AU','AV','AW','AX','AY','AZ', - 'BA','BB','BC','BD','BE','BF','BG','BH','BI','BJ','BK','BL','BM','BN','BO','BP','BQ','BR','BS','BT','BU','BV','BW','BX','BY','BZ',] - ac = AlphabetCounter() - num = 26 # A-Z - num += (26*26) # AA-ZZ - num += 26 # AAZ - num += 1 # ABA - num += 2 # ABC - for i in range(num): - x = ac.next() - assert x == 'ABC' - testAlphabetCounter() - del testAlphabetCounter - - class Default: # represents 'use the default value' # useful for keyword arguments to virtual methods diff --git a/direct/src/stdpy/threading.py b/direct/src/stdpy/threading.py index 97cdf387f0..96effd86b5 100644 --- a/direct/src/stdpy/threading.py +++ b/direct/src/stdpy/threading.py @@ -435,108 +435,3 @@ def setprofile(func): def stack_size(size = None): raise ThreadError - - -if __debug__: - def _test(): - from collections import deque - - _sleep = core.Thread.sleep - - _VERBOSE = False - - class _Verbose(object): - - def __init__(self, verbose=None): - if verbose is None: - verbose = _VERBOSE - self.__verbose = verbose - - def _note(self, format, *args): - if self.__verbose: - format = format % args - format = "%s: %s\n" % ( - currentThread().getName(), format) - _sys.stderr.write(format) - - class BoundedQueue(_Verbose): - - def __init__(self, limit): - _Verbose.__init__(self) - self.mon = Lock(name = "BoundedQueue.mon") - self.rc = Condition(self.mon) - self.wc = Condition(self.mon) - self.limit = limit - self.queue = deque() - - def put(self, item): - self.mon.acquire() - while len(self.queue) >= self.limit: - self._note("put(%s): queue full", item) - self.wc.wait() - self.queue.append(item) - self._note("put(%s): appended, length now %d", - item, len(self.queue)) - self.rc.notify() - self.mon.release() - - def get(self): - self.mon.acquire() - while not self.queue: - self._note("get(): queue empty") - self.rc.wait() - item = self.queue.popleft() - self._note("get(): got %s, %d left", item, len(self.queue)) - self.wc.notify() - self.mon.release() - return item - - class ProducerThread(Thread): - - def __init__(self, queue, quota): - Thread.__init__(self, name="Producer") - self.queue = queue - self.quota = quota - - def run(self): - from random import random - counter = 0 - while counter < self.quota: - counter = counter + 1 - self.queue.put("%s.%d" % (self.getName(), counter)) - _sleep(random() * 0.00001) - - class ConsumerThread(Thread): - - def __init__(self, queue, count): - Thread.__init__(self, name="Consumer") - self.queue = queue - self.count = count - - def run(self): - while self.count > 0: - item = self.queue.get() - print(item) - self.count = self.count - 1 - - NP = 3 - QL = 4 - NI = 5 - - Q = BoundedQueue(QL) - P = [] - for i in range(NP): - t = ProducerThread(Q, NI) - t.setName("Producer-%d" % (i+1)) - P.append(t) - C = ConsumerThread(Q, NI*NP) - for t in P: - t.start() - _sleep(0.000001) - C.start() - for t in P: - t.join() - C.join() - - if __name__ == '__main__': - _test() diff --git a/direct/src/stdpy/threading2.py b/direct/src/stdpy/threading2.py index 3bc3f22b1e..8bdde3a27c 100644 --- a/direct/src/stdpy/threading2.py +++ b/direct/src/stdpy/threading2.py @@ -762,92 +762,3 @@ def main_thread(): ## from thread import _local as local ## except ImportError: ## from _threading_local import local - - -# Self-test code -if __debug__: - def _test(): - from collections import deque - - class BoundedQueue(_Verbose): - - def __init__(self, limit): - _Verbose.__init__(self) - self.mon = RLock() - self.rc = Condition(self.mon) - self.wc = Condition(self.mon) - self.limit = limit - self.queue = deque() - - def put(self, item): - self.mon.acquire() - while len(self.queue) >= self.limit: - self._note("put(%s): queue full", item) - self.wc.wait() - self.queue.append(item) - self._note("put(%s): appended, length now %d", - item, len(self.queue)) - self.rc.notify() - self.mon.release() - - def get(self): - self.mon.acquire() - while not self.queue: - self._note("get(): queue empty") - self.rc.wait() - item = self.queue.popleft() - self._note("get(): got %s, %d left", item, len(self.queue)) - self.wc.notify() - self.mon.release() - return item - - class ProducerThread(Thread): - - def __init__(self, queue, quota): - Thread.__init__(self, name="Producer") - self.queue = queue - self.quota = quota - - def run(self): - from random import random - counter = 0 - while counter < self.quota: - counter = counter + 1 - self.queue.put("%s.%d" % (self.getName(), counter)) - _sleep(random() * 0.00001) - - - class ConsumerThread(Thread): - - def __init__(self, queue, count): - Thread.__init__(self, name="Consumer") - self.queue = queue - self.count = count - - def run(self): - while self.count > 0: - item = self.queue.get() - print(item) - self.count = self.count - 1 - - NP = 3 - QL = 4 - NI = 5 - - Q = BoundedQueue(QL) - P = [] - for i in range(NP): - t = ProducerThread(Q, NI) - t.setName("Producer-%d" % (i+1)) - P.append(t) - C = ConsumerThread(Q, NI*NP) - for t in P: - t.start() - _sleep(0.000001) - C.start() - for t in P: - t.join() - C.join() - - if __name__ == '__main__': - _test() diff --git a/direct/src/task/Task.py b/direct/src/task/Task.py index 24358b3573..470eb73cdf 100644 --- a/direct/src/task/Task.py +++ b/direct/src/task/Task.py @@ -801,532 +801,6 @@ class TaskManager: # time.sleep(delta) # delta = minFinTime - self.globalClock.getRealTime() - if __debug__: - # to catch memory leaks during the tests at the bottom of the file - def _startTrackingMemLeaks(self): - pass - - def _stopTrackingMemLeaks(self): - pass - - def _checkMemLeaks(self): - pass - - def _runTests(self): - if __debug__: - tm = TaskManager() - tm.setClock(ClockObject()) - tm.setupTaskChain("default", tickClock = True) - - # check for memory leaks after every test - tm._startTrackingMemLeaks() - tm._checkMemLeaks() - - # run-once task - l = [] - - def _testDone(task, l=l): - l.append(None) - return task.done - tm.add(_testDone, 'testDone') - tm.step() - assert len(l) == 1 - tm.step() - assert len(l) == 1 - _testDone = None - tm._checkMemLeaks() - - # remove by name - def _testRemoveByName(task): - return task.done - tm.add(_testRemoveByName, 'testRemoveByName') - assert tm.remove('testRemoveByName') == 1 - assert tm.remove('testRemoveByName') == 0 - _testRemoveByName = None - tm._checkMemLeaks() - - # duplicate named tasks - def _testDupNamedTasks(task): - return task.done - tm.add(_testDupNamedTasks, 'testDupNamedTasks') - tm.add(_testDupNamedTasks, 'testDupNamedTasks') - assert tm.remove('testRemoveByName') == 0 - _testDupNamedTasks = None - tm._checkMemLeaks() - - # continued task - l = [] - - def _testCont(task, l = l): - l.append(None) - return task.cont - tm.add(_testCont, 'testCont') - tm.step() - assert len(l) == 1 - tm.step() - assert len(l) == 2 - tm.remove('testCont') - _testCont = None - tm._checkMemLeaks() - - # continue until done task - l = [] - - def _testContDone(task, l = l): - l.append(None) - if len(l) >= 2: - return task.done - else: - return task.cont - tm.add(_testContDone, 'testContDone') - tm.step() - assert len(l) == 1 - tm.step() - assert len(l) == 2 - tm.step() - assert len(l) == 2 - assert not tm.hasTaskNamed('testContDone') - _testContDone = None - tm._checkMemLeaks() - - # hasTaskNamed - def _testHasTaskNamed(task): - return task.done - tm.add(_testHasTaskNamed, 'testHasTaskNamed') - assert tm.hasTaskNamed('testHasTaskNamed') - tm.step() - assert not tm.hasTaskNamed('testHasTaskNamed') - _testHasTaskNamed = None - tm._checkMemLeaks() - - # task sort - l = [] - - def _testPri1(task, l = l): - l.append(1) - return task.cont - - def _testPri2(task, l = l): - l.append(2) - return task.cont - tm.add(_testPri1, 'testPri1', sort = 1) - tm.add(_testPri2, 'testPri2', sort = 2) - tm.step() - assert len(l) == 2 - assert l == [1, 2,] - tm.step() - assert len(l) == 4 - assert l == [1, 2, 1, 2,] - tm.remove('testPri1') - tm.remove('testPri2') - _testPri1 = None - _testPri2 = None - tm._checkMemLeaks() - - # task extraArgs - l = [] - - def _testExtraArgs(arg1, arg2, l=l): - l.extend([arg1, arg2,]) - return done - tm.add(_testExtraArgs, 'testExtraArgs', extraArgs=[4,5]) - tm.step() - assert len(l) == 2 - assert l == [4, 5,] - _testExtraArgs = None - tm._checkMemLeaks() - - # task appendTask - l = [] - - def _testAppendTask(arg1, arg2, task, l=l): - l.extend([arg1, arg2,]) - return task.done - tm.add(_testAppendTask, '_testAppendTask', extraArgs=[4,5], appendTask=True) - tm.step() - assert len(l) == 2 - assert l == [4, 5,] - _testAppendTask = None - tm._checkMemLeaks() - - # task uponDeath - l = [] - - def _uponDeathFunc(task, l=l): - l.append(task.name) - - def _testUponDeath(task): - return done - tm.add(_testUponDeath, 'testUponDeath', uponDeath=_uponDeathFunc) - tm.step() - assert len(l) == 1 - assert l == ['testUponDeath'] - _testUponDeath = None - _uponDeathFunc = None - tm._checkMemLeaks() - - # task owner - class _TaskOwner: - def _addTask(self, task): - self.addedTaskName = task.name - - def _clearTask(self, task): - self.clearedTaskName = task.name - to = _TaskOwner() - l = [] - - def _testOwner(task): - return done - tm.add(_testOwner, 'testOwner', owner=to) - tm.step() - assert getattr(to, 'addedTaskName', None) == 'testOwner' - assert getattr(to, 'clearedTaskName', None) == 'testOwner' - _testOwner = None - del to - _TaskOwner = None - tm._checkMemLeaks() - - doLaterTests = [0,] - - # doLater - l = [] - - def _testDoLater1(task, l=l): - l.append(1) - - def _testDoLater2(task, l=l): - l.append(2) - - def _monitorDoLater(task, tm=tm, l=l, doLaterTests=doLaterTests): - if task.time > .03: - assert l == [1, 2,] - doLaterTests[0] -= 1 - return task.done - return task.cont - tm.doMethodLater(.01, _testDoLater1, 'testDoLater1') - tm.doMethodLater(.02, _testDoLater2, 'testDoLater2') - doLaterTests[0] += 1 - # make sure we run this task after the doLaters if they all occur on the same frame - tm.add(_monitorDoLater, 'monitorDoLater', sort=10) - _testDoLater1 = None - _testDoLater2 = None - _monitorDoLater = None - # don't check until all the doLaters are finished - #tm._checkMemLeaks() - - # doLater sort - l = [] - - def _testDoLaterPri1(task, l=l): - l.append(1) - - def _testDoLaterPri2(task, l=l): - l.append(2) - - def _monitorDoLaterPri(task, tm=tm, l=l, doLaterTests=doLaterTests): - if task.time > .02: - assert l == [1, 2,] - doLaterTests[0] -= 1 - return task.done - return task.cont - tm.doMethodLater(.01, _testDoLaterPri1, 'testDoLaterPri1', sort=1) - tm.doMethodLater(.01, _testDoLaterPri2, 'testDoLaterPri2', sort=2) - doLaterTests[0] += 1 - # make sure we run this task after the doLaters if they all occur on the same frame - tm.add(_monitorDoLaterPri, 'monitorDoLaterPri', sort=10) - _testDoLaterPri1 = None - _testDoLaterPri2 = None - _monitorDoLaterPri = None - # don't check until all the doLaters are finished - #tm._checkMemLeaks() - - # doLater extraArgs - l = [] - - def _testDoLaterExtraArgs(arg1, l=l): - l.append(arg1) - - def _monitorDoLaterExtraArgs(task, tm=tm, l=l, doLaterTests=doLaterTests): - if task.time > .02: - assert l == [3,] - doLaterTests[0] -= 1 - return task.done - return task.cont - tm.doMethodLater(.01, _testDoLaterExtraArgs, 'testDoLaterExtraArgs', extraArgs=[3,]) - doLaterTests[0] += 1 - # make sure we run this task after the doLaters if they all occur on the same frame - tm.add(_monitorDoLaterExtraArgs, 'monitorDoLaterExtraArgs', sort=10) - _testDoLaterExtraArgs = None - _monitorDoLaterExtraArgs = None - # don't check until all the doLaters are finished - #tm._checkMemLeaks() - - # doLater appendTask - l = [] - - def _testDoLaterAppendTask(arg1, task, l=l): - assert task.name == 'testDoLaterAppendTask' - l.append(arg1) - - def _monitorDoLaterAppendTask(task, tm=tm, l=l, doLaterTests=doLaterTests): - if task.time > .02: - assert l == [4,] - doLaterTests[0] -= 1 - return task.done - return task.cont - tm.doMethodLater(.01, _testDoLaterAppendTask, 'testDoLaterAppendTask', - extraArgs=[4,], appendTask=True) - doLaterTests[0] += 1 - # make sure we run this task after the doLaters if they all occur on the same frame - tm.add(_monitorDoLaterAppendTask, 'monitorDoLaterAppendTask', sort=10) - _testDoLaterAppendTask = None - _monitorDoLaterAppendTask = None - # don't check until all the doLaters are finished - #tm._checkMemLeaks() - - # doLater uponDeath - l = [] - - def _testUponDeathFunc(task, l=l): - assert task.name == 'testDoLaterUponDeath' - l.append(10) - - def _testDoLaterUponDeath(arg1, l=l): - return done - - def _monitorDoLaterUponDeath(task, tm=tm, l=l, doLaterTests=doLaterTests): - if task.time > .02: - assert l == [10,] - doLaterTests[0] -= 1 - return task.done - return task.cont - tm.doMethodLater(.01, _testDoLaterUponDeath, 'testDoLaterUponDeath', - uponDeath=_testUponDeathFunc) - doLaterTests[0] += 1 - # make sure we run this task after the doLaters if they all occur on the same frame - tm.add(_monitorDoLaterUponDeath, 'monitorDoLaterUponDeath', sort=10) - _testUponDeathFunc = None - _testDoLaterUponDeath = None - _monitorDoLaterUponDeath = None - # don't check until all the doLaters are finished - #tm._checkMemLeaks() - - # doLater owner - class _DoLaterOwner: - def _addTask(self, task): - self.addedTaskName = task.name - - def _clearTask(self, task): - self.clearedTaskName = task.name - doLaterOwner = _DoLaterOwner() - l = [] - - def _testDoLaterOwner(l=l): - pass - - def _monitorDoLaterOwner(task, tm=tm, l=l, doLaterOwner=doLaterOwner, - doLaterTests=doLaterTests): - if task.time > .02: - assert getattr(doLaterOwner, 'addedTaskName', None) == 'testDoLaterOwner' - assert getattr(doLaterOwner, 'clearedTaskName', None) == 'testDoLaterOwner' - doLaterTests[0] -= 1 - return task.done - return task.cont - tm.doMethodLater(.01, _testDoLaterOwner, 'testDoLaterOwner', - owner=doLaterOwner) - doLaterTests[0] += 1 - # make sure we run this task after the doLaters if they all occur on the same frame - tm.add(_monitorDoLaterOwner, 'monitorDoLaterOwner', sort=10) - _testDoLaterOwner = None - _monitorDoLaterOwner = None - del doLaterOwner - _DoLaterOwner = None - # don't check until all the doLaters are finished - #tm._checkMemLeaks() - - # run the doLater tests - while doLaterTests[0] > 0: - tm.step() - del doLaterTests - tm._checkMemLeaks() - - # getTasks - def _testGetTasks(task): - return task.cont - # No doLaterProcessor in the new world. - assert len(tm.getTasks()) == 0 - tm.add(_testGetTasks, 'testGetTasks1') - assert len(tm.getTasks()) == 1 - assert (tm.getTasks()[0].name == 'testGetTasks1' or - tm.getTasks()[1].name == 'testGetTasks1') - tm.add(_testGetTasks, 'testGetTasks2') - tm.add(_testGetTasks, 'testGetTasks3') - assert len(tm.getTasks()) == 3 - tm.remove('testGetTasks2') - assert len(tm.getTasks()) == 2 - tm.remove('testGetTasks1') - tm.remove('testGetTasks3') - assert len(tm.getTasks()) == 0 - _testGetTasks = None - tm._checkMemLeaks() - - # getDoLaters - def _testGetDoLaters(): - pass - assert len(tm.getDoLaters()) == 0 - tm.doMethodLater(.1, _testGetDoLaters, 'testDoLater1') - assert len(tm.getDoLaters()) == 1 - assert tm.getDoLaters()[0].name == 'testDoLater1' - tm.doMethodLater(.1, _testGetDoLaters, 'testDoLater2') - tm.doMethodLater(.1, _testGetDoLaters, 'testDoLater3') - assert len(tm.getDoLaters()) == 3 - tm.remove('testDoLater2') - assert len(tm.getDoLaters()) == 2 - tm.remove('testDoLater1') - tm.remove('testDoLater3') - assert len(tm.getDoLaters()) == 0 - _testGetDoLaters = None - tm._checkMemLeaks() - - # duplicate named doLaters removed via taskMgr.remove - def _testDupNameDoLaters(): - pass - # the doLaterProcessor is always running - tm.doMethodLater(.1, _testDupNameDoLaters, 'testDupNameDoLater') - tm.doMethodLater(.1, _testDupNameDoLaters, 'testDupNameDoLater') - assert len(tm.getDoLaters()) == 2 - tm.remove('testDupNameDoLater') - assert len(tm.getDoLaters()) == 0 - _testDupNameDoLaters = None - tm._checkMemLeaks() - - # duplicate named doLaters removed via remove() - def _testDupNameDoLatersRemove(): - pass - # the doLaterProcessor is always running - dl1 = tm.doMethodLater(.1, _testDupNameDoLatersRemove, 'testDupNameDoLaterRemove') - dl2 = tm.doMethodLater(.1, _testDupNameDoLatersRemove, 'testDupNameDoLaterRemove') - assert len(tm.getDoLaters()) == 2 - dl2.remove() - assert len(tm.getDoLaters()) == 1 - dl1.remove() - assert len(tm.getDoLaters()) == 0 - _testDupNameDoLatersRemove = None - # nameDict etc. isn't cleared out right away with task.remove() - tm._checkMemLeaks() - - # getTasksNamed - def _testGetTasksNamed(task): - return task.cont - assert len(tm.getTasksNamed('testGetTasksNamed')) == 0 - tm.add(_testGetTasksNamed, 'testGetTasksNamed') - assert len(tm.getTasksNamed('testGetTasksNamed')) == 1 - assert tm.getTasksNamed('testGetTasksNamed')[0].name == 'testGetTasksNamed' - tm.add(_testGetTasksNamed, 'testGetTasksNamed') - tm.add(_testGetTasksNamed, 'testGetTasksNamed') - assert len(tm.getTasksNamed('testGetTasksNamed')) == 3 - tm.remove('testGetTasksNamed') - assert len(tm.getTasksNamed('testGetTasksNamed')) == 0 - _testGetTasksNamed = None - tm._checkMemLeaks() - - # removeTasksMatching - def _testRemoveTasksMatching(task): - return task.cont - tm.add(_testRemoveTasksMatching, 'testRemoveTasksMatching') - assert len(tm.getTasksNamed('testRemoveTasksMatching')) == 1 - tm.removeTasksMatching('testRemoveTasksMatching') - assert len(tm.getTasksNamed('testRemoveTasksMatching')) == 0 - tm.add(_testRemoveTasksMatching, 'testRemoveTasksMatching1') - tm.add(_testRemoveTasksMatching, 'testRemoveTasksMatching2') - assert len(tm.getTasksNamed('testRemoveTasksMatching1')) == 1 - assert len(tm.getTasksNamed('testRemoveTasksMatching2')) == 1 - tm.removeTasksMatching('testRemoveTasksMatching*') - assert len(tm.getTasksNamed('testRemoveTasksMatching1')) == 0 - assert len(tm.getTasksNamed('testRemoveTasksMatching2')) == 0 - tm.add(_testRemoveTasksMatching, 'testRemoveTasksMatching1a') - tm.add(_testRemoveTasksMatching, 'testRemoveTasksMatching2a') - assert len(tm.getTasksNamed('testRemoveTasksMatching1a')) == 1 - assert len(tm.getTasksNamed('testRemoveTasksMatching2a')) == 1 - tm.removeTasksMatching('testRemoveTasksMatching?a') - assert len(tm.getTasksNamed('testRemoveTasksMatching1a')) == 0 - assert len(tm.getTasksNamed('testRemoveTasksMatching2a')) == 0 - _testRemoveTasksMatching = None - tm._checkMemLeaks() - - # create Task object and add to mgr - l = [] - - def _testTaskObj(task, l=l): - l.append(None) - return task.cont - t = Task(_testTaskObj) - tm.add(t, 'testTaskObj') - tm.step() - assert len(l) == 1 - tm.step() - assert len(l) == 2 - tm.remove('testTaskObj') - tm.step() - assert len(l) == 2 - _testTaskObj = None - tm._checkMemLeaks() - - # remove Task via task.remove() - l = [] - - def _testTaskObjRemove(task, l=l): - l.append(None) - return task.cont - t = Task(_testTaskObjRemove) - tm.add(t, 'testTaskObjRemove') - tm.step() - assert len(l) == 1 - tm.step() - assert len(l) == 2 - t.remove() - tm.step() - assert len(l) == 2 - del t - _testTaskObjRemove = None - tm._checkMemLeaks() - - # this test fails, and it's not clear what the correct behavior should be. - # sort passed to Task.__init__ is always overridden by taskMgr.add() - # even if no sort is specified, and calling Task.setSort() has no - # effect on the taskMgr's behavior. - # set/get Task sort - #l = [] - #def _testTaskObjSort(arg, task, l=l): - # l.append(arg) - # return task.cont - #t1 = Task(_testTaskObjSort, sort=1) - #t2 = Task(_testTaskObjSort, sort=2) - #tm.add(t1, 'testTaskObjSort1', extraArgs=['a',], appendTask=True) - #tm.add(t2, 'testTaskObjSort2', extraArgs=['b',], appendTask=True) - #tm.step() - #assert len(l) == 2 - #assert l == ['a', 'b'] - #assert t1.getSort() == 1 - #assert t2.getSort() == 2 - #t1.setSort(3) - #assert t1.getSort() == 3 - #tm.step() - #assert len(l) == 4 - #assert l == ['a', 'b', 'b', 'a',] - #t1.remove() - #t2.remove() - #tm.step() - #assert len(l) == 4 - #del t1 - #del t2 - #_testTaskObjSort = None - #tm._checkMemLeaks() - - del l - tm.destroy() - del tm - if __debug__: def checkLeak(): diff --git a/direct/src/tkpanels/ParticlePanel.py b/direct/src/tkpanels/ParticlePanel.py index 7408497ac2..6d41ba808f 100644 --- a/direct/src/tkpanels/ParticlePanel.py +++ b/direct/src/tkpanels/ParticlePanel.py @@ -2909,21 +2909,3 @@ class ParticlePanel(AppShell): min = 0.01, value = force.getRadius()) self.createForceActiveWidget(frame, pageName, forceName, force) - -###################################################################### - - -# Create demo in root window for testing. -if __name__ == '__main__': - try: - base - except NameError: - from direct.showbase.ShowBase import ShowBase - base = ShowBase() - - root = Pmw.initialise() - pp = ParticlePanel() - base.pp=pp - #ve = VectorEntry(Toplevel(), relief = GROOVE) - #ve.pack() - base.run() diff --git a/direct/src/tkpanels/Placer.py b/direct/src/tkpanels/Placer.py index addbe1f414..6fdf0767f1 100644 --- a/direct/src/tkpanels/Placer.py +++ b/direct/src/tkpanels/Placer.py @@ -786,11 +786,3 @@ class Placer(AppShell): def place(nodePath): return Placer(nodePath = nodePath) - -###################################################################### - - -# Create demo in root window for testing. -if __name__ == '__main__': - root = Pmw.initialise() - widget = Placer() diff --git a/direct/src/tkwidgets/AppShell.py b/direct/src/tkwidgets/AppShell.py index ad76a7ccae..b5913e958e 100644 --- a/direct/src/tkwidgets/AppShell.py +++ b/direct/src/tkwidgets/AppShell.py @@ -550,7 +550,3 @@ class TestAppShell(AppShell): def createInterface(self): self.createButtons() self.createMain() - - -if __name__ == '__main__': - test = TestAppShell(balloon_state='none') diff --git a/direct/src/tkwidgets/Dial.py b/direct/src/tkwidgets/Dial.py index 2b1c062439..ca2211ea77 100644 --- a/direct/src/tkwidgets/Dial.py +++ b/direct/src/tkwidgets/Dial.py @@ -422,18 +422,3 @@ class DialWidget(Pmw.MegaWidget): """ User redefinable callback executed on button release """ if self['postCallback']: self['postCallback'](*self['callbackData']) - - -if __name__ == '__main__': - tl = tk.Toplevel() - d = Dial(tl) - d2 = Dial(tl, dial_numSegments = 12, max = 360, - dial_fRollover = 0, value = 180) - d3 = Dial(tl, dial_numSegments = 12, max = 90, min = -90, - dial_fRollover = 0) - d4 = Dial(tl, dial_numSegments = 16, max = 256, - dial_fRollover = 0) - d.pack(expand = 1, fill = tk.X) - d2.pack(expand = 1, fill = tk.X) - d3.pack(expand = 1, fill = tk.X) - d4.pack(expand = 1, fill = tk.X) diff --git a/direct/src/tkwidgets/EntryScale.py b/direct/src/tkwidgets/EntryScale.py index cb6516275c..5ae9bf335e 100644 --- a/direct/src/tkwidgets/EntryScale.py +++ b/direct/src/tkwidgets/EntryScale.py @@ -517,45 +517,3 @@ def rgbPanel(nodePath, callback = None): messenger.send('RGBPanel_setColor', [nodePath, r, g, b, a]) esg['postCallback'] = onRelease return esg - - -## SAMPLE CODE -if __name__ == '__main__': - # Initialise Tkinter and Pmw. - root = tk.Toplevel() - root.title('Pmw EntryScale demonstration') - - # Dummy command - def printVal(val): - print(val) - - # Create and pack a EntryScale megawidget. - mega1 = EntryScale(root, command = printVal) - mega1.pack(side = 'left', expand = 1, fill = 'x') - - # These are things you can set/configure - # Starting value for entryScale - #mega1['value'] = 123.456 - #mega1['text'] = 'Drive delta X' - #mega1['min'] = 0.0 - #mega1['max'] = 1000.0 - #mega1['resolution'] = 1.0 - # To change the color of the label: - #mega1.label['foreground'] = 'Red' - # Max change/update, default is 100 - # To have really fine control, for example - # mega1['maxVelocity'] = 0.1 - # Number of digits to the right of the decimal point, default = 2 - # mega1['numDigits'] = 5 - - # To create a entryScale group to set an RGBA value: - group1 = EntryScaleGroup(root, dim = 4, - title = 'Simple RGBA Panel', - labels = ('R', 'G', 'B', 'A'), - Valuator_min = 0.0, - Valuator_max = 255.0, - Valuator_resolution = 1.0, - command = printVal) - - # Uncomment this if you aren't running in IDLE - #root.mainloop() diff --git a/direct/src/tkwidgets/Floater.py b/direct/src/tkwidgets/Floater.py index 6544eb3890..432070f6ec 100644 --- a/direct/src/tkwidgets/Floater.py +++ b/direct/src/tkwidgets/Floater.py @@ -329,42 +329,3 @@ class FloaterGroup(Pmw.MegaToplevel): def reset(self): self.set(self['value']) - - -## SAMPLE CODE -if __name__ == '__main__': - # Initialise Tkinter and Pmw. - root = tk.Toplevel() - root.title('Pmw Floater demonstration') - - # Dummy command - def printVal(val): - print(val) - - # Create and pack a Floater megawidget. - mega1 = Floater(root, command = printVal) - mega1.pack(side = 'left', expand = 1, fill = 'x') - - # These are things you can set/configure - # Starting value for floater - #mega1['value'] = 123.456 - #mega1['text'] = 'Drive delta X' - # To change the color of the label: - #mega1.label['foreground'] = 'Red' - # Max change/update, default is 100 - # To have really fine control, for example - #mega1['maxVelocity'] = 0.1 - # Number of digits to the right of the decimal point, default = 2 - #mega1['numDigits'] = 5 - - # To create a floater group to set an RGBA value: - group1 = FloaterGroup(root, dim = 4, - title = 'Simple RGBA Panel', - labels = ('R', 'G', 'B', 'A'), - Valuator_min = 0.0, - Valuator_max = 255.0, - Valuator_resolution = 1.0, - command = printVal) - - # Uncomment this if you aren't running in IDLE - #root.mainloop() diff --git a/direct/src/tkwidgets/VectorWidgets.py b/direct/src/tkwidgets/VectorWidgets.py index 6797782f71..e9abf8f63d 100644 --- a/direct/src/tkwidgets/VectorWidgets.py +++ b/direct/src/tkwidgets/VectorWidgets.py @@ -329,17 +329,3 @@ class ColorEntry(VectorEntry): initialcolor = tuple(self.get()[:3]))[0] if color: self.set((color[0], color[1], color[2], self.getAt(3))) - - -if __name__ == '__main__': - root = tk.Toplevel() - root.title('Vector Widget demo') - - ve = VectorEntry(root) - ve.pack() - v3e = Vector3Entry(root) - v3e.pack() - v4e = Vector4Entry(root) - v4e.pack() - ce = ColorEntry(root) - ce.pack() diff --git a/requirements-test.txt b/requirements-test.txt new file mode 100644 index 0000000000..bf6a71e61c --- /dev/null +++ b/requirements-test.txt @@ -0,0 +1,4 @@ +pytest +pytest-cov + +Pmw-py3==2.1 diff --git a/tests/display/conftest.py b/tests/conftest.py similarity index 77% rename from tests/display/conftest.py rename to tests/conftest.py index 36d498b9a3..9c2a01c6ca 100644 --- a/tests/display/conftest.py +++ b/tests/conftest.py @@ -1,4 +1,27 @@ +import sys +import tkinter as tk import pytest +from panda3d import core +from direct.showbase.ShowBase import ShowBase + + +@pytest.fixture +def base(): + base = ShowBase(windowType='none') + yield base + base.destroy() + + +@pytest.fixture +def tk_toplevel(): + if sys.platform == 'darwin' and not core.ConfigVariableBool('want-tk', False): + pytest.skip('"want-tk" must be true to use tkinter with Panda3D on macOS') + try: + root = tk.Toplevel() + except tk.TclError as e: + pytest.skip(str(e)) + yield root + root.destroy() @pytest.fixture(scope='session') diff --git a/tests/distributed/test_CRDataCache.py b/tests/distributed/test_CRDataCache.py new file mode 100644 index 0000000000..1ba4928487 --- /dev/null +++ b/tests/distributed/test_CRDataCache.py @@ -0,0 +1,42 @@ +from direct.distributed.CachedDOData import CachedDOData +from direct.distributed.CRDataCache import CRDataCache + + +def test_CRDataCache(): + dc = CRDataCache() + dc._startMemLeakCheck() + + cd = CachedDOData() + cd.foo = 34 + dc.setCachedData(1, 'testCachedData', cd) + del cd + cd = CachedDOData() + cd.bar = 45 + dc.setCachedData(1, 'testCachedData2', cd) + del cd + assert dc.hasCachedData(1) + assert dc.hasCachedData(1) + assert not dc.hasCachedData(2) + # data is dict of dataName->data + data = dc.popCachedData(1) + assert len(data) == 2 + assert 'testCachedData' in data + assert 'testCachedData2' in data + assert data['testCachedData'].foo == 34 + assert data['testCachedData2'].bar == 45 + for cd in data.values(): + cd.flush() + del data + dc._checkMemLeaks() + + cd = CachedDOData() + cd.bar = 1234 + dc.setCachedData(43, 'testCachedData2', cd) + del cd + assert dc.hasCachedData(43) + dc.flush() + dc._checkMemLeaks() + + dc._stopMemLeakCheck() + dc.destroy() + del dc diff --git a/tests/fsm/test_StatePush.py b/tests/fsm/test_StatePush.py new file mode 100644 index 0000000000..a5a7093ae5 --- /dev/null +++ b/tests/fsm/test_StatePush.py @@ -0,0 +1,144 @@ +from direct.fsm import StatePush + + +def test_PushesStateChanges(): + psc = StatePush.PushesStateChanges(0) + assert psc.getState() == 0 + psc.destroy() + + +def test_ReceivesStateChanges(): + rsc = StatePush.ReceivesStateChanges(None) + rsc.destroy() + + +def test_StateVar(): + sv = StatePush.StateVar(0) + assert sv.get() == 0 + sv.set(1) + assert sv.get() == 1 + sv.destroy() + + +def test_StateChangeNode(): + sv = StatePush.StateVar(0) + assert sv.get() == 0 + scn = StatePush.StateChangeNode(sv) + assert scn.getState() == 0 + sv.set(1) + assert sv.get() == 1 + assert scn.getState() == 1 + scn2 = StatePush.StateChangeNode(scn) + assert scn2.getState() == 1 + sv.set(2) + assert scn2.getState() == 2 + scn3 = StatePush.StateChangeNode(scn) + assert scn3.getState() == 2 + sv.set(3) + assert scn2.getState() == 3 + assert scn3.getState() == 3 + scn3.destroy() + scn2.destroy() + scn.destroy() + sv.destroy() + + +def test_ReceivesMultipleStateChanges(): + rsc = StatePush.ReceivesMultipleStateChanges() + sv = StatePush.StateVar(0) + sv2 = StatePush.StateVar('b') + rsc._subscribeTo(sv, 'a') + rsc._subscribeTo(sv2, 2) + rsc._unsubscribe('a') + rsc.destroy() + + +def test_FunctionCall_1(): + l = [] + def handler1(value, l=l): + l.append(value) + assert not l + sv = StatePush.StateVar(0) + fc = StatePush.FunctionCall(handler1, sv) + assert not l + fc.pushCurrentState() + assert l == [0,] + sv.set(1) + assert l == [0,1,] + sv.set(2) + assert l == [0,1,2,] + fc.destroy() + sv.destroy() + + +def test_FunctionCall_2(): + l = [] + def handler2(value, kDummy=None, kValue=None, l=l): + l.append((value, kValue)) + assert not l + sv = StatePush.StateVar(0) + ksv = StatePush.StateVar('a') + fc = StatePush.FunctionCall(handler2, sv, kValue=ksv) + assert not l + fc.pushCurrentState() + assert l == [(0,'a',),] + sv.set(1) + assert l == [(0,'a'),(1,'a'),] + ksv.set('b') + assert l == [(0,'a'),(1,'a'),(1,'b'),] + fc.destroy() + sv.destroy() + + +def test_EnterExit(): + l = [] + def enter(l=l): + l.append(1) + def exit(l=l): + l.append(0) + sv = StatePush.StateVar(0) + ee = StatePush.EnterExit(sv, enter, exit) + sv.set(0) + assert not l + sv.set(1) + assert l == [1,] + sv.set(2) + assert l == [1,] + sv.set(0) + assert l == [1,0,] + sv.set(True) + assert l == [1,0,1,] + sv.set(False) + assert l == [1,0,1,0,] + ee.destroy() + sv.destroy() + + +def test_Pulse(): + l = [] + def handler(value, l=l): + l.append(value) + p = StatePush.Pulse() + fc = StatePush.FunctionCall(handler, p) + assert not l + fc.pushCurrentState() + assert l == [False, ] + p.sendPulse() + assert l == [False, True, False, ] + p.sendPulse() + assert l == [False, True, False, True, False, ] + fc.destroy() + p.destroy() + + +def test_AttrSetter(): + from types import SimpleNamespace + o = SimpleNamespace() + svar = StatePush.StateVar(0) + aset = StatePush.AttrSetter(svar, o, 'testAttr') + assert hasattr(o, 'testAttr') + assert o.testAttr == 0 + svar.set('red') + assert o.testAttr == 'red' + aset.destroy() + svar.destroy() diff --git a/direct/src/gui/DirectGuiTest.py b/tests/gui/test_DirectGui.py similarity index 92% rename from direct/src/gui/DirectGuiTest.py rename to tests/gui/test_DirectGui.py index 622bd17d77..f72419a5c3 100644 --- a/direct/src/gui/DirectGuiTest.py +++ b/tests/gui/test_DirectGui.py @@ -1,19 +1,11 @@ -"""Undocumented Module""" - -__all__ = [] +from random import random +from panda3d.core import Point3 +from direct.task.TaskManagerGlobal import taskMgr +from direct.gui import DirectGuiGlobals +from direct.gui.DirectGui import DirectButton, DirectDialog, DirectEntry, DirectFrame, YesNoDialog -if __name__ == "__main__": - from panda3d.core import Point3 - from direct.showbase.ShowBase import ShowBase - from direct.task.TaskManagerGlobal import taskMgr - from . import DirectGuiGlobals - from .DirectGui import DirectButton, DirectDialog, DirectEntry, DirectFrame, YesNoDialog - #from whrandom import * - from random import random - - base = ShowBase() - +def test_DirectGui(base): # EXAMPLE CODE # Load a model smiley = base.loader.loadModel('models/misc/smiley') @@ -142,5 +134,3 @@ if __name__ == "__main__": print('WIDTH: %s' % de1.getWidth()) print('HEIGHT: %s' % de1.getHeight()) print('CENTER: %s' % (de1.getCenter(),)) - - base.run() diff --git a/direct/src/particles/ParticleTest.py b/tests/particles/test_particle.py similarity index 54% rename from direct/src/particles/ParticleTest.py rename to tests/particles/test_particle.py index f385b69c57..e41aa35ec2 100644 --- a/direct/src/particles/ParticleTest.py +++ b/tests/particles/test_particle.py @@ -1,15 +1,11 @@ +from panda3d.core import Vec3 +from panda3d.physics import LinearVectorForce +from direct.particles import ParticleEffect +from direct.particles import Particles +from direct.particles import ForceGroup -if __name__ == "__main__": - from panda3d.core import Vec3 - from panda3d.physics import LinearVectorForce - - from direct.directbase.TestStart import base - from direct.tkpanels import ParticlePanel - - from . import ParticleEffect - from . import Particles - from . import ForceGroup +def test_particle(base): # Showbase base.enableParticles() @@ -29,6 +25,4 @@ if __name__ == "__main__": pe.addParticles(p) # Particle Panel - pp = ParticlePanel.ParticlePanel(pe) - - base.run() + # pp = ParticlePanel.ParticlePanel(pe) diff --git a/direct/src/particles/ParticleFloorTest.py b/tests/particles/test_particle_floor.py old mode 100755 new mode 100644 similarity index 93% rename from direct/src/particles/ParticleFloorTest.py rename to tests/particles/test_particle_floor.py index fc79a600e4..acf60d4d81 --- a/direct/src/particles/ParticleFloorTest.py +++ b/tests/particles/test_particle_floor.py @@ -1,4 +1,3 @@ - from panda3d.core import NodePath, Vec3 from panda3d.physics import LinearVectorForce from direct.particles import ParticleEffect @@ -49,10 +48,9 @@ class ParticleFloorTest(NodePath): self.f.enable() -if __name__ == "__main__": - from direct.directbase.TestStart import base +def test_ParticleFloorTest(base): + base.enableParticles() pt = ParticleFloorTest() pt.reparentTo(base.render) pt.start() - base.camera.setY(-10.0) - base.run() + # base.camera.setY(-10.0) diff --git a/direct/src/physics/FallTest.py b/tests/physics/test_fall.py similarity index 92% rename from direct/src/physics/FallTest.py rename to tests/physics/test_fall.py index cec8b69129..99397072a8 100644 --- a/direct/src/physics/FallTest.py +++ b/tests/physics/test_fall.py @@ -26,9 +26,9 @@ class FallTest(NodePath): avatarNodePath = base.loader.loadModel("models/misc/smiley") assert not avatarNodePath.isEmpty() - camLL = base.render.find("**/camLL") - camLL.reparentTo(avatarNodePath) - camLL.setPosHpr(0, -10, 0, 0, 0, 0) + # camLL = base.render.find("**/camLL") + # camLL.reparentTo(avatarNodePath) + # camLL.setPosHpr(0, -10, 0, 0, 0, 0) avatarNodePath.reparentTo(actorNodePath) #avatarNodePath.setPos(Vec3(0)) #avatarNodePath.setHpr(Vec3(0)) @@ -86,10 +86,11 @@ class FallTest(NodePath): #self.actorNode.getPhysicsObject().resetPosition(self.avatarNodePath.getPos()) #self.actorNode.updateTransform() -if __name__ == "__main__": - from direct.directbase.ThreeUpStart import base + +def test_FallTest(base): + base.enableParticles() + base.addAngularIntegrator() test = FallTest() test.reparentTo(base.render) test.setup() - base.camera.setY(-10.0) - base.run() + # base.camera.setY(-10.0) diff --git a/direct/src/physics/RotationTest.py b/tests/physics/test_rotation.py similarity index 92% rename from direct/src/physics/RotationTest.py rename to tests/physics/test_rotation.py index d9f3ba9b62..ec24cf433b 100644 --- a/direct/src/physics/RotationTest.py +++ b/tests/physics/test_rotation.py @@ -27,9 +27,9 @@ class RotationTest(NodePath): avatarNodePath = base.loader.loadModel("models/misc/smiley") assert not avatarNodePath.isEmpty() - camLL = base.render.find("**/camLL") - camLL.reparentTo(avatarNodePath) - camLL.setPosHpr(0, -10, 0, 0, 0, 0) + # camLL = base.render.find("**/camLL") + # camLL.reparentTo(avatarNodePath) + # camLL.setPosHpr(0, -10, 0, 0, 0, 0) avatarNodePath.reparentTo(actorNodePath) #avatarNodePath.setPos(Vec3(0)) #avatarNodePath.setHpr(Vec3(0)) @@ -97,10 +97,11 @@ class RotationTest(NodePath): #self.actorNode.getPhysicsObject().resetPosition(self.avatarNodePath.getPos()) #self.actorNode.updateTransform() -if __name__ == "__main__": - from direct.directbase.ThreeUpStart import base + +def test_RotationTest(base): + base.enableParticles() + base.addAngularIntegrator() test = RotationTest() test.reparentTo(base.render) test.setup() - base.camera.setY(-10.0) - base.run() + # base.camera.setY(-10.0) diff --git a/tests/showbase/test_CountedResource.py b/tests/showbase/test_CountedResource.py new file mode 100644 index 0000000000..1d5f6807c9 --- /dev/null +++ b/tests/showbase/test_CountedResource.py @@ -0,0 +1,145 @@ +from direct.showbase.CountedResource import CountedResource + + +def test_CountedResource(): + class MouseResource(CountedResource): + """ + A simple class to demonstrate the acquisition of a resource. + """ + @classmethod + def acquire(cls): + # The call to the super-class's acquire() is + # not necessary at the moment, but may be in + # the future, so do it now for good measure. + super(MouseResource, cls).acquire() + + # Now acquire the resource this class is + # managing. + print('-- Acquire Mouse') + + @classmethod + def release(cls): + # First, release the resource this class is + # managing. + print('-- Release Mouse') + + # The call to the super-class's release() is + # not necessary at the moment, but may be in + # the future, so do it now for good measure. + super(MouseResource, cls).release() + + + def __init__(self): + super(MouseResource, self).__init__() + + def __del__(self): + super(MouseResource, self).__del__() + + class CursorResource(CountedResource): + """ + A class to demonstrate how to implement a dependent + resource. Notice how this class also inherits from + CountedResource. Instead of subclassing MouseCounter, + we will just acquire it in our __init__() and release + it in our __del__(). + """ + @classmethod + def acquire(cls): + super(CursorResource, cls).acquire() + print('-- Acquire Cursor') + + @classmethod + def release(cls): + print('-- Release Cursor') + + super(CursorResource, cls).release() + + def __init__(self): + # The required resource references should + # be stored on 'self' since we want to + # release it when the object is deleted. + self.__mouseResource = MouseResource() + + # Call the super-classes __init__() + # after all required resources are + # referenced. + super(CursorResource, self).__init__() + + def __del__(self): + # Free up the most dependent resource + # first, the one this class is managing. + super(CursorResource, self).__del__() + + # Now unlink any required resources. + del self.__mouseResource + + class InvalidResource(MouseResource): + @classmethod + def acquire(cls): + super(InvalidResource, cls).acquire() + print('-- Acquire Invalid') + + @classmethod + def release(cls): + print('-- Release Invalid') + super(InvalidResource, cls).release() + + print('\nAllocate Mouse') + m = MouseResource() + print('Free up Mouse') + del m + + print('\nAllocate Cursor') + c = CursorResource() + print('Free up Cursor') + del c + + print('\nAllocate Mouse then Cursor') + m = MouseResource() + c = CursorResource() + print('Free up Cursor') + del c + print('Free up Mouse') + del m + + print('\nAllocate Mouse then Cursor') + m = MouseResource() + c = CursorResource() + print('Free up Mouse') + del m + print('Free up Cursor') + del c + + print('\nAllocate Cursor then Mouse') + c = CursorResource() + m = MouseResource() + print('Free up Mouse') + del m + print('Free up Cursor') + del c + + print('\nAllocate Cursor then Mouse') + c = CursorResource() + m = MouseResource() + print('Free up Cursor') + del c + + # example of an invalid subclass + try: + print('\nAllocate Invalid') + i = InvalidResource() + print('Free up Invalid') + except AssertionError as e: + print(e) + print('') + + print('Free up Mouse') + del m + + def demoFunc(): + print('\nAllocate Cursor within function') + c = CursorResource() + + print('Cursor will be freed on function exit') + + demoFunc() diff --git a/tests/showbase/test_DistancePhasedNode.py b/tests/showbase/test_DistancePhasedNode.py new file mode 100644 index 0000000000..60d7f289b3 --- /dev/null +++ b/tests/showbase/test_DistancePhasedNode.py @@ -0,0 +1,30 @@ +from panda3d import core +from direct.showbase.DistancePhasedNode import BufferedDistancePhasedNode + + +def test_BufferedDistancePhasedNode(base): + cSphere = core.CollisionSphere(0, 0, 0, 0.1) + cNode = core.CollisionNode('camCol') + cNode.addSolid(cSphere) + cNodePath = core.NodePath(cNode) + # cNodePath.reparentTo(base.cam) + # cNodePath.show() + # cNodePath.setPos(25,0,0) + + base.cTrav = core.CollisionTraverser() + + eventHandler = core.CollisionHandlerEvent() + eventHandler.addInPattern('enter%in') + eventHandler.addOutPattern('exit%in') + + # messenger.toggleVerbose() + base.cTrav.addCollider(cNodePath, eventHandler) + + p = BufferedDistancePhasedNode('p', {'At': (10, 20), 'Near': (100, 200), 'Far': (1000, 1020)}, + autoCleanup=False, + fromCollideNode=cNodePath, + ) + + p.reparentTo(base.render) + p._DistancePhasedNode__oneTimeCollide() + base.eventMgr.doEvents() diff --git a/tests/showbase/test_PythonUtil.py b/tests/showbase/test_PythonUtil.py index df174ef76b..06e82bfa0a 100644 --- a/tests/showbase/test_PythonUtil.py +++ b/tests/showbase/test_PythonUtil.py @@ -56,6 +56,49 @@ def test_flywheel(): assert obj2count[4] == 4 * 3 +def test_formatTimeCompact(): + ftc = PythonUtil.formatTimeCompact + assert ftc(0) == '0s' + assert ftc(1) == '1s' + assert ftc(60) == '1m0s' + assert ftc(64) == '1m4s' + assert ftc(60*60) == '1h0m0s' + assert ftc(24*60*60) == '1d0h0m0s' + assert ftc(24*60*60 + 2*60*60 + 34*60 + 12) == '1d2h34m12s' + + +def test_formatTimeExact(): + fte = PythonUtil.formatTimeExact + assert fte(0) == '0s' + assert fte(1) == '1s' + assert fte(2) == '2s' + assert fte(61) == '1m1s' + assert fte(60) == '1m' + assert fte(60*60) == '1h' + assert fte(24*60*60) == '1d' + assert fte((24*60*60) + (2 * 60)) == '1d0h2m' + del fte + + +def test_AlphabetCounter(): + tempList = [] + ac = PythonUtil.AlphabetCounter() + for i in range(26*3): + tempList.append(ac.next()) + assert tempList == [ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + 'AA','AB','AC','AD','AE','AF','AG','AH','AI','AJ','AK','AL','AM','AN','AO','AP','AQ','AR','AS','AT','AU','AV','AW','AX','AY','AZ', + 'BA','BB','BC','BD','BE','BF','BG','BH','BI','BJ','BK','BL','BM','BN','BO','BP','BQ','BR','BS','BT','BU','BV','BW','BX','BY','BZ',] + ac = PythonUtil.AlphabetCounter() + num = 26 # A-Z + num += (26*26) # AA-ZZ + num += 26 # AAZ + num += 1 # ABA + num += 2 # ABC + for i in range(num): + x = ac.next() + assert x == 'ABC' + + def test_unescape_html_string(): assert PythonUtil.unescapeHtmlString('asdf') == 'asdf' assert PythonUtil.unescapeHtmlString('as+df') == 'as df' diff --git a/tests/stdpy/test_threading.py b/tests/stdpy/test_threading.py index 557a9e428e..a105ad20e1 100644 --- a/tests/stdpy/test_threading.py +++ b/tests/stdpy/test_threading.py @@ -1,3 +1,5 @@ +import sys +from panda3d import core from direct.stdpy import threading import pytest @@ -5,3 +7,104 @@ import pytest def test_threading_error(): with pytest.raises(threading.ThreadError): threading.stack_size() + + +def test_threading(): + from collections import deque + + _sleep = core.Thread.sleep + + _VERBOSE = False + + class _Verbose(object): + + def __init__(self, verbose=None): + if verbose is None: + verbose = _VERBOSE + self.__verbose = verbose + + def _note(self, format, *args): + if self.__verbose: + format = format % args + format = "%s: %s\n" % ( + threading.currentThread().getName(), format) + sys.stderr.write(format) + + class BoundedQueue(_Verbose): + + def __init__(self, limit): + _Verbose.__init__(self) + self.mon = threading.Lock(name = "BoundedQueue.mon") + self.rc = threading.Condition(self.mon) + self.wc = threading.Condition(self.mon) + self.limit = limit + self.queue = deque() + + def put(self, item): + self.mon.acquire() + while len(self.queue) >= self.limit: + self._note("put(%s): queue full", item) + self.wc.wait() + self.queue.append(item) + self._note("put(%s): appended, length now %d", + item, len(self.queue)) + self.rc.notify() + self.mon.release() + + def get(self): + self.mon.acquire() + while not self.queue: + self._note("get(): queue empty") + self.rc.wait() + item = self.queue.popleft() + self._note("get(): got %s, %d left", item, len(self.queue)) + self.wc.notify() + self.mon.release() + return item + + class ProducerThread(threading.Thread): + + def __init__(self, queue, quota): + threading.Thread.__init__(self, name="Producer") + self.queue = queue + self.quota = quota + + def run(self): + from random import random + counter = 0 + while counter < self.quota: + counter = counter + 1 + self.queue.put("%s.%d" % (self.getName(), counter)) + _sleep(random() * 0.00001) + + class ConsumerThread(threading.Thread): + + def __init__(self, queue, count): + threading.Thread.__init__(self, name="Consumer") + self.queue = queue + self.count = count + + def run(self): + while self.count > 0: + item = self.queue.get() + print(item) + self.count = self.count - 1 + + NP = 3 + QL = 4 + NI = 5 + + Q = BoundedQueue(QL) + P = [] + for i in range(NP): + t = ProducerThread(Q, NI) + t.setName("Producer-%d" % (i+1)) + P.append(t) + C = ConsumerThread(Q, NI*NP) + for t in P: + t.start() + _sleep(0.000001) + C.start() + for t in P: + t.join() + C.join() diff --git a/tests/stdpy/test_threading2.py b/tests/stdpy/test_threading2.py new file mode 100644 index 0000000000..f2a31dc172 --- /dev/null +++ b/tests/stdpy/test_threading2.py @@ -0,0 +1,84 @@ +from collections import deque +from panda3d import core +from direct.stdpy import threading2 + + +def test_threading2(): + class BoundedQueue(threading2._Verbose): + + def __init__(self, limit): + threading2._Verbose.__init__(self) + self.mon = threading2.RLock() + self.rc = threading2.Condition(self.mon) + self.wc = threading2.Condition(self.mon) + self.limit = limit + self.queue = deque() + + def put(self, item): + self.mon.acquire() + while len(self.queue) >= self.limit: + self._note("put(%s): queue full", item) + self.wc.wait() + self.queue.append(item) + self._note("put(%s): appended, length now %d", + item, len(self.queue)) + self.rc.notify() + self.mon.release() + + def get(self): + self.mon.acquire() + while not self.queue: + self._note("get(): queue empty") + self.rc.wait() + item = self.queue.popleft() + self._note("get(): got %s, %d left", item, len(self.queue)) + self.wc.notify() + self.mon.release() + return item + + class ProducerThread(threading2.Thread): + + def __init__(self, queue, quota): + threading2.Thread.__init__(self, name="Producer") + self.queue = queue + self.quota = quota + + def run(self): + from random import random + counter = 0 + while counter < self.quota: + counter = counter + 1 + self.queue.put("%s.%d" % (self.getName(), counter)) + core.Thread.sleep(random() * 0.00001) + + class ConsumerThread(threading2.Thread): + + def __init__(self, queue, count): + threading2.Thread.__init__(self, name="Consumer") + self.queue = queue + self.count = count + + def run(self): + while self.count > 0: + item = self.queue.get() + print(item) + self.count = self.count - 1 + + NP = 3 + QL = 4 + NI = 5 + + Q = BoundedQueue(QL) + P = [] + for i in range(NP): + t = ProducerThread(Q, NI) + t.setName("Producer-%d" % (i+1)) + P.append(t) + C = ConsumerThread(Q, NI*NP) + for t in P: + t.start() + core.Thread.sleep(0.000001) + C.start() + for t in P: + t.join() + C.join() diff --git a/tests/task/test_Task.py b/tests/task/test_Task.py new file mode 100644 index 0000000000..46710362b1 --- /dev/null +++ b/tests/task/test_Task.py @@ -0,0 +1,518 @@ +from panda3d import core +from direct.task import Task + + +def test_TaskManager(): + tm = Task.TaskManager() + tm.mgr = core.AsyncTaskManager("Test manager") + tm.setClock(core.ClockObject()) + tm.setupTaskChain("default", tickClock = True) + + tm._startTrackingMemLeaks = lambda: None + tm._stopTrackingMemLeaks = lambda: None + tm._checkMemLeaks = lambda: None + + # check for memory leaks after every test + tm._startTrackingMemLeaks() + tm._checkMemLeaks() + + # run-once task + l = [] + + def _testDone(task, l=l): + l.append(None) + return task.done + tm.add(_testDone, 'testDone') + tm.step() + assert len(l) == 1 + tm.step() + assert len(l) == 1 + _testDone = None + tm._checkMemLeaks() + + # remove by name + def _testRemoveByName(task): + return task.done + tm.add(_testRemoveByName, 'testRemoveByName') + assert tm.remove('testRemoveByName') == 1 + assert tm.remove('testRemoveByName') == 0 + _testRemoveByName = None + tm._checkMemLeaks() + + # duplicate named tasks + def _testDupNamedTasks(task): + return task.done + tm.add(_testDupNamedTasks, 'testDupNamedTasks') + tm.add(_testDupNamedTasks, 'testDupNamedTasks') + assert tm.remove('testRemoveByName') == 0 + _testDupNamedTasks = None + tm._checkMemLeaks() + + # continued task + l = [] + + def _testCont(task, l = l): + l.append(None) + return task.cont + tm.add(_testCont, 'testCont') + tm.step() + assert len(l) == 1 + tm.step() + assert len(l) == 2 + tm.remove('testCont') + _testCont = None + tm._checkMemLeaks() + + # continue until done task + l = [] + + def _testContDone(task, l = l): + l.append(None) + if len(l) >= 2: + return task.done + else: + return task.cont + tm.add(_testContDone, 'testContDone') + tm.step() + assert len(l) == 1 + tm.step() + assert len(l) == 2 + tm.step() + assert len(l) == 2 + assert not tm.hasTaskNamed('testContDone') + _testContDone = None + tm._checkMemLeaks() + + # hasTaskNamed + def _testHasTaskNamed(task): + return task.done + tm.add(_testHasTaskNamed, 'testHasTaskNamed') + assert tm.hasTaskNamed('testHasTaskNamed') + tm.step() + assert not tm.hasTaskNamed('testHasTaskNamed') + _testHasTaskNamed = None + tm._checkMemLeaks() + + # task sort + l = [] + + def _testPri1(task, l = l): + l.append(1) + return task.cont + + def _testPri2(task, l = l): + l.append(2) + return task.cont + tm.add(_testPri1, 'testPri1', sort = 1) + tm.add(_testPri2, 'testPri2', sort = 2) + tm.step() + assert len(l) == 2 + assert l == [1, 2,] + tm.step() + assert len(l) == 4 + assert l == [1, 2, 1, 2,] + tm.remove('testPri1') + tm.remove('testPri2') + _testPri1 = None + _testPri2 = None + tm._checkMemLeaks() + + # task extraArgs + l = [] + + def _testExtraArgs(arg1, arg2, l=l): + l.extend([arg1, arg2,]) + return Task.done + tm.add(_testExtraArgs, 'testExtraArgs', extraArgs=[4,5]) + tm.step() + assert len(l) == 2 + assert l == [4, 5,] + _testExtraArgs = None + tm._checkMemLeaks() + + # task appendTask + l = [] + + def _testAppendTask(arg1, arg2, task, l=l): + l.extend([arg1, arg2,]) + return task.done + tm.add(_testAppendTask, '_testAppendTask', extraArgs=[4,5], appendTask=True) + tm.step() + assert len(l) == 2 + assert l == [4, 5,] + _testAppendTask = None + tm._checkMemLeaks() + + # task uponDeath + l = [] + + def _uponDeathFunc(task, l=l): + l.append(task.name) + + def _testUponDeath(task): + return Task.done + tm.add(_testUponDeath, 'testUponDeath', uponDeath=_uponDeathFunc) + tm.step() + assert len(l) == 1 + assert l == ['testUponDeath'] + _testUponDeath = None + _uponDeathFunc = None + tm._checkMemLeaks() + + # task owner + class _TaskOwner: + def _addTask(self, task): + self.addedTaskName = task.name + + def _clearTask(self, task): + self.clearedTaskName = task.name + to = _TaskOwner() + l = [] + + def _testOwner(task): + return Task.done + tm.add(_testOwner, 'testOwner', owner=to) + tm.step() + assert getattr(to, 'addedTaskName', None) == 'testOwner' + assert getattr(to, 'clearedTaskName', None) == 'testOwner' + _testOwner = None + del to + _TaskOwner = None + tm._checkMemLeaks() + + doLaterTests = [0,] + + # doLater + l = [] + + def _testDoLater1(task, l=l): + l.append(1) + + def _testDoLater2(task, l=l): + l.append(2) + + def _monitorDoLater(task, tm=tm, l=l, doLaterTests=doLaterTests): + if task.time > .03: + assert l == [1, 2,] + doLaterTests[0] -= 1 + return task.done + return task.cont + tm.doMethodLater(.01, _testDoLater1, 'testDoLater1') + tm.doMethodLater(.02, _testDoLater2, 'testDoLater2') + doLaterTests[0] += 1 + # make sure we run this task after the doLaters if they all occur on the same frame + tm.add(_monitorDoLater, 'monitorDoLater', sort=10) + _testDoLater1 = None + _testDoLater2 = None + _monitorDoLater = None + # don't check until all the doLaters are finished + #tm._checkMemLeaks() + + # doLater sort + l = [] + + def _testDoLaterPri1(task, l=l): + l.append(1) + + def _testDoLaterPri2(task, l=l): + l.append(2) + + def _monitorDoLaterPri(task, tm=tm, l=l, doLaterTests=doLaterTests): + if task.time > .02: + assert l == [1, 2,] + doLaterTests[0] -= 1 + return task.done + return task.cont + tm.doMethodLater(.01, _testDoLaterPri1, 'testDoLaterPri1', sort=1) + tm.doMethodLater(.01, _testDoLaterPri2, 'testDoLaterPri2', sort=2) + doLaterTests[0] += 1 + # make sure we run this task after the doLaters if they all occur on the same frame + tm.add(_monitorDoLaterPri, 'monitorDoLaterPri', sort=10) + _testDoLaterPri1 = None + _testDoLaterPri2 = None + _monitorDoLaterPri = None + # don't check until all the doLaters are finished + #tm._checkMemLeaks() + + # doLater extraArgs + l = [] + + def _testDoLaterExtraArgs(arg1, l=l): + l.append(arg1) + + def _monitorDoLaterExtraArgs(task, tm=tm, l=l, doLaterTests=doLaterTests): + if task.time > .02: + assert l == [3,] + doLaterTests[0] -= 1 + return task.done + return task.cont + tm.doMethodLater(.01, _testDoLaterExtraArgs, 'testDoLaterExtraArgs', extraArgs=[3,]) + doLaterTests[0] += 1 + # make sure we run this task after the doLaters if they all occur on the same frame + tm.add(_monitorDoLaterExtraArgs, 'monitorDoLaterExtraArgs', sort=10) + _testDoLaterExtraArgs = None + _monitorDoLaterExtraArgs = None + # don't check until all the doLaters are finished + #tm._checkMemLeaks() + + # doLater appendTask + l = [] + + def _testDoLaterAppendTask(arg1, task, l=l): + assert task.name == 'testDoLaterAppendTask' + l.append(arg1) + + def _monitorDoLaterAppendTask(task, tm=tm, l=l, doLaterTests=doLaterTests): + if task.time > .02: + assert l == [4,] + doLaterTests[0] -= 1 + return task.done + return task.cont + tm.doMethodLater(.01, _testDoLaterAppendTask, 'testDoLaterAppendTask', + extraArgs=[4,], appendTask=True) + doLaterTests[0] += 1 + # make sure we run this task after the doLaters if they all occur on the same frame + tm.add(_monitorDoLaterAppendTask, 'monitorDoLaterAppendTask', sort=10) + _testDoLaterAppendTask = None + _monitorDoLaterAppendTask = None + # don't check until all the doLaters are finished + #tm._checkMemLeaks() + + # doLater uponDeath + l = [] + + def _testUponDeathFunc(task, l=l): + assert task.name == 'testDoLaterUponDeath' + l.append(10) + + def _testDoLaterUponDeath(arg1, l=l): + return Task.done + + def _monitorDoLaterUponDeath(task, tm=tm, l=l, doLaterTests=doLaterTests): + if task.time > .02: + assert l == [10,] + doLaterTests[0] -= 1 + return task.done + return task.cont + tm.doMethodLater(.01, _testDoLaterUponDeath, 'testDoLaterUponDeath', + uponDeath=_testUponDeathFunc) + doLaterTests[0] += 1 + # make sure we run this task after the doLaters if they all occur on the same frame + tm.add(_monitorDoLaterUponDeath, 'monitorDoLaterUponDeath', sort=10) + _testUponDeathFunc = None + _testDoLaterUponDeath = None + _monitorDoLaterUponDeath = None + # don't check until all the doLaters are finished + #tm._checkMemLeaks() + + # doLater owner + class _DoLaterOwner: + def _addTask(self, task): + self.addedTaskName = task.name + + def _clearTask(self, task): + self.clearedTaskName = task.name + doLaterOwner = _DoLaterOwner() + l = [] + + def _testDoLaterOwner(l=l): + pass + + def _monitorDoLaterOwner(task, tm=tm, l=l, doLaterOwner=doLaterOwner, + doLaterTests=doLaterTests): + if task.time > .02: + assert getattr(doLaterOwner, 'addedTaskName', None) == 'testDoLaterOwner' + assert getattr(doLaterOwner, 'clearedTaskName', None) == 'testDoLaterOwner' + doLaterTests[0] -= 1 + return task.done + return task.cont + tm.doMethodLater(.01, _testDoLaterOwner, 'testDoLaterOwner', + owner=doLaterOwner) + doLaterTests[0] += 1 + # make sure we run this task after the doLaters if they all occur on the same frame + tm.add(_monitorDoLaterOwner, 'monitorDoLaterOwner', sort=10) + _testDoLaterOwner = None + _monitorDoLaterOwner = None + del doLaterOwner + _DoLaterOwner = None + # don't check until all the doLaters are finished + #tm._checkMemLeaks() + + # run the doLater tests + while doLaterTests[0] > 0: + tm.step() + del doLaterTests + tm._checkMemLeaks() + + # getTasks + def _testGetTasks(task): + return task.cont + # No doLaterProcessor in the new world. + assert len(tm.getTasks()) == 0 + tm.add(_testGetTasks, 'testGetTasks1') + assert len(tm.getTasks()) == 1 + assert (tm.getTasks()[0].name == 'testGetTasks1' or + tm.getTasks()[1].name == 'testGetTasks1') + tm.add(_testGetTasks, 'testGetTasks2') + tm.add(_testGetTasks, 'testGetTasks3') + assert len(tm.getTasks()) == 3 + tm.remove('testGetTasks2') + assert len(tm.getTasks()) == 2 + tm.remove('testGetTasks1') + tm.remove('testGetTasks3') + assert len(tm.getTasks()) == 0 + _testGetTasks = None + tm._checkMemLeaks() + + # getDoLaters + def _testGetDoLaters(): + pass + assert len(tm.getDoLaters()) == 0 + tm.doMethodLater(.1, _testGetDoLaters, 'testDoLater1') + assert len(tm.getDoLaters()) == 1 + assert tm.getDoLaters()[0].name == 'testDoLater1' + tm.doMethodLater(.1, _testGetDoLaters, 'testDoLater2') + tm.doMethodLater(.1, _testGetDoLaters, 'testDoLater3') + assert len(tm.getDoLaters()) == 3 + tm.remove('testDoLater2') + assert len(tm.getDoLaters()) == 2 + tm.remove('testDoLater1') + tm.remove('testDoLater3') + assert len(tm.getDoLaters()) == 0 + _testGetDoLaters = None + tm._checkMemLeaks() + + # duplicate named doLaters removed via taskMgr.remove + def _testDupNameDoLaters(): + pass + # the doLaterProcessor is always running + tm.doMethodLater(.1, _testDupNameDoLaters, 'testDupNameDoLater') + tm.doMethodLater(.1, _testDupNameDoLaters, 'testDupNameDoLater') + assert len(tm.getDoLaters()) == 2 + tm.remove('testDupNameDoLater') + assert len(tm.getDoLaters()) == 0 + _testDupNameDoLaters = None + tm._checkMemLeaks() + + # duplicate named doLaters removed via remove() + def _testDupNameDoLatersRemove(): + pass + # the doLaterProcessor is always running + dl1 = tm.doMethodLater(.1, _testDupNameDoLatersRemove, 'testDupNameDoLaterRemove') + dl2 = tm.doMethodLater(.1, _testDupNameDoLatersRemove, 'testDupNameDoLaterRemove') + assert len(tm.getDoLaters()) == 2 + dl2.remove() + assert len(tm.getDoLaters()) == 1 + dl1.remove() + assert len(tm.getDoLaters()) == 0 + _testDupNameDoLatersRemove = None + # nameDict etc. isn't cleared out right away with task.remove() + tm._checkMemLeaks() + + # getTasksNamed + def _testGetTasksNamed(task): + return task.cont + assert len(tm.getTasksNamed('testGetTasksNamed')) == 0 + tm.add(_testGetTasksNamed, 'testGetTasksNamed') + assert len(tm.getTasksNamed('testGetTasksNamed')) == 1 + assert tm.getTasksNamed('testGetTasksNamed')[0].name == 'testGetTasksNamed' + tm.add(_testGetTasksNamed, 'testGetTasksNamed') + tm.add(_testGetTasksNamed, 'testGetTasksNamed') + assert len(tm.getTasksNamed('testGetTasksNamed')) == 3 + tm.remove('testGetTasksNamed') + assert len(tm.getTasksNamed('testGetTasksNamed')) == 0 + _testGetTasksNamed = None + tm._checkMemLeaks() + + # removeTasksMatching + def _testRemoveTasksMatching(task): + return task.cont + tm.add(_testRemoveTasksMatching, 'testRemoveTasksMatching') + assert len(tm.getTasksNamed('testRemoveTasksMatching')) == 1 + tm.removeTasksMatching('testRemoveTasksMatching') + assert len(tm.getTasksNamed('testRemoveTasksMatching')) == 0 + tm.add(_testRemoveTasksMatching, 'testRemoveTasksMatching1') + tm.add(_testRemoveTasksMatching, 'testRemoveTasksMatching2') + assert len(tm.getTasksNamed('testRemoveTasksMatching1')) == 1 + assert len(tm.getTasksNamed('testRemoveTasksMatching2')) == 1 + tm.removeTasksMatching('testRemoveTasksMatching*') + assert len(tm.getTasksNamed('testRemoveTasksMatching1')) == 0 + assert len(tm.getTasksNamed('testRemoveTasksMatching2')) == 0 + tm.add(_testRemoveTasksMatching, 'testRemoveTasksMatching1a') + tm.add(_testRemoveTasksMatching, 'testRemoveTasksMatching2a') + assert len(tm.getTasksNamed('testRemoveTasksMatching1a')) == 1 + assert len(tm.getTasksNamed('testRemoveTasksMatching2a')) == 1 + tm.removeTasksMatching('testRemoveTasksMatching?a') + assert len(tm.getTasksNamed('testRemoveTasksMatching1a')) == 0 + assert len(tm.getTasksNamed('testRemoveTasksMatching2a')) == 0 + _testRemoveTasksMatching = None + tm._checkMemLeaks() + + # create Task object and add to mgr + l = [] + + def _testTaskObj(task, l=l): + l.append(None) + return task.cont + t = Task.Task(_testTaskObj) + tm.add(t, 'testTaskObj') + tm.step() + assert len(l) == 1 + tm.step() + assert len(l) == 2 + tm.remove('testTaskObj') + tm.step() + assert len(l) == 2 + _testTaskObj = None + tm._checkMemLeaks() + + # remove Task via task.remove() + l = [] + + def _testTaskObjRemove(task, l=l): + l.append(None) + return task.cont + t = Task.Task(_testTaskObjRemove) + tm.add(t, 'testTaskObjRemove') + tm.step() + assert len(l) == 1 + tm.step() + assert len(l) == 2 + t.remove() + tm.step() + assert len(l) == 2 + del t + _testTaskObjRemove = None + tm._checkMemLeaks() + + # set/get Task sort + l = [] + def _testTaskObjSort(arg, task, l=l): + l.append(arg) + return task.cont + t1 = Task.Task(_testTaskObjSort) + t2 = Task.Task(_testTaskObjSort) + tm.add(t1, 'testTaskObjSort1', extraArgs=['a',], appendTask=True, sort=1) + tm.add(t2, 'testTaskObjSort2', extraArgs=['b',], appendTask=True, sort=2) + tm.step() + assert len(l) == 2 + assert l == ['a', 'b'] + assert t1.getSort() == 1 + assert t2.getSort() == 2 + t1.setSort(3) + assert t1.getSort() == 3 + tm.step() + assert len(l) == 4 + assert l == ['a', 'b', 'b', 'a',] + t1.remove() + t2.remove() + tm.step() + assert len(l) == 4 + del t1 + del t2 + _testTaskObjSort = None + tm._checkMemLeaks() + + del l + tm.destroy() + del tm diff --git a/tests/task/test_task_arg.py b/tests/task/test_task_arg.py index 4243c44f2b..26b3552053 100644 --- a/tests/task/test_task_arg.py +++ b/tests/task/test_task_arg.py @@ -2,7 +2,7 @@ from direct.showbase.ShowBase import ShowBase from direct.task import Task from panda3d.core import Vec2 -def test_task_arg(): +def test_task_arg(base): def test(ship, flood, task): ship.y += flood return task.done @@ -10,7 +10,6 @@ def test_task_arg(): ship = Vec2(2.2, 2) flood = 1 - base = ShowBase(windowType='none') task = base.addTask(test, 'test_task', extraArgs=[ship, flood], appendTask=True) base.taskMgr.step() assert ship.y == 3 @@ -25,4 +24,3 @@ def test_task_arg(): task = base.taskMgr.add(task) base.taskMgr.step() assert ship.y == 6 - \ No newline at end of file diff --git a/direct/src/task/TaskTester.py b/tests/task/test_tasks.py old mode 100755 new mode 100644 similarity index 82% rename from direct/src/task/TaskTester.py rename to tests/task/test_tasks.py index 582b7486da..b5e4ff9d8b --- a/direct/src/task/TaskTester.py +++ b/tests/task/test_tasks.py @@ -1,11 +1,7 @@ -"""Undocumented Module""" - -__all__ = [] - -from direct.task.TaskManagerGlobal import taskMgr from direct.task import Task import random +taskMgr = Task.TaskManager() numTasks = 10000 maxDelay = 20 counter = 0 @@ -24,8 +20,10 @@ def taskCallback(task): spawnNewTask() return Task.done -if __name__ == '__main__': +def test_tasks(): taskMgr.removeTasksMatching("taskTester*") for i in range(numTasks): spawnNewTask() + + taskMgr.destroy() diff --git a/tests/test_imports.py b/tests/test_imports.py index b7df8d8239..58b146e589 100644 --- a/tests/test_imports.py +++ b/tests/test_imports.py @@ -93,7 +93,6 @@ def test_imports_direct(): import direct.gui.DirectGui import direct.gui.DirectGuiBase import direct.gui.DirectGuiGlobals - import direct.gui.DirectGuiTest import direct.gui.DirectLabel import direct.gui.DirectOptionMenu import direct.gui.DirectRadioButton @@ -112,7 +111,6 @@ def test_imports_direct(): import direct.interval.Interval import direct.interval.IntervalGlobal import direct.interval.IntervalManager - import direct.interval.IntervalTest import direct.interval.LerpBlendHelpers import direct.interval.LerpInterval import direct.interval.MetaInterval @@ -185,7 +183,6 @@ def test_imports_direct(): import direct.task.Task import direct.task.TaskManagerGlobal import direct.task.TaskProfiler - import direct.task.TaskTester import direct.task.Timer @@ -196,13 +193,9 @@ def test_imports_direct_physics(): import direct.particles.ForceGroup import direct.particles.GlobalForceGroup import direct.particles.ParticleEffect - import direct.particles.ParticleFloorTest import direct.particles.ParticleManagerGlobal - import direct.particles.ParticleTest import direct.particles.Particles import direct.particles.SpriteParticleRendererExt - import direct.physics.FallTest - import direct.physics.RotationTest import direct.showbase.PhysicsManagerGlobal diff --git a/tests/tkpanels/test_ParticlePanel.py b/tests/tkpanels/test_ParticlePanel.py new file mode 100644 index 0000000000..e1498a4868 --- /dev/null +++ b/tests/tkpanels/test_ParticlePanel.py @@ -0,0 +1,11 @@ +import pytest +Pmw = pytest.importorskip('Pmw') +from direct.tkpanels.ParticlePanel import ParticlePanel + + +def test_ParticlePanel(base, tk_toplevel): + root = Pmw.initialise() + pp = ParticlePanel() + base.pp=pp + #ve = VectorEntry(Toplevel(), relief = GROOVE) + #ve.pack() diff --git a/tests/tkpanels/test_Placer.py b/tests/tkpanels/test_Placer.py new file mode 100644 index 0000000000..1a5072bf82 --- /dev/null +++ b/tests/tkpanels/test_Placer.py @@ -0,0 +1,12 @@ +import pytest +Pmw = pytest.importorskip('Pmw') +from direct.showbase.ShowBase import ShowBase +from direct.tkpanels.Placer import Placer + + +def test_Placer(window): + base = ShowBase() + base.start_direct() + root = Pmw.initialise() + widget = Placer() + base.destroy() diff --git a/tests/tkwidgets/test_AppShell.py b/tests/tkwidgets/test_AppShell.py new file mode 100644 index 0000000000..e87889d34b --- /dev/null +++ b/tests/tkwidgets/test_AppShell.py @@ -0,0 +1,7 @@ +import pytest +pytest.importorskip('Pmw') +from direct.tkwidgets import AppShell + + +def test_TestAppShell(tk_toplevel): + test = AppShell.TestAppShell(balloon_state='none') diff --git a/tests/tkwidgets/test_Dial.py b/tests/tkwidgets/test_Dial.py new file mode 100644 index 0000000000..eda8d0591b --- /dev/null +++ b/tests/tkwidgets/test_Dial.py @@ -0,0 +1,19 @@ +import tkinter as tk +import pytest +pytest.importorskip('Pmw') +from direct.tkwidgets.Dial import Dial + + +def test_Dial(tk_toplevel): + tl = tk_toplevel + d = Dial(tl) + d2 = Dial(tl, dial_numSegments = 12, max = 360, + dial_fRollover = 0, value = 180) + d3 = Dial(tl, dial_numSegments = 12, max = 90, min = -90, + dial_fRollover = 0) + d4 = Dial(tl, dial_numSegments = 16, max = 256, + dial_fRollover = 0) + d.pack(expand = 1, fill = tk.X) + d2.pack(expand = 1, fill = tk.X) + d3.pack(expand = 1, fill = tk.X) + d4.pack(expand = 1, fill = tk.X) diff --git a/tests/tkwidgets/test_EntryScale.py b/tests/tkwidgets/test_EntryScale.py new file mode 100644 index 0000000000..f06fb036ed --- /dev/null +++ b/tests/tkwidgets/test_EntryScale.py @@ -0,0 +1,44 @@ +import pytest +pytest.importorskip('Pmw') +from direct.tkwidgets.EntryScale import EntryScale, EntryScaleGroup + + +def test_EntryScale(tk_toplevel): + # Initialise Tkinter and Pmw. + root = tk_toplevel + root.title('Pmw EntryScale demonstration') + + # Dummy command + def printVal(val): + print(val) + + # Create and pack a EntryScale megawidget. + mega1 = EntryScale(root, command = printVal) + mega1.pack(side = 'left', expand = 1, fill = 'x') + + # These are things you can set/configure + # Starting value for entryScale + #mega1['value'] = 123.456 + #mega1['text'] = 'Drive delta X' + #mega1['min'] = 0.0 + #mega1['max'] = 1000.0 + #mega1['resolution'] = 1.0 + # To change the color of the label: + #mega1.label['foreground'] = 'Red' + # Max change/update, default is 100 + # To have really fine control, for example + # mega1['maxVelocity'] = 0.1 + # Number of digits to the right of the decimal point, default = 2 + # mega1['numDigits'] = 5 + + # To create a entryScale group to set an RGBA value: + group1 = EntryScaleGroup(root, dim = 4, + title = 'Simple RGBA Panel', + labels = ('R', 'G', 'B', 'A'), + Valuator_min = 0.0, + Valuator_max = 255.0, + Valuator_resolution = 1.0, + command = printVal) + + # Uncomment this if you aren't running in IDLE + #root.mainloop() diff --git a/tests/tkwidgets/test_Floater.py b/tests/tkwidgets/test_Floater.py new file mode 100644 index 0000000000..dfd470763f --- /dev/null +++ b/tests/tkwidgets/test_Floater.py @@ -0,0 +1,41 @@ +import pytest +pytest.importorskip('Pmw') +from direct.tkwidgets.Floater import Floater, FloaterGroup + + +def test_Floater(tk_toplevel): + # Initialise Tkinter and Pmw. + root = tk_toplevel + root.title('Pmw Floater demonstration') + + # Dummy command + def printVal(val): + print(val) + + # Create and pack a Floater megawidget. + mega1 = Floater(root, command = printVal) + mega1.pack(side = 'left', expand = 1, fill = 'x') + + # These are things you can set/configure + # Starting value for floater + #mega1['value'] = 123.456 + #mega1['text'] = 'Drive delta X' + # To change the color of the label: + #mega1.label['foreground'] = 'Red' + # Max change/update, default is 100 + # To have really fine control, for example + #mega1['maxVelocity'] = 0.1 + # Number of digits to the right of the decimal point, default = 2 + #mega1['numDigits'] = 5 + + # To create a floater group to set an RGBA value: + group1 = FloaterGroup(root, dim = 4, + title = 'Simple RGBA Panel', + labels = ('R', 'G', 'B', 'A'), + Valuator_min = 0.0, + Valuator_max = 255.0, + Valuator_resolution = 1.0, + command = printVal) + + # Uncomment this if you aren't running in IDLE + #root.mainloop() diff --git a/tests/tkwidgets/test_VectorWidgets.py b/tests/tkwidgets/test_VectorWidgets.py new file mode 100644 index 0000000000..fecad4cfa7 --- /dev/null +++ b/tests/tkwidgets/test_VectorWidgets.py @@ -0,0 +1,17 @@ +import pytest +pytest.importorskip('Pmw') +from direct.tkwidgets import VectorWidgets + + +def test_VectorEntry(tk_toplevel): + root = tk_toplevel + root.title('Vector Widget demo') + + ve = VectorWidgets.VectorEntry(root) + ve.pack() + v3e = VectorWidgets.Vector3Entry(root) + v3e.pack() + v4e = VectorWidgets.Vector4Entry(root) + v4e.pack() + ce = VectorWidgets.ColorEntry(root) + ce.pack() From bc039a0476b31fa624ce548629b7e05cccd2d570 Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 2 Aug 2023 11:06:32 +0200 Subject: [PATCH 44/84] cppparser: Allow referencing enumerant within enum scope --- dtool/src/cppparser/cppBison.cxx.prebuilt | 6351 +++++++++++---------- dtool/src/cppparser/cppBison.yxx | 11 +- 2 files changed, 3194 insertions(+), 3168 deletions(-) diff --git a/dtool/src/cppparser/cppBison.cxx.prebuilt b/dtool/src/cppparser/cppBison.cxx.prebuilt index 26e92e8511..ab408c73c5 100644 --- a/dtool/src/cppparser/cppBison.cxx.prebuilt +++ b/dtool/src/cppparser/cppBison.cxx.prebuilt @@ -556,39 +556,40 @@ enum yysymbol_kind_t YYSYMBOL_class_derivation = 254, /* class_derivation */ YYSYMBOL_base_specification = 255, /* base_specification */ YYSYMBOL_enum = 256, /* enum */ - YYSYMBOL_enum_decl = 257, /* enum_decl */ - YYSYMBOL_enum_element_type = 258, /* enum_element_type */ - YYSYMBOL_enum_body_trailing_comma = 259, /* enum_body_trailing_comma */ - YYSYMBOL_enum_body = 260, /* enum_body */ - YYSYMBOL_enum_keyword = 261, /* enum_keyword */ - YYSYMBOL_struct_keyword = 262, /* struct_keyword */ - YYSYMBOL_namespace_declaration = 263, /* namespace_declaration */ - YYSYMBOL_264_19 = 264, /* $@19 */ + YYSYMBOL_257_19 = 257, /* $@19 */ + YYSYMBOL_enum_decl = 258, /* enum_decl */ + YYSYMBOL_enum_element_type = 259, /* enum_element_type */ + YYSYMBOL_enum_body_trailing_comma = 260, /* enum_body_trailing_comma */ + YYSYMBOL_enum_body = 261, /* enum_body */ + YYSYMBOL_enum_keyword = 262, /* enum_keyword */ + YYSYMBOL_struct_keyword = 263, /* struct_keyword */ + YYSYMBOL_namespace_declaration = 264, /* namespace_declaration */ YYSYMBOL_265_20 = 265, /* $@20 */ - YYSYMBOL_using_declaration = 266, /* using_declaration */ - YYSYMBOL_simple_type = 267, /* simple_type */ - YYSYMBOL_simple_int_type = 268, /* simple_int_type */ - YYSYMBOL_simple_float_type = 269, /* simple_float_type */ - YYSYMBOL_simple_void_type = 270, /* simple_void_type */ - YYSYMBOL_code = 271, /* code */ - YYSYMBOL_272_21 = 272, /* $@21 */ - YYSYMBOL_code_block = 273, /* code_block */ - YYSYMBOL_element = 274, /* element */ - YYSYMBOL_optional_const_expr = 275, /* optional_const_expr */ - YYSYMBOL_optional_const_expr_comma = 276, /* optional_const_expr_comma */ - YYSYMBOL_const_expr_comma = 277, /* const_expr_comma */ - YYSYMBOL_no_angle_bracket_const_expr = 278, /* no_angle_bracket_const_expr */ - YYSYMBOL_const_expr = 279, /* const_expr */ - YYSYMBOL_const_operand = 280, /* const_operand */ - YYSYMBOL_formal_const_expr = 281, /* formal_const_expr */ - YYSYMBOL_formal_const_operand = 282, /* formal_const_operand */ - YYSYMBOL_capture_list = 283, /* capture_list */ - YYSYMBOL_capture = 284, /* capture */ - YYSYMBOL_class_derivation_name = 285, /* class_derivation_name */ - YYSYMBOL_name = 286, /* name */ - YYSYMBOL_name_no_final = 287, /* name_no_final */ - YYSYMBOL_string_literal = 288, /* string_literal */ - YYSYMBOL_empty = 289 /* empty */ + YYSYMBOL_266_21 = 266, /* $@21 */ + YYSYMBOL_using_declaration = 267, /* using_declaration */ + YYSYMBOL_simple_type = 268, /* simple_type */ + YYSYMBOL_simple_int_type = 269, /* simple_int_type */ + YYSYMBOL_simple_float_type = 270, /* simple_float_type */ + YYSYMBOL_simple_void_type = 271, /* simple_void_type */ + YYSYMBOL_code = 272, /* code */ + YYSYMBOL_273_22 = 273, /* $@22 */ + YYSYMBOL_code_block = 274, /* code_block */ + YYSYMBOL_element = 275, /* element */ + YYSYMBOL_optional_const_expr = 276, /* optional_const_expr */ + YYSYMBOL_optional_const_expr_comma = 277, /* optional_const_expr_comma */ + YYSYMBOL_const_expr_comma = 278, /* const_expr_comma */ + YYSYMBOL_no_angle_bracket_const_expr = 279, /* no_angle_bracket_const_expr */ + YYSYMBOL_const_expr = 280, /* const_expr */ + YYSYMBOL_const_operand = 281, /* const_operand */ + YYSYMBOL_formal_const_expr = 282, /* formal_const_expr */ + YYSYMBOL_formal_const_operand = 283, /* formal_const_operand */ + YYSYMBOL_capture_list = 284, /* capture_list */ + YYSYMBOL_capture = 285, /* capture */ + YYSYMBOL_class_derivation_name = 286, /* class_derivation_name */ + YYSYMBOL_name = 287, /* name */ + YYSYMBOL_name_no_final = 288, /* name_no_final */ + YYSYMBOL_string_literal = 289, /* string_literal */ + YYSYMBOL_empty = 290 /* empty */ }; typedef enum yysymbol_kind_t yysymbol_kind_t; @@ -919,16 +920,16 @@ union yyalloc /* YYFINAL -- State number of the termination state. */ #define YYFINAL 108 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 7072 +#define YYLAST 7071 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 178 /* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 112 +#define YYNNTS 113 /* YYNRULES -- Number of rules. */ -#define YYNRULES 781 +#define YYNRULES 782 /* YYNSTATES -- Number of states. */ -#define YYNSTATES 1670 +#define YYNSTATES 1671 /* YYMAXUTOK -- Last valid token kind. */ #define YYMAXUTOK 408 @@ -1028,49 +1029,49 @@ static const yytype_int16 yyrline[] = 2752, 2756, 2764, 2768, 2784, 2800, 2809, 2819, 2826, 2830, 2838, 2842, 2847, 2851, 2860, 2859, 2884, 2883, 2913, 2914, 2921, 2922, 2926, 2927, 2931, 2935, 2939, 2943, 2947, 2951, - 2955, 2959, 2963, 2967, 2974, 2982, 2986, 2990, 2995, 3003, - 3007, 3014, 3015, 3020, 3027, 3028, 3033, 3041, 3045, 3049, - 3056, 3060, 3064, 3072, 3071, 3094, 3093, 3116, 3117, 3121, - 3127, 3134, 3140, 3149, 3150, 3151, 3155, 3159, 3163, 3167, - 3171, 3175, 3179, 3184, 3189, 3194, 3199, 3203, 3208, 3217, - 3222, 3230, 3234, 3238, 3246, 3256, 3256, 3266, 3267, 3271, - 3272, 3273, 3274, 3275, 3276, 3277, 3278, 3279, 3280, 3281, - 3282, 3282, 3282, 3283, 3283, 3283, 3283, 3283, 3284, 3284, - 3284, 3284, 3284, 3285, 3285, 3285, 3286, 3286, 3286, 3286, - 3286, 3287, 3287, 3287, 3287, 3287, 3288, 3288, 3289, 3289, - 3289, 3289, 3289, 3290, 3290, 3290, 3290, 3290, 3291, 3291, - 3291, 3291, 3291, 3292, 3292, 3292, 3292, 3292, 3293, 3293, - 3293, 3293, 3293, 3294, 3294, 3294, 3294, 3294, 3295, 3295, - 3295, 3295, 3295, 3295, 3296, 3296, 3296, 3296, 3296, 3297, - 3297, 3297, 3297, 3298, 3298, 3298, 3298, 3299, 3299, 3299, - 3299, 3299, 3300, 3300, 3300, 3300, 3301, 3301, 3301, 3301, - 3301, 3302, 3302, 3302, 3302, 3303, 3303, 3303, 3303, 3303, - 3304, 3304, 3307, 3307, 3307, 3307, 3307, 3307, 3307, 3307, - 3307, 3307, 3307, 3308, 3308, 3308, 3308, 3308, 3308, 3308, - 3308, 3308, 3308, 3309, 3309, 3313, 3317, 3324, 3328, 3335, - 3339, 3346, 3350, 3354, 3358, 3362, 3366, 3370, 3374, 3378, - 3382, 3386, 3390, 3394, 3398, 3402, 3406, 3410, 3414, 3418, - 3422, 3426, 3430, 3434, 3438, 3442, 3446, 3450, 3454, 3458, - 3462, 3466, 3470, 3474, 3478, 3482, 3486, 3490, 3494, 3498, - 3502, 3510, 3514, 3518, 3522, 3526, 3530, 3534, 3544, 3554, - 3560, 3566, 3572, 3578, 3584, 3590, 3596, 3603, 3610, 3617, - 3624, 3630, 3636, 3640, 3644, 3648, 3652, 3656, 3660, 3671, - 3682, 3686, 3690, 3694, 3698, 3702, 3706, 3710, 3714, 3718, - 3722, 3726, 3730, 3734, 3738, 3742, 3746, 3750, 3754, 3758, - 3762, 3766, 3770, 3774, 3778, 3782, 3786, 3790, 3794, 3798, - 3802, 3806, 3810, 3817, 3821, 3825, 3829, 3833, 3837, 3841, - 3845, 3849, 3855, 3861, 3865, 3872, 3880, 3884, 3888, 3892, - 3896, 3900, 3904, 3908, 3912, 3916, 3920, 3924, 3928, 3932, - 3936, 3940, 3944, 3948, 3962, 3966, 3970, 3974, 3978, 3982, - 3986, 3990, 3994, 3998, 4002, 4006, 4010, 4021, 4032, 4036, - 4040, 4044, 4048, 4052, 4056, 4060, 4064, 4068, 4072, 4076, - 4080, 4084, 4088, 4092, 4096, 4100, 4104, 4108, 4112, 4116, - 4120, 4124, 4128, 4132, 4136, 4140, 4144, 4148, 4152, 4159, - 4163, 4167, 4171, 4175, 4179, 4183, 4187, 4191, 4197, 4203, - 4211, 4215, 4219, 4223, 4230, 4240, 4246, 4252, 4262, 4274, - 4282, 4286, 4316, 4320, 4324, 4328, 4332, 4336, 4342, 4346, - 4350, 4354, 4358, 4369, 4373, 4377, 4381, 4389, 4393, 4397, - 4403, 4414 + 2955, 2959, 2963, 2967, 2975, 2974, 2991, 2995, 2999, 3004, + 3012, 3016, 3023, 3024, 3029, 3036, 3037, 3042, 3050, 3054, + 3058, 3065, 3069, 3073, 3081, 3080, 3103, 3102, 3125, 3126, + 3130, 3136, 3143, 3149, 3158, 3159, 3160, 3164, 3168, 3172, + 3176, 3180, 3184, 3188, 3193, 3198, 3203, 3208, 3212, 3217, + 3226, 3231, 3239, 3243, 3247, 3255, 3265, 3265, 3275, 3276, + 3280, 3281, 3282, 3283, 3284, 3285, 3286, 3287, 3288, 3289, + 3290, 3291, 3291, 3291, 3292, 3292, 3292, 3292, 3292, 3293, + 3293, 3293, 3293, 3293, 3294, 3294, 3294, 3295, 3295, 3295, + 3295, 3295, 3296, 3296, 3296, 3296, 3296, 3297, 3297, 3298, + 3298, 3298, 3298, 3298, 3299, 3299, 3299, 3299, 3299, 3300, + 3300, 3300, 3300, 3300, 3301, 3301, 3301, 3301, 3301, 3302, + 3302, 3302, 3302, 3302, 3303, 3303, 3303, 3303, 3303, 3304, + 3304, 3304, 3304, 3304, 3304, 3305, 3305, 3305, 3305, 3305, + 3306, 3306, 3306, 3306, 3307, 3307, 3307, 3307, 3308, 3308, + 3308, 3308, 3308, 3309, 3309, 3309, 3309, 3310, 3310, 3310, + 3310, 3310, 3311, 3311, 3311, 3311, 3312, 3312, 3312, 3312, + 3312, 3313, 3313, 3316, 3316, 3316, 3316, 3316, 3316, 3316, + 3316, 3316, 3316, 3316, 3317, 3317, 3317, 3317, 3317, 3317, + 3317, 3317, 3317, 3317, 3318, 3318, 3322, 3326, 3333, 3337, + 3344, 3348, 3355, 3359, 3363, 3367, 3371, 3375, 3379, 3383, + 3387, 3391, 3395, 3399, 3403, 3407, 3411, 3415, 3419, 3423, + 3427, 3431, 3435, 3439, 3443, 3447, 3451, 3455, 3459, 3463, + 3467, 3471, 3475, 3479, 3483, 3487, 3491, 3495, 3499, 3503, + 3507, 3511, 3519, 3523, 3527, 3531, 3535, 3539, 3543, 3553, + 3563, 3569, 3575, 3581, 3587, 3593, 3599, 3605, 3612, 3619, + 3626, 3633, 3639, 3645, 3649, 3653, 3657, 3661, 3665, 3669, + 3680, 3691, 3695, 3699, 3703, 3707, 3711, 3715, 3719, 3723, + 3727, 3731, 3735, 3739, 3743, 3747, 3751, 3755, 3759, 3763, + 3767, 3771, 3775, 3779, 3783, 3787, 3791, 3795, 3799, 3803, + 3807, 3811, 3815, 3819, 3826, 3830, 3834, 3838, 3842, 3846, + 3850, 3854, 3858, 3864, 3870, 3874, 3881, 3889, 3893, 3897, + 3901, 3905, 3909, 3913, 3917, 3921, 3925, 3929, 3933, 3937, + 3941, 3945, 3949, 3953, 3957, 3971, 3975, 3979, 3983, 3987, + 3991, 3995, 3999, 4003, 4007, 4011, 4015, 4019, 4030, 4041, + 4045, 4049, 4053, 4057, 4061, 4065, 4069, 4073, 4077, 4081, + 4085, 4089, 4093, 4097, 4101, 4105, 4109, 4113, 4117, 4121, + 4125, 4129, 4133, 4137, 4141, 4145, 4149, 4153, 4157, 4161, + 4168, 4172, 4176, 4180, 4184, 4188, 4192, 4196, 4200, 4206, + 4212, 4220, 4224, 4228, 4232, 4239, 4249, 4255, 4261, 4271, + 4283, 4291, 4295, 4325, 4329, 4333, 4337, 4341, 4345, 4351, + 4355, 4359, 4363, 4367, 4378, 4382, 4386, 4390, 4398, 4402, + 4406, 4412, 4423 }; #endif @@ -1147,11 +1148,11 @@ static const char *const yytname[] = "empty_instance_identifier", "type", "type_pack", "type_decl", "predefined_type", "var_type_decl", "full_type", "anonymous_struct", "$@17", "named_struct", "$@18", "maybe_final", "maybe_class_derivation", - "class_derivation", "base_specification", "enum", "enum_decl", + "class_derivation", "base_specification", "enum", "$@19", "enum_decl", "enum_element_type", "enum_body_trailing_comma", "enum_body", - "enum_keyword", "struct_keyword", "namespace_declaration", "$@19", - "$@20", "using_declaration", "simple_type", "simple_int_type", - "simple_float_type", "simple_void_type", "code", "$@21", "code_block", + "enum_keyword", "struct_keyword", "namespace_declaration", "$@20", + "$@21", "using_declaration", "simple_type", "simple_int_type", + "simple_float_type", "simple_void_type", "code", "$@22", "code_block", "element", "optional_const_expr", "optional_const_expr_comma", "const_expr_comma", "no_angle_bracket_const_expr", "const_expr", "const_operand", "formal_const_expr", "formal_const_operand", @@ -1166,12 +1167,12 @@ yysymbol_name (yysymbol_kind_t yysymbol) } #endif -#define YYPACT_NINF (-1076) +#define YYPACT_NINF (-1070) #define yypact_value_is_default(Yyn) \ ((Yyn) == YYPACT_NINF) -#define YYTABLE_NINF (-777) +#define YYTABLE_NINF (-778) #define yytable_value_is_error(Yyn) \ 0 @@ -1180,173 +1181,174 @@ yysymbol_name (yysymbol_kind_t yysymbol) STATE-NUM. */ static const yytype_int16 yypact[] = { - 417, -1076, 4272, 6265, 143, 61, -1076, -1076, -1076, -1076, - -1076, -1076, -1076, -1076, -89, -14, -9, 25, 37, 49, - 76, -49, 117, 146, -1076, -1076, 145, 148, 152, 154, - 168, 172, 174, 179, 200, 208, 232, 235, 249, 253, - 256, 287, 304, 335, 348, 365, 6529, 4272, -1076, -1076, - 186, 376, 384, 2182, 254, -1076, 386, 395, 400, 4272, - 4272, 4272, 4272, 4272, 2842, 845, 4272, 4149, -1076, 114, - -1076, -1076, -1076, -1076, -1076, -1076, -1076, -1076, -1076, 6384, - 401, -1076, 8, -1076, -1076, 2327, 4831, 4831, -1076, 5163, - 406, -1076, 4831, -1076, -1076, 478, 478, -1076, -1076, -1076, - -1076, 427, 245, 245, -1076, -1076, -1076, -1076, -1076, 5119, - 413, 340, -1076, 4272, 4272, 6265, 4272, 4272, 4272, 4272, - 4272, 6265, 4272, 6265, 4272, 6265, 4272, 6265, 6265, 6265, - 6265, 6265, 6265, 6265, 6265, 6265, 6265, 6265, 6265, 6265, - 6265, 6265, 6265, 4272, -1076, -1076, 414, 5163, 422, 430, - 245, 245, -1076, 5381, 6265, 4272, 4272, 435, 2842, 228, - 6265, 2842, 4272, 4272, 228, 228, 228, 228, 228, -89, - -9, 25, 37, 49, 76, 117, 145, 152, 3616, 5935, - 6113, 6727, 400, 437, -101, 4149, -1076, -1076, -1076, -1076, - -1076, -1076, -1076, -1076, -1076, -1076, -1076, -1076, 5163, 5163, - -114, 454, -1076, -1076, 228, 4272, 4272, 4272, 4272, 4272, - 4272, 4272, 4272, 4272, 4272, 4272, 4272, 4272, 4272, 4272, - 4272, 4272, 4272, 4272, 4272, 4272, 5163, 3278, 4272, -1076, - -1076, 478, 478, 3420, -1076, -1076, -1076, 4831, -1076, -1076, - -1076, -1076, 6265, -1076, 421, 632, 245, 478, 478, 245, - 245, 109, 443, -1076, 447, -1076, -1076, 139, 2016, 5163, - 576, 473, 464, 2989, -1076, 6815, 462, 484, -1076, 467, - 475, 480, 482, 488, 489, 490, 483, 499, 508, 503, - 504, 505, 506, 527, 509, -81, 529, 514, 515, 518, - 519, 520, 521, 522, 524, 536, 538, 542, 544, 4272, - -1076, 6265, 4272, 5163, 5163, -1076, 539, 552, 553, 5163, - 556, 567, 559, 5402, 564, 566, 4272, 4272, -1076, 686, - -1076, 1071, 569, 4272, -1076, -1076, 2317, 5871, 1747, 1747, - 635, 635, 1356, 731, 731, -1076, 5696, 5888, 1569, 1956, - 635, 635, 135, 135, 228, 228, 228, -1076, -1076, -64, - 2201, -1076, -1076, 571, 5421, 572, 245, 245, 316, 443, - -1076, 443, -1076, 316, 316, -1076, 245, 245, 245, 6172, - 574, 29, -1076, 575, 4272, 5163, 568, -1076, -1076, -1076, - -1076, -1076, 2083, 593, 11, 171, 173, 182, -1076, -1076, - -1076, 604, 245, 5163, 4777, -89, -1076, 591, 5163, 596, - 597, -1076, -1076, -1076, 245, 245, -1076, 5440, -1076, 6924, - 6924, 6924, 6924, 6924, -1076, 6924, 5934, 6924, 4272, 613, - -1076, 6920, 600, 601, 603, 605, 606, 607, 6924, 32, - 619, 624, 625, 6924, 6924, 614, 6737, 6924, 6924, 5005, - 6924, 6924, -1076, -1076, -1076, 5050, -1076, -1076, -1076, -1076, - -1076, -1076, -1076, -1076, -1076, -1076, -1076, -1076, -1076, 616, - -1076, 617, -1076, -1076, -1076, -1076, 6265, -1076, 6265, -1076, - 6265, -1076, -1076, -1076, -1076, -1076, -1076, -1076, -1076, -1076, - -1076, -1076, -1076, 5480, 611, 622, -1076, -1076, 618, -1076, - -1076, 623, 4414, 626, -1076, -1076, -1076, -1076, 228, 4149, - -1076, 5163, 454, 40, 1061, -1076, 4149, 4272, -1076, -1076, - -1076, -1076, -1076, 316, 636, 644, 5163, 245, 316, 316, - 245, 245, 640, -1076, 640, 640, 316, 316, 316, 6291, - 245, 257, 537, -1076, -1076, 56, 637, 4149, -1076, 245, - -1076, -1076, -1076, -1076, 2083, -1076, 710, 5163, -1076, -1076, - -1076, -1076, -1076, -1076, -1076, -1076, 627, 654, 658, -1076, - -1076, 6529, -1076, -1076, 660, 4919, 661, -1076, 657, 4272, - 4272, 4272, 4272, 2842, 4272, 663, 41, -1076, -1076, 4433, - -1076, 114, 665, 3562, -1076, 6265, 245, 1565, 2016, 245, - 6065, 6924, -1076, -1076, -1076, -1076, -1076, -1076, 6924, -1076, - -1076, -1076, 5499, -1076, 6815, 4614, -1076, 5163, 5163, 5163, - 5163, 5163, 5163, -1076, -1076, 5163, -1076, -1076, -1076, -1076, - -1076, 4272, -1076, 5154, -1076, 672, -1076, 5247, -1076, 5163, - 5163, 84, -1076, -1076, 377, 668, 6410, -1076, 5163, -1076, - 336, 685, -1076, 4272, 4272, 670, 671, 679, -1076, -1076, - -1076, 4272, -1076, 4272, -1076, 680, -1076, -1076, -1076, -1076, - -1076, -1076, 4272, -1076, 674, -1076, -1076, 808, 4149, 640, - 245, 245, 316, 640, 640, 316, 316, 4272, -77, 87, - 104, 6384, 257, 537, -1076, 691, 245, 257, 257, 245, - 245, 257, -105, 245, -1076, 692, 5163, 245, 537, 537, - 245, 245, 537, -98, 1061, -1076, -1076, 245, 77, 707, - 51, -1076, 706, -1076, 816, 6265, 6265, 6265, 694, 6265, - 695, 2842, 271, 6265, 2842, 228, 228, 228, 228, 696, - 120, 228, -1076, -1076, 4801, 4272, 4272, 4272, 4272, 4272, - 4272, 4272, 4272, 4272, 4272, 4272, 4272, 4272, 4272, 4272, - 4272, 4272, 4272, 4272, 4272, 4272, 5163, 3704, 4272, 697, - 5599, 698, -1076, -1076, 711, -1076, -1076, -1076, 6924, -1076, - -1076, 715, 718, 720, 722, 723, 725, 728, 52, 732, - 5321, 6076, 399, 713, 336, -1076, -1076, 734, 735, -1076, - 729, -1076, 57, 6622, 498, -1076, 716, 130, -1076, -1076, - 3136, -1076, -1076, 712, 126, 144, -1076, -1076, -1076, 158, - 167, -1076, 5658, 494, 6503, 738, -1076, 316, -1076, 640, - 640, 640, 724, 733, 737, 739, 257, 537, -105, -98, - 245, 257, 741, 741, 257, 257, 164, 4272, -1076, -1076, - 245, 245, 537, 742, 742, 537, 537, 216, 4272, -1076, - 808, 743, -1076, 4272, -1076, 4755, 756, 740, -1076, 245, - 744, 748, 753, 4272, 755, 5163, 746, 759, 750, 5677, - 4272, -1076, -1076, -1076, 2317, 5871, 1747, 1747, 635, 635, - 1356, 731, 731, -1076, 5715, 5888, 1569, 1956, 635, 635, - 135, 135, 228, 228, 228, -1076, -1076, 187, 2862, -1076, - -1076, -1076, 2083, -1076, 90, -1076, 918, 921, 922, 923, - 925, 926, -1076, -1076, 177, 781, -1076, -1076, -1076, -1076, - 6139, -1076, 776, 786, 6707, -1076, 118, -1076, -1076, 35, - -1076, 712, -1076, -1076, 6265, 40, 770, 778, 712, 40, - 498, 780, 245, 498, 498, 245, 245, 183, 245, -1076, - 97, -1076, -1076, -1076, 5163, 328, -1076, 771, -1076, 792, - 793, 3846, 3439, 783, 245, 712, 4985, 712, 245, 245, - 712, -1076, 3, 405, 245, -1076, -1076, -1076, -1076, 1061, - -1076, -1076, 18, 6529, 478, -1076, 640, 245, 40, 40, - 40, -105, -98, -1076, -1076, 257, 741, 741, 741, 782, - 775, 537, -1076, 742, 742, 742, 787, 785, -1076, 3865, - 5241, 6616, 6631, 5163, 333, -1076, -1076, 943, -1076, 4755, - -1076, -1076, 795, 797, 796, 804, 803, 4414, 806, -1076, - -1076, 228, 4272, -1076, -1076, 707, -1076, -1076, 824, 192, - 825, 829, 830, 831, -1076, 34, -1076, 118, 6893, 6076, - 5163, 834, 826, 245, 118, 118, 245, 245, 118, -92, - 742, -1076, 405, 839, 822, 827, 712, 458, 823, 258, - 245, 498, 828, 828, 498, 498, -1076, 4272, -1076, -1076, - 40, 835, 330, -1076, -65, 842, 844, -1076, 2665, -1076, - -1076, -1076, 3846, 836, 847, 4149, -1076, -1076, 245, 712, - 392, 995, -1076, -1076, -1076, -1076, -1076, -1076, -1076, -1076, - -1076, -1076, -1076, -1076, -1076, -1076, -1076, -1076, -1076, -1076, - -1076, -1076, -1076, -1076, -1076, -1076, -1076, -1076, -1076, -1076, - -1076, -1076, -1076, -1076, -1076, -1076, -1076, -1076, -1076, 832, - 837, -1076, 245, 392, 712, 712, 461, 4272, -1076, 4272, - -1076, 3136, 858, -1076, -1076, 808, 841, -1076, 478, -1076, - 843, -1076, 846, 849, 850, -1076, -1076, 741, 40, 245, - 742, 40, 245, -1076, 6653, -1076, 6653, -1076, 6653, -1076, - -1076, 6653, 6653, 6653, -1076, 98, -1076, 4272, 4272, -1076, - 4272, -1076, 4272, 4149, 116, 1006, 1009, 865, 1016, 853, - -1076, 1020, 1021, 1022, 195, 877, -92, 742, -1076, -1076, - -1076, -1076, -1076, -1076, 6265, 245, 118, 118, 118, 1246, - -1076, -1076, 879, -1076, -1076, -1076, -1076, 479, 866, -1076, - -1076, 498, 828, 828, 828, 40, 860, 867, -1076, -1076, - 5163, 4272, 4272, -1076, -1076, -1076, -1076, -1076, -1076, -1076, - -1076, -1076, -1076, -1076, -1076, -1076, -1076, -1076, -1076, -1076, - -1076, -1076, -1076, -1076, -1076, -1076, -1076, -1076, -1076, -1076, - -1076, -1076, -1076, -1076, -1076, -1076, -1076, -1076, -1076, -1076, - -1076, -1076, -1076, -1076, -1076, -1076, -1076, -1076, -1076, -1076, - -1076, -1076, -1076, -1076, -1076, -1076, -1076, -1076, -1076, -1076, - -1076, -1076, -1076, -1076, -1076, -1076, -1076, -1076, -1076, -1076, - -1076, -1076, -1076, -1076, -1076, -1076, -1076, -1076, -1076, -1076, - -1076, -1076, -1076, -1076, -1076, -1076, -1076, -1076, -1076, -1076, - -1076, -1076, -1076, -1076, -1076, -1076, -1076, -1076, -1076, -1076, - -1076, -1076, -1076, -1076, -1076, -1076, -1076, -1076, -1076, -1076, - -1076, -1076, -1076, -1076, -1076, -1076, -1076, -1076, -1076, -1076, - -1076, -1076, -1076, -1076, -1076, -1076, -1076, -1076, -1076, -1076, - -1076, -1076, -1076, -1076, -1076, -1076, -1076, -1076, -1076, -1076, - -1076, -1076, 869, -1076, 3988, 712, 392, 245, -1076, -1076, - -1076, 392, 392, -1076, 4149, 4777, 863, 3439, 712, 891, - -1076, -1076, -1076, -1076, -1076, -1076, 874, -1076, 875, -1076, - -1076, -1076, -1076, -1076, -1076, -1076, -1076, 197, 205, 229, - 239, -1076, 878, 267, -1076, 896, 900, 291, 885, 303, - -1076, -1076, -1076, -1076, 118, 888, 899, 901, 902, 4556, - 903, 1246, 1246, 1246, 1246, 1246, 2842, 1246, 5758, -1076, - 712, 1061, 40, 895, -1076, 1061, 40, 828, 894, 245, - -1076, 897, -1076, 905, 910, 2488, -1076, 3846, 4149, 392, - -1076, 911, 245, -1076, -1076, 1061, 1061, 1061, -1076, -1076, - -1076, -1076, -1076, -1076, 913, 1065, 915, 1067, -1076, 1076, - 931, 932, 1079, 934, 6265, 6265, 6265, 6265, 920, 2842, - 278, 6265, 278, 278, 278, 278, 278, 919, 308, 278, - 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, - 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 5163, - 4130, 4272, -1076, -1076, 924, -1076, 40, -1076, 927, -1076, - -1076, 1061, -1076, -1076, 1080, -1076, 928, -1076, -1076, 929, - 808, 808, 808, 1061, 1061, -1076, 939, -1076, 933, 942, - -1076, -1076, 312, -1076, 936, 941, 944, 953, 5163, 946, - 954, 1246, -1076, 5776, 1794, 2223, 2223, 1142, 1142, 1397, - 1122, 1122, -1076, 1850, 5932, 5949, 2424, 301, 301, 278, - 278, 278, -1076, -1076, 324, 3154, -1076, 40, 947, -1076, - 702, -1076, -1076, -1076, 1061, -1076, -1076, -1076, -1076, -1076, - -1076, 1112, 950, 970, 1119, 1121, 978, -1076, 968, 969, - 971, 976, 4659, 972, 278, 1246, -1076, -1076, 1061, 977, - -1076, 702, -1076, -1076, 999, -1076, 984, 325, -1076, 4272, - 4272, 4272, -1076, 4272, 5758, -1076, -1076, 1061, -1076, 1003, - 1150, 1005, 326, 342, 364, 369, 1061, 808, -1076, 989, - -1076, -1076, -1076, -1076, -1076, 808, -1076, 1012, -1076, -1076 + 383, -1070, 4549, 6313, 82, 61, -1070, -1070, -1070, -1070, + -1070, -1070, -1070, -1070, -76, -68, -58, -52, -36, 11, + 32, 76, 80, 85, -1070, -1070, 96, 100, 104, 108, + 126, 137, 148, 159, 165, 168, 171, 179, 182, 194, + 205, 215, 230, 255, 264, 268, 6577, 4549, -1070, -1070, + 303, 279, 302, 3413, 318, -1070, 325, 337, 339, 4549, + 4549, 4549, 4549, 4549, 2336, 1461, 4549, 4426, -1070, 319, + -1070, -1070, -1070, -1070, -1070, -1070, -1070, -1070, -1070, 6432, + 341, -1070, 7, -1070, -1070, 6922, 6200, 6200, -1070, 1698, + 346, -1070, 6200, -1070, -1070, 180, 180, -1070, -1070, -1070, + -1070, -1070, 446, 446, -1070, -1070, -1070, -1070, -1070, 2236, + 354, -67, -1070, 4549, 4549, 6313, 4549, 4549, 4549, 4549, + 4549, 6313, 4549, 6313, 4549, 6313, 4549, 6313, 6313, 6313, + 6313, 6313, 6313, 6313, 6313, 6313, 6313, 6313, 6313, 6313, + 6313, 6313, 6313, 4549, -1070, -1070, 365, 1698, 368, 370, + 446, 446, -1070, 5314, 6313, 4549, 4549, 378, 2336, 63, + 6313, 2336, 4549, 4549, 63, 63, 63, 63, 63, -76, + -58, -52, -36, 11, 32, 80, 96, 104, 2791, 3893, + 5236, 5873, 339, 89, -90, 4426, -1070, -1070, -1070, -1070, + -1070, -1070, -1070, -1070, -1070, -1070, -1070, -1070, 1698, 1698, + -74, 235, -1070, -1070, 63, 4549, 4549, 4549, 4549, 4549, + 4549, 4549, 4549, 4549, 4549, 4549, 4549, 4549, 4549, 4549, + 4549, 4549, 4549, 4549, 4549, 4549, 1698, 3555, 4549, -1070, + -1070, 180, 180, 3697, -1070, -1070, -1070, 6200, -1070, -1070, + -1070, -1070, 6313, -1070, 393, 772, 446, 180, 180, 446, + 446, 223, 398, -1070, 407, -1070, 427, 27, 1243, 1698, + 544, 440, 426, 3124, -1070, 6781, 430, 451, -1070, 434, + 435, 436, 439, 441, 445, 447, 437, 449, 450, 453, + 457, 458, 463, 470, 464, -72, 471, 465, 467, 468, + 473, 476, 483, 484, 485, 492, 493, 495, 498, 4549, + -1070, 6313, 4549, 1698, 1698, -1070, 480, 502, 503, 1698, + 504, 515, 507, 5335, 508, 510, 4549, 4549, -1070, 634, + -1070, 1631, 516, 4549, -1070, -1070, 1957, 4686, 4990, 4990, + 1977, 1977, 1054, 853, 853, -1070, 5629, 5804, 5821, 5883, + 1977, 1977, 277, 277, 63, 63, 63, -1070, -1070, -50, + 2563, -1070, -1070, 513, 5354, 517, 446, 446, 151, 398, + -1070, 398, -1070, 151, 151, -1070, 446, 446, 446, 6214, + 520, 33, -1070, 522, 4549, -1070, -1070, -1070, -1070, -1070, + 2052, 541, -9, -8, -4, 20, -1070, -1070, -1070, 542, + 446, 1698, 1329, -76, -1070, 534, 1698, 538, 543, -1070, + -1070, -1070, 446, 446, -1070, 5373, -1070, 6890, 6890, 6890, + 6890, 6890, -1070, 6890, 2485, 6890, 4549, 559, -1070, 6886, + 546, 547, 551, 553, 555, 556, 6890, 83, 576, 578, + 579, 6890, 6890, 557, 6703, 6890, 6890, 6701, 6890, 6890, + -1070, -1070, -1070, 2773, -1070, -1070, -1070, -1070, -1070, -1070, + -1070, -1070, -1070, -1070, -1070, -1070, -1070, 565, -1070, 567, + -1070, -1070, -1070, -1070, 6313, -1070, 6313, -1070, 6313, -1070, + -1070, -1070, -1070, -1070, -1070, -1070, -1070, -1070, -1070, -1070, + -1070, 5413, 568, 569, -1070, -1070, 573, -1070, -1070, 574, + 4691, 575, -1070, -1070, -1070, -1070, 63, 4426, -1070, 1698, + 235, 43, 6053, -1070, 4426, 4549, -1070, -1070, -1070, -1070, + -1070, 151, 580, 584, 1698, 446, 151, 151, 446, 446, + 581, -1070, 581, 581, 151, 151, 151, 6339, 446, 795, + 355, -1070, -1070, 84, 564, 4426, -1070, 1698, 577, -1070, + -1070, -1070, -1070, 2052, -1070, 674, 1698, -1070, -1070, -1070, + -1070, -1070, -1070, -1070, -1070, 585, 593, 595, -1070, -1070, + 6577, -1070, -1070, 597, 2161, 601, -1070, 594, 4549, 4549, + 4549, 4549, 2336, 4549, 591, 56, -1070, -1070, 4710, -1070, + 319, 598, 3839, -1070, 6313, 446, 2436, 1243, 446, 6074, + 6890, -1070, -1070, -1070, -1070, -1070, -1070, 6890, -1070, -1070, + -1070, 5432, -1070, 6781, 1796, -1070, 1698, 1698, 1698, 1698, + 1698, 1698, -1070, -1070, 1698, -1070, -1070, -1070, -1070, -1070, + 4549, -1070, 5059, -1070, 605, -1070, 5180, -1070, 1698, 1698, + 58, -1070, -1070, 307, 602, 6458, -1070, 1698, -1070, 213, + 617, -1070, 4549, 4549, 603, 604, 607, -1070, -1070, -1070, + 4549, -1070, 4549, -1070, 611, -1070, -1070, -1070, -1070, -1070, + -1070, 4549, -1070, 614, -1070, -1070, 741, 4426, 581, 446, + 446, 151, 581, 581, 151, 151, 4549, -15, 246, 283, + 6432, 795, 355, -1070, 620, 446, 795, 795, 446, 446, + 795, -83, 446, -1070, 621, 1698, 446, 355, 355, 446, + 446, 355, 9, 6053, -1070, -1070, 446, 446, -1070, 635, + 3, -1070, 633, -1070, 742, 6313, 6313, 6313, 626, 6313, + 628, 2336, 88, 6313, 2336, 63, 63, 63, 63, 627, + -48, 63, -1070, -1070, 1877, 4549, 4549, 4549, 4549, 4549, + 4549, 4549, 4549, 4549, 4549, 4549, 4549, 4549, 4549, 4549, + 4549, 4549, 4549, 4549, 4549, 4549, 1698, 3981, 4549, 629, + 5532, 630, -1070, -1070, 645, -1070, -1070, -1070, 6890, -1070, + -1070, 655, 656, 659, 660, 662, 664, 665, 50, 667, + 5254, 6121, 399, 650, 213, -1070, -1070, 668, 670, -1070, + 671, -1070, 49, 6670, 216, -1070, 663, 391, -1070, -1070, + 3271, -1070, -1070, 651, -11, -3, -1070, -1070, -1070, 5, + 150, -1070, 5591, 572, 6551, 683, -1070, 151, -1070, 581, + 581, 581, 661, 669, 672, 673, 795, 355, -83, 9, + 446, 795, 666, 666, 795, 795, 317, 4549, -1070, -1070, + 446, 446, 355, 678, 678, 355, 355, 328, 4549, -1070, + 741, 679, 161, -1070, 2448, 688, 691, -1070, 446, 681, + 692, 694, 4549, 695, 1698, 686, 698, 689, 5610, 4549, + -1070, -1070, -1070, 1957, 4686, 4990, 4990, 1977, 1977, 1054, + 853, 853, -1070, 5648, 5804, 5821, 5883, 1977, 1977, 277, + 277, 63, 63, 63, -1070, -1070, 206, 3143, -1070, -1070, + -1070, 2052, -1070, 87, -1070, 833, 854, 855, 856, 857, + 862, -1070, -1070, 397, 718, -1070, -1070, -1070, -1070, 6174, + -1070, 717, 736, 5128, -1070, 997, -1070, -1070, 54, -1070, + 651, -1070, -1070, 6313, 43, 722, 731, 651, 43, 216, + 732, 446, 216, 216, 446, 446, 51, 446, -1070, 91, + -1070, -1070, -1070, 1698, 101, -1070, 728, -1070, 748, 749, + 4123, 3716, 745, 446, 651, 5058, 651, 446, 446, 651, + -1070, 176, 400, 446, -1070, -1070, -1070, -1070, 6053, -1070, + -1070, 25, 6577, 180, -1070, 581, 446, 43, 43, 43, + -83, 9, -1070, -1070, 795, 666, 666, 666, 744, 740, + 355, -1070, 678, 678, 678, 750, 746, -1070, -1070, 4549, + 2803, 6664, 6679, 1698, 452, -1070, -1070, 906, -1070, 2448, + -1070, -1070, 753, 754, 755, 756, 757, 4691, 758, -1070, + -1070, 63, 4549, -1070, -1070, 635, -1070, -1070, 777, 220, + 779, 780, 781, 785, -1070, 48, -1070, 997, 6859, 6121, + 1698, 769, 783, 446, 997, 997, 446, 446, 997, 17, + 678, -1070, 400, 788, 773, 774, 651, 404, 778, 348, + 446, 216, 775, 775, 216, 216, -1070, 4549, -1070, -1070, + 43, 776, 409, -1070, -62, 797, 798, -1070, 2949, -1070, + -1070, -1070, 4123, 786, 800, 4426, -1070, -1070, 446, 651, + 395, 948, -1070, -1070, -1070, -1070, -1070, -1070, -1070, -1070, + -1070, -1070, -1070, -1070, -1070, -1070, -1070, -1070, -1070, -1070, + -1070, -1070, -1070, -1070, -1070, -1070, -1070, -1070, -1070, -1070, + -1070, -1070, -1070, -1070, -1070, -1070, -1070, -1070, -1070, 790, + 789, -1070, 446, 395, 651, 651, 413, 4549, -1070, 4549, + -1070, 3271, 814, -1070, -1070, 741, 799, -1070, 180, -1070, + 802, -1070, 806, 807, 809, -1070, -1070, 666, 43, 446, + 678, 43, 446, 4142, 2809, -1070, 2809, -1070, 2809, -1070, + -1070, 2809, 2809, 2809, -1070, 217, -1070, 4549, 4549, -1070, + 4549, -1070, 4549, 4426, 284, 962, 964, 828, 975, 817, + -1070, 982, 986, 988, 305, 843, 17, 678, -1070, -1070, + -1070, -1070, -1070, -1070, 6313, 446, 997, 997, 997, 4833, + -1070, -1070, 845, -1070, -1070, -1070, -1070, 418, 830, -1070, + -1070, 216, 775, 775, 775, 43, 826, 832, -1070, -1070, + 1698, 4549, 4549, -1070, -1070, -1070, -1070, -1070, -1070, -1070, + -1070, -1070, -1070, -1070, -1070, -1070, -1070, -1070, -1070, -1070, + -1070, -1070, -1070, -1070, -1070, -1070, -1070, -1070, -1070, -1070, + -1070, -1070, -1070, -1070, -1070, -1070, -1070, -1070, -1070, -1070, + -1070, -1070, -1070, -1070, -1070, -1070, -1070, -1070, -1070, -1070, + -1070, -1070, -1070, -1070, -1070, -1070, -1070, -1070, -1070, -1070, + -1070, -1070, -1070, -1070, -1070, -1070, -1070, -1070, -1070, -1070, + -1070, -1070, -1070, -1070, -1070, -1070, -1070, -1070, -1070, -1070, + -1070, -1070, -1070, -1070, -1070, -1070, -1070, -1070, -1070, -1070, + -1070, -1070, -1070, -1070, -1070, -1070, -1070, -1070, -1070, -1070, + -1070, -1070, -1070, -1070, -1070, -1070, -1070, -1070, -1070, -1070, + -1070, -1070, -1070, -1070, -1070, -1070, -1070, -1070, -1070, -1070, + -1070, -1070, -1070, -1070, -1070, -1070, -1070, -1070, -1070, -1070, + -1070, -1070, -1070, -1070, -1070, -1070, -1070, -1070, -1070, -1070, + -1070, -1070, 840, -1070, 4265, 651, 395, 446, -1070, -1070, + -1070, 395, 395, -1070, 4426, 1329, 846, 3716, 651, 874, + -1070, -1070, -1070, -1070, -1070, -1070, 858, -1070, 859, -1070, + -1070, -1070, -1070, -1070, -1070, -1070, -1070, -1070, 221, 224, + 226, 227, -1070, 860, 242, -1070, 875, 873, 249, 861, + 273, -1070, -1070, -1070, -1070, 997, 865, 868, 877, 878, + 1932, 879, 4833, 4833, 4833, 4833, 4833, 2336, 4833, 5710, + -1070, 651, 6053, 43, 866, -1070, 6053, 43, 775, 870, + 446, -1070, 876, -1070, 881, 871, 2632, -1070, 4123, 4426, + 395, -1070, 886, 446, -1070, -1070, 6053, 6053, 6053, -1070, + -1070, -1070, -1070, -1070, -1070, 892, 1039, 894, 1042, -1070, + 1052, 910, 911, 1058, 913, 6313, 6313, 6313, 6313, 899, + 2336, 131, 6313, 131, 131, 131, 131, 131, 901, 286, + 131, 4833, 4833, 4833, 4833, 4833, 4833, 4833, 4833, 4833, + 4833, 4833, 4833, 4833, 4833, 4833, 4833, 4833, 4833, 4833, + 1698, 4407, 4549, -1070, -1070, 908, -1070, 43, -1070, 915, + -1070, -1070, 6053, -1070, -1070, 1065, -1070, 909, -1070, -1070, + 917, 741, 741, 741, 6053, 6053, -1070, 935, -1070, 919, + 939, -1070, -1070, 288, -1070, 924, 940, 944, 945, 1698, + 936, 947, 4833, -1070, 1180, 5866, 5975, 5975, 2202, 2202, + 1127, 934, 934, -1070, 5691, 5900, 5917, 5926, 536, 536, + 131, 131, 131, -1070, -1070, 297, 3432, -1070, 43, 942, + -1070, 535, -1070, -1070, -1070, 6053, -1070, -1070, -1070, -1070, + -1070, -1070, 1103, 946, 958, 1108, 1111, 966, -1070, 951, + 952, 953, 956, 4936, 954, 131, 4833, -1070, -1070, 6053, + 959, -1070, 535, -1070, -1070, 971, -1070, 960, 298, -1070, + 4549, 4549, 4549, -1070, 4549, 5710, -1070, -1070, 6053, -1070, + 979, 1126, 981, 299, 314, 331, 332, 6053, 741, -1070, + 965, -1070, -1070, -1070, -1070, -1070, 741, -1070, 985, -1070, + -1070 }; /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. @@ -1354,207 +1356,208 @@ static const yytype_int16 yypact[] = means the default is an error. */ static const yytype_int16 yydefact[] = { - 0, 781, 0, 0, 0, 781, 5, 667, 663, 666, - 777, 778, 669, 670, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 665, 671, 0, 0, 0, 0, + 0, 782, 0, 0, 0, 782, 5, 668, 664, 667, + 778, 779, 670, 671, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 666, 672, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 673, 672, - 0, 0, 0, 0, 0, 664, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 781, 0, 3, 601, 668, - 305, 316, 315, 396, 397, 399, 400, 401, 380, 0, - 0, 412, 377, 411, 406, 403, 402, 405, 381, 0, - 0, 382, 404, 414, 398, 781, 781, 4, 307, 308, - 309, 0, 781, 781, 304, 393, 394, 395, 1, 0, - 0, 7, 63, 781, 781, 0, 781, 781, 781, 781, - 781, 0, 781, 0, 781, 0, 781, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 674, 673, + 0, 0, 0, 0, 0, 665, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 782, 0, 3, 602, 669, + 305, 316, 315, 397, 398, 400, 401, 402, 381, 0, + 0, 413, 378, 412, 407, 404, 403, 406, 382, 0, + 0, 383, 405, 415, 399, 782, 782, 4, 307, 308, + 309, 364, 782, 782, 304, 394, 395, 396, 1, 0, + 0, 7, 63, 782, 782, 0, 782, 782, 782, 782, + 782, 0, 782, 0, 782, 0, 782, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 781, 331, 337, 0, 0, 0, 626, - 781, 781, 330, 0, 0, 781, 781, 0, 0, 623, - 0, 0, 781, 781, 635, 633, 632, 634, 631, 305, - 396, 397, 399, 400, 401, 412, 411, 406, 403, 402, - 405, 404, 398, 0, 0, 559, 762, 763, 764, 772, - 765, 768, 766, 770, 769, 767, 771, 751, 752, 0, - 0, 781, 757, 750, 630, 0, 0, 0, 0, 0, + 0, 0, 0, 782, 331, 337, 0, 0, 0, 627, + 782, 782, 330, 0, 0, 782, 782, 0, 0, 624, + 0, 0, 782, 782, 636, 634, 633, 635, 632, 305, + 397, 398, 400, 401, 402, 413, 412, 407, 404, 403, + 406, 405, 399, 0, 0, 560, 763, 764, 765, 773, + 766, 769, 767, 771, 770, 768, 772, 752, 753, 0, + 0, 782, 758, 751, 631, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 779, - 780, 781, 781, 0, 378, 379, 413, 403, 408, 407, - 410, 306, 0, 409, 0, 291, 781, 781, 781, 781, - 781, 781, 0, 340, 290, 342, 781, 366, 0, 0, - 0, 68, 70, 0, 6, 781, 0, 558, 557, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 780, + 781, 782, 782, 0, 379, 380, 414, 404, 409, 408, + 411, 306, 0, 410, 0, 291, 782, 782, 782, 782, + 782, 782, 0, 340, 290, 342, 0, 367, 0, 0, + 0, 68, 70, 0, 6, 782, 0, 559, 558, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 332, 0, 781, 0, 0, 659, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 662, 755, - 758, 0, 781, 0, 753, 220, 644, 645, 646, 647, - 648, 649, 650, 653, 654, 661, 0, 641, 642, 643, - 651, 652, 639, 640, 636, 637, 638, 660, 658, 0, - 0, 341, 343, 0, 0, 0, 781, 781, 781, 0, - 293, 0, 294, 781, 781, 205, 781, 781, 781, 0, - 0, 206, 209, 63, 781, 374, 0, 371, 773, 774, - 775, 776, 0, 368, 762, 763, 764, 766, 344, 310, - 346, 0, 781, 0, 781, 318, 329, 0, 0, 0, - 0, 320, 321, 322, 781, 781, 317, 0, 22, 781, - 781, 781, 781, 781, 23, 781, 781, 781, 0, 0, - 43, 781, 0, 0, 0, 0, 0, 0, 781, 781, - 0, 0, 0, 781, 781, 0, 781, 781, 781, 0, - 781, 781, 18, 8, 20, 0, 16, 17, 19, 78, - 45, 608, 607, 625, 615, 610, 612, 613, 614, 0, - 621, 0, 620, 676, 609, 677, 0, 679, 0, 680, - 0, 683, 684, 685, 686, 687, 688, 689, 690, 691, - 692, 693, 617, 0, 0, 0, 334, 333, 0, 616, - 619, 0, 622, 0, 628, 629, 618, 611, 602, 560, - 756, 0, 781, 781, 781, 103, 221, 0, 657, 656, - 313, 312, 314, 781, 292, 0, 281, 781, 781, 781, - 781, 781, 297, 280, 296, 295, 781, 781, 781, 0, - 781, 781, 0, 781, 208, 781, 0, 556, 555, 781, - 364, 370, 365, 369, 0, 781, 781, 0, 64, 69, - 743, 739, 742, 745, 746, 212, 0, 0, 0, 741, - 747, 0, 749, 748, 0, 0, 0, 740, 0, 0, - 0, 0, 0, 0, 0, 0, 213, 247, 216, 248, - 694, 744, 63, 0, 319, 0, 781, 366, 0, 781, - 781, 781, 60, 46, 57, 58, 59, 61, 781, 47, - 160, 52, 0, 24, 781, 0, 50, 0, 0, 0, - 0, 0, 0, 56, 781, 0, 27, 26, 25, 54, - 49, 0, 164, 0, 163, 0, 62, 0, 21, 0, - 0, 781, 51, 55, 339, 318, 0, 14, 0, 75, - 0, 338, 72, 0, 0, 0, 0, 0, 335, 336, - 627, 0, 624, 0, 754, 0, 111, 104, 113, 108, - 112, 106, 0, 109, 0, 105, 110, 781, 655, 298, - 781, 781, 781, 283, 284, 781, 781, 781, 0, 0, - 0, 0, 781, 0, 246, 0, 781, 781, 781, 781, - 781, 781, 781, 781, 258, 0, 269, 781, 0, 0, - 781, 781, 0, 781, 781, 207, 210, 781, 375, 311, - 781, 349, 781, 348, 0, 0, 0, 0, 704, 0, - 0, 0, 701, 0, 0, 712, 711, 710, 709, 0, - 0, 708, 71, 215, 781, 0, 0, 0, 0, 0, + 332, 0, 782, 0, 0, 660, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 663, 756, + 759, 0, 782, 0, 754, 220, 645, 646, 647, 648, + 649, 650, 651, 654, 655, 662, 0, 642, 643, 644, + 652, 653, 640, 641, 637, 638, 639, 661, 659, 0, + 0, 341, 343, 0, 0, 0, 782, 782, 782, 0, + 293, 0, 294, 782, 782, 205, 782, 782, 782, 0, + 0, 206, 209, 63, 782, 782, 774, 775, 776, 777, + 0, 369, 763, 764, 765, 767, 344, 310, 346, 0, + 782, 0, 782, 318, 329, 0, 0, 0, 0, 320, + 321, 322, 782, 782, 317, 0, 22, 782, 782, 782, + 782, 782, 23, 782, 782, 782, 0, 0, 43, 782, + 0, 0, 0, 0, 0, 0, 782, 782, 0, 0, + 0, 782, 782, 0, 782, 782, 782, 0, 782, 782, + 18, 8, 20, 0, 16, 17, 19, 78, 45, 609, + 608, 626, 616, 611, 613, 614, 615, 0, 622, 0, + 621, 677, 610, 678, 0, 680, 0, 681, 0, 684, + 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, + 618, 0, 0, 0, 334, 333, 0, 617, 620, 0, + 623, 0, 629, 630, 619, 612, 603, 561, 757, 0, + 782, 782, 782, 103, 221, 0, 658, 657, 313, 312, + 314, 782, 292, 0, 281, 782, 782, 782, 782, 782, + 297, 280, 296, 295, 782, 782, 782, 0, 782, 782, + 0, 782, 208, 782, 0, 557, 556, 375, 0, 372, + 371, 366, 370, 0, 782, 782, 0, 64, 69, 744, + 740, 743, 746, 747, 212, 0, 0, 0, 742, 748, + 0, 750, 749, 0, 0, 0, 741, 0, 0, 0, + 0, 0, 0, 0, 0, 213, 247, 216, 248, 695, + 745, 63, 0, 319, 0, 782, 367, 0, 782, 782, + 782, 60, 46, 57, 58, 59, 61, 782, 47, 160, + 52, 0, 24, 782, 0, 50, 0, 0, 0, 0, + 0, 0, 56, 782, 0, 27, 26, 25, 54, 49, + 0, 164, 0, 163, 0, 62, 0, 21, 0, 0, + 782, 51, 55, 339, 318, 0, 14, 0, 75, 0, + 338, 72, 0, 0, 0, 0, 0, 335, 336, 628, + 0, 625, 0, 755, 0, 111, 104, 113, 108, 112, + 106, 0, 109, 0, 105, 110, 782, 656, 298, 782, + 782, 782, 283, 284, 782, 782, 782, 0, 0, 0, + 0, 782, 0, 246, 0, 782, 782, 782, 782, 782, + 782, 782, 782, 258, 0, 269, 782, 0, 0, 782, + 782, 0, 782, 782, 207, 210, 782, 782, 365, 311, + 782, 349, 782, 348, 0, 0, 0, 0, 705, 0, + 0, 0, 702, 0, 0, 713, 712, 711, 710, 0, + 0, 709, 71, 215, 782, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 67, 325, 368, 323, 66, 48, 781, 44, - 781, 0, 0, 0, 0, 0, 0, 0, 781, 0, - 0, 781, 339, 318, 0, 338, 81, 0, 0, 389, - 0, 86, 90, 0, 781, 781, 0, 0, 415, 227, - 0, 77, 74, 0, 0, 0, 678, 681, 682, 0, - 0, 781, 0, 0, 0, 0, 199, 781, 282, 287, - 286, 285, 0, 0, 0, 0, 781, 0, 781, 781, - 781, 781, 260, 261, 781, 781, 0, 781, 240, 259, - 781, 781, 0, 271, 272, 0, 0, 0, 781, 243, - 781, 299, 372, 0, 345, 0, 0, 351, 350, 781, - 0, 0, 0, 781, 0, 0, 0, 0, 0, 0, - 0, 738, 214, 217, 721, 722, 723, 724, 725, 726, - 727, 730, 731, 737, 0, 718, 719, 720, 728, 729, - 716, 717, 713, 714, 715, 736, 735, 0, 0, 327, - 326, 328, 0, 53, 781, 385, 0, 0, 0, 0, - 0, 0, 387, 383, 0, 0, 181, 182, 183, 169, - 0, 170, 0, 166, 171, 167, 781, 180, 165, 0, - 83, 0, 392, 391, 0, 781, 0, 0, 0, 781, - 781, 0, 781, 781, 781, 781, 781, 0, 781, 249, - 781, 92, 415, 222, 0, 0, 76, 0, 781, 0, - 0, 781, 0, 0, 781, 0, 0, 0, 781, 781, - 0, 73, 781, 781, 781, 605, 604, 606, 603, 781, - 107, 114, 0, 0, 781, 415, 288, 781, 781, 781, - 781, 781, 781, 241, 244, 781, 264, 263, 262, 268, - 0, 0, 270, 275, 274, 273, 279, 0, 300, 376, - 770, 0, 769, 0, 0, 352, 354, 759, 781, 0, - 65, 703, 0, 0, 0, 0, 0, 700, 0, 706, - 707, 695, 0, 734, 733, 324, 388, 781, 0, 0, - 781, 0, 0, 0, 781, 0, 42, 781, 781, 0, - 174, 172, 0, 781, 781, 781, 781, 781, 781, 781, - 178, 82, 781, 0, 0, 0, 0, 0, 0, 0, - 781, 781, 251, 252, 781, 781, 98, 781, 250, 15, - 781, 0, 0, 9, 0, 0, 0, 228, 416, 417, - 230, 231, 781, 0, 234, 236, 233, 229, 781, 0, + 0, 0, 67, 325, 369, 323, 66, 48, 782, 44, + 782, 0, 0, 0, 0, 0, 0, 0, 782, 0, + 0, 782, 339, 318, 0, 338, 81, 0, 0, 390, + 0, 86, 90, 0, 782, 782, 0, 0, 416, 227, + 0, 77, 74, 0, 0, 0, 679, 682, 683, 0, + 0, 782, 0, 0, 0, 0, 199, 782, 282, 287, + 286, 285, 0, 0, 0, 0, 782, 0, 782, 782, + 782, 782, 260, 261, 782, 782, 0, 782, 240, 259, + 782, 782, 0, 271, 272, 0, 0, 0, 782, 243, + 782, 299, 376, 345, 0, 0, 351, 350, 782, 0, + 0, 0, 782, 0, 0, 0, 0, 0, 0, 0, + 739, 214, 217, 722, 723, 724, 725, 726, 727, 728, + 731, 732, 738, 0, 719, 720, 721, 729, 730, 717, + 718, 714, 715, 716, 737, 736, 0, 0, 327, 326, + 328, 0, 53, 782, 386, 0, 0, 0, 0, 0, + 0, 388, 384, 0, 0, 181, 182, 183, 169, 0, + 170, 0, 166, 171, 167, 782, 180, 165, 0, 83, + 0, 393, 392, 0, 782, 0, 0, 0, 782, 782, + 0, 782, 782, 782, 782, 782, 0, 782, 249, 782, + 92, 416, 222, 0, 0, 76, 0, 782, 0, 0, + 782, 0, 0, 782, 0, 0, 0, 782, 782, 0, + 73, 782, 782, 782, 606, 605, 607, 604, 782, 107, + 114, 0, 0, 782, 416, 288, 782, 782, 782, 782, + 782, 782, 241, 244, 782, 264, 263, 262, 268, 0, + 0, 270, 275, 274, 273, 279, 0, 300, 373, 0, + 771, 0, 770, 0, 0, 352, 354, 760, 782, 0, + 65, 704, 0, 0, 0, 0, 0, 701, 0, 707, + 708, 696, 0, 735, 734, 324, 389, 782, 0, 0, + 782, 0, 0, 0, 782, 0, 42, 782, 782, 0, + 174, 172, 0, 782, 782, 782, 782, 782, 782, 782, + 178, 82, 782, 0, 0, 0, 0, 0, 0, 0, + 782, 782, 251, 252, 782, 782, 98, 782, 250, 15, + 782, 0, 0, 9, 0, 0, 0, 228, 417, 418, + 230, 231, 782, 0, 234, 236, 233, 229, 782, 0, 187, 0, 127, 128, 129, 130, 131, 132, 135, 136, 137, 152, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 156, 155, 139, 138, 124, 126, 125, 133, 134, 122, 123, 119, 120, 121, 118, 0, - 0, 117, 781, 188, 0, 0, 0, 0, 195, 781, - 197, 0, 0, 79, 184, 781, 0, 115, 781, 200, - 0, 289, 0, 0, 0, 242, 245, 265, 781, 781, - 276, 781, 781, 373, 0, 357, 0, 356, 0, 355, - 760, 0, 0, 0, 761, 781, 353, 0, 0, 705, - 0, 702, 0, 732, 781, 0, 0, 0, 0, 0, - 202, 0, 0, 0, 781, 0, 781, 179, 159, 157, - 162, 158, 168, 175, 0, 781, 781, 781, 781, 0, - 176, 218, 0, 84, 390, 781, 88, 0, 0, 781, - 100, 781, 255, 254, 253, 781, 0, 0, 223, 415, - 0, 781, 781, 225, 226, 419, 420, 424, 421, 429, - 422, 423, 425, 426, 427, 428, 430, 431, 432, 433, - 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, - 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, - 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, - 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, - 474, 475, 476, 477, 478, 479, 480, 481, 482, 504, - 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, - 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, - 503, 505, 506, 507, 508, 509, 510, 511, 512, 513, - 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, - 524, 525, 526, 527, 528, 529, 530, 531, 781, 548, - 549, 550, 541, 553, 537, 538, 536, 543, 544, 532, - 533, 534, 535, 542, 540, 547, 545, 551, 546, 539, - 552, 418, 0, 232, 235, 0, 191, 781, 154, 153, - 185, 190, 189, 194, 198, 781, 0, 221, 0, 0, - 116, 201, 674, 781, 781, 781, 0, 266, 0, 277, - 363, 362, 361, 360, 359, 358, 347, 0, 0, 0, - 0, 386, 0, 0, 34, 203, 0, 0, 0, 0, - 384, 41, 177, 173, 781, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 219, 561, - 0, 781, 781, 0, 94, 781, 781, 256, 0, 781, - 781, 0, 10, 0, 0, 0, 237, 781, 238, 192, - 186, 0, 781, 80, 415, 781, 781, 781, 781, 781, - 698, 697, 699, 696, 0, 0, 0, 0, 28, 0, + 0, 117, 782, 188, 0, 0, 0, 0, 195, 782, + 197, 0, 0, 79, 184, 782, 0, 115, 782, 200, + 0, 289, 0, 0, 0, 242, 245, 265, 782, 782, + 276, 782, 782, 377, 0, 357, 0, 356, 0, 355, + 761, 0, 0, 0, 762, 782, 353, 0, 0, 706, + 0, 703, 0, 733, 782, 0, 0, 0, 0, 0, + 202, 0, 0, 0, 782, 0, 782, 179, 159, 157, + 162, 158, 168, 175, 0, 782, 782, 782, 782, 0, + 176, 218, 0, 84, 391, 782, 88, 0, 0, 782, + 100, 782, 255, 254, 253, 782, 0, 0, 223, 416, + 0, 782, 782, 225, 226, 420, 421, 425, 422, 430, + 423, 424, 426, 427, 428, 429, 431, 432, 433, 434, + 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, + 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, + 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, + 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, + 475, 476, 477, 478, 479, 480, 481, 482, 483, 505, + 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, + 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, + 504, 506, 507, 508, 509, 510, 511, 512, 513, 514, + 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, + 525, 526, 527, 528, 529, 530, 531, 532, 782, 549, + 550, 551, 542, 554, 538, 539, 537, 544, 545, 533, + 534, 535, 536, 543, 541, 548, 546, 552, 547, 540, + 553, 419, 0, 232, 235, 0, 191, 782, 154, 153, + 185, 190, 189, 194, 198, 782, 0, 221, 0, 0, + 116, 201, 675, 782, 782, 782, 0, 266, 0, 277, + 374, 363, 362, 361, 360, 359, 358, 347, 0, 0, + 0, 0, 387, 0, 0, 34, 203, 0, 0, 0, + 0, 385, 41, 177, 173, 782, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 219, + 562, 0, 782, 782, 0, 94, 782, 782, 256, 0, + 782, 782, 0, 10, 0, 0, 0, 237, 782, 238, + 192, 186, 0, 782, 80, 416, 782, 782, 782, 782, + 782, 699, 698, 700, 697, 0, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 568, 0, 576, 574, 573, 575, 572, 0, 0, 571, + 0, 569, 0, 577, 575, 574, 576, 573, 0, 0, + 572, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 85, 87, 0, 96, 781, 91, 0, 781, - 257, 781, 224, 13, 11, 554, 0, 781, 193, 0, - 781, 781, 781, 781, 781, 37, 781, 35, 0, 0, - 38, 40, 0, 30, 0, 0, 0, 0, 0, 0, - 0, 0, 600, 585, 586, 587, 588, 589, 590, 591, - 592, 593, 599, 0, 582, 583, 584, 580, 581, 577, - 578, 579, 598, 597, 0, 0, 781, 781, 0, 781, - 99, 93, 12, 239, 781, 675, 303, 302, 301, 267, - 278, 0, 0, 0, 0, 0, 0, 570, 0, 0, - 0, 0, 567, 0, 562, 0, 596, 595, 781, 0, - 781, 101, 196, 203, 0, 29, 0, 0, 31, 0, - 0, 0, 569, 0, 594, 89, 781, 781, 36, 0, - 0, 0, 0, 0, 0, 0, 781, 781, 39, 0, - 32, 565, 564, 566, 563, 781, 95, 0, 97, 33 + 0, 0, 0, 85, 87, 0, 96, 782, 91, 0, + 782, 257, 782, 224, 13, 11, 555, 0, 782, 193, + 0, 782, 782, 782, 782, 782, 37, 782, 35, 0, + 0, 38, 40, 0, 30, 0, 0, 0, 0, 0, + 0, 0, 0, 601, 586, 587, 588, 589, 590, 591, + 592, 593, 594, 600, 0, 583, 584, 585, 581, 582, + 578, 579, 580, 599, 598, 0, 0, 782, 782, 0, + 782, 99, 93, 12, 239, 782, 676, 303, 302, 301, + 267, 278, 0, 0, 0, 0, 0, 0, 571, 0, + 0, 0, 0, 568, 0, 563, 0, 597, 596, 782, + 0, 782, 101, 196, 203, 0, 29, 0, 0, 31, + 0, 0, 0, 570, 0, 595, 89, 782, 782, 36, + 0, 0, 0, 0, 0, 0, 0, 782, 782, 39, + 0, 32, 566, 565, 567, 564, 782, 95, 0, 97, + 33 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int16 yypgoto[] = { - -1076, -1076, -389, -1076, -1076, -71, -1076, -1076, 578, -429, - -1076, -222, 779, -344, -1076, -427, -1076, -1076, -226, -1076, - -1076, -277, -1076, -1076, -1076, -1076, 558, -1076, -1076, -1076, - -1076, -1076, -497, -1076, -1076, -410, -1076, -1076, -1076, -1076, - 131, 259, -862, -1076, -903, -845, -370, -501, -1076, -208, - -1076, -18, -470, -1076, -739, -1075, -1076, -391, 455, -897, - -481, -460, -66, -95, -54, -58, -252, -535, 563, 1372, - -240, -1076, -232, -1076, -1076, -1076, -1076, 176, -225, -1076, - -514, -1076, -1076, -22, -19, -1076, -1076, -1076, -1076, -27, - -8, -1076, -1076, -923, -1076, -165, -1076, -620, -104, -60, - 590, 1053, 416, 631, -1076, -1076, 881, -925, 1452, -223, - -386, -1 + -1070, -1070, -525, -1070, -1070, -102, -1070, -1070, 540, -420, + -1070, 475, 729, -359, -1070, -419, -1070, -1070, -243, -1070, + -1070, -307, -1070, -1070, -1070, -1070, 532, -1070, -1070, -1070, + -1070, -1070, -485, -1070, -1070, -402, -1070, -1070, -1070, -1070, + 111, 244, -890, -1070, -912, -790, -392, -456, -1070, -229, + -1070, -38, -483, -1070, -755, -1069, -1070, -390, 438, -873, + -496, -486, -41, -75, -69, -63, -237, -540, 545, 154, + -238, -1070, -211, -1070, -1070, -1070, -1070, 156, -200, -1070, + -1070, -515, -1070, -1070, -19, 34, -1070, -1070, -1070, -1070, + -22, -51, -1070, -1070, -929, -1070, -185, -1070, -645, -113, + -7, 327, 1514, -254, 613, -1070, -1070, 863, -925, 1359, + 210, -384, -1 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int16 yydefgoto[] = { - 0, 4, 5, 265, 1082, 1083, 442, 795, 443, 444, - 604, 445, 369, 260, 261, 446, 803, 797, 971, 628, - 931, 1061, 639, 935, 1452, 939, 640, 1080, 1536, 1597, - 1235, 1456, 504, 1142, 1210, 447, 625, 922, 923, 924, - 925, 926, 972, 1395, 973, 815, 1199, 370, 371, 575, - 576, 1220, 324, 956, 801, 1093, 1094, 372, 578, 947, - 832, 843, 252, 253, 95, 96, 641, 149, 642, 97, - 98, 545, 99, 546, 712, 856, 857, 1015, 100, 101, - 542, 375, 376, 102, 103, 448, 1044, 1037, 449, 104, - 105, 106, 107, 957, 958, 1088, 1381, 536, 266, 267, - 1624, 185, 68, 579, 580, 200, 201, 1016, 1017, 693, - 69, 112 + 0, 4, 5, 265, 1082, 1083, 440, 795, 441, 442, + 603, 443, 369, 260, 261, 444, 803, 797, 970, 627, + 930, 1061, 638, 934, 1453, 938, 639, 1080, 1537, 1598, + 1235, 1457, 502, 1142, 1210, 445, 624, 921, 922, 923, + 924, 925, 971, 1395, 972, 815, 1199, 370, 371, 574, + 575, 1220, 324, 955, 801, 1093, 1094, 372, 577, 946, + 832, 843, 252, 253, 95, 96, 640, 149, 641, 97, + 98, 544, 99, 545, 712, 855, 856, 1015, 100, 256, + 101, 541, 537, 538, 102, 103, 446, 1044, 1037, 447, + 104, 105, 106, 107, 956, 957, 1088, 1381, 534, 266, + 267, 1625, 185, 68, 578, 579, 200, 201, 1016, 1017, + 692, 69, 112 }; /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If @@ -1562,1556 +1565,1556 @@ static const yytype_int16 yydefgoto[] = number is the opposite. If YYTABLE_NINF, syntax error. */ static const yytype_int16 yytable[] = { - 6, 255, 655, 577, 184, 1008, 600, 622, 581, 624, - 269, 400, 271, 272, 273, 274, 275, 1382, 277, 152, - 279, 232, 281, 401, 150, 231, 718, 151, 1062, 1081, - 709, 402, 654, 1156, 383, 390, 704, 814, 403, 298, - 229, 321, 230, 1069, 534, 930, 1072, 1073, 937, 549, - 692, 307, 308, 323, 317, 365, 733, 822, 314, 315, - 323, -2, 1160, 322, 203, 113, 1219, 936, 837, 234, - 937, 705, 703, 318, 468, 848, 1067, 238, 239, 240, - 109, 837, 110, 114, 243, 1175, 1177, 1179, 109, 1241, - 110, 317, -773, 469, 254, 254, 677, 823, 184, 109, - 109, 110, 110, 1100, 109, 1143, 110, 1242, 1146, 109, - 508, 110, 268, 268, 121, 268, 268, 268, 268, 268, - 229, 268, 230, 268, 365, 268, 366, 1150, 378, 379, - 380, 1052, 109, 696, 110, 1053, 351, 352, 109, 684, - 110, 235, 268, 108, 706, 109, 109, 110, 110, 378, - 379, 380, 360, 362, 268, 268, 710, 109, 115, 110, - 1147, 268, 268, 116, 109, -773, 110, 349, -773, 214, - 238, 239, 240, 243, 1232, 1148, 1149, 1233, 1234, 581, - 1054, 359, 361, 10, 535, 11, 614, 592, 593, 594, - 595, 596, 1157, 597, 599, 601, 734, 117, 485, 606, - 325, 828, 938, 714, 1227, 401, 613, 833, 1205, 118, - 836, 619, 620, 402, 623, 626, 627, 1000, 632, 633, - 403, 119, 838, 829, 938, 778, 854, 912, 1007, 238, - 254, 254, 852, 849, 1153, 853, 406, 1386, 381, 844, - 789, 404, 847, 109, 405, 110, 254, 254, 120, 1410, - 373, 1411, -774, 1412, -775, 377, 1413, 1414, 1415, 381, - 677, 824, 214, -776, 450, 1036, 1055, 378, 379, 380, - 685, 367, 1079, 1416, 686, 317, 368, 677, 825, 984, - 1056, 317, 1391, 1392, 952, 1057, 953, 954, 955, 122, - 1058, 1421, 522, 109, 871, 110, 382, 524, 525, 317, - 975, 268, 223, 224, 225, 744, 226, 227, 228, 123, - 1399, 532, 1519, 317, 979, 531, 1461, 124, 976, 687, - 125, 505, 317, 1223, 126, -774, 127, -775, -774, 515, - -775, 516, 977, 517, 1457, 1519, -776, 837, 999, -776, - 128, 978, 317, 577, 129, 991, 130, 1196, 581, 154, - 996, 131, 317, 997, 998, 1076, 1077, 523, 993, 994, - 317, 1033, 523, 523, 764, 390, 1197, 992, 599, 606, - 1430, 1480, 132, 538, 543, 785, 767, 381, 518, 1481, - 133, 904, 1003, 401, 317, 1004, 1005, 401, 1035, 848, - 1006, 402, 1546, 582, 317, 402, 1085, 1086, 403, 226, - 227, 228, 403, 1482, 134, 688, 950, 135, 450, 450, - 450, 450, 450, 1483, 450, 450, 450, 160, 406, 689, - 450, 136, 1485, 404, 690, 137, 405, 450, 138, 691, - 1230, 1077, 450, 450, 1064, 450, 450, 450, 1068, 450, - 450, 1486, 756, 757, 758, 1059, 1489, 669, 1158, 1529, - 1530, 1531, 673, 674, 1181, 1182, 1183, 1236, 1492, 139, - 678, 679, 680, 317, 519, 1490, 1060, 1615, 1526, 1527, - 1528, 683, 1529, 1530, 1531, 682, 140, 1493, 520, 317, - 1650, 317, 1572, 521, 1239, 1240, 1616, 1162, 1163, 1164, - 798, 244, 799, 245, 800, 246, 264, 317, 1626, 1651, - 1661, 325, 373, 1152, 186, 187, 188, 141, 378, 379, - 380, 941, 523, 730, 1167, 942, 1662, 523, 523, 317, - 142, 1165, 1166, 1469, 317, 523, 523, 523, 1045, 1396, - 694, -102, 505, -102, 152, -102, 543, 143, 1663, 150, - 247, 1170, 151, 1664, 6, 713, 903, 1062, 155, 791, - 695, 1549, 696, -102, 697, -102, 156, -102, 161, 798, - 943, 799, 189, 1151, 1148, 1149, 1206, 162, 1, 2, - 3, 948, 163, 233, 833, 190, 191, 836, 242, 1237, - 974, 256, 794, 804, 805, 263, 299, 1207, 356, 450, - 450, 809, 1222, 810, 301, 844, 406, 450, 847, 698, - 406, 404, 302, 450, 405, 404, 819, 309, 405, 820, - 821, 316, 323, 6, 192, 193, 374, 194, 381, 1208, - -280, 1209, 195, 827, 196, 392, 248, 826, 393, 1185, - 1148, 1149, 1228, 1148, 1149, 1393, 394, 451, 1211, 317, - 249, 452, 186, 187, 188, 250, 944, 459, 1194, 453, - 251, 1148, 1149, 1453, 454, 1204, 455, 211, 212, 213, - 945, 730, 456, 457, 458, 946, 816, 1406, 981, 214, - 1408, 523, 461, 460, 523, 523, 538, 462, 463, 464, - 465, 694, 466, 467, 470, 699, 694, 694, 471, 472, - 694, 325, 473, 474, 475, 476, 477, 897, 478, 700, - 189, 500, 325, 488, 701, 1606, 1607, 1608, 974, 702, - 479, 858, 480, 190, 191, 974, 481, 948, 482, 656, - 948, 948, 378, 379, 380, 963, 489, 490, 1451, 964, - 492, 493, 1455, 494, 1458, 996, 997, 998, 496, 940, - 497, 503, 974, 540, 974, 510, 512, 974, 533, -204, - 544, 986, 192, 193, 927, 194, 1003, 1004, 1005, 1024, - 195, 547, 196, 583, 657, 214, 658, 450, 585, 6, - 603, 586, 607, 608, 965, 609, 616, 610, 611, 612, - 928, 617, 618, 659, 111, 649, 621, 152, 643, 644, - 651, 711, 150, 949, 6, 151, 650, 652, 653, 715, - 221, 222, 223, 224, 225, -281, 226, 227, 228, -282, - 505, 670, 1666, 677, 707, 660, 523, 716, 661, 662, - 1668, 717, 663, 719, 723, 694, 623, 325, 325, 724, - 694, 966, 381, 694, 694, 781, 538, 732, 664, -211, - 792, 802, 814, 974, 806, 807, 813, 538, 948, 816, - 665, 948, 948, 808, 811, 186, 187, 188, 830, 840, - 967, -367, 268, 855, 666, 859, 863, 865, 902, 905, - 870, 899, 901, 906, 968, 907, 974, 908, 909, 969, - 910, 257, 258, 911, 970, 929, 913, 934, 951, 1159, - 932, 933, 985, 927, 543, 1019, 221, 222, 223, 224, - 225, 987, 226, 227, 228, 988, 1475, 1476, 1477, 989, - 1018, 990, 1022, 189, 837, 848, -289, 1023, 1021, 1025, - 1027, 974, 974, 1028, 1029, 694, 190, 191, 1038, 303, - 304, 1039, 1040, 1041, 373, 1042, 1043, 1046, 373, 949, - 1048, 1049, 949, 949, 1065, 1066, 1087, 1070, 1090, 1091, - 1098, 1534, 1169, 1167, 1168, 1538, 152, 1089, 1184, 1171, - 1096, 150, 1172, 1541, 151, 192, 193, 1187, 194, 1188, - 1189, 816, 325, 195, 1170, 196, 1190, 1191, 1192, 1195, - 1198, 1553, 1554, 254, 1201, 1202, 1203, 373, 373, 373, - 325, 325, 1214, 1215, 694, 1224, 1225, 1229, 1243, 1226, - 1244, 1077, 1384, 197, 577, 1387, 1388, 198, 948, 581, - 1238, 1383, 199, 1398, 1389, 1400, 1422, 6, 1402, 1423, - 1403, 1424, 927, 1404, 1405, 358, 1425, 1426, 363, 364, - 1427, 1428, 1429, 1431, 1450, 1598, 6, 1459, 1454, 1200, - 1472, 1460, 1600, 6, 1466, 1474, 694, 450, 1478, 1479, - 1604, 1487, 1484, 694, 694, 67, 1488, 694, 1221, 1491, - 1494, 325, 1495, 1401, 1496, 1497, 1501, 1535, 1539, 1555, - 949, 1557, 1542, 949, 949, 1556, 538, 1558, 656, 373, - 1543, 186, 187, 188, 1544, 1547, 1559, 1560, 1561, 1562, - 1563, 1096, 1568, 1571, 1611, 1602, 1629, 1614, 1596, 1628, - 153, 1599, 1631, 1603, 1605, 1618, 159, 1613, 1619, 109, - 1617, 110, 164, 165, 166, 167, 168, 1620, 1623, 204, - 1622, 1630, 1633, 657, 1634, 658, 1635, 1417, 1418, 1636, - 1419, 1637, 1420, 1647, 1638, 513, 514, 1463, 1464, 189, - 1639, 1640, 659, 1641, 1643, 526, 527, 528, 538, 1656, - 1642, 1646, 190, 191, 816, 1648, 1519, 254, 1649, 1658, - 1659, 1660, 974, 1667, 1516, 1517, 1518, 373, 1669, 1462, - 373, 548, 1473, 1532, 660, 974, 1519, 661, 662, 1047, - 1212, 663, 769, 587, 588, 784, 1612, 1471, 1432, 873, - 786, 192, 193, 1465, 194, 1186, 722, 664, 0, 195, - 0, 196, 502, 0, 0, 1221, 0, 0, 615, 665, - 0, 0, 0, 0, 313, 694, 694, 694, 0, 0, - 0, 0, 0, 666, 505, 0, 0, 974, 505, 0, - 949, 0, 0, 501, 373, 0, 0, 0, 199, 0, - 268, 268, 0, 0, 0, 0, 0, 0, 0, 7, - 8, 9, 10, 0, 11, 12, 13, 0, 326, 327, - 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, - 338, 339, 340, 341, 342, 343, 344, 345, 346, 0, - 0, 350, 0, 667, 0, 0, 354, 1524, 1525, 1526, - 1527, 1528, 0, 1529, 1530, 1531, 672, 1435, 0, 675, - 676, 0, 0, 0, 0, 0, 0, 1524, 1525, 1526, - 1527, 1528, 1436, 1529, 1530, 1531, 407, 1437, 708, 0, - 0, 0, 0, 0, 0, 0, 24, 25, 0, 0, - 0, 0, 27, 0, 0, 0, 29, 30, 31, 32, + 6, 269, 576, 271, 272, 273, 274, 275, 580, 277, + 231, 279, 599, 281, 621, 623, 232, 653, 1062, 710, + 718, 255, 1081, 1382, 152, 399, 398, 150, 709, 929, + 298, 822, 548, 691, 238, 239, 240, 376, 377, 378, + 1156, 243, 307, 308, 702, 654, 703, 1067, 532, 314, + 315, 109, 400, 110, 229, 1160, 230, 184, 365, 935, + 1007, -2, 936, 401, 203, 317, 1069, 936, 234, 1072, + 1073, 733, -774, -775, 1100, 323, 1143, -776, 113, 1146, + 151, 321, 108, 466, 318, 1175, 1177, 1179, 778, 264, + 837, 109, 1241, 110, 254, 254, 114, 214, 109, 704, + 110, -777, 467, 322, 115, 317, 109, 317, 110, 109, + 1242, 110, 268, 268, 116, 268, 268, 268, 268, 268, + 117, 268, 744, 268, 506, 268, 870, 238, 239, 240, + 243, 109, 109, 110, 110, 109, 118, 110, 683, 109, + 235, 110, 268, 705, 317, -774, -775, 379, -774, -775, + -776, 184, 317, -776, 268, 268, 351, 352, 676, 823, + 317, 268, 268, 974, 513, 1520, 514, 323, 515, 1085, + 1086, 975, 360, 362, -777, 1219, 1227, -777, 853, 976, + 580, 1150, 848, 119, 380, 828, 238, 714, 533, 483, + 837, 833, 999, 244, 836, 245, 829, 246, 1232, 1157, + 325, 1233, 1234, 1006, 120, 399, 359, 361, 838, 1386, + 814, 734, 844, 516, 789, 847, 937, 1153, 183, 849, + 349, 937, 1205, 1076, 1077, 911, 376, 377, 378, 940, + 254, 254, 400, 941, 226, 227, 228, 613, 365, 121, + 366, 404, 247, 401, 402, 903, 254, 254, 123, 1411, + 373, 1412, 122, 1413, 1391, 1392, 1414, 1415, 1416, 756, + 757, 758, 1036, 316, 448, 109, 1079, 110, 124, 270, + 949, 109, 125, 110, 983, 276, 126, 278, 942, 280, + 127, 282, 283, 284, 285, 286, 287, 288, 289, 290, + 291, 292, 293, 294, 295, 296, 297, 403, 128, 517, + 529, 268, 1530, 1531, 1532, 317, 530, 1223, 306, 129, + 1462, 214, 310, 518, 311, 312, 1008, 520, 519, 1009, + 130, 503, 522, 523, 977, 229, 978, 230, 248, 542, + 990, 131, 109, 1147, 110, 995, 379, 132, 996, 997, + 133, 991, 249, 134, 576, 992, 993, 250, 1148, 1149, + 580, 135, 251, 109, 136, 110, 1002, 521, 1458, 1003, + 1004, 317, 521, 521, 943, 1399, 137, 798, 694, 799, + 695, 800, 696, 536, 539, 1196, 317, 138, 944, 317, + 1033, 317, 317, 945, 399, 367, 1035, 139, 399, 785, + 368, 581, 1417, 323, 1197, 1481, 355, 1486, 1482, 1547, + 1483, 1484, 140, 10, 1490, 11, 448, 448, 448, 448, + 448, 400, 448, 448, 448, 400, 1487, 697, 448, 676, + 824, 404, 401, 1491, 402, 448, 401, 141, 1493, 1059, + 448, 448, 1236, 448, 448, 448, 142, 448, 448, 1060, + 143, 317, 1158, 1616, 223, 224, 225, 1494, 226, 227, + 228, 155, 317, 1651, 317, 482, 676, 825, 681, 1422, + 1573, -102, 1617, -102, 682, -102, 154, 381, 388, 317, + 668, 1627, 1652, 1662, 156, 672, 673, 403, 1064, 791, + 1431, 160, 1068, 677, 678, 679, 317, 317, 1663, 1152, + 837, 998, 542, 1185, 109, 1470, 110, 161, 1167, 325, + 373, 848, 1005, 698, 1396, 1664, 1665, 1165, 1166, 162, + 521, 163, 1194, 233, 1170, 521, 521, 699, 242, 1204, + 1230, 1077, 700, 521, 521, 521, 263, 701, 693, 1045, + 503, 1162, 1163, 1164, 1, 2, 3, 299, 152, 1062, + 301, 150, 302, 6, 713, 951, 1550, 952, 953, 954, + 309, 1206, 655, -102, 798, -102, 799, -102, 1151, 833, + 356, 1207, 836, 1239, 1240, 730, 794, 1148, 1149, 844, + 1520, 374, 847, 1181, 1182, 1183, 1148, 1149, 1228, 1222, + -280, 375, 186, 187, 188, 1148, 1149, 1393, 448, 448, + 1148, 1149, 1454, 390, 151, 391, 448, 656, 392, 657, + 404, 457, 448, 402, 404, 449, 317, 402, 450, 451, + 452, 826, 6, 453, 459, 454, 658, 827, 644, 455, + 645, 456, 646, 458, 1237, 464, 468, 460, 1208, 1209, + 819, 461, 462, 820, 821, 804, 805, 463, 465, 469, + 189, 470, 471, 809, 486, 810, 1211, 472, 659, 498, + 473, 660, 661, 190, 191, 662, 403, 474, 475, 476, + 403, 376, 377, 378, 962, 816, 477, 478, 963, 479, + 521, 663, 480, 521, 521, 536, 487, 488, 490, 491, + 693, 492, 494, 664, 495, 693, 693, 508, 501, 693, + 325, 510, 192, 193, 531, 194, -204, 665, 543, 546, + 195, 325, 196, 1527, 1528, 1529, 582, 1530, 1531, 1532, + 584, 857, 1406, 964, 730, 1408, 602, 585, 606, 607, + 995, 996, 997, 608, 939, 609, 729, 610, 611, 620, + 1002, 1003, 1004, 615, 111, 616, 617, 642, 761, 643, + 1452, 706, 648, 649, 1456, 650, 980, 652, 651, 1024, + 896, 669, 708, -282, 676, 711, 716, 715, 717, 926, + 719, 1607, 1608, 1609, 723, 732, 724, 448, 781, 6, + 965, 379, -211, 802, 792, 814, 985, 806, 807, 1459, + 927, 808, 186, 187, 188, 811, 813, 830, 840, -368, + 854, 858, 152, 948, 6, 150, 764, 388, 862, 966, + 864, 869, 901, 898, 900, 376, 377, 378, 684, 904, + 503, 905, 685, 967, 906, 907, 521, 908, 968, 909, + 910, 912, 928, 969, 931, 693, 932, 325, 325, 933, + 693, 257, 258, 693, 693, 950, 536, 984, 986, 837, + 189, 987, 1018, 1038, 988, 989, 1019, 536, 151, 816, + 542, 848, -289, 190, 191, 1021, 1022, 686, 1023, 1025, + 1027, 268, 1028, 1029, 1039, 1040, 1041, 1042, 1667, 859, + 860, 861, 1043, 863, 1046, 865, 1669, 866, 867, 303, + 304, 1048, 591, 592, 593, 594, 595, 214, 596, 598, + 600, 1049, 192, 193, 605, 194, 1065, 926, 1066, 1070, + 195, 612, 196, 1087, 1090, 1091, 618, 619, 1159, 622, + 625, 626, 1098, 631, 632, 379, 1168, 1169, 1476, 1477, + 1478, 1184, 1171, 1172, 693, 1187, 1188, 1214, 1190, 1189, + 1192, 1191, 1195, 373, 1198, 1201, 1202, 373, 948, 1167, + 1203, 948, 948, 687, 1224, -281, 1226, 1225, 1077, 1170, + 1215, 1238, 1229, 1243, 1244, 1384, 1089, 688, 1387, 1096, + 152, 1383, 689, 150, 1388, 1450, 1389, 690, 1520, 1398, + 816, 325, 1423, 1400, 1424, 358, 1542, 1402, 363, 364, + 1403, 1404, 254, 1405, 1425, 1426, 373, 373, 373, 325, + 325, 1427, 1428, 693, 1554, 1555, 1429, 1535, 1430, 1432, + 1451, 1539, 1455, 1460, 947, 576, 1461, 376, 377, 378, + 1052, 580, 695, 973, 1053, 1467, 151, 6, 221, 222, + 223, 224, 225, 1473, 226, 227, 228, 926, 1475, 1489, + 1488, 1496, 1479, 1480, 1485, 1492, 6, 1495, 1536, 1200, + 1497, 1498, 1502, 6, 1540, 1545, 693, 448, 1556, 1557, + 1558, 1543, 1559, 693, 693, 1601, 1544, 693, 1221, 1054, + 1548, 325, 1560, 1605, 598, 605, 1561, 1562, 1563, 1564, + 948, 1569, 767, 948, 948, 1572, 536, 212, 213, 373, + 1603, 1599, 1597, 1401, 1604, 511, 512, 1063, 214, 1600, + 1612, 1096, 1606, 1614, 1615, 524, 525, 526, 1618, 1525, + 1526, 1527, 1528, 1529, 1619, 1530, 1531, 1532, 1620, 1621, + 1623, 1624, 1629, 1634, 1636, 1632, 1631, 379, 1637, 547, + 1635, 1638, 1639, 1640, 1641, 1642, 1644, 1649, 1464, 1465, + 1643, 586, 587, 1647, 1650, 1659, 1660, 1661, 1463, 1668, + 973, 1670, 1630, 769, 1533, 1055, 1648, 973, 536, 947, + 1518, 1519, 947, 947, 816, 1474, 614, 254, 784, 1056, + 1212, 1520, 1657, 1047, 1057, 1613, 1472, 373, 1433, 1058, + 373, 786, 872, 1466, 973, 1186, 973, 722, 0, 973, + 1418, 1419, 0, 1420, 500, 1421, 1450, 0, 1450, 1450, + 1450, 1450, 1450, 0, 1450, 0, 0, 1512, 1513, 1514, + 1515, 1516, 1517, 1518, 1519, 1221, 0, 0, 0, 0, + 0, 0, 0, 0, 1520, 693, 693, 693, 0, 221, + 222, 223, 224, 225, 503, 226, 227, 228, 503, 0, + 948, 666, 0, 0, 373, 0, 0, 0, 0, 0, + 268, 268, 0, 902, 671, 0, 0, 674, 675, 0, + 0, 0, 0, 382, 383, 384, 0, 1450, 1450, 1450, + 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, + 1450, 1450, 1450, 1450, 1450, 1450, 973, 0, 0, 0, + 0, 947, 0, 0, 947, 947, 0, 0, 0, 0, + 0, 0, 1525, 1526, 1527, 1528, 1529, 0, 1530, 1531, + 1532, 0, 0, 0, 0, 0, 0, 0, 0, 973, + 0, 189, 0, 0, 762, 0, 0, 766, 1450, 0, + 0, 0, 0, 0, 190, 191, 0, 0, 0, 0, + 0, 0, 549, 550, 551, 10, 0, 11, 552, 553, + 1522, 1523, 1524, 0, 554, 1525, 1526, 1527, 1528, 1529, + 0, 1530, 1531, 1532, 973, 973, 0, 1089, 0, 790, + 0, 0, 0, 385, 193, 0, 194, 0, 1434, 1450, + 0, 195, 1450, 196, 0, 0, 0, 109, 0, 110, + 555, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 581, 556, 0, 386, 817, 818, + 557, 0, 503, 503, 503, 0, 0, 0, 0, 558, + 559, 0, 0, 0, 831, 0, 0, 834, 835, 0, + 0, 839, 0, 0, 202, 842, 0, 0, 845, 846, + 0, 0, 850, 0, 693, 851, 852, 0, 0, 111, + 1509, 947, 0, 0, 560, 0, 0, 561, 241, 562, + 0, 0, 373, 0, 563, 0, 373, 0, 564, 0, + 503, 565, 0, 0, 0, 0, 566, 1096, 262, 567, + 0, 186, 187, 188, 0, 0, 0, 0, 503, 503, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 568, 0, 1509, 569, 570, 0, 0, 0, 571, + 0, 572, 0, 0, 0, 573, 300, 111, 0, 0, + 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, + 0, 0, 0, 622, 1595, 0, 0, 0, 0, 189, + 0, 0, 0, 0, 0, 0, 373, 0, 0, 503, + 0, 0, 190, 191, 0, 0, 1449, 503, 0, 0, + 816, 816, 816, 0, 0, 0, 1200, 319, 320, 994, + 0, 153, 0, 0, 0, 0, 0, 159, 0, 1000, + 1001, 0, 0, 164, 165, 166, 167, 168, 0, 0, + 204, 192, 193, 0, 194, 347, 0, 1020, 0, 195, + 0, 196, 0, 0, 0, 973, 503, 373, 0, 503, + 0, 1508, 0, 0, 357, 0, 0, 0, 973, 0, + 0, 0, 0, 0, 0, 0, 0, 387, 389, 197, + 0, 0, 0, 198, 0, 0, 0, 0, 199, 0, + 503, 0, 111, 1653, 1654, 1655, 0, 1656, 0, 0, + 0, 186, 187, 188, 0, 0, 503, 0, 0, 1565, + 1566, 1567, 1568, 0, 1570, 0, 1571, 816, 0, 0, + 0, 973, 484, 485, 0, 816, 0, 0, 489, 0, + 1071, 0, 0, 1074, 1075, 313, 1078, 0, 111, 0, + 202, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1099, 0, 0, 0, 1144, 1145, 0, 189, + 0, 0, 1154, 0, 0, 0, 0, 1155, 186, 187, + 188, 0, 190, 191, 0, 1161, 0, 0, 0, 326, + 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, + 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, + 0, 0, 350, 0, 0, 0, 0, 354, 0, 0, + 262, 192, 193, 0, 194, 583, 0, 0, 0, 195, + 0, 196, 0, 0, 0, 0, 189, 1501, 0, 1503, + 1504, 1505, 1506, 1507, 0, 1510, 0, 405, 0, 190, + 191, 0, 1216, 0, 0, 1217, 1218, 0, 0, 0, + 0, 0, 0, 499, 0, 0, 630, 0, 199, 1231, + 0, 0, 0, 0, 0, 0, 186, 187, 188, 0, + 0, 0, 0, 481, 0, 0, 0, 0, 192, 193, + 0, 194, 0, 0, 0, 0, 195, 1385, 196, 0, + 496, 497, 0, 0, 0, 0, 0, 504, 1574, 1575, + 1576, 1577, 1578, 1579, 1580, 1581, 1582, 1583, 1584, 1585, + 1586, 1587, 1588, 1589, 1590, 1591, 1592, 0, 319, 0, + 0, 0, 0, 0, 189, 0, 0, 0, 0, 0, + 0, 1390, 0, 670, 0, 0, 0, 190, 191, 0, + 549, 550, 551, 10, 0, 11, 552, 553, 535, 0, + 0, 0, 871, 0, 0, 0, 707, 0, 1407, 0, + 0, 1409, 0, 0, 0, 262, 0, 0, 0, 0, + 0, 0, 0, 0, 111, 0, 192, 193, 0, 194, + 0, 0, 0, 111, 195, 109, 196, 110, 555, 0, + 601, 0, 0, 111, 0, 7, 8, 9, 10, 0, + 11, 12, 13, 556, 1435, 763, 765, 1499, 557, 0, + 770, 0, 0, 1645, 0, 0, 0, 558, 559, 0, + 0, 0, 0, 771, 0, 772, 773, 774, 775, 776, + 777, 0, 0, 779, 206, 207, 208, 209, 210, 211, + 212, 213, 0, 1436, 0, 0, 0, 787, 788, 0, + 0, 214, 560, 0, 0, 561, 796, 562, 1437, 211, + 212, 213, 563, 1438, 496, 0, 564, 0, 0, 565, + 0, 214, 24, 25, 566, 0, 0, 567, 27, 667, + 0, 0, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, 39, 40, 41, 42, 43, 44, 0, 568, + 0, 0, 569, 570, 0, 0, 0, 571, 0, 572, + 48, 0, 49, 573, 841, 0, 0, 1439, 0, 0, + 0, 1440, 0, 540, 1441, 0, 0, 0, 0, 55, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 725, 726, 727, 728, 0, 731, 0, 0, + 0, 0, 0, 0, 1442, 0, 760, 1443, 1444, 1445, + 0, 0, 1446, 0, 1500, 65, 0, 73, 1448, 74, + 75, 76, 77, 0, 0, 894, 1471, 216, 217, 218, + 219, 220, 221, 222, 223, 224, 225, 0, 226, 227, + 228, 0, 0, 0, 780, 0, 0, 0, 0, 0, + 0, 84, 221, 222, 223, 224, 225, 0, 226, 227, + 228, 0, 0, 0, 0, 0, 0, 0, 237, 0, + 0, 0, 0, 0, 549, 550, 551, 10, 0, 11, + 552, 553, 981, 0, 0, 812, 720, 0, 0, 86, + 87, 1534, 0, 0, 0, 1538, 0, 0, 0, 1541, + 535, 0, 0, 0, 0, 0, 92, 0, 0, 0, + 0, 94, 1549, 0, 0, 1551, 1552, 1553, 0, 0, + 0, 0, 555, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1026, 1517, 1518, 1519, 556, 0, 0, + 0, 0, 557, 0, 0, 0, 1520, 0, 868, 0, + 0, 558, 559, 0, 0, 0, 186, 187, 188, 873, + 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, + 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, + 0, 1602, 897, 0, 0, 0, 560, 0, 0, 561, + 0, 562, 1051, 1610, 1611, 0, 563, 0, 0, 0, + 564, 0, 0, 565, 0, 0, 0, 0, 566, 0, + 0, 567, 0, 0, 189, 0, 0, 0, 0, 0, + 0, 0, 1084, 0, 961, 0, 0, 190, 191, 0, + 0, 0, 0, 568, 0, 0, 569, 570, 0, 0, + 0, 571, 0, 721, 1633, 0, 0, 573, 0, 7, + 8, 9, 10, 0, 11, 12, 13, 169, 71, 0, + 0, 535, 0, 0, 0, 0, 192, 193, 1646, 194, + 0, 0, 535, 0, 195, 0, 196, 1525, 1526, 1527, + 1528, 1529, 1180, 1530, 1531, 1532, 0, 1658, 0, 0, + 0, 259, 0, 1031, 0, 0, 1666, 15, 72, 0, + 0, 170, 0, 171, 172, 173, 174, 78, 79, 0, + 0, 0, 21, 80, 0, 0, 175, 23, 0, 1213, + 82, 0, 0, 0, 0, 0, 24, 25, 176, 0, + 0, 0, 27, 0, 0, 177, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, - 43, 44, 483, 0, 0, 0, 0, 1089, 0, 0, - 0, 0, 0, 0, 48, 762, 49, 0, 766, 498, - 499, 1438, 0, 0, 0, 1439, 506, 0, 1440, 212, - 213, 0, 0, 55, 0, 0, 1508, 0, 0, 0, - 214, 0, 0, 0, 582, 0, 0, 0, 0, 0, - 0, 0, 505, 505, 505, 0, 0, 0, 1441, 0, - 790, 1442, 1443, 1444, 0, 0, 1445, 0, 1446, 65, - 1517, 1518, 1447, 0, 0, 0, 0, 537, 0, 0, - 0, 1519, 0, 694, 0, 0, 183, 0, 0, 1508, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 817, - 818, 373, 0, 0, 0, 373, 0, 0, 0, 505, - 0, 0, 0, 0, 0, 831, 1096, 0, 834, 835, - 1594, 602, 839, 0, 0, 0, 842, 505, 505, 845, - 846, 0, 0, 850, 0, 0, 851, 270, 0, 111, - 0, 0, 0, 276, 0, 278, 0, 280, 0, 282, - 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, - 293, 294, 295, 296, 297, 0, 0, 202, 0, 0, - 0, 221, 222, 223, 224, 225, 306, 226, 227, 228, - 310, 0, 311, 312, 0, 373, 0, 0, 505, 0, - 0, 241, 0, 0, 0, 498, 505, 0, 0, 816, - 816, 816, 0, 0, 0, 1200, 0, 111, 0, 0, - 668, 262, 1524, 1525, 1526, 1527, 1528, 0, 1529, 1530, - 1531, 0, 0, 0, 0, 384, 385, 386, 0, 1652, - 1653, 1654, 0, 1655, 0, 0, 0, 207, 208, 209, - 210, 211, 212, 213, 0, 505, 373, 0, 505, 300, - 0, 0, 0, 214, 0, 0, 0, 0, 0, 995, - 0, 0, 0, 0, 355, 0, 0, 0, 0, 1001, - 1002, 0, 725, 726, 727, 728, 0, 731, 0, 505, - 0, 0, 0, 189, 0, 1449, 760, 0, 1020, 0, - 0, 0, 0, 0, 0, 505, 190, 191, 0, 0, - 319, 320, 0, 0, 0, 0, 816, 0, 0, 0, - 0, 0, 0, 0, 816, 0, 0, 0, 0, 0, - 0, 0, 0, 484, 780, 0, 0, 0, 347, 0, - 0, 0, 0, 111, 0, 387, 193, 0, 194, 0, - 0, 0, 0, 195, 0, 196, 0, 357, 0, 0, + 43, 44, 178, 0, 0, 0, 382, 383, 384, 0, + 0, 46, 0, 47, 48, 0, 49, 0, 186, 187, + 188, 50, 0, 179, 180, 53, 0, 0, 54, 88, + 0, 0, 0, 55, 1095, 0, 56, 89, 90, 91, + 181, 0, 0, 93, 0, 182, 0, 0, 0, 0, + 0, 597, 0, 0, 0, 0, 0, 0, 59, 0, + 0, 60, 61, 62, 189, 0, 63, 0, 64, 65, + 0, 0, 66, 0, 0, 0, 189, 190, 191, 0, + 0, 0, 0, 1173, 0, 0, 0, 0, 0, 190, + 191, 0, 0, 0, 0, 0, 0, 0, 0, 407, + 0, 1031, 0, 0, 0, 0, 1193, 408, 409, 410, + 411, 0, 0, 0, 0, 0, 385, 193, 0, 194, + 413, 414, 415, 416, 195, 0, 196, 0, 192, 1010, + 1011, 1012, 0, 590, 0, 0, 195, 0, 196, 205, + 206, 207, 208, 209, 210, 211, 212, 213, 0, 1013, + 0, 535, 0, 380, 1014, 0, 0, 214, 426, 1084, + 0, 0, 0, 0, 0, 0, 1095, 0, 0, 431, + 0, 0, 0, 0, 0, 432, 0, 0, 0, 434, + 435, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 438, 0, 439, 0, 1245, 1246, 1247, 1248, 1249, + 1250, 1251, 1252, 1253, 1254, 1255, 0, 1256, 1257, 1258, + 1259, 1260, 1261, 1262, 1263, 1264, 1265, 1266, 1267, 0, + 0, 1394, 0, 535, 0, 1397, 1268, 1269, 1270, 1271, + 1272, 1273, 1274, 1275, 1276, 1277, 1278, 1279, 1280, 1281, + 1282, 1283, 1284, 1285, 1286, 0, 0, 1287, 1288, 1289, + 1290, 1291, 1292, 1293, 1294, 1295, 1296, 1297, 1298, 1299, + 1300, 1301, 1302, 1303, 1304, 0, 1305, 0, 1306, 1307, + 1308, 1309, 1310, 1311, 1312, 1313, 1314, 1315, 0, 1316, + 1317, 1318, 215, 216, 217, 218, 219, 220, 221, 222, + 223, 224, 225, 0, 226, 227, 228, 0, 1319, 0, + 507, 0, 0, 0, 0, 1320, 1321, 1322, 1323, 1324, + 1325, 1326, 1327, 1328, 1329, 1330, 1331, 1332, 1333, 1334, + 1335, 1336, 1337, 1338, 1339, 1340, 1341, 1342, 1343, 1344, + 1345, 1346, 1347, 1348, 1349, 1350, 1351, 1352, 1353, 1354, + 1355, 1356, 1357, 633, 634, 0, 1358, 1359, 1360, 1361, + 1362, 1363, 1364, 1365, 1366, 1367, 1368, 1369, 1370, 1371, + 1372, 1373, 1374, 1375, 1376, 1377, 1378, 1546, 1379, 1380, + 0, 0, 0, 186, 187, 188, 0, 0, 0, 186, + 187, 188, 0, 0, 0, 394, 0, 0, 73, 0, + 74, 75, 76, 77, 78, 0, 0, 0, 0, 0, + 395, 0, 0, 81, 0, 0, 73, 82, 74, 75, + 76, 77, 0, 0, 0, 83, 0, 0, 0, 0, + 0, 236, 84, 0, 0, 0, 0, 0, 0, 0, + 0, 189, 0, 0, 0, 0, 0, 189, 0, 85, + 84, 0, 0, 0, 190, 191, 0, 0, 0, 1593, + 190, 191, 635, 0, 0, 0, 0, 237, 1469, 0, + 86, 87, 0, 0, 0, 0, 88, 0, 0, 0, + 0, 0, 0, 0, 396, 397, 91, 92, 86, 87, + 93, 0, 94, 192, 193, 0, 194, 636, 1622, 192, + 193, 195, 194, 196, 0, 92, 0, 195, 0, 196, + 94, 0, 0, 637, 1013, 0, 0, 0, 0, 1174, + 1013, 0, 1245, 1246, 1247, 1248, 1249, 1250, 1251, 1252, + 1253, 1254, 1255, 143, 1256, 1257, 1258, 1259, 1260, 1261, + 1262, 1263, 1264, 1265, 1266, 1267, 0, 0, 0, 0, + 0, 0, 1095, 1268, 1269, 1270, 1271, 1272, 1273, 1274, + 1275, 1276, 1277, 1278, 1279, 1280, 1281, 1282, 1283, 1284, + 1285, 1286, 0, 0, 1287, 1288, 1289, 1290, 1291, 1292, + 1293, 1294, 1295, 1296, 1297, 1298, 1299, 1300, 1301, 1302, + 1303, 1304, 0, 1305, 0, 1306, 1307, 1308, 1309, 1310, + 1311, 1312, 1313, 1314, 1315, 0, 1316, 1317, 1318, 0, + 0, 0, 0, 0, 0, 0, 1596, 0, 0, 0, + 0, 0, 0, 0, 0, 1319, 0, 0, 0, 0, + 0, 0, 1320, 1321, 1322, 1323, 1324, 1325, 1326, 1327, + 1328, 1329, 1330, 1331, 1332, 1333, 1334, 1335, 1336, 1337, + 1338, 1339, 1340, 1341, 1342, 1343, 1344, 1345, 1346, 1347, + 1348, 1349, 1350, 1351, 1352, 1353, 1354, 1355, 1356, 1357, + 0, 0, 0, 1358, 1359, 1360, 1361, 1362, 1363, 1364, + 1365, 1366, 1367, 1368, 1369, 1370, 1371, 1372, 1373, 1374, + 1375, 1376, 1377, 1378, 0, 1379, 1380, 7, 8, 9, + 10, 0, 11, 12, 13, 393, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 389, 391, 0, 0, 0, 812, 0, 0, 0, 0, - 0, 1071, 382, 0, 1074, 1075, 0, 1078, 0, 111, - 537, 218, 219, 220, 221, 222, 223, 224, 225, 0, - 226, 227, 228, 1099, 0, 0, 0, 1144, 1145, 0, - 0, 0, 0, 1154, 0, 486, 487, 0, 1155, 0, - 0, 491, 0, 0, 0, 0, 1161, 209, 210, 211, - 212, 213, 0, 202, 0, 0, 0, 869, 0, 0, - 0, 214, 0, 0, 0, 0, 0, 0, 874, 875, - 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, - 886, 887, 888, 889, 890, 891, 892, 893, 894, 1448, - 0, 898, 1512, 1513, 1514, 1515, 1516, 1517, 1518, 0, - 0, 0, 0, 0, 0, 0, 0, 539, 1519, 0, - 0, 0, 1216, 0, 0, 1217, 1218, 0, 645, 0, - 646, 0, 647, 0, 0, 262, 0, 0, 0, 1231, - 584, 0, 0, 962, 0, 1449, 0, 1449, 1449, 1449, - 1449, 1449, 0, 1449, 0, 0, 1510, 1511, 1512, 1513, - 1514, 1515, 1516, 1517, 1518, 0, 0, 1385, 0, 0, - 0, 0, 0, 0, 1519, 0, 0, 0, 0, 0, - 537, 631, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 537, 0, 0, 0, 0, 1009, 0, 0, 0, - 219, 220, 221, 222, 223, 224, 225, 0, 226, 227, - 228, 1390, 0, 1031, 0, 0, 1449, 1449, 1449, 1449, - 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, - 1449, 1449, 1449, 1449, 1449, 729, 0, 0, 1407, 0, - 0, 1409, 0, 319, 1521, 1522, 1523, 761, 0, 1524, - 1525, 1526, 1527, 1528, 111, 1529, 1530, 1531, 671, 0, - 0, 0, 0, 111, 207, 208, 209, 210, 211, 212, - 213, 0, 0, 111, 0, 0, 0, 1449, 0, 0, - 214, 0, 0, 0, 1434, 0, 0, 0, 0, 262, - 0, 0, 0, 0, 0, 0, 0, 1625, 0, 1520, - 1521, 1522, 1523, 0, 1095, 1524, 1525, 1526, 1527, 1528, - 0, 1529, 1530, 1531, 0, 0, 384, 385, 386, 1500, - 0, 1502, 1503, 1504, 1505, 1506, 0, 1509, 1449, 763, - 765, 1449, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 771, 0, 772, - 773, 774, 775, 776, 777, 0, 0, 779, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1031, 787, 788, 0, 189, 1193, 0, 860, 861, 862, - 796, 864, 0, 866, 541, 867, 868, 190, 191, 0, - 1573, 1574, 1575, 1576, 1577, 1578, 1579, 1580, 1581, 1582, - 1583, 1584, 1585, 1586, 1587, 1588, 1589, 1590, 1591, 219, - 220, 221, 222, 223, 224, 225, 0, 226, 227, 228, - 537, 0, 0, 0, 0, 0, 387, 193, 73, 194, - 74, 75, 76, 77, 195, 1095, 196, 0, 841, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1470, 0, 0, 0, - 388, 0, 84, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 7, 8, 9, 10, 237, - 11, 12, 13, 14, 0, 0, 0, 157, 0, 0, - 1394, 0, 537, 0, 1397, 0, 0, 0, 895, 0, - 86, 87, 0, 0, 0, 1644, 0, 205, 206, 207, - 208, 209, 210, 211, 212, 213, 0, 92, 0, 0, - 1533, 0, 94, 15, 1537, 214, 0, 16, 1540, 17, - 18, 19, 20, 1514, 1515, 1516, 1517, 1518, 21, 0, - 0, 1548, 22, 23, 1550, 1551, 1552, 1519, 0, 0, - 0, 0, 24, 25, 26, 982, 0, 0, 27, 0, - 0, 28, 29, 30, 31, 32, 33, 34, 35, 36, - 37, 38, 39, 40, 41, 42, 43, 44, 45, 0, - 0, 0, 0, 0, 0, 0, 0, 46, 0, 47, - 48, 0, 49, 0, 0, 0, 1063, 50, 0, 51, - 52, 53, 0, 0, 54, 0, 0, 1026, 0, 55, - 1601, 0, 56, 0, 0, 0, 57, 0, 0, 0, - 0, 58, 1609, 1610, 206, 207, 208, 209, 210, 211, - 212, 213, 0, 0, 59, 0, 0, 60, 61, 62, - 0, 214, 63, 0, 158, 65, 0, 0, 66, 0, - 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, - 225, 0, 226, 227, 228, 0, 1051, 0, 509, 0, - 0, 0, 73, 1632, 74, 75, 76, 77, 1524, 1525, - 1526, 1527, 1528, 0, 1529, 1530, 1531, 236, 0, 0, - 0, 0, 0, 0, 0, 0, 1084, 1645, 0, 0, - 0, 0, 0, 0, 0, 0, 84, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1657, 0, 0, 0, - 0, 0, 0, 237, 0, 1665, 0, 1468, 0, 0, - 0, 0, 1512, 1513, 1514, 1515, 1516, 1517, 1518, 0, - 0, 0, 0, 0, 86, 87, 0, 0, 1519, 0, - 0, 0, 0, 0, 0, 1180, 0, 0, 0, 0, - 0, 92, 0, 0, 0, 0, 94, 216, 217, 218, - 219, 220, 221, 222, 223, 224, 225, 0, 226, 227, - 228, 1245, 1246, 1247, 1248, 1249, 1250, 1251, 1252, 1253, - 1254, 1255, 1213, 1256, 1257, 1258, 1259, 1260, 1261, 1262, - 1263, 1264, 1265, 1266, 1267, 0, 0, 0, 0, 0, - 1095, 0, 1268, 1269, 1270, 1271, 1272, 1273, 1274, 1275, - 1276, 1277, 1278, 1279, 1280, 1281, 1282, 1283, 1284, 1285, - 1286, 0, 0, 1287, 1288, 1289, 1290, 1291, 1292, 1293, - 1294, 1295, 1296, 1297, 1298, 1299, 1300, 1301, 1302, 1303, - 1304, 0, 1305, 0, 1306, 1307, 1308, 1309, 1310, 1311, - 1312, 1313, 1314, 1315, 0, 1316, 1317, 1318, 0, 0, - 0, 0, 0, 0, 1595, 0, 1433, 0, 0, 1524, - 1525, 1526, 1527, 1528, 1319, 1529, 1530, 1531, 0, 0, - 0, 1320, 1321, 1322, 1323, 1324, 1325, 1326, 1327, 1328, - 1329, 1330, 1331, 1332, 1333, 1334, 1335, 1336, 1337, 1338, - 1339, 1340, 1341, 1342, 1343, 1344, 1345, 1346, 1347, 1348, - 1349, 1350, 1351, 1352, 1353, 1354, 1355, 1356, 1357, 0, - 0, 0, 1358, 1359, 1360, 1361, 1362, 1363, 1364, 1365, - 1366, 1367, 1368, 1369, 1370, 1371, 1372, 1373, 1374, 1375, - 1376, 1377, 1378, 1545, 1379, 1380, 0, 0, 1245, 1246, - 1247, 1248, 1249, 1250, 1251, 1252, 1253, 1254, 1255, 0, - 1256, 1257, 1258, 1259, 1260, 1261, 1262, 1263, 1264, 1265, - 1266, 1267, 1084, 0, 0, 0, 0, 0, 0, 1268, - 1269, 1270, 1271, 1272, 1273, 1274, 1275, 1276, 1277, 1278, - 1279, 1280, 1281, 1282, 1283, 1284, 1285, 1286, 0, 0, - 1287, 1288, 1289, 1290, 1291, 1292, 1293, 1294, 1295, 1296, - 1297, 1298, 1299, 1300, 1301, 1302, 1303, 1304, 0, 1305, - 0, 1306, 1307, 1308, 1309, 1310, 1311, 1312, 1313, 1314, - 1315, 0, 1316, 1317, 1318, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1319, 0, 0, 0, 0, 0, 0, 1320, 1321, - 1322, 1323, 1324, 1325, 1326, 1327, 1328, 1329, 1330, 1331, - 1332, 1333, 1334, 1335, 1336, 1337, 1338, 1339, 1340, 1341, - 1342, 1343, 1344, 1345, 1346, 1347, 1348, 1349, 1350, 1351, - 1352, 1353, 1354, 1355, 1356, 1357, 0, 0, 1507, 1358, - 1359, 1360, 1361, 1362, 1363, 1364, 1365, 1366, 1367, 1368, - 1369, 1370, 1371, 1372, 1373, 1374, 1375, 1376, 1377, 1378, - 0, 1379, 1380, 0, 0, 7, 8, 9, 10, 0, - 11, 12, 13, 169, 71, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1564, 1565, 1566, 1567, - 0, 1569, 0, 1570, 0, 0, 0, 0, 205, 206, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 205, + 206, 207, 208, 209, 210, 211, 212, 213, 0, 0, + 0, 0, 0, 0, 0, 15, 394, 214, 0, 170, + 0, 171, 172, 173, 174, 78, 0, 0, 0, 0, + 21, 395, 0, 0, 175, 23, 0, 0, 82, 0, + 0, 0, 0, 0, 24, 25, 176, 0, 0, 0, + 27, 0, 0, 177, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 178, 0, 0, 0, 0, 0, 0, 0, 0, 46, + 0, 47, 48, 0, 49, 0, 0, 0, 0, 50, + 0, 179, 180, 53, 0, 0, 54, 88, 0, 0, + 0, 55, 0, 0, 56, 396, 397, 91, 181, 0, + 0, 93, 0, 182, 7, 8, 9, 10, 0, 11, + 12, 13, 14, 0, 0, 0, 59, 0, 0, 60, + 61, 62, 0, 0, 63, 0, 64, 65, 0, 0, + 66, 0, 215, 216, 217, 218, 219, 220, 221, 222, + 223, 224, 225, 0, 226, 227, 228, 0, 0, 0, + 1034, 0, 15, 0, 0, 0, 16, 0, 17, 18, + 19, 20, 0, 0, 0, 0, 0, 21, 0, 958, + 959, 22, 23, 0, 0, 0, 0, 0, 0, 0, + 0, 24, 25, 26, 0, 0, 0, 27, 0, 0, + 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 43, 44, 45, 0, 0, + 0, 0, 0, 0, 0, 0, 46, 0, 47, 48, + 0, 49, 0, 0, 0, 0, 50, 0, 51, 52, + 53, 0, 0, 54, 0, 0, 0, 0, 55, 0, + 0, 56, 0, 0, 0, 57, 7, 8, 9, 10, + 58, 11, 12, 13, 14, 960, 0, 0, 157, 0, + 0, 0, 0, 59, 0, 0, 60, 61, 62, 0, + 0, 63, 0, 64, 65, 0, 0, 66, 205, 206, 207, 208, 209, 210, 211, 212, 213, 0, 0, 0, - 0, 0, 0, 15, 72, 0, 214, 170, 0, 171, - 172, 173, 174, 78, 79, 0, 0, 0, 21, 80, - 0, 0, 175, 23, 0, 0, 82, 0, 0, 0, - 0, 0, 24, 25, 176, 0, 0, 0, 27, 0, - 0, 177, 29, 30, 31, 32, 33, 34, 35, 36, - 37, 38, 39, 40, 41, 42, 43, 44, 178, 0, - 0, 0, 0, 0, 0, 0, 0, 46, 0, 47, - 48, 0, 49, 0, 0, 0, 0, 50, 0, 179, - 180, 53, 0, 0, 54, 88, 0, 0, 0, 55, - 0, 1592, 56, 89, 90, 91, 181, 0, 0, 93, - 0, 182, 7, 8, 9, 10, 0, 11, 12, 13, - 395, 0, 0, 0, 59, 0, 0, 60, 61, 62, - 0, 0, 63, 0, 64, 65, 0, 0, 66, 0, - 1621, 215, 216, 217, 218, 219, 220, 221, 222, 223, - 224, 225, 0, 226, 227, 228, 0, 0, 0, 1034, - 15, 396, 0, 0, 170, 0, 171, 172, 173, 174, - 78, 0, 0, 0, 0, 21, 397, 0, 0, 175, - 23, 0, 0, 82, 0, 0, 0, 0, 0, 24, - 25, 176, 0, 0, 0, 27, 0, 0, 177, 29, + 0, 0, 0, 0, 15, 0, 214, 0, 16, 0, + 17, 18, 19, 20, 0, 0, 0, 0, 0, 21, + 0, 0, 0, 22, 23, 0, 0, 0, 0, 0, + 0, 0, 0, 24, 25, 26, 0, 0, 0, 27, + 0, 0, 28, 29, 30, 31, 32, 33, 34, 35, + 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, + 0, 0, 0, 0, 0, 0, 0, 0, 46, 0, + 47, 48, 0, 49, 0, 0, 0, 0, 50, 0, + 51, 52, 53, 0, 0, 54, 0, 0, 0, 0, + 55, 0, 0, 56, 0, 0, 0, 57, 7, 8, + 9, 10, 58, 11, 12, 13, 14, 0, 0, 0, + 0, 0, 0, 0, 0, 59, 0, 0, 60, 61, + 62, 0, 0, 63, 0, 158, 65, 0, 0, 66, + 0, 215, 216, 217, 218, 219, 220, 221, 222, 223, + 224, 225, 0, 226, 227, 228, 15, 0, 0, 1628, + 16, 0, 17, 18, 19, 20, 0, 0, 0, 0, + 0, 21, 0, 0, 0, 22, 23, 0, 0, 0, + 0, 0, 0, 0, 0, 24, 25, 26, 0, 0, + 0, 27, 0, 0, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, + 44, 45, 0, 0, 0, 0, 0, 0, 0, 0, + 46, 0, 47, 48, 0, 49, 0, 0, 0, 0, + 50, 0, 51, 52, 53, 0, 0, 54, 0, 0, + 0, 0, 55, 0, 0, 56, 0, 0, 0, 57, + 7, 8, 9, 10, 58, 11, 12, 13, 14, 0, + 0, 0, 0, 0, 0, 0, 0, 59, 0, 0, + 60, 61, 62, 0, 0, 63, 0, 64, 65, 348, + 0, 66, 205, 206, 207, 208, 209, 210, 211, 212, + 213, 0, 0, 0, 0, 0, 0, 0, 15, 353, + 214, 0, 16, 0, 17, 18, 19, 20, 0, 0, + 0, 0, 0, 21, 0, 0, 0, 22, 23, 0, + 0, 0, 0, 0, 0, 0, 0, 24, 25, 26, + 0, 0, 0, 27, 0, 0, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, + 42, 43, 44, 45, 0, 0, 0, 0, 0, 0, + 0, 0, 46, 0, 47, 48, 0, 49, 0, 0, + 0, 0, 50, 0, 51, 52, 53, 0, 0, 54, + 0, 0, 0, 0, 55, 0, 0, 56, 0, 0, + 0, 57, 7, 8, 9, 10, 58, 11, 12, 13, + 14, 0, 0, 0, 0, 0, 0, 0, 0, 59, + 0, 0, 60, 61, 62, 0, 0, 63, 0, 64, + 65, 0, 1097, 66, 0, 215, 216, 217, 218, 219, + 220, 221, 222, 223, 224, 225, 0, 226, 227, 228, + 15, 759, 0, 0, 16, 0, 17, 18, 19, 20, + 0, 0, 0, 0, 0, 21, 0, 0, 0, 22, + 23, 0, 0, 0, 0, 0, 0, 0, 0, 24, + 25, 26, 0, 0, 0, 27, 0, 0, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 178, 0, 0, 0, 0, - 0, 0, 0, 0, 46, 0, 47, 48, 0, 49, - 0, 0, 0, 0, 50, 0, 179, 180, 53, 0, - 0, 54, 88, 0, 0, 0, 55, 0, 0, 56, - 398, 399, 91, 181, 0, 0, 93, 0, 182, 7, - 8, 9, 10, 0, 11, 12, 13, 14, 0, 0, + 40, 41, 42, 43, 44, 45, 0, 0, 73, 0, + 74, 75, 76, 77, 46, 0, 47, 48, 0, 49, + 0, 0, 0, 0, 50, 0, 51, 52, 53, 0, + 0, 54, 0, 0, 0, 0, 55, 0, 0, 56, + 0, 0, 84, 57, 7, 8, 9, 10, 58, 11, + 12, 13, 14, 0, 0, 0, 0, 0, 0, 237, 0, 59, 0, 0, 60, 61, 62, 0, 0, 63, 0, 64, 65, 0, 0, 66, 0, 0, 0, 0, - 205, 206, 207, 208, 209, 210, 211, 212, 213, 0, - 0, 0, 0, 0, 0, 0, 0, 15, 214, 0, - 0, 16, 0, 17, 18, 19, 20, 0, 0, 0, - 0, 0, 21, 0, 959, 960, 22, 23, 0, 0, - 0, 0, 0, 0, 0, 0, 24, 25, 26, 0, - 0, 0, 27, 0, 0, 28, 29, 30, 31, 32, - 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, - 43, 44, 45, 0, 0, 0, 0, 0, 0, 0, - 0, 46, 0, 47, 48, 0, 49, 0, 0, 0, - 0, 50, 0, 51, 52, 53, 0, 0, 54, 0, - 0, 0, 0, 55, 0, 0, 56, 0, 0, 0, - 57, 7, 8, 9, 10, 58, 11, 12, 13, 14, - 961, 0, 0, 0, 0, 0, 0, 0, 59, 0, - 0, 60, 61, 62, 0, 0, 63, 0, 64, 65, - 0, 0, 66, 215, 216, 217, 218, 219, 220, 221, - 222, 223, 224, 225, 0, 226, 227, 228, 0, 15, - 0, 1627, 0, 16, 0, 17, 18, 19, 20, 0, - 0, 0, 0, 0, 21, 0, 0, 0, 22, 23, - 0, 0, 0, 0, 0, 0, 0, 0, 24, 25, - 26, 0, 0, 0, 27, 0, 0, 28, 29, 30, - 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 0, 0, 0, 0, 0, - 0, 0, 0, 46, 0, 47, 48, 0, 49, 0, - 0, 0, 0, 50, 0, 51, 52, 53, 0, 0, - 54, 0, 0, 0, 0, 55, 0, 0, 56, 0, - 0, 0, 57, 7, 8, 9, 10, 58, 11, 12, - 13, 14, 0, 0, 0, 0, 0, 0, 0, 0, - 59, 0, 0, 60, 61, 62, 0, 0, 63, 0, - 64, 65, 348, 0, 66, 205, 206, 207, 208, 209, - 210, 211, 212, 213, 0, 0, 0, 0, 0, 0, - 0, 15, 353, 214, 0, 16, 0, 17, 18, 19, - 20, 0, 0, 0, 0, 0, 21, 0, 0, 0, - 22, 23, 0, 0, 0, 0, 0, 0, 0, 0, - 24, 25, 26, 0, 0, 0, 27, 0, 0, 28, - 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, - 39, 40, 41, 42, 43, 44, 45, 0, 0, 0, - 0, 0, 0, 0, 0, 46, 0, 47, 48, 0, - 49, 0, 0, 0, 0, 50, 0, 51, 52, 53, - 0, 0, 54, 0, 0, 0, 0, 55, 0, 0, - 56, 0, 0, 0, 57, 7, 8, 9, 10, 58, - 11, 12, 13, 14, 0, 0, 0, 0, 0, 0, - 0, 0, 59, 0, 0, 60, 61, 62, 0, 0, - 63, 0, 64, 65, 0, 1097, 66, 0, 215, 216, - 217, 218, 219, 220, 221, 222, 223, 224, 225, 0, - 226, 227, 228, 15, 759, 0, 0, 16, 0, 17, - 18, 19, 20, 0, 0, 0, 0, 0, 21, 0, - 0, 0, 22, 23, 0, 0, 0, 0, 0, 0, - 0, 0, 24, 25, 26, 0, 0, 0, 27, 0, - 0, 28, 29, 30, 31, 32, 33, 34, 35, 36, - 37, 38, 39, 40, 41, 42, 43, 44, 45, 0, - 0, 73, 0, 74, 75, 76, 77, 46, 0, 47, - 48, 0, 49, 0, 0, 0, 236, 50, 0, 51, - 52, 53, 0, 0, 54, 0, 0, 0, 0, 55, - 0, 0, 56, 0, 0, 84, 57, 7, 8, 9, - 10, 58, 11, 12, 13, 14, 0, 0, 0, 0, - 0, 0, 237, 0, 59, 0, 0, 60, 61, 62, - 0, 0, 63, 0, 64, 65, 0, 0, 66, 0, - 0, 0, 0, 86, 87, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 15, 0, 0, 0, 16, - 92, 17, 18, 19, 20, 94, 0, 0, 0, 0, - 21, 0, 0, 0, 22, 23, 0, 0, 0, 0, - 0, 0, 0, 0, 24, 25, 26, 0, 143, 0, - 27, 0, 0, 28, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, - 45, 0, 0, 0, 0, 0, 0, 0, 0, 46, - 0, 47, 48, 0, 49, 0, 0, 0, 0, 50, - 0, 51, 52, 53, 0, 0, 54, 0, 0, 0, - 0, 55, 0, 0, 56, 0, 0, 0, 57, 7, - 8, 9, 10, 58, 11, 12, 13, 14, 0, 0, - 0, 0, 0, 0, 0, 0, 59, 0, 0, 60, - 61, 62, 0, 0, 63, 0, 64, 65, 896, 0, - 66, 205, 206, 207, 208, 209, 210, 211, 212, 213, - 0, 0, 0, 0, 0, 0, 0, 15, 0, 214, - 0, 16, 0, 17, 18, 19, 20, 0, 0, 0, - 0, 0, 21, 0, 0, 0, 22, 23, 0, 0, - 0, 0, 0, 0, 0, 0, 24, 25, 26, 0, - 0, 0, 27, 0, 0, 28, 29, 30, 31, 32, - 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, - 43, 44, 45, 0, 0, 0, 0, 0, 0, 0, - 0, 46, 0, 47, 48, 0, 49, 0, 0, 0, - 0, 50, 0, 51, 52, 53, 0, 0, 54, 0, - 0, 0, 0, 55, 0, 0, 56, 0, 0, 0, - 57, 7, 8, 9, 10, 58, 11, 12, 13, 14, - 1092, 0, 0, 0, 0, 0, 0, 0, 59, 0, - 0, 60, 61, 62, 0, 0, 63, 0, 64, 65, - 1173, 0, 66, 0, 215, 216, 217, 218, 219, 220, - 221, 222, 223, 224, 225, 0, 226, 227, 228, 15, - 0, 0, 0, 16, 0, 17, 18, 19, 20, 0, - 0, 0, 0, 0, 21, 0, 0, 0, 22, 23, - 0, 0, 0, 0, 0, 0, 0, 0, 24, 25, - 26, 0, 0, 0, 27, 0, 0, 28, 29, 30, - 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 0, 0, 0, 0, 0, - 0, 0, 0, 46, 0, 47, 48, 0, 49, 0, - 0, 0, 0, 50, 0, 51, 52, 53, 0, 0, - 54, 0, 0, 0, 0, 55, 0, 0, 56, 0, - 0, 0, 57, 7, 8, 9, 10, 58, 11, 12, - 13, 14, 1467, 0, 0, 0, 0, 0, 0, 0, - 59, 0, 0, 60, 61, 62, 0, 0, 63, 0, - 64, 65, 0, 0, 66, 205, 206, 207, 208, 209, - 210, 211, 212, 213, 0, 0, 0, 0, 0, 0, - 0, 15, 0, 214, 0, 16, 0, 17, 18, 19, - 20, 0, 0, 0, 0, 0, 21, 0, 0, 0, - 22, 23, 0, 0, 0, 0, 0, 0, 0, 0, - 24, 25, 26, 0, 0, 0, 27, 0, 0, 28, - 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, - 39, 40, 41, 42, 43, 44, 45, 0, 0, 0, - 0, 0, 0, 0, 0, 46, 0, 47, 48, 0, - 49, 0, 0, 0, 0, 50, 0, 51, 52, 53, - 0, 0, 54, 0, 0, 0, 0, 55, 0, 0, - 56, 0, 0, 0, 57, 7, 8, 9, 10, 58, - 11, 12, 13, 14, 0, 0, 0, 0, 0, 0, - 0, 0, 59, 0, 0, 60, 61, 62, 0, 0, - 63, 0, 64, 65, 1593, 0, 66, 0, 215, 216, - 217, 218, 219, 220, 221, 222, 223, 224, 225, 0, - 226, 227, 228, 15, 0, 0, 0, 16, 0, 17, - 18, 19, 20, 0, 0, 0, 0, 0, 21, 0, - 0, 0, 22, 23, 0, 0, 0, 0, 0, 0, - 0, 0, 24, 25, 26, 0, 0, 0, 27, 0, - 0, 28, 29, 30, 31, 32, 33, 34, 35, 36, - 37, 38, 39, 40, 41, 42, 43, 44, 45, 0, - 0, 0, 0, 0, 0, 0, 0, 46, 0, 47, - 48, 0, 49, 0, 0, 0, 0, 50, 0, 51, - 52, 53, 0, 0, 54, 0, 0, 0, 0, 55, - 0, 0, 56, 0, 0, 0, 57, 7, 8, 9, - 10, 58, 11, 12, 13, 14, 0, 0, 0, 0, - 0, 0, 0, 0, 59, 0, 0, 60, 61, 62, - 0, 0, 63, 0, 64, 65, 0, 0, 66, 735, - 736, 737, 738, 739, 740, 741, 742, 743, 0, 0, - 0, 0, 0, 0, 0, 15, 0, 744, 0, 16, - 0, 17, 18, 19, 20, 0, 0, 0, 0, 0, - 21, 0, 0, 0, 22, 23, 0, 0, 0, 0, - 0, 0, 0, 0, 24, 25, 26, 0, 0, 0, - 27, 0, 0, 28, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, - 45, 0, 0, 0, 0, 0, 0, 0, 0, 46, - 0, 47, 48, 0, 49, 0, 0, 0, 0, 50, - 0, 51, 52, 53, 0, 0, 54, 0, 0, 0, - 0, 55, 0, 0, 56, 0, 0, 0, 57, 7, - 8, 9, 10, 58, 11, 12, 13, 0, 0, 0, - 0, 1498, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 63, 0, 64, 65, 0, 0, - 66, 0, 745, 746, 747, 748, 749, 750, 751, 752, - 753, 754, 755, 0, 756, 757, 758, 1435, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1436, 0, 186, 187, 188, 1437, 0, 0, - 0, 0, 0, 0, 0, 0, 24, 25, 0, 0, - 0, 0, 27, 0, 0, 0, 29, 30, 31, 32, - 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, - 43, 44, 7, 8, 9, 10, 0, 11, 12, 13, - 0, 0, 0, 0, 48, 0, 49, 0, 0, 0, - 0, 1438, 189, 0, 0, 1439, 0, 0, 1440, 0, - 0, 0, 0, 55, 0, 190, 191, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1435, 0, 0, 0, 0, 0, 0, 0, 1441, 0, - 0, 1442, 1443, 1444, 0, 1436, 1445, 0, 1499, 65, - 1437, 0, 1447, 0, 192, 193, 0, 194, 0, 24, - 25, 0, 195, 0, 196, 27, 0, 0, 0, 29, - 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 186, 187, 188, 770, 0, - 0, 0, 0, 0, 0, 0, 0, 48, 0, 49, - 550, 551, 552, 10, 1438, 11, 553, 554, 1439, 0, - 0, 1440, 555, 0, 0, 0, 55, 0, 0, 0, - 0, 0, 0, 0, 550, 551, 552, 10, 0, 11, - 553, 554, 0, 0, 0, 0, 872, 0, 0, 0, - 0, 0, 0, 189, 0, 109, 0, 110, 556, 1445, - 0, 1446, 65, 0, 0, 1447, 190, 191, 0, 0, - 0, 0, 0, 557, 0, 0, 0, 0, 558, 109, - 0, 110, 556, 0, 0, 0, 0, 559, 560, 0, - 0, 0, 0, 0, 0, 0, 0, 557, 0, 0, - 0, 0, 558, 0, 0, 192, 1010, 1011, 1012, 0, - 0, 559, 560, 195, 0, 196, 73, 0, 74, 75, - 76, 77, 561, 0, 0, 562, 1013, 563, 0, 0, - 0, 1014, 564, 0, 0, 0, 565, 0, 0, 566, - 0, 0, 0, 0, 567, 0, 561, 568, 0, 562, - 84, 563, 550, 551, 552, 10, 564, 11, 553, 554, - 565, 0, 0, 566, 720, 0, 0, 237, 567, 569, - 0, 568, 570, 571, 0, 0, 0, 572, 0, 573, - 0, 0, 0, 574, 0, 0, 0, 0, 86, 87, - 0, 0, 0, 569, 0, 0, 570, 571, 0, 0, - 556, 572, 0, 573, 0, 92, 0, 574, 0, 0, - 94, 0, 0, 0, 0, 557, 0, 0, 0, 0, - 558, 1101, 0, 0, 0, 0, 0, 0, 0, 559, - 560, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, - 0, 0, 0, 0, 0, 186, 187, 188, 0, 1111, - 0, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, - 1121, 1122, 1123, 0, 561, 0, 0, 562, 0, 563, - 0, 0, 0, 0, 564, 0, 0, 0, 565, 0, - 0, 566, 0, 0, 1124, 0, 567, 0, 0, 568, - 634, 635, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 189, 0, 0, 0, 0, 0, 629, - 0, 569, 0, 0, 570, 571, 190, 191, 0, 572, - 0, 721, 0, 0, 0, 574, 0, 0, 0, 0, - 1125, 0, 396, 0, 0, 73, 0, 74, 75, 76, - 77, 78, 0, 0, 0, 0, 0, 397, 0, 630, - 81, 0, 0, 0, 82, 192, 193, 0, 194, 186, - 187, 188, 83, 195, 0, 196, 0, 0, 0, 84, - 1126, 0, 0, 1127, 0, 1128, 1129, 1130, 1131, 1132, - 1133, 1134, 1135, 1136, 1137, 1138, 85, 1139, 1140, 0, - 0, 1141, 0, 0, 634, 635, 0, 0, 0, 636, - 0, 0, 0, 186, 187, 188, 0, 86, 87, 0, - 0, 0, 0, 88, 0, 0, 0, 189, 0, 0, - 0, 398, 399, 91, 92, 0, 0, 93, 0, 94, - 190, 191, 0, 0, 637, 0, 396, 0, 0, 73, - 0, 74, 75, 76, 77, 78, 0, 0, 0, 0, - 638, 397, 0, 0, 81, 0, 0, 0, 82, 0, - 0, 189, 0, 0, 0, 0, 83, 0, 0, 192, - 193, 0, 194, 84, 190, 191, 0, 195, 0, 196, - 0, 186, 187, 188, 0, 0, 0, 782, 783, 0, - 85, 0, 0, 0, 259, 0, 0, 0, 0, 0, - 0, 0, 0, 636, 0, 0, 0, 0, 0, 0, - 0, 86, 87, 192, 193, 0, 194, 88, 0, 0, - 0, 195, 0, 196, 0, 398, 399, 91, 92, 396, - 0, 93, 73, 94, 74, 75, 76, 77, 78, 189, - 0, 0, 0, 0, 397, 0, 0, 81, 0, 0, - 0, 82, 190, 191, 638, 0, 0, 0, 0, 83, - 0, 0, 0, 0, 0, 0, 84, 205, 206, 207, - 208, 209, 210, 211, 212, 213, 0, 0, 0, 0, - 0, 0, 0, 85, 0, 214, 0, 0, 0, 0, - 0, 192, 193, 0, 194, 0, 636, 0, 0, 195, - 0, 196, 0, 0, 86, 87, 0, 0, 0, 0, - 88, 0, 1013, 0, 0, 0, 0, 1174, 398, 399, - 91, 92, 0, 0, 93, 0, 94, 205, 206, 207, - 208, 209, 210, 211, 212, 213, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 214, 0, 638, 205, 206, + 86, 87, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 15, 0, 0, 0, 16, 92, 17, 18, + 19, 20, 94, 0, 0, 0, 0, 21, 0, 0, + 0, 22, 23, 0, 0, 0, 0, 0, 0, 0, + 0, 24, 25, 26, 0, 155, 0, 27, 0, 0, + 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 43, 44, 45, 0, 0, + 0, 0, 0, 0, 0, 0, 46, 0, 47, 48, + 0, 49, 0, 0, 0, 0, 50, 0, 51, 52, + 53, 0, 0, 54, 0, 0, 0, 0, 55, 0, + 0, 56, 0, 0, 0, 57, 7, 8, 9, 10, + 58, 11, 12, 13, 14, 0, 0, 0, 0, 0, + 0, 0, 0, 59, 0, 0, 60, 61, 62, 0, + 0, 63, 0, 64, 65, 895, 0, 66, 205, 206, 207, 208, 209, 210, 211, 212, 213, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 214, 205, 206, 207, + 0, 0, 0, 0, 15, 0, 214, 0, 16, 0, + 17, 18, 19, 20, 0, 0, 0, 0, 0, 21, + 0, 0, 0, 22, 23, 0, 0, 0, 0, 0, + 0, 0, 0, 24, 25, 26, 0, 0, 0, 27, + 0, 0, 28, 29, 30, 31, 32, 33, 34, 35, + 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, + 0, 0, 0, 0, 0, 0, 0, 0, 46, 0, + 47, 48, 0, 49, 0, 0, 0, 0, 50, 0, + 51, 52, 53, 0, 0, 54, 0, 0, 0, 0, + 55, 0, 0, 56, 0, 0, 0, 57, 7, 8, + 9, 10, 58, 11, 12, 13, 14, 1092, 0, 0, + 0, 0, 0, 0, 0, 59, 0, 0, 60, 61, + 62, 0, 0, 63, 0, 64, 65, 1410, 0, 66, + 0, 215, 216, 217, 218, 219, 220, 221, 222, 223, + 224, 225, 0, 226, 227, 228, 15, 0, 0, 0, + 16, 0, 17, 18, 19, 20, 0, 0, 0, 0, + 0, 21, 0, 0, 0, 22, 23, 0, 0, 0, + 0, 0, 0, 0, 0, 24, 25, 26, 0, 0, + 0, 27, 0, 0, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, + 44, 45, 0, 0, 0, 0, 0, 0, 0, 0, + 46, 0, 47, 48, 0, 49, 0, 0, 0, 0, + 50, 0, 51, 52, 53, 0, 0, 54, 0, 0, + 0, 0, 55, 0, 0, 56, 0, 0, 0, 57, + 7, 8, 9, 10, 58, 11, 12, 13, 14, 1468, + 0, 0, 0, 0, 0, 0, 0, 59, 0, 0, + 60, 61, 62, 0, 0, 63, 0, 64, 65, 0, + 0, 66, 205, 206, 207, 208, 209, 210, 211, 212, + 213, 0, 0, 0, 0, 0, 0, 0, 15, 0, + 214, 0, 16, 0, 17, 18, 19, 20, 0, 0, + 0, 0, 0, 21, 0, 0, 0, 22, 23, 0, + 0, 0, 0, 0, 0, 0, 0, 24, 25, 26, + 0, 0, 0, 27, 0, 0, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, + 42, 43, 44, 45, 0, 0, 0, 0, 0, 0, + 0, 0, 46, 0, 47, 48, 0, 49, 0, 0, + 0, 0, 50, 0, 51, 52, 53, 0, 0, 54, + 0, 0, 0, 0, 55, 0, 0, 56, 0, 0, + 0, 57, 7, 8, 9, 10, 58, 11, 12, 13, + 14, 0, 0, 0, 0, 0, 0, 0, 0, 59, + 0, 0, 60, 61, 62, 0, 0, 63, 0, 64, + 65, 1594, 0, 66, 0, 215, 216, 217, 218, 219, + 220, 221, 222, 223, 224, 225, 0, 226, 227, 228, + 15, 0, 0, 0, 16, 0, 17, 18, 19, 20, + 0, 0, 0, 0, 0, 21, 0, 0, 0, 22, + 23, 0, 0, 0, 0, 0, 0, 0, 0, 24, + 25, 26, 0, 0, 0, 27, 0, 0, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 0, 0, 0, 0, + 0, 0, 0, 0, 46, 0, 47, 48, 0, 49, + 0, 0, 0, 0, 50, 0, 51, 52, 53, 0, + 0, 54, 0, 0, 0, 0, 55, 0, 0, 56, + 0, 0, 0, 57, 7, 8, 9, 10, 58, 11, + 12, 13, 14, 0, 207, 208, 209, 210, 211, 212, + 213, 59, 0, 0, 60, 61, 62, 0, 0, 63, + 214, 64, 65, 0, 0, 66, 735, 736, 737, 738, + 739, 740, 741, 742, 743, 0, 0, 0, 0, 0, + 0, 0, 15, 0, 744, 0, 16, 0, 17, 18, + 19, 20, 0, 0, 0, 0, 0, 21, 0, 0, + 0, 22, 23, 0, 0, 0, 0, 0, 0, 0, + 0, 24, 25, 26, 0, 0, 0, 27, 0, 0, + 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 43, 44, 45, 0, 0, + 0, 0, 0, 0, 0, 0, 46, 0, 47, 48, + 0, 49, 0, 0, 0, 0, 50, 0, 51, 52, + 53, 0, 0, 54, 0, 0, 0, 0, 55, 0, + 0, 56, 0, 0, 0, 57, 7, 8, 9, 10, + 58, 11, 12, 13, 0, 0, 216, 217, 218, 219, + 220, 221, 222, 223, 224, 225, 0, 226, 227, 228, + 0, 63, 0, 64, 65, 0, 0, 66, 0, 745, + 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, + 0, 756, 757, 758, 1436, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1437, + 0, 0, 0, 0, 1438, 0, 0, 0, 0, 0, + 0, 0, 0, 24, 25, 0, 0, 0, 0, 27, + 0, 0, 0, 29, 30, 31, 32, 33, 34, 35, + 36, 37, 38, 39, 40, 41, 42, 43, 44, 7, + 8, 9, 10, 0, 11, 12, 13, 0, 0, 0, + 0, 48, 0, 49, 0, 0, 0, 0, 1439, 0, + 0, 0, 1440, 0, 0, 1441, 0, 0, 0, 0, + 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1436, 0, 0, + 0, 0, 0, 0, 0, 1442, 0, 0, 1443, 1444, + 1445, 0, 1437, 1446, 0, 1447, 65, 1438, 0, 1448, + 209, 210, 211, 212, 213, 0, 24, 25, 0, 0, + 0, 0, 27, 0, 214, 0, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, + 43, 44, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 48, 0, 49, 0, 0, 0, + 0, 1439, 0, 0, 1101, 1440, 0, 0, 1441, 633, + 634, 0, 0, 55, 1102, 1103, 1104, 1105, 1106, 1107, + 1108, 1109, 1110, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1111, 0, 1112, 1113, 1114, 1115, 1116, 1117, + 1118, 1119, 1120, 1121, 1122, 1123, 1446, 0, 1447, 65, + 0, 394, 1448, 0, 73, 0, 74, 75, 76, 77, + 78, 0, 0, 0, 0, 0, 395, 1124, 0, 81, + 0, 0, 0, 82, 0, 0, 0, 0, 186, 187, + 188, 83, 0, 1050, 0, 0, 0, 0, 84, 0, + 0, 0, 0, 219, 220, 221, 222, 223, 224, 225, + 0, 226, 227, 228, 0, 85, 0, 0, 0, 0, + 0, 0, 0, 1125, 0, 0, 0, 0, 635, 0, + 0, 0, 0, 0, 0, 0, 86, 87, 0, 0, + 782, 783, 88, 0, 0, 0, 189, 0, 0, 0, + 396, 397, 91, 92, 0, 0, 93, 0, 94, 190, + 191, 0, 0, 1126, 0, 0, 1127, 0, 1128, 1129, + 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 637, + 1139, 1140, 394, 0, 1141, 73, 0, 74, 75, 76, + 77, 78, 0, 0, 0, 0, 0, 395, 192, 193, + 81, 194, 0, 0, 82, 0, 195, 0, 196, 0, + 0, 0, 83, 0, 0, 0, 0, 0, 0, 84, + 205, 206, 207, 208, 209, 210, 211, 212, 213, 0, + 0, 0, 0, 0, 0, 0, 85, 0, 214, 0, + 0, 73, 0, 74, 75, 76, 77, 0, 0, 635, + 0, 0, 0, 0, 0, 0, 0, 86, 87, 0, + 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, + 0, 396, 397, 91, 92, 84, 0, 93, 0, 94, + 205, 206, 207, 208, 209, 210, 211, 212, 213, 0, + 0, 0, 237, 0, 0, 0, 0, 0, 214, 0, + 637, 205, 206, 207, 208, 209, 210, 211, 212, 213, + 0, 0, 0, 86, 87, 0, 0, 0, 0, 214, + 205, 206, 207, 208, 209, 210, 211, 212, 213, 0, + 92, 0, 0, 0, 0, 94, 0, 0, 214, 205, + 206, 207, 208, 209, 210, 211, 212, 213, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 214, 156, 913, + 0, 0, 0, 215, 216, 217, 218, 219, 220, 221, + 222, 223, 224, 225, 0, 226, 227, 228, 914, 205, + 206, 207, 208, 209, 210, 211, 212, 213, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 214, 205, 206, + 207, 208, 209, 210, 211, 212, 213, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 214, 0, 0, 0, + 0, 0, 0, 215, 216, 217, 218, 219, 220, 221, + 222, 223, 224, 225, 0, 226, 227, 228, 305, 0, + 0, 0, 0, 0, 215, 216, 217, 218, 219, 220, + 221, 222, 223, 224, 225, 0, 226, 227, 228, 493, + 0, 0, 0, 215, 216, 217, 218, 219, 220, 221, + 222, 223, 224, 225, 0, 226, 227, 228, 509, 0, + 0, 0, 215, 216, 217, 218, 219, 220, 221, 222, + 223, 224, 225, 0, 226, 227, 228, 588, 205, 206, + 207, 208, 209, 210, 211, 212, 213, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 214, 0, 0, 0, + 0, 0, 215, 216, 217, 218, 219, 220, 221, 222, + 223, 224, 225, 0, 226, 227, 228, 647, 0, 0, + 0, 215, 216, 217, 218, 219, 220, 221, 222, 223, + 224, 225, 0, 226, 227, 228, 768, 205, 206, 207, 208, 209, 210, 211, 212, 213, 0, 0, 0, 0, 0, 0, 0, 0, 0, 214, 205, 206, 207, 208, - 209, 210, 211, 212, 213, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 214, 0, 914, 0, 0, 0, - 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, - 225, 0, 226, 227, 228, 915, 205, 206, 207, 208, 209, 210, 211, 212, 213, 0, 0, 0, 0, 0, 0, 0, 0, 0, 214, 205, 206, 207, 208, 209, 210, 211, 212, 213, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 214, 0, 0, 0, 0, 0, 0, - 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, - 225, 0, 226, 227, 228, 305, 0, 0, 0, 0, - 0, 215, 216, 217, 218, 219, 220, 221, 222, 223, - 224, 225, 0, 226, 227, 228, 495, 0, 0, 0, - 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, - 225, 0, 226, 227, 228, 511, 0, 0, 0, 215, - 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, - 0, 226, 227, 228, 589, 205, 206, 207, 208, 209, - 210, 211, 212, 213, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 214, 0, 0, 0, 0, 0, 215, - 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, - 0, 226, 227, 228, 648, 0, 0, 0, 215, 216, - 217, 218, 219, 220, 221, 222, 223, 224, 225, 0, - 226, 227, 228, 768, 205, 206, 207, 208, 209, 210, + 0, 0, 0, 214, 205, 206, 207, 208, 209, 210, 211, 212, 213, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 214, 205, 206, 207, 208, 209, 210, 211, - 212, 213, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 214, 205, 206, 207, 208, 209, 210, 211, 212, - 213, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 214, 205, 206, 207, 208, 209, 210, 211, 212, 213, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 214, - 0, 0, 0, 0, 0, 0, 0, 0, 215, 216, + 0, 0, 214, 0, 0, 0, 0, 0, 0, 0, + 0, 215, 216, 217, 218, 219, 220, 221, 222, 223, + 224, 225, 0, 226, 227, 228, 899, 1511, 1512, 1513, + 1514, 1515, 1516, 1517, 1518, 1519, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1520, 1511, 1512, 1513, 1514, + 1515, 1516, 1517, 1518, 1519, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1520, 0, 0, 0, 0, 0, + 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, + 225, 0, 226, 227, 228, 979, 0, 0, 0, 215, + 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, + 0, 226, 227, 228, 1030, 0, 505, 0, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 0, - 226, 227, 228, 900, 1510, 1511, 1512, 1513, 1514, 1515, - 1516, 1517, 1518, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1519, 1511, 1512, 1513, 1514, 1515, 1516, 1517, - 1518, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1519, 0, 0, 0, 0, 0, 0, 215, 216, 217, + 226, 227, 228, 0, 0, 1032, 0, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 0, 226, - 227, 228, 980, 0, 0, 0, 215, 216, 217, 218, - 219, 220, 221, 222, 223, 224, 225, 0, 226, 227, - 228, 1030, 0, 507, 0, 215, 216, 217, 218, 219, - 220, 221, 222, 223, 224, 225, 0, 226, 227, 228, - 0, 0, 1032, 0, 215, 216, 217, 218, 219, 220, - 221, 222, 223, 224, 225, 0, 226, 227, 228, 207, - 208, 209, 210, 211, 212, 213, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 214, 207, 208, 209, 210, - 211, 212, 213, 0, 0, 0, 0, 1520, 1521, 1522, - 1523, 0, 214, 1524, 1525, 1526, 1527, 1528, 0, 1529, - 1530, 1531, 0, 0, 0, 0, 1521, 1522, 1523, 0, - 598, 1524, 1525, 1526, 1527, 1528, 0, 1529, 1530, 1531, - 1512, 1513, 1514, 1515, 1516, 1517, 1518, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1519, 1512, 1513, 1514, - 1515, 1516, 1517, 1518, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1519, 0, 0, 0, 0, 409, 0, - 73, 0, 74, 75, 76, 77, 410, 411, 412, 413, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 415, - 416, 417, 418, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 591, 0, 84, 0, 0, 0, 0, 0, - 0, 216, 217, 218, 219, 220, 221, 222, 223, 224, - 225, 237, 226, 227, 228, 0, 0, 428, 0, 217, - 218, 219, 220, 221, 222, 223, 224, 225, 433, 226, - 227, 228, 86, 87, 434, 0, 0, 0, 436, 437, - 0, 598, 0, 0, 0, 0, 0, 0, 0, 92, - 440, 0, 441, 0, 94, 0, 916, 917, 918, 0, - 0, 0, 0, 1522, 1523, 0, 0, 1524, 1525, 1526, - 1527, 1528, 0, 1529, 1530, 1531, 0, 155, 0, 0, - 0, 1523, 0, 0, 1524, 1525, 1526, 1527, 1528, 409, - 1529, 1530, 1531, 0, 0, 0, 0, 410, 411, 412, - 413, 73, 0, 74, 75, 76, 77, 919, 920, 0, - 415, 590, 417, 418, 0, 0, 81, 0, 0, 916, - 917, 918, 0, 591, 0, 0, 0, 0, 83, 0, - 0, 0, 0, 0, 0, 84, 0, 0, 73, 0, - 74, 75, 76, 77, 0, 0, 0, 0, 428, 0, - 0, 0, 85, 70, 71, 0, 0, 0, 0, 433, - 0, 0, 0, 0, 73, 434, 74, 75, 76, 77, - 437, 0, 84, 86, 87, 0, 0, 0, 0, 81, - 0, 440, 0, 441, 0, 0, 0, 921, 0, 237, - 92, 83, 0, 93, 72, 94, 0, 73, 84, 74, - 75, 76, 77, 78, 529, 0, 0, 0, 0, 80, - 86, 87, 81, 0, 0, 85, 82, 0, 0, 0, - 0, 0, 0, 0, 83, 0, 0, 92, 0, 0, - 0, 84, 94, 0, 0, 0, 86, 87, 0, 0, - 0, 0, 0, 0, 0, 0, 70, 71, 85, 0, - 0, 0, 0, 92, 0, 156, 93, 0, 94, 0, - 0, 0, 0, 0, 0, 0, 530, 0, 0, 86, - 87, 0, 70, 71, 0, 88, 0, 0, 0, 0, - 0, 0, 0, 89, 90, 91, 92, 72, 0, 93, - 73, 94, 74, 75, 76, 77, 78, 79, 0, 0, - 0, 0, 80, 0, 0, 81, 0, 0, 0, 82, - 0, 0, 0, 72, 0, 0, 73, 83, 74, 75, - 76, 77, 78, 0, 84, 0, 0, 0, 80, 0, - 0, 81, 0, 0, 0, 82, 0, 0, 0, 0, - 0, 85, 0, 83, 0, 0, 0, 0, 0, 0, - 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 86, 87, 0, 70, 71, 85, 88, 0, - 0, 0, 0, 0, 0, 0, 89, 90, 91, 92, - 0, 0, 93, 0, 94, 681, 0, 0, 86, 87, - 0, 70, 0, 0, 88, 0, 0, 0, 0, 0, - 0, 0, 89, 90, 91, 92, 72, 0, 93, 73, - 94, 74, 75, 76, 77, 78, 0, 0, 0, 0, - 0, 80, 0, 0, 81, 0, 0, 0, 82, 0, - 0, 0, 72, 0, 0, 73, 83, 74, 75, 76, - 77, 78, 793, 84, 0, 0, 0, 80, 0, 0, - 81, 0, 0, 0, 82, 0, 0, 0, 0, 0, - 85, 0, 83, 0, 0, 0, 0, 0, 0, 84, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 86, 87, 0, 144, 0, 85, 88, 0, 0, - 0, 0, 0, 0, 0, 89, 90, 91, 92, 0, - 0, 93, 0, 94, 0, 0, 0, 86, 87, 0, - 144, 0, 0, 88, 0, 0, 0, 0, 0, 0, - 0, 89, 90, 91, 92, 145, 0, 93, 73, 94, - 74, 75, 76, 77, 78, 983, 0, 0, 0, 0, - 146, 0, 0, 81, 0, 0, 0, 82, 0, 0, - 0, 145, 0, 0, 73, 83, 74, 75, 76, 77, - 78, 0, 84, 0, 0, 0, 146, 0, 0, 81, + 227, 228, 207, 208, 209, 210, 211, 212, 213, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 214, 207, + 208, 209, 210, 211, 212, 213, 0, 0, 1626, 0, + 1521, 1522, 1523, 1524, 0, 214, 1525, 1526, 1527, 1528, + 1529, 0, 1530, 1531, 1532, 0, 0, 0, 0, 1521, + 1522, 1523, 1524, 0, 0, 1525, 1526, 1527, 1528, 1529, + 0, 1530, 1531, 1532, 1513, 1514, 1515, 1516, 1517, 1518, + 1519, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1520, 207, 208, 209, 210, 211, 212, 213, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 214, 1513, 1514, + 1515, 1516, 1517, 1518, 1519, 0, 0, 0, 73, 0, + 74, 75, 76, 77, 1520, 1513, 1514, 1515, 1516, 1517, + 1518, 1519, 0, 0, 1513, 1514, 1515, 1516, 1517, 1518, + 1519, 1520, 0, 0, 0, 0, 0, 0, 0, 0, + 1520, 0, 84, 0, 0, 217, 218, 219, 220, 221, + 222, 223, 224, 225, 0, 226, 227, 228, 0, 237, + 0, 0, 0, 218, 219, 220, 221, 222, 223, 224, + 225, 0, 226, 227, 228, 1515, 1516, 1517, 1518, 1519, + 86, 87, 0, 0, 0, 0, 0, 0, 0, 1520, + 0, 0, 0, 0, 0, 0, 0, 92, 0, 0, + 0, 0, 94, 0, 0, 0, 1522, 1523, 1524, 0, + 0, 1525, 1526, 1527, 1528, 1529, 0, 1530, 1531, 1532, + 0, 0, 0, 0, 0, 162, 219, 220, 221, 222, + 223, 224, 225, 0, 226, 227, 228, 0, 0, 0, + 0, 1523, 1524, 0, 0, 1525, 1526, 1527, 1528, 1529, + 655, 1530, 1531, 1532, 0, 0, 0, 0, 0, 1524, + 597, 0, 1525, 1526, 1527, 1528, 1529, 0, 1530, 1531, + 1532, 1525, 1526, 1527, 1528, 1529, 0, 1530, 1531, 1532, + 0, 109, 0, 110, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 656, 0, 657, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 407, 0, + 0, 915, 916, 917, 658, 0, 408, 409, 410, 411, + 1525, 1526, 1527, 1528, 1529, 0, 1530, 1531, 1532, 413, + 589, 415, 416, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 590, 0, 0, 0, 659, 0, 0, 660, + 661, 0, 0, 662, 0, 0, 73, 0, 74, 75, + 76, 77, 918, 919, 915, 916, 917, 426, 0, 663, + 0, 81, 0, 0, 0, 0, 0, 0, 431, 0, + 0, 664, 0, 83, 432, 0, 0, 0, 0, 435, + 84, 0, 0, 0, 0, 665, 0, 0, 0, 0, + 438, 0, 439, 0, 0, 70, 71, 85, 0, 73, + 0, 74, 75, 76, 77, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 81, 0, 0, 0, 86, 87, + 0, 0, 0, 0, 0, 73, 83, 74, 75, 76, + 77, 0, 920, 84, 0, 92, 72, 0, 93, 73, + 94, 74, 75, 76, 77, 78, 527, 0, 0, 0, + 85, 80, 0, 0, 81, 0, 0, 0, 82, 84, + 0, 0, 0, 0, 0, 0, 83, 0, 0, 0, + 0, 86, 87, 84, 0, 0, 237, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 92, 0, + 85, 93, 0, 94, 70, 71, 0, 86, 87, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 528, 0, + 0, 86, 87, 0, 92, 0, 0, 88, 0, 94, + 70, 71, 0, 0, 0, 89, 90, 91, 92, 0, + 0, 93, 0, 94, 0, 72, 0, 0, 73, 0, + 74, 75, 76, 77, 78, 79, 0, 0, 0, 0, + 80, 0, 0, 81, 0, 0, 0, 82, 0, 0, + 0, 72, 0, 0, 73, 83, 74, 75, 76, 77, + 78, 0, 84, 0, 0, 0, 80, 0, 0, 81, 0, 0, 0, 82, 0, 0, 0, 0, 0, 85, 0, 83, 0, 0, 0, 0, 0, 0, 84, 0, - 0, 0, 0, 0, 0, 0, 186, 187, 188, 0, - 86, 87, 0, 70, 0, 85, 88, 0, 0, 0, - 0, 186, 187, 188, 147, 148, 91, 92, 0, 0, - 93, 0, 94, 0, 0, 0, 86, 87, 0, 0, - 0, 0, 88, 186, 187, 188, 0, 0, 0, 0, - 147, 148, 91, 92, 72, 0, 93, 73, 94, 74, - 75, 76, 77, 78, 189, 0, 0, 0, 0, 80, - 0, 0, 81, 0, 0, 0, 82, 190, 191, 189, - 0, 0, 0, 0, 83, 0, 0, 0, 0, 0, - 0, 84, 190, 191, 0, 0, 0, 186, 187, 188, - 0, 189, 1050, 0, 0, 0, 0, 0, 85, 0, - 0, 0, 0, 0, 190, 191, 192, 193, 0, 194, - 0, 0, 0, 0, 195, 0, 196, 0, 0, 86, - 87, 192, 193, 0, 194, 88, 0, 1013, 0, 195, - 0, 196, 1176, 89, 90, 91, 92, 0, 0, 93, - 0, 94, 1013, 192, 193, 189, 194, 1178, 0, 0, - 0, 195, 73, 196, 74, 75, 76, 77, 190, 191, - 0, 409, 0, 0, 1013, 0, 0, 0, 0, 410, - 411, 412, 413, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 415, 590, 417, 418, 84, 0, 0, 0, - 420, 0, 0, 0, 0, 591, 0, 192, 193, 0, - 194, 0, 0, 237, 0, 195, 0, 196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 428, 0, 0, 0, 86, 87, 0, 0, 0, 0, - 0, 433, 0, 0, 0, 0, 0, 434, 408, 409, - 0, 92, 437, 0, 0, 0, 94, 410, 411, 412, - 413, 0, 439, 440, 0, 441, 0, 0, 414, 0, - 415, 416, 417, 418, 419, 0, 0, 0, 420, 162, - -161, 0, 0, 421, 0, 0, 0, 0, 0, 0, + 86, 87, 0, 70, 71, 85, 88, 0, 0, 0, + 0, 0, 0, 0, 89, 90, 91, 92, 0, 0, + 93, 0, 94, 680, 0, 0, 86, 87, 0, 70, + 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, + 89, 90, 91, 92, 72, 0, 93, 73, 94, 74, + 75, 76, 77, 78, 0, 0, 0, 0, 0, 80, + 0, 0, 81, 0, 0, 0, 82, 0, 0, 0, + 72, 0, 0, 73, 83, 74, 75, 76, 77, 78, + 793, 84, 0, 0, 0, 80, 0, 0, 81, 0, + 0, 0, 82, 0, 0, 0, 0, 0, 85, 0, + 83, 0, 0, 0, 0, 0, 0, 84, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, + 87, 0, 144, 0, 85, 88, 0, 0, 0, 0, + 0, 0, 0, 89, 90, 91, 92, 0, 0, 93, + 0, 94, 0, 0, 0, 86, 87, 0, 144, 0, + 0, 88, 0, 0, 0, 0, 0, 0, 0, 89, + 90, 91, 92, 145, 0, 93, 73, 94, 74, 75, + 76, 77, 78, 982, 0, 0, 0, 0, 146, 0, + 0, 81, 0, 0, 0, 82, 0, 0, 0, 145, + 0, 0, 73, 83, 74, 75, 76, 77, 78, 0, + 84, 0, 0, 0, 146, 0, 0, 81, 0, 0, + 0, 82, 0, 0, 0, 0, 0, 85, 0, 83, + 0, 0, 0, 0, 0, 0, 84, 0, 0, 0, + 0, 0, 0, 0, 186, 187, 188, 0, 86, 87, + 0, 70, 0, 85, 88, 0, 0, 0, 0, 186, + 187, 188, 147, 148, 91, 92, 0, 0, 93, 0, + 94, 0, 0, 0, 86, 87, 0, 0, 0, 0, + 88, 186, 187, 188, 0, 0, 0, 0, 147, 148, + 91, 92, 72, 0, 93, 73, 94, 74, 75, 76, + 77, 78, 189, 0, 0, 0, 0, 80, 0, 0, + 81, 0, 0, 0, 82, 190, 191, 189, 0, 0, + 0, 0, 83, 0, 0, 0, 0, 407, 0, 84, + 190, 191, 0, 0, 0, 408, 409, 410, 411, 189, + 0, 0, 0, 0, 0, 628, 85, 0, 413, 589, + 415, 416, 190, 191, 192, 193, 418, 194, 0, 0, + 0, 590, 195, 0, 196, 0, 0, 86, 87, 192, + 193, 0, 194, 88, 0, 1013, 0, 195, 0, 196, + 1176, 89, 90, 91, 92, 629, 426, 93, 0, 94, + 1013, 192, 193, 0, 194, 1178, 0, 431, 0, 195, + 0, 196, 0, 432, 406, 407, 0, 0, 435, 0, + 0, 0, 0, 408, 409, 410, 411, 0, 437, 438, + 0, 439, 0, 0, 412, 0, 413, 414, 415, 416, + 417, 0, 0, 0, 418, 0, -161, 0, 0, 419, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 422, 423, 424, 425, 426, 427, 428, 429, - 0, 0, 0, 0, 0, 0, 430, 431, 432, 433, - 0, 0, 0, 0, 0, 434, 435, 409, 0, 436, - 437, 0, 0, 0, 438, 410, 411, 412, 413, 0, - 439, 440, 0, 441, 0, 0, 0, 0, 415, 416, - 417, 418, 0, 0, 409, 0, 420, 0, 409, 0, - 0, 591, 410, 411, 412, 413, 410, 411, 412, 413, - 0, 0, 0, 0, 0, 415, 590, 417, 418, 415, - 590, 417, 418, 0, 0, 0, 428, 0, 591, 0, - 0, 0, 591, 0, 0, 0, 0, 433, 0, 0, - 0, 0, 0, 434, 0, 0, 0, 436, 437, 0, - 0, 0, 0, 428, 605, 0, 0, 428, 439, 440, - 0, 441, 0, 0, 433, 0, 0, 0, 433, 0, - 434, 0, 0, 0, 434, 437, 0, 0, 0, 437, - 0, 0, 0, 0, 0, 0, 440, 0, 441, 0, - 440, 0, 441 + 0, 0, 0, 0, 0, 0, 0, 0, 420, 421, + 422, 423, 424, 425, 426, 427, 0, 0, 0, 0, + 0, 0, 428, 429, 430, 431, 0, 0, 0, 0, + 0, 432, 433, 407, 0, 434, 435, 0, 0, 0, + 436, 408, 409, 410, 411, 0, 437, 438, 0, 439, + 0, 0, 0, 0, 413, 414, 415, 416, 0, 0, + 407, 0, 418, 0, 407, 0, 0, 590, 408, 409, + 410, 411, 408, 409, 410, 411, 0, 0, 0, 0, + 0, 413, 589, 415, 416, 413, 589, 415, 416, 0, + 0, 0, 426, 0, 590, 0, 0, 73, 590, 74, + 75, 76, 77, 431, 0, 0, 0, 0, 0, 432, + 0, 0, 236, 434, 435, 0, 0, 0, 0, 426, + 604, 0, 0, 426, 437, 438, 0, 439, 0, 0, + 431, 84, 0, 0, 431, 0, 432, 0, 0, 0, + 432, 435, 0, 0, 0, 435, 0, 0, 237, 0, + 0, 0, 438, 0, 439, 0, 438, 0, 439, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, + 87, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 92, 0, 0, 0, + 0, 94 }; static const yytype_int16 yycheck[] = { - 1, 96, 503, 394, 64, 850, 416, 436, 394, 436, - 114, 263, 116, 117, 118, 119, 120, 1092, 122, 46, - 124, 79, 126, 263, 46, 79, 561, 46, 931, 952, - 544, 263, 502, 15, 257, 258, 533, 34, 263, 143, - 6, 155, 8, 940, 15, 784, 943, 944, 13, 393, - 531, 155, 156, 158, 155, 15, 15, 677, 162, 163, - 158, 0, 985, 177, 65, 154, 158, 10, 173, 61, - 13, 15, 532, 174, 155, 173, 938, 85, 86, 87, - 48, 173, 50, 172, 92, 1010, 1011, 1012, 48, 154, - 50, 155, 81, 174, 95, 96, 173, 174, 158, 48, - 48, 50, 50, 965, 48, 967, 50, 172, 970, 48, - 174, 50, 113, 114, 163, 116, 117, 118, 119, 120, - 6, 122, 8, 124, 15, 126, 17, 972, 10, 11, - 12, 13, 48, 15, 50, 17, 231, 232, 48, 530, - 50, 133, 143, 0, 535, 48, 48, 50, 50, 10, - 11, 12, 247, 248, 155, 156, 545, 48, 172, 50, - 157, 162, 163, 172, 48, 154, 50, 227, 157, 34, - 178, 179, 180, 181, 1071, 172, 173, 1074, 1075, 565, - 62, 247, 248, 6, 155, 8, 154, 409, 410, 411, - 412, 413, 174, 415, 416, 417, 155, 172, 302, 421, - 201, 682, 167, 547, 1066, 445, 428, 688, 174, 172, - 691, 433, 434, 445, 436, 437, 438, 837, 440, 441, - 445, 172, 692, 683, 167, 614, 175, 175, 848, 237, - 231, 232, 155, 703, 973, 158, 263, 1099, 120, 699, - 156, 263, 702, 48, 263, 50, 247, 248, 172, 1174, - 251, 1176, 81, 1178, 81, 256, 1181, 1182, 1183, 120, - 173, 174, 34, 81, 265, 175, 148, 10, 11, 12, - 13, 162, 175, 175, 17, 155, 167, 173, 174, 814, - 162, 155, 1144, 1145, 154, 167, 156, 157, 158, 172, - 172, 175, 358, 48, 174, 50, 157, 363, 364, 155, - 174, 302, 167, 168, 169, 34, 171, 172, 173, 163, - 1155, 369, 34, 155, 811, 369, 1239, 172, 174, 62, - 172, 322, 155, 1062, 172, 154, 172, 154, 157, 13, - 157, 15, 174, 17, 1231, 34, 154, 173, 174, 157, - 172, 174, 155, 734, 172, 826, 172, 155, 734, 163, - 831, 172, 155, 834, 835, 172, 173, 358, 828, 829, - 155, 174, 363, 364, 587, 588, 174, 827, 590, 591, - 175, 174, 172, 374, 382, 627, 598, 120, 62, 174, - 172, 770, 842, 623, 155, 845, 846, 627, 902, 173, - 174, 623, 1467, 394, 155, 627, 68, 69, 623, 171, - 172, 173, 627, 174, 172, 148, 795, 172, 409, 410, - 411, 412, 413, 174, 415, 416, 417, 163, 445, 162, - 421, 172, 155, 445, 167, 172, 445, 428, 172, 172, - 172, 173, 433, 434, 935, 436, 437, 438, 939, 440, - 441, 174, 171, 172, 173, 926, 155, 513, 983, 171, - 172, 173, 518, 519, 121, 122, 123, 1077, 155, 172, - 526, 527, 528, 155, 148, 174, 926, 155, 167, 168, - 169, 529, 171, 172, 173, 529, 172, 174, 162, 155, - 155, 155, 174, 167, 154, 155, 174, 988, 989, 990, - 154, 13, 156, 15, 158, 17, 156, 155, 174, 174, - 174, 502, 503, 973, 10, 11, 12, 172, 10, 11, - 12, 13, 513, 573, 995, 17, 174, 518, 519, 155, - 172, 991, 992, 1385, 155, 526, 527, 528, 914, 1149, - 531, 154, 533, 156, 561, 158, 544, 172, 174, 561, - 62, 1001, 561, 174, 545, 546, 768, 1450, 172, 172, - 13, 1474, 15, 154, 17, 156, 172, 158, 172, 154, - 62, 156, 68, 158, 172, 173, 1047, 172, 151, 152, - 153, 794, 172, 172, 1055, 81, 82, 1058, 172, 1080, - 803, 154, 636, 643, 644, 172, 172, 1047, 167, 590, - 591, 651, 1062, 653, 172, 1055, 623, 598, 1058, 62, - 627, 623, 172, 604, 623, 627, 672, 172, 627, 675, - 676, 174, 158, 614, 120, 121, 173, 123, 120, 1048, - 173, 1048, 128, 681, 130, 49, 148, 681, 155, 1018, - 172, 173, 174, 172, 173, 174, 172, 175, 1048, 155, - 162, 174, 10, 11, 12, 167, 148, 164, 1037, 174, - 172, 172, 173, 174, 174, 1044, 174, 22, 23, 24, - 162, 721, 174, 174, 174, 167, 667, 1168, 174, 34, - 1171, 672, 164, 174, 675, 676, 677, 174, 174, 174, - 174, 682, 155, 174, 155, 148, 687, 688, 174, 174, - 691, 692, 174, 174, 174, 174, 174, 757, 174, 162, - 68, 15, 703, 164, 167, 1550, 1551, 1552, 931, 172, - 174, 712, 174, 81, 82, 938, 174, 940, 174, 17, - 943, 944, 10, 11, 12, 13, 174, 174, 1225, 17, - 174, 164, 1229, 174, 1235, 1216, 1217, 1218, 174, 793, - 174, 172, 965, 175, 967, 174, 174, 970, 174, 174, - 157, 817, 120, 121, 781, 123, 1216, 1217, 1218, 863, - 128, 157, 130, 172, 62, 34, 64, 768, 172, 770, - 157, 174, 172, 172, 62, 172, 157, 172, 172, 172, - 781, 157, 157, 81, 5, 174, 172, 814, 172, 172, - 172, 81, 814, 794, 795, 814, 174, 174, 172, 172, - 165, 166, 167, 168, 169, 173, 171, 172, 173, 173, - 811, 167, 1657, 173, 177, 113, 817, 163, 116, 117, - 1665, 163, 120, 163, 163, 826, 1048, 828, 829, 172, - 831, 119, 120, 834, 835, 163, 837, 174, 136, 174, - 172, 156, 34, 1066, 174, 174, 172, 848, 1071, 850, - 148, 1074, 1075, 174, 174, 10, 11, 12, 167, 167, - 148, 154, 863, 157, 162, 49, 172, 172, 157, 154, - 174, 174, 174, 155, 162, 155, 1099, 155, 155, 167, - 155, 102, 103, 155, 172, 172, 154, 158, 172, 984, - 156, 156, 154, 920, 902, 155, 165, 166, 167, 168, - 169, 177, 171, 172, 173, 172, 1403, 1404, 1405, 172, - 154, 172, 164, 68, 173, 173, 173, 164, 174, 164, - 174, 1144, 1145, 164, 174, 926, 81, 82, 10, 150, - 151, 10, 10, 10, 935, 10, 10, 156, 939, 940, - 164, 155, 943, 944, 174, 167, 175, 167, 156, 156, - 167, 1452, 177, 1434, 172, 1456, 983, 958, 15, 172, - 961, 983, 177, 1460, 983, 120, 121, 172, 123, 172, - 174, 972, 973, 128, 1434, 130, 172, 174, 172, 155, - 155, 1478, 1479, 984, 155, 155, 155, 988, 989, 990, - 991, 992, 158, 167, 995, 156, 174, 174, 156, 172, - 156, 173, 155, 158, 1395, 10, 174, 162, 1231, 1395, - 175, 175, 167, 155, 177, 174, 10, 1018, 175, 10, - 174, 156, 1049, 174, 174, 246, 10, 174, 249, 250, - 10, 10, 10, 156, 155, 1536, 1037, 177, 172, 1040, - 177, 174, 1539, 1044, 175, 154, 1047, 1048, 174, 174, - 1547, 155, 174, 1054, 1055, 2, 156, 1058, 1059, 174, - 172, 1062, 163, 1158, 163, 163, 163, 172, 174, 156, - 1071, 156, 175, 1074, 1075, 10, 1077, 10, 17, 1080, - 175, 10, 11, 12, 174, 174, 10, 156, 156, 10, - 156, 1092, 172, 174, 155, 15, 1597, 155, 174, 1596, - 47, 174, 1599, 175, 175, 164, 53, 174, 164, 48, - 174, 50, 59, 60, 61, 62, 63, 164, 164, 66, - 174, 174, 10, 62, 174, 64, 156, 1187, 1188, 10, - 1190, 10, 1192, 1630, 156, 356, 357, 1241, 1242, 68, - 172, 172, 81, 172, 172, 366, 367, 368, 1149, 1646, - 174, 174, 81, 82, 1155, 156, 34, 1158, 174, 156, - 10, 156, 1385, 174, 22, 23, 24, 1168, 156, 1240, - 1171, 392, 1398, 1450, 113, 1398, 34, 116, 117, 920, - 1049, 120, 604, 404, 405, 627, 1556, 1395, 1206, 734, - 627, 120, 121, 1358, 123, 1019, 565, 136, -1, 128, - -1, 130, 321, -1, -1, 1206, -1, -1, 429, 148, - -1, -1, -1, -1, 161, 1216, 1217, 1218, -1, -1, - -1, -1, -1, 162, 1225, -1, -1, 1450, 1229, -1, - 1231, -1, -1, 162, 1235, -1, -1, -1, 167, -1, - 1241, 1242, -1, -1, -1, -1, -1, -1, -1, 3, - 4, 5, 6, -1, 8, 9, 10, -1, 205, 206, - 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, - 217, 218, 219, 220, 221, 222, 223, 224, 225, -1, - -1, 228, -1, 504, -1, -1, 233, 165, 166, 167, - 168, 169, -1, 171, 172, 173, 517, 51, -1, 520, - 521, -1, -1, -1, -1, -1, -1, 165, 166, 167, - 168, 169, 66, 171, 172, 173, 263, 71, 539, -1, - -1, -1, -1, -1, -1, -1, 80, 81, -1, -1, - -1, -1, 86, -1, -1, -1, 90, 91, 92, 93, - 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, - 104, 105, 299, -1, -1, -1, -1, 1358, -1, -1, - -1, -1, -1, -1, 118, 586, 120, -1, 589, 316, - 317, 125, -1, -1, -1, 129, 323, -1, 132, 23, - 24, -1, -1, 137, -1, -1, 1446, -1, -1, -1, - 34, -1, -1, -1, 1395, -1, -1, -1, -1, -1, - -1, -1, 1403, 1404, 1405, -1, -1, -1, 162, -1, - 631, 165, 166, 167, -1, -1, 170, -1, 172, 173, - 23, 24, 176, -1, -1, -1, -1, 374, -1, -1, - -1, 34, -1, 1434, -1, -1, 64, -1, -1, 1499, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 670, - 671, 1452, -1, -1, -1, 1456, -1, -1, -1, 1460, - -1, -1, -1, -1, -1, 686, 1467, -1, 689, 690, - 1530, 418, 693, -1, -1, -1, 697, 1478, 1479, 700, - 701, -1, -1, 704, -1, -1, 707, 115, -1, 710, - -1, -1, -1, 121, -1, 123, -1, 125, -1, 127, - 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, - 138, 139, 140, 141, 142, -1, -1, 65, -1, -1, - -1, 165, 166, 167, 168, 169, 154, 171, 172, 173, - 158, -1, 160, 161, -1, 1536, -1, -1, 1539, -1, - -1, 89, -1, -1, -1, 492, 1547, -1, -1, 1550, - 1551, 1552, -1, -1, -1, 1556, -1, 778, -1, -1, - 507, 109, 165, 166, 167, 168, 169, -1, 171, 172, - 173, -1, -1, -1, -1, 10, 11, 12, -1, 1639, - 1640, 1641, -1, 1643, -1, -1, -1, 18, 19, 20, - 21, 22, 23, 24, -1, 1596, 1597, -1, 1599, 147, - -1, -1, -1, 34, -1, -1, -1, -1, -1, 830, - -1, -1, -1, -1, 242, -1, -1, -1, -1, 840, - 841, -1, 569, 570, 571, 572, -1, 574, -1, 1630, - -1, -1, -1, 68, -1, 1219, 583, -1, 859, -1, - -1, -1, -1, -1, -1, 1646, 81, 82, -1, -1, - 198, 199, -1, -1, -1, -1, 1657, -1, -1, -1, - -1, -1, -1, -1, 1665, -1, -1, -1, -1, -1, - -1, -1, -1, 301, 621, -1, -1, -1, 226, -1, - -1, -1, -1, 904, -1, 120, 121, -1, 123, -1, - -1, -1, -1, 128, -1, 130, -1, 245, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 258, 259, -1, -1, -1, 662, -1, -1, -1, -1, - -1, 942, 157, -1, 945, 946, -1, 948, -1, 950, - 677, 162, 163, 164, 165, 166, 167, 168, 169, -1, - 171, 172, 173, 964, -1, -1, -1, 968, 969, -1, - -1, -1, -1, 974, -1, 303, 304, -1, 979, -1, - -1, 309, -1, -1, -1, -1, 987, 20, 21, 22, - 23, 24, -1, 321, -1, -1, -1, 724, -1, -1, - -1, 34, -1, -1, -1, -1, -1, -1, 735, 736, - 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, - 747, 748, 749, 750, 751, 752, 753, 754, 755, 1219, - -1, 758, 18, 19, 20, 21, 22, 23, 24, -1, - -1, -1, -1, -1, -1, -1, -1, 375, 34, -1, - -1, -1, 1053, -1, -1, 1056, 1057, -1, 466, -1, - 468, -1, 470, -1, -1, 393, -1, -1, -1, 1070, - 398, -1, -1, 800, -1, 1439, -1, 1441, 1442, 1443, - 1444, 1445, -1, 1447, -1, -1, 16, 17, 18, 19, - 20, 21, 22, 23, 24, -1, -1, 1098, -1, -1, - -1, -1, -1, -1, 34, -1, -1, -1, -1, -1, - 837, 439, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 848, -1, -1, -1, -1, 853, -1, -1, -1, - 163, 164, 165, 166, 167, 168, 169, -1, 171, 172, - 173, 1142, -1, 870, -1, -1, 1510, 1511, 1512, 1513, + 1, 114, 392, 116, 117, 118, 119, 120, 392, 122, + 79, 124, 414, 126, 434, 434, 79, 500, 930, 544, + 560, 96, 951, 1092, 46, 263, 263, 46, 543, 784, + 143, 676, 391, 529, 85, 86, 87, 10, 11, 12, + 15, 92, 155, 156, 530, 501, 531, 937, 15, 162, + 163, 48, 263, 50, 6, 984, 8, 64, 15, 10, + 850, 0, 13, 263, 65, 155, 939, 13, 61, 942, + 943, 15, 81, 81, 964, 158, 966, 81, 154, 969, + 46, 155, 0, 155, 174, 1010, 1011, 1012, 613, 156, + 173, 48, 154, 50, 95, 96, 172, 34, 48, 15, + 50, 81, 174, 177, 172, 155, 48, 155, 50, 48, + 172, 50, 113, 114, 172, 116, 117, 118, 119, 120, + 172, 122, 34, 124, 174, 126, 174, 178, 179, 180, + 181, 48, 48, 50, 50, 48, 172, 50, 528, 48, + 133, 50, 143, 533, 155, 154, 154, 120, 157, 157, + 154, 158, 155, 157, 155, 156, 231, 232, 173, 174, + 155, 162, 163, 174, 13, 34, 15, 158, 17, 68, + 69, 174, 247, 248, 154, 158, 1066, 157, 175, 174, + 564, 971, 173, 172, 157, 681, 237, 546, 155, 302, + 173, 687, 837, 13, 690, 15, 682, 17, 1071, 174, + 201, 1074, 1075, 848, 172, 443, 247, 248, 691, 1099, + 34, 155, 698, 62, 156, 701, 167, 972, 64, 702, + 227, 167, 174, 172, 173, 175, 10, 11, 12, 13, + 231, 232, 443, 17, 171, 172, 173, 154, 15, 163, + 17, 263, 62, 443, 263, 770, 247, 248, 163, 1174, + 251, 1176, 172, 1178, 1144, 1145, 1181, 1182, 1183, 171, + 172, 173, 175, 174, 265, 48, 175, 50, 172, 115, + 795, 48, 172, 50, 814, 121, 172, 123, 62, 125, + 172, 127, 128, 129, 130, 131, 132, 133, 134, 135, + 136, 137, 138, 139, 140, 141, 142, 263, 172, 148, + 369, 302, 171, 172, 173, 155, 369, 1062, 154, 172, + 1239, 34, 158, 162, 160, 161, 155, 358, 167, 158, + 172, 322, 363, 364, 174, 6, 811, 8, 148, 380, + 826, 172, 48, 157, 50, 831, 120, 172, 834, 835, + 172, 827, 162, 172, 734, 828, 829, 167, 172, 173, + 734, 172, 172, 48, 172, 50, 842, 358, 1231, 845, + 846, 155, 363, 364, 148, 1155, 172, 154, 13, 156, + 15, 158, 17, 374, 375, 155, 155, 172, 162, 155, + 174, 155, 155, 167, 622, 162, 901, 172, 626, 626, + 167, 392, 175, 158, 174, 174, 242, 155, 174, 1468, + 174, 174, 172, 6, 155, 8, 407, 408, 409, 410, + 411, 622, 413, 414, 415, 626, 174, 62, 419, 173, + 174, 443, 622, 174, 443, 426, 626, 172, 155, 925, + 431, 432, 1077, 434, 435, 436, 172, 438, 439, 925, + 172, 155, 982, 155, 167, 168, 169, 174, 171, 172, + 173, 172, 155, 155, 155, 301, 173, 174, 527, 175, + 174, 154, 174, 156, 527, 158, 163, 257, 258, 155, + 511, 174, 174, 174, 172, 516, 517, 443, 934, 172, + 175, 163, 938, 524, 525, 526, 155, 155, 174, 972, + 173, 174, 543, 1018, 48, 1385, 50, 172, 994, 500, + 501, 173, 174, 148, 1149, 174, 174, 990, 991, 172, + 511, 172, 1037, 172, 1000, 516, 517, 162, 172, 1044, + 172, 173, 167, 524, 525, 526, 172, 172, 529, 913, + 531, 987, 988, 989, 151, 152, 153, 172, 560, 1451, + 172, 560, 172, 544, 545, 154, 1475, 156, 157, 158, + 172, 1047, 17, 154, 154, 156, 156, 158, 158, 1055, + 167, 1047, 1058, 154, 155, 572, 635, 172, 173, 1055, + 34, 173, 1058, 121, 122, 123, 172, 173, 174, 1062, + 173, 154, 10, 11, 12, 172, 173, 174, 589, 590, + 172, 173, 174, 49, 560, 155, 597, 62, 172, 64, + 622, 164, 603, 622, 626, 175, 155, 626, 174, 174, + 174, 680, 613, 174, 164, 174, 81, 680, 464, 174, + 466, 174, 468, 174, 1080, 155, 155, 174, 1048, 1048, + 671, 174, 174, 674, 675, 642, 643, 174, 174, 174, + 68, 174, 174, 650, 164, 652, 1048, 174, 113, 15, + 174, 116, 117, 81, 82, 120, 622, 174, 174, 174, + 626, 10, 11, 12, 13, 666, 174, 174, 17, 174, + 671, 136, 174, 674, 675, 676, 174, 174, 174, 164, + 681, 174, 174, 148, 174, 686, 687, 174, 172, 690, + 691, 174, 120, 121, 174, 123, 174, 162, 157, 157, + 128, 702, 130, 167, 168, 169, 172, 171, 172, 173, + 172, 712, 1168, 62, 721, 1171, 157, 174, 172, 172, + 1216, 1217, 1218, 172, 793, 172, 572, 172, 172, 172, + 1216, 1217, 1218, 157, 5, 157, 157, 172, 584, 172, + 1225, 177, 174, 174, 1229, 172, 174, 172, 174, 862, + 757, 167, 175, 173, 173, 81, 163, 172, 163, 781, + 163, 1551, 1552, 1553, 163, 174, 172, 768, 163, 770, + 119, 120, 174, 156, 172, 34, 817, 174, 174, 1235, + 781, 174, 10, 11, 12, 174, 172, 167, 167, 154, + 157, 49, 814, 794, 795, 814, 586, 587, 172, 148, + 172, 174, 157, 174, 174, 10, 11, 12, 13, 154, + 811, 155, 17, 162, 155, 155, 817, 155, 167, 155, + 155, 154, 172, 172, 156, 826, 156, 828, 829, 158, + 831, 102, 103, 834, 835, 172, 837, 154, 177, 173, + 68, 172, 154, 10, 172, 172, 155, 848, 814, 850, + 901, 173, 173, 81, 82, 174, 164, 62, 164, 164, + 174, 862, 164, 174, 10, 10, 10, 10, 1658, 715, + 716, 717, 10, 719, 156, 721, 1666, 723, 724, 150, + 151, 164, 407, 408, 409, 410, 411, 34, 413, 414, + 415, 155, 120, 121, 419, 123, 174, 919, 167, 167, + 128, 426, 130, 175, 156, 156, 431, 432, 983, 434, + 435, 436, 167, 438, 439, 120, 172, 177, 1403, 1404, + 1405, 15, 172, 177, 925, 172, 172, 158, 172, 174, + 172, 174, 155, 934, 155, 155, 155, 938, 939, 1435, + 155, 942, 943, 148, 156, 173, 172, 174, 173, 1435, + 167, 175, 174, 156, 156, 155, 957, 162, 10, 960, + 982, 175, 167, 982, 174, 1219, 177, 172, 34, 155, + 971, 972, 10, 174, 10, 246, 1461, 175, 249, 250, + 174, 174, 983, 174, 156, 10, 987, 988, 989, 990, + 991, 174, 10, 994, 1479, 1480, 10, 1453, 10, 156, + 155, 1457, 172, 177, 794, 1395, 174, 10, 11, 12, + 13, 1395, 15, 803, 17, 175, 982, 1018, 165, 166, + 167, 168, 169, 177, 171, 172, 173, 1049, 154, 156, + 155, 163, 174, 174, 174, 174, 1037, 172, 172, 1040, + 163, 163, 163, 1044, 174, 174, 1047, 1048, 156, 10, + 156, 175, 10, 1054, 1055, 1540, 175, 1058, 1059, 62, + 174, 1062, 10, 1548, 589, 590, 156, 156, 10, 156, + 1071, 172, 597, 1074, 1075, 174, 1077, 23, 24, 1080, + 15, 1537, 174, 1158, 175, 356, 357, 933, 34, 174, + 155, 1092, 175, 174, 155, 366, 367, 368, 174, 165, + 166, 167, 168, 169, 164, 171, 172, 173, 164, 164, + 174, 164, 1597, 10, 156, 1600, 174, 120, 10, 390, + 174, 10, 156, 172, 172, 172, 172, 156, 1241, 1242, + 174, 402, 403, 174, 174, 156, 10, 156, 1240, 174, + 930, 156, 1598, 603, 1451, 148, 1631, 937, 1149, 939, + 23, 24, 942, 943, 1155, 1398, 427, 1158, 626, 162, + 1049, 34, 1647, 919, 167, 1557, 1395, 1168, 1206, 172, + 1171, 626, 734, 1358, 964, 1019, 966, 564, -1, 969, + 1187, 1188, -1, 1190, 321, 1192, 1440, -1, 1442, 1443, + 1444, 1445, 1446, -1, 1448, -1, -1, 17, 18, 19, + 20, 21, 22, 23, 24, 1206, -1, -1, -1, -1, + -1, -1, -1, -1, 34, 1216, 1217, 1218, -1, 165, + 166, 167, 168, 169, 1225, 171, 172, 173, 1229, -1, + 1231, 502, -1, -1, 1235, -1, -1, -1, -1, -1, + 1241, 1242, -1, 768, 515, -1, -1, 518, 519, -1, + -1, -1, -1, 10, 11, 12, -1, 1511, 1512, 1513, 1514, 1515, 1516, 1517, 1518, 1519, 1520, 1521, 1522, 1523, - 1524, 1525, 1526, 1527, 1528, 573, -1, -1, 1169, -1, - -1, 1172, -1, 501, 160, 161, 162, 585, -1, 165, - 166, 167, 168, 169, 1185, 171, 172, 173, 516, -1, - -1, -1, -1, 1194, 18, 19, 20, 21, 22, 23, - 24, -1, -1, 1204, -1, -1, -1, 1571, -1, -1, - 34, -1, -1, -1, 1215, -1, -1, -1, -1, 547, - -1, -1, -1, -1, -1, -1, -1, 157, -1, 159, - 160, 161, 162, -1, 961, 165, 166, 167, 168, 169, - -1, 171, 172, 173, -1, -1, 10, 11, 12, 1439, - -1, 1441, 1442, 1443, 1444, 1445, -1, 1447, 1622, 587, - 588, 1625, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 605, -1, 607, - 608, 609, 610, 611, 612, -1, -1, 615, -1, -1, + 1524, 1525, 1526, 1527, 1528, 1529, 1066, -1, -1, -1, + -1, 1071, -1, -1, 1074, 1075, -1, -1, -1, -1, + -1, -1, 165, 166, 167, 168, 169, -1, 171, 172, + 173, -1, -1, -1, -1, -1, -1, -1, -1, 1099, + -1, 68, -1, -1, 585, -1, -1, 588, 1572, -1, + -1, -1, -1, -1, 81, 82, -1, -1, -1, -1, + -1, -1, 3, 4, 5, 6, -1, 8, 9, 10, + 160, 161, 162, -1, 15, 165, 166, 167, 168, 169, + -1, 171, 172, 173, 1144, 1145, -1, 1358, -1, 630, + -1, -1, -1, 120, 121, -1, 123, -1, 1214, 1623, + -1, 128, 1626, 130, -1, -1, -1, 48, -1, 50, + 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 1395, 66, -1, 154, 669, 670, + 71, -1, 1403, 1404, 1405, -1, -1, -1, -1, 80, + 81, -1, -1, -1, 685, -1, -1, 688, 689, -1, + -1, 692, -1, -1, 65, 696, -1, -1, 699, 700, + -1, -1, 703, -1, 1435, 706, 707, -1, -1, 710, + 1447, 1231, -1, -1, 115, -1, -1, 118, 89, 120, + -1, -1, 1453, -1, 125, -1, 1457, -1, 129, -1, + 1461, 132, -1, -1, -1, -1, 137, 1468, 109, 140, + -1, 10, 11, 12, -1, -1, -1, -1, 1479, 1480, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 1027, 629, 630, -1, 68, 1032, -1, 715, 716, 717, - 638, 719, -1, 721, 11, 723, 724, 81, 82, -1, - 1510, 1511, 1512, 1513, 1514, 1515, 1516, 1517, 1518, 1519, - 1520, 1521, 1522, 1523, 1524, 1525, 1526, 1527, 1528, 163, - 164, 165, 166, 167, 168, 169, -1, 171, 172, 173, - 1077, -1, -1, -1, -1, -1, 120, 121, 55, 123, - 57, 58, 59, 60, 128, 1092, 130, -1, 696, -1, + -1, 162, -1, 1500, 165, 166, -1, -1, -1, 170, + -1, 172, -1, -1, -1, 176, 147, 778, -1, -1, + -1, -1, -1, -1, -1, -1, 2, -1, -1, -1, + -1, -1, -1, 1048, 1531, -1, -1, -1, -1, 68, + -1, -1, -1, -1, -1, -1, 1537, -1, -1, 1540, + -1, -1, 81, 82, -1, -1, 1219, 1548, -1, -1, + 1551, 1552, 1553, -1, -1, -1, 1557, 198, 199, 830, + -1, 47, -1, -1, -1, -1, -1, 53, -1, 840, + 841, -1, -1, 59, 60, 61, 62, 63, -1, -1, + 66, 120, 121, -1, 123, 226, -1, 858, -1, 128, + -1, 130, -1, -1, -1, 1385, 1597, 1598, -1, 1600, + -1, 1447, -1, -1, 245, -1, -1, -1, 1398, -1, + -1, -1, -1, -1, -1, -1, -1, 258, 259, 158, + -1, -1, -1, 162, -1, -1, -1, -1, 167, -1, + 1631, -1, 903, 1640, 1641, 1642, -1, 1644, -1, -1, + -1, 10, 11, 12, -1, -1, 1647, -1, -1, 1495, + 1496, 1497, 1498, -1, 1500, -1, 1502, 1658, -1, -1, + -1, 1451, 303, 304, -1, 1666, -1, -1, 309, -1, + 941, -1, -1, 944, 945, 161, 947, -1, 949, -1, + 321, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 963, -1, -1, -1, 967, 968, -1, 68, + -1, -1, 973, -1, -1, -1, -1, 978, 10, 11, + 12, -1, 81, 82, -1, 986, -1, -1, -1, 205, + 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, + 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, + -1, -1, 228, -1, -1, -1, -1, 233, -1, -1, + 391, 120, 121, -1, 123, 396, -1, -1, -1, 128, + -1, 130, -1, -1, -1, -1, 68, 1440, -1, 1442, + 1443, 1444, 1445, 1446, -1, 1448, -1, 263, -1, 81, + 82, -1, 1053, -1, -1, 1056, 1057, -1, -1, -1, + -1, -1, -1, 162, -1, -1, 437, -1, 167, 1070, + -1, -1, -1, -1, -1, -1, 10, 11, 12, -1, + -1, -1, -1, 299, -1, -1, -1, -1, 120, 121, + -1, 123, -1, -1, -1, -1, 128, 1098, 130, -1, + 316, 317, -1, -1, -1, -1, -1, 323, 1511, 1512, + 1513, 1514, 1515, 1516, 1517, 1518, 1519, 1520, 1521, 1522, + 1523, 1524, 1525, 1526, 1527, 1528, 1529, -1, 499, -1, + -1, -1, -1, -1, 68, -1, -1, -1, -1, -1, + -1, 1142, -1, 514, -1, -1, -1, 81, 82, -1, + 3, 4, 5, 6, -1, 8, 9, 10, 374, -1, + -1, -1, 15, -1, -1, -1, 537, -1, 1169, -1, + -1, 1172, -1, -1, -1, 546, -1, -1, -1, -1, + -1, -1, -1, -1, 1185, -1, 120, 121, -1, 123, + -1, -1, -1, 1194, 128, 48, 130, 50, 51, -1, + 416, -1, -1, 1204, -1, 3, 4, 5, 6, -1, + 8, 9, 10, 66, 1215, 586, 587, 15, 71, -1, + 154, -1, -1, 1626, -1, -1, -1, 80, 81, -1, + -1, -1, -1, 604, -1, 606, 607, 608, 609, 610, + 611, -1, -1, 614, 17, 18, 19, 20, 21, 22, + 23, 24, -1, 51, -1, -1, -1, 628, 629, -1, + -1, 34, 115, -1, -1, 118, 637, 120, 66, 22, + 23, 24, 125, 71, 490, -1, 129, -1, -1, 132, + -1, 34, 80, 81, 137, -1, -1, 140, 86, 505, + -1, -1, 90, 91, 92, 93, 94, 95, 96, 97, + 98, 99, 100, 101, 102, 103, 104, 105, -1, 162, + -1, -1, 165, 166, -1, -1, -1, 170, -1, 172, + 118, -1, 120, 176, 695, -1, -1, 125, -1, -1, + -1, 129, -1, 11, 132, -1, -1, -1, -1, 137, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 1387, -1, -1, -1, - 154, -1, 89, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 3, 4, 5, 6, 106, - 8, 9, 10, 11, -1, -1, -1, 15, -1, -1, - 1147, -1, 1149, -1, 1151, -1, -1, -1, 756, -1, - 127, 128, -1, -1, -1, 1625, -1, 16, 17, 18, - 19, 20, 21, 22, 23, 24, -1, 144, -1, -1, - 1451, -1, 149, 51, 1455, 34, -1, 55, 1459, 57, - 58, 59, 60, 20, 21, 22, 23, 24, 66, -1, - -1, 1472, 70, 71, 1475, 1476, 1477, 34, -1, -1, - -1, -1, 80, 81, 82, 813, -1, -1, 86, -1, - -1, 89, 90, 91, 92, 93, 94, 95, 96, 97, - 98, 99, 100, 101, 102, 103, 104, 105, 106, -1, - -1, -1, -1, -1, -1, -1, -1, 115, -1, 117, - 118, -1, 120, -1, -1, -1, 934, 125, -1, 127, - 128, 129, -1, -1, 132, -1, -1, 865, -1, 137, - 1541, -1, 140, -1, -1, -1, 144, -1, -1, -1, - -1, 149, 1553, 1554, 17, 18, 19, 20, 21, 22, - 23, 24, -1, -1, 162, -1, -1, 165, 166, 167, - -1, 34, 170, -1, 172, 173, -1, -1, 176, -1, - 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, - 169, -1, 171, 172, 173, -1, 924, -1, 177, -1, - -1, -1, 55, 1604, 57, 58, 59, 60, 165, 166, - 167, 168, 169, -1, 171, 172, 173, 70, -1, -1, - -1, -1, -1, -1, -1, -1, 954, 1628, -1, -1, - -1, -1, -1, -1, -1, -1, 89, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 1647, -1, -1, -1, - -1, -1, -1, 106, -1, 1656, -1, 1384, -1, -1, - -1, -1, 18, 19, 20, 21, 22, 23, 24, -1, - -1, -1, -1, -1, 127, 128, -1, -1, 34, -1, - -1, -1, -1, -1, -1, 1013, -1, -1, -1, -1, - -1, 144, -1, -1, -1, -1, 149, 160, 161, 162, + -1, -1, 568, 569, 570, 571, -1, 573, -1, -1, + -1, -1, -1, -1, 162, -1, 582, 165, 166, 167, + -1, -1, 170, -1, 172, 173, -1, 55, 176, 57, + 58, 59, 60, -1, -1, 756, 1387, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, -1, 171, 172, - 173, 3, 4, 5, 6, 7, 8, 9, 10, 11, - 12, 13, 1050, 15, 16, 17, 18, 19, 20, 21, - 22, 23, 24, 25, 26, -1, -1, -1, -1, -1, - 1467, -1, 34, 35, 36, 37, 38, 39, 40, 41, - 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, - 52, -1, -1, 55, 56, 57, 58, 59, 60, 61, - 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, - 72, -1, 74, -1, 76, 77, 78, 79, 80, 81, - 82, 83, 84, 85, -1, 87, 88, 89, -1, -1, - -1, -1, -1, -1, 1531, -1, 1214, -1, -1, 165, - 166, 167, 168, 169, 106, 171, 172, 173, -1, -1, - -1, 113, 114, 115, 116, 117, 118, 119, 120, 121, - 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, - 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, - 142, 143, 144, 145, 146, 147, 148, 149, 150, -1, - -1, -1, 154, 155, 156, 157, 158, 159, 160, 161, - 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, - 172, 173, 174, 175, 176, 177, -1, -1, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, -1, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 1240, -1, -1, -1, -1, -1, -1, 34, - 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, - 45, 46, 47, 48, 49, 50, 51, 52, -1, -1, - 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, - 65, 66, 67, 68, 69, 70, 71, 72, -1, 74, - -1, 76, 77, 78, 79, 80, 81, 82, 83, 84, - 85, -1, 87, 88, 89, -1, -1, -1, -1, -1, + 173, -1, -1, -1, 620, -1, -1, -1, -1, -1, + -1, 89, 165, 166, 167, 168, 169, -1, 171, 172, + 173, -1, -1, -1, -1, -1, -1, -1, 106, -1, + -1, -1, -1, -1, 3, 4, 5, 6, -1, 8, + 9, 10, 813, -1, -1, 661, 15, -1, -1, 127, + 128, 1452, -1, -1, -1, 1456, -1, -1, -1, 1460, + 676, -1, -1, -1, -1, -1, 144, -1, -1, -1, + -1, 149, 1473, -1, -1, 1476, 1477, 1478, -1, -1, + -1, -1, 51, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 864, 22, 23, 24, 66, -1, -1, + -1, -1, 71, -1, -1, -1, 34, -1, 724, -1, + -1, 80, 81, -1, -1, -1, 10, 11, 12, 735, + 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, + 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, + -1, 1542, 758, -1, -1, -1, 115, -1, -1, 118, + -1, 120, 923, 1554, 1555, -1, 125, -1, -1, -1, + 129, -1, -1, 132, -1, -1, -1, -1, 137, -1, + -1, 140, -1, -1, 68, -1, -1, -1, -1, -1, + -1, -1, 953, -1, 800, -1, -1, 81, 82, -1, + -1, -1, -1, 162, -1, -1, 165, 166, -1, -1, + -1, 170, -1, 172, 1605, -1, -1, 176, -1, 3, + 4, 5, 6, -1, 8, 9, 10, 11, 12, -1, + -1, 837, -1, -1, -1, -1, 120, 121, 1629, 123, + -1, -1, 848, -1, 128, -1, 130, 165, 166, 167, + 168, 169, 1013, 171, 172, 173, -1, 1648, -1, -1, + -1, 145, -1, 869, -1, -1, 1657, 51, 52, -1, + -1, 55, -1, 57, 58, 59, 60, 61, 62, -1, + -1, -1, 66, 67, -1, -1, 70, 71, -1, 1050, + 74, -1, -1, -1, -1, -1, 80, 81, 82, -1, + -1, -1, 86, -1, -1, 89, 90, 91, 92, 93, + 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, -1, -1, -1, 10, 11, 12, -1, + -1, 115, -1, 117, 118, -1, 120, -1, 10, 11, + 12, 125, -1, 127, 128, 129, -1, -1, 132, 133, + -1, -1, -1, 137, 960, -1, 140, 141, 142, 143, + 144, -1, -1, 147, -1, 149, -1, -1, -1, -1, + -1, 6, -1, -1, -1, -1, -1, -1, 162, -1, + -1, 165, 166, 167, 68, -1, 170, -1, 172, 173, + -1, -1, 176, -1, -1, -1, 68, 81, 82, -1, + -1, -1, -1, 1009, -1, -1, -1, -1, -1, 81, + 82, -1, -1, -1, -1, -1, -1, -1, -1, 54, + -1, 1027, -1, -1, -1, -1, 1032, 62, 63, 64, + 65, -1, -1, -1, -1, -1, 120, 121, -1, 123, + 75, 76, 77, 78, 128, -1, 130, -1, 120, 121, + 122, 123, -1, 88, -1, -1, 128, -1, 130, 16, + 17, 18, 19, 20, 21, 22, 23, 24, -1, 141, + -1, 1077, -1, 157, 146, -1, -1, 34, 113, 1240, + -1, -1, -1, -1, -1, -1, 1092, -1, -1, 124, + -1, -1, -1, -1, -1, 130, -1, -1, -1, 134, + 135, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 146, -1, 148, -1, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, -1, 15, 16, 17, + 18, 19, 20, 21, 22, 23, 24, 25, 26, -1, + -1, 1147, -1, 1149, -1, 1151, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, -1, -1, 55, 56, 57, + 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, + 68, 69, 70, 71, 72, -1, 74, -1, 76, 77, + 78, 79, 80, 81, 82, 83, 84, 85, -1, 87, + 88, 89, 159, 160, 161, 162, 163, 164, 165, 166, + 167, 168, 169, -1, 171, 172, 173, -1, 106, -1, + 177, -1, -1, -1, -1, 113, 114, 115, 116, 117, + 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, + 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, + 148, 149, 150, 10, 11, -1, 154, 155, 156, 157, + 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, + -1, -1, -1, 10, 11, 12, -1, -1, -1, 10, + 11, 12, -1, -1, -1, 52, -1, -1, 55, -1, + 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, + 67, -1, -1, 70, -1, -1, 55, 74, 57, 58, + 59, 60, -1, -1, -1, 82, -1, -1, -1, -1, + -1, 70, 89, -1, -1, -1, -1, -1, -1, -1, + -1, 68, -1, -1, -1, -1, -1, 68, -1, 106, + 89, -1, -1, -1, 81, 82, -1, -1, -1, 1530, + 81, 82, 119, -1, -1, -1, -1, 106, 1384, -1, + 127, 128, -1, -1, -1, -1, 133, -1, -1, -1, + -1, -1, -1, -1, 141, 142, 143, 144, 127, 128, + 147, -1, 149, 120, 121, -1, 123, 154, 1569, 120, + 121, 128, 123, 130, -1, 144, -1, 128, -1, 130, + 149, -1, -1, 170, 141, -1, -1, -1, -1, 146, + 141, -1, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 172, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, -1, -1, -1, -1, + -1, -1, 1468, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, -1, -1, 55, 56, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, + 71, 72, -1, 74, -1, 76, 77, 78, 79, 80, + 81, 82, 83, 84, 85, -1, 87, 88, 89, -1, + -1, -1, -1, -1, -1, -1, 1532, -1, -1, -1, + -1, -1, -1, -1, -1, 106, -1, -1, -1, -1, + -1, -1, 113, 114, 115, 116, 117, 118, 119, 120, + 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, + 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, + 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, + -1, -1, -1, 154, 155, 156, 157, 158, 159, 160, + 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, + 171, 172, 173, 174, -1, 176, 177, 3, 4, 5, + 6, -1, 8, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 106, -1, -1, -1, -1, -1, -1, 113, 114, - 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, - 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, - 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, - 145, 146, 147, 148, 149, 150, -1, -1, 1446, 154, - 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, - 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, - -1, 176, 177, -1, -1, 3, 4, 5, 6, -1, - 8, 9, 10, 11, 12, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 1494, 1495, 1496, 1497, - -1, 1499, -1, 1501, -1, -1, -1, -1, 16, 17, - 18, 19, 20, 21, 22, 23, 24, -1, -1, -1, - -1, -1, -1, 51, 52, -1, 34, 55, -1, 57, - 58, 59, 60, 61, 62, -1, -1, -1, 66, 67, - -1, -1, 70, 71, -1, -1, 74, -1, -1, -1, - -1, -1, 80, 81, 82, -1, -1, -1, 86, -1, - -1, 89, 90, 91, 92, 93, 94, 95, 96, 97, - 98, 99, 100, 101, 102, 103, 104, 105, 106, -1, - -1, -1, -1, -1, -1, -1, -1, 115, -1, 117, - 118, -1, 120, -1, -1, -1, -1, 125, -1, 127, - 128, 129, -1, -1, 132, 133, -1, -1, -1, 137, - -1, 1529, 140, 141, 142, 143, 144, -1, -1, 147, - -1, 149, 3, 4, 5, 6, -1, 8, 9, 10, - 11, -1, -1, -1, 162, -1, -1, 165, 166, 167, - -1, -1, 170, -1, 172, 173, -1, -1, 176, -1, - 1568, 159, 160, 161, 162, 163, 164, 165, 166, 167, - 168, 169, -1, 171, 172, 173, -1, -1, -1, 177, - 51, 52, -1, -1, 55, -1, 57, 58, 59, 60, - 61, -1, -1, -1, -1, 66, 67, -1, -1, 70, - 71, -1, -1, 74, -1, -1, -1, -1, -1, 80, - 81, 82, -1, -1, -1, 86, -1, -1, 89, 90, - 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, - 101, 102, 103, 104, 105, 106, -1, -1, -1, -1, - -1, -1, -1, -1, 115, -1, 117, 118, -1, 120, - -1, -1, -1, -1, 125, -1, 127, 128, 129, -1, - -1, 132, 133, -1, -1, -1, 137, -1, -1, 140, - 141, 142, 143, 144, -1, -1, 147, -1, 149, 3, - 4, 5, 6, -1, 8, 9, 10, 11, -1, -1, - -1, 162, -1, -1, 165, 166, 167, -1, -1, 170, - -1, 172, 173, -1, -1, 176, -1, -1, -1, -1, - 16, 17, 18, 19, 20, 21, 22, 23, 24, -1, - -1, -1, -1, -1, -1, -1, -1, 51, 34, -1, - -1, 55, -1, 57, 58, 59, 60, -1, -1, -1, - -1, -1, 66, -1, 68, 69, 70, 71, -1, -1, - -1, -1, -1, -1, -1, -1, 80, 81, 82, -1, - -1, -1, 86, -1, -1, 89, 90, 91, 92, 93, - 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, - 104, 105, 106, -1, -1, -1, -1, -1, -1, -1, - -1, 115, -1, 117, 118, -1, 120, -1, -1, -1, - -1, 125, -1, 127, 128, 129, -1, -1, 132, -1, - -1, -1, -1, 137, -1, -1, 140, -1, -1, -1, - 144, 3, 4, 5, 6, 149, 8, 9, 10, 11, - 154, -1, -1, -1, -1, -1, -1, -1, 162, -1, - -1, 165, 166, 167, -1, -1, 170, -1, 172, 173, - -1, -1, 176, 159, 160, 161, 162, 163, 164, 165, - 166, 167, 168, 169, -1, 171, 172, 173, -1, 51, - -1, 177, -1, 55, -1, 57, 58, 59, 60, -1, - -1, -1, -1, -1, 66, -1, -1, -1, 70, 71, - -1, -1, -1, -1, -1, -1, -1, -1, 80, 81, - 82, -1, -1, -1, 86, -1, -1, 89, 90, 91, - 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, - 102, 103, 104, 105, 106, -1, -1, -1, -1, -1, - -1, -1, -1, 115, -1, 117, 118, -1, 120, -1, - -1, -1, -1, 125, -1, 127, 128, 129, -1, -1, - 132, -1, -1, -1, -1, 137, -1, -1, 140, -1, - -1, -1, 144, 3, 4, 5, 6, 149, 8, 9, - 10, 11, -1, -1, -1, -1, -1, -1, -1, -1, - 162, -1, -1, 165, 166, 167, -1, -1, 170, -1, - 172, 173, 174, -1, 176, 16, 17, 18, 19, 20, - 21, 22, 23, 24, -1, -1, -1, -1, -1, -1, - -1, 51, 52, 34, -1, 55, -1, 57, 58, 59, - 60, -1, -1, -1, -1, -1, 66, -1, -1, -1, - 70, 71, -1, -1, -1, -1, -1, -1, -1, -1, - 80, 81, 82, -1, -1, -1, 86, -1, -1, 89, - 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, - 100, 101, 102, 103, 104, 105, 106, -1, -1, -1, - -1, -1, -1, -1, -1, 115, -1, 117, 118, -1, - 120, -1, -1, -1, -1, 125, -1, 127, 128, 129, - -1, -1, 132, -1, -1, -1, -1, 137, -1, -1, - 140, -1, -1, -1, 144, 3, 4, 5, 6, 149, - 8, 9, 10, 11, -1, -1, -1, -1, -1, -1, - -1, -1, 162, -1, -1, 165, 166, 167, -1, -1, - 170, -1, 172, 173, -1, 156, 176, -1, 159, 160, - 161, 162, 163, 164, 165, 166, 167, 168, 169, -1, - 171, 172, 173, 51, 52, -1, -1, 55, -1, 57, - 58, 59, 60, -1, -1, -1, -1, -1, 66, -1, - -1, -1, 70, 71, -1, -1, -1, -1, -1, -1, - -1, -1, 80, 81, 82, -1, -1, -1, 86, -1, - -1, 89, 90, 91, 92, 93, 94, 95, 96, 97, - 98, 99, 100, 101, 102, 103, 104, 105, 106, -1, - -1, 55, -1, 57, 58, 59, 60, 115, -1, 117, - 118, -1, 120, -1, -1, -1, 70, 125, -1, 127, - 128, 129, -1, -1, 132, -1, -1, -1, -1, 137, - -1, -1, 140, -1, -1, 89, 144, 3, 4, 5, - 6, 149, 8, 9, 10, 11, -1, -1, -1, -1, - -1, -1, 106, -1, 162, -1, -1, 165, 166, 167, - -1, -1, 170, -1, 172, 173, -1, -1, 176, -1, - -1, -1, -1, 127, 128, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 51, -1, -1, -1, 55, - 144, 57, 58, 59, 60, 149, -1, -1, -1, -1, - 66, -1, -1, -1, 70, 71, -1, -1, -1, -1, - -1, -1, -1, -1, 80, 81, 82, -1, 172, -1, - 86, -1, -1, 89, 90, 91, 92, 93, 94, 95, - 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, - 106, -1, -1, -1, -1, -1, -1, -1, -1, 115, - -1, 117, 118, -1, 120, -1, -1, -1, -1, 125, - -1, 127, 128, 129, -1, -1, 132, -1, -1, -1, - -1, 137, -1, -1, 140, -1, -1, -1, 144, 3, - 4, 5, 6, 149, 8, 9, 10, 11, -1, -1, - -1, -1, -1, -1, -1, -1, 162, -1, -1, 165, - 166, 167, -1, -1, 170, -1, 172, 173, 174, -1, - 176, 16, 17, 18, 19, 20, 21, 22, 23, 24, - -1, -1, -1, -1, -1, -1, -1, 51, -1, 34, - -1, 55, -1, 57, 58, 59, 60, -1, -1, -1, - -1, -1, 66, -1, -1, -1, 70, 71, -1, -1, - -1, -1, -1, -1, -1, -1, 80, 81, 82, -1, - -1, -1, 86, -1, -1, 89, 90, 91, 92, 93, - 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, - 104, 105, 106, -1, -1, -1, -1, -1, -1, -1, - -1, 115, -1, 117, 118, -1, 120, -1, -1, -1, - -1, 125, -1, 127, 128, 129, -1, -1, 132, -1, - -1, -1, -1, 137, -1, -1, 140, -1, -1, -1, - 144, 3, 4, 5, 6, 149, 8, 9, 10, 11, - 154, -1, -1, -1, -1, -1, -1, -1, 162, -1, - -1, 165, 166, 167, -1, -1, 170, -1, 172, 173, - 155, -1, 176, -1, 159, 160, 161, 162, 163, 164, - 165, 166, 167, 168, 169, -1, 171, 172, 173, 51, - -1, -1, -1, 55, -1, 57, 58, 59, 60, -1, - -1, -1, -1, -1, 66, -1, -1, -1, 70, 71, - -1, -1, -1, -1, -1, -1, -1, -1, 80, 81, - 82, -1, -1, -1, 86, -1, -1, 89, 90, 91, - 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, - 102, 103, 104, 105, 106, -1, -1, -1, -1, -1, - -1, -1, -1, 115, -1, 117, 118, -1, 120, -1, - -1, -1, -1, 125, -1, 127, 128, 129, -1, -1, - 132, -1, -1, -1, -1, 137, -1, -1, 140, -1, - -1, -1, 144, 3, 4, 5, 6, 149, 8, 9, - 10, 11, 154, -1, -1, -1, -1, -1, -1, -1, - 162, -1, -1, 165, 166, 167, -1, -1, 170, -1, - 172, 173, -1, -1, 176, 16, 17, 18, 19, 20, - 21, 22, 23, 24, -1, -1, -1, -1, -1, -1, - -1, 51, -1, 34, -1, 55, -1, 57, 58, 59, - 60, -1, -1, -1, -1, -1, 66, -1, -1, -1, - 70, 71, -1, -1, -1, -1, -1, -1, -1, -1, - 80, 81, 82, -1, -1, -1, 86, -1, -1, 89, - 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, - 100, 101, 102, 103, 104, 105, 106, -1, -1, -1, - -1, -1, -1, -1, -1, 115, -1, 117, 118, -1, - 120, -1, -1, -1, -1, 125, -1, 127, 128, 129, - -1, -1, 132, -1, -1, -1, -1, 137, -1, -1, - 140, -1, -1, -1, 144, 3, 4, 5, 6, 149, - 8, 9, 10, 11, -1, -1, -1, -1, -1, -1, - -1, -1, 162, -1, -1, 165, 166, 167, -1, -1, - 170, -1, 172, 173, 174, -1, 176, -1, 159, 160, - 161, 162, 163, 164, 165, 166, 167, 168, 169, -1, - 171, 172, 173, 51, -1, -1, -1, 55, -1, 57, - 58, 59, 60, -1, -1, -1, -1, -1, 66, -1, - -1, -1, 70, 71, -1, -1, -1, -1, -1, -1, - -1, -1, 80, 81, 82, -1, -1, -1, 86, -1, - -1, 89, 90, 91, 92, 93, 94, 95, 96, 97, - 98, 99, 100, 101, 102, 103, 104, 105, 106, -1, - -1, -1, -1, -1, -1, -1, -1, 115, -1, 117, - 118, -1, 120, -1, -1, -1, -1, 125, -1, 127, - 128, 129, -1, -1, 132, -1, -1, -1, -1, 137, - -1, -1, 140, -1, -1, -1, 144, 3, 4, 5, - 6, 149, 8, 9, 10, 11, -1, -1, -1, -1, - -1, -1, -1, -1, 162, -1, -1, 165, 166, 167, - -1, -1, 170, -1, 172, 173, -1, -1, 176, 16, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 16, 17, 18, 19, 20, 21, 22, 23, 24, -1, -1, - -1, -1, -1, -1, -1, 51, -1, 34, -1, 55, - -1, 57, 58, 59, 60, -1, -1, -1, -1, -1, - 66, -1, -1, -1, 70, 71, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 51, 52, 34, -1, 55, + -1, 57, 58, 59, 60, 61, -1, -1, -1, -1, + 66, 67, -1, -1, 70, 71, -1, -1, 74, -1, -1, -1, -1, -1, 80, 81, 82, -1, -1, -1, 86, -1, -1, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, -1, -1, -1, -1, -1, -1, -1, -1, 115, -1, 117, 118, -1, 120, -1, -1, -1, -1, 125, - -1, 127, 128, 129, -1, -1, 132, -1, -1, -1, - -1, 137, -1, -1, 140, -1, -1, -1, 144, 3, - 4, 5, 6, 149, 8, 9, 10, -1, -1, -1, - -1, 15, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 170, -1, 172, 173, -1, -1, + -1, 127, 128, 129, -1, -1, 132, 133, -1, -1, + -1, 137, -1, -1, 140, 141, 142, 143, 144, -1, + -1, 147, -1, 149, 3, 4, 5, 6, -1, 8, + 9, 10, 11, -1, -1, -1, 162, -1, -1, 165, + 166, 167, -1, -1, 170, -1, 172, 173, -1, -1, 176, -1, 159, 160, 161, 162, 163, 164, 165, 166, - 167, 168, 169, -1, 171, 172, 173, 51, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 66, -1, 10, 11, 12, 71, -1, -1, - -1, -1, -1, -1, -1, -1, 80, 81, -1, -1, - -1, -1, 86, -1, -1, -1, 90, 91, 92, 93, - 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, - 104, 105, 3, 4, 5, 6, -1, 8, 9, 10, - -1, -1, -1, -1, 118, -1, 120, -1, -1, -1, - -1, 125, 68, -1, -1, 129, -1, -1, 132, -1, - -1, -1, -1, 137, -1, 81, 82, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 51, -1, -1, -1, -1, -1, -1, -1, 162, -1, - -1, 165, 166, 167, -1, 66, 170, -1, 172, 173, - 71, -1, 176, -1, 120, 121, -1, 123, -1, 80, - 81, -1, 128, -1, 130, 86, -1, -1, -1, 90, - 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, - 101, 102, 103, 104, 105, 10, 11, 12, 154, -1, - -1, -1, -1, -1, -1, -1, -1, 118, -1, 120, - 3, 4, 5, 6, 125, 8, 9, 10, 129, -1, - -1, 132, 15, -1, -1, -1, 137, -1, -1, -1, - -1, -1, -1, -1, 3, 4, 5, 6, -1, 8, - 9, 10, -1, -1, -1, -1, 15, -1, -1, -1, - -1, -1, -1, 68, -1, 48, -1, 50, 51, 170, - -1, 172, 173, -1, -1, 176, 81, 82, -1, -1, - -1, -1, -1, 66, -1, -1, -1, -1, 71, 48, - -1, 50, 51, -1, -1, -1, -1, 80, 81, -1, - -1, -1, -1, -1, -1, -1, -1, 66, -1, -1, - -1, -1, 71, -1, -1, 120, 121, 122, 123, -1, - -1, 80, 81, 128, -1, 130, 55, -1, 57, 58, - 59, 60, 115, -1, -1, 118, 141, 120, -1, -1, - -1, 146, 125, -1, -1, -1, 129, -1, -1, 132, - -1, -1, -1, -1, 137, -1, 115, 140, -1, 118, - 89, 120, 3, 4, 5, 6, 125, 8, 9, 10, - 129, -1, -1, 132, 15, -1, -1, 106, 137, 162, - -1, 140, 165, 166, -1, -1, -1, 170, -1, 172, - -1, -1, -1, 176, -1, -1, -1, -1, 127, 128, - -1, -1, -1, 162, -1, -1, 165, 166, -1, -1, - 51, 170, -1, 172, -1, 144, -1, 176, -1, -1, - 149, -1, -1, -1, -1, 66, -1, -1, -1, -1, - 71, 6, -1, -1, -1, -1, -1, -1, -1, 80, - 81, 16, 17, 18, 19, 20, 21, 22, 23, 24, - -1, -1, -1, -1, -1, 10, 11, 12, -1, 34, - -1, 36, 37, 38, 39, 40, 41, 42, 43, 44, - 45, 46, 47, -1, 115, -1, -1, 118, -1, 120, - -1, -1, -1, -1, 125, -1, -1, -1, 129, -1, - -1, 132, -1, -1, 69, -1, 137, -1, -1, 140, - 10, 11, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 68, -1, -1, -1, -1, -1, 74, - -1, 162, -1, -1, 165, 166, 81, 82, -1, 170, - -1, 172, -1, -1, -1, 176, -1, -1, -1, -1, - 115, -1, 52, -1, -1, 55, -1, 57, 58, 59, - 60, 61, -1, -1, -1, -1, -1, 67, -1, 114, - 70, -1, -1, -1, 74, 120, 121, -1, 123, 10, - 11, 12, 82, 128, -1, 130, -1, -1, -1, 89, - 155, -1, -1, 158, -1, 160, 161, 162, 163, 164, - 165, 166, 167, 168, 169, 170, 106, 172, 173, -1, - -1, 176, -1, -1, 10, 11, -1, -1, -1, 119, - -1, -1, -1, 10, 11, 12, -1, 127, 128, -1, - -1, -1, -1, 133, -1, -1, -1, 68, -1, -1, - -1, 141, 142, 143, 144, -1, -1, 147, -1, 149, - 81, 82, -1, -1, 154, -1, 52, -1, -1, 55, - -1, 57, 58, 59, 60, 61, -1, -1, -1, -1, - 170, 67, -1, -1, 70, -1, -1, -1, 74, -1, - -1, 68, -1, -1, -1, -1, 82, -1, -1, 120, - 121, -1, 123, 89, 81, 82, -1, 128, -1, 130, - -1, 10, 11, 12, -1, -1, -1, 10, 11, -1, - 106, -1, -1, -1, 145, -1, -1, -1, -1, -1, - -1, -1, -1, 119, -1, -1, -1, -1, -1, -1, - -1, 127, 128, 120, 121, -1, 123, 133, -1, -1, - -1, 128, -1, 130, -1, 141, 142, 143, 144, 52, - -1, 147, 55, 149, 57, 58, 59, 60, 61, 68, - -1, -1, -1, -1, 67, -1, -1, 70, -1, -1, - -1, 74, 81, 82, 170, -1, -1, -1, -1, 82, - -1, -1, -1, -1, -1, -1, 89, 16, 17, 18, - 19, 20, 21, 22, 23, 24, -1, -1, -1, -1, - -1, -1, -1, 106, -1, 34, -1, -1, -1, -1, - -1, 120, 121, -1, 123, -1, 119, -1, -1, 128, - -1, 130, -1, -1, 127, 128, -1, -1, -1, -1, - 133, -1, 141, -1, -1, -1, -1, 146, 141, 142, - 143, 144, -1, -1, 147, -1, 149, 16, 17, 18, - 19, 20, 21, 22, 23, 24, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 34, -1, 170, 16, 17, + 167, 168, 169, -1, 171, 172, 173, -1, -1, -1, + 177, -1, 51, -1, -1, -1, 55, -1, 57, 58, + 59, 60, -1, -1, -1, -1, -1, 66, -1, 68, + 69, 70, 71, -1, -1, -1, -1, -1, -1, -1, + -1, 80, 81, 82, -1, -1, -1, 86, -1, -1, + 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, + 99, 100, 101, 102, 103, 104, 105, 106, -1, -1, + -1, -1, -1, -1, -1, -1, 115, -1, 117, 118, + -1, 120, -1, -1, -1, -1, 125, -1, 127, 128, + 129, -1, -1, 132, -1, -1, -1, -1, 137, -1, + -1, 140, -1, -1, -1, 144, 3, 4, 5, 6, + 149, 8, 9, 10, 11, 154, -1, -1, 15, -1, + -1, -1, -1, 162, -1, -1, 165, 166, 167, -1, + -1, 170, -1, 172, 173, -1, -1, 176, 16, 17, 18, 19, 20, 21, 22, 23, 24, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 34, 16, 17, 18, + -1, -1, -1, -1, 51, -1, 34, -1, 55, -1, + 57, 58, 59, 60, -1, -1, -1, -1, -1, 66, + -1, -1, -1, 70, 71, -1, -1, -1, -1, -1, + -1, -1, -1, 80, 81, 82, -1, -1, -1, 86, + -1, -1, 89, 90, 91, 92, 93, 94, 95, 96, + 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, + -1, -1, -1, -1, -1, -1, -1, -1, 115, -1, + 117, 118, -1, 120, -1, -1, -1, -1, 125, -1, + 127, 128, 129, -1, -1, 132, -1, -1, -1, -1, + 137, -1, -1, 140, -1, -1, -1, 144, 3, 4, + 5, 6, 149, 8, 9, 10, 11, -1, -1, -1, + -1, -1, -1, -1, -1, 162, -1, -1, 165, 166, + 167, -1, -1, 170, -1, 172, 173, -1, -1, 176, + -1, 159, 160, 161, 162, 163, 164, 165, 166, 167, + 168, 169, -1, 171, 172, 173, 51, -1, -1, 177, + 55, -1, 57, 58, 59, 60, -1, -1, -1, -1, + -1, 66, -1, -1, -1, 70, 71, -1, -1, -1, + -1, -1, -1, -1, -1, 80, 81, 82, -1, -1, + -1, 86, -1, -1, 89, 90, 91, 92, 93, 94, + 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, -1, -1, -1, -1, -1, -1, -1, -1, + 115, -1, 117, 118, -1, 120, -1, -1, -1, -1, + 125, -1, 127, 128, 129, -1, -1, 132, -1, -1, + -1, -1, 137, -1, -1, 140, -1, -1, -1, 144, + 3, 4, 5, 6, 149, 8, 9, 10, 11, -1, + -1, -1, -1, -1, -1, -1, -1, 162, -1, -1, + 165, 166, 167, -1, -1, 170, -1, 172, 173, 174, + -1, 176, 16, 17, 18, 19, 20, 21, 22, 23, + 24, -1, -1, -1, -1, -1, -1, -1, 51, 52, + 34, -1, 55, -1, 57, 58, 59, 60, -1, -1, + -1, -1, -1, 66, -1, -1, -1, 70, 71, -1, + -1, -1, -1, -1, -1, -1, -1, 80, 81, 82, + -1, -1, -1, 86, -1, -1, 89, 90, 91, 92, + 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, + 103, 104, 105, 106, -1, -1, -1, -1, -1, -1, + -1, -1, 115, -1, 117, 118, -1, 120, -1, -1, + -1, -1, 125, -1, 127, 128, 129, -1, -1, 132, + -1, -1, -1, -1, 137, -1, -1, 140, -1, -1, + -1, 144, 3, 4, 5, 6, 149, 8, 9, 10, + 11, -1, -1, -1, -1, -1, -1, -1, -1, 162, + -1, -1, 165, 166, 167, -1, -1, 170, -1, 172, + 173, -1, 156, 176, -1, 159, 160, 161, 162, 163, + 164, 165, 166, 167, 168, 169, -1, 171, 172, 173, + 51, 52, -1, -1, 55, -1, 57, 58, 59, 60, + -1, -1, -1, -1, -1, 66, -1, -1, -1, 70, + 71, -1, -1, -1, -1, -1, -1, -1, -1, 80, + 81, 82, -1, -1, -1, 86, -1, -1, 89, 90, + 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, + 101, 102, 103, 104, 105, 106, -1, -1, 55, -1, + 57, 58, 59, 60, 115, -1, 117, 118, -1, 120, + -1, -1, -1, -1, 125, -1, 127, 128, 129, -1, + -1, 132, -1, -1, -1, -1, 137, -1, -1, 140, + -1, -1, 89, 144, 3, 4, 5, 6, 149, 8, + 9, 10, 11, -1, -1, -1, -1, -1, -1, 106, + -1, 162, -1, -1, 165, 166, 167, -1, -1, 170, + -1, 172, 173, -1, -1, 176, -1, -1, -1, -1, + 127, 128, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 51, -1, -1, -1, 55, 144, 57, 58, + 59, 60, 149, -1, -1, -1, -1, 66, -1, -1, + -1, 70, 71, -1, -1, -1, -1, -1, -1, -1, + -1, 80, 81, 82, -1, 172, -1, 86, -1, -1, + 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, + 99, 100, 101, 102, 103, 104, 105, 106, -1, -1, + -1, -1, -1, -1, -1, -1, 115, -1, 117, 118, + -1, 120, -1, -1, -1, -1, 125, -1, 127, 128, + 129, -1, -1, 132, -1, -1, -1, -1, 137, -1, + -1, 140, -1, -1, -1, 144, 3, 4, 5, 6, + 149, 8, 9, 10, 11, -1, -1, -1, -1, -1, + -1, -1, -1, 162, -1, -1, 165, 166, 167, -1, + -1, 170, -1, 172, 173, 174, -1, 176, 16, 17, + 18, 19, 20, 21, 22, 23, 24, -1, -1, -1, + -1, -1, -1, -1, 51, -1, 34, -1, 55, -1, + 57, 58, 59, 60, -1, -1, -1, -1, -1, 66, + -1, -1, -1, 70, 71, -1, -1, -1, -1, -1, + -1, -1, -1, 80, 81, 82, -1, -1, -1, 86, + -1, -1, 89, 90, 91, 92, 93, 94, 95, 96, + 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, + -1, -1, -1, -1, -1, -1, -1, -1, 115, -1, + 117, 118, -1, 120, -1, -1, -1, -1, 125, -1, + 127, 128, 129, -1, -1, 132, -1, -1, -1, -1, + 137, -1, -1, 140, -1, -1, -1, 144, 3, 4, + 5, 6, 149, 8, 9, 10, 11, 154, -1, -1, + -1, -1, -1, -1, -1, 162, -1, -1, 165, 166, + 167, -1, -1, 170, -1, 172, 173, 155, -1, 176, + -1, 159, 160, 161, 162, 163, 164, 165, 166, 167, + 168, 169, -1, 171, 172, 173, 51, -1, -1, -1, + 55, -1, 57, 58, 59, 60, -1, -1, -1, -1, + -1, 66, -1, -1, -1, 70, 71, -1, -1, -1, + -1, -1, -1, -1, -1, 80, 81, 82, -1, -1, + -1, 86, -1, -1, 89, 90, 91, 92, 93, 94, + 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, -1, -1, -1, -1, -1, -1, -1, -1, + 115, -1, 117, 118, -1, 120, -1, -1, -1, -1, + 125, -1, 127, 128, 129, -1, -1, 132, -1, -1, + -1, -1, 137, -1, -1, 140, -1, -1, -1, 144, + 3, 4, 5, 6, 149, 8, 9, 10, 11, 154, + -1, -1, -1, -1, -1, -1, -1, 162, -1, -1, + 165, 166, 167, -1, -1, 170, -1, 172, 173, -1, + -1, 176, 16, 17, 18, 19, 20, 21, 22, 23, + 24, -1, -1, -1, -1, -1, -1, -1, 51, -1, + 34, -1, 55, -1, 57, 58, 59, 60, -1, -1, + -1, -1, -1, 66, -1, -1, -1, 70, 71, -1, + -1, -1, -1, -1, -1, -1, -1, 80, 81, 82, + -1, -1, -1, 86, -1, -1, 89, 90, 91, 92, + 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, + 103, 104, 105, 106, -1, -1, -1, -1, -1, -1, + -1, -1, 115, -1, 117, 118, -1, 120, -1, -1, + -1, -1, 125, -1, 127, 128, 129, -1, -1, 132, + -1, -1, -1, -1, 137, -1, -1, 140, -1, -1, + -1, 144, 3, 4, 5, 6, 149, 8, 9, 10, + 11, -1, -1, -1, -1, -1, -1, -1, -1, 162, + -1, -1, 165, 166, 167, -1, -1, 170, -1, 172, + 173, 174, -1, 176, -1, 159, 160, 161, 162, 163, + 164, 165, 166, 167, 168, 169, -1, 171, 172, 173, + 51, -1, -1, -1, 55, -1, 57, 58, 59, 60, + -1, -1, -1, -1, -1, 66, -1, -1, -1, 70, + 71, -1, -1, -1, -1, -1, -1, -1, -1, 80, + 81, 82, -1, -1, -1, 86, -1, -1, 89, 90, + 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, + 101, 102, 103, 104, 105, 106, -1, -1, -1, -1, + -1, -1, -1, -1, 115, -1, 117, 118, -1, 120, + -1, -1, -1, -1, 125, -1, 127, 128, 129, -1, + -1, 132, -1, -1, -1, -1, 137, -1, -1, 140, + -1, -1, -1, 144, 3, 4, 5, 6, 149, 8, + 9, 10, 11, -1, 18, 19, 20, 21, 22, 23, + 24, 162, -1, -1, 165, 166, 167, -1, -1, 170, + 34, 172, 173, -1, -1, 176, 16, 17, 18, 19, + 20, 21, 22, 23, 24, -1, -1, -1, -1, -1, + -1, -1, 51, -1, 34, -1, 55, -1, 57, 58, + 59, 60, -1, -1, -1, -1, -1, 66, -1, -1, + -1, 70, 71, -1, -1, -1, -1, -1, -1, -1, + -1, 80, 81, 82, -1, -1, -1, 86, -1, -1, + 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, + 99, 100, 101, 102, 103, 104, 105, 106, -1, -1, + -1, -1, -1, -1, -1, -1, 115, -1, 117, 118, + -1, 120, -1, -1, -1, -1, 125, -1, 127, 128, + 129, -1, -1, 132, -1, -1, -1, -1, 137, -1, + -1, 140, -1, -1, -1, 144, 3, 4, 5, 6, + 149, 8, 9, 10, -1, -1, 160, 161, 162, 163, + 164, 165, 166, 167, 168, 169, -1, 171, 172, 173, + -1, 170, -1, 172, 173, -1, -1, 176, -1, 159, + 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, + -1, 171, 172, 173, 51, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 66, + -1, -1, -1, -1, 71, -1, -1, -1, -1, -1, + -1, -1, -1, 80, 81, -1, -1, -1, -1, 86, + -1, -1, -1, 90, 91, 92, 93, 94, 95, 96, + 97, 98, 99, 100, 101, 102, 103, 104, 105, 3, + 4, 5, 6, -1, 8, 9, 10, -1, -1, -1, + -1, 118, -1, 120, -1, -1, -1, -1, 125, -1, + -1, -1, 129, -1, -1, 132, -1, -1, -1, -1, + 137, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 51, -1, -1, + -1, -1, -1, -1, -1, 162, -1, -1, 165, 166, + 167, -1, 66, 170, -1, 172, 173, 71, -1, 176, + 20, 21, 22, 23, 24, -1, 80, 81, -1, -1, + -1, -1, 86, -1, 34, -1, 90, 91, 92, 93, + 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, + 104, 105, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 118, -1, 120, -1, -1, -1, + -1, 125, -1, -1, 6, 129, -1, -1, 132, 10, + 11, -1, -1, 137, 16, 17, 18, 19, 20, 21, + 22, 23, 24, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 34, -1, 36, 37, 38, 39, 40, 41, + 42, 43, 44, 45, 46, 47, 170, -1, 172, 173, + -1, 52, 176, -1, 55, -1, 57, 58, 59, 60, + 61, -1, -1, -1, -1, -1, 67, 69, -1, 70, + -1, -1, -1, 74, -1, -1, -1, -1, 10, 11, + 12, 82, -1, 15, -1, -1, -1, -1, 89, -1, + -1, -1, -1, 163, 164, 165, 166, 167, 168, 169, + -1, 171, 172, 173, -1, 106, -1, -1, -1, -1, + -1, -1, -1, 115, -1, -1, -1, -1, 119, -1, + -1, -1, -1, -1, -1, -1, 127, 128, -1, -1, + 10, 11, 133, -1, -1, -1, 68, -1, -1, -1, + 141, 142, 143, 144, -1, -1, 147, -1, 149, 81, + 82, -1, -1, 155, -1, -1, 158, -1, 160, 161, + 162, 163, 164, 165, 166, 167, 168, 169, 170, 170, + 172, 173, 52, -1, 176, 55, -1, 57, 58, 59, + 60, 61, -1, -1, -1, -1, -1, 67, 120, 121, + 70, 123, -1, -1, 74, -1, 128, -1, 130, -1, + -1, -1, 82, -1, -1, -1, -1, -1, -1, 89, + 16, 17, 18, 19, 20, 21, 22, 23, 24, -1, + -1, -1, -1, -1, -1, -1, 106, -1, 34, -1, + -1, 55, -1, 57, 58, 59, 60, -1, -1, 119, + -1, -1, -1, -1, -1, -1, -1, 127, 128, -1, + -1, -1, -1, 133, -1, -1, -1, -1, -1, -1, + -1, 141, 142, 143, 144, 89, -1, 147, -1, 149, + 16, 17, 18, 19, 20, 21, 22, 23, 24, -1, + -1, -1, 106, -1, -1, -1, -1, -1, 34, -1, + 170, 16, 17, 18, 19, 20, 21, 22, 23, 24, + -1, -1, -1, 127, 128, -1, -1, -1, -1, 34, + 16, 17, 18, 19, 20, 21, 22, 23, 24, -1, + 144, -1, -1, -1, -1, 149, -1, -1, 34, 16, + 17, 18, 19, 20, 21, 22, 23, 24, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 34, 172, 155, + -1, -1, -1, 159, 160, 161, 162, 163, 164, 165, + 166, 167, 168, 169, -1, 171, 172, 173, 174, 16, + 17, 18, 19, 20, 21, 22, 23, 24, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 34, 16, 17, + 18, 19, 20, 21, 22, 23, 24, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 34, -1, -1, -1, + -1, -1, -1, 159, 160, 161, 162, 163, 164, 165, + 166, 167, 168, 169, -1, 171, 172, 173, 174, -1, + -1, -1, -1, -1, 159, 160, 161, 162, 163, 164, + 165, 166, 167, 168, 169, -1, 171, 172, 173, 174, + -1, -1, -1, 159, 160, 161, 162, 163, 164, 165, + 166, 167, 168, 169, -1, 171, 172, 173, 174, -1, + -1, -1, 159, 160, 161, 162, 163, 164, 165, 166, + 167, 168, 169, -1, 171, 172, 173, 174, 16, 17, + 18, 19, 20, 21, 22, 23, 24, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 34, -1, -1, -1, + -1, -1, 159, 160, 161, 162, 163, 164, 165, 166, + 167, 168, 169, -1, 171, 172, 173, 174, -1, -1, + -1, 159, 160, 161, 162, 163, 164, 165, 166, 167, + 168, 169, -1, 171, 172, 173, 174, 16, 17, 18, 19, 20, 21, 22, 23, 24, -1, -1, -1, -1, -1, -1, -1, -1, -1, 34, 16, 17, 18, 19, - 20, 21, 22, 23, 24, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 34, -1, 155, -1, -1, -1, - 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, - 169, -1, 171, 172, 173, 174, 16, 17, 18, 19, 20, 21, 22, 23, 24, -1, -1, -1, -1, -1, -1, -1, -1, -1, 34, 16, 17, 18, 19, 20, 21, 22, 23, 24, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 34, -1, -1, -1, -1, -1, -1, - 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, - 169, -1, 171, 172, 173, 174, -1, -1, -1, -1, + -1, -1, -1, 34, 16, 17, 18, 19, 20, 21, + 22, 23, 24, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 34, -1, -1, -1, -1, -1, -1, -1, -1, 159, 160, 161, 162, 163, 164, 165, 166, 167, - 168, 169, -1, 171, 172, 173, 174, -1, -1, -1, + 168, 169, -1, 171, 172, 173, 174, 16, 17, 18, + 19, 20, 21, 22, 23, 24, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 34, 16, 17, 18, 19, + 20, 21, 22, 23, 24, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 34, -1, -1, -1, -1, -1, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, -1, 171, 172, 173, 174, -1, -1, -1, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, - -1, 171, 172, 173, 174, 16, 17, 18, 19, 20, - 21, 22, 23, 24, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 34, -1, -1, -1, -1, -1, 159, - 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, - -1, 171, 172, 173, 174, -1, -1, -1, 159, 160, + -1, 171, 172, 173, 174, -1, 157, -1, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, -1, - 171, 172, 173, 174, 16, 17, 18, 19, 20, 21, - 22, 23, 24, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 34, 16, 17, 18, 19, 20, 21, 22, - 23, 24, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 34, 16, 17, 18, 19, 20, 21, 22, 23, - 24, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 34, 16, 17, 18, 19, 20, 21, 22, 23, 24, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 34, - -1, -1, -1, -1, -1, -1, -1, -1, 159, 160, - 161, 162, 163, 164, 165, 166, 167, 168, 169, -1, - 171, 172, 173, 174, 16, 17, 18, 19, 20, 21, - 22, 23, 24, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 34, 17, 18, 19, 20, 21, 22, 23, - 24, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 34, -1, -1, -1, -1, -1, -1, 159, 160, 161, + 171, 172, 173, -1, -1, 157, -1, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, -1, 171, - 172, 173, 174, -1, -1, -1, 159, 160, 161, 162, - 163, 164, 165, 166, 167, 168, 169, -1, 171, 172, - 173, 174, -1, 157, -1, 159, 160, 161, 162, 163, - 164, 165, 166, 167, 168, 169, -1, 171, 172, 173, - -1, -1, 157, -1, 159, 160, 161, 162, 163, 164, - 165, 166, 167, 168, 169, -1, 171, 172, 173, 18, - 19, 20, 21, 22, 23, 24, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 34, 18, 19, 20, 21, - 22, 23, 24, -1, -1, -1, -1, 159, 160, 161, - 162, -1, 34, 165, 166, 167, 168, 169, -1, 171, - 172, 173, -1, -1, -1, -1, 160, 161, 162, -1, - 6, 165, 166, 167, 168, 169, -1, 171, 172, 173, - 18, 19, 20, 21, 22, 23, 24, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 34, 18, 19, 20, - 21, 22, 23, 24, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 34, -1, -1, -1, -1, 54, -1, - 55, -1, 57, 58, 59, 60, 62, 63, 64, 65, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 75, + 172, 173, 18, 19, 20, 21, 22, 23, 24, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 34, 18, + 19, 20, 21, 22, 23, 24, -1, -1, 157, -1, + 159, 160, 161, 162, -1, 34, 165, 166, 167, 168, + 169, -1, 171, 172, 173, -1, -1, -1, -1, 159, + 160, 161, 162, -1, -1, 165, 166, 167, 168, 169, + -1, 171, 172, 173, 18, 19, 20, 21, 22, 23, + 24, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 34, 18, 19, 20, 21, 22, 23, 24, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 34, 18, 19, + 20, 21, 22, 23, 24, -1, -1, -1, 55, -1, + 57, 58, 59, 60, 34, 18, 19, 20, 21, 22, + 23, 24, -1, -1, 18, 19, 20, 21, 22, 23, + 24, 34, -1, -1, -1, -1, -1, -1, -1, -1, + 34, -1, 89, -1, -1, 161, 162, 163, 164, 165, + 166, 167, 168, 169, -1, 171, 172, 173, -1, 106, + -1, -1, -1, 162, 163, 164, 165, 166, 167, 168, + 169, -1, 171, 172, 173, 20, 21, 22, 23, 24, + 127, 128, -1, -1, -1, -1, -1, -1, -1, 34, + -1, -1, -1, -1, -1, -1, -1, 144, -1, -1, + -1, -1, 149, -1, -1, -1, 160, 161, 162, -1, + -1, 165, 166, 167, 168, 169, -1, 171, 172, 173, + -1, -1, -1, -1, -1, 172, 163, 164, 165, 166, + 167, 168, 169, -1, 171, 172, 173, -1, -1, -1, + -1, 161, 162, -1, -1, 165, 166, 167, 168, 169, + 17, 171, 172, 173, -1, -1, -1, -1, -1, 162, + 6, -1, 165, 166, 167, 168, 169, -1, 171, 172, + 173, 165, 166, 167, 168, 169, -1, 171, 172, 173, + -1, 48, -1, 50, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 62, -1, 64, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 54, -1, + -1, 10, 11, 12, 81, -1, 62, 63, 64, 65, + 165, 166, 167, 168, 169, -1, 171, 172, 173, 75, 76, 77, 78, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 88, -1, 89, -1, -1, -1, -1, -1, - -1, 160, 161, 162, 163, 164, 165, 166, 167, 168, - 169, 106, 171, 172, 173, -1, -1, 113, -1, 161, - 162, 163, 164, 165, 166, 167, 168, 169, 124, 171, - 172, 173, 127, 128, 130, -1, -1, -1, 134, 135, - -1, 6, -1, -1, -1, -1, -1, -1, -1, 144, - 146, -1, 148, -1, 149, -1, 10, 11, 12, -1, - -1, -1, -1, 161, 162, -1, -1, 165, 166, 167, - 168, 169, -1, 171, 172, 173, -1, 172, -1, -1, - -1, 162, -1, -1, 165, 166, 167, 168, 169, 54, - 171, 172, 173, -1, -1, -1, -1, 62, 63, 64, - 65, 55, -1, 57, 58, 59, 60, 61, 62, -1, - 75, 76, 77, 78, -1, -1, 70, -1, -1, 10, - 11, 12, -1, 88, -1, -1, -1, -1, 82, -1, - -1, -1, -1, -1, -1, 89, -1, -1, 55, -1, - 57, 58, 59, 60, -1, -1, -1, -1, 113, -1, - -1, -1, 106, 11, 12, -1, -1, -1, -1, 124, - -1, -1, -1, -1, 55, 130, 57, 58, 59, 60, - 135, -1, 89, 127, 128, -1, -1, -1, -1, 70, - -1, 146, -1, 148, -1, -1, -1, 141, -1, 106, - 144, 82, -1, 147, 52, 149, -1, 55, 89, 57, - 58, 59, 60, 61, 62, -1, -1, -1, -1, 67, - 127, 128, 70, -1, -1, 106, 74, -1, -1, -1, - -1, -1, -1, -1, 82, -1, -1, 144, -1, -1, - -1, 89, 149, -1, -1, -1, 127, 128, -1, -1, - -1, -1, -1, -1, -1, -1, 11, 12, 106, -1, - -1, -1, -1, 144, -1, 172, 147, -1, 149, -1, - -1, -1, -1, -1, -1, -1, 124, -1, -1, 127, - 128, -1, 11, 12, -1, 133, -1, -1, -1, -1, - -1, -1, -1, 141, 142, 143, 144, 52, -1, 147, - 55, 149, 57, 58, 59, 60, 61, 62, -1, -1, - -1, -1, 67, -1, -1, 70, -1, -1, -1, 74, - -1, -1, -1, 52, -1, -1, 55, 82, 57, 58, - 59, 60, 61, -1, 89, -1, -1, -1, 67, -1, - -1, 70, -1, -1, -1, 74, -1, -1, -1, -1, - -1, 106, -1, 82, -1, -1, -1, -1, -1, -1, - 89, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 127, 128, -1, 11, 12, 106, 133, -1, - -1, -1, -1, -1, -1, -1, 141, 142, 143, 144, - -1, -1, 147, -1, 149, 124, -1, -1, 127, 128, - -1, 11, -1, -1, 133, -1, -1, -1, -1, -1, - -1, -1, 141, 142, 143, 144, 52, -1, 147, 55, - 149, 57, 58, 59, 60, 61, -1, -1, -1, -1, - -1, 67, -1, -1, 70, -1, -1, -1, 74, -1, - -1, -1, 52, -1, -1, 55, 82, 57, 58, 59, - 60, 61, 62, 89, -1, -1, -1, 67, -1, -1, - 70, -1, -1, -1, 74, -1, -1, -1, -1, -1, - 106, -1, 82, -1, -1, -1, -1, -1, -1, 89, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 127, 128, -1, 11, -1, 106, 133, -1, -1, - -1, -1, -1, -1, -1, 141, 142, 143, 144, -1, - -1, 147, -1, 149, -1, -1, -1, 127, 128, -1, - 11, -1, -1, 133, -1, -1, -1, -1, -1, -1, - -1, 141, 142, 143, 144, 52, -1, 147, 55, 149, + -1, -1, 88, -1, -1, -1, 113, -1, -1, 116, + 117, -1, -1, 120, -1, -1, 55, -1, 57, 58, + 59, 60, 61, 62, 10, 11, 12, 113, -1, 136, + -1, 70, -1, -1, -1, -1, -1, -1, 124, -1, + -1, 148, -1, 82, 130, -1, -1, -1, -1, 135, + 89, -1, -1, -1, -1, 162, -1, -1, -1, -1, + 146, -1, 148, -1, -1, 11, 12, 106, -1, 55, + -1, 57, 58, 59, 60, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 70, -1, -1, -1, 127, 128, + -1, -1, -1, -1, -1, 55, 82, 57, 58, 59, + 60, -1, 141, 89, -1, 144, 52, -1, 147, 55, + 149, 57, 58, 59, 60, 61, 62, -1, -1, -1, + 106, 67, -1, -1, 70, -1, -1, -1, 74, 89, + -1, -1, -1, -1, -1, -1, 82, -1, -1, -1, + -1, 127, 128, 89, -1, -1, 106, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 144, -1, + 106, 147, -1, 149, 11, 12, -1, 127, 128, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 124, -1, + -1, 127, 128, -1, 144, -1, -1, 133, -1, 149, + 11, 12, -1, -1, -1, 141, 142, 143, 144, -1, + -1, 147, -1, 149, -1, 52, -1, -1, 55, -1, 57, 58, 59, 60, 61, 62, -1, -1, -1, -1, 67, -1, -1, 70, -1, -1, -1, 74, -1, -1, -1, 52, -1, -1, 55, 82, 57, 58, 59, 60, 61, -1, 89, -1, -1, -1, 67, -1, -1, 70, -1, -1, -1, 74, -1, -1, -1, -1, -1, 106, -1, 82, -1, -1, -1, -1, -1, -1, 89, -1, - -1, -1, -1, -1, -1, -1, 10, 11, 12, -1, - 127, 128, -1, 11, -1, 106, 133, -1, -1, -1, - -1, 10, 11, 12, 141, 142, 143, 144, -1, -1, - 147, -1, 149, -1, -1, -1, 127, 128, -1, -1, - -1, -1, 133, 10, 11, 12, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 127, 128, -1, 11, 12, 106, 133, -1, -1, -1, + -1, -1, -1, -1, 141, 142, 143, 144, -1, -1, + 147, -1, 149, 124, -1, -1, 127, 128, -1, 11, + -1, -1, 133, -1, -1, -1, -1, -1, -1, -1, 141, 142, 143, 144, 52, -1, 147, 55, 149, 57, - 58, 59, 60, 61, 68, -1, -1, -1, -1, 67, - -1, -1, 70, -1, -1, -1, 74, 81, 82, 68, - -1, -1, -1, -1, 82, -1, -1, -1, -1, -1, - -1, 89, 81, 82, -1, -1, -1, 10, 11, 12, - -1, 68, 15, -1, -1, -1, -1, -1, 106, -1, - -1, -1, -1, -1, 81, 82, 120, 121, -1, 123, - -1, -1, -1, -1, 128, -1, 130, -1, -1, 127, - 128, 120, 121, -1, 123, 133, -1, 141, -1, 128, - -1, 130, 146, 141, 142, 143, 144, -1, -1, 147, - -1, 149, 141, 120, 121, 68, 123, 146, -1, -1, - -1, 128, 55, 130, 57, 58, 59, 60, 81, 82, - -1, 54, -1, -1, 141, -1, -1, -1, -1, 62, - 63, 64, 65, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 75, 76, 77, 78, 89, -1, -1, -1, - 83, -1, -1, -1, -1, 88, -1, 120, 121, -1, - 123, -1, -1, 106, -1, 128, -1, 130, -1, -1, + 58, 59, 60, 61, -1, -1, -1, -1, -1, 67, + -1, -1, 70, -1, -1, -1, 74, -1, -1, -1, + 52, -1, -1, 55, 82, 57, 58, 59, 60, 61, + 62, 89, -1, -1, -1, 67, -1, -1, 70, -1, + -1, -1, 74, -1, -1, -1, -1, -1, 106, -1, + 82, -1, -1, -1, -1, -1, -1, 89, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 127, + 128, -1, 11, -1, 106, 133, -1, -1, -1, -1, + -1, -1, -1, 141, 142, 143, 144, -1, -1, 147, + -1, 149, -1, -1, -1, 127, 128, -1, 11, -1, + -1, 133, -1, -1, -1, -1, -1, -1, -1, 141, + 142, 143, 144, 52, -1, 147, 55, 149, 57, 58, + 59, 60, 61, 62, -1, -1, -1, -1, 67, -1, + -1, 70, -1, -1, -1, 74, -1, -1, -1, 52, + -1, -1, 55, 82, 57, 58, 59, 60, 61, -1, + 89, -1, -1, -1, 67, -1, -1, 70, -1, -1, + -1, 74, -1, -1, -1, -1, -1, 106, -1, 82, + -1, -1, -1, -1, -1, -1, 89, -1, -1, -1, + -1, -1, -1, -1, 10, 11, 12, -1, 127, 128, + -1, 11, -1, 106, 133, -1, -1, -1, -1, 10, + 11, 12, 141, 142, 143, 144, -1, -1, 147, -1, + 149, -1, -1, -1, 127, 128, -1, -1, -1, -1, + 133, 10, 11, 12, -1, -1, -1, -1, 141, 142, + 143, 144, 52, -1, 147, 55, 149, 57, 58, 59, + 60, 61, 68, -1, -1, -1, -1, 67, -1, -1, + 70, -1, -1, -1, 74, 81, 82, 68, -1, -1, + -1, -1, 82, -1, -1, -1, -1, 54, -1, 89, + 81, 82, -1, -1, -1, 62, 63, 64, 65, 68, + -1, -1, -1, -1, -1, 74, 106, -1, 75, 76, + 77, 78, 81, 82, 120, 121, 83, 123, -1, -1, + -1, 88, 128, -1, 130, -1, -1, 127, 128, 120, + 121, -1, 123, 133, -1, 141, -1, 128, -1, 130, + 146, 141, 142, 143, 144, 114, 113, 147, -1, 149, + 141, 120, 121, -1, 123, 146, -1, 124, -1, 128, + -1, 130, -1, 130, 53, 54, -1, -1, 135, -1, + -1, -1, -1, 62, 63, 64, 65, -1, 145, 146, + -1, 148, -1, -1, 73, -1, 75, 76, 77, 78, + 79, -1, -1, -1, 83, -1, 163, -1, -1, 88, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 113, -1, -1, -1, 127, 128, -1, -1, -1, -1, - -1, 124, -1, -1, -1, -1, -1, 130, 53, 54, - -1, 144, 135, -1, -1, -1, 149, 62, 63, 64, - 65, -1, 145, 146, -1, 148, -1, -1, 73, -1, - 75, 76, 77, 78, 79, -1, -1, -1, 83, 172, - 163, -1, -1, 88, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 107, 108, 109, 110, 111, 112, 113, 114, - -1, -1, -1, -1, -1, -1, 121, 122, 123, 124, - -1, -1, -1, -1, -1, 130, 131, 54, -1, 134, - 135, -1, -1, -1, 139, 62, 63, 64, 65, -1, - 145, 146, -1, 148, -1, -1, -1, -1, 75, 76, - 77, 78, -1, -1, 54, -1, 83, -1, 54, -1, - -1, 88, 62, 63, 64, 65, 62, 63, 64, 65, - -1, -1, -1, -1, -1, 75, 76, 77, 78, 75, - 76, 77, 78, -1, -1, -1, 113, -1, 88, -1, - -1, -1, 88, -1, -1, -1, -1, 124, -1, -1, - -1, -1, -1, 130, -1, -1, -1, 134, 135, -1, - -1, -1, -1, 113, 114, -1, -1, 113, 145, 146, - -1, 148, -1, -1, 124, -1, -1, -1, 124, -1, - 130, -1, -1, -1, 130, 135, -1, -1, -1, 135, - -1, -1, -1, -1, -1, -1, 146, -1, 148, -1, - 146, -1, 148 + -1, -1, -1, -1, -1, -1, -1, -1, 107, 108, + 109, 110, 111, 112, 113, 114, -1, -1, -1, -1, + -1, -1, 121, 122, 123, 124, -1, -1, -1, -1, + -1, 130, 131, 54, -1, 134, 135, -1, -1, -1, + 139, 62, 63, 64, 65, -1, 145, 146, -1, 148, + -1, -1, -1, -1, 75, 76, 77, 78, -1, -1, + 54, -1, 83, -1, 54, -1, -1, 88, 62, 63, + 64, 65, 62, 63, 64, 65, -1, -1, -1, -1, + -1, 75, 76, 77, 78, 75, 76, 77, 78, -1, + -1, -1, 113, -1, 88, -1, -1, 55, 88, 57, + 58, 59, 60, 124, -1, -1, -1, -1, -1, 130, + -1, -1, 70, 134, 135, -1, -1, -1, -1, 113, + 114, -1, -1, 113, 145, 146, -1, 148, -1, -1, + 124, 89, -1, -1, 124, -1, 130, -1, -1, -1, + 130, 135, -1, -1, -1, 135, -1, -1, 106, -1, + -1, -1, 146, -1, 148, -1, 146, -1, 148, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 127, + 128, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 144, -1, -1, -1, + -1, 149 }; /* YYSTOS[STATE-NUM] -- The symbol kind of the accessing symbol of state STATE-NUM. */ static const yytype_int16 yystos[] = { - 0, 151, 152, 153, 179, 180, 289, 3, 4, 5, + 0, 151, 152, 153, 179, 180, 290, 3, 4, 5, 6, 8, 9, 10, 11, 51, 55, 57, 58, 59, 60, 66, 70, 71, 80, 81, 82, 86, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 115, 117, 118, 120, 125, 127, 128, 129, 132, 137, 140, 144, 149, 162, - 165, 166, 167, 170, 172, 173, 176, 279, 280, 288, + 165, 166, 167, 170, 172, 173, 176, 280, 281, 289, 11, 12, 52, 55, 57, 58, 59, 60, 61, 62, 67, 70, 74, 82, 89, 106, 127, 128, 133, 141, 142, 143, 144, 147, 149, 242, 243, 247, 248, 250, - 256, 257, 261, 262, 267, 268, 269, 270, 0, 48, - 50, 190, 289, 154, 172, 172, 172, 172, 172, 172, + 256, 258, 262, 263, 268, 269, 270, 271, 0, 48, + 50, 190, 290, 154, 172, 172, 172, 172, 172, 172, 172, 163, 172, 163, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 11, 52, 67, 141, 142, 245, - 261, 262, 267, 279, 163, 172, 172, 15, 172, 279, - 163, 172, 172, 172, 279, 279, 279, 279, 279, 11, + 262, 263, 268, 280, 163, 172, 172, 15, 172, 280, + 163, 172, 172, 172, 280, 280, 280, 280, 280, 11, 55, 57, 58, 59, 60, 70, 82, 89, 106, 127, - 128, 144, 149, 247, 277, 279, 10, 11, 12, 68, + 128, 144, 149, 247, 278, 280, 10, 11, 12, 68, 81, 82, 120, 121, 123, 128, 130, 158, 162, 167, - 283, 284, 286, 289, 279, 16, 17, 18, 19, 20, + 284, 285, 287, 290, 280, 16, 17, 18, 19, 20, 21, 22, 23, 24, 34, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 171, 172, 173, 6, - 8, 242, 243, 172, 61, 133, 70, 106, 268, 268, - 268, 286, 172, 268, 13, 15, 17, 62, 148, 162, - 167, 172, 240, 241, 289, 241, 154, 190, 190, 145, - 191, 192, 286, 172, 156, 181, 276, 277, 289, 276, - 247, 276, 276, 276, 276, 276, 247, 276, 247, 276, - 247, 276, 247, 247, 247, 247, 247, 247, 247, 247, - 247, 247, 247, 247, 247, 247, 247, 247, 276, 172, - 286, 172, 172, 190, 190, 174, 247, 276, 276, 172, - 247, 247, 247, 279, 276, 276, 174, 155, 174, 286, - 286, 155, 177, 158, 230, 289, 279, 279, 279, 279, - 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, - 279, 279, 279, 279, 279, 279, 279, 286, 174, 277, - 279, 241, 241, 52, 279, 247, 167, 286, 190, 240, + 8, 242, 243, 172, 61, 133, 70, 106, 269, 269, + 269, 287, 172, 269, 13, 15, 17, 62, 148, 162, + 167, 172, 240, 241, 290, 241, 257, 190, 190, 145, + 191, 192, 287, 172, 156, 181, 277, 278, 290, 277, + 247, 277, 277, 277, 277, 277, 247, 277, 247, 277, + 247, 277, 247, 247, 247, 247, 247, 247, 247, 247, + 247, 247, 247, 247, 247, 247, 247, 247, 277, 172, + 287, 172, 172, 190, 190, 174, 247, 277, 277, 172, + 247, 247, 247, 280, 277, 277, 174, 155, 174, 287, + 287, 155, 177, 158, 230, 290, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 287, 174, 278, + 280, 241, 241, 52, 280, 247, 167, 287, 190, 240, 241, 240, 241, 190, 190, 15, 17, 162, 167, 190, - 225, 226, 235, 289, 173, 259, 260, 289, 10, 11, - 12, 120, 157, 287, 10, 11, 12, 120, 154, 286, - 287, 286, 49, 155, 172, 11, 52, 67, 141, 142, - 244, 248, 250, 256, 261, 262, 267, 279, 53, 54, - 62, 63, 64, 65, 73, 75, 76, 77, 78, 79, - 83, 88, 107, 108, 109, 110, 111, 112, 113, 114, - 121, 122, 123, 124, 130, 131, 134, 135, 139, 145, - 146, 148, 184, 186, 187, 189, 193, 213, 263, 266, - 289, 175, 174, 174, 174, 174, 174, 174, 174, 164, - 174, 164, 174, 174, 174, 174, 155, 174, 155, 174, - 155, 174, 174, 174, 174, 174, 174, 174, 174, 174, - 174, 174, 174, 279, 247, 276, 286, 286, 164, 174, - 174, 286, 174, 164, 174, 174, 174, 174, 279, 279, - 15, 162, 284, 172, 210, 289, 279, 157, 174, 177, - 174, 174, 174, 190, 190, 13, 15, 17, 62, 148, - 162, 167, 240, 289, 240, 240, 190, 190, 190, 62, - 124, 242, 243, 174, 15, 155, 275, 279, 289, 286, - 175, 11, 258, 268, 157, 249, 251, 157, 190, 191, - 3, 4, 5, 9, 10, 15, 51, 66, 71, 80, - 81, 115, 118, 120, 125, 129, 132, 137, 140, 162, - 165, 166, 170, 172, 176, 227, 228, 235, 236, 281, - 282, 288, 289, 172, 286, 172, 174, 190, 190, 174, - 76, 88, 189, 189, 189, 189, 189, 189, 6, 189, - 213, 189, 279, 157, 188, 114, 189, 172, 172, 172, - 172, 172, 172, 189, 154, 190, 157, 157, 157, 189, - 189, 172, 187, 189, 193, 214, 189, 189, 197, 74, - 114, 286, 189, 189, 10, 11, 119, 154, 170, 200, - 204, 244, 246, 172, 172, 247, 247, 247, 174, 174, - 174, 172, 174, 172, 230, 225, 17, 62, 64, 81, - 113, 116, 117, 120, 136, 148, 162, 190, 279, 240, - 167, 286, 190, 240, 240, 190, 190, 173, 240, 240, - 240, 124, 242, 243, 235, 13, 17, 62, 148, 162, - 167, 172, 238, 287, 289, 13, 15, 17, 62, 148, - 162, 167, 172, 239, 210, 15, 235, 177, 190, 258, - 180, 81, 252, 289, 191, 172, 163, 163, 245, 163, - 15, 172, 281, 163, 172, 279, 279, 279, 279, 247, - 277, 279, 174, 15, 155, 16, 17, 18, 19, 20, + 225, 226, 235, 290, 173, 154, 10, 11, 12, 120, + 157, 288, 10, 11, 12, 120, 154, 287, 288, 287, + 49, 155, 172, 11, 52, 67, 141, 142, 244, 248, + 250, 256, 262, 263, 268, 280, 53, 54, 62, 63, + 64, 65, 73, 75, 76, 77, 78, 79, 83, 88, + 107, 108, 109, 110, 111, 112, 113, 114, 121, 122, + 123, 124, 130, 131, 134, 135, 139, 145, 146, 148, + 184, 186, 187, 189, 193, 213, 264, 267, 290, 175, + 174, 174, 174, 174, 174, 174, 174, 164, 174, 164, + 174, 174, 174, 174, 155, 174, 155, 174, 155, 174, + 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, + 174, 280, 247, 277, 287, 287, 164, 174, 174, 287, + 174, 164, 174, 174, 174, 174, 280, 280, 15, 162, + 285, 172, 210, 290, 280, 157, 174, 177, 174, 174, + 174, 190, 190, 13, 15, 17, 62, 148, 162, 167, + 240, 290, 240, 240, 190, 190, 190, 62, 124, 242, + 243, 174, 15, 155, 276, 280, 290, 260, 261, 290, + 11, 259, 269, 157, 249, 251, 157, 190, 191, 3, + 4, 5, 9, 10, 15, 51, 66, 71, 80, 81, + 115, 118, 120, 125, 129, 132, 137, 140, 162, 165, + 166, 170, 172, 176, 227, 228, 235, 236, 282, 283, + 289, 290, 172, 287, 172, 174, 190, 190, 174, 76, + 88, 189, 189, 189, 189, 189, 189, 6, 189, 213, + 189, 280, 157, 188, 114, 189, 172, 172, 172, 172, + 172, 172, 189, 154, 190, 157, 157, 157, 189, 189, + 172, 187, 189, 193, 214, 189, 189, 197, 74, 114, + 287, 189, 189, 10, 11, 119, 154, 170, 200, 204, + 244, 246, 172, 172, 247, 247, 247, 174, 174, 174, + 172, 174, 172, 230, 225, 17, 62, 64, 81, 113, + 116, 117, 120, 136, 148, 162, 190, 280, 240, 167, + 287, 190, 240, 240, 190, 190, 173, 240, 240, 240, + 124, 242, 243, 235, 13, 17, 62, 148, 162, 167, + 172, 238, 288, 290, 13, 15, 17, 62, 148, 162, + 167, 172, 239, 210, 15, 235, 177, 287, 175, 259, + 180, 81, 252, 290, 191, 172, 163, 163, 245, 163, + 15, 172, 282, 163, 172, 280, 280, 280, 280, 247, + 278, 280, 174, 15, 155, 16, 17, 18, 19, 20, 21, 22, 23, 24, 34, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 171, 172, 173, 52, - 279, 247, 190, 286, 287, 286, 190, 189, 174, 186, - 154, 286, 286, 286, 286, 286, 286, 286, 180, 286, - 279, 163, 10, 11, 204, 244, 246, 286, 286, 156, - 190, 172, 172, 62, 242, 185, 286, 195, 154, 156, - 158, 232, 156, 194, 277, 277, 174, 174, 174, 277, - 277, 174, 279, 172, 34, 223, 289, 190, 190, 240, - 240, 240, 275, 174, 174, 174, 242, 243, 238, 239, + 280, 247, 190, 287, 288, 287, 190, 189, 174, 186, + 154, 287, 287, 287, 287, 287, 287, 287, 180, 287, + 280, 163, 10, 11, 204, 244, 246, 287, 287, 156, + 190, 172, 172, 62, 242, 185, 287, 195, 154, 156, + 158, 232, 156, 194, 278, 278, 174, 174, 174, 278, + 278, 174, 280, 172, 34, 223, 290, 190, 190, 240, + 240, 240, 276, 174, 174, 174, 242, 243, 238, 239, 167, 190, 238, 238, 190, 190, 238, 173, 230, 190, - 167, 286, 190, 239, 239, 190, 190, 239, 173, 230, - 190, 190, 155, 158, 175, 157, 253, 254, 289, 49, - 247, 247, 247, 172, 247, 172, 247, 247, 247, 279, - 174, 174, 15, 236, 279, 279, 279, 279, 279, 279, - 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, - 279, 279, 279, 279, 279, 286, 174, 277, 279, 174, - 174, 174, 157, 189, 180, 154, 155, 155, 155, 155, - 155, 155, 175, 154, 155, 174, 10, 11, 12, 61, - 62, 141, 215, 216, 217, 218, 219, 267, 289, 172, - 232, 198, 156, 156, 158, 201, 10, 13, 167, 203, - 242, 13, 17, 62, 148, 162, 167, 237, 287, 289, - 180, 172, 154, 156, 157, 158, 231, 271, 272, 68, - 69, 154, 279, 13, 17, 62, 119, 148, 162, 167, - 172, 196, 220, 222, 287, 174, 174, 174, 174, 210, - 174, 174, 286, 62, 245, 154, 240, 177, 172, 172, - 172, 238, 239, 230, 230, 190, 238, 238, 238, 174, - 275, 190, 190, 239, 239, 239, 174, 275, 223, 279, - 121, 122, 123, 141, 146, 255, 285, 286, 154, 155, - 190, 174, 164, 164, 276, 164, 286, 174, 164, 174, - 174, 279, 157, 174, 177, 258, 175, 265, 10, 10, - 10, 10, 10, 10, 264, 288, 156, 219, 164, 155, - 15, 286, 13, 17, 62, 148, 162, 167, 172, 238, + 167, 287, 190, 239, 239, 190, 190, 239, 173, 230, + 190, 190, 190, 175, 157, 253, 254, 290, 49, 247, + 247, 247, 172, 247, 172, 247, 247, 247, 280, 174, + 174, 15, 236, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 287, 174, 278, 280, 174, 174, + 174, 157, 189, 180, 154, 155, 155, 155, 155, 155, + 155, 175, 154, 155, 174, 10, 11, 12, 61, 62, + 141, 215, 216, 217, 218, 219, 268, 290, 172, 232, + 198, 156, 156, 158, 201, 10, 13, 167, 203, 242, + 13, 17, 62, 148, 162, 167, 237, 288, 290, 180, + 172, 154, 156, 157, 158, 231, 272, 273, 68, 69, + 154, 280, 13, 17, 62, 119, 148, 162, 167, 172, + 196, 220, 222, 288, 174, 174, 174, 174, 210, 174, + 174, 287, 62, 245, 154, 240, 177, 172, 172, 172, + 238, 239, 230, 230, 190, 238, 238, 238, 174, 276, + 190, 190, 239, 239, 239, 174, 276, 223, 155, 158, + 121, 122, 123, 141, 146, 255, 286, 287, 154, 155, + 190, 174, 164, 164, 277, 164, 287, 174, 164, 174, + 174, 280, 157, 174, 177, 259, 175, 266, 10, 10, + 10, 10, 10, 10, 265, 289, 156, 219, 164, 155, + 15, 287, 13, 17, 62, 148, 162, 167, 172, 238, 239, 199, 222, 247, 225, 174, 167, 220, 225, 237, 167, 190, 237, 237, 190, 190, 172, 173, 190, 175, - 205, 271, 182, 183, 286, 68, 69, 175, 273, 289, - 156, 156, 154, 233, 234, 279, 289, 156, 167, 190, + 205, 272, 182, 183, 287, 68, 69, 175, 274, 290, + 156, 156, 154, 233, 234, 280, 290, 156, 167, 190, 220, 6, 16, 17, 18, 19, 20, 21, 22, 23, 24, 34, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 69, 115, 155, 158, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 172, 173, 176, 211, 220, 190, 190, 220, 157, 172, 173, 223, 158, 230, 232, 190, 190, 15, 174, 245, 241, - 271, 190, 225, 225, 225, 230, 230, 238, 172, 177, - 239, 172, 177, 155, 146, 285, 146, 285, 146, 285, - 286, 121, 122, 123, 15, 180, 255, 172, 172, 174, - 172, 174, 172, 279, 180, 155, 155, 174, 155, 224, - 289, 155, 155, 155, 180, 174, 238, 239, 187, 193, - 212, 213, 218, 286, 158, 167, 190, 190, 190, 158, - 229, 289, 230, 232, 156, 174, 172, 220, 174, 174, - 172, 190, 237, 237, 237, 208, 275, 225, 175, 154, + 272, 190, 225, 225, 225, 230, 230, 238, 172, 177, + 239, 172, 177, 280, 146, 286, 146, 286, 146, 286, + 287, 121, 122, 123, 15, 180, 255, 172, 172, 174, + 172, 174, 172, 280, 180, 155, 155, 174, 155, 224, + 290, 155, 155, 155, 180, 174, 238, 239, 187, 193, + 212, 213, 218, 287, 158, 167, 190, 190, 190, 158, + 229, 290, 230, 232, 156, 174, 172, 220, 174, 174, + 172, 190, 237, 237, 237, 208, 276, 225, 175, 154, 155, 154, 172, 156, 156, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 34, 35, @@ -3126,35 +3129,36 @@ static const yytype_int16 yystos[] = 143, 144, 145, 146, 147, 148, 149, 150, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 176, - 177, 274, 233, 175, 155, 190, 220, 10, 174, 177, - 190, 220, 220, 174, 279, 221, 275, 279, 155, 223, + 177, 275, 233, 175, 155, 190, 220, 10, 174, 177, + 190, 220, 220, 174, 280, 221, 276, 280, 155, 223, 174, 241, 175, 174, 174, 174, 225, 190, 225, 190, - 285, 285, 285, 285, 285, 285, 175, 277, 277, 277, - 277, 175, 10, 10, 156, 10, 174, 10, 10, 10, - 175, 156, 229, 247, 190, 51, 66, 71, 125, 129, - 132, 162, 165, 166, 167, 170, 172, 176, 278, 280, - 155, 210, 202, 174, 172, 210, 209, 237, 225, 177, - 174, 271, 183, 276, 276, 273, 175, 154, 279, 220, - 190, 227, 177, 196, 154, 210, 210, 210, 174, 174, - 174, 174, 174, 174, 174, 155, 174, 155, 156, 155, - 174, 174, 155, 174, 172, 163, 163, 163, 15, 172, - 278, 163, 278, 278, 278, 278, 278, 247, 277, 278, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 34, - 159, 160, 161, 162, 165, 166, 167, 168, 169, 171, - 172, 173, 199, 190, 225, 172, 206, 190, 225, 174, - 190, 210, 175, 175, 174, 175, 233, 174, 190, 271, - 190, 190, 190, 210, 210, 156, 10, 156, 10, 10, - 156, 156, 10, 156, 247, 247, 247, 247, 172, 247, - 247, 174, 174, 278, 278, 278, 278, 278, 278, 278, - 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, - 278, 278, 286, 174, 277, 279, 174, 207, 225, 174, - 210, 190, 15, 175, 210, 175, 223, 223, 223, 190, - 190, 155, 224, 174, 155, 155, 174, 174, 164, 164, - 164, 286, 174, 164, 278, 157, 174, 177, 210, 225, - 174, 210, 190, 10, 174, 156, 10, 10, 156, 172, - 172, 172, 174, 172, 278, 190, 174, 210, 156, 174, - 155, 174, 277, 277, 277, 277, 210, 190, 156, 10, - 156, 174, 174, 174, 174, 190, 223, 174, 223, 156 + 155, 286, 286, 286, 286, 286, 286, 175, 278, 278, + 278, 278, 175, 10, 10, 156, 10, 174, 10, 10, + 10, 175, 156, 229, 247, 190, 51, 66, 71, 125, + 129, 132, 162, 165, 166, 167, 170, 172, 176, 279, + 281, 155, 210, 202, 174, 172, 210, 209, 237, 225, + 177, 174, 272, 183, 277, 277, 274, 175, 154, 280, + 220, 190, 227, 177, 196, 154, 210, 210, 210, 174, + 174, 174, 174, 174, 174, 174, 155, 174, 155, 156, + 155, 174, 174, 155, 174, 172, 163, 163, 163, 15, + 172, 279, 163, 279, 279, 279, 279, 279, 247, 278, + 279, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 34, 159, 160, 161, 162, 165, 166, 167, 168, 169, + 171, 172, 173, 199, 190, 225, 172, 206, 190, 225, + 174, 190, 210, 175, 175, 174, 175, 233, 174, 190, + 272, 190, 190, 190, 210, 210, 156, 10, 156, 10, + 10, 156, 156, 10, 156, 247, 247, 247, 247, 172, + 247, 247, 174, 174, 279, 279, 279, 279, 279, 279, + 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, + 279, 279, 279, 287, 174, 278, 280, 174, 207, 225, + 174, 210, 190, 15, 175, 210, 175, 223, 223, 223, + 190, 190, 155, 224, 174, 155, 155, 174, 174, 164, + 164, 164, 287, 174, 164, 279, 157, 174, 177, 210, + 225, 174, 210, 190, 10, 174, 156, 10, 10, 156, + 172, 172, 172, 174, 172, 279, 190, 174, 210, 156, + 174, 155, 174, 278, 278, 278, 278, 210, 190, 156, + 10, 156, 174, 174, 174, 174, 190, 223, 174, 223, + 156 }; /* YYR1[RULE-NUM] -- Symbol kind of the left-hand side of rule RULE-NUM. */ @@ -3196,49 +3200,49 @@ static const yytype_int16 yyr1[] = 245, 245, 245, 245, 245, 245, 245, 245, 246, 246, 247, 247, 247, 247, 249, 248, 251, 250, 252, 252, 253, 253, 254, 254, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 256, 257, 257, 257, 257, 258, - 258, 259, 259, 259, 260, 260, 260, 261, 261, 261, - 262, 262, 262, 264, 263, 265, 263, 263, 263, 266, - 266, 266, 266, 267, 267, 267, 268, 268, 268, 268, - 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - 268, 269, 269, 269, 270, 272, 271, 273, 273, 274, - 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, - 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, - 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, - 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, - 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, - 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, - 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, - 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, - 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, - 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, - 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, - 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, - 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, - 274, 274, 274, 274, 274, 275, 275, 276, 276, 277, - 277, 278, 278, 278, 278, 278, 278, 278, 278, 278, - 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, - 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, - 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, - 278, 279, 279, 279, 279, 279, 279, 279, 279, 279, + 255, 255, 255, 255, 257, 256, 258, 258, 258, 258, + 259, 259, 260, 260, 260, 261, 261, 261, 262, 262, + 262, 263, 263, 263, 265, 264, 266, 264, 264, 264, + 267, 267, 267, 267, 268, 268, 268, 269, 269, 269, + 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, + 269, 269, 270, 270, 270, 271, 273, 272, 274, 274, + 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, + 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, + 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, + 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, + 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, + 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, + 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, + 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, + 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, + 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, + 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, + 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, + 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, + 275, 275, 275, 275, 275, 275, 276, 276, 277, 277, + 278, 278, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, - 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, - 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, - 279, 279, 279, 280, 280, 280, 280, 280, 280, 280, + 279, 279, 280, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, - 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, - 281, 281, 281, 281, 281, 281, 281, 281, 281, 282, + 281, 281, 281, 281, 281, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 283, 283, 283, 283, 283, 284, 284, 284, 284, 285, - 285, 285, 286, 286, 286, 286, 286, 286, 286, 286, - 286, 286, 286, 287, 287, 287, 287, 288, 288, 288, - 288, 289 + 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, + 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, + 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, + 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, + 283, 284, 284, 284, 284, 284, 285, 285, 285, 285, + 286, 286, 286, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 288, 288, 288, 288, 289, 289, + 289, 289, 290 }; /* YYR2[RULE-NUM] -- Number of symbols on the right-hand side of rule RULE-NUM. */ @@ -3280,12 +3284,12 @@ static const yytype_int8 yyr2[] = 1, 1, 2, 3, 3, 4, 4, 1, 1, 1, 2, 3, 2, 3, 0, 6, 0, 9, 1, 1, 1, 1, 2, 3, 1, 2, 2, 2, 3, 3, - 3, 3, 3, 3, 4, 4, 2, 5, 3, 1, - 1, 1, 4, 6, 1, 3, 5, 1, 2, 2, - 1, 1, 1, 0, 7, 0, 7, 4, 5, 3, - 6, 4, 4, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, - 2, 1, 1, 2, 1, 0, 2, 1, 2, 1, + 3, 3, 3, 3, 0, 5, 4, 2, 5, 3, + 1, 1, 1, 4, 6, 1, 3, 5, 1, 2, + 2, 1, 1, 1, 0, 7, 0, 7, 4, 5, + 3, 6, 4, 4, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, + 2, 2, 1, 1, 2, 1, 0, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -3299,30 +3303,30 @@ static const yytype_int8 yyr2[] = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, - 3, 1, 4, 7, 7, 7, 7, 4, 2, 5, - 4, 2, 2, 2, 2, 2, 2, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 5, 4, 4, 3, 3, 3, - 3, 1, 4, 7, 7, 7, 7, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 2, 5, 4, 2, 5, 4, 4, - 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, + 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, + 1, 3, 1, 4, 7, 7, 7, 7, 4, 2, + 5, 4, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 4, 4, 3, 3, - 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 9, 12, 4, 4, 6, 4, - 4, 6, 6, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 1, 4, 7, 7, 7, 7, - 4, 2, 5, 4, 2, 5, 4, 4, 2, 2, - 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 1, 4, 7, 7, 7, 7, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 2, 5, 4, 2, 5, 4, + 4, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 5, 4, 4, 3, 3, 3, 3, 1, + 3, 3, 3, 3, 3, 3, 5, 4, 4, 3, + 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 9, 12, 4, 4, 6, + 4, 4, 6, 6, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 1, 4, 7, 7, 7, + 7, 4, 2, 5, 4, 2, 5, 4, 4, 2, + 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 5, 4, 4, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 2, 4, 2, 3, 1, 2, 1, - 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, - 2, 0 + 1, 1, 1, 1, 2, 4, 2, 3, 1, 2, + 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 0 }; @@ -3911,7 +3915,7 @@ yyreduce: { current_expr = (yyvsp[0].u.expr); } -#line 3915 "built/tmp/cppBison.yxx.c" +#line 3919 "built/tmp/cppBison.yxx.c" break; case 4: /* grammar: START_TYPE full_type */ @@ -3919,7 +3923,7 @@ yyreduce: { current_type = (yyvsp[0].u.type); } -#line 3923 "built/tmp/cppBison.yxx.c" +#line 3927 "built/tmp/cppBison.yxx.c" break; case 6: /* cpp: cpp optional_attributes ';' */ @@ -3929,7 +3933,7 @@ yyreduce: current_scope->add_declaration(new CPPDeclaration((yylsp[-1]).file, (yyvsp[-1].attr_list)), global_scope, current_lexer, (yylsp[-1])); } } -#line 3933 "built/tmp/cppBison.yxx.c" +#line 3937 "built/tmp/cppBison.yxx.c" break; case 7: /* $@1: %empty */ @@ -3937,7 +3941,7 @@ yyreduce: { current_attributes = (yyvsp[0].attr_list); } -#line 3941 "built/tmp/cppBison.yxx.c" +#line 3945 "built/tmp/cppBison.yxx.c" break; case 8: /* cpp: cpp optional_attributes $@1 declaration */ @@ -3945,7 +3949,7 @@ yyreduce: { current_attributes = CPPAttributeList(); } -#line 3949 "built/tmp/cppBison.yxx.c" +#line 3953 "built/tmp/cppBison.yxx.c" break; case 11: /* constructor_init: name '(' optional_const_expr_comma ')' */ @@ -3953,7 +3957,7 @@ yyreduce: { delete (yyvsp[-1].u.expr); } -#line 3957 "built/tmp/cppBison.yxx.c" +#line 3961 "built/tmp/cppBison.yxx.c" break; case 12: /* constructor_init: name '(' optional_const_expr_comma ')' ELLIPSIS */ @@ -3961,7 +3965,7 @@ yyreduce: { delete (yyvsp[-2].u.expr); } -#line 3965 "built/tmp/cppBison.yxx.c" +#line 3969 "built/tmp/cppBison.yxx.c" break; case 13: /* constructor_init: name '{' optional_const_expr_comma '}' */ @@ -3969,7 +3973,7 @@ yyreduce: { delete (yyvsp[-1].u.expr); } -#line 3973 "built/tmp/cppBison.yxx.c" +#line 3977 "built/tmp/cppBison.yxx.c" break; case 14: /* $@2: %empty */ @@ -3978,7 +3982,7 @@ yyreduce: push_storage_class((current_storage_class & ~CPPInstance::SC_c_binding) | ((yyvsp[-1].u.integer) & CPPInstance::SC_c_binding)); } -#line 3982 "built/tmp/cppBison.yxx.c" +#line 3986 "built/tmp/cppBison.yxx.c" break; case 15: /* extern_c: storage_class '{' $@2 cpp '}' */ @@ -3986,7 +3990,7 @@ yyreduce: { pop_storage_class(); } -#line 3990 "built/tmp/cppBison.yxx.c" +#line 3994 "built/tmp/cppBison.yxx.c" break; case 22: /* declaration: KW_BEGIN_PUBLISH */ @@ -4003,7 +4007,7 @@ yyreduce: publish_nest_level++; current_scope->set_current_vis(V_published); } -#line 4007 "built/tmp/cppBison.yxx.c" +#line 4011 "built/tmp/cppBison.yxx.c" break; case 23: /* declaration: KW_END_PUBLISH */ @@ -4016,7 +4020,7 @@ yyreduce: } publish_nest_level = 0; } -#line 4020 "built/tmp/cppBison.yxx.c" +#line 4024 "built/tmp/cppBison.yxx.c" break; case 24: /* declaration: KW_PUBLISHED ':' */ @@ -4024,7 +4028,7 @@ yyreduce: { current_scope->set_current_vis(V_published); } -#line 4028 "built/tmp/cppBison.yxx.c" +#line 4032 "built/tmp/cppBison.yxx.c" break; case 25: /* declaration: KW_PUBLIC ':' */ @@ -4036,7 +4040,7 @@ yyreduce: current_scope->set_current_vis(V_public); } } -#line 4040 "built/tmp/cppBison.yxx.c" +#line 4044 "built/tmp/cppBison.yxx.c" break; case 26: /* declaration: KW_PROTECTED ':' */ @@ -4044,7 +4048,7 @@ yyreduce: { current_scope->set_current_vis(V_protected); } -#line 4048 "built/tmp/cppBison.yxx.c" +#line 4052 "built/tmp/cppBison.yxx.c" break; case 27: /* declaration: KW_PRIVATE ':' */ @@ -4052,7 +4056,7 @@ yyreduce: { current_scope->set_current_vis(V_private); } -#line 4056 "built/tmp/cppBison.yxx.c" +#line 4060 "built/tmp/cppBison.yxx.c" break; case 28: /* declaration: KW_MAKE_PROPERTY '(' name ',' IDENTIFIER maybe_comma_identifier ')' ';' */ @@ -4077,7 +4081,7 @@ yyreduce: current_scope->add_declaration(make_property, global_scope, current_lexer, (yylsp[-7])); } } -#line 4081 "built/tmp/cppBison.yxx.c" +#line 4085 "built/tmp/cppBison.yxx.c" break; case 29: /* declaration: KW_MAKE_PROPERTY '(' name ',' IDENTIFIER ',' IDENTIFIER ',' IDENTIFIER ')' ';' */ @@ -4108,7 +4112,7 @@ yyreduce: current_scope->add_declaration(make_property, global_scope, current_lexer, (yylsp[-10])); } } -#line 4112 "built/tmp/cppBison.yxx.c" +#line 4116 "built/tmp/cppBison.yxx.c" break; case 30: /* declaration: KW_MAKE_SEQ_PROPERTY '(' name ',' IDENTIFIER ',' IDENTIFIER ')' ';' */ @@ -4133,7 +4137,7 @@ yyreduce: current_scope->add_declaration(make_property, global_scope, current_lexer, (yylsp[-8])); } } -#line 4137 "built/tmp/cppBison.yxx.c" +#line 4141 "built/tmp/cppBison.yxx.c" break; case 31: /* declaration: KW_MAKE_SEQ_PROPERTY '(' name ',' IDENTIFIER ',' IDENTIFIER ',' IDENTIFIER ')' ';' */ @@ -4166,7 +4170,7 @@ yyreduce: current_scope->add_declaration(make_property, global_scope, current_lexer, (yylsp[-10])); } } -#line 4170 "built/tmp/cppBison.yxx.c" +#line 4174 "built/tmp/cppBison.yxx.c" break; case 32: /* declaration: KW_MAKE_SEQ_PROPERTY '(' name ',' IDENTIFIER ',' IDENTIFIER ',' IDENTIFIER ',' IDENTIFIER ')' ';' */ @@ -4206,7 +4210,7 @@ yyreduce: current_scope->add_declaration(make_property, global_scope, current_lexer, (yylsp[-12])); } } -#line 4210 "built/tmp/cppBison.yxx.c" +#line 4214 "built/tmp/cppBison.yxx.c" break; case 33: /* declaration: KW_MAKE_SEQ_PROPERTY '(' name ',' IDENTIFIER ',' IDENTIFIER ',' IDENTIFIER ',' IDENTIFIER ',' IDENTIFIER ')' ';' */ @@ -4253,7 +4257,7 @@ yyreduce: current_scope->add_declaration(make_property, global_scope, current_lexer, (yylsp[-14])); } } -#line 4257 "built/tmp/cppBison.yxx.c" +#line 4261 "built/tmp/cppBison.yxx.c" break; case 34: /* declaration: KW_MAKE_MAP_PROPERTY '(' name ',' IDENTIFIER ')' ';' */ @@ -4269,7 +4273,7 @@ yyreduce: current_scope->add_declaration(make_property, global_scope, current_lexer, (yylsp[-6])); } } -#line 4273 "built/tmp/cppBison.yxx.c" +#line 4277 "built/tmp/cppBison.yxx.c" break; case 35: /* declaration: KW_MAKE_MAP_PROPERTY '(' name ',' IDENTIFIER ',' IDENTIFIER ')' ';' */ @@ -4294,7 +4298,7 @@ yyreduce: current_scope->add_declaration(make_property, global_scope, current_lexer, (yylsp[-8])); } } -#line 4298 "built/tmp/cppBison.yxx.c" +#line 4302 "built/tmp/cppBison.yxx.c" break; case 36: /* declaration: KW_MAKE_MAP_PROPERTY '(' name ',' IDENTIFIER ',' IDENTIFIER ',' IDENTIFIER maybe_comma_identifier ')' ';' */ @@ -4334,7 +4338,7 @@ yyreduce: current_scope->add_declaration(make_property, global_scope, current_lexer, (yylsp[-11])); } } -#line 4338 "built/tmp/cppBison.yxx.c" +#line 4342 "built/tmp/cppBison.yxx.c" break; case 37: /* declaration: KW_MAKE_MAP_KEYS_SEQ '(' name ',' IDENTIFIER ',' IDENTIFIER ')' ';' */ @@ -4372,7 +4376,7 @@ yyreduce: } } } -#line 4376 "built/tmp/cppBison.yxx.c" +#line 4380 "built/tmp/cppBison.yxx.c" break; case 38: /* declaration: KW_MAKE_PROPERTY2 '(' name ',' IDENTIFIER ',' IDENTIFIER ')' ';' */ @@ -4398,7 +4402,7 @@ yyreduce: current_scope->add_declaration(make_property, global_scope, current_lexer, (yylsp[-8])); } } -#line 4402 "built/tmp/cppBison.yxx.c" +#line 4406 "built/tmp/cppBison.yxx.c" break; case 39: /* declaration: KW_MAKE_PROPERTY2 '(' name ',' IDENTIFIER ',' IDENTIFIER ',' IDENTIFIER ',' IDENTIFIER ')' ';' */ @@ -4438,7 +4442,7 @@ yyreduce: current_scope->add_declaration(make_property, global_scope, current_lexer, (yylsp[-12])); } } -#line 4442 "built/tmp/cppBison.yxx.c" +#line 4446 "built/tmp/cppBison.yxx.c" break; case 40: /* declaration: KW_MAKE_SEQ '(' name ',' IDENTIFIER ',' IDENTIFIER ')' ';' */ @@ -4464,7 +4468,7 @@ yyreduce: current_scope->add_declaration(make_seq, global_scope, current_lexer, (yylsp[-8])); } } -#line 4468 "built/tmp/cppBison.yxx.c" +#line 4472 "built/tmp/cppBison.yxx.c" break; case 41: /* declaration: KW_STATIC_ASSERT '(' const_expr ',' string_literal ')' ';' */ @@ -4479,7 +4483,7 @@ yyreduce: yywarning("static_assert failed: " + str.str(), (yylsp[-4])); } } -#line 4483 "built/tmp/cppBison.yxx.c" +#line 4487 "built/tmp/cppBison.yxx.c" break; case 42: /* declaration: KW_STATIC_ASSERT '(' const_expr ')' ';' */ @@ -4493,7 +4497,7 @@ yyreduce: yywarning("static_assert failed", (yylsp[-2])); } } -#line 4497 "built/tmp/cppBison.yxx.c" +#line 4501 "built/tmp/cppBison.yxx.c" break; case 43: /* $@3: %empty */ @@ -4503,7 +4507,7 @@ yyreduce: V_public); push_scope(new_scope); } -#line 4507 "built/tmp/cppBison.yxx.c" +#line 4511 "built/tmp/cppBison.yxx.c" break; case 44: /* friend_declaration: KW_FRIEND $@3 declaration */ @@ -4512,7 +4516,7 @@ yyreduce: delete current_scope; pop_scope(); } -#line 4516 "built/tmp/cppBison.yxx.c" +#line 4520 "built/tmp/cppBison.yxx.c" break; case 45: /* storage_class: empty */ @@ -4520,7 +4524,7 @@ yyreduce: { (yyval.u.integer) = 0; } -#line 4524 "built/tmp/cppBison.yxx.c" +#line 4528 "built/tmp/cppBison.yxx.c" break; case 46: /* storage_class: KW_CONST storage_class */ @@ -4529,7 +4533,7 @@ yyreduce: // This isn't really a storage class, but it helps with parsing. (yyval.u.integer) = (yyvsp[0].u.integer) | (int)CPPInstance::SC_const; } -#line 4533 "built/tmp/cppBison.yxx.c" +#line 4537 "built/tmp/cppBison.yxx.c" break; case 47: /* storage_class: KW_EXTERN storage_class */ @@ -4537,7 +4541,7 @@ yyreduce: { (yyval.u.integer) = (yyvsp[0].u.integer) | (int)CPPInstance::SC_extern; } -#line 4541 "built/tmp/cppBison.yxx.c" +#line 4545 "built/tmp/cppBison.yxx.c" break; case 48: /* storage_class: KW_EXTERN SIMPLE_STRING storage_class */ @@ -4552,7 +4556,7 @@ yyreduce: yywarning("Ignoring unknown linkage type \"" + (yyvsp[-1].str) + "\"", (yylsp[-1])); } } -#line 4556 "built/tmp/cppBison.yxx.c" +#line 4560 "built/tmp/cppBison.yxx.c" break; case 49: /* storage_class: KW_STATIC storage_class */ @@ -4560,7 +4564,7 @@ yyreduce: { (yyval.u.integer) = (yyvsp[0].u.integer) | (int)CPPInstance::SC_static; } -#line 4564 "built/tmp/cppBison.yxx.c" +#line 4568 "built/tmp/cppBison.yxx.c" break; case 50: /* storage_class: KW_INLINE storage_class */ @@ -4568,7 +4572,7 @@ yyreduce: { (yyval.u.integer) = (yyvsp[0].u.integer) | (int)CPPInstance::SC_inline; } -#line 4572 "built/tmp/cppBison.yxx.c" +#line 4576 "built/tmp/cppBison.yxx.c" break; case 51: /* storage_class: KW_VIRTUAL storage_class */ @@ -4576,7 +4580,7 @@ yyreduce: { (yyval.u.integer) = (yyvsp[0].u.integer) | (int)CPPInstance::SC_virtual; } -#line 4580 "built/tmp/cppBison.yxx.c" +#line 4584 "built/tmp/cppBison.yxx.c" break; case 52: /* storage_class: KW_EXPLICIT storage_class */ @@ -4584,7 +4588,7 @@ yyreduce: { (yyval.u.integer) = (yyvsp[0].u.integer) | (int)CPPInstance::SC_explicit; } -#line 4588 "built/tmp/cppBison.yxx.c" +#line 4592 "built/tmp/cppBison.yxx.c" break; case 53: /* storage_class: KW_EXPLICIT_LPAREN const_expr ')' storage_class */ @@ -4597,7 +4601,7 @@ yyreduce: (yyval.u.integer) = (yyvsp[0].u.integer) | (int)CPPInstance::SC_explicit; } } -#line 4601 "built/tmp/cppBison.yxx.c" +#line 4605 "built/tmp/cppBison.yxx.c" break; case 54: /* storage_class: KW_REGISTER storage_class */ @@ -4605,7 +4609,7 @@ yyreduce: { (yyval.u.integer) = (yyvsp[0].u.integer) | (int)CPPInstance::SC_register; } -#line 4609 "built/tmp/cppBison.yxx.c" +#line 4613 "built/tmp/cppBison.yxx.c" break; case 55: /* storage_class: KW_VOLATILE storage_class */ @@ -4613,7 +4617,7 @@ yyreduce: { (yyval.u.integer) = (yyvsp[0].u.integer) | (int)CPPInstance::SC_volatile; } -#line 4617 "built/tmp/cppBison.yxx.c" +#line 4621 "built/tmp/cppBison.yxx.c" break; case 56: /* storage_class: KW_MUTABLE storage_class */ @@ -4621,7 +4625,7 @@ yyreduce: { (yyval.u.integer) = (yyvsp[0].u.integer) | (int)CPPInstance::SC_mutable; } -#line 4625 "built/tmp/cppBison.yxx.c" +#line 4629 "built/tmp/cppBison.yxx.c" break; case 57: /* storage_class: KW_CONSTEVAL storage_class */ @@ -4629,7 +4633,7 @@ yyreduce: { (yyval.u.integer) = (yyvsp[0].u.integer) | (int)CPPInstance::SC_consteval; } -#line 4633 "built/tmp/cppBison.yxx.c" +#line 4637 "built/tmp/cppBison.yxx.c" break; case 58: /* storage_class: KW_CONSTEXPR storage_class */ @@ -4637,7 +4641,7 @@ yyreduce: { (yyval.u.integer) = (yyvsp[0].u.integer) | (int)CPPInstance::SC_constexpr; } -#line 4641 "built/tmp/cppBison.yxx.c" +#line 4645 "built/tmp/cppBison.yxx.c" break; case 59: /* storage_class: KW_CONSTINIT storage_class */ @@ -4645,7 +4649,7 @@ yyreduce: { (yyval.u.integer) = (yyvsp[0].u.integer) | (int)CPPInstance::SC_constinit; } -#line 4649 "built/tmp/cppBison.yxx.c" +#line 4653 "built/tmp/cppBison.yxx.c" break; case 60: /* storage_class: KW_BLOCKING storage_class */ @@ -4653,7 +4657,7 @@ yyreduce: { (yyval.u.integer) = (yyvsp[0].u.integer) | (int)CPPInstance::SC_blocking; } -#line 4657 "built/tmp/cppBison.yxx.c" +#line 4661 "built/tmp/cppBison.yxx.c" break; case 61: /* storage_class: KW_EXTENSION storage_class */ @@ -4661,7 +4665,7 @@ yyreduce: { (yyval.u.integer) = (yyvsp[0].u.integer) | (int)CPPInstance::SC_extension; } -#line 4665 "built/tmp/cppBison.yxx.c" +#line 4669 "built/tmp/cppBison.yxx.c" break; case 62: /* storage_class: KW_THREAD_LOCAL storage_class */ @@ -4669,7 +4673,7 @@ yyreduce: { (yyval.u.integer) = (yyvsp[0].u.integer) | (int)CPPInstance::SC_thread_local; } -#line 4673 "built/tmp/cppBison.yxx.c" +#line 4677 "built/tmp/cppBison.yxx.c" break; case 63: /* optional_attributes: empty */ @@ -4677,7 +4681,7 @@ yyreduce: { (yyval.attr_list) = CPPAttributeList(); } -#line 4681 "built/tmp/cppBison.yxx.c" +#line 4685 "built/tmp/cppBison.yxx.c" break; case 64: /* optional_attributes: ATTR_LEFT attribute_specifiers ATTR_RIGHT optional_attributes */ @@ -4686,7 +4690,7 @@ yyreduce: (yyval.attr_list) = (yyvsp[-2].attr_list); (yyval.attr_list).add_attributes_from((yyvsp[0].attr_list)); } -#line 4690 "built/tmp/cppBison.yxx.c" +#line 4694 "built/tmp/cppBison.yxx.c" break; case 65: /* optional_attributes: ATTR_LEFT KW_USING name ':' attribute_specifiers ATTR_RIGHT optional_attributes */ @@ -4698,7 +4702,7 @@ yyreduce: } (yyval.attr_list).add_attributes_from((yyvsp[0].attr_list)); } -#line 4702 "built/tmp/cppBison.yxx.c" +#line 4706 "built/tmp/cppBison.yxx.c" break; case 66: /* optional_attributes: KW_ALIGNAS '(' const_expr ')' optional_attributes */ @@ -4707,7 +4711,7 @@ yyreduce: (yyval.attr_list) = (yyvsp[0].attr_list); (yyval.attr_list).add_alignas((yyvsp[-2].u.expr)->as_expression()); } -#line 4711 "built/tmp/cppBison.yxx.c" +#line 4715 "built/tmp/cppBison.yxx.c" break; case 67: /* optional_attributes: KW_ALIGNAS '(' type_decl ')' optional_attributes */ @@ -4716,7 +4720,7 @@ yyreduce: (yyval.attr_list) = (yyvsp[0].attr_list); (yyval.attr_list).add_alignas((yyvsp[-2].u.decl)->as_type()); } -#line 4720 "built/tmp/cppBison.yxx.c" +#line 4724 "built/tmp/cppBison.yxx.c" break; case 68: /* attribute_specifiers: attribute_specifier */ @@ -4724,7 +4728,7 @@ yyreduce: { (yyval.attr_list) = (yyvsp[0].attr_list); } -#line 4728 "built/tmp/cppBison.yxx.c" +#line 4732 "built/tmp/cppBison.yxx.c" break; case 69: /* attribute_specifiers: attribute_specifier ',' attribute_specifiers */ @@ -4733,7 +4737,7 @@ yyreduce: (yyval.attr_list) = (yyvsp[-2].attr_list); (yyval.attr_list).add_attributes_from((yyvsp[0].attr_list)); } -#line 4737 "built/tmp/cppBison.yxx.c" +#line 4741 "built/tmp/cppBison.yxx.c" break; case 70: /* attribute_specifier: name */ @@ -4742,7 +4746,7 @@ yyreduce: (yyval.attr_list) = CPPAttributeList(); (yyval.attr_list).add_attribute((yyvsp[0].u.identifier)); } -#line 4746 "built/tmp/cppBison.yxx.c" +#line 4750 "built/tmp/cppBison.yxx.c" break; case 71: /* attribute_specifier: name '(' formal_parameter_list ')' */ @@ -4751,7 +4755,7 @@ yyreduce: (yyval.attr_list) = CPPAttributeList(); (yyval.attr_list).add_attribute((yyvsp[-3].u.identifier)); } -#line 4755 "built/tmp/cppBison.yxx.c" +#line 4759 "built/tmp/cppBison.yxx.c" break; case 72: /* $@4: %empty */ @@ -4766,7 +4770,7 @@ yyreduce: } push_storage_class((yyvsp[-1].u.integer)); } -#line 4770 "built/tmp/cppBison.yxx.c" +#line 4774 "built/tmp/cppBison.yxx.c" break; case 73: /* type_like_declaration: storage_class var_type_decl $@4 multiple_instance_identifiers */ @@ -4774,7 +4778,7 @@ yyreduce: { pop_storage_class(); } -#line 4778 "built/tmp/cppBison.yxx.c" +#line 4782 "built/tmp/cppBison.yxx.c" break; case 74: /* type_like_declaration: storage_class type_decl ';' */ @@ -4787,7 +4791,7 @@ yyreduce: current_scope->add_declaration((yyvsp[-1].u.decl), global_scope, current_lexer, (yylsp[-1])); } -#line 4791 "built/tmp/cppBison.yxx.c" +#line 4795 "built/tmp/cppBison.yxx.c" break; case 75: /* $@5: %empty */ @@ -4800,7 +4804,7 @@ yyreduce: (yyvsp[0].u.instance)->_storage_class |= (current_storage_class | (yyvsp[-1].u.integer)); } } -#line 4804 "built/tmp/cppBison.yxx.c" +#line 4808 "built/tmp/cppBison.yxx.c" break; case 76: /* type_like_declaration: storage_class constructor_prototype $@5 maybe_initialize_or_constructor_body */ @@ -4812,7 +4816,7 @@ yyreduce: (yyvsp[-2].u.instance)->set_initializer((yyvsp[0].u.expr)); } } -#line 4816 "built/tmp/cppBison.yxx.c" +#line 4820 "built/tmp/cppBison.yxx.c" break; case 77: /* type_like_declaration: storage_class function_prototype maybe_initialize_or_function_body */ @@ -4824,7 +4828,7 @@ yyreduce: (yyvsp[-1].u.instance)->set_initializer((yyvsp[0].u.expr)); } } -#line 4828 "built/tmp/cppBison.yxx.c" +#line 4832 "built/tmp/cppBison.yxx.c" break; case 79: /* multiple_instance_identifiers: instance_identifier_and_maybe_trailing_return_type maybe_initialize_or_function_body */ @@ -4840,7 +4844,7 @@ yyreduce: inst->set_initializer((yyvsp[0].u.expr)); current_scope->add_declaration(inst, global_scope, current_lexer, (yylsp[-1])); } -#line 4844 "built/tmp/cppBison.yxx.c" +#line 4848 "built/tmp/cppBison.yxx.c" break; case 80: /* multiple_instance_identifiers: instance_identifier_and_maybe_trailing_return_type maybe_initialize ',' multiple_instance_identifiers */ @@ -4856,7 +4860,7 @@ yyreduce: inst->set_initializer((yyvsp[-2].u.expr)); current_scope->add_declaration(inst, global_scope, current_lexer, (yylsp[-3])); } -#line 4860 "built/tmp/cppBison.yxx.c" +#line 4864 "built/tmp/cppBison.yxx.c" break; case 81: /* $@6: %empty */ @@ -4871,7 +4875,7 @@ yyreduce: } push_storage_class((yyvsp[-1].u.integer)); } -#line 4875 "built/tmp/cppBison.yxx.c" +#line 4879 "built/tmp/cppBison.yxx.c" break; case 82: /* typedef_declaration: storage_class var_type_decl $@6 typedef_instance_identifiers */ @@ -4879,7 +4883,7 @@ yyreduce: { pop_storage_class(); } -#line 4883 "built/tmp/cppBison.yxx.c" +#line 4887 "built/tmp/cppBison.yxx.c" break; case 83: /* typedef_declaration: storage_class function_prototype maybe_initialize_or_function_body */ @@ -4895,7 +4899,7 @@ yyreduce: } } } -#line 4899 "built/tmp/cppBison.yxx.c" +#line 4903 "built/tmp/cppBison.yxx.c" break; case 84: /* typedef_instance_identifiers: instance_identifier_and_maybe_trailing_return_type maybe_initialize_or_function_body */ @@ -4909,7 +4913,7 @@ yyreduce: CPPTypedefType *typedef_type = new CPPTypedefType(target_type, (yyvsp[-1].u.inst_ident), current_scope, (yylsp[-1]).file); current_scope->add_declaration(CPPType::new_type(typedef_type), global_scope, current_lexer, (yylsp[-1])); } -#line 4913 "built/tmp/cppBison.yxx.c" +#line 4917 "built/tmp/cppBison.yxx.c" break; case 85: /* typedef_instance_identifiers: instance_identifier_and_maybe_trailing_return_type maybe_initialize ',' typedef_instance_identifiers */ @@ -4923,7 +4927,7 @@ yyreduce: CPPTypedefType *typedef_type = new CPPTypedefType(target_type, (yyvsp[-3].u.inst_ident), current_scope, (yylsp[-3]).file); current_scope->add_declaration(CPPType::new_type(typedef_type), global_scope, current_lexer, (yylsp[-3])); } -#line 4927 "built/tmp/cppBison.yxx.c" +#line 4931 "built/tmp/cppBison.yxx.c" break; case 86: /* $@7: %empty */ @@ -4940,7 +4944,7 @@ yyreduce: push_scope(scope); } -#line 4944 "built/tmp/cppBison.yxx.c" +#line 4948 "built/tmp/cppBison.yxx.c" break; case 87: /* constructor_prototype: IDENTIFIER '(' $@7 function_parameter_list ')' function_post optional_attributes */ @@ -4971,7 +4975,7 @@ yyreduce: (yyval.u.instance) = new CPPInstance(type, ii, 0, (yylsp[-6]).file); } -#line 4975 "built/tmp/cppBison.yxx.c" +#line 4979 "built/tmp/cppBison.yxx.c" break; case 88: /* $@8: %empty */ @@ -4988,7 +4992,7 @@ yyreduce: push_scope(scope); } -#line 4992 "built/tmp/cppBison.yxx.c" +#line 4996 "built/tmp/cppBison.yxx.c" break; case 89: /* constructor_prototype: TYPENAME_IDENTIFIER '(' IDENTIFIER ')' '(' $@8 function_parameter_list ')' function_post optional_attributes */ @@ -5007,7 +5011,7 @@ yyreduce: (yyval.u.instance) = new CPPInstance(type, ii, 0, (yylsp[-9]).file); } -#line 5011 "built/tmp/cppBison.yxx.c" +#line 5015 "built/tmp/cppBison.yxx.c" break; case 90: /* $@9: %empty */ @@ -5024,7 +5028,7 @@ yyreduce: push_scope(scope); } -#line 5028 "built/tmp/cppBison.yxx.c" +#line 5032 "built/tmp/cppBison.yxx.c" break; case 91: /* constructor_prototype: TYPENAME_IDENTIFIER '(' $@9 function_parameter_list ')' function_post optional_attributes */ @@ -5047,7 +5051,7 @@ yyreduce: (yyval.u.instance) = new CPPInstance(type, ii, 0, (yylsp[-6]).file); } -#line 5051 "built/tmp/cppBison.yxx.c" +#line 5055 "built/tmp/cppBison.yxx.c" break; case 92: /* $@10: %empty */ @@ -5055,7 +5059,7 @@ yyreduce: { push_scope((yyvsp[-1].u.identifier)->get_scope(current_scope, global_scope)); } -#line 5059 "built/tmp/cppBison.yxx.c" +#line 5063 "built/tmp/cppBison.yxx.c" break; case 93: /* function_prototype: '~' name '(' $@10 function_parameter_list ')' function_post optional_attributes */ @@ -5079,7 +5083,7 @@ yyreduce: (yyval.u.instance) = new CPPInstance(type, ii, 0, (yylsp[-6]).file); } } -#line 5083 "built/tmp/cppBison.yxx.c" +#line 5087 "built/tmp/cppBison.yxx.c" break; case 94: /* $@11: %empty */ @@ -5087,7 +5091,7 @@ yyreduce: { push_scope((yyvsp[-2].u.inst_ident)->get_scope(current_scope, global_scope)); } -#line 5091 "built/tmp/cppBison.yxx.c" +#line 5095 "built/tmp/cppBison.yxx.c" break; case 95: /* function_prototype: TYPENAME_IDENTIFIER '(' '*' instance_identifier ')' '(' $@11 function_parameter_list ')' function_post optional_attributes maybe_trailing_return_type */ @@ -5106,7 +5110,7 @@ yyreduce: ii->add_attributes(current_attributes); (yyval.u.instance) = new CPPInstance(type, ii, 0, (yylsp[-11]).file); } -#line 5110 "built/tmp/cppBison.yxx.c" +#line 5114 "built/tmp/cppBison.yxx.c" break; case 96: /* $@12: %empty */ @@ -5114,7 +5118,7 @@ yyreduce: { push_scope((yyvsp[-2].u.inst_ident)->get_scope(current_scope, global_scope)); } -#line 5118 "built/tmp/cppBison.yxx.c" +#line 5122 "built/tmp/cppBison.yxx.c" break; case 97: /* function_prototype: TYPENAME_IDENTIFIER '(' SCOPING '*' instance_identifier ')' '(' $@12 function_parameter_list ')' function_post optional_attributes maybe_trailing_return_type */ @@ -5133,7 +5137,7 @@ yyreduce: ii->add_attributes(current_attributes); (yyval.u.instance) = new CPPInstance(type, ii, 0, (yylsp[-12]).file); } -#line 5137 "built/tmp/cppBison.yxx.c" +#line 5141 "built/tmp/cppBison.yxx.c" break; case 98: /* $@13: %empty */ @@ -5143,7 +5147,7 @@ yyreduce: push_scope((yyvsp[-3].u.identifier)->get_scope(current_scope, global_scope)); } } -#line 5147 "built/tmp/cppBison.yxx.c" +#line 5151 "built/tmp/cppBison.yxx.c" break; case 99: /* function_prototype: KW_OPERATOR type not_paren_formal_parameter_identifier '(' $@13 function_parameter_list ')' function_post */ @@ -5173,7 +5177,7 @@ yyreduce: (new CPPInstance((yyvsp[-6].u.type), (yyvsp[-5].u.inst_ident), 0, (yylsp[-5]).file), ident, (yyvsp[-2].u.param_list), (yyvsp[0].u.integer)); (yyval.u.instance)->_attributes.add_attributes_from(current_attributes); } -#line 5177 "built/tmp/cppBison.yxx.c" +#line 5181 "built/tmp/cppBison.yxx.c" break; case 100: /* $@14: %empty */ @@ -5183,7 +5187,7 @@ yyreduce: push_scope((yyvsp[-4].u.identifier)->get_scope(current_scope, global_scope)); } } -#line 5187 "built/tmp/cppBison.yxx.c" +#line 5191 "built/tmp/cppBison.yxx.c" break; case 101: /* function_prototype: KW_OPERATOR KW_CONST type not_paren_formal_parameter_identifier '(' $@14 function_parameter_list ')' function_post */ @@ -5204,7 +5208,7 @@ yyreduce: (yyval.u.instance) = CPPInstance::make_typecast_function (new CPPInstance((yyvsp[-6].u.type), (yyvsp[-5].u.inst_ident), 0, (yylsp[-5]).file), ident, (yyvsp[-2].u.param_list), (yyvsp[0].u.integer)); } -#line 5208 "built/tmp/cppBison.yxx.c" +#line 5212 "built/tmp/cppBison.yxx.c" break; case 102: /* function_prototype: IDENTIFIER */ @@ -5218,7 +5222,7 @@ yyreduce: (yyval.u.instance) = nullptr; } } -#line 5222 "built/tmp/cppBison.yxx.c" +#line 5226 "built/tmp/cppBison.yxx.c" break; case 103: /* function_post: empty */ @@ -5226,7 +5230,7 @@ yyreduce: { (yyval.u.integer) = 0; } -#line 5230 "built/tmp/cppBison.yxx.c" +#line 5234 "built/tmp/cppBison.yxx.c" break; case 104: /* function_post: function_post KW_CONST */ @@ -5234,7 +5238,7 @@ yyreduce: { (yyval.u.integer) = (yyvsp[-1].u.integer) | (int)CPPFunctionType::F_const_method; } -#line 5238 "built/tmp/cppBison.yxx.c" +#line 5242 "built/tmp/cppBison.yxx.c" break; case 105: /* function_post: function_post KW_VOLATILE */ @@ -5242,7 +5246,7 @@ yyreduce: { (yyval.u.integer) = (yyvsp[-1].u.integer) | (int)CPPFunctionType::F_volatile_method; } -#line 5246 "built/tmp/cppBison.yxx.c" +#line 5250 "built/tmp/cppBison.yxx.c" break; case 106: /* function_post: function_post KW_NOEXCEPT */ @@ -5250,7 +5254,7 @@ yyreduce: { (yyval.u.integer) = (yyvsp[-1].u.integer) | (int)CPPFunctionType::F_noexcept; } -#line 5254 "built/tmp/cppBison.yxx.c" +#line 5258 "built/tmp/cppBison.yxx.c" break; case 107: /* function_post: function_post KW_NOEXCEPT_LPAREN const_expr ')' */ @@ -5263,7 +5267,7 @@ yyreduce: (yyval.u.integer) = (yyvsp[-3].u.integer) | (int)CPPFunctionType::F_noexcept; } } -#line 5267 "built/tmp/cppBison.yxx.c" +#line 5271 "built/tmp/cppBison.yxx.c" break; case 108: /* function_post: function_post KW_FINAL */ @@ -5271,7 +5275,7 @@ yyreduce: { (yyval.u.integer) = (yyvsp[-1].u.integer) | (int)CPPFunctionType::F_final; } -#line 5275 "built/tmp/cppBison.yxx.c" +#line 5279 "built/tmp/cppBison.yxx.c" break; case 109: /* function_post: function_post KW_OVERRIDE */ @@ -5279,7 +5283,7 @@ yyreduce: { (yyval.u.integer) = (yyvsp[-1].u.integer) | (int)CPPFunctionType::F_override; } -#line 5283 "built/tmp/cppBison.yxx.c" +#line 5287 "built/tmp/cppBison.yxx.c" break; case 110: /* function_post: function_post '&' */ @@ -5287,7 +5291,7 @@ yyreduce: { (yyval.u.integer) = (yyvsp[-1].u.integer) | (int)CPPFunctionType::F_lvalue_method; } -#line 5291 "built/tmp/cppBison.yxx.c" +#line 5295 "built/tmp/cppBison.yxx.c" break; case 111: /* function_post: function_post ANDAND */ @@ -5295,7 +5299,7 @@ yyreduce: { (yyval.u.integer) = (yyvsp[-1].u.integer) | (int)CPPFunctionType::F_rvalue_method; } -#line 5299 "built/tmp/cppBison.yxx.c" +#line 5303 "built/tmp/cppBison.yxx.c" break; case 112: /* function_post: function_post KW_MUTABLE */ @@ -5304,7 +5308,7 @@ yyreduce: // Used for lambdas, currently ignored. (yyval.u.integer) = (yyvsp[-1].u.integer); } -#line 5308 "built/tmp/cppBison.yxx.c" +#line 5312 "built/tmp/cppBison.yxx.c" break; case 113: /* function_post: function_post KW_CONSTEXPR */ @@ -5313,7 +5317,7 @@ yyreduce: // Used for lambdas in C++17, currently ignored. (yyval.u.integer) = (yyvsp[-1].u.integer); } -#line 5317 "built/tmp/cppBison.yxx.c" +#line 5321 "built/tmp/cppBison.yxx.c" break; case 114: /* function_post: function_post KW_THROW '(' ')' */ @@ -5321,7 +5325,7 @@ yyreduce: { (yyval.u.integer) = (yyvsp[-3].u.integer); } -#line 5325 "built/tmp/cppBison.yxx.c" +#line 5329 "built/tmp/cppBison.yxx.c" break; case 115: /* function_post: function_post KW_THROW '(' name ')' */ @@ -5329,7 +5333,7 @@ yyreduce: { (yyval.u.integer) = (yyvsp[-4].u.integer); } -#line 5333 "built/tmp/cppBison.yxx.c" +#line 5337 "built/tmp/cppBison.yxx.c" break; case 116: /* function_post: function_post KW_THROW '(' name ELLIPSIS ')' */ @@ -5337,7 +5341,7 @@ yyreduce: { (yyval.u.integer) = (yyvsp[-5].u.integer); } -#line 5341 "built/tmp/cppBison.yxx.c" +#line 5345 "built/tmp/cppBison.yxx.c" break; case 117: /* function_operator: '!' */ @@ -5345,7 +5349,7 @@ yyreduce: { (yyval.str) = "!"; } -#line 5349 "built/tmp/cppBison.yxx.c" +#line 5353 "built/tmp/cppBison.yxx.c" break; case 118: /* function_operator: '~' */ @@ -5353,7 +5357,7 @@ yyreduce: { (yyval.str) = "~"; } -#line 5357 "built/tmp/cppBison.yxx.c" +#line 5361 "built/tmp/cppBison.yxx.c" break; case 119: /* function_operator: '*' */ @@ -5361,7 +5365,7 @@ yyreduce: { (yyval.str) = "*"; } -#line 5365 "built/tmp/cppBison.yxx.c" +#line 5369 "built/tmp/cppBison.yxx.c" break; case 120: /* function_operator: '/' */ @@ -5369,7 +5373,7 @@ yyreduce: { (yyval.str) = "/"; } -#line 5373 "built/tmp/cppBison.yxx.c" +#line 5377 "built/tmp/cppBison.yxx.c" break; case 121: /* function_operator: '%' */ @@ -5377,7 +5381,7 @@ yyreduce: { (yyval.str) = "%"; } -#line 5381 "built/tmp/cppBison.yxx.c" +#line 5385 "built/tmp/cppBison.yxx.c" break; case 122: /* function_operator: '+' */ @@ -5385,7 +5389,7 @@ yyreduce: { (yyval.str) = "+"; } -#line 5389 "built/tmp/cppBison.yxx.c" +#line 5393 "built/tmp/cppBison.yxx.c" break; case 123: /* function_operator: '-' */ @@ -5393,7 +5397,7 @@ yyreduce: { (yyval.str) = "-"; } -#line 5397 "built/tmp/cppBison.yxx.c" +#line 5401 "built/tmp/cppBison.yxx.c" break; case 124: /* function_operator: '|' */ @@ -5401,7 +5405,7 @@ yyreduce: { (yyval.str) = "|"; } -#line 5405 "built/tmp/cppBison.yxx.c" +#line 5409 "built/tmp/cppBison.yxx.c" break; case 125: /* function_operator: '&' */ @@ -5409,7 +5413,7 @@ yyreduce: { (yyval.str) = "&"; } -#line 5413 "built/tmp/cppBison.yxx.c" +#line 5417 "built/tmp/cppBison.yxx.c" break; case 126: /* function_operator: '^' */ @@ -5417,7 +5421,7 @@ yyreduce: { (yyval.str) = "^"; } -#line 5421 "built/tmp/cppBison.yxx.c" +#line 5425 "built/tmp/cppBison.yxx.c" break; case 127: /* function_operator: OROR */ @@ -5425,7 +5429,7 @@ yyreduce: { (yyval.str) = "||"; } -#line 5429 "built/tmp/cppBison.yxx.c" +#line 5433 "built/tmp/cppBison.yxx.c" break; case 128: /* function_operator: ANDAND */ @@ -5433,7 +5437,7 @@ yyreduce: { (yyval.str) = "&&"; } -#line 5437 "built/tmp/cppBison.yxx.c" +#line 5441 "built/tmp/cppBison.yxx.c" break; case 129: /* function_operator: EQCOMPARE */ @@ -5441,7 +5445,7 @@ yyreduce: { (yyval.str) = "=="; } -#line 5445 "built/tmp/cppBison.yxx.c" +#line 5449 "built/tmp/cppBison.yxx.c" break; case 130: /* function_operator: NECOMPARE */ @@ -5449,7 +5453,7 @@ yyreduce: { (yyval.str) = "!="; } -#line 5453 "built/tmp/cppBison.yxx.c" +#line 5457 "built/tmp/cppBison.yxx.c" break; case 131: /* function_operator: LECOMPARE */ @@ -5457,7 +5461,7 @@ yyreduce: { (yyval.str) = "<="; } -#line 5461 "built/tmp/cppBison.yxx.c" +#line 5465 "built/tmp/cppBison.yxx.c" break; case 132: /* function_operator: GECOMPARE */ @@ -5465,7 +5469,7 @@ yyreduce: { (yyval.str) = ">="; } -#line 5469 "built/tmp/cppBison.yxx.c" +#line 5473 "built/tmp/cppBison.yxx.c" break; case 133: /* function_operator: '<' */ @@ -5473,7 +5477,7 @@ yyreduce: { (yyval.str) = "<"; } -#line 5477 "built/tmp/cppBison.yxx.c" +#line 5481 "built/tmp/cppBison.yxx.c" break; case 134: /* function_operator: '>' */ @@ -5481,7 +5485,7 @@ yyreduce: { (yyval.str) = ">"; } -#line 5485 "built/tmp/cppBison.yxx.c" +#line 5489 "built/tmp/cppBison.yxx.c" break; case 135: /* function_operator: SPACESHIP */ @@ -5489,7 +5493,7 @@ yyreduce: { (yyval.str) = "<=>"; } -#line 5493 "built/tmp/cppBison.yxx.c" +#line 5497 "built/tmp/cppBison.yxx.c" break; case 136: /* function_operator: LSHIFT */ @@ -5497,7 +5501,7 @@ yyreduce: { (yyval.str) = "<<"; } -#line 5501 "built/tmp/cppBison.yxx.c" +#line 5505 "built/tmp/cppBison.yxx.c" break; case 137: /* function_operator: RSHIFT */ @@ -5505,7 +5509,7 @@ yyreduce: { (yyval.str) = ">>"; } -#line 5509 "built/tmp/cppBison.yxx.c" +#line 5513 "built/tmp/cppBison.yxx.c" break; case 138: /* function_operator: '=' */ @@ -5513,7 +5517,7 @@ yyreduce: { (yyval.str) = "="; } -#line 5517 "built/tmp/cppBison.yxx.c" +#line 5521 "built/tmp/cppBison.yxx.c" break; case 139: /* function_operator: ',' */ @@ -5521,7 +5525,7 @@ yyreduce: { (yyval.str) = ","; } -#line 5525 "built/tmp/cppBison.yxx.c" +#line 5529 "built/tmp/cppBison.yxx.c" break; case 140: /* function_operator: PLUSPLUS */ @@ -5529,7 +5533,7 @@ yyreduce: { (yyval.str) = "++"; } -#line 5533 "built/tmp/cppBison.yxx.c" +#line 5537 "built/tmp/cppBison.yxx.c" break; case 141: /* function_operator: MINUSMINUS */ @@ -5537,7 +5541,7 @@ yyreduce: { (yyval.str) = "--"; } -#line 5541 "built/tmp/cppBison.yxx.c" +#line 5545 "built/tmp/cppBison.yxx.c" break; case 142: /* function_operator: TIMESEQUAL */ @@ -5545,7 +5549,7 @@ yyreduce: { (yyval.str) = "*="; } -#line 5549 "built/tmp/cppBison.yxx.c" +#line 5553 "built/tmp/cppBison.yxx.c" break; case 143: /* function_operator: DIVIDEEQUAL */ @@ -5553,7 +5557,7 @@ yyreduce: { (yyval.str) = "/="; } -#line 5557 "built/tmp/cppBison.yxx.c" +#line 5561 "built/tmp/cppBison.yxx.c" break; case 144: /* function_operator: MODEQUAL */ @@ -5561,7 +5565,7 @@ yyreduce: { (yyval.str) = "%="; } -#line 5565 "built/tmp/cppBison.yxx.c" +#line 5569 "built/tmp/cppBison.yxx.c" break; case 145: /* function_operator: PLUSEQUAL */ @@ -5569,7 +5573,7 @@ yyreduce: { (yyval.str) = "+="; } -#line 5573 "built/tmp/cppBison.yxx.c" +#line 5577 "built/tmp/cppBison.yxx.c" break; case 146: /* function_operator: MINUSEQUAL */ @@ -5577,7 +5581,7 @@ yyreduce: { (yyval.str) = "-="; } -#line 5581 "built/tmp/cppBison.yxx.c" +#line 5585 "built/tmp/cppBison.yxx.c" break; case 147: /* function_operator: OREQUAL */ @@ -5585,7 +5589,7 @@ yyreduce: { (yyval.str) = "|="; } -#line 5589 "built/tmp/cppBison.yxx.c" +#line 5593 "built/tmp/cppBison.yxx.c" break; case 148: /* function_operator: ANDEQUAL */ @@ -5593,7 +5597,7 @@ yyreduce: { (yyval.str) = "&="; } -#line 5597 "built/tmp/cppBison.yxx.c" +#line 5601 "built/tmp/cppBison.yxx.c" break; case 149: /* function_operator: XOREQUAL */ @@ -5601,7 +5605,7 @@ yyreduce: { (yyval.str) = "^="; } -#line 5605 "built/tmp/cppBison.yxx.c" +#line 5609 "built/tmp/cppBison.yxx.c" break; case 150: /* function_operator: LSHIFTEQUAL */ @@ -5609,7 +5613,7 @@ yyreduce: { (yyval.str) = "<<="; } -#line 5613 "built/tmp/cppBison.yxx.c" +#line 5617 "built/tmp/cppBison.yxx.c" break; case 151: /* function_operator: RSHIFTEQUAL */ @@ -5617,7 +5621,7 @@ yyreduce: { (yyval.str) = ">>="; } -#line 5621 "built/tmp/cppBison.yxx.c" +#line 5625 "built/tmp/cppBison.yxx.c" break; case 152: /* function_operator: POINTSAT */ @@ -5625,7 +5629,7 @@ yyreduce: { (yyval.str) = "->"; } -#line 5629 "built/tmp/cppBison.yxx.c" +#line 5633 "built/tmp/cppBison.yxx.c" break; case 153: /* function_operator: '[' ']' */ @@ -5633,7 +5637,7 @@ yyreduce: { (yyval.str) = "[]"; } -#line 5637 "built/tmp/cppBison.yxx.c" +#line 5641 "built/tmp/cppBison.yxx.c" break; case 154: /* function_operator: '(' ')' */ @@ -5641,7 +5645,7 @@ yyreduce: { (yyval.str) = "()"; } -#line 5645 "built/tmp/cppBison.yxx.c" +#line 5649 "built/tmp/cppBison.yxx.c" break; case 155: /* function_operator: KW_NEW */ @@ -5649,7 +5653,7 @@ yyreduce: { (yyval.str) = "new"; } -#line 5653 "built/tmp/cppBison.yxx.c" +#line 5657 "built/tmp/cppBison.yxx.c" break; case 156: /* function_operator: KW_DELETE */ @@ -5657,7 +5661,7 @@ yyreduce: { (yyval.str) = "delete"; } -#line 5661 "built/tmp/cppBison.yxx.c" +#line 5665 "built/tmp/cppBison.yxx.c" break; case 161: /* $@15: %empty */ @@ -5665,7 +5669,7 @@ yyreduce: { push_scope(new CPPTemplateScope(current_scope)); } -#line 5669 "built/tmp/cppBison.yxx.c" +#line 5673 "built/tmp/cppBison.yxx.c" break; case 162: /* template_declaration: KW_TEMPLATE $@15 '<' template_formal_parameters '>' more_template_declaration */ @@ -5673,7 +5677,7 @@ yyreduce: { pop_scope(); } -#line 5677 "built/tmp/cppBison.yxx.c" +#line 5681 "built/tmp/cppBison.yxx.c" break; case 167: /* template_nonempty_formal_parameters: template_formal_parameter */ @@ -5683,7 +5687,7 @@ yyreduce: assert(ts != nullptr); ts->add_template_parameter((yyvsp[0].u.decl)); } -#line 5687 "built/tmp/cppBison.yxx.c" +#line 5691 "built/tmp/cppBison.yxx.c" break; case 168: /* template_nonempty_formal_parameters: template_nonempty_formal_parameters ',' template_formal_parameter */ @@ -5693,7 +5697,7 @@ yyreduce: assert(ts != nullptr); ts->add_template_parameter((yyvsp[0].u.decl)); } -#line 5697 "built/tmp/cppBison.yxx.c" +#line 5701 "built/tmp/cppBison.yxx.c" break; case 171: /* template_formal_parameter: typename_keyword */ @@ -5701,7 +5705,7 @@ yyreduce: { (yyval.u.decl) = CPPType::new_type(new CPPClassTemplateParameter(nullptr)); } -#line 5705 "built/tmp/cppBison.yxx.c" +#line 5709 "built/tmp/cppBison.yxx.c" break; case 172: /* template_formal_parameter: typename_keyword name */ @@ -5709,7 +5713,7 @@ yyreduce: { (yyval.u.decl) = CPPType::new_type(new CPPClassTemplateParameter((yyvsp[0].u.identifier))); } -#line 5713 "built/tmp/cppBison.yxx.c" +#line 5717 "built/tmp/cppBison.yxx.c" break; case 173: /* template_formal_parameter: typename_keyword name '=' full_type */ @@ -5717,7 +5721,7 @@ yyreduce: { (yyval.u.decl) = CPPType::new_type(new CPPClassTemplateParameter((yyvsp[-2].u.identifier), (yyvsp[0].u.type))); } -#line 5721 "built/tmp/cppBison.yxx.c" +#line 5725 "built/tmp/cppBison.yxx.c" break; case 174: /* template_formal_parameter: typename_keyword ELLIPSIS */ @@ -5727,7 +5731,7 @@ yyreduce: ctp->_packed = true; (yyval.u.decl) = CPPType::new_type(ctp); } -#line 5731 "built/tmp/cppBison.yxx.c" +#line 5735 "built/tmp/cppBison.yxx.c" break; case 175: /* template_formal_parameter: typename_keyword ELLIPSIS name */ @@ -5737,7 +5741,7 @@ yyreduce: ctp->_packed = true; (yyval.u.decl) = CPPType::new_type(ctp); } -#line 5741 "built/tmp/cppBison.yxx.c" +#line 5745 "built/tmp/cppBison.yxx.c" break; case 176: /* template_formal_parameter: template_formal_parameter_type formal_parameter_identifier template_parameter_maybe_initialize */ @@ -5747,7 +5751,7 @@ yyreduce: inst->set_initializer((yyvsp[0].u.expr)); (yyval.u.decl) = inst; } -#line 5751 "built/tmp/cppBison.yxx.c" +#line 5755 "built/tmp/cppBison.yxx.c" break; case 177: /* template_formal_parameter: KW_CONST template_formal_parameter_type formal_parameter_identifier template_parameter_maybe_initialize */ @@ -5758,7 +5762,7 @@ yyreduce: inst->set_initializer((yyvsp[0].u.expr)); (yyval.u.decl) = inst; } -#line 5762 "built/tmp/cppBison.yxx.c" +#line 5766 "built/tmp/cppBison.yxx.c" break; case 178: /* template_formal_parameter: template_formal_parameter_type parameter_pack_identifier */ @@ -5767,7 +5771,7 @@ yyreduce: CPPInstance *inst = new CPPInstance((yyvsp[-1].u.type), (yyvsp[0].u.inst_ident), 0, (yylsp[0]).file); (yyval.u.decl) = inst; } -#line 5771 "built/tmp/cppBison.yxx.c" +#line 5775 "built/tmp/cppBison.yxx.c" break; case 179: /* template_formal_parameter: KW_CONST template_formal_parameter_type parameter_pack_identifier */ @@ -5777,7 +5781,7 @@ yyreduce: CPPInstance *inst = new CPPInstance((yyvsp[-1].u.type), (yyvsp[0].u.inst_ident), 0, (yylsp[0]).file); (yyval.u.decl) = inst; } -#line 5781 "built/tmp/cppBison.yxx.c" +#line 5785 "built/tmp/cppBison.yxx.c" break; case 180: /* template_formal_parameter_type: simple_type */ @@ -5785,7 +5789,7 @@ yyreduce: { (yyval.u.type) = CPPType::new_type((yyvsp[0].u.simple_type)); } -#line 5789 "built/tmp/cppBison.yxx.c" +#line 5793 "built/tmp/cppBison.yxx.c" break; case 181: /* template_formal_parameter_type: IDENTIFIER */ @@ -5794,7 +5798,7 @@ yyreduce: yywarning("Not a type: " + (yyvsp[0].u.identifier)->get_fully_scoped_name(), (yylsp[0])); (yyval.u.type) = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_unknown)); } -#line 5798 "built/tmp/cppBison.yxx.c" +#line 5802 "built/tmp/cppBison.yxx.c" break; case 182: /* template_formal_parameter_type: TYPENAME_IDENTIFIER */ @@ -5806,7 +5810,7 @@ yyreduce: } assert((yyval.u.type) != nullptr); } -#line 5810 "built/tmp/cppBison.yxx.c" +#line 5814 "built/tmp/cppBison.yxx.c" break; case 183: /* template_formal_parameter_type: TYPEPACK_IDENTIFIER */ @@ -5818,7 +5822,7 @@ yyreduce: } assert((yyval.u.type) != nullptr); } -#line 5822 "built/tmp/cppBison.yxx.c" +#line 5826 "built/tmp/cppBison.yxx.c" break; case 184: /* instance_identifier: name_no_final optional_attributes */ @@ -5826,7 +5830,7 @@ yyreduce: { (yyval.u.inst_ident) = new CPPInstanceIdentifier((yyvsp[-1].u.identifier), (yyvsp[0].attr_list)); } -#line 5830 "built/tmp/cppBison.yxx.c" +#line 5834 "built/tmp/cppBison.yxx.c" break; case 185: /* instance_identifier: KW_OPERATOR function_operator optional_attributes */ @@ -5844,7 +5848,7 @@ yyreduce: (yyval.u.inst_ident) = new CPPInstanceIdentifier(ident, (yyvsp[0].attr_list)); } -#line 5848 "built/tmp/cppBison.yxx.c" +#line 5852 "built/tmp/cppBison.yxx.c" break; case 186: /* instance_identifier: KW_OPERATOR SIMPLE_STRING IDENTIFIER optional_attributes */ @@ -5863,7 +5867,7 @@ yyreduce: (yyval.u.inst_ident) = new CPPInstanceIdentifier(ident, (yyvsp[0].attr_list)); } -#line 5867 "built/tmp/cppBison.yxx.c" +#line 5871 "built/tmp/cppBison.yxx.c" break; case 187: /* instance_identifier: KW_CONST instance_identifier */ @@ -5872,7 +5876,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_const); } -#line 5876 "built/tmp/cppBison.yxx.c" +#line 5880 "built/tmp/cppBison.yxx.c" break; case 188: /* instance_identifier: KW_VOLATILE instance_identifier */ @@ -5881,7 +5885,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_volatile); } -#line 5885 "built/tmp/cppBison.yxx.c" +#line 5889 "built/tmp/cppBison.yxx.c" break; case 189: /* instance_identifier: '*' optional_attributes instance_identifier */ @@ -5890,7 +5894,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_pointer, (yyvsp[-1].attr_list)); } -#line 5894 "built/tmp/cppBison.yxx.c" +#line 5898 "built/tmp/cppBison.yxx.c" break; case 190: /* instance_identifier: '&' optional_attributes instance_identifier */ @@ -5899,7 +5903,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_reference, (yyvsp[-1].attr_list)); } -#line 5903 "built/tmp/cppBison.yxx.c" +#line 5907 "built/tmp/cppBison.yxx.c" break; case 191: /* instance_identifier: ANDAND optional_attributes instance_identifier */ @@ -5908,7 +5912,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_rvalue_reference, (yyvsp[-1].attr_list)); } -#line 5912 "built/tmp/cppBison.yxx.c" +#line 5916 "built/tmp/cppBison.yxx.c" break; case 192: /* instance_identifier: SCOPING '*' optional_attributes instance_identifier */ @@ -5917,7 +5921,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_scoped_pointer_modifier((yyvsp[-3].u.identifier), (yyvsp[-1].attr_list)); } -#line 5921 "built/tmp/cppBison.yxx.c" +#line 5925 "built/tmp/cppBison.yxx.c" break; case 193: /* instance_identifier: instance_identifier '[' optional_const_expr ']' optional_attributes */ @@ -5926,7 +5930,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[-4].u.inst_ident); (yyval.u.inst_ident)->add_array_modifier((yyvsp[-2].u.expr), (yyvsp[0].attr_list)); } -#line 5930 "built/tmp/cppBison.yxx.c" +#line 5934 "built/tmp/cppBison.yxx.c" break; case 194: /* instance_identifier: '(' instance_identifier ')' */ @@ -5935,7 +5939,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[-1].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_paren); } -#line 5939 "built/tmp/cppBison.yxx.c" +#line 5943 "built/tmp/cppBison.yxx.c" break; case 195: /* $@16: %empty */ @@ -5952,7 +5956,7 @@ yyreduce: push_scope(scope); } -#line 5956 "built/tmp/cppBison.yxx.c" +#line 5960 "built/tmp/cppBison.yxx.c" break; case 196: /* instance_identifier: instance_identifier '(' $@16 formal_parameter_list ')' function_post optional_attributes */ @@ -5970,7 +5974,7 @@ yyreduce: (yyval.u.inst_ident)->add_func_modifier((yyvsp[-3].u.param_list), (yyvsp[-1].u.integer), nullptr, (yyvsp[0].attr_list)); } } -#line 5974 "built/tmp/cppBison.yxx.c" +#line 5978 "built/tmp/cppBison.yxx.c" break; case 197: /* instance_identifier_and_maybe_trailing_return_type: instance_identifier maybe_trailing_return_type */ @@ -5984,7 +5988,7 @@ yyreduce: } (yyval.u.inst_ident) = (yyvsp[-1].u.inst_ident); } -#line 5988 "built/tmp/cppBison.yxx.c" +#line 5992 "built/tmp/cppBison.yxx.c" break; case 198: /* instance_identifier_and_maybe_trailing_return_type: instance_identifier ':' const_expr */ @@ -5994,7 +5998,7 @@ yyreduce: (yyvsp[-2].u.inst_ident)->_bit_width = (yyvsp[0].u.expr); (yyval.u.inst_ident) = (yyvsp[-2].u.inst_ident); } -#line 5998 "built/tmp/cppBison.yxx.c" +#line 6002 "built/tmp/cppBison.yxx.c" break; case 199: /* maybe_trailing_return_type: empty */ @@ -6002,7 +6006,7 @@ yyreduce: { (yyval.u.type) = nullptr; } -#line 6006 "built/tmp/cppBison.yxx.c" +#line 6010 "built/tmp/cppBison.yxx.c" break; case 200: /* maybe_trailing_return_type: POINTSAT predefined_type empty_instance_identifier */ @@ -6010,7 +6014,7 @@ yyreduce: { (yyval.u.type) = (yyvsp[0].u.inst_ident)->unroll_type((yyvsp[-1].u.type)); } -#line 6014 "built/tmp/cppBison.yxx.c" +#line 6018 "built/tmp/cppBison.yxx.c" break; case 201: /* maybe_trailing_return_type: POINTSAT KW_CONST predefined_type empty_instance_identifier */ @@ -6019,7 +6023,7 @@ yyreduce: (yyvsp[0].u.inst_ident)->add_modifier(IIT_const); (yyval.u.type) = (yyvsp[0].u.inst_ident)->unroll_type((yyvsp[-1].u.type)); } -#line 6023 "built/tmp/cppBison.yxx.c" +#line 6027 "built/tmp/cppBison.yxx.c" break; case 202: /* maybe_comma_identifier: empty */ @@ -6027,7 +6031,7 @@ yyreduce: { (yyval.u.identifier) = nullptr; } -#line 6031 "built/tmp/cppBison.yxx.c" +#line 6035 "built/tmp/cppBison.yxx.c" break; case 203: /* maybe_comma_identifier: ',' IDENTIFIER */ @@ -6035,7 +6039,7 @@ yyreduce: { (yyval.u.identifier) = (yyvsp[0].u.identifier); } -#line 6039 "built/tmp/cppBison.yxx.c" +#line 6043 "built/tmp/cppBison.yxx.c" break; case 204: /* function_parameter_list: empty */ @@ -6043,7 +6047,7 @@ yyreduce: { (yyval.u.param_list) = new CPPParameterList; } -#line 6047 "built/tmp/cppBison.yxx.c" +#line 6051 "built/tmp/cppBison.yxx.c" break; case 205: /* function_parameter_list: ELLIPSIS */ @@ -6052,7 +6056,7 @@ yyreduce: (yyval.u.param_list) = new CPPParameterList; (yyval.u.param_list)->_includes_ellipsis = true; } -#line 6056 "built/tmp/cppBison.yxx.c" +#line 6060 "built/tmp/cppBison.yxx.c" break; case 206: /* function_parameter_list: function_parameters */ @@ -6060,7 +6064,7 @@ yyreduce: { (yyval.u.param_list) = (yyvsp[0].u.param_list); } -#line 6064 "built/tmp/cppBison.yxx.c" +#line 6068 "built/tmp/cppBison.yxx.c" break; case 207: /* function_parameter_list: function_parameters ',' ELLIPSIS */ @@ -6069,7 +6073,7 @@ yyreduce: (yyval.u.param_list) = (yyvsp[-2].u.param_list); (yyval.u.param_list)->_includes_ellipsis = true; } -#line 6073 "built/tmp/cppBison.yxx.c" +#line 6077 "built/tmp/cppBison.yxx.c" break; case 208: /* function_parameter_list: function_parameters ELLIPSIS */ @@ -6078,7 +6082,7 @@ yyreduce: (yyval.u.param_list) = (yyvsp[-1].u.param_list); (yyval.u.param_list)->_includes_ellipsis = true; } -#line 6082 "built/tmp/cppBison.yxx.c" +#line 6086 "built/tmp/cppBison.yxx.c" break; case 209: /* function_parameters: function_parameter */ @@ -6087,7 +6091,7 @@ yyreduce: (yyval.u.param_list) = new CPPParameterList; (yyval.u.param_list)->_parameters.push_back((yyvsp[0].u.instance)); } -#line 6091 "built/tmp/cppBison.yxx.c" +#line 6095 "built/tmp/cppBison.yxx.c" break; case 210: /* function_parameters: function_parameters ',' function_parameter */ @@ -6096,7 +6100,7 @@ yyreduce: (yyval.u.param_list) = (yyvsp[-2].u.param_list); (yyval.u.param_list)->_parameters.push_back((yyvsp[0].u.instance)); } -#line 6100 "built/tmp/cppBison.yxx.c" +#line 6104 "built/tmp/cppBison.yxx.c" break; case 211: /* formal_parameter_list: empty */ @@ -6104,7 +6108,7 @@ yyreduce: { (yyval.u.param_list) = new CPPParameterList; } -#line 6108 "built/tmp/cppBison.yxx.c" +#line 6112 "built/tmp/cppBison.yxx.c" break; case 212: /* formal_parameter_list: ELLIPSIS */ @@ -6113,7 +6117,7 @@ yyreduce: (yyval.u.param_list) = new CPPParameterList; (yyval.u.param_list)->_includes_ellipsis = true; } -#line 6117 "built/tmp/cppBison.yxx.c" +#line 6121 "built/tmp/cppBison.yxx.c" break; case 213: /* formal_parameter_list: formal_parameters */ @@ -6121,7 +6125,7 @@ yyreduce: { (yyval.u.param_list) = (yyvsp[0].u.param_list); } -#line 6125 "built/tmp/cppBison.yxx.c" +#line 6129 "built/tmp/cppBison.yxx.c" break; case 214: /* formal_parameter_list: formal_parameters ',' ELLIPSIS */ @@ -6130,7 +6134,7 @@ yyreduce: (yyval.u.param_list) = (yyvsp[-2].u.param_list); (yyval.u.param_list)->_includes_ellipsis = true; } -#line 6134 "built/tmp/cppBison.yxx.c" +#line 6138 "built/tmp/cppBison.yxx.c" break; case 215: /* formal_parameter_list: formal_parameters ELLIPSIS */ @@ -6139,7 +6143,7 @@ yyreduce: (yyval.u.param_list) = (yyvsp[-1].u.param_list); (yyval.u.param_list)->_includes_ellipsis = true; } -#line 6143 "built/tmp/cppBison.yxx.c" +#line 6147 "built/tmp/cppBison.yxx.c" break; case 216: /* formal_parameters: formal_parameter */ @@ -6148,7 +6152,7 @@ yyreduce: (yyval.u.param_list) = new CPPParameterList; (yyval.u.param_list)->_parameters.push_back((yyvsp[0].u.instance)); } -#line 6152 "built/tmp/cppBison.yxx.c" +#line 6156 "built/tmp/cppBison.yxx.c" break; case 217: /* formal_parameters: formal_parameters ',' formal_parameter */ @@ -6157,7 +6161,7 @@ yyreduce: (yyval.u.param_list) = (yyvsp[-2].u.param_list); (yyval.u.param_list)->_parameters.push_back((yyvsp[0].u.instance)); } -#line 6161 "built/tmp/cppBison.yxx.c" +#line 6165 "built/tmp/cppBison.yxx.c" break; case 218: /* template_parameter_maybe_initialize: empty */ @@ -6165,7 +6169,7 @@ yyreduce: { (yyval.u.expr) = nullptr; } -#line 6169 "built/tmp/cppBison.yxx.c" +#line 6173 "built/tmp/cppBison.yxx.c" break; case 219: /* template_parameter_maybe_initialize: '=' no_angle_bracket_const_expr */ @@ -6173,7 +6177,7 @@ yyreduce: { (yyval.u.expr) = (yyvsp[0].u.expr); } -#line 6177 "built/tmp/cppBison.yxx.c" +#line 6181 "built/tmp/cppBison.yxx.c" break; case 220: /* maybe_initialize: empty */ @@ -6181,7 +6185,7 @@ yyreduce: { (yyval.u.expr) = nullptr; } -#line 6185 "built/tmp/cppBison.yxx.c" +#line 6189 "built/tmp/cppBison.yxx.c" break; case 221: /* maybe_initialize: '=' const_expr */ @@ -6189,7 +6193,7 @@ yyreduce: { (yyval.u.expr) = (yyvsp[0].u.expr); } -#line 6193 "built/tmp/cppBison.yxx.c" +#line 6197 "built/tmp/cppBison.yxx.c" break; case 222: /* maybe_initialize_or_constructor_body: ';' */ @@ -6197,7 +6201,7 @@ yyreduce: { (yyval.u.expr) = nullptr; } -#line 6201 "built/tmp/cppBison.yxx.c" +#line 6205 "built/tmp/cppBison.yxx.c" break; case 223: /* maybe_initialize_or_constructor_body: '{' code '}' */ @@ -6205,7 +6209,7 @@ yyreduce: { (yyval.u.expr) = nullptr; } -#line 6209 "built/tmp/cppBison.yxx.c" +#line 6213 "built/tmp/cppBison.yxx.c" break; case 224: /* maybe_initialize_or_constructor_body: ':' constructor_inits '{' code '}' */ @@ -6213,7 +6217,7 @@ yyreduce: { (yyval.u.expr) = nullptr; } -#line 6217 "built/tmp/cppBison.yxx.c" +#line 6221 "built/tmp/cppBison.yxx.c" break; case 225: /* maybe_initialize_or_constructor_body: '=' KW_DEFAULT ';' */ @@ -6221,7 +6225,7 @@ yyreduce: { (yyval.u.expr) = new CPPExpression(CPPExpression::get_default()); } -#line 6225 "built/tmp/cppBison.yxx.c" +#line 6229 "built/tmp/cppBison.yxx.c" break; case 226: /* maybe_initialize_or_constructor_body: '=' KW_DELETE ';' */ @@ -6229,7 +6233,7 @@ yyreduce: { (yyval.u.expr) = new CPPExpression(CPPExpression::get_delete()); } -#line 6233 "built/tmp/cppBison.yxx.c" +#line 6237 "built/tmp/cppBison.yxx.c" break; case 227: /* maybe_initialize_or_function_body: ';' */ @@ -6237,7 +6241,7 @@ yyreduce: { (yyval.u.expr) = nullptr; } -#line 6241 "built/tmp/cppBison.yxx.c" +#line 6245 "built/tmp/cppBison.yxx.c" break; case 228: /* maybe_initialize_or_function_body: '{' code '}' */ @@ -6245,7 +6249,7 @@ yyreduce: { (yyval.u.expr) = nullptr; } -#line 6249 "built/tmp/cppBison.yxx.c" +#line 6253 "built/tmp/cppBison.yxx.c" break; case 229: /* maybe_initialize_or_function_body: '=' const_expr ';' */ @@ -6253,7 +6257,7 @@ yyreduce: { (yyval.u.expr) = (yyvsp[-1].u.expr); } -#line 6257 "built/tmp/cppBison.yxx.c" +#line 6261 "built/tmp/cppBison.yxx.c" break; case 230: /* maybe_initialize_or_function_body: '=' KW_DEFAULT ';' */ @@ -6261,7 +6265,7 @@ yyreduce: { (yyval.u.expr) = new CPPExpression(CPPExpression::get_default()); } -#line 6265 "built/tmp/cppBison.yxx.c" +#line 6269 "built/tmp/cppBison.yxx.c" break; case 231: /* maybe_initialize_or_function_body: '=' KW_DELETE ';' */ @@ -6269,7 +6273,7 @@ yyreduce: { (yyval.u.expr) = new CPPExpression(CPPExpression::get_delete()); } -#line 6273 "built/tmp/cppBison.yxx.c" +#line 6277 "built/tmp/cppBison.yxx.c" break; case 232: /* maybe_initialize_or_function_body: '=' '{' structure_init '}' */ @@ -6277,14 +6281,14 @@ yyreduce: { (yyval.u.expr) = nullptr; } -#line 6281 "built/tmp/cppBison.yxx.c" +#line 6285 "built/tmp/cppBison.yxx.c" break; case 236: /* structure_init_body: const_expr */ #line 2176 "dtool/src/cppparser/cppBison.yxx" { } -#line 6288 "built/tmp/cppBison.yxx.c" +#line 6292 "built/tmp/cppBison.yxx.c" break; case 240: /* function_parameter: optional_attributes type formal_parameter_identifier maybe_initialize */ @@ -6294,7 +6298,7 @@ yyreduce: (yyval.u.instance) = new CPPInstance((yyvsp[-2].u.type), (yyvsp[-1].u.inst_ident), 0, (yylsp[-1]).file); (yyval.u.instance)->set_initializer((yyvsp[0].u.expr)); } -#line 6298 "built/tmp/cppBison.yxx.c" +#line 6302 "built/tmp/cppBison.yxx.c" break; case 241: /* function_parameter: optional_attributes KW_CONST type formal_parameter_identifier maybe_initialize */ @@ -6305,7 +6309,7 @@ yyreduce: (yyval.u.instance) = new CPPInstance((yyvsp[-2].u.type), (yyvsp[-1].u.inst_ident), 0, (yylsp[-1]).file); (yyval.u.instance)->set_initializer((yyvsp[0].u.expr)); } -#line 6309 "built/tmp/cppBison.yxx.c" +#line 6313 "built/tmp/cppBison.yxx.c" break; case 242: /* function_parameter: optional_attributes KW_CONST KW_REGISTER type formal_parameter_identifier maybe_initialize */ @@ -6316,7 +6320,7 @@ yyreduce: (yyval.u.instance) = new CPPInstance((yyvsp[-2].u.type), (yyvsp[-1].u.inst_ident), 0, (yylsp[-2]).file); (yyval.u.instance)->set_initializer((yyvsp[0].u.expr)); } -#line 6320 "built/tmp/cppBison.yxx.c" +#line 6324 "built/tmp/cppBison.yxx.c" break; case 243: /* function_parameter: optional_attributes type_pack parameter_pack_identifier maybe_initialize */ @@ -6326,7 +6330,7 @@ yyreduce: (yyval.u.instance) = new CPPInstance((yyvsp[-2].u.type), (yyvsp[-1].u.inst_ident), 0, (yylsp[-1]).file); (yyval.u.instance)->set_initializer((yyvsp[0].u.expr)); } -#line 6330 "built/tmp/cppBison.yxx.c" +#line 6334 "built/tmp/cppBison.yxx.c" break; case 244: /* function_parameter: optional_attributes KW_CONST type_pack parameter_pack_identifier maybe_initialize */ @@ -6337,7 +6341,7 @@ yyreduce: (yyval.u.instance) = new CPPInstance((yyvsp[-2].u.type), (yyvsp[-1].u.inst_ident), 0, (yylsp[-1]).file); (yyval.u.instance)->set_initializer((yyvsp[0].u.expr)); } -#line 6341 "built/tmp/cppBison.yxx.c" +#line 6345 "built/tmp/cppBison.yxx.c" break; case 245: /* function_parameter: optional_attributes KW_CONST KW_REGISTER type_pack parameter_pack_identifier maybe_initialize */ @@ -6348,7 +6352,7 @@ yyreduce: (yyval.u.instance) = new CPPInstance((yyvsp[-2].u.type), (yyvsp[-1].u.inst_ident), 0, (yylsp[-2]).file); (yyval.u.instance)->set_initializer((yyvsp[0].u.expr)); } -#line 6352 "built/tmp/cppBison.yxx.c" +#line 6356 "built/tmp/cppBison.yxx.c" break; case 246: /* function_parameter: optional_attributes KW_REGISTER function_parameter */ @@ -6357,7 +6361,7 @@ yyreduce: (yyval.u.instance) = (yyvsp[0].u.instance); (yyval.u.instance)->_attributes.add_attributes_from((yyvsp[-2].attr_list)); } -#line 6361 "built/tmp/cppBison.yxx.c" +#line 6365 "built/tmp/cppBison.yxx.c" break; case 247: /* formal_parameter: function_parameter */ @@ -6365,7 +6369,7 @@ yyreduce: { (yyval.u.instance) = (yyvsp[0].u.instance); } -#line 6369 "built/tmp/cppBison.yxx.c" +#line 6373 "built/tmp/cppBison.yxx.c" break; case 248: /* formal_parameter: formal_const_expr */ @@ -6376,7 +6380,7 @@ yyreduce: (yyval.u.instance) = new CPPInstance(type, "expr"); (yyval.u.instance)->set_initializer((yyvsp[0].u.expr)); } -#line 6380 "built/tmp/cppBison.yxx.c" +#line 6384 "built/tmp/cppBison.yxx.c" break; case 249: /* not_paren_formal_parameter_identifier: empty */ @@ -6384,7 +6388,7 @@ yyreduce: { (yyval.u.inst_ident) = new CPPInstanceIdentifier(nullptr); } -#line 6388 "built/tmp/cppBison.yxx.c" +#line 6392 "built/tmp/cppBison.yxx.c" break; case 250: /* not_paren_formal_parameter_identifier: name_no_final optional_attributes */ @@ -6392,7 +6396,7 @@ yyreduce: { (yyval.u.inst_ident) = new CPPInstanceIdentifier((yyvsp[-1].u.identifier), (yyvsp[0].attr_list)); } -#line 6396 "built/tmp/cppBison.yxx.c" +#line 6400 "built/tmp/cppBison.yxx.c" break; case 251: /* not_paren_formal_parameter_identifier: KW_CONST not_paren_formal_parameter_identifier */ @@ -6401,7 +6405,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_const); } -#line 6405 "built/tmp/cppBison.yxx.c" +#line 6409 "built/tmp/cppBison.yxx.c" break; case 252: /* not_paren_formal_parameter_identifier: KW_VOLATILE not_paren_formal_parameter_identifier */ @@ -6410,7 +6414,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_volatile); } -#line 6414 "built/tmp/cppBison.yxx.c" +#line 6418 "built/tmp/cppBison.yxx.c" break; case 253: /* not_paren_formal_parameter_identifier: '*' optional_attributes not_paren_formal_parameter_identifier */ @@ -6419,7 +6423,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_pointer, (yyvsp[-1].attr_list)); } -#line 6423 "built/tmp/cppBison.yxx.c" +#line 6427 "built/tmp/cppBison.yxx.c" break; case 254: /* not_paren_formal_parameter_identifier: '&' optional_attributes not_paren_formal_parameter_identifier */ @@ -6428,7 +6432,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_reference, (yyvsp[-1].attr_list)); } -#line 6432 "built/tmp/cppBison.yxx.c" +#line 6436 "built/tmp/cppBison.yxx.c" break; case 255: /* not_paren_formal_parameter_identifier: ANDAND optional_attributes not_paren_formal_parameter_identifier */ @@ -6437,7 +6441,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_rvalue_reference, (yyvsp[-1].attr_list)); } -#line 6441 "built/tmp/cppBison.yxx.c" +#line 6445 "built/tmp/cppBison.yxx.c" break; case 256: /* not_paren_formal_parameter_identifier: SCOPING '*' optional_attributes not_paren_formal_parameter_identifier */ @@ -6446,7 +6450,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_scoped_pointer_modifier((yyvsp[-3].u.identifier), (yyvsp[-1].attr_list)); } -#line 6450 "built/tmp/cppBison.yxx.c" +#line 6454 "built/tmp/cppBison.yxx.c" break; case 257: /* not_paren_formal_parameter_identifier: not_paren_formal_parameter_identifier '[' optional_const_expr ']' optional_attributes */ @@ -6455,7 +6459,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[-4].u.inst_ident); (yyval.u.inst_ident)->add_array_modifier((yyvsp[-2].u.expr), (yyvsp[0].attr_list)); } -#line 6459 "built/tmp/cppBison.yxx.c" +#line 6463 "built/tmp/cppBison.yxx.c" break; case 258: /* formal_parameter_identifier: empty */ @@ -6463,7 +6467,7 @@ yyreduce: { (yyval.u.inst_ident) = new CPPInstanceIdentifier(nullptr); } -#line 6467 "built/tmp/cppBison.yxx.c" +#line 6471 "built/tmp/cppBison.yxx.c" break; case 259: /* formal_parameter_identifier: name_no_final optional_attributes */ @@ -6471,7 +6475,7 @@ yyreduce: { (yyval.u.inst_ident) = new CPPInstanceIdentifier((yyvsp[-1].u.identifier), (yyvsp[0].attr_list)); } -#line 6475 "built/tmp/cppBison.yxx.c" +#line 6479 "built/tmp/cppBison.yxx.c" break; case 260: /* formal_parameter_identifier: KW_CONST formal_parameter_identifier */ @@ -6480,7 +6484,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_const); } -#line 6484 "built/tmp/cppBison.yxx.c" +#line 6488 "built/tmp/cppBison.yxx.c" break; case 261: /* formal_parameter_identifier: KW_VOLATILE formal_parameter_identifier */ @@ -6489,7 +6493,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_volatile); } -#line 6493 "built/tmp/cppBison.yxx.c" +#line 6497 "built/tmp/cppBison.yxx.c" break; case 262: /* formal_parameter_identifier: '*' optional_attributes formal_parameter_identifier */ @@ -6498,7 +6502,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_pointer, (yyvsp[-1].attr_list)); } -#line 6502 "built/tmp/cppBison.yxx.c" +#line 6506 "built/tmp/cppBison.yxx.c" break; case 263: /* formal_parameter_identifier: '&' optional_attributes formal_parameter_identifier */ @@ -6507,7 +6511,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_reference, (yyvsp[-1].attr_list)); } -#line 6511 "built/tmp/cppBison.yxx.c" +#line 6515 "built/tmp/cppBison.yxx.c" break; case 264: /* formal_parameter_identifier: ANDAND optional_attributes formal_parameter_identifier */ @@ -6516,7 +6520,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_rvalue_reference, (yyvsp[-1].attr_list)); } -#line 6520 "built/tmp/cppBison.yxx.c" +#line 6524 "built/tmp/cppBison.yxx.c" break; case 265: /* formal_parameter_identifier: SCOPING '*' optional_attributes formal_parameter_identifier */ @@ -6525,7 +6529,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_scoped_pointer_modifier((yyvsp[-3].u.identifier), (yyvsp[-1].attr_list)); } -#line 6529 "built/tmp/cppBison.yxx.c" +#line 6533 "built/tmp/cppBison.yxx.c" break; case 266: /* formal_parameter_identifier: formal_parameter_identifier '[' optional_const_expr ']' optional_attributes */ @@ -6534,7 +6538,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[-4].u.inst_ident); (yyval.u.inst_ident)->add_array_modifier((yyvsp[-2].u.expr), (yyvsp[0].attr_list)); } -#line 6538 "built/tmp/cppBison.yxx.c" +#line 6542 "built/tmp/cppBison.yxx.c" break; case 267: /* formal_parameter_identifier: '(' formal_parameter_identifier ')' '(' function_parameter_list ')' function_post optional_attributes */ @@ -6544,7 +6548,7 @@ yyreduce: (yyval.u.inst_ident)->add_modifier(IIT_paren); (yyval.u.inst_ident)->add_func_modifier((yyvsp[-3].u.param_list), (yyvsp[-1].u.integer), nullptr, (yyvsp[0].attr_list)); } -#line 6548 "built/tmp/cppBison.yxx.c" +#line 6552 "built/tmp/cppBison.yxx.c" break; case 268: /* formal_parameter_identifier: '(' formal_parameter_identifier ')' */ @@ -6553,7 +6557,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[-1].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_paren); } -#line 6557 "built/tmp/cppBison.yxx.c" +#line 6561 "built/tmp/cppBison.yxx.c" break; case 269: /* parameter_pack_identifier: ELLIPSIS */ @@ -6562,7 +6566,7 @@ yyreduce: (yyval.u.inst_ident) = new CPPInstanceIdentifier(nullptr); (yyval.u.inst_ident)->_packed = true; } -#line 6566 "built/tmp/cppBison.yxx.c" +#line 6570 "built/tmp/cppBison.yxx.c" break; case 270: /* parameter_pack_identifier: ELLIPSIS name optional_attributes */ @@ -6571,7 +6575,7 @@ yyreduce: (yyval.u.inst_ident) = new CPPInstanceIdentifier((yyvsp[-1].u.identifier), (yyvsp[0].attr_list)); (yyval.u.inst_ident)->_packed = true; } -#line 6575 "built/tmp/cppBison.yxx.c" +#line 6579 "built/tmp/cppBison.yxx.c" break; case 271: /* parameter_pack_identifier: KW_CONST parameter_pack_identifier */ @@ -6580,7 +6584,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_const); } -#line 6584 "built/tmp/cppBison.yxx.c" +#line 6588 "built/tmp/cppBison.yxx.c" break; case 272: /* parameter_pack_identifier: KW_VOLATILE parameter_pack_identifier */ @@ -6589,7 +6593,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_volatile); } -#line 6593 "built/tmp/cppBison.yxx.c" +#line 6597 "built/tmp/cppBison.yxx.c" break; case 273: /* parameter_pack_identifier: '*' optional_attributes parameter_pack_identifier */ @@ -6598,7 +6602,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_pointer, (yyvsp[-1].attr_list)); } -#line 6602 "built/tmp/cppBison.yxx.c" +#line 6606 "built/tmp/cppBison.yxx.c" break; case 274: /* parameter_pack_identifier: '&' optional_attributes parameter_pack_identifier */ @@ -6607,7 +6611,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_reference, (yyvsp[-1].attr_list)); } -#line 6611 "built/tmp/cppBison.yxx.c" +#line 6615 "built/tmp/cppBison.yxx.c" break; case 275: /* parameter_pack_identifier: ANDAND optional_attributes parameter_pack_identifier */ @@ -6616,7 +6620,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_rvalue_reference, (yyvsp[-1].attr_list)); } -#line 6620 "built/tmp/cppBison.yxx.c" +#line 6624 "built/tmp/cppBison.yxx.c" break; case 276: /* parameter_pack_identifier: SCOPING '*' optional_attributes parameter_pack_identifier */ @@ -6625,7 +6629,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_scoped_pointer_modifier((yyvsp[-3].u.identifier), (yyvsp[-1].attr_list)); } -#line 6629 "built/tmp/cppBison.yxx.c" +#line 6633 "built/tmp/cppBison.yxx.c" break; case 277: /* parameter_pack_identifier: parameter_pack_identifier '[' optional_const_expr ']' optional_attributes */ @@ -6634,7 +6638,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[-4].u.inst_ident); (yyval.u.inst_ident)->add_array_modifier((yyvsp[-2].u.expr), (yyvsp[0].attr_list)); } -#line 6638 "built/tmp/cppBison.yxx.c" +#line 6642 "built/tmp/cppBison.yxx.c" break; case 278: /* parameter_pack_identifier: '(' parameter_pack_identifier ')' '(' function_parameter_list ')' function_post optional_attributes */ @@ -6644,7 +6648,7 @@ yyreduce: (yyval.u.inst_ident)->add_modifier(IIT_paren); (yyval.u.inst_ident)->add_func_modifier((yyvsp[-3].u.param_list), (yyvsp[-1].u.integer), nullptr, (yyvsp[0].attr_list)); } -#line 6648 "built/tmp/cppBison.yxx.c" +#line 6652 "built/tmp/cppBison.yxx.c" break; case 279: /* parameter_pack_identifier: '(' parameter_pack_identifier ')' */ @@ -6653,7 +6657,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[-1].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_paren); } -#line 6657 "built/tmp/cppBison.yxx.c" +#line 6661 "built/tmp/cppBison.yxx.c" break; case 280: /* not_paren_empty_instance_identifier: empty */ @@ -6661,7 +6665,7 @@ yyreduce: { (yyval.u.inst_ident) = new CPPInstanceIdentifier(nullptr); } -#line 6665 "built/tmp/cppBison.yxx.c" +#line 6669 "built/tmp/cppBison.yxx.c" break; case 281: /* not_paren_empty_instance_identifier: ELLIPSIS */ @@ -6670,7 +6674,7 @@ yyreduce: (yyval.u.inst_ident) = new CPPInstanceIdentifier(nullptr); (yyval.u.inst_ident)->_packed = true; } -#line 6674 "built/tmp/cppBison.yxx.c" +#line 6678 "built/tmp/cppBison.yxx.c" break; case 282: /* not_paren_empty_instance_identifier: ELLIPSIS name optional_attributes */ @@ -6679,7 +6683,7 @@ yyreduce: (yyval.u.inst_ident) = new CPPInstanceIdentifier((yyvsp[-1].u.identifier), (yyvsp[0].attr_list)); (yyval.u.inst_ident)->_packed = true; } -#line 6683 "built/tmp/cppBison.yxx.c" +#line 6687 "built/tmp/cppBison.yxx.c" break; case 283: /* not_paren_empty_instance_identifier: KW_CONST not_paren_empty_instance_identifier */ @@ -6688,7 +6692,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_const); } -#line 6692 "built/tmp/cppBison.yxx.c" +#line 6696 "built/tmp/cppBison.yxx.c" break; case 284: /* not_paren_empty_instance_identifier: KW_VOLATILE not_paren_empty_instance_identifier */ @@ -6697,7 +6701,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_volatile); } -#line 6701 "built/tmp/cppBison.yxx.c" +#line 6705 "built/tmp/cppBison.yxx.c" break; case 285: /* not_paren_empty_instance_identifier: '*' optional_attributes not_paren_empty_instance_identifier */ @@ -6706,7 +6710,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_pointer, (yyvsp[-1].attr_list)); } -#line 6710 "built/tmp/cppBison.yxx.c" +#line 6714 "built/tmp/cppBison.yxx.c" break; case 286: /* not_paren_empty_instance_identifier: '&' optional_attributes not_paren_empty_instance_identifier */ @@ -6715,7 +6719,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_reference, (yyvsp[-1].attr_list)); } -#line 6719 "built/tmp/cppBison.yxx.c" +#line 6723 "built/tmp/cppBison.yxx.c" break; case 287: /* not_paren_empty_instance_identifier: ANDAND optional_attributes not_paren_empty_instance_identifier */ @@ -6724,7 +6728,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_rvalue_reference, (yyvsp[-1].attr_list)); } -#line 6728 "built/tmp/cppBison.yxx.c" +#line 6732 "built/tmp/cppBison.yxx.c" break; case 288: /* not_paren_empty_instance_identifier: SCOPING '*' optional_attributes not_paren_empty_instance_identifier */ @@ -6733,7 +6737,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_scoped_pointer_modifier((yyvsp[-3].u.identifier), (yyvsp[-1].attr_list)); } -#line 6737 "built/tmp/cppBison.yxx.c" +#line 6741 "built/tmp/cppBison.yxx.c" break; case 289: /* not_paren_empty_instance_identifier: not_paren_empty_instance_identifier '[' optional_const_expr ']' optional_attributes */ @@ -6742,7 +6746,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[-4].u.inst_ident); (yyval.u.inst_ident)->add_array_modifier((yyvsp[-2].u.expr), (yyvsp[0].attr_list)); } -#line 6746 "built/tmp/cppBison.yxx.c" +#line 6750 "built/tmp/cppBison.yxx.c" break; case 290: /* empty_instance_identifier: empty */ @@ -6750,7 +6754,7 @@ yyreduce: { (yyval.u.inst_ident) = new CPPInstanceIdentifier(nullptr); } -#line 6754 "built/tmp/cppBison.yxx.c" +#line 6758 "built/tmp/cppBison.yxx.c" break; case 291: /* empty_instance_identifier: ELLIPSIS */ @@ -6759,7 +6763,7 @@ yyreduce: (yyval.u.inst_ident) = new CPPInstanceIdentifier(nullptr); (yyval.u.inst_ident)->_packed = true; } -#line 6763 "built/tmp/cppBison.yxx.c" +#line 6767 "built/tmp/cppBison.yxx.c" break; case 292: /* empty_instance_identifier: ELLIPSIS name optional_attributes */ @@ -6768,7 +6772,7 @@ yyreduce: (yyval.u.inst_ident) = new CPPInstanceIdentifier((yyvsp[-1].u.identifier), (yyvsp[0].attr_list)); (yyval.u.inst_ident)->_packed = true; } -#line 6772 "built/tmp/cppBison.yxx.c" +#line 6776 "built/tmp/cppBison.yxx.c" break; case 293: /* empty_instance_identifier: KW_CONST empty_instance_identifier */ @@ -6777,7 +6781,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_const); } -#line 6781 "built/tmp/cppBison.yxx.c" +#line 6785 "built/tmp/cppBison.yxx.c" break; case 294: /* empty_instance_identifier: KW_VOLATILE empty_instance_identifier */ @@ -6786,7 +6790,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_volatile); } -#line 6790 "built/tmp/cppBison.yxx.c" +#line 6794 "built/tmp/cppBison.yxx.c" break; case 295: /* empty_instance_identifier: '*' optional_attributes not_paren_empty_instance_identifier */ @@ -6795,7 +6799,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_pointer, (yyvsp[-1].attr_list)); } -#line 6799 "built/tmp/cppBison.yxx.c" +#line 6803 "built/tmp/cppBison.yxx.c" break; case 296: /* empty_instance_identifier: '&' optional_attributes not_paren_empty_instance_identifier */ @@ -6804,7 +6808,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_reference, (yyvsp[-1].attr_list)); } -#line 6808 "built/tmp/cppBison.yxx.c" +#line 6812 "built/tmp/cppBison.yxx.c" break; case 297: /* empty_instance_identifier: ANDAND optional_attributes not_paren_empty_instance_identifier */ @@ -6813,7 +6817,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_rvalue_reference, (yyvsp[-1].attr_list)); } -#line 6817 "built/tmp/cppBison.yxx.c" +#line 6821 "built/tmp/cppBison.yxx.c" break; case 298: /* empty_instance_identifier: SCOPING '*' optional_attributes not_paren_empty_instance_identifier */ @@ -6822,7 +6826,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_scoped_pointer_modifier((yyvsp[-3].u.identifier), (yyvsp[-1].attr_list)); } -#line 6826 "built/tmp/cppBison.yxx.c" +#line 6830 "built/tmp/cppBison.yxx.c" break; case 299: /* empty_instance_identifier: not_paren_empty_instance_identifier '[' optional_const_expr ']' optional_attributes */ @@ -6831,7 +6835,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[-4].u.inst_ident); (yyval.u.inst_ident)->add_array_modifier((yyvsp[-2].u.expr), (yyvsp[0].attr_list)); } -#line 6835 "built/tmp/cppBison.yxx.c" +#line 6839 "built/tmp/cppBison.yxx.c" break; case 300: /* empty_instance_identifier: '(' function_parameter_list ')' function_post optional_attributes maybe_trailing_return_type */ @@ -6841,7 +6845,7 @@ yyreduce: (yyval.u.inst_ident)->add_modifier(IIT_paren); (yyval.u.inst_ident)->add_func_modifier((yyvsp[-4].u.param_list), (yyvsp[-2].u.integer), (yyvsp[0].u.type), (yyvsp[-1].attr_list)); } -#line 6845 "built/tmp/cppBison.yxx.c" +#line 6849 "built/tmp/cppBison.yxx.c" break; case 301: /* empty_instance_identifier: '(' '*' optional_attributes not_paren_empty_instance_identifier ')' '(' function_parameter_list ')' function_post optional_attributes maybe_trailing_return_type */ @@ -6852,7 +6856,7 @@ yyreduce: (yyval.u.inst_ident)->add_modifier(IIT_paren); (yyval.u.inst_ident)->add_func_modifier((yyvsp[-4].u.param_list), (yyvsp[-2].u.integer), (yyvsp[0].u.type), (yyvsp[-1].attr_list)); } -#line 6856 "built/tmp/cppBison.yxx.c" +#line 6860 "built/tmp/cppBison.yxx.c" break; case 302: /* empty_instance_identifier: '(' '&' optional_attributes not_paren_empty_instance_identifier ')' '(' function_parameter_list ')' function_post optional_attributes maybe_trailing_return_type */ @@ -6863,7 +6867,7 @@ yyreduce: (yyval.u.inst_ident)->add_modifier(IIT_paren); (yyval.u.inst_ident)->add_func_modifier((yyvsp[-4].u.param_list), (yyvsp[-2].u.integer), (yyvsp[0].u.type), (yyvsp[-1].attr_list)); } -#line 6867 "built/tmp/cppBison.yxx.c" +#line 6871 "built/tmp/cppBison.yxx.c" break; case 303: /* empty_instance_identifier: '(' ANDAND optional_attributes not_paren_empty_instance_identifier ')' '(' function_parameter_list ')' function_post optional_attributes maybe_trailing_return_type */ @@ -6874,7 +6878,7 @@ yyreduce: (yyval.u.inst_ident)->add_modifier(IIT_paren); (yyval.u.inst_ident)->add_func_modifier((yyvsp[-4].u.param_list), (yyvsp[-2].u.integer), (yyvsp[0].u.type), (yyvsp[-1].attr_list)); } -#line 6878 "built/tmp/cppBison.yxx.c" +#line 6882 "built/tmp/cppBison.yxx.c" break; case 304: /* type: simple_type */ @@ -6882,7 +6886,7 @@ yyreduce: { (yyval.u.type) = CPPType::new_type((yyvsp[0].u.simple_type)); } -#line 6886 "built/tmp/cppBison.yxx.c" +#line 6890 "built/tmp/cppBison.yxx.c" break; case 305: /* type: TYPENAME_IDENTIFIER */ @@ -6894,7 +6898,7 @@ yyreduce: } assert((yyval.u.type) != nullptr); } -#line 6898 "built/tmp/cppBison.yxx.c" +#line 6902 "built/tmp/cppBison.yxx.c" break; case 306: /* type: KW_TYPENAME name */ @@ -6902,7 +6906,7 @@ yyreduce: { (yyval.u.type) = CPPType::new_type(new CPPTBDType((yyvsp[0].u.identifier))); } -#line 6906 "built/tmp/cppBison.yxx.c" +#line 6910 "built/tmp/cppBison.yxx.c" break; case 307: /* type: anonymous_struct */ @@ -6910,7 +6914,7 @@ yyreduce: { (yyval.u.type) = CPPType::new_type((yyvsp[0].u.struct_type)); } -#line 6914 "built/tmp/cppBison.yxx.c" +#line 6918 "built/tmp/cppBison.yxx.c" break; case 308: /* type: named_struct */ @@ -6918,7 +6922,7 @@ yyreduce: { (yyval.u.type) = CPPType::new_type((yyvsp[0].u.struct_type)); } -#line 6922 "built/tmp/cppBison.yxx.c" +#line 6926 "built/tmp/cppBison.yxx.c" break; case 309: /* type: enum */ @@ -6926,7 +6930,7 @@ yyreduce: { (yyval.u.type) = CPPType::new_type((yyvsp[0].u.enum_type)); } -#line 6930 "built/tmp/cppBison.yxx.c" +#line 6934 "built/tmp/cppBison.yxx.c" break; case 310: /* type: struct_keyword optional_attributes name */ @@ -6946,7 +6950,7 @@ yyreduce: (yyval.u.type) = et; } } -#line 6950 "built/tmp/cppBison.yxx.c" +#line 6954 "built/tmp/cppBison.yxx.c" break; case 311: /* type: enum_keyword optional_attributes name_no_final ':' enum_element_type */ @@ -6966,7 +6970,7 @@ yyreduce: (yyval.u.type) = et; } } -#line 6970 "built/tmp/cppBison.yxx.c" +#line 6974 "built/tmp/cppBison.yxx.c" break; case 312: /* type: KW_DECLTYPE '(' const_expr ')' */ @@ -6979,7 +6983,7 @@ yyreduce: yyerror("could not determine type of " + str.str(), (yylsp[-1])); } } -#line 6983 "built/tmp/cppBison.yxx.c" +#line 6987 "built/tmp/cppBison.yxx.c" break; case 313: /* type: KW_DECLTYPE '(' KW_AUTO ')' */ @@ -6987,7 +6991,7 @@ yyreduce: { (yyval.u.type) = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_auto)); } -#line 6991 "built/tmp/cppBison.yxx.c" +#line 6995 "built/tmp/cppBison.yxx.c" break; case 314: /* type: KW_UNDERLYING_TYPE '(' full_type ')' */ @@ -7001,7 +7005,7 @@ yyreduce: (yyval.u.type) = enum_type->get_underlying_type(); } } -#line 7005 "built/tmp/cppBison.yxx.c" +#line 7009 "built/tmp/cppBison.yxx.c" break; case 315: /* type: KW_AUTO */ @@ -7009,7 +7013,7 @@ yyreduce: { (yyval.u.type) = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_auto)); } -#line 7013 "built/tmp/cppBison.yxx.c" +#line 7017 "built/tmp/cppBison.yxx.c" break; case 316: /* type_pack: TYPEPACK_IDENTIFIER */ @@ -7021,7 +7025,7 @@ yyreduce: } assert((yyval.u.type) != nullptr); } -#line 7025 "built/tmp/cppBison.yxx.c" +#line 7029 "built/tmp/cppBison.yxx.c" break; case 317: /* type_decl: simple_type */ @@ -7029,7 +7033,7 @@ yyreduce: { (yyval.u.decl) = CPPType::new_type((yyvsp[0].u.simple_type)); } -#line 7033 "built/tmp/cppBison.yxx.c" +#line 7037 "built/tmp/cppBison.yxx.c" break; case 318: /* type_decl: TYPENAME_IDENTIFIER */ @@ -7041,7 +7045,7 @@ yyreduce: } assert((yyval.u.decl) != nullptr); } -#line 7045 "built/tmp/cppBison.yxx.c" +#line 7049 "built/tmp/cppBison.yxx.c" break; case 319: /* type_decl: KW_TYPENAME name */ @@ -7049,7 +7053,7 @@ yyreduce: { (yyval.u.decl) = CPPType::new_type(new CPPTBDType((yyvsp[0].u.identifier))); } -#line 7053 "built/tmp/cppBison.yxx.c" +#line 7057 "built/tmp/cppBison.yxx.c" break; case 320: /* type_decl: anonymous_struct */ @@ -7057,7 +7061,7 @@ yyreduce: { (yyval.u.decl) = CPPType::new_type((yyvsp[0].u.struct_type)); } -#line 7061 "built/tmp/cppBison.yxx.c" +#line 7065 "built/tmp/cppBison.yxx.c" break; case 321: /* type_decl: named_struct */ @@ -7065,7 +7069,7 @@ yyreduce: { (yyval.u.decl) = new CPPTypeDeclaration(CPPType::new_type((yyvsp[0].u.struct_type))); } -#line 7069 "built/tmp/cppBison.yxx.c" +#line 7073 "built/tmp/cppBison.yxx.c" break; case 322: /* type_decl: enum */ @@ -7073,7 +7077,7 @@ yyreduce: { (yyval.u.decl) = new CPPTypeDeclaration(CPPType::new_type((yyvsp[0].u.enum_type))); } -#line 7077 "built/tmp/cppBison.yxx.c" +#line 7081 "built/tmp/cppBison.yxx.c" break; case 323: /* type_decl: struct_keyword optional_attributes name */ @@ -7093,7 +7097,7 @@ yyreduce: (yyval.u.decl) = et; } } -#line 7097 "built/tmp/cppBison.yxx.c" +#line 7101 "built/tmp/cppBison.yxx.c" break; case 324: /* type_decl: enum_keyword optional_attributes name_no_final ':' enum_element_type */ @@ -7113,7 +7117,7 @@ yyreduce: (yyval.u.decl) = et; } } -#line 7117 "built/tmp/cppBison.yxx.c" +#line 7121 "built/tmp/cppBison.yxx.c" break; case 325: /* type_decl: enum_keyword optional_attributes name */ @@ -7135,7 +7139,7 @@ yyreduce: (yyval.u.decl) = et; } } -#line 7139 "built/tmp/cppBison.yxx.c" +#line 7143 "built/tmp/cppBison.yxx.c" break; case 326: /* type_decl: KW_DECLTYPE '(' const_expr ')' */ @@ -7148,7 +7152,7 @@ yyreduce: yyerror("could not determine type of " + str.str(), (yylsp[-1])); } } -#line 7152 "built/tmp/cppBison.yxx.c" +#line 7156 "built/tmp/cppBison.yxx.c" break; case 327: /* type_decl: KW_DECLTYPE '(' KW_AUTO ')' */ @@ -7156,7 +7160,7 @@ yyreduce: { (yyval.u.decl) = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_auto)); } -#line 7160 "built/tmp/cppBison.yxx.c" +#line 7164 "built/tmp/cppBison.yxx.c" break; case 328: /* type_decl: KW_UNDERLYING_TYPE '(' full_type ')' */ @@ -7170,7 +7174,7 @@ yyreduce: (yyval.u.decl) = enum_type->get_underlying_type(); } } -#line 7174 "built/tmp/cppBison.yxx.c" +#line 7178 "built/tmp/cppBison.yxx.c" break; case 329: /* type_decl: KW_AUTO */ @@ -7178,7 +7182,7 @@ yyreduce: { (yyval.u.decl) = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_auto)); } -#line 7182 "built/tmp/cppBison.yxx.c" +#line 7186 "built/tmp/cppBison.yxx.c" break; case 330: /* predefined_type: simple_type */ @@ -7186,7 +7190,7 @@ yyreduce: { (yyval.u.type) = CPPType::new_type((yyvsp[0].u.simple_type)); } -#line 7190 "built/tmp/cppBison.yxx.c" +#line 7194 "built/tmp/cppBison.yxx.c" break; case 331: /* predefined_type: TYPENAME_IDENTIFIER */ @@ -7198,7 +7202,7 @@ yyreduce: } assert((yyval.u.type) != nullptr); } -#line 7202 "built/tmp/cppBison.yxx.c" +#line 7206 "built/tmp/cppBison.yxx.c" break; case 332: /* predefined_type: KW_TYPENAME name */ @@ -7206,7 +7210,7 @@ yyreduce: { (yyval.u.type) = CPPType::new_type(new CPPTBDType((yyvsp[0].u.identifier))); } -#line 7210 "built/tmp/cppBison.yxx.c" +#line 7214 "built/tmp/cppBison.yxx.c" break; case 333: /* predefined_type: struct_keyword optional_attributes name */ @@ -7226,7 +7230,7 @@ yyreduce: (yyval.u.type) = et; } } -#line 7230 "built/tmp/cppBison.yxx.c" +#line 7234 "built/tmp/cppBison.yxx.c" break; case 334: /* predefined_type: enum_keyword optional_attributes name */ @@ -7246,7 +7250,7 @@ yyreduce: (yyval.u.type) = et; } } -#line 7250 "built/tmp/cppBison.yxx.c" +#line 7254 "built/tmp/cppBison.yxx.c" break; case 335: /* predefined_type: KW_DECLTYPE '(' const_expr ')' */ @@ -7259,7 +7263,7 @@ yyreduce: yyerror("could not determine type of " + str.str(), (yylsp[-1])); } } -#line 7263 "built/tmp/cppBison.yxx.c" +#line 7267 "built/tmp/cppBison.yxx.c" break; case 336: /* predefined_type: KW_UNDERLYING_TYPE '(' full_type ')' */ @@ -7273,7 +7277,7 @@ yyreduce: (yyval.u.type) = enum_type->get_underlying_type(); } } -#line 7277 "built/tmp/cppBison.yxx.c" +#line 7281 "built/tmp/cppBison.yxx.c" break; case 337: /* predefined_type: KW_AUTO */ @@ -7281,7 +7285,7 @@ yyreduce: { (yyval.u.type) = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_auto)); } -#line 7285 "built/tmp/cppBison.yxx.c" +#line 7289 "built/tmp/cppBison.yxx.c" break; case 338: /* var_type_decl: type_decl */ @@ -7289,7 +7293,7 @@ yyreduce: { (yyval.u.decl) = (yyvsp[0].u.decl); } -#line 7293 "built/tmp/cppBison.yxx.c" +#line 7297 "built/tmp/cppBison.yxx.c" break; case 339: /* var_type_decl: IDENTIFIER */ @@ -7299,7 +7303,7 @@ yyreduce: (yyval.u.decl) = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_unknown)); } -#line 7303 "built/tmp/cppBison.yxx.c" +#line 7307 "built/tmp/cppBison.yxx.c" break; case 340: /* full_type: type empty_instance_identifier */ @@ -7307,7 +7311,7 @@ yyreduce: { (yyval.u.type) = (yyvsp[0].u.inst_ident)->unroll_type((yyvsp[-1].u.type)); } -#line 7311 "built/tmp/cppBison.yxx.c" +#line 7315 "built/tmp/cppBison.yxx.c" break; case 341: /* full_type: KW_CONST type empty_instance_identifier */ @@ -7316,7 +7320,7 @@ yyreduce: (yyvsp[0].u.inst_ident)->add_modifier(IIT_const); (yyval.u.type) = (yyvsp[0].u.inst_ident)->unroll_type((yyvsp[-1].u.type)); } -#line 7320 "built/tmp/cppBison.yxx.c" +#line 7324 "built/tmp/cppBison.yxx.c" break; case 342: /* full_type: type_pack empty_instance_identifier */ @@ -7324,7 +7328,7 @@ yyreduce: { (yyval.u.type) = (yyvsp[0].u.inst_ident)->unroll_type((yyvsp[-1].u.type)); } -#line 7328 "built/tmp/cppBison.yxx.c" +#line 7332 "built/tmp/cppBison.yxx.c" break; case 343: /* full_type: KW_CONST type_pack empty_instance_identifier */ @@ -7333,7 +7337,7 @@ yyreduce: (yyvsp[0].u.inst_ident)->add_modifier(IIT_const); (yyval.u.type) = (yyvsp[0].u.inst_ident)->unroll_type((yyvsp[-1].u.type)); } -#line 7337 "built/tmp/cppBison.yxx.c" +#line 7341 "built/tmp/cppBison.yxx.c" break; case 344: /* $@17: %empty */ @@ -7351,7 +7355,7 @@ yyreduce: push_scope(new_scope); push_struct(st); } -#line 7355 "built/tmp/cppBison.yxx.c" +#line 7359 "built/tmp/cppBison.yxx.c" break; case 345: /* anonymous_struct: struct_keyword optional_attributes '{' $@17 cpp '}' */ @@ -7362,7 +7366,7 @@ yyreduce: pop_struct(); pop_scope(); } -#line 7366 "built/tmp/cppBison.yxx.c" +#line 7370 "built/tmp/cppBison.yxx.c" break; case 346: /* $@18: %empty */ @@ -7386,7 +7390,7 @@ yyreduce: push_scope(new_scope); push_struct(st); } -#line 7390 "built/tmp/cppBison.yxx.c" +#line 7394 "built/tmp/cppBison.yxx.c" break; case 347: /* named_struct: struct_keyword optional_attributes name_no_final $@18 maybe_final maybe_class_derivation '{' cpp '}' */ @@ -7397,7 +7401,7 @@ yyreduce: pop_struct(); pop_scope(); } -#line 7401 "built/tmp/cppBison.yxx.c" +#line 7405 "built/tmp/cppBison.yxx.c" break; case 349: /* maybe_final: KW_FINAL */ @@ -7405,7 +7409,7 @@ yyreduce: { current_struct->_final = true; } -#line 7409 "built/tmp/cppBison.yxx.c" +#line 7413 "built/tmp/cppBison.yxx.c" break; case 354: /* base_specification: class_derivation_name */ @@ -7413,7 +7417,7 @@ yyreduce: { current_struct->append_derivation((yyvsp[0].u.type), V_unknown, false); } -#line 7417 "built/tmp/cppBison.yxx.c" +#line 7421 "built/tmp/cppBison.yxx.c" break; case 355: /* base_specification: KW_PUBLIC class_derivation_name */ @@ -7421,7 +7425,7 @@ yyreduce: { current_struct->append_derivation((yyvsp[0].u.type), V_public, false); } -#line 7425 "built/tmp/cppBison.yxx.c" +#line 7429 "built/tmp/cppBison.yxx.c" break; case 356: /* base_specification: KW_PROTECTED class_derivation_name */ @@ -7429,7 +7433,7 @@ yyreduce: { current_struct->append_derivation((yyvsp[0].u.type), V_protected, false); } -#line 7433 "built/tmp/cppBison.yxx.c" +#line 7437 "built/tmp/cppBison.yxx.c" break; case 357: /* base_specification: KW_PRIVATE class_derivation_name */ @@ -7437,7 +7441,7 @@ yyreduce: { current_struct->append_derivation((yyvsp[0].u.type), V_private, false); } -#line 7441 "built/tmp/cppBison.yxx.c" +#line 7445 "built/tmp/cppBison.yxx.c" break; case 358: /* base_specification: KW_VIRTUAL KW_PUBLIC class_derivation_name */ @@ -7445,7 +7449,7 @@ yyreduce: { current_struct->append_derivation((yyvsp[0].u.type), V_public, true); } -#line 7449 "built/tmp/cppBison.yxx.c" +#line 7453 "built/tmp/cppBison.yxx.c" break; case 359: /* base_specification: KW_VIRTUAL KW_PROTECTED class_derivation_name */ @@ -7453,7 +7457,7 @@ yyreduce: { current_struct->append_derivation((yyvsp[0].u.type), V_protected, true); } -#line 7457 "built/tmp/cppBison.yxx.c" +#line 7461 "built/tmp/cppBison.yxx.c" break; case 360: /* base_specification: KW_VIRTUAL KW_PRIVATE class_derivation_name */ @@ -7461,7 +7465,7 @@ yyreduce: { current_struct->append_derivation((yyvsp[0].u.type), V_private, true); } -#line 7465 "built/tmp/cppBison.yxx.c" +#line 7469 "built/tmp/cppBison.yxx.c" break; case 361: /* base_specification: KW_PUBLIC KW_VIRTUAL class_derivation_name */ @@ -7469,7 +7473,7 @@ yyreduce: { current_struct->append_derivation((yyvsp[0].u.type), V_public, true); } -#line 7473 "built/tmp/cppBison.yxx.c" +#line 7477 "built/tmp/cppBison.yxx.c" break; case 362: /* base_specification: KW_PROTECTED KW_VIRTUAL class_derivation_name */ @@ -7477,7 +7481,7 @@ yyreduce: { current_struct->append_derivation((yyvsp[0].u.type), V_protected, true); } -#line 7481 "built/tmp/cppBison.yxx.c" +#line 7485 "built/tmp/cppBison.yxx.c" break; case 363: /* base_specification: KW_PRIVATE KW_VIRTUAL class_derivation_name */ @@ -7485,154 +7489,167 @@ yyreduce: { current_struct->append_derivation((yyvsp[0].u.type), V_private, true); } -#line 7489 "built/tmp/cppBison.yxx.c" +#line 7493 "built/tmp/cppBison.yxx.c" break; - case 364: /* enum: enum_decl '{' enum_body '}' */ + case 364: /* $@19: %empty */ #line 2975 "dtool/src/cppparser/cppBison.yxx" { + if (current_enum->_scope != nullptr) { + push_scope(current_enum->_scope); + } +} +#line 7503 "built/tmp/cppBison.yxx.c" + break; + + case 365: /* enum: enum_decl $@19 '{' enum_body '}' */ +#line 2981 "dtool/src/cppparser/cppBison.yxx" +{ + if (current_enum->_scope != nullptr) { + pop_scope(); + } (yyval.u.enum_type) = current_enum; current_enum = nullptr; } -#line 7498 "built/tmp/cppBison.yxx.c" +#line 7515 "built/tmp/cppBison.yxx.c" break; - case 365: /* enum_decl: enum_keyword optional_attributes ':' enum_element_type */ -#line 2983 "dtool/src/cppparser/cppBison.yxx" + case 366: /* enum_decl: enum_keyword optional_attributes ':' enum_element_type */ +#line 2992 "dtool/src/cppparser/cppBison.yxx" { current_enum = new CPPEnumType((yyvsp[-3].u.extension_enum), nullptr, (yyvsp[0].u.type), current_scope, nullptr, (yylsp[-3]).file, (yyvsp[-2].attr_list)); } -#line 7506 "built/tmp/cppBison.yxx.c" - break; - - case 366: /* enum_decl: enum_keyword optional_attributes */ -#line 2987 "dtool/src/cppparser/cppBison.yxx" -{ - current_enum = new CPPEnumType((yyvsp[-1].u.extension_enum), nullptr, current_scope, nullptr, (yylsp[-1]).file, (yyvsp[0].attr_list)); -} -#line 7514 "built/tmp/cppBison.yxx.c" - break; - - case 367: /* enum_decl: enum_keyword optional_attributes name_no_final ':' enum_element_type */ -#line 2991 "dtool/src/cppparser/cppBison.yxx" -{ - CPPScope *new_scope = new CPPScope(current_scope, (yyvsp[-2].u.identifier)->_names.back(), V_public); - current_enum = new CPPEnumType((yyvsp[-4].u.extension_enum), (yyvsp[-2].u.identifier), (yyvsp[0].u.type), current_scope, new_scope, (yylsp[-4]).file, (yyvsp[-3].attr_list)); -} #line 7523 "built/tmp/cppBison.yxx.c" break; - case 368: /* enum_decl: enum_keyword optional_attributes name_no_final */ + case 367: /* enum_decl: enum_keyword optional_attributes */ #line 2996 "dtool/src/cppparser/cppBison.yxx" { - CPPScope *new_scope = new CPPScope(current_scope, (yyvsp[0].u.identifier)->_names.back(), V_public); - current_enum = new CPPEnumType((yyvsp[-2].u.extension_enum), (yyvsp[0].u.identifier), current_scope, new_scope, (yylsp[-2]).file, (yyvsp[-1].attr_list)); + current_enum = new CPPEnumType((yyvsp[-1].u.extension_enum), nullptr, current_scope, nullptr, (yylsp[-1]).file, (yyvsp[0].attr_list)); } -#line 7532 "built/tmp/cppBison.yxx.c" +#line 7531 "built/tmp/cppBison.yxx.c" break; - case 369: /* enum_element_type: simple_int_type */ -#line 3004 "dtool/src/cppparser/cppBison.yxx" + case 368: /* enum_decl: enum_keyword optional_attributes name_no_final ':' enum_element_type */ +#line 3000 "dtool/src/cppparser/cppBison.yxx" { - (yyval.u.type) = CPPType::new_type((yyvsp[0].u.simple_type)); + CPPScope *new_scope = new CPPScope(current_scope, (yyvsp[-2].u.identifier)->_names.back(), V_public); + current_enum = new CPPEnumType((yyvsp[-4].u.extension_enum), (yyvsp[-2].u.identifier), (yyvsp[0].u.type), current_scope, new_scope, (yylsp[-4]).file, (yyvsp[-3].attr_list)); } #line 7540 "built/tmp/cppBison.yxx.c" break; - case 370: /* enum_element_type: TYPENAME_IDENTIFIER */ -#line 3008 "dtool/src/cppparser/cppBison.yxx" + case 369: /* enum_decl: enum_keyword optional_attributes name_no_final */ +#line 3005 "dtool/src/cppparser/cppBison.yxx" { - (yyval.u.type) = (yyvsp[0].u.identifier)->find_type(current_scope, global_scope, false, current_lexer); + CPPScope *new_scope = new CPPScope(current_scope, (yyvsp[0].u.identifier)->_names.back(), V_public); + current_enum = new CPPEnumType((yyvsp[-2].u.extension_enum), (yyvsp[0].u.identifier), current_scope, new_scope, (yylsp[-2]).file, (yyvsp[-1].attr_list)); } -#line 7548 "built/tmp/cppBison.yxx.c" +#line 7549 "built/tmp/cppBison.yxx.c" break; - case 372: /* enum_body_trailing_comma: enum_body_trailing_comma name optional_attributes ',' */ -#line 3016 "dtool/src/cppparser/cppBison.yxx" + case 370: /* enum_element_type: simple_int_type */ +#line 3013 "dtool/src/cppparser/cppBison.yxx" { - assert(current_enum != nullptr); - current_enum->add_element((yyvsp[-2].u.identifier)->get_simple_name(), nullptr, current_lexer, (yylsp[-2]), (yyvsp[-1].attr_list)); + (yyval.u.type) = CPPType::new_type((yyvsp[0].u.simple_type)); } #line 7557 "built/tmp/cppBison.yxx.c" break; - case 373: /* enum_body_trailing_comma: enum_body_trailing_comma name optional_attributes '=' const_expr ',' */ -#line 3021 "dtool/src/cppparser/cppBison.yxx" + case 371: /* enum_element_type: TYPENAME_IDENTIFIER */ +#line 3017 "dtool/src/cppparser/cppBison.yxx" +{ + (yyval.u.type) = (yyvsp[0].u.identifier)->find_type(current_scope, global_scope, false, current_lexer); +} +#line 7565 "built/tmp/cppBison.yxx.c" + break; + + case 373: /* enum_body_trailing_comma: enum_body_trailing_comma name optional_attributes ',' */ +#line 3025 "dtool/src/cppparser/cppBison.yxx" +{ + assert(current_enum != nullptr); + current_enum->add_element((yyvsp[-2].u.identifier)->get_simple_name(), nullptr, current_lexer, (yylsp[-2]), (yyvsp[-1].attr_list)); +} +#line 7574 "built/tmp/cppBison.yxx.c" + break; + + case 374: /* enum_body_trailing_comma: enum_body_trailing_comma name optional_attributes '=' const_expr ',' */ +#line 3030 "dtool/src/cppparser/cppBison.yxx" { assert(current_enum != nullptr); current_enum->add_element((yyvsp[-4].u.identifier)->get_simple_name(), (yyvsp[-1].u.expr), current_lexer, (yylsp[-4]), (yyvsp[-3].attr_list)); } -#line 7566 "built/tmp/cppBison.yxx.c" +#line 7583 "built/tmp/cppBison.yxx.c" break; - case 375: /* enum_body: enum_body_trailing_comma name optional_attributes */ -#line 3029 "dtool/src/cppparser/cppBison.yxx" + case 376: /* enum_body: enum_body_trailing_comma name optional_attributes */ +#line 3038 "dtool/src/cppparser/cppBison.yxx" { assert(current_enum != nullptr); current_enum->add_element((yyvsp[-1].u.identifier)->get_simple_name(), nullptr, current_lexer, (yylsp[-1]), (yyvsp[0].attr_list)); } -#line 7575 "built/tmp/cppBison.yxx.c" +#line 7592 "built/tmp/cppBison.yxx.c" break; - case 376: /* enum_body: enum_body_trailing_comma name optional_attributes '=' const_expr */ -#line 3034 "dtool/src/cppparser/cppBison.yxx" + case 377: /* enum_body: enum_body_trailing_comma name optional_attributes '=' const_expr */ +#line 3043 "dtool/src/cppparser/cppBison.yxx" { assert(current_enum != nullptr); current_enum->add_element((yyvsp[-3].u.identifier)->get_simple_name(), (yyvsp[0].u.expr), current_lexer, (yylsp[-3]), (yyvsp[-2].attr_list)); } -#line 7584 "built/tmp/cppBison.yxx.c" +#line 7601 "built/tmp/cppBison.yxx.c" break; - case 377: /* enum_keyword: KW_ENUM */ -#line 3042 "dtool/src/cppparser/cppBison.yxx" + case 378: /* enum_keyword: KW_ENUM */ +#line 3051 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.extension_enum) = CPPExtensionType::T_enum; } -#line 7592 "built/tmp/cppBison.yxx.c" +#line 7609 "built/tmp/cppBison.yxx.c" break; - case 378: /* enum_keyword: KW_ENUM KW_CLASS */ -#line 3046 "dtool/src/cppparser/cppBison.yxx" + case 379: /* enum_keyword: KW_ENUM KW_CLASS */ +#line 3055 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.extension_enum) = CPPExtensionType::T_enum_class; } -#line 7600 "built/tmp/cppBison.yxx.c" +#line 7617 "built/tmp/cppBison.yxx.c" break; - case 379: /* enum_keyword: KW_ENUM KW_STRUCT */ -#line 3050 "dtool/src/cppparser/cppBison.yxx" + case 380: /* enum_keyword: KW_ENUM KW_STRUCT */ +#line 3059 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.extension_enum) = CPPExtensionType::T_enum_struct; } -#line 7608 "built/tmp/cppBison.yxx.c" +#line 7625 "built/tmp/cppBison.yxx.c" break; - case 380: /* struct_keyword: KW_CLASS */ -#line 3057 "dtool/src/cppparser/cppBison.yxx" + case 381: /* struct_keyword: KW_CLASS */ +#line 3066 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.extension_enum) = CPPExtensionType::T_class; } -#line 7616 "built/tmp/cppBison.yxx.c" +#line 7633 "built/tmp/cppBison.yxx.c" break; - case 381: /* struct_keyword: KW_STRUCT */ -#line 3061 "dtool/src/cppparser/cppBison.yxx" + case 382: /* struct_keyword: KW_STRUCT */ +#line 3070 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.extension_enum) = CPPExtensionType::T_struct; } -#line 7624 "built/tmp/cppBison.yxx.c" +#line 7641 "built/tmp/cppBison.yxx.c" break; - case 382: /* struct_keyword: KW_UNION */ -#line 3065 "dtool/src/cppparser/cppBison.yxx" + case 383: /* struct_keyword: KW_UNION */ +#line 3074 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.extension_enum) = CPPExtensionType::T_union; } -#line 7632 "built/tmp/cppBison.yxx.c" +#line 7649 "built/tmp/cppBison.yxx.c" break; - case 383: /* $@19: %empty */ -#line 3072 "dtool/src/cppparser/cppBison.yxx" + case 384: /* $@20: %empty */ +#line 3081 "dtool/src/cppparser/cppBison.yxx" { CPPScope *scope = (yyvsp[-1].u.identifier)->find_scope(current_scope, global_scope, current_lexer); if (scope == nullptr) { @@ -7650,19 +7667,19 @@ yyreduce: current_scope->define_namespace(nspace); push_scope(scope); } -#line 7654 "built/tmp/cppBison.yxx.c" +#line 7671 "built/tmp/cppBison.yxx.c" break; - case 384: /* namespace_declaration: KW_NAMESPACE optional_attributes name '{' $@19 cpp '}' */ -#line 3090 "dtool/src/cppparser/cppBison.yxx" + case 385: /* namespace_declaration: KW_NAMESPACE optional_attributes name '{' $@20 cpp '}' */ +#line 3099 "dtool/src/cppparser/cppBison.yxx" { pop_scope(); } -#line 7662 "built/tmp/cppBison.yxx.c" +#line 7679 "built/tmp/cppBison.yxx.c" break; - case 385: /* $@20: %empty */ -#line 3094 "dtool/src/cppparser/cppBison.yxx" + case 386: /* $@21: %empty */ +#line 3103 "dtool/src/cppparser/cppBison.yxx" { CPPScope *scope = (yyvsp[-1].u.identifier)->find_scope(current_scope, global_scope, current_lexer); if (scope == nullptr) { @@ -7681,161 +7698,161 @@ yyreduce: current_scope->define_namespace(nspace); push_scope(scope); } -#line 7685 "built/tmp/cppBison.yxx.c" +#line 7702 "built/tmp/cppBison.yxx.c" break; - case 386: /* namespace_declaration: KW_INLINE KW_NAMESPACE name '{' $@20 cpp '}' */ -#line 3113 "dtool/src/cppparser/cppBison.yxx" + case 387: /* namespace_declaration: KW_INLINE KW_NAMESPACE name '{' $@21 cpp '}' */ +#line 3122 "dtool/src/cppparser/cppBison.yxx" { pop_scope(); } -#line 7693 "built/tmp/cppBison.yxx.c" +#line 7710 "built/tmp/cppBison.yxx.c" break; - case 389: /* using_declaration: KW_USING name ';' */ -#line 3122 "dtool/src/cppparser/cppBison.yxx" + case 390: /* using_declaration: KW_USING name ';' */ +#line 3131 "dtool/src/cppparser/cppBison.yxx" { CPPUsing *using_decl = new CPPUsing((yyvsp[-1].u.identifier), false, (yylsp[-2]).file); current_scope->add_declaration(using_decl, global_scope, current_lexer, (yylsp[-2])); current_scope->add_using(using_decl, global_scope, current_lexer); } -#line 7703 "built/tmp/cppBison.yxx.c" +#line 7720 "built/tmp/cppBison.yxx.c" break; - case 390: /* using_declaration: KW_USING name optional_attributes '=' full_type ';' */ -#line 3128 "dtool/src/cppparser/cppBison.yxx" + case 391: /* using_declaration: KW_USING name optional_attributes '=' full_type ';' */ +#line 3137 "dtool/src/cppparser/cppBison.yxx" { // This is really just an alternative way to declare a typedef. CPPTypedefType *typedef_type = new CPPTypedefType((yyvsp[-1].u.type), (yyvsp[-4].u.identifier), current_scope, (yyvsp[-3].attr_list)); typedef_type->_using = true; current_scope->add_declaration(CPPType::new_type(typedef_type), global_scope, current_lexer, (yylsp[-5])); } -#line 7714 "built/tmp/cppBison.yxx.c" +#line 7731 "built/tmp/cppBison.yxx.c" break; - case 391: /* using_declaration: KW_USING KW_NAMESPACE name ';' */ -#line 3135 "dtool/src/cppparser/cppBison.yxx" + case 392: /* using_declaration: KW_USING KW_NAMESPACE name ';' */ +#line 3144 "dtool/src/cppparser/cppBison.yxx" { CPPUsing *using_decl = new CPPUsing((yyvsp[-1].u.identifier), true, (yylsp[-3]).file); current_scope->add_declaration(using_decl, global_scope, current_lexer, (yylsp[-3])); current_scope->add_using(using_decl, global_scope, current_lexer); } -#line 7724 "built/tmp/cppBison.yxx.c" +#line 7741 "built/tmp/cppBison.yxx.c" break; - case 392: /* using_declaration: KW_USING KW_ENUM name ';' */ -#line 3141 "dtool/src/cppparser/cppBison.yxx" + case 393: /* using_declaration: KW_USING KW_ENUM name ';' */ +#line 3150 "dtool/src/cppparser/cppBison.yxx" { CPPUsing *using_decl = new CPPUsing((yyvsp[-1].u.identifier), false, (yylsp[-3]).file); current_scope->add_declaration(using_decl, global_scope, current_lexer, (yylsp[-3])); current_scope->add_using(using_decl, global_scope, current_lexer); } -#line 7734 "built/tmp/cppBison.yxx.c" +#line 7751 "built/tmp/cppBison.yxx.c" break; - case 396: /* simple_int_type: KW_BOOL */ -#line 3156 "dtool/src/cppparser/cppBison.yxx" + case 397: /* simple_int_type: KW_BOOL */ +#line 3165 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.simple_type) = new CPPSimpleType(CPPSimpleType::T_bool); } -#line 7742 "built/tmp/cppBison.yxx.c" +#line 7759 "built/tmp/cppBison.yxx.c" break; - case 397: /* simple_int_type: KW_CHAR */ -#line 3160 "dtool/src/cppparser/cppBison.yxx" + case 398: /* simple_int_type: KW_CHAR */ +#line 3169 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.simple_type) = new CPPSimpleType(CPPSimpleType::T_char); } -#line 7750 "built/tmp/cppBison.yxx.c" +#line 7767 "built/tmp/cppBison.yxx.c" break; - case 398: /* simple_int_type: KW_WCHAR_T */ -#line 3164 "dtool/src/cppparser/cppBison.yxx" + case 399: /* simple_int_type: KW_WCHAR_T */ +#line 3173 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.simple_type) = new CPPSimpleType(CPPSimpleType::T_wchar_t); } -#line 7758 "built/tmp/cppBison.yxx.c" +#line 7775 "built/tmp/cppBison.yxx.c" break; - case 399: /* simple_int_type: KW_CHAR8_T */ -#line 3168 "dtool/src/cppparser/cppBison.yxx" + case 400: /* simple_int_type: KW_CHAR8_T */ +#line 3177 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.simple_type) = new CPPSimpleType(CPPSimpleType::T_char8_t); } -#line 7766 "built/tmp/cppBison.yxx.c" +#line 7783 "built/tmp/cppBison.yxx.c" break; - case 400: /* simple_int_type: KW_CHAR16_T */ -#line 3172 "dtool/src/cppparser/cppBison.yxx" + case 401: /* simple_int_type: KW_CHAR16_T */ +#line 3181 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.simple_type) = new CPPSimpleType(CPPSimpleType::T_char16_t); } -#line 7774 "built/tmp/cppBison.yxx.c" - break; - - case 401: /* simple_int_type: KW_CHAR32_T */ -#line 3176 "dtool/src/cppparser/cppBison.yxx" -{ - (yyval.u.simple_type) = new CPPSimpleType(CPPSimpleType::T_char32_t); -} -#line 7782 "built/tmp/cppBison.yxx.c" - break; - - case 402: /* simple_int_type: KW_SHORT */ -#line 3180 "dtool/src/cppparser/cppBison.yxx" -{ - (yyval.u.simple_type) = new CPPSimpleType(CPPSimpleType::T_int, - CPPSimpleType::F_short); -} #line 7791 "built/tmp/cppBison.yxx.c" break; - case 403: /* simple_int_type: KW_LONG */ + case 402: /* simple_int_type: KW_CHAR32_T */ #line 3185 "dtool/src/cppparser/cppBison.yxx" +{ + (yyval.u.simple_type) = new CPPSimpleType(CPPSimpleType::T_char32_t); +} +#line 7799 "built/tmp/cppBison.yxx.c" + break; + + case 403: /* simple_int_type: KW_SHORT */ +#line 3189 "dtool/src/cppparser/cppBison.yxx" +{ + (yyval.u.simple_type) = new CPPSimpleType(CPPSimpleType::T_int, + CPPSimpleType::F_short); +} +#line 7808 "built/tmp/cppBison.yxx.c" + break; + + case 404: /* simple_int_type: KW_LONG */ +#line 3194 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.simple_type) = new CPPSimpleType(CPPSimpleType::T_int, CPPSimpleType::F_long); } -#line 7800 "built/tmp/cppBison.yxx.c" +#line 7817 "built/tmp/cppBison.yxx.c" break; - case 404: /* simple_int_type: KW_UNSIGNED */ -#line 3190 "dtool/src/cppparser/cppBison.yxx" + case 405: /* simple_int_type: KW_UNSIGNED */ +#line 3199 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.simple_type) = new CPPSimpleType(CPPSimpleType::T_int, CPPSimpleType::F_unsigned); } -#line 7809 "built/tmp/cppBison.yxx.c" +#line 7826 "built/tmp/cppBison.yxx.c" break; - case 405: /* simple_int_type: KW_SIGNED */ -#line 3195 "dtool/src/cppparser/cppBison.yxx" + case 406: /* simple_int_type: KW_SIGNED */ +#line 3204 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.simple_type) = new CPPSimpleType(CPPSimpleType::T_int, CPPSimpleType::F_signed); } -#line 7818 "built/tmp/cppBison.yxx.c" +#line 7835 "built/tmp/cppBison.yxx.c" break; - case 406: /* simple_int_type: KW_INT */ -#line 3200 "dtool/src/cppparser/cppBison.yxx" + case 407: /* simple_int_type: KW_INT */ +#line 3209 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.simple_type) = new CPPSimpleType(CPPSimpleType::T_int); } -#line 7826 "built/tmp/cppBison.yxx.c" +#line 7843 "built/tmp/cppBison.yxx.c" break; - case 407: /* simple_int_type: KW_SHORT simple_int_type */ -#line 3204 "dtool/src/cppparser/cppBison.yxx" + case 408: /* simple_int_type: KW_SHORT simple_int_type */ +#line 3213 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.simple_type) = (yyvsp[0].u.simple_type); (yyval.u.simple_type)->_flags |= CPPSimpleType::F_short; } -#line 7835 "built/tmp/cppBison.yxx.c" +#line 7852 "built/tmp/cppBison.yxx.c" break; - case 408: /* simple_int_type: KW_LONG simple_int_type */ -#line 3209 "dtool/src/cppparser/cppBison.yxx" + case 409: /* simple_int_type: KW_LONG simple_int_type */ +#line 3218 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.simple_type) = (yyvsp[0].u.simple_type); if ((yyval.u.simple_type)->_flags & CPPSimpleType::F_long) { @@ -7844,501 +7861,501 @@ yyreduce: (yyval.u.simple_type)->_flags |= CPPSimpleType::F_long; } } -#line 7848 "built/tmp/cppBison.yxx.c" +#line 7865 "built/tmp/cppBison.yxx.c" break; - case 409: /* simple_int_type: KW_UNSIGNED simple_int_type */ -#line 3218 "dtool/src/cppparser/cppBison.yxx" + case 410: /* simple_int_type: KW_UNSIGNED simple_int_type */ +#line 3227 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.simple_type) = (yyvsp[0].u.simple_type); (yyval.u.simple_type)->_flags |= CPPSimpleType::F_unsigned; } -#line 7857 "built/tmp/cppBison.yxx.c" +#line 7874 "built/tmp/cppBison.yxx.c" break; - case 410: /* simple_int_type: KW_SIGNED simple_int_type */ -#line 3223 "dtool/src/cppparser/cppBison.yxx" + case 411: /* simple_int_type: KW_SIGNED simple_int_type */ +#line 3232 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.simple_type) = (yyvsp[0].u.simple_type); (yyval.u.simple_type)->_flags |= CPPSimpleType::F_signed; } -#line 7866 "built/tmp/cppBison.yxx.c" +#line 7883 "built/tmp/cppBison.yxx.c" break; - case 411: /* simple_float_type: KW_FLOAT */ -#line 3231 "dtool/src/cppparser/cppBison.yxx" + case 412: /* simple_float_type: KW_FLOAT */ +#line 3240 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.simple_type) = new CPPSimpleType(CPPSimpleType::T_float); } -#line 7874 "built/tmp/cppBison.yxx.c" - break; - - case 412: /* simple_float_type: KW_DOUBLE */ -#line 3235 "dtool/src/cppparser/cppBison.yxx" -{ - (yyval.u.simple_type) = new CPPSimpleType(CPPSimpleType::T_double); -} -#line 7882 "built/tmp/cppBison.yxx.c" - break; - - case 413: /* simple_float_type: KW_LONG KW_DOUBLE */ -#line 3239 "dtool/src/cppparser/cppBison.yxx" -{ - (yyval.u.simple_type) = new CPPSimpleType(CPPSimpleType::T_double, - CPPSimpleType::F_long); -} #line 7891 "built/tmp/cppBison.yxx.c" break; - case 414: /* simple_void_type: KW_VOID */ -#line 3247 "dtool/src/cppparser/cppBison.yxx" + case 413: /* simple_float_type: KW_DOUBLE */ +#line 3244 "dtool/src/cppparser/cppBison.yxx" { - (yyval.u.simple_type) = new CPPSimpleType(CPPSimpleType::T_void); + (yyval.u.simple_type) = new CPPSimpleType(CPPSimpleType::T_double); } #line 7899 "built/tmp/cppBison.yxx.c" break; - case 415: /* $@21: %empty */ + case 414: /* simple_float_type: KW_LONG KW_DOUBLE */ +#line 3248 "dtool/src/cppparser/cppBison.yxx" +{ + (yyval.u.simple_type) = new CPPSimpleType(CPPSimpleType::T_double, + CPPSimpleType::F_long); +} +#line 7908 "built/tmp/cppBison.yxx.c" + break; + + case 415: /* simple_void_type: KW_VOID */ #line 3256 "dtool/src/cppparser/cppBison.yxx" +{ + (yyval.u.simple_type) = new CPPSimpleType(CPPSimpleType::T_void); +} +#line 7916 "built/tmp/cppBison.yxx.c" + break; + + case 416: /* $@22: %empty */ +#line 3265 "dtool/src/cppparser/cppBison.yxx" { current_lexer->_resolve_identifiers = false; } -#line 7907 "built/tmp/cppBison.yxx.c" +#line 7924 "built/tmp/cppBison.yxx.c" break; - case 416: /* code: $@21 code_block */ -#line 3260 "dtool/src/cppparser/cppBison.yxx" + case 417: /* code: $@22 code_block */ +#line 3269 "dtool/src/cppparser/cppBison.yxx" { current_lexer->_resolve_identifiers = true; } -#line 7915 "built/tmp/cppBison.yxx.c" +#line 7932 "built/tmp/cppBison.yxx.c" break; - case 531: /* element: KW_WHILE */ -#line 3305 "dtool/src/cppparser/cppBison.yxx" -{ -} -#line 7922 "built/tmp/cppBison.yxx.c" - break; - - case 555: /* optional_const_expr: empty */ + case 532: /* element: KW_WHILE */ #line 3314 "dtool/src/cppparser/cppBison.yxx" { - (yyval.u.expr) = nullptr; } -#line 7930 "built/tmp/cppBison.yxx.c" +#line 7939 "built/tmp/cppBison.yxx.c" break; - case 556: /* optional_const_expr: const_expr */ -#line 3318 "dtool/src/cppparser/cppBison.yxx" -{ - (yyval.u.expr) = (yyvsp[0].u.expr); -} -#line 7938 "built/tmp/cppBison.yxx.c" - break; - - case 557: /* optional_const_expr_comma: empty */ -#line 3325 "dtool/src/cppparser/cppBison.yxx" + case 556: /* optional_const_expr: empty */ +#line 3323 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = nullptr; } -#line 7946 "built/tmp/cppBison.yxx.c" +#line 7947 "built/tmp/cppBison.yxx.c" break; - case 558: /* optional_const_expr_comma: const_expr_comma */ -#line 3329 "dtool/src/cppparser/cppBison.yxx" + case 557: /* optional_const_expr: const_expr */ +#line 3327 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = (yyvsp[0].u.expr); } -#line 7954 "built/tmp/cppBison.yxx.c" +#line 7955 "built/tmp/cppBison.yxx.c" break; - case 559: /* const_expr_comma: const_expr */ -#line 3336 "dtool/src/cppparser/cppBison.yxx" + case 558: /* optional_const_expr_comma: empty */ +#line 3334 "dtool/src/cppparser/cppBison.yxx" +{ + (yyval.u.expr) = nullptr; +} +#line 7963 "built/tmp/cppBison.yxx.c" + break; + + case 559: /* optional_const_expr_comma: const_expr_comma */ +#line 3338 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = (yyvsp[0].u.expr); } -#line 7962 "built/tmp/cppBison.yxx.c" +#line 7971 "built/tmp/cppBison.yxx.c" break; - case 560: /* const_expr_comma: const_expr_comma ',' const_expr */ -#line 3340 "dtool/src/cppparser/cppBison.yxx" + case 560: /* const_expr_comma: const_expr */ +#line 3345 "dtool/src/cppparser/cppBison.yxx" +{ + (yyval.u.expr) = (yyvsp[0].u.expr); +} +#line 7979 "built/tmp/cppBison.yxx.c" + break; + + case 561: /* const_expr_comma: const_expr_comma ',' const_expr */ +#line 3349 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(',', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 7970 "built/tmp/cppBison.yxx.c" +#line 7987 "built/tmp/cppBison.yxx.c" break; - case 561: /* no_angle_bracket_const_expr: const_operand */ -#line 3347 "dtool/src/cppparser/cppBison.yxx" + case 562: /* no_angle_bracket_const_expr: const_operand */ +#line 3356 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = (yyvsp[0].u.expr); } -#line 7978 "built/tmp/cppBison.yxx.c" +#line 7995 "built/tmp/cppBison.yxx.c" break; - case 562: /* no_angle_bracket_const_expr: '(' full_type ')' no_angle_bracket_const_expr */ -#line 3351 "dtool/src/cppparser/cppBison.yxx" + case 563: /* no_angle_bracket_const_expr: '(' full_type ')' no_angle_bracket_const_expr */ +#line 3360 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::typecast_op((yyvsp[-2].u.type), (yyvsp[0].u.expr))); } -#line 7986 "built/tmp/cppBison.yxx.c" +#line 8003 "built/tmp/cppBison.yxx.c" break; - case 563: /* no_angle_bracket_const_expr: KW_STATIC_CAST '<' full_type '>' '(' const_expr_comma ')' */ -#line 3355 "dtool/src/cppparser/cppBison.yxx" + case 564: /* no_angle_bracket_const_expr: KW_STATIC_CAST '<' full_type '>' '(' const_expr_comma ')' */ +#line 3364 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::typecast_op((yyvsp[-4].u.type), (yyvsp[-1].u.expr), CPPExpression::T_static_cast)); } -#line 7994 "built/tmp/cppBison.yxx.c" +#line 8011 "built/tmp/cppBison.yxx.c" break; - case 564: /* no_angle_bracket_const_expr: KW_DYNAMIC_CAST '<' full_type '>' '(' const_expr_comma ')' */ -#line 3359 "dtool/src/cppparser/cppBison.yxx" + case 565: /* no_angle_bracket_const_expr: KW_DYNAMIC_CAST '<' full_type '>' '(' const_expr_comma ')' */ +#line 3368 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::typecast_op((yyvsp[-4].u.type), (yyvsp[-1].u.expr), CPPExpression::T_dynamic_cast)); } -#line 8002 "built/tmp/cppBison.yxx.c" +#line 8019 "built/tmp/cppBison.yxx.c" break; - case 565: /* no_angle_bracket_const_expr: KW_CONST_CAST '<' full_type '>' '(' const_expr_comma ')' */ -#line 3363 "dtool/src/cppparser/cppBison.yxx" + case 566: /* no_angle_bracket_const_expr: KW_CONST_CAST '<' full_type '>' '(' const_expr_comma ')' */ +#line 3372 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::typecast_op((yyvsp[-4].u.type), (yyvsp[-1].u.expr), CPPExpression::T_const_cast)); } -#line 8010 "built/tmp/cppBison.yxx.c" +#line 8027 "built/tmp/cppBison.yxx.c" break; - case 566: /* no_angle_bracket_const_expr: KW_REINTERPRET_CAST '<' full_type '>' '(' const_expr_comma ')' */ -#line 3367 "dtool/src/cppparser/cppBison.yxx" + case 567: /* no_angle_bracket_const_expr: KW_REINTERPRET_CAST '<' full_type '>' '(' const_expr_comma ')' */ +#line 3376 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::typecast_op((yyvsp[-4].u.type), (yyvsp[-1].u.expr), CPPExpression::T_reinterpret_cast)); } -#line 8018 "built/tmp/cppBison.yxx.c" +#line 8035 "built/tmp/cppBison.yxx.c" break; - case 567: /* no_angle_bracket_const_expr: KW_SIZEOF '(' full_type ')' */ -#line 3371 "dtool/src/cppparser/cppBison.yxx" + case 568: /* no_angle_bracket_const_expr: KW_SIZEOF '(' full_type ')' */ +#line 3380 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::sizeof_func((yyvsp[-1].u.type))); } -#line 8026 "built/tmp/cppBison.yxx.c" +#line 8043 "built/tmp/cppBison.yxx.c" break; - case 568: /* no_angle_bracket_const_expr: KW_SIZEOF no_angle_bracket_const_expr */ -#line 3375 "dtool/src/cppparser/cppBison.yxx" + case 569: /* no_angle_bracket_const_expr: KW_SIZEOF no_angle_bracket_const_expr */ +#line 3384 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::sizeof_func((yyvsp[0].u.expr))); } -#line 8034 "built/tmp/cppBison.yxx.c" +#line 8051 "built/tmp/cppBison.yxx.c" break; - case 569: /* no_angle_bracket_const_expr: KW_SIZEOF ELLIPSIS '(' name ')' */ -#line 3379 "dtool/src/cppparser/cppBison.yxx" + case 570: /* no_angle_bracket_const_expr: KW_SIZEOF ELLIPSIS '(' name ')' */ +#line 3388 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::sizeof_ellipsis_func((yyvsp[-1].u.identifier))); } -#line 8042 "built/tmp/cppBison.yxx.c" +#line 8059 "built/tmp/cppBison.yxx.c" break; - case 570: /* no_angle_bracket_const_expr: KW_ALIGNOF '(' full_type ')' */ -#line 3383 "dtool/src/cppparser/cppBison.yxx" + case 571: /* no_angle_bracket_const_expr: KW_ALIGNOF '(' full_type ')' */ +#line 3392 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::alignof_func((yyvsp[-1].u.type))); } -#line 8050 "built/tmp/cppBison.yxx.c" +#line 8067 "built/tmp/cppBison.yxx.c" break; - case 571: /* no_angle_bracket_const_expr: '!' no_angle_bracket_const_expr */ -#line 3387 "dtool/src/cppparser/cppBison.yxx" + case 572: /* no_angle_bracket_const_expr: '!' no_angle_bracket_const_expr */ +#line 3396 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(UNARY_NOT, (yyvsp[0].u.expr)); } -#line 8058 "built/tmp/cppBison.yxx.c" +#line 8075 "built/tmp/cppBison.yxx.c" break; - case 572: /* no_angle_bracket_const_expr: '~' no_angle_bracket_const_expr */ -#line 3391 "dtool/src/cppparser/cppBison.yxx" + case 573: /* no_angle_bracket_const_expr: '~' no_angle_bracket_const_expr */ +#line 3400 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(UNARY_NEGATE, (yyvsp[0].u.expr)); } -#line 8066 "built/tmp/cppBison.yxx.c" +#line 8083 "built/tmp/cppBison.yxx.c" break; - case 573: /* no_angle_bracket_const_expr: '-' no_angle_bracket_const_expr */ -#line 3395 "dtool/src/cppparser/cppBison.yxx" + case 574: /* no_angle_bracket_const_expr: '-' no_angle_bracket_const_expr */ +#line 3404 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(UNARY_MINUS, (yyvsp[0].u.expr)); } -#line 8074 "built/tmp/cppBison.yxx.c" +#line 8091 "built/tmp/cppBison.yxx.c" break; - case 574: /* no_angle_bracket_const_expr: '+' no_angle_bracket_const_expr */ -#line 3399 "dtool/src/cppparser/cppBison.yxx" + case 575: /* no_angle_bracket_const_expr: '+' no_angle_bracket_const_expr */ +#line 3408 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(UNARY_PLUS, (yyvsp[0].u.expr)); } -#line 8082 "built/tmp/cppBison.yxx.c" +#line 8099 "built/tmp/cppBison.yxx.c" break; - case 575: /* no_angle_bracket_const_expr: '*' no_angle_bracket_const_expr */ -#line 3403 "dtool/src/cppparser/cppBison.yxx" + case 576: /* no_angle_bracket_const_expr: '*' no_angle_bracket_const_expr */ +#line 3412 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(UNARY_STAR, (yyvsp[0].u.expr)); } -#line 8090 "built/tmp/cppBison.yxx.c" +#line 8107 "built/tmp/cppBison.yxx.c" break; - case 576: /* no_angle_bracket_const_expr: '&' no_angle_bracket_const_expr */ -#line 3407 "dtool/src/cppparser/cppBison.yxx" + case 577: /* no_angle_bracket_const_expr: '&' no_angle_bracket_const_expr */ +#line 3416 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(UNARY_REF, (yyvsp[0].u.expr)); } -#line 8098 "built/tmp/cppBison.yxx.c" +#line 8115 "built/tmp/cppBison.yxx.c" break; - case 577: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr '*' no_angle_bracket_const_expr */ -#line 3411 "dtool/src/cppparser/cppBison.yxx" + case 578: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr '*' no_angle_bracket_const_expr */ +#line 3420 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('*', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8106 "built/tmp/cppBison.yxx.c" +#line 8123 "built/tmp/cppBison.yxx.c" break; - case 578: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr '/' no_angle_bracket_const_expr */ -#line 3415 "dtool/src/cppparser/cppBison.yxx" + case 579: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr '/' no_angle_bracket_const_expr */ +#line 3424 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('/', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8114 "built/tmp/cppBison.yxx.c" +#line 8131 "built/tmp/cppBison.yxx.c" break; - case 579: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr '%' no_angle_bracket_const_expr */ -#line 3419 "dtool/src/cppparser/cppBison.yxx" + case 580: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr '%' no_angle_bracket_const_expr */ +#line 3428 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('%', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8122 "built/tmp/cppBison.yxx.c" +#line 8139 "built/tmp/cppBison.yxx.c" break; - case 580: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr '+' no_angle_bracket_const_expr */ -#line 3423 "dtool/src/cppparser/cppBison.yxx" + case 581: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr '+' no_angle_bracket_const_expr */ +#line 3432 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('+', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8130 "built/tmp/cppBison.yxx.c" +#line 8147 "built/tmp/cppBison.yxx.c" break; - case 581: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr '-' no_angle_bracket_const_expr */ -#line 3427 "dtool/src/cppparser/cppBison.yxx" + case 582: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr '-' no_angle_bracket_const_expr */ +#line 3436 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('-', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8138 "built/tmp/cppBison.yxx.c" +#line 8155 "built/tmp/cppBison.yxx.c" break; - case 582: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr '|' no_angle_bracket_const_expr */ -#line 3431 "dtool/src/cppparser/cppBison.yxx" + case 583: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr '|' no_angle_bracket_const_expr */ +#line 3440 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('|', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8146 "built/tmp/cppBison.yxx.c" +#line 8163 "built/tmp/cppBison.yxx.c" break; - case 583: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr '^' no_angle_bracket_const_expr */ -#line 3435 "dtool/src/cppparser/cppBison.yxx" + case 584: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr '^' no_angle_bracket_const_expr */ +#line 3444 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('^', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8154 "built/tmp/cppBison.yxx.c" +#line 8171 "built/tmp/cppBison.yxx.c" break; - case 584: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr '&' no_angle_bracket_const_expr */ -#line 3439 "dtool/src/cppparser/cppBison.yxx" + case 585: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr '&' no_angle_bracket_const_expr */ +#line 3448 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('&', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8162 "built/tmp/cppBison.yxx.c" +#line 8179 "built/tmp/cppBison.yxx.c" break; - case 585: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr OROR no_angle_bracket_const_expr */ -#line 3443 "dtool/src/cppparser/cppBison.yxx" + case 586: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr OROR no_angle_bracket_const_expr */ +#line 3452 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(OROR, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8170 "built/tmp/cppBison.yxx.c" +#line 8187 "built/tmp/cppBison.yxx.c" break; - case 586: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr ANDAND no_angle_bracket_const_expr */ -#line 3447 "dtool/src/cppparser/cppBison.yxx" + case 587: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr ANDAND no_angle_bracket_const_expr */ +#line 3456 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(ANDAND, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8178 "built/tmp/cppBison.yxx.c" +#line 8195 "built/tmp/cppBison.yxx.c" break; - case 587: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr EQCOMPARE no_angle_bracket_const_expr */ -#line 3451 "dtool/src/cppparser/cppBison.yxx" + case 588: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr EQCOMPARE no_angle_bracket_const_expr */ +#line 3460 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(EQCOMPARE, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8186 "built/tmp/cppBison.yxx.c" +#line 8203 "built/tmp/cppBison.yxx.c" break; - case 588: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr NECOMPARE no_angle_bracket_const_expr */ -#line 3455 "dtool/src/cppparser/cppBison.yxx" + case 589: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr NECOMPARE no_angle_bracket_const_expr */ +#line 3464 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(NECOMPARE, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8194 "built/tmp/cppBison.yxx.c" +#line 8211 "built/tmp/cppBison.yxx.c" break; - case 589: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr LECOMPARE no_angle_bracket_const_expr */ -#line 3459 "dtool/src/cppparser/cppBison.yxx" + case 590: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr LECOMPARE no_angle_bracket_const_expr */ +#line 3468 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(LECOMPARE, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8202 "built/tmp/cppBison.yxx.c" +#line 8219 "built/tmp/cppBison.yxx.c" break; - case 590: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr GECOMPARE no_angle_bracket_const_expr */ -#line 3463 "dtool/src/cppparser/cppBison.yxx" + case 591: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr GECOMPARE no_angle_bracket_const_expr */ +#line 3472 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(GECOMPARE, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8210 "built/tmp/cppBison.yxx.c" +#line 8227 "built/tmp/cppBison.yxx.c" break; - case 591: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr SPACESHIP no_angle_bracket_const_expr */ -#line 3467 "dtool/src/cppparser/cppBison.yxx" + case 592: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr SPACESHIP no_angle_bracket_const_expr */ +#line 3476 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(SPACESHIP, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8218 "built/tmp/cppBison.yxx.c" +#line 8235 "built/tmp/cppBison.yxx.c" break; - case 592: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr LSHIFT no_angle_bracket_const_expr */ -#line 3471 "dtool/src/cppparser/cppBison.yxx" + case 593: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr LSHIFT no_angle_bracket_const_expr */ +#line 3480 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(LSHIFT, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8226 "built/tmp/cppBison.yxx.c" +#line 8243 "built/tmp/cppBison.yxx.c" break; - case 593: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr RSHIFT no_angle_bracket_const_expr */ -#line 3475 "dtool/src/cppparser/cppBison.yxx" + case 594: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr RSHIFT no_angle_bracket_const_expr */ +#line 3484 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(RSHIFT, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8234 "built/tmp/cppBison.yxx.c" +#line 8251 "built/tmp/cppBison.yxx.c" break; - case 594: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr '?' no_angle_bracket_const_expr ':' no_angle_bracket_const_expr */ -#line 3479 "dtool/src/cppparser/cppBison.yxx" + case 595: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr '?' no_angle_bracket_const_expr ':' no_angle_bracket_const_expr */ +#line 3488 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('?', (yyvsp[-4].u.expr), (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8242 "built/tmp/cppBison.yxx.c" +#line 8259 "built/tmp/cppBison.yxx.c" break; - case 595: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr '[' const_expr ']' */ -#line 3483 "dtool/src/cppparser/cppBison.yxx" + case 596: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr '[' const_expr ']' */ +#line 3492 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('[', (yyvsp[-3].u.expr), (yyvsp[-1].u.expr)); } -#line 8250 "built/tmp/cppBison.yxx.c" +#line 8267 "built/tmp/cppBison.yxx.c" break; - case 596: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr '(' const_expr_comma ')' */ -#line 3487 "dtool/src/cppparser/cppBison.yxx" + case 597: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr '(' const_expr_comma ')' */ +#line 3496 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('f', (yyvsp[-3].u.expr), (yyvsp[-1].u.expr)); } -#line 8258 "built/tmp/cppBison.yxx.c" +#line 8275 "built/tmp/cppBison.yxx.c" break; - case 597: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr '(' ')' */ -#line 3491 "dtool/src/cppparser/cppBison.yxx" + case 598: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr '(' ')' */ +#line 3500 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('f', (yyvsp[-2].u.expr)); } -#line 8266 "built/tmp/cppBison.yxx.c" +#line 8283 "built/tmp/cppBison.yxx.c" break; - case 598: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr '.' name */ -#line 3495 "dtool/src/cppparser/cppBison.yxx" + case 599: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr '.' name */ +#line 3504 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('.', (yyvsp[-2].u.expr), new CPPExpression((yyvsp[0].u.identifier), current_scope, global_scope, current_lexer)); } -#line 8274 "built/tmp/cppBison.yxx.c" +#line 8291 "built/tmp/cppBison.yxx.c" break; - case 599: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr POINTSAT no_angle_bracket_const_expr */ -#line 3499 "dtool/src/cppparser/cppBison.yxx" + case 600: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr POINTSAT no_angle_bracket_const_expr */ +#line 3508 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(POINTSAT, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8282 "built/tmp/cppBison.yxx.c" +#line 8299 "built/tmp/cppBison.yxx.c" break; - case 600: /* no_angle_bracket_const_expr: '(' const_expr_comma ')' */ -#line 3503 "dtool/src/cppparser/cppBison.yxx" + case 601: /* no_angle_bracket_const_expr: '(' const_expr_comma ')' */ +#line 3512 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = (yyvsp[-1].u.expr); } -#line 8290 "built/tmp/cppBison.yxx.c" +#line 8307 "built/tmp/cppBison.yxx.c" break; - case 601: /* const_expr: const_operand */ -#line 3511 "dtool/src/cppparser/cppBison.yxx" + case 602: /* const_expr: const_operand */ +#line 3520 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = (yyvsp[0].u.expr); } -#line 8298 "built/tmp/cppBison.yxx.c" +#line 8315 "built/tmp/cppBison.yxx.c" break; - case 602: /* const_expr: '(' full_type ')' const_expr */ -#line 3515 "dtool/src/cppparser/cppBison.yxx" + case 603: /* const_expr: '(' full_type ')' const_expr */ +#line 3524 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::typecast_op((yyvsp[-2].u.type), (yyvsp[0].u.expr))); } -#line 8306 "built/tmp/cppBison.yxx.c" +#line 8323 "built/tmp/cppBison.yxx.c" break; - case 603: /* const_expr: KW_STATIC_CAST '<' full_type '>' '(' const_expr_comma ')' */ -#line 3519 "dtool/src/cppparser/cppBison.yxx" + case 604: /* const_expr: KW_STATIC_CAST '<' full_type '>' '(' const_expr_comma ')' */ +#line 3528 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::typecast_op((yyvsp[-4].u.type), (yyvsp[-1].u.expr), CPPExpression::T_static_cast)); } -#line 8314 "built/tmp/cppBison.yxx.c" +#line 8331 "built/tmp/cppBison.yxx.c" break; - case 604: /* const_expr: KW_DYNAMIC_CAST '<' full_type '>' '(' const_expr_comma ')' */ -#line 3523 "dtool/src/cppparser/cppBison.yxx" + case 605: /* const_expr: KW_DYNAMIC_CAST '<' full_type '>' '(' const_expr_comma ')' */ +#line 3532 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::typecast_op((yyvsp[-4].u.type), (yyvsp[-1].u.expr), CPPExpression::T_dynamic_cast)); } -#line 8322 "built/tmp/cppBison.yxx.c" +#line 8339 "built/tmp/cppBison.yxx.c" break; - case 605: /* const_expr: KW_CONST_CAST '<' full_type '>' '(' const_expr_comma ')' */ -#line 3527 "dtool/src/cppparser/cppBison.yxx" + case 606: /* const_expr: KW_CONST_CAST '<' full_type '>' '(' const_expr_comma ')' */ +#line 3536 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::typecast_op((yyvsp[-4].u.type), (yyvsp[-1].u.expr), CPPExpression::T_const_cast)); } -#line 8330 "built/tmp/cppBison.yxx.c" +#line 8347 "built/tmp/cppBison.yxx.c" break; - case 606: /* const_expr: KW_REINTERPRET_CAST '<' full_type '>' '(' const_expr_comma ')' */ -#line 3531 "dtool/src/cppparser/cppBison.yxx" + case 607: /* const_expr: KW_REINTERPRET_CAST '<' full_type '>' '(' const_expr_comma ')' */ +#line 3540 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::typecast_op((yyvsp[-4].u.type), (yyvsp[-1].u.expr), CPPExpression::T_reinterpret_cast)); } -#line 8338 "built/tmp/cppBison.yxx.c" +#line 8355 "built/tmp/cppBison.yxx.c" break; - case 607: /* const_expr: TYPENAME_IDENTIFIER '(' optional_const_expr_comma ')' */ -#line 3535 "dtool/src/cppparser/cppBison.yxx" + case 608: /* const_expr: TYPENAME_IDENTIFIER '(' optional_const_expr_comma ')' */ +#line 3544 "dtool/src/cppparser/cppBison.yxx" { // A constructor call. CPPType *type = (yyvsp[-3].u.identifier)->find_type(current_scope, global_scope, false, current_lexer); @@ -8348,11 +8365,11 @@ yyreduce: assert(type != nullptr); (yyval.u.expr) = new CPPExpression(CPPExpression::construct_op(type, (yyvsp[-1].u.expr))); } -#line 8352 "built/tmp/cppBison.yxx.c" +#line 8369 "built/tmp/cppBison.yxx.c" break; - case 608: /* const_expr: TYPENAME_IDENTIFIER '{' optional_const_expr_comma '}' */ -#line 3545 "dtool/src/cppparser/cppBison.yxx" + case 609: /* const_expr: TYPENAME_IDENTIFIER '{' optional_const_expr_comma '}' */ +#line 3554 "dtool/src/cppparser/cppBison.yxx" { // Aggregate initialization. CPPType *type = (yyvsp[-3].u.identifier)->find_type(current_scope, global_scope, false, current_lexer); @@ -8362,193 +8379,193 @@ yyreduce: assert(type != nullptr); (yyval.u.expr) = new CPPExpression(CPPExpression::aggregate_init_op(type, (yyvsp[-1].u.expr))); } -#line 8366 "built/tmp/cppBison.yxx.c" +#line 8383 "built/tmp/cppBison.yxx.c" break; - case 609: /* const_expr: KW_INT '(' optional_const_expr_comma ')' */ -#line 3555 "dtool/src/cppparser/cppBison.yxx" + case 610: /* const_expr: KW_INT '(' optional_const_expr_comma ')' */ +#line 3564 "dtool/src/cppparser/cppBison.yxx" { CPPType *type = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_int)); (yyval.u.expr) = new CPPExpression(CPPExpression::construct_op(type, (yyvsp[-1].u.expr))); } -#line 8376 "built/tmp/cppBison.yxx.c" +#line 8393 "built/tmp/cppBison.yxx.c" break; - case 610: /* const_expr: KW_CHAR '(' optional_const_expr_comma ')' */ -#line 3561 "dtool/src/cppparser/cppBison.yxx" + case 611: /* const_expr: KW_CHAR '(' optional_const_expr_comma ')' */ +#line 3570 "dtool/src/cppparser/cppBison.yxx" { CPPType *type = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_char)); (yyval.u.expr) = new CPPExpression(CPPExpression::construct_op(type, (yyvsp[-1].u.expr))); } -#line 8386 "built/tmp/cppBison.yxx.c" +#line 8403 "built/tmp/cppBison.yxx.c" break; - case 611: /* const_expr: KW_WCHAR_T '(' optional_const_expr_comma ')' */ -#line 3567 "dtool/src/cppparser/cppBison.yxx" + case 612: /* const_expr: KW_WCHAR_T '(' optional_const_expr_comma ')' */ +#line 3576 "dtool/src/cppparser/cppBison.yxx" { CPPType *type = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_wchar_t)); (yyval.u.expr) = new CPPExpression(CPPExpression::construct_op(type, (yyvsp[-1].u.expr))); } -#line 8396 "built/tmp/cppBison.yxx.c" +#line 8413 "built/tmp/cppBison.yxx.c" break; - case 612: /* const_expr: KW_CHAR8_T '(' optional_const_expr_comma ')' */ -#line 3573 "dtool/src/cppparser/cppBison.yxx" + case 613: /* const_expr: KW_CHAR8_T '(' optional_const_expr_comma ')' */ +#line 3582 "dtool/src/cppparser/cppBison.yxx" { CPPType *type = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_char8_t)); (yyval.u.expr) = new CPPExpression(CPPExpression::construct_op(type, (yyvsp[-1].u.expr))); } -#line 8406 "built/tmp/cppBison.yxx.c" +#line 8423 "built/tmp/cppBison.yxx.c" break; - case 613: /* const_expr: KW_CHAR16_T '(' optional_const_expr_comma ')' */ -#line 3579 "dtool/src/cppparser/cppBison.yxx" + case 614: /* const_expr: KW_CHAR16_T '(' optional_const_expr_comma ')' */ +#line 3588 "dtool/src/cppparser/cppBison.yxx" { CPPType *type = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_char16_t)); (yyval.u.expr) = new CPPExpression(CPPExpression::construct_op(type, (yyvsp[-1].u.expr))); } -#line 8416 "built/tmp/cppBison.yxx.c" +#line 8433 "built/tmp/cppBison.yxx.c" break; - case 614: /* const_expr: KW_CHAR32_T '(' optional_const_expr_comma ')' */ -#line 3585 "dtool/src/cppparser/cppBison.yxx" + case 615: /* const_expr: KW_CHAR32_T '(' optional_const_expr_comma ')' */ +#line 3594 "dtool/src/cppparser/cppBison.yxx" { CPPType *type = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_char32_t)); (yyval.u.expr) = new CPPExpression(CPPExpression::construct_op(type, (yyvsp[-1].u.expr))); } -#line 8426 "built/tmp/cppBison.yxx.c" +#line 8443 "built/tmp/cppBison.yxx.c" break; - case 615: /* const_expr: KW_BOOL '(' optional_const_expr_comma ')' */ -#line 3591 "dtool/src/cppparser/cppBison.yxx" + case 616: /* const_expr: KW_BOOL '(' optional_const_expr_comma ')' */ +#line 3600 "dtool/src/cppparser/cppBison.yxx" { CPPType *type = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_bool)); (yyval.u.expr) = new CPPExpression(CPPExpression::construct_op(type, (yyvsp[-1].u.expr))); } -#line 8436 "built/tmp/cppBison.yxx.c" +#line 8453 "built/tmp/cppBison.yxx.c" break; - case 616: /* const_expr: KW_SHORT '(' optional_const_expr_comma ')' */ -#line 3597 "dtool/src/cppparser/cppBison.yxx" + case 617: /* const_expr: KW_SHORT '(' optional_const_expr_comma ')' */ +#line 3606 "dtool/src/cppparser/cppBison.yxx" { CPPType *type = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_int, CPPSimpleType::F_short)); (yyval.u.expr) = new CPPExpression(CPPExpression::construct_op(type, (yyvsp[-1].u.expr))); } -#line 8447 "built/tmp/cppBison.yxx.c" +#line 8464 "built/tmp/cppBison.yxx.c" break; - case 617: /* const_expr: KW_LONG '(' optional_const_expr_comma ')' */ -#line 3604 "dtool/src/cppparser/cppBison.yxx" + case 618: /* const_expr: KW_LONG '(' optional_const_expr_comma ')' */ +#line 3613 "dtool/src/cppparser/cppBison.yxx" { CPPType *type = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_int, CPPSimpleType::F_long)); (yyval.u.expr) = new CPPExpression(CPPExpression::construct_op(type, (yyvsp[-1].u.expr))); } -#line 8458 "built/tmp/cppBison.yxx.c" +#line 8475 "built/tmp/cppBison.yxx.c" break; - case 618: /* const_expr: KW_UNSIGNED '(' optional_const_expr_comma ')' */ -#line 3611 "dtool/src/cppparser/cppBison.yxx" + case 619: /* const_expr: KW_UNSIGNED '(' optional_const_expr_comma ')' */ +#line 3620 "dtool/src/cppparser/cppBison.yxx" { CPPType *type = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_int, CPPSimpleType::F_unsigned)); (yyval.u.expr) = new CPPExpression(CPPExpression::construct_op(type, (yyvsp[-1].u.expr))); } -#line 8469 "built/tmp/cppBison.yxx.c" +#line 8486 "built/tmp/cppBison.yxx.c" break; - case 619: /* const_expr: KW_SIGNED '(' optional_const_expr_comma ')' */ -#line 3618 "dtool/src/cppparser/cppBison.yxx" + case 620: /* const_expr: KW_SIGNED '(' optional_const_expr_comma ')' */ +#line 3627 "dtool/src/cppparser/cppBison.yxx" { CPPType *type = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_int, CPPSimpleType::F_signed)); (yyval.u.expr) = new CPPExpression(CPPExpression::construct_op(type, (yyvsp[-1].u.expr))); } -#line 8480 "built/tmp/cppBison.yxx.c" +#line 8497 "built/tmp/cppBison.yxx.c" break; - case 620: /* const_expr: KW_FLOAT '(' optional_const_expr_comma ')' */ -#line 3625 "dtool/src/cppparser/cppBison.yxx" + case 621: /* const_expr: KW_FLOAT '(' optional_const_expr_comma ')' */ +#line 3634 "dtool/src/cppparser/cppBison.yxx" { CPPType *type = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_float)); (yyval.u.expr) = new CPPExpression(CPPExpression::construct_op(type, (yyvsp[-1].u.expr))); } -#line 8490 "built/tmp/cppBison.yxx.c" +#line 8507 "built/tmp/cppBison.yxx.c" break; - case 621: /* const_expr: KW_DOUBLE '(' optional_const_expr_comma ')' */ -#line 3631 "dtool/src/cppparser/cppBison.yxx" + case 622: /* const_expr: KW_DOUBLE '(' optional_const_expr_comma ')' */ +#line 3640 "dtool/src/cppparser/cppBison.yxx" { CPPType *type = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_double)); (yyval.u.expr) = new CPPExpression(CPPExpression::construct_op(type, (yyvsp[-1].u.expr))); } -#line 8500 "built/tmp/cppBison.yxx.c" +#line 8517 "built/tmp/cppBison.yxx.c" break; - case 622: /* const_expr: KW_SIZEOF '(' full_type ')' */ -#line 3637 "dtool/src/cppparser/cppBison.yxx" + case 623: /* const_expr: KW_SIZEOF '(' full_type ')' */ +#line 3646 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::sizeof_func((yyvsp[-1].u.type))); } -#line 8508 "built/tmp/cppBison.yxx.c" +#line 8525 "built/tmp/cppBison.yxx.c" break; - case 623: /* const_expr: KW_SIZEOF const_expr */ -#line 3641 "dtool/src/cppparser/cppBison.yxx" + case 624: /* const_expr: KW_SIZEOF const_expr */ +#line 3650 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::sizeof_func((yyvsp[0].u.expr))); } -#line 8516 "built/tmp/cppBison.yxx.c" +#line 8533 "built/tmp/cppBison.yxx.c" break; - case 624: /* const_expr: KW_SIZEOF ELLIPSIS '(' name ')' */ -#line 3645 "dtool/src/cppparser/cppBison.yxx" + case 625: /* const_expr: KW_SIZEOF ELLIPSIS '(' name ')' */ +#line 3654 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::sizeof_ellipsis_func((yyvsp[-1].u.identifier))); } -#line 8524 "built/tmp/cppBison.yxx.c" +#line 8541 "built/tmp/cppBison.yxx.c" break; - case 625: /* const_expr: KW_ALIGNOF '(' full_type ')' */ -#line 3649 "dtool/src/cppparser/cppBison.yxx" + case 626: /* const_expr: KW_ALIGNOF '(' full_type ')' */ +#line 3658 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::alignof_func((yyvsp[-1].u.type))); } -#line 8532 "built/tmp/cppBison.yxx.c" +#line 8549 "built/tmp/cppBison.yxx.c" break; - case 626: /* const_expr: KW_NEW predefined_type */ -#line 3653 "dtool/src/cppparser/cppBison.yxx" + case 627: /* const_expr: KW_NEW predefined_type */ +#line 3662 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::new_op((yyvsp[0].u.type))); } -#line 8540 "built/tmp/cppBison.yxx.c" +#line 8557 "built/tmp/cppBison.yxx.c" break; - case 627: /* const_expr: KW_NEW predefined_type '(' optional_const_expr_comma ')' */ -#line 3657 "dtool/src/cppparser/cppBison.yxx" + case 628: /* const_expr: KW_NEW predefined_type '(' optional_const_expr_comma ')' */ +#line 3666 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::new_op((yyvsp[-3].u.type), (yyvsp[-1].u.expr))); } -#line 8548 "built/tmp/cppBison.yxx.c" +#line 8565 "built/tmp/cppBison.yxx.c" break; - case 628: /* const_expr: KW_TYPEID '(' full_type ')' */ -#line 3661 "dtool/src/cppparser/cppBison.yxx" + case 629: /* const_expr: KW_TYPEID '(' full_type ')' */ +#line 3670 "dtool/src/cppparser/cppBison.yxx" { CPPIdentifier ident(""); ident.add_name("std"); @@ -8559,11 +8576,11 @@ yyreduce: } (yyval.u.expr) = new CPPExpression(CPPExpression::typeid_op((yyvsp[-1].u.type), std_type_info)); } -#line 8563 "built/tmp/cppBison.yxx.c" +#line 8580 "built/tmp/cppBison.yxx.c" break; - case 629: /* const_expr: KW_TYPEID '(' const_expr ')' */ -#line 3672 "dtool/src/cppparser/cppBison.yxx" + case 630: /* const_expr: KW_TYPEID '(' const_expr ')' */ +#line 3681 "dtool/src/cppparser/cppBison.yxx" { CPPIdentifier ident(""); ident.add_name("std"); @@ -8574,378 +8591,378 @@ yyreduce: } (yyval.u.expr) = new CPPExpression(CPPExpression::typeid_op((yyvsp[-1].u.expr), std_type_info)); } -#line 8578 "built/tmp/cppBison.yxx.c" +#line 8595 "built/tmp/cppBison.yxx.c" break; - case 630: /* const_expr: '!' const_expr */ -#line 3683 "dtool/src/cppparser/cppBison.yxx" + case 631: /* const_expr: '!' const_expr */ +#line 3692 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(UNARY_NOT, (yyvsp[0].u.expr)); } -#line 8586 "built/tmp/cppBison.yxx.c" +#line 8603 "built/tmp/cppBison.yxx.c" break; - case 631: /* const_expr: '~' const_expr */ -#line 3687 "dtool/src/cppparser/cppBison.yxx" + case 632: /* const_expr: '~' const_expr */ +#line 3696 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(UNARY_NEGATE, (yyvsp[0].u.expr)); } -#line 8594 "built/tmp/cppBison.yxx.c" +#line 8611 "built/tmp/cppBison.yxx.c" break; - case 632: /* const_expr: '-' const_expr */ -#line 3691 "dtool/src/cppparser/cppBison.yxx" + case 633: /* const_expr: '-' const_expr */ +#line 3700 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(UNARY_MINUS, (yyvsp[0].u.expr)); } -#line 8602 "built/tmp/cppBison.yxx.c" +#line 8619 "built/tmp/cppBison.yxx.c" break; - case 633: /* const_expr: '+' const_expr */ -#line 3695 "dtool/src/cppparser/cppBison.yxx" + case 634: /* const_expr: '+' const_expr */ +#line 3704 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(UNARY_PLUS, (yyvsp[0].u.expr)); } -#line 8610 "built/tmp/cppBison.yxx.c" +#line 8627 "built/tmp/cppBison.yxx.c" break; - case 634: /* const_expr: '*' const_expr */ -#line 3699 "dtool/src/cppparser/cppBison.yxx" + case 635: /* const_expr: '*' const_expr */ +#line 3708 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(UNARY_STAR, (yyvsp[0].u.expr)); } -#line 8618 "built/tmp/cppBison.yxx.c" +#line 8635 "built/tmp/cppBison.yxx.c" break; - case 635: /* const_expr: '&' const_expr */ -#line 3703 "dtool/src/cppparser/cppBison.yxx" + case 636: /* const_expr: '&' const_expr */ +#line 3712 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(UNARY_REF, (yyvsp[0].u.expr)); } -#line 8626 "built/tmp/cppBison.yxx.c" +#line 8643 "built/tmp/cppBison.yxx.c" break; - case 636: /* const_expr: const_expr '*' const_expr */ -#line 3707 "dtool/src/cppparser/cppBison.yxx" + case 637: /* const_expr: const_expr '*' const_expr */ +#line 3716 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('*', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8634 "built/tmp/cppBison.yxx.c" +#line 8651 "built/tmp/cppBison.yxx.c" break; - case 637: /* const_expr: const_expr '/' const_expr */ -#line 3711 "dtool/src/cppparser/cppBison.yxx" + case 638: /* const_expr: const_expr '/' const_expr */ +#line 3720 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('/', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8642 "built/tmp/cppBison.yxx.c" +#line 8659 "built/tmp/cppBison.yxx.c" break; - case 638: /* const_expr: const_expr '%' const_expr */ -#line 3715 "dtool/src/cppparser/cppBison.yxx" + case 639: /* const_expr: const_expr '%' const_expr */ +#line 3724 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('%', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8650 "built/tmp/cppBison.yxx.c" +#line 8667 "built/tmp/cppBison.yxx.c" break; - case 639: /* const_expr: const_expr '+' const_expr */ -#line 3719 "dtool/src/cppparser/cppBison.yxx" + case 640: /* const_expr: const_expr '+' const_expr */ +#line 3728 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('+', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8658 "built/tmp/cppBison.yxx.c" +#line 8675 "built/tmp/cppBison.yxx.c" break; - case 640: /* const_expr: const_expr '-' const_expr */ -#line 3723 "dtool/src/cppparser/cppBison.yxx" + case 641: /* const_expr: const_expr '-' const_expr */ +#line 3732 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('-', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8666 "built/tmp/cppBison.yxx.c" +#line 8683 "built/tmp/cppBison.yxx.c" break; - case 641: /* const_expr: const_expr '|' const_expr */ -#line 3727 "dtool/src/cppparser/cppBison.yxx" + case 642: /* const_expr: const_expr '|' const_expr */ +#line 3736 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('|', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8674 "built/tmp/cppBison.yxx.c" +#line 8691 "built/tmp/cppBison.yxx.c" break; - case 642: /* const_expr: const_expr '^' const_expr */ -#line 3731 "dtool/src/cppparser/cppBison.yxx" + case 643: /* const_expr: const_expr '^' const_expr */ +#line 3740 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('^', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8682 "built/tmp/cppBison.yxx.c" +#line 8699 "built/tmp/cppBison.yxx.c" break; - case 643: /* const_expr: const_expr '&' const_expr */ -#line 3735 "dtool/src/cppparser/cppBison.yxx" + case 644: /* const_expr: const_expr '&' const_expr */ +#line 3744 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('&', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8690 "built/tmp/cppBison.yxx.c" +#line 8707 "built/tmp/cppBison.yxx.c" break; - case 644: /* const_expr: const_expr OROR const_expr */ -#line 3739 "dtool/src/cppparser/cppBison.yxx" + case 645: /* const_expr: const_expr OROR const_expr */ +#line 3748 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(OROR, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8698 "built/tmp/cppBison.yxx.c" +#line 8715 "built/tmp/cppBison.yxx.c" break; - case 645: /* const_expr: const_expr ANDAND const_expr */ -#line 3743 "dtool/src/cppparser/cppBison.yxx" + case 646: /* const_expr: const_expr ANDAND const_expr */ +#line 3752 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(ANDAND, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8706 "built/tmp/cppBison.yxx.c" +#line 8723 "built/tmp/cppBison.yxx.c" break; - case 646: /* const_expr: const_expr EQCOMPARE const_expr */ -#line 3747 "dtool/src/cppparser/cppBison.yxx" + case 647: /* const_expr: const_expr EQCOMPARE const_expr */ +#line 3756 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(EQCOMPARE, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8714 "built/tmp/cppBison.yxx.c" +#line 8731 "built/tmp/cppBison.yxx.c" break; - case 647: /* const_expr: const_expr NECOMPARE const_expr */ -#line 3751 "dtool/src/cppparser/cppBison.yxx" + case 648: /* const_expr: const_expr NECOMPARE const_expr */ +#line 3760 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(NECOMPARE, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8722 "built/tmp/cppBison.yxx.c" +#line 8739 "built/tmp/cppBison.yxx.c" break; - case 648: /* const_expr: const_expr LECOMPARE const_expr */ -#line 3755 "dtool/src/cppparser/cppBison.yxx" + case 649: /* const_expr: const_expr LECOMPARE const_expr */ +#line 3764 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(LECOMPARE, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8730 "built/tmp/cppBison.yxx.c" +#line 8747 "built/tmp/cppBison.yxx.c" break; - case 649: /* const_expr: const_expr GECOMPARE const_expr */ -#line 3759 "dtool/src/cppparser/cppBison.yxx" + case 650: /* const_expr: const_expr GECOMPARE const_expr */ +#line 3768 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(GECOMPARE, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8738 "built/tmp/cppBison.yxx.c" +#line 8755 "built/tmp/cppBison.yxx.c" break; - case 650: /* const_expr: const_expr SPACESHIP const_expr */ -#line 3763 "dtool/src/cppparser/cppBison.yxx" + case 651: /* const_expr: const_expr SPACESHIP const_expr */ +#line 3772 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(SPACESHIP, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8746 "built/tmp/cppBison.yxx.c" +#line 8763 "built/tmp/cppBison.yxx.c" break; - case 651: /* const_expr: const_expr '<' const_expr */ -#line 3767 "dtool/src/cppparser/cppBison.yxx" + case 652: /* const_expr: const_expr '<' const_expr */ +#line 3776 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('<', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8754 "built/tmp/cppBison.yxx.c" +#line 8771 "built/tmp/cppBison.yxx.c" break; - case 652: /* const_expr: const_expr '>' const_expr */ -#line 3771 "dtool/src/cppparser/cppBison.yxx" + case 653: /* const_expr: const_expr '>' const_expr */ +#line 3780 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('>', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8762 "built/tmp/cppBison.yxx.c" +#line 8779 "built/tmp/cppBison.yxx.c" break; - case 653: /* const_expr: const_expr LSHIFT const_expr */ -#line 3775 "dtool/src/cppparser/cppBison.yxx" + case 654: /* const_expr: const_expr LSHIFT const_expr */ +#line 3784 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(LSHIFT, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8770 "built/tmp/cppBison.yxx.c" +#line 8787 "built/tmp/cppBison.yxx.c" break; - case 654: /* const_expr: const_expr RSHIFT const_expr */ -#line 3779 "dtool/src/cppparser/cppBison.yxx" + case 655: /* const_expr: const_expr RSHIFT const_expr */ +#line 3788 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(RSHIFT, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8778 "built/tmp/cppBison.yxx.c" +#line 8795 "built/tmp/cppBison.yxx.c" break; - case 655: /* const_expr: const_expr '?' const_expr ':' const_expr */ -#line 3783 "dtool/src/cppparser/cppBison.yxx" + case 656: /* const_expr: const_expr '?' const_expr ':' const_expr */ +#line 3792 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('?', (yyvsp[-4].u.expr), (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8786 "built/tmp/cppBison.yxx.c" +#line 8803 "built/tmp/cppBison.yxx.c" break; - case 656: /* const_expr: const_expr '[' const_expr ']' */ -#line 3787 "dtool/src/cppparser/cppBison.yxx" + case 657: /* const_expr: const_expr '[' const_expr ']' */ +#line 3796 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('[', (yyvsp[-3].u.expr), (yyvsp[-1].u.expr)); } -#line 8794 "built/tmp/cppBison.yxx.c" +#line 8811 "built/tmp/cppBison.yxx.c" break; - case 657: /* const_expr: const_expr '(' const_expr_comma ')' */ -#line 3791 "dtool/src/cppparser/cppBison.yxx" + case 658: /* const_expr: const_expr '(' const_expr_comma ')' */ +#line 3800 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('f', (yyvsp[-3].u.expr), (yyvsp[-1].u.expr)); } -#line 8802 "built/tmp/cppBison.yxx.c" +#line 8819 "built/tmp/cppBison.yxx.c" break; - case 658: /* const_expr: const_expr '(' ')' */ -#line 3795 "dtool/src/cppparser/cppBison.yxx" + case 659: /* const_expr: const_expr '(' ')' */ +#line 3804 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('f', (yyvsp[-2].u.expr)); } -#line 8810 "built/tmp/cppBison.yxx.c" +#line 8827 "built/tmp/cppBison.yxx.c" break; - case 659: /* const_expr: KW_NOEXCEPT_LPAREN const_expr ')' */ -#line 3799 "dtool/src/cppparser/cppBison.yxx" + case 660: /* const_expr: KW_NOEXCEPT_LPAREN const_expr ')' */ +#line 3808 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(KW_NOEXCEPT, (yyvsp[-1].u.expr)); } -#line 8818 "built/tmp/cppBison.yxx.c" +#line 8835 "built/tmp/cppBison.yxx.c" break; - case 660: /* const_expr: const_expr '.' name */ -#line 3803 "dtool/src/cppparser/cppBison.yxx" + case 661: /* const_expr: const_expr '.' name */ +#line 3812 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('.', (yyvsp[-2].u.expr), new CPPExpression((yyvsp[0].u.identifier), current_scope, global_scope, current_lexer)); } -#line 8826 "built/tmp/cppBison.yxx.c" +#line 8843 "built/tmp/cppBison.yxx.c" break; - case 661: /* const_expr: const_expr POINTSAT const_expr */ -#line 3807 "dtool/src/cppparser/cppBison.yxx" + case 662: /* const_expr: const_expr POINTSAT const_expr */ +#line 3816 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(POINTSAT, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8834 "built/tmp/cppBison.yxx.c" +#line 8851 "built/tmp/cppBison.yxx.c" break; - case 662: /* const_expr: '(' const_expr_comma ')' */ -#line 3811 "dtool/src/cppparser/cppBison.yxx" + case 663: /* const_expr: '(' const_expr_comma ')' */ +#line 3820 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = (yyvsp[-1].u.expr); } -#line 8842 "built/tmp/cppBison.yxx.c" +#line 8859 "built/tmp/cppBison.yxx.c" break; - case 663: /* const_operand: INTEGER */ -#line 3818 "dtool/src/cppparser/cppBison.yxx" + case 664: /* const_operand: INTEGER */ +#line 3827 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression((yyvsp[0].u.integer)); } -#line 8850 "built/tmp/cppBison.yxx.c" +#line 8867 "built/tmp/cppBison.yxx.c" break; - case 664: /* const_operand: KW_TRUE */ -#line 3822 "dtool/src/cppparser/cppBison.yxx" + case 665: /* const_operand: KW_TRUE */ +#line 3831 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(true); } -#line 8858 "built/tmp/cppBison.yxx.c" +#line 8875 "built/tmp/cppBison.yxx.c" break; - case 665: /* const_operand: KW_FALSE */ -#line 3826 "dtool/src/cppparser/cppBison.yxx" + case 666: /* const_operand: KW_FALSE */ +#line 3835 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(false); } -#line 8866 "built/tmp/cppBison.yxx.c" +#line 8883 "built/tmp/cppBison.yxx.c" break; - case 666: /* const_operand: CHAR_TOK */ -#line 3830 "dtool/src/cppparser/cppBison.yxx" + case 667: /* const_operand: CHAR_TOK */ +#line 3839 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression((yyvsp[0].u.integer)); } -#line 8874 "built/tmp/cppBison.yxx.c" +#line 8891 "built/tmp/cppBison.yxx.c" break; - case 667: /* const_operand: REAL */ -#line 3834 "dtool/src/cppparser/cppBison.yxx" + case 668: /* const_operand: REAL */ +#line 3843 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression((yyvsp[0].u.real)); } -#line 8882 "built/tmp/cppBison.yxx.c" +#line 8899 "built/tmp/cppBison.yxx.c" break; - case 668: /* const_operand: string_literal */ -#line 3838 "dtool/src/cppparser/cppBison.yxx" + case 669: /* const_operand: string_literal */ +#line 3847 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = (yyvsp[0].u.expr); } -#line 8890 "built/tmp/cppBison.yxx.c" +#line 8907 "built/tmp/cppBison.yxx.c" break; - case 669: /* const_operand: CUSTOM_LITERAL */ -#line 3842 "dtool/src/cppparser/cppBison.yxx" + case 670: /* const_operand: CUSTOM_LITERAL */ +#line 3851 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = (yyvsp[0].u.expr); } -#line 8898 "built/tmp/cppBison.yxx.c" +#line 8915 "built/tmp/cppBison.yxx.c" break; - case 670: /* const_operand: IDENTIFIER */ -#line 3846 "dtool/src/cppparser/cppBison.yxx" + case 671: /* const_operand: IDENTIFIER */ +#line 3855 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression((yyvsp[0].u.identifier), current_scope, global_scope, current_lexer); } -#line 8906 "built/tmp/cppBison.yxx.c" +#line 8923 "built/tmp/cppBison.yxx.c" break; - case 671: /* const_operand: KW_FINAL */ -#line 3850 "dtool/src/cppparser/cppBison.yxx" + case 672: /* const_operand: KW_FINAL */ +#line 3859 "dtool/src/cppparser/cppBison.yxx" { // A variable named "final". C++11 explicitly permits this. CPPIdentifier *ident = new CPPIdentifier("final", (yylsp[0])); (yyval.u.expr) = new CPPExpression(ident, current_scope, global_scope, current_lexer); } -#line 8916 "built/tmp/cppBison.yxx.c" +#line 8933 "built/tmp/cppBison.yxx.c" break; - case 672: /* const_operand: KW_OVERRIDE */ -#line 3856 "dtool/src/cppparser/cppBison.yxx" + case 673: /* const_operand: KW_OVERRIDE */ +#line 3865 "dtool/src/cppparser/cppBison.yxx" { // A variable named "override". C++11 explicitly permits this. CPPIdentifier *ident = new CPPIdentifier("override", (yylsp[0])); (yyval.u.expr) = new CPPExpression(ident, current_scope, global_scope, current_lexer); } -#line 8926 "built/tmp/cppBison.yxx.c" +#line 8943 "built/tmp/cppBison.yxx.c" break; - case 673: /* const_operand: KW_NULLPTR */ -#line 3862 "dtool/src/cppparser/cppBison.yxx" + case 674: /* const_operand: KW_NULLPTR */ +#line 3871 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::get_nullptr()); } -#line 8934 "built/tmp/cppBison.yxx.c" +#line 8951 "built/tmp/cppBison.yxx.c" break; - case 674: /* const_operand: '[' capture_list ']' function_post optional_attributes maybe_trailing_return_type '{' code '}' */ -#line 3866 "dtool/src/cppparser/cppBison.yxx" + case 675: /* const_operand: '[' capture_list ']' function_post optional_attributes maybe_trailing_return_type '{' code '}' */ +#line 3875 "dtool/src/cppparser/cppBison.yxx" { (yyvsp[-7].u.closure_type)->_flags = (yyvsp[-5].u.integer); (yyvsp[-7].u.closure_type)->_attributes = (yyvsp[-4].attr_list); (yyvsp[-7].u.closure_type)->_return_type = (yyvsp[-3].u.type); (yyval.u.expr) = new CPPExpression(CPPExpression::lambda((yyvsp[-7].u.closure_type))); } -#line 8945 "built/tmp/cppBison.yxx.c" +#line 8962 "built/tmp/cppBison.yxx.c" break; - case 675: /* const_operand: '[' capture_list ']' '(' function_parameter_list ')' function_post optional_attributes maybe_trailing_return_type '{' code '}' */ -#line 3873 "dtool/src/cppparser/cppBison.yxx" + case 676: /* const_operand: '[' capture_list ']' '(' function_parameter_list ')' function_post optional_attributes maybe_trailing_return_type '{' code '}' */ +#line 3882 "dtool/src/cppparser/cppBison.yxx" { (yyvsp[-10].u.closure_type)->_parameters = (yyvsp[-7].u.param_list); (yyvsp[-10].u.closure_type)->_flags = (yyvsp[-5].u.integer); @@ -8953,251 +8970,251 @@ yyreduce: (yyvsp[-10].u.closure_type)->_return_type = (yyvsp[-3].u.type); (yyval.u.expr) = new CPPExpression(CPPExpression::lambda((yyvsp[-10].u.closure_type))); } -#line 8957 "built/tmp/cppBison.yxx.c" +#line 8974 "built/tmp/cppBison.yxx.c" break; - case 676: /* const_operand: KW_HAS_VIRTUAL_DESTRUCTOR '(' full_type ')' */ -#line 3881 "dtool/src/cppparser/cppBison.yxx" + case 677: /* const_operand: KW_HAS_VIRTUAL_DESTRUCTOR '(' full_type ')' */ +#line 3890 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::type_trait(KW_HAS_VIRTUAL_DESTRUCTOR, (yyvsp[-1].u.type))); } -#line 8965 "built/tmp/cppBison.yxx.c" +#line 8982 "built/tmp/cppBison.yxx.c" break; - case 677: /* const_operand: KW_IS_ABSTRACT '(' full_type ')' */ -#line 3885 "dtool/src/cppparser/cppBison.yxx" + case 678: /* const_operand: KW_IS_ABSTRACT '(' full_type ')' */ +#line 3894 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::type_trait(KW_IS_ABSTRACT, (yyvsp[-1].u.type))); } -#line 8973 "built/tmp/cppBison.yxx.c" +#line 8990 "built/tmp/cppBison.yxx.c" break; - case 678: /* const_operand: KW_IS_BASE_OF '(' full_type ',' full_type ')' */ -#line 3889 "dtool/src/cppparser/cppBison.yxx" + case 679: /* const_operand: KW_IS_BASE_OF '(' full_type ',' full_type ')' */ +#line 3898 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::type_trait(KW_IS_CLASS, (yyvsp[-3].u.type), (yyvsp[-1].u.type))); } -#line 8981 "built/tmp/cppBison.yxx.c" +#line 8998 "built/tmp/cppBison.yxx.c" break; - case 679: /* const_operand: KW_IS_CLASS '(' full_type ')' */ -#line 3893 "dtool/src/cppparser/cppBison.yxx" + case 680: /* const_operand: KW_IS_CLASS '(' full_type ')' */ +#line 3902 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::type_trait(KW_IS_CLASS, (yyvsp[-1].u.type))); } -#line 8989 "built/tmp/cppBison.yxx.c" +#line 9006 "built/tmp/cppBison.yxx.c" break; - case 680: /* const_operand: KW_IS_CONSTRUCTIBLE '(' full_type ')' */ -#line 3897 "dtool/src/cppparser/cppBison.yxx" + case 681: /* const_operand: KW_IS_CONSTRUCTIBLE '(' full_type ')' */ +#line 3906 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::type_trait(KW_IS_CONSTRUCTIBLE, (yyvsp[-1].u.type))); } -#line 8997 "built/tmp/cppBison.yxx.c" +#line 9014 "built/tmp/cppBison.yxx.c" break; - case 681: /* const_operand: KW_IS_CONSTRUCTIBLE '(' full_type ',' full_type ')' */ -#line 3901 "dtool/src/cppparser/cppBison.yxx" + case 682: /* const_operand: KW_IS_CONSTRUCTIBLE '(' full_type ',' full_type ')' */ +#line 3910 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::type_trait(KW_IS_CONSTRUCTIBLE, (yyvsp[-3].u.type), (yyvsp[-1].u.type))); } -#line 9005 "built/tmp/cppBison.yxx.c" +#line 9022 "built/tmp/cppBison.yxx.c" break; - case 682: /* const_operand: KW_IS_CONVERTIBLE_TO '(' full_type ',' full_type ')' */ -#line 3905 "dtool/src/cppparser/cppBison.yxx" + case 683: /* const_operand: KW_IS_CONVERTIBLE_TO '(' full_type ',' full_type ')' */ +#line 3914 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::type_trait(KW_IS_CONVERTIBLE_TO, (yyvsp[-3].u.type), (yyvsp[-1].u.type))); } -#line 9013 "built/tmp/cppBison.yxx.c" +#line 9030 "built/tmp/cppBison.yxx.c" break; - case 683: /* const_operand: KW_IS_DESTRUCTIBLE '(' full_type ')' */ -#line 3909 "dtool/src/cppparser/cppBison.yxx" + case 684: /* const_operand: KW_IS_DESTRUCTIBLE '(' full_type ')' */ +#line 3918 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::type_trait(KW_IS_DESTRUCTIBLE, (yyvsp[-1].u.type))); } -#line 9021 "built/tmp/cppBison.yxx.c" +#line 9038 "built/tmp/cppBison.yxx.c" break; - case 684: /* const_operand: KW_IS_EMPTY '(' full_type ')' */ -#line 3913 "dtool/src/cppparser/cppBison.yxx" + case 685: /* const_operand: KW_IS_EMPTY '(' full_type ')' */ +#line 3922 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::type_trait(KW_IS_EMPTY, (yyvsp[-1].u.type))); } -#line 9029 "built/tmp/cppBison.yxx.c" +#line 9046 "built/tmp/cppBison.yxx.c" break; - case 685: /* const_operand: KW_IS_ENUM '(' full_type ')' */ -#line 3917 "dtool/src/cppparser/cppBison.yxx" + case 686: /* const_operand: KW_IS_ENUM '(' full_type ')' */ +#line 3926 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::type_trait(KW_IS_ENUM, (yyvsp[-1].u.type))); } -#line 9037 "built/tmp/cppBison.yxx.c" +#line 9054 "built/tmp/cppBison.yxx.c" break; - case 686: /* const_operand: KW_IS_FINAL '(' full_type ')' */ -#line 3921 "dtool/src/cppparser/cppBison.yxx" + case 687: /* const_operand: KW_IS_FINAL '(' full_type ')' */ +#line 3930 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::type_trait(KW_IS_FINAL, (yyvsp[-1].u.type))); } -#line 9045 "built/tmp/cppBison.yxx.c" +#line 9062 "built/tmp/cppBison.yxx.c" break; - case 687: /* const_operand: KW_IS_FUNDAMENTAL '(' full_type ')' */ -#line 3925 "dtool/src/cppparser/cppBison.yxx" + case 688: /* const_operand: KW_IS_FUNDAMENTAL '(' full_type ')' */ +#line 3934 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::type_trait(KW_IS_FUNDAMENTAL, (yyvsp[-1].u.type))); } -#line 9053 "built/tmp/cppBison.yxx.c" +#line 9070 "built/tmp/cppBison.yxx.c" break; - case 688: /* const_operand: KW_IS_POD '(' full_type ')' */ -#line 3929 "dtool/src/cppparser/cppBison.yxx" + case 689: /* const_operand: KW_IS_POD '(' full_type ')' */ +#line 3938 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::type_trait(KW_IS_POD, (yyvsp[-1].u.type))); } -#line 9061 "built/tmp/cppBison.yxx.c" +#line 9078 "built/tmp/cppBison.yxx.c" break; - case 689: /* const_operand: KW_IS_POLYMORPHIC '(' full_type ')' */ -#line 3933 "dtool/src/cppparser/cppBison.yxx" + case 690: /* const_operand: KW_IS_POLYMORPHIC '(' full_type ')' */ +#line 3942 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::type_trait(KW_IS_POLYMORPHIC, (yyvsp[-1].u.type))); } -#line 9069 "built/tmp/cppBison.yxx.c" +#line 9086 "built/tmp/cppBison.yxx.c" break; - case 690: /* const_operand: KW_IS_STANDARD_LAYOUT '(' full_type ')' */ -#line 3937 "dtool/src/cppparser/cppBison.yxx" + case 691: /* const_operand: KW_IS_STANDARD_LAYOUT '(' full_type ')' */ +#line 3946 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::type_trait(KW_IS_STANDARD_LAYOUT, (yyvsp[-1].u.type))); } -#line 9077 "built/tmp/cppBison.yxx.c" +#line 9094 "built/tmp/cppBison.yxx.c" break; - case 691: /* const_operand: KW_IS_TRIVIAL '(' full_type ')' */ -#line 3941 "dtool/src/cppparser/cppBison.yxx" + case 692: /* const_operand: KW_IS_TRIVIAL '(' full_type ')' */ +#line 3950 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::type_trait(KW_IS_TRIVIAL, (yyvsp[-1].u.type))); } -#line 9085 "built/tmp/cppBison.yxx.c" +#line 9102 "built/tmp/cppBison.yxx.c" break; - case 692: /* const_operand: KW_IS_TRIVIALLY_COPYABLE '(' full_type ')' */ -#line 3945 "dtool/src/cppparser/cppBison.yxx" + case 693: /* const_operand: KW_IS_TRIVIALLY_COPYABLE '(' full_type ')' */ +#line 3954 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::type_trait(KW_IS_TRIVIALLY_COPYABLE, (yyvsp[-1].u.type))); } -#line 9093 "built/tmp/cppBison.yxx.c" +#line 9110 "built/tmp/cppBison.yxx.c" break; - case 693: /* const_operand: KW_IS_UNION '(' full_type ')' */ -#line 3949 "dtool/src/cppparser/cppBison.yxx" + case 694: /* const_operand: KW_IS_UNION '(' full_type ')' */ +#line 3958 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::type_trait(KW_IS_UNION, (yyvsp[-1].u.type))); } -#line 9101 "built/tmp/cppBison.yxx.c" +#line 9118 "built/tmp/cppBison.yxx.c" break; - case 694: /* formal_const_expr: formal_const_operand */ -#line 3963 "dtool/src/cppparser/cppBison.yxx" + case 695: /* formal_const_expr: formal_const_operand */ +#line 3972 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = (yyvsp[0].u.expr); } -#line 9109 "built/tmp/cppBison.yxx.c" +#line 9126 "built/tmp/cppBison.yxx.c" break; - case 695: /* formal_const_expr: '(' full_type ')' const_expr */ -#line 3967 "dtool/src/cppparser/cppBison.yxx" + case 696: /* formal_const_expr: '(' full_type ')' const_expr */ +#line 3976 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::typecast_op((yyvsp[-2].u.type), (yyvsp[0].u.expr))); } -#line 9117 "built/tmp/cppBison.yxx.c" +#line 9134 "built/tmp/cppBison.yxx.c" break; - case 696: /* formal_const_expr: KW_STATIC_CAST '<' full_type '>' '(' const_expr_comma ')' */ -#line 3971 "dtool/src/cppparser/cppBison.yxx" + case 697: /* formal_const_expr: KW_STATIC_CAST '<' full_type '>' '(' const_expr_comma ')' */ +#line 3980 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::typecast_op((yyvsp[-4].u.type), (yyvsp[-1].u.expr), CPPExpression::T_static_cast)); } -#line 9125 "built/tmp/cppBison.yxx.c" +#line 9142 "built/tmp/cppBison.yxx.c" break; - case 697: /* formal_const_expr: KW_DYNAMIC_CAST '<' full_type '>' '(' const_expr_comma ')' */ -#line 3975 "dtool/src/cppparser/cppBison.yxx" + case 698: /* formal_const_expr: KW_DYNAMIC_CAST '<' full_type '>' '(' const_expr_comma ')' */ +#line 3984 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::typecast_op((yyvsp[-4].u.type), (yyvsp[-1].u.expr), CPPExpression::T_dynamic_cast)); } -#line 9133 "built/tmp/cppBison.yxx.c" +#line 9150 "built/tmp/cppBison.yxx.c" break; - case 698: /* formal_const_expr: KW_CONST_CAST '<' full_type '>' '(' const_expr_comma ')' */ -#line 3979 "dtool/src/cppparser/cppBison.yxx" + case 699: /* formal_const_expr: KW_CONST_CAST '<' full_type '>' '(' const_expr_comma ')' */ +#line 3988 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::typecast_op((yyvsp[-4].u.type), (yyvsp[-1].u.expr), CPPExpression::T_const_cast)); } -#line 9141 "built/tmp/cppBison.yxx.c" +#line 9158 "built/tmp/cppBison.yxx.c" break; - case 699: /* formal_const_expr: KW_REINTERPRET_CAST '<' full_type '>' '(' const_expr_comma ')' */ -#line 3983 "dtool/src/cppparser/cppBison.yxx" + case 700: /* formal_const_expr: KW_REINTERPRET_CAST '<' full_type '>' '(' const_expr_comma ')' */ +#line 3992 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::typecast_op((yyvsp[-4].u.type), (yyvsp[-1].u.expr), CPPExpression::T_reinterpret_cast)); } -#line 9149 "built/tmp/cppBison.yxx.c" +#line 9166 "built/tmp/cppBison.yxx.c" break; - case 700: /* formal_const_expr: KW_SIZEOF '(' full_type ')' */ -#line 3987 "dtool/src/cppparser/cppBison.yxx" + case 701: /* formal_const_expr: KW_SIZEOF '(' full_type ')' */ +#line 3996 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::sizeof_func((yyvsp[-1].u.type))); } -#line 9157 "built/tmp/cppBison.yxx.c" +#line 9174 "built/tmp/cppBison.yxx.c" break; - case 701: /* formal_const_expr: KW_SIZEOF formal_const_expr */ -#line 3991 "dtool/src/cppparser/cppBison.yxx" + case 702: /* formal_const_expr: KW_SIZEOF formal_const_expr */ +#line 4000 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::sizeof_func((yyvsp[0].u.expr))); } -#line 9165 "built/tmp/cppBison.yxx.c" +#line 9182 "built/tmp/cppBison.yxx.c" break; - case 702: /* formal_const_expr: KW_SIZEOF ELLIPSIS '(' name ')' */ -#line 3995 "dtool/src/cppparser/cppBison.yxx" + case 703: /* formal_const_expr: KW_SIZEOF ELLIPSIS '(' name ')' */ +#line 4004 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::sizeof_ellipsis_func((yyvsp[-1].u.identifier))); } -#line 9173 "built/tmp/cppBison.yxx.c" +#line 9190 "built/tmp/cppBison.yxx.c" break; - case 703: /* formal_const_expr: KW_ALIGNOF '(' full_type ')' */ -#line 3999 "dtool/src/cppparser/cppBison.yxx" + case 704: /* formal_const_expr: KW_ALIGNOF '(' full_type ')' */ +#line 4008 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::alignof_func((yyvsp[-1].u.type))); } -#line 9181 "built/tmp/cppBison.yxx.c" +#line 9198 "built/tmp/cppBison.yxx.c" break; - case 704: /* formal_const_expr: KW_NEW predefined_type */ -#line 4003 "dtool/src/cppparser/cppBison.yxx" + case 705: /* formal_const_expr: KW_NEW predefined_type */ +#line 4012 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::new_op((yyvsp[0].u.type))); } -#line 9189 "built/tmp/cppBison.yxx.c" +#line 9206 "built/tmp/cppBison.yxx.c" break; - case 705: /* formal_const_expr: KW_NEW predefined_type '(' optional_const_expr_comma ')' */ -#line 4007 "dtool/src/cppparser/cppBison.yxx" + case 706: /* formal_const_expr: KW_NEW predefined_type '(' optional_const_expr_comma ')' */ +#line 4016 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::new_op((yyvsp[-3].u.type), (yyvsp[-1].u.expr))); } -#line 9197 "built/tmp/cppBison.yxx.c" +#line 9214 "built/tmp/cppBison.yxx.c" break; - case 706: /* formal_const_expr: KW_TYPEID '(' full_type ')' */ -#line 4011 "dtool/src/cppparser/cppBison.yxx" + case 707: /* formal_const_expr: KW_TYPEID '(' full_type ')' */ +#line 4020 "dtool/src/cppparser/cppBison.yxx" { CPPIdentifier ident(""); ident.add_name("std"); @@ -9208,11 +9225,11 @@ yyreduce: } (yyval.u.expr) = new CPPExpression(CPPExpression::typeid_op((yyvsp[-1].u.type), std_type_info)); } -#line 9212 "built/tmp/cppBison.yxx.c" +#line 9229 "built/tmp/cppBison.yxx.c" break; - case 707: /* formal_const_expr: KW_TYPEID '(' const_expr ')' */ -#line 4022 "dtool/src/cppparser/cppBison.yxx" + case 708: /* formal_const_expr: KW_TYPEID '(' const_expr ')' */ +#line 4031 "dtool/src/cppparser/cppBison.yxx" { CPPIdentifier ident(""); ident.add_name("std"); @@ -9223,417 +9240,417 @@ yyreduce: } (yyval.u.expr) = new CPPExpression(CPPExpression::typeid_op((yyvsp[-1].u.expr), std_type_info)); } -#line 9227 "built/tmp/cppBison.yxx.c" +#line 9244 "built/tmp/cppBison.yxx.c" break; - case 708: /* formal_const_expr: '!' const_expr */ -#line 4033 "dtool/src/cppparser/cppBison.yxx" + case 709: /* formal_const_expr: '!' const_expr */ +#line 4042 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(UNARY_NOT, (yyvsp[0].u.expr)); } -#line 9235 "built/tmp/cppBison.yxx.c" +#line 9252 "built/tmp/cppBison.yxx.c" break; - case 709: /* formal_const_expr: '~' const_expr */ -#line 4037 "dtool/src/cppparser/cppBison.yxx" + case 710: /* formal_const_expr: '~' const_expr */ +#line 4046 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(UNARY_NEGATE, (yyvsp[0].u.expr)); } -#line 9243 "built/tmp/cppBison.yxx.c" +#line 9260 "built/tmp/cppBison.yxx.c" break; - case 710: /* formal_const_expr: '-' const_expr */ -#line 4041 "dtool/src/cppparser/cppBison.yxx" + case 711: /* formal_const_expr: '-' const_expr */ +#line 4050 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(UNARY_MINUS, (yyvsp[0].u.expr)); } -#line 9251 "built/tmp/cppBison.yxx.c" +#line 9268 "built/tmp/cppBison.yxx.c" break; - case 711: /* formal_const_expr: '+' const_expr */ -#line 4045 "dtool/src/cppparser/cppBison.yxx" + case 712: /* formal_const_expr: '+' const_expr */ +#line 4054 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(UNARY_PLUS, (yyvsp[0].u.expr)); } -#line 9259 "built/tmp/cppBison.yxx.c" +#line 9276 "built/tmp/cppBison.yxx.c" break; - case 712: /* formal_const_expr: '&' const_expr */ -#line 4049 "dtool/src/cppparser/cppBison.yxx" + case 713: /* formal_const_expr: '&' const_expr */ +#line 4058 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(UNARY_REF, (yyvsp[0].u.expr)); } -#line 9267 "built/tmp/cppBison.yxx.c" +#line 9284 "built/tmp/cppBison.yxx.c" break; - case 713: /* formal_const_expr: formal_const_expr '*' const_expr */ -#line 4053 "dtool/src/cppparser/cppBison.yxx" + case 714: /* formal_const_expr: formal_const_expr '*' const_expr */ +#line 4062 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('*', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 9275 "built/tmp/cppBison.yxx.c" +#line 9292 "built/tmp/cppBison.yxx.c" break; - case 714: /* formal_const_expr: formal_const_expr '/' const_expr */ -#line 4057 "dtool/src/cppparser/cppBison.yxx" + case 715: /* formal_const_expr: formal_const_expr '/' const_expr */ +#line 4066 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('/', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 9283 "built/tmp/cppBison.yxx.c" +#line 9300 "built/tmp/cppBison.yxx.c" break; - case 715: /* formal_const_expr: formal_const_expr '%' const_expr */ -#line 4061 "dtool/src/cppparser/cppBison.yxx" + case 716: /* formal_const_expr: formal_const_expr '%' const_expr */ +#line 4070 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('%', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 9291 "built/tmp/cppBison.yxx.c" +#line 9308 "built/tmp/cppBison.yxx.c" break; - case 716: /* formal_const_expr: formal_const_expr '+' const_expr */ -#line 4065 "dtool/src/cppparser/cppBison.yxx" + case 717: /* formal_const_expr: formal_const_expr '+' const_expr */ +#line 4074 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('+', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 9299 "built/tmp/cppBison.yxx.c" +#line 9316 "built/tmp/cppBison.yxx.c" break; - case 717: /* formal_const_expr: formal_const_expr '-' const_expr */ -#line 4069 "dtool/src/cppparser/cppBison.yxx" + case 718: /* formal_const_expr: formal_const_expr '-' const_expr */ +#line 4078 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('-', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 9307 "built/tmp/cppBison.yxx.c" +#line 9324 "built/tmp/cppBison.yxx.c" break; - case 718: /* formal_const_expr: formal_const_expr '|' const_expr */ -#line 4073 "dtool/src/cppparser/cppBison.yxx" + case 719: /* formal_const_expr: formal_const_expr '|' const_expr */ +#line 4082 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('|', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 9315 "built/tmp/cppBison.yxx.c" +#line 9332 "built/tmp/cppBison.yxx.c" break; - case 719: /* formal_const_expr: formal_const_expr '^' const_expr */ -#line 4077 "dtool/src/cppparser/cppBison.yxx" + case 720: /* formal_const_expr: formal_const_expr '^' const_expr */ +#line 4086 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('^', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 9323 "built/tmp/cppBison.yxx.c" +#line 9340 "built/tmp/cppBison.yxx.c" break; - case 720: /* formal_const_expr: formal_const_expr '&' const_expr */ -#line 4081 "dtool/src/cppparser/cppBison.yxx" + case 721: /* formal_const_expr: formal_const_expr '&' const_expr */ +#line 4090 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('&', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 9331 "built/tmp/cppBison.yxx.c" +#line 9348 "built/tmp/cppBison.yxx.c" break; - case 721: /* formal_const_expr: formal_const_expr OROR const_expr */ -#line 4085 "dtool/src/cppparser/cppBison.yxx" + case 722: /* formal_const_expr: formal_const_expr OROR const_expr */ +#line 4094 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(OROR, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 9339 "built/tmp/cppBison.yxx.c" +#line 9356 "built/tmp/cppBison.yxx.c" break; - case 722: /* formal_const_expr: formal_const_expr ANDAND const_expr */ -#line 4089 "dtool/src/cppparser/cppBison.yxx" + case 723: /* formal_const_expr: formal_const_expr ANDAND const_expr */ +#line 4098 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(ANDAND, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 9347 "built/tmp/cppBison.yxx.c" +#line 9364 "built/tmp/cppBison.yxx.c" break; - case 723: /* formal_const_expr: formal_const_expr EQCOMPARE const_expr */ -#line 4093 "dtool/src/cppparser/cppBison.yxx" + case 724: /* formal_const_expr: formal_const_expr EQCOMPARE const_expr */ +#line 4102 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(EQCOMPARE, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 9355 "built/tmp/cppBison.yxx.c" +#line 9372 "built/tmp/cppBison.yxx.c" break; - case 724: /* formal_const_expr: formal_const_expr NECOMPARE const_expr */ -#line 4097 "dtool/src/cppparser/cppBison.yxx" + case 725: /* formal_const_expr: formal_const_expr NECOMPARE const_expr */ +#line 4106 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(NECOMPARE, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 9363 "built/tmp/cppBison.yxx.c" +#line 9380 "built/tmp/cppBison.yxx.c" break; - case 725: /* formal_const_expr: formal_const_expr LECOMPARE const_expr */ -#line 4101 "dtool/src/cppparser/cppBison.yxx" + case 726: /* formal_const_expr: formal_const_expr LECOMPARE const_expr */ +#line 4110 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(LECOMPARE, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 9371 "built/tmp/cppBison.yxx.c" +#line 9388 "built/tmp/cppBison.yxx.c" break; - case 726: /* formal_const_expr: formal_const_expr GECOMPARE const_expr */ -#line 4105 "dtool/src/cppparser/cppBison.yxx" + case 727: /* formal_const_expr: formal_const_expr GECOMPARE const_expr */ +#line 4114 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(GECOMPARE, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 9379 "built/tmp/cppBison.yxx.c" +#line 9396 "built/tmp/cppBison.yxx.c" break; - case 727: /* formal_const_expr: formal_const_expr SPACESHIP const_expr */ -#line 4109 "dtool/src/cppparser/cppBison.yxx" + case 728: /* formal_const_expr: formal_const_expr SPACESHIP const_expr */ +#line 4118 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(SPACESHIP, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 9387 "built/tmp/cppBison.yxx.c" +#line 9404 "built/tmp/cppBison.yxx.c" break; - case 728: /* formal_const_expr: formal_const_expr '<' const_expr */ -#line 4113 "dtool/src/cppparser/cppBison.yxx" + case 729: /* formal_const_expr: formal_const_expr '<' const_expr */ +#line 4122 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('<', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 9395 "built/tmp/cppBison.yxx.c" +#line 9412 "built/tmp/cppBison.yxx.c" break; - case 729: /* formal_const_expr: formal_const_expr '>' const_expr */ -#line 4117 "dtool/src/cppparser/cppBison.yxx" + case 730: /* formal_const_expr: formal_const_expr '>' const_expr */ +#line 4126 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('>', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 9403 "built/tmp/cppBison.yxx.c" +#line 9420 "built/tmp/cppBison.yxx.c" break; - case 730: /* formal_const_expr: formal_const_expr LSHIFT const_expr */ -#line 4121 "dtool/src/cppparser/cppBison.yxx" + case 731: /* formal_const_expr: formal_const_expr LSHIFT const_expr */ +#line 4130 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(LSHIFT, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 9411 "built/tmp/cppBison.yxx.c" +#line 9428 "built/tmp/cppBison.yxx.c" break; - case 731: /* formal_const_expr: formal_const_expr RSHIFT const_expr */ -#line 4125 "dtool/src/cppparser/cppBison.yxx" + case 732: /* formal_const_expr: formal_const_expr RSHIFT const_expr */ +#line 4134 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(RSHIFT, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 9419 "built/tmp/cppBison.yxx.c" +#line 9436 "built/tmp/cppBison.yxx.c" break; - case 732: /* formal_const_expr: formal_const_expr '?' const_expr ':' const_expr */ -#line 4129 "dtool/src/cppparser/cppBison.yxx" + case 733: /* formal_const_expr: formal_const_expr '?' const_expr ':' const_expr */ +#line 4138 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('?', (yyvsp[-4].u.expr), (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 9427 "built/tmp/cppBison.yxx.c" +#line 9444 "built/tmp/cppBison.yxx.c" break; - case 733: /* formal_const_expr: formal_const_expr '[' const_expr ']' */ -#line 4133 "dtool/src/cppparser/cppBison.yxx" + case 734: /* formal_const_expr: formal_const_expr '[' const_expr ']' */ +#line 4142 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('[', (yyvsp[-3].u.expr), (yyvsp[-1].u.expr)); } -#line 9435 "built/tmp/cppBison.yxx.c" +#line 9452 "built/tmp/cppBison.yxx.c" break; - case 734: /* formal_const_expr: formal_const_expr '(' const_expr_comma ')' */ -#line 4137 "dtool/src/cppparser/cppBison.yxx" + case 735: /* formal_const_expr: formal_const_expr '(' const_expr_comma ')' */ +#line 4146 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('f', (yyvsp[-3].u.expr), (yyvsp[-1].u.expr)); } -#line 9443 "built/tmp/cppBison.yxx.c" +#line 9460 "built/tmp/cppBison.yxx.c" break; - case 735: /* formal_const_expr: formal_const_expr '(' ')' */ -#line 4141 "dtool/src/cppparser/cppBison.yxx" + case 736: /* formal_const_expr: formal_const_expr '(' ')' */ +#line 4150 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('f', (yyvsp[-2].u.expr)); } -#line 9451 "built/tmp/cppBison.yxx.c" +#line 9468 "built/tmp/cppBison.yxx.c" break; - case 736: /* formal_const_expr: formal_const_expr '.' name */ -#line 4145 "dtool/src/cppparser/cppBison.yxx" + case 737: /* formal_const_expr: formal_const_expr '.' name */ +#line 4154 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('.', (yyvsp[-2].u.expr), new CPPExpression((yyvsp[0].u.identifier), current_scope, global_scope, current_lexer)); } -#line 9459 "built/tmp/cppBison.yxx.c" +#line 9476 "built/tmp/cppBison.yxx.c" break; - case 737: /* formal_const_expr: formal_const_expr POINTSAT const_expr */ -#line 4149 "dtool/src/cppparser/cppBison.yxx" + case 738: /* formal_const_expr: formal_const_expr POINTSAT const_expr */ +#line 4158 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(POINTSAT, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 9467 "built/tmp/cppBison.yxx.c" +#line 9484 "built/tmp/cppBison.yxx.c" break; - case 738: /* formal_const_expr: '(' const_expr_comma ')' */ -#line 4153 "dtool/src/cppparser/cppBison.yxx" + case 739: /* formal_const_expr: '(' const_expr_comma ')' */ +#line 4162 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = (yyvsp[-1].u.expr); } -#line 9475 "built/tmp/cppBison.yxx.c" +#line 9492 "built/tmp/cppBison.yxx.c" break; - case 739: /* formal_const_operand: INTEGER */ -#line 4160 "dtool/src/cppparser/cppBison.yxx" + case 740: /* formal_const_operand: INTEGER */ +#line 4169 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression((yyvsp[0].u.integer)); } -#line 9483 "built/tmp/cppBison.yxx.c" +#line 9500 "built/tmp/cppBison.yxx.c" break; - case 740: /* formal_const_operand: KW_TRUE */ -#line 4164 "dtool/src/cppparser/cppBison.yxx" + case 741: /* formal_const_operand: KW_TRUE */ +#line 4173 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(true); } -#line 9491 "built/tmp/cppBison.yxx.c" +#line 9508 "built/tmp/cppBison.yxx.c" break; - case 741: /* formal_const_operand: KW_FALSE */ -#line 4168 "dtool/src/cppparser/cppBison.yxx" + case 742: /* formal_const_operand: KW_FALSE */ +#line 4177 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(false); } -#line 9499 "built/tmp/cppBison.yxx.c" +#line 9516 "built/tmp/cppBison.yxx.c" break; - case 742: /* formal_const_operand: CHAR_TOK */ -#line 4172 "dtool/src/cppparser/cppBison.yxx" + case 743: /* formal_const_operand: CHAR_TOK */ +#line 4181 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression((yyvsp[0].u.integer)); } -#line 9507 "built/tmp/cppBison.yxx.c" +#line 9524 "built/tmp/cppBison.yxx.c" break; - case 743: /* formal_const_operand: REAL */ -#line 4176 "dtool/src/cppparser/cppBison.yxx" + case 744: /* formal_const_operand: REAL */ +#line 4185 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression((yyvsp[0].u.real)); } -#line 9515 "built/tmp/cppBison.yxx.c" +#line 9532 "built/tmp/cppBison.yxx.c" break; - case 744: /* formal_const_operand: string_literal */ -#line 4180 "dtool/src/cppparser/cppBison.yxx" + case 745: /* formal_const_operand: string_literal */ +#line 4189 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = (yyvsp[0].u.expr); } -#line 9523 "built/tmp/cppBison.yxx.c" +#line 9540 "built/tmp/cppBison.yxx.c" break; - case 745: /* formal_const_operand: CUSTOM_LITERAL */ -#line 4184 "dtool/src/cppparser/cppBison.yxx" + case 746: /* formal_const_operand: CUSTOM_LITERAL */ +#line 4193 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = (yyvsp[0].u.expr); } -#line 9531 "built/tmp/cppBison.yxx.c" +#line 9548 "built/tmp/cppBison.yxx.c" break; - case 746: /* formal_const_operand: IDENTIFIER */ -#line 4188 "dtool/src/cppparser/cppBison.yxx" + case 747: /* formal_const_operand: IDENTIFIER */ +#line 4197 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression((yyvsp[0].u.identifier), current_scope, global_scope, current_lexer); } -#line 9539 "built/tmp/cppBison.yxx.c" +#line 9556 "built/tmp/cppBison.yxx.c" break; - case 747: /* formal_const_operand: KW_FINAL */ -#line 4192 "dtool/src/cppparser/cppBison.yxx" + case 748: /* formal_const_operand: KW_FINAL */ +#line 4201 "dtool/src/cppparser/cppBison.yxx" { // A variable named "final". C++11 explicitly permits this. CPPIdentifier *ident = new CPPIdentifier("final", (yylsp[0])); (yyval.u.expr) = new CPPExpression(ident, current_scope, global_scope, current_lexer); } -#line 9549 "built/tmp/cppBison.yxx.c" +#line 9566 "built/tmp/cppBison.yxx.c" break; - case 748: /* formal_const_operand: KW_OVERRIDE */ -#line 4198 "dtool/src/cppparser/cppBison.yxx" + case 749: /* formal_const_operand: KW_OVERRIDE */ +#line 4207 "dtool/src/cppparser/cppBison.yxx" { // A variable named "override". C++11 explicitly permits this. CPPIdentifier *ident = new CPPIdentifier("override", (yylsp[0])); (yyval.u.expr) = new CPPExpression(ident, current_scope, global_scope, current_lexer); } -#line 9559 "built/tmp/cppBison.yxx.c" +#line 9576 "built/tmp/cppBison.yxx.c" break; - case 749: /* formal_const_operand: KW_NULLPTR */ -#line 4204 "dtool/src/cppparser/cppBison.yxx" + case 750: /* formal_const_operand: KW_NULLPTR */ +#line 4213 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::get_nullptr()); } -#line 9567 "built/tmp/cppBison.yxx.c" +#line 9584 "built/tmp/cppBison.yxx.c" break; - case 750: /* capture_list: empty */ -#line 4212 "dtool/src/cppparser/cppBison.yxx" + case 751: /* capture_list: empty */ +#line 4221 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.closure_type) = new CPPClosureType(); } -#line 9575 "built/tmp/cppBison.yxx.c" +#line 9592 "built/tmp/cppBison.yxx.c" break; - case 751: /* capture_list: '=' */ -#line 4216 "dtool/src/cppparser/cppBison.yxx" + case 752: /* capture_list: '=' */ +#line 4225 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.closure_type) = new CPPClosureType(CPPClosureType::CT_by_value); } -#line 9583 "built/tmp/cppBison.yxx.c" +#line 9600 "built/tmp/cppBison.yxx.c" break; - case 752: /* capture_list: '&' */ -#line 4220 "dtool/src/cppparser/cppBison.yxx" + case 753: /* capture_list: '&' */ +#line 4229 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.closure_type) = new CPPClosureType(CPPClosureType::CT_by_reference); } -#line 9591 "built/tmp/cppBison.yxx.c" +#line 9608 "built/tmp/cppBison.yxx.c" break; - case 753: /* capture_list: capture maybe_initialize */ -#line 4224 "dtool/src/cppparser/cppBison.yxx" + case 754: /* capture_list: capture maybe_initialize */ +#line 4233 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.closure_type) = new CPPClosureType(); (yyvsp[-1].u.capture)->_initializer = (yyvsp[0].u.expr); (yyval.u.closure_type)->_captures.push_back(*(yyvsp[-1].u.capture)); delete (yyvsp[-1].u.capture); } -#line 9602 "built/tmp/cppBison.yxx.c" +#line 9619 "built/tmp/cppBison.yxx.c" break; - case 754: /* capture_list: capture_list ',' capture maybe_initialize */ -#line 4231 "dtool/src/cppparser/cppBison.yxx" + case 755: /* capture_list: capture_list ',' capture maybe_initialize */ +#line 4240 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.closure_type) = (yyvsp[-3].u.closure_type); (yyvsp[-1].u.capture)->_initializer = (yyvsp[0].u.expr); (yyval.u.closure_type)->_captures.push_back(*(yyvsp[-1].u.capture)); delete (yyvsp[-1].u.capture); } -#line 9613 "built/tmp/cppBison.yxx.c" +#line 9630 "built/tmp/cppBison.yxx.c" break; - case 755: /* capture: '&' name */ -#line 4241 "dtool/src/cppparser/cppBison.yxx" + case 756: /* capture: '&' name */ +#line 4250 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.capture) = new CPPClosureType::Capture; (yyval.u.capture)->_name = (yyvsp[0].u.identifier)->get_simple_name(); (yyval.u.capture)->_type = CPPClosureType::CT_by_reference; } -#line 9623 "built/tmp/cppBison.yxx.c" +#line 9640 "built/tmp/cppBison.yxx.c" break; - case 756: /* capture: '&' name ELLIPSIS */ -#line 4247 "dtool/src/cppparser/cppBison.yxx" + case 757: /* capture: '&' name ELLIPSIS */ +#line 4256 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.capture) = new CPPClosureType::Capture; (yyval.u.capture)->_name = (yyvsp[-1].u.identifier)->get_simple_name(); (yyval.u.capture)->_type = CPPClosureType::CT_by_reference; } -#line 9633 "built/tmp/cppBison.yxx.c" +#line 9650 "built/tmp/cppBison.yxx.c" break; - case 757: /* capture: name */ -#line 4253 "dtool/src/cppparser/cppBison.yxx" + case 758: /* capture: name */ +#line 4262 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.capture) = new CPPClosureType::Capture; (yyval.u.capture)->_name = (yyvsp[0].u.identifier)->get_simple_name(); @@ -9643,11 +9660,11 @@ yyreduce: (yyval.u.capture)->_type = CPPClosureType::CT_by_value; } } -#line 9647 "built/tmp/cppBison.yxx.c" +#line 9664 "built/tmp/cppBison.yxx.c" break; - case 758: /* capture: '*' name */ -#line 4263 "dtool/src/cppparser/cppBison.yxx" + case 759: /* capture: '*' name */ +#line 4272 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.capture) = new CPPClosureType::Capture; (yyval.u.capture)->_name = (yyvsp[0].u.identifier)->get_simple_name(); @@ -9656,11 +9673,11 @@ yyreduce: yywarning("only capture name 'this' may be preceded by an asterisk", (yylsp[0])); } } -#line 9660 "built/tmp/cppBison.yxx.c" +#line 9677 "built/tmp/cppBison.yxx.c" break; - case 759: /* class_derivation_name: name */ -#line 4275 "dtool/src/cppparser/cppBison.yxx" + case 760: /* class_derivation_name: name */ +#line 4284 "dtool/src/cppparser/cppBison.yxx" { CPPType *type = (yyvsp[0].u.identifier)->find_type(current_scope, global_scope, true); if (type == nullptr) { @@ -9668,177 +9685,177 @@ yyreduce: } (yyval.u.type) = type; } -#line 9672 "built/tmp/cppBison.yxx.c" +#line 9689 "built/tmp/cppBison.yxx.c" break; - case 760: /* class_derivation_name: KW_TYPENAME name */ -#line 4283 "dtool/src/cppparser/cppBison.yxx" + case 761: /* class_derivation_name: KW_TYPENAME name */ +#line 4292 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.type) = CPPType::new_type(new CPPTBDType((yyvsp[0].u.identifier))); } -#line 9680 "built/tmp/cppBison.yxx.c" +#line 9697 "built/tmp/cppBison.yxx.c" break; - case 761: /* class_derivation_name: name ELLIPSIS */ -#line 4287 "dtool/src/cppparser/cppBison.yxx" + case 762: /* class_derivation_name: name ELLIPSIS */ +#line 4296 "dtool/src/cppparser/cppBison.yxx" { CPPClassTemplateParameter *ctp = new CPPClassTemplateParameter((yyvsp[-1].u.identifier)); ctp->_packed = true; (yyval.u.type) = CPPType::new_type(ctp); } -#line 9690 "built/tmp/cppBison.yxx.c" +#line 9707 "built/tmp/cppBison.yxx.c" break; - case 762: /* name: IDENTIFIER */ -#line 4317 "dtool/src/cppparser/cppBison.yxx" + case 763: /* name: IDENTIFIER */ +#line 4326 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.identifier) = (yyvsp[0].u.identifier); } -#line 9698 "built/tmp/cppBison.yxx.c" +#line 9715 "built/tmp/cppBison.yxx.c" break; - case 763: /* name: TYPENAME_IDENTIFIER */ -#line 4321 "dtool/src/cppparser/cppBison.yxx" + case 764: /* name: TYPENAME_IDENTIFIER */ +#line 4330 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.identifier) = (yyvsp[0].u.identifier); } -#line 9706 "built/tmp/cppBison.yxx.c" +#line 9723 "built/tmp/cppBison.yxx.c" break; - case 764: /* name: TYPEPACK_IDENTIFIER */ -#line 4325 "dtool/src/cppparser/cppBison.yxx" + case 765: /* name: TYPEPACK_IDENTIFIER */ +#line 4334 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.identifier) = (yyvsp[0].u.identifier); } -#line 9714 "built/tmp/cppBison.yxx.c" +#line 9731 "built/tmp/cppBison.yxx.c" break; - case 765: /* name: KW_FINAL */ -#line 4329 "dtool/src/cppparser/cppBison.yxx" + case 766: /* name: KW_FINAL */ +#line 4338 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.identifier) = new CPPIdentifier("final", (yylsp[0])); } -#line 9722 "built/tmp/cppBison.yxx.c" +#line 9739 "built/tmp/cppBison.yxx.c" break; - case 766: /* name: KW_OVERRIDE */ -#line 4333 "dtool/src/cppparser/cppBison.yxx" + case 767: /* name: KW_OVERRIDE */ +#line 4342 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.identifier) = new CPPIdentifier("override", (yylsp[0])); } -#line 9730 "built/tmp/cppBison.yxx.c" +#line 9747 "built/tmp/cppBison.yxx.c" break; - case 767: /* name: KW_SIGNED */ -#line 4337 "dtool/src/cppparser/cppBison.yxx" + case 768: /* name: KW_SIGNED */ +#line 4346 "dtool/src/cppparser/cppBison.yxx" { // This is not a keyword in Python, so it is useful to be able to use this // in MAKE_PROPERTY definitions, etc. (yyval.u.identifier) = new CPPIdentifier("signed", (yylsp[0])); } -#line 9740 "built/tmp/cppBison.yxx.c" +#line 9757 "built/tmp/cppBison.yxx.c" break; - case 768: /* name: KW_FLOAT */ -#line 4343 "dtool/src/cppparser/cppBison.yxx" + case 769: /* name: KW_FLOAT */ +#line 4352 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.identifier) = new CPPIdentifier("float", (yylsp[0])); } -#line 9748 "built/tmp/cppBison.yxx.c" +#line 9765 "built/tmp/cppBison.yxx.c" break; - case 769: /* name: KW_PUBLIC */ -#line 4347 "dtool/src/cppparser/cppBison.yxx" + case 770: /* name: KW_PUBLIC */ +#line 4356 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.identifier) = new CPPIdentifier("public", (yylsp[0])); } -#line 9756 "built/tmp/cppBison.yxx.c" +#line 9773 "built/tmp/cppBison.yxx.c" break; - case 770: /* name: KW_PRIVATE */ -#line 4351 "dtool/src/cppparser/cppBison.yxx" + case 771: /* name: KW_PRIVATE */ +#line 4360 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.identifier) = new CPPIdentifier("private", (yylsp[0])); } -#line 9764 "built/tmp/cppBison.yxx.c" +#line 9781 "built/tmp/cppBison.yxx.c" break; - case 771: /* name: KW_STATIC */ -#line 4355 "dtool/src/cppparser/cppBison.yxx" + case 772: /* name: KW_STATIC */ +#line 4364 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.identifier) = new CPPIdentifier("static", (yylsp[0])); } -#line 9772 "built/tmp/cppBison.yxx.c" +#line 9789 "built/tmp/cppBison.yxx.c" break; - case 772: /* name: KW_DEFAULT */ -#line 4359 "dtool/src/cppparser/cppBison.yxx" + case 773: /* name: KW_DEFAULT */ +#line 4368 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.identifier) = new CPPIdentifier("default", (yylsp[0])); } -#line 9780 "built/tmp/cppBison.yxx.c" +#line 9797 "built/tmp/cppBison.yxx.c" break; - case 773: /* name_no_final: IDENTIFIER */ -#line 4370 "dtool/src/cppparser/cppBison.yxx" + case 774: /* name_no_final: IDENTIFIER */ +#line 4379 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.identifier) = (yyvsp[0].u.identifier); } -#line 9788 "built/tmp/cppBison.yxx.c" +#line 9805 "built/tmp/cppBison.yxx.c" break; - case 774: /* name_no_final: TYPENAME_IDENTIFIER */ -#line 4374 "dtool/src/cppparser/cppBison.yxx" + case 775: /* name_no_final: TYPENAME_IDENTIFIER */ +#line 4383 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.identifier) = (yyvsp[0].u.identifier); } -#line 9796 "built/tmp/cppBison.yxx.c" +#line 9813 "built/tmp/cppBison.yxx.c" break; - case 775: /* name_no_final: TYPEPACK_IDENTIFIER */ -#line 4378 "dtool/src/cppparser/cppBison.yxx" + case 776: /* name_no_final: TYPEPACK_IDENTIFIER */ +#line 4387 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.identifier) = (yyvsp[0].u.identifier); } -#line 9804 "built/tmp/cppBison.yxx.c" +#line 9821 "built/tmp/cppBison.yxx.c" break; - case 776: /* name_no_final: KW_OVERRIDE */ -#line 4382 "dtool/src/cppparser/cppBison.yxx" + case 777: /* name_no_final: KW_OVERRIDE */ +#line 4391 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.identifier) = new CPPIdentifier("override", (yylsp[0])); } -#line 9812 "built/tmp/cppBison.yxx.c" +#line 9829 "built/tmp/cppBison.yxx.c" break; - case 777: /* string_literal: SIMPLE_STRING */ -#line 4390 "dtool/src/cppparser/cppBison.yxx" + case 778: /* string_literal: SIMPLE_STRING */ +#line 4399 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression((yyvsp[0].str)); } -#line 9820 "built/tmp/cppBison.yxx.c" +#line 9837 "built/tmp/cppBison.yxx.c" break; - case 778: /* string_literal: STRING_LITERAL */ -#line 4394 "dtool/src/cppparser/cppBison.yxx" + case 779: /* string_literal: STRING_LITERAL */ +#line 4403 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = (yyvsp[0].u.expr); } -#line 9828 "built/tmp/cppBison.yxx.c" +#line 9845 "built/tmp/cppBison.yxx.c" break; - case 779: /* string_literal: string_literal SIMPLE_STRING */ -#line 4398 "dtool/src/cppparser/cppBison.yxx" + case 780: /* string_literal: string_literal SIMPLE_STRING */ +#line 4407 "dtool/src/cppparser/cppBison.yxx" { // The right string takes on the literal type of the left. (yyval.u.expr) = (yyvsp[-1].u.expr); (yyval.u.expr)->_str += (yyvsp[0].str); } -#line 9838 "built/tmp/cppBison.yxx.c" +#line 9855 "built/tmp/cppBison.yxx.c" break; - case 780: /* string_literal: string_literal STRING_LITERAL */ -#line 4404 "dtool/src/cppparser/cppBison.yxx" + case 781: /* string_literal: string_literal STRING_LITERAL */ +#line 4413 "dtool/src/cppparser/cppBison.yxx" { // We have to check that the two literal types match up. (yyval.u.expr) = (yyvsp[-1].u.expr); @@ -9847,11 +9864,11 @@ yyreduce: } (yyval.u.expr)->_str += (yyvsp[0].u.expr)->_str; } -#line 9851 "built/tmp/cppBison.yxx.c" +#line 9868 "built/tmp/cppBison.yxx.c" break; -#line 9855 "built/tmp/cppBison.yxx.c" +#line 9872 "built/tmp/cppBison.yxx.c" default: break; } diff --git a/dtool/src/cppparser/cppBison.yxx b/dtool/src/cppparser/cppBison.yxx index 0eed60e0d9..6c0cf2a0d3 100644 --- a/dtool/src/cppparser/cppBison.yxx +++ b/dtool/src/cppparser/cppBison.yxx @@ -2971,8 +2971,17 @@ base_specification: ; enum: - enum_decl '{' enum_body '}' + enum_decl { + if (current_enum->_scope != nullptr) { + push_scope(current_enum->_scope); + } +} + '{' enum_body '}' +{ + if (current_enum->_scope != nullptr) { + pop_scope(); + } $$ = current_enum; current_enum = nullptr; } From c34f2bbc646a980b52eb3061a380ad004f794f32 Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 2 Aug 2023 11:16:54 +0200 Subject: [PATCH 45/84] Switch to UPPER_CASE convention for enum classes as per PEP-8 Old names are still kept around for compatibility reasons, but deprecated - fortunately there are not that many cases of enum classes yet --- panda/src/device/clientDevice.cxx | 2 +- panda/src/device/clientTrackerDevice.I | 2 +- panda/src/device/evdevInputDevice.cxx | 192 +++++++++--------- panda/src/device/evdevInputDevice.h | 2 +- panda/src/device/inputDevice.I | 12 +- panda/src/device/inputDevice.cxx | 106 +++++----- panda/src/device/inputDevice.h | 118 +++++++---- panda/src/device/ioKitInputDevice.cxx | 119 ++++++----- panda/src/device/linuxJoystickDevice.cxx | 78 +++---- panda/src/device/winRawInputDevice.cxx | 120 +++++------ panda/src/device/xInputDevice.cxx | 60 +++--- .../src/display/graphicsWindowInputDevice.cxx | 10 +- panda/src/event/pointerEvent.h | 2 +- panda/src/putil/pointerData.h | 19 +- 14 files changed, 449 insertions(+), 393 deletions(-) diff --git a/panda/src/device/clientDevice.cxx b/panda/src/device/clientDevice.cxx index 278977f30b..198270f563 100644 --- a/panda/src/device/clientDevice.cxx +++ b/panda/src/device/clientDevice.cxx @@ -24,7 +24,7 @@ TypeHandle ClientDevice::_type_handle; ClientDevice:: ClientDevice(ClientBase *client, TypeHandle device_type, const std::string &device_name) : - InputDevice(device_name, DeviceClass::unknown), + InputDevice(device_name, DeviceClass::UNKNOWN), _client(client), _device_type(device_type) { diff --git a/panda/src/device/clientTrackerDevice.I b/panda/src/device/clientTrackerDevice.I index 6ff99528e5..7012b53faa 100644 --- a/panda/src/device/clientTrackerDevice.I +++ b/panda/src/device/clientTrackerDevice.I @@ -18,5 +18,5 @@ INLINE ClientTrackerDevice:: ClientTrackerDevice(ClientBase *client, const std::string &device_name): ClientDevice(client, get_class_type(), device_name) { - enable_feature(Feature::tracker); + enable_feature(Feature::TRACKER); } diff --git a/panda/src/device/evdevInputDevice.cxx b/panda/src/device/evdevInputDevice.cxx index 8fb35ed477..5e0a158f87 100644 --- a/panda/src/device/evdevInputDevice.cxx +++ b/panda/src/device/evdevInputDevice.cxx @@ -80,41 +80,41 @@ static const struct DeviceMapping { int quirks; } mapping_presets[] = { // NVIDIA Shield Controller - {0x0955, 0x7214, InputDevice::DeviceClass::gamepad, QB_rstick_from_z}, + {0x0955, 0x7214, InputDevice::DeviceClass::GAMEPAD, QB_rstick_from_z}, // T.Flight Hotas X - {0x044f, 0xb108, InputDevice::DeviceClass::flight_stick, QB_centered_throttle | QB_reversed_throttle | QB_rudder_from_throttle}, + {0x044f, 0xb108, InputDevice::DeviceClass::FLIGHT_STICK, QB_centered_throttle | QB_reversed_throttle | QB_rudder_from_throttle}, // Xbox 360 Wireless Controller - {0x045e, 0x0719, InputDevice::DeviceClass::gamepad, QB_connect_if_nonzero}, + {0x045e, 0x0719, InputDevice::DeviceClass::GAMEPAD, QB_connect_if_nonzero}, // Steam Controller (wired) - {0x28de, 0x1102, InputDevice::DeviceClass::unknown, QB_steam_controller}, + {0x28de, 0x1102, InputDevice::DeviceClass::UNKNOWN, QB_steam_controller}, // Steam Controller (wireless) - {0x28de, 0x1142, InputDevice::DeviceClass::unknown, QB_steam_controller}, + {0x28de, 0x1142, InputDevice::DeviceClass::UNKNOWN, QB_steam_controller}, // Jess Tech Colour Rumble Pad - {0x0f30, 0x0111, InputDevice::DeviceClass::gamepad, QB_rstick_from_z | QB_right_axes_swapped}, + {0x0f30, 0x0111, InputDevice::DeviceClass::GAMEPAD, QB_rstick_from_z | QB_right_axes_swapped}, // Trust GXT 24 - {0x0079, 0x0006, InputDevice::DeviceClass::gamepad, QB_no_analog_triggers | QB_alt_button_mapping}, + {0x0079, 0x0006, InputDevice::DeviceClass::GAMEPAD, QB_no_analog_triggers | QB_alt_button_mapping}, // 8bitdo N30 Pro Controller - {0x2dc8, 0x9001, InputDevice::DeviceClass::gamepad, QB_rstick_from_z}, + {0x2dc8, 0x9001, InputDevice::DeviceClass::GAMEPAD, QB_rstick_from_z}, // Generic gamepad - {0x0810, 0x0001, InputDevice::DeviceClass::gamepad, QB_no_analog_triggers | QB_alt_button_mapping | QB_rstick_from_z | QB_right_axes_swapped}, + {0x0810, 0x0001, InputDevice::DeviceClass::GAMEPAD, QB_no_analog_triggers | QB_alt_button_mapping | QB_rstick_from_z | QB_right_axes_swapped}, // Generic gamepad without sticks - {0x0810, 0xe501, InputDevice::DeviceClass::gamepad, QB_no_analog_triggers | QB_alt_button_mapping}, + {0x0810, 0xe501, InputDevice::DeviceClass::GAMEPAD, QB_no_analog_triggers | QB_alt_button_mapping}, // 3Dconnexion Space Traveller 3D Mouse - {0x046d, 0xc623, InputDevice::DeviceClass::spatial_mouse, 0}, + {0x046d, 0xc623, InputDevice::DeviceClass::SPATIAL_MOUSE, 0}, // 3Dconnexion Space Pilot 3D Mouse - {0x046d, 0xc625, InputDevice::DeviceClass::spatial_mouse, 0}, + {0x046d, 0xc625, InputDevice::DeviceClass::SPATIAL_MOUSE, 0}, // 3Dconnexion Space Navigator 3D Mouse - {0x046d, 0xc626, InputDevice::DeviceClass::spatial_mouse, 0}, + {0x046d, 0xc626, InputDevice::DeviceClass::SPATIAL_MOUSE, 0}, // 3Dconnexion Space Explorer 3D Mouse - {0x046d, 0xc627, InputDevice::DeviceClass::spatial_mouse, 0}, + {0x046d, 0xc627, InputDevice::DeviceClass::SPATIAL_MOUSE, 0}, // 3Dconnexion Space Navigator for Notebooks - {0x046d, 0xc628, InputDevice::DeviceClass::spatial_mouse, 0}, + {0x046d, 0xc628, InputDevice::DeviceClass::SPATIAL_MOUSE, 0}, // 3Dconnexion SpacePilot Pro 3D Mouse - {0x046d, 0xc629, InputDevice::DeviceClass::spatial_mouse, 0}, + {0x046d, 0xc629, InputDevice::DeviceClass::SPATIAL_MOUSE, 0}, // 3Dconnexion Space Mouse Pro - {0x046d, 0xc62b, InputDevice::DeviceClass::spatial_mouse, 0}, + {0x046d, 0xc62b, InputDevice::DeviceClass::SPATIAL_MOUSE, 0}, // FrSky Simulator - {0x0483, 0x5720, InputDevice::DeviceClass::flight_stick, 0}, + {0x0483, 0x5720, InputDevice::DeviceClass::FLIGHT_STICK, 0}, {0}, }; @@ -322,7 +322,7 @@ init_device() { has_keys = true; if (test_bit(KEY_A, keys) && test_bit(KEY_Z, keys)) { - enable_feature(Feature::keyboard); + enable_feature(Feature::KEYBOARD); } } @@ -364,7 +364,7 @@ init_device() { // The Steam Controller reports as multiple devices, one of which a gamepad. if (quirks & QB_steam_controller) { if (test_bit(BTN_GAMEPAD, keys)) { - _device_class = DeviceClass::gamepad; + _device_class = DeviceClass::GAMEPAD; // If we have a virtual gamepad on the system, then careful: if Steam is // running, it may disable its own gamepad in favour of the virtual @@ -380,41 +380,41 @@ init_device() { _quirks = quirks; // Try to detect which type of device we have here - if (_device_class == DeviceClass::unknown) { - int device_scores[(size_t)DeviceClass::digitizer + 1] = {0}; + if (_device_class == DeviceClass::UNKNOWN) { + int device_scores[(size_t)DeviceClass::DIGITIZER + 1] = {0}; // Test for specific keys if (test_bit(BTN_GAMEPAD, keys) && test_bit(ABS_X, axes) && test_bit(ABS_RX, axes)) { - device_scores[(size_t)DeviceClass::gamepad] += 5; - device_scores[(size_t)DeviceClass::steering_wheel] += 5; - device_scores[(size_t)DeviceClass::flight_stick] += 5; + device_scores[(size_t)DeviceClass::GAMEPAD] += 5; + device_scores[(size_t)DeviceClass::STEERING_WHEEL] += 5; + device_scores[(size_t)DeviceClass::FLIGHT_STICK] += 5; } if (test_bit(ABS_WHEEL, axes) && test_bit(ABS_GAS, axes) && test_bit(ABS_BRAKE, axes)) { - device_scores[(size_t)DeviceClass::steering_wheel] += 10; + device_scores[(size_t)DeviceClass::STEERING_WHEEL] += 10; } if (test_bit(BTN_GEAR_DOWN, keys) && test_bit(BTN_GEAR_UP, keys)) { - device_scores[(size_t)DeviceClass::steering_wheel] += 10; + device_scores[(size_t)DeviceClass::STEERING_WHEEL] += 10; } if (test_bit(BTN_JOYSTICK, keys) && test_bit(ABS_X, axes)) { - device_scores[(size_t)DeviceClass::flight_stick] += 10; + device_scores[(size_t)DeviceClass::FLIGHT_STICK] += 10; } if (test_bit(BTN_MOUSE, keys) && test_bit(EV_REL, evtypes)) { - device_scores[(size_t)DeviceClass::mouse] += 20; + device_scores[(size_t)DeviceClass::MOUSE] += 20; } if (test_bit(BTN_DIGI, keys) && test_bit(EV_ABS, evtypes)) { - device_scores[(size_t)DeviceClass::digitizer] += 20; + device_scores[(size_t)DeviceClass::DIGITIZER] += 20; } uint8_t unknown_keys[] = {KEY_POWER}; for (int i = 0; i < 1; i++) { if (test_bit(unknown_keys[i], keys)) { if (unknown_keys[i] == KEY_POWER) { } - device_scores[(size_t)DeviceClass::unknown] += 20; + device_scores[(size_t)DeviceClass::UNKNOWN] += 20; } } - if (_features & (unsigned int)Feature::keyboard) { - device_scores[(size_t)DeviceClass::keyboard] += 20; + if (_features & (unsigned int)Feature::KEYBOARD) { + device_scores[(size_t)DeviceClass::KEYBOARD] += 20; } // Test for specific name tags @@ -423,28 +423,28 @@ init_device() { lowercase_name[x] = tolower(lowercase_name[x]); } if (lowercase_name.find("gamepad") != string::npos) { - device_scores[(size_t)DeviceClass::gamepad] += 10; + device_scores[(size_t)DeviceClass::GAMEPAD] += 10; } if (lowercase_name.find("wheel") != string::npos) { - device_scores[(size_t)DeviceClass::steering_wheel] += 10; + device_scores[(size_t)DeviceClass::STEERING_WHEEL] += 10; } if (lowercase_name.find("mouse") != string::npos || lowercase_name.find("touchpad") != string::npos) { - device_scores[(size_t)DeviceClass::mouse] += 10; + device_scores[(size_t)DeviceClass::MOUSE] += 10; } if (lowercase_name.find("keyboard") != string::npos) { - device_scores[(size_t)DeviceClass::keyboard] += 10; + device_scores[(size_t)DeviceClass::KEYBOARD] += 10; } // List of lowercase names that occur in unknown devices string unknown_names[] = {"video bus", "power button", "sleep button"}; for(int i = 0; i < 3; i++) { if (lowercase_name.find(unknown_names[i]) != string::npos) { - device_scores[(size_t)DeviceClass::unknown] += 20; + device_scores[(size_t)DeviceClass::UNKNOWN] += 20; } } // Check which device type got the most points int highest_score = 0; - for (size_t i = 0; i <= (size_t)DeviceClass::digitizer; i++) { + for (size_t i = 0; i <= (size_t)DeviceClass::DIGITIZER; i++) { if (device_scores[i] > highest_score) { highest_score = device_scores[i]; _device_class = (DeviceClass)i; @@ -499,113 +499,113 @@ init_device() { for (int i = 0; i < num_bits; ++i) { if (test_bit(i, axes)) { - Axis axis = Axis::none; + Axis axis = Axis::NONE; switch (i) { case ABS_X: - if (_device_class == DeviceClass::gamepad) { - axis = InputDevice::Axis::left_x; - } else if (_device_class == DeviceClass::flight_stick) { - axis = InputDevice::Axis::roll; + if (_device_class == DeviceClass::GAMEPAD) { + axis = Axis::LEFT_X; + } else if (_device_class == DeviceClass::FLIGHT_STICK) { + axis = Axis::ROLL; } else { - axis = InputDevice::Axis::x; + axis = Axis::X; } break; case ABS_Y: - if (_device_class == DeviceClass::gamepad) { - axis = InputDevice::Axis::left_y; - } else if (_device_class == DeviceClass::flight_stick) { - axis = InputDevice::Axis::pitch; + if (_device_class == DeviceClass::GAMEPAD) { + axis = Axis::LEFT_Y; + } else if (_device_class == DeviceClass::FLIGHT_STICK) { + axis = Axis::PITCH; } else { - axis = InputDevice::Axis::y; + axis = Axis::Y; } break; case ABS_Z: if (quirks & QB_rstick_from_z) { if (quirks & QB_right_axes_swapped) { - axis = InputDevice::Axis::right_y; + axis = Axis::RIGHT_Y; } else { - axis = InputDevice::Axis::right_x; + axis = Axis::RIGHT_X; } - } else if (_device_class == DeviceClass::gamepad) { + } else if (_device_class == DeviceClass::GAMEPAD) { if ((quirks & QB_no_analog_triggers) == 0) { - axis = InputDevice::Axis::left_trigger; + axis = Axis::LEFT_TRIGGER; have_analog_triggers = true; } - } else if (_device_class == DeviceClass::spatial_mouse) { - axis = InputDevice::Axis::z; + } else if (_device_class == DeviceClass::SPATIAL_MOUSE) { + axis = Axis::Z; } else { - axis = InputDevice::Axis::throttle; + axis = Axis::THROTTLE; } break; case ABS_RX: - if (_device_class == DeviceClass::spatial_mouse) { - axis = InputDevice::Axis::pitch; + if (_device_class == DeviceClass::SPATIAL_MOUSE) { + axis = Axis::PITCH; } else if ((quirks & QB_rstick_from_z) == 0) { - axis = InputDevice::Axis::right_x; + axis = Axis::RIGHT_X; } break; case ABS_RY: - if (_device_class == DeviceClass::spatial_mouse) { - axis = InputDevice::Axis::roll; + if (_device_class == DeviceClass::SPATIAL_MOUSE) { + axis = Axis::ROLL; } else if ((quirks & QB_rstick_from_z) == 0) { - axis = InputDevice::Axis::right_y; + axis = Axis::RIGHT_Y; } break; case ABS_RZ: if (quirks & QB_rstick_from_z) { if (quirks & QB_right_axes_swapped) { - axis = InputDevice::Axis::right_x; + axis = Axis::RIGHT_X; } else { - axis = InputDevice::Axis::right_y; + axis = Axis::RIGHT_Y; } - } else if (_device_class == DeviceClass::gamepad) { + } else if (_device_class == DeviceClass::GAMEPAD) { if ((quirks & QB_no_analog_triggers) == 0) { - axis = InputDevice::Axis::right_trigger; + axis = Axis::RIGHT_TRIGGER; have_analog_triggers = true; } else { // Special weird case for Trust GXT 24 - axis = InputDevice::Axis::right_y; + axis = Axis::RIGHT_Y; } } else { - axis = InputDevice::Axis::yaw; + axis = Axis::YAW; } break; case ABS_THROTTLE: if (quirks & QB_rudder_from_throttle) { - axis = InputDevice::Axis::rudder; + axis = Axis::RUDDER; } else { - axis = InputDevice::Axis::throttle; + axis = Axis::THROTTLE; } break; case ABS_RUDDER: - axis = InputDevice::Axis::rudder; + axis = Axis::RUDDER; break; case ABS_WHEEL: - axis = InputDevice::Axis::wheel; + axis = Axis::WHEEL; break; case ABS_GAS: - if (_device_class == DeviceClass::gamepad) { + if (_device_class == DeviceClass::GAMEPAD) { if ((quirks & QB_no_analog_triggers) == 0) { - axis = InputDevice::Axis::right_trigger; + axis = Axis::RIGHT_TRIGGER; have_analog_triggers = true; } } else { - axis = InputDevice::Axis::accelerator; + axis = Axis::ACCELERATOR; } break; case ABS_BRAKE: - if (_device_class == DeviceClass::gamepad) { - axis = InputDevice::Axis::left_trigger; + if (_device_class == DeviceClass::GAMEPAD) { + axis = Axis::LEFT_TRIGGER; have_analog_triggers = true; } else { - axis = InputDevice::Axis::brake; + axis = Axis::BRAKE; } break; case ABS_HAT0X: if (emulate_dpad) { _dpad_x_axis = i; _dpad_left_button = (int)_buttons.size(); - if (_device_class == DeviceClass::gamepad) { + if (_device_class == DeviceClass::GAMEPAD) { _buttons.push_back(ButtonState(GamepadButton::dpad_left())); _buttons.push_back(ButtonState(GamepadButton::dpad_right())); } else { @@ -620,7 +620,7 @@ init_device() { if (emulate_dpad) { _dpad_y_axis = i; _dpad_up_button = (int)_buttons.size(); - if (_device_class == DeviceClass::gamepad) { + if (_device_class == DeviceClass::GAMEPAD) { _buttons.push_back(ButtonState(GamepadButton::dpad_up())); _buttons.push_back(ButtonState(GamepadButton::dpad_down())); } else { @@ -633,18 +633,18 @@ init_device() { break; case ABS_HAT2X: if (quirks & QB_steam_controller) { - axis = InputDevice::Axis::right_trigger; + axis = Axis::RIGHT_TRIGGER; have_analog_triggers = true; } break; case ABS_HAT2Y: if (quirks & QB_steam_controller) { - axis = InputDevice::Axis::left_trigger; + axis = Axis::LEFT_TRIGGER; have_analog_triggers = true; } break; case ABS_PRESSURE: - axis = InputDevice::Axis::pressure; + axis = Axis::PRESSURE; break; } @@ -655,13 +655,13 @@ init_device() { // We'd like to reverse the Y axis to match the XInput behavior. // Also reverse the yaw axis to match right-hand coordinate system. // Also T.Flight Hotas X throttle is reversed and can go backwards. - if (axis == Axis::yaw || axis == Axis::rudder || axis == Axis::left_y || axis == Axis::right_y || - (axis == Axis::throttle && (quirks & QB_reversed_throttle) != 0) || - (_device_class == DeviceClass::spatial_mouse && (axis == Axis::y || axis == Axis::z || axis == Axis::roll)) || - (_device_class == DeviceClass::digitizer && axis == Axis::y)) { + if (axis == Axis::YAW || axis == Axis::RUDDER || axis == Axis::LEFT_Y || axis == Axis::RIGHT_Y || + (axis == Axis::THROTTLE && (quirks & QB_reversed_throttle) != 0) || + (_device_class == DeviceClass::SPATIAL_MOUSE && (axis == Axis::Y || axis == Axis::Z || axis == Axis::ROLL)) || + (_device_class == DeviceClass::DIGITIZER && axis == Axis::Y)) { std::swap(absinfo.maximum, absinfo.minimum); } - if (axis == Axis::throttle && (quirks & QB_centered_throttle) != 0) { + if (axis == Axis::THROTTLE && (quirks & QB_centered_throttle) != 0) { index = add_axis(axis, absinfo.minimum, absinfo.maximum, true); } else { index = add_axis(axis, absinfo.minimum, absinfo.maximum); @@ -678,8 +678,8 @@ init_device() { } if (test_bit(EV_REL, evtypes)) { - enable_feature(Feature::pointer); - add_pointer(PointerType::unknown, 0); + enable_feature(Feature::POINTER); + add_pointer(PointerType::UNKNOWN, 0); } if (test_bit(EV_FF, evtypes)) { @@ -688,7 +688,7 @@ init_device() { if (test_bit(FF_RUMBLE, effects)) { if (_can_write) { - enable_feature(Feature::vibration); + enable_feature(Feature::VIBRATION); } else { // Let the user know what he's missing out on. device_cat.warning() @@ -701,8 +701,8 @@ init_device() { if (_ltrigger_code >= 0 && _rtrigger_code >= 0 && !have_analog_triggers) { // Emulate analog triggers. _ltrigger_axis = (int)_axes.size(); - add_axis(Axis::left_trigger, 0, 1, false); - add_axis(Axis::right_trigger, 0, 1, false); + add_axis(Axis::LEFT_TRIGGER, 0, 1, false); + add_axis(Axis::RIGHT_TRIGGER, 0, 1, false); } else { _ltrigger_code = -1; _rtrigger_code = -1; @@ -1033,7 +1033,7 @@ map_button(int code, DeviceClass device_class, int quirks) { // BTN_THUMB and BTN_THUMB2 detect touching the touchpads. return ButtonHandle::none(); - } else if (device_class == DeviceClass::gamepad && + } else if (device_class == DeviceClass::GAMEPAD && (quirks & QB_alt_button_mapping) != 0) { static const ButtonHandle mapping[] = { GamepadButton::face_y(), @@ -1053,7 +1053,7 @@ map_button(int code, DeviceClass device_class, int quirks) { return mapping[code & 0xf]; } - } else if (device_class == DeviceClass::gamepad) { + } else if (device_class == DeviceClass::GAMEPAD) { // Based on "Jess Tech Colour Rumble Pad" static const ButtonHandle mapping[] = { GamepadButton::face_x(), diff --git a/panda/src/device/evdevInputDevice.h b/panda/src/device/evdevInputDevice.h index ce9e152cdc..ce5f966d5b 100644 --- a/panda/src/device/evdevInputDevice.h +++ b/panda/src/device/evdevInputDevice.h @@ -70,7 +70,7 @@ private: public: static ButtonHandle map_button(int code, - DeviceClass device_class = DeviceClass::unknown, + DeviceClass device_class = DeviceClass::UNKNOWN, int quirks = 0); public: diff --git a/panda/src/device/inputDevice.I b/panda/src/device/inputDevice.I index 3bf6aa9001..5b4a25e275 100644 --- a/panda/src/device/inputDevice.I +++ b/panda/src/device/inputDevice.I @@ -105,7 +105,7 @@ has_feature(Feature feature) const { */ INLINE bool InputDevice:: has_pointer() const { - return has_feature(Feature::pointer); + return has_feature(Feature::POINTER); } /** @@ -113,7 +113,7 @@ has_pointer() const { */ INLINE bool InputDevice:: has_keyboard() const { - return has_feature(Feature::keyboard); + return has_feature(Feature::KEYBOARD); } /** @@ -122,7 +122,7 @@ has_keyboard() const { */ INLINE bool InputDevice:: has_tracker() const { - return has_feature(Feature::tracker); + return has_feature(Feature::TRACKER); } /** @@ -131,7 +131,7 @@ has_tracker() const { */ INLINE bool InputDevice:: has_vibration() const { - return has_feature(Feature::vibration); + return has_feature(Feature::VIBRATION); } /** @@ -140,7 +140,7 @@ has_vibration() const { */ INLINE bool InputDevice:: has_battery() const { - return has_feature(Feature::battery); + return has_feature(Feature::BATTERY); } /** @@ -270,7 +270,7 @@ get_num_axes() const { /** * Associates the indicated Axis with the axis of the indicated index - * number. Pass Axis::none to turn off any association. + * number. Pass Axis::NONE to turn off any association. * * It is not necessary to call this if you simply want to query the state of * the various axes by index number. diff --git a/panda/src/device/inputDevice.cxx b/panda/src/device/inputDevice.cxx index 71869abc64..7997680847 100644 --- a/panda/src/device/inputDevice.cxx +++ b/panda/src/device/inputDevice.cxx @@ -134,18 +134,18 @@ add_axis(Axis axis, int minimum, int maximum, bool centered) { int InputDevice:: add_axis(Axis axis, int minimum, int maximum) { bool centered = (minimum < 0) - || axis == Axis::x - || axis == Axis::y - || axis == Axis::z - || axis == Axis::yaw - || axis == Axis::pitch - || axis == Axis::roll - || axis == Axis::left_x - || axis == Axis::left_y - || axis == Axis::right_x - || axis == Axis::right_y - || axis == Axis::wheel - || axis == Axis::rudder; + || axis == Axis::X + || axis == Axis::Y + || axis == Axis::Z + || axis == Axis::YAW + || axis == Axis::PITCH + || axis == Axis::ROLL + || axis == Axis::LEFT_X + || axis == Axis::LEFT_Y + || axis == Axis::RIGHT_X + || axis == Axis::RIGHT_Y + || axis == Axis::WHEEL + || axis == Axis::RUDDER; return add_axis(axis, minimum, maximum, centered); } @@ -321,7 +321,7 @@ set_axis_value(int index, double value) { device_cat.spam() << "Changed axis " << index; - if (_axes[index].axis != Axis::none) { + if (_axes[index].axis != Axis::NONE) { device_cat.spam(false) << " (" << _axes[index].axis << ")"; } @@ -350,7 +350,7 @@ axis_changed(int index, int state) { device_cat.spam() << "Changed axis " << index; - if (_axes[index].axis != Axis::none) { + if (_axes[index].axis != Axis::NONE) { device_cat.spam(false) << " (" << _axes[index].axis << ")"; } @@ -388,7 +388,7 @@ output(std::ostream &out) const { out << "connected)"; - if (_device_class != DeviceClass::unknown) { + if (_device_class != DeviceClass::UNKNOWN) { out << ", " << _device_class; } @@ -404,19 +404,19 @@ output(std::ostream &out) const { << (_axes.size() != 1 ? 'e' : 'i') << 's'; } - if (_features & (1 << (unsigned int)Feature::pointer)) { + if (_features & (1 << (unsigned int)Feature::POINTER)) { out << ", pointer"; } - if (_features & (1 << (unsigned int)Feature::keyboard)) { + if (_features & (1 << (unsigned int)Feature::KEYBOARD)) { out << ", keyboard"; } - if (_features & (1 << (unsigned int)Feature::tracker)) { + if (_features & (1 << (unsigned int)Feature::TRACKER)) { out << ", tracker"; } - if (_features & (1 << (unsigned int)Feature::vibration)) { + if (_features & (1 << (unsigned int)Feature::VIBRATION)) { out << ", vibration"; } - if (_features & (1 << (unsigned int)Feature::battery)) { + if (_features & (1 << (unsigned int)Feature::BATTERY)) { out << ", battery"; if (_battery_data.level > 0 && _battery_data.max_level > 0) { @@ -546,40 +546,40 @@ do_poll() { std::string InputDevice:: format_device_class(DeviceClass dc) { switch (dc) { - case InputDevice::DeviceClass::unknown: + case InputDevice::DeviceClass::UNKNOWN: return "unknown"; - case InputDevice::DeviceClass::virtual_device: - return "virtual_device"; + case InputDevice::DeviceClass::VIRTUAL: + return "virtual"; - case InputDevice::DeviceClass::keyboard: + case InputDevice::DeviceClass::KEYBOARD: return "keyboard"; - case InputDevice::DeviceClass::mouse: + case InputDevice::DeviceClass::MOUSE: return "mouse"; - case InputDevice::DeviceClass::touch: + case InputDevice::DeviceClass::TOUCH: return "touch"; - case InputDevice::DeviceClass::gamepad: + case InputDevice::DeviceClass::GAMEPAD: return "gamepad"; - case InputDevice::DeviceClass::flight_stick: + case InputDevice::DeviceClass::FLIGHT_STICK: return "flight_stick"; - case InputDevice::DeviceClass::steering_wheel: + case InputDevice::DeviceClass::STEERING_WHEEL: return "steering_wheel"; - case InputDevice::DeviceClass::dance_pad: + case InputDevice::DeviceClass::DANCE_PAD: return "dance_pad"; - case InputDevice::DeviceClass::hmd: + case InputDevice::DeviceClass::HMD: return "hmd"; - case InputDevice::DeviceClass::spatial_mouse: + case InputDevice::DeviceClass::SPATIAL_MOUSE: return "spatial_mouse"; - case InputDevice::DeviceClass::digitizer: + case InputDevice::DeviceClass::DIGITIZER: return "digitizer"; } return "**invalid**"; @@ -591,64 +591,64 @@ format_device_class(DeviceClass dc) { std::string InputDevice:: format_axis(Axis axis) { switch (axis) { - case InputDevice::Axis::none: + case Axis::NONE: return "none"; - case InputDevice::Axis::x: + case Axis::X: return "x"; - case InputDevice::Axis::y: + case Axis::Y: return "y"; - case InputDevice::Axis::z: + case Axis::Z: return "z"; - case InputDevice::Axis::yaw: + case Axis::YAW: return "yaw"; - case InputDevice::Axis::pitch: + case Axis::PITCH: return "pitch"; - case InputDevice::Axis::roll: + case Axis::ROLL: return "roll"; - case InputDevice::Axis::left_x: + case Axis::LEFT_X: return "left_x"; - case InputDevice::Axis::left_y: + case Axis::LEFT_Y: return "left_y"; - case InputDevice::Axis::left_trigger: + case Axis::LEFT_TRIGGER: return "left_trigger"; - case InputDevice::Axis::right_x: + case Axis::RIGHT_X: return "right_x"; - case InputDevice::Axis::right_y: + case Axis::RIGHT_Y: return "right_y"; - case InputDevice::Axis::right_trigger: + case Axis::RIGHT_TRIGGER: return "right_trigger"; - //case InputDevice::Axis::trigger: + //case Axis::TRIGGER: // return "trigger"; - case InputDevice::Axis::throttle: + case Axis::THROTTLE: return "throttle"; - case InputDevice::Axis::rudder: + case Axis::RUDDER: return "rudder"; - case InputDevice::Axis::wheel: + case Axis::WHEEL: return "wheel"; - case InputDevice::Axis::accelerator: + case Axis::ACCELERATOR: return "accelerator"; - case InputDevice::Axis::brake: + case Axis::BRAKE: return "brake"; - case InputDevice::Axis::pressure: + case Axis::PRESSURE: return "pressure"; } return "**invalid**"; diff --git a/panda/src/device/inputDevice.h b/panda/src/device/inputDevice.h index 83038075a8..445e0d07f1 100644 --- a/panda/src/device/inputDevice.h +++ b/panda/src/device/inputDevice.h @@ -56,84 +56,126 @@ PUBLISHED: // type of input device. enum class DeviceClass { // It is not known what type of device this is. - unknown, + UNKNOWN, // This means that the device doesn't correspond to a physical // device, but rather to a dynamic source of input events. - virtual_device, + VIRTUAL, // A physical, alphabetical keyboard. - keyboard, + KEYBOARD, - mouse, - touch, + MOUSE, + TOUCH, // A gamepad with action buttons, a D-pad, and thumbsticks. - gamepad, + GAMEPAD, - flight_stick, - steering_wheel, - dance_pad, + FLIGHT_STICK, + STEERING_WHEEL, + DANCE_PAD, // Head-mounted display. - hmd, + HMD, // 3D mouse, such as produced by 3Dconnexion. - spatial_mouse, + SPATIAL_MOUSE, // A graphics tablet with stylus/pen. - digitizer, + DIGITIZER, + + // Deprecated aliases. + unknown = UNKNOWN, + virtual_device = VIRTUAL, + keyboard = KEYBOARD, + mouse = MOUSE, + touch = TOUCH, + gamepad = GAMEPAD, + flight_stick = FLIGHT_STICK, + steering_wheel = STEERING_WHEEL, + dance_pad = DANCE_PAD, + hmd = HMD, + spatial_mouse = SPATIAL_MOUSE, + digitizer = DIGITIZER, }; enum class Feature { // The device provides absolute screen coordinates. - pointer, + POINTER, // The device has an interface for providing text input. - keyboard, + KEYBOARD, // The device has a motion tracker, such as an HMD. - tracker, + TRACKER, // The device can produce force feedback. - vibration, + VIBRATION, // The device provides information about battery life. - battery, + BATTERY, + + // Deprecated aliases. + pointer = POINTER, + keyboard = KEYBOARD, + tracker = TRACKER, + vibration = VIBRATION, + battery = BATTERY, }; enum class Axis { - none, + NONE, // Generic translational axes - x, - y, - z, + X, + Y, + Z, // Generic rotational axes, used by joysticks and 3D mice - yaw, - pitch, - roll, + YAW, + PITCH, + ROLL, // Gamepad - left_x, - left_y, - left_trigger, - right_x, - right_y, - right_trigger, + LEFT_X, + LEFT_Y, + LEFT_TRIGGER, + RIGHT_X, + RIGHT_Y, + RIGHT_TRIGGER, // Flight stick specific - throttle, - rudder, // When available separately from yaw + THROTTLE, + RUDDER, // When available separately from yaw // Steering wheel / pedals - wheel, - accelerator, - brake, + WHEEL, + ACCELERATOR, + BRAKE, // Pen pressure - pressure, + PRESSURE, + + // Deprecated aliases + none = NONE, + x = X, + y = Y, + z = Z, + yaw = YAW, + pitch = PITCH, + roll = ROLL, + left_x = LEFT_X, + left_y = LEFT_Y, + left_trigger = LEFT_TRIGGER, + right_x = RIGHT_X, + right_y = RIGHT_Y, + right_trigger = RIGHT_TRIGGER, + throttle = THROTTLE, + rudder = RUDDER, + wheel = WHEEL, + accelerator = ACCELERATOR, + brake = BRAKE, + pressure = PRESSURE, }; enum State { @@ -168,7 +210,7 @@ PUBLISHED: PUBLISHED: operator bool() { return known && value != 0.0; } - Axis axis = Axis::none; + Axis axis = Axis::NONE; double value = 0.0; bool known = false; @@ -319,7 +361,7 @@ protected: std::string _name; std::string _serial_number; std::string _manufacturer; - DeviceClass _device_class = DeviceClass::unknown; + DeviceClass _device_class = DeviceClass::UNKNOWN; unsigned int _features = 0; int _event_sequence = 0; unsigned short _vendor_id = 0; diff --git a/panda/src/device/ioKitInputDevice.cxx b/panda/src/device/ioKitInputDevice.cxx index e80dfccd94..470b13e46c 100644 --- a/panda/src/device/ioKitInputDevice.cxx +++ b/panda/src/device/ioKitInputDevice.cxx @@ -80,19 +80,25 @@ IOKitInputDevice(IOHIDDeviceRef device) : } if (IOHIDDeviceConformsTo(device, kHIDPage_GenericDesktop, kHIDUsage_GD_Mouse)) { - _device_class = DeviceClass::mouse; - } else if (IOHIDDeviceConformsTo(device, kHIDPage_GenericDesktop, kHIDUsage_GD_Keyboard)) { - _device_class = DeviceClass::keyboard; - } else if (IOHIDDeviceConformsTo(device, kHIDPage_GenericDesktop, kHIDUsage_GD_GamePad)) { - _device_class = DeviceClass::gamepad; - } else if (IOHIDDeviceConformsTo(device, kHIDPage_Simulation, kHIDUsage_Sim_FlightStick)) { - _device_class = DeviceClass::flight_stick; - } else if (IOHIDDeviceConformsTo(device, kHIDPage_Simulation, kHIDUsage_GD_Joystick)) { - _device_class = DeviceClass::flight_stick; - } else if (_vendor_id == 0x044f && _product_id == 0xb108) { + _device_class = DeviceClass::MOUSE; + } + else if (IOHIDDeviceConformsTo(device, kHIDPage_GenericDesktop, kHIDUsage_GD_Keyboard)) { + _device_class = DeviceClass::KEYBOARD; + } + else if (IOHIDDeviceConformsTo(device, kHIDPage_GenericDesktop, kHIDUsage_GD_GamePad)) { + _device_class = DeviceClass::GAMEPAD; + } + else if (IOHIDDeviceConformsTo(device, kHIDPage_Simulation, kHIDUsage_Sim_FlightStick)) { + _device_class = DeviceClass::FLIGHT_STICK; + } + else if (IOHIDDeviceConformsTo(device, kHIDPage_Simulation, kHIDUsage_GD_Joystick)) { + _device_class = DeviceClass::FLIGHT_STICK; + } + else if (_vendor_id == 0x044f && _product_id == 0xb108) { // T.Flight Hotas X - _device_class = DeviceClass::flight_stick; - } else if (_vendor_id == 0x046d && + _device_class = DeviceClass::FLIGHT_STICK; + } + else if (_vendor_id == 0x046d && (_product_id == 0xc623 || _product_id == 0xc625 || _product_id == 0xc626 || @@ -101,9 +107,10 @@ IOKitInputDevice(IOHIDDeviceRef device) : _product_id == 0xc629 || _product_id == 0xc62b)) { // 3Dconnexion SpaceNavigator and friends. - _device_class = DeviceClass::spatial_mouse; - } else if (_name == "usb gamepad") { - _device_class = DeviceClass::gamepad; + _device_class = DeviceClass::SPATIAL_MOUSE; + } + else if (_name == "usb gamepad") { + _device_class = DeviceClass::GAMEPAD; } CFArrayRef elements = IOHIDDeviceCopyMatchingElements(device, nullptr, 0); @@ -125,8 +132,8 @@ IOKitInputDevice(IOHIDDeviceRef device) : } if (_pointer_x != nullptr && _pointer_y != nullptr) { - enable_feature(Feature::pointer); - add_pointer(PointerType::unknown, 0); + enable_feature(Feature::POINTER); + add_pointer(PointerType::UNKNOWN, 0); } _is_connected = true; @@ -145,7 +152,7 @@ IOKitInputDevice:: void IOKitInputDevice:: parse_element(IOHIDElementRef element) { ButtonHandle handle = ButtonHandle::none(); - Axis axis = Axis::none; + Axis axis = Axis::NONE; uint32_t page = IOHIDElementGetUsagePage(element); uint32_t usage = IOHIDElementGetUsage(element); @@ -155,61 +162,61 @@ parse_element(IOHIDElementRef element) { case kHIDPage_GenericDesktop: switch (usage) { case kHIDUsage_GD_X: - if (_device_class == DeviceClass::gamepad) { - axis = Axis::left_x; - } else if (_device_class == DeviceClass::flight_stick) { - axis = Axis::roll; - } else if (_device_class == DeviceClass::mouse) { + if (_device_class == DeviceClass::GAMEPAD) { + axis = Axis::LEFT_X; + } else if (_device_class == DeviceClass::FLIGHT_STICK) { + axis = Axis::ROLL; + } else if (_device_class == DeviceClass::MOUSE) { _pointer_x = element; return; } else { - axis = Axis::x; + axis = Axis::X; } break; case kHIDUsage_GD_Y: - if (_device_class == DeviceClass::gamepad) { - axis = Axis::left_y; - } else if (_device_class == DeviceClass::flight_stick) { - axis = Axis::pitch; - } else if (_device_class == DeviceClass::mouse) { + if (_device_class == DeviceClass::GAMEPAD) { + axis = Axis::LEFT_Y; + } else if (_device_class == DeviceClass::FLIGHT_STICK) { + axis = Axis::PITCH; + } else if (_device_class == DeviceClass::MOUSE) { _pointer_y = element; return; } else { - axis = Axis::y; + axis = Axis::Y; } break; case kHIDUsage_GD_Z: - if (_device_class == DeviceClass::gamepad) { - axis = Axis::left_trigger; - } else if (_device_class == DeviceClass::flight_stick) { - axis = Axis::throttle; + if (_device_class == DeviceClass::GAMEPAD) { + axis = Axis::LEFT_TRIGGER; + } else if (_device_class == DeviceClass::FLIGHT_STICK) { + axis = Axis::THROTTLE; } else { - axis = Axis::z; + axis = Axis::Z; } break; case kHIDUsage_GD_Rx: - if (_device_class == DeviceClass::gamepad) { - axis = Axis::right_x; + if (_device_class == DeviceClass::GAMEPAD) { + axis = Axis::RIGHT_X; } else { - axis = Axis::pitch; + axis = Axis::PITCH; } break; case kHIDUsage_GD_Ry: - if (_device_class == DeviceClass::gamepad) { - axis = Axis::right_y; + if (_device_class == DeviceClass::GAMEPAD) { + axis = Axis::RIGHT_Y; } else { - axis = Axis::roll; + axis = Axis::ROLL; } break; case kHIDUsage_GD_Rz: - if (_device_class == DeviceClass::gamepad) { - axis = Axis::right_trigger; + if (_device_class == DeviceClass::GAMEPAD) { + axis = Axis::RIGHT_TRIGGER; } else { - axis = Axis::yaw; + axis = Axis::YAW; } break; case kHIDUsage_GD_Slider: - axis = Axis::rudder; + axis = Axis::RUDDER; break; case kHIDUsage_GD_Dial: break; @@ -241,28 +248,28 @@ parse_element(IOHIDElementRef element) { case kHIDPage_Simulation: switch (usage) { case kHIDUsage_Sim_Rudder: - axis = Axis::rudder; + axis = Axis::RUDDER; break; case kHIDUsage_Sim_Throttle: - axis = Axis::throttle; + axis = Axis::THROTTLE; break; case kHIDUsage_Sim_Accelerator: - axis = Axis::accelerator; + axis = Axis::ACCELERATOR; break; case kHIDUsage_Sim_Brake: - axis = Axis::brake; + axis = Axis::BRAKE; break; } break; } - if (axis != Axis::none) { + if (axis != Axis::NONE) { int min = IOHIDElementGetLogicalMin(element); int max = IOHIDElementGetLogicalMax(element); - if (_vendor_id == 0x044f && _product_id == 0xb108 && axis == Axis::throttle) { + if (_vendor_id == 0x044f && _product_id == 0xb108 && axis == Axis::THROTTLE) { // T.Flight Hotas X throttle is reversed and can go backwards. add_axis(axis, max, min, true); - } else if (axis == Axis::yaw || axis == Axis::rudder || axis == Axis::left_y || axis == Axis::right_y || - (_device_class == DeviceClass::spatial_mouse && (axis == Axis::y || axis == Axis::z || axis == Axis::roll))) { + } else if (axis == Axis::YAW || axis == Axis::RUDDER || axis == Axis::LEFT_Y || axis == Axis::RIGHT_Y || + (_device_class == DeviceClass::SPATIAL_MOUSE && (axis == Axis::Y || axis == Axis::Z || axis == Axis::ROLL))) { // We'd like to reverse the Y axis to match the XInput behavior. // We also reverse yaw to obey the right-hand rule. add_axis(axis, max, min); @@ -600,7 +607,7 @@ parse_element(IOHIDElementRef element) { break; case kHIDPage_Button: - if (_device_class == DeviceClass::gamepad) { + if (_device_class == DeviceClass::GAMEPAD) { if (_vendor_id == 0x0810 && _product_id == 0xe501) { // SNES-style USB gamepad static const ButtonHandle gamepad_buttons[] = { @@ -644,11 +651,11 @@ parse_element(IOHIDElementRef element) { handle = gamepad_buttons[usage]; } } - } else if (_device_class == DeviceClass::flight_stick) { + } else if (_device_class == DeviceClass::FLIGHT_STICK) { if (usage > 0) { handle = GamepadButton::joystick(usage - 1); } - } else if (_device_class == DeviceClass::mouse) { + } else if (_device_class == DeviceClass::MOUSE) { // In Panda, wheel and right button are flipped around... int button = (usage == 2 || usage == 3) ? (4 - usage) : (usage - 1); handle = MouseButton::button(button); diff --git a/panda/src/device/linuxJoystickDevice.cxx b/panda/src/device/linuxJoystickDevice.cxx index 697300adff..22f2851537 100644 --- a/panda/src/device/linuxJoystickDevice.cxx +++ b/panda/src/device/linuxJoystickDevice.cxx @@ -136,9 +136,9 @@ open_device() { << " button " << (int)i << ": 0x" << std::hex << btnmap[i] << "\n"; } } else if (handle == GamepadButton::face_a()) { - _device_class = DeviceClass::gamepad; + _device_class = DeviceClass::GAMEPAD; } else if (handle == GamepadButton::trigger()) { - _device_class = DeviceClass::flight_stick; + _device_class = DeviceClass::FLIGHT_STICK; } else if (handle == GamepadButton::dpad_left()) { emulate_dpad = false; } else if (handle == GamepadButton::ltrigger()) { @@ -155,71 +155,71 @@ open_device() { ioctl(_fd, JSIOCGAXMAP, axmap); for (uint8_t i = 0; i < num_axes; ++i) { - Axis axis = Axis::none; + Axis axis = Axis::NONE; switch (axmap[i]) { case ABS_X: - if (_device_class == DeviceClass::gamepad) { - axis = InputDevice::Axis::left_x; - } else if (_device_class == DeviceClass::flight_stick) { - axis = InputDevice::Axis::roll; + if (_device_class == DeviceClass::GAMEPAD) { + axis = Axis::LEFT_X; + } else if (_device_class == DeviceClass::FLIGHT_STICK) { + axis = Axis::ROLL; } else { - axis = InputDevice::Axis::x; + axis = Axis::X; } break; case ABS_Y: - if (_device_class == DeviceClass::gamepad) { - axis = InputDevice::Axis::left_y; - } else if (_device_class == DeviceClass::flight_stick) { - axis = InputDevice::Axis::pitch; + if (_device_class == DeviceClass::GAMEPAD) { + axis = Axis::LEFT_Y; + } else if (_device_class == DeviceClass::FLIGHT_STICK) { + axis = Axis::PITCH; } else { - axis = InputDevice::Axis::y; + axis = Axis::Y; } break; case ABS_Z: - if (_device_class == DeviceClass::gamepad) { - axis = Axis::left_trigger; + if (_device_class == DeviceClass::GAMEPAD) { + axis = Axis::LEFT_TRIGGER; } else { - //axis = Axis::trigger; + //axis = Axis::TRIGGER; } break; case ABS_RX: - axis = Axis::right_x; + axis = Axis::RIGHT_X; break; case ABS_RY: - axis = Axis::right_y; + axis = Axis::RIGHT_Y; break; case ABS_RZ: - if (_device_class == DeviceClass::gamepad) { - axis = InputDevice::Axis::right_trigger; + if (_device_class == DeviceClass::GAMEPAD) { + axis = Axis::RIGHT_TRIGGER; } else { - axis = InputDevice::Axis::yaw; + axis = Axis::YAW; } break; case ABS_THROTTLE: - axis = InputDevice::Axis::throttle; + axis = Axis::THROTTLE; break; case ABS_RUDDER: - axis = InputDevice::Axis::rudder; + axis = Axis::RUDDER; break; case ABS_WHEEL: - axis = InputDevice::Axis::wheel; + axis = Axis::WHEEL; break; case ABS_GAS: - axis = InputDevice::Axis::accelerator; + axis = Axis::ACCELERATOR; break; case ABS_BRAKE: - axis = InputDevice::Axis::brake; + axis = Axis::BRAKE; break; case ABS_HAT0X: @@ -227,7 +227,7 @@ open_device() { // Emulate D-Pad or hat switch. _dpad_x_axis = i; _dpad_left_button = (int)_buttons.size(); - if (_device_class == DeviceClass::gamepad) { + if (_device_class == DeviceClass::GAMEPAD) { add_button(GamepadButton::dpad_left()); add_button(GamepadButton::dpad_right()); } else { @@ -236,7 +236,7 @@ open_device() { } _buttons[_dpad_left_button]._state = S_up; _buttons[_dpad_left_button+1]._state = S_up; - axis = Axis::none; + axis = Axis::NONE; } break; @@ -245,7 +245,7 @@ open_device() { // Emulate D-Pad. _dpad_y_axis = i; _dpad_up_button = (int)_buttons.size(); - if (_device_class == DeviceClass::gamepad) { + if (_device_class == DeviceClass::GAMEPAD) { add_button(GamepadButton::dpad_up()); add_button(GamepadButton::dpad_down()); } else { @@ -254,19 +254,19 @@ open_device() { } _buttons[_dpad_up_button]._state = S_up; _buttons[_dpad_up_button+1]._state = S_up; - axis = Axis::none; + axis = Axis::NONE; } break; case ABS_HAT2X: - if (_device_class == DeviceClass::gamepad) { - axis = InputDevice::Axis::right_trigger; + if (_device_class == DeviceClass::GAMEPAD) { + axis = Axis::RIGHT_TRIGGER; } break; case ABS_HAT2Y: - if (_device_class == DeviceClass::gamepad) { - axis = InputDevice::Axis::left_trigger; + if (_device_class == DeviceClass::GAMEPAD) { + axis = Axis::LEFT_TRIGGER; } break; @@ -275,17 +275,17 @@ open_device() { device_cat.debug() << "Unmapped /dev/input/js" << _index << " axis " << (int)i << ": 0x" << std::hex << (int)axmap[i] << "\n"; } - axis = Axis::none; + axis = Axis::NONE; break; } _axes[i].axis = axis; - if (axis == Axis::left_trigger || axis == Axis::right_trigger) { + if (axis == Axis::LEFT_TRIGGER || axis == Axis::RIGHT_TRIGGER) { // We'd like to use 0.0 to indicate the resting position. _axes[i]._scale = 1.0 / 65534.0; _axes[i]._bias = 0.5; have_analog_triggers = true; - } else if (axis == Axis::left_y || axis == Axis::right_y || axis == Axis::y) { + } else if (axis == Axis::LEFT_Y || axis == Axis::RIGHT_Y || axis == Axis::Y) { _axes[i]._scale = 1.0 / -32767.0; _axes[i]._bias = 0.0; } else { @@ -298,8 +298,8 @@ open_device() { if (_ltrigger_button >= 0 && _rtrigger_button >= 0 && !have_analog_triggers) { // Emulate analog triggers. _ltrigger_axis = (int)_axes.size(); - add_axis(Axis::left_trigger, 0, 1, false); - add_axis(Axis::right_trigger, 0, 1, false); + add_axis(Axis::LEFT_TRIGGER, 0, 1, false); + add_axis(Axis::RIGHT_TRIGGER, 0, 1, false); } else { _ltrigger_button = -1; _rtrigger_button = -1; diff --git a/panda/src/device/winRawInputDevice.cxx b/panda/src/device/winRawInputDevice.cxx index 0e1eb937bf..13dea22e03 100644 --- a/panda/src/device/winRawInputDevice.cxx +++ b/panda/src/device/winRawInputDevice.cxx @@ -50,43 +50,43 @@ static const struct DeviceMapping { } mapping_presets[] = { // SNES-style USB gamepad, or cheap unbranded USB gamepad with no sticks // ABXY are mapped based on their position, not based on their label. - {0x0810, 0xe501, InputDevice::DeviceClass::gamepad, QB_no_analog_triggers, + {0x0810, 0xe501, InputDevice::DeviceClass::GAMEPAD, QB_no_analog_triggers, {"face_y", "face_b", "face_a", "face_x", "lshoulder", "rshoulder", "ltrigger", "rtrigger", "back", "start"} }, // Unbranded generic cheap USB gamepad - {0x0810, 0x0001, InputDevice::DeviceClass::gamepad, QB_rstick_from_z | QB_no_analog_triggers | QB_right_axes_swapped, + {0x0810, 0x0001, InputDevice::DeviceClass::GAMEPAD, QB_rstick_from_z | QB_no_analog_triggers | QB_right_axes_swapped, {"face_y", "face_b", "face_a", "face_x", "lshoulder", "rshoulder", "ltrigger", "rtrigger", "back", "start", "lstick", "rstick"} }, // Trust GXT 24 / SPEED Link SL-6535-SBK-01 - {0x0079, 0x0006, InputDevice::DeviceClass::gamepad, QB_rstick_from_z | QB_no_analog_triggers, + {0x0079, 0x0006, InputDevice::DeviceClass::GAMEPAD, QB_rstick_from_z | QB_no_analog_triggers, {"face_y", "face_b", "face_a", "face_x", "lshoulder", "rshoulder", "ltrigger", "rtrigger", "back", "start", "lstick", "rstick"} }, // T.Flight Hotas X - {0x044f, 0xb108, InputDevice::DeviceClass::flight_stick, QB_centered_throttle | QB_reversed_throttle, + {0x044f, 0xb108, InputDevice::DeviceClass::FLIGHT_STICK, QB_centered_throttle | QB_reversed_throttle, {0} }, // NVIDIA Shield Controller - {0x0955, 0x7214, InputDevice::DeviceClass::gamepad, 0, + {0x0955, 0x7214, InputDevice::DeviceClass::GAMEPAD, 0, {"face_a", "face_b", 0, "face_x", "face_y", "rshoulder", "lshoulder", "rshoulder", 0, 0, 0, "start", 0, "lstick", "rstick", 0} }, // Dualshock (PS4) - {0x054c, 0x05c4, InputDevice::DeviceClass::gamepad, QB_rstick_from_z, + {0x054c, 0x05c4, InputDevice::DeviceClass::GAMEPAD, QB_rstick_from_z, {"face_x", "face_a", "face_b", "face_y", "lshoulder", "rshoulder", 0, 0, "back", "start", "lstick", "rstick", "guide", 0} }, // Dualshock 2nd Gen (PS4 Slim) - {0x054c, 0x09cc, InputDevice::DeviceClass::gamepad, QB_rstick_from_z, + {0x054c, 0x09cc, InputDevice::DeviceClass::GAMEPAD, QB_rstick_from_z, {"face_x", "face_a", "face_b", "face_y", "lshoulder", "rshoulder", 0, 0, "back", "start", "lstick", "rstick", "guide", 0} }, // Dualshock 2nd Gen (PS4 wireless adapter) - {0x054c, 0x0ba0, InputDevice::DeviceClass::gamepad, QB_rstick_from_z, + {0x054c, 0x0ba0, InputDevice::DeviceClass::GAMEPAD, QB_rstick_from_z, {"face_x", "face_a", "face_b", "face_y", "lshoulder", "rshoulder", 0, 0, "back", "start", "lstick", "rstick", "guide", 0} }, // PS2 controller connected through a USB adapter - {0x2563, 0x0523, InputDevice::DeviceClass::gamepad, QB_rstick_from_z | QB_no_analog_triggers, + {0x2563, 0x0523, InputDevice::DeviceClass::GAMEPAD, QB_rstick_from_z | QB_no_analog_triggers, {"face_y", "face_b", "face_a", "face_x", "lshoulder", "rshoulder", "ltrigger", "rtrigger", "back", "start", "lstick", "rstick"} }, // FrSky Simulator - {0x0483, 0x5720, InputDevice::DeviceClass::flight_stick, 0, + {0x0483, 0x5720, InputDevice::DeviceClass::FLIGHT_STICK, 0, {0} }, {0}, @@ -183,11 +183,11 @@ on_arrival(HANDLE handle, const RID_DEVICE_INFO &info, std::string name) { switch (info.dwType) { case RIM_TYPEMOUSE: - _device_class = DeviceClass::mouse; + _device_class = DeviceClass::MOUSE; break; case RIM_TYPEKEYBOARD: - _device_class = DeviceClass::keyboard; + _device_class = DeviceClass::KEYBOARD; break; case RIM_TYPEHID: @@ -197,32 +197,32 @@ on_arrival(HANDLE handle, const RID_DEVICE_INFO &info, std::string name) { // Gamepads if (info.hid.usUsagePage == HID_USAGE_PAGE_GENERIC && info.hid.usUsage == HID_USAGE_GENERIC_GAMEPAD) { - _device_class = DeviceClass::gamepad; + _device_class = DeviceClass::GAMEPAD; // Various game controllers, incl. flight sticks and some gamepads } else if (info.hid.usUsagePage == HID_USAGE_PAGE_GENERIC && info.hid.usUsage == HID_USAGE_GENERIC_JOYSTICK) { - _device_class = DeviceClass::flight_stick; + _device_class = DeviceClass::FLIGHT_STICK; if (_name == "usb gamepad") { // Well, it claims to be a gamepad... - _device_class = DeviceClass::gamepad; + _device_class = DeviceClass::GAMEPAD; } // Mice } else if (info.hid.usUsagePage == HID_USAGE_PAGE_GENERIC && info.hid.usUsage == HID_USAGE_GENERIC_MOUSE) { - _device_class = DeviceClass::mouse; + _device_class = DeviceClass::MOUSE; // Keyboards } else if (info.hid.usUsagePage == HID_USAGE_PAGE_GENERIC && info.hid.usUsage == HID_USAGE_GENERIC_KEYBOARD) { - _device_class = DeviceClass::keyboard; + _device_class = DeviceClass::KEYBOARD; // Digitizers } else if (info.hid.usUsagePage == HID_USAGE_PAGE_DIGITIZER && info.hid.usUsage == 1) { - _device_class = DeviceClass::digitizer; + _device_class = DeviceClass::DIGITIZER; // 3Dconnexion SpaceNavigator and friends. } else if (_vendor_id == 0x046d && @@ -233,7 +233,7 @@ on_arrival(HANDLE handle, const RID_DEVICE_INFO &info, std::string name) { _product_id == 0xc628 || _product_id == 0xc629 || _product_id == 0xc62b)) { - _device_class = DeviceClass::spatial_mouse; + _device_class = DeviceClass::SPATIAL_MOUSE; } break; @@ -241,8 +241,8 @@ on_arrival(HANDLE handle, const RID_DEVICE_INFO &info, std::string name) { return false; } - if (_device_class == DeviceClass::gamepad || - _device_class == DeviceClass::flight_stick) { + if (_device_class == DeviceClass::GAMEPAD || + _device_class == DeviceClass::FLIGHT_STICK) { // Do we have a built-in mapping? const DeviceMapping *mapping = mapping_presets; while (mapping->vendor != 0) { @@ -354,17 +354,17 @@ on_arrival(HANDLE handle, const RID_DEVICE_INFO &info, std::string name) { ButtonHandle handle = ButtonHandle::none(); switch (cap.UsagePage) { case HID_USAGE_PAGE_BUTTON: - if (_device_class == DeviceClass::gamepad) { + if (_device_class == DeviceClass::GAMEPAD) { if (usage > 0 && usage - 1 < _countof(default_gamepad_mapping)) { if (gamepad_buttons[usage - 1] != nullptr) { handle = registry->find_button(gamepad_buttons[usage - 1]); } } - } else if (_device_class == DeviceClass::flight_stick) { + } else if (_device_class == DeviceClass::FLIGHT_STICK) { if (usage > 0) { handle = GamepadButton::joystick(usage - 1); } - } else if (_device_class == DeviceClass::mouse) { + } else if (_device_class == DeviceClass::MOUSE) { // In Panda, wheel and right button are flipped around... int button = (usage == 2 || usage == 3) ? (4 - usage) : (usage - 1); handle = MouseButton::button(button); @@ -434,44 +434,44 @@ on_arrival(HANDLE handle, const RID_DEVICE_INFO &info, std::string name) { is_signed = false; } - Axis axis = Axis::none; + Axis axis = Axis::NONE; switch (cap.UsagePage) { case HID_USAGE_PAGE_GENERIC: switch (usage) { case HID_USAGE_GENERIC_X: - if (_device_class == DeviceClass::gamepad) { - axis = Axis::left_x; - } else if (_device_class == DeviceClass::flight_stick) { - axis = Axis::roll; + if (_device_class == DeviceClass::GAMEPAD) { + axis = Axis::LEFT_X; + } else if (_device_class == DeviceClass::FLIGHT_STICK) { + axis = Axis::ROLL; } else { - axis = Axis::x; + axis = Axis::X; } break; case HID_USAGE_GENERIC_Y: - if (_device_class == DeviceClass::gamepad) { - axis = Axis::left_y; + if (_device_class == DeviceClass::GAMEPAD) { + axis = Axis::LEFT_Y; swap(cap.LogicalMin, cap.LogicalMax); - } else if (_device_class == DeviceClass::flight_stick) { - axis = Axis::pitch; + } else if (_device_class == DeviceClass::FLIGHT_STICK) { + axis = Axis::PITCH; } else { - axis = Axis::y; + axis = Axis::Y; swap(cap.LogicalMin, cap.LogicalMax); } break; case HID_USAGE_GENERIC_Z: - if (_device_class == DeviceClass::gamepad) { + if (_device_class == DeviceClass::GAMEPAD) { if (quirks & QB_rstick_from_z) { if (quirks & QB_right_axes_swapped) { - axis = InputDevice::Axis::right_y; + axis = InputDevice::Axis::RIGHT_Y; swap(cap.LogicalMin, cap.LogicalMax); } else { - axis = InputDevice::Axis::right_x; + axis = InputDevice::Axis::RIGHT_X; } } else if ((quirks & QB_no_analog_triggers) == 0) { - axis = Axis::left_trigger; + axis = Axis::LEFT_TRIGGER; } - } else if (_device_class == DeviceClass::flight_stick) { - axis = Axis::throttle; + } else if (_device_class == DeviceClass::FLIGHT_STICK) { + axis = Axis::THROTTLE; if ((quirks & QB_reversed_throttle) != 0) { std::swap(cap.LogicalMin, cap.LogicalMax); } @@ -479,63 +479,63 @@ on_arrival(HANDLE handle, const RID_DEVICE_INFO &info, std::string name) { is_signed = false; } } else { - axis = Axis::z; + axis = Axis::Z; swap(cap.LogicalMin, cap.LogicalMax); } break; case HID_USAGE_GENERIC_RX: - if (_device_class == DeviceClass::gamepad) { + if (_device_class == DeviceClass::GAMEPAD) { if (quirks & QB_rstick_from_z) { if ((quirks & QB_no_analog_triggers) == 0) { - axis = Axis::left_trigger; + axis = Axis::LEFT_TRIGGER; } } else { - axis = Axis::right_x; + axis = Axis::RIGHT_X; } } else { - axis = Axis::pitch; + axis = Axis::PITCH; } break; case HID_USAGE_GENERIC_RY: - if (_device_class == DeviceClass::gamepad) { + if (_device_class == DeviceClass::GAMEPAD) { if (quirks & QB_rstick_from_z) { if ((quirks & QB_no_analog_triggers) == 0) { - axis = Axis::right_trigger; + axis = Axis::RIGHT_TRIGGER; } } else { - axis = Axis::right_y; + axis = Axis::RIGHT_Y; swap(cap.LogicalMin, cap.LogicalMax); } } else { - axis = Axis::roll; + axis = Axis::ROLL; swap(cap.LogicalMin, cap.LogicalMax); } break; case HID_USAGE_GENERIC_RZ: - if (_device_class == DeviceClass::gamepad) { + if (_device_class == DeviceClass::GAMEPAD) { if (quirks & QB_rstick_from_z) { if (quirks & QB_right_axes_swapped) { - axis = InputDevice::Axis::right_x; + axis = InputDevice::Axis::RIGHT_X; } else { - axis = InputDevice::Axis::right_y; + axis = InputDevice::Axis::RIGHT_Y; swap(cap.LogicalMin, cap.LogicalMax); } } else if ((quirks & QB_no_analog_triggers) == 0) { - axis = Axis::right_trigger; + axis = Axis::RIGHT_TRIGGER; } } else { // Flip to match Panda's convention for heading. - axis = Axis::yaw; + axis = Axis::YAW; swap(cap.LogicalMin, cap.LogicalMax); } break; case HID_USAGE_GENERIC_SLIDER: // Flip to match Panda's convention for heading. - axis = Axis::rudder; + axis = Axis::RUDDER; swap(cap.LogicalMin, cap.LogicalMax); break; case HID_USAGE_GENERIC_WHEEL: - axis = Axis::wheel; + axis = Axis::WHEEL; break; case HID_USAGE_GENERIC_HATSWITCH: // This is handled specially. @@ -548,7 +548,7 @@ on_arrival(HANDLE handle, const RID_DEVICE_INFO &info, std::string name) { case HID_USAGE_PAGE_DIGITIZER: switch (usage) { case 0x30: - axis = Axis::pressure; + axis = Axis::PRESSURE; break; } break; @@ -559,7 +559,7 @@ on_arrival(HANDLE handle, const RID_DEVICE_INFO &info, std::string name) { // have a weird extra Z axis with DataIndex 2 that should be ignored. for (size_t i = 0; i < _axes.size(); ++i) { if (_axes[i].axis == axis) { - axis = Axis::none; + axis = Axis::NONE; break; } } @@ -589,7 +589,7 @@ on_arrival(HANDLE handle, const RID_DEVICE_INFO &info, std::string name) { // Do we need to emulate a hat switch or directional pad? if (_hat_data_index != -1) { _hat_left_button = (int)_buttons.size(); - if (_device_class == DeviceClass::gamepad) { + if (_device_class == DeviceClass::GAMEPAD) { _buttons.push_back(ButtonState(GamepadButton::dpad_left())); _buttons.push_back(ButtonState(GamepadButton::dpad_right())); _buttons.push_back(ButtonState(GamepadButton::dpad_down())); diff --git a/panda/src/device/xInputDevice.cxx b/panda/src/device/xInputDevice.cxx index 70b7d5bf3f..4405cc7225 100644 --- a/panda/src/device/xInputDevice.cxx +++ b/panda/src/device/xInputDevice.cxx @@ -335,43 +335,43 @@ init_device(const XINPUT_CAPABILITIES_EX &caps, const XINPUT_STATE &state) { switch (caps.SubType) { default: case XINPUT_DEVSUBTYPE_GAMEPAD: - _device_class = DeviceClass::gamepad; - _axes[0].axis = Axis::left_trigger; - _axes[1].axis = Axis::right_trigger; - _axes[2].axis = Axis::left_x; - _axes[3].axis = Axis::left_y; - _axes[4].axis = Axis::right_x; - _axes[5].axis = Axis::right_y; + _device_class = DeviceClass::GAMEPAD; + _axes[0].axis = Axis::LEFT_TRIGGER; + _axes[1].axis = Axis::RIGHT_TRIGGER; + _axes[2].axis = Axis::LEFT_X; + _axes[3].axis = Axis::LEFT_Y; + _axes[4].axis = Axis::RIGHT_X; + _axes[5].axis = Axis::RIGHT_Y; break; case XINPUT_DEVSUBTYPE_WHEEL: - _device_class = DeviceClass::steering_wheel; - _axes[0].axis = Axis::brake; - _axes[1].axis = Axis::accelerator; - _axes[2].axis = Axis::wheel; - _axes[3].axis = Axis::none; - _axes[4].axis = Axis::none; - _axes[5].axis = Axis::none; + _device_class = DeviceClass::STEERING_WHEEL; + _axes[0].axis = Axis::BRAKE; + _axes[1].axis = Axis::ACCELERATOR; + _axes[2].axis = Axis::WHEEL; + _axes[3].axis = Axis::NONE; + _axes[4].axis = Axis::NONE; + _axes[5].axis = Axis::NONE; break; case XINPUT_DEVSUBTYPE_FLIGHT_STICK: - _device_class = DeviceClass::flight_stick; - _axes[0].axis = Axis::yaw; - _axes[1].axis = Axis::throttle; - _axes[2].axis = Axis::roll; - _axes[3].axis = Axis::pitch; - _axes[4].axis = Axis::none; - _axes[5].axis = Axis::none; + _device_class = DeviceClass::FLIGHT_STICK; + _axes[0].axis = Axis::YAW; + _axes[1].axis = Axis::THROTTLE; + _axes[2].axis = Axis::ROLL; + _axes[3].axis = Axis::PITCH; + _axes[4].axis = Axis::NONE; + _axes[5].axis = Axis::NONE; break; case XINPUT_DEVSUBTYPE_DANCE_PAD: - _device_class = DeviceClass::dance_pad; - _axes[0].axis = Axis::none; - _axes[1].axis = Axis::none; - _axes[2].axis = Axis::none; - _axes[3].axis = Axis::none; - _axes[4].axis = Axis::none; - _axes[5].axis = Axis::none; + _device_class = DeviceClass::DANCE_PAD; + _axes[0].axis = Axis::NONE; + _axes[1].axis = Axis::NONE; + _axes[2].axis = Axis::NONE; + _axes[3].axis = Axis::NONE; + _axes[4].axis = Axis::NONE; + _axes[5].axis = Axis::NONE; break; } @@ -414,7 +414,7 @@ init_device(const XINPUT_CAPABILITIES_EX &caps, const XINPUT_STATE &state) { if (caps.Vibration.wLeftMotorSpeed != 0 || caps.Vibration.wRightMotorSpeed != 0) { - enable_feature(Feature::vibration); + enable_feature(Feature::VIBRATION); } if (get_battery_information != nullptr) { @@ -423,7 +423,7 @@ init_device(const XINPUT_CAPABILITIES_EX &caps, const XINPUT_STATE &state) { if (batt.BatteryType != BATTERY_TYPE_DISCONNECTED && batt.BatteryType != BATTERY_TYPE_WIRED) { // This device has a battery. Report the battery level. - enable_feature(Feature::battery); + enable_feature(Feature::BATTERY); _battery_data.level = batt.BatteryLevel; _battery_data.max_level = BATTERY_LEVEL_FULL; } diff --git a/panda/src/display/graphicsWindowInputDevice.cxx b/panda/src/display/graphicsWindowInputDevice.cxx index 04bac6d81d..6eb1c61d44 100644 --- a/panda/src/display/graphicsWindowInputDevice.cxx +++ b/panda/src/display/graphicsWindowInputDevice.cxx @@ -30,14 +30,14 @@ using std::string; */ GraphicsWindowInputDevice:: GraphicsWindowInputDevice(GraphicsWindow *host, const string &name, bool pointer, bool keyboard) : - InputDevice(name, DeviceClass::virtual_device) + InputDevice(name, DeviceClass::VIRTUAL) { if (pointer) { - enable_feature(Feature::pointer); - add_pointer(PointerType::mouse, 0); + enable_feature(Feature::POINTER); + add_pointer(PointerType::MOUSE, 0); } if (keyboard) { - enable_feature(Feature::keyboard); + enable_feature(Feature::KEYBOARD); } } @@ -167,7 +167,7 @@ set_pointer_in_window(double x, double y, double time) { LightMutexHolder holder(_lock); PointerData data = _pointers[0]; data._id = 0; - data._type = PointerType::mouse; + data._type = PointerType::MOUSE; data._xpos = x; data._ypos = y; data._in_window = true; diff --git a/panda/src/event/pointerEvent.h b/panda/src/event/pointerEvent.h index c0c354efd6..6fc9ac9ede 100644 --- a/panda/src/event/pointerEvent.h +++ b/panda/src/event/pointerEvent.h @@ -39,7 +39,7 @@ public: public: bool _in_window = false; int _id = 0; - PointerType _type = PointerType::unknown; + PointerType _type = PointerType::UNKNOWN; double _xpos = 0.0; double _ypos = 0.0; double _dx = 0.0; diff --git a/panda/src/putil/pointerData.h b/panda/src/putil/pointerData.h index 30580cbd6a..32a8006092 100644 --- a/panda/src/putil/pointerData.h +++ b/panda/src/putil/pointerData.h @@ -23,11 +23,18 @@ BEGIN_PUBLISH * Contains the types of pointer device. */ enum class PointerType { - unknown, - mouse, - finger, - stylus, - eraser, + UNKNOWN, + MOUSE, + FINGER, + STYLUS, + ERASER, + + // deprecated aliases + unknown = UNKNOWN, + mouse = MOUSE, + finger = FINGER, + stylus = STYLUS, + eraser = ERASER, }; END_PUBLISH @@ -61,7 +68,7 @@ public: double _xpos = 0.0; double _ypos = 0.0; double _pressure = 0.0; - PointerType _type = PointerType::unknown; + PointerType _type = PointerType::UNKNOWN; int _id = 0; }; From e3f73f37f68aeb0cfa761ab52f241a0a266a7c71 Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 2 Aug 2023 11:38:51 +0200 Subject: [PATCH 46/84] doc: Adding coding style guide Closes #279 Co-authored-by: Sam Edwards [skip ci] --- doc/CODING_STYLE.md | 200 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 200 insertions(+) create mode 100644 doc/CODING_STYLE.md diff --git a/doc/CODING_STYLE.md b/doc/CODING_STYLE.md new file mode 100644 index 0000000000..614057737d --- /dev/null +++ b/doc/CODING_STYLE.md @@ -0,0 +1,200 @@ +Panda3D C++ Style Guide +======================= + +Rather than try to justify every decision made, this document attempts to be as +at-a-glance as possible. Examples provided where necessary to illustrate best +practices. + +Note that this style guide is, for the most part, not very strict, and there +are exceptions to every rule. However, this guide does serve to illustrate the +preferred style for the entire codebase. + +Naming conventions +------------------ + +- **Classes**: `CamelCaseFirstUpper` +- **Filenames**: `lowerCamelCase.h`, `lowerCamelCase.cxx` + - Note, every header file must have a unique filename. They are all + installed into the same path. +- **Functions**: `lower_snake_case_without_prefix` +- **Local variables**: `lower_snake_case_without_prefix` +- **Member variables**: `_lower_snake_case_with_initial_score` +- **Enum constants**: `SE_enum_value` (for an enum type named SomeEnum) +- **Enum class constants**: `ENUM_VALUE` + +Indentation +----------- + +Always use two spaces to indent. Tabs should never appear in a C++ file. + +Access modifiers (`public`/`private`/`protected`/`PUBLISHED`) are never +indented relative to the class they are in, and do not affect the indentation +of the surrounding lines. + +Spaces +------ + +Always put one space after a control keyword, before the condition's +parentheses. Don't pad the inside of parentheses with spaces unless there are +several nested parenthetical expressions and the extra spaces contribute +substantially to readability. + + if (x == y) { + +Don't place a space after a function name (declarations, definitions, or calls). + + void function_name(); + ... + function_name(); + +Always place a space after each comma in an arguments list. + + function_call(x, y, z); + +Always pad binary operators with a space on either side. + + a || b + +Never end a line with trailing whitespace. + +Function definitions +-------------------- + +The recipe for a function definition is: + +1. JavaDoc comment describing the purpose of the function +2. Function return value and class +3. **At the beginning of its own line,** the function's name, followed by the + parameter list and anything else necessary for the function's signature. +4. Opening brace on the same line, not its own line. +5. Single empty line before next definition. + +For example: + + /** + * String documenting the function, in JavaDoc style. + */ + void ClassName:: + function_name(int x, int y) const { + ... + } + + /** + * ... + */ + ... + +If the function is a constructor with an initializer list, the `:` goes on the +same line as the constructor name, and the initializers are listed *one per +line*, indented by two spaces. + + ClassName:: + ClassName() : + _a("a"), + _b("b"), + _c("c") + { + } + +Empty function bodies in a .cxx/.I file still contain a single line break (i.e. +to put `}` on its own line). In a .h file, an empty function can be given as +`{}` + +Braces +------ + +Always put an opening `{` on the same line as the statement that calls for the +brace. There is exactly one exception to this: constructors with initializer +lists. + + SomeClass:: + SomeClass() : + _one(1), + _two(2) + { + if (_one < _two) { + ... + } + } + +Comments +-------- + +Comments should be properly-formatted English, with proper capitalization and +punctuation rules. There are two spaces between sentences. + +Note that `//` is preferred over `/*` except in some special circumstances. + +Except for commented-out lines of code, there should be a space between the +first word and the `//`. + + // The following line is commented out. + //if (value == 0) { + +Line limits and continuations +----------------------------- + +Lines should be limited to 80 columns. This is not a hard limit, and lines +should not be wrapped if doing so hurts readability, except comments, which +should always be wrapped. + +Continuation lines shall be aligned to the same column as appropriate, or +indented two spaces otherwise: + + if ((a && + b) || + c) { + ... + } + +When choosing where to break a line, these are the preferred places, from best +to worst: + +1. If inside a comment, break the comment to as many lines as appropriate, but + only after moving the comment to its own line. +2. After a comma in an argument/parameter list. +3. After a binary operator (leaving the binary operator at the end of the line) +4. In a function declaration, after the function's return type but before the + function's name. (Indented by two spaces.) +5. In a log statement with `<<`, before a `<<`. (Avoid ending a line with `<<`) +6. Around a string literal, at a natural word boundary, with a space left on + the previous line (e.g. `"This is a "` / `"continued string literal."`) +7. After the `=` in an assignment operator. +8. As a last resort, after the opening `(` in a function call. + +If none of these rules can apply cleanly, it is okay to have lines extend past +the 80-column boundary. + +Alignment +--------- + +Avoid the temptation to align multiple assignments in consecutive lines of code. +While it may look neater, it decreases the maintainability of the code. + +Asterisks and ampersands indicating a pointer or reference type should always +be aligned against the name, and not the type: + + Type *x, &y; + +Grouping +-------- + +Try to group logically-similar lines, separating them with a single blank line. + +Modern language features +------------------------ + +Panda3D is a C++11 project. The use of the following modern language features +is greatly encouraged: + +1. `nullptr` over `NULL` +2. `std::move` and move semantics +3. Range-based for loops + +Using `auto` can be okay, such as when storing an iterator, but consider +creating a typedef for the container type instead. + +Avoid using `std::function` in cases where a lambda can be accepted directly +(using a template function), since it has extra overhead over lambdas. + +C++14 and C++17 features should be avoided for now. From 4097dc2e28e231e2806c313bc5f98b88726f71dc Mon Sep 17 00:00:00 2001 From: Aidan Noll Date: Wed, 2 Aug 2023 12:24:20 +0200 Subject: [PATCH 47/84] downloader: Fix issues with error codes with LibreSSL on Windows Closes #1503 Co-authored-by: rdb --- panda/src/downloader/bioPtr.cxx | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/panda/src/downloader/bioPtr.cxx b/panda/src/downloader/bioPtr.cxx index 56a288987b..7c8647e0e6 100644 --- a/panda/src/downloader/bioPtr.cxx +++ b/panda/src/downloader/bioPtr.cxx @@ -56,6 +56,33 @@ static string format_error() { #define format_error() strerror(errno) #endif +#if defined(_WIN32) && defined(LIBRESSL_VERSION_NUMBER) +/** +* This exists to work around an issue with LibreSSL's version of +* BIO_sock_should_retry, which does not understand Windows error codes. +* The implementation here matches the behaviour of OpenSSL on Windows. +*/ +static int +sock_should_retry(int i) { + if (i == 0 || i == -1) { + int err = WSAGetLastError(); + + switch (err) { + case WSAEWOULDBLOCK: + case ENOTCONN: + case EINPROGRESS: + case EALREADY: + return 1; + default: + break; + } + } + return 0; +} +#else +#define sock_should_retry(err) BIO_sock_should_retry(err) +#endif + /** * This flavor of the constructor automatically creates a socket BIO and feeds * it the server and port name from the indicated URL. It doesn't call @@ -201,8 +228,7 @@ connect() { result = BIO_sock_error(fd); } else { result = ::connect(fd, (sockaddr *)&_addr, _addrlen); - - if (result != 0 && BIO_sock_should_retry(-1)) { + if (result != 0 && sock_should_retry(-1)) { // It's still in progress; we should retry later. This causes // should_retry() to return true. BIO_set_flags(_bio, BIO_FLAGS_SHOULD_RETRY); From 8cbf93162a46f6022576b3c9239cdc8395a18a61 Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 2 Aug 2023 12:40:37 +0200 Subject: [PATCH 48/84] cppparser: Backport enum scope fix to 1.10 From bc039a0476b31fa624ce548629b7e05cccd2d570 --- dtool/src/cppparser/cppBison.cxx.prebuilt | 6264 +++++++++++---------- dtool/src/cppparser/cppBison.yxx | 11 +- 2 files changed, 3148 insertions(+), 3127 deletions(-) diff --git a/dtool/src/cppparser/cppBison.cxx.prebuilt b/dtool/src/cppparser/cppBison.cxx.prebuilt index 99372f6ed6..2acccd79f3 100644 --- a/dtool/src/cppparser/cppBison.cxx.prebuilt +++ b/dtool/src/cppparser/cppBison.cxx.prebuilt @@ -548,39 +548,40 @@ enum yysymbol_kind_t YYSYMBOL_class_derivation = 247, /* class_derivation */ YYSYMBOL_base_specification = 248, /* base_specification */ YYSYMBOL_enum = 249, /* enum */ - YYSYMBOL_enum_decl = 250, /* enum_decl */ - YYSYMBOL_enum_element_type = 251, /* enum_element_type */ - YYSYMBOL_enum_body_trailing_comma = 252, /* enum_body_trailing_comma */ - YYSYMBOL_enum_body = 253, /* enum_body */ - YYSYMBOL_enum_keyword = 254, /* enum_keyword */ - YYSYMBOL_struct_keyword = 255, /* struct_keyword */ - YYSYMBOL_namespace_declaration = 256, /* namespace_declaration */ - YYSYMBOL_257_18 = 257, /* $@18 */ + YYSYMBOL_250_18 = 250, /* $@18 */ + YYSYMBOL_enum_decl = 251, /* enum_decl */ + YYSYMBOL_enum_element_type = 252, /* enum_element_type */ + YYSYMBOL_enum_body_trailing_comma = 253, /* enum_body_trailing_comma */ + YYSYMBOL_enum_body = 254, /* enum_body */ + YYSYMBOL_enum_keyword = 255, /* enum_keyword */ + YYSYMBOL_struct_keyword = 256, /* struct_keyword */ + YYSYMBOL_namespace_declaration = 257, /* namespace_declaration */ YYSYMBOL_258_19 = 258, /* $@19 */ - YYSYMBOL_using_declaration = 259, /* using_declaration */ - YYSYMBOL_simple_type = 260, /* simple_type */ - YYSYMBOL_simple_int_type = 261, /* simple_int_type */ - YYSYMBOL_simple_float_type = 262, /* simple_float_type */ - YYSYMBOL_simple_void_type = 263, /* simple_void_type */ - YYSYMBOL_code = 264, /* code */ - YYSYMBOL_265_20 = 265, /* $@20 */ - YYSYMBOL_code_block = 266, /* code_block */ - YYSYMBOL_element = 267, /* element */ - YYSYMBOL_optional_const_expr = 268, /* optional_const_expr */ - YYSYMBOL_optional_const_expr_comma = 269, /* optional_const_expr_comma */ - YYSYMBOL_const_expr_comma = 270, /* const_expr_comma */ - YYSYMBOL_no_angle_bracket_const_expr = 271, /* no_angle_bracket_const_expr */ - YYSYMBOL_const_expr = 272, /* const_expr */ - YYSYMBOL_const_operand = 273, /* const_operand */ - YYSYMBOL_formal_const_expr = 274, /* formal_const_expr */ - YYSYMBOL_formal_const_operand = 275, /* formal_const_operand */ - YYSYMBOL_capture_list = 276, /* capture_list */ - YYSYMBOL_capture = 277, /* capture */ - YYSYMBOL_class_derivation_name = 278, /* class_derivation_name */ - YYSYMBOL_name = 279, /* name */ - YYSYMBOL_name_no_final = 280, /* name_no_final */ - YYSYMBOL_string_literal = 281, /* string_literal */ - YYSYMBOL_empty = 282 /* empty */ + YYSYMBOL_259_20 = 259, /* $@20 */ + YYSYMBOL_using_declaration = 260, /* using_declaration */ + YYSYMBOL_simple_type = 261, /* simple_type */ + YYSYMBOL_simple_int_type = 262, /* simple_int_type */ + YYSYMBOL_simple_float_type = 263, /* simple_float_type */ + YYSYMBOL_simple_void_type = 264, /* simple_void_type */ + YYSYMBOL_code = 265, /* code */ + YYSYMBOL_266_21 = 266, /* $@21 */ + YYSYMBOL_code_block = 267, /* code_block */ + YYSYMBOL_element = 268, /* element */ + YYSYMBOL_optional_const_expr = 269, /* optional_const_expr */ + YYSYMBOL_optional_const_expr_comma = 270, /* optional_const_expr_comma */ + YYSYMBOL_const_expr_comma = 271, /* const_expr_comma */ + YYSYMBOL_no_angle_bracket_const_expr = 272, /* no_angle_bracket_const_expr */ + YYSYMBOL_const_expr = 273, /* const_expr */ + YYSYMBOL_const_operand = 274, /* const_operand */ + YYSYMBOL_formal_const_expr = 275, /* formal_const_expr */ + YYSYMBOL_formal_const_operand = 276, /* formal_const_operand */ + YYSYMBOL_capture_list = 277, /* capture_list */ + YYSYMBOL_capture = 278, /* capture */ + YYSYMBOL_class_derivation_name = 279, /* class_derivation_name */ + YYSYMBOL_name = 280, /* name */ + YYSYMBOL_name_no_final = 281, /* name_no_final */ + YYSYMBOL_string_literal = 282, /* string_literal */ + YYSYMBOL_empty = 283 /* empty */ }; typedef enum yysymbol_kind_t yysymbol_kind_t; @@ -911,16 +912,16 @@ union yyalloc /* YYFINAL -- State number of the termination state. */ #define YYFINAL 104 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 7707 +#define YYLAST 7671 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 171 /* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 112 +#define YYNNTS 113 /* YYNRULES -- Number of rules. */ -#define YYNRULES 769 +#define YYNRULES 770 /* YYNSTATES -- Number of states. */ -#define YYNSTATES 1632 +#define YYNSTATES 1633 /* YYMAXUTOK -- Last valid token kind. */ #define YYMAXUTOK 401 @@ -1020,47 +1021,48 @@ static const yytype_int16 yyrline[] = 2674, 2682, 2686, 2702, 2718, 2727, 2737, 2744, 2748, 2756, 2760, 2765, 2769, 2777, 2778, 2779, 2780, 2785, 2784, 2809, 2808, 2838, 2839, 2846, 2847, 2851, 2852, 2856, 2860, 2864, - 2868, 2872, 2876, 2880, 2884, 2888, 2892, 2899, 2907, 2911, - 2915, 2920, 2928, 2932, 2939, 2940, 2945, 2952, 2953, 2958, - 2966, 2970, 2974, 2981, 2985, 2989, 2997, 2996, 3019, 3018, - 3041, 3042, 3046, 3052, 3059, 3068, 3069, 3070, 3074, 3078, - 3082, 3086, 3090, 3094, 3099, 3104, 3109, 3114, 3118, 3123, - 3132, 3137, 3145, 3149, 3153, 3161, 3171, 3171, 3181, 3182, - 3186, 3187, 3188, 3189, 3190, 3191, 3192, 3193, 3194, 3195, - 3196, 3197, 3197, 3197, 3198, 3198, 3198, 3198, 3199, 3199, - 3199, 3199, 3199, 3200, 3200, 3200, 3201, 3201, 3201, 3201, - 3201, 3202, 3202, 3202, 3202, 3202, 3203, 3203, 3204, 3204, - 3204, 3204, 3204, 3205, 3205, 3205, 3205, 3205, 3206, 3206, - 3206, 3206, 3207, 3207, 3207, 3207, 3207, 3208, 3208, 3208, - 3208, 3208, 3209, 3209, 3209, 3209, 3209, 3209, 3210, 3210, - 3210, 3210, 3210, 3211, 3211, 3211, 3211, 3212, 3212, 3212, - 3212, 3213, 3213, 3213, 3213, 3213, 3214, 3214, 3214, 3214, - 3215, 3215, 3215, 3215, 3215, 3216, 3216, 3216, 3216, 3217, - 3217, 3217, 3217, 3217, 3218, 3218, 3221, 3221, 3221, 3221, - 3221, 3221, 3221, 3221, 3221, 3221, 3221, 3222, 3222, 3222, - 3222, 3222, 3222, 3222, 3222, 3222, 3222, 3223, 3223, 3227, - 3231, 3238, 3242, 3249, 3253, 3260, 3264, 3268, 3272, 3276, - 3280, 3284, 3288, 3292, 3296, 3300, 3304, 3308, 3312, 3316, - 3320, 3324, 3328, 3332, 3336, 3340, 3344, 3348, 3352, 3356, - 3360, 3364, 3368, 3372, 3376, 3380, 3384, 3388, 3392, 3396, - 3400, 3404, 3408, 3412, 3420, 3424, 3428, 3432, 3436, 3440, - 3444, 3454, 3464, 3470, 3476, 3482, 3488, 3494, 3500, 3507, - 3514, 3521, 3528, 3534, 3540, 3544, 3548, 3552, 3556, 3560, - 3564, 3575, 3586, 3590, 3594, 3598, 3602, 3606, 3610, 3614, - 3618, 3622, 3626, 3630, 3634, 3638, 3642, 3646, 3650, 3654, - 3658, 3662, 3666, 3670, 3674, 3678, 3682, 3686, 3690, 3694, - 3698, 3702, 3706, 3713, 3717, 3721, 3725, 3729, 3733, 3737, - 3741, 3745, 3751, 3757, 3761, 3767, 3774, 3778, 3782, 3786, - 3790, 3794, 3798, 3802, 3806, 3810, 3814, 3818, 3822, 3826, - 3830, 3834, 3838, 3852, 3856, 3860, 3864, 3868, 3872, 3876, - 3880, 3884, 3888, 3892, 3896, 3900, 3911, 3922, 3926, 3930, - 3934, 3938, 3942, 3946, 3950, 3954, 3958, 3962, 3966, 3970, - 3974, 3978, 3982, 3986, 3990, 3994, 3998, 4002, 4006, 4010, - 4014, 4018, 4022, 4026, 4030, 4034, 4038, 4045, 4049, 4053, - 4057, 4061, 4065, 4069, 4073, 4077, 4083, 4089, 4097, 4101, - 4105, 4109, 4116, 4126, 4132, 4138, 4148, 4160, 4168, 4172, - 4202, 4206, 4210, 4214, 4218, 4222, 4228, 4232, 4236, 4240, - 4244, 4255, 4259, 4263, 4267, 4275, 4279, 4283, 4289, 4300 + 2868, 2872, 2876, 2880, 2884, 2888, 2892, 2900, 2899, 2916, + 2920, 2924, 2929, 2937, 2941, 2948, 2949, 2954, 2961, 2962, + 2967, 2975, 2979, 2983, 2990, 2994, 2998, 3006, 3005, 3028, + 3027, 3050, 3051, 3055, 3061, 3068, 3077, 3078, 3079, 3083, + 3087, 3091, 3095, 3099, 3103, 3108, 3113, 3118, 3123, 3127, + 3132, 3141, 3146, 3154, 3158, 3162, 3170, 3180, 3180, 3190, + 3191, 3195, 3196, 3197, 3198, 3199, 3200, 3201, 3202, 3203, + 3204, 3205, 3206, 3206, 3206, 3207, 3207, 3207, 3207, 3208, + 3208, 3208, 3208, 3208, 3209, 3209, 3209, 3210, 3210, 3210, + 3210, 3210, 3211, 3211, 3211, 3211, 3211, 3212, 3212, 3213, + 3213, 3213, 3213, 3213, 3214, 3214, 3214, 3214, 3214, 3215, + 3215, 3215, 3215, 3216, 3216, 3216, 3216, 3216, 3217, 3217, + 3217, 3217, 3217, 3218, 3218, 3218, 3218, 3218, 3218, 3219, + 3219, 3219, 3219, 3219, 3220, 3220, 3220, 3220, 3221, 3221, + 3221, 3221, 3222, 3222, 3222, 3222, 3222, 3223, 3223, 3223, + 3223, 3224, 3224, 3224, 3224, 3224, 3225, 3225, 3225, 3225, + 3226, 3226, 3226, 3226, 3226, 3227, 3227, 3230, 3230, 3230, + 3230, 3230, 3230, 3230, 3230, 3230, 3230, 3230, 3231, 3231, + 3231, 3231, 3231, 3231, 3231, 3231, 3231, 3231, 3232, 3232, + 3236, 3240, 3247, 3251, 3258, 3262, 3269, 3273, 3277, 3281, + 3285, 3289, 3293, 3297, 3301, 3305, 3309, 3313, 3317, 3321, + 3325, 3329, 3333, 3337, 3341, 3345, 3349, 3353, 3357, 3361, + 3365, 3369, 3373, 3377, 3381, 3385, 3389, 3393, 3397, 3401, + 3405, 3409, 3413, 3417, 3421, 3429, 3433, 3437, 3441, 3445, + 3449, 3453, 3463, 3473, 3479, 3485, 3491, 3497, 3503, 3509, + 3516, 3523, 3530, 3537, 3543, 3549, 3553, 3557, 3561, 3565, + 3569, 3573, 3584, 3595, 3599, 3603, 3607, 3611, 3615, 3619, + 3623, 3627, 3631, 3635, 3639, 3643, 3647, 3651, 3655, 3659, + 3663, 3667, 3671, 3675, 3679, 3683, 3687, 3691, 3695, 3699, + 3703, 3707, 3711, 3715, 3722, 3726, 3730, 3734, 3738, 3742, + 3746, 3750, 3754, 3760, 3766, 3770, 3776, 3783, 3787, 3791, + 3795, 3799, 3803, 3807, 3811, 3815, 3819, 3823, 3827, 3831, + 3835, 3839, 3843, 3847, 3861, 3865, 3869, 3873, 3877, 3881, + 3885, 3889, 3893, 3897, 3901, 3905, 3909, 3920, 3931, 3935, + 3939, 3943, 3947, 3951, 3955, 3959, 3963, 3967, 3971, 3975, + 3979, 3983, 3987, 3991, 3995, 3999, 4003, 4007, 4011, 4015, + 4019, 4023, 4027, 4031, 4035, 4039, 4043, 4047, 4054, 4058, + 4062, 4066, 4070, 4074, 4078, 4082, 4086, 4092, 4098, 4106, + 4110, 4114, 4118, 4125, 4135, 4141, 4147, 4157, 4169, 4177, + 4181, 4211, 4215, 4219, 4223, 4227, 4231, 4237, 4241, 4245, + 4249, 4253, 4264, 4268, 4272, 4276, 4284, 4288, 4292, 4298, + 4309 }; #endif @@ -1137,10 +1139,11 @@ static const char *const yytname[] = "predefined_type", "var_type_decl", "full_type", "struct_attributes", "anonymous_struct", "$@16", "named_struct", "$@17", "maybe_final", "maybe_class_derivation", "class_derivation", "base_specification", - "enum", "enum_decl", "enum_element_type", "enum_body_trailing_comma", - "enum_body", "enum_keyword", "struct_keyword", "namespace_declaration", - "$@18", "$@19", "using_declaration", "simple_type", "simple_int_type", - "simple_float_type", "simple_void_type", "code", "$@20", "code_block", + "enum", "$@18", "enum_decl", "enum_element_type", + "enum_body_trailing_comma", "enum_body", "enum_keyword", + "struct_keyword", "namespace_declaration", "$@19", "$@20", + "using_declaration", "simple_type", "simple_int_type", + "simple_float_type", "simple_void_type", "code", "$@21", "code_block", "element", "optional_const_expr", "optional_const_expr_comma", "const_expr_comma", "no_angle_bracket_const_expr", "const_expr", "const_operand", "formal_const_expr", "formal_const_operand", @@ -1160,7 +1163,7 @@ yysymbol_name (yysymbol_kind_t yysymbol) #define yypact_value_is_default(Yyn) \ ((Yyn) == YYPACT_NINF) -#define YYTABLE_NINF (-765) +#define YYTABLE_NINF (-766) #define yytable_value_is_error(Yyn) \ 0 @@ -1169,121 +1172,121 @@ yysymbol_name (yysymbol_kind_t yysymbol) STATE-NUM. */ static const yytype_int16 yypact[] = { - 244, -937, 4264, 6409, 71, 5678, -937, -937, -937, -937, - -937, -937, -937, -937, -55, 45, 63, 73, 81, 101, - -41, 109, -12, -937, -937, 114, 119, 143, 148, 152, - 156, 164, 169, 176, 186, 209, 221, 240, 245, 251, - 257, 267, 270, 282, 6660, -937, -937, -2, 298, 306, - 2561, 215, -937, 317, 319, 333, 4264, 4264, 4264, 4264, - 4264, 2904, 554, 4264, 5515, -937, 87, -937, -937, -937, - -937, -937, -937, -937, -937, 6520, 339, -937, -6, -937, - -937, 5170, 5582, 5582, -937, 5373, 343, -937, 5582, -937, - -937, 323, 323, -937, -937, -937, -937, 366, 77, -937, - -937, -937, -937, -937, -937, 6442, 355, -937, 7566, 7566, - 7566, -937, 7566, 5998, 7566, 373, -937, 2485, 362, 368, - 369, 371, 372, 375, 7566, 4368, 385, 391, 393, 7566, - 7566, 379, 7391, 7566, 7566, 5879, 7566, 7566, -937, -937, - -937, -937, 5097, -937, -937, -937, -937, -937, 4264, 4264, - 6409, 4264, 4264, 4264, 4264, 6409, 4264, 6409, 4264, 6409, - 4264, 6409, 6409, 6409, 6409, 6409, 6409, 6409, 6409, 6409, - 6409, 6409, 6409, 6409, 6409, 6409, 4264, -937, -937, 381, - 5373, 383, 388, 5373, -937, -937, 6409, 4264, 4264, 390, - 2904, 132, 6409, 2904, 4264, 4264, 132, 132, 132, 132, - 132, -55, 63, 73, 81, 101, 109, 114, 143, 337, - 3091, 6420, 6808, 333, 348, -104, 5515, -937, -937, -937, - -937, -937, -937, -937, -937, -937, -937, -937, -937, 5373, - 5373, -108, 399, -937, -937, 132, 4264, 4264, 4264, 4264, - 4264, 4264, 4264, 4264, 4264, 4264, 4264, 4264, 4264, 4264, - 4264, 4264, 4264, 4264, 4264, 4264, 5373, 3319, 4264, -937, - -937, 323, 323, 3454, -937, -937, -937, 5582, -937, -937, - -937, -937, 6409, -937, 396, 320, 332, 323, 323, 332, - 332, 5792, 403, -937, 405, -937, -937, -937, -937, -937, - -937, 5238, 407, 3378, -937, 5373, 524, 426, 410, 3044, - 6025, 7566, -937, -937, -937, -937, 7566, -937, -937, -937, - -937, 7484, 4643, -937, 5373, 5373, 5373, 5373, 5373, 5373, - -937, -937, 429, -937, -937, -937, -937, -937, 4264, -937, - 5189, -937, 423, -937, 5276, -937, 5373, 301, -937, -937, - 160, 415, -937, 416, 6549, 5373, 420, -937, 5373, -937, - 17, 437, -937, -937, -937, -937, 1627, -937, -937, 419, - 440, -937, 427, 428, 430, 431, 435, 438, 433, 439, - 447, 442, 445, 446, 452, 459, 453, -88, 475, 457, - 460, 461, 465, 468, 469, 472, 473, 478, 484, 489, - 4264, -937, 6409, 4264, -937, 7372, 485, 490, 492, 5373, - 493, 504, 496, 4418, 497, 509, 4264, 4264, -937, 614, - -937, 1364, 506, 4264, -937, -937, 1514, 5676, 5119, 5119, - 927, 927, 704, 704, -937, 3202, 1693, 5722, 5852, 927, - 927, 92, 92, 132, 132, 132, -937, -937, -73, 2082, - -937, -937, 511, 4693, 512, 332, 332, 6442, 515, 436, - -937, 403, -937, 403, -937, 436, 436, -937, 332, 6442, - 6433, 6322, 332, 332, 514, 36, -937, 413, 532, -937, - 4264, 5373, 520, -937, -937, -937, -937, 5238, -50, -33, - -29, 6442, 517, -28, -937, -937, -937, 540, 7566, 6442, - 4399, -55, 526, 5345, -937, -937, -937, 527, 543, 546, - 550, 551, 552, 553, 6852, -937, 1990, 6101, 268, 537, - 17, -937, -937, 555, -937, 6409, -937, 14, 3589, 6747, - 1222, -937, 6409, -937, 538, 350, -937, -937, 3184, -937, - -937, 128, -937, 556, 3378, -937, -937, -937, -937, -937, - -937, -937, 547, -937, 548, -937, -937, -937, -937, 6409, - -937, 6409, -937, 6409, -937, -937, -937, -937, -937, -937, - -937, -937, -937, -937, -937, 5403, 544, 558, -937, 559, - -937, -937, 562, 4539, 568, -937, -937, -937, -937, 132, - 5515, -937, 5373, 399, 6201, 1891, -937, 5515, 4264, -937, - -937, -937, -937, -937, 436, 549, 669, 3044, 561, 5373, - 332, 436, 436, 332, 332, 573, -937, 573, 573, 436, - 670, 6520, 413, 532, -937, 436, 436, -937, -937, 6293, - 581, 332, 413, 413, 332, 332, 413, 79, 332, -937, - 583, 5373, 332, 532, 532, 332, 332, 532, 206, 576, - 5515, -937, -83, -937, 572, 699, 3044, -937, 672, 6442, - -937, -937, -937, -937, -937, -937, -937, -937, 584, 594, - 596, -937, -937, 6660, -937, -937, 597, 1831, 598, -937, - 599, 4264, 4264, 4264, 4264, 2904, 4264, 592, 44, -937, - -937, 5612, -937, 87, -937, 7566, 7566, 6925, -937, 751, - 752, 755, 756, 760, 761, -937, -937, 462, 618, -937, - -937, -937, -937, 6133, -937, 616, 626, 7366, -937, 222, - -937, -937, 9, -937, 128, -937, 628, 6201, 608, 620, - 128, 6201, 611, 5424, 1222, 623, 332, 1222, 1222, 332, - 332, -84, 332, -937, 617, 6998, -937, -937, -937, 5373, - -7, -937, 619, -937, 640, 643, 3724, 3611, 637, 332, - 128, 5029, 128, 332, 332, 128, -937, 178, 358, 332, - 5238, -937, 4264, 4264, 634, 635, 641, -937, -937, -937, - 4264, -937, 4264, -937, 645, -937, 6636, 6442, -937, -937, - -937, -937, -937, -937, 649, -937, -937, 663, -937, 5515, - 573, 332, 648, 5442, 332, 332, 436, 573, 573, 436, - 436, 4264, -64, 6322, 413, 532, 79, 206, 4, 54, - 1891, -937, -937, 332, 413, 654, 654, 413, 413, 273, - 4264, -937, -937, 332, 332, 532, 655, 655, 532, 532, - 310, 4264, -937, 332, -937, 4264, -937, 656, 5460, 7071, - -937, 677, -937, -937, 6409, 6409, 6409, 657, 6409, 664, - 2904, 234, 6409, 2904, 132, 132, 132, 132, 665, -62, - 132, -937, -937, 4674, 4264, 4264, 4264, 4264, 4264, 4264, - 4264, 4264, 4264, 4264, 4264, 4264, 4264, 4264, 4264, 4264, - 4264, 4264, 4264, 4264, 5373, 3859, 4264, -937, -937, -937, - -937, 683, -24, 685, 688, 689, 693, 7144, 48, -937, - 222, 7557, 6101, 5373, 691, 684, 332, 222, 222, 332, - 332, 222, 214, 655, -937, 358, -937, 676, 681, 128, - 262, 680, -937, -937, 345, 332, 1222, 690, 690, 1222, - 1222, -937, 4264, -937, -937, -937, 6201, 682, 370, -937, - 13, 700, 702, -937, 2736, -937, -937, -937, 3724, 686, - 712, 5515, -937, -937, 332, 128, 365, 851, -937, -937, + 300, -937, 4486, 6316, 60, 5787, -937, -937, -937, -937, + -937, -937, -937, -937, -125, -88, -71, -60, -50, -19, + -86, -11, 12, -937, -937, 41, 80, 92, 114, 118, + 125, 143, 166, 169, 172, 208, 211, 214, 226, 231, + 240, 242, 247, 252, 6567, -937, -937, 21, 266, 272, + 3406, 68, -937, 291, 297, 306, 4486, 4486, 4486, 4486, + 4486, 2385, 771, 4486, 5624, -937, 207, -937, -937, -937, + -937, -937, -937, -937, -937, 6427, 309, -937, -8, -937, + -937, 2514, 1397, 1397, -937, 6003, 315, -937, 1397, -937, + -937, 204, 204, -937, -937, -937, -937, -937, 76, -937, + -937, -937, -937, -937, -937, 5421, 321, -937, 7530, 7530, + 7530, -937, 7530, 5959, 7530, -69, -937, 7481, 329, 335, + 338, 354, 357, 359, 7530, 2545, 205, 238, 277, 7530, + 7530, 362, 7350, 7530, 7530, 5886, 7530, 7530, -937, -937, + -937, -937, 1296, -937, -937, -937, -937, -937, 4486, 4486, + 6316, 4486, 4486, 4486, 4486, 6316, 4486, 6316, 4486, 6316, + 4486, 6316, 6316, 6316, 6316, 6316, 6316, 6316, 6316, 6316, + 6316, 6316, 6316, 6316, 6316, 6316, 4486, -937, -937, 366, + 6003, 369, 379, 6003, -937, -937, 6316, 4486, 4486, 390, + 2385, 46, 6316, 2385, 4486, 4486, 46, 46, 46, 46, + 46, -125, -71, -60, -50, -19, -11, 41, 92, 6038, + 6128, 6715, 7239, 306, 126, -95, 5624, -937, -937, -937, + -937, -937, -937, -937, -937, -937, -937, -937, -937, 6003, + 6003, -124, 405, -937, -937, 46, 4486, 4486, 4486, 4486, + 4486, 4486, 4486, 4486, 4486, 4486, 4486, 4486, 4486, 4486, + 4486, 4486, 4486, 4486, 4486, 4486, 6003, 3541, 4486, -937, + -937, 204, 204, 3676, -937, -937, -937, 1397, -937, -937, + -937, -937, 6316, -937, 403, 412, 262, 204, 204, 262, + 262, 5901, 400, -937, 401, -937, 422, -937, -937, -937, + -937, 1172, 420, 2453, -937, 6003, 524, 426, 410, 2637, + 2788, 7530, -937, -937, -937, -937, 7530, -937, -937, -937, + -937, 7443, 4590, -937, 6003, 6003, 6003, 6003, 6003, 6003, + -937, -937, 432, -937, -937, -937, -937, -937, 4486, -937, + 2773, -937, 428, -937, 5327, -937, 6003, 175, -937, -937, + 267, 421, -937, 424, 6456, 6003, 427, -937, 6003, -937, + 314, 438, -937, -937, -937, -937, 1213, -937, -937, 425, + 452, -937, 434, 435, 436, 437, 440, 441, 448, 443, + 454, 449, 451, 455, 458, 467, 461, -84, 481, 463, + 465, 466, 471, 474, 476, 482, 483, 484, 485, 486, + 4486, -937, 6316, 4486, -937, 7279, 477, 489, 493, 6003, + 495, 491, 499, 4915, 500, 503, 4486, 4486, -937, 656, + -937, 959, 429, 4486, -937, -937, 3559, 2868, 1424, 1424, + 614, 614, 89, 89, -937, 3289, 1443, 1529, 5773, 614, + 614, 157, 157, 46, 46, 46, -937, -937, -75, 1958, + -937, -937, 510, 5354, 512, 262, 262, 5421, 515, 413, + -937, 400, -937, 400, -937, 413, 413, -937, 262, 5421, + 6340, 6222, 262, 262, 521, 23, -937, 891, 312, -937, + 4486, -937, -937, -937, -937, 1172, -20, 112, 128, 5421, + 517, 142, -937, -937, -937, 543, 7530, 5421, 4621, -125, + 529, 5396, -937, -937, -937, 552, 553, 554, 555, 557, + 558, 561, 6759, -937, 4640, 5993, 360, 545, 314, -937, + -937, 562, -937, 6316, -937, 45, 3811, 6654, 1263, -937, + 6316, -937, 547, 332, -937, -937, 3271, -937, -937, 430, + -937, 563, 2453, -937, -937, -937, -937, -937, -937, -937, + 549, -937, 551, -937, -937, -937, -937, 6316, -937, 6316, + -937, 6316, -937, -937, -937, -937, -937, -937, -937, -937, + -937, -937, -937, 5454, 550, 556, -937, 559, -937, -937, + 560, 4761, 566, -937, -937, -937, -937, 46, 5624, -937, + 6003, 405, 6090, 2476, -937, 5624, 4486, -937, -937, -937, + -937, -937, 413, 569, 670, 2637, 568, 6003, 262, 413, + 413, 262, 262, 570, -937, 570, 570, 413, 684, 6427, + 891, 312, -937, 413, 413, -937, -937, 6184, 578, 262, + 891, 891, 262, 262, 891, -67, 262, -937, 580, 6003, + 262, 312, 312, 262, 262, 312, -47, 572, 5624, -937, + 6003, 577, -937, 602, 703, 2637, -937, 682, 5421, -937, + -937, -937, -937, -937, -937, -937, -937, 594, 606, 609, + -937, -937, 6567, -937, -937, 612, 1897, 621, -937, 619, + 4486, 4486, 4486, 4486, 2385, 4486, 626, 52, -937, -937, + 5658, -937, 207, -937, 7530, 7530, 6832, -937, 782, 785, + 786, 790, 791, 796, -937, -937, 260, 658, -937, -937, + -937, -937, 6052, -937, 652, 666, 7273, -937, 904, -937, + -937, 7, -937, 430, -937, 675, 6090, 660, 659, 430, + 6090, 661, 5506, 1263, 665, 262, 1263, 1263, 262, 262, + -2, 262, -937, 664, 6905, -937, -937, -937, 6003, 163, + -937, 668, -937, 683, 689, 3946, 3833, 673, 262, 430, + 2209, 430, 262, 262, 430, -937, 26, 361, 262, 1172, + -937, 4486, 4486, 674, 678, 690, -937, -937, -937, 4486, + -937, 4486, -937, 691, -937, 6543, 5421, -937, -937, -937, + -937, -937, -937, 694, -937, -937, 693, -937, 5624, 570, + 262, 695, 5548, 262, 262, 413, 570, 570, 413, 413, + 4486, 69, 6222, 891, 312, -67, -47, 137, 196, 2476, + -937, -937, 262, 891, 697, 697, 891, 891, 330, 4486, + -937, -937, 262, 262, 312, 699, 699, 312, 312, 347, + 4486, -937, 262, 72, -937, -937, 700, 5566, 6978, -937, + 710, -937, -937, 6316, 6316, 6316, 696, 6316, 704, 2385, + 234, 6316, 2385, 46, 46, 46, 46, 705, -74, 46, + -937, -937, 4896, 4486, 4486, 4486, 4486, 4486, 4486, 4486, + 4486, 4486, 4486, 4486, 4486, 4486, 4486, 4486, 4486, 4486, + 4486, 4486, 4486, 6003, 4081, 4486, -937, -937, -937, -937, + 722, -70, 730, 731, 732, 733, 7051, 42, -937, 904, + 7359, 5993, 6003, 735, 736, 262, 904, 904, 262, 262, + 904, -41, 699, -937, 361, -937, 715, 724, 430, 285, + 723, -937, -937, 268, 262, 1263, 727, 727, 1263, 1263, + -937, 4486, -937, -937, -937, 6090, 739, 393, -937, 9, + 748, 762, -937, 3103, -937, -937, -937, 3946, 752, 775, + 5624, -937, -937, 262, 430, 381, 915, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, - -937, -937, -937, -937, 705, 697, -937, 332, 365, 128, - 128, 279, 4264, -937, 4264, -937, 3184, 725, -937, -937, - 572, -21, -18, -937, -937, -937, -11, 47, -937, 6660, - 323, 826, 239, -937, -937, 332, 332, 436, -937, 573, - 573, 573, 706, 710, -937, 79, 206, -937, -937, 713, - 714, -937, 413, 654, 654, 654, 716, 717, 532, -937, - 655, 655, 655, 718, 720, 727, 3881, -937, -937, -937, - 6015, 735, 738, -937, 724, 737, 740, 4264, 746, 5373, - 728, 747, 741, 5497, 4264, -937, -937, -937, 1514, 5676, - 5119, 5119, 927, 927, 704, 704, -937, 4151, 1693, 5722, - 5852, 927, 927, 92, 92, 132, 132, 132, -937, -937, - 51, 2425, 7217, 895, 899, 763, 903, 753, -937, 914, - 916, 920, -937, 783, 214, 655, -937, -937, -937, -937, - -937, -937, 6409, 332, 222, 222, 222, 4814, -937, -937, - 785, -937, -937, -937, 295, 771, -937, -937, 1222, 690, - 690, 690, 6201, 770, 774, -937, -937, 5373, 4264, 4264, + -937, -937, -937, 766, 759, -937, 262, 381, 430, 430, + 372, 4486, -937, 4486, -937, 3271, 787, -937, -937, 602, + -66, -53, -937, -937, -937, -46, -28, -937, 6567, 204, + 888, 230, -937, -937, 262, 262, 413, -937, 570, 570, + 570, 768, 774, -937, -67, -47, -937, -937, 776, 777, + -937, 891, 697, 697, 697, 778, 770, 312, -937, 699, + 699, 699, 784, 780, 781, -937, 4486, -937, -937, -937, + 4980, 805, 806, -937, 792, 800, 801, 4486, 804, 6003, + 795, 808, 807, 5606, 4486, -937, -937, -937, 3559, 2868, + 1424, 1424, 614, 614, 89, 89, -937, 4103, 1443, 1529, + 5773, 614, 614, 157, 157, 46, 46, 46, -937, -937, + -22, 2259, 7124, 953, 957, 819, 962, 809, -937, 965, + 967, 968, -937, 830, -41, 699, -937, -937, -937, -937, + -937, -937, 6316, 262, 904, 904, 904, 5137, -937, -937, + 832, -937, -937, -937, 386, 817, -937, -937, 1263, 727, + 727, 727, 6090, 813, 823, -937, -937, 6003, 4486, 4486, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, @@ -1297,42 +1300,42 @@ static const yytype_int16 yypact[] = -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, - -937, -937, 777, -937, 3994, 128, 365, 332, -937, -937, - -937, 365, 365, -937, 5515, 4399, 772, 3611, 128, -937, - -937, -937, -937, 1891, 323, -937, -937, -937, 6, 780, - -937, -937, 573, 332, 6201, -937, -937, 6201, 6201, 654, - 6201, 332, 655, 6201, 332, -937, 6163, 6284, 6735, 5373, - 376, -937, -937, 936, -937, 6015, -937, 787, 790, 789, - 792, 794, 4539, 799, -937, -937, 132, 4264, -937, -937, - -937, 798, 52, -937, 811, 822, 75, 813, 76, -937, - -937, -937, 222, 816, 827, 829, 830, 2183, 831, 4814, - 4814, 4814, 4814, 4814, 2904, 4814, 4937, -937, 128, 1020, - 6201, 817, -937, 1020, 6201, 690, 821, 332, -937, 825, - -937, 828, 823, 2353, -937, 3724, 5515, 365, -937, 835, - 332, -937, 847, -937, 838, -937, -937, -937, 842, 843, - 848, 849, -937, 853, -937, 6777, -937, 6777, -937, 6777, - -937, -937, 6777, 6777, 6777, -937, 7290, -937, 4264, 4264, - -937, 4264, -937, 4264, 5515, 869, 1011, 874, 1019, -937, - 1021, 881, 887, 1022, 894, 6409, 6409, 6409, 6409, 896, - 2904, 248, 6409, 248, 248, 248, 248, 248, 893, 88, - 248, 4814, 4814, 4814, 4814, 4814, 4814, 4814, 4814, 4814, - 4814, 4814, 4814, 4814, 4814, 4814, 4814, 4814, 4814, 5373, - 4129, 4264, -937, 897, -937, 6201, 898, -937, -937, 1020, - -937, -937, 1047, -937, 900, -937, -937, -937, -937, -937, + -937, -937, 828, -937, 4216, 430, 381, 262, -937, -937, + -937, 381, 381, -937, 5624, 4621, 835, 3833, 430, -937, + -937, -937, -937, 2476, 204, -937, -937, -937, 6, 838, + -937, -937, 570, 262, 6090, -937, -937, 6090, 6090, 697, + 6090, 262, 699, 6090, 262, 4373, 4865, 6642, 6684, 6003, + 446, -937, -937, 997, -937, 4980, -937, 848, 850, 852, + 855, 857, 4761, 861, -937, -937, 46, 4486, -937, -937, + -937, 860, -7, -937, 874, 879, 96, 864, 117, -937, + -937, -937, 904, 873, 883, 886, 887, 5037, 892, 5137, + 5137, 5137, 5137, 5137, 2385, 5137, 1699, -937, 430, 579, + 6090, 882, -937, 579, 6090, 727, 885, 262, -937, 881, + -937, 889, 893, 2935, -937, 3946, 5624, 381, -937, 894, + 262, -937, 903, -937, 895, -937, -937, -937, 896, 898, + 900, 901, -937, 907, -937, -937, 6415, -937, 6415, -937, + 6415, -937, -937, 6415, 6415, 6415, -937, 7197, -937, 4486, + 4486, -937, 4486, -937, 4486, 5624, 906, 1048, 921, 1061, + -937, 1066, 930, 932, 1075, 937, 6316, 6316, 6316, 6316, + 922, 2385, 255, 6316, 255, 255, 255, 255, 255, 935, + 134, 255, 5137, 5137, 5137, 5137, 5137, 5137, 5137, 5137, + 5137, 5137, 5137, 5137, 5137, 5137, 5137, 5137, 5137, 5137, + 6003, 4351, 4486, -937, 944, -937, 6090, 945, -937, -937, + 579, -937, -937, 1038, -937, 920, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, -937, - -937, 111, 122, 123, 127, -937, 915, -937, 904, 922, - -937, -937, 139, -937, 905, 917, 921, 925, 5373, 912, - 937, 4814, -937, 1435, 5103, 2019, 2019, 1384, 1384, 757, - 757, -937, 956, 5875, 5902, 1347, 488, 488, 248, 248, - 248, -937, -937, 166, 2923, -937, 6201, 930, -937, 1020, - -937, -937, 1020, 931, 1891, 1891, 1891, 1020, 1020, -937, - -937, -937, -937, 1088, 933, 953, 1093, 1094, 958, -937, - 940, 947, 954, 961, 4914, 964, 248, 4814, -937, -937, - 1020, 965, -937, 1020, -937, -937, -937, -937, -937, 987, - -937, 971, 170, -937, 4264, 4264, 4264, -937, 4264, 4937, - -937, 1891, -937, 990, 1130, 993, 175, 191, 211, 218, - 1891, -937, -937, 976, -937, -937, -937, -937, -937, -937, - 995, -937 + -937, -937, 147, 165, 190, 194, -937, 941, -937, 948, + 952, -937, -937, 201, -937, 949, 960, 961, 964, 6003, + 955, 969, 5137, -937, 5718, 1719, 833, 833, 933, 933, + 1004, 1004, -937, 1087, 1646, 5831, 2240, 625, 625, 255, + 255, 255, -937, -937, 219, 2656, -937, 6090, 963, -937, + 579, -937, -937, 579, 966, 2476, 2476, 2476, 579, 579, + -937, -937, -937, -937, 1117, 971, 979, 1119, 1122, 984, + -937, 974, 975, 977, 976, 5237, 980, 255, 5137, -937, + -937, 579, 982, -937, 579, -937, -937, -937, -937, -937, + 987, -937, 983, 223, -937, 4486, 4486, 4486, -937, 4486, + 1699, -937, 2476, -937, 1005, 1136, 1009, 227, 236, 237, + 239, 2476, -937, -937, 992, -937, -937, -937, -937, -937, + -937, 1012, -937 }; /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. @@ -1340,204 +1343,204 @@ static const yytype_int16 yypact[] = means the default is an error. */ static const yytype_int16 yydefact[] = { - 0, 769, 0, 0, 0, 769, 5, 657, 653, 656, - 765, 766, 659, 660, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 655, 661, 0, 0, 0, 0, 0, + 0, 770, 0, 0, 0, 770, 5, 658, 654, 657, + 766, 767, 660, 661, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 656, 662, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 663, 662, 0, 0, 0, - 0, 0, 654, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 769, 0, 3, 594, 658, 304, 315, 314, - 398, 399, 401, 402, 383, 0, 0, 413, 380, 412, - 407, 404, 403, 406, 384, 0, 0, 385, 405, 415, - 400, 769, 769, 4, 306, 307, 308, 0, 369, 769, - 303, 395, 396, 397, 1, 0, 0, 21, 769, 769, - 769, 22, 769, 769, 769, 0, 42, 769, 0, 0, - 0, 0, 0, 0, 769, 0, 0, 0, 0, 769, - 769, 0, 769, 769, 769, 0, 769, 769, 6, 17, - 7, 19, 0, 15, 16, 18, 77, 44, 769, 769, - 0, 769, 769, 769, 769, 0, 769, 0, 769, 0, - 769, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 769, 330, 336, 0, - 0, 0, 618, 0, 769, 329, 0, 769, 769, 0, - 0, 615, 0, 0, 769, 769, 627, 625, 624, 626, - 623, 304, 398, 399, 401, 402, 413, 412, 407, 404, - 403, 406, 405, 400, 0, 0, 553, 750, 751, 752, - 760, 753, 756, 754, 758, 757, 755, 759, 739, 740, - 0, 0, 769, 745, 738, 622, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 664, 663, 0, 0, 0, + 0, 0, 655, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 770, 0, 3, 595, 659, 304, 315, 314, + 399, 400, 402, 403, 384, 0, 0, 414, 381, 413, + 408, 405, 404, 407, 385, 0, 0, 386, 406, 416, + 401, 770, 770, 4, 306, 307, 308, 367, 370, 770, + 303, 396, 397, 398, 1, 0, 0, 21, 770, 770, + 770, 22, 770, 770, 770, 0, 42, 770, 0, 0, + 0, 0, 0, 0, 770, 0, 0, 0, 0, 770, + 770, 0, 770, 770, 770, 0, 770, 770, 6, 17, + 7, 19, 0, 15, 16, 18, 77, 44, 770, 770, + 0, 770, 770, 770, 770, 0, 770, 0, 770, 0, + 770, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 770, 330, 336, 0, + 0, 0, 619, 0, 770, 329, 0, 770, 770, 0, + 0, 616, 0, 0, 770, 770, 628, 626, 625, 627, + 624, 304, 399, 400, 402, 403, 414, 413, 408, 405, + 404, 407, 406, 401, 0, 0, 554, 751, 752, 753, + 761, 754, 757, 755, 759, 758, 756, 760, 740, 741, + 0, 0, 770, 746, 739, 623, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 767, - 768, 769, 769, 0, 381, 382, 414, 404, 409, 408, - 411, 305, 0, 410, 0, 290, 769, 769, 769, 769, - 769, 769, 0, 339, 289, 341, 769, 761, 762, 763, - 764, 0, 371, 0, 343, 0, 0, 66, 68, 0, - 769, 769, 56, 45, 55, 57, 769, 46, 158, 51, - 23, 769, 0, 49, 0, 0, 0, 0, 0, 0, - 54, 769, 0, 26, 25, 24, 52, 48, 0, 162, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 768, + 769, 770, 770, 0, 382, 383, 415, 405, 410, 409, + 412, 305, 0, 411, 0, 290, 770, 770, 770, 770, + 770, 770, 0, 339, 289, 341, 0, 762, 763, 764, + 765, 0, 372, 0, 343, 0, 0, 66, 68, 0, + 770, 770, 56, 45, 55, 57, 770, 46, 158, 51, + 23, 770, 0, 49, 0, 0, 0, 0, 0, 0, + 54, 770, 0, 26, 25, 24, 52, 48, 0, 162, 0, 161, 0, 58, 0, 20, 0, 0, 50, 53, 338, 317, 328, 0, 0, 0, 0, 13, 0, 74, - 0, 337, 71, 319, 320, 321, 369, 769, 316, 0, - 552, 551, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 337, 71, 319, 320, 321, 370, 770, 316, 0, + 553, 552, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 331, 0, 769, 333, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 652, 743, - 746, 0, 769, 0, 741, 218, 636, 637, 638, 639, - 640, 641, 644, 645, 651, 0, 633, 634, 635, 642, - 643, 631, 632, 628, 629, 630, 650, 649, 0, 0, - 340, 342, 0, 0, 0, 769, 769, 0, 0, 769, - 62, 0, 292, 0, 293, 769, 769, 203, 769, 0, - 0, 0, 769, 769, 0, 204, 207, 769, 0, 202, - 769, 377, 0, 374, 373, 368, 372, 0, 750, 751, - 752, 0, 0, 754, 347, 309, 349, 0, 769, 0, - 769, 317, 0, 0, 47, 43, 769, 0, 0, 0, - 0, 0, 0, 0, 769, 386, 0, 769, 338, 317, - 0, 337, 80, 0, 392, 0, 85, 89, 0, 0, - 769, 318, 0, 769, 0, 0, 416, 225, 0, 76, - 73, 0, 324, 371, 0, 601, 600, 617, 607, 603, - 605, 606, 0, 613, 0, 612, 666, 602, 667, 0, - 669, 0, 670, 0, 673, 674, 675, 676, 677, 678, - 679, 680, 681, 682, 609, 0, 0, 0, 332, 0, - 608, 611, 0, 614, 0, 620, 621, 610, 604, 595, - 554, 744, 0, 769, 769, 769, 102, 219, 0, 648, - 647, 312, 311, 313, 769, 291, 0, 0, 0, 280, - 769, 769, 769, 769, 769, 296, 279, 295, 294, 769, - 0, 0, 769, 0, 244, 769, 769, 769, 206, 0, - 0, 769, 769, 769, 769, 769, 769, 769, 769, 257, - 0, 268, 769, 0, 0, 769, 769, 0, 769, 0, - 550, 549, 378, 367, 310, 0, 0, 769, 769, 0, - 59, 67, 731, 727, 730, 733, 734, 210, 0, 0, - 0, 729, 735, 0, 737, 736, 0, 0, 0, 728, - 0, 0, 0, 0, 0, 0, 0, 0, 211, 246, - 214, 247, 683, 732, 209, 769, 769, 769, 388, 0, - 0, 0, 0, 0, 0, 390, 769, 0, 0, 179, - 180, 181, 167, 0, 168, 0, 164, 169, 165, 769, - 178, 163, 0, 82, 0, 394, 0, 769, 0, 0, - 0, 769, 0, 0, 769, 0, 769, 769, 769, 769, - 769, 0, 769, 248, 0, 769, 91, 416, 220, 0, - 0, 75, 0, 769, 0, 0, 769, 0, 0, 769, - 0, 0, 0, 769, 769, 0, 72, 769, 769, 769, - 0, 322, 0, 0, 0, 0, 0, 334, 335, 619, - 0, 616, 0, 742, 0, 109, 0, 0, 103, 111, - 106, 110, 105, 107, 0, 104, 108, 0, 197, 646, - 297, 769, 0, 0, 769, 769, 769, 282, 283, 769, - 769, 769, 0, 0, 769, 0, 769, 769, 0, 0, - 769, 205, 208, 769, 769, 259, 260, 769, 769, 0, - 769, 238, 258, 769, 769, 0, 270, 271, 0, 0, - 0, 769, 241, 769, 375, 0, 344, 0, 0, 769, - 352, 769, 351, 70, 0, 0, 0, 693, 0, 0, - 0, 690, 0, 0, 701, 700, 699, 698, 0, 0, - 697, 69, 213, 0, 0, 0, 0, 0, 0, 0, + 0, 331, 0, 770, 333, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 653, 744, + 747, 0, 770, 0, 742, 218, 637, 638, 639, 640, + 641, 642, 645, 646, 652, 0, 634, 635, 636, 643, + 644, 632, 633, 629, 630, 631, 651, 650, 0, 0, + 340, 342, 0, 0, 0, 770, 770, 0, 0, 770, + 62, 0, 292, 0, 293, 770, 770, 203, 770, 0, + 0, 0, 770, 770, 0, 204, 207, 770, 0, 202, + 770, 770, 374, 369, 373, 0, 751, 752, 753, 0, + 0, 755, 347, 309, 349, 0, 770, 0, 770, 317, + 0, 0, 47, 43, 770, 0, 0, 0, 0, 0, + 0, 0, 770, 387, 0, 770, 338, 317, 0, 337, + 80, 0, 393, 0, 85, 89, 0, 0, 770, 318, + 0, 770, 0, 0, 417, 225, 0, 76, 73, 0, + 324, 372, 0, 602, 601, 618, 608, 604, 606, 607, + 0, 614, 0, 613, 667, 603, 668, 0, 670, 0, + 671, 0, 674, 675, 676, 677, 678, 679, 680, 681, + 682, 683, 610, 0, 0, 0, 332, 0, 609, 612, + 0, 615, 0, 621, 622, 611, 605, 596, 555, 745, + 0, 770, 770, 770, 102, 219, 0, 649, 648, 312, + 311, 313, 770, 291, 0, 0, 0, 280, 770, 770, + 770, 770, 770, 296, 279, 295, 294, 770, 0, 0, + 770, 0, 244, 770, 770, 770, 206, 0, 0, 770, + 770, 770, 770, 770, 770, 770, 770, 257, 0, 268, + 770, 0, 0, 770, 770, 0, 770, 0, 551, 550, + 378, 0, 375, 310, 0, 0, 770, 770, 0, 59, + 67, 732, 728, 731, 734, 735, 210, 0, 0, 0, + 730, 736, 0, 738, 737, 0, 0, 0, 729, 0, + 0, 0, 0, 0, 0, 0, 0, 211, 246, 214, + 247, 684, 733, 209, 770, 770, 770, 389, 0, 0, + 0, 0, 0, 0, 391, 770, 0, 0, 179, 180, + 181, 167, 0, 168, 0, 164, 169, 165, 770, 178, + 163, 0, 82, 0, 395, 0, 770, 0, 0, 0, + 770, 0, 0, 770, 0, 770, 770, 770, 770, 770, + 0, 770, 248, 0, 770, 91, 417, 220, 0, 0, + 75, 0, 770, 0, 0, 770, 0, 0, 770, 0, + 0, 0, 770, 770, 0, 72, 770, 770, 770, 0, + 322, 0, 0, 0, 0, 0, 334, 335, 620, 0, + 617, 0, 743, 0, 109, 0, 0, 103, 111, 106, + 110, 105, 107, 0, 104, 108, 0, 197, 647, 297, + 770, 0, 0, 770, 770, 770, 282, 283, 770, 770, + 770, 0, 0, 770, 0, 770, 770, 0, 0, 770, + 205, 208, 770, 770, 259, 260, 770, 770, 0, 770, + 238, 258, 770, 770, 0, 270, 271, 0, 0, 0, + 770, 241, 770, 379, 368, 344, 0, 0, 770, 352, + 770, 351, 70, 0, 0, 0, 694, 0, 0, 0, + 691, 0, 0, 702, 701, 700, 699, 0, 0, 698, + 69, 213, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 61, 60, 391, - 769, 0, 0, 769, 0, 0, 0, 769, 0, 41, - 769, 769, 0, 172, 170, 0, 769, 769, 769, 769, - 769, 769, 769, 176, 81, 769, 393, 0, 0, 0, - 0, 0, 326, 325, 0, 769, 769, 250, 251, 769, - 769, 97, 769, 249, 327, 14, 769, 0, 0, 8, - 0, 0, 0, 226, 417, 418, 228, 229, 769, 0, - 232, 234, 231, 227, 769, 0, 185, 0, 126, 127, - 128, 129, 130, 131, 134, 135, 150, 138, 139, 140, - 141, 142, 143, 144, 145, 146, 147, 148, 149, 154, - 153, 137, 136, 123, 125, 124, 132, 133, 121, 122, - 118, 119, 120, 117, 0, 0, 116, 769, 186, 0, - 0, 0, 0, 193, 769, 195, 0, 0, 78, 182, - 323, 0, 0, 668, 671, 672, 0, 0, 769, 0, - 769, 0, 0, 416, 63, 769, 769, 769, 281, 286, - 285, 284, 0, 0, 245, 769, 769, 239, 242, 0, - 0, 299, 769, 263, 262, 261, 267, 0, 0, 269, - 274, 273, 272, 278, 0, 298, 379, 346, 345, 348, - 0, 0, 354, 353, 0, 0, 0, 769, 0, 0, - 0, 0, 0, 0, 0, 726, 212, 215, 710, 711, - 712, 713, 714, 715, 718, 719, 725, 0, 707, 708, - 709, 716, 717, 705, 706, 702, 703, 704, 724, 723, - 0, 0, 769, 0, 0, 0, 0, 0, 200, 0, - 0, 0, 387, 0, 769, 177, 157, 155, 160, 156, - 166, 173, 0, 769, 769, 769, 769, 0, 174, 216, - 0, 83, 769, 87, 0, 0, 769, 99, 769, 254, - 253, 252, 769, 0, 0, 221, 416, 0, 769, 769, - 223, 224, 420, 421, 425, 422, 430, 423, 424, 426, - 427, 428, 429, 431, 432, 433, 434, 435, 436, 437, - 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, - 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, - 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, - 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, - 478, 498, 479, 480, 481, 482, 483, 484, 485, 486, - 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, - 497, 499, 500, 501, 502, 503, 504, 505, 506, 507, - 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, - 518, 519, 520, 521, 522, 523, 524, 525, 769, 542, - 543, 544, 535, 547, 531, 532, 530, 537, 538, 526, - 527, 528, 529, 536, 534, 541, 539, 545, 540, 533, - 546, 419, 0, 230, 233, 0, 189, 769, 152, 151, - 183, 188, 187, 192, 196, 769, 0, 219, 0, 598, - 597, 599, 596, 769, 769, 198, 115, 112, 0, 0, - 65, 64, 287, 769, 769, 240, 243, 769, 769, 264, - 769, 769, 275, 769, 769, 376, 758, 0, 757, 0, - 0, 355, 357, 747, 769, 0, 692, 0, 0, 0, - 0, 0, 689, 0, 695, 696, 684, 0, 722, 721, - 389, 0, 0, 33, 201, 0, 0, 0, 0, 40, - 175, 171, 769, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 217, 555, 0, 86, - 769, 0, 93, 90, 769, 255, 0, 769, 769, 0, - 9, 0, 0, 0, 235, 769, 236, 190, 184, 0, - 769, 79, 0, 199, 0, 113, 664, 288, 0, 0, - 0, 0, 265, 0, 276, 0, 360, 0, 359, 0, - 358, 748, 0, 0, 0, 749, 769, 356, 0, 0, - 694, 0, 691, 0, 720, 0, 0, 0, 0, 27, + 0, 0, 0, 0, 0, 0, 61, 60, 392, 770, + 0, 0, 770, 0, 0, 0, 770, 0, 41, 770, + 770, 0, 172, 170, 0, 770, 770, 770, 770, 770, + 770, 770, 176, 81, 770, 394, 0, 0, 0, 0, + 0, 326, 325, 0, 770, 770, 250, 251, 770, 770, + 97, 770, 249, 327, 14, 770, 0, 0, 8, 0, + 0, 0, 226, 418, 419, 228, 229, 770, 0, 232, + 234, 231, 227, 770, 0, 185, 0, 126, 127, 128, + 129, 130, 131, 134, 135, 150, 138, 139, 140, 141, + 142, 143, 144, 145, 146, 147, 148, 149, 154, 153, + 137, 136, 123, 125, 124, 132, 133, 121, 122, 118, + 119, 120, 117, 0, 0, 116, 770, 186, 0, 0, + 0, 0, 193, 770, 195, 0, 0, 78, 182, 323, + 0, 0, 669, 672, 673, 0, 0, 770, 0, 770, + 0, 0, 417, 63, 770, 770, 770, 281, 286, 285, + 284, 0, 0, 245, 770, 770, 239, 242, 0, 0, + 299, 770, 263, 262, 261, 267, 0, 0, 269, 274, + 273, 272, 278, 0, 298, 376, 0, 346, 345, 348, + 0, 0, 354, 353, 0, 0, 0, 770, 0, 0, + 0, 0, 0, 0, 0, 727, 212, 215, 711, 712, + 713, 714, 715, 716, 719, 720, 726, 0, 708, 709, + 710, 717, 718, 706, 707, 703, 704, 705, 725, 724, + 0, 0, 770, 0, 0, 0, 0, 0, 200, 0, + 0, 0, 388, 0, 770, 177, 157, 155, 160, 156, + 166, 173, 0, 770, 770, 770, 770, 0, 174, 216, + 0, 83, 770, 87, 0, 0, 770, 99, 770, 254, + 253, 252, 770, 0, 0, 221, 417, 0, 770, 770, + 223, 224, 421, 422, 426, 423, 431, 424, 425, 427, + 428, 429, 430, 432, 433, 434, 435, 436, 437, 438, + 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, + 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, + 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, + 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, + 479, 499, 480, 481, 482, 483, 484, 485, 486, 487, + 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, + 498, 500, 501, 502, 503, 504, 505, 506, 507, 508, + 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, + 519, 520, 521, 522, 523, 524, 525, 526, 770, 543, + 544, 545, 536, 548, 532, 533, 531, 538, 539, 527, + 528, 529, 530, 537, 535, 542, 540, 546, 541, 534, + 547, 420, 0, 230, 233, 0, 189, 770, 152, 151, + 183, 188, 187, 192, 196, 770, 0, 219, 0, 599, + 598, 600, 597, 770, 770, 198, 115, 112, 0, 0, + 65, 64, 287, 770, 770, 240, 243, 770, 770, 264, + 770, 770, 275, 770, 770, 380, 759, 0, 758, 0, + 0, 355, 357, 748, 770, 0, 693, 0, 0, 0, + 0, 0, 690, 0, 696, 697, 685, 0, 723, 722, + 390, 0, 0, 33, 201, 0, 0, 0, 0, 40, + 175, 171, 770, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 217, 556, 0, 86, + 770, 0, 93, 90, 770, 255, 0, 770, 770, 0, + 9, 0, 0, 0, 235, 770, 236, 190, 184, 0, + 770, 79, 0, 199, 0, 113, 665, 288, 0, 0, + 0, 0, 265, 0, 276, 377, 0, 360, 0, 359, + 0, 358, 749, 0, 0, 0, 750, 770, 356, 0, + 0, 695, 0, 692, 0, 721, 0, 0, 0, 0, + 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 563, 0, 571, 569, 568, 570, 567, 0, + 0, 566, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 562, 0, 570, 568, 567, 569, 566, 0, 0, - 565, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 84, 0, 95, 769, 0, 769, 256, 92, - 222, 12, 10, 548, 0, 769, 191, 416, 114, 769, - 769, 769, 769, 769, 366, 365, 364, 363, 362, 361, - 350, 0, 0, 0, 0, 36, 769, 34, 0, 0, - 37, 39, 0, 29, 0, 0, 0, 0, 0, 0, - 0, 0, 593, 579, 580, 581, 582, 583, 584, 585, - 586, 592, 0, 576, 577, 578, 574, 575, 571, 572, - 573, 591, 590, 0, 0, 769, 769, 0, 769, 98, - 11, 237, 194, 0, 769, 769, 769, 266, 277, 687, - 686, 688, 685, 0, 0, 0, 0, 0, 0, 564, - 0, 0, 0, 0, 561, 0, 556, 0, 589, 588, - 88, 0, 769, 100, 665, 302, 301, 300, 201, 0, - 28, 0, 0, 30, 0, 0, 0, 563, 0, 587, - 769, 769, 35, 0, 0, 0, 0, 0, 0, 0, - 769, 94, 38, 0, 31, 559, 558, 560, 557, 96, - 0, 32 + 0, 0, 0, 84, 0, 95, 770, 0, 770, 256, + 92, 222, 12, 10, 549, 0, 770, 191, 417, 114, + 770, 770, 770, 770, 770, 366, 365, 364, 363, 362, + 361, 350, 0, 0, 0, 0, 36, 770, 34, 0, + 0, 37, 39, 0, 29, 0, 0, 0, 0, 0, + 0, 0, 0, 594, 580, 581, 582, 583, 584, 585, + 586, 587, 593, 0, 577, 578, 579, 575, 576, 572, + 573, 574, 592, 591, 0, 0, 770, 770, 0, 770, + 98, 11, 237, 194, 0, 770, 770, 770, 266, 277, + 688, 687, 689, 686, 0, 0, 0, 0, 0, 0, + 565, 0, 0, 0, 0, 562, 0, 557, 0, 590, + 589, 88, 0, 770, 100, 666, 302, 301, 300, 201, + 0, 28, 0, 0, 30, 0, 0, 0, 564, 0, + 588, 770, 770, 35, 0, 0, 0, 0, 0, 0, + 0, 770, 94, 38, 0, 31, 560, 559, 561, 558, + 96, 0, 32 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int16 yypgoto[] = { - -937, -937, -320, -937, 3, -937, -937, 834, -129, -937, - 1175, 1301, -409, 503, -125, -937, -937, -145, -937, -937, - -224, -937, -937, -937, -937, 833, -937, -937, -937, -937, - -937, -533, -937, -937, -107, -937, -937, -937, -937, 254, - 454, -651, -937, -706, -740, -356, -532, -937, -133, -937, - 49, -542, -937, -495, -936, -937, -456, 302, -682, 84, - -267, 557, -81, -52, -59, -285, -650, 836, 883, -166, - -132, -937, -122, -937, -937, -937, -937, -171, -117, -937, - -458, -937, -937, -8, 20, -937, -937, -937, -937, 182, - -5, -937, -937, -728, -937, -90, -937, -659, -121, -32, - 698, 941, 507, 502, -937, -937, 765, -79, 1310, 8, - -488, -1 + -937, -937, -313, -937, 24, -937, -937, 863, -130, -937, + 1043, 1315, -416, 530, -129, -937, -937, -117, -937, -937, + -196, -937, -937, -937, -937, 851, -937, -937, -937, -937, + -937, -515, -937, -937, -112, -937, -937, -937, -937, 283, + 505, -702, -937, -700, -744, -331, -554, -937, -87, -937, + 97, -519, -937, -501, -936, -937, -452, 348, -589, -378, + -450, -108, -82, -59, -52, -280, -635, 878, 1484, -159, + -127, -937, -100, -937, -937, -937, -937, -122, -97, -937, + -937, -461, -937, -937, -18, 36, -937, -937, -937, -937, + 59, 61, -937, -937, -731, -937, -43, -937, -734, -119, + -32, 729, 951, 711, 567, -937, -937, 810, -574, 1388, + -54, -482, -1 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int16 yydefgoto[] = { - 0, 4, 5, 938, 939, 139, 523, 140, 141, 311, - 142, 449, 296, 297, 143, 531, 525, 756, 335, 714, - 914, 349, 717, 1380, 721, 350, 936, 1485, 1556, 1142, - 1384, 585, 997, 1118, 144, 332, 705, 706, 707, 708, - 709, 757, 1295, 758, 787, 1107, 464, 465, 677, 678, - 1128, 414, 741, 529, 949, 950, 466, 680, 731, 815, - 826, 282, 283, 91, 92, 351, 182, 352, 93, 293, - 94, 647, 95, 648, 841, 1061, 1062, 1331, 96, 97, - 475, 471, 472, 98, 99, 145, 696, 890, 146, 100, - 101, 102, 103, 742, 743, 944, 1281, 639, 359, 360, - 1586, 216, 65, 681, 682, 231, 232, 1332, 1333, 628, - 66, 450 + 0, 4, 5, 937, 938, 139, 521, 140, 141, 311, + 142, 449, 296, 297, 143, 529, 523, 755, 335, 713, + 913, 349, 716, 1380, 720, 350, 935, 1486, 1557, 1142, + 1384, 583, 996, 1118, 144, 332, 704, 705, 706, 707, + 708, 756, 1295, 757, 786, 1107, 464, 465, 676, 677, + 1128, 414, 740, 527, 948, 949, 466, 679, 730, 814, + 825, 282, 283, 91, 92, 351, 182, 352, 93, 293, + 94, 646, 95, 647, 840, 1061, 1062, 1331, 96, 286, + 97, 473, 640, 641, 98, 99, 145, 695, 889, 146, + 100, 101, 102, 103, 741, 742, 943, 1281, 637, 359, + 360, 1587, 216, 65, 680, 681, 231, 232, 1332, 1333, + 626, 66, 450 }; /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If @@ -1545,1479 +1548,1474 @@ static const yytype_int16 yydefgoto[] = number is the opposite. If YYTABLE_NINF, syntax error. */ static const yytype_int16 yytable[] = { - 6, 504, 683, 329, 147, 614, 308, 331, 915, 937, - 353, 285, 1282, 847, 492, 713, 262, 1005, 395, 644, - 354, 1404, 719, 261, 718, 355, -761, 719, 362, 215, - 364, 365, 366, 367, 679, 369, 183, 371, 596, 373, - 411, 773, 924, -762, 407, 927, 928, -763, -764, 511, - 610, 618, 774, 264, 259, 389, 260, 941, 942, 862, - 551, 234, 412, 408, 184, 834, 397, 398, 835, 920, - 1041, 104, 645, 404, 405, 407, 268, 269, 270, 552, - 651, 931, 932, 273, 810, 821, 407, 287, 288, 289, - 284, 284, 148, 259, 589, 260, 832, -761, 294, 956, - -761, 998, 801, 1033, 1001, 1075, 292, 147, 147, 147, - 149, 147, 147, 147, -762, 155, 147, -762, -763, -764, - 265, -763, -764, 147, 1104, 244, 1020, 407, 147, 147, - 407, 147, 147, 147, 356, 147, 147, 407, 287, 288, - 289, 748, 1032, 1105, 157, 749, 1299, 361, 361, 1300, - 361, 361, 361, 361, 186, 361, 1301, 361, 215, 361, - 1148, 1047, 357, 812, 526, 244, 527, 353, 528, 720, - 801, 1039, 1054, 1405, 720, 361, 687, 354, 1149, 683, - 440, 441, 355, 294, 619, 917, 361, 361, 750, 921, - 290, 534, 863, 361, 361, 407, 452, 454, 353, 407, - 1436, 638, 353, 735, 268, 269, 270, 273, 354, 898, - 150, 776, 354, 355, 1302, 1113, 1007, 355, 1348, 1437, - 801, 1040, 468, 1440, 1443, 438, 185, 291, 151, 467, - 413, 415, 287, 288, 289, 905, 407, 631, 152, 906, - 751, 290, 1441, 1444, 1139, 820, 153, 1140, 1141, 217, - 218, 219, 253, 254, 255, 1532, 256, 257, 258, 407, - 284, 284, 268, 1008, 1037, 1038, 154, 872, 1134, 752, - 407, 407, 567, 1143, 156, 407, 284, 284, 1569, 158, - 469, 1469, 907, 753, 159, 473, 476, 1577, 754, 1570, - 1571, 356, 520, 755, 1572, 1309, 256, 257, 258, 147, - 147, 486, 1010, 220, 1286, 147, 1578, -101, 160, -101, - 147, -101, 792, 161, 407, 221, 222, 162, 1614, 357, - 6, 163, 356, 407, 358, 516, 356, 839, 1002, 164, - 217, 218, 219, 1588, 165, 290, 274, 1615, 275, 407, - 276, 166, 1625, 1003, 1004, 1296, 807, 1034, 1291, 1292, - 357, 167, 223, 224, 357, 225, 294, 413, 1626, 407, - 226, 837, 227, 908, 533, 1127, 407, 827, 1021, 1304, - 830, 192, 831, 1130, 168, 683, 897, 909, 1627, 447, - 820, 448, 910, 277, 220, 1628, 169, 911, 1, 2, - 3, 70, 361, 71, 72, 73, 221, 222, 884, 885, - 886, 613, 468, 266, 1144, 170, 1307, 679, 612, 467, - 171, 586, 1479, 1480, 1481, -101, 172, -101, 1389, -101, - 1131, 80, 173, 287, 288, 289, 620, 1003, 1004, 1135, - 621, 468, 174, 223, 224, 175, 225, 267, 467, 820, - 1046, 226, 913, 227, 1003, 1004, 1293, 176, 606, 598, - 514, 599, 515, 600, 606, 606, 1385, 82, 83, 1494, - 1003, 1004, 1381, 187, 278, 353, 629, 724, 10, 641, - 11, 188, 476, 622, 88, 354, 831, 1053, 279, 90, - 355, 358, 193, 280, 194, 1303, -280, 147, 281, 684, - 1422, 1423, 1424, 1315, 1316, 6, 601, 737, 195, 738, - 739, 740, 176, 147, 263, 526, 711, 527, 272, 1006, - 1137, 932, 358, 286, 353, 406, 358, 1146, 1147, 733, - 299, 1469, 6, 310, 354, 468, 290, 314, 732, 355, - 1003, 1004, 467, 315, 316, 323, 317, 318, 1036, 759, - 319, 324, 486, 325, 328, 630, 390, 631, 392, 632, - 413, 627, 805, 393, 623, 399, 445, 477, 1050, 804, - 468, 1051, 1052, 1402, 217, 218, 219, 467, 624, 470, - 1102, -279, 488, 625, 489, 490, 505, 602, 626, 507, - 517, 518, 415, 469, 788, 522, 530, 535, 407, 356, - 542, 603, 633, 606, 536, 537, 604, 538, 539, 1379, - 606, 606, 540, 1383, 544, 541, 543, 549, 606, 545, - 1386, 629, 546, 547, 606, 606, 586, 357, 220, 548, - 550, 629, 629, 553, 554, 629, 415, 555, 556, 581, - 221, 222, 557, 1115, 1397, 558, 559, 415, 356, 560, - 561, 827, 569, 859, 830, 562, 6, 842, 1476, 1477, - 1478, 563, 1479, 1480, 1481, 183, 564, 570, 468, 571, - 573, 574, 468, 575, 577, 467, 357, 223, 224, 467, - 225, 584, 915, 634, 688, 226, 578, 227, 591, 593, - 597, 617, 646, 184, 147, 147, 147, 635, 643, 710, - 649, 689, 636, 685, 690, 6, 806, 637, 691, 692, - 693, 694, 712, 736, 715, 228, 760, 816, 629, 229, - 819, 768, 762, 763, 230, -281, 469, 791, 803, -370, - 469, 794, 759, 733, 770, 769, 733, 733, 759, 771, - 1011, 1012, 732, 772, 147, 732, 732, 244, 1016, 801, - 1017, 813, 945, 823, 468, 952, 833, 836, 840, 844, - 845, 467, 846, 848, 852, 476, 788, 415, 759, 861, - 759, 891, 892, 759, 853, 893, 894, 899, 183, 1563, - 895, 896, 1116, 901, 902, 918, 1117, 916, 922, 358, - 919, 1322, 1408, 925, 934, 1409, 1410, 943, 1411, 946, - 1469, 1413, 947, 912, 1119, 606, 184, 954, 606, 606, - 641, 1013, 1014, 629, 468, 415, 415, 683, 1015, 788, - 1023, 467, 1018, 629, 1022, 1025, 629, 629, 859, 641, - 820, 831, 1067, 1057, 1595, 1596, 1597, 1060, 358, 1069, - 641, 1103, 1074, 1106, 451, 453, 1109, 1110, 147, 679, - 1063, 1111, 1122, 1132, 1123, 185, 1133, 1136, 1483, 1150, - 1145, 1151, 1486, 1100, 1283, 1489, 932, 1050, 1051, 1052, - 1284, 1287, 251, 252, 253, 254, 255, 1289, 256, 257, - 258, 1621, 1288, 1298, 1306, 1314, 1313, 468, 1317, 1318, - 1629, 1320, 1334, 1323, 467, 710, 1335, 1321, 1035, 6, - 1324, 1336, 1108, -288, 1337, 1342, 147, 1338, 1043, 629, - 147, 1044, 1045, 1340, 1343, 1351, 629, 629, 1344, 1352, - 629, 1129, 1353, 1354, 415, 1474, 1475, 1476, 1477, 1478, - 1355, 1479, 1480, 1481, 1356, 733, 1357, 759, 733, 733, - 1358, 641, 1359, 1378, 732, 469, 1382, 732, 732, 1305, - 1387, 1388, 1400, 64, 214, 1394, 1339, 952, 1406, 242, - 243, 1425, 1428, 1557, 1559, 1429, 1430, 1431, 185, 1438, - 244, 1432, 1562, 759, 1433, 1435, 1564, 1565, 1566, 1567, - 1568, 1439, 1461, 1462, 1463, 1464, 1465, 1466, 1467, 1468, - 1442, 1445, 1484, 1446, 1114, 1447, 1448, 1452, 1487, 1469, - 1492, 191, 816, 1490, 1497, 819, 1491, 196, 197, 198, - 199, 200, 1495, 641, 235, 1498, 605, 759, 759, 1499, - 1500, 183, 607, 608, 1426, 1501, 1502, 586, 1515, 284, - 1503, 1516, 1590, 1517, 1591, 1593, 606, 1391, 1392, 1518, - 1520, 1519, 1522, 363, 415, 415, 1521, 775, 368, 184, - 370, 629, 372, 1523, 374, 375, 376, 377, 378, 379, - 380, 381, 382, 383, 384, 385, 386, 387, 388, 1611, - 1531, 1528, 1560, 1573, 1555, 1558, 361, 777, 1561, 396, - 1576, 1575, 1579, 400, 1580, 401, 402, 1620, 1581, 1584, - 778, 779, 1582, 468, 710, 251, 252, 253, 254, 255, - 467, 256, 257, 258, 1585, 1322, 780, 1592, 1598, 1594, - 1599, 147, 1600, 1601, 1602, 1604, 1587, 1603, 1470, 1471, - 1472, 1473, 1605, 1129, 1474, 1475, 1476, 1477, 1478, 1606, - 1479, 1480, 1481, 629, 629, 629, 1319, 781, 1607, 1608, - 782, 586, 1610, 783, 403, 586, 1612, 733, 1613, 1622, - 1623, 469, 1624, 1630, 1631, 495, 732, 361, 361, 784, - 1390, 790, 843, 1401, 1482, 444, 1120, 900, 797, 798, - 1574, 785, 1399, 1360, 1427, 1077, 802, 510, 1393, 851, - 512, 0, 808, 809, 0, 786, 583, 416, 417, 418, + 6, 308, 329, 331, 147, 936, 682, 712, 502, 612, + 285, 1282, 1004, 914, 643, 353, 261, 919, 636, 490, + 718, 1404, 148, 262, 411, 395, 183, 846, 773, 215, + 362, 594, 364, 365, 366, 367, 678, 369, 616, 371, + 149, 373, 354, 608, 292, 355, 412, 955, 259, 997, + 260, 264, 1000, 407, 509, 717, -762, 389, 718, 775, + 104, 234, 772, 644, 549, 1040, 1031, 861, 397, 398, + 155, 650, 408, 407, 407, 404, 405, 150, 1104, 244, + 184, 310, 407, 550, 413, 1046, 287, 288, 289, 625, + 284, 284, 587, 1075, 151, 407, 1053, 1105, 294, 819, + 809, 1299, 407, 185, 413, 152, 820, 147, 147, 147, + 1127, 147, 147, 147, 1300, 153, 147, 831, 265, 830, + 407, 1301, 244, 147, 356, 819, 407, -762, 147, 147, + -762, 147, 147, 147, 923, 147, 147, 926, 927, 1302, + 1019, 1437, 268, 269, 270, 1348, 154, 361, 361, 273, + 361, 361, 361, 361, 156, 361, 1148, 361, 215, 361, + 1438, 806, 916, 930, 931, 811, 920, 719, 157, 451, + 453, 617, 353, 1405, 1149, 361, 1001, 186, 357, 440, + 441, 686, 826, 294, 682, 829, 361, 361, -763, 290, + 244, 1002, 1003, 361, 361, 452, 454, 1143, 532, 354, + 862, 358, 355, 353, -764, 719, 158, 353, 734, 1113, + 256, 257, 258, 259, 897, 260, 1134, 274, -765, 275, + 1055, 276, 467, 1056, 192, 438, 291, 940, 941, 468, + 354, 415, 805, 355, 354, 800, 1032, 355, 1006, 484, + 217, 218, 219, 815, 1441, 159, 818, 251, 252, 253, + 254, 255, 1286, 256, 257, 258, 1007, 160, 912, -763, + 284, 284, -763, 1442, 277, 1444, 10, 871, 11, 1296, + 268, 269, 270, 273, 565, -764, 284, 284, -764, 161, + 469, 356, 407, 162, 1445, 518, 1036, 1037, 1470, -765, + 163, 1309, -765, 406, 220, 407, 1291, 1292, 1009, 147, + 147, 1533, 531, 800, 1038, 147, 221, 222, 164, 447, + 147, 448, 356, 407, 1570, 791, 356, 253, 254, 255, + 6, 256, 257, 258, 512, 628, 513, 629, 268, 630, + 911, 165, 1571, 838, 166, 357, 1139, 167, 407, 1140, + 1141, 603, 407, 223, 224, 278, 225, 605, 606, 1578, + 1033, 226, 474, 227, 1035, 323, 294, 1572, 358, 279, + 1020, 1573, 800, 1039, 280, 836, 357, 407, 1579, 281, + 357, 1615, 631, 168, 1049, 407, 169, 1050, 1051, 170, + 682, 1144, 896, 1304, 407, 407, 1589, 407, 324, 358, + 1616, 171, 361, 358, 1626, 1130, 172, 1307, 883, 884, + 885, 610, 467, 1627, 1628, 173, 1629, 174, 611, 468, + 678, 584, 175, 1131, -101, 1389, -101, 176, -101, 1480, + 1481, 1482, 217, 218, 219, 1034, 596, 325, 597, 467, + 598, 187, 514, 1137, 931, 1042, 468, 188, 1043, 1044, + 287, 288, 289, 747, 1, 2, 3, 748, 604, 1115, + 1002, 1003, 1135, 632, 604, 604, 193, 826, 723, 1495, + 829, 524, 194, 525, 731, 526, 627, 633, 353, 639, + 642, 195, 634, 599, 263, 758, 220, 635, 484, 736, + 272, 737, 738, 739, 789, 147, 299, 683, 221, 222, + 749, 796, 797, 6, 314, 354, 819, 1045, 355, 801, + 315, 147, 1303, 316, 710, 807, 808, -101, 524, -101, + 525, -101, 1005, 830, 1052, 1315, 1316, 732, 353, 317, + 6, 1114, 318, 467, 319, 223, 224, 328, 225, 815, + 468, 390, 818, 226, 392, 227, 474, 1002, 1003, 1293, + 1146, 1147, 750, 290, 393, 354, 1002, 1003, 355, 1385, + 803, 1002, 1003, 1381, 600, 399, 413, 804, 467, 1402, + 1423, 1424, 1425, 445, 709, 468, 470, -279, 601, 471, + 475, 751, 486, 602, 487, 488, 1102, 356, -280, 503, + 415, 469, 787, 1397, 505, 752, 515, 528, 1386, 516, + 753, 604, 520, 533, 582, 754, 774, 1322, 604, 604, + 407, 534, 535, 536, 537, 540, 604, 538, 539, 627, + 541, 542, 604, 604, 584, 547, 543, 1379, 544, 627, + 627, 1383, 545, 627, 415, 546, 776, 356, 548, 551, + 552, 357, 553, 554, 567, 415, 242, 243, 555, 777, + 778, 556, 858, 557, 183, 6, 841, 244, 572, 558, + 559, 560, 561, 562, 358, 779, 568, 467, 1470, 758, + 569, 467, 571, 1319, 468, 758, 573, 575, 468, 731, + 576, 579, 731, 731, 1049, 1050, 1051, 589, 914, 591, + 595, 357, 645, 147, 147, 147, 780, 1028, 615, 781, + 1029, 1030, 782, 648, 6, 758, 684, 758, 184, 687, + 758, 688, 689, 690, 358, 691, 692, 627, 783, 693, + 711, 714, 735, 759, 761, 469, 762, 767, 790, 469, + 784, 185, 732, 768, 769, 732, 732, 770, 793, 1010, + 1011, 771, 802, 147, 785, -281, 800, 1015, 812, 1016, + 822, 944, 832, 467, 951, 834, 1042, 1043, 1044, -371, + 468, 835, 1417, 1419, 1421, 787, 415, 183, 839, 843, + 1408, 709, 844, 1409, 1410, 845, 1411, 1564, 847, 1413, + 1116, 1117, 251, 252, 253, 254, 255, 851, 256, 257, + 258, 217, 218, 219, 852, 1477, 1478, 1479, 1119, 1480, + 1481, 1482, 890, 860, 604, 891, 892, 604, 604, 639, + 893, 894, 627, 467, 415, 415, 895, 898, 787, 900, + 468, 184, 627, 682, 901, 627, 627, 858, 639, 918, + 474, 1596, 1597, 1598, 915, 924, 1484, 917, 921, 639, + 1487, 933, 945, 953, 185, 220, 942, 147, 946, 1063, + 1022, 1012, 1505, 678, 1506, 1013, 1507, 221, 222, 1508, + 1509, 1510, 1100, 1466, 1467, 1468, 1469, 1014, 1017, 1021, + 1060, 1067, 1024, 819, 758, 830, 1470, 1057, 1622, 1069, + 1103, 731, 1074, 1490, 731, 731, 467, 1630, 1106, 1109, + 1110, 1111, 1132, 468, 223, 224, 1122, 225, 6, 1133, + 1136, 1108, 226, 931, 227, 147, 1123, 1150, 627, 147, + 758, 287, 288, 289, 618, 627, 627, 1145, 619, 627, + 1129, 1151, 1322, 415, 287, 288, 289, 904, 1312, 629, + 1283, 905, 228, 1284, 732, 1287, 229, 732, 732, 1289, + 639, 230, 1558, 1288, 469, 1298, 1306, 1305, 1313, 1314, + 1321, 1317, 1318, 1320, 758, 758, 951, -288, 1339, 1323, + 1324, 620, 1334, 64, 1335, 1468, 1469, 1337, 1338, 1336, + 709, 1340, 1342, 1351, 906, 1343, 1470, 1352, 1353, 217, + 218, 219, 1354, 1560, 1344, 1356, 1355, 1357, 1358, 1359, + 1378, 1563, 1382, 1387, 1319, 1565, 1566, 1567, 1568, 1569, + 1388, 1475, 1476, 1477, 1478, 1479, 1394, 1480, 1481, 1482, + 183, 191, 639, 1592, 290, 1400, 1406, 196, 197, 198, + 199, 200, 1426, 1429, 235, 1430, 584, 290, 284, 1431, + 1432, 1427, 1439, 220, 1433, 604, 1434, 1436, 1440, 1391, + 1392, 1443, 621, 415, 415, 221, 222, 1470, 1446, 1447, + 627, 1591, 1448, 1449, 1594, 907, 622, 1485, 1453, 1491, + 1498, 623, 1488, 1561, 184, 1516, 624, 1492, 1517, 908, + 1493, 1496, 1499, 1500, 909, 1501, 361, 1502, 1503, 910, + 1518, 1519, 223, 224, 1504, 225, 1520, 185, 1612, 1521, + 226, 1522, 227, 467, 731, 1523, 1524, 1529, 1562, 1574, + 468, 1475, 1476, 1477, 1478, 1479, 1621, 1480, 1481, 1482, + 1577, 147, 1532, 1462, 1463, 1464, 1465, 1466, 1467, 1468, + 1469, 1556, 1559, 1129, 580, 1576, 1580, 1581, 1582, 230, + 1470, 1583, 1585, 627, 627, 627, 1586, 1599, 1601, 1602, + 1593, 584, 1603, 1604, 1595, 584, 1613, 732, 1600, 1605, + 1606, 469, 1607, 1608, 403, 1609, 1624, 361, 361, 1611, + 1614, 302, 303, 304, 1623, 305, 307, 309, 1625, 1631, + 313, 1632, 1475, 1476, 1477, 1478, 1479, 320, 1480, 1481, + 1482, 1390, 326, 327, 493, 330, 333, 334, 842, 338, + 339, 1401, 1483, 472, 1120, 508, 1575, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, - 429, 430, 431, 432, 433, 434, 435, 0, 0, 439, - 0, 185, 0, 0, 443, 0, 0, 0, 1043, 1044, - 1045, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1403, 0, 0, 0, 0, 0, 0, - 0, 0, 287, 288, 289, 725, 468, 0, 0, 726, - 493, 0, 0, 467, 0, 0, 0, 1416, 1418, 1420, - 0, 0, 0, 0, 0, 468, 0, 945, 468, 468, - 0, 468, 467, 0, 468, 467, 467, 0, 467, 506, - 0, 467, 0, 0, 0, 566, 0, 0, 0, 0, - 0, 0, 727, 302, 303, 304, 0, 305, 307, 309, - 0, 0, 313, 759, 684, 0, 0, 0, 0, 320, - 0, 0, 788, 284, 326, 327, 759, 330, 333, 334, - 0, 338, 339, 469, 0, 0, 469, 469, 0, 469, - 0, 468, 469, 0, 0, 468, 0, 0, 467, 0, - 0, 565, 467, 6, 0, 290, 1504, 0, 1505, 0, - 1506, 0, 1459, 1507, 1508, 1509, 0, 579, 580, 0, - 0, 0, 0, 1029, 587, 0, 1030, 1031, 0, 0, - 0, 629, 0, 728, 0, 1463, 1464, 1465, 1466, 1467, - 1468, 0, 233, 0, 217, 218, 219, 729, 0, 469, - 1469, 0, 730, 469, 0, 0, 759, 586, 0, 0, - 0, 0, 0, 0, 952, 271, 1511, 1512, 716, 1513, - 0, 1514, 0, 0, 0, 734, 1467, 1468, 0, 0, - 0, 640, 0, 0, 0, 298, 0, 1469, 1459, 0, - 0, 0, 0, 0, 0, 147, 468, 0, 220, 0, - 0, 0, 764, 467, 765, 322, 766, 0, 0, 0, - 221, 222, 0, 0, 0, 337, 1319, 0, 1553, 0, - 0, 0, 1462, 1463, 1464, 1465, 1466, 1467, 1468, 723, - 0, 0, 0, 0, 0, 0, 0, 0, 1469, 747, - 0, 0, 0, 0, 0, 307, 313, 223, 224, 0, - 225, 494, 0, 0, 469, 226, 586, 227, 0, 0, - 391, 0, 0, 394, 586, 0, 0, 468, 586, 586, - 586, 586, 586, 0, 467, 1474, 1475, 1476, 1477, 1478, - 0, 1479, 1480, 1481, 579, 1108, 0, 0, 0, 582, - 0, 0, 0, 0, 230, 0, 0, 0, 0, 789, - 0, 237, 238, 239, 240, 241, 242, 243, 793, 409, - 410, 0, 1474, 1475, 1476, 1477, 1478, 244, 1479, 1480, - 1481, 0, 0, 0, 586, 469, 0, 586, 858, 0, - 0, 0, 0, 788, 788, 788, 436, 0, 0, 0, - 0, 0, 1616, 1617, 1618, 0, 1619, 0, 0, 0, - 455, 456, 0, 0, 1312, 446, 0, 838, 1471, 1472, - 1473, 586, 0, 1474, 1475, 1476, 1477, 1478, 0, 1479, - 1480, 1481, 0, 485, 0, 487, 0, 0, 0, 586, - 788, 0, 854, 855, 856, 857, 0, 860, 0, 788, - 0, 0, 497, 0, 498, 499, 500, 501, 502, 503, - 0, 0, 0, 0, 1377, 0, 0, 478, 479, 480, - 0, 0, 0, 0, 0, 0, 513, 0, 0, 0, - 0, 0, 0, 0, 0, 521, 0, 0, 524, 0, - 0, 0, 0, 650, 0, 0, 532, 246, 247, 248, + 429, 430, 431, 432, 433, 434, 435, 899, 1399, 439, + 1077, 1360, 510, 1428, 443, 1393, 0, 0, 0, 0, + 0, 581, 1403, 476, 477, 478, 70, 0, 71, 72, + 73, 758, 0, 850, 0, 0, 467, 1588, 0, 1471, + 1472, 1473, 1474, 468, 758, 1475, 1476, 1477, 1478, 1479, + 491, 1480, 1481, 1482, 0, 467, 80, 944, 467, 467, + 0, 467, 468, 0, 467, 468, 468, 0, 468, 0, + 0, 468, 267, 287, 288, 289, 724, 220, 0, 504, + 725, 0, 0, 0, 0, 0, 0, 0, 0, 221, + 222, 0, 82, 83, 683, 0, 0, 0, 0, 0, + 0, 0, 787, 284, 0, 0, 340, 341, 0, 88, + 0, 0, 0, 469, 90, 0, 469, 469, 0, 469, + 0, 467, 469, 726, 758, 467, 481, 224, 468, 225, + 0, 0, 468, 6, 226, 0, 227, 0, 0, 0, + 0, 563, 1460, 307, 313, 0, 0, 342, 0, 492, + 70, 0, 71, 72, 73, 74, 0, 577, 578, 343, + 0, 627, 77, 291, 585, 0, 78, 0, 0, 0, + 0, 0, 0, 79, 0, 0, 290, 0, 0, 469, + 80, 0, 0, 469, 0, 0, 0, 584, 0, 0, + 0, 0, 0, 0, 951, 0, 81, 1512, 1513, 0, + 1514, 0, 1515, 0, 727, 0, 0, 0, 344, 0, + 0, 0, 0, 0, 0, 0, 82, 83, 728, 1460, + 0, 638, 84, 729, 0, 0, 147, 467, 0, 0, + 345, 346, 87, 88, 468, 0, 89, 0, 90, 0, + 0, 0, 0, 347, 240, 241, 242, 243, 0, 1554, + 233, 70, 0, 71, 72, 73, 0, 244, 0, 348, + 0, 238, 239, 240, 241, 242, 243, 722, 0, 0, + 0, 0, 0, 271, 0, 0, 244, 746, 0, 0, + 0, 80, 0, 0, 0, 469, 0, 584, 0, 0, + 0, 0, 0, 298, 0, 584, 0, 267, 467, 584, + 584, 584, 584, 584, 0, 468, 0, 0, 0, 0, + 0, 0, 0, 322, 0, 0, 1108, 82, 83, 0, + 0, 0, 577, 337, 0, 0, 0, 0, 0, 649, + 0, 0, 0, 0, 88, 0, 0, 788, 0, 90, + 0, 0, 0, 0, 0, 214, 792, 238, 239, 240, + 241, 242, 243, 0, 0, 584, 469, 0, 584, 0, + 0, 0, 244, 0, 787, 787, 787, 0, 391, 0, + 0, 394, 0, 1617, 1618, 1619, 0, 1620, 0, 0, 249, 250, 251, 252, 253, 254, 255, 0, 256, 257, - 258, 0, 0, 0, 0, 0, 0, 951, 0, 0, - 0, 220, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 221, 222, 568, 0, 0, 0, 572, - 0, 238, 239, 240, 241, 242, 243, 0, 0, 0, - 0, 233, 0, 0, 0, 0, 244, 1064, 1065, 1066, - 0, 1068, 0, 1070, 0, 1071, 1072, 0, 0, 0, - 483, 224, 640, 225, 0, 0, 594, 595, 226, 0, - 227, 0, 0, 0, 0, 0, 0, 298, 0, 609, - 0, 640, 0, 615, 616, 0, 0, 0, 0, 298, - 0, 0, 640, 0, 0, 0, 1056, 291, 0, 0, - 0, 642, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 298, 0, 0, 1073, 0, 0, 0, 0, 298, - 0, 0, 0, 0, 0, 1078, 1079, 1080, 1081, 1082, - 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, - 1093, 1094, 1095, 1096, 1097, 1376, 0, 1101, 0, 0, - 0, 0, 0, 0, 652, 653, 654, 10, 0, 11, - 655, 656, 0, 0, 761, 0, 849, 247, 248, 249, + 258, 0, 584, 0, 455, 456, 837, 247, 248, 249, 250, 251, 252, 253, 254, 255, 0, 256, 257, 258, - 887, 888, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 640, 1377, 0, 1377, 1377, 1377, 1377, - 1377, 658, 1377, 0, 0, 0, 0, 0, 0, 951, - 0, 0, 409, 659, 0, 0, 0, 0, 660, 0, - 0, 796, 0, 0, 799, 800, 661, 662, 775, 795, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 814, 0, 776, 817, 818, 0, 0, 822, - 0, 0, 0, 825, 0, 0, 828, 829, 777, 0, - 663, 824, 664, 1294, 665, 640, 0, 1297, 0, 666, - 0, 778, 779, 667, 0, 0, 668, 0, 0, 298, - 0, 669, 0, 0, 670, 0, 0, 780, 1377, 1377, - 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, - 1377, 1377, 1377, 1377, 1377, 1377, 671, 0, 0, 672, - 673, 0, 0, 0, 674, 0, 850, 0, 781, 0, - 676, 782, 0, 0, 783, 1361, 236, 237, 238, 239, - 240, 241, 242, 243, 0, 1346, 0, 904, 0, 0, - 784, 0, 0, 244, 0, 0, 0, 926, 0, 0, - 929, 930, 785, 933, 0, 0, 0, 0, 1377, 1465, - 1466, 1467, 1468, 0, 0, 0, 786, 0, 0, 940, - 955, 0, 1469, 0, 999, 1000, 0, 0, 0, 0, - 1009, 0, 0, 0, 0, 1451, 0, 1453, 1454, 1455, - 1456, 1457, 0, 1460, 0, 0, 330, 0, 0, 0, + 584, 787, 0, 0, 0, 0, 0, 409, 410, 0, + 787, 853, 854, 855, 856, 0, 859, 0, 0, 0, + 0, 0, 0, 0, 363, 0, 0, 0, 0, 368, + 0, 370, 0, 372, 436, 374, 375, 376, 377, 378, + 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, + 0, 0, 0, 446, 1464, 1465, 1466, 1467, 1468, 1469, + 396, 0, 0, 0, 400, 0, 401, 402, 0, 1470, + 0, 483, 0, 485, 248, 249, 250, 251, 252, 253, + 254, 255, 0, 256, 257, 258, 950, 0, 0, 0, + 495, 0, 496, 497, 498, 499, 500, 501, 0, 0, + 0, 0, 0, 0, 0, 1462, 1463, 1464, 1465, 1466, + 1467, 1468, 1469, 0, 511, 0, 0, 886, 887, 0, + 0, 0, 1470, 519, 0, 0, 522, 1464, 1465, 1466, + 1467, 1468, 1469, 0, 530, 0, 0, 0, 0, 0, + 0, 638, 1470, 0, 0, 0, 444, 0, 0, 0, + 592, 593, 0, 0, 0, 0, 0, 0, 0, 0, + 638, 0, 0, 607, 0, 0, 0, 613, 614, 0, + 0, 638, 0, 566, 0, 0, 0, 570, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 233, + 1473, 1474, 0, 1073, 1475, 1476, 1477, 1478, 1479, 0, + 1480, 1481, 1482, 0, 1078, 1079, 1080, 1081, 1082, 1083, + 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, + 1094, 1095, 1096, 1097, 0, 298, 1101, 0, 1377, 0, 0, 0, 0, 0, 0, 0, 0, 298, 0, 0, - 0, 1377, 1024, 0, 1377, 1027, 1028, 0, 236, 237, - 238, 239, 240, 241, 242, 243, 0, 0, 0, 0, - 0, 0, 0, 0, 1042, 244, 0, 0, 0, 0, - 0, 0, 0, 0, 1048, 1049, 0, 0, 0, 0, - 0, 0, 0, 0, 1055, 0, 0, 0, 697, 0, - 0, 0, 245, 246, 247, 248, 249, 250, 251, 252, - 253, 254, 255, 0, 256, 257, 258, 698, 0, 1533, - 1534, 1535, 1536, 1537, 1538, 1539, 1540, 1541, 1542, 1543, - 1544, 1545, 1546, 1547, 1548, 1549, 1550, 1474, 1475, 1476, - 1477, 1478, 0, 1479, 1480, 1481, 7, 8, 9, 10, - 0, 11, 12, 13, 1098, 0, 0, 0, 1449, 0, - 0, 0, 0, 0, 0, 0, 0, 1124, 0, 0, - 1125, 1126, 0, 1121, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1396, 1138, 0, 0, 0, - 0, 0, 0, 1363, 245, 246, 247, 248, 249, 250, - 251, 252, 253, 254, 255, 1364, 256, 257, 258, 0, - 1365, 0, 590, 0, 0, 1285, 0, 1458, 23, 24, - 0, 0, 0, 0, 26, 0, 0, 0, 28, 29, - 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 1346, 0, 1609, 0, 0, 1434, 0, - 0, 0, 0, 0, 45, 0, 46, 0, 1290, 0, - 0, 1366, 0, 0, 0, 1367, 0, 0, 1368, 0, - 0, 0, 0, 52, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1310, 1311, 1524, 1525, - 1526, 1527, 1308, 1529, 0, 1530, 951, 0, 1369, 0, - 0, 1370, 1371, 1372, 0, 0, 1373, 0, 1450, 62, - 0, 0, 1375, 0, 0, 0, 1152, 1153, 1154, 1155, + 0, 1471, 1472, 1473, 1474, 0, 1376, 1475, 1476, 1477, + 1478, 1479, 0, 1480, 1481, 1482, 0, 298, 0, 0, + 0, 0, 1472, 1473, 1474, 298, 564, 1475, 1476, 1477, + 1478, 1479, 638, 1480, 1481, 1482, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 950, 0, + 651, 652, 653, 10, 0, 11, 654, 655, 0, 0, + 0, 0, 848, 795, 0, 0, 798, 799, 0, 0, + 760, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 813, 0, 0, 816, 817, 0, + 0, 821, 0, 330, 0, 824, 0, 657, 827, 828, + 0, 0, 1294, 0, 638, 0, 1297, 0, 0, 658, + 0, 0, 0, 0, 659, 0, 0, 0, 409, 0, + 0, 0, 660, 661, 236, 237, 238, 239, 240, 241, + 242, 243, 0, 0, 0, 794, 0, 0, 0, 0, + 0, 244, 0, 0, 0, 0, 0, 715, 0, 0, + 0, 0, 0, 0, 733, 0, 662, 1325, 663, 0, + 664, 0, 0, 0, 0, 665, 0, 823, 0, 666, + 0, 0, 667, 0, 0, 1346, 0, 668, 833, 0, + 669, 763, 0, 764, 0, 765, 298, 0, 0, 0, + 925, 0, 0, 928, 929, 0, 932, 0, 0, 0, + 0, 0, 670, 0, 0, 671, 672, 0, 0, 0, + 673, 0, 849, 954, 0, 0, 675, 998, 999, 0, + 0, 0, 0, 1008, 0, 0, 0, 0, 1377, 0, + 1377, 1377, 1377, 1377, 1377, 0, 1377, 0, 0, 0, + 0, 0, 0, 0, 903, 0, 1452, 0, 1454, 1455, + 1456, 1457, 1458, 0, 1461, 1023, 0, 0, 1026, 1027, + 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, + 255, 0, 256, 257, 258, 0, 939, 1041, 588, 0, + 0, 0, 0, 0, 0, 0, 0, 1047, 1048, 0, + 0, 0, 0, 0, 0, 0, 0, 1054, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 857, 0, + 0, 0, 0, 0, 298, 0, 0, 0, 0, 0, + 0, 0, 0, 1377, 1377, 1377, 1377, 1377, 1377, 1377, + 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, + 1377, 1534, 1535, 1536, 1537, 1538, 1539, 1540, 1541, 1542, + 1543, 1544, 1545, 1546, 1547, 1548, 1549, 1550, 1551, 0, + 0, 0, 0, 0, 0, 956, 0, 0, 0, 0, + 1124, 0, 0, 1125, 1126, 957, 958, 959, 960, 961, + 962, 963, 964, 0, 0, 1396, 0, 0, 0, 1138, + 0, 0, 965, 1377, 966, 967, 968, 969, 970, 971, + 972, 973, 974, 975, 976, 977, 0, 0, 1464, 1465, + 1466, 1467, 1468, 1469, 0, 0, 0, 0, 1285, 0, + 0, 1098, 0, 1470, 978, 236, 237, 238, 239, 240, + 241, 242, 243, 0, 0, 0, 0, 0, 0, 0, + 1121, 0, 244, 1346, 0, 0, 1377, 0, 1435, 1377, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1290, 0, 0, 0, 0, 0, 1610, 979, 0, + 0, 0, 0, 0, 0, 0, 0, 1064, 1065, 1066, + 0, 1068, 0, 1070, 0, 1071, 1072, 0, 0, 1310, + 1311, 0, 0, 0, 0, 0, 950, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 980, 0, 0, + 981, 0, 982, 983, 984, 985, 986, 987, 988, 989, + 990, 991, 992, 0, 993, 994, 0, 0, 995, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, + 9, 10, 0, 11, 12, 13, 201, 68, 1475, 1476, + 1477, 1478, 1479, 0, 1480, 1481, 1482, 0, 0, 1308, + 0, 245, 246, 247, 248, 249, 250, 251, 252, 253, + 254, 255, 0, 256, 257, 258, 0, 0, 0, 1349, + 0, 0, 0, 1555, 0, 15, 69, 0, 1362, 202, + 0, 203, 204, 205, 74, 75, 0, 20, 76, 0, + 0, 206, 22, 0, 0, 78, 0, 1341, 0, 0, + 23, 24, 207, 476, 477, 478, 26, 0, 0, 208, + 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 209, 0, 0, 0, 0, + 0, 0, 0, 774, 44, 0, 45, 0, 46, 0, + 479, 0, 480, 47, 0, 210, 211, 50, 0, 775, + 51, 84, 0, 0, 0, 52, 0, 220, 53, 85, + 86, 87, 212, 776, 0, 89, 0, 213, 0, 221, + 222, 0, 0, 0, 0, 939, 777, 778, 0, 0, + 56, 0, 0, 57, 58, 59, 0, 0, 60, 0, + 61, 62, 779, 0, 63, 217, 218, 219, 0, 0, + 0, 0, 0, 0, 0, 0, 481, 224, 70, 225, + 71, 72, 73, 0, 226, 0, 227, 0, 0, 0, + 266, 0, 0, 780, 0, 0, 781, 0, 0, 782, + 0, 0, 0, 0, 0, 0, 0, 0, 80, 0, + 482, 0, 1398, 0, 0, 783, 1361, 0, 0, 220, + 0, 0, 0, 0, 267, 0, 0, 784, 0, 0, + 0, 221, 222, 0, 0, 0, 0, 0, 1407, 0, + 0, 785, 0, 0, 82, 83, 1412, 0, 0, 1414, + 7, 8, 9, 10, 0, 11, 12, 13, 489, 0, + 0, 88, 0, 0, 0, 0, 90, 0, 223, 224, + 0, 225, 0, 0, 0, 0, 226, 0, 227, 0, + 0, 0, 236, 237, 238, 239, 240, 241, 242, 243, + 0, 0, 0, 0, 0, 0, 0, 15, 342, 244, + 0, 202, 321, 203, 204, 205, 74, 0, 0, 20, + 343, 0, 1489, 206, 22, 0, 0, 78, 0, 0, + 0, 0, 23, 24, 207, 1497, 0, 1422, 26, 0, + 0, 208, 28, 29, 30, 31, 32, 33, 34, 35, + 36, 37, 38, 39, 40, 41, 42, 209, 0, 0, + 0, 0, 0, 0, 0, 0, 44, 0, 45, 0, + 46, 0, 0, 0, 0, 47, 0, 210, 211, 50, + 0, 0, 51, 84, 0, 0, 0, 52, 0, 0, + 53, 345, 346, 87, 212, 0, 0, 89, 0, 213, + 0, 0, 0, 340, 341, 0, 0, 0, 0, 0, + 0, 0, 56, 0, 306, 57, 58, 59, 0, 0, + 60, 0, 61, 62, 0, 0, 63, 0, 245, 246, + 247, 248, 249, 250, 251, 252, 253, 254, 255, 0, + 256, 257, 258, 0, 342, 0, 1590, 70, 0, 71, + 72, 73, 74, 0, 0, 105, 343, 106, 0, 77, + 0, 108, 0, 78, 0, 0, 0, 0, 109, 110, + 79, 0, 0, 0, 0, 0, 0, 80, 1459, 112, + 300, 114, 0, 0, 0, 0, 0, 0, 1552, 0, + 0, 301, 0, 81, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 344, 238, 239, 240, 241, + 242, 243, 0, 82, 83, 124, 0, 0, 0, 84, + 0, 244, 0, 0, 0, 129, 0, 345, 346, 87, + 88, 130, 0, 89, 0, 90, 133, 1584, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 136, 0, 137, + 1525, 1526, 1527, 1528, 0, 1530, 348, 1531, 1152, 1153, + 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 0, + 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, + 1173, 0, 0, 0, 0, 0, 0, 0, 1174, 1175, + 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, + 1186, 1187, 1188, 1189, 1190, 1191, 1192, 0, 0, 1193, + 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, + 1204, 1205, 1206, 1207, 0, 1208, 0, 1209, 1210, 1211, + 1212, 1213, 1214, 1215, 1216, 1217, 0, 1218, 1219, 1220, + 0, 246, 247, 248, 249, 250, 251, 252, 253, 254, + 255, 0, 256, 257, 258, 1221, 0, 0, 0, 0, + 0, 0, 1222, 1223, 1224, 0, 1225, 1226, 1227, 1228, + 1229, 1230, 1231, 1232, 1233, 1234, 1235, 1236, 1237, 1238, + 1239, 1240, 1241, 1242, 1243, 1244, 1245, 1246, 1247, 1248, + 1249, 1250, 1251, 1252, 1253, 1254, 1255, 1256, 1257, 0, + 0, 0, 1258, 1259, 1260, 1261, 1262, 1263, 1264, 1265, + 1266, 1267, 1268, 1269, 1270, 1271, 1272, 1273, 1274, 1275, + 1276, 1277, 1278, 1494, 1279, 1280, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 0, 1163, 1164, - 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1341, + 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 0, 0, 0, 0, 0, 0, 0, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 0, 0, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, - 1206, 1207, 1554, 1208, 1362, 1209, 1210, 1211, 1212, 1213, + 1206, 1207, 0, 1208, 0, 1209, 1210, 1211, 1212, 1213, 1214, 1215, 1216, 1217, 0, 1218, 1219, 1220, 0, 0, - 0, 236, 237, 238, 239, 240, 241, 242, 243, 0, - 0, 0, 0, 1221, 0, 0, 0, 940, 244, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1221, 0, 0, 0, 0, 0, 0, 1222, 1223, 1224, 0, 1225, 1226, 1227, 1228, 1229, 1230, 1231, 1232, 1233, 1234, 1235, 1236, 1237, 1238, 1239, 1240, 1241, 1242, 1243, 1244, 1245, 1246, 1247, 1248, 1249, 1250, 1251, 1252, 1253, 1254, 1255, 1256, 1257, 0, 0, 0, 1258, 1259, 1260, 1261, 1262, 1263, 1264, 1265, 1266, 1267, 1268, 1269, 1270, 1271, 1272, 1273, 1274, 1275, 1276, 1277, - 1278, 1493, 1279, 1280, 0, 0, 0, 0, 0, 0, - 0, 0, 105, 0, 106, 0, 0, 0, 108, 0, - 0, 0, 0, 0, 0, 109, 110, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 112, 300, 114, 0, - 0, 0, 0, 0, 7, 8, 9, 10, 301, 11, - 12, 13, 14, 0, 0, 0, 189, 245, 246, 247, - 248, 249, 250, 251, 252, 253, 254, 255, 1398, 256, - 257, 258, 124, 312, 0, 1349, 0, 0, 0, 0, - 0, 0, 129, 0, 0, 0, 0, 0, 130, 0, - 0, 15, 0, 133, 1407, 16, 0, 17, 18, 19, - 0, 0, 1412, 20, 136, 1414, 137, 21, 22, 0, - 0, 0, 0, 0, 0, 0, 23, 24, 25, 1421, + 1278, 0, 1279, 1280, 7, 8, 9, 10, 0, 11, + 12, 13, 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 236, 237, 238, 239, 240, + 241, 242, 243, 0, 0, 0, 0, 0, 0, 0, + 0, 15, 244, 0, 0, 16, 0, 17, 18, 19, + 0, 0, 0, 20, 0, 743, 744, 21, 22, 0, + 0, 0, 0, 0, 0, 0, 23, 24, 25, 0, 0, 0, 26, 0, 0, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 45, 0, 46, 0, 0, 0, 0, 47, - 0, 48, 49, 50, 0, 0, 51, 0, 1488, 0, - 0, 52, 0, 0, 53, 0, 0, 0, 54, 0, - 0, 1496, 0, 55, 0, 0, 0, 0, 0, 0, + 0, 48, 49, 50, 0, 0, 51, 0, 0, 0, + 0, 52, 0, 0, 53, 0, 0, 0, 54, 7, + 8, 9, 10, 55, 11, 12, 13, 14, 745, 0, + 0, 189, 0, 0, 0, 0, 56, 0, 0, 57, + 58, 59, 0, 0, 60, 0, 61, 62, 0, 586, + 63, 245, 246, 247, 248, 249, 250, 251, 252, 253, + 254, 255, 0, 256, 257, 258, 15, 0, 0, 0, + 16, 0, 17, 18, 19, 0, 0, 0, 20, 0, + 0, 0, 21, 22, 0, 0, 0, 0, 0, 0, + 0, 23, 24, 25, 0, 0, 0, 26, 0, 0, + 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, 39, 40, 41, 42, 43, 0, 0, 0, + 0, 0, 0, 0, 0, 44, 0, 45, 0, 46, + 0, 0, 0, 0, 47, 0, 48, 49, 50, 0, + 0, 51, 0, 0, 0, 0, 52, 0, 0, 53, + 0, 0, 0, 54, 7, 8, 9, 10, 55, 11, + 12, 13, 14, 0, 0, 0, 0, 0, 0, 0, + 0, 56, 0, 0, 57, 58, 59, 0, 0, 60, + 0, 190, 62, 0, 0, 63, 237, 238, 239, 240, + 241, 242, 243, 0, 0, 0, 0, 0, 0, 0, + 0, 15, 244, 0, 0, 16, 0, 17, 18, 19, + 0, 0, 0, 20, 0, 0, 0, 21, 22, 0, + 0, 0, 0, 0, 0, 0, 23, 24, 25, 0, + 0, 0, 26, 0, 0, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, + 42, 43, 0, 0, 0, 0, 0, 0, 0, 0, + 44, 0, 45, 0, 46, 0, 0, 0, 0, 47, + 0, 48, 49, 50, 0, 0, 51, 0, 0, 0, + 0, 52, 0, 0, 53, 0, 0, 0, 54, 7, + 8, 9, 10, 55, 11, 12, 13, 14, 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 57, - 58, 59, 0, 0, 60, 0, 190, 62, 0, 0, - 63, 0, 0, 0, 0, 0, 0, 0, 0, 1152, - 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, - 0, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, - 1172, 1173, 0, 0, 0, 0, 0, 0, 0, 1174, - 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, - 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 0, 1551, - 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, - 1203, 1204, 1205, 1206, 1207, 0, 1208, 0, 1209, 1210, - 1211, 1212, 1213, 1214, 1215, 1216, 1217, 0, 1218, 1219, - 1220, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1221, 0, 1583, 0, - 0, 0, 0, 1222, 1223, 1224, 0, 1225, 1226, 1227, - 1228, 1229, 1230, 1231, 1232, 1233, 1234, 1235, 1236, 1237, - 1238, 1239, 1240, 1241, 1242, 1243, 1244, 1245, 1246, 1247, - 1248, 1249, 1250, 1251, 1252, 1253, 1254, 1255, 1256, 1257, - 0, 0, 0, 1258, 1259, 1260, 1261, 1262, 1263, 1264, - 1265, 1266, 1267, 1268, 1269, 1270, 1271, 1272, 1273, 1274, - 1275, 1276, 1277, 1278, 0, 1279, 1280, 7, 8, 9, - 10, 0, 11, 12, 13, 201, 68, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 236, + 58, 59, 0, 0, 60, 0, 61, 62, 437, 0, + 63, 0, 246, 247, 248, 249, 250, 251, 252, 253, + 254, 255, 0, 256, 257, 258, 15, 442, 0, 0, + 16, 0, 17, 18, 19, 0, 0, 0, 20, 0, + 0, 0, 21, 22, 0, 0, 0, 0, 0, 0, + 0, 23, 24, 25, 0, 0, 0, 26, 0, 0, + 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, 39, 40, 41, 42, 43, 0, 0, 0, + 0, 0, 0, 0, 0, 44, 0, 45, 0, 46, + 0, 0, 0, 0, 47, 0, 48, 49, 50, 0, + 0, 51, 0, 0, 0, 0, 52, 0, 0, 53, + 0, 0, 0, 54, 7, 8, 9, 10, 55, 11, + 12, 13, 14, 0, 0, 0, 0, 0, 0, 0, + 0, 56, 0, 0, 57, 58, 59, 0, 0, 60, + 0, 61, 62, 0, 0, 63, 0, 0, 0, 236, 237, 238, 239, 240, 241, 242, 243, 0, 0, 0, - 0, 0, 0, 0, 15, 69, 244, 0, 202, 0, - 203, 204, 205, 74, 75, 0, 20, 76, 0, 0, - 206, 22, 0, 0, 78, 0, 0, 0, 0, 23, - 24, 207, 0, 0, 0, 26, 0, 0, 208, 28, - 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, - 39, 40, 41, 42, 209, 0, 0, 0, 0, 0, - 0, 0, 0, 44, 0, 45, 0, 46, 0, 0, - 0, 0, 47, 0, 210, 211, 50, 0, 0, 51, - 84, 0, 0, 0, 52, 0, 0, 53, 85, 86, - 87, 212, 0, 0, 89, 0, 213, 7, 8, 9, - 10, 0, 11, 12, 13, 491, 0, 0, 0, 56, - 0, 0, 57, 58, 59, 0, 0, 60, 0, 61, - 62, 0, 0, 63, 0, 245, 246, 247, 248, 249, - 250, 251, 252, 253, 254, 255, 0, 256, 257, 258, - 0, 0, 0, 1589, 15, 342, 0, 0, 202, 0, - 203, 204, 205, 74, 0, 0, 20, 343, 0, 0, - 206, 22, 0, 0, 78, 0, 0, 0, 0, 23, - 24, 207, 0, 0, 0, 26, 0, 0, 208, 28, - 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, - 39, 40, 41, 42, 209, 70, 0, 71, 72, 73, - 0, 0, 0, 44, 0, 45, 0, 46, 0, 0, - 0, 0, 47, 0, 210, 211, 50, 0, 0, 51, - 84, 0, 0, 0, 52, 80, 0, 53, 345, 346, - 87, 212, 0, 0, 89, 0, 213, 7, 8, 9, - 10, 267, 11, 12, 13, 14, 0, 0, 0, 56, - 0, 0, 57, 58, 59, 0, 0, 60, 0, 61, - 62, 82, 83, 63, 0, 0, 0, 0, 236, 237, - 238, 239, 240, 241, 242, 243, 0, 0, 88, 0, - 0, 0, 0, 90, 15, 244, 0, 0, 16, 0, - 17, 18, 19, 0, 0, 0, 20, 0, 744, 745, - 21, 22, 0, 0, 0, 0, 187, 0, 0, 23, - 24, 25, 0, 0, 0, 26, 0, 0, 27, 28, - 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, - 39, 40, 41, 42, 43, 0, 0, 0, 0, 0, - 0, 0, 0, 44, 0, 45, 0, 46, 0, 0, - 0, 0, 47, 0, 48, 49, 50, 0, 0, 51, - 0, 0, 0, 0, 52, 0, 0, 53, 0, 0, - 0, 54, 7, 8, 9, 10, 55, 11, 12, 13, - 14, 746, 0, 0, 0, 0, 0, 0, 0, 56, - 0, 0, 57, 58, 59, 0, 0, 60, 0, 61, - 62, 0, 588, 63, 245, 246, 247, 248, 249, 250, - 251, 252, 253, 254, 255, 0, 256, 257, 258, 15, - 0, 0, 0, 16, 0, 17, 18, 19, 0, 0, - 0, 20, 0, 0, 0, 21, 22, 0, 478, 479, - 480, 0, 0, 0, 23, 24, 25, 0, 0, 0, - 26, 0, 0, 27, 28, 29, 30, 31, 32, 33, - 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, - 0, 0, 0, 0, 0, 481, 0, 482, 44, 0, - 45, 0, 46, 0, 0, 0, 0, 47, 0, 48, - 49, 50, 220, 0, 51, 0, 0, 0, 0, 52, - 0, 0, 53, 0, 221, 222, 54, 7, 8, 9, - 10, 55, 11, 12, 13, 14, 0, 0, 0, 0, - 0, 0, 0, 0, 56, 0, 0, 57, 58, 59, - 0, 0, 60, 0, 61, 62, 437, 0, 63, 0, - 0, 483, 224, 0, 225, 0, 0, 0, 0, 226, - 0, 227, 0, 0, 15, 442, 0, 0, 16, 0, - 17, 18, 19, 0, 0, 0, 20, 0, 0, 0, - 21, 22, 0, 0, 0, 484, 0, 0, 0, 23, - 24, 25, 0, 0, 0, 26, 0, 0, 27, 28, - 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, - 39, 40, 41, 42, 43, 0, 0, 0, 0, 0, - 0, 0, 0, 44, 0, 45, 0, 46, 0, 0, - 0, 0, 47, 0, 48, 49, 50, 0, 0, 51, - 0, 0, 0, 0, 52, 0, 0, 53, 0, 0, - 0, 54, 7, 8, 9, 10, 55, 11, 12, 13, - 14, 0, 0, 0, 0, 0, 0, 0, 0, 56, - 0, 0, 57, 58, 59, 0, 0, 60, 0, 61, - 62, 0, 0, 63, 0, 0, 0, 236, 237, 238, - 239, 240, 241, 242, 243, 0, 0, 0, 0, 15, - 722, 0, 0, 16, 244, 17, 18, 19, 0, 0, - 0, 20, 0, 0, 0, 21, 22, 0, 0, 0, - 0, 0, 0, 0, 23, 24, 25, 0, 0, 0, - 26, 0, 0, 27, 28, 29, 30, 31, 32, 33, - 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, - 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, - 45, 0, 46, 0, 0, 0, 0, 47, 0, 48, - 49, 50, 0, 0, 51, 0, 0, 0, 0, 52, - 0, 0, 53, 0, 0, 0, 54, 7, 8, 9, - 10, 55, 11, 12, 13, 14, 0, 0, 0, 0, - 0, 0, 0, 0, 56, 0, 0, 57, 58, 59, - 0, 0, 60, 0, 61, 62, 0, 0, 63, 0, - 953, 0, 0, 245, 246, 247, 248, 249, 250, 251, - 252, 253, 254, 255, 15, 256, 257, 258, 16, 0, - 17, 18, 19, 0, 0, 0, 20, 0, 0, 0, - 21, 22, 0, 0, 0, 0, 0, 0, 0, 23, - 24, 25, 0, 0, 0, 26, 0, 0, 27, 28, - 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, - 39, 40, 41, 42, 43, 0, 0, 0, 0, 0, - 0, 0, 0, 44, 0, 45, 0, 46, 0, 0, - 0, 0, 47, 0, 48, 49, 50, 0, 0, 51, - 0, 0, 0, 0, 52, 0, 0, 53, 0, 0, - 0, 54, 7, 8, 9, 10, 55, 11, 12, 13, - 14, 948, 0, 0, 0, 0, 0, 0, 0, 56, - 0, 0, 57, 58, 59, 0, 0, 60, 0, 61, - 62, 0, 0, 63, 0, 0, 0, 236, 237, 238, - 239, 240, 241, 242, 243, 0, 0, 0, 0, 15, - 0, 0, 0, 16, 244, 17, 18, 19, 0, 0, - 0, 20, 0, 0, 0, 21, 22, 0, 0, 0, - 0, 0, 0, 0, 23, 24, 25, 0, 0, 0, - 26, 0, 0, 27, 28, 29, 30, 31, 32, 33, - 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, - 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, - 45, 0, 46, 0, 0, 0, 0, 47, 0, 48, - 49, 50, 0, 0, 51, 0, 0, 0, 0, 52, - 0, 0, 53, 0, 0, 0, 54, 7, 8, 9, - 10, 55, 11, 12, 13, 14, 0, 0, 0, 0, - 0, 0, 0, 0, 56, 0, 0, 57, 58, 59, - 0, 0, 60, 0, 61, 62, 1099, 0, 63, 1325, - 0, 0, 0, 245, 246, 247, 248, 249, 250, 251, - 252, 253, 254, 255, 15, 256, 257, 258, 16, 0, - 17, 18, 19, 0, 0, 0, 20, 0, 0, 0, - 21, 22, 0, 0, 0, 0, 0, 0, 0, 23, - 24, 25, 0, 0, 0, 26, 0, 0, 27, 28, - 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, - 39, 40, 41, 42, 43, 0, 0, 0, 0, 0, - 0, 0, 0, 44, 0, 45, 0, 46, 0, 0, - 0, 0, 47, 0, 48, 49, 50, 0, 0, 51, - 0, 0, 0, 0, 52, 0, 0, 53, 0, 0, - 0, 54, 7, 8, 9, 10, 55, 11, 12, 13, - 14, 1395, 0, 0, 0, 0, 0, 0, 0, 56, - 0, 0, 57, 58, 59, 0, 0, 60, 0, 61, - 62, 0, 0, 63, 0, 0, 0, 236, 237, 238, - 239, 240, 241, 242, 243, 0, 0, 0, 0, 15, - 0, 0, 0, 16, 244, 17, 18, 19, 0, 0, - 0, 20, 0, 0, 0, 21, 22, 0, 0, 0, - 0, 0, 0, 0, 23, 24, 25, 0, 0, 0, - 26, 0, 0, 27, 28, 29, 30, 31, 32, 33, - 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, - 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, - 45, 0, 46, 0, 0, 0, 0, 47, 0, 48, - 49, 50, 0, 0, 51, 0, 0, 0, 0, 52, - 0, 0, 53, 0, 0, 0, 54, 7, 8, 9, - 10, 55, 11, 12, 13, 14, 0, 0, 0, 0, - 0, 0, 0, 0, 56, 0, 0, 57, 58, 59, - 0, 0, 60, 0, 61, 62, 1552, 0, 63, 0, - 0, 1347, 0, 245, 246, 247, 248, 249, 250, 251, - 252, 253, 254, 255, 15, 256, 257, 258, 16, 0, - 17, 18, 19, 0, 0, 0, 20, 0, 0, 0, - 21, 22, 0, 0, 0, 0, 0, 0, 0, 23, - 24, 25, 0, 0, 0, 26, 0, 0, 27, 28, - 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, - 39, 40, 41, 42, 43, 0, 0, 0, 0, 0, - 0, 0, 0, 44, 0, 45, 0, 46, 217, 218, - 219, 0, 47, 0, 48, 49, 50, 0, 0, 51, - 0, 0, 0, 0, 52, 0, 0, 53, 0, 0, - 0, 54, 652, 653, 654, 10, 55, 11, 655, 656, - 67, 68, 0, 0, 657, 0, 0, 0, 0, 56, - 0, 0, 57, 58, 59, 0, 0, 60, 0, 61, - 62, 0, 220, 63, 236, 237, 238, 239, 240, 241, - 242, 243, 0, 0, 221, 222, 459, 0, 0, 658, - 69, 244, 0, 70, 0, 71, 72, 73, 74, 460, - 0, 659, 76, 0, 0, 77, 660, 0, 0, 78, - 0, 0, 0, 0, 661, 662, 79, 0, 0, 0, - 0, 223, 224, 80, 225, 0, 0, 0, 0, 226, - 0, 227, 0, 0, 0, 0, 0, 0, 0, 81, - 0, 0, 0, 0, 0, 0, 0, 0, 663, 0, - 664, 0, 665, 0, 0, 321, 461, 666, 0, 82, - 83, 667, 0, 0, 668, 84, 0, 0, 0, 669, - 0, 0, 670, 85, 86, 87, 88, 0, 0, 89, - 0, 90, 7, 8, 9, 10, 0, 11, 12, 13, - 14, 0, 0, 0, 671, 0, 0, 672, 673, 0, - 0, 0, 674, 0, 675, 0, 0, 0, 676, 0, - 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, - 255, 0, 256, 257, 258, 576, 0, 0, 0, 15, - 0, 0, 0, 16, 0, 17, 18, 19, 0, 0, - 0, 20, 0, 0, 0, 21, 22, 0, 0, 0, - 0, 0, 0, 0, 23, 24, 25, 0, 0, 0, - 26, 0, 0, 27, 28, 29, 30, 31, 32, 33, - 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, - 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, - 45, 0, 46, 217, 218, 219, 0, 47, 0, 48, - 49, 50, 0, 0, 51, 0, 0, 0, 0, 52, - 0, 0, 53, 0, 0, 0, 54, 652, 653, 654, - 10, 55, 11, 655, 656, 67, 68, 0, 0, 1076, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 60, 0, 61, 62, 0, 220, 63, 236, - 237, 238, 239, 240, 241, 242, 243, 0, 0, 221, - 222, 459, 0, 0, 658, 69, 244, 0, 70, 0, - 71, 72, 73, 74, 460, 0, 659, 76, 0, 0, - 77, 660, 0, 0, 78, 0, 0, 0, 0, 661, - 662, 79, 0, 0, 0, 0, 223, 224, 80, 225, - 0, 0, 0, 0, 226, 0, 227, 0, 0, 0, - 0, 0, 0, 0, 81, 0, 0, 0, 0, 0, - 0, 0, 0, 663, 0, 664, 0, 665, 0, 0, - 496, 461, 666, 0, 82, 83, 667, 0, 0, 668, - 84, 0, 0, 0, 669, 0, 0, 670, 85, 86, - 87, 88, 0, 0, 89, 0, 90, 7, 8, 9, - 10, 0, 11, 12, 13, 0, 0, 0, 0, 671, - 0, 0, 672, 673, 0, 0, 0, 674, 0, 675, - 0, 0, 0, 676, 0, 245, 246, 247, 248, 249, - 250, 251, 252, 253, 254, 255, 0, 256, 257, 258, - 592, 0, 0, 0, 1363, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1364, 0, 0, 0, - 0, 1365, 0, 0, 0, 0, 0, 0, 0, 23, - 24, 0, 0, 0, 0, 26, 0, 0, 0, 28, - 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, - 39, 40, 41, 42, 0, 0, 0, 7, 8, 9, - 10, 0, 11, 12, 13, 45, 0, 46, 0, 0, - 0, 0, 1366, 0, 0, 0, 1367, 0, 0, 1368, - 0, 0, 0, 0, 52, 0, 0, 0, 0, 0, - 0, 0, 0, 1461, 1462, 1463, 1464, 1465, 1466, 1467, - 1468, 0, 0, 0, 1363, 0, 0, 0, 0, 1369, - 1469, 0, 1370, 1371, 1372, 0, 1364, 1373, 0, 1374, - 62, 1365, 0, 1375, 0, 0, 0, 0, 0, 23, - 24, 0, 0, 0, 0, 26, 0, 0, 0, 28, - 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, - 39, 40, 41, 42, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 45, 0, 46, 0, 0, - 0, 0, 1366, 0, 0, 957, 1367, 0, 0, 1368, - 0, 0, 0, 0, 52, 958, 959, 960, 961, 962, - 963, 964, 965, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 966, 0, 967, 968, 969, 970, 971, 972, - 973, 974, 975, 976, 977, 978, 0, 1373, 0, 1374, - 62, 0, 0, 1375, 0, 0, 0, 0, 0, 1470, - 1471, 1472, 1473, 0, 979, 1474, 1475, 1476, 1477, 1478, - 0, 1479, 1480, 1481, 0, 0, 0, 340, 341, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1463, 1464, 1465, 1466, 1467, 1468, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1469, 0, 980, 240, - 241, 242, 243, 0, 0, 0, 0, 0, 342, 0, - 0, 70, 244, 71, 72, 73, 74, 0, 0, 0, - 343, 0, 0, 77, 0, 0, 0, 78, 0, 0, - 0, 0, 0, 0, 79, 0, 0, 981, 0, 0, - 982, 80, 983, 984, 985, 986, 987, 988, 989, 990, - 991, 992, 993, 0, 994, 995, 0, 81, 996, 340, - 341, 0, 0, 0, 0, 0, 0, 0, 0, 344, - 0, 0, 0, 0, 0, 0, 0, 82, 83, 0, - 0, 0, 0, 84, 70, 0, 71, 72, 73, 0, - 0, 345, 346, 87, 88, 0, 266, 89, 0, 90, - 342, 0, 0, 70, 347, 71, 72, 73, 74, 474, - 0, 0, 343, 0, 80, 77, 1471, 1472, 1473, 78, - 348, 1474, 1475, 1476, 1477, 1478, 79, 1479, 1480, 1481, - 267, 0, 0, 80, 0, 249, 250, 251, 252, 253, - 254, 255, 0, 256, 257, 258, 508, 509, 0, 81, - 82, 83, 70, 0, 71, 72, 73, 0, 0, 0, - 0, 344, 0, 0, 0, 0, 0, 88, 0, 82, - 83, 0, 90, 0, 0, 84, 0, 0, 0, 0, - 0, 0, 80, 345, 346, 87, 88, 342, 0, 89, - 70, 90, 71, 72, 73, 74, 0, 0, 267, 343, - 0, 0, 77, 0, 0, 0, 78, 0, 0, 0, - 0, 0, 348, 79, 0, 0, 0, 0, 82, 83, - 80, 236, 237, 238, 239, 240, 241, 242, 243, 0, - 0, 0, 0, 0, 0, 88, 81, 0, 244, 0, - 90, 0, 0, 217, 218, 219, 0, 0, 344, 0, - 0, 0, 0, 0, 0, 0, 82, 83, 0, 0, - 0, 0, 84, 0, 0, 0, 0, 0, 0, 0, - 345, 346, 87, 88, 0, 0, 89, 0, 90, 236, + 0, 15, 721, 0, 0, 16, 244, 17, 18, 19, + 0, 0, 0, 20, 0, 0, 0, 21, 22, 0, + 0, 0, 0, 0, 0, 0, 23, 24, 25, 0, + 0, 0, 26, 0, 0, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, + 42, 43, 0, 0, 0, 0, 0, 0, 0, 0, + 44, 0, 45, 0, 46, 0, 0, 0, 0, 47, + 0, 48, 49, 50, 0, 0, 51, 0, 0, 0, + 0, 52, 0, 0, 53, 0, 0, 0, 54, 7, + 8, 9, 10, 55, 11, 12, 13, 14, 0, 0, + 0, 0, 0, 0, 0, 0, 56, 0, 0, 57, + 58, 59, 0, 0, 60, 0, 61, 62, 0, 0, + 63, 0, 952, 0, 0, 245, 246, 247, 248, 249, + 250, 251, 252, 253, 254, 255, 15, 256, 257, 258, + 16, 0, 17, 18, 19, 0, 0, 0, 20, 0, + 0, 0, 21, 22, 0, 0, 0, 0, 0, 0, + 0, 23, 24, 25, 0, 0, 0, 26, 0, 0, + 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, 39, 40, 41, 42, 43, 0, 0, 0, + 0, 0, 0, 0, 0, 44, 0, 45, 0, 46, + 0, 0, 0, 0, 47, 0, 48, 49, 50, 0, + 0, 51, 0, 0, 0, 0, 52, 0, 0, 53, + 0, 0, 0, 54, 7, 8, 9, 10, 55, 11, + 12, 13, 14, 947, 0, 0, 0, 0, 0, 0, + 0, 56, 0, 0, 57, 58, 59, 0, 0, 60, + 0, 61, 62, 0, 0, 63, 0, 0, 0, 236, 237, 238, 239, 240, 241, 242, 243, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 244, 220, 0, 348, - 236, 237, 238, 239, 240, 241, 242, 243, 0, 221, - 222, 0, 0, 0, 0, 0, 0, 244, 236, 237, - 238, 239, 240, 241, 242, 243, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 244, 236, 237, 238, 239, - 240, 241, 242, 243, 0, 0, 223, 224, 0, 225, - 0, 0, 0, 244, 226, 0, 227, 245, 246, 247, - 248, 249, 250, 251, 252, 253, 254, 255, 0, 256, - 257, 258, 686, 236, 237, 238, 239, 240, 241, 242, - 243, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 244, 236, 237, 238, 239, 240, 241, 242, 243, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 244, 0, - 0, 0, 0, 0, 0, 245, 246, 247, 248, 249, - 250, 251, 252, 253, 254, 255, 0, 256, 257, 258, - 767, 0, 0, 0, 0, 0, 245, 246, 247, 248, - 249, 250, 251, 252, 253, 254, 255, 0, 256, 257, - 258, 923, 0, 0, 245, 246, 247, 248, 249, 250, - 251, 252, 253, 254, 255, 0, 256, 257, 258, 1026, - 0, 0, 245, 246, 247, 248, 249, 250, 251, 252, - 253, 254, 255, 0, 256, 257, 258, 1058, 864, 865, - 866, 867, 868, 869, 870, 871, 70, 0, 71, 72, - 73, 0, 0, 0, 0, 872, 0, 0, 0, 245, - 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, - 0, 256, 257, 258, 1345, 0, 80, 245, 246, 247, - 248, 249, 250, 251, 252, 253, 254, 255, -2, 256, - 257, 258, 267, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 238, 239, 240, 241, 242, 243, - 0, 0, 82, 83, 0, 0, 0, 0, 0, 244, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 88, - 0, 0, 0, 0, 90, 105, 0, 106, 0, 0, - 107, 108, 0, 0, 0, 0, 0, 0, 109, 110, - 238, 239, 240, 241, 242, 243, 0, 111, 0, 112, - 113, 114, 115, 0, 0, 244, 116, 0, 0, 0, - 0, 117, 0, 0, 873, 874, 875, 876, 877, 878, - 879, 880, 881, 882, 883, 0, 884, 885, 886, 118, - 119, 120, 121, 122, 123, 124, 125, 0, 0, 0, - 0, 0, 126, 127, 128, 129, 0, 0, 0, 0, - 0, 130, 131, 67, 68, 132, 133, 457, 0, 458, - 134, 0, 0, 0, 0, 0, 135, 136, 0, 137, - 0, 0, 0, 0, 0, 0, 0, 138, 0, 246, - 247, 248, 249, 250, 251, 252, 253, 254, 255, 459, - 256, 257, 258, 69, 0, 0, 70, 0, 71, 72, - 73, 74, 460, 0, 0, 76, 0, 0, 77, 0, - 0, 0, 78, 0, 0, 0, 0, 0, 0, 79, - 238, 239, 240, 241, 242, 243, 80, 248, 249, 250, - 251, 252, 253, 254, 255, 244, 256, 257, 258, 217, - 218, 219, 81, 1463, 1464, 1465, 1466, 1467, 1468, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1469, 461, - 0, 0, 82, 83, 0, 0, 0, 0, 84, 0, - 1463, 1464, 1465, 1466, 1467, 1468, 85, 86, 87, 88, - 0, 0, 89, 0, 90, 1469, 0, 0, 0, 0, - 0, 0, 0, 220, 0, 0, 0, 462, 0, 0, - 0, 0, 463, 0, 0, 221, 222, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 336, 0, 0, - 0, 0, 223, 224, 0, 225, 0, 0, 0, 0, - 226, 0, 227, 0, 306, 0, 0, 0, 249, 250, - 251, 252, 253, 254, 255, 0, 256, 257, 258, 0, - 0, 0, 0, 0, 0, 217, 218, 219, 0, 1472, - 1473, 306, 0, 1474, 1475, 1476, 1477, 1478, 0, 1479, - 1480, 1481, 0, 0, 0, 105, 0, 106, 0, 0, - 0, 108, 0, 0, 0, 0, 0, 1473, 109, 110, - 1474, 1475, 1476, 1477, 1478, 0, 1479, 1480, 1481, 112, - 113, 114, 105, 0, 106, 0, 0, 0, 108, 220, - 0, 301, 0, 0, 0, 109, 110, 0, 0, 0, - 0, 221, 222, 0, 0, 0, 112, 300, 114, 0, - 0, 0, 0, 0, 0, 124, 0, 0, 301, 0, - 0, 699, 700, 701, 0, 129, 0, 0, 0, 0, - 0, 130, 0, 0, 0, 132, 133, 0, 223, 1326, - 1327, 1328, 124, 0, 0, 0, 226, 136, 227, 137, - 0, 0, 129, 699, 700, 701, 0, 0, 130, 1329, - 0, 0, 0, 133, 1330, 70, 0, 71, 72, 73, - 702, 703, 0, 0, 136, 0, 137, 77, 0, 0, - 0, 0, 0, 217, 218, 219, 0, 0, 79, 0, - 0, 0, 0, 0, 0, 80, 0, 70, 0, 71, - 72, 73, 0, 0, 0, 0, 0, 0, 0, 77, + 0, 15, 0, 0, 0, 16, 244, 17, 18, 19, + 0, 0, 0, 20, 0, 0, 0, 21, 22, 0, + 0, 0, 0, 0, 0, 0, 23, 24, 25, 0, + 0, 0, 26, 0, 0, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, + 42, 43, 0, 0, 0, 0, 0, 0, 0, 0, + 44, 0, 45, 0, 46, 0, 0, 0, 0, 47, + 0, 48, 49, 50, 0, 0, 51, 0, 0, 0, + 0, 52, 0, 0, 53, 0, 0, 0, 54, 7, + 8, 9, 10, 55, 11, 12, 13, 14, 0, 0, + 0, 0, 0, 0, 0, 0, 56, 0, 0, 57, + 58, 59, 0, 0, 60, 0, 61, 62, 1099, 0, + 63, 0, 0, 1347, 0, 245, 246, 247, 248, 249, + 250, 251, 252, 253, 254, 255, 15, 256, 257, 258, + 16, 0, 17, 18, 19, 0, 0, 0, 20, 0, + 0, 0, 21, 22, 0, 0, 0, 0, 0, 0, + 0, 23, 24, 25, 0, 0, 0, 26, 0, 0, + 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, 39, 40, 41, 42, 43, 0, 0, 0, + 0, 0, 0, 0, 0, 44, 0, 45, 0, 46, + 0, 0, 0, 0, 47, 0, 48, 49, 50, 0, + 0, 51, 0, 0, 0, 0, 52, 0, 0, 53, + 0, 0, 0, 54, 7, 8, 9, 10, 55, 11, + 12, 13, 14, 1395, 0, 0, 0, 0, 0, 0, + 0, 56, 0, 0, 57, 58, 59, 0, 0, 60, + 0, 61, 62, 0, 0, 63, 0, 0, 0, 236, + 237, 238, 239, 240, 241, 242, 243, 0, 0, 0, + 0, 15, 0, 0, 0, 16, 244, 17, 18, 19, + 0, 0, 0, 20, 0, 0, 0, 21, 22, 0, + 0, 0, 0, 0, 0, 0, 23, 24, 25, 0, + 0, 0, 26, 0, 0, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, + 42, 43, 0, 0, 0, 0, 0, 0, 0, 0, + 44, 0, 45, 0, 46, 0, 0, 0, 0, 47, + 0, 48, 49, 50, 0, 0, 51, 0, 0, 0, + 0, 52, 0, 0, 53, 0, 0, 0, 54, 7, + 8, 9, 10, 55, 11, 12, 13, 14, 0, 0, + 0, 0, 0, 0, 0, 0, 56, 0, 0, 57, + 58, 59, 0, 0, 60, 0, 61, 62, 1553, 0, + 63, 1415, 0, 0, 0, 245, 246, 247, 248, 249, + 250, 251, 252, 253, 254, 255, 15, 256, 257, 258, + 16, 0, 17, 18, 19, 0, 0, 0, 20, 0, + 0, 0, 21, 22, 0, 0, 0, 0, 0, 0, + 0, 23, 24, 25, 0, 0, 0, 26, 0, 0, + 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, 39, 40, 41, 42, 43, 0, 0, 0, + 0, 0, 0, 0, 0, 44, 0, 45, 0, 46, + 217, 218, 219, 0, 47, 0, 48, 49, 50, 0, + 0, 51, 0, 0, 0, 0, 52, 0, 0, 53, + 0, 0, 0, 54, 651, 652, 653, 10, 55, 11, + 654, 655, 67, 68, 0, 0, 656, 0, 0, 0, + 0, 56, 0, 0, 57, 58, 59, 0, 0, 60, + 0, 61, 62, 0, 220, 63, 236, 237, 238, 239, + 240, 241, 242, 243, 0, 0, 221, 222, 459, 0, + 0, 657, 69, 244, 0, 70, 0, 71, 72, 73, + 74, 460, 0, 658, 76, 0, 0, 77, 659, 0, + 0, 78, 0, 0, 0, 0, 660, 661, 79, 0, + 0, 0, 0, 223, 224, 80, 225, 0, 0, 0, + 0, 226, 0, 227, 0, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 0, 0, 0, 0, 0, - 79, 0, 67, 68, 0, 0, 457, 80, 0, 0, - 0, 82, 83, 0, 0, 0, 0, 220, 0, 0, - 0, 0, 0, 81, 0, 704, 0, 0, 88, 221, - 222, 89, 0, 90, 0, 0, 0, 0, 459, 0, - 0, 0, 69, 82, 83, 70, 0, 71, 72, 73, - 74, 460, 0, 0, 76, 0, 0, 77, 0, 0, - 88, 78, 0, 89, 0, 90, 223, 224, 79, 225, - 0, 0, 0, 0, 226, 80, 227, 0, 0, 0, - 0, 0, 0, 0, 217, 218, 219, 1329, 0, 0, - 0, 81, 1415, 0, 67, 68, 0, 0, 811, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 461, 0, - 0, 82, 83, 0, 0, 0, 0, 84, 0, 0, - 0, 0, 0, 67, 68, 85, 86, 87, 88, 0, - 459, 89, 0, 90, 69, 0, 0, 70, 220, 71, - 72, 73, 74, 460, 0, 0, 76, 0, 0, 77, - 221, 222, 0, 78, 0, 0, 0, 0, 0, 459, - 79, 0, 0, 69, 0, 0, 70, 80, 71, 72, - 73, 74, 460, 0, 0, 76, 0, 0, 77, 0, - 0, 0, 78, 81, 0, 0, 0, 223, 224, 79, - 225, 0, 0, 0, 0, 226, 80, 227, 0, 0, - 461, 0, 0, 82, 83, 0, 0, 0, 1329, 84, - 67, 68, 81, 1417, 0, 0, 0, 85, 86, 87, - 88, 0, 0, 89, 0, 90, 0, 0, 0, 461, - 0, 0, 82, 83, 67, 68, 0, 0, 84, 0, - 0, 0, 217, 218, 219, 0, 85, 86, 87, 88, - 69, 0, 89, 70, 90, 71, 72, 73, 74, 75, - 0, 0, 76, 0, 70, 77, 71, 72, 73, 78, - 0, 0, 0, 0, 69, 0, 79, 70, 0, 71, - 72, 73, 74, 80, 0, 0, 76, 0, 0, 77, - 0, 0, 0, 78, 80, 0, 220, 0, 0, 81, - 79, 0, 0, 0, 0, 0, 0, 80, 221, 222, - 267, 0, 0, 0, 0, 0, 0, 0, 0, 82, - 83, 67, 68, 81, 0, 84, 0, 0, 0, 0, - 82, 83, 0, 85, 86, 87, 88, 0, 0, 89, - 611, 90, 0, 82, 83, 223, 224, 88, 225, 84, - 67, 0, 90, 226, 0, 227, 0, 85, 86, 87, - 88, 69, 0, 89, 70, 90, 71, 72, 73, 74, - 295, 0, 0, 76, 0, 188, 77, 0, 0, 0, + 662, 0, 663, 0, 664, 0, 0, 494, 461, 665, + 0, 82, 83, 666, 0, 0, 667, 84, 0, 0, + 0, 668, 0, 0, 669, 85, 86, 87, 88, 0, + 0, 89, 0, 90, 7, 8, 9, 10, 0, 11, + 12, 13, 14, 0, 0, 0, 670, 0, 0, 671, + 672, 0, 0, 0, 673, 0, 674, 0, 696, 0, + 675, 0, 245, 246, 247, 248, 249, 250, 251, 252, + 253, 254, 255, 0, 256, 257, 258, 697, 0, 0, + 0, 15, 0, 0, 0, 16, 0, 17, 18, 19, + 0, 0, 0, 20, 0, 0, 0, 21, 22, 0, + 0, 0, 0, 0, 0, 0, 23, 24, 25, 0, + 0, 0, 26, 0, 0, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, + 42, 43, 0, 0, 0, 0, 0, 0, 0, 0, + 44, 0, 45, 0, 46, 217, 218, 219, 0, 47, + 0, 48, 49, 50, 0, 0, 51, 0, 0, 0, + 0, 52, 0, 0, 53, 0, 0, 0, 54, 651, + 652, 653, 10, 55, 11, 654, 655, 67, 68, 0, + 0, 1076, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 60, 0, 61, 62, 0, 220, + 63, 236, 237, 238, 239, 240, 241, 242, 243, 0, + 0, 221, 222, 459, 0, 0, 657, 69, 244, 0, + 70, 0, 71, 72, 73, 74, 460, 0, 658, 76, + 0, 0, 77, 659, 0, 0, 78, 0, 0, 0, + 0, 660, 661, 79, 0, 0, 0, 0, 223, 224, + 80, 225, 0, 0, 0, 0, 226, 0, 227, 0, + 217, 218, 219, 0, 0, 0, 81, 0, 0, 1329, + 0, 0, 0, 0, 1416, 662, 0, 663, 0, 664, + 0, 0, 0, 461, 665, 0, 82, 83, 666, 0, + 0, 667, 84, 0, 0, 0, 668, 0, 0, 669, + 85, 86, 87, 88, 0, 0, 89, 0, 90, 0, + 7, 8, 9, 10, 220, 11, 12, 13, 0, 0, + 0, 670, 1450, 0, 671, 672, 221, 222, 0, 673, + 0, 674, 0, 0, 0, 675, 0, 245, 246, 247, + 248, 249, 250, 251, 252, 253, 254, 255, 0, 256, + 257, 258, 574, 0, 0, 0, 0, 1363, 0, 0, + 0, 0, 0, 223, 1326, 1327, 1328, 0, 0, 1364, + 0, 226, 0, 227, 1365, 0, 0, 0, 0, 0, + 0, 0, 23, 24, 1329, 0, 0, 0, 26, 1330, + 0, 0, 28, 29, 30, 31, 32, 33, 34, 35, + 36, 37, 38, 39, 40, 41, 42, 0, 0, 0, + 7, 8, 9, 10, 0, 11, 12, 13, 45, 0, + 46, 0, 0, 0, 0, 1366, 0, 0, 0, 1367, + 0, 0, 1368, 0, 0, 0, 0, 52, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1363, 0, 0, + 0, 0, 1369, 0, 0, 1370, 1371, 1372, 0, 1364, + 1373, 0, 1451, 62, 1365, 0, 1375, 0, 0, 0, + 0, 0, 23, 24, 0, 0, 0, 0, 26, 0, + 0, 0, 28, 29, 30, 31, 32, 33, 34, 35, + 36, 37, 38, 39, 40, 41, 42, 0, 0, 0, + 7, 8, 9, 10, 0, 11, 12, 13, 45, 0, + 46, 0, 0, 0, 0, 1366, 0, 0, 0, 1367, + 0, 0, 1368, 0, 0, 0, 0, 52, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1363, 0, 0, + 0, 0, 1369, 0, 0, 1370, 1371, 1372, 0, 1364, + 1373, 0, 1374, 62, 1365, 0, 1375, 0, 0, 0, + 0, 0, 23, 24, 0, 0, 0, 0, 26, 0, + 0, 0, 28, 29, 30, 31, 32, 33, 34, 35, + 36, 37, 38, 39, 40, 41, 42, 506, 507, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, + 46, 0, 0, 0, 0, 1366, 0, 0, 0, 1367, + 0, 0, 1368, 0, 0, 0, 0, 52, 0, 0, + 236, 237, 238, 239, 240, 241, 242, 243, 342, 0, + 0, 70, 0, 71, 72, 73, 74, 244, 0, 0, + 343, 0, 0, 77, 0, 0, 0, 78, 0, 0, + 1373, 0, 1374, 62, 79, 0, 1375, 0, 0, 0, + 0, 80, 236, 237, 238, 239, 240, 241, 242, 243, + 0, 0, 0, 0, 0, 0, 0, 81, 0, 244, + 0, 217, 218, 219, 0, 0, 0, 0, 0, 344, + 0, 0, 0, 0, 0, 0, 0, 82, 83, 0, + 0, 0, 0, 84, 0, 0, 0, 0, 0, 0, + 0, 345, 346, 87, 88, 0, 0, 89, 0, 90, + 236, 237, 238, 239, 240, 241, 242, 243, 0, 0, + 0, 0, 0, 0, 0, 220, 0, 244, 0, 0, + 348, 0, 0, 0, 0, 0, 0, 221, 222, 0, + 0, 0, 0, 0, 0, 0, 245, 246, 247, 248, + 249, 250, 251, 252, 253, 254, 255, 0, 256, 257, + 258, 590, 236, 237, 238, 239, 240, 241, 242, 243, + 0, 0, 0, 0, 223, 224, 0, 225, 0, 244, + 0, 0, 226, 0, 227, 0, 0, 0, 245, 246, + 247, 248, 249, 250, 251, 252, 253, 254, 255, 295, + 256, 257, 258, 685, 236, 237, 238, 239, 240, 241, + 242, 243, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 244, 236, 237, 238, 239, 240, 241, 242, 243, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 244, + 0, 0, 0, 0, 0, 0, 245, 246, 247, 248, + 249, 250, 251, 252, 253, 254, 255, 0, 256, 257, + 258, 766, 236, 237, 238, 239, 240, 241, 242, 243, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 244, + 236, 237, 238, 239, 240, 241, 242, 243, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 244, 245, 246, + 247, 248, 249, 250, 251, 252, 253, 254, 255, 0, + 256, 257, 258, 922, 863, 864, 865, 866, 867, 868, + 869, 870, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 871, 0, 0, 0, 0, 0, 0, 0, 0, + 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, + 255, 0, 256, 257, 258, 1025, 0, 0, 245, 246, + 247, 248, 249, 250, 251, 252, 253, 254, 255, 0, + 256, 257, 258, 1058, 0, 1463, 1464, 1465, 1466, 1467, + 1468, 1469, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1470, 0, 0, 0, 0, 0, 0, 245, 246, + 247, 248, 249, 250, 251, 252, 253, 254, 255, 0, + 256, 257, 258, 1345, 0, 0, 245, 246, 247, 248, + 249, 250, 251, 252, 253, 254, 255, -2, 256, 257, + 258, 238, 239, 240, 241, 242, 243, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 244, 0, 0, 0, + 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, + 882, 0, 883, 884, 885, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 105, 0, 106, 0, 0, 107, + 108, 0, 0, 0, 0, 0, 0, 109, 110, 1464, + 1465, 1466, 1467, 1468, 1469, 0, 111, 0, 112, 113, + 114, 115, 0, 0, 1470, 116, 0, 0, 0, 0, + 117, 1472, 1473, 1474, 0, 0, 1475, 1476, 1477, 1478, + 1479, 0, 1480, 1481, 1482, 0, 0, 0, 118, 119, + 120, 121, 122, 123, 124, 125, 217, 218, 219, 0, + 0, 126, 127, 128, 129, 0, 0, 0, 0, 0, + 130, 131, 67, 68, 132, 133, 457, 0, 458, 134, + 0, 0, 0, 0, 0, 135, 136, 0, 137, 249, + 250, 251, 252, 253, 254, 255, 138, 256, 257, 258, + 0, 0, 0, 0, 0, 0, 0, 0, 459, 0, + 220, 0, 69, 0, 0, 70, 0, 71, 72, 73, + 74, 460, 221, 222, 76, 306, 0, 77, 0, 0, + 0, 78, 0, 0, 0, 0, 0, 0, 79, 0, + 0, 0, 0, 0, 0, 80, 1474, 0, 0, 1475, + 1476, 1477, 1478, 1479, 336, 1480, 1481, 1482, 0, 223, + 224, 81, 225, 698, 699, 700, 105, 226, 106, 227, + 0, 0, 108, 217, 218, 219, 0, 0, 461, 109, + 110, 82, 83, 0, 0, 0, 0, 84, 0, 0, + 112, 113, 114, 0, 0, 85, 86, 87, 88, 0, + 0, 89, 301, 90, 0, 0, 0, 70, 0, 71, + 72, 73, 701, 702, 0, 0, 462, 0, 0, 77, + 0, 463, 698, 699, 700, 0, 124, 220, 0, 0, + 79, 0, 0, 0, 0, 0, 129, 80, 0, 221, + 222, 0, 130, 0, 0, 0, 132, 133, 0, 0, + 0, 0, 70, 81, 71, 72, 73, 0, 136, 0, + 137, 67, 68, 0, 266, 457, 70, 0, 71, 72, + 73, 0, 0, 82, 83, 0, 223, 224, 77, 225, + 0, 0, 80, 0, 226, 0, 227, 703, 0, 79, + 88, 0, 0, 89, 0, 90, 80, 459, 267, 0, + 0, 69, 0, 0, 70, 0, 71, 72, 73, 74, + 460, 0, 81, 76, 0, 0, 77, 0, 82, 83, 78, 0, 0, 0, 0, 0, 0, 79, 0, 0, - 69, 0, 0, 70, 80, 71, 72, 73, 74, 519, - 0, 0, 76, 0, 0, 77, 0, 0, 0, 78, - 81, 0, 0, 0, 0, 0, 79, 0, 0, 0, - 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, - 82, 83, 0, 0, 0, 0, 84, 177, 0, 81, - 0, 0, 0, 0, 85, 86, 87, 88, 0, 0, - 89, 0, 90, 0, 0, 0, 0, 0, 0, 82, - 83, 177, 0, 0, 0, 84, 0, 0, 0, 0, - 0, 0, 0, 85, 86, 87, 88, 178, 0, 89, - 70, 90, 71, 72, 73, 74, 1019, 0, 0, 179, + 0, 0, 82, 83, 80, 88, 0, 0, 0, 0, + 90, 0, 70, 0, 71, 72, 73, 0, 0, 88, + 81, 0, 89, 0, 90, 67, 68, 0, 0, 810, + 0, 0, 0, 176, 0, 0, 0, 461, 0, 0, + 82, 83, 80, 0, 0, 0, 84, 0, 0, 0, + 0, 0, 0, 0, 85, 86, 87, 88, 267, 0, + 89, 459, 90, 67, 68, 69, 0, 0, 70, 0, + 71, 72, 73, 74, 460, 0, 0, 76, 82, 83, + 77, 0, 0, 0, 78, 0, 0, 0, 0, 0, + 0, 79, 0, 0, 0, 88, 0, 0, 80, 459, + 90, 0, 0, 69, 0, 0, 70, 0, 71, 72, + 73, 74, 460, 0, 81, 76, 0, 0, 77, 0, + 0, 0, 78, 187, 0, 0, 0, 0, 0, 79, + 0, 461, 0, 0, 82, 83, 80, 0, 0, 0, + 84, 0, 0, 0, 0, 0, 0, 0, 85, 86, + 87, 88, 81, 0, 89, 0, 90, 67, 68, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 461, + 0, 0, 82, 83, 0, 0, 0, 0, 84, 0, + 0, 67, 68, 0, 0, 0, 85, 86, 87, 88, + 0, 0, 89, 0, 90, 0, 0, 69, 0, 0, + 70, 0, 71, 72, 73, 74, 75, 0, 0, 76, 0, 0, 77, 0, 0, 0, 78, 0, 0, 0, - 0, 178, 0, 79, 70, 0, 71, 72, 73, 74, - 80, 0, 0, 179, 0, 0, 77, 0, 0, 0, + 0, 69, 0, 79, 70, 0, 71, 72, 73, 74, + 80, 0, 0, 76, 0, 0, 77, 0, 0, 0, 78, 0, 0, 0, 0, 0, 81, 79, 0, 0, 0, 0, 0, 0, 80, 217, 218, 219, 0, 0, - 0, 0, 0, 0, 0, 0, 82, 83, 67, 0, + 0, 0, 0, 0, 0, 0, 82, 83, 67, 68, 81, 0, 84, 0, 0, 0, 0, 0, 0, 0, - 180, 181, 87, 88, 0, 0, 89, 0, 90, 0, - 82, 83, 0, 0, 0, 0, 84, 217, 218, 219, - 0, 0, 0, 0, 180, 181, 87, 88, 69, 220, + 85, 86, 87, 88, 0, 0, 89, 609, 90, 0, + 82, 83, 0, 0, 0, 0, 84, 67, 0, 0, + 0, 0, 0, 0, 85, 86, 87, 88, 69, 220, 89, 70, 90, 71, 72, 73, 74, 0, 0, 0, 76, 221, 222, 77, 0, 0, 0, 78, 0, 0, - 0, 0, 0, 0, 79, 0, 0, 0, 0, 0, - 0, 80, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 220, 0, 0, 0, 0, 0, 81, 223, 224, - 0, 225, 0, 221, 222, 0, 226, 0, 227, 0, - 0, 0, 70, 0, 71, 72, 73, 82, 83, 1329, - 0, 0, 0, 84, 1419, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 79, 0, 0, 69, 0, 0, + 70, 80, 71, 72, 73, 74, 517, 0, 0, 76, + 0, 0, 77, 0, 0, 0, 78, 81, 223, 224, + 0, 225, 0, 79, 0, 0, 226, 0, 227, 0, + 80, 0, 0, 0, 0, 0, 0, 82, 83, 1329, + 0, 0, 0, 84, 177, 0, 81, 0, 0, 0, 0, 85, 86, 87, 88, 0, 0, 89, 0, 90, - 223, 224, 80, 225, 0, 0, 0, 0, 226, 105, - 227, 106, 0, 0, 107, 108, 0, 0, 267, 0, - 0, 1329, 109, 110, 0, 0, 0, 0, 0, 0, - 0, 111, 0, 112, 113, 114, 115, 0, 82, 83, + 0, 0, 0, 0, 0, 0, 82, 83, 177, 0, + 0, 0, 84, 0, 0, 0, 0, 0, 0, 0, + 85, 86, 87, 88, 178, 0, 89, 70, 90, 71, + 72, 73, 74, 1018, 0, 0, 179, 0, 0, 77, + 0, 0, 0, 78, 0, 0, 0, 0, 178, 0, + 79, 70, 0, 71, 72, 73, 74, 80, 0, 0, + 179, 0, 0, 77, 0, 0, 0, 78, 0, 0, + 0, 0, 0, 81, 79, 0, 0, 0, 0, 0, + 0, 80, 217, 218, 219, 0, 0, 0, 0, 0, + 0, 0, 0, 82, 83, 67, 0, 81, 0, 84, + 0, 0, 0, 0, 0, 0, 0, 180, 181, 87, + 88, 0, 0, 89, 0, 90, 0, 82, 83, 0, + 0, 0, 0, 84, 217, 218, 219, 0, 0, 0, + 0, 180, 181, 87, 88, 69, 220, 89, 70, 90, + 71, 72, 73, 74, 0, 0, 0, 76, 221, 222, + 77, 0, 0, 0, 78, 0, 0, 0, 0, 0, + 0, 79, 0, 0, 0, 0, 0, 0, 80, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 220, 0, + 0, 0, 0, 0, 81, 223, 224, 0, 225, 0, + 221, 222, 0, 226, 0, 227, 0, 0, 0, 70, + 0, 71, 72, 73, 82, 83, 1329, 0, 0, 0, + 84, 1418, 0, 0, 0, 0, 0, 0, 85, 86, + 87, 88, 0, 0, 89, 0, 90, 223, 224, 80, + 225, 0, 0, 0, 0, 226, 105, 227, 106, 0, + 0, 107, 108, 0, 0, 267, 0, 0, 1329, 109, + 110, 0, 0, 1420, 0, 0, 0, 0, 111, 0, + 112, 113, 114, 115, 0, 82, 83, 116, 0, 0, + 0, 0, 117, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 88, 0, 0, 0, 0, 90, 0, 0, + 118, 119, 120, 121, 122, 123, 124, 125, 0, 0, + 0, 0, 0, 126, 127, 128, 129, 0, 0, 105, + 188, 106, 130, 131, 107, 108, 132, 133, 0, 0, + 0, 134, 109, 110, 0, 0, 0, 135, 136, 0, + 137, 111, 0, 112, 113, 114, 115, 0, 138, 0, 116, 0, 0, 0, 0, 117, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 88, 0, 0, 0, 0, - 90, 0, 0, 118, 119, 120, 121, 122, 123, 124, + 0, 0, 0, 0, 0, 0, 0, 694, 0, 0, + 0, 0, 0, 118, 119, 120, 121, 122, 123, 124, 125, 0, 0, 0, 0, 0, 126, 127, 128, 129, - 0, 0, 105, 194, 106, 130, 131, 107, 108, 132, + 0, 0, 105, 0, 106, 130, 131, 107, 108, 132, 133, 0, 0, 0, 134, 109, 110, 0, 0, 0, 135, 136, 0, 137, 111, 0, 112, 113, 114, 115, 0, 138, 0, 116, 0, 0, 0, 0, 117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 695, 0, 0, 0, 0, 0, 118, 119, 120, 121, + 888, 0, 0, 0, 0, 0, 118, 119, 120, 121, 122, 123, 124, 125, 0, 0, 0, 0, 0, 126, 127, 128, 129, 0, 0, 105, 0, 106, 130, 131, 107, 108, 132, 133, 0, 0, 0, 134, 109, 110, 0, 0, 0, 135, 136, 0, 137, 111, 0, 112, 113, 114, 115, 0, 138, 0, 116, 0, 0, 0, 0, 117, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 889, 0, 0, 0, 0, 0, 118, + 0, 0, 0, 934, 0, 0, 0, 0, 0, 118, 119, 120, 121, 122, 123, 124, 125, 0, 0, 0, 0, 0, 126, 127, 128, 129, 0, 0, 105, 0, 106, 130, 131, 107, 108, 132, 133, 0, 0, 0, 134, 109, 110, 0, 0, 0, 135, 136, 0, 137, 111, 0, 112, 113, 114, 115, 0, 138, 0, 116, 0, 0, 0, 0, 117, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 935, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1059, 0, 0, 0, 0, 0, 118, 119, 120, 121, 122, 123, 124, 125, 0, 0, 0, 0, 0, 126, 127, 128, 129, 0, 0, 105, 0, 106, 130, 131, 107, 108, 132, 133, 0, 0, 0, 134, 109, 110, 0, 0, 0, 135, 136, 0, 137, 111, 0, 112, 113, 114, 115, 0, 138, 0, 116, 0, 0, 0, 0, 117, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1059, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1112, 0, 0, 0, 0, 0, 118, 119, 120, 121, 122, 123, 124, 125, 0, 0, 0, 0, 0, 126, 127, 128, 129, 0, 0, 105, 0, 106, 130, 131, 107, 108, 132, 133, 0, 0, 0, 134, 109, 110, 0, 0, 0, 135, 136, 0, 137, 111, 0, 112, 113, 114, 115, 0, 138, 0, 116, 0, 0, 0, 0, - 117, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1112, 0, 0, 0, 0, 0, 118, 119, + 117, 0, 0, 217, 218, 219, 0, 0, 902, 217, + 218, 219, 1350, 70, 0, 71, 72, 73, 118, 119, 120, 121, 122, 123, 124, 125, 0, 0, 0, 0, - 0, 126, 127, 128, 129, 0, 0, 105, 0, 106, - 130, 131, 107, 108, 132, 133, 0, 0, 0, 134, - 109, 110, 0, 0, 0, 135, 136, 0, 137, 111, - 0, 112, 113, 114, 115, 0, 138, 0, 116, 0, - 0, 0, 0, 117, 0, 0, 217, 218, 219, 0, - 0, 903, 217, 218, 219, 1350, 0, 0, 0, 0, - 0, 118, 119, 120, 121, 122, 123, 124, 125, 0, - 0, 0, 0, 0, 126, 127, 128, 129, 0, 0, - 0, 0, 0, 130, 131, 0, 0, 132, 133, 481, - 0, 482, 134, 0, 0, 0, 0, 0, 135, 136, - 220, 137, 0, 0, 0, 0, 220, 0, 105, 138, - 106, 0, 221, 222, 108, 0, 0, 0, 221, 222, - 0, 109, 110, 0, 0, 0, 0, 0, 1510, 0, - 0, 0, 112, 300, 114, 0, 0, 0, 0, 116, - 0, 0, 0, 0, 301, 0, 0, 0, 0, 223, - 224, 0, 225, 0, 0, 223, 224, 226, 225, 227, - 0, 0, 0, 226, 0, 227, 0, 0, 124, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 129, 0, - 0, 0, 0, 0, 130, 0, 0, 0, 0, 133, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 135, - 136, 105, 137, 106, 0, 0, 107, 108, 0, 0, - 0, 0, 0, 0, 109, 110, 0, -159, 0, 0, - 0, 0, 0, 111, 0, 112, 113, 114, 115, 0, - 0, 0, 116, 0, 0, 0, 0, 117, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 118, 119, 120, 121, 122, - 123, 124, 125, 0, 0, 0, 0, 0, 126, 127, - 128, 129, 0, 0, 105, 0, 106, 130, 131, 0, - 108, 132, 133, 105, 0, 106, 134, 109, 110, 108, - 0, 0, 135, 136, 0, 137, 109, 110, 112, 113, - 114, 0, 0, 0, 0, 116, 0, 112, 300, 114, - 301, 0, 0, 0, 0, 0, 0, 0, 0, 301, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 124, 0, 0, 0, 0, 0, - 0, 0, 0, 124, 129, 0, 0, 0, 0, 0, - 130, 0, 0, 129, 132, 133, 0, 0, 0, 130, - 0, 0, 0, 0, 133, 135, 136, 0, 137, 0, - 0, 0, 0, 0, 0, 136, 0, 137 + 0, 126, 127, 128, 129, 0, 0, 0, 0, 0, + 130, 131, 0, 80, 132, 133, 479, 0, 480, 134, + 0, 0, 0, 0, 0, 135, 136, 220, 137, 267, + 0, 0, 0, 220, 0, 0, 138, 0, 0, 221, + 222, 0, 0, 0, 0, 221, 222, 0, 0, 82, + 83, 0, 0, 0, 0, 1511, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 88, 0, 0, 0, + 0, 90, 0, 0, 0, 0, 223, 224, 0, 225, + 0, 0, 223, 224, 226, 225, 227, 105, 0, 106, + 226, 0, 227, 108, 194, 0, 105, 0, 106, 0, + 109, 110, 108, 0, 0, 0, 0, 0, 0, 109, + 110, 112, 300, 114, 0, 0, 0, 0, 116, 0, + 112, 113, 114, 301, 0, 0, 0, 116, 0, 0, + 0, 0, 301, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 124, 0, 0, + 0, 0, 0, 0, 0, 0, 124, 129, 0, 0, + 0, 0, 0, 130, 0, 0, 129, 0, 133, 0, + 0, 0, 130, 0, 0, 0, 132, 133, 135, 136, + 105, 137, 106, 0, 0, 107, 108, 135, 136, 0, + 137, 0, 0, 109, 110, 0, -159, 0, 0, 0, + 0, 0, 111, 0, 112, 113, 114, 115, 0, 0, + 0, 116, 0, 0, 0, 0, 117, 0, 105, 0, + 106, 0, 0, 0, 108, 0, 0, 0, 0, 0, + 0, 109, 110, 0, 118, 119, 120, 121, 122, 123, + 124, 125, 112, 300, 114, 0, 0, 126, 127, 128, + 129, 0, 0, 0, 301, 0, 130, 131, 0, 0, + 132, 133, 0, 0, 0, 134, 0, 105, 0, 106, + 0, 135, 136, 108, 137, 0, 0, 0, 124, 312, + 109, 110, 0, 0, 0, 0, 0, 0, 129, 0, + 0, 112, 300, 114, 130, 0, 0, 0, 0, 133, + 0, 0, 0, 301, 0, 0, 0, 0, 0, 0, + 136, 0, 137, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 124, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 129, 0, 0, + 0, 0, 0, 130, 0, 0, 0, 0, 133, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 136, + 0, 137 }; static const yytype_int16 yycheck[] = { - 1, 321, 490, 132, 5, 461, 113, 132, 714, 737, - 142, 92, 948, 663, 299, 510, 75, 757, 184, 477, - 142, 15, 13, 75, 10, 142, 76, 13, 149, 61, - 151, 152, 153, 154, 490, 156, 44, 158, 447, 160, - 148, 583, 724, 76, 148, 727, 728, 76, 76, 334, - 459, 15, 584, 59, 6, 176, 8, 64, 65, 15, - 148, 62, 170, 167, 44, 148, 187, 188, 151, 720, - 810, 0, 481, 194, 195, 148, 81, 82, 83, 167, - 489, 165, 166, 88, 617, 627, 148, 10, 11, 12, - 91, 92, 147, 6, 167, 8, 638, 147, 99, 750, - 150, 752, 166, 167, 755, 167, 98, 108, 109, 110, - 165, 112, 113, 114, 147, 156, 117, 150, 147, 147, - 126, 150, 150, 124, 148, 33, 776, 148, 129, 130, - 148, 132, 133, 134, 142, 136, 137, 148, 10, 11, - 12, 13, 801, 167, 156, 17, 167, 148, 149, 167, - 151, 152, 153, 154, 156, 156, 167, 158, 190, 160, - 147, 820, 142, 619, 147, 33, 149, 299, 151, 160, - 166, 167, 831, 167, 160, 176, 496, 299, 165, 667, - 261, 262, 299, 184, 148, 717, 187, 188, 60, 721, - 113, 357, 148, 194, 195, 148, 277, 278, 330, 148, - 148, 468, 334, 523, 209, 210, 211, 212, 330, 697, - 165, 33, 334, 330, 167, 167, 758, 334, 167, 167, - 166, 167, 281, 148, 148, 257, 44, 150, 165, 281, - 151, 232, 10, 11, 12, 13, 148, 15, 165, 17, - 112, 113, 167, 167, 926, 166, 165, 929, 930, 10, - 11, 12, 160, 161, 162, 167, 164, 165, 166, 148, - 261, 262, 267, 758, 806, 807, 165, 33, 919, 141, - 148, 148, 393, 932, 165, 148, 277, 278, 167, 165, - 281, 33, 60, 155, 165, 286, 291, 148, 160, 167, - 167, 299, 344, 165, 167, 1023, 164, 165, 166, 300, - 301, 293, 760, 64, 955, 306, 167, 147, 165, 149, - 311, 151, 597, 165, 148, 76, 77, 165, 148, 299, - 321, 165, 330, 148, 142, 165, 334, 647, 150, 165, - 10, 11, 12, 167, 165, 113, 13, 167, 15, 148, - 17, 165, 167, 165, 166, 1004, 613, 803, 999, 1000, - 330, 165, 113, 114, 334, 116, 357, 151, 167, 148, - 121, 646, 123, 141, 356, 151, 148, 634, 777, 1019, - 637, 156, 166, 915, 165, 863, 696, 155, 167, 47, - 166, 49, 160, 60, 64, 167, 165, 165, 144, 145, - 146, 54, 393, 56, 57, 58, 76, 77, 164, 165, - 166, 460, 461, 66, 936, 165, 167, 863, 460, 461, - 165, 412, 164, 165, 166, 147, 165, 149, 1146, 151, - 915, 84, 165, 10, 11, 12, 13, 165, 166, 167, - 17, 490, 165, 113, 114, 165, 116, 100, 490, 166, - 167, 121, 709, 123, 165, 166, 167, 165, 449, 13, - 149, 15, 151, 17, 455, 456, 1138, 120, 121, 1395, - 165, 166, 167, 165, 141, 597, 467, 519, 6, 470, - 8, 165, 477, 60, 137, 597, 166, 167, 155, 142, - 597, 299, 165, 160, 165, 1018, 166, 488, 165, 490, - 114, 115, 116, 1035, 1036, 496, 60, 147, 165, 149, - 150, 151, 165, 504, 165, 147, 507, 149, 165, 151, - 165, 166, 330, 147, 646, 167, 334, 147, 148, 520, - 165, 33, 523, 150, 646, 584, 113, 165, 520, 646, - 165, 166, 584, 165, 165, 150, 165, 165, 805, 531, - 165, 150, 534, 150, 165, 13, 165, 15, 165, 17, - 151, 467, 611, 165, 141, 165, 160, 150, 825, 611, - 619, 828, 829, 1303, 10, 11, 12, 619, 155, 166, - 890, 166, 48, 160, 148, 165, 147, 141, 165, 156, - 165, 165, 583, 584, 585, 165, 149, 168, 148, 597, - 157, 155, 60, 594, 167, 167, 160, 167, 167, 1132, - 601, 602, 167, 1136, 157, 167, 167, 148, 609, 167, - 1142, 612, 167, 167, 615, 616, 617, 597, 64, 167, - 167, 622, 623, 148, 167, 626, 627, 167, 167, 15, - 76, 77, 167, 900, 1285, 167, 167, 638, 646, 167, - 167, 908, 157, 675, 911, 167, 647, 648, 160, 161, - 162, 167, 164, 165, 166, 663, 167, 167, 717, 167, - 167, 157, 721, 167, 167, 717, 646, 113, 114, 721, - 116, 165, 1378, 141, 147, 121, 167, 123, 167, 167, - 165, 167, 165, 663, 685, 686, 687, 155, 168, 507, - 150, 148, 160, 167, 148, 696, 612, 165, 148, 148, - 148, 148, 165, 165, 149, 151, 150, 623, 709, 155, - 626, 167, 165, 165, 160, 166, 717, 48, 48, 147, - 721, 160, 714, 724, 165, 167, 727, 728, 720, 167, - 762, 763, 724, 165, 735, 727, 728, 33, 770, 166, - 772, 160, 743, 160, 803, 746, 170, 48, 76, 165, - 156, 803, 156, 156, 156, 760, 757, 758, 750, 167, - 752, 10, 10, 755, 165, 10, 10, 149, 776, 1497, - 10, 10, 901, 157, 148, 167, 901, 149, 167, 597, - 160, 1048, 1314, 160, 167, 1317, 1318, 168, 1320, 149, - 33, 1323, 149, 709, 901, 796, 776, 160, 799, 800, - 801, 167, 167, 804, 863, 806, 807, 1295, 167, 810, - 147, 863, 167, 814, 165, 167, 817, 818, 850, 820, - 166, 166, 165, 167, 1564, 1565, 1566, 150, 646, 165, - 831, 148, 167, 148, 277, 278, 148, 148, 839, 1295, - 841, 148, 151, 167, 160, 663, 165, 167, 1380, 149, - 168, 149, 1384, 885, 168, 1388, 166, 1124, 1125, 1126, - 148, 10, 158, 159, 160, 161, 162, 170, 164, 165, - 166, 1611, 167, 148, 48, 165, 170, 936, 165, 165, - 1620, 165, 147, 165, 936, 703, 148, 170, 804, 890, - 170, 167, 893, 166, 157, 167, 897, 157, 814, 900, - 901, 817, 818, 157, 157, 10, 907, 908, 167, 10, - 911, 912, 149, 10, 915, 158, 159, 160, 161, 162, - 167, 164, 165, 166, 10, 926, 10, 919, 929, 930, - 10, 932, 149, 148, 926, 936, 165, 929, 930, 1020, - 170, 167, 170, 2, 61, 168, 1067, 948, 168, 22, - 23, 15, 165, 1485, 1487, 165, 167, 165, 776, 148, - 33, 167, 1495, 955, 165, 167, 1499, 1500, 1501, 1502, - 1503, 149, 16, 17, 18, 19, 20, 21, 22, 23, - 167, 165, 165, 156, 900, 156, 156, 156, 167, 33, - 167, 50, 908, 168, 147, 911, 168, 56, 57, 58, - 59, 60, 167, 1004, 63, 167, 449, 999, 1000, 167, - 167, 1019, 455, 456, 1334, 167, 167, 1018, 149, 1020, - 167, 10, 1555, 149, 1556, 1558, 1027, 1148, 1149, 10, - 149, 10, 10, 150, 1035, 1036, 149, 17, 155, 1019, - 157, 1042, 159, 149, 161, 162, 163, 164, 165, 166, - 167, 168, 169, 170, 171, 172, 173, 174, 175, 1592, - 167, 165, 15, 148, 167, 167, 1067, 47, 168, 186, - 148, 167, 167, 190, 157, 192, 193, 1610, 157, 167, - 60, 61, 157, 1142, 902, 158, 159, 160, 161, 162, - 1142, 164, 165, 166, 157, 1362, 76, 167, 10, 168, - 167, 1102, 149, 10, 10, 165, 150, 149, 152, 153, - 154, 155, 165, 1114, 158, 159, 160, 161, 162, 165, - 164, 165, 166, 1124, 1125, 1126, 1042, 107, 167, 165, - 110, 1132, 167, 113, 193, 1136, 149, 1138, 167, 149, - 10, 1142, 149, 167, 149, 311, 1138, 1148, 1149, 129, - 1147, 594, 649, 1298, 1378, 272, 902, 703, 601, 602, - 1516, 141, 1295, 1114, 1335, 863, 609, 334, 1258, 667, - 334, -1, 615, 616, -1, 155, 411, 236, 237, 238, + 1, 113, 132, 132, 5, 736, 488, 508, 321, 461, + 92, 947, 756, 713, 475, 142, 75, 719, 468, 299, + 13, 15, 147, 75, 148, 184, 44, 662, 582, 61, + 149, 447, 151, 152, 153, 154, 488, 156, 15, 158, + 165, 160, 142, 459, 98, 142, 170, 749, 6, 751, + 8, 59, 754, 148, 334, 10, 76, 176, 13, 33, + 0, 62, 581, 479, 148, 809, 800, 15, 187, 188, + 156, 487, 167, 148, 148, 194, 195, 165, 148, 33, + 44, 150, 148, 167, 151, 819, 10, 11, 12, 467, + 91, 92, 167, 167, 165, 148, 830, 167, 99, 166, + 615, 167, 148, 44, 151, 165, 625, 108, 109, 110, + 151, 112, 113, 114, 167, 165, 117, 636, 126, 166, + 148, 167, 33, 124, 142, 166, 148, 147, 129, 130, + 150, 132, 133, 134, 723, 136, 137, 726, 727, 167, + 775, 148, 81, 82, 83, 167, 165, 148, 149, 88, + 151, 152, 153, 154, 165, 156, 147, 158, 190, 160, + 167, 611, 716, 165, 166, 617, 720, 160, 156, 277, + 278, 148, 299, 167, 165, 176, 150, 156, 142, 261, + 262, 494, 632, 184, 666, 635, 187, 188, 76, 113, + 33, 165, 166, 194, 195, 277, 278, 931, 357, 299, + 148, 142, 299, 330, 76, 160, 165, 334, 521, 167, + 164, 165, 166, 6, 696, 8, 918, 13, 76, 15, + 148, 17, 281, 151, 156, 257, 150, 64, 65, 281, + 330, 232, 610, 330, 334, 166, 167, 334, 757, 293, + 10, 11, 12, 621, 148, 165, 624, 158, 159, 160, + 161, 162, 954, 164, 165, 166, 757, 165, 708, 147, + 261, 262, 150, 167, 60, 148, 6, 33, 8, 1003, + 209, 210, 211, 212, 393, 147, 277, 278, 150, 165, + 281, 299, 148, 165, 167, 344, 805, 806, 33, 147, + 165, 1022, 150, 167, 64, 148, 998, 999, 759, 300, + 301, 167, 356, 166, 167, 306, 76, 77, 165, 47, + 311, 49, 330, 148, 167, 595, 334, 160, 161, 162, + 321, 164, 165, 166, 149, 13, 151, 15, 267, 17, + 708, 165, 167, 646, 165, 299, 925, 165, 148, 928, + 929, 449, 148, 113, 114, 141, 116, 455, 456, 148, + 802, 121, 291, 123, 804, 150, 357, 167, 299, 155, + 776, 167, 166, 167, 160, 645, 330, 148, 167, 165, + 334, 148, 60, 165, 824, 148, 165, 827, 828, 165, + 862, 935, 695, 1018, 148, 148, 167, 148, 150, 330, + 167, 165, 393, 334, 167, 914, 165, 167, 164, 165, + 166, 460, 461, 167, 167, 165, 167, 165, 460, 461, + 862, 412, 165, 914, 147, 1146, 149, 165, 151, 164, + 165, 166, 10, 11, 12, 803, 13, 150, 15, 488, + 17, 165, 165, 165, 166, 813, 488, 165, 816, 817, + 10, 11, 12, 13, 144, 145, 146, 17, 449, 899, + 165, 166, 167, 141, 455, 456, 165, 907, 517, 1395, + 910, 147, 165, 149, 518, 151, 467, 155, 595, 470, + 471, 165, 160, 60, 165, 529, 64, 165, 532, 147, + 165, 149, 150, 151, 592, 486, 165, 488, 76, 77, + 60, 599, 600, 494, 165, 595, 166, 167, 595, 607, + 165, 502, 1017, 165, 505, 613, 614, 147, 147, 149, + 149, 151, 151, 166, 167, 1034, 1035, 518, 645, 165, + 521, 899, 165, 582, 165, 113, 114, 165, 116, 907, + 582, 165, 910, 121, 165, 123, 475, 165, 166, 167, + 147, 148, 112, 113, 165, 645, 165, 166, 645, 1138, + 609, 165, 166, 167, 141, 165, 151, 609, 617, 1303, + 114, 115, 116, 160, 505, 617, 166, 166, 155, 147, + 150, 141, 48, 160, 148, 165, 889, 595, 166, 147, + 581, 582, 583, 1285, 156, 155, 165, 149, 1142, 165, + 160, 592, 165, 168, 165, 165, 17, 1047, 599, 600, + 148, 167, 167, 167, 167, 157, 607, 167, 167, 610, + 167, 157, 613, 614, 615, 148, 167, 1132, 167, 620, + 621, 1136, 167, 624, 625, 167, 47, 645, 167, 148, + 167, 595, 167, 167, 157, 636, 22, 23, 167, 60, + 61, 167, 674, 167, 662, 646, 647, 33, 157, 167, + 167, 167, 167, 167, 595, 76, 167, 716, 33, 713, + 167, 720, 167, 1041, 716, 719, 167, 167, 720, 723, + 167, 15, 726, 727, 1124, 1125, 1126, 167, 1378, 167, + 165, 645, 165, 684, 685, 686, 107, 795, 167, 110, + 798, 799, 113, 150, 695, 749, 167, 751, 662, 147, + 754, 148, 148, 148, 645, 148, 148, 708, 129, 148, + 165, 149, 165, 150, 165, 716, 165, 167, 48, 720, + 141, 662, 723, 167, 165, 726, 727, 167, 160, 761, + 762, 165, 48, 734, 155, 166, 166, 769, 160, 771, + 160, 742, 170, 802, 745, 168, 1124, 1125, 1126, 147, + 802, 48, 1326, 1327, 1328, 756, 757, 775, 76, 165, + 1314, 702, 156, 1317, 1318, 156, 1320, 1498, 156, 1323, + 900, 900, 158, 159, 160, 161, 162, 156, 164, 165, + 166, 10, 11, 12, 165, 160, 161, 162, 900, 164, + 165, 166, 10, 167, 795, 10, 10, 798, 799, 800, + 10, 10, 803, 862, 805, 806, 10, 149, 809, 157, + 862, 775, 813, 1295, 148, 816, 817, 849, 819, 160, + 759, 1565, 1566, 1567, 149, 160, 1380, 167, 167, 830, + 1384, 167, 149, 160, 775, 64, 168, 838, 149, 840, + 147, 167, 1416, 1295, 1418, 167, 1420, 76, 77, 1423, + 1424, 1425, 884, 20, 21, 22, 23, 167, 167, 165, + 150, 165, 167, 166, 918, 166, 33, 167, 1612, 165, + 148, 925, 167, 1388, 928, 929, 935, 1621, 148, 148, + 148, 148, 167, 935, 113, 114, 151, 116, 889, 165, + 167, 892, 121, 166, 123, 896, 160, 149, 899, 900, + 954, 10, 11, 12, 13, 906, 907, 168, 17, 910, + 911, 149, 1362, 914, 10, 11, 12, 13, 1026, 15, + 168, 17, 151, 148, 925, 10, 155, 928, 929, 170, + 931, 160, 1486, 167, 935, 148, 48, 1019, 170, 165, + 170, 165, 165, 165, 998, 999, 947, 166, 1067, 165, + 170, 60, 147, 2, 148, 22, 23, 157, 157, 167, + 901, 157, 167, 10, 60, 157, 33, 10, 149, 10, + 11, 12, 10, 1488, 167, 10, 167, 10, 10, 149, + 148, 1496, 165, 170, 1362, 1500, 1501, 1502, 1503, 1504, + 167, 158, 159, 160, 161, 162, 168, 164, 165, 166, + 1018, 50, 1003, 1557, 113, 170, 168, 56, 57, 58, + 59, 60, 15, 165, 63, 165, 1017, 113, 1019, 167, + 165, 1334, 148, 64, 167, 1026, 165, 167, 149, 1148, + 1149, 167, 141, 1034, 1035, 76, 77, 33, 165, 156, + 1041, 1556, 156, 156, 1559, 141, 155, 165, 156, 168, + 147, 160, 167, 15, 1018, 149, 165, 168, 10, 155, + 167, 167, 167, 167, 160, 167, 1067, 167, 167, 165, + 149, 10, 113, 114, 167, 116, 10, 1018, 1593, 149, + 121, 149, 123, 1142, 1138, 10, 149, 165, 168, 148, + 1142, 158, 159, 160, 161, 162, 1611, 164, 165, 166, + 148, 1102, 167, 16, 17, 18, 19, 20, 21, 22, + 23, 167, 167, 1114, 155, 167, 167, 157, 157, 160, + 33, 157, 167, 1124, 1125, 1126, 157, 10, 149, 10, + 167, 1132, 10, 149, 168, 1136, 149, 1138, 167, 165, + 165, 1142, 165, 167, 193, 165, 10, 1148, 1149, 167, + 167, 108, 109, 110, 149, 112, 113, 114, 149, 167, + 117, 149, 158, 159, 160, 161, 162, 124, 164, 165, + 166, 1147, 129, 130, 311, 132, 133, 134, 648, 136, + 137, 1298, 1378, 11, 901, 334, 1517, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, - 249, 250, 251, 252, 253, 254, 255, -1, -1, 258, - -1, 1019, -1, -1, 263, -1, -1, -1, 1124, 1125, - 1126, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 1304, -1, -1, -1, -1, -1, -1, - -1, -1, 10, 11, 12, 13, 1295, -1, -1, 17, - 299, -1, -1, 1295, -1, -1, -1, 1326, 1327, 1328, - -1, -1, -1, -1, -1, 1314, -1, 1258, 1317, 1318, - -1, 1320, 1314, -1, 1323, 1317, 1318, -1, 1320, 328, - -1, 1323, -1, -1, -1, 392, -1, -1, -1, -1, - -1, -1, 60, 108, 109, 110, -1, 112, 113, 114, - -1, -1, 117, 1285, 1295, -1, -1, -1, -1, 124, - -1, -1, 1303, 1304, 129, 130, 1298, 132, 133, 134, - -1, 136, 137, 1314, -1, -1, 1317, 1318, -1, 1320, - -1, 1380, 1323, -1, -1, 1384, -1, -1, 1380, -1, - -1, 390, 1384, 1334, -1, 113, 1415, -1, 1417, -1, - 1419, -1, 1374, 1422, 1423, 1424, -1, 406, 407, -1, - -1, -1, -1, 796, 413, -1, 799, 800, -1, -1, - -1, 1362, -1, 141, -1, 18, 19, 20, 21, 22, - 23, -1, 62, -1, 10, 11, 12, 155, -1, 1380, - 33, -1, 160, 1384, -1, -1, 1378, 1388, -1, -1, - -1, -1, -1, -1, 1395, 85, 1428, 1429, 515, 1431, - -1, 1433, -1, -1, -1, 522, 22, 23, -1, -1, - -1, 470, -1, -1, -1, 105, -1, 33, 1450, -1, - -1, -1, -1, -1, -1, 1426, 1485, -1, 64, -1, - -1, -1, 549, 1485, 551, 125, 553, -1, -1, -1, - 76, 77, -1, -1, -1, 135, 1362, -1, 1480, -1, - -1, -1, 17, 18, 19, 20, 21, 22, 23, 518, - -1, -1, -1, -1, -1, -1, -1, -1, 33, 528, - -1, -1, -1, -1, -1, 300, 301, 113, 114, -1, - 116, 306, -1, -1, 1485, 121, 1487, 123, -1, -1, - 180, -1, -1, 183, 1495, -1, -1, 1556, 1499, 1500, - 1501, 1502, 1503, -1, 1556, 158, 159, 160, 161, 162, - -1, 164, 165, 166, 573, 1516, -1, -1, -1, 155, - -1, -1, -1, -1, 160, -1, -1, -1, -1, 588, - -1, 17, 18, 19, 20, 21, 22, 23, 597, 229, - 230, -1, 158, 159, 160, 161, 162, 33, 164, 165, - 166, -1, -1, -1, 1555, 1556, -1, 1558, 675, -1, - -1, -1, -1, 1564, 1565, 1566, 256, -1, -1, -1, - -1, -1, 1604, 1605, 1606, -1, 1608, -1, -1, -1, - 279, 280, -1, -1, 1027, 275, -1, 646, 153, 154, - 155, 1592, -1, 158, 159, 160, 161, 162, -1, 164, - 165, 166, -1, 293, -1, 295, -1, -1, -1, 1610, - 1611, -1, 671, 672, 673, 674, -1, 676, -1, 1620, - -1, -1, 312, -1, 314, 315, 316, 317, 318, 319, - -1, -1, -1, -1, 1127, -1, -1, 10, 11, 12, - -1, -1, -1, -1, -1, -1, 336, -1, -1, -1, - -1, -1, -1, -1, -1, 345, -1, -1, 348, -1, - -1, -1, -1, 488, -1, -1, 356, 153, 154, 155, + 249, 250, 251, 252, 253, 254, 255, 702, 1295, 258, + 862, 1114, 334, 1335, 263, 1258, -1, -1, -1, -1, + -1, 411, 1304, 10, 11, 12, 54, -1, 56, 57, + 58, 1285, -1, 666, -1, -1, 1295, 150, -1, 152, + 153, 154, 155, 1295, 1298, 158, 159, 160, 161, 162, + 299, 164, 165, 166, -1, 1314, 84, 1258, 1317, 1318, + -1, 1320, 1314, -1, 1323, 1317, 1318, -1, 1320, -1, + -1, 1323, 100, 10, 11, 12, 13, 64, -1, 328, + 17, -1, -1, -1, -1, -1, -1, -1, -1, 76, + 77, -1, 120, 121, 1295, -1, -1, -1, -1, -1, + -1, -1, 1303, 1304, -1, -1, 10, 11, -1, 137, + -1, -1, -1, 1314, 142, -1, 1317, 1318, -1, 1320, + -1, 1380, 1323, 60, 1378, 1384, 113, 114, 1380, 116, + -1, -1, 1384, 1334, 121, -1, 123, -1, -1, -1, + -1, 390, 1374, 300, 301, -1, -1, 51, -1, 306, + 54, -1, 56, 57, 58, 59, -1, 406, 407, 63, + -1, 1362, 66, 150, 413, -1, 70, -1, -1, -1, + -1, -1, -1, 77, -1, -1, 113, -1, -1, 1380, + 84, -1, -1, 1384, -1, -1, -1, 1388, -1, -1, + -1, -1, -1, -1, 1395, -1, 100, 1429, 1430, -1, + 1432, -1, 1434, -1, 141, -1, -1, -1, 112, -1, + -1, -1, -1, -1, -1, -1, 120, 121, 155, 1451, + -1, 470, 126, 160, -1, -1, 1427, 1486, -1, -1, + 134, 135, 136, 137, 1486, -1, 140, -1, 142, -1, + -1, -1, -1, 147, 20, 21, 22, 23, -1, 1481, + 62, 54, -1, 56, 57, 58, -1, 33, -1, 163, + -1, 18, 19, 20, 21, 22, 23, 516, -1, -1, + -1, -1, -1, 85, -1, -1, 33, 526, -1, -1, + -1, 84, -1, -1, -1, 1486, -1, 1488, -1, -1, + -1, -1, -1, 105, -1, 1496, -1, 100, 1557, 1500, + 1501, 1502, 1503, 1504, -1, 1557, -1, -1, -1, -1, + -1, -1, -1, 125, -1, -1, 1517, 120, 121, -1, + -1, -1, 571, 135, -1, -1, -1, -1, -1, 486, + -1, -1, -1, -1, 137, -1, -1, 586, -1, 142, + -1, -1, -1, -1, -1, 61, 595, 18, 19, 20, + 21, 22, 23, -1, -1, 1556, 1557, -1, 1559, -1, + -1, -1, 33, -1, 1565, 1566, 1567, -1, 180, -1, + -1, 183, -1, 1605, 1606, 1607, -1, 1609, -1, -1, 156, 157, 158, 159, 160, 161, 162, -1, 164, 165, - 166, -1, -1, -1, -1, -1, -1, 746, -1, -1, - -1, 64, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 76, 77, 395, -1, -1, -1, 399, - -1, 18, 19, 20, 21, 22, 23, -1, -1, -1, - -1, 411, -1, -1, -1, -1, 33, 844, 845, 846, - -1, 848, -1, 850, -1, 852, 853, -1, -1, -1, - 113, 114, 801, 116, -1, -1, 445, 446, 121, -1, - 123, -1, -1, -1, -1, -1, -1, 447, -1, 458, - -1, 820, -1, 462, 463, -1, -1, -1, -1, 459, - -1, -1, 831, -1, -1, -1, 835, 150, -1, -1, - -1, 471, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 481, -1, -1, 853, -1, -1, -1, -1, 489, - -1, -1, -1, -1, -1, 864, 865, 866, 867, 868, - 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, - 879, 880, 881, 882, 883, 1127, -1, 886, -1, -1, - -1, -1, -1, -1, 3, 4, 5, 6, -1, 8, - 9, 10, -1, -1, 534, -1, 15, 154, 155, 156, + 166, -1, 1593, -1, 279, 280, 645, 154, 155, 156, 157, 158, 159, 160, 161, 162, -1, 164, 165, 166, - 685, 686, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 932, 1367, -1, 1369, 1370, 1371, 1372, - 1373, 50, 1375, -1, -1, -1, -1, -1, -1, 948, - -1, -1, 582, 62, -1, -1, -1, -1, 67, -1, - -1, 600, -1, -1, 603, 604, 75, 76, 17, 599, + 1611, 1612, -1, -1, -1, -1, -1, 229, 230, -1, + 1621, 670, 671, 672, 673, -1, 675, -1, -1, -1, + -1, -1, -1, -1, 150, -1, -1, -1, -1, 155, + -1, 157, -1, 159, 256, 161, 162, 163, 164, 165, + 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, + -1, -1, -1, 275, 18, 19, 20, 21, 22, 23, + 186, -1, -1, -1, 190, -1, 192, 193, -1, 33, + -1, 293, -1, 295, 155, 156, 157, 158, 159, 160, + 161, 162, -1, 164, 165, 166, 745, -1, -1, -1, + 312, -1, 314, 315, 316, 317, 318, 319, -1, -1, + -1, -1, -1, -1, -1, 16, 17, 18, 19, 20, + 21, 22, 23, -1, 336, -1, -1, 684, 685, -1, + -1, -1, 33, 345, -1, -1, 348, 18, 19, 20, + 21, 22, 23, -1, 356, -1, -1, -1, -1, -1, + -1, 800, 33, -1, -1, -1, 272, -1, -1, -1, + 445, 446, -1, -1, -1, -1, -1, -1, -1, -1, + 819, -1, -1, 458, -1, -1, -1, 462, 463, -1, + -1, 830, -1, 395, -1, -1, -1, 399, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 411, + 154, 155, -1, 852, 158, 159, 160, 161, 162, -1, + 164, 165, 166, -1, 863, 864, 865, 866, 867, 868, + 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, + 879, 880, 881, 882, -1, 447, 885, -1, 1127, -1, + -1, -1, -1, -1, -1, -1, -1, 459, -1, -1, + -1, 152, 153, 154, 155, -1, 1127, 158, 159, 160, + 161, 162, -1, 164, 165, 166, -1, 479, -1, -1, + -1, -1, 153, 154, 155, 487, 392, 158, 159, 160, + 161, 162, 931, 164, 165, 166, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 947, -1, + 3, 4, 5, 6, -1, 8, 9, 10, -1, -1, + -1, -1, 15, 598, -1, -1, 601, 602, -1, -1, + 532, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 619, -1, -1, 622, 623, -1, + -1, 626, -1, 900, -1, 630, -1, 50, 633, 634, + -1, -1, 1001, -1, 1003, -1, 1005, -1, -1, 62, + -1, -1, -1, -1, 67, -1, -1, -1, 580, -1, + -1, -1, 75, 76, 16, 17, 18, 19, 20, 21, + 22, 23, -1, -1, -1, 597, -1, -1, -1, -1, + -1, 33, -1, -1, -1, -1, -1, 513, -1, -1, + -1, -1, -1, -1, 520, -1, 109, 1056, 111, -1, + 113, -1, -1, -1, -1, 118, -1, 629, -1, 122, + -1, -1, 125, -1, -1, 1074, -1, 130, 640, -1, + 133, 547, -1, 549, -1, 551, 648, -1, -1, -1, + 725, -1, -1, 728, 729, -1, 731, -1, -1, -1, + -1, -1, 155, -1, -1, 158, 159, -1, -1, -1, + 163, -1, 165, 748, -1, -1, 169, 752, 753, -1, + -1, -1, -1, 758, -1, -1, -1, -1, 1367, -1, + 1369, 1370, 1371, 1372, 1373, -1, 1375, -1, -1, -1, + -1, -1, -1, -1, 706, -1, 1367, -1, 1369, 1370, + 1371, 1372, 1373, -1, 1375, 790, -1, -1, 793, 794, + 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, + 162, -1, 164, 165, 166, -1, 738, 812, 170, -1, + -1, -1, -1, -1, -1, -1, -1, 822, 823, -1, + -1, -1, -1, -1, -1, -1, -1, 832, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 674, -1, + -1, -1, -1, -1, 776, -1, -1, -1, -1, -1, + -1, -1, -1, 1462, 1463, 1464, 1465, 1466, 1467, 1468, + 1469, 1470, 1471, 1472, 1473, 1474, 1475, 1476, 1477, 1478, + 1479, 1462, 1463, 1464, 1465, 1466, 1467, 1468, 1469, 1470, + 1471, 1472, 1473, 1474, 1475, 1476, 1477, 1478, 1479, -1, + -1, -1, -1, -1, -1, 6, -1, -1, -1, -1, + 905, -1, -1, 908, 909, 16, 17, 18, 19, 20, + 21, 22, 23, -1, -1, 1284, -1, -1, -1, 924, + -1, -1, 33, 1532, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, -1, -1, 18, 19, + 20, 21, 22, 23, -1, -1, -1, -1, 953, -1, + -1, 883, -1, 33, 65, 16, 17, 18, 19, 20, + 21, 22, 23, -1, -1, -1, -1, -1, -1, -1, + 902, -1, 33, 1342, -1, -1, 1585, -1, 1347, 1588, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 621, -1, 33, 624, 625, -1, -1, 628, - -1, -1, -1, 632, -1, -1, 635, 636, 47, -1, - 109, 631, 111, 1002, 113, 1004, -1, 1006, -1, 118, - -1, 60, 61, 122, -1, -1, 125, -1, -1, 649, - -1, 130, -1, -1, 133, -1, -1, 76, 1461, 1462, - 1463, 1464, 1465, 1466, 1467, 1468, 1469, 1470, 1471, 1472, - 1473, 1474, 1475, 1476, 1477, 1478, 155, -1, -1, 158, - 159, -1, -1, -1, 163, -1, 165, -1, 107, -1, - 169, 110, -1, -1, 113, 1122, 16, 17, 18, 19, - 20, 21, 22, 23, -1, 1074, -1, 707, -1, -1, - 129, -1, -1, 33, -1, -1, -1, 726, -1, -1, - 729, 730, 141, 732, -1, -1, -1, -1, 1531, 20, - 21, 22, 23, -1, -1, -1, 155, -1, -1, 739, - 749, -1, 33, -1, 753, 754, -1, -1, -1, -1, - 759, -1, -1, -1, -1, 1367, -1, 1369, 1370, 1371, - 1372, 1373, -1, 1375, -1, -1, 901, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 777, -1, -1, - -1, 1584, 791, -1, 1587, 794, 795, -1, 16, 17, - 18, 19, 20, 21, 22, 23, -1, -1, -1, -1, - -1, -1, -1, -1, 813, 33, -1, -1, -1, -1, - -1, -1, -1, -1, 823, 824, -1, -1, -1, -1, - -1, -1, -1, -1, 833, -1, -1, -1, 148, -1, - -1, -1, 152, 153, 154, 155, 156, 157, 158, 159, - 160, 161, 162, -1, 164, 165, 166, 167, -1, 1461, - 1462, 1463, 1464, 1465, 1466, 1467, 1468, 1469, 1470, 1471, - 1472, 1473, 1474, 1475, 1476, 1477, 1478, 158, 159, 160, - 161, 162, -1, 164, 165, 166, 3, 4, 5, 6, - -1, 8, 9, 10, 884, -1, -1, -1, 15, -1, - -1, -1, -1, -1, -1, -1, -1, 906, -1, -1, - 909, 910, -1, 903, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 1284, 925, -1, -1, -1, - -1, -1, -1, 50, 152, 153, 154, 155, 156, 157, - 158, 159, 160, 161, 162, 62, 164, 165, 166, -1, - 67, -1, 170, -1, -1, 954, -1, 1374, 75, 76, - -1, -1, -1, -1, 81, -1, -1, -1, 85, 86, - 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, - 97, 98, 99, 1342, -1, 1587, -1, -1, 1347, -1, - -1, -1, -1, -1, 111, -1, 113, -1, 997, -1, - -1, 118, -1, -1, -1, 122, -1, -1, 125, -1, - -1, -1, -1, 130, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 1025, 1026, 1445, 1446, - 1447, 1448, 1022, 1450, -1, 1452, 1395, -1, 155, -1, - -1, 158, 159, 160, -1, -1, 163, -1, 165, 166, - -1, -1, 169, -1, -1, -1, 3, 4, 5, 6, + -1, 996, -1, -1, -1, -1, -1, 1588, 109, -1, + -1, -1, -1, -1, -1, -1, -1, 843, 844, 845, + -1, 847, -1, 849, -1, 851, 852, -1, -1, 1024, + 1025, -1, -1, -1, -1, -1, 1395, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 148, -1, -1, + 151, -1, 153, 154, 155, 156, 157, 158, 159, 160, + 161, 162, 163, -1, 165, 166, -1, -1, 169, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 3, 4, + 5, 6, -1, 8, 9, 10, 11, 12, 158, 159, + 160, 161, 162, -1, 164, 165, 166, -1, -1, 1021, + -1, 152, 153, 154, 155, 156, 157, 158, 159, 160, + 161, 162, -1, 164, 165, 166, -1, -1, -1, 170, + -1, -1, -1, 1482, -1, 50, 51, -1, 1123, 54, + -1, 56, 57, 58, 59, 60, -1, 62, 63, -1, + -1, 66, 67, -1, -1, 70, -1, 1069, -1, -1, + 75, 76, 77, 10, 11, 12, 81, -1, -1, 84, + 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, + 95, 96, 97, 98, 99, 100, -1, -1, -1, -1, + -1, -1, -1, 17, 109, -1, 111, -1, 113, -1, + 47, -1, 49, 118, -1, 120, 121, 122, -1, 33, + 125, 126, -1, -1, -1, 130, -1, 64, 133, 134, + 135, 136, 137, 47, -1, 140, -1, 142, -1, 76, + 77, -1, -1, -1, -1, 1147, 60, 61, -1, -1, + 155, -1, -1, 158, 159, 160, -1, -1, 163, -1, + 165, 166, 76, -1, 169, 10, 11, 12, -1, -1, + -1, -1, -1, -1, -1, -1, 113, 114, 54, 116, + 56, 57, 58, -1, 121, -1, 123, -1, -1, -1, + 66, -1, -1, 107, -1, -1, 110, -1, -1, 113, + -1, -1, -1, -1, -1, -1, -1, -1, 84, -1, + 147, -1, 1287, -1, -1, 129, 1122, -1, -1, 64, + -1, -1, -1, -1, 100, -1, -1, 141, -1, -1, + -1, 76, 77, -1, -1, -1, -1, -1, 1313, -1, + -1, 155, -1, -1, 120, 121, 1321, -1, -1, 1324, + 3, 4, 5, 6, -1, 8, 9, 10, 11, -1, + -1, 137, -1, -1, -1, -1, 142, -1, 113, 114, + -1, 116, -1, -1, -1, -1, 121, -1, 123, -1, + -1, -1, 16, 17, 18, 19, 20, 21, 22, 23, + -1, -1, -1, -1, -1, -1, -1, 50, 51, 33, + -1, 54, 147, 56, 57, 58, 59, -1, -1, 62, + 63, -1, 1387, 66, 67, -1, -1, 70, -1, -1, + -1, -1, 75, 76, 77, 1400, -1, 1329, 81, -1, + -1, 84, 85, 86, 87, 88, 89, 90, 91, 92, + 93, 94, 95, 96, 97, 98, 99, 100, -1, -1, + -1, -1, -1, -1, -1, -1, 109, -1, 111, -1, + 113, -1, -1, -1, -1, 118, -1, 120, 121, 122, + -1, -1, 125, 126, -1, -1, -1, 130, -1, -1, + 133, 134, 135, 136, 137, -1, -1, 140, -1, 142, + -1, -1, -1, 10, 11, -1, -1, -1, -1, -1, + -1, -1, 155, -1, 6, 158, 159, 160, -1, -1, + 163, -1, 165, 166, -1, -1, 169, -1, 152, 153, + 154, 155, 156, 157, 158, 159, 160, 161, 162, -1, + 164, 165, 166, -1, 51, -1, 170, 54, -1, 56, + 57, 58, 59, -1, -1, 47, 63, 49, -1, 66, + -1, 53, -1, 70, -1, -1, -1, -1, 60, 61, + 77, -1, -1, -1, -1, -1, -1, 84, 1374, 71, + 72, 73, -1, -1, -1, -1, -1, -1, 1480, -1, + -1, 83, -1, 100, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 112, 18, 19, 20, 21, + 22, 23, -1, 120, 121, 107, -1, -1, -1, 126, + -1, 33, -1, -1, -1, 117, -1, 134, 135, 136, + 137, 123, -1, 140, -1, 142, 128, 1529, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 139, -1, 141, + 1446, 1447, 1448, 1449, -1, 1451, 163, 1453, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, -1, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, -1, -1, -1, -1, -1, -1, -1, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, -1, -1, 54, + 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, -1, 70, -1, 72, 73, 74, + 75, 76, 77, 78, 79, 80, -1, 82, 83, 84, + -1, 153, 154, 155, 156, 157, 158, 159, 160, 161, + 162, -1, 164, 165, 166, 100, -1, -1, -1, -1, + -1, -1, 107, 108, 109, -1, 111, 112, 113, 114, + 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, + 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 137, 138, 139, 140, 141, 142, 143, -1, + -1, -1, 147, 148, 149, 150, 151, 152, 153, 154, + 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 166, 167, 168, 169, 170, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, -1, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 24, 25, 1069, + 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, -1, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, - 67, 68, 1481, 70, 1123, 72, 73, 74, 75, 76, + 67, 68, -1, 70, -1, 72, 73, 74, 75, 76, 77, 78, 79, 80, -1, 82, 83, 84, -1, -1, - -1, 16, 17, 18, 19, 20, 21, 22, 23, -1, - -1, -1, -1, 100, -1, -1, -1, 1147, 33, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 100, -1, -1, -1, -1, -1, -1, 107, 108, 109, -1, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, -1, -1, -1, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, - 167, 168, 169, 170, -1, -1, -1, -1, -1, -1, - -1, -1, 47, -1, 49, -1, -1, -1, 53, -1, - -1, -1, -1, -1, -1, 60, 61, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 71, 72, 73, -1, - -1, -1, -1, -1, 3, 4, 5, 6, 83, 8, - 9, 10, 11, -1, -1, -1, 15, 152, 153, 154, - 155, 156, 157, 158, 159, 160, 161, 162, 1287, 164, - 165, 166, 107, 108, -1, 170, -1, -1, -1, -1, - -1, -1, 117, -1, -1, -1, -1, -1, 123, -1, - -1, 50, -1, 128, 1313, 54, -1, 56, 57, 58, - -1, -1, 1321, 62, 139, 1324, 141, 66, 67, -1, - -1, -1, -1, -1, -1, -1, 75, 76, 77, 1329, + 167, -1, 169, 170, 3, 4, 5, 6, -1, 8, + 9, 10, 11, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 16, 17, 18, 19, 20, + 21, 22, 23, -1, -1, -1, -1, -1, -1, -1, + -1, 50, 33, -1, -1, 54, -1, 56, 57, 58, + -1, -1, -1, 62, -1, 64, 65, 66, 67, -1, + -1, -1, -1, -1, -1, -1, 75, 76, 77, -1, -1, -1, 81, -1, -1, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, -1, -1, -1, -1, -1, -1, -1, -1, 109, -1, 111, -1, 113, -1, -1, -1, -1, 118, - -1, 120, 121, 122, -1, -1, 125, -1, 1387, -1, - -1, 130, -1, -1, 133, -1, -1, -1, 137, -1, - -1, 1400, -1, 142, -1, -1, -1, -1, -1, -1, + -1, 120, 121, 122, -1, -1, 125, -1, -1, -1, + -1, 130, -1, -1, 133, -1, -1, -1, 137, 3, + 4, 5, 6, 142, 8, 9, 10, 11, 147, -1, + -1, 15, -1, -1, -1, -1, 155, -1, -1, 158, + 159, 160, -1, -1, 163, -1, 165, 166, -1, 150, + 169, 152, 153, 154, 155, 156, 157, 158, 159, 160, + 161, 162, -1, 164, 165, 166, 50, -1, -1, -1, + 54, -1, 56, 57, 58, -1, -1, -1, 62, -1, + -1, -1, 66, 67, -1, -1, -1, -1, -1, -1, + -1, 75, 76, 77, -1, -1, -1, 81, -1, -1, + 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, + 94, 95, 96, 97, 98, 99, 100, -1, -1, -1, + -1, -1, -1, -1, -1, 109, -1, 111, -1, 113, + -1, -1, -1, -1, 118, -1, 120, 121, 122, -1, + -1, 125, -1, -1, -1, -1, 130, -1, -1, 133, + -1, -1, -1, 137, 3, 4, 5, 6, 142, 8, + 9, 10, 11, -1, -1, -1, -1, -1, -1, -1, + -1, 155, -1, -1, 158, 159, 160, -1, -1, 163, + -1, 165, 166, -1, -1, 169, 17, 18, 19, 20, + 21, 22, 23, -1, -1, -1, -1, -1, -1, -1, + -1, 50, 33, -1, -1, 54, -1, 56, 57, 58, + -1, -1, -1, 62, -1, -1, -1, 66, 67, -1, + -1, -1, -1, -1, -1, -1, 75, 76, 77, -1, + -1, -1, 81, -1, -1, 84, 85, 86, 87, 88, + 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, + 99, 100, -1, -1, -1, -1, -1, -1, -1, -1, + 109, -1, 111, -1, 113, -1, -1, -1, -1, 118, + -1, 120, 121, 122, -1, -1, 125, -1, -1, -1, + -1, 130, -1, -1, 133, -1, -1, -1, 137, 3, + 4, 5, 6, 142, 8, 9, 10, 11, -1, -1, + -1, -1, -1, -1, -1, -1, 155, -1, -1, 158, + 159, 160, -1, -1, 163, -1, 165, 166, 167, -1, + 169, -1, 153, 154, 155, 156, 157, 158, 159, 160, + 161, 162, -1, 164, 165, 166, 50, 51, -1, -1, + 54, -1, 56, 57, 58, -1, -1, -1, 62, -1, + -1, -1, 66, 67, -1, -1, -1, -1, -1, -1, + -1, 75, 76, 77, -1, -1, -1, 81, -1, -1, + 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, + 94, 95, 96, 97, 98, 99, 100, -1, -1, -1, + -1, -1, -1, -1, -1, 109, -1, 111, -1, 113, + -1, -1, -1, -1, 118, -1, 120, 121, 122, -1, + -1, 125, -1, -1, -1, -1, 130, -1, -1, 133, + -1, -1, -1, 137, 3, 4, 5, 6, 142, 8, + 9, 10, 11, -1, -1, -1, -1, -1, -1, -1, + -1, 155, -1, -1, 158, 159, 160, -1, -1, 163, + -1, 165, 166, -1, -1, 169, -1, -1, -1, 16, + 17, 18, 19, 20, 21, 22, 23, -1, -1, -1, + -1, 50, 51, -1, -1, 54, 33, 56, 57, 58, + -1, -1, -1, 62, -1, -1, -1, 66, 67, -1, + -1, -1, -1, -1, -1, -1, 75, 76, 77, -1, + -1, -1, 81, -1, -1, 84, 85, 86, 87, 88, + 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, + 99, 100, -1, -1, -1, -1, -1, -1, -1, -1, + 109, -1, 111, -1, 113, -1, -1, -1, -1, 118, + -1, 120, 121, 122, -1, -1, 125, -1, -1, -1, + -1, 130, -1, -1, 133, -1, -1, -1, 137, 3, + 4, 5, 6, 142, 8, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1, -1, 155, -1, -1, 158, 159, 160, -1, -1, 163, -1, 165, 166, -1, -1, - 169, -1, -1, -1, -1, -1, -1, -1, -1, 3, - 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, - -1, 15, 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, -1, -1, -1, -1, -1, -1, -1, 33, - 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, - 44, 45, 46, 47, 48, 49, 50, 51, -1, 1479, - 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, - 64, 65, 66, 67, 68, -1, 70, -1, 72, 73, - 74, 75, 76, 77, 78, 79, 80, -1, 82, 83, - 84, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 100, -1, 1528, -1, - -1, -1, -1, 107, 108, 109, -1, 111, 112, 113, - 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, - 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, - 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, - -1, -1, -1, 147, 148, 149, 150, 151, 152, 153, - 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, - 164, 165, 166, 167, -1, 169, 170, 3, 4, 5, - 6, -1, 8, 9, 10, 11, 12, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 16, + 169, -1, 149, -1, -1, 152, 153, 154, 155, 156, + 157, 158, 159, 160, 161, 162, 50, 164, 165, 166, + 54, -1, 56, 57, 58, -1, -1, -1, 62, -1, + -1, -1, 66, 67, -1, -1, -1, -1, -1, -1, + -1, 75, 76, 77, -1, -1, -1, 81, -1, -1, + 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, + 94, 95, 96, 97, 98, 99, 100, -1, -1, -1, + -1, -1, -1, -1, -1, 109, -1, 111, -1, 113, + -1, -1, -1, -1, 118, -1, 120, 121, 122, -1, + -1, 125, -1, -1, -1, -1, 130, -1, -1, 133, + -1, -1, -1, 137, 3, 4, 5, 6, 142, 8, + 9, 10, 11, 147, -1, -1, -1, -1, -1, -1, + -1, 155, -1, -1, 158, 159, 160, -1, -1, 163, + -1, 165, 166, -1, -1, 169, -1, -1, -1, 16, 17, 18, 19, 20, 21, 22, 23, -1, -1, -1, - -1, -1, -1, -1, 50, 51, 33, -1, 54, -1, - 56, 57, 58, 59, 60, -1, 62, 63, -1, -1, - 66, 67, -1, -1, 70, -1, -1, -1, -1, 75, - 76, 77, -1, -1, -1, 81, -1, -1, 84, 85, - 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, - 96, 97, 98, 99, 100, -1, -1, -1, -1, -1, - -1, -1, -1, 109, -1, 111, -1, 113, -1, -1, - -1, -1, 118, -1, 120, 121, 122, -1, -1, 125, - 126, -1, -1, -1, 130, -1, -1, 133, 134, 135, - 136, 137, -1, -1, 140, -1, 142, 3, 4, 5, - 6, -1, 8, 9, 10, 11, -1, -1, -1, 155, - -1, -1, 158, 159, 160, -1, -1, 163, -1, 165, - 166, -1, -1, 169, -1, 152, 153, 154, 155, 156, - 157, 158, 159, 160, 161, 162, -1, 164, 165, 166, - -1, -1, -1, 170, 50, 51, -1, -1, 54, -1, - 56, 57, 58, 59, -1, -1, 62, 63, -1, -1, - 66, 67, -1, -1, 70, -1, -1, -1, -1, 75, - 76, 77, -1, -1, -1, 81, -1, -1, 84, 85, - 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, - 96, 97, 98, 99, 100, 54, -1, 56, 57, 58, - -1, -1, -1, 109, -1, 111, -1, 113, -1, -1, - -1, -1, 118, -1, 120, 121, 122, -1, -1, 125, - 126, -1, -1, -1, 130, 84, -1, 133, 134, 135, - 136, 137, -1, -1, 140, -1, 142, 3, 4, 5, - 6, 100, 8, 9, 10, 11, -1, -1, -1, 155, - -1, -1, 158, 159, 160, -1, -1, 163, -1, 165, - 166, 120, 121, 169, -1, -1, -1, -1, 16, 17, - 18, 19, 20, 21, 22, 23, -1, -1, 137, -1, - -1, -1, -1, 142, 50, 33, -1, -1, 54, -1, - 56, 57, 58, -1, -1, -1, 62, -1, 64, 65, - 66, 67, -1, -1, -1, -1, 165, -1, -1, 75, - 76, 77, -1, -1, -1, 81, -1, -1, 84, 85, - 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, - 96, 97, 98, 99, 100, -1, -1, -1, -1, -1, - -1, -1, -1, 109, -1, 111, -1, 113, -1, -1, - -1, -1, 118, -1, 120, 121, 122, -1, -1, 125, - -1, -1, -1, -1, 130, -1, -1, 133, -1, -1, - -1, 137, 3, 4, 5, 6, 142, 8, 9, 10, - 11, 147, -1, -1, -1, -1, -1, -1, -1, 155, - -1, -1, 158, 159, 160, -1, -1, 163, -1, 165, - 166, -1, 150, 169, 152, 153, 154, 155, 156, 157, - 158, 159, 160, 161, 162, -1, 164, 165, 166, 50, - -1, -1, -1, 54, -1, 56, 57, 58, -1, -1, - -1, 62, -1, -1, -1, 66, 67, -1, 10, 11, - 12, -1, -1, -1, 75, 76, 77, -1, -1, -1, - 81, -1, -1, 84, 85, 86, 87, 88, 89, 90, - 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, - -1, -1, -1, -1, -1, 47, -1, 49, 109, -1, - 111, -1, 113, -1, -1, -1, -1, 118, -1, 120, - 121, 122, 64, -1, 125, -1, -1, -1, -1, 130, - -1, -1, 133, -1, 76, 77, 137, 3, 4, 5, - 6, 142, 8, 9, 10, 11, -1, -1, -1, -1, - -1, -1, -1, -1, 155, -1, -1, 158, 159, 160, - -1, -1, 163, -1, 165, 166, 167, -1, 169, -1, - -1, 113, 114, -1, 116, -1, -1, -1, -1, 121, - -1, 123, -1, -1, 50, 51, -1, -1, 54, -1, - 56, 57, 58, -1, -1, -1, 62, -1, -1, -1, - 66, 67, -1, -1, -1, 147, -1, -1, -1, 75, - 76, 77, -1, -1, -1, 81, -1, -1, 84, 85, - 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, - 96, 97, 98, 99, 100, -1, -1, -1, -1, -1, - -1, -1, -1, 109, -1, 111, -1, 113, -1, -1, - -1, -1, 118, -1, 120, 121, 122, -1, -1, 125, - -1, -1, -1, -1, 130, -1, -1, 133, -1, -1, - -1, 137, 3, 4, 5, 6, 142, 8, 9, 10, - 11, -1, -1, -1, -1, -1, -1, -1, -1, 155, - -1, -1, 158, 159, 160, -1, -1, 163, -1, 165, - 166, -1, -1, 169, -1, -1, -1, 16, 17, 18, - 19, 20, 21, 22, 23, -1, -1, -1, -1, 50, - 51, -1, -1, 54, 33, 56, 57, 58, -1, -1, - -1, 62, -1, -1, -1, 66, 67, -1, -1, -1, - -1, -1, -1, -1, 75, 76, 77, -1, -1, -1, - 81, -1, -1, 84, 85, 86, 87, 88, 89, 90, - 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, - -1, -1, -1, -1, -1, -1, -1, -1, 109, -1, - 111, -1, 113, -1, -1, -1, -1, 118, -1, 120, - 121, 122, -1, -1, 125, -1, -1, -1, -1, 130, - -1, -1, 133, -1, -1, -1, 137, 3, 4, 5, - 6, 142, 8, 9, 10, 11, -1, -1, -1, -1, - -1, -1, -1, -1, 155, -1, -1, 158, 159, 160, - -1, -1, 163, -1, 165, 166, -1, -1, 169, -1, - 149, -1, -1, 152, 153, 154, 155, 156, 157, 158, - 159, 160, 161, 162, 50, 164, 165, 166, 54, -1, - 56, 57, 58, -1, -1, -1, 62, -1, -1, -1, - 66, 67, -1, -1, -1, -1, -1, -1, -1, 75, - 76, 77, -1, -1, -1, 81, -1, -1, 84, 85, - 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, - 96, 97, 98, 99, 100, -1, -1, -1, -1, -1, - -1, -1, -1, 109, -1, 111, -1, 113, -1, -1, - -1, -1, 118, -1, 120, 121, 122, -1, -1, 125, - -1, -1, -1, -1, 130, -1, -1, 133, -1, -1, - -1, 137, 3, 4, 5, 6, 142, 8, 9, 10, - 11, 147, -1, -1, -1, -1, -1, -1, -1, 155, - -1, -1, 158, 159, 160, -1, -1, 163, -1, 165, - 166, -1, -1, 169, -1, -1, -1, 16, 17, 18, - 19, 20, 21, 22, 23, -1, -1, -1, -1, 50, - -1, -1, -1, 54, 33, 56, 57, 58, -1, -1, - -1, 62, -1, -1, -1, 66, 67, -1, -1, -1, - -1, -1, -1, -1, 75, 76, 77, -1, -1, -1, - 81, -1, -1, 84, 85, 86, 87, 88, 89, 90, - 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, - -1, -1, -1, -1, -1, -1, -1, -1, 109, -1, - 111, -1, 113, -1, -1, -1, -1, 118, -1, 120, - 121, 122, -1, -1, 125, -1, -1, -1, -1, 130, - -1, -1, 133, -1, -1, -1, 137, 3, 4, 5, - 6, 142, 8, 9, 10, 11, -1, -1, -1, -1, - -1, -1, -1, -1, 155, -1, -1, 158, 159, 160, - -1, -1, 163, -1, 165, 166, 167, -1, 169, 148, - -1, -1, -1, 152, 153, 154, 155, 156, 157, 158, - 159, 160, 161, 162, 50, 164, 165, 166, 54, -1, - 56, 57, 58, -1, -1, -1, 62, -1, -1, -1, - 66, 67, -1, -1, -1, -1, -1, -1, -1, 75, - 76, 77, -1, -1, -1, 81, -1, -1, 84, 85, - 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, - 96, 97, 98, 99, 100, -1, -1, -1, -1, -1, - -1, -1, -1, 109, -1, 111, -1, 113, -1, -1, - -1, -1, 118, -1, 120, 121, 122, -1, -1, 125, - -1, -1, -1, -1, 130, -1, -1, 133, -1, -1, - -1, 137, 3, 4, 5, 6, 142, 8, 9, 10, - 11, 147, -1, -1, -1, -1, -1, -1, -1, 155, - -1, -1, 158, 159, 160, -1, -1, 163, -1, 165, - 166, -1, -1, 169, -1, -1, -1, 16, 17, 18, - 19, 20, 21, 22, 23, -1, -1, -1, -1, 50, - -1, -1, -1, 54, 33, 56, 57, 58, -1, -1, - -1, 62, -1, -1, -1, 66, 67, -1, -1, -1, - -1, -1, -1, -1, 75, 76, 77, -1, -1, -1, - 81, -1, -1, 84, 85, 86, 87, 88, 89, 90, - 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, - -1, -1, -1, -1, -1, -1, -1, -1, 109, -1, - 111, -1, 113, -1, -1, -1, -1, 118, -1, 120, - 121, 122, -1, -1, 125, -1, -1, -1, -1, 130, - -1, -1, 133, -1, -1, -1, 137, 3, 4, 5, - 6, 142, 8, 9, 10, 11, -1, -1, -1, -1, - -1, -1, -1, -1, 155, -1, -1, 158, 159, 160, - -1, -1, 163, -1, 165, 166, 167, -1, 169, -1, - -1, 150, -1, 152, 153, 154, 155, 156, 157, 158, - 159, 160, 161, 162, 50, 164, 165, 166, 54, -1, - 56, 57, 58, -1, -1, -1, 62, -1, -1, -1, - 66, 67, -1, -1, -1, -1, -1, -1, -1, 75, - 76, 77, -1, -1, -1, 81, -1, -1, 84, 85, - 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, - 96, 97, 98, 99, 100, -1, -1, -1, -1, -1, - -1, -1, -1, 109, -1, 111, -1, 113, 10, 11, - 12, -1, 118, -1, 120, 121, 122, -1, -1, 125, - -1, -1, -1, -1, 130, -1, -1, 133, -1, -1, - -1, 137, 3, 4, 5, 6, 142, 8, 9, 10, - 11, 12, -1, -1, 15, -1, -1, -1, -1, 155, - -1, -1, 158, 159, 160, -1, -1, 163, -1, 165, - 166, -1, 64, 169, 16, 17, 18, 19, 20, 21, - 22, 23, -1, -1, 76, 77, 47, -1, -1, 50, - 51, 33, -1, 54, -1, 56, 57, 58, 59, 60, - -1, 62, 63, -1, -1, 66, 67, -1, -1, 70, - -1, -1, -1, -1, 75, 76, 77, -1, -1, -1, - -1, 113, 114, 84, 116, -1, -1, -1, -1, 121, - -1, 123, -1, -1, -1, -1, -1, -1, -1, 100, - -1, -1, -1, -1, -1, -1, -1, -1, 109, -1, - 111, -1, 113, -1, -1, 147, 117, 118, -1, 120, - 121, 122, -1, -1, 125, 126, -1, -1, -1, 130, - -1, -1, 133, 134, 135, 136, 137, -1, -1, 140, - -1, 142, 3, 4, 5, 6, -1, 8, 9, 10, - 11, -1, -1, -1, 155, -1, -1, 158, 159, -1, - -1, -1, 163, -1, 165, -1, -1, -1, 169, -1, - 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, - 162, -1, 164, 165, 166, 167, -1, -1, -1, 50, - -1, -1, -1, 54, -1, 56, 57, 58, -1, -1, - -1, 62, -1, -1, -1, 66, 67, -1, -1, -1, - -1, -1, -1, -1, 75, 76, 77, -1, -1, -1, - 81, -1, -1, 84, 85, 86, 87, 88, 89, 90, - 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, - -1, -1, -1, -1, -1, -1, -1, -1, 109, -1, - 111, -1, 113, 10, 11, 12, -1, 118, -1, 120, - 121, 122, -1, -1, 125, -1, -1, -1, -1, 130, - -1, -1, 133, -1, -1, -1, 137, 3, 4, 5, - 6, 142, 8, 9, 10, 11, 12, -1, -1, 15, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 163, -1, 165, 166, -1, 64, 169, 16, - 17, 18, 19, 20, 21, 22, 23, -1, -1, 76, - 77, 47, -1, -1, 50, 51, 33, -1, 54, -1, - 56, 57, 58, 59, 60, -1, 62, 63, -1, -1, - 66, 67, -1, -1, 70, -1, -1, -1, -1, 75, - 76, 77, -1, -1, -1, -1, 113, 114, 84, 116, - -1, -1, -1, -1, 121, -1, 123, -1, -1, -1, - -1, -1, -1, -1, 100, -1, -1, -1, -1, -1, - -1, -1, -1, 109, -1, 111, -1, 113, -1, -1, - 147, 117, 118, -1, 120, 121, 122, -1, -1, 125, - 126, -1, -1, -1, 130, -1, -1, 133, 134, 135, - 136, 137, -1, -1, 140, -1, 142, 3, 4, 5, - 6, -1, 8, 9, 10, -1, -1, -1, -1, 155, - -1, -1, 158, 159, -1, -1, -1, 163, -1, 165, - -1, -1, -1, 169, -1, 152, 153, 154, 155, 156, - 157, 158, 159, 160, 161, 162, -1, 164, 165, 166, - 167, -1, -1, -1, 50, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, - -1, 67, -1, -1, -1, -1, -1, -1, -1, 75, - 76, -1, -1, -1, -1, 81, -1, -1, -1, 85, - 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, - 96, 97, 98, 99, -1, -1, -1, 3, 4, 5, - 6, -1, 8, 9, 10, 111, -1, 113, -1, -1, - -1, -1, 118, -1, -1, -1, 122, -1, -1, 125, - -1, -1, -1, -1, 130, -1, -1, -1, -1, -1, - -1, -1, -1, 16, 17, 18, 19, 20, 21, 22, - 23, -1, -1, -1, 50, -1, -1, -1, -1, 155, - 33, -1, 158, 159, 160, -1, 62, 163, -1, 165, - 166, 67, -1, 169, -1, -1, -1, -1, -1, 75, - 76, -1, -1, -1, -1, 81, -1, -1, -1, 85, - 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, - 96, 97, 98, 99, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 111, -1, 113, -1, -1, - -1, -1, 118, -1, -1, 6, 122, -1, -1, 125, - -1, -1, -1, -1, 130, 16, 17, 18, 19, 20, - 21, 22, 23, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 33, -1, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, -1, 163, -1, 165, - 166, -1, -1, 169, -1, -1, -1, -1, -1, 152, - 153, 154, 155, -1, 65, 158, 159, 160, 161, 162, - -1, 164, 165, 166, -1, -1, -1, 10, 11, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 18, 19, 20, 21, 22, 23, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 33, -1, 109, 20, - 21, 22, 23, -1, -1, -1, -1, -1, 51, -1, - -1, 54, 33, 56, 57, 58, 59, -1, -1, -1, - 63, -1, -1, 66, -1, -1, -1, 70, -1, -1, - -1, -1, -1, -1, 77, -1, -1, 148, -1, -1, - 151, 84, 153, 154, 155, 156, 157, 158, 159, 160, - 161, 162, 163, -1, 165, 166, -1, 100, 169, 10, - 11, -1, -1, -1, -1, -1, -1, -1, -1, 112, - -1, -1, -1, -1, -1, -1, -1, 120, 121, -1, - -1, -1, -1, 126, 54, -1, 56, 57, 58, -1, - -1, 134, 135, 136, 137, -1, 66, 140, -1, 142, - 51, -1, -1, 54, 147, 56, 57, 58, 59, 11, - -1, -1, 63, -1, 84, 66, 153, 154, 155, 70, - 163, 158, 159, 160, 161, 162, 77, 164, 165, 166, - 100, -1, -1, 84, -1, 156, 157, 158, 159, 160, - 161, 162, -1, 164, 165, 166, 10, 11, -1, 100, - 120, 121, 54, -1, 56, 57, 58, -1, -1, -1, - -1, 112, -1, -1, -1, -1, -1, 137, -1, 120, - 121, -1, 142, -1, -1, 126, -1, -1, -1, -1, - -1, -1, 84, 134, 135, 136, 137, 51, -1, 140, - 54, 142, 56, 57, 58, 59, -1, -1, 100, 63, - -1, -1, 66, -1, -1, -1, 70, -1, -1, -1, - -1, -1, 163, 77, -1, -1, -1, -1, 120, 121, - 84, 16, 17, 18, 19, 20, 21, 22, 23, -1, - -1, -1, -1, -1, -1, 137, 100, -1, 33, -1, - 142, -1, -1, 10, 11, 12, -1, -1, 112, -1, - -1, -1, -1, -1, -1, -1, 120, 121, -1, -1, - -1, -1, 126, -1, -1, -1, -1, -1, -1, -1, - 134, 135, 136, 137, -1, -1, 140, -1, 142, 16, + -1, 50, -1, -1, -1, 54, 33, 56, 57, 58, + -1, -1, -1, 62, -1, -1, -1, 66, 67, -1, + -1, -1, -1, -1, -1, -1, 75, 76, 77, -1, + -1, -1, 81, -1, -1, 84, 85, 86, 87, 88, + 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, + 99, 100, -1, -1, -1, -1, -1, -1, -1, -1, + 109, -1, 111, -1, 113, -1, -1, -1, -1, 118, + -1, 120, 121, 122, -1, -1, 125, -1, -1, -1, + -1, 130, -1, -1, 133, -1, -1, -1, 137, 3, + 4, 5, 6, 142, 8, 9, 10, 11, -1, -1, + -1, -1, -1, -1, -1, -1, 155, -1, -1, 158, + 159, 160, -1, -1, 163, -1, 165, 166, 167, -1, + 169, -1, -1, 150, -1, 152, 153, 154, 155, 156, + 157, 158, 159, 160, 161, 162, 50, 164, 165, 166, + 54, -1, 56, 57, 58, -1, -1, -1, 62, -1, + -1, -1, 66, 67, -1, -1, -1, -1, -1, -1, + -1, 75, 76, 77, -1, -1, -1, 81, -1, -1, + 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, + 94, 95, 96, 97, 98, 99, 100, -1, -1, -1, + -1, -1, -1, -1, -1, 109, -1, 111, -1, 113, + -1, -1, -1, -1, 118, -1, 120, 121, 122, -1, + -1, 125, -1, -1, -1, -1, 130, -1, -1, 133, + -1, -1, -1, 137, 3, 4, 5, 6, 142, 8, + 9, 10, 11, 147, -1, -1, -1, -1, -1, -1, + -1, 155, -1, -1, 158, 159, 160, -1, -1, 163, + -1, 165, 166, -1, -1, 169, -1, -1, -1, 16, 17, 18, 19, 20, 21, 22, 23, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 33, 64, -1, 163, - 16, 17, 18, 19, 20, 21, 22, 23, -1, 76, - 77, -1, -1, -1, -1, -1, -1, 33, 16, 17, - 18, 19, 20, 21, 22, 23, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 33, 16, 17, 18, 19, - 20, 21, 22, 23, -1, -1, 113, 114, -1, 116, - -1, -1, -1, 33, 121, -1, 123, 152, 153, 154, - 155, 156, 157, 158, 159, 160, 161, 162, -1, 164, - 165, 166, 167, 16, 17, 18, 19, 20, 21, 22, - 23, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 33, 16, 17, 18, 19, 20, 21, 22, 23, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 33, -1, - -1, -1, -1, -1, -1, 152, 153, 154, 155, 156, - 157, 158, 159, 160, 161, 162, -1, 164, 165, 166, - 167, -1, -1, -1, -1, -1, 152, 153, 154, 155, - 156, 157, 158, 159, 160, 161, 162, -1, 164, 165, - 166, 167, -1, -1, 152, 153, 154, 155, 156, 157, - 158, 159, 160, 161, 162, -1, 164, 165, 166, 167, - -1, -1, 152, 153, 154, 155, 156, 157, 158, 159, - 160, 161, 162, -1, 164, 165, 166, 167, 16, 17, - 18, 19, 20, 21, 22, 23, 54, -1, 56, 57, - 58, -1, -1, -1, -1, 33, -1, -1, -1, 152, - 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, - -1, 164, 165, 166, 167, -1, 84, 152, 153, 154, - 155, 156, 157, 158, 159, 160, 161, 162, 0, 164, - 165, 166, 100, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 18, 19, 20, 21, 22, 23, - -1, -1, 120, 121, -1, -1, -1, -1, -1, 33, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 137, - -1, -1, -1, -1, 142, 47, -1, 49, -1, -1, - 52, 53, -1, -1, -1, -1, -1, -1, 60, 61, - 18, 19, 20, 21, 22, 23, -1, 69, -1, 71, - 72, 73, 74, -1, -1, 33, 78, -1, -1, -1, - -1, 83, -1, -1, 152, 153, 154, 155, 156, 157, - 158, 159, 160, 161, 162, -1, 164, 165, 166, 101, - 102, 103, 104, 105, 106, 107, 108, -1, -1, -1, - -1, -1, 114, 115, 116, 117, -1, -1, -1, -1, - -1, 123, 124, 11, 12, 127, 128, 15, -1, 17, - 132, -1, -1, -1, -1, -1, 138, 139, -1, 141, - -1, -1, -1, -1, -1, -1, -1, 149, -1, 153, - 154, 155, 156, 157, 158, 159, 160, 161, 162, 47, - 164, 165, 166, 51, -1, -1, 54, -1, 56, 57, - 58, 59, 60, -1, -1, 63, -1, -1, 66, -1, - -1, -1, 70, -1, -1, -1, -1, -1, -1, 77, - 18, 19, 20, 21, 22, 23, 84, 155, 156, 157, - 158, 159, 160, 161, 162, 33, 164, 165, 166, 10, - 11, 12, 100, 18, 19, 20, 21, 22, 23, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 33, 117, - -1, -1, 120, 121, -1, -1, -1, -1, 126, -1, - 18, 19, 20, 21, 22, 23, 134, 135, 136, 137, - -1, -1, 140, -1, 142, 33, -1, -1, -1, -1, - -1, -1, -1, 64, -1, -1, -1, 155, -1, -1, - -1, -1, 160, -1, -1, 76, 77, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 108, -1, -1, - -1, -1, 113, 114, -1, 116, -1, -1, -1, -1, - 121, -1, 123, -1, 6, -1, -1, -1, 156, 157, - 158, 159, 160, 161, 162, -1, 164, 165, 166, -1, - -1, -1, -1, -1, -1, 10, 11, 12, -1, 154, - 155, 6, -1, 158, 159, 160, 161, 162, -1, 164, - 165, 166, -1, -1, -1, 47, -1, 49, -1, -1, - -1, 53, -1, -1, -1, -1, -1, 155, 60, 61, - 158, 159, 160, 161, 162, -1, 164, 165, 166, 71, - 72, 73, 47, -1, 49, -1, -1, -1, 53, 64, - -1, 83, -1, -1, -1, 60, 61, -1, -1, -1, - -1, 76, 77, -1, -1, -1, 71, 72, 73, -1, - -1, -1, -1, -1, -1, 107, -1, -1, 83, -1, - -1, 10, 11, 12, -1, 117, -1, -1, -1, -1, - -1, 123, -1, -1, -1, 127, 128, -1, 113, 114, - 115, 116, 107, -1, -1, -1, 121, 139, 123, 141, - -1, -1, 117, 10, 11, 12, -1, -1, 123, 134, - -1, -1, -1, 128, 139, 54, -1, 56, 57, 58, - 59, 60, -1, -1, 139, -1, 141, 66, -1, -1, - -1, -1, -1, 10, 11, 12, -1, -1, 77, -1, - -1, -1, -1, -1, -1, 84, -1, 54, -1, 56, - 57, 58, -1, -1, -1, -1, -1, -1, -1, 66, + -1, 50, -1, -1, -1, 54, 33, 56, 57, 58, + -1, -1, -1, 62, -1, -1, -1, 66, 67, -1, + -1, -1, -1, -1, -1, -1, 75, 76, 77, -1, + -1, -1, 81, -1, -1, 84, 85, 86, 87, 88, + 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, + 99, 100, -1, -1, -1, -1, -1, -1, -1, -1, + 109, -1, 111, -1, 113, -1, -1, -1, -1, 118, + -1, 120, 121, 122, -1, -1, 125, -1, -1, -1, + -1, 130, -1, -1, 133, -1, -1, -1, 137, 3, + 4, 5, 6, 142, 8, 9, 10, 11, -1, -1, + -1, -1, -1, -1, -1, -1, 155, -1, -1, 158, + 159, 160, -1, -1, 163, -1, 165, 166, 167, -1, + 169, 148, -1, -1, -1, 152, 153, 154, 155, 156, + 157, 158, 159, 160, 161, 162, 50, 164, 165, 166, + 54, -1, 56, 57, 58, -1, -1, -1, 62, -1, + -1, -1, 66, 67, -1, -1, -1, -1, -1, -1, + -1, 75, 76, 77, -1, -1, -1, 81, -1, -1, + 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, + 94, 95, 96, 97, 98, 99, 100, -1, -1, -1, + -1, -1, -1, -1, -1, 109, -1, 111, -1, 113, + 10, 11, 12, -1, 118, -1, 120, 121, 122, -1, + -1, 125, -1, -1, -1, -1, 130, -1, -1, 133, + -1, -1, -1, 137, 3, 4, 5, 6, 142, 8, + 9, 10, 11, 12, -1, -1, 15, -1, -1, -1, + -1, 155, -1, -1, 158, 159, 160, -1, -1, 163, + -1, 165, 166, -1, 64, 169, 16, 17, 18, 19, + 20, 21, 22, 23, -1, -1, 76, 77, 47, -1, + -1, 50, 51, 33, -1, 54, -1, 56, 57, 58, + 59, 60, -1, 62, 63, -1, -1, 66, 67, -1, + -1, 70, -1, -1, -1, -1, 75, 76, 77, -1, + -1, -1, -1, 113, 114, 84, 116, -1, -1, -1, + -1, 121, -1, 123, -1, -1, -1, -1, -1, -1, -1, 100, -1, -1, -1, -1, -1, -1, -1, -1, - 77, -1, 11, 12, -1, -1, 15, 84, -1, -1, - -1, 120, 121, -1, -1, -1, -1, 64, -1, -1, - -1, -1, -1, 100, -1, 134, -1, -1, 137, 76, - 77, 140, -1, 142, -1, -1, -1, -1, 47, -1, - -1, -1, 51, 120, 121, 54, -1, 56, 57, 58, - 59, 60, -1, -1, 63, -1, -1, 66, -1, -1, - 137, 70, -1, 140, -1, 142, 113, 114, 77, 116, - -1, -1, -1, -1, 121, 84, 123, -1, -1, -1, - -1, -1, -1, -1, 10, 11, 12, 134, -1, -1, - -1, 100, 139, -1, 11, 12, -1, -1, 15, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 117, -1, - -1, 120, 121, -1, -1, -1, -1, 126, -1, -1, - -1, -1, -1, 11, 12, 134, 135, 136, 137, -1, - 47, 140, -1, 142, 51, -1, -1, 54, 64, 56, - 57, 58, 59, 60, -1, -1, 63, -1, -1, 66, - 76, 77, -1, 70, -1, -1, -1, -1, -1, 47, - 77, -1, -1, 51, -1, -1, 54, 84, 56, 57, - 58, 59, 60, -1, -1, 63, -1, -1, 66, -1, - -1, -1, 70, 100, -1, -1, -1, 113, 114, 77, - 116, -1, -1, -1, -1, 121, 84, 123, -1, -1, - 117, -1, -1, 120, 121, -1, -1, -1, 134, 126, - 11, 12, 100, 139, -1, -1, -1, 134, 135, 136, - 137, -1, -1, 140, -1, 142, -1, -1, -1, 117, - -1, -1, 120, 121, 11, 12, -1, -1, 126, -1, - -1, -1, 10, 11, 12, -1, 134, 135, 136, 137, - 51, -1, 140, 54, 142, 56, 57, 58, 59, 60, - -1, -1, 63, -1, 54, 66, 56, 57, 58, 70, - -1, -1, -1, -1, 51, -1, 77, 54, -1, 56, - 57, 58, 59, 84, -1, -1, 63, -1, -1, 66, - -1, -1, -1, 70, 84, -1, 64, -1, -1, 100, - 77, -1, -1, -1, -1, -1, -1, 84, 76, 77, - 100, -1, -1, -1, -1, -1, -1, -1, -1, 120, - 121, 11, 12, 100, -1, 126, -1, -1, -1, -1, - 120, 121, -1, 134, 135, 136, 137, -1, -1, 140, - 117, 142, -1, 120, 121, 113, 114, 137, 116, 126, - 11, -1, 142, 121, -1, 123, -1, 134, 135, 136, - 137, 51, -1, 140, 54, 142, 56, 57, 58, 59, - 138, -1, -1, 63, -1, 165, 66, -1, -1, -1, + 109, -1, 111, -1, 113, -1, -1, 147, 117, 118, + -1, 120, 121, 122, -1, -1, 125, 126, -1, -1, + -1, 130, -1, -1, 133, 134, 135, 136, 137, -1, + -1, 140, -1, 142, 3, 4, 5, 6, -1, 8, + 9, 10, 11, -1, -1, -1, 155, -1, -1, 158, + 159, -1, -1, -1, 163, -1, 165, -1, 148, -1, + 169, -1, 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, -1, 164, 165, 166, 167, -1, -1, + -1, 50, -1, -1, -1, 54, -1, 56, 57, 58, + -1, -1, -1, 62, -1, -1, -1, 66, 67, -1, + -1, -1, -1, -1, -1, -1, 75, 76, 77, -1, + -1, -1, 81, -1, -1, 84, 85, 86, 87, 88, + 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, + 99, 100, -1, -1, -1, -1, -1, -1, -1, -1, + 109, -1, 111, -1, 113, 10, 11, 12, -1, 118, + -1, 120, 121, 122, -1, -1, 125, -1, -1, -1, + -1, 130, -1, -1, 133, -1, -1, -1, 137, 3, + 4, 5, 6, 142, 8, 9, 10, 11, 12, -1, + -1, 15, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 163, -1, 165, 166, -1, 64, + 169, 16, 17, 18, 19, 20, 21, 22, 23, -1, + -1, 76, 77, 47, -1, -1, 50, 51, 33, -1, + 54, -1, 56, 57, 58, 59, 60, -1, 62, 63, + -1, -1, 66, 67, -1, -1, 70, -1, -1, -1, + -1, 75, 76, 77, -1, -1, -1, -1, 113, 114, + 84, 116, -1, -1, -1, -1, 121, -1, 123, -1, + 10, 11, 12, -1, -1, -1, 100, -1, -1, 134, + -1, -1, -1, -1, 139, 109, -1, 111, -1, 113, + -1, -1, -1, 117, 118, -1, 120, 121, 122, -1, + -1, 125, 126, -1, -1, -1, 130, -1, -1, 133, + 134, 135, 136, 137, -1, -1, 140, -1, 142, -1, + 3, 4, 5, 6, 64, 8, 9, 10, -1, -1, + -1, 155, 15, -1, 158, 159, 76, 77, -1, 163, + -1, 165, -1, -1, -1, 169, -1, 152, 153, 154, + 155, 156, 157, 158, 159, 160, 161, 162, -1, 164, + 165, 166, 167, -1, -1, -1, -1, 50, -1, -1, + -1, -1, -1, 113, 114, 115, 116, -1, -1, 62, + -1, 121, -1, 123, 67, -1, -1, -1, -1, -1, + -1, -1, 75, 76, 134, -1, -1, -1, 81, 139, + -1, -1, 85, 86, 87, 88, 89, 90, 91, 92, + 93, 94, 95, 96, 97, 98, 99, -1, -1, -1, + 3, 4, 5, 6, -1, 8, 9, 10, 111, -1, + 113, -1, -1, -1, -1, 118, -1, -1, -1, 122, + -1, -1, 125, -1, -1, -1, -1, 130, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 50, -1, -1, + -1, -1, 155, -1, -1, 158, 159, 160, -1, 62, + 163, -1, 165, 166, 67, -1, 169, -1, -1, -1, + -1, -1, 75, 76, -1, -1, -1, -1, 81, -1, + -1, -1, 85, 86, 87, 88, 89, 90, 91, 92, + 93, 94, 95, 96, 97, 98, 99, -1, -1, -1, + 3, 4, 5, 6, -1, 8, 9, 10, 111, -1, + 113, -1, -1, -1, -1, 118, -1, -1, -1, 122, + -1, -1, 125, -1, -1, -1, -1, 130, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 50, -1, -1, + -1, -1, 155, -1, -1, 158, 159, 160, -1, 62, + 163, -1, 165, 166, 67, -1, 169, -1, -1, -1, + -1, -1, 75, 76, -1, -1, -1, -1, 81, -1, + -1, -1, 85, 86, 87, 88, 89, 90, 91, 92, + 93, 94, 95, 96, 97, 98, 99, 10, 11, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 111, -1, + 113, -1, -1, -1, -1, 118, -1, -1, -1, 122, + -1, -1, 125, -1, -1, -1, -1, 130, -1, -1, + 16, 17, 18, 19, 20, 21, 22, 23, 51, -1, + -1, 54, -1, 56, 57, 58, 59, 33, -1, -1, + 63, -1, -1, 66, -1, -1, -1, 70, -1, -1, + 163, -1, 165, 166, 77, -1, 169, -1, -1, -1, + -1, 84, 16, 17, 18, 19, 20, 21, 22, 23, + -1, -1, -1, -1, -1, -1, -1, 100, -1, 33, + -1, 10, 11, 12, -1, -1, -1, -1, -1, 112, + -1, -1, -1, -1, -1, -1, -1, 120, 121, -1, + -1, -1, -1, 126, -1, -1, -1, -1, -1, -1, + -1, 134, 135, 136, 137, -1, -1, 140, -1, 142, + 16, 17, 18, 19, 20, 21, 22, 23, -1, -1, + -1, -1, -1, -1, -1, 64, -1, 33, -1, -1, + 163, -1, -1, -1, -1, -1, -1, 76, 77, -1, + -1, -1, -1, -1, -1, -1, 152, 153, 154, 155, + 156, 157, 158, 159, 160, 161, 162, -1, 164, 165, + 166, 167, 16, 17, 18, 19, 20, 21, 22, 23, + -1, -1, -1, -1, 113, 114, -1, 116, -1, 33, + -1, -1, 121, -1, 123, -1, -1, -1, 152, 153, + 154, 155, 156, 157, 158, 159, 160, 161, 162, 138, + 164, 165, 166, 167, 16, 17, 18, 19, 20, 21, + 22, 23, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 33, 16, 17, 18, 19, 20, 21, 22, 23, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 33, + -1, -1, -1, -1, -1, -1, 152, 153, 154, 155, + 156, 157, 158, 159, 160, 161, 162, -1, 164, 165, + 166, 167, 16, 17, 18, 19, 20, 21, 22, 23, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 33, + 16, 17, 18, 19, 20, 21, 22, 23, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 33, 152, 153, + 154, 155, 156, 157, 158, 159, 160, 161, 162, -1, + 164, 165, 166, 167, 16, 17, 18, 19, 20, 21, + 22, 23, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 33, -1, -1, -1, -1, -1, -1, -1, -1, + 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, + 162, -1, 164, 165, 166, 167, -1, -1, 152, 153, + 154, 155, 156, 157, 158, 159, 160, 161, 162, -1, + 164, 165, 166, 167, -1, 17, 18, 19, 20, 21, + 22, 23, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 33, -1, -1, -1, -1, -1, -1, 152, 153, + 154, 155, 156, 157, 158, 159, 160, 161, 162, -1, + 164, 165, 166, 167, -1, -1, 152, 153, 154, 155, + 156, 157, 158, 159, 160, 161, 162, 0, 164, 165, + 166, 18, 19, 20, 21, 22, 23, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 33, -1, -1, -1, + 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, + 162, -1, 164, 165, 166, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 47, -1, 49, -1, -1, 52, + 53, -1, -1, -1, -1, -1, -1, 60, 61, 18, + 19, 20, 21, 22, 23, -1, 69, -1, 71, 72, + 73, 74, -1, -1, 33, 78, -1, -1, -1, -1, + 83, 153, 154, 155, -1, -1, 158, 159, 160, 161, + 162, -1, 164, 165, 166, -1, -1, -1, 101, 102, + 103, 104, 105, 106, 107, 108, 10, 11, 12, -1, + -1, 114, 115, 116, 117, -1, -1, -1, -1, -1, + 123, 124, 11, 12, 127, 128, 15, -1, 17, 132, + -1, -1, -1, -1, -1, 138, 139, -1, 141, 156, + 157, 158, 159, 160, 161, 162, 149, 164, 165, 166, + -1, -1, -1, -1, -1, -1, -1, -1, 47, -1, + 64, -1, 51, -1, -1, 54, -1, 56, 57, 58, + 59, 60, 76, 77, 63, 6, -1, 66, -1, -1, + -1, 70, -1, -1, -1, -1, -1, -1, 77, -1, + -1, -1, -1, -1, -1, 84, 155, -1, -1, 158, + 159, 160, 161, 162, 108, 164, 165, 166, -1, 113, + 114, 100, 116, 10, 11, 12, 47, 121, 49, 123, + -1, -1, 53, 10, 11, 12, -1, -1, 117, 60, + 61, 120, 121, -1, -1, -1, -1, 126, -1, -1, + 71, 72, 73, -1, -1, 134, 135, 136, 137, -1, + -1, 140, 83, 142, -1, -1, -1, 54, -1, 56, + 57, 58, 59, 60, -1, -1, 155, -1, -1, 66, + -1, 160, 10, 11, 12, -1, 107, 64, -1, -1, + 77, -1, -1, -1, -1, -1, 117, 84, -1, 76, + 77, -1, 123, -1, -1, -1, 127, 128, -1, -1, + -1, -1, 54, 100, 56, 57, 58, -1, 139, -1, + 141, 11, 12, -1, 66, 15, 54, -1, 56, 57, + 58, -1, -1, 120, 121, -1, 113, 114, 66, 116, + -1, -1, 84, -1, 121, -1, 123, 134, -1, 77, + 137, -1, -1, 140, -1, 142, 84, 47, 100, -1, + -1, 51, -1, -1, 54, -1, 56, 57, 58, 59, + 60, -1, 100, 63, -1, -1, 66, -1, 120, 121, 70, -1, -1, -1, -1, -1, -1, 77, -1, -1, - 51, -1, -1, 54, 84, 56, 57, 58, 59, 60, - -1, -1, 63, -1, -1, 66, -1, -1, -1, 70, - 100, -1, -1, -1, -1, -1, 77, -1, -1, -1, - -1, -1, -1, 84, -1, -1, -1, -1, -1, -1, - 120, 121, -1, -1, -1, -1, 126, 11, -1, 100, - -1, -1, -1, -1, 134, 135, 136, 137, -1, -1, - 140, -1, 142, -1, -1, -1, -1, -1, -1, 120, - 121, 11, -1, -1, -1, 126, -1, -1, -1, -1, - -1, -1, -1, 134, 135, 136, 137, 51, -1, 140, - 54, 142, 56, 57, 58, 59, 60, -1, -1, 63, + -1, -1, 120, 121, 84, 137, -1, -1, -1, -1, + 142, -1, 54, -1, 56, 57, 58, -1, -1, 137, + 100, -1, 140, -1, 142, 11, 12, -1, -1, 15, + -1, -1, -1, 165, -1, -1, -1, 117, -1, -1, + 120, 121, 84, -1, -1, -1, 126, -1, -1, -1, + -1, -1, -1, -1, 134, 135, 136, 137, 100, -1, + 140, 47, 142, 11, 12, 51, -1, -1, 54, -1, + 56, 57, 58, 59, 60, -1, -1, 63, 120, 121, + 66, -1, -1, -1, 70, -1, -1, -1, -1, -1, + -1, 77, -1, -1, -1, 137, -1, -1, 84, 47, + 142, -1, -1, 51, -1, -1, 54, -1, 56, 57, + 58, 59, 60, -1, 100, 63, -1, -1, 66, -1, + -1, -1, 70, 165, -1, -1, -1, -1, -1, 77, + -1, 117, -1, -1, 120, 121, 84, -1, -1, -1, + 126, -1, -1, -1, -1, -1, -1, -1, 134, 135, + 136, 137, 100, -1, 140, -1, 142, 11, 12, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 117, + -1, -1, 120, 121, -1, -1, -1, -1, 126, -1, + -1, 11, 12, -1, -1, -1, 134, 135, 136, 137, + -1, -1, 140, -1, 142, -1, -1, 51, -1, -1, + 54, -1, 56, 57, 58, 59, 60, -1, -1, 63, -1, -1, 66, -1, -1, -1, 70, -1, -1, -1, -1, 51, -1, 77, 54, -1, 56, 57, 58, 59, 84, -1, -1, 63, -1, -1, 66, -1, -1, -1, 70, -1, -1, -1, -1, -1, 100, 77, -1, -1, -1, -1, -1, -1, 84, 10, 11, 12, -1, -1, - -1, -1, -1, -1, -1, -1, 120, 121, 11, -1, + -1, -1, -1, -1, -1, -1, 120, 121, 11, 12, 100, -1, 126, -1, -1, -1, -1, -1, -1, -1, - 134, 135, 136, 137, -1, -1, 140, -1, 142, -1, - 120, 121, -1, -1, -1, -1, 126, 10, 11, 12, + 134, 135, 136, 137, -1, -1, 140, 117, 142, -1, + 120, 121, -1, -1, -1, -1, 126, 11, -1, -1, -1, -1, -1, -1, 134, 135, 136, 137, 51, 64, 140, 54, 142, 56, 57, 58, 59, -1, -1, -1, 63, 76, 77, 66, -1, -1, -1, 70, -1, -1, - -1, -1, -1, -1, 77, -1, -1, -1, -1, -1, - -1, 84, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 64, -1, -1, -1, -1, -1, 100, 113, 114, - -1, 116, -1, 76, 77, -1, 121, -1, 123, -1, - -1, -1, 54, -1, 56, 57, 58, 120, 121, 134, - -1, -1, -1, 126, 139, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 77, -1, -1, 51, -1, -1, + 54, 84, 56, 57, 58, 59, 60, -1, -1, 63, + -1, -1, 66, -1, -1, -1, 70, 100, 113, 114, + -1, 116, -1, 77, -1, -1, 121, -1, 123, -1, + 84, -1, -1, -1, -1, -1, -1, 120, 121, 134, + -1, -1, -1, 126, 11, -1, 100, -1, -1, -1, -1, 134, 135, 136, 137, -1, -1, 140, -1, 142, - 113, 114, 84, 116, -1, -1, -1, -1, 121, 47, - 123, 49, -1, -1, 52, 53, -1, -1, 100, -1, - -1, 134, 60, 61, -1, -1, -1, -1, -1, -1, - -1, 69, -1, 71, 72, 73, 74, -1, 120, 121, + -1, -1, -1, -1, -1, -1, 120, 121, 11, -1, + -1, -1, 126, -1, -1, -1, -1, -1, -1, -1, + 134, 135, 136, 137, 51, -1, 140, 54, 142, 56, + 57, 58, 59, 60, -1, -1, 63, -1, -1, 66, + -1, -1, -1, 70, -1, -1, -1, -1, 51, -1, + 77, 54, -1, 56, 57, 58, 59, 84, -1, -1, + 63, -1, -1, 66, -1, -1, -1, 70, -1, -1, + -1, -1, -1, 100, 77, -1, -1, -1, -1, -1, + -1, 84, 10, 11, 12, -1, -1, -1, -1, -1, + -1, -1, -1, 120, 121, 11, -1, 100, -1, 126, + -1, -1, -1, -1, -1, -1, -1, 134, 135, 136, + 137, -1, -1, 140, -1, 142, -1, 120, 121, -1, + -1, -1, -1, 126, 10, 11, 12, -1, -1, -1, + -1, 134, 135, 136, 137, 51, 64, 140, 54, 142, + 56, 57, 58, 59, -1, -1, -1, 63, 76, 77, + 66, -1, -1, -1, 70, -1, -1, -1, -1, -1, + -1, 77, -1, -1, -1, -1, -1, -1, 84, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 64, -1, + -1, -1, -1, -1, 100, 113, 114, -1, 116, -1, + 76, 77, -1, 121, -1, 123, -1, -1, -1, 54, + -1, 56, 57, 58, 120, 121, 134, -1, -1, -1, + 126, 139, -1, -1, -1, -1, -1, -1, 134, 135, + 136, 137, -1, -1, 140, -1, 142, 113, 114, 84, + 116, -1, -1, -1, -1, 121, 47, 123, 49, -1, + -1, 52, 53, -1, -1, 100, -1, -1, 134, 60, + 61, -1, -1, 139, -1, -1, -1, -1, 69, -1, + 71, 72, 73, 74, -1, 120, 121, 78, -1, -1, + -1, -1, 83, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 137, -1, -1, -1, -1, 142, -1, -1, + 101, 102, 103, 104, 105, 106, 107, 108, -1, -1, + -1, -1, -1, 114, 115, 116, 117, -1, -1, 47, + 165, 49, 123, 124, 52, 53, 127, 128, -1, -1, + -1, 132, 60, 61, -1, -1, -1, 138, 139, -1, + 141, 69, -1, 71, 72, 73, 74, -1, 149, -1, 78, -1, -1, -1, -1, 83, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 137, -1, -1, -1, -1, - 142, -1, -1, 101, 102, 103, 104, 105, 106, 107, + -1, -1, -1, -1, -1, -1, -1, 168, -1, -1, + -1, -1, -1, 101, 102, 103, 104, 105, 106, 107, 108, -1, -1, -1, -1, -1, 114, 115, 116, 117, - -1, -1, 47, 165, 49, 123, 124, 52, 53, 127, + -1, -1, 47, -1, 49, 123, 124, 52, 53, 127, 128, -1, -1, -1, 132, 60, 61, -1, -1, -1, 138, 139, -1, 141, 69, -1, 71, 72, 73, 74, -1, 149, -1, 78, -1, -1, -1, -1, 83, -1, @@ -3050,168 +3048,167 @@ static const yytype_int16 yycheck[] = 53, 127, 128, -1, -1, -1, 132, 60, 61, -1, -1, -1, 138, 139, -1, 141, 69, -1, 71, 72, 73, 74, -1, 149, -1, 78, -1, -1, -1, -1, - 83, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 168, -1, -1, -1, -1, -1, 101, 102, + 83, -1, -1, 10, 11, 12, -1, -1, 15, 10, + 11, 12, 168, 54, -1, 56, 57, 58, 101, 102, 103, 104, 105, 106, 107, 108, -1, -1, -1, -1, - -1, 114, 115, 116, 117, -1, -1, 47, -1, 49, - 123, 124, 52, 53, 127, 128, -1, -1, -1, 132, - 60, 61, -1, -1, -1, 138, 139, -1, 141, 69, - -1, 71, 72, 73, 74, -1, 149, -1, 78, -1, - -1, -1, -1, 83, -1, -1, 10, 11, 12, -1, - -1, 15, 10, 11, 12, 168, -1, -1, -1, -1, - -1, 101, 102, 103, 104, 105, 106, 107, 108, -1, - -1, -1, -1, -1, 114, 115, 116, 117, -1, -1, - -1, -1, -1, 123, 124, -1, -1, 127, 128, 47, - -1, 49, 132, -1, -1, -1, -1, -1, 138, 139, - 64, 141, -1, -1, -1, -1, 64, -1, 47, 149, - 49, -1, 76, 77, 53, -1, -1, -1, 76, 77, - -1, 60, 61, -1, -1, -1, -1, -1, 168, -1, - -1, -1, 71, 72, 73, -1, -1, -1, -1, 78, - -1, -1, -1, -1, 83, -1, -1, -1, -1, 113, - 114, -1, 116, -1, -1, 113, 114, 121, 116, 123, - -1, -1, -1, 121, -1, 123, -1, -1, 107, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 117, -1, - -1, -1, -1, -1, 123, -1, -1, -1, -1, 128, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 138, - 139, 47, 141, 49, -1, -1, 52, 53, -1, -1, - -1, -1, -1, -1, 60, 61, -1, 156, -1, -1, - -1, -1, -1, 69, -1, 71, 72, 73, 74, -1, - -1, -1, 78, -1, -1, -1, -1, 83, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 101, 102, 103, 104, 105, - 106, 107, 108, -1, -1, -1, -1, -1, 114, 115, - 116, 117, -1, -1, 47, -1, 49, 123, 124, -1, - 53, 127, 128, 47, -1, 49, 132, 60, 61, 53, - -1, -1, 138, 139, -1, 141, 60, 61, 71, 72, - 73, -1, -1, -1, -1, 78, -1, 71, 72, 73, - 83, -1, -1, -1, -1, -1, -1, -1, -1, 83, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 107, -1, -1, -1, -1, -1, - -1, -1, -1, 107, 117, -1, -1, -1, -1, -1, - 123, -1, -1, 117, 127, 128, -1, -1, -1, 123, - -1, -1, -1, -1, 128, 138, 139, -1, 141, -1, - -1, -1, -1, -1, -1, 139, -1, 141 + -1, 114, 115, 116, 117, -1, -1, -1, -1, -1, + 123, 124, -1, 84, 127, 128, 47, -1, 49, 132, + -1, -1, -1, -1, -1, 138, 139, 64, 141, 100, + -1, -1, -1, 64, -1, -1, 149, -1, -1, 76, + 77, -1, -1, -1, -1, 76, 77, -1, -1, 120, + 121, -1, -1, -1, -1, 168, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 137, -1, -1, -1, + -1, 142, -1, -1, -1, -1, 113, 114, -1, 116, + -1, -1, 113, 114, 121, 116, 123, 47, -1, 49, + 121, -1, 123, 53, 165, -1, 47, -1, 49, -1, + 60, 61, 53, -1, -1, -1, -1, -1, -1, 60, + 61, 71, 72, 73, -1, -1, -1, -1, 78, -1, + 71, 72, 73, 83, -1, -1, -1, 78, -1, -1, + -1, -1, 83, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 107, -1, -1, + -1, -1, -1, -1, -1, -1, 107, 117, -1, -1, + -1, -1, -1, 123, -1, -1, 117, -1, 128, -1, + -1, -1, 123, -1, -1, -1, 127, 128, 138, 139, + 47, 141, 49, -1, -1, 52, 53, 138, 139, -1, + 141, -1, -1, 60, 61, -1, 156, -1, -1, -1, + -1, -1, 69, -1, 71, 72, 73, 74, -1, -1, + -1, 78, -1, -1, -1, -1, 83, -1, 47, -1, + 49, -1, -1, -1, 53, -1, -1, -1, -1, -1, + -1, 60, 61, -1, 101, 102, 103, 104, 105, 106, + 107, 108, 71, 72, 73, -1, -1, 114, 115, 116, + 117, -1, -1, -1, 83, -1, 123, 124, -1, -1, + 127, 128, -1, -1, -1, 132, -1, 47, -1, 49, + -1, 138, 139, 53, 141, -1, -1, -1, 107, 108, + 60, 61, -1, -1, -1, -1, -1, -1, 117, -1, + -1, 71, 72, 73, 123, -1, -1, -1, -1, 128, + -1, -1, -1, 83, -1, -1, -1, -1, -1, -1, + 139, -1, 141, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 107, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 117, -1, -1, + -1, -1, -1, 123, -1, -1, -1, -1, 128, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 139, + -1, 141 }; /* YYSTOS[STATE-NUM] -- The symbol kind of the accessing symbol of state STATE-NUM. */ static const yytype_int16 yystos[] = { - 0, 144, 145, 146, 172, 173, 282, 3, 4, 5, + 0, 144, 145, 146, 172, 173, 283, 3, 4, 5, 6, 8, 9, 10, 11, 50, 54, 56, 57, 58, 62, 66, 67, 75, 76, 77, 81, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 109, 111, 113, 118, 120, 121, 122, 125, 130, 133, 137, 142, 155, 158, 159, 160, - 163, 165, 166, 169, 272, 273, 281, 11, 12, 51, + 163, 165, 166, 169, 273, 274, 282, 11, 12, 51, 54, 56, 57, 58, 59, 60, 63, 66, 70, 77, 84, 100, 120, 121, 126, 134, 135, 136, 137, 140, - 142, 234, 235, 239, 241, 243, 249, 250, 254, 255, - 260, 261, 262, 263, 0, 47, 49, 52, 53, 60, + 142, 234, 235, 239, 241, 243, 249, 251, 255, 256, + 261, 262, 263, 264, 0, 47, 49, 52, 53, 60, 61, 69, 71, 72, 73, 74, 78, 83, 101, 102, 103, 104, 105, 106, 107, 108, 114, 115, 116, 117, 123, 124, 127, 128, 132, 138, 139, 141, 149, 176, - 178, 179, 181, 185, 205, 256, 259, 282, 147, 165, + 178, 179, 181, 185, 205, 257, 260, 283, 147, 165, 165, 165, 165, 165, 165, 156, 165, 156, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 11, 51, 63, - 134, 135, 237, 254, 255, 260, 156, 165, 165, 15, - 165, 272, 156, 165, 165, 165, 272, 272, 272, 272, - 272, 11, 54, 56, 57, 58, 66, 77, 84, 100, - 120, 121, 137, 142, 239, 270, 272, 10, 11, 12, + 134, 135, 237, 255, 256, 261, 156, 165, 165, 15, + 165, 273, 156, 165, 165, 165, 273, 273, 273, 273, + 273, 11, 54, 56, 57, 58, 66, 77, 84, 100, + 120, 121, 137, 142, 239, 271, 273, 10, 11, 12, 64, 76, 77, 113, 114, 116, 121, 123, 151, 155, - 160, 276, 277, 279, 282, 272, 16, 17, 18, 19, + 160, 277, 278, 280, 283, 273, 16, 17, 18, 19, 20, 21, 22, 23, 33, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 164, 165, 166, 6, - 8, 234, 235, 165, 59, 126, 66, 100, 261, 261, - 261, 279, 165, 261, 13, 15, 17, 60, 141, 155, - 160, 165, 232, 233, 282, 233, 147, 10, 11, 12, - 113, 150, 280, 240, 282, 138, 183, 184, 279, 165, + 8, 234, 235, 165, 59, 126, 66, 100, 262, 262, + 262, 280, 165, 262, 13, 15, 17, 60, 141, 155, + 160, 165, 232, 233, 283, 233, 250, 10, 11, 12, + 113, 150, 281, 240, 283, 138, 183, 184, 280, 165, 72, 83, 181, 181, 181, 181, 6, 181, 205, 181, 150, 180, 108, 181, 165, 165, 165, 165, 165, 165, - 181, 147, 279, 150, 150, 150, 181, 181, 165, 179, - 181, 185, 206, 181, 181, 189, 108, 279, 181, 181, + 181, 147, 280, 150, 150, 150, 181, 181, 165, 179, + 181, 185, 206, 181, 181, 189, 108, 280, 181, 181, 10, 11, 51, 63, 112, 134, 135, 147, 163, 192, - 196, 236, 238, 241, 243, 249, 254, 255, 260, 269, - 270, 282, 269, 239, 269, 269, 269, 269, 239, 269, - 239, 269, 239, 269, 239, 239, 239, 239, 239, 239, - 239, 239, 239, 239, 239, 239, 239, 239, 239, 269, - 165, 279, 165, 165, 279, 240, 239, 269, 269, 165, - 239, 239, 239, 272, 269, 269, 167, 148, 167, 279, - 279, 148, 170, 151, 222, 282, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 279, 167, 270, 272, - 233, 233, 51, 272, 239, 160, 279, 47, 49, 182, - 282, 232, 233, 232, 233, 182, 182, 15, 17, 47, - 60, 117, 155, 160, 217, 218, 227, 234, 235, 282, - 166, 252, 253, 282, 11, 251, 261, 150, 10, 11, - 12, 47, 49, 113, 147, 279, 280, 279, 48, 148, - 165, 11, 236, 272, 181, 178, 147, 279, 279, 279, - 279, 279, 279, 279, 173, 147, 272, 156, 10, 11, - 196, 236, 238, 279, 149, 151, 165, 165, 165, 60, - 234, 279, 165, 177, 279, 187, 147, 149, 151, 224, - 149, 186, 279, 280, 240, 168, 167, 167, 167, 167, - 167, 167, 157, 167, 157, 167, 167, 167, 167, 148, - 167, 148, 167, 148, 167, 167, 167, 167, 167, 167, - 167, 167, 167, 167, 167, 272, 239, 269, 279, 157, - 167, 167, 279, 167, 157, 167, 167, 167, 167, 272, - 272, 15, 155, 277, 165, 202, 282, 272, 150, 167, - 170, 167, 167, 167, 182, 182, 183, 165, 13, 15, - 17, 60, 141, 155, 160, 232, 282, 232, 232, 182, - 183, 117, 234, 235, 227, 182, 182, 167, 15, 148, - 13, 17, 60, 141, 155, 160, 165, 230, 280, 282, - 13, 15, 17, 60, 141, 155, 160, 165, 231, 268, - 272, 282, 279, 168, 251, 183, 165, 242, 244, 150, - 181, 183, 3, 4, 5, 9, 10, 15, 50, 62, - 67, 75, 76, 109, 111, 113, 118, 122, 125, 130, - 133, 155, 158, 159, 163, 165, 169, 219, 220, 227, - 228, 274, 275, 281, 282, 167, 167, 173, 147, 148, - 148, 148, 148, 148, 148, 168, 257, 148, 167, 10, - 11, 12, 59, 60, 134, 207, 208, 209, 210, 211, - 260, 282, 165, 224, 190, 149, 239, 193, 10, 13, - 160, 195, 51, 272, 234, 13, 17, 60, 141, 155, - 160, 229, 280, 282, 239, 173, 165, 147, 149, 150, - 151, 223, 264, 265, 64, 65, 147, 272, 13, 17, - 60, 112, 141, 155, 160, 165, 188, 212, 214, 280, - 150, 279, 165, 165, 239, 239, 239, 167, 167, 167, - 165, 167, 165, 222, 217, 17, 33, 47, 60, 61, - 76, 107, 110, 113, 129, 141, 155, 215, 282, 272, - 232, 48, 236, 272, 160, 279, 182, 232, 232, 182, - 182, 166, 232, 48, 234, 235, 230, 231, 232, 232, - 202, 15, 227, 160, 182, 230, 230, 182, 182, 230, - 166, 222, 182, 160, 279, 182, 231, 231, 182, 182, - 231, 166, 222, 170, 148, 151, 48, 236, 272, 173, - 76, 245, 282, 184, 165, 156, 156, 237, 156, 15, - 165, 274, 156, 165, 272, 272, 272, 272, 239, 270, - 272, 167, 15, 148, 16, 17, 18, 19, 20, 21, - 22, 23, 33, 152, 153, 154, 155, 156, 157, 158, - 159, 160, 161, 162, 164, 165, 166, 181, 181, 168, - 258, 10, 10, 10, 10, 10, 10, 173, 281, 149, - 211, 157, 148, 15, 279, 13, 17, 60, 141, 155, - 160, 165, 230, 231, 191, 214, 149, 217, 167, 160, - 212, 217, 167, 167, 229, 160, 182, 229, 229, 182, - 182, 165, 166, 182, 167, 168, 197, 264, 174, 175, - 279, 64, 65, 168, 266, 282, 149, 149, 147, 225, - 226, 272, 282, 149, 160, 182, 212, 6, 16, 17, - 18, 19, 20, 21, 22, 23, 33, 35, 36, 37, - 38, 39, 40, 41, 42, 43, 44, 45, 46, 65, - 109, 148, 151, 153, 154, 155, 156, 157, 158, 159, - 160, 161, 162, 163, 165, 166, 169, 203, 212, 182, - 182, 212, 150, 165, 166, 215, 151, 222, 224, 182, - 251, 270, 270, 167, 167, 167, 270, 270, 167, 60, - 237, 183, 165, 147, 182, 167, 167, 182, 182, 232, - 232, 232, 268, 167, 227, 230, 231, 222, 222, 167, - 167, 215, 182, 230, 230, 230, 167, 268, 182, 182, - 231, 231, 231, 167, 268, 182, 272, 167, 167, 168, - 150, 246, 247, 282, 239, 239, 239, 165, 239, 165, - 239, 239, 239, 272, 167, 167, 15, 228, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 279, 167, - 270, 272, 173, 148, 148, 167, 148, 216, 282, 148, + 196, 236, 238, 241, 243, 249, 255, 256, 261, 270, + 271, 283, 270, 239, 270, 270, 270, 270, 239, 270, + 239, 270, 239, 270, 239, 239, 239, 239, 239, 239, + 239, 239, 239, 239, 239, 239, 239, 239, 239, 270, + 165, 280, 165, 165, 280, 240, 239, 270, 270, 165, + 239, 239, 239, 273, 270, 270, 167, 148, 167, 280, + 280, 148, 170, 151, 222, 283, 273, 273, 273, 273, + 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, + 273, 273, 273, 273, 273, 273, 280, 167, 271, 273, + 233, 233, 51, 273, 239, 160, 280, 47, 49, 182, + 283, 232, 233, 232, 233, 182, 182, 15, 17, 47, + 60, 117, 155, 160, 217, 218, 227, 234, 235, 283, + 166, 147, 11, 252, 262, 150, 10, 11, 12, 47, + 49, 113, 147, 280, 281, 280, 48, 148, 165, 11, + 236, 273, 181, 178, 147, 280, 280, 280, 280, 280, + 280, 280, 173, 147, 273, 156, 10, 11, 196, 236, + 238, 280, 149, 151, 165, 165, 165, 60, 234, 280, + 165, 177, 280, 187, 147, 149, 151, 224, 149, 186, + 280, 281, 240, 168, 167, 167, 167, 167, 167, 167, + 157, 167, 157, 167, 167, 167, 167, 148, 167, 148, + 167, 148, 167, 167, 167, 167, 167, 167, 167, 167, + 167, 167, 167, 273, 239, 270, 280, 157, 167, 167, + 280, 167, 157, 167, 167, 167, 167, 273, 273, 15, + 155, 278, 165, 202, 283, 273, 150, 167, 170, 167, + 167, 167, 182, 182, 183, 165, 13, 15, 17, 60, + 141, 155, 160, 232, 283, 232, 232, 182, 183, 117, + 234, 235, 227, 182, 182, 167, 15, 148, 13, 17, + 60, 141, 155, 160, 165, 230, 281, 283, 13, 15, + 17, 60, 141, 155, 160, 165, 231, 269, 273, 283, + 253, 254, 283, 252, 183, 165, 242, 244, 150, 181, + 183, 3, 4, 5, 9, 10, 15, 50, 62, 67, + 75, 76, 109, 111, 113, 118, 122, 125, 130, 133, + 155, 158, 159, 163, 165, 169, 219, 220, 227, 228, + 275, 276, 282, 283, 167, 167, 173, 147, 148, 148, + 148, 148, 148, 148, 168, 258, 148, 167, 10, 11, + 12, 59, 60, 134, 207, 208, 209, 210, 211, 261, + 283, 165, 224, 190, 149, 239, 193, 10, 13, 160, + 195, 51, 273, 234, 13, 17, 60, 141, 155, 160, + 229, 281, 283, 239, 173, 165, 147, 149, 150, 151, + 223, 265, 266, 64, 65, 147, 273, 13, 17, 60, + 112, 141, 155, 160, 165, 188, 212, 214, 281, 150, + 280, 165, 165, 239, 239, 239, 167, 167, 167, 165, + 167, 165, 222, 217, 17, 33, 47, 60, 61, 76, + 107, 110, 113, 129, 141, 155, 215, 283, 273, 232, + 48, 236, 273, 160, 280, 182, 232, 232, 182, 182, + 166, 232, 48, 234, 235, 230, 231, 232, 232, 202, + 15, 227, 160, 182, 230, 230, 182, 182, 230, 166, + 222, 182, 160, 280, 182, 231, 231, 182, 182, 231, + 166, 222, 170, 280, 168, 48, 236, 273, 173, 76, + 245, 283, 184, 165, 156, 156, 237, 156, 15, 165, + 275, 156, 165, 273, 273, 273, 273, 239, 271, 273, + 167, 15, 148, 16, 17, 18, 19, 20, 21, 22, + 23, 33, 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 164, 165, 166, 181, 181, 168, 259, + 10, 10, 10, 10, 10, 10, 173, 282, 149, 211, + 157, 148, 15, 280, 13, 17, 60, 141, 155, 160, + 165, 230, 231, 191, 214, 149, 217, 167, 160, 212, + 217, 167, 167, 229, 160, 182, 229, 229, 182, 182, + 165, 166, 182, 167, 168, 197, 265, 174, 175, 280, + 64, 65, 168, 267, 283, 149, 149, 147, 225, 226, + 273, 283, 149, 160, 182, 212, 6, 16, 17, 18, + 19, 20, 21, 22, 23, 33, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 65, 109, + 148, 151, 153, 154, 155, 156, 157, 158, 159, 160, + 161, 162, 163, 165, 166, 169, 203, 212, 182, 182, + 212, 150, 165, 166, 215, 151, 222, 224, 182, 252, + 271, 271, 167, 167, 167, 271, 271, 167, 60, 237, + 183, 165, 147, 182, 167, 167, 182, 182, 232, 232, + 232, 269, 167, 227, 230, 231, 222, 222, 167, 167, + 215, 182, 230, 230, 230, 167, 269, 182, 182, 231, + 231, 231, 167, 269, 182, 148, 151, 167, 167, 168, + 150, 246, 247, 283, 239, 239, 239, 165, 239, 165, + 239, 239, 239, 273, 167, 167, 15, 228, 273, 273, + 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, + 273, 273, 273, 273, 273, 273, 273, 273, 280, 167, + 271, 273, 173, 148, 148, 167, 148, 216, 283, 148, 148, 148, 168, 167, 230, 231, 179, 185, 204, 205, - 210, 279, 151, 160, 182, 182, 182, 151, 221, 282, + 210, 280, 151, 160, 182, 182, 182, 151, 221, 283, 222, 224, 167, 165, 212, 167, 167, 165, 182, 229, - 229, 229, 200, 268, 217, 168, 147, 148, 147, 165, + 229, 229, 200, 269, 217, 168, 147, 148, 147, 165, 149, 149, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 33, 34, 35, 36, 37, 38, @@ -3225,42 +3222,42 @@ static const yytype_int16 yystos[] = 136, 137, 138, 139, 140, 141, 142, 143, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 169, - 170, 267, 225, 168, 148, 182, 212, 10, 167, 170, - 182, 212, 212, 167, 272, 213, 268, 272, 148, 167, - 167, 167, 167, 202, 237, 233, 48, 167, 279, 264, + 170, 268, 225, 168, 148, 182, 212, 10, 167, 170, + 182, 212, 212, 167, 273, 213, 269, 273, 148, 167, + 167, 167, 167, 202, 237, 233, 48, 167, 280, 265, 182, 182, 232, 170, 165, 222, 222, 165, 165, 230, - 165, 170, 231, 165, 170, 148, 114, 115, 116, 134, - 139, 248, 278, 279, 147, 148, 167, 157, 157, 269, - 157, 279, 167, 157, 167, 167, 272, 150, 167, 170, + 165, 170, 231, 165, 170, 273, 114, 115, 116, 134, + 139, 248, 279, 280, 147, 148, 167, 157, 157, 270, + 157, 280, 167, 157, 167, 167, 273, 150, 167, 170, 168, 10, 10, 149, 10, 167, 10, 10, 10, 149, 221, 239, 182, 50, 62, 67, 118, 122, 125, 155, - 158, 159, 160, 163, 165, 169, 271, 273, 148, 202, - 194, 167, 165, 202, 201, 229, 217, 170, 167, 264, - 175, 269, 269, 266, 168, 147, 272, 212, 182, 219, + 158, 159, 160, 163, 165, 169, 272, 274, 148, 202, + 194, 167, 165, 202, 201, 229, 217, 170, 167, 265, + 175, 270, 270, 267, 168, 147, 273, 212, 182, 219, 170, 188, 215, 233, 15, 167, 168, 182, 217, 217, - 217, 217, 182, 217, 182, 139, 278, 139, 278, 139, - 278, 279, 114, 115, 116, 15, 173, 248, 165, 165, - 167, 165, 167, 165, 272, 167, 148, 167, 148, 149, - 148, 167, 167, 148, 167, 165, 156, 156, 156, 15, - 165, 271, 156, 271, 271, 271, 271, 271, 239, 270, - 271, 16, 17, 18, 19, 20, 21, 22, 23, 33, - 152, 153, 154, 155, 158, 159, 160, 161, 162, 164, - 165, 166, 191, 217, 165, 198, 217, 167, 182, 202, - 168, 168, 167, 168, 225, 167, 182, 147, 167, 167, - 167, 167, 167, 167, 278, 278, 278, 278, 278, 278, - 168, 270, 270, 270, 270, 149, 10, 149, 10, 10, - 149, 149, 10, 149, 239, 239, 239, 239, 165, 239, - 239, 167, 167, 271, 271, 271, 271, 271, 271, 271, - 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, - 271, 279, 167, 270, 272, 167, 199, 217, 167, 202, - 15, 168, 202, 264, 202, 202, 202, 202, 202, 167, - 167, 167, 167, 148, 216, 167, 148, 148, 167, 167, - 157, 157, 157, 279, 167, 157, 271, 150, 167, 170, - 202, 217, 167, 202, 168, 215, 215, 215, 10, 167, - 149, 10, 10, 149, 165, 165, 165, 167, 165, 271, - 167, 202, 149, 167, 148, 167, 270, 270, 270, 270, - 202, 215, 149, 10, 149, 167, 167, 167, 167, 215, - 167, 149 + 217, 217, 182, 217, 182, 148, 139, 279, 139, 279, + 139, 279, 280, 114, 115, 116, 15, 173, 248, 165, + 165, 167, 165, 167, 165, 273, 167, 148, 167, 148, + 149, 148, 167, 167, 148, 167, 165, 156, 156, 156, + 15, 165, 272, 156, 272, 272, 272, 272, 272, 239, + 271, 272, 16, 17, 18, 19, 20, 21, 22, 23, + 33, 152, 153, 154, 155, 158, 159, 160, 161, 162, + 164, 165, 166, 191, 217, 165, 198, 217, 167, 182, + 202, 168, 168, 167, 168, 225, 167, 182, 147, 167, + 167, 167, 167, 167, 167, 279, 279, 279, 279, 279, + 279, 168, 271, 271, 271, 271, 149, 10, 149, 10, + 10, 149, 149, 10, 149, 239, 239, 239, 239, 165, + 239, 239, 167, 167, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 280, 167, 271, 273, 167, 199, 217, 167, + 202, 15, 168, 202, 265, 202, 202, 202, 202, 202, + 167, 167, 167, 167, 148, 216, 167, 148, 148, 167, + 167, 157, 157, 157, 280, 167, 157, 272, 150, 167, + 170, 202, 217, 167, 202, 168, 215, 215, 215, 10, + 167, 149, 10, 10, 149, 165, 165, 165, 167, 165, + 272, 167, 202, 149, 167, 148, 167, 271, 271, 271, + 271, 202, 215, 149, 10, 149, 167, 167, 167, 167, + 215, 167, 149 }; /* YYR1[RULE-NUM] -- Symbol kind of the left-hand side of rule RULE-NUM. */ @@ -3302,47 +3299,48 @@ static const yytype_int16 yyr1[] = 237, 237, 237, 237, 237, 237, 237, 238, 238, 239, 239, 239, 239, 240, 240, 240, 240, 242, 241, 244, 243, 245, 245, 246, 246, 247, 247, 248, 248, 248, - 248, 248, 248, 248, 248, 248, 248, 249, 250, 250, - 250, 250, 251, 251, 252, 252, 252, 253, 253, 253, - 254, 254, 254, 255, 255, 255, 257, 256, 258, 256, - 256, 256, 259, 259, 259, 260, 260, 260, 261, 261, - 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, - 261, 261, 262, 262, 262, 263, 265, 264, 266, 266, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 268, - 268, 269, 269, 270, 270, 271, 271, 271, 271, 271, - 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, - 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, - 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, - 271, 271, 271, 271, 272, 272, 272, 272, 272, 272, + 248, 248, 248, 248, 248, 248, 248, 250, 249, 251, + 251, 251, 251, 252, 252, 253, 253, 253, 254, 254, + 254, 255, 255, 255, 256, 256, 256, 258, 257, 259, + 257, 257, 257, 260, 260, 260, 261, 261, 261, 262, + 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, + 262, 262, 262, 263, 263, 263, 264, 266, 265, 267, + 267, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 269, 269, 270, 270, 271, 271, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 273, 273, 273, 273, 273, 273, 273, + 272, 272, 272, 272, 272, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, - 273, 273, 273, 274, 274, 274, 274, 274, 274, 274, + 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, + 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, + 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, + 273, 273, 273, 273, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, - 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, - 274, 274, 274, 274, 274, 274, 274, 275, 275, 275, + 274, 274, 274, 274, 275, 275, 275, 275, 275, 275, + 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, + 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, + 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 276, 276, - 276, 276, 276, 277, 277, 277, 277, 278, 278, 278, - 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, - 279, 280, 280, 280, 280, 281, 281, 281, 281, 282 + 276, 276, 276, 276, 276, 276, 276, 276, 276, 277, + 277, 277, 277, 277, 278, 278, 278, 278, 279, 279, + 279, 280, 280, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 281, 281, 281, 281, 282, 282, 282, 282, + 283 }; /* YYR2[RULE-NUM] -- Number of symbols on the right-hand side of rule RULE-NUM. */ @@ -3384,12 +3382,13 @@ static const yytype_int8 yyr2[] = 1, 2, 3, 2, 4, 4, 1, 1, 1, 2, 3, 2, 3, 1, 4, 5, 5, 0, 6, 0, 9, 1, 1, 1, 1, 2, 3, 1, 2, 2, - 2, 3, 3, 3, 3, 3, 3, 4, 3, 1, - 4, 2, 1, 1, 1, 3, 5, 1, 2, 4, - 1, 2, 2, 1, 1, 1, 0, 6, 0, 7, - 4, 5, 3, 5, 4, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, - 2, 2, 1, 1, 2, 1, 0, 2, 1, 2, + 2, 3, 3, 3, 3, 3, 3, 0, 5, 3, + 1, 4, 2, 1, 1, 1, 3, 5, 1, 2, + 4, 1, 2, 2, 1, 1, 1, 0, 6, 0, + 7, 4, 5, 3, 5, 4, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, + 2, 2, 2, 1, 1, 2, 1, 0, 2, 1, + 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -3401,30 +3400,30 @@ static const yytype_int8 yyr2[] = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, - 1, 1, 1, 1, 3, 1, 4, 7, 7, 7, - 7, 4, 2, 5, 4, 2, 2, 2, 2, 2, - 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 5, 4, 4, - 3, 3, 3, 3, 1, 4, 7, 7, 7, 7, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 2, 5, 4, 2, 5, - 4, 4, 2, 2, 2, 2, 2, 2, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 5, 4, 4, 3, - 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 8, 11, 4, 4, 6, 4, - 4, 6, 6, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 1, 4, 7, 7, 7, 7, 4, - 2, 5, 4, 2, 5, 4, 4, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, + 1, 1, 1, 1, 1, 3, 1, 4, 7, 7, + 7, 7, 4, 2, 5, 4, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 5, 4, + 4, 3, 3, 3, 3, 1, 4, 7, 7, 7, + 7, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 2, 5, 4, 2, + 5, 4, 4, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 5, 4, 4, 3, 3, 3, 3, 1, 1, 1, + 3, 3, 3, 3, 3, 3, 3, 5, 4, 4, + 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 8, 11, 4, 4, 6, + 4, 4, 6, 6, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 1, 4, 7, 7, 7, 7, + 4, 2, 5, 4, 2, 5, 4, 4, 2, 2, + 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 5, 4, 4, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 2, 4, 2, 3, 1, 2, 1, 2, 2, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 2, 2, 0 + 1, 1, 2, 4, 2, 3, 1, 2, 1, 2, + 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, + 0 }; @@ -4013,7 +4012,7 @@ yyreduce: { current_expr = (yyvsp[0].u.expr); } -#line 4017 "built/tmp/cppBison.yxx.c" +#line 4016 "built/tmp/cppBison.yxx.c" break; case 4: /* grammar: START_TYPE full_type */ @@ -4021,7 +4020,7 @@ yyreduce: { current_type = (yyvsp[0].u.type); } -#line 4025 "built/tmp/cppBison.yxx.c" +#line 4024 "built/tmp/cppBison.yxx.c" break; case 10: /* constructor_init: name '(' optional_const_expr_comma ')' */ @@ -4029,7 +4028,7 @@ yyreduce: { delete (yyvsp[-1].u.expr); } -#line 4033 "built/tmp/cppBison.yxx.c" +#line 4032 "built/tmp/cppBison.yxx.c" break; case 11: /* constructor_init: name '(' optional_const_expr_comma ')' ELLIPSIS */ @@ -4037,7 +4036,7 @@ yyreduce: { delete (yyvsp[-2].u.expr); } -#line 4041 "built/tmp/cppBison.yxx.c" +#line 4040 "built/tmp/cppBison.yxx.c" break; case 12: /* constructor_init: name '{' optional_const_expr_comma '}' */ @@ -4045,7 +4044,7 @@ yyreduce: { delete (yyvsp[-1].u.expr); } -#line 4049 "built/tmp/cppBison.yxx.c" +#line 4048 "built/tmp/cppBison.yxx.c" break; case 13: /* $@1: %empty */ @@ -4054,7 +4053,7 @@ yyreduce: push_storage_class((current_storage_class & ~CPPInstance::SC_c_binding) | ((yyvsp[-1].u.integer) & CPPInstance::SC_c_binding)); } -#line 4058 "built/tmp/cppBison.yxx.c" +#line 4057 "built/tmp/cppBison.yxx.c" break; case 14: /* extern_c: storage_class '{' $@1 cpp '}' */ @@ -4062,7 +4061,7 @@ yyreduce: { pop_storage_class(); } -#line 4066 "built/tmp/cppBison.yxx.c" +#line 4065 "built/tmp/cppBison.yxx.c" break; case 21: /* declaration: KW_BEGIN_PUBLISH */ @@ -4079,7 +4078,7 @@ yyreduce: publish_nest_level++; current_scope->set_current_vis(V_published); } -#line 4083 "built/tmp/cppBison.yxx.c" +#line 4082 "built/tmp/cppBison.yxx.c" break; case 22: /* declaration: KW_END_PUBLISH */ @@ -4092,7 +4091,7 @@ yyreduce: } publish_nest_level = 0; } -#line 4096 "built/tmp/cppBison.yxx.c" +#line 4095 "built/tmp/cppBison.yxx.c" break; case 23: /* declaration: KW_PUBLISHED ':' */ @@ -4100,7 +4099,7 @@ yyreduce: { current_scope->set_current_vis(V_published); } -#line 4104 "built/tmp/cppBison.yxx.c" +#line 4103 "built/tmp/cppBison.yxx.c" break; case 24: /* declaration: KW_PUBLIC ':' */ @@ -4112,7 +4111,7 @@ yyreduce: current_scope->set_current_vis(V_public); } } -#line 4116 "built/tmp/cppBison.yxx.c" +#line 4115 "built/tmp/cppBison.yxx.c" break; case 25: /* declaration: KW_PROTECTED ':' */ @@ -4120,7 +4119,7 @@ yyreduce: { current_scope->set_current_vis(V_protected); } -#line 4124 "built/tmp/cppBison.yxx.c" +#line 4123 "built/tmp/cppBison.yxx.c" break; case 26: /* declaration: KW_PRIVATE ':' */ @@ -4128,7 +4127,7 @@ yyreduce: { current_scope->set_current_vis(V_private); } -#line 4132 "built/tmp/cppBison.yxx.c" +#line 4131 "built/tmp/cppBison.yxx.c" break; case 27: /* declaration: KW_MAKE_PROPERTY '(' name ',' IDENTIFIER maybe_comma_identifier ')' ';' */ @@ -4153,7 +4152,7 @@ yyreduce: current_scope->add_declaration(make_property, global_scope, current_lexer, (yylsp[-7])); } } -#line 4157 "built/tmp/cppBison.yxx.c" +#line 4156 "built/tmp/cppBison.yxx.c" break; case 28: /* declaration: KW_MAKE_PROPERTY '(' name ',' IDENTIFIER ',' IDENTIFIER ',' IDENTIFIER ')' ';' */ @@ -4184,7 +4183,7 @@ yyreduce: current_scope->add_declaration(make_property, global_scope, current_lexer, (yylsp[-10])); } } -#line 4188 "built/tmp/cppBison.yxx.c" +#line 4187 "built/tmp/cppBison.yxx.c" break; case 29: /* declaration: KW_MAKE_SEQ_PROPERTY '(' name ',' IDENTIFIER ',' IDENTIFIER ')' ';' */ @@ -4209,7 +4208,7 @@ yyreduce: current_scope->add_declaration(make_property, global_scope, current_lexer, (yylsp[-8])); } } -#line 4213 "built/tmp/cppBison.yxx.c" +#line 4212 "built/tmp/cppBison.yxx.c" break; case 30: /* declaration: KW_MAKE_SEQ_PROPERTY '(' name ',' IDENTIFIER ',' IDENTIFIER ',' IDENTIFIER ')' ';' */ @@ -4242,7 +4241,7 @@ yyreduce: current_scope->add_declaration(make_property, global_scope, current_lexer, (yylsp[-10])); } } -#line 4246 "built/tmp/cppBison.yxx.c" +#line 4245 "built/tmp/cppBison.yxx.c" break; case 31: /* declaration: KW_MAKE_SEQ_PROPERTY '(' name ',' IDENTIFIER ',' IDENTIFIER ',' IDENTIFIER ',' IDENTIFIER ')' ';' */ @@ -4282,7 +4281,7 @@ yyreduce: current_scope->add_declaration(make_property, global_scope, current_lexer, (yylsp[-12])); } } -#line 4286 "built/tmp/cppBison.yxx.c" +#line 4285 "built/tmp/cppBison.yxx.c" break; case 32: /* declaration: KW_MAKE_SEQ_PROPERTY '(' name ',' IDENTIFIER ',' IDENTIFIER ',' IDENTIFIER ',' IDENTIFIER ',' IDENTIFIER ')' ';' */ @@ -4329,7 +4328,7 @@ yyreduce: current_scope->add_declaration(make_property, global_scope, current_lexer, (yylsp[-14])); } } -#line 4333 "built/tmp/cppBison.yxx.c" +#line 4332 "built/tmp/cppBison.yxx.c" break; case 33: /* declaration: KW_MAKE_MAP_PROPERTY '(' name ',' IDENTIFIER ')' ';' */ @@ -4345,7 +4344,7 @@ yyreduce: current_scope->add_declaration(make_property, global_scope, current_lexer, (yylsp[-6])); } } -#line 4349 "built/tmp/cppBison.yxx.c" +#line 4348 "built/tmp/cppBison.yxx.c" break; case 34: /* declaration: KW_MAKE_MAP_PROPERTY '(' name ',' IDENTIFIER ',' IDENTIFIER ')' ';' */ @@ -4370,7 +4369,7 @@ yyreduce: current_scope->add_declaration(make_property, global_scope, current_lexer, (yylsp[-8])); } } -#line 4374 "built/tmp/cppBison.yxx.c" +#line 4373 "built/tmp/cppBison.yxx.c" break; case 35: /* declaration: KW_MAKE_MAP_PROPERTY '(' name ',' IDENTIFIER ',' IDENTIFIER ',' IDENTIFIER maybe_comma_identifier ')' ';' */ @@ -4410,7 +4409,7 @@ yyreduce: current_scope->add_declaration(make_property, global_scope, current_lexer, (yylsp[-11])); } } -#line 4414 "built/tmp/cppBison.yxx.c" +#line 4413 "built/tmp/cppBison.yxx.c" break; case 36: /* declaration: KW_MAKE_MAP_KEYS_SEQ '(' name ',' IDENTIFIER ',' IDENTIFIER ')' ';' */ @@ -4448,7 +4447,7 @@ yyreduce: } } } -#line 4452 "built/tmp/cppBison.yxx.c" +#line 4451 "built/tmp/cppBison.yxx.c" break; case 37: /* declaration: KW_MAKE_PROPERTY2 '(' name ',' IDENTIFIER ',' IDENTIFIER ')' ';' */ @@ -4474,7 +4473,7 @@ yyreduce: current_scope->add_declaration(make_property, global_scope, current_lexer, (yylsp[-8])); } } -#line 4478 "built/tmp/cppBison.yxx.c" +#line 4477 "built/tmp/cppBison.yxx.c" break; case 38: /* declaration: KW_MAKE_PROPERTY2 '(' name ',' IDENTIFIER ',' IDENTIFIER ',' IDENTIFIER ',' IDENTIFIER ')' ';' */ @@ -4514,7 +4513,7 @@ yyreduce: current_scope->add_declaration(make_property, global_scope, current_lexer, (yylsp[-12])); } } -#line 4518 "built/tmp/cppBison.yxx.c" +#line 4517 "built/tmp/cppBison.yxx.c" break; case 39: /* declaration: KW_MAKE_SEQ '(' name ',' IDENTIFIER ',' IDENTIFIER ')' ';' */ @@ -4540,7 +4539,7 @@ yyreduce: current_scope->add_declaration(make_seq, global_scope, current_lexer, (yylsp[-8])); } } -#line 4544 "built/tmp/cppBison.yxx.c" +#line 4543 "built/tmp/cppBison.yxx.c" break; case 40: /* declaration: KW_STATIC_ASSERT '(' const_expr ',' string_literal ')' ';' */ @@ -4555,7 +4554,7 @@ yyreduce: yywarning("static_assert failed: " + str.str(), (yylsp[-4])); } } -#line 4559 "built/tmp/cppBison.yxx.c" +#line 4558 "built/tmp/cppBison.yxx.c" break; case 41: /* declaration: KW_STATIC_ASSERT '(' const_expr ')' ';' */ @@ -4569,7 +4568,7 @@ yyreduce: yywarning("static_assert failed", (yylsp[-2])); } } -#line 4573 "built/tmp/cppBison.yxx.c" +#line 4572 "built/tmp/cppBison.yxx.c" break; case 42: /* $@2: %empty */ @@ -4579,7 +4578,7 @@ yyreduce: V_public); push_scope(new_scope); } -#line 4583 "built/tmp/cppBison.yxx.c" +#line 4582 "built/tmp/cppBison.yxx.c" break; case 43: /* friend_declaration: KW_FRIEND $@2 declaration */ @@ -4588,7 +4587,7 @@ yyreduce: delete current_scope; pop_scope(); } -#line 4592 "built/tmp/cppBison.yxx.c" +#line 4591 "built/tmp/cppBison.yxx.c" break; case 44: /* storage_class: empty */ @@ -4596,7 +4595,7 @@ yyreduce: { (yyval.u.integer) = 0; } -#line 4600 "built/tmp/cppBison.yxx.c" +#line 4599 "built/tmp/cppBison.yxx.c" break; case 45: /* storage_class: KW_CONST storage_class */ @@ -4605,7 +4604,7 @@ yyreduce: // This isn't really a storage class, but it helps with parsing. (yyval.u.integer) = (yyvsp[0].u.integer) | (int)CPPInstance::SC_const; } -#line 4609 "built/tmp/cppBison.yxx.c" +#line 4608 "built/tmp/cppBison.yxx.c" break; case 46: /* storage_class: KW_EXTERN storage_class */ @@ -4613,7 +4612,7 @@ yyreduce: { (yyval.u.integer) = (yyvsp[0].u.integer) | (int)CPPInstance::SC_extern; } -#line 4617 "built/tmp/cppBison.yxx.c" +#line 4616 "built/tmp/cppBison.yxx.c" break; case 47: /* storage_class: KW_EXTERN SIMPLE_STRING storage_class */ @@ -4628,7 +4627,7 @@ yyreduce: yywarning("Ignoring unknown linkage type \"" + (yyvsp[-1].str) + "\"", (yylsp[-1])); } } -#line 4632 "built/tmp/cppBison.yxx.c" +#line 4631 "built/tmp/cppBison.yxx.c" break; case 48: /* storage_class: KW_STATIC storage_class */ @@ -4636,7 +4635,7 @@ yyreduce: { (yyval.u.integer) = (yyvsp[0].u.integer) | (int)CPPInstance::SC_static; } -#line 4640 "built/tmp/cppBison.yxx.c" +#line 4639 "built/tmp/cppBison.yxx.c" break; case 49: /* storage_class: KW_INLINE storage_class */ @@ -4644,7 +4643,7 @@ yyreduce: { (yyval.u.integer) = (yyvsp[0].u.integer) | (int)CPPInstance::SC_inline; } -#line 4648 "built/tmp/cppBison.yxx.c" +#line 4647 "built/tmp/cppBison.yxx.c" break; case 50: /* storage_class: KW_VIRTUAL storage_class */ @@ -4652,7 +4651,7 @@ yyreduce: { (yyval.u.integer) = (yyvsp[0].u.integer) | (int)CPPInstance::SC_virtual; } -#line 4656 "built/tmp/cppBison.yxx.c" +#line 4655 "built/tmp/cppBison.yxx.c" break; case 51: /* storage_class: KW_EXPLICIT storage_class */ @@ -4660,7 +4659,7 @@ yyreduce: { (yyval.u.integer) = (yyvsp[0].u.integer) | (int)CPPInstance::SC_explicit; } -#line 4664 "built/tmp/cppBison.yxx.c" +#line 4663 "built/tmp/cppBison.yxx.c" break; case 52: /* storage_class: KW_REGISTER storage_class */ @@ -4668,7 +4667,7 @@ yyreduce: { (yyval.u.integer) = (yyvsp[0].u.integer) | (int)CPPInstance::SC_register; } -#line 4672 "built/tmp/cppBison.yxx.c" +#line 4671 "built/tmp/cppBison.yxx.c" break; case 53: /* storage_class: KW_VOLATILE storage_class */ @@ -4676,7 +4675,7 @@ yyreduce: { (yyval.u.integer) = (yyvsp[0].u.integer) | (int)CPPInstance::SC_volatile; } -#line 4680 "built/tmp/cppBison.yxx.c" +#line 4679 "built/tmp/cppBison.yxx.c" break; case 54: /* storage_class: KW_MUTABLE storage_class */ @@ -4684,7 +4683,7 @@ yyreduce: { (yyval.u.integer) = (yyvsp[0].u.integer) | (int)CPPInstance::SC_mutable; } -#line 4688 "built/tmp/cppBison.yxx.c" +#line 4687 "built/tmp/cppBison.yxx.c" break; case 55: /* storage_class: KW_CONSTEXPR storage_class */ @@ -4692,7 +4691,7 @@ yyreduce: { (yyval.u.integer) = (yyvsp[0].u.integer) | (int)CPPInstance::SC_constexpr; } -#line 4696 "built/tmp/cppBison.yxx.c" +#line 4695 "built/tmp/cppBison.yxx.c" break; case 56: /* storage_class: KW_BLOCKING storage_class */ @@ -4700,7 +4699,7 @@ yyreduce: { (yyval.u.integer) = (yyvsp[0].u.integer) | (int)CPPInstance::SC_blocking; } -#line 4704 "built/tmp/cppBison.yxx.c" +#line 4703 "built/tmp/cppBison.yxx.c" break; case 57: /* storage_class: KW_EXTENSION storage_class */ @@ -4708,7 +4707,7 @@ yyreduce: { (yyval.u.integer) = (yyvsp[0].u.integer) | (int)CPPInstance::SC_extension; } -#line 4712 "built/tmp/cppBison.yxx.c" +#line 4711 "built/tmp/cppBison.yxx.c" break; case 58: /* storage_class: KW_THREAD_LOCAL storage_class */ @@ -4716,7 +4715,7 @@ yyreduce: { (yyval.u.integer) = (yyvsp[0].u.integer) | (int)CPPInstance::SC_thread_local; } -#line 4720 "built/tmp/cppBison.yxx.c" +#line 4719 "built/tmp/cppBison.yxx.c" break; case 59: /* storage_class: ATTR_LEFT attribute_specifiers ATTR_RIGHT storage_class */ @@ -4725,7 +4724,7 @@ yyreduce: // Ignore attribute specifiers for now. (yyval.u.integer) = (yyvsp[0].u.integer); } -#line 4729 "built/tmp/cppBison.yxx.c" +#line 4728 "built/tmp/cppBison.yxx.c" break; case 60: /* storage_class: KW_ALIGNAS '(' const_expr ')' storage_class */ @@ -4733,7 +4732,7 @@ yyreduce: { (yyval.u.integer) = (yyvsp[0].u.integer); } -#line 4737 "built/tmp/cppBison.yxx.c" +#line 4736 "built/tmp/cppBison.yxx.c" break; case 61: /* storage_class: KW_ALIGNAS '(' type_decl ')' storage_class */ @@ -4741,7 +4740,7 @@ yyreduce: { (yyval.u.integer) = (yyvsp[0].u.integer); } -#line 4745 "built/tmp/cppBison.yxx.c" +#line 4744 "built/tmp/cppBison.yxx.c" break; case 71: /* $@3: %empty */ @@ -4756,7 +4755,7 @@ yyreduce: } push_storage_class((yyvsp[-1].u.integer)); } -#line 4760 "built/tmp/cppBison.yxx.c" +#line 4759 "built/tmp/cppBison.yxx.c" break; case 72: /* type_like_declaration: storage_class var_type_decl $@3 multiple_instance_identifiers */ @@ -4764,7 +4763,7 @@ yyreduce: { pop_storage_class(); } -#line 4768 "built/tmp/cppBison.yxx.c" +#line 4767 "built/tmp/cppBison.yxx.c" break; case 73: /* type_like_declaration: storage_class type_decl ';' */ @@ -4777,7 +4776,7 @@ yyreduce: current_scope->add_declaration((yyvsp[-1].u.decl), global_scope, current_lexer, (yylsp[-1])); } -#line 4781 "built/tmp/cppBison.yxx.c" +#line 4780 "built/tmp/cppBison.yxx.c" break; case 74: /* $@4: %empty */ @@ -4790,7 +4789,7 @@ yyreduce: (yyvsp[0].u.instance)->_storage_class |= (current_storage_class | (yyvsp[-1].u.integer)); } } -#line 4794 "built/tmp/cppBison.yxx.c" +#line 4793 "built/tmp/cppBison.yxx.c" break; case 75: /* type_like_declaration: storage_class constructor_prototype $@4 maybe_initialize_or_constructor_body */ @@ -4802,7 +4801,7 @@ yyreduce: (yyvsp[-2].u.instance)->set_initializer((yyvsp[0].u.expr)); } } -#line 4806 "built/tmp/cppBison.yxx.c" +#line 4805 "built/tmp/cppBison.yxx.c" break; case 76: /* type_like_declaration: storage_class function_prototype maybe_initialize_or_function_body */ @@ -4814,7 +4813,7 @@ yyreduce: (yyvsp[-1].u.instance)->set_initializer((yyvsp[0].u.expr)); } } -#line 4818 "built/tmp/cppBison.yxx.c" +#line 4817 "built/tmp/cppBison.yxx.c" break; case 78: /* multiple_instance_identifiers: instance_identifier_and_maybe_trailing_return_type maybe_initialize_or_function_body */ @@ -4829,7 +4828,7 @@ yyreduce: inst->set_initializer((yyvsp[0].u.expr)); current_scope->add_declaration(inst, global_scope, current_lexer, (yylsp[-1])); } -#line 4833 "built/tmp/cppBison.yxx.c" +#line 4832 "built/tmp/cppBison.yxx.c" break; case 79: /* multiple_instance_identifiers: instance_identifier_and_maybe_trailing_return_type maybe_initialize ',' multiple_instance_identifiers */ @@ -4844,7 +4843,7 @@ yyreduce: inst->set_initializer((yyvsp[-2].u.expr)); current_scope->add_declaration(inst, global_scope, current_lexer, (yylsp[-3])); } -#line 4848 "built/tmp/cppBison.yxx.c" +#line 4847 "built/tmp/cppBison.yxx.c" break; case 80: /* $@5: %empty */ @@ -4859,7 +4858,7 @@ yyreduce: } push_storage_class((yyvsp[-1].u.integer)); } -#line 4863 "built/tmp/cppBison.yxx.c" +#line 4862 "built/tmp/cppBison.yxx.c" break; case 81: /* typedef_declaration: storage_class var_type_decl $@5 typedef_instance_identifiers */ @@ -4867,7 +4866,7 @@ yyreduce: { pop_storage_class(); } -#line 4871 "built/tmp/cppBison.yxx.c" +#line 4870 "built/tmp/cppBison.yxx.c" break; case 82: /* typedef_declaration: storage_class function_prototype maybe_initialize_or_function_body */ @@ -4883,7 +4882,7 @@ yyreduce: } } } -#line 4887 "built/tmp/cppBison.yxx.c" +#line 4886 "built/tmp/cppBison.yxx.c" break; case 83: /* typedef_instance_identifiers: instance_identifier_and_maybe_trailing_return_type maybe_initialize_or_function_body */ @@ -4896,7 +4895,7 @@ yyreduce: CPPTypedefType *typedef_type = new CPPTypedefType(target_type, (yyvsp[-1].u.inst_ident), current_scope, (yylsp[-1]).file); current_scope->add_declaration(CPPType::new_type(typedef_type), global_scope, current_lexer, (yylsp[-1])); } -#line 4900 "built/tmp/cppBison.yxx.c" +#line 4899 "built/tmp/cppBison.yxx.c" break; case 84: /* typedef_instance_identifiers: instance_identifier_and_maybe_trailing_return_type maybe_initialize ',' typedef_instance_identifiers */ @@ -4909,7 +4908,7 @@ yyreduce: CPPTypedefType *typedef_type = new CPPTypedefType(target_type, (yyvsp[-3].u.inst_ident), current_scope, (yylsp[-3]).file); current_scope->add_declaration(CPPType::new_type(typedef_type), global_scope, current_lexer, (yylsp[-3])); } -#line 4913 "built/tmp/cppBison.yxx.c" +#line 4912 "built/tmp/cppBison.yxx.c" break; case 85: /* $@6: %empty */ @@ -4926,7 +4925,7 @@ yyreduce: push_scope(scope); } -#line 4930 "built/tmp/cppBison.yxx.c" +#line 4929 "built/tmp/cppBison.yxx.c" break; case 86: /* constructor_prototype: IDENTIFIER '(' $@6 function_parameter_list ')' function_post */ @@ -4954,7 +4953,7 @@ yyreduce: (yyval.u.instance) = new CPPInstance(type, ii, 0, (yylsp[-5]).file); } -#line 4958 "built/tmp/cppBison.yxx.c" +#line 4957 "built/tmp/cppBison.yxx.c" break; case 87: /* $@7: %empty */ @@ -4971,7 +4970,7 @@ yyreduce: push_scope(scope); } -#line 4975 "built/tmp/cppBison.yxx.c" +#line 4974 "built/tmp/cppBison.yxx.c" break; case 88: /* constructor_prototype: TYPENAME_IDENTIFIER '(' IDENTIFIER ')' '(' $@7 function_parameter_list ')' function_post */ @@ -4989,7 +4988,7 @@ yyreduce: (yyval.u.instance) = new CPPInstance(type, ii, 0, (yylsp[-8]).file); } -#line 4993 "built/tmp/cppBison.yxx.c" +#line 4992 "built/tmp/cppBison.yxx.c" break; case 89: /* $@8: %empty */ @@ -5006,7 +5005,7 @@ yyreduce: push_scope(scope); } -#line 5010 "built/tmp/cppBison.yxx.c" +#line 5009 "built/tmp/cppBison.yxx.c" break; case 90: /* constructor_prototype: TYPENAME_IDENTIFIER '(' $@8 function_parameter_list ')' function_post */ @@ -5028,7 +5027,7 @@ yyreduce: (yyval.u.instance) = new CPPInstance(type, ii, 0, (yylsp[-5]).file); } -#line 5032 "built/tmp/cppBison.yxx.c" +#line 5031 "built/tmp/cppBison.yxx.c" break; case 91: /* $@9: %empty */ @@ -5036,7 +5035,7 @@ yyreduce: { push_scope((yyvsp[-1].u.identifier)->get_scope(current_scope, global_scope)); } -#line 5040 "built/tmp/cppBison.yxx.c" +#line 5039 "built/tmp/cppBison.yxx.c" break; case 92: /* function_prototype: '~' name '(' $@9 function_parameter_list ')' function_post */ @@ -5059,7 +5058,7 @@ yyreduce: (yyval.u.instance) = new CPPInstance(type, ii, 0, (yylsp[-5]).file); } } -#line 5063 "built/tmp/cppBison.yxx.c" +#line 5062 "built/tmp/cppBison.yxx.c" break; case 93: /* $@10: %empty */ @@ -5067,7 +5066,7 @@ yyreduce: { push_scope((yyvsp[-2].u.inst_ident)->get_scope(current_scope, global_scope)); } -#line 5071 "built/tmp/cppBison.yxx.c" +#line 5070 "built/tmp/cppBison.yxx.c" break; case 94: /* function_prototype: TYPENAME_IDENTIFIER '(' '*' instance_identifier ')' '(' $@10 function_parameter_list ')' function_post maybe_trailing_return_type */ @@ -5085,7 +5084,7 @@ yyreduce: ii->add_func_modifier((yyvsp[-3].u.param_list), (yyvsp[-1].u.integer)); (yyval.u.instance) = new CPPInstance(type, ii, 0, (yylsp[-10]).file); } -#line 5089 "built/tmp/cppBison.yxx.c" +#line 5088 "built/tmp/cppBison.yxx.c" break; case 95: /* $@11: %empty */ @@ -5093,7 +5092,7 @@ yyreduce: { push_scope((yyvsp[-2].u.inst_ident)->get_scope(current_scope, global_scope)); } -#line 5097 "built/tmp/cppBison.yxx.c" +#line 5096 "built/tmp/cppBison.yxx.c" break; case 96: /* function_prototype: TYPENAME_IDENTIFIER '(' SCOPING '*' instance_identifier ')' '(' $@11 function_parameter_list ')' function_post maybe_trailing_return_type */ @@ -5111,7 +5110,7 @@ yyreduce: ii->add_func_modifier((yyvsp[-3].u.param_list), (yyvsp[-1].u.integer)); (yyval.u.instance) = new CPPInstance(type, ii, 0, (yylsp[-11]).file); } -#line 5115 "built/tmp/cppBison.yxx.c" +#line 5114 "built/tmp/cppBison.yxx.c" break; case 97: /* $@12: %empty */ @@ -5121,7 +5120,7 @@ yyreduce: push_scope((yyvsp[-3].u.identifier)->get_scope(current_scope, global_scope)); } } -#line 5125 "built/tmp/cppBison.yxx.c" +#line 5124 "built/tmp/cppBison.yxx.c" break; case 98: /* function_prototype: KW_OPERATOR type not_paren_formal_parameter_identifier '(' $@12 function_parameter_list ')' function_post */ @@ -5150,7 +5149,7 @@ yyreduce: (yyval.u.instance) = CPPInstance::make_typecast_function (new CPPInstance((yyvsp[-6].u.type), (yyvsp[-5].u.inst_ident), 0, (yylsp[-5]).file), ident, (yyvsp[-2].u.param_list), (yyvsp[0].u.integer)); } -#line 5154 "built/tmp/cppBison.yxx.c" +#line 5153 "built/tmp/cppBison.yxx.c" break; case 99: /* $@13: %empty */ @@ -5160,7 +5159,7 @@ yyreduce: push_scope((yyvsp[-4].u.identifier)->get_scope(current_scope, global_scope)); } } -#line 5164 "built/tmp/cppBison.yxx.c" +#line 5163 "built/tmp/cppBison.yxx.c" break; case 100: /* function_prototype: KW_OPERATOR KW_CONST type not_paren_formal_parameter_identifier '(' $@13 function_parameter_list ')' function_post */ @@ -5180,7 +5179,7 @@ yyreduce: (yyval.u.instance) = CPPInstance::make_typecast_function (new CPPInstance((yyvsp[-6].u.type), (yyvsp[-5].u.inst_ident), 0, (yylsp[-5]).file), ident, (yyvsp[-2].u.param_list), (yyvsp[0].u.integer)); } -#line 5184 "built/tmp/cppBison.yxx.c" +#line 5183 "built/tmp/cppBison.yxx.c" break; case 101: /* function_prototype: IDENTIFIER */ @@ -5194,7 +5193,7 @@ yyreduce: (yyval.u.instance) = nullptr; } } -#line 5198 "built/tmp/cppBison.yxx.c" +#line 5197 "built/tmp/cppBison.yxx.c" break; case 102: /* function_post: empty */ @@ -5202,7 +5201,7 @@ yyreduce: { (yyval.u.integer) = 0; } -#line 5206 "built/tmp/cppBison.yxx.c" +#line 5205 "built/tmp/cppBison.yxx.c" break; case 103: /* function_post: function_post KW_CONST */ @@ -5210,7 +5209,7 @@ yyreduce: { (yyval.u.integer) = (yyvsp[-1].u.integer) | (int)CPPFunctionType::F_const_method; } -#line 5214 "built/tmp/cppBison.yxx.c" +#line 5213 "built/tmp/cppBison.yxx.c" break; case 104: /* function_post: function_post KW_VOLATILE */ @@ -5218,7 +5217,7 @@ yyreduce: { (yyval.u.integer) = (yyvsp[-1].u.integer) | (int)CPPFunctionType::F_volatile_method; } -#line 5222 "built/tmp/cppBison.yxx.c" +#line 5221 "built/tmp/cppBison.yxx.c" break; case 105: /* function_post: function_post KW_NOEXCEPT */ @@ -5226,7 +5225,7 @@ yyreduce: { (yyval.u.integer) = (yyvsp[-1].u.integer) | (int)CPPFunctionType::F_noexcept; } -#line 5230 "built/tmp/cppBison.yxx.c" +#line 5229 "built/tmp/cppBison.yxx.c" break; case 106: /* function_post: function_post KW_FINAL */ @@ -5234,7 +5233,7 @@ yyreduce: { (yyval.u.integer) = (yyvsp[-1].u.integer) | (int)CPPFunctionType::F_final; } -#line 5238 "built/tmp/cppBison.yxx.c" +#line 5237 "built/tmp/cppBison.yxx.c" break; case 107: /* function_post: function_post KW_OVERRIDE */ @@ -5242,7 +5241,7 @@ yyreduce: { (yyval.u.integer) = (yyvsp[-1].u.integer) | (int)CPPFunctionType::F_override; } -#line 5246 "built/tmp/cppBison.yxx.c" +#line 5245 "built/tmp/cppBison.yxx.c" break; case 108: /* function_post: function_post '&' */ @@ -5250,7 +5249,7 @@ yyreduce: { (yyval.u.integer) = (yyvsp[-1].u.integer) | (int)CPPFunctionType::F_lvalue_method; } -#line 5254 "built/tmp/cppBison.yxx.c" +#line 5253 "built/tmp/cppBison.yxx.c" break; case 109: /* function_post: function_post ANDAND */ @@ -5258,7 +5257,7 @@ yyreduce: { (yyval.u.integer) = (yyvsp[-1].u.integer) | (int)CPPFunctionType::F_rvalue_method; } -#line 5262 "built/tmp/cppBison.yxx.c" +#line 5261 "built/tmp/cppBison.yxx.c" break; case 110: /* function_post: function_post KW_MUTABLE */ @@ -5267,7 +5266,7 @@ yyreduce: // Used for lambdas, currently ignored. (yyval.u.integer) = (yyvsp[-1].u.integer); } -#line 5271 "built/tmp/cppBison.yxx.c" +#line 5270 "built/tmp/cppBison.yxx.c" break; case 111: /* function_post: function_post KW_CONSTEXPR */ @@ -5276,7 +5275,7 @@ yyreduce: // Used for lambdas in C++17, currently ignored. (yyval.u.integer) = (yyvsp[-1].u.integer); } -#line 5280 "built/tmp/cppBison.yxx.c" +#line 5279 "built/tmp/cppBison.yxx.c" break; case 112: /* function_post: function_post KW_THROW '(' ')' */ @@ -5284,7 +5283,7 @@ yyreduce: { (yyval.u.integer) = (yyvsp[-3].u.integer); } -#line 5288 "built/tmp/cppBison.yxx.c" +#line 5287 "built/tmp/cppBison.yxx.c" break; case 113: /* function_post: function_post KW_THROW '(' name ')' */ @@ -5292,7 +5291,7 @@ yyreduce: { (yyval.u.integer) = (yyvsp[-4].u.integer); } -#line 5296 "built/tmp/cppBison.yxx.c" +#line 5295 "built/tmp/cppBison.yxx.c" break; case 114: /* function_post: function_post KW_THROW '(' name ELLIPSIS ')' */ @@ -5300,7 +5299,7 @@ yyreduce: { (yyval.u.integer) = (yyvsp[-5].u.integer); } -#line 5304 "built/tmp/cppBison.yxx.c" +#line 5303 "built/tmp/cppBison.yxx.c" break; case 115: /* function_post: function_post ATTR_LEFT attribute_specifiers ATTR_RIGHT */ @@ -5308,7 +5307,7 @@ yyreduce: { (yyval.u.integer) = (yyvsp[-3].u.integer); } -#line 5312 "built/tmp/cppBison.yxx.c" +#line 5311 "built/tmp/cppBison.yxx.c" break; case 116: /* function_operator: '!' */ @@ -5316,7 +5315,7 @@ yyreduce: { (yyval.str) = "!"; } -#line 5320 "built/tmp/cppBison.yxx.c" +#line 5319 "built/tmp/cppBison.yxx.c" break; case 117: /* function_operator: '~' */ @@ -5324,7 +5323,7 @@ yyreduce: { (yyval.str) = "~"; } -#line 5328 "built/tmp/cppBison.yxx.c" +#line 5327 "built/tmp/cppBison.yxx.c" break; case 118: /* function_operator: '*' */ @@ -5332,7 +5331,7 @@ yyreduce: { (yyval.str) = "*"; } -#line 5336 "built/tmp/cppBison.yxx.c" +#line 5335 "built/tmp/cppBison.yxx.c" break; case 119: /* function_operator: '/' */ @@ -5340,7 +5339,7 @@ yyreduce: { (yyval.str) = "/"; } -#line 5344 "built/tmp/cppBison.yxx.c" +#line 5343 "built/tmp/cppBison.yxx.c" break; case 120: /* function_operator: '%' */ @@ -5348,7 +5347,7 @@ yyreduce: { (yyval.str) = "%"; } -#line 5352 "built/tmp/cppBison.yxx.c" +#line 5351 "built/tmp/cppBison.yxx.c" break; case 121: /* function_operator: '+' */ @@ -5356,7 +5355,7 @@ yyreduce: { (yyval.str) = "+"; } -#line 5360 "built/tmp/cppBison.yxx.c" +#line 5359 "built/tmp/cppBison.yxx.c" break; case 122: /* function_operator: '-' */ @@ -5364,7 +5363,7 @@ yyreduce: { (yyval.str) = "-"; } -#line 5368 "built/tmp/cppBison.yxx.c" +#line 5367 "built/tmp/cppBison.yxx.c" break; case 123: /* function_operator: '|' */ @@ -5372,7 +5371,7 @@ yyreduce: { (yyval.str) = "|"; } -#line 5376 "built/tmp/cppBison.yxx.c" +#line 5375 "built/tmp/cppBison.yxx.c" break; case 124: /* function_operator: '&' */ @@ -5380,7 +5379,7 @@ yyreduce: { (yyval.str) = "&"; } -#line 5384 "built/tmp/cppBison.yxx.c" +#line 5383 "built/tmp/cppBison.yxx.c" break; case 125: /* function_operator: '^' */ @@ -5388,7 +5387,7 @@ yyreduce: { (yyval.str) = "^"; } -#line 5392 "built/tmp/cppBison.yxx.c" +#line 5391 "built/tmp/cppBison.yxx.c" break; case 126: /* function_operator: OROR */ @@ -5396,7 +5395,7 @@ yyreduce: { (yyval.str) = "||"; } -#line 5400 "built/tmp/cppBison.yxx.c" +#line 5399 "built/tmp/cppBison.yxx.c" break; case 127: /* function_operator: ANDAND */ @@ -5404,7 +5403,7 @@ yyreduce: { (yyval.str) = "&&"; } -#line 5408 "built/tmp/cppBison.yxx.c" +#line 5407 "built/tmp/cppBison.yxx.c" break; case 128: /* function_operator: EQCOMPARE */ @@ -5412,7 +5411,7 @@ yyreduce: { (yyval.str) = "=="; } -#line 5416 "built/tmp/cppBison.yxx.c" +#line 5415 "built/tmp/cppBison.yxx.c" break; case 129: /* function_operator: NECOMPARE */ @@ -5420,7 +5419,7 @@ yyreduce: { (yyval.str) = "!="; } -#line 5424 "built/tmp/cppBison.yxx.c" +#line 5423 "built/tmp/cppBison.yxx.c" break; case 130: /* function_operator: LECOMPARE */ @@ -5428,7 +5427,7 @@ yyreduce: { (yyval.str) = "<="; } -#line 5432 "built/tmp/cppBison.yxx.c" +#line 5431 "built/tmp/cppBison.yxx.c" break; case 131: /* function_operator: GECOMPARE */ @@ -5436,7 +5435,7 @@ yyreduce: { (yyval.str) = ">="; } -#line 5440 "built/tmp/cppBison.yxx.c" +#line 5439 "built/tmp/cppBison.yxx.c" break; case 132: /* function_operator: '<' */ @@ -5444,7 +5443,7 @@ yyreduce: { (yyval.str) = "<"; } -#line 5448 "built/tmp/cppBison.yxx.c" +#line 5447 "built/tmp/cppBison.yxx.c" break; case 133: /* function_operator: '>' */ @@ -5452,7 +5451,7 @@ yyreduce: { (yyval.str) = ">"; } -#line 5456 "built/tmp/cppBison.yxx.c" +#line 5455 "built/tmp/cppBison.yxx.c" break; case 134: /* function_operator: LSHIFT */ @@ -5460,7 +5459,7 @@ yyreduce: { (yyval.str) = "<<"; } -#line 5464 "built/tmp/cppBison.yxx.c" +#line 5463 "built/tmp/cppBison.yxx.c" break; case 135: /* function_operator: RSHIFT */ @@ -5468,7 +5467,7 @@ yyreduce: { (yyval.str) = ">>"; } -#line 5472 "built/tmp/cppBison.yxx.c" +#line 5471 "built/tmp/cppBison.yxx.c" break; case 136: /* function_operator: '=' */ @@ -5476,7 +5475,7 @@ yyreduce: { (yyval.str) = "="; } -#line 5480 "built/tmp/cppBison.yxx.c" +#line 5479 "built/tmp/cppBison.yxx.c" break; case 137: /* function_operator: ',' */ @@ -5484,7 +5483,7 @@ yyreduce: { (yyval.str) = ","; } -#line 5488 "built/tmp/cppBison.yxx.c" +#line 5487 "built/tmp/cppBison.yxx.c" break; case 138: /* function_operator: PLUSPLUS */ @@ -5492,7 +5491,7 @@ yyreduce: { (yyval.str) = "++"; } -#line 5496 "built/tmp/cppBison.yxx.c" +#line 5495 "built/tmp/cppBison.yxx.c" break; case 139: /* function_operator: MINUSMINUS */ @@ -5500,7 +5499,7 @@ yyreduce: { (yyval.str) = "--"; } -#line 5504 "built/tmp/cppBison.yxx.c" +#line 5503 "built/tmp/cppBison.yxx.c" break; case 140: /* function_operator: TIMESEQUAL */ @@ -5508,7 +5507,7 @@ yyreduce: { (yyval.str) = "*="; } -#line 5512 "built/tmp/cppBison.yxx.c" +#line 5511 "built/tmp/cppBison.yxx.c" break; case 141: /* function_operator: DIVIDEEQUAL */ @@ -5516,7 +5515,7 @@ yyreduce: { (yyval.str) = "/="; } -#line 5520 "built/tmp/cppBison.yxx.c" +#line 5519 "built/tmp/cppBison.yxx.c" break; case 142: /* function_operator: MODEQUAL */ @@ -5524,7 +5523,7 @@ yyreduce: { (yyval.str) = "%="; } -#line 5528 "built/tmp/cppBison.yxx.c" +#line 5527 "built/tmp/cppBison.yxx.c" break; case 143: /* function_operator: PLUSEQUAL */ @@ -5532,7 +5531,7 @@ yyreduce: { (yyval.str) = "+="; } -#line 5536 "built/tmp/cppBison.yxx.c" +#line 5535 "built/tmp/cppBison.yxx.c" break; case 144: /* function_operator: MINUSEQUAL */ @@ -5540,7 +5539,7 @@ yyreduce: { (yyval.str) = "-="; } -#line 5544 "built/tmp/cppBison.yxx.c" +#line 5543 "built/tmp/cppBison.yxx.c" break; case 145: /* function_operator: OREQUAL */ @@ -5548,7 +5547,7 @@ yyreduce: { (yyval.str) = "|="; } -#line 5552 "built/tmp/cppBison.yxx.c" +#line 5551 "built/tmp/cppBison.yxx.c" break; case 146: /* function_operator: ANDEQUAL */ @@ -5556,7 +5555,7 @@ yyreduce: { (yyval.str) = "&="; } -#line 5560 "built/tmp/cppBison.yxx.c" +#line 5559 "built/tmp/cppBison.yxx.c" break; case 147: /* function_operator: XOREQUAL */ @@ -5564,7 +5563,7 @@ yyreduce: { (yyval.str) = "^="; } -#line 5568 "built/tmp/cppBison.yxx.c" +#line 5567 "built/tmp/cppBison.yxx.c" break; case 148: /* function_operator: LSHIFTEQUAL */ @@ -5572,7 +5571,7 @@ yyreduce: { (yyval.str) = "<<="; } -#line 5576 "built/tmp/cppBison.yxx.c" +#line 5575 "built/tmp/cppBison.yxx.c" break; case 149: /* function_operator: RSHIFTEQUAL */ @@ -5580,7 +5579,7 @@ yyreduce: { (yyval.str) = ">>="; } -#line 5584 "built/tmp/cppBison.yxx.c" +#line 5583 "built/tmp/cppBison.yxx.c" break; case 150: /* function_operator: POINTSAT */ @@ -5588,7 +5587,7 @@ yyreduce: { (yyval.str) = "->"; } -#line 5592 "built/tmp/cppBison.yxx.c" +#line 5591 "built/tmp/cppBison.yxx.c" break; case 151: /* function_operator: '[' ']' */ @@ -5596,7 +5595,7 @@ yyreduce: { (yyval.str) = "[]"; } -#line 5600 "built/tmp/cppBison.yxx.c" +#line 5599 "built/tmp/cppBison.yxx.c" break; case 152: /* function_operator: '(' ')' */ @@ -5604,7 +5603,7 @@ yyreduce: { (yyval.str) = "()"; } -#line 5608 "built/tmp/cppBison.yxx.c" +#line 5607 "built/tmp/cppBison.yxx.c" break; case 153: /* function_operator: KW_NEW */ @@ -5612,7 +5611,7 @@ yyreduce: { (yyval.str) = "new"; } -#line 5616 "built/tmp/cppBison.yxx.c" +#line 5615 "built/tmp/cppBison.yxx.c" break; case 154: /* function_operator: KW_DELETE */ @@ -5620,7 +5619,7 @@ yyreduce: { (yyval.str) = "delete"; } -#line 5624 "built/tmp/cppBison.yxx.c" +#line 5623 "built/tmp/cppBison.yxx.c" break; case 159: /* $@14: %empty */ @@ -5628,7 +5627,7 @@ yyreduce: { push_scope(new CPPTemplateScope(current_scope)); } -#line 5632 "built/tmp/cppBison.yxx.c" +#line 5631 "built/tmp/cppBison.yxx.c" break; case 160: /* template_declaration: KW_TEMPLATE $@14 '<' template_formal_parameters '>' more_template_declaration */ @@ -5636,7 +5635,7 @@ yyreduce: { pop_scope(); } -#line 5640 "built/tmp/cppBison.yxx.c" +#line 5639 "built/tmp/cppBison.yxx.c" break; case 165: /* template_nonempty_formal_parameters: template_formal_parameter */ @@ -5646,7 +5645,7 @@ yyreduce: assert(ts != nullptr); ts->add_template_parameter((yyvsp[0].u.decl)); } -#line 5650 "built/tmp/cppBison.yxx.c" +#line 5649 "built/tmp/cppBison.yxx.c" break; case 166: /* template_nonempty_formal_parameters: template_nonempty_formal_parameters ',' template_formal_parameter */ @@ -5656,7 +5655,7 @@ yyreduce: assert(ts != nullptr); ts->add_template_parameter((yyvsp[0].u.decl)); } -#line 5660 "built/tmp/cppBison.yxx.c" +#line 5659 "built/tmp/cppBison.yxx.c" break; case 169: /* template_formal_parameter: typename_keyword */ @@ -5664,7 +5663,7 @@ yyreduce: { (yyval.u.decl) = CPPType::new_type(new CPPClassTemplateParameter(nullptr)); } -#line 5668 "built/tmp/cppBison.yxx.c" +#line 5667 "built/tmp/cppBison.yxx.c" break; case 170: /* template_formal_parameter: typename_keyword name */ @@ -5672,7 +5671,7 @@ yyreduce: { (yyval.u.decl) = CPPType::new_type(new CPPClassTemplateParameter((yyvsp[0].u.identifier))); } -#line 5676 "built/tmp/cppBison.yxx.c" +#line 5675 "built/tmp/cppBison.yxx.c" break; case 171: /* template_formal_parameter: typename_keyword name '=' full_type */ @@ -5680,7 +5679,7 @@ yyreduce: { (yyval.u.decl) = CPPType::new_type(new CPPClassTemplateParameter((yyvsp[-2].u.identifier), (yyvsp[0].u.type))); } -#line 5684 "built/tmp/cppBison.yxx.c" +#line 5683 "built/tmp/cppBison.yxx.c" break; case 172: /* template_formal_parameter: typename_keyword ELLIPSIS */ @@ -5690,7 +5689,7 @@ yyreduce: ctp->_packed = true; (yyval.u.decl) = CPPType::new_type(ctp); } -#line 5694 "built/tmp/cppBison.yxx.c" +#line 5693 "built/tmp/cppBison.yxx.c" break; case 173: /* template_formal_parameter: typename_keyword ELLIPSIS name */ @@ -5700,7 +5699,7 @@ yyreduce: ctp->_packed = true; (yyval.u.decl) = CPPType::new_type(ctp); } -#line 5704 "built/tmp/cppBison.yxx.c" +#line 5703 "built/tmp/cppBison.yxx.c" break; case 174: /* template_formal_parameter: template_formal_parameter_type formal_parameter_identifier template_parameter_maybe_initialize */ @@ -5710,7 +5709,7 @@ yyreduce: inst->set_initializer((yyvsp[0].u.expr)); (yyval.u.decl) = inst; } -#line 5714 "built/tmp/cppBison.yxx.c" +#line 5713 "built/tmp/cppBison.yxx.c" break; case 175: /* template_formal_parameter: KW_CONST template_formal_parameter_type formal_parameter_identifier template_parameter_maybe_initialize */ @@ -5721,7 +5720,7 @@ yyreduce: inst->set_initializer((yyvsp[0].u.expr)); (yyval.u.decl) = inst; } -#line 5725 "built/tmp/cppBison.yxx.c" +#line 5724 "built/tmp/cppBison.yxx.c" break; case 176: /* template_formal_parameter: template_formal_parameter_type parameter_pack_identifier */ @@ -5730,7 +5729,7 @@ yyreduce: CPPInstance *inst = new CPPInstance((yyvsp[-1].u.type), (yyvsp[0].u.inst_ident), 0, (yylsp[0]).file); (yyval.u.decl) = inst; } -#line 5734 "built/tmp/cppBison.yxx.c" +#line 5733 "built/tmp/cppBison.yxx.c" break; case 177: /* template_formal_parameter: KW_CONST template_formal_parameter_type parameter_pack_identifier */ @@ -5740,7 +5739,7 @@ yyreduce: CPPInstance *inst = new CPPInstance((yyvsp[-1].u.type), (yyvsp[0].u.inst_ident), 0, (yylsp[0]).file); (yyval.u.decl) = inst; } -#line 5744 "built/tmp/cppBison.yxx.c" +#line 5743 "built/tmp/cppBison.yxx.c" break; case 178: /* template_formal_parameter_type: simple_type */ @@ -5748,7 +5747,7 @@ yyreduce: { (yyval.u.type) = CPPType::new_type((yyvsp[0].u.simple_type)); } -#line 5752 "built/tmp/cppBison.yxx.c" +#line 5751 "built/tmp/cppBison.yxx.c" break; case 179: /* template_formal_parameter_type: IDENTIFIER */ @@ -5757,7 +5756,7 @@ yyreduce: yywarning("Not a type: " + (yyvsp[0].u.identifier)->get_fully_scoped_name(), (yylsp[0])); (yyval.u.type) = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_unknown)); } -#line 5761 "built/tmp/cppBison.yxx.c" +#line 5760 "built/tmp/cppBison.yxx.c" break; case 180: /* template_formal_parameter_type: TYPENAME_IDENTIFIER */ @@ -5769,7 +5768,7 @@ yyreduce: } assert((yyval.u.type) != nullptr); } -#line 5773 "built/tmp/cppBison.yxx.c" +#line 5772 "built/tmp/cppBison.yxx.c" break; case 181: /* template_formal_parameter_type: TYPEPACK_IDENTIFIER */ @@ -5781,7 +5780,7 @@ yyreduce: } assert((yyval.u.type) != nullptr); } -#line 5785 "built/tmp/cppBison.yxx.c" +#line 5784 "built/tmp/cppBison.yxx.c" break; case 182: /* instance_identifier: name_no_final optional_attributes */ @@ -5789,7 +5788,7 @@ yyreduce: { (yyval.u.inst_ident) = new CPPInstanceIdentifier((yyvsp[-1].u.identifier)); } -#line 5793 "built/tmp/cppBison.yxx.c" +#line 5792 "built/tmp/cppBison.yxx.c" break; case 183: /* instance_identifier: KW_OPERATOR function_operator optional_attributes */ @@ -5807,7 +5806,7 @@ yyreduce: (yyval.u.inst_ident) = new CPPInstanceIdentifier(ident); } -#line 5811 "built/tmp/cppBison.yxx.c" +#line 5810 "built/tmp/cppBison.yxx.c" break; case 184: /* instance_identifier: KW_OPERATOR SIMPLE_STRING IDENTIFIER optional_attributes */ @@ -5826,7 +5825,7 @@ yyreduce: (yyval.u.inst_ident) = new CPPInstanceIdentifier(ident); } -#line 5830 "built/tmp/cppBison.yxx.c" +#line 5829 "built/tmp/cppBison.yxx.c" break; case 185: /* instance_identifier: KW_CONST instance_identifier */ @@ -5835,7 +5834,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_const); } -#line 5839 "built/tmp/cppBison.yxx.c" +#line 5838 "built/tmp/cppBison.yxx.c" break; case 186: /* instance_identifier: KW_VOLATILE instance_identifier */ @@ -5844,7 +5843,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_volatile); } -#line 5848 "built/tmp/cppBison.yxx.c" +#line 5847 "built/tmp/cppBison.yxx.c" break; case 187: /* instance_identifier: '*' optional_attributes instance_identifier */ @@ -5853,7 +5852,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_pointer); } -#line 5857 "built/tmp/cppBison.yxx.c" +#line 5856 "built/tmp/cppBison.yxx.c" break; case 188: /* instance_identifier: '&' optional_attributes instance_identifier */ @@ -5862,7 +5861,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_reference); } -#line 5866 "built/tmp/cppBison.yxx.c" +#line 5865 "built/tmp/cppBison.yxx.c" break; case 189: /* instance_identifier: ANDAND optional_attributes instance_identifier */ @@ -5871,7 +5870,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_rvalue_reference); } -#line 5875 "built/tmp/cppBison.yxx.c" +#line 5874 "built/tmp/cppBison.yxx.c" break; case 190: /* instance_identifier: SCOPING '*' optional_attributes instance_identifier */ @@ -5880,7 +5879,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_scoped_pointer_modifier((yyvsp[-3].u.identifier)); } -#line 5884 "built/tmp/cppBison.yxx.c" +#line 5883 "built/tmp/cppBison.yxx.c" break; case 191: /* instance_identifier: instance_identifier '[' optional_const_expr ']' optional_attributes */ @@ -5889,7 +5888,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[-4].u.inst_ident); (yyval.u.inst_ident)->add_array_modifier((yyvsp[-2].u.expr)); } -#line 5893 "built/tmp/cppBison.yxx.c" +#line 5892 "built/tmp/cppBison.yxx.c" break; case 192: /* instance_identifier: '(' instance_identifier ')' */ @@ -5898,7 +5897,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[-1].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_paren); } -#line 5902 "built/tmp/cppBison.yxx.c" +#line 5901 "built/tmp/cppBison.yxx.c" break; case 193: /* $@15: %empty */ @@ -5915,7 +5914,7 @@ yyreduce: push_scope(scope); } -#line 5919 "built/tmp/cppBison.yxx.c" +#line 5918 "built/tmp/cppBison.yxx.c" break; case 194: /* instance_identifier: instance_identifier '(' $@15 formal_parameter_list ')' function_post */ @@ -5933,7 +5932,7 @@ yyreduce: (yyval.u.inst_ident)->add_func_modifier((yyvsp[-2].u.param_list), (yyvsp[0].u.integer)); } } -#line 5937 "built/tmp/cppBison.yxx.c" +#line 5936 "built/tmp/cppBison.yxx.c" break; case 195: /* instance_identifier_and_maybe_trailing_return_type: instance_identifier maybe_trailing_return_type */ @@ -5947,7 +5946,7 @@ yyreduce: } (yyval.u.inst_ident) = (yyvsp[-1].u.inst_ident); } -#line 5951 "built/tmp/cppBison.yxx.c" +#line 5950 "built/tmp/cppBison.yxx.c" break; case 196: /* instance_identifier_and_maybe_trailing_return_type: instance_identifier ':' const_expr */ @@ -5957,7 +5956,7 @@ yyreduce: (yyvsp[-2].u.inst_ident)->_bit_width = (yyvsp[0].u.expr); (yyval.u.inst_ident) = (yyvsp[-2].u.inst_ident); } -#line 5961 "built/tmp/cppBison.yxx.c" +#line 5960 "built/tmp/cppBison.yxx.c" break; case 197: /* maybe_trailing_return_type: empty */ @@ -5965,7 +5964,7 @@ yyreduce: { (yyval.u.type) = nullptr; } -#line 5969 "built/tmp/cppBison.yxx.c" +#line 5968 "built/tmp/cppBison.yxx.c" break; case 198: /* maybe_trailing_return_type: POINTSAT predefined_type empty_instance_identifier */ @@ -5973,7 +5972,7 @@ yyreduce: { (yyval.u.type) = (yyvsp[0].u.inst_ident)->unroll_type((yyvsp[-1].u.type)); } -#line 5977 "built/tmp/cppBison.yxx.c" +#line 5976 "built/tmp/cppBison.yxx.c" break; case 199: /* maybe_trailing_return_type: POINTSAT KW_CONST predefined_type empty_instance_identifier */ @@ -5982,7 +5981,7 @@ yyreduce: (yyvsp[0].u.inst_ident)->add_modifier(IIT_const); (yyval.u.type) = (yyvsp[0].u.inst_ident)->unroll_type((yyvsp[-1].u.type)); } -#line 5986 "built/tmp/cppBison.yxx.c" +#line 5985 "built/tmp/cppBison.yxx.c" break; case 200: /* maybe_comma_identifier: empty */ @@ -5990,7 +5989,7 @@ yyreduce: { (yyval.u.identifier) = nullptr; } -#line 5994 "built/tmp/cppBison.yxx.c" +#line 5993 "built/tmp/cppBison.yxx.c" break; case 201: /* maybe_comma_identifier: ',' IDENTIFIER */ @@ -5998,7 +5997,7 @@ yyreduce: { (yyval.u.identifier) = (yyvsp[0].u.identifier); } -#line 6002 "built/tmp/cppBison.yxx.c" +#line 6001 "built/tmp/cppBison.yxx.c" break; case 202: /* function_parameter_list: empty */ @@ -6006,7 +6005,7 @@ yyreduce: { (yyval.u.param_list) = new CPPParameterList; } -#line 6010 "built/tmp/cppBison.yxx.c" +#line 6009 "built/tmp/cppBison.yxx.c" break; case 203: /* function_parameter_list: ELLIPSIS */ @@ -6015,7 +6014,7 @@ yyreduce: (yyval.u.param_list) = new CPPParameterList; (yyval.u.param_list)->_includes_ellipsis = true; } -#line 6019 "built/tmp/cppBison.yxx.c" +#line 6018 "built/tmp/cppBison.yxx.c" break; case 204: /* function_parameter_list: function_parameters */ @@ -6023,7 +6022,7 @@ yyreduce: { (yyval.u.param_list) = (yyvsp[0].u.param_list); } -#line 6027 "built/tmp/cppBison.yxx.c" +#line 6026 "built/tmp/cppBison.yxx.c" break; case 205: /* function_parameter_list: function_parameters ',' ELLIPSIS */ @@ -6032,7 +6031,7 @@ yyreduce: (yyval.u.param_list) = (yyvsp[-2].u.param_list); (yyval.u.param_list)->_includes_ellipsis = true; } -#line 6036 "built/tmp/cppBison.yxx.c" +#line 6035 "built/tmp/cppBison.yxx.c" break; case 206: /* function_parameter_list: function_parameters ELLIPSIS */ @@ -6041,7 +6040,7 @@ yyreduce: (yyval.u.param_list) = (yyvsp[-1].u.param_list); (yyval.u.param_list)->_includes_ellipsis = true; } -#line 6045 "built/tmp/cppBison.yxx.c" +#line 6044 "built/tmp/cppBison.yxx.c" break; case 207: /* function_parameters: function_parameter */ @@ -6050,7 +6049,7 @@ yyreduce: (yyval.u.param_list) = new CPPParameterList; (yyval.u.param_list)->_parameters.push_back((yyvsp[0].u.instance)); } -#line 6054 "built/tmp/cppBison.yxx.c" +#line 6053 "built/tmp/cppBison.yxx.c" break; case 208: /* function_parameters: function_parameters ',' function_parameter */ @@ -6059,7 +6058,7 @@ yyreduce: (yyval.u.param_list) = (yyvsp[-2].u.param_list); (yyval.u.param_list)->_parameters.push_back((yyvsp[0].u.instance)); } -#line 6063 "built/tmp/cppBison.yxx.c" +#line 6062 "built/tmp/cppBison.yxx.c" break; case 209: /* formal_parameter_list: empty */ @@ -6067,7 +6066,7 @@ yyreduce: { (yyval.u.param_list) = new CPPParameterList; } -#line 6071 "built/tmp/cppBison.yxx.c" +#line 6070 "built/tmp/cppBison.yxx.c" break; case 210: /* formal_parameter_list: ELLIPSIS */ @@ -6076,7 +6075,7 @@ yyreduce: (yyval.u.param_list) = new CPPParameterList; (yyval.u.param_list)->_includes_ellipsis = true; } -#line 6080 "built/tmp/cppBison.yxx.c" +#line 6079 "built/tmp/cppBison.yxx.c" break; case 211: /* formal_parameter_list: formal_parameters */ @@ -6084,7 +6083,7 @@ yyreduce: { (yyval.u.param_list) = (yyvsp[0].u.param_list); } -#line 6088 "built/tmp/cppBison.yxx.c" +#line 6087 "built/tmp/cppBison.yxx.c" break; case 212: /* formal_parameter_list: formal_parameters ',' ELLIPSIS */ @@ -6093,7 +6092,7 @@ yyreduce: (yyval.u.param_list) = (yyvsp[-2].u.param_list); (yyval.u.param_list)->_includes_ellipsis = true; } -#line 6097 "built/tmp/cppBison.yxx.c" +#line 6096 "built/tmp/cppBison.yxx.c" break; case 213: /* formal_parameter_list: formal_parameters ELLIPSIS */ @@ -6102,7 +6101,7 @@ yyreduce: (yyval.u.param_list) = (yyvsp[-1].u.param_list); (yyval.u.param_list)->_includes_ellipsis = true; } -#line 6106 "built/tmp/cppBison.yxx.c" +#line 6105 "built/tmp/cppBison.yxx.c" break; case 214: /* formal_parameters: formal_parameter */ @@ -6111,7 +6110,7 @@ yyreduce: (yyval.u.param_list) = new CPPParameterList; (yyval.u.param_list)->_parameters.push_back((yyvsp[0].u.instance)); } -#line 6115 "built/tmp/cppBison.yxx.c" +#line 6114 "built/tmp/cppBison.yxx.c" break; case 215: /* formal_parameters: formal_parameters ',' formal_parameter */ @@ -6120,7 +6119,7 @@ yyreduce: (yyval.u.param_list) = (yyvsp[-2].u.param_list); (yyval.u.param_list)->_parameters.push_back((yyvsp[0].u.instance)); } -#line 6124 "built/tmp/cppBison.yxx.c" +#line 6123 "built/tmp/cppBison.yxx.c" break; case 216: /* template_parameter_maybe_initialize: empty */ @@ -6128,7 +6127,7 @@ yyreduce: { (yyval.u.expr) = nullptr; } -#line 6132 "built/tmp/cppBison.yxx.c" +#line 6131 "built/tmp/cppBison.yxx.c" break; case 217: /* template_parameter_maybe_initialize: '=' no_angle_bracket_const_expr */ @@ -6136,7 +6135,7 @@ yyreduce: { (yyval.u.expr) = (yyvsp[0].u.expr); } -#line 6140 "built/tmp/cppBison.yxx.c" +#line 6139 "built/tmp/cppBison.yxx.c" break; case 218: /* maybe_initialize: empty */ @@ -6144,7 +6143,7 @@ yyreduce: { (yyval.u.expr) = nullptr; } -#line 6148 "built/tmp/cppBison.yxx.c" +#line 6147 "built/tmp/cppBison.yxx.c" break; case 219: /* maybe_initialize: '=' const_expr */ @@ -6152,7 +6151,7 @@ yyreduce: { (yyval.u.expr) = (yyvsp[0].u.expr); } -#line 6156 "built/tmp/cppBison.yxx.c" +#line 6155 "built/tmp/cppBison.yxx.c" break; case 220: /* maybe_initialize_or_constructor_body: ';' */ @@ -6160,7 +6159,7 @@ yyreduce: { (yyval.u.expr) = nullptr; } -#line 6164 "built/tmp/cppBison.yxx.c" +#line 6163 "built/tmp/cppBison.yxx.c" break; case 221: /* maybe_initialize_or_constructor_body: '{' code '}' */ @@ -6168,7 +6167,7 @@ yyreduce: { (yyval.u.expr) = nullptr; } -#line 6172 "built/tmp/cppBison.yxx.c" +#line 6171 "built/tmp/cppBison.yxx.c" break; case 222: /* maybe_initialize_or_constructor_body: ':' constructor_inits '{' code '}' */ @@ -6176,7 +6175,7 @@ yyreduce: { (yyval.u.expr) = nullptr; } -#line 6180 "built/tmp/cppBison.yxx.c" +#line 6179 "built/tmp/cppBison.yxx.c" break; case 223: /* maybe_initialize_or_constructor_body: '=' KW_DEFAULT ';' */ @@ -6184,7 +6183,7 @@ yyreduce: { (yyval.u.expr) = new CPPExpression(CPPExpression::get_default()); } -#line 6188 "built/tmp/cppBison.yxx.c" +#line 6187 "built/tmp/cppBison.yxx.c" break; case 224: /* maybe_initialize_or_constructor_body: '=' KW_DELETE ';' */ @@ -6192,7 +6191,7 @@ yyreduce: { (yyval.u.expr) = new CPPExpression(CPPExpression::get_delete()); } -#line 6196 "built/tmp/cppBison.yxx.c" +#line 6195 "built/tmp/cppBison.yxx.c" break; case 225: /* maybe_initialize_or_function_body: ';' */ @@ -6200,7 +6199,7 @@ yyreduce: { (yyval.u.expr) = nullptr; } -#line 6204 "built/tmp/cppBison.yxx.c" +#line 6203 "built/tmp/cppBison.yxx.c" break; case 226: /* maybe_initialize_or_function_body: '{' code '}' */ @@ -6208,7 +6207,7 @@ yyreduce: { (yyval.u.expr) = nullptr; } -#line 6212 "built/tmp/cppBison.yxx.c" +#line 6211 "built/tmp/cppBison.yxx.c" break; case 227: /* maybe_initialize_or_function_body: '=' const_expr ';' */ @@ -6216,7 +6215,7 @@ yyreduce: { (yyval.u.expr) = (yyvsp[-1].u.expr); } -#line 6220 "built/tmp/cppBison.yxx.c" +#line 6219 "built/tmp/cppBison.yxx.c" break; case 228: /* maybe_initialize_or_function_body: '=' KW_DEFAULT ';' */ @@ -6224,7 +6223,7 @@ yyreduce: { (yyval.u.expr) = new CPPExpression(CPPExpression::get_default()); } -#line 6228 "built/tmp/cppBison.yxx.c" +#line 6227 "built/tmp/cppBison.yxx.c" break; case 229: /* maybe_initialize_or_function_body: '=' KW_DELETE ';' */ @@ -6232,7 +6231,7 @@ yyreduce: { (yyval.u.expr) = new CPPExpression(CPPExpression::get_delete()); } -#line 6236 "built/tmp/cppBison.yxx.c" +#line 6235 "built/tmp/cppBison.yxx.c" break; case 230: /* maybe_initialize_or_function_body: '=' '{' structure_init '}' */ @@ -6240,14 +6239,14 @@ yyreduce: { (yyval.u.expr) = nullptr; } -#line 6244 "built/tmp/cppBison.yxx.c" +#line 6243 "built/tmp/cppBison.yxx.c" break; case 234: /* structure_init_body: const_expr */ #line 2097 "dtool/src/cppparser/cppBison.yxx" { } -#line 6251 "built/tmp/cppBison.yxx.c" +#line 6250 "built/tmp/cppBison.yxx.c" break; case 238: /* function_parameter: type formal_parameter_identifier maybe_initialize */ @@ -6256,7 +6255,7 @@ yyreduce: (yyval.u.instance) = new CPPInstance((yyvsp[-2].u.type), (yyvsp[-1].u.inst_ident), 0, (yylsp[-1]).file); (yyval.u.instance)->set_initializer((yyvsp[0].u.expr)); } -#line 6260 "built/tmp/cppBison.yxx.c" +#line 6259 "built/tmp/cppBison.yxx.c" break; case 239: /* function_parameter: KW_CONST type formal_parameter_identifier maybe_initialize */ @@ -6266,7 +6265,7 @@ yyreduce: (yyval.u.instance) = new CPPInstance((yyvsp[-2].u.type), (yyvsp[-1].u.inst_ident), 0, (yylsp[-1]).file); (yyval.u.instance)->set_initializer((yyvsp[0].u.expr)); } -#line 6270 "built/tmp/cppBison.yxx.c" +#line 6269 "built/tmp/cppBison.yxx.c" break; case 240: /* function_parameter: KW_CONST KW_REGISTER type formal_parameter_identifier maybe_initialize */ @@ -6276,7 +6275,7 @@ yyreduce: (yyval.u.instance) = new CPPInstance((yyvsp[-2].u.type), (yyvsp[-1].u.inst_ident), 0, (yylsp[-2]).file); (yyval.u.instance)->set_initializer((yyvsp[0].u.expr)); } -#line 6280 "built/tmp/cppBison.yxx.c" +#line 6279 "built/tmp/cppBison.yxx.c" break; case 241: /* function_parameter: type_pack parameter_pack_identifier maybe_initialize */ @@ -6285,7 +6284,7 @@ yyreduce: (yyval.u.instance) = new CPPInstance((yyvsp[-2].u.type), (yyvsp[-1].u.inst_ident), 0, (yylsp[-1]).file); (yyval.u.instance)->set_initializer((yyvsp[0].u.expr)); } -#line 6289 "built/tmp/cppBison.yxx.c" +#line 6288 "built/tmp/cppBison.yxx.c" break; case 242: /* function_parameter: KW_CONST type_pack parameter_pack_identifier maybe_initialize */ @@ -6295,7 +6294,7 @@ yyreduce: (yyval.u.instance) = new CPPInstance((yyvsp[-2].u.type), (yyvsp[-1].u.inst_ident), 0, (yylsp[-1]).file); (yyval.u.instance)->set_initializer((yyvsp[0].u.expr)); } -#line 6299 "built/tmp/cppBison.yxx.c" +#line 6298 "built/tmp/cppBison.yxx.c" break; case 243: /* function_parameter: KW_CONST KW_REGISTER type_pack parameter_pack_identifier maybe_initialize */ @@ -6305,7 +6304,7 @@ yyreduce: (yyval.u.instance) = new CPPInstance((yyvsp[-2].u.type), (yyvsp[-1].u.inst_ident), 0, (yylsp[-2]).file); (yyval.u.instance)->set_initializer((yyvsp[0].u.expr)); } -#line 6309 "built/tmp/cppBison.yxx.c" +#line 6308 "built/tmp/cppBison.yxx.c" break; case 244: /* function_parameter: KW_REGISTER function_parameter */ @@ -6313,7 +6312,7 @@ yyreduce: { (yyval.u.instance) = (yyvsp[0].u.instance); } -#line 6317 "built/tmp/cppBison.yxx.c" +#line 6316 "built/tmp/cppBison.yxx.c" break; case 245: /* function_parameter: ATTR_LEFT attribute_specifiers ATTR_RIGHT function_parameter */ @@ -6321,7 +6320,7 @@ yyreduce: { (yyval.u.instance) = (yyvsp[0].u.instance); } -#line 6325 "built/tmp/cppBison.yxx.c" +#line 6324 "built/tmp/cppBison.yxx.c" break; case 246: /* formal_parameter: function_parameter */ @@ -6329,7 +6328,7 @@ yyreduce: { (yyval.u.instance) = (yyvsp[0].u.instance); } -#line 6333 "built/tmp/cppBison.yxx.c" +#line 6332 "built/tmp/cppBison.yxx.c" break; case 247: /* formal_parameter: formal_const_expr */ @@ -6340,7 +6339,7 @@ yyreduce: (yyval.u.instance) = new CPPInstance(type, "expr"); (yyval.u.instance)->set_initializer((yyvsp[0].u.expr)); } -#line 6344 "built/tmp/cppBison.yxx.c" +#line 6343 "built/tmp/cppBison.yxx.c" break; case 248: /* not_paren_formal_parameter_identifier: empty */ @@ -6348,7 +6347,7 @@ yyreduce: { (yyval.u.inst_ident) = new CPPInstanceIdentifier(nullptr); } -#line 6352 "built/tmp/cppBison.yxx.c" +#line 6351 "built/tmp/cppBison.yxx.c" break; case 249: /* not_paren_formal_parameter_identifier: name_no_final optional_attributes */ @@ -6356,7 +6355,7 @@ yyreduce: { (yyval.u.inst_ident) = new CPPInstanceIdentifier((yyvsp[-1].u.identifier)); } -#line 6360 "built/tmp/cppBison.yxx.c" +#line 6359 "built/tmp/cppBison.yxx.c" break; case 250: /* not_paren_formal_parameter_identifier: KW_CONST not_paren_formal_parameter_identifier */ @@ -6365,7 +6364,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_const); } -#line 6369 "built/tmp/cppBison.yxx.c" +#line 6368 "built/tmp/cppBison.yxx.c" break; case 251: /* not_paren_formal_parameter_identifier: KW_VOLATILE not_paren_formal_parameter_identifier */ @@ -6374,7 +6373,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_volatile); } -#line 6378 "built/tmp/cppBison.yxx.c" +#line 6377 "built/tmp/cppBison.yxx.c" break; case 252: /* not_paren_formal_parameter_identifier: '*' optional_attributes not_paren_formal_parameter_identifier */ @@ -6383,7 +6382,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_pointer); } -#line 6387 "built/tmp/cppBison.yxx.c" +#line 6386 "built/tmp/cppBison.yxx.c" break; case 253: /* not_paren_formal_parameter_identifier: '&' optional_attributes not_paren_formal_parameter_identifier */ @@ -6392,7 +6391,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_reference); } -#line 6396 "built/tmp/cppBison.yxx.c" +#line 6395 "built/tmp/cppBison.yxx.c" break; case 254: /* not_paren_formal_parameter_identifier: ANDAND optional_attributes not_paren_formal_parameter_identifier */ @@ -6401,7 +6400,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_rvalue_reference); } -#line 6405 "built/tmp/cppBison.yxx.c" +#line 6404 "built/tmp/cppBison.yxx.c" break; case 255: /* not_paren_formal_parameter_identifier: SCOPING '*' optional_attributes not_paren_formal_parameter_identifier */ @@ -6410,7 +6409,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_scoped_pointer_modifier((yyvsp[-3].u.identifier)); } -#line 6414 "built/tmp/cppBison.yxx.c" +#line 6413 "built/tmp/cppBison.yxx.c" break; case 256: /* not_paren_formal_parameter_identifier: not_paren_formal_parameter_identifier '[' optional_const_expr ']' optional_attributes */ @@ -6419,7 +6418,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[-4].u.inst_ident); (yyval.u.inst_ident)->add_array_modifier((yyvsp[-2].u.expr)); } -#line 6423 "built/tmp/cppBison.yxx.c" +#line 6422 "built/tmp/cppBison.yxx.c" break; case 257: /* formal_parameter_identifier: empty */ @@ -6427,7 +6426,7 @@ yyreduce: { (yyval.u.inst_ident) = new CPPInstanceIdentifier(nullptr); } -#line 6431 "built/tmp/cppBison.yxx.c" +#line 6430 "built/tmp/cppBison.yxx.c" break; case 258: /* formal_parameter_identifier: name_no_final optional_attributes */ @@ -6435,7 +6434,7 @@ yyreduce: { (yyval.u.inst_ident) = new CPPInstanceIdentifier((yyvsp[-1].u.identifier)); } -#line 6439 "built/tmp/cppBison.yxx.c" +#line 6438 "built/tmp/cppBison.yxx.c" break; case 259: /* formal_parameter_identifier: KW_CONST formal_parameter_identifier */ @@ -6444,7 +6443,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_const); } -#line 6448 "built/tmp/cppBison.yxx.c" +#line 6447 "built/tmp/cppBison.yxx.c" break; case 260: /* formal_parameter_identifier: KW_VOLATILE formal_parameter_identifier */ @@ -6453,7 +6452,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_volatile); } -#line 6457 "built/tmp/cppBison.yxx.c" +#line 6456 "built/tmp/cppBison.yxx.c" break; case 261: /* formal_parameter_identifier: '*' optional_attributes formal_parameter_identifier */ @@ -6462,7 +6461,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_pointer); } -#line 6466 "built/tmp/cppBison.yxx.c" +#line 6465 "built/tmp/cppBison.yxx.c" break; case 262: /* formal_parameter_identifier: '&' optional_attributes formal_parameter_identifier */ @@ -6471,7 +6470,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_reference); } -#line 6475 "built/tmp/cppBison.yxx.c" +#line 6474 "built/tmp/cppBison.yxx.c" break; case 263: /* formal_parameter_identifier: ANDAND optional_attributes formal_parameter_identifier */ @@ -6480,7 +6479,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_rvalue_reference); } -#line 6484 "built/tmp/cppBison.yxx.c" +#line 6483 "built/tmp/cppBison.yxx.c" break; case 264: /* formal_parameter_identifier: SCOPING '*' optional_attributes formal_parameter_identifier */ @@ -6489,7 +6488,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_scoped_pointer_modifier((yyvsp[-3].u.identifier)); } -#line 6493 "built/tmp/cppBison.yxx.c" +#line 6492 "built/tmp/cppBison.yxx.c" break; case 265: /* formal_parameter_identifier: formal_parameter_identifier '[' optional_const_expr ']' optional_attributes */ @@ -6498,7 +6497,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[-4].u.inst_ident); (yyval.u.inst_ident)->add_array_modifier((yyvsp[-2].u.expr)); } -#line 6502 "built/tmp/cppBison.yxx.c" +#line 6501 "built/tmp/cppBison.yxx.c" break; case 266: /* formal_parameter_identifier: '(' formal_parameter_identifier ')' '(' function_parameter_list ')' function_post */ @@ -6508,7 +6507,7 @@ yyreduce: (yyval.u.inst_ident)->add_modifier(IIT_paren); (yyval.u.inst_ident)->add_func_modifier((yyvsp[-2].u.param_list), (yyvsp[0].u.integer)); } -#line 6512 "built/tmp/cppBison.yxx.c" +#line 6511 "built/tmp/cppBison.yxx.c" break; case 267: /* formal_parameter_identifier: '(' formal_parameter_identifier ')' */ @@ -6517,7 +6516,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[-1].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_paren); } -#line 6521 "built/tmp/cppBison.yxx.c" +#line 6520 "built/tmp/cppBison.yxx.c" break; case 268: /* parameter_pack_identifier: ELLIPSIS */ @@ -6526,7 +6525,7 @@ yyreduce: (yyval.u.inst_ident) = new CPPInstanceIdentifier(nullptr); (yyval.u.inst_ident)->_packed = true; } -#line 6530 "built/tmp/cppBison.yxx.c" +#line 6529 "built/tmp/cppBison.yxx.c" break; case 269: /* parameter_pack_identifier: ELLIPSIS name optional_attributes */ @@ -6535,7 +6534,7 @@ yyreduce: (yyval.u.inst_ident) = new CPPInstanceIdentifier((yyvsp[-1].u.identifier)); (yyval.u.inst_ident)->_packed = true; } -#line 6539 "built/tmp/cppBison.yxx.c" +#line 6538 "built/tmp/cppBison.yxx.c" break; case 270: /* parameter_pack_identifier: KW_CONST parameter_pack_identifier */ @@ -6544,7 +6543,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_const); } -#line 6548 "built/tmp/cppBison.yxx.c" +#line 6547 "built/tmp/cppBison.yxx.c" break; case 271: /* parameter_pack_identifier: KW_VOLATILE parameter_pack_identifier */ @@ -6553,7 +6552,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_volatile); } -#line 6557 "built/tmp/cppBison.yxx.c" +#line 6556 "built/tmp/cppBison.yxx.c" break; case 272: /* parameter_pack_identifier: '*' optional_attributes parameter_pack_identifier */ @@ -6562,7 +6561,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_pointer); } -#line 6566 "built/tmp/cppBison.yxx.c" +#line 6565 "built/tmp/cppBison.yxx.c" break; case 273: /* parameter_pack_identifier: '&' optional_attributes parameter_pack_identifier */ @@ -6571,7 +6570,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_reference); } -#line 6575 "built/tmp/cppBison.yxx.c" +#line 6574 "built/tmp/cppBison.yxx.c" break; case 274: /* parameter_pack_identifier: ANDAND optional_attributes parameter_pack_identifier */ @@ -6580,7 +6579,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_rvalue_reference); } -#line 6584 "built/tmp/cppBison.yxx.c" +#line 6583 "built/tmp/cppBison.yxx.c" break; case 275: /* parameter_pack_identifier: SCOPING '*' optional_attributes parameter_pack_identifier */ @@ -6589,7 +6588,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_scoped_pointer_modifier((yyvsp[-3].u.identifier)); } -#line 6593 "built/tmp/cppBison.yxx.c" +#line 6592 "built/tmp/cppBison.yxx.c" break; case 276: /* parameter_pack_identifier: parameter_pack_identifier '[' optional_const_expr ']' optional_attributes */ @@ -6598,7 +6597,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[-4].u.inst_ident); (yyval.u.inst_ident)->add_array_modifier((yyvsp[-2].u.expr)); } -#line 6602 "built/tmp/cppBison.yxx.c" +#line 6601 "built/tmp/cppBison.yxx.c" break; case 277: /* parameter_pack_identifier: '(' parameter_pack_identifier ')' '(' function_parameter_list ')' function_post */ @@ -6608,7 +6607,7 @@ yyreduce: (yyval.u.inst_ident)->add_modifier(IIT_paren); (yyval.u.inst_ident)->add_func_modifier((yyvsp[-2].u.param_list), (yyvsp[0].u.integer)); } -#line 6612 "built/tmp/cppBison.yxx.c" +#line 6611 "built/tmp/cppBison.yxx.c" break; case 278: /* parameter_pack_identifier: '(' parameter_pack_identifier ')' */ @@ -6617,7 +6616,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[-1].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_paren); } -#line 6621 "built/tmp/cppBison.yxx.c" +#line 6620 "built/tmp/cppBison.yxx.c" break; case 279: /* not_paren_empty_instance_identifier: empty */ @@ -6625,7 +6624,7 @@ yyreduce: { (yyval.u.inst_ident) = new CPPInstanceIdentifier(nullptr); } -#line 6629 "built/tmp/cppBison.yxx.c" +#line 6628 "built/tmp/cppBison.yxx.c" break; case 280: /* not_paren_empty_instance_identifier: ELLIPSIS */ @@ -6634,7 +6633,7 @@ yyreduce: (yyval.u.inst_ident) = new CPPInstanceIdentifier(nullptr); (yyval.u.inst_ident)->_packed = true; } -#line 6638 "built/tmp/cppBison.yxx.c" +#line 6637 "built/tmp/cppBison.yxx.c" break; case 281: /* not_paren_empty_instance_identifier: ELLIPSIS name optional_attributes */ @@ -6643,7 +6642,7 @@ yyreduce: (yyval.u.inst_ident) = new CPPInstanceIdentifier((yyvsp[-1].u.identifier)); (yyval.u.inst_ident)->_packed = true; } -#line 6647 "built/tmp/cppBison.yxx.c" +#line 6646 "built/tmp/cppBison.yxx.c" break; case 282: /* not_paren_empty_instance_identifier: KW_CONST not_paren_empty_instance_identifier */ @@ -6652,7 +6651,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_const); } -#line 6656 "built/tmp/cppBison.yxx.c" +#line 6655 "built/tmp/cppBison.yxx.c" break; case 283: /* not_paren_empty_instance_identifier: KW_VOLATILE not_paren_empty_instance_identifier */ @@ -6661,7 +6660,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_volatile); } -#line 6665 "built/tmp/cppBison.yxx.c" +#line 6664 "built/tmp/cppBison.yxx.c" break; case 284: /* not_paren_empty_instance_identifier: '*' optional_attributes not_paren_empty_instance_identifier */ @@ -6670,7 +6669,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_pointer); } -#line 6674 "built/tmp/cppBison.yxx.c" +#line 6673 "built/tmp/cppBison.yxx.c" break; case 285: /* not_paren_empty_instance_identifier: '&' optional_attributes not_paren_empty_instance_identifier */ @@ -6679,7 +6678,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_reference); } -#line 6683 "built/tmp/cppBison.yxx.c" +#line 6682 "built/tmp/cppBison.yxx.c" break; case 286: /* not_paren_empty_instance_identifier: ANDAND optional_attributes not_paren_empty_instance_identifier */ @@ -6688,7 +6687,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_rvalue_reference); } -#line 6692 "built/tmp/cppBison.yxx.c" +#line 6691 "built/tmp/cppBison.yxx.c" break; case 287: /* not_paren_empty_instance_identifier: SCOPING '*' optional_attributes not_paren_empty_instance_identifier */ @@ -6697,7 +6696,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_scoped_pointer_modifier((yyvsp[-3].u.identifier)); } -#line 6701 "built/tmp/cppBison.yxx.c" +#line 6700 "built/tmp/cppBison.yxx.c" break; case 288: /* not_paren_empty_instance_identifier: not_paren_empty_instance_identifier '[' optional_const_expr ']' optional_attributes */ @@ -6706,7 +6705,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[-4].u.inst_ident); (yyval.u.inst_ident)->add_array_modifier((yyvsp[-2].u.expr)); } -#line 6710 "built/tmp/cppBison.yxx.c" +#line 6709 "built/tmp/cppBison.yxx.c" break; case 289: /* empty_instance_identifier: empty */ @@ -6714,7 +6713,7 @@ yyreduce: { (yyval.u.inst_ident) = new CPPInstanceIdentifier(nullptr); } -#line 6718 "built/tmp/cppBison.yxx.c" +#line 6717 "built/tmp/cppBison.yxx.c" break; case 290: /* empty_instance_identifier: ELLIPSIS */ @@ -6723,7 +6722,7 @@ yyreduce: (yyval.u.inst_ident) = new CPPInstanceIdentifier(nullptr); (yyval.u.inst_ident)->_packed = true; } -#line 6727 "built/tmp/cppBison.yxx.c" +#line 6726 "built/tmp/cppBison.yxx.c" break; case 291: /* empty_instance_identifier: ELLIPSIS name optional_attributes */ @@ -6732,7 +6731,7 @@ yyreduce: (yyval.u.inst_ident) = new CPPInstanceIdentifier((yyvsp[-1].u.identifier)); (yyval.u.inst_ident)->_packed = true; } -#line 6736 "built/tmp/cppBison.yxx.c" +#line 6735 "built/tmp/cppBison.yxx.c" break; case 292: /* empty_instance_identifier: KW_CONST empty_instance_identifier */ @@ -6741,7 +6740,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_const); } -#line 6745 "built/tmp/cppBison.yxx.c" +#line 6744 "built/tmp/cppBison.yxx.c" break; case 293: /* empty_instance_identifier: KW_VOLATILE empty_instance_identifier */ @@ -6750,7 +6749,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_volatile); } -#line 6754 "built/tmp/cppBison.yxx.c" +#line 6753 "built/tmp/cppBison.yxx.c" break; case 294: /* empty_instance_identifier: '*' optional_attributes not_paren_empty_instance_identifier */ @@ -6759,7 +6758,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_pointer); } -#line 6763 "built/tmp/cppBison.yxx.c" +#line 6762 "built/tmp/cppBison.yxx.c" break; case 295: /* empty_instance_identifier: '&' optional_attributes not_paren_empty_instance_identifier */ @@ -6768,7 +6767,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_reference); } -#line 6772 "built/tmp/cppBison.yxx.c" +#line 6771 "built/tmp/cppBison.yxx.c" break; case 296: /* empty_instance_identifier: ANDAND optional_attributes not_paren_empty_instance_identifier */ @@ -6777,7 +6776,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_rvalue_reference); } -#line 6781 "built/tmp/cppBison.yxx.c" +#line 6780 "built/tmp/cppBison.yxx.c" break; case 297: /* empty_instance_identifier: SCOPING '*' optional_attributes not_paren_empty_instance_identifier */ @@ -6786,7 +6785,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_scoped_pointer_modifier((yyvsp[-3].u.identifier)); } -#line 6790 "built/tmp/cppBison.yxx.c" +#line 6789 "built/tmp/cppBison.yxx.c" break; case 298: /* empty_instance_identifier: not_paren_empty_instance_identifier '[' optional_const_expr ']' optional_attributes */ @@ -6795,7 +6794,7 @@ yyreduce: (yyval.u.inst_ident) = (yyvsp[-4].u.inst_ident); (yyval.u.inst_ident)->add_array_modifier((yyvsp[-2].u.expr)); } -#line 6799 "built/tmp/cppBison.yxx.c" +#line 6798 "built/tmp/cppBison.yxx.c" break; case 299: /* empty_instance_identifier: '(' function_parameter_list ')' function_post maybe_trailing_return_type */ @@ -6805,7 +6804,7 @@ yyreduce: (yyval.u.inst_ident)->add_modifier(IIT_paren); (yyval.u.inst_ident)->add_func_modifier((yyvsp[-3].u.param_list), (yyvsp[-1].u.integer), (yyvsp[0].u.type)); } -#line 6809 "built/tmp/cppBison.yxx.c" +#line 6808 "built/tmp/cppBison.yxx.c" break; case 300: /* empty_instance_identifier: '(' '*' optional_attributes not_paren_empty_instance_identifier ')' '(' function_parameter_list ')' function_post maybe_trailing_return_type */ @@ -6816,7 +6815,7 @@ yyreduce: (yyval.u.inst_ident)->add_modifier(IIT_paren); (yyval.u.inst_ident)->add_func_modifier((yyvsp[-3].u.param_list), (yyvsp[-1].u.integer), (yyvsp[0].u.type)); } -#line 6820 "built/tmp/cppBison.yxx.c" +#line 6819 "built/tmp/cppBison.yxx.c" break; case 301: /* empty_instance_identifier: '(' '&' optional_attributes not_paren_empty_instance_identifier ')' '(' function_parameter_list ')' function_post maybe_trailing_return_type */ @@ -6827,7 +6826,7 @@ yyreduce: (yyval.u.inst_ident)->add_modifier(IIT_paren); (yyval.u.inst_ident)->add_func_modifier((yyvsp[-3].u.param_list), (yyvsp[-1].u.integer), (yyvsp[0].u.type)); } -#line 6831 "built/tmp/cppBison.yxx.c" +#line 6830 "built/tmp/cppBison.yxx.c" break; case 302: /* empty_instance_identifier: '(' ANDAND optional_attributes not_paren_empty_instance_identifier ')' '(' function_parameter_list ')' function_post maybe_trailing_return_type */ @@ -6838,7 +6837,7 @@ yyreduce: (yyval.u.inst_ident)->add_modifier(IIT_paren); (yyval.u.inst_ident)->add_func_modifier((yyvsp[-3].u.param_list), (yyvsp[-1].u.integer), (yyvsp[0].u.type)); } -#line 6842 "built/tmp/cppBison.yxx.c" +#line 6841 "built/tmp/cppBison.yxx.c" break; case 303: /* type: simple_type */ @@ -6846,7 +6845,7 @@ yyreduce: { (yyval.u.type) = CPPType::new_type((yyvsp[0].u.simple_type)); } -#line 6850 "built/tmp/cppBison.yxx.c" +#line 6849 "built/tmp/cppBison.yxx.c" break; case 304: /* type: TYPENAME_IDENTIFIER */ @@ -6858,7 +6857,7 @@ yyreduce: } assert((yyval.u.type) != nullptr); } -#line 6862 "built/tmp/cppBison.yxx.c" +#line 6861 "built/tmp/cppBison.yxx.c" break; case 305: /* type: KW_TYPENAME name */ @@ -6866,7 +6865,7 @@ yyreduce: { (yyval.u.type) = CPPType::new_type(new CPPTBDType((yyvsp[0].u.identifier))); } -#line 6870 "built/tmp/cppBison.yxx.c" +#line 6869 "built/tmp/cppBison.yxx.c" break; case 306: /* type: anonymous_struct */ @@ -6874,7 +6873,7 @@ yyreduce: { (yyval.u.type) = CPPType::new_type((yyvsp[0].u.struct_type)); } -#line 6878 "built/tmp/cppBison.yxx.c" +#line 6877 "built/tmp/cppBison.yxx.c" break; case 307: /* type: named_struct */ @@ -6882,7 +6881,7 @@ yyreduce: { (yyval.u.type) = CPPType::new_type((yyvsp[0].u.struct_type)); } -#line 6886 "built/tmp/cppBison.yxx.c" +#line 6885 "built/tmp/cppBison.yxx.c" break; case 308: /* type: enum */ @@ -6890,7 +6889,7 @@ yyreduce: { (yyval.u.type) = CPPType::new_type((yyvsp[0].u.enum_type)); } -#line 6894 "built/tmp/cppBison.yxx.c" +#line 6893 "built/tmp/cppBison.yxx.c" break; case 309: /* type: struct_keyword struct_attributes name */ @@ -6910,7 +6909,7 @@ yyreduce: (yyval.u.type) = et; } } -#line 6914 "built/tmp/cppBison.yxx.c" +#line 6913 "built/tmp/cppBison.yxx.c" break; case 310: /* type: enum_keyword name_no_final ':' enum_element_type */ @@ -6930,7 +6929,7 @@ yyreduce: (yyval.u.type) = et; } } -#line 6934 "built/tmp/cppBison.yxx.c" +#line 6933 "built/tmp/cppBison.yxx.c" break; case 311: /* type: KW_DECLTYPE '(' const_expr ')' */ @@ -6943,7 +6942,7 @@ yyreduce: yyerror("could not determine type of " + str.str(), (yylsp[-1])); } } -#line 6947 "built/tmp/cppBison.yxx.c" +#line 6946 "built/tmp/cppBison.yxx.c" break; case 312: /* type: KW_DECLTYPE '(' KW_AUTO ')' */ @@ -6951,7 +6950,7 @@ yyreduce: { (yyval.u.type) = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_auto)); } -#line 6955 "built/tmp/cppBison.yxx.c" +#line 6954 "built/tmp/cppBison.yxx.c" break; case 313: /* type: KW_UNDERLYING_TYPE '(' full_type ')' */ @@ -6965,7 +6964,7 @@ yyreduce: (yyval.u.type) = enum_type->get_underlying_type(); } } -#line 6969 "built/tmp/cppBison.yxx.c" +#line 6968 "built/tmp/cppBison.yxx.c" break; case 314: /* type: KW_AUTO */ @@ -6973,7 +6972,7 @@ yyreduce: { (yyval.u.type) = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_auto)); } -#line 6977 "built/tmp/cppBison.yxx.c" +#line 6976 "built/tmp/cppBison.yxx.c" break; case 315: /* type_pack: TYPEPACK_IDENTIFIER */ @@ -6985,7 +6984,7 @@ yyreduce: } assert((yyval.u.type) != nullptr); } -#line 6989 "built/tmp/cppBison.yxx.c" +#line 6988 "built/tmp/cppBison.yxx.c" break; case 316: /* type_decl: simple_type */ @@ -6993,7 +6992,7 @@ yyreduce: { (yyval.u.decl) = CPPType::new_type((yyvsp[0].u.simple_type)); } -#line 6997 "built/tmp/cppBison.yxx.c" +#line 6996 "built/tmp/cppBison.yxx.c" break; case 317: /* type_decl: TYPENAME_IDENTIFIER */ @@ -7005,7 +7004,7 @@ yyreduce: } assert((yyval.u.decl) != nullptr); } -#line 7009 "built/tmp/cppBison.yxx.c" +#line 7008 "built/tmp/cppBison.yxx.c" break; case 318: /* type_decl: KW_TYPENAME name */ @@ -7013,7 +7012,7 @@ yyreduce: { (yyval.u.decl) = CPPType::new_type(new CPPTBDType((yyvsp[0].u.identifier))); } -#line 7017 "built/tmp/cppBison.yxx.c" +#line 7016 "built/tmp/cppBison.yxx.c" break; case 319: /* type_decl: anonymous_struct */ @@ -7021,7 +7020,7 @@ yyreduce: { (yyval.u.decl) = CPPType::new_type((yyvsp[0].u.struct_type)); } -#line 7025 "built/tmp/cppBison.yxx.c" +#line 7024 "built/tmp/cppBison.yxx.c" break; case 320: /* type_decl: named_struct */ @@ -7029,7 +7028,7 @@ yyreduce: { (yyval.u.decl) = new CPPTypeDeclaration(CPPType::new_type((yyvsp[0].u.struct_type))); } -#line 7033 "built/tmp/cppBison.yxx.c" +#line 7032 "built/tmp/cppBison.yxx.c" break; case 321: /* type_decl: enum */ @@ -7037,7 +7036,7 @@ yyreduce: { (yyval.u.decl) = new CPPTypeDeclaration(CPPType::new_type((yyvsp[0].u.enum_type))); } -#line 7041 "built/tmp/cppBison.yxx.c" +#line 7040 "built/tmp/cppBison.yxx.c" break; case 322: /* type_decl: struct_keyword struct_attributes name */ @@ -7057,7 +7056,7 @@ yyreduce: (yyval.u.decl) = et; } } -#line 7061 "built/tmp/cppBison.yxx.c" +#line 7060 "built/tmp/cppBison.yxx.c" break; case 323: /* type_decl: enum_keyword name_no_final ':' enum_element_type */ @@ -7077,7 +7076,7 @@ yyreduce: (yyval.u.decl) = et; } } -#line 7081 "built/tmp/cppBison.yxx.c" +#line 7080 "built/tmp/cppBison.yxx.c" break; case 324: /* type_decl: enum_keyword name */ @@ -7099,7 +7098,7 @@ yyreduce: (yyval.u.decl) = et; } } -#line 7103 "built/tmp/cppBison.yxx.c" +#line 7102 "built/tmp/cppBison.yxx.c" break; case 325: /* type_decl: KW_DECLTYPE '(' const_expr ')' */ @@ -7112,7 +7111,7 @@ yyreduce: yyerror("could not determine type of " + str.str(), (yylsp[-1])); } } -#line 7116 "built/tmp/cppBison.yxx.c" +#line 7115 "built/tmp/cppBison.yxx.c" break; case 326: /* type_decl: KW_DECLTYPE '(' KW_AUTO ')' */ @@ -7120,7 +7119,7 @@ yyreduce: { (yyval.u.decl) = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_auto)); } -#line 7124 "built/tmp/cppBison.yxx.c" +#line 7123 "built/tmp/cppBison.yxx.c" break; case 327: /* type_decl: KW_UNDERLYING_TYPE '(' full_type ')' */ @@ -7134,7 +7133,7 @@ yyreduce: (yyval.u.decl) = enum_type->get_underlying_type(); } } -#line 7138 "built/tmp/cppBison.yxx.c" +#line 7137 "built/tmp/cppBison.yxx.c" break; case 328: /* type_decl: KW_AUTO */ @@ -7142,7 +7141,7 @@ yyreduce: { (yyval.u.decl) = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_auto)); } -#line 7146 "built/tmp/cppBison.yxx.c" +#line 7145 "built/tmp/cppBison.yxx.c" break; case 329: /* predefined_type: simple_type */ @@ -7150,7 +7149,7 @@ yyreduce: { (yyval.u.type) = CPPType::new_type((yyvsp[0].u.simple_type)); } -#line 7154 "built/tmp/cppBison.yxx.c" +#line 7153 "built/tmp/cppBison.yxx.c" break; case 330: /* predefined_type: TYPENAME_IDENTIFIER */ @@ -7162,7 +7161,7 @@ yyreduce: } assert((yyval.u.type) != nullptr); } -#line 7166 "built/tmp/cppBison.yxx.c" +#line 7165 "built/tmp/cppBison.yxx.c" break; case 331: /* predefined_type: KW_TYPENAME name */ @@ -7170,7 +7169,7 @@ yyreduce: { (yyval.u.type) = CPPType::new_type(new CPPTBDType((yyvsp[0].u.identifier))); } -#line 7174 "built/tmp/cppBison.yxx.c" +#line 7173 "built/tmp/cppBison.yxx.c" break; case 332: /* predefined_type: struct_keyword struct_attributes name */ @@ -7190,7 +7189,7 @@ yyreduce: (yyval.u.type) = et; } } -#line 7194 "built/tmp/cppBison.yxx.c" +#line 7193 "built/tmp/cppBison.yxx.c" break; case 333: /* predefined_type: enum_keyword name */ @@ -7210,7 +7209,7 @@ yyreduce: (yyval.u.type) = et; } } -#line 7214 "built/tmp/cppBison.yxx.c" +#line 7213 "built/tmp/cppBison.yxx.c" break; case 334: /* predefined_type: KW_DECLTYPE '(' const_expr ')' */ @@ -7223,7 +7222,7 @@ yyreduce: yyerror("could not determine type of " + str.str(), (yylsp[-1])); } } -#line 7227 "built/tmp/cppBison.yxx.c" +#line 7226 "built/tmp/cppBison.yxx.c" break; case 335: /* predefined_type: KW_UNDERLYING_TYPE '(' full_type ')' */ @@ -7237,7 +7236,7 @@ yyreduce: (yyval.u.type) = enum_type->get_underlying_type(); } } -#line 7241 "built/tmp/cppBison.yxx.c" +#line 7240 "built/tmp/cppBison.yxx.c" break; case 336: /* predefined_type: KW_AUTO */ @@ -7245,7 +7244,7 @@ yyreduce: { (yyval.u.type) = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_auto)); } -#line 7249 "built/tmp/cppBison.yxx.c" +#line 7248 "built/tmp/cppBison.yxx.c" break; case 337: /* var_type_decl: type_decl */ @@ -7253,7 +7252,7 @@ yyreduce: { (yyval.u.decl) = (yyvsp[0].u.decl); } -#line 7257 "built/tmp/cppBison.yxx.c" +#line 7256 "built/tmp/cppBison.yxx.c" break; case 338: /* var_type_decl: IDENTIFIER */ @@ -7263,7 +7262,7 @@ yyreduce: (yyval.u.decl) = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_unknown)); } -#line 7267 "built/tmp/cppBison.yxx.c" +#line 7266 "built/tmp/cppBison.yxx.c" break; case 339: /* full_type: type empty_instance_identifier */ @@ -7271,7 +7270,7 @@ yyreduce: { (yyval.u.type) = (yyvsp[0].u.inst_ident)->unroll_type((yyvsp[-1].u.type)); } -#line 7275 "built/tmp/cppBison.yxx.c" +#line 7274 "built/tmp/cppBison.yxx.c" break; case 340: /* full_type: KW_CONST type empty_instance_identifier */ @@ -7280,7 +7279,7 @@ yyreduce: (yyvsp[0].u.inst_ident)->add_modifier(IIT_const); (yyval.u.type) = (yyvsp[0].u.inst_ident)->unroll_type((yyvsp[-1].u.type)); } -#line 7284 "built/tmp/cppBison.yxx.c" +#line 7283 "built/tmp/cppBison.yxx.c" break; case 341: /* full_type: type_pack empty_instance_identifier */ @@ -7288,7 +7287,7 @@ yyreduce: { (yyval.u.type) = (yyvsp[0].u.inst_ident)->unroll_type((yyvsp[-1].u.type)); } -#line 7292 "built/tmp/cppBison.yxx.c" +#line 7291 "built/tmp/cppBison.yxx.c" break; case 342: /* full_type: KW_CONST type_pack empty_instance_identifier */ @@ -7297,7 +7296,7 @@ yyreduce: (yyvsp[0].u.inst_ident)->add_modifier(IIT_const); (yyval.u.type) = (yyvsp[0].u.inst_ident)->unroll_type((yyvsp[-1].u.type)); } -#line 7301 "built/tmp/cppBison.yxx.c" +#line 7300 "built/tmp/cppBison.yxx.c" break; case 347: /* $@16: %empty */ @@ -7315,7 +7314,7 @@ yyreduce: push_scope(new_scope); push_struct(st); } -#line 7319 "built/tmp/cppBison.yxx.c" +#line 7318 "built/tmp/cppBison.yxx.c" break; case 348: /* anonymous_struct: struct_keyword struct_attributes '{' $@16 cpp '}' */ @@ -7326,7 +7325,7 @@ yyreduce: pop_struct(); pop_scope(); } -#line 7330 "built/tmp/cppBison.yxx.c" +#line 7329 "built/tmp/cppBison.yxx.c" break; case 349: /* $@17: %empty */ @@ -7350,7 +7349,7 @@ yyreduce: push_scope(new_scope); push_struct(st); } -#line 7354 "built/tmp/cppBison.yxx.c" +#line 7353 "built/tmp/cppBison.yxx.c" break; case 350: /* named_struct: struct_keyword struct_attributes name_no_final $@17 maybe_final maybe_class_derivation '{' cpp '}' */ @@ -7361,7 +7360,7 @@ yyreduce: pop_struct(); pop_scope(); } -#line 7365 "built/tmp/cppBison.yxx.c" +#line 7364 "built/tmp/cppBison.yxx.c" break; case 352: /* maybe_final: KW_FINAL */ @@ -7369,7 +7368,7 @@ yyreduce: { current_struct->_final = true; } -#line 7373 "built/tmp/cppBison.yxx.c" +#line 7372 "built/tmp/cppBison.yxx.c" break; case 357: /* base_specification: class_derivation_name */ @@ -7377,7 +7376,7 @@ yyreduce: { current_struct->append_derivation((yyvsp[0].u.type), V_unknown, false); } -#line 7381 "built/tmp/cppBison.yxx.c" +#line 7380 "built/tmp/cppBison.yxx.c" break; case 358: /* base_specification: KW_PUBLIC class_derivation_name */ @@ -7385,7 +7384,7 @@ yyreduce: { current_struct->append_derivation((yyvsp[0].u.type), V_public, false); } -#line 7389 "built/tmp/cppBison.yxx.c" +#line 7388 "built/tmp/cppBison.yxx.c" break; case 359: /* base_specification: KW_PROTECTED class_derivation_name */ @@ -7393,7 +7392,7 @@ yyreduce: { current_struct->append_derivation((yyvsp[0].u.type), V_protected, false); } -#line 7397 "built/tmp/cppBison.yxx.c" +#line 7396 "built/tmp/cppBison.yxx.c" break; case 360: /* base_specification: KW_PRIVATE class_derivation_name */ @@ -7401,7 +7400,7 @@ yyreduce: { current_struct->append_derivation((yyvsp[0].u.type), V_private, false); } -#line 7405 "built/tmp/cppBison.yxx.c" +#line 7404 "built/tmp/cppBison.yxx.c" break; case 361: /* base_specification: KW_VIRTUAL KW_PUBLIC class_derivation_name */ @@ -7409,7 +7408,7 @@ yyreduce: { current_struct->append_derivation((yyvsp[0].u.type), V_public, true); } -#line 7413 "built/tmp/cppBison.yxx.c" +#line 7412 "built/tmp/cppBison.yxx.c" break; case 362: /* base_specification: KW_VIRTUAL KW_PROTECTED class_derivation_name */ @@ -7417,7 +7416,7 @@ yyreduce: { current_struct->append_derivation((yyvsp[0].u.type), V_protected, true); } -#line 7421 "built/tmp/cppBison.yxx.c" +#line 7420 "built/tmp/cppBison.yxx.c" break; case 363: /* base_specification: KW_VIRTUAL KW_PRIVATE class_derivation_name */ @@ -7425,7 +7424,7 @@ yyreduce: { current_struct->append_derivation((yyvsp[0].u.type), V_private, true); } -#line 7429 "built/tmp/cppBison.yxx.c" +#line 7428 "built/tmp/cppBison.yxx.c" break; case 364: /* base_specification: KW_PUBLIC KW_VIRTUAL class_derivation_name */ @@ -7433,7 +7432,7 @@ yyreduce: { current_struct->append_derivation((yyvsp[0].u.type), V_public, true); } -#line 7437 "built/tmp/cppBison.yxx.c" +#line 7436 "built/tmp/cppBison.yxx.c" break; case 365: /* base_specification: KW_PROTECTED KW_VIRTUAL class_derivation_name */ @@ -7441,7 +7440,7 @@ yyreduce: { current_struct->append_derivation((yyvsp[0].u.type), V_protected, true); } -#line 7445 "built/tmp/cppBison.yxx.c" +#line 7444 "built/tmp/cppBison.yxx.c" break; case 366: /* base_specification: KW_PRIVATE KW_VIRTUAL class_derivation_name */ @@ -7449,154 +7448,167 @@ yyreduce: { current_struct->append_derivation((yyvsp[0].u.type), V_private, true); } -#line 7453 "built/tmp/cppBison.yxx.c" +#line 7452 "built/tmp/cppBison.yxx.c" break; - case 367: /* enum: enum_decl '{' enum_body '}' */ + case 367: /* $@18: %empty */ #line 2900 "dtool/src/cppparser/cppBison.yxx" { - (yyval.u.enum_type) = current_enum; - current_enum = nullptr; + if (current_enum->_scope != nullptr) { + push_scope(current_enum->_scope); + } } #line 7462 "built/tmp/cppBison.yxx.c" break; - case 368: /* enum_decl: enum_keyword ':' enum_element_type */ -#line 2908 "dtool/src/cppparser/cppBison.yxx" + case 368: /* enum: enum_decl $@18 '{' enum_body '}' */ +#line 2906 "dtool/src/cppparser/cppBison.yxx" +{ + if (current_enum->_scope != nullptr) { + pop_scope(); + } + (yyval.u.enum_type) = current_enum; + current_enum = nullptr; +} +#line 7474 "built/tmp/cppBison.yxx.c" + break; + + case 369: /* enum_decl: enum_keyword ':' enum_element_type */ +#line 2917 "dtool/src/cppparser/cppBison.yxx" { current_enum = new CPPEnumType((yyvsp[-2].u.extension_enum), nullptr, (yyvsp[0].u.type), current_scope, nullptr, (yylsp[-2]).file); } -#line 7470 "built/tmp/cppBison.yxx.c" +#line 7482 "built/tmp/cppBison.yxx.c" break; - case 369: /* enum_decl: enum_keyword */ -#line 2912 "dtool/src/cppparser/cppBison.yxx" + case 370: /* enum_decl: enum_keyword */ +#line 2921 "dtool/src/cppparser/cppBison.yxx" { current_enum = new CPPEnumType((yyvsp[0].u.extension_enum), nullptr, current_scope, nullptr, (yylsp[0]).file); } -#line 7478 "built/tmp/cppBison.yxx.c" +#line 7490 "built/tmp/cppBison.yxx.c" break; - case 370: /* enum_decl: enum_keyword name_no_final ':' enum_element_type */ -#line 2916 "dtool/src/cppparser/cppBison.yxx" + case 371: /* enum_decl: enum_keyword name_no_final ':' enum_element_type */ +#line 2925 "dtool/src/cppparser/cppBison.yxx" { CPPScope *new_scope = new CPPScope(current_scope, (yyvsp[-2].u.identifier)->_names.back(), V_public); current_enum = new CPPEnumType((yyvsp[-3].u.extension_enum), (yyvsp[-2].u.identifier), (yyvsp[0].u.type), current_scope, new_scope, (yylsp[-3]).file); } -#line 7487 "built/tmp/cppBison.yxx.c" +#line 7499 "built/tmp/cppBison.yxx.c" break; - case 371: /* enum_decl: enum_keyword name_no_final */ -#line 2921 "dtool/src/cppparser/cppBison.yxx" + case 372: /* enum_decl: enum_keyword name_no_final */ +#line 2930 "dtool/src/cppparser/cppBison.yxx" { CPPScope *new_scope = new CPPScope(current_scope, (yyvsp[0].u.identifier)->_names.back(), V_public); current_enum = new CPPEnumType((yyvsp[-1].u.extension_enum), (yyvsp[0].u.identifier), current_scope, new_scope, (yylsp[-1]).file); } -#line 7496 "built/tmp/cppBison.yxx.c" +#line 7508 "built/tmp/cppBison.yxx.c" break; - case 372: /* enum_element_type: simple_int_type */ -#line 2929 "dtool/src/cppparser/cppBison.yxx" + case 373: /* enum_element_type: simple_int_type */ +#line 2938 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.type) = CPPType::new_type((yyvsp[0].u.simple_type)); } -#line 7504 "built/tmp/cppBison.yxx.c" +#line 7516 "built/tmp/cppBison.yxx.c" break; - case 373: /* enum_element_type: TYPENAME_IDENTIFIER */ -#line 2933 "dtool/src/cppparser/cppBison.yxx" + case 374: /* enum_element_type: TYPENAME_IDENTIFIER */ +#line 2942 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.type) = (yyvsp[0].u.identifier)->find_type(current_scope, global_scope, false, current_lexer); } -#line 7512 "built/tmp/cppBison.yxx.c" +#line 7524 "built/tmp/cppBison.yxx.c" break; - case 375: /* enum_body_trailing_comma: enum_body_trailing_comma name ',' */ -#line 2941 "dtool/src/cppparser/cppBison.yxx" + case 376: /* enum_body_trailing_comma: enum_body_trailing_comma name ',' */ +#line 2950 "dtool/src/cppparser/cppBison.yxx" { assert(current_enum != nullptr); current_enum->add_element((yyvsp[-1].u.identifier)->get_simple_name(), nullptr, current_lexer, (yylsp[-1])); } -#line 7521 "built/tmp/cppBison.yxx.c" +#line 7533 "built/tmp/cppBison.yxx.c" break; - case 376: /* enum_body_trailing_comma: enum_body_trailing_comma name '=' const_expr ',' */ -#line 2946 "dtool/src/cppparser/cppBison.yxx" + case 377: /* enum_body_trailing_comma: enum_body_trailing_comma name '=' const_expr ',' */ +#line 2955 "dtool/src/cppparser/cppBison.yxx" { assert(current_enum != nullptr); current_enum->add_element((yyvsp[-3].u.identifier)->get_simple_name(), (yyvsp[-1].u.expr), current_lexer, (yylsp[-3])); } -#line 7530 "built/tmp/cppBison.yxx.c" +#line 7542 "built/tmp/cppBison.yxx.c" break; - case 378: /* enum_body: enum_body_trailing_comma name */ -#line 2954 "dtool/src/cppparser/cppBison.yxx" + case 379: /* enum_body: enum_body_trailing_comma name */ +#line 2963 "dtool/src/cppparser/cppBison.yxx" { assert(current_enum != nullptr); current_enum->add_element((yyvsp[0].u.identifier)->get_simple_name(), nullptr, current_lexer, (yylsp[0])); } -#line 7539 "built/tmp/cppBison.yxx.c" +#line 7551 "built/tmp/cppBison.yxx.c" break; - case 379: /* enum_body: enum_body_trailing_comma name '=' const_expr */ -#line 2959 "dtool/src/cppparser/cppBison.yxx" + case 380: /* enum_body: enum_body_trailing_comma name '=' const_expr */ +#line 2968 "dtool/src/cppparser/cppBison.yxx" { assert(current_enum != nullptr); current_enum->add_element((yyvsp[-2].u.identifier)->get_simple_name(), (yyvsp[0].u.expr), current_lexer, (yylsp[-2])); } -#line 7548 "built/tmp/cppBison.yxx.c" +#line 7560 "built/tmp/cppBison.yxx.c" break; - case 380: /* enum_keyword: KW_ENUM */ -#line 2967 "dtool/src/cppparser/cppBison.yxx" + case 381: /* enum_keyword: KW_ENUM */ +#line 2976 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.extension_enum) = CPPExtensionType::T_enum; } -#line 7556 "built/tmp/cppBison.yxx.c" +#line 7568 "built/tmp/cppBison.yxx.c" break; - case 381: /* enum_keyword: KW_ENUM KW_CLASS */ -#line 2971 "dtool/src/cppparser/cppBison.yxx" + case 382: /* enum_keyword: KW_ENUM KW_CLASS */ +#line 2980 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.extension_enum) = CPPExtensionType::T_enum_class; } -#line 7564 "built/tmp/cppBison.yxx.c" +#line 7576 "built/tmp/cppBison.yxx.c" break; - case 382: /* enum_keyword: KW_ENUM KW_STRUCT */ -#line 2975 "dtool/src/cppparser/cppBison.yxx" + case 383: /* enum_keyword: KW_ENUM KW_STRUCT */ +#line 2984 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.extension_enum) = CPPExtensionType::T_enum_struct; } -#line 7572 "built/tmp/cppBison.yxx.c" +#line 7584 "built/tmp/cppBison.yxx.c" break; - case 383: /* struct_keyword: KW_CLASS */ -#line 2982 "dtool/src/cppparser/cppBison.yxx" + case 384: /* struct_keyword: KW_CLASS */ +#line 2991 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.extension_enum) = CPPExtensionType::T_class; } -#line 7580 "built/tmp/cppBison.yxx.c" +#line 7592 "built/tmp/cppBison.yxx.c" break; - case 384: /* struct_keyword: KW_STRUCT */ -#line 2986 "dtool/src/cppparser/cppBison.yxx" + case 385: /* struct_keyword: KW_STRUCT */ +#line 2995 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.extension_enum) = CPPExtensionType::T_struct; } -#line 7588 "built/tmp/cppBison.yxx.c" +#line 7600 "built/tmp/cppBison.yxx.c" break; - case 385: /* struct_keyword: KW_UNION */ -#line 2990 "dtool/src/cppparser/cppBison.yxx" + case 386: /* struct_keyword: KW_UNION */ +#line 2999 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.extension_enum) = CPPExtensionType::T_union; } -#line 7596 "built/tmp/cppBison.yxx.c" +#line 7608 "built/tmp/cppBison.yxx.c" break; - case 386: /* $@18: %empty */ -#line 2997 "dtool/src/cppparser/cppBison.yxx" + case 387: /* $@19: %empty */ +#line 3006 "dtool/src/cppparser/cppBison.yxx" { CPPScope *scope = (yyvsp[-1].u.identifier)->find_scope(current_scope, global_scope, current_lexer); if (scope == nullptr) { @@ -7614,19 +7626,19 @@ yyreduce: current_scope->define_namespace(nspace); push_scope(scope); } -#line 7618 "built/tmp/cppBison.yxx.c" +#line 7630 "built/tmp/cppBison.yxx.c" break; - case 387: /* namespace_declaration: KW_NAMESPACE name '{' $@18 cpp '}' */ -#line 3015 "dtool/src/cppparser/cppBison.yxx" + case 388: /* namespace_declaration: KW_NAMESPACE name '{' $@19 cpp '}' */ +#line 3024 "dtool/src/cppparser/cppBison.yxx" { pop_scope(); } -#line 7626 "built/tmp/cppBison.yxx.c" +#line 7638 "built/tmp/cppBison.yxx.c" break; - case 388: /* $@19: %empty */ -#line 3019 "dtool/src/cppparser/cppBison.yxx" + case 389: /* $@20: %empty */ +#line 3028 "dtool/src/cppparser/cppBison.yxx" { CPPScope *scope = (yyvsp[-1].u.identifier)->find_scope(current_scope, global_scope, current_lexer); if (scope == nullptr) { @@ -7645,143 +7657,143 @@ yyreduce: current_scope->define_namespace(nspace); push_scope(scope); } -#line 7649 "built/tmp/cppBison.yxx.c" +#line 7661 "built/tmp/cppBison.yxx.c" break; - case 389: /* namespace_declaration: KW_INLINE KW_NAMESPACE name '{' $@19 cpp '}' */ -#line 3038 "dtool/src/cppparser/cppBison.yxx" + case 390: /* namespace_declaration: KW_INLINE KW_NAMESPACE name '{' $@20 cpp '}' */ +#line 3047 "dtool/src/cppparser/cppBison.yxx" { pop_scope(); } -#line 7657 "built/tmp/cppBison.yxx.c" +#line 7669 "built/tmp/cppBison.yxx.c" break; - case 392: /* using_declaration: KW_USING name ';' */ -#line 3047 "dtool/src/cppparser/cppBison.yxx" + case 393: /* using_declaration: KW_USING name ';' */ +#line 3056 "dtool/src/cppparser/cppBison.yxx" { CPPUsing *using_decl = new CPPUsing((yyvsp[-1].u.identifier), false, (yylsp[-2]).file); current_scope->add_declaration(using_decl, global_scope, current_lexer, (yylsp[-2])); current_scope->add_using(using_decl, global_scope, current_lexer); } -#line 7667 "built/tmp/cppBison.yxx.c" +#line 7679 "built/tmp/cppBison.yxx.c" break; - case 393: /* using_declaration: KW_USING name '=' full_type ';' */ -#line 3053 "dtool/src/cppparser/cppBison.yxx" + case 394: /* using_declaration: KW_USING name '=' full_type ';' */ +#line 3062 "dtool/src/cppparser/cppBison.yxx" { // This is really just an alternative way to declare a typedef. CPPTypedefType *typedef_type = new CPPTypedefType((yyvsp[-1].u.type), (yyvsp[-3].u.identifier), current_scope); typedef_type->_using = true; current_scope->add_declaration(CPPType::new_type(typedef_type), global_scope, current_lexer, (yylsp[-4])); } -#line 7678 "built/tmp/cppBison.yxx.c" +#line 7690 "built/tmp/cppBison.yxx.c" break; - case 394: /* using_declaration: KW_USING KW_NAMESPACE name ';' */ -#line 3060 "dtool/src/cppparser/cppBison.yxx" + case 395: /* using_declaration: KW_USING KW_NAMESPACE name ';' */ +#line 3069 "dtool/src/cppparser/cppBison.yxx" { CPPUsing *using_decl = new CPPUsing((yyvsp[-1].u.identifier), true, (yylsp[-3]).file); current_scope->add_declaration(using_decl, global_scope, current_lexer, (yylsp[-3])); current_scope->add_using(using_decl, global_scope, current_lexer); } -#line 7688 "built/tmp/cppBison.yxx.c" +#line 7700 "built/tmp/cppBison.yxx.c" break; - case 398: /* simple_int_type: KW_BOOL */ -#line 3075 "dtool/src/cppparser/cppBison.yxx" + case 399: /* simple_int_type: KW_BOOL */ +#line 3084 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.simple_type) = new CPPSimpleType(CPPSimpleType::T_bool); } -#line 7696 "built/tmp/cppBison.yxx.c" +#line 7708 "built/tmp/cppBison.yxx.c" break; - case 399: /* simple_int_type: KW_CHAR */ -#line 3079 "dtool/src/cppparser/cppBison.yxx" + case 400: /* simple_int_type: KW_CHAR */ +#line 3088 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.simple_type) = new CPPSimpleType(CPPSimpleType::T_char); } -#line 7704 "built/tmp/cppBison.yxx.c" +#line 7716 "built/tmp/cppBison.yxx.c" break; - case 400: /* simple_int_type: KW_WCHAR_T */ -#line 3083 "dtool/src/cppparser/cppBison.yxx" + case 401: /* simple_int_type: KW_WCHAR_T */ +#line 3092 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.simple_type) = new CPPSimpleType(CPPSimpleType::T_wchar_t); } -#line 7712 "built/tmp/cppBison.yxx.c" +#line 7724 "built/tmp/cppBison.yxx.c" break; - case 401: /* simple_int_type: KW_CHAR16_T */ -#line 3087 "dtool/src/cppparser/cppBison.yxx" + case 402: /* simple_int_type: KW_CHAR16_T */ +#line 3096 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.simple_type) = new CPPSimpleType(CPPSimpleType::T_char16_t); } -#line 7720 "built/tmp/cppBison.yxx.c" +#line 7732 "built/tmp/cppBison.yxx.c" break; - case 402: /* simple_int_type: KW_CHAR32_T */ -#line 3091 "dtool/src/cppparser/cppBison.yxx" + case 403: /* simple_int_type: KW_CHAR32_T */ +#line 3100 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.simple_type) = new CPPSimpleType(CPPSimpleType::T_char32_t); } -#line 7728 "built/tmp/cppBison.yxx.c" +#line 7740 "built/tmp/cppBison.yxx.c" break; - case 403: /* simple_int_type: KW_SHORT */ -#line 3095 "dtool/src/cppparser/cppBison.yxx" + case 404: /* simple_int_type: KW_SHORT */ +#line 3104 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.simple_type) = new CPPSimpleType(CPPSimpleType::T_int, CPPSimpleType::F_short); } -#line 7737 "built/tmp/cppBison.yxx.c" +#line 7749 "built/tmp/cppBison.yxx.c" break; - case 404: /* simple_int_type: KW_LONG */ -#line 3100 "dtool/src/cppparser/cppBison.yxx" + case 405: /* simple_int_type: KW_LONG */ +#line 3109 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.simple_type) = new CPPSimpleType(CPPSimpleType::T_int, CPPSimpleType::F_long); } -#line 7746 "built/tmp/cppBison.yxx.c" +#line 7758 "built/tmp/cppBison.yxx.c" break; - case 405: /* simple_int_type: KW_UNSIGNED */ -#line 3105 "dtool/src/cppparser/cppBison.yxx" + case 406: /* simple_int_type: KW_UNSIGNED */ +#line 3114 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.simple_type) = new CPPSimpleType(CPPSimpleType::T_int, CPPSimpleType::F_unsigned); } -#line 7755 "built/tmp/cppBison.yxx.c" +#line 7767 "built/tmp/cppBison.yxx.c" break; - case 406: /* simple_int_type: KW_SIGNED */ -#line 3110 "dtool/src/cppparser/cppBison.yxx" + case 407: /* simple_int_type: KW_SIGNED */ +#line 3119 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.simple_type) = new CPPSimpleType(CPPSimpleType::T_int, CPPSimpleType::F_signed); } -#line 7764 "built/tmp/cppBison.yxx.c" +#line 7776 "built/tmp/cppBison.yxx.c" break; - case 407: /* simple_int_type: KW_INT */ -#line 3115 "dtool/src/cppparser/cppBison.yxx" + case 408: /* simple_int_type: KW_INT */ +#line 3124 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.simple_type) = new CPPSimpleType(CPPSimpleType::T_int); } -#line 7772 "built/tmp/cppBison.yxx.c" +#line 7784 "built/tmp/cppBison.yxx.c" break; - case 408: /* simple_int_type: KW_SHORT simple_int_type */ -#line 3119 "dtool/src/cppparser/cppBison.yxx" + case 409: /* simple_int_type: KW_SHORT simple_int_type */ +#line 3128 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.simple_type) = (yyvsp[0].u.simple_type); (yyval.u.simple_type)->_flags |= CPPSimpleType::F_short; } -#line 7781 "built/tmp/cppBison.yxx.c" +#line 7793 "built/tmp/cppBison.yxx.c" break; - case 409: /* simple_int_type: KW_LONG simple_int_type */ -#line 3124 "dtool/src/cppparser/cppBison.yxx" + case 410: /* simple_int_type: KW_LONG simple_int_type */ +#line 3133 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.simple_type) = (yyvsp[0].u.simple_type); if ((yyval.u.simple_type)->_flags & CPPSimpleType::F_long) { @@ -7790,493 +7802,493 @@ yyreduce: (yyval.u.simple_type)->_flags |= CPPSimpleType::F_long; } } -#line 7794 "built/tmp/cppBison.yxx.c" +#line 7806 "built/tmp/cppBison.yxx.c" break; - case 410: /* simple_int_type: KW_UNSIGNED simple_int_type */ -#line 3133 "dtool/src/cppparser/cppBison.yxx" + case 411: /* simple_int_type: KW_UNSIGNED simple_int_type */ +#line 3142 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.simple_type) = (yyvsp[0].u.simple_type); (yyval.u.simple_type)->_flags |= CPPSimpleType::F_unsigned; } -#line 7803 "built/tmp/cppBison.yxx.c" +#line 7815 "built/tmp/cppBison.yxx.c" break; - case 411: /* simple_int_type: KW_SIGNED simple_int_type */ -#line 3138 "dtool/src/cppparser/cppBison.yxx" + case 412: /* simple_int_type: KW_SIGNED simple_int_type */ +#line 3147 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.simple_type) = (yyvsp[0].u.simple_type); (yyval.u.simple_type)->_flags |= CPPSimpleType::F_signed; } -#line 7812 "built/tmp/cppBison.yxx.c" +#line 7824 "built/tmp/cppBison.yxx.c" break; - case 412: /* simple_float_type: KW_FLOAT */ -#line 3146 "dtool/src/cppparser/cppBison.yxx" + case 413: /* simple_float_type: KW_FLOAT */ +#line 3155 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.simple_type) = new CPPSimpleType(CPPSimpleType::T_float); } -#line 7820 "built/tmp/cppBison.yxx.c" +#line 7832 "built/tmp/cppBison.yxx.c" break; - case 413: /* simple_float_type: KW_DOUBLE */ -#line 3150 "dtool/src/cppparser/cppBison.yxx" + case 414: /* simple_float_type: KW_DOUBLE */ +#line 3159 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.simple_type) = new CPPSimpleType(CPPSimpleType::T_double); } -#line 7828 "built/tmp/cppBison.yxx.c" +#line 7840 "built/tmp/cppBison.yxx.c" break; - case 414: /* simple_float_type: KW_LONG KW_DOUBLE */ -#line 3154 "dtool/src/cppparser/cppBison.yxx" + case 415: /* simple_float_type: KW_LONG KW_DOUBLE */ +#line 3163 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.simple_type) = new CPPSimpleType(CPPSimpleType::T_double, CPPSimpleType::F_long); } -#line 7837 "built/tmp/cppBison.yxx.c" +#line 7849 "built/tmp/cppBison.yxx.c" break; - case 415: /* simple_void_type: KW_VOID */ -#line 3162 "dtool/src/cppparser/cppBison.yxx" + case 416: /* simple_void_type: KW_VOID */ +#line 3171 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.simple_type) = new CPPSimpleType(CPPSimpleType::T_void); } -#line 7845 "built/tmp/cppBison.yxx.c" +#line 7857 "built/tmp/cppBison.yxx.c" break; - case 416: /* $@20: %empty */ -#line 3171 "dtool/src/cppparser/cppBison.yxx" + case 417: /* $@21: %empty */ +#line 3180 "dtool/src/cppparser/cppBison.yxx" { current_lexer->_resolve_identifiers = false; } -#line 7853 "built/tmp/cppBison.yxx.c" +#line 7865 "built/tmp/cppBison.yxx.c" break; - case 417: /* code: $@20 code_block */ -#line 3175 "dtool/src/cppparser/cppBison.yxx" + case 418: /* code: $@21 code_block */ +#line 3184 "dtool/src/cppparser/cppBison.yxx" { current_lexer->_resolve_identifiers = true; } -#line 7861 "built/tmp/cppBison.yxx.c" +#line 7873 "built/tmp/cppBison.yxx.c" break; - case 525: /* element: KW_WHILE */ -#line 3219 "dtool/src/cppparser/cppBison.yxx" -{ -} -#line 7868 "built/tmp/cppBison.yxx.c" - break; - - case 549: /* optional_const_expr: empty */ + case 526: /* element: KW_WHILE */ #line 3228 "dtool/src/cppparser/cppBison.yxx" { - (yyval.u.expr) = nullptr; } -#line 7876 "built/tmp/cppBison.yxx.c" +#line 7880 "built/tmp/cppBison.yxx.c" break; - case 550: /* optional_const_expr: const_expr */ -#line 3232 "dtool/src/cppparser/cppBison.yxx" -{ - (yyval.u.expr) = (yyvsp[0].u.expr); -} -#line 7884 "built/tmp/cppBison.yxx.c" - break; - - case 551: /* optional_const_expr_comma: empty */ -#line 3239 "dtool/src/cppparser/cppBison.yxx" + case 550: /* optional_const_expr: empty */ +#line 3237 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = nullptr; } -#line 7892 "built/tmp/cppBison.yxx.c" +#line 7888 "built/tmp/cppBison.yxx.c" break; - case 552: /* optional_const_expr_comma: const_expr_comma */ -#line 3243 "dtool/src/cppparser/cppBison.yxx" + case 551: /* optional_const_expr: const_expr */ +#line 3241 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = (yyvsp[0].u.expr); } -#line 7900 "built/tmp/cppBison.yxx.c" +#line 7896 "built/tmp/cppBison.yxx.c" break; - case 553: /* const_expr_comma: const_expr */ -#line 3250 "dtool/src/cppparser/cppBison.yxx" + case 552: /* optional_const_expr_comma: empty */ +#line 3248 "dtool/src/cppparser/cppBison.yxx" +{ + (yyval.u.expr) = nullptr; +} +#line 7904 "built/tmp/cppBison.yxx.c" + break; + + case 553: /* optional_const_expr_comma: const_expr_comma */ +#line 3252 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = (yyvsp[0].u.expr); } -#line 7908 "built/tmp/cppBison.yxx.c" +#line 7912 "built/tmp/cppBison.yxx.c" break; - case 554: /* const_expr_comma: const_expr_comma ',' const_expr */ -#line 3254 "dtool/src/cppparser/cppBison.yxx" + case 554: /* const_expr_comma: const_expr */ +#line 3259 "dtool/src/cppparser/cppBison.yxx" +{ + (yyval.u.expr) = (yyvsp[0].u.expr); +} +#line 7920 "built/tmp/cppBison.yxx.c" + break; + + case 555: /* const_expr_comma: const_expr_comma ',' const_expr */ +#line 3263 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(',', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 7916 "built/tmp/cppBison.yxx.c" +#line 7928 "built/tmp/cppBison.yxx.c" break; - case 555: /* no_angle_bracket_const_expr: const_operand */ -#line 3261 "dtool/src/cppparser/cppBison.yxx" + case 556: /* no_angle_bracket_const_expr: const_operand */ +#line 3270 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = (yyvsp[0].u.expr); } -#line 7924 "built/tmp/cppBison.yxx.c" +#line 7936 "built/tmp/cppBison.yxx.c" break; - case 556: /* no_angle_bracket_const_expr: '(' full_type ')' no_angle_bracket_const_expr */ -#line 3265 "dtool/src/cppparser/cppBison.yxx" + case 557: /* no_angle_bracket_const_expr: '(' full_type ')' no_angle_bracket_const_expr */ +#line 3274 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::typecast_op((yyvsp[-2].u.type), (yyvsp[0].u.expr))); } -#line 7932 "built/tmp/cppBison.yxx.c" +#line 7944 "built/tmp/cppBison.yxx.c" break; - case 557: /* no_angle_bracket_const_expr: KW_STATIC_CAST '<' full_type '>' '(' const_expr_comma ')' */ -#line 3269 "dtool/src/cppparser/cppBison.yxx" + case 558: /* no_angle_bracket_const_expr: KW_STATIC_CAST '<' full_type '>' '(' const_expr_comma ')' */ +#line 3278 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::typecast_op((yyvsp[-4].u.type), (yyvsp[-1].u.expr), CPPExpression::T_static_cast)); } -#line 7940 "built/tmp/cppBison.yxx.c" +#line 7952 "built/tmp/cppBison.yxx.c" break; - case 558: /* no_angle_bracket_const_expr: KW_DYNAMIC_CAST '<' full_type '>' '(' const_expr_comma ')' */ -#line 3273 "dtool/src/cppparser/cppBison.yxx" + case 559: /* no_angle_bracket_const_expr: KW_DYNAMIC_CAST '<' full_type '>' '(' const_expr_comma ')' */ +#line 3282 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::typecast_op((yyvsp[-4].u.type), (yyvsp[-1].u.expr), CPPExpression::T_dynamic_cast)); } -#line 7948 "built/tmp/cppBison.yxx.c" +#line 7960 "built/tmp/cppBison.yxx.c" break; - case 559: /* no_angle_bracket_const_expr: KW_CONST_CAST '<' full_type '>' '(' const_expr_comma ')' */ -#line 3277 "dtool/src/cppparser/cppBison.yxx" + case 560: /* no_angle_bracket_const_expr: KW_CONST_CAST '<' full_type '>' '(' const_expr_comma ')' */ +#line 3286 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::typecast_op((yyvsp[-4].u.type), (yyvsp[-1].u.expr), CPPExpression::T_const_cast)); } -#line 7956 "built/tmp/cppBison.yxx.c" +#line 7968 "built/tmp/cppBison.yxx.c" break; - case 560: /* no_angle_bracket_const_expr: KW_REINTERPRET_CAST '<' full_type '>' '(' const_expr_comma ')' */ -#line 3281 "dtool/src/cppparser/cppBison.yxx" + case 561: /* no_angle_bracket_const_expr: KW_REINTERPRET_CAST '<' full_type '>' '(' const_expr_comma ')' */ +#line 3290 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::typecast_op((yyvsp[-4].u.type), (yyvsp[-1].u.expr), CPPExpression::T_reinterpret_cast)); } -#line 7964 "built/tmp/cppBison.yxx.c" +#line 7976 "built/tmp/cppBison.yxx.c" break; - case 561: /* no_angle_bracket_const_expr: KW_SIZEOF '(' full_type ')' */ -#line 3285 "dtool/src/cppparser/cppBison.yxx" + case 562: /* no_angle_bracket_const_expr: KW_SIZEOF '(' full_type ')' */ +#line 3294 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::sizeof_func((yyvsp[-1].u.type))); } -#line 7972 "built/tmp/cppBison.yxx.c" +#line 7984 "built/tmp/cppBison.yxx.c" break; - case 562: /* no_angle_bracket_const_expr: KW_SIZEOF no_angle_bracket_const_expr */ -#line 3289 "dtool/src/cppparser/cppBison.yxx" + case 563: /* no_angle_bracket_const_expr: KW_SIZEOF no_angle_bracket_const_expr */ +#line 3298 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::sizeof_func((yyvsp[0].u.expr))); } -#line 7980 "built/tmp/cppBison.yxx.c" +#line 7992 "built/tmp/cppBison.yxx.c" break; - case 563: /* no_angle_bracket_const_expr: KW_SIZEOF ELLIPSIS '(' name ')' */ -#line 3293 "dtool/src/cppparser/cppBison.yxx" + case 564: /* no_angle_bracket_const_expr: KW_SIZEOF ELLIPSIS '(' name ')' */ +#line 3302 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::sizeof_ellipsis_func((yyvsp[-1].u.identifier))); } -#line 7988 "built/tmp/cppBison.yxx.c" +#line 8000 "built/tmp/cppBison.yxx.c" break; - case 564: /* no_angle_bracket_const_expr: KW_ALIGNOF '(' full_type ')' */ -#line 3297 "dtool/src/cppparser/cppBison.yxx" + case 565: /* no_angle_bracket_const_expr: KW_ALIGNOF '(' full_type ')' */ +#line 3306 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::alignof_func((yyvsp[-1].u.type))); } -#line 7996 "built/tmp/cppBison.yxx.c" +#line 8008 "built/tmp/cppBison.yxx.c" break; - case 565: /* no_angle_bracket_const_expr: '!' no_angle_bracket_const_expr */ -#line 3301 "dtool/src/cppparser/cppBison.yxx" + case 566: /* no_angle_bracket_const_expr: '!' no_angle_bracket_const_expr */ +#line 3310 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(UNARY_NOT, (yyvsp[0].u.expr)); } -#line 8004 "built/tmp/cppBison.yxx.c" +#line 8016 "built/tmp/cppBison.yxx.c" break; - case 566: /* no_angle_bracket_const_expr: '~' no_angle_bracket_const_expr */ -#line 3305 "dtool/src/cppparser/cppBison.yxx" + case 567: /* no_angle_bracket_const_expr: '~' no_angle_bracket_const_expr */ +#line 3314 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(UNARY_NEGATE, (yyvsp[0].u.expr)); } -#line 8012 "built/tmp/cppBison.yxx.c" +#line 8024 "built/tmp/cppBison.yxx.c" break; - case 567: /* no_angle_bracket_const_expr: '-' no_angle_bracket_const_expr */ -#line 3309 "dtool/src/cppparser/cppBison.yxx" + case 568: /* no_angle_bracket_const_expr: '-' no_angle_bracket_const_expr */ +#line 3318 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(UNARY_MINUS, (yyvsp[0].u.expr)); } -#line 8020 "built/tmp/cppBison.yxx.c" +#line 8032 "built/tmp/cppBison.yxx.c" break; - case 568: /* no_angle_bracket_const_expr: '+' no_angle_bracket_const_expr */ -#line 3313 "dtool/src/cppparser/cppBison.yxx" + case 569: /* no_angle_bracket_const_expr: '+' no_angle_bracket_const_expr */ +#line 3322 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(UNARY_PLUS, (yyvsp[0].u.expr)); } -#line 8028 "built/tmp/cppBison.yxx.c" +#line 8040 "built/tmp/cppBison.yxx.c" break; - case 569: /* no_angle_bracket_const_expr: '*' no_angle_bracket_const_expr */ -#line 3317 "dtool/src/cppparser/cppBison.yxx" + case 570: /* no_angle_bracket_const_expr: '*' no_angle_bracket_const_expr */ +#line 3326 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(UNARY_STAR, (yyvsp[0].u.expr)); } -#line 8036 "built/tmp/cppBison.yxx.c" +#line 8048 "built/tmp/cppBison.yxx.c" break; - case 570: /* no_angle_bracket_const_expr: '&' no_angle_bracket_const_expr */ -#line 3321 "dtool/src/cppparser/cppBison.yxx" + case 571: /* no_angle_bracket_const_expr: '&' no_angle_bracket_const_expr */ +#line 3330 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(UNARY_REF, (yyvsp[0].u.expr)); } -#line 8044 "built/tmp/cppBison.yxx.c" +#line 8056 "built/tmp/cppBison.yxx.c" break; - case 571: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr '*' no_angle_bracket_const_expr */ -#line 3325 "dtool/src/cppparser/cppBison.yxx" + case 572: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr '*' no_angle_bracket_const_expr */ +#line 3334 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('*', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8052 "built/tmp/cppBison.yxx.c" +#line 8064 "built/tmp/cppBison.yxx.c" break; - case 572: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr '/' no_angle_bracket_const_expr */ -#line 3329 "dtool/src/cppparser/cppBison.yxx" + case 573: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr '/' no_angle_bracket_const_expr */ +#line 3338 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('/', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8060 "built/tmp/cppBison.yxx.c" +#line 8072 "built/tmp/cppBison.yxx.c" break; - case 573: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr '%' no_angle_bracket_const_expr */ -#line 3333 "dtool/src/cppparser/cppBison.yxx" + case 574: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr '%' no_angle_bracket_const_expr */ +#line 3342 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('%', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8068 "built/tmp/cppBison.yxx.c" +#line 8080 "built/tmp/cppBison.yxx.c" break; - case 574: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr '+' no_angle_bracket_const_expr */ -#line 3337 "dtool/src/cppparser/cppBison.yxx" + case 575: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr '+' no_angle_bracket_const_expr */ +#line 3346 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('+', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8076 "built/tmp/cppBison.yxx.c" +#line 8088 "built/tmp/cppBison.yxx.c" break; - case 575: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr '-' no_angle_bracket_const_expr */ -#line 3341 "dtool/src/cppparser/cppBison.yxx" + case 576: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr '-' no_angle_bracket_const_expr */ +#line 3350 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('-', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8084 "built/tmp/cppBison.yxx.c" +#line 8096 "built/tmp/cppBison.yxx.c" break; - case 576: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr '|' no_angle_bracket_const_expr */ -#line 3345 "dtool/src/cppparser/cppBison.yxx" + case 577: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr '|' no_angle_bracket_const_expr */ +#line 3354 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('|', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8092 "built/tmp/cppBison.yxx.c" +#line 8104 "built/tmp/cppBison.yxx.c" break; - case 577: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr '^' no_angle_bracket_const_expr */ -#line 3349 "dtool/src/cppparser/cppBison.yxx" + case 578: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr '^' no_angle_bracket_const_expr */ +#line 3358 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('^', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8100 "built/tmp/cppBison.yxx.c" +#line 8112 "built/tmp/cppBison.yxx.c" break; - case 578: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr '&' no_angle_bracket_const_expr */ -#line 3353 "dtool/src/cppparser/cppBison.yxx" + case 579: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr '&' no_angle_bracket_const_expr */ +#line 3362 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('&', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8108 "built/tmp/cppBison.yxx.c" +#line 8120 "built/tmp/cppBison.yxx.c" break; - case 579: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr OROR no_angle_bracket_const_expr */ -#line 3357 "dtool/src/cppparser/cppBison.yxx" + case 580: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr OROR no_angle_bracket_const_expr */ +#line 3366 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(OROR, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8116 "built/tmp/cppBison.yxx.c" +#line 8128 "built/tmp/cppBison.yxx.c" break; - case 580: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr ANDAND no_angle_bracket_const_expr */ -#line 3361 "dtool/src/cppparser/cppBison.yxx" + case 581: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr ANDAND no_angle_bracket_const_expr */ +#line 3370 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(ANDAND, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8124 "built/tmp/cppBison.yxx.c" +#line 8136 "built/tmp/cppBison.yxx.c" break; - case 581: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr EQCOMPARE no_angle_bracket_const_expr */ -#line 3365 "dtool/src/cppparser/cppBison.yxx" + case 582: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr EQCOMPARE no_angle_bracket_const_expr */ +#line 3374 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(EQCOMPARE, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8132 "built/tmp/cppBison.yxx.c" +#line 8144 "built/tmp/cppBison.yxx.c" break; - case 582: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr NECOMPARE no_angle_bracket_const_expr */ -#line 3369 "dtool/src/cppparser/cppBison.yxx" + case 583: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr NECOMPARE no_angle_bracket_const_expr */ +#line 3378 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(NECOMPARE, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8140 "built/tmp/cppBison.yxx.c" +#line 8152 "built/tmp/cppBison.yxx.c" break; - case 583: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr LECOMPARE no_angle_bracket_const_expr */ -#line 3373 "dtool/src/cppparser/cppBison.yxx" + case 584: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr LECOMPARE no_angle_bracket_const_expr */ +#line 3382 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(LECOMPARE, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8148 "built/tmp/cppBison.yxx.c" +#line 8160 "built/tmp/cppBison.yxx.c" break; - case 584: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr GECOMPARE no_angle_bracket_const_expr */ -#line 3377 "dtool/src/cppparser/cppBison.yxx" + case 585: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr GECOMPARE no_angle_bracket_const_expr */ +#line 3386 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(GECOMPARE, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8156 "built/tmp/cppBison.yxx.c" +#line 8168 "built/tmp/cppBison.yxx.c" break; - case 585: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr LSHIFT no_angle_bracket_const_expr */ -#line 3381 "dtool/src/cppparser/cppBison.yxx" + case 586: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr LSHIFT no_angle_bracket_const_expr */ +#line 3390 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(LSHIFT, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8164 "built/tmp/cppBison.yxx.c" +#line 8176 "built/tmp/cppBison.yxx.c" break; - case 586: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr RSHIFT no_angle_bracket_const_expr */ -#line 3385 "dtool/src/cppparser/cppBison.yxx" + case 587: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr RSHIFT no_angle_bracket_const_expr */ +#line 3394 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(RSHIFT, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8172 "built/tmp/cppBison.yxx.c" +#line 8184 "built/tmp/cppBison.yxx.c" break; - case 587: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr '?' no_angle_bracket_const_expr ':' no_angle_bracket_const_expr */ -#line 3389 "dtool/src/cppparser/cppBison.yxx" + case 588: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr '?' no_angle_bracket_const_expr ':' no_angle_bracket_const_expr */ +#line 3398 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('?', (yyvsp[-4].u.expr), (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8180 "built/tmp/cppBison.yxx.c" +#line 8192 "built/tmp/cppBison.yxx.c" break; - case 588: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr '[' const_expr ']' */ -#line 3393 "dtool/src/cppparser/cppBison.yxx" + case 589: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr '[' const_expr ']' */ +#line 3402 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('[', (yyvsp[-3].u.expr), (yyvsp[-1].u.expr)); } -#line 8188 "built/tmp/cppBison.yxx.c" +#line 8200 "built/tmp/cppBison.yxx.c" break; - case 589: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr '(' const_expr_comma ')' */ -#line 3397 "dtool/src/cppparser/cppBison.yxx" + case 590: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr '(' const_expr_comma ')' */ +#line 3406 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('f', (yyvsp[-3].u.expr), (yyvsp[-1].u.expr)); } -#line 8196 "built/tmp/cppBison.yxx.c" +#line 8208 "built/tmp/cppBison.yxx.c" break; - case 590: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr '(' ')' */ -#line 3401 "dtool/src/cppparser/cppBison.yxx" + case 591: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr '(' ')' */ +#line 3410 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('f', (yyvsp[-2].u.expr)); } -#line 8204 "built/tmp/cppBison.yxx.c" +#line 8216 "built/tmp/cppBison.yxx.c" break; - case 591: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr '.' name */ -#line 3405 "dtool/src/cppparser/cppBison.yxx" + case 592: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr '.' name */ +#line 3414 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('.', (yyvsp[-2].u.expr), new CPPExpression((yyvsp[0].u.identifier), current_scope, global_scope, current_lexer)); } -#line 8212 "built/tmp/cppBison.yxx.c" +#line 8224 "built/tmp/cppBison.yxx.c" break; - case 592: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr POINTSAT no_angle_bracket_const_expr */ -#line 3409 "dtool/src/cppparser/cppBison.yxx" + case 593: /* no_angle_bracket_const_expr: no_angle_bracket_const_expr POINTSAT no_angle_bracket_const_expr */ +#line 3418 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(POINTSAT, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8220 "built/tmp/cppBison.yxx.c" +#line 8232 "built/tmp/cppBison.yxx.c" break; - case 593: /* no_angle_bracket_const_expr: '(' const_expr_comma ')' */ -#line 3413 "dtool/src/cppparser/cppBison.yxx" + case 594: /* no_angle_bracket_const_expr: '(' const_expr_comma ')' */ +#line 3422 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = (yyvsp[-1].u.expr); } -#line 8228 "built/tmp/cppBison.yxx.c" +#line 8240 "built/tmp/cppBison.yxx.c" break; - case 594: /* const_expr: const_operand */ -#line 3421 "dtool/src/cppparser/cppBison.yxx" + case 595: /* const_expr: const_operand */ +#line 3430 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = (yyvsp[0].u.expr); } -#line 8236 "built/tmp/cppBison.yxx.c" +#line 8248 "built/tmp/cppBison.yxx.c" break; - case 595: /* const_expr: '(' full_type ')' const_expr */ -#line 3425 "dtool/src/cppparser/cppBison.yxx" + case 596: /* const_expr: '(' full_type ')' const_expr */ +#line 3434 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::typecast_op((yyvsp[-2].u.type), (yyvsp[0].u.expr))); } -#line 8244 "built/tmp/cppBison.yxx.c" +#line 8256 "built/tmp/cppBison.yxx.c" break; - case 596: /* const_expr: KW_STATIC_CAST '<' full_type '>' '(' const_expr_comma ')' */ -#line 3429 "dtool/src/cppparser/cppBison.yxx" + case 597: /* const_expr: KW_STATIC_CAST '<' full_type '>' '(' const_expr_comma ')' */ +#line 3438 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::typecast_op((yyvsp[-4].u.type), (yyvsp[-1].u.expr), CPPExpression::T_static_cast)); } -#line 8252 "built/tmp/cppBison.yxx.c" +#line 8264 "built/tmp/cppBison.yxx.c" break; - case 597: /* const_expr: KW_DYNAMIC_CAST '<' full_type '>' '(' const_expr_comma ')' */ -#line 3433 "dtool/src/cppparser/cppBison.yxx" + case 598: /* const_expr: KW_DYNAMIC_CAST '<' full_type '>' '(' const_expr_comma ')' */ +#line 3442 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::typecast_op((yyvsp[-4].u.type), (yyvsp[-1].u.expr), CPPExpression::T_dynamic_cast)); } -#line 8260 "built/tmp/cppBison.yxx.c" +#line 8272 "built/tmp/cppBison.yxx.c" break; - case 598: /* const_expr: KW_CONST_CAST '<' full_type '>' '(' const_expr_comma ')' */ -#line 3437 "dtool/src/cppparser/cppBison.yxx" + case 599: /* const_expr: KW_CONST_CAST '<' full_type '>' '(' const_expr_comma ')' */ +#line 3446 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::typecast_op((yyvsp[-4].u.type), (yyvsp[-1].u.expr), CPPExpression::T_const_cast)); } -#line 8268 "built/tmp/cppBison.yxx.c" +#line 8280 "built/tmp/cppBison.yxx.c" break; - case 599: /* const_expr: KW_REINTERPRET_CAST '<' full_type '>' '(' const_expr_comma ')' */ -#line 3441 "dtool/src/cppparser/cppBison.yxx" + case 600: /* const_expr: KW_REINTERPRET_CAST '<' full_type '>' '(' const_expr_comma ')' */ +#line 3450 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::typecast_op((yyvsp[-4].u.type), (yyvsp[-1].u.expr), CPPExpression::T_reinterpret_cast)); } -#line 8276 "built/tmp/cppBison.yxx.c" +#line 8288 "built/tmp/cppBison.yxx.c" break; - case 600: /* const_expr: TYPENAME_IDENTIFIER '(' optional_const_expr_comma ')' */ -#line 3445 "dtool/src/cppparser/cppBison.yxx" + case 601: /* const_expr: TYPENAME_IDENTIFIER '(' optional_const_expr_comma ')' */ +#line 3454 "dtool/src/cppparser/cppBison.yxx" { // A constructor call. CPPType *type = (yyvsp[-3].u.identifier)->find_type(current_scope, global_scope, false, current_lexer); @@ -8286,11 +8298,11 @@ yyreduce: assert(type != nullptr); (yyval.u.expr) = new CPPExpression(CPPExpression::construct_op(type, (yyvsp[-1].u.expr))); } -#line 8290 "built/tmp/cppBison.yxx.c" +#line 8302 "built/tmp/cppBison.yxx.c" break; - case 601: /* const_expr: TYPENAME_IDENTIFIER '{' optional_const_expr_comma '}' */ -#line 3455 "dtool/src/cppparser/cppBison.yxx" + case 602: /* const_expr: TYPENAME_IDENTIFIER '{' optional_const_expr_comma '}' */ +#line 3464 "dtool/src/cppparser/cppBison.yxx" { // Aggregate initialization. CPPType *type = (yyvsp[-3].u.identifier)->find_type(current_scope, global_scope, false, current_lexer); @@ -8300,183 +8312,183 @@ yyreduce: assert(type != nullptr); (yyval.u.expr) = new CPPExpression(CPPExpression::aggregate_init_op(type, (yyvsp[-1].u.expr))); } -#line 8304 "built/tmp/cppBison.yxx.c" +#line 8316 "built/tmp/cppBison.yxx.c" break; - case 602: /* const_expr: KW_INT '(' optional_const_expr_comma ')' */ -#line 3465 "dtool/src/cppparser/cppBison.yxx" + case 603: /* const_expr: KW_INT '(' optional_const_expr_comma ')' */ +#line 3474 "dtool/src/cppparser/cppBison.yxx" { CPPType *type = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_int)); (yyval.u.expr) = new CPPExpression(CPPExpression::construct_op(type, (yyvsp[-1].u.expr))); } -#line 8314 "built/tmp/cppBison.yxx.c" +#line 8326 "built/tmp/cppBison.yxx.c" break; - case 603: /* const_expr: KW_CHAR '(' optional_const_expr_comma ')' */ -#line 3471 "dtool/src/cppparser/cppBison.yxx" + case 604: /* const_expr: KW_CHAR '(' optional_const_expr_comma ')' */ +#line 3480 "dtool/src/cppparser/cppBison.yxx" { CPPType *type = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_char)); (yyval.u.expr) = new CPPExpression(CPPExpression::construct_op(type, (yyvsp[-1].u.expr))); } -#line 8324 "built/tmp/cppBison.yxx.c" +#line 8336 "built/tmp/cppBison.yxx.c" break; - case 604: /* const_expr: KW_WCHAR_T '(' optional_const_expr_comma ')' */ -#line 3477 "dtool/src/cppparser/cppBison.yxx" + case 605: /* const_expr: KW_WCHAR_T '(' optional_const_expr_comma ')' */ +#line 3486 "dtool/src/cppparser/cppBison.yxx" { CPPType *type = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_wchar_t)); (yyval.u.expr) = new CPPExpression(CPPExpression::construct_op(type, (yyvsp[-1].u.expr))); } -#line 8334 "built/tmp/cppBison.yxx.c" +#line 8346 "built/tmp/cppBison.yxx.c" break; - case 605: /* const_expr: KW_CHAR16_T '(' optional_const_expr_comma ')' */ -#line 3483 "dtool/src/cppparser/cppBison.yxx" + case 606: /* const_expr: KW_CHAR16_T '(' optional_const_expr_comma ')' */ +#line 3492 "dtool/src/cppparser/cppBison.yxx" { CPPType *type = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_char16_t)); (yyval.u.expr) = new CPPExpression(CPPExpression::construct_op(type, (yyvsp[-1].u.expr))); } -#line 8344 "built/tmp/cppBison.yxx.c" +#line 8356 "built/tmp/cppBison.yxx.c" break; - case 606: /* const_expr: KW_CHAR32_T '(' optional_const_expr_comma ')' */ -#line 3489 "dtool/src/cppparser/cppBison.yxx" + case 607: /* const_expr: KW_CHAR32_T '(' optional_const_expr_comma ')' */ +#line 3498 "dtool/src/cppparser/cppBison.yxx" { CPPType *type = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_char32_t)); (yyval.u.expr) = new CPPExpression(CPPExpression::construct_op(type, (yyvsp[-1].u.expr))); } -#line 8354 "built/tmp/cppBison.yxx.c" +#line 8366 "built/tmp/cppBison.yxx.c" break; - case 607: /* const_expr: KW_BOOL '(' optional_const_expr_comma ')' */ -#line 3495 "dtool/src/cppparser/cppBison.yxx" + case 608: /* const_expr: KW_BOOL '(' optional_const_expr_comma ')' */ +#line 3504 "dtool/src/cppparser/cppBison.yxx" { CPPType *type = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_bool)); (yyval.u.expr) = new CPPExpression(CPPExpression::construct_op(type, (yyvsp[-1].u.expr))); } -#line 8364 "built/tmp/cppBison.yxx.c" +#line 8376 "built/tmp/cppBison.yxx.c" break; - case 608: /* const_expr: KW_SHORT '(' optional_const_expr_comma ')' */ -#line 3501 "dtool/src/cppparser/cppBison.yxx" + case 609: /* const_expr: KW_SHORT '(' optional_const_expr_comma ')' */ +#line 3510 "dtool/src/cppparser/cppBison.yxx" { CPPType *type = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_int, CPPSimpleType::F_short)); (yyval.u.expr) = new CPPExpression(CPPExpression::construct_op(type, (yyvsp[-1].u.expr))); } -#line 8375 "built/tmp/cppBison.yxx.c" +#line 8387 "built/tmp/cppBison.yxx.c" break; - case 609: /* const_expr: KW_LONG '(' optional_const_expr_comma ')' */ -#line 3508 "dtool/src/cppparser/cppBison.yxx" + case 610: /* const_expr: KW_LONG '(' optional_const_expr_comma ')' */ +#line 3517 "dtool/src/cppparser/cppBison.yxx" { CPPType *type = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_int, CPPSimpleType::F_long)); (yyval.u.expr) = new CPPExpression(CPPExpression::construct_op(type, (yyvsp[-1].u.expr))); } -#line 8386 "built/tmp/cppBison.yxx.c" +#line 8398 "built/tmp/cppBison.yxx.c" break; - case 610: /* const_expr: KW_UNSIGNED '(' optional_const_expr_comma ')' */ -#line 3515 "dtool/src/cppparser/cppBison.yxx" + case 611: /* const_expr: KW_UNSIGNED '(' optional_const_expr_comma ')' */ +#line 3524 "dtool/src/cppparser/cppBison.yxx" { CPPType *type = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_int, CPPSimpleType::F_unsigned)); (yyval.u.expr) = new CPPExpression(CPPExpression::construct_op(type, (yyvsp[-1].u.expr))); } -#line 8397 "built/tmp/cppBison.yxx.c" +#line 8409 "built/tmp/cppBison.yxx.c" break; - case 611: /* const_expr: KW_SIGNED '(' optional_const_expr_comma ')' */ -#line 3522 "dtool/src/cppparser/cppBison.yxx" + case 612: /* const_expr: KW_SIGNED '(' optional_const_expr_comma ')' */ +#line 3531 "dtool/src/cppparser/cppBison.yxx" { CPPType *type = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_int, CPPSimpleType::F_signed)); (yyval.u.expr) = new CPPExpression(CPPExpression::construct_op(type, (yyvsp[-1].u.expr))); } -#line 8408 "built/tmp/cppBison.yxx.c" +#line 8420 "built/tmp/cppBison.yxx.c" break; - case 612: /* const_expr: KW_FLOAT '(' optional_const_expr_comma ')' */ -#line 3529 "dtool/src/cppparser/cppBison.yxx" + case 613: /* const_expr: KW_FLOAT '(' optional_const_expr_comma ')' */ +#line 3538 "dtool/src/cppparser/cppBison.yxx" { CPPType *type = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_float)); (yyval.u.expr) = new CPPExpression(CPPExpression::construct_op(type, (yyvsp[-1].u.expr))); } -#line 8418 "built/tmp/cppBison.yxx.c" +#line 8430 "built/tmp/cppBison.yxx.c" break; - case 613: /* const_expr: KW_DOUBLE '(' optional_const_expr_comma ')' */ -#line 3535 "dtool/src/cppparser/cppBison.yxx" + case 614: /* const_expr: KW_DOUBLE '(' optional_const_expr_comma ')' */ +#line 3544 "dtool/src/cppparser/cppBison.yxx" { CPPType *type = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_double)); (yyval.u.expr) = new CPPExpression(CPPExpression::construct_op(type, (yyvsp[-1].u.expr))); } -#line 8428 "built/tmp/cppBison.yxx.c" +#line 8440 "built/tmp/cppBison.yxx.c" break; - case 614: /* const_expr: KW_SIZEOF '(' full_type ')' */ -#line 3541 "dtool/src/cppparser/cppBison.yxx" + case 615: /* const_expr: KW_SIZEOF '(' full_type ')' */ +#line 3550 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::sizeof_func((yyvsp[-1].u.type))); } -#line 8436 "built/tmp/cppBison.yxx.c" +#line 8448 "built/tmp/cppBison.yxx.c" break; - case 615: /* const_expr: KW_SIZEOF const_expr */ -#line 3545 "dtool/src/cppparser/cppBison.yxx" + case 616: /* const_expr: KW_SIZEOF const_expr */ +#line 3554 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::sizeof_func((yyvsp[0].u.expr))); } -#line 8444 "built/tmp/cppBison.yxx.c" +#line 8456 "built/tmp/cppBison.yxx.c" break; - case 616: /* const_expr: KW_SIZEOF ELLIPSIS '(' name ')' */ -#line 3549 "dtool/src/cppparser/cppBison.yxx" + case 617: /* const_expr: KW_SIZEOF ELLIPSIS '(' name ')' */ +#line 3558 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::sizeof_ellipsis_func((yyvsp[-1].u.identifier))); } -#line 8452 "built/tmp/cppBison.yxx.c" +#line 8464 "built/tmp/cppBison.yxx.c" break; - case 617: /* const_expr: KW_ALIGNOF '(' full_type ')' */ -#line 3553 "dtool/src/cppparser/cppBison.yxx" + case 618: /* const_expr: KW_ALIGNOF '(' full_type ')' */ +#line 3562 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::alignof_func((yyvsp[-1].u.type))); } -#line 8460 "built/tmp/cppBison.yxx.c" +#line 8472 "built/tmp/cppBison.yxx.c" break; - case 618: /* const_expr: KW_NEW predefined_type */ -#line 3557 "dtool/src/cppparser/cppBison.yxx" + case 619: /* const_expr: KW_NEW predefined_type */ +#line 3566 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::new_op((yyvsp[0].u.type))); } -#line 8468 "built/tmp/cppBison.yxx.c" +#line 8480 "built/tmp/cppBison.yxx.c" break; - case 619: /* const_expr: KW_NEW predefined_type '(' optional_const_expr_comma ')' */ -#line 3561 "dtool/src/cppparser/cppBison.yxx" + case 620: /* const_expr: KW_NEW predefined_type '(' optional_const_expr_comma ')' */ +#line 3570 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::new_op((yyvsp[-3].u.type), (yyvsp[-1].u.expr))); } -#line 8476 "built/tmp/cppBison.yxx.c" +#line 8488 "built/tmp/cppBison.yxx.c" break; - case 620: /* const_expr: KW_TYPEID '(' full_type ')' */ -#line 3565 "dtool/src/cppparser/cppBison.yxx" + case 621: /* const_expr: KW_TYPEID '(' full_type ')' */ +#line 3574 "dtool/src/cppparser/cppBison.yxx" { CPPIdentifier ident(""); ident.add_name("std"); @@ -8487,11 +8499,11 @@ yyreduce: } (yyval.u.expr) = new CPPExpression(CPPExpression::typeid_op((yyvsp[-1].u.type), std_type_info)); } -#line 8491 "built/tmp/cppBison.yxx.c" +#line 8503 "built/tmp/cppBison.yxx.c" break; - case 621: /* const_expr: KW_TYPEID '(' const_expr ')' */ -#line 3576 "dtool/src/cppparser/cppBison.yxx" + case 622: /* const_expr: KW_TYPEID '(' const_expr ')' */ +#line 3585 "dtool/src/cppparser/cppBison.yxx" { CPPIdentifier ident(""); ident.add_name("std"); @@ -8502,604 +8514,604 @@ yyreduce: } (yyval.u.expr) = new CPPExpression(CPPExpression::typeid_op((yyvsp[-1].u.expr), std_type_info)); } -#line 8506 "built/tmp/cppBison.yxx.c" +#line 8518 "built/tmp/cppBison.yxx.c" break; - case 622: /* const_expr: '!' const_expr */ -#line 3587 "dtool/src/cppparser/cppBison.yxx" + case 623: /* const_expr: '!' const_expr */ +#line 3596 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(UNARY_NOT, (yyvsp[0].u.expr)); } -#line 8514 "built/tmp/cppBison.yxx.c" +#line 8526 "built/tmp/cppBison.yxx.c" break; - case 623: /* const_expr: '~' const_expr */ -#line 3591 "dtool/src/cppparser/cppBison.yxx" + case 624: /* const_expr: '~' const_expr */ +#line 3600 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(UNARY_NEGATE, (yyvsp[0].u.expr)); } -#line 8522 "built/tmp/cppBison.yxx.c" +#line 8534 "built/tmp/cppBison.yxx.c" break; - case 624: /* const_expr: '-' const_expr */ -#line 3595 "dtool/src/cppparser/cppBison.yxx" + case 625: /* const_expr: '-' const_expr */ +#line 3604 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(UNARY_MINUS, (yyvsp[0].u.expr)); } -#line 8530 "built/tmp/cppBison.yxx.c" +#line 8542 "built/tmp/cppBison.yxx.c" break; - case 625: /* const_expr: '+' const_expr */ -#line 3599 "dtool/src/cppparser/cppBison.yxx" + case 626: /* const_expr: '+' const_expr */ +#line 3608 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(UNARY_PLUS, (yyvsp[0].u.expr)); } -#line 8538 "built/tmp/cppBison.yxx.c" +#line 8550 "built/tmp/cppBison.yxx.c" break; - case 626: /* const_expr: '*' const_expr */ -#line 3603 "dtool/src/cppparser/cppBison.yxx" + case 627: /* const_expr: '*' const_expr */ +#line 3612 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(UNARY_STAR, (yyvsp[0].u.expr)); } -#line 8546 "built/tmp/cppBison.yxx.c" +#line 8558 "built/tmp/cppBison.yxx.c" break; - case 627: /* const_expr: '&' const_expr */ -#line 3607 "dtool/src/cppparser/cppBison.yxx" + case 628: /* const_expr: '&' const_expr */ +#line 3616 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(UNARY_REF, (yyvsp[0].u.expr)); } -#line 8554 "built/tmp/cppBison.yxx.c" +#line 8566 "built/tmp/cppBison.yxx.c" break; - case 628: /* const_expr: const_expr '*' const_expr */ -#line 3611 "dtool/src/cppparser/cppBison.yxx" + case 629: /* const_expr: const_expr '*' const_expr */ +#line 3620 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('*', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8562 "built/tmp/cppBison.yxx.c" +#line 8574 "built/tmp/cppBison.yxx.c" break; - case 629: /* const_expr: const_expr '/' const_expr */ -#line 3615 "dtool/src/cppparser/cppBison.yxx" + case 630: /* const_expr: const_expr '/' const_expr */ +#line 3624 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('/', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8570 "built/tmp/cppBison.yxx.c" +#line 8582 "built/tmp/cppBison.yxx.c" break; - case 630: /* const_expr: const_expr '%' const_expr */ -#line 3619 "dtool/src/cppparser/cppBison.yxx" + case 631: /* const_expr: const_expr '%' const_expr */ +#line 3628 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('%', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8578 "built/tmp/cppBison.yxx.c" +#line 8590 "built/tmp/cppBison.yxx.c" break; - case 631: /* const_expr: const_expr '+' const_expr */ -#line 3623 "dtool/src/cppparser/cppBison.yxx" + case 632: /* const_expr: const_expr '+' const_expr */ +#line 3632 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('+', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8586 "built/tmp/cppBison.yxx.c" +#line 8598 "built/tmp/cppBison.yxx.c" break; - case 632: /* const_expr: const_expr '-' const_expr */ -#line 3627 "dtool/src/cppparser/cppBison.yxx" + case 633: /* const_expr: const_expr '-' const_expr */ +#line 3636 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('-', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8594 "built/tmp/cppBison.yxx.c" +#line 8606 "built/tmp/cppBison.yxx.c" break; - case 633: /* const_expr: const_expr '|' const_expr */ -#line 3631 "dtool/src/cppparser/cppBison.yxx" + case 634: /* const_expr: const_expr '|' const_expr */ +#line 3640 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('|', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8602 "built/tmp/cppBison.yxx.c" +#line 8614 "built/tmp/cppBison.yxx.c" break; - case 634: /* const_expr: const_expr '^' const_expr */ -#line 3635 "dtool/src/cppparser/cppBison.yxx" + case 635: /* const_expr: const_expr '^' const_expr */ +#line 3644 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('^', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8610 "built/tmp/cppBison.yxx.c" +#line 8622 "built/tmp/cppBison.yxx.c" break; - case 635: /* const_expr: const_expr '&' const_expr */ -#line 3639 "dtool/src/cppparser/cppBison.yxx" + case 636: /* const_expr: const_expr '&' const_expr */ +#line 3648 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('&', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8618 "built/tmp/cppBison.yxx.c" +#line 8630 "built/tmp/cppBison.yxx.c" break; - case 636: /* const_expr: const_expr OROR const_expr */ -#line 3643 "dtool/src/cppparser/cppBison.yxx" + case 637: /* const_expr: const_expr OROR const_expr */ +#line 3652 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(OROR, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8626 "built/tmp/cppBison.yxx.c" +#line 8638 "built/tmp/cppBison.yxx.c" break; - case 637: /* const_expr: const_expr ANDAND const_expr */ -#line 3647 "dtool/src/cppparser/cppBison.yxx" + case 638: /* const_expr: const_expr ANDAND const_expr */ +#line 3656 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(ANDAND, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8634 "built/tmp/cppBison.yxx.c" +#line 8646 "built/tmp/cppBison.yxx.c" break; - case 638: /* const_expr: const_expr EQCOMPARE const_expr */ -#line 3651 "dtool/src/cppparser/cppBison.yxx" + case 639: /* const_expr: const_expr EQCOMPARE const_expr */ +#line 3660 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(EQCOMPARE, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8642 "built/tmp/cppBison.yxx.c" +#line 8654 "built/tmp/cppBison.yxx.c" break; - case 639: /* const_expr: const_expr NECOMPARE const_expr */ -#line 3655 "dtool/src/cppparser/cppBison.yxx" + case 640: /* const_expr: const_expr NECOMPARE const_expr */ +#line 3664 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(NECOMPARE, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8650 "built/tmp/cppBison.yxx.c" +#line 8662 "built/tmp/cppBison.yxx.c" break; - case 640: /* const_expr: const_expr LECOMPARE const_expr */ -#line 3659 "dtool/src/cppparser/cppBison.yxx" + case 641: /* const_expr: const_expr LECOMPARE const_expr */ +#line 3668 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(LECOMPARE, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8658 "built/tmp/cppBison.yxx.c" +#line 8670 "built/tmp/cppBison.yxx.c" break; - case 641: /* const_expr: const_expr GECOMPARE const_expr */ -#line 3663 "dtool/src/cppparser/cppBison.yxx" + case 642: /* const_expr: const_expr GECOMPARE const_expr */ +#line 3672 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(GECOMPARE, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8666 "built/tmp/cppBison.yxx.c" +#line 8678 "built/tmp/cppBison.yxx.c" break; - case 642: /* const_expr: const_expr '<' const_expr */ -#line 3667 "dtool/src/cppparser/cppBison.yxx" + case 643: /* const_expr: const_expr '<' const_expr */ +#line 3676 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('<', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8674 "built/tmp/cppBison.yxx.c" +#line 8686 "built/tmp/cppBison.yxx.c" break; - case 643: /* const_expr: const_expr '>' const_expr */ -#line 3671 "dtool/src/cppparser/cppBison.yxx" + case 644: /* const_expr: const_expr '>' const_expr */ +#line 3680 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('>', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8682 "built/tmp/cppBison.yxx.c" +#line 8694 "built/tmp/cppBison.yxx.c" break; - case 644: /* const_expr: const_expr LSHIFT const_expr */ -#line 3675 "dtool/src/cppparser/cppBison.yxx" + case 645: /* const_expr: const_expr LSHIFT const_expr */ +#line 3684 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(LSHIFT, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8690 "built/tmp/cppBison.yxx.c" +#line 8702 "built/tmp/cppBison.yxx.c" break; - case 645: /* const_expr: const_expr RSHIFT const_expr */ -#line 3679 "dtool/src/cppparser/cppBison.yxx" + case 646: /* const_expr: const_expr RSHIFT const_expr */ +#line 3688 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(RSHIFT, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8698 "built/tmp/cppBison.yxx.c" +#line 8710 "built/tmp/cppBison.yxx.c" break; - case 646: /* const_expr: const_expr '?' const_expr ':' const_expr */ -#line 3683 "dtool/src/cppparser/cppBison.yxx" + case 647: /* const_expr: const_expr '?' const_expr ':' const_expr */ +#line 3692 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('?', (yyvsp[-4].u.expr), (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8706 "built/tmp/cppBison.yxx.c" +#line 8718 "built/tmp/cppBison.yxx.c" break; - case 647: /* const_expr: const_expr '[' const_expr ']' */ -#line 3687 "dtool/src/cppparser/cppBison.yxx" + case 648: /* const_expr: const_expr '[' const_expr ']' */ +#line 3696 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('[', (yyvsp[-3].u.expr), (yyvsp[-1].u.expr)); } -#line 8714 "built/tmp/cppBison.yxx.c" +#line 8726 "built/tmp/cppBison.yxx.c" break; - case 648: /* const_expr: const_expr '(' const_expr_comma ')' */ -#line 3691 "dtool/src/cppparser/cppBison.yxx" + case 649: /* const_expr: const_expr '(' const_expr_comma ')' */ +#line 3700 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('f', (yyvsp[-3].u.expr), (yyvsp[-1].u.expr)); } -#line 8722 "built/tmp/cppBison.yxx.c" +#line 8734 "built/tmp/cppBison.yxx.c" break; - case 649: /* const_expr: const_expr '(' ')' */ -#line 3695 "dtool/src/cppparser/cppBison.yxx" + case 650: /* const_expr: const_expr '(' ')' */ +#line 3704 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('f', (yyvsp[-2].u.expr)); } -#line 8730 "built/tmp/cppBison.yxx.c" +#line 8742 "built/tmp/cppBison.yxx.c" break; - case 650: /* const_expr: const_expr '.' name */ -#line 3699 "dtool/src/cppparser/cppBison.yxx" + case 651: /* const_expr: const_expr '.' name */ +#line 3708 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('.', (yyvsp[-2].u.expr), new CPPExpression((yyvsp[0].u.identifier), current_scope, global_scope, current_lexer)); } -#line 8738 "built/tmp/cppBison.yxx.c" +#line 8750 "built/tmp/cppBison.yxx.c" break; - case 651: /* const_expr: const_expr POINTSAT const_expr */ -#line 3703 "dtool/src/cppparser/cppBison.yxx" + case 652: /* const_expr: const_expr POINTSAT const_expr */ +#line 3712 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(POINTSAT, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8746 "built/tmp/cppBison.yxx.c" +#line 8758 "built/tmp/cppBison.yxx.c" break; - case 652: /* const_expr: '(' const_expr_comma ')' */ -#line 3707 "dtool/src/cppparser/cppBison.yxx" + case 653: /* const_expr: '(' const_expr_comma ')' */ +#line 3716 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = (yyvsp[-1].u.expr); } -#line 8754 "built/tmp/cppBison.yxx.c" +#line 8766 "built/tmp/cppBison.yxx.c" break; - case 653: /* const_operand: INTEGER */ -#line 3714 "dtool/src/cppparser/cppBison.yxx" + case 654: /* const_operand: INTEGER */ +#line 3723 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression((yyvsp[0].u.integer)); } -#line 8762 "built/tmp/cppBison.yxx.c" +#line 8774 "built/tmp/cppBison.yxx.c" break; - case 654: /* const_operand: KW_TRUE */ -#line 3718 "dtool/src/cppparser/cppBison.yxx" + case 655: /* const_operand: KW_TRUE */ +#line 3727 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(true); } -#line 8770 "built/tmp/cppBison.yxx.c" +#line 8782 "built/tmp/cppBison.yxx.c" break; - case 655: /* const_operand: KW_FALSE */ -#line 3722 "dtool/src/cppparser/cppBison.yxx" + case 656: /* const_operand: KW_FALSE */ +#line 3731 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(false); } -#line 8778 "built/tmp/cppBison.yxx.c" +#line 8790 "built/tmp/cppBison.yxx.c" break; - case 656: /* const_operand: CHAR_TOK */ -#line 3726 "dtool/src/cppparser/cppBison.yxx" + case 657: /* const_operand: CHAR_TOK */ +#line 3735 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression((yyvsp[0].u.integer)); } -#line 8786 "built/tmp/cppBison.yxx.c" +#line 8798 "built/tmp/cppBison.yxx.c" break; - case 657: /* const_operand: REAL */ -#line 3730 "dtool/src/cppparser/cppBison.yxx" + case 658: /* const_operand: REAL */ +#line 3739 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression((yyvsp[0].u.real)); } -#line 8794 "built/tmp/cppBison.yxx.c" +#line 8806 "built/tmp/cppBison.yxx.c" break; - case 658: /* const_operand: string_literal */ -#line 3734 "dtool/src/cppparser/cppBison.yxx" + case 659: /* const_operand: string_literal */ +#line 3743 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = (yyvsp[0].u.expr); } -#line 8802 "built/tmp/cppBison.yxx.c" +#line 8814 "built/tmp/cppBison.yxx.c" break; - case 659: /* const_operand: CUSTOM_LITERAL */ -#line 3738 "dtool/src/cppparser/cppBison.yxx" + case 660: /* const_operand: CUSTOM_LITERAL */ +#line 3747 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = (yyvsp[0].u.expr); } -#line 8810 "built/tmp/cppBison.yxx.c" +#line 8822 "built/tmp/cppBison.yxx.c" break; - case 660: /* const_operand: IDENTIFIER */ -#line 3742 "dtool/src/cppparser/cppBison.yxx" + case 661: /* const_operand: IDENTIFIER */ +#line 3751 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression((yyvsp[0].u.identifier), current_scope, global_scope, current_lexer); } -#line 8818 "built/tmp/cppBison.yxx.c" +#line 8830 "built/tmp/cppBison.yxx.c" break; - case 661: /* const_operand: KW_FINAL */ -#line 3746 "dtool/src/cppparser/cppBison.yxx" + case 662: /* const_operand: KW_FINAL */ +#line 3755 "dtool/src/cppparser/cppBison.yxx" { // A variable named "final". C++11 explicitly permits this. CPPIdentifier *ident = new CPPIdentifier("final", (yylsp[0])); (yyval.u.expr) = new CPPExpression(ident, current_scope, global_scope, current_lexer); } -#line 8828 "built/tmp/cppBison.yxx.c" +#line 8840 "built/tmp/cppBison.yxx.c" break; - case 662: /* const_operand: KW_OVERRIDE */ -#line 3752 "dtool/src/cppparser/cppBison.yxx" + case 663: /* const_operand: KW_OVERRIDE */ +#line 3761 "dtool/src/cppparser/cppBison.yxx" { // A variable named "override". C++11 explicitly permits this. CPPIdentifier *ident = new CPPIdentifier("override", (yylsp[0])); (yyval.u.expr) = new CPPExpression(ident, current_scope, global_scope, current_lexer); } -#line 8838 "built/tmp/cppBison.yxx.c" +#line 8850 "built/tmp/cppBison.yxx.c" break; - case 663: /* const_operand: KW_NULLPTR */ -#line 3758 "dtool/src/cppparser/cppBison.yxx" + case 664: /* const_operand: KW_NULLPTR */ +#line 3767 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::get_nullptr()); } -#line 8846 "built/tmp/cppBison.yxx.c" +#line 8858 "built/tmp/cppBison.yxx.c" break; - case 664: /* const_operand: '[' capture_list ']' function_post maybe_trailing_return_type '{' code '}' */ -#line 3762 "dtool/src/cppparser/cppBison.yxx" + case 665: /* const_operand: '[' capture_list ']' function_post maybe_trailing_return_type '{' code '}' */ +#line 3771 "dtool/src/cppparser/cppBison.yxx" { (yyvsp[-6].u.closure_type)->_flags = (yyvsp[-4].u.integer); (yyvsp[-6].u.closure_type)->_return_type = (yyvsp[-3].u.type); (yyval.u.expr) = new CPPExpression(CPPExpression::lambda((yyvsp[-6].u.closure_type))); } -#line 8856 "built/tmp/cppBison.yxx.c" +#line 8868 "built/tmp/cppBison.yxx.c" break; - case 665: /* const_operand: '[' capture_list ']' '(' function_parameter_list ')' function_post maybe_trailing_return_type '{' code '}' */ -#line 3768 "dtool/src/cppparser/cppBison.yxx" + case 666: /* const_operand: '[' capture_list ']' '(' function_parameter_list ')' function_post maybe_trailing_return_type '{' code '}' */ +#line 3777 "dtool/src/cppparser/cppBison.yxx" { (yyvsp[-9].u.closure_type)->_parameters = (yyvsp[-6].u.param_list); (yyvsp[-9].u.closure_type)->_flags = (yyvsp[-4].u.integer); (yyvsp[-9].u.closure_type)->_return_type = (yyvsp[-3].u.type); (yyval.u.expr) = new CPPExpression(CPPExpression::lambda((yyvsp[-9].u.closure_type))); } -#line 8867 "built/tmp/cppBison.yxx.c" +#line 8879 "built/tmp/cppBison.yxx.c" break; - case 666: /* const_operand: KW_HAS_VIRTUAL_DESTRUCTOR '(' full_type ')' */ -#line 3775 "dtool/src/cppparser/cppBison.yxx" + case 667: /* const_operand: KW_HAS_VIRTUAL_DESTRUCTOR '(' full_type ')' */ +#line 3784 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::type_trait(KW_HAS_VIRTUAL_DESTRUCTOR, (yyvsp[-1].u.type))); } -#line 8875 "built/tmp/cppBison.yxx.c" +#line 8887 "built/tmp/cppBison.yxx.c" break; - case 667: /* const_operand: KW_IS_ABSTRACT '(' full_type ')' */ -#line 3779 "dtool/src/cppparser/cppBison.yxx" + case 668: /* const_operand: KW_IS_ABSTRACT '(' full_type ')' */ +#line 3788 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::type_trait(KW_IS_ABSTRACT, (yyvsp[-1].u.type))); } -#line 8883 "built/tmp/cppBison.yxx.c" +#line 8895 "built/tmp/cppBison.yxx.c" break; - case 668: /* const_operand: KW_IS_BASE_OF '(' full_type ',' full_type ')' */ -#line 3783 "dtool/src/cppparser/cppBison.yxx" + case 669: /* const_operand: KW_IS_BASE_OF '(' full_type ',' full_type ')' */ +#line 3792 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::type_trait(KW_IS_CLASS, (yyvsp[-3].u.type), (yyvsp[-1].u.type))); } -#line 8891 "built/tmp/cppBison.yxx.c" +#line 8903 "built/tmp/cppBison.yxx.c" break; - case 669: /* const_operand: KW_IS_CLASS '(' full_type ')' */ -#line 3787 "dtool/src/cppparser/cppBison.yxx" + case 670: /* const_operand: KW_IS_CLASS '(' full_type ')' */ +#line 3796 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::type_trait(KW_IS_CLASS, (yyvsp[-1].u.type))); } -#line 8899 "built/tmp/cppBison.yxx.c" +#line 8911 "built/tmp/cppBison.yxx.c" break; - case 670: /* const_operand: KW_IS_CONSTRUCTIBLE '(' full_type ')' */ -#line 3791 "dtool/src/cppparser/cppBison.yxx" + case 671: /* const_operand: KW_IS_CONSTRUCTIBLE '(' full_type ')' */ +#line 3800 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::type_trait(KW_IS_CONSTRUCTIBLE, (yyvsp[-1].u.type))); } -#line 8907 "built/tmp/cppBison.yxx.c" +#line 8919 "built/tmp/cppBison.yxx.c" break; - case 671: /* const_operand: KW_IS_CONSTRUCTIBLE '(' full_type ',' full_type ')' */ -#line 3795 "dtool/src/cppparser/cppBison.yxx" + case 672: /* const_operand: KW_IS_CONSTRUCTIBLE '(' full_type ',' full_type ')' */ +#line 3804 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::type_trait(KW_IS_CONSTRUCTIBLE, (yyvsp[-3].u.type), (yyvsp[-1].u.type))); } -#line 8915 "built/tmp/cppBison.yxx.c" +#line 8927 "built/tmp/cppBison.yxx.c" break; - case 672: /* const_operand: KW_IS_CONVERTIBLE_TO '(' full_type ',' full_type ')' */ -#line 3799 "dtool/src/cppparser/cppBison.yxx" + case 673: /* const_operand: KW_IS_CONVERTIBLE_TO '(' full_type ',' full_type ')' */ +#line 3808 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::type_trait(KW_IS_CONVERTIBLE_TO, (yyvsp[-3].u.type), (yyvsp[-1].u.type))); } -#line 8923 "built/tmp/cppBison.yxx.c" +#line 8935 "built/tmp/cppBison.yxx.c" break; - case 673: /* const_operand: KW_IS_DESTRUCTIBLE '(' full_type ')' */ -#line 3803 "dtool/src/cppparser/cppBison.yxx" + case 674: /* const_operand: KW_IS_DESTRUCTIBLE '(' full_type ')' */ +#line 3812 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::type_trait(KW_IS_DESTRUCTIBLE, (yyvsp[-1].u.type))); } -#line 8931 "built/tmp/cppBison.yxx.c" +#line 8943 "built/tmp/cppBison.yxx.c" break; - case 674: /* const_operand: KW_IS_EMPTY '(' full_type ')' */ -#line 3807 "dtool/src/cppparser/cppBison.yxx" + case 675: /* const_operand: KW_IS_EMPTY '(' full_type ')' */ +#line 3816 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::type_trait(KW_IS_EMPTY, (yyvsp[-1].u.type))); } -#line 8939 "built/tmp/cppBison.yxx.c" +#line 8951 "built/tmp/cppBison.yxx.c" break; - case 675: /* const_operand: KW_IS_ENUM '(' full_type ')' */ -#line 3811 "dtool/src/cppparser/cppBison.yxx" + case 676: /* const_operand: KW_IS_ENUM '(' full_type ')' */ +#line 3820 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::type_trait(KW_IS_ENUM, (yyvsp[-1].u.type))); } -#line 8947 "built/tmp/cppBison.yxx.c" +#line 8959 "built/tmp/cppBison.yxx.c" break; - case 676: /* const_operand: KW_IS_FINAL '(' full_type ')' */ -#line 3815 "dtool/src/cppparser/cppBison.yxx" + case 677: /* const_operand: KW_IS_FINAL '(' full_type ')' */ +#line 3824 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::type_trait(KW_IS_FINAL, (yyvsp[-1].u.type))); } -#line 8955 "built/tmp/cppBison.yxx.c" +#line 8967 "built/tmp/cppBison.yxx.c" break; - case 677: /* const_operand: KW_IS_FUNDAMENTAL '(' full_type ')' */ -#line 3819 "dtool/src/cppparser/cppBison.yxx" + case 678: /* const_operand: KW_IS_FUNDAMENTAL '(' full_type ')' */ +#line 3828 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::type_trait(KW_IS_FUNDAMENTAL, (yyvsp[-1].u.type))); } -#line 8963 "built/tmp/cppBison.yxx.c" +#line 8975 "built/tmp/cppBison.yxx.c" break; - case 678: /* const_operand: KW_IS_POD '(' full_type ')' */ -#line 3823 "dtool/src/cppparser/cppBison.yxx" + case 679: /* const_operand: KW_IS_POD '(' full_type ')' */ +#line 3832 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::type_trait(KW_IS_POD, (yyvsp[-1].u.type))); } -#line 8971 "built/tmp/cppBison.yxx.c" +#line 8983 "built/tmp/cppBison.yxx.c" break; - case 679: /* const_operand: KW_IS_POLYMORPHIC '(' full_type ')' */ -#line 3827 "dtool/src/cppparser/cppBison.yxx" + case 680: /* const_operand: KW_IS_POLYMORPHIC '(' full_type ')' */ +#line 3836 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::type_trait(KW_IS_POLYMORPHIC, (yyvsp[-1].u.type))); } -#line 8979 "built/tmp/cppBison.yxx.c" +#line 8991 "built/tmp/cppBison.yxx.c" break; - case 680: /* const_operand: KW_IS_STANDARD_LAYOUT '(' full_type ')' */ -#line 3831 "dtool/src/cppparser/cppBison.yxx" + case 681: /* const_operand: KW_IS_STANDARD_LAYOUT '(' full_type ')' */ +#line 3840 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::type_trait(KW_IS_STANDARD_LAYOUT, (yyvsp[-1].u.type))); } -#line 8987 "built/tmp/cppBison.yxx.c" +#line 8999 "built/tmp/cppBison.yxx.c" break; - case 681: /* const_operand: KW_IS_TRIVIAL '(' full_type ')' */ -#line 3835 "dtool/src/cppparser/cppBison.yxx" + case 682: /* const_operand: KW_IS_TRIVIAL '(' full_type ')' */ +#line 3844 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::type_trait(KW_IS_TRIVIAL, (yyvsp[-1].u.type))); } -#line 8995 "built/tmp/cppBison.yxx.c" +#line 9007 "built/tmp/cppBison.yxx.c" break; - case 682: /* const_operand: KW_IS_UNION '(' full_type ')' */ -#line 3839 "dtool/src/cppparser/cppBison.yxx" + case 683: /* const_operand: KW_IS_UNION '(' full_type ')' */ +#line 3848 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::type_trait(KW_IS_UNION, (yyvsp[-1].u.type))); } -#line 9003 "built/tmp/cppBison.yxx.c" +#line 9015 "built/tmp/cppBison.yxx.c" break; - case 683: /* formal_const_expr: formal_const_operand */ -#line 3853 "dtool/src/cppparser/cppBison.yxx" + case 684: /* formal_const_expr: formal_const_operand */ +#line 3862 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = (yyvsp[0].u.expr); } -#line 9011 "built/tmp/cppBison.yxx.c" +#line 9023 "built/tmp/cppBison.yxx.c" break; - case 684: /* formal_const_expr: '(' full_type ')' const_expr */ -#line 3857 "dtool/src/cppparser/cppBison.yxx" + case 685: /* formal_const_expr: '(' full_type ')' const_expr */ +#line 3866 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::typecast_op((yyvsp[-2].u.type), (yyvsp[0].u.expr))); } -#line 9019 "built/tmp/cppBison.yxx.c" +#line 9031 "built/tmp/cppBison.yxx.c" break; - case 685: /* formal_const_expr: KW_STATIC_CAST '<' full_type '>' '(' const_expr_comma ')' */ -#line 3861 "dtool/src/cppparser/cppBison.yxx" + case 686: /* formal_const_expr: KW_STATIC_CAST '<' full_type '>' '(' const_expr_comma ')' */ +#line 3870 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::typecast_op((yyvsp[-4].u.type), (yyvsp[-1].u.expr), CPPExpression::T_static_cast)); } -#line 9027 "built/tmp/cppBison.yxx.c" +#line 9039 "built/tmp/cppBison.yxx.c" break; - case 686: /* formal_const_expr: KW_DYNAMIC_CAST '<' full_type '>' '(' const_expr_comma ')' */ -#line 3865 "dtool/src/cppparser/cppBison.yxx" + case 687: /* formal_const_expr: KW_DYNAMIC_CAST '<' full_type '>' '(' const_expr_comma ')' */ +#line 3874 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::typecast_op((yyvsp[-4].u.type), (yyvsp[-1].u.expr), CPPExpression::T_dynamic_cast)); } -#line 9035 "built/tmp/cppBison.yxx.c" +#line 9047 "built/tmp/cppBison.yxx.c" break; - case 687: /* formal_const_expr: KW_CONST_CAST '<' full_type '>' '(' const_expr_comma ')' */ -#line 3869 "dtool/src/cppparser/cppBison.yxx" + case 688: /* formal_const_expr: KW_CONST_CAST '<' full_type '>' '(' const_expr_comma ')' */ +#line 3878 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::typecast_op((yyvsp[-4].u.type), (yyvsp[-1].u.expr), CPPExpression::T_const_cast)); } -#line 9043 "built/tmp/cppBison.yxx.c" +#line 9055 "built/tmp/cppBison.yxx.c" break; - case 688: /* formal_const_expr: KW_REINTERPRET_CAST '<' full_type '>' '(' const_expr_comma ')' */ -#line 3873 "dtool/src/cppparser/cppBison.yxx" + case 689: /* formal_const_expr: KW_REINTERPRET_CAST '<' full_type '>' '(' const_expr_comma ')' */ +#line 3882 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::typecast_op((yyvsp[-4].u.type), (yyvsp[-1].u.expr), CPPExpression::T_reinterpret_cast)); } -#line 9051 "built/tmp/cppBison.yxx.c" +#line 9063 "built/tmp/cppBison.yxx.c" break; - case 689: /* formal_const_expr: KW_SIZEOF '(' full_type ')' */ -#line 3877 "dtool/src/cppparser/cppBison.yxx" + case 690: /* formal_const_expr: KW_SIZEOF '(' full_type ')' */ +#line 3886 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::sizeof_func((yyvsp[-1].u.type))); } -#line 9059 "built/tmp/cppBison.yxx.c" +#line 9071 "built/tmp/cppBison.yxx.c" break; - case 690: /* formal_const_expr: KW_SIZEOF formal_const_expr */ -#line 3881 "dtool/src/cppparser/cppBison.yxx" + case 691: /* formal_const_expr: KW_SIZEOF formal_const_expr */ +#line 3890 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::sizeof_func((yyvsp[0].u.expr))); } -#line 9067 "built/tmp/cppBison.yxx.c" +#line 9079 "built/tmp/cppBison.yxx.c" break; - case 691: /* formal_const_expr: KW_SIZEOF ELLIPSIS '(' name ')' */ -#line 3885 "dtool/src/cppparser/cppBison.yxx" + case 692: /* formal_const_expr: KW_SIZEOF ELLIPSIS '(' name ')' */ +#line 3894 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::sizeof_ellipsis_func((yyvsp[-1].u.identifier))); } -#line 9075 "built/tmp/cppBison.yxx.c" +#line 9087 "built/tmp/cppBison.yxx.c" break; - case 692: /* formal_const_expr: KW_ALIGNOF '(' full_type ')' */ -#line 3889 "dtool/src/cppparser/cppBison.yxx" + case 693: /* formal_const_expr: KW_ALIGNOF '(' full_type ')' */ +#line 3898 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::alignof_func((yyvsp[-1].u.type))); } -#line 9083 "built/tmp/cppBison.yxx.c" +#line 9095 "built/tmp/cppBison.yxx.c" break; - case 693: /* formal_const_expr: KW_NEW predefined_type */ -#line 3893 "dtool/src/cppparser/cppBison.yxx" + case 694: /* formal_const_expr: KW_NEW predefined_type */ +#line 3902 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::new_op((yyvsp[0].u.type))); } -#line 9091 "built/tmp/cppBison.yxx.c" +#line 9103 "built/tmp/cppBison.yxx.c" break; - case 694: /* formal_const_expr: KW_NEW predefined_type '(' optional_const_expr_comma ')' */ -#line 3897 "dtool/src/cppparser/cppBison.yxx" + case 695: /* formal_const_expr: KW_NEW predefined_type '(' optional_const_expr_comma ')' */ +#line 3906 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::new_op((yyvsp[-3].u.type), (yyvsp[-1].u.expr))); } -#line 9099 "built/tmp/cppBison.yxx.c" +#line 9111 "built/tmp/cppBison.yxx.c" break; - case 695: /* formal_const_expr: KW_TYPEID '(' full_type ')' */ -#line 3901 "dtool/src/cppparser/cppBison.yxx" + case 696: /* formal_const_expr: KW_TYPEID '(' full_type ')' */ +#line 3910 "dtool/src/cppparser/cppBison.yxx" { CPPIdentifier ident(""); ident.add_name("std"); @@ -9110,11 +9122,11 @@ yyreduce: } (yyval.u.expr) = new CPPExpression(CPPExpression::typeid_op((yyvsp[-1].u.type), std_type_info)); } -#line 9114 "built/tmp/cppBison.yxx.c" +#line 9126 "built/tmp/cppBison.yxx.c" break; - case 696: /* formal_const_expr: KW_TYPEID '(' const_expr ')' */ -#line 3912 "dtool/src/cppparser/cppBison.yxx" + case 697: /* formal_const_expr: KW_TYPEID '(' const_expr ')' */ +#line 3921 "dtool/src/cppparser/cppBison.yxx" { CPPIdentifier ident(""); ident.add_name("std"); @@ -9125,409 +9137,409 @@ yyreduce: } (yyval.u.expr) = new CPPExpression(CPPExpression::typeid_op((yyvsp[-1].u.expr), std_type_info)); } -#line 9129 "built/tmp/cppBison.yxx.c" +#line 9141 "built/tmp/cppBison.yxx.c" break; - case 697: /* formal_const_expr: '!' const_expr */ -#line 3923 "dtool/src/cppparser/cppBison.yxx" + case 698: /* formal_const_expr: '!' const_expr */ +#line 3932 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(UNARY_NOT, (yyvsp[0].u.expr)); } -#line 9137 "built/tmp/cppBison.yxx.c" +#line 9149 "built/tmp/cppBison.yxx.c" break; - case 698: /* formal_const_expr: '~' const_expr */ -#line 3927 "dtool/src/cppparser/cppBison.yxx" + case 699: /* formal_const_expr: '~' const_expr */ +#line 3936 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(UNARY_NEGATE, (yyvsp[0].u.expr)); } -#line 9145 "built/tmp/cppBison.yxx.c" +#line 9157 "built/tmp/cppBison.yxx.c" break; - case 699: /* formal_const_expr: '-' const_expr */ -#line 3931 "dtool/src/cppparser/cppBison.yxx" + case 700: /* formal_const_expr: '-' const_expr */ +#line 3940 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(UNARY_MINUS, (yyvsp[0].u.expr)); } -#line 9153 "built/tmp/cppBison.yxx.c" +#line 9165 "built/tmp/cppBison.yxx.c" break; - case 700: /* formal_const_expr: '+' const_expr */ -#line 3935 "dtool/src/cppparser/cppBison.yxx" + case 701: /* formal_const_expr: '+' const_expr */ +#line 3944 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(UNARY_PLUS, (yyvsp[0].u.expr)); } -#line 9161 "built/tmp/cppBison.yxx.c" +#line 9173 "built/tmp/cppBison.yxx.c" break; - case 701: /* formal_const_expr: '&' const_expr */ -#line 3939 "dtool/src/cppparser/cppBison.yxx" + case 702: /* formal_const_expr: '&' const_expr */ +#line 3948 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(UNARY_REF, (yyvsp[0].u.expr)); } -#line 9169 "built/tmp/cppBison.yxx.c" +#line 9181 "built/tmp/cppBison.yxx.c" break; - case 702: /* formal_const_expr: formal_const_expr '*' const_expr */ -#line 3943 "dtool/src/cppparser/cppBison.yxx" + case 703: /* formal_const_expr: formal_const_expr '*' const_expr */ +#line 3952 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('*', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 9177 "built/tmp/cppBison.yxx.c" +#line 9189 "built/tmp/cppBison.yxx.c" break; - case 703: /* formal_const_expr: formal_const_expr '/' const_expr */ -#line 3947 "dtool/src/cppparser/cppBison.yxx" + case 704: /* formal_const_expr: formal_const_expr '/' const_expr */ +#line 3956 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('/', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 9185 "built/tmp/cppBison.yxx.c" +#line 9197 "built/tmp/cppBison.yxx.c" break; - case 704: /* formal_const_expr: formal_const_expr '%' const_expr */ -#line 3951 "dtool/src/cppparser/cppBison.yxx" + case 705: /* formal_const_expr: formal_const_expr '%' const_expr */ +#line 3960 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('%', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 9193 "built/tmp/cppBison.yxx.c" +#line 9205 "built/tmp/cppBison.yxx.c" break; - case 705: /* formal_const_expr: formal_const_expr '+' const_expr */ -#line 3955 "dtool/src/cppparser/cppBison.yxx" + case 706: /* formal_const_expr: formal_const_expr '+' const_expr */ +#line 3964 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('+', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 9201 "built/tmp/cppBison.yxx.c" +#line 9213 "built/tmp/cppBison.yxx.c" break; - case 706: /* formal_const_expr: formal_const_expr '-' const_expr */ -#line 3959 "dtool/src/cppparser/cppBison.yxx" + case 707: /* formal_const_expr: formal_const_expr '-' const_expr */ +#line 3968 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('-', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 9209 "built/tmp/cppBison.yxx.c" +#line 9221 "built/tmp/cppBison.yxx.c" break; - case 707: /* formal_const_expr: formal_const_expr '|' const_expr */ -#line 3963 "dtool/src/cppparser/cppBison.yxx" + case 708: /* formal_const_expr: formal_const_expr '|' const_expr */ +#line 3972 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('|', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 9217 "built/tmp/cppBison.yxx.c" +#line 9229 "built/tmp/cppBison.yxx.c" break; - case 708: /* formal_const_expr: formal_const_expr '^' const_expr */ -#line 3967 "dtool/src/cppparser/cppBison.yxx" + case 709: /* formal_const_expr: formal_const_expr '^' const_expr */ +#line 3976 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('^', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 9225 "built/tmp/cppBison.yxx.c" +#line 9237 "built/tmp/cppBison.yxx.c" break; - case 709: /* formal_const_expr: formal_const_expr '&' const_expr */ -#line 3971 "dtool/src/cppparser/cppBison.yxx" + case 710: /* formal_const_expr: formal_const_expr '&' const_expr */ +#line 3980 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('&', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 9233 "built/tmp/cppBison.yxx.c" +#line 9245 "built/tmp/cppBison.yxx.c" break; - case 710: /* formal_const_expr: formal_const_expr OROR const_expr */ -#line 3975 "dtool/src/cppparser/cppBison.yxx" + case 711: /* formal_const_expr: formal_const_expr OROR const_expr */ +#line 3984 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(OROR, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 9241 "built/tmp/cppBison.yxx.c" +#line 9253 "built/tmp/cppBison.yxx.c" break; - case 711: /* formal_const_expr: formal_const_expr ANDAND const_expr */ -#line 3979 "dtool/src/cppparser/cppBison.yxx" + case 712: /* formal_const_expr: formal_const_expr ANDAND const_expr */ +#line 3988 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(ANDAND, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 9249 "built/tmp/cppBison.yxx.c" +#line 9261 "built/tmp/cppBison.yxx.c" break; - case 712: /* formal_const_expr: formal_const_expr EQCOMPARE const_expr */ -#line 3983 "dtool/src/cppparser/cppBison.yxx" + case 713: /* formal_const_expr: formal_const_expr EQCOMPARE const_expr */ +#line 3992 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(EQCOMPARE, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 9257 "built/tmp/cppBison.yxx.c" +#line 9269 "built/tmp/cppBison.yxx.c" break; - case 713: /* formal_const_expr: formal_const_expr NECOMPARE const_expr */ -#line 3987 "dtool/src/cppparser/cppBison.yxx" + case 714: /* formal_const_expr: formal_const_expr NECOMPARE const_expr */ +#line 3996 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(NECOMPARE, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 9265 "built/tmp/cppBison.yxx.c" +#line 9277 "built/tmp/cppBison.yxx.c" break; - case 714: /* formal_const_expr: formal_const_expr LECOMPARE const_expr */ -#line 3991 "dtool/src/cppparser/cppBison.yxx" + case 715: /* formal_const_expr: formal_const_expr LECOMPARE const_expr */ +#line 4000 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(LECOMPARE, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 9273 "built/tmp/cppBison.yxx.c" +#line 9285 "built/tmp/cppBison.yxx.c" break; - case 715: /* formal_const_expr: formal_const_expr GECOMPARE const_expr */ -#line 3995 "dtool/src/cppparser/cppBison.yxx" + case 716: /* formal_const_expr: formal_const_expr GECOMPARE const_expr */ +#line 4004 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(GECOMPARE, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 9281 "built/tmp/cppBison.yxx.c" +#line 9293 "built/tmp/cppBison.yxx.c" break; - case 716: /* formal_const_expr: formal_const_expr '<' const_expr */ -#line 3999 "dtool/src/cppparser/cppBison.yxx" + case 717: /* formal_const_expr: formal_const_expr '<' const_expr */ +#line 4008 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('<', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 9289 "built/tmp/cppBison.yxx.c" +#line 9301 "built/tmp/cppBison.yxx.c" break; - case 717: /* formal_const_expr: formal_const_expr '>' const_expr */ -#line 4003 "dtool/src/cppparser/cppBison.yxx" + case 718: /* formal_const_expr: formal_const_expr '>' const_expr */ +#line 4012 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('>', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 9297 "built/tmp/cppBison.yxx.c" +#line 9309 "built/tmp/cppBison.yxx.c" break; - case 718: /* formal_const_expr: formal_const_expr LSHIFT const_expr */ -#line 4007 "dtool/src/cppparser/cppBison.yxx" + case 719: /* formal_const_expr: formal_const_expr LSHIFT const_expr */ +#line 4016 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(LSHIFT, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 9305 "built/tmp/cppBison.yxx.c" +#line 9317 "built/tmp/cppBison.yxx.c" break; - case 719: /* formal_const_expr: formal_const_expr RSHIFT const_expr */ -#line 4011 "dtool/src/cppparser/cppBison.yxx" + case 720: /* formal_const_expr: formal_const_expr RSHIFT const_expr */ +#line 4020 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(RSHIFT, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 9313 "built/tmp/cppBison.yxx.c" +#line 9325 "built/tmp/cppBison.yxx.c" break; - case 720: /* formal_const_expr: formal_const_expr '?' const_expr ':' const_expr */ -#line 4015 "dtool/src/cppparser/cppBison.yxx" + case 721: /* formal_const_expr: formal_const_expr '?' const_expr ':' const_expr */ +#line 4024 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('?', (yyvsp[-4].u.expr), (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 9321 "built/tmp/cppBison.yxx.c" +#line 9333 "built/tmp/cppBison.yxx.c" break; - case 721: /* formal_const_expr: formal_const_expr '[' const_expr ']' */ -#line 4019 "dtool/src/cppparser/cppBison.yxx" + case 722: /* formal_const_expr: formal_const_expr '[' const_expr ']' */ +#line 4028 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('[', (yyvsp[-3].u.expr), (yyvsp[-1].u.expr)); } -#line 9329 "built/tmp/cppBison.yxx.c" +#line 9341 "built/tmp/cppBison.yxx.c" break; - case 722: /* formal_const_expr: formal_const_expr '(' const_expr_comma ')' */ -#line 4023 "dtool/src/cppparser/cppBison.yxx" + case 723: /* formal_const_expr: formal_const_expr '(' const_expr_comma ')' */ +#line 4032 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('f', (yyvsp[-3].u.expr), (yyvsp[-1].u.expr)); } -#line 9337 "built/tmp/cppBison.yxx.c" +#line 9349 "built/tmp/cppBison.yxx.c" break; - case 723: /* formal_const_expr: formal_const_expr '(' ')' */ -#line 4027 "dtool/src/cppparser/cppBison.yxx" + case 724: /* formal_const_expr: formal_const_expr '(' ')' */ +#line 4036 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('f', (yyvsp[-2].u.expr)); } -#line 9345 "built/tmp/cppBison.yxx.c" +#line 9357 "built/tmp/cppBison.yxx.c" break; - case 724: /* formal_const_expr: formal_const_expr '.' name */ -#line 4031 "dtool/src/cppparser/cppBison.yxx" + case 725: /* formal_const_expr: formal_const_expr '.' name */ +#line 4040 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression('.', (yyvsp[-2].u.expr), new CPPExpression((yyvsp[0].u.identifier), current_scope, global_scope, current_lexer)); } -#line 9353 "built/tmp/cppBison.yxx.c" +#line 9365 "built/tmp/cppBison.yxx.c" break; - case 725: /* formal_const_expr: formal_const_expr POINTSAT const_expr */ -#line 4035 "dtool/src/cppparser/cppBison.yxx" + case 726: /* formal_const_expr: formal_const_expr POINTSAT const_expr */ +#line 4044 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(POINTSAT, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 9361 "built/tmp/cppBison.yxx.c" +#line 9373 "built/tmp/cppBison.yxx.c" break; - case 726: /* formal_const_expr: '(' const_expr_comma ')' */ -#line 4039 "dtool/src/cppparser/cppBison.yxx" + case 727: /* formal_const_expr: '(' const_expr_comma ')' */ +#line 4048 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = (yyvsp[-1].u.expr); } -#line 9369 "built/tmp/cppBison.yxx.c" +#line 9381 "built/tmp/cppBison.yxx.c" break; - case 727: /* formal_const_operand: INTEGER */ -#line 4046 "dtool/src/cppparser/cppBison.yxx" + case 728: /* formal_const_operand: INTEGER */ +#line 4055 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression((yyvsp[0].u.integer)); } -#line 9377 "built/tmp/cppBison.yxx.c" +#line 9389 "built/tmp/cppBison.yxx.c" break; - case 728: /* formal_const_operand: KW_TRUE */ -#line 4050 "dtool/src/cppparser/cppBison.yxx" + case 729: /* formal_const_operand: KW_TRUE */ +#line 4059 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(true); } -#line 9385 "built/tmp/cppBison.yxx.c" +#line 9397 "built/tmp/cppBison.yxx.c" break; - case 729: /* formal_const_operand: KW_FALSE */ -#line 4054 "dtool/src/cppparser/cppBison.yxx" + case 730: /* formal_const_operand: KW_FALSE */ +#line 4063 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(false); } -#line 9393 "built/tmp/cppBison.yxx.c" +#line 9405 "built/tmp/cppBison.yxx.c" break; - case 730: /* formal_const_operand: CHAR_TOK */ -#line 4058 "dtool/src/cppparser/cppBison.yxx" + case 731: /* formal_const_operand: CHAR_TOK */ +#line 4067 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression((yyvsp[0].u.integer)); } -#line 9401 "built/tmp/cppBison.yxx.c" +#line 9413 "built/tmp/cppBison.yxx.c" break; - case 731: /* formal_const_operand: REAL */ -#line 4062 "dtool/src/cppparser/cppBison.yxx" + case 732: /* formal_const_operand: REAL */ +#line 4071 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression((yyvsp[0].u.real)); } -#line 9409 "built/tmp/cppBison.yxx.c" +#line 9421 "built/tmp/cppBison.yxx.c" break; - case 732: /* formal_const_operand: string_literal */ -#line 4066 "dtool/src/cppparser/cppBison.yxx" + case 733: /* formal_const_operand: string_literal */ +#line 4075 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = (yyvsp[0].u.expr); } -#line 9417 "built/tmp/cppBison.yxx.c" +#line 9429 "built/tmp/cppBison.yxx.c" break; - case 733: /* formal_const_operand: CUSTOM_LITERAL */ -#line 4070 "dtool/src/cppparser/cppBison.yxx" + case 734: /* formal_const_operand: CUSTOM_LITERAL */ +#line 4079 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = (yyvsp[0].u.expr); } -#line 9425 "built/tmp/cppBison.yxx.c" +#line 9437 "built/tmp/cppBison.yxx.c" break; - case 734: /* formal_const_operand: IDENTIFIER */ -#line 4074 "dtool/src/cppparser/cppBison.yxx" + case 735: /* formal_const_operand: IDENTIFIER */ +#line 4083 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression((yyvsp[0].u.identifier), current_scope, global_scope, current_lexer); } -#line 9433 "built/tmp/cppBison.yxx.c" +#line 9445 "built/tmp/cppBison.yxx.c" break; - case 735: /* formal_const_operand: KW_FINAL */ -#line 4078 "dtool/src/cppparser/cppBison.yxx" + case 736: /* formal_const_operand: KW_FINAL */ +#line 4087 "dtool/src/cppparser/cppBison.yxx" { // A variable named "final". C++11 explicitly permits this. CPPIdentifier *ident = new CPPIdentifier("final", (yylsp[0])); (yyval.u.expr) = new CPPExpression(ident, current_scope, global_scope, current_lexer); } -#line 9443 "built/tmp/cppBison.yxx.c" +#line 9455 "built/tmp/cppBison.yxx.c" break; - case 736: /* formal_const_operand: KW_OVERRIDE */ -#line 4084 "dtool/src/cppparser/cppBison.yxx" + case 737: /* formal_const_operand: KW_OVERRIDE */ +#line 4093 "dtool/src/cppparser/cppBison.yxx" { // A variable named "override". C++11 explicitly permits this. CPPIdentifier *ident = new CPPIdentifier("override", (yylsp[0])); (yyval.u.expr) = new CPPExpression(ident, current_scope, global_scope, current_lexer); } -#line 9453 "built/tmp/cppBison.yxx.c" +#line 9465 "built/tmp/cppBison.yxx.c" break; - case 737: /* formal_const_operand: KW_NULLPTR */ -#line 4090 "dtool/src/cppparser/cppBison.yxx" + case 738: /* formal_const_operand: KW_NULLPTR */ +#line 4099 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression(CPPExpression::get_nullptr()); } -#line 9461 "built/tmp/cppBison.yxx.c" +#line 9473 "built/tmp/cppBison.yxx.c" break; - case 738: /* capture_list: empty */ -#line 4098 "dtool/src/cppparser/cppBison.yxx" + case 739: /* capture_list: empty */ +#line 4107 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.closure_type) = new CPPClosureType(); } -#line 9469 "built/tmp/cppBison.yxx.c" +#line 9481 "built/tmp/cppBison.yxx.c" break; - case 739: /* capture_list: '=' */ -#line 4102 "dtool/src/cppparser/cppBison.yxx" + case 740: /* capture_list: '=' */ +#line 4111 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.closure_type) = new CPPClosureType(CPPClosureType::CT_by_value); } -#line 9477 "built/tmp/cppBison.yxx.c" +#line 9489 "built/tmp/cppBison.yxx.c" break; - case 740: /* capture_list: '&' */ -#line 4106 "dtool/src/cppparser/cppBison.yxx" + case 741: /* capture_list: '&' */ +#line 4115 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.closure_type) = new CPPClosureType(CPPClosureType::CT_by_reference); } -#line 9485 "built/tmp/cppBison.yxx.c" +#line 9497 "built/tmp/cppBison.yxx.c" break; - case 741: /* capture_list: capture maybe_initialize */ -#line 4110 "dtool/src/cppparser/cppBison.yxx" + case 742: /* capture_list: capture maybe_initialize */ +#line 4119 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.closure_type) = new CPPClosureType(); (yyvsp[-1].u.capture)->_initializer = (yyvsp[0].u.expr); (yyval.u.closure_type)->_captures.push_back(*(yyvsp[-1].u.capture)); delete (yyvsp[-1].u.capture); } -#line 9496 "built/tmp/cppBison.yxx.c" +#line 9508 "built/tmp/cppBison.yxx.c" break; - case 742: /* capture_list: capture_list ',' capture maybe_initialize */ -#line 4117 "dtool/src/cppparser/cppBison.yxx" + case 743: /* capture_list: capture_list ',' capture maybe_initialize */ +#line 4126 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.closure_type) = (yyvsp[-3].u.closure_type); (yyvsp[-1].u.capture)->_initializer = (yyvsp[0].u.expr); (yyval.u.closure_type)->_captures.push_back(*(yyvsp[-1].u.capture)); delete (yyvsp[-1].u.capture); } -#line 9507 "built/tmp/cppBison.yxx.c" +#line 9519 "built/tmp/cppBison.yxx.c" break; - case 743: /* capture: '&' name */ -#line 4127 "dtool/src/cppparser/cppBison.yxx" + case 744: /* capture: '&' name */ +#line 4136 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.capture) = new CPPClosureType::Capture; (yyval.u.capture)->_name = (yyvsp[0].u.identifier)->get_simple_name(); (yyval.u.capture)->_type = CPPClosureType::CT_by_reference; } -#line 9517 "built/tmp/cppBison.yxx.c" +#line 9529 "built/tmp/cppBison.yxx.c" break; - case 744: /* capture: '&' name ELLIPSIS */ -#line 4133 "dtool/src/cppparser/cppBison.yxx" + case 745: /* capture: '&' name ELLIPSIS */ +#line 4142 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.capture) = new CPPClosureType::Capture; (yyval.u.capture)->_name = (yyvsp[-1].u.identifier)->get_simple_name(); (yyval.u.capture)->_type = CPPClosureType::CT_by_reference; } -#line 9527 "built/tmp/cppBison.yxx.c" +#line 9539 "built/tmp/cppBison.yxx.c" break; - case 745: /* capture: name */ -#line 4139 "dtool/src/cppparser/cppBison.yxx" + case 746: /* capture: name */ +#line 4148 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.capture) = new CPPClosureType::Capture; (yyval.u.capture)->_name = (yyvsp[0].u.identifier)->get_simple_name(); @@ -9537,11 +9549,11 @@ yyreduce: (yyval.u.capture)->_type = CPPClosureType::CT_by_value; } } -#line 9541 "built/tmp/cppBison.yxx.c" +#line 9553 "built/tmp/cppBison.yxx.c" break; - case 746: /* capture: '*' name */ -#line 4149 "dtool/src/cppparser/cppBison.yxx" + case 747: /* capture: '*' name */ +#line 4158 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.capture) = new CPPClosureType::Capture; (yyval.u.capture)->_name = (yyvsp[0].u.identifier)->get_simple_name(); @@ -9550,11 +9562,11 @@ yyreduce: yywarning("only capture name 'this' may be preceded by an asterisk", (yylsp[0])); } } -#line 9554 "built/tmp/cppBison.yxx.c" +#line 9566 "built/tmp/cppBison.yxx.c" break; - case 747: /* class_derivation_name: name */ -#line 4161 "dtool/src/cppparser/cppBison.yxx" + case 748: /* class_derivation_name: name */ +#line 4170 "dtool/src/cppparser/cppBison.yxx" { CPPType *type = (yyvsp[0].u.identifier)->find_type(current_scope, global_scope, true); if (type == nullptr) { @@ -9562,177 +9574,177 @@ yyreduce: } (yyval.u.type) = type; } -#line 9566 "built/tmp/cppBison.yxx.c" +#line 9578 "built/tmp/cppBison.yxx.c" break; - case 748: /* class_derivation_name: KW_TYPENAME name */ -#line 4169 "dtool/src/cppparser/cppBison.yxx" + case 749: /* class_derivation_name: KW_TYPENAME name */ +#line 4178 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.type) = CPPType::new_type(new CPPTBDType((yyvsp[0].u.identifier))); } -#line 9574 "built/tmp/cppBison.yxx.c" +#line 9586 "built/tmp/cppBison.yxx.c" break; - case 749: /* class_derivation_name: name ELLIPSIS */ -#line 4173 "dtool/src/cppparser/cppBison.yxx" + case 750: /* class_derivation_name: name ELLIPSIS */ +#line 4182 "dtool/src/cppparser/cppBison.yxx" { CPPClassTemplateParameter *ctp = new CPPClassTemplateParameter((yyvsp[-1].u.identifier)); ctp->_packed = true; (yyval.u.type) = CPPType::new_type(ctp); } -#line 9584 "built/tmp/cppBison.yxx.c" +#line 9596 "built/tmp/cppBison.yxx.c" break; - case 750: /* name: IDENTIFIER */ -#line 4203 "dtool/src/cppparser/cppBison.yxx" + case 751: /* name: IDENTIFIER */ +#line 4212 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.identifier) = (yyvsp[0].u.identifier); } -#line 9592 "built/tmp/cppBison.yxx.c" +#line 9604 "built/tmp/cppBison.yxx.c" break; - case 751: /* name: TYPENAME_IDENTIFIER */ -#line 4207 "dtool/src/cppparser/cppBison.yxx" + case 752: /* name: TYPENAME_IDENTIFIER */ +#line 4216 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.identifier) = (yyvsp[0].u.identifier); } -#line 9600 "built/tmp/cppBison.yxx.c" +#line 9612 "built/tmp/cppBison.yxx.c" break; - case 752: /* name: TYPEPACK_IDENTIFIER */ -#line 4211 "dtool/src/cppparser/cppBison.yxx" + case 753: /* name: TYPEPACK_IDENTIFIER */ +#line 4220 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.identifier) = (yyvsp[0].u.identifier); } -#line 9608 "built/tmp/cppBison.yxx.c" +#line 9620 "built/tmp/cppBison.yxx.c" break; - case 753: /* name: KW_FINAL */ -#line 4215 "dtool/src/cppparser/cppBison.yxx" + case 754: /* name: KW_FINAL */ +#line 4224 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.identifier) = new CPPIdentifier("final", (yylsp[0])); } -#line 9616 "built/tmp/cppBison.yxx.c" +#line 9628 "built/tmp/cppBison.yxx.c" break; - case 754: /* name: KW_OVERRIDE */ -#line 4219 "dtool/src/cppparser/cppBison.yxx" + case 755: /* name: KW_OVERRIDE */ +#line 4228 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.identifier) = new CPPIdentifier("override", (yylsp[0])); } -#line 9624 "built/tmp/cppBison.yxx.c" +#line 9636 "built/tmp/cppBison.yxx.c" break; - case 755: /* name: KW_SIGNED */ -#line 4223 "dtool/src/cppparser/cppBison.yxx" + case 756: /* name: KW_SIGNED */ +#line 4232 "dtool/src/cppparser/cppBison.yxx" { // This is not a keyword in Python, so it is useful to be able to use this // in MAKE_PROPERTY definitions, etc. (yyval.u.identifier) = new CPPIdentifier("signed", (yylsp[0])); } -#line 9634 "built/tmp/cppBison.yxx.c" +#line 9646 "built/tmp/cppBison.yxx.c" break; - case 756: /* name: KW_FLOAT */ -#line 4229 "dtool/src/cppparser/cppBison.yxx" + case 757: /* name: KW_FLOAT */ +#line 4238 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.identifier) = new CPPIdentifier("float", (yylsp[0])); } -#line 9642 "built/tmp/cppBison.yxx.c" +#line 9654 "built/tmp/cppBison.yxx.c" break; - case 757: /* name: KW_PUBLIC */ -#line 4233 "dtool/src/cppparser/cppBison.yxx" + case 758: /* name: KW_PUBLIC */ +#line 4242 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.identifier) = new CPPIdentifier("public", (yylsp[0])); } -#line 9650 "built/tmp/cppBison.yxx.c" +#line 9662 "built/tmp/cppBison.yxx.c" break; - case 758: /* name: KW_PRIVATE */ -#line 4237 "dtool/src/cppparser/cppBison.yxx" + case 759: /* name: KW_PRIVATE */ +#line 4246 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.identifier) = new CPPIdentifier("private", (yylsp[0])); } -#line 9658 "built/tmp/cppBison.yxx.c" +#line 9670 "built/tmp/cppBison.yxx.c" break; - case 759: /* name: KW_STATIC */ -#line 4241 "dtool/src/cppparser/cppBison.yxx" + case 760: /* name: KW_STATIC */ +#line 4250 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.identifier) = new CPPIdentifier("static", (yylsp[0])); } -#line 9666 "built/tmp/cppBison.yxx.c" +#line 9678 "built/tmp/cppBison.yxx.c" break; - case 760: /* name: KW_DEFAULT */ -#line 4245 "dtool/src/cppparser/cppBison.yxx" + case 761: /* name: KW_DEFAULT */ +#line 4254 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.identifier) = new CPPIdentifier("default", (yylsp[0])); } -#line 9674 "built/tmp/cppBison.yxx.c" +#line 9686 "built/tmp/cppBison.yxx.c" break; - case 761: /* name_no_final: IDENTIFIER */ -#line 4256 "dtool/src/cppparser/cppBison.yxx" + case 762: /* name_no_final: IDENTIFIER */ +#line 4265 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.identifier) = (yyvsp[0].u.identifier); } -#line 9682 "built/tmp/cppBison.yxx.c" +#line 9694 "built/tmp/cppBison.yxx.c" break; - case 762: /* name_no_final: TYPENAME_IDENTIFIER */ -#line 4260 "dtool/src/cppparser/cppBison.yxx" + case 763: /* name_no_final: TYPENAME_IDENTIFIER */ +#line 4269 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.identifier) = (yyvsp[0].u.identifier); } -#line 9690 "built/tmp/cppBison.yxx.c" +#line 9702 "built/tmp/cppBison.yxx.c" break; - case 763: /* name_no_final: TYPEPACK_IDENTIFIER */ -#line 4264 "dtool/src/cppparser/cppBison.yxx" + case 764: /* name_no_final: TYPEPACK_IDENTIFIER */ +#line 4273 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.identifier) = (yyvsp[0].u.identifier); } -#line 9698 "built/tmp/cppBison.yxx.c" +#line 9710 "built/tmp/cppBison.yxx.c" break; - case 764: /* name_no_final: KW_OVERRIDE */ -#line 4268 "dtool/src/cppparser/cppBison.yxx" + case 765: /* name_no_final: KW_OVERRIDE */ +#line 4277 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.identifier) = new CPPIdentifier("override", (yylsp[0])); } -#line 9706 "built/tmp/cppBison.yxx.c" +#line 9718 "built/tmp/cppBison.yxx.c" break; - case 765: /* string_literal: SIMPLE_STRING */ -#line 4276 "dtool/src/cppparser/cppBison.yxx" + case 766: /* string_literal: SIMPLE_STRING */ +#line 4285 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = new CPPExpression((yyvsp[0].str)); } -#line 9714 "built/tmp/cppBison.yxx.c" +#line 9726 "built/tmp/cppBison.yxx.c" break; - case 766: /* string_literal: STRING_LITERAL */ -#line 4280 "dtool/src/cppparser/cppBison.yxx" + case 767: /* string_literal: STRING_LITERAL */ +#line 4289 "dtool/src/cppparser/cppBison.yxx" { (yyval.u.expr) = (yyvsp[0].u.expr); } -#line 9722 "built/tmp/cppBison.yxx.c" +#line 9734 "built/tmp/cppBison.yxx.c" break; - case 767: /* string_literal: string_literal SIMPLE_STRING */ -#line 4284 "dtool/src/cppparser/cppBison.yxx" + case 768: /* string_literal: string_literal SIMPLE_STRING */ +#line 4293 "dtool/src/cppparser/cppBison.yxx" { // The right string takes on the literal type of the left. (yyval.u.expr) = (yyvsp[-1].u.expr); (yyval.u.expr)->_str += (yyvsp[0].str); } -#line 9732 "built/tmp/cppBison.yxx.c" +#line 9744 "built/tmp/cppBison.yxx.c" break; - case 768: /* string_literal: string_literal STRING_LITERAL */ -#line 4290 "dtool/src/cppparser/cppBison.yxx" + case 769: /* string_literal: string_literal STRING_LITERAL */ +#line 4299 "dtool/src/cppparser/cppBison.yxx" { // We have to check that the two literal types match up. (yyval.u.expr) = (yyvsp[-1].u.expr); @@ -9741,11 +9753,11 @@ yyreduce: } (yyval.u.expr)->_str += (yyvsp[0].u.expr)->_str; } -#line 9745 "built/tmp/cppBison.yxx.c" +#line 9757 "built/tmp/cppBison.yxx.c" break; -#line 9749 "built/tmp/cppBison.yxx.c" +#line 9761 "built/tmp/cppBison.yxx.c" default: break; } diff --git a/dtool/src/cppparser/cppBison.yxx b/dtool/src/cppparser/cppBison.yxx index 72f90f055f..c1567fb181 100644 --- a/dtool/src/cppparser/cppBison.yxx +++ b/dtool/src/cppparser/cppBison.yxx @@ -2896,8 +2896,17 @@ base_specification: ; enum: - enum_decl '{' enum_body '}' + enum_decl { + if (current_enum->_scope != nullptr) { + push_scope(current_enum->_scope); + } +} + '{' enum_body '}' +{ + if (current_enum->_scope != nullptr) { + pop_scope(); + } $$ = current_enum; current_enum = nullptr; } From 1cb2554c487434bae161dfdeca4a82f1ec9c41c2 Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 2 Aug 2023 16:36:04 +0200 Subject: [PATCH 49/84] tests: Test that tools run when testing wheels Intended to catch issues like #1504 --- tests/test_tools.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 tests/test_tools.py diff --git a/tests/test_tools.py b/tests/test_tools.py new file mode 100644 index 0000000000..a6dfa6d441 --- /dev/null +++ b/tests/test_tools.py @@ -0,0 +1,19 @@ +import pytest +import subprocess + +# Currently only works when Panda was installed from wheel +panda3d_tools = pytest.importorskip("panda3d_tools") + + +@pytest.mark.skipif(not hasattr(panda3d_tools, 'bam_info'), + reason="requires bam-info") +def test_bam_info(): + output = subprocess.check_output(['bam-info', '-h'], stderr=subprocess.STDOUT).strip() + assert output.startswith(b"This program scans one or more Bam files") + + +@pytest.mark.skipif(not hasattr(panda3d_tools, 'pzip'), + reason="requires pzip") +def test_pzip(): + output = subprocess.check_output(['pzip', '-h'], stderr=subprocess.STDOUT).strip() + assert output.startswith(b"This program compresses the named file") From 45375408203ec12ce5a4a0b3d2c4c6cd050c70e3 Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 2 Aug 2023 16:45:40 +0200 Subject: [PATCH 50/84] tests: Look for tools in proper location without relying on PATH --- tests/test_tools.py | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/tests/test_tools.py b/tests/test_tools.py index a6dfa6d441..81a65e008e 100644 --- a/tests/test_tools.py +++ b/tests/test_tools.py @@ -1,19 +1,30 @@ import pytest import subprocess +import sys +import os # Currently only works when Panda was installed from wheel panda3d_tools = pytest.importorskip("panda3d_tools") +def get_tool(name): + if sys.platform == 'win32': + name += '.exe' + + tools_dir = os.path.dirname(panda3d_tools.__file__) + path = os.path.join(tools_dir, name) + if not os.path.isfile(path): + pytest.skip(name + ' not found') + + return path + -@pytest.mark.skipif(not hasattr(panda3d_tools, 'bam_info'), - reason="requires bam-info") def test_bam_info(): - output = subprocess.check_output(['bam-info', '-h'], stderr=subprocess.STDOUT).strip() + path = get_tool('bam-info') + output = subprocess.check_output([path, '-h'], stderr=subprocess.STDOUT).strip() assert output.startswith(b"This program scans one or more Bam files") -@pytest.mark.skipif(not hasattr(panda3d_tools, 'pzip'), - reason="requires pzip") def test_pzip(): - output = subprocess.check_output(['pzip', '-h'], stderr=subprocess.STDOUT).strip() + path = get_tool('pzip') + output = subprocess.check_output([path, '-h'], stderr=subprocess.STDOUT).strip() assert output.startswith(b"This program compresses the named file") From 3f3819e7faf9f9d26095506a3ffb748f0bba80cf Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 3 Aug 2023 13:19:53 +0200 Subject: [PATCH 51/84] tests: Further expand on tools tests --- tests/test_tools.py | 45 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 39 insertions(+), 6 deletions(-) diff --git a/tests/test_tools.py b/tests/test_tools.py index 81a65e008e..b6b187ebc2 100644 --- a/tests/test_tools.py +++ b/tests/test_tools.py @@ -2,15 +2,24 @@ import pytest import subprocess import sys import os +import tempfile +import panda3d + +try: + panda3d_tools = pytest.importorskip("panda3d_tools") +except: + panda3d_tools = None -# Currently only works when Panda was installed from wheel -panda3d_tools = pytest.importorskip("panda3d_tools") def get_tool(name): if sys.platform == 'win32': name += '.exe' - tools_dir = os.path.dirname(panda3d_tools.__file__) + if panda3d_tools: + tools_dir = os.path.dirname(panda3d_tools.__file__) + else: + tools_dir = os.path.join(os.path.dirname(os.path.dirname(panda3d.__file__)), 'bin') + path = os.path.join(tools_dir, name) if not os.path.isfile(path): pytest.skip(name + ' not found') @@ -24,7 +33,31 @@ def test_bam_info(): assert output.startswith(b"This program scans one or more Bam files") -def test_pzip(): - path = get_tool('pzip') +def test_egg_trans(): + path = get_tool('egg-trans') output = subprocess.check_output([path, '-h'], stderr=subprocess.STDOUT).strip() - assert output.startswith(b"This program compresses the named file") + assert output.startswith(b"egg-trans reads an egg file and writes") + + +def test_pzip(): + data = b'test \000 data' + + try: + file = tempfile.NamedTemporaryFile(suffix='.bin', delete=False) + file.write(data) + file.close() + + path = get_tool('pzip') + subprocess.check_output([path, file.name]) + + zlib = pytest.importorskip('zlib') + + with open(file.name + '.pz', 'rb') as pz: + assert zlib.decompress(pz.read(), 32 + 15, 4096) == data + + finally: + if os.path.isfile(file.name): + os.remove(file.name) + + if os.path.isfile(file.name + '.pz'): + os.remove(file.name + '.pz') From 596ff9ddb8ca451d52b4dab99e0127104d7eec74 Mon Sep 17 00:00:00 2001 From: Disyer Date: Thu, 3 Aug 2023 21:35:33 +0300 Subject: [PATCH 52/84] python: Remove usage of private _PyUnicode C API calls --- dtool/src/interrogatedb/py_panda.cxx | 6 ++---- panda/src/pgraph/renderState_ext.cxx | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/dtool/src/interrogatedb/py_panda.cxx b/dtool/src/interrogatedb/py_panda.cxx index 71572d7b78..f8c3bb194c 100644 --- a/dtool/src/interrogatedb/py_panda.cxx +++ b/dtool/src/interrogatedb/py_panda.cxx @@ -623,7 +623,7 @@ PyObject *Dtool_PyModuleInitHelper(const LibraryDef *defs[], const char *modulen if (main_module == NULL) { interrogatedb_cat.warning() << "Unable to import __main__\n"; } - + // Extract the __file__ attribute, if present. Filename main_dir; PyObject *file_attr = nullptr; @@ -784,9 +784,7 @@ bool Dtool_ExtractArg(PyObject **result, PyObject *args, PyObject *kwds, if (kwds != nullptr && PyDict_GET_SIZE(kwds) == 1 && PyDict_Next(kwds, &ppos, &key, result)) { // We got the item, we just need to make sure that it had the right key. -#if PY_VERSION_HEX >= 0x03060000 - return PyUnicode_CheckExact(key) && _PyUnicode_EqualToASCIIString(key, keyword); -#elif PY_MAJOR_VERSION >= 3 +#if PY_MAJOR_VERSION >= 3 return PyUnicode_CheckExact(key) && PyUnicode_CompareWithASCIIString(key, keyword) == 0; #else return PyString_CheckExact(key) && strcmp(PyString_AS_STRING(key), keyword) == 0; diff --git a/panda/src/pgraph/renderState_ext.cxx b/panda/src/pgraph/renderState_ext.cxx index 931edbe8a6..c7a9fe0672 100644 --- a/panda/src/pgraph/renderState_ext.cxx +++ b/panda/src/pgraph/renderState_ext.cxx @@ -39,7 +39,7 @@ make(PyObject *args, PyObject *kwds) { } // We got the item, we just need to make sure that it had the right key. - if (!PyUnicode_CheckExact(key) || !_PyUnicode_EqualToASCIIString(key, "override")) { + if (!PyUnicode_CheckExact(key) || PyUnicode_CompareWithASCIIString(key, "override") != 0) { Dtool_Raise_TypeError("RenderState.make() received an unexpected keyword argument"); return nullptr; } From 3160d7f3e98f5d4c746b0f2984fdd31a3fd6df84 Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 3 Aug 2023 22:21:42 +0200 Subject: [PATCH 53/84] py_panda: Don't use _PyUnicode_EqualToASCIIString in Python 3.13+ See #1523 --- dtool/src/interrogatedb/py_panda.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dtool/src/interrogatedb/py_panda.cxx b/dtool/src/interrogatedb/py_panda.cxx index 6190b6e642..bfd871b096 100644 --- a/dtool/src/interrogatedb/py_panda.cxx +++ b/dtool/src/interrogatedb/py_panda.cxx @@ -801,7 +801,7 @@ bool Dtool_ExtractArg(PyObject **result, PyObject *args, PyObject *kwds, if (kwds != nullptr && PyDict_GET_SIZE(kwds) == 1 && PyDict_Next(kwds, &ppos, &key, result)) { // We got the item, we just need to make sure that it had the right key. -#if PY_VERSION_HEX >= 0x03060000 +#if PY_VERSION_HEX >= 0x03060000 && PY_VERSION_HEX < 0x030D0000 return PyUnicode_CheckExact(key) && _PyUnicode_EqualToASCIIString(key, keyword); #elif PY_MAJOR_VERSION >= 3 return PyUnicode_CheckExact(key) && PyUnicode_CompareWithASCIIString(key, keyword) == 0; From c08353dea7ed9cf9bff8c0b78854da14d3e91407 Mon Sep 17 00:00:00 2001 From: rdb Date: Fri, 4 Aug 2023 13:26:52 +0200 Subject: [PATCH 54/84] showbase: Don't disable Windows mesasge loop with multi-threaded pipeline Fixes half of #1494 --- direct/src/showbase/ShowBase.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/direct/src/showbase/ShowBase.py b/direct/src/showbase/ShowBase.py index 8e39f7b6ab..7db064fbea 100644 --- a/direct/src/showbase/ShowBase.py +++ b/direct/src/showbase/ShowBase.py @@ -3219,8 +3219,9 @@ class ShowBase(DirectObject.DirectObject): init_app_for_gui() # Disable the Windows message loop, since Tcl wants to handle this all - # on its own. - ConfigVariableBool('disable-message-loop', False).value = True + # on its own, except if the Panda window is on a separate thread. + if self.graphicsEngine.getThreadingModel().getDrawStage() == 0: + ConfigVariableBool('disable-message-loop', False).value = True if ConfigVariableBool('tk-main-loop', True): # Put Tkinter in charge of the main loop. It really From 360bf20933a41e35920036ce2b6c47dcabd656df Mon Sep 17 00:00:00 2001 From: rdb Date: Fri, 4 Aug 2023 14:02:13 +0200 Subject: [PATCH 55/84] dcparser: Fix segfault with nested struct or switch Fixes #1499 --- direct/src/dcparser/dcParser.cxx.prebuilt | 2314 ++++++++++----------- direct/src/dcparser/dcParser.h.prebuilt | 106 +- direct/src/dcparser/dcParser.yxx | 6 +- 3 files changed, 1165 insertions(+), 1261 deletions(-) diff --git a/direct/src/dcparser/dcParser.cxx.prebuilt b/direct/src/dcparser/dcParser.cxx.prebuilt index 399e4af2f9..6f4f167302 100644 --- a/direct/src/dcparser/dcParser.cxx.prebuilt +++ b/direct/src/dcparser/dcParser.cxx.prebuilt @@ -1,8 +1,9 @@ -/* A Bison parser, made by GNU Bison 3.1. */ +/* A Bison parser, made by GNU Bison 3.8.2. */ /* Bison implementation for Yacc-like parsers in C - Copyright (C) 1984, 1989-1990, 2000-2015, 2018 Free Software Foundation, Inc. + Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation, + Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -15,7 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program. If not, see . */ + along with this program. If not, see . */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work @@ -33,6 +34,10 @@ /* C LALR(1) parser skeleton written by Richard Stallman, by simplifying the original so-called "semantic" parser. */ +/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual, + especially those whose name start with YY_ or yy_. They are + private implementation details that can be changed or removed. */ + /* All symbols defined below should begin with yy or YY, to avoid infringing on user name space. This should be done even for local variables, as they might otherwise be expanded by user macros. @@ -40,11 +45,11 @@ define necessary library symbols; they are noted "INFRINGES ON USER NAME SPACE" below. */ -/* Identify Bison output. */ -#define YYBISON 1 +/* Identify Bison output, and Bison version. */ +#define YYBISON 30802 -/* Bison version. */ -#define YYBISON_VERSION "3.1" +/* Bison version string. */ +#define YYBISON_VERSION "3.8.2" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" @@ -65,12 +70,11 @@ #define yyerror dcyyerror #define yydebug dcyydebug #define yynerrs dcyynerrs - #define yylval dcyylval #define yychar dcyychar -/* Copy the first part of user declarations. */ -#line 7 "direct/src/dcparser/dcParser.yxx" /* yacc.c:339 */ +/* First part of user prologue. */ +#line 7 "direct/src/dcparser/dcParser.yxx" #include "dcLexerDefs.h" #include "dcParserDefs.h" @@ -152,172 +156,273 @@ dc_cleanup_parser() { } -#line 156 "built/tmp/dcParser.yxx.c" /* yacc.c:339 */ +#line 160 "built/tmp/dcParser.yxx.c" -# ifndef YY_NULLPTR -# if defined __cplusplus && 201103L <= __cplusplus -# define YY_NULLPTR nullptr +# ifndef YY_CAST +# ifdef __cplusplus +# define YY_CAST(Type, Val) static_cast (Val) +# define YY_REINTERPRET_CAST(Type, Val) reinterpret_cast (Val) # else -# define YY_NULLPTR 0 +# define YY_CAST(Type, Val) ((Type) (Val)) +# define YY_REINTERPRET_CAST(Type, Val) ((Type) (Val)) +# endif +# endif +# ifndef YY_NULLPTR +# if defined __cplusplus +# if 201103L <= __cplusplus +# define YY_NULLPTR nullptr +# else +# define YY_NULLPTR 0 +# endif +# else +# define YY_NULLPTR ((void*)0) # endif # endif -/* Enabling verbose error messages. */ -#ifdef YYERROR_VERBOSE -# undef YYERROR_VERBOSE -# define YYERROR_VERBOSE 1 -#else -# define YYERROR_VERBOSE 0 -#endif - -/* In a future release of Bison, this section will be replaced - by #include "dcParser.yxx.h". */ -#ifndef YY_DCYY_BUILT_TMP_DCPARSER_YXX_H_INCLUDED -# define YY_DCYY_BUILT_TMP_DCPARSER_YXX_H_INCLUDED -/* Debug traces. */ -#ifndef YYDEBUG -# define YYDEBUG 0 -#endif -#if YYDEBUG -extern int dcyydebug; -#endif - -/* Token type. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - enum yytokentype - { - UNSIGNED_INTEGER = 258, - SIGNED_INTEGER = 259, - REAL = 260, - STRING = 261, - IDENTIFIER = 262, - HEX_STRING = 263, - KEYWORD = 264, - KW_DCLASS = 265, - KW_STRUCT = 266, - KW_FROM = 267, - KW_IMPORT = 268, - KW_TYPEDEF = 269, - KW_KEYWORD = 270, - KW_SWITCH = 271, - KW_CASE = 272, - KW_DEFAULT = 273, - KW_BREAK = 274, - KW_INT8 = 275, - KW_INT16 = 276, - KW_INT32 = 277, - KW_INT64 = 278, - KW_UINT8 = 279, - KW_UINT16 = 280, - KW_UINT32 = 281, - KW_UINT64 = 282, - KW_FLOAT64 = 283, - KW_STRING = 284, - KW_BLOB = 285, - KW_BLOB32 = 286, - KW_INT8ARRAY = 287, - KW_INT16ARRAY = 288, - KW_INT32ARRAY = 289, - KW_UINT8ARRAY = 290, - KW_UINT16ARRAY = 291, - KW_UINT32ARRAY = 292, - KW_UINT32UINT8ARRAY = 293, - KW_CHAR = 294, - START_DC = 295, - START_PARAMETER_VALUE = 296, - START_PARAMETER_DESCRIPTION = 297 - }; -#endif -/* Tokens. */ -#define UNSIGNED_INTEGER 258 -#define SIGNED_INTEGER 259 -#define REAL 260 -#define STRING 261 -#define IDENTIFIER 262 -#define HEX_STRING 263 -#define KEYWORD 264 -#define KW_DCLASS 265 -#define KW_STRUCT 266 -#define KW_FROM 267 -#define KW_IMPORT 268 -#define KW_TYPEDEF 269 -#define KW_KEYWORD 270 -#define KW_SWITCH 271 -#define KW_CASE 272 -#define KW_DEFAULT 273 -#define KW_BREAK 274 -#define KW_INT8 275 -#define KW_INT16 276 -#define KW_INT32 277 -#define KW_INT64 278 -#define KW_UINT8 279 -#define KW_UINT16 280 -#define KW_UINT32 281 -#define KW_UINT64 282 -#define KW_FLOAT64 283 -#define KW_STRING 284 -#define KW_BLOB 285 -#define KW_BLOB32 286 -#define KW_INT8ARRAY 287 -#define KW_INT16ARRAY 288 -#define KW_INT32ARRAY 289 -#define KW_UINT8ARRAY 290 -#define KW_UINT16ARRAY 291 -#define KW_UINT32ARRAY 292 -#define KW_UINT32UINT8ARRAY 293 -#define KW_CHAR 294 -#define START_DC 295 -#define START_PARAMETER_VALUE 296 -#define START_PARAMETER_DESCRIPTION 297 - -/* Value type. */ +#include "dcParser.yxx.h" +/* Symbol kind. */ +enum yysymbol_kind_t +{ + YYSYMBOL_YYEMPTY = -2, + YYSYMBOL_YYEOF = 0, /* "end of file" */ + YYSYMBOL_YYerror = 1, /* error */ + YYSYMBOL_YYUNDEF = 2, /* "invalid token" */ + YYSYMBOL_UNSIGNED_INTEGER = 3, /* UNSIGNED_INTEGER */ + YYSYMBOL_SIGNED_INTEGER = 4, /* SIGNED_INTEGER */ + YYSYMBOL_REAL = 5, /* REAL */ + YYSYMBOL_STRING = 6, /* STRING */ + YYSYMBOL_IDENTIFIER = 7, /* IDENTIFIER */ + YYSYMBOL_HEX_STRING = 8, /* HEX_STRING */ + YYSYMBOL_KEYWORD = 9, /* KEYWORD */ + YYSYMBOL_KW_DCLASS = 10, /* KW_DCLASS */ + YYSYMBOL_KW_STRUCT = 11, /* KW_STRUCT */ + YYSYMBOL_KW_FROM = 12, /* KW_FROM */ + YYSYMBOL_KW_IMPORT = 13, /* KW_IMPORT */ + YYSYMBOL_KW_TYPEDEF = 14, /* KW_TYPEDEF */ + YYSYMBOL_KW_KEYWORD = 15, /* KW_KEYWORD */ + YYSYMBOL_KW_SWITCH = 16, /* KW_SWITCH */ + YYSYMBOL_KW_CASE = 17, /* KW_CASE */ + YYSYMBOL_KW_DEFAULT = 18, /* KW_DEFAULT */ + YYSYMBOL_KW_BREAK = 19, /* KW_BREAK */ + YYSYMBOL_KW_INT8 = 20, /* KW_INT8 */ + YYSYMBOL_KW_INT16 = 21, /* KW_INT16 */ + YYSYMBOL_KW_INT32 = 22, /* KW_INT32 */ + YYSYMBOL_KW_INT64 = 23, /* KW_INT64 */ + YYSYMBOL_KW_UINT8 = 24, /* KW_UINT8 */ + YYSYMBOL_KW_UINT16 = 25, /* KW_UINT16 */ + YYSYMBOL_KW_UINT32 = 26, /* KW_UINT32 */ + YYSYMBOL_KW_UINT64 = 27, /* KW_UINT64 */ + YYSYMBOL_KW_FLOAT64 = 28, /* KW_FLOAT64 */ + YYSYMBOL_KW_STRING = 29, /* KW_STRING */ + YYSYMBOL_KW_BLOB = 30, /* KW_BLOB */ + YYSYMBOL_KW_BLOB32 = 31, /* KW_BLOB32 */ + YYSYMBOL_KW_INT8ARRAY = 32, /* KW_INT8ARRAY */ + YYSYMBOL_KW_INT16ARRAY = 33, /* KW_INT16ARRAY */ + YYSYMBOL_KW_INT32ARRAY = 34, /* KW_INT32ARRAY */ + YYSYMBOL_KW_UINT8ARRAY = 35, /* KW_UINT8ARRAY */ + YYSYMBOL_KW_UINT16ARRAY = 36, /* KW_UINT16ARRAY */ + YYSYMBOL_KW_UINT32ARRAY = 37, /* KW_UINT32ARRAY */ + YYSYMBOL_KW_UINT32UINT8ARRAY = 38, /* KW_UINT32UINT8ARRAY */ + YYSYMBOL_KW_CHAR = 39, /* KW_CHAR */ + YYSYMBOL_START_DC = 40, /* START_DC */ + YYSYMBOL_START_PARAMETER_VALUE = 41, /* START_PARAMETER_VALUE */ + YYSYMBOL_START_PARAMETER_DESCRIPTION = 42, /* START_PARAMETER_DESCRIPTION */ + YYSYMBOL_43_ = 43, /* ';' */ + YYSYMBOL_44_ = 44, /* '/' */ + YYSYMBOL_45_ = 45, /* '.' */ + YYSYMBOL_46_ = 46, /* '*' */ + YYSYMBOL_47_ = 47, /* ',' */ + YYSYMBOL_48_ = 48, /* '{' */ + YYSYMBOL_49_ = 49, /* '}' */ + YYSYMBOL_50_ = 50, /* ':' */ + YYSYMBOL_51_ = 51, /* '(' */ + YYSYMBOL_52_ = 52, /* ')' */ + YYSYMBOL_53_ = 53, /* '=' */ + YYSYMBOL_54_ = 54, /* '%' */ + YYSYMBOL_55_ = 55, /* '-' */ + YYSYMBOL_56_ = 56, /* '[' */ + YYSYMBOL_57_ = 57, /* ']' */ + YYSYMBOL_YYACCEPT = 58, /* $accept */ + YYSYMBOL_grammar = 59, /* grammar */ + YYSYMBOL_dc = 60, /* dc */ + YYSYMBOL_slash_identifier = 61, /* slash_identifier */ + YYSYMBOL_import_identifier = 62, /* import_identifier */ + YYSYMBOL_import = 63, /* import */ + YYSYMBOL_64_1 = 64, /* $@1 */ + YYSYMBOL_import_symbol_list_or_star = 65, /* import_symbol_list_or_star */ + YYSYMBOL_import_symbol_list = 66, /* import_symbol_list */ + YYSYMBOL_typedef_decl = 67, /* typedef_decl */ + YYSYMBOL_keyword_decl = 68, /* keyword_decl */ + YYSYMBOL_keyword_decl_list = 69, /* keyword_decl_list */ + YYSYMBOL_dclass_or_struct = 70, /* dclass_or_struct */ + YYSYMBOL_dclass = 71, /* dclass */ + YYSYMBOL_72_2 = 72, /* @2 */ + YYSYMBOL_dclass_name = 73, /* dclass_name */ + YYSYMBOL_dclass_derivation = 74, /* dclass_derivation */ + YYSYMBOL_dclass_base_list = 75, /* dclass_base_list */ + YYSYMBOL_dclass_fields = 76, /* dclass_fields */ + YYSYMBOL_dclass_field = 77, /* dclass_field */ + YYSYMBOL_struct = 78, /* struct */ + YYSYMBOL_79_3 = 79, /* @3 */ + YYSYMBOL_struct_name = 80, /* struct_name */ + YYSYMBOL_struct_derivation = 81, /* struct_derivation */ + YYSYMBOL_struct_base_list = 82, /* struct_base_list */ + YYSYMBOL_struct_fields = 83, /* struct_fields */ + YYSYMBOL_struct_field = 84, /* struct_field */ + YYSYMBOL_atomic_field = 85, /* atomic_field */ + YYSYMBOL_86_4 = 86, /* @4 */ + YYSYMBOL_parameter_list = 87, /* parameter_list */ + YYSYMBOL_nonempty_parameter_list = 88, /* nonempty_parameter_list */ + YYSYMBOL_atomic_element = 89, /* atomic_element */ + YYSYMBOL_named_parameter = 90, /* named_parameter */ + YYSYMBOL_91_5 = 91, /* $@5 */ + YYSYMBOL_unnamed_parameter = 92, /* unnamed_parameter */ + YYSYMBOL_named_parameter_with_default = 93, /* named_parameter_with_default */ + YYSYMBOL_94_6 = 94, /* $@6 */ + YYSYMBOL_unnamed_parameter_with_default = 95, /* unnamed_parameter_with_default */ + YYSYMBOL_96_7 = 96, /* $@7 */ + YYSYMBOL_parameter = 97, /* parameter */ + YYSYMBOL_parameter_with_default = 98, /* parameter_with_default */ + YYSYMBOL_parameter_or_atomic = 99, /* parameter_or_atomic */ + YYSYMBOL_parameter_description = 100, /* parameter_description */ + YYSYMBOL_simple_type_name = 101, /* simple_type_name */ + YYSYMBOL_type_name = 102, /* type_name */ + YYSYMBOL_double_range = 103, /* double_range */ + YYSYMBOL_uint_range = 104, /* uint_range */ + YYSYMBOL_type_definition = 105, /* type_definition */ + YYSYMBOL_parameter_definition = 106, /* parameter_definition */ + YYSYMBOL_char_or_uint = 107, /* char_or_uint */ + YYSYMBOL_small_unsigned_integer = 108, /* small_unsigned_integer */ + YYSYMBOL_small_negative_integer = 109, /* small_negative_integer */ + YYSYMBOL_signed_integer = 110, /* signed_integer */ + YYSYMBOL_unsigned_integer = 111, /* unsigned_integer */ + YYSYMBOL_number = 112, /* number */ + YYSYMBOL_char_or_number = 113, /* char_or_number */ + YYSYMBOL_parameter_value = 114, /* parameter_value */ + YYSYMBOL_115_8 = 115, /* $@8 */ + YYSYMBOL_parameter_actual_value = 116, /* parameter_actual_value */ + YYSYMBOL_117_9 = 117, /* $@9 */ + YYSYMBOL_118_10 = 118, /* $@10 */ + YYSYMBOL_119_11 = 119, /* $@11 */ + YYSYMBOL_array = 120, /* array */ + YYSYMBOL_maybe_comma = 121, /* maybe_comma */ + YYSYMBOL_array_def = 122, /* array_def */ + YYSYMBOL_type_token = 123, /* type_token */ + YYSYMBOL_keyword_list = 124, /* keyword_list */ + YYSYMBOL_no_keyword_list = 125, /* no_keyword_list */ + YYSYMBOL_molecular_field = 126, /* molecular_field */ + YYSYMBOL_127_12 = 127, /* $@12 */ + YYSYMBOL_atomic_name = 128, /* atomic_name */ + YYSYMBOL_molecular_atom_list = 129, /* molecular_atom_list */ + YYSYMBOL_optional_name = 130, /* optional_name */ + YYSYMBOL_switch = 131, /* switch */ + YYSYMBOL_132_13 = 132, /* @13 */ + YYSYMBOL_switch_fields = 133, /* switch_fields */ + YYSYMBOL_switch_case = 134, /* switch_case */ + YYSYMBOL_135_14 = 135, /* $@14 */ + YYSYMBOL_switch_default = 136, /* switch_default */ + YYSYMBOL_switch_break = 137, /* switch_break */ + YYSYMBOL_switch_field = 138, /* switch_field */ + YYSYMBOL_empty = 139 /* empty */ +}; +typedef enum yysymbol_kind_t yysymbol_kind_t; -extern YYSTYPE dcyylval; -int dcyyparse (void); - -#endif /* !YY_DCYY_BUILT_TMP_DCPARSER_YXX_H_INCLUDED */ - -/* Copy the second part of user declarations. */ - -#line 286 "built/tmp/dcParser.yxx.c" /* yacc.c:358 */ #ifdef short # undef short #endif -#ifdef YYTYPE_UINT8 -typedef YYTYPE_UINT8 yytype_uint8; -#else -typedef unsigned char yytype_uint8; +/* On compilers that do not define __PTRDIFF_MAX__ etc., make sure + and (if available) are included + so that the code can choose integer types of a good width. */ + +#ifndef __PTRDIFF_MAX__ +# include /* INFRINGES ON USER NAME SPACE */ +# if defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ +# include /* INFRINGES ON USER NAME SPACE */ +# define YY_STDINT_H +# endif #endif -#ifdef YYTYPE_INT8 -typedef YYTYPE_INT8 yytype_int8; +/* Narrow types that promote to a signed type and that can represent a + signed or unsigned integer of at least N bits. In tables they can + save space and decrease cache pressure. Promoting to a signed type + helps avoid bugs in integer arithmetic. */ + +#ifdef __INT_LEAST8_MAX__ +typedef __INT_LEAST8_TYPE__ yytype_int8; +#elif defined YY_STDINT_H +typedef int_least8_t yytype_int8; #else typedef signed char yytype_int8; #endif -#ifdef YYTYPE_UINT16 -typedef YYTYPE_UINT16 yytype_uint16; -#else -typedef unsigned short yytype_uint16; -#endif - -#ifdef YYTYPE_INT16 -typedef YYTYPE_INT16 yytype_int16; +#ifdef __INT_LEAST16_MAX__ +typedef __INT_LEAST16_TYPE__ yytype_int16; +#elif defined YY_STDINT_H +typedef int_least16_t yytype_int16; #else typedef short yytype_int16; #endif +/* Work around bug in HP-UX 11.23, which defines these macros + incorrectly for preprocessor constants. This workaround can likely + be removed in 2023, as HPE has promised support for HP-UX 11.23 + (aka HP-UX 11i v2) only through the end of 2022; see Table 2 of + . */ +#ifdef __hpux +# undef UINT_LEAST8_MAX +# undef UINT_LEAST16_MAX +# define UINT_LEAST8_MAX 255 +# define UINT_LEAST16_MAX 65535 +#endif + +#if defined __UINT_LEAST8_MAX__ && __UINT_LEAST8_MAX__ <= __INT_MAX__ +typedef __UINT_LEAST8_TYPE__ yytype_uint8; +#elif (!defined __UINT_LEAST8_MAX__ && defined YY_STDINT_H \ + && UINT_LEAST8_MAX <= INT_MAX) +typedef uint_least8_t yytype_uint8; +#elif !defined __UINT_LEAST8_MAX__ && UCHAR_MAX <= INT_MAX +typedef unsigned char yytype_uint8; +#else +typedef short yytype_uint8; +#endif + +#if defined __UINT_LEAST16_MAX__ && __UINT_LEAST16_MAX__ <= __INT_MAX__ +typedef __UINT_LEAST16_TYPE__ yytype_uint16; +#elif (!defined __UINT_LEAST16_MAX__ && defined YY_STDINT_H \ + && UINT_LEAST16_MAX <= INT_MAX) +typedef uint_least16_t yytype_uint16; +#elif !defined __UINT_LEAST16_MAX__ && USHRT_MAX <= INT_MAX +typedef unsigned short yytype_uint16; +#else +typedef int yytype_uint16; +#endif + +#ifndef YYPTRDIFF_T +# if defined __PTRDIFF_TYPE__ && defined __PTRDIFF_MAX__ +# define YYPTRDIFF_T __PTRDIFF_TYPE__ +# define YYPTRDIFF_MAXIMUM __PTRDIFF_MAX__ +# elif defined PTRDIFF_MAX +# ifndef ptrdiff_t +# include /* INFRINGES ON USER NAME SPACE */ +# endif +# define YYPTRDIFF_T ptrdiff_t +# define YYPTRDIFF_MAXIMUM PTRDIFF_MAX +# else +# define YYPTRDIFF_T long +# define YYPTRDIFF_MAXIMUM LONG_MAX +# endif +#endif + #ifndef YYSIZE_T # ifdef __SIZE_TYPE__ # define YYSIZE_T __SIZE_TYPE__ # elif defined size_t # define YYSIZE_T size_t -# elif ! defined YYSIZE_T +# elif defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ # include /* INFRINGES ON USER NAME SPACE */ # define YYSIZE_T size_t # else @@ -325,7 +430,20 @@ typedef short yytype_int16; # endif #endif -#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) +#define YYSIZE_MAXIMUM \ + YY_CAST (YYPTRDIFF_T, \ + (YYPTRDIFF_MAXIMUM < YY_CAST (YYSIZE_T, -1) \ + ? YYPTRDIFF_MAXIMUM \ + : YY_CAST (YYSIZE_T, -1))) + +#define YYSIZEOF(X) YY_CAST (YYPTRDIFF_T, sizeof (X)) + + +/* Stored state numbers (used for stacks). */ +typedef yytype_int16 yy_state_t; + +/* State numbers in computations. */ +typedef int yy_state_fast_t; #ifndef YY_ # if defined YYENABLE_NLS && YYENABLE_NLS @@ -339,47 +457,43 @@ typedef short yytype_int16; # endif #endif -#ifndef YY_ATTRIBUTE -# if (defined __GNUC__ \ - && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \ - || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C -# define YY_ATTRIBUTE(Spec) __attribute__(Spec) + +#ifndef YY_ATTRIBUTE_PURE +# if defined __GNUC__ && 2 < __GNUC__ + (96 <= __GNUC_MINOR__) +# define YY_ATTRIBUTE_PURE __attribute__ ((__pure__)) # else -# define YY_ATTRIBUTE(Spec) /* empty */ +# define YY_ATTRIBUTE_PURE # endif #endif -#ifndef YY_ATTRIBUTE_PURE -# define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__)) -#endif - #ifndef YY_ATTRIBUTE_UNUSED -# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__)) -#endif - -#if !defined _Noreturn \ - && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112) -# if defined _MSC_VER && 1200 <= _MSC_VER -# define _Noreturn __declspec (noreturn) +# if defined __GNUC__ && 2 < __GNUC__ + (7 <= __GNUC_MINOR__) +# define YY_ATTRIBUTE_UNUSED __attribute__ ((__unused__)) # else -# define _Noreturn YY_ATTRIBUTE ((__noreturn__)) +# define YY_ATTRIBUTE_UNUSED # endif #endif /* Suppress unused-variable warnings by "using" E. */ #if ! defined lint || defined __GNUC__ -# define YYUSE(E) ((void) (E)) +# define YY_USE(E) ((void) (E)) #else -# define YYUSE(E) /* empty */ +# define YY_USE(E) /* empty */ #endif -#if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ /* Suppress an incorrect diagnostic about yylval being uninitialized. */ -# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ - _Pragma ("GCC diagnostic push") \ - _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\ +#if defined __GNUC__ && ! defined __ICC && 406 <= __GNUC__ * 100 + __GNUC_MINOR__ +# if __GNUC__ * 100 + __GNUC_MINOR__ < 407 +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ + _Pragma ("GCC diagnostic push") \ + _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") +# else +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ + _Pragma ("GCC diagnostic push") \ + _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") \ _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") -# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ +# endif +# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ _Pragma ("GCC diagnostic pop") #else # define YY_INITIAL_VALUE(Value) Value @@ -392,8 +506,22 @@ typedef short yytype_int16; # define YY_INITIAL_VALUE(Value) /* Nothing. */ #endif +#if defined __cplusplus && defined __GNUC__ && ! defined __ICC && 6 <= __GNUC__ +# define YY_IGNORE_USELESS_CAST_BEGIN \ + _Pragma ("GCC diagnostic push") \ + _Pragma ("GCC diagnostic ignored \"-Wuseless-cast\"") +# define YY_IGNORE_USELESS_CAST_END \ + _Pragma ("GCC diagnostic pop") +#endif +#ifndef YY_IGNORE_USELESS_CAST_BEGIN +# define YY_IGNORE_USELESS_CAST_BEGIN +# define YY_IGNORE_USELESS_CAST_END +#endif -#if ! defined yyoverflow || YYERROR_VERBOSE + +#define YY_ASSERT(E) ((void) (0 && (E))) + +#if !defined yyoverflow /* The parser invokes alloca or malloc; define the necessary symbols. */ @@ -458,8 +586,7 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */ # endif # endif # endif -#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ - +#endif /* !defined yyoverflow */ #if (! defined yyoverflow \ && (! defined __cplusplus \ @@ -468,17 +595,17 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */ /* A type that is properly aligned for any stack member. */ union yyalloc { - yytype_int16 yyss_alloc; + yy_state_t yyss_alloc; YYSTYPE yyvs_alloc; }; /* The size of the maximum gap between one aligned stack and the next. */ -# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) +# define YYSTACK_GAP_MAXIMUM (YYSIZEOF (union yyalloc) - 1) /* The size of an array large to enough to hold all stacks, each with N elements. */ # define YYSTACK_BYTES(N) \ - ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + ((N) * (YYSIZEOF (yy_state_t) + YYSIZEOF (YYSTYPE)) \ + YYSTACK_GAP_MAXIMUM) # define YYCOPY_NEEDED 1 @@ -491,11 +618,11 @@ union yyalloc # define YYSTACK_RELOCATE(Stack_alloc, Stack) \ do \ { \ - YYSIZE_T yynewbytes; \ + YYPTRDIFF_T yynewbytes; \ YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ Stack = &yyptr->Stack_alloc; \ - yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ - yyptr += yynewbytes / sizeof (*yyptr); \ + yynewbytes = yystacksize * YYSIZEOF (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / YYSIZEOF (*yyptr); \ } \ while (0) @@ -507,12 +634,12 @@ union yyalloc # ifndef YYCOPY # if defined __GNUC__ && 1 < __GNUC__ # define YYCOPY(Dst, Src, Count) \ - __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src))) + __builtin_memcpy (Dst, Src, YY_CAST (YYSIZE_T, (Count)) * sizeof (*(Src))) # else # define YYCOPY(Dst, Src, Count) \ do \ { \ - YYSIZE_T yyi; \ + YYPTRDIFF_T yyi; \ for (yyi = 0; yyi < (Count); yyi++) \ (Dst)[yyi] = (Src)[yyi]; \ } \ @@ -535,17 +662,20 @@ union yyalloc /* YYNSTATES -- Number of states. */ #define YYNSTATES 282 -/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned - by yylex, with out-of-bounds checking. */ -#define YYUNDEFTOK 2 +/* YYMAXUTOK -- Last valid token kind. */ #define YYMAXUTOK 297 -#define YYTRANSLATE(YYX) \ - ((unsigned) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM + as returned by yylex, with out-of-bounds checking. */ +#define YYTRANSLATE(YYX) \ + (0 <= (YYX) && (YYX) <= YYMAXUTOK \ + ? YY_CAST (yysymbol_kind_t, yytranslate[YYX]) \ + : YYSYMBOL_YYUNDEF) /* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM - as returned by yylex, without out-of-bounds checking. */ -static const yytype_uint8 yytranslate[] = + as returned by yylex. */ +static const yytype_int8 yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -580,56 +710,63 @@ static const yytype_uint8 yytranslate[] = }; #if YYDEBUG - /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ -static const yytype_uint16 yyrline[] = +/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ +static const yytype_int16 yyrline[] = { 0, 174, 174, 175, 176, 183, 184, 185, 196, 202, 203, 204, 208, 209, 216, 217, 224, 229, 228, 236, 237, 244, 248, 255, 273, 277, 278, 282, 293, 294, - 299, 298, 310, 333, 334, 338, 344, 358, 359, 360, - 373, 383, 384, 392, 403, 402, 414, 437, 438, 442, - 448, 457, 458, 459, 470, 477, 478, 482, 490, 489, - 507, 508, 512, 513, 517, 527, 526, 537, 541, 543, - 542, 571, 573, 572, 601, 602, 606, 607, 611, 615, - 622, 626, 630, 637, 641, 650, 666, 681, 682, 714, - 730, 749, 753, 760, 767, 776, 782, 788, 799, 803, - 810, 817, 824, 830, 836, 845, 846, 857, 862, 877, - 892, 899, 908, 912, 923, 937, 941, 945, 949, 953, - 957, 966, 971, 975, 974, 989, 993, 997, 1001, 1005, - 1010, 1009, 1018, 1017, 1026, 1025, 1033, 1039, 1045, 1051, - 1060, 1061, 1065, 1066, 1070, 1071, 1075, 1079, 1083, 1087, - 1091, 1095, 1099, 1103, 1107, 1111, 1115, 1119, 1123, 1127, - 1131, 1135, 1139, 1143, 1147, 1151, 1158, 1162, 1169, 1179, - 1178, 1189, 1216, 1222, 1236, 1240, 1245, 1244, 1257, 1258, - 1259, 1260, 1261, 1262, 1276, 1275, 1296, 1305, 1312, 1316, - 1322 + 299, 298, 311, 334, 335, 339, 345, 359, 360, 361, + 374, 384, 385, 393, 404, 403, 416, 439, 440, 444, + 450, 459, 460, 461, 472, 479, 480, 484, 492, 491, + 510, 511, 515, 516, 520, 530, 529, 540, 544, 546, + 545, 574, 576, 575, 604, 605, 609, 610, 614, 618, + 625, 629, 633, 640, 644, 653, 669, 684, 685, 717, + 733, 752, 756, 763, 770, 779, 785, 791, 802, 806, + 813, 820, 827, 833, 839, 848, 849, 860, 865, 880, + 895, 902, 911, 915, 926, 940, 944, 948, 952, 956, + 960, 969, 974, 978, 977, 992, 996, 1000, 1004, 1008, + 1013, 1012, 1021, 1020, 1029, 1028, 1036, 1042, 1048, 1054, + 1063, 1064, 1068, 1069, 1073, 1074, 1078, 1082, 1086, 1090, + 1094, 1098, 1102, 1106, 1110, 1114, 1118, 1122, 1126, 1130, + 1134, 1138, 1142, 1146, 1150, 1154, 1161, 1165, 1172, 1182, + 1181, 1192, 1219, 1225, 1239, 1243, 1248, 1247, 1261, 1262, + 1263, 1264, 1265, 1266, 1280, 1279, 1300, 1309, 1316, 1320, + 1326 }; #endif -#if YYDEBUG || YYERROR_VERBOSE || 0 +/** Accessing symbol of state STATE. */ +#define YY_ACCESSING_SYMBOL(State) YY_CAST (yysymbol_kind_t, yystos[State]) + +#if YYDEBUG || 0 +/* The user-facing name of the symbol whose (internal) number is + YYSYMBOL. No bounds checking. */ +static const char *yysymbol_name (yysymbol_kind_t yysymbol) YY_ATTRIBUTE_UNUSED; + /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = { - "$end", "error", "$undefined", "UNSIGNED_INTEGER", "SIGNED_INTEGER", - "REAL", "STRING", "IDENTIFIER", "HEX_STRING", "KEYWORD", "KW_DCLASS", - "KW_STRUCT", "KW_FROM", "KW_IMPORT", "KW_TYPEDEF", "KW_KEYWORD", - "KW_SWITCH", "KW_CASE", "KW_DEFAULT", "KW_BREAK", "KW_INT8", "KW_INT16", - "KW_INT32", "KW_INT64", "KW_UINT8", "KW_UINT16", "KW_UINT32", - "KW_UINT64", "KW_FLOAT64", "KW_STRING", "KW_BLOB", "KW_BLOB32", - "KW_INT8ARRAY", "KW_INT16ARRAY", "KW_INT32ARRAY", "KW_UINT8ARRAY", - "KW_UINT16ARRAY", "KW_UINT32ARRAY", "KW_UINT32UINT8ARRAY", "KW_CHAR", - "START_DC", "START_PARAMETER_VALUE", "START_PARAMETER_DESCRIPTION", - "';'", "'/'", "'.'", "'*'", "','", "'{'", "'}'", "':'", "'('", "')'", - "'='", "'%'", "'-'", "'['", "']'", "$accept", "grammar", "dc", - "slash_identifier", "import_identifier", "import", "$@1", - "import_symbol_list_or_star", "import_symbol_list", "typedef_decl", - "keyword_decl", "keyword_decl_list", "dclass_or_struct", "dclass", "@2", - "dclass_name", "dclass_derivation", "dclass_base_list", "dclass_fields", - "dclass_field", "struct", "@3", "struct_name", "struct_derivation", - "struct_base_list", "struct_fields", "struct_field", "atomic_field", - "@4", "parameter_list", "nonempty_parameter_list", "atomic_element", - "named_parameter", "$@5", "unnamed_parameter", + "\"end of file\"", "error", "\"invalid token\"", "UNSIGNED_INTEGER", + "SIGNED_INTEGER", "REAL", "STRING", "IDENTIFIER", "HEX_STRING", + "KEYWORD", "KW_DCLASS", "KW_STRUCT", "KW_FROM", "KW_IMPORT", + "KW_TYPEDEF", "KW_KEYWORD", "KW_SWITCH", "KW_CASE", "KW_DEFAULT", + "KW_BREAK", "KW_INT8", "KW_INT16", "KW_INT32", "KW_INT64", "KW_UINT8", + "KW_UINT16", "KW_UINT32", "KW_UINT64", "KW_FLOAT64", "KW_STRING", + "KW_BLOB", "KW_BLOB32", "KW_INT8ARRAY", "KW_INT16ARRAY", "KW_INT32ARRAY", + "KW_UINT8ARRAY", "KW_UINT16ARRAY", "KW_UINT32ARRAY", + "KW_UINT32UINT8ARRAY", "KW_CHAR", "START_DC", "START_PARAMETER_VALUE", + "START_PARAMETER_DESCRIPTION", "';'", "'/'", "'.'", "'*'", "','", "'{'", + "'}'", "':'", "'('", "')'", "'='", "'%'", "'-'", "'['", "']'", "$accept", + "grammar", "dc", "slash_identifier", "import_identifier", "import", + "$@1", "import_symbol_list_or_star", "import_symbol_list", + "typedef_decl", "keyword_decl", "keyword_decl_list", "dclass_or_struct", + "dclass", "@2", "dclass_name", "dclass_derivation", "dclass_base_list", + "dclass_fields", "dclass_field", "struct", "@3", "struct_name", + "struct_derivation", "struct_base_list", "struct_fields", "struct_field", + "atomic_field", "@4", "parameter_list", "nonempty_parameter_list", + "atomic_element", "named_parameter", "$@5", "unnamed_parameter", "named_parameter_with_default", "$@6", "unnamed_parameter_with_default", "$@7", "parameter", "parameter_with_default", "parameter_or_atomic", "parameter_description", "simple_type_name", "type_name", "double_range", @@ -642,34 +779,26 @@ static const char *const yytname[] = "optional_name", "switch", "@13", "switch_fields", "switch_case", "$@14", "switch_default", "switch_break", "switch_field", "empty", YY_NULLPTR }; + +static const char * +yysymbol_name (yysymbol_kind_t yysymbol) +{ + return yytname[yysymbol]; +} #endif -# ifdef YYPRINT -/* YYTOKNUM[NUM] -- (External) token number corresponding to the - (internal) symbol number NUM (which must be that of a token). */ -static const yytype_uint16 yytoknum[] = -{ - 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, - 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, - 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, - 295, 296, 297, 59, 47, 46, 42, 44, 123, 125, - 58, 40, 41, 61, 37, 45, 91, 93 -}; -# endif +#define YYPACT_NINF (-127) -#define YYPACT_NINF -127 +#define yypact_value_is_default(Yyn) \ + ((Yyn) == YYPACT_NINF) -#define yypact_value_is_default(Yystate) \ - (!!((Yystate) == (-127))) +#define YYTABLE_NINF (-176) -#define YYTABLE_NINF -176 - -#define yytable_value_is_error(Yytable_value) \ +#define yytable_value_is_error(Yyn) \ 0 - /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing - STATE-NUM. */ +/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ static const yytype_int16 yypact[] = { 61, -127, 104, 359, 19, 128, -127, -127, -127, -23, @@ -703,9 +832,9 @@ static const yytype_int16 yypact[] = -127, -127 }; - /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. - Performed when YYTABLE does not specify something else to do. Zero - means the default is an error. */ +/* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. + Performed when YYTABLE does not specify something else to do. Zero + means the default is an error. */ static const yytype_uint8 yydefact[] = { 0, 190, 0, 190, 0, 2, 5, 116, 115, 127, @@ -739,7 +868,7 @@ static const yytype_uint8 yydefact[] = 173, 185 }; - /* YYPGOTO[NTERM-NUM]. */ +/* YYPGOTO[NTERM-NUM]. */ static const yytype_int16 yypgoto[] = { -127, -127, -127, -126, 143, -127, -127, -127, -127, -127, @@ -753,10 +882,10 @@ static const yytype_int16 yypgoto[] = -127, 3 }; - /* YYDEFGOTO[NTERM-NUM]. */ +/* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int16 yydefgoto[] = { - -1, 4, 5, 97, 98, 64, 186, 209, 210, 65, + 0, 4, 5, 97, 98, 64, 186, 209, 210, 65, 66, 104, 67, 68, 143, 204, 183, 205, 222, 240, 43, 120, 190, 156, 191, 212, 229, 44, 142, 177, 178, 179, 45, 93, 46, 101, 123, 102, 124, 161, @@ -767,9 +896,9 @@ static const yytype_int16 yydefgoto[] = 270, 84 }; - /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If - positive, shift that token. If negative, reduce the rule whose - number is the opposite. If YYTABLE_NINF, syntax error. */ +/* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule whose + number is the opposite. If YYTABLE_NINF, syntax error. */ static const yytype_int16 yytable[] = { 18, 134, 47, 48, 6, 158, 56, 87, 88, 129, @@ -866,8 +995,8 @@ static const yytype_int16 yycheck[] = 38, 39 }; - /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing - symbol of state STATE-NUM. */ +/* YYSTOS[STATE-NUM] -- The symbol kind of the accessing symbol of + state STATE-NUM. */ static const yytype_uint8 yystos[] = { 0, 40, 41, 42, 59, 60, 139, 3, 4, 5, @@ -901,7 +1030,7 @@ static const yytype_uint8 yystos[] = 128, 50 }; - /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +/* YYR1[RULE-NUM] -- Symbol kind of the left-hand side of rule RULE-NUM. */ static const yytype_uint8 yyr1[] = { 0, 58, 59, 59, 59, 60, 60, 60, 60, 60, @@ -926,8 +1055,8 @@ static const yytype_uint8 yyr1[] = 139 }; - /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ -static const yytype_uint8 yyr2[] = +/* YYR2[RULE-NUM] -- Number of symbols on the right-hand side of rule RULE-NUM. */ +static const yytype_int8 yyr2[] = { 0, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1, 3, 1, 3, 2, 0, 5, 1, @@ -952,39 +1081,39 @@ static const yytype_uint8 yyr2[] = }; +enum { YYENOMEM = -2 }; + #define yyerrok (yyerrstatus = 0) #define yyclearin (yychar = YYEMPTY) -#define YYEMPTY (-2) -#define YYEOF 0 #define YYACCEPT goto yyacceptlab #define YYABORT goto yyabortlab #define YYERROR goto yyerrorlab +#define YYNOMEM goto yyexhaustedlab #define YYRECOVERING() (!!yyerrstatus) -#define YYBACKUP(Token, Value) \ -do \ - if (yychar == YYEMPTY) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - YYPOPSTACK (yylen); \ - yystate = *yyssp; \ - goto yybackup; \ - } \ - else \ - { \ - yyerror (YY_("syntax error: cannot back up")); \ - YYERROR; \ - } \ -while (0) - -/* Error token number */ -#define YYTERROR 1 -#define YYERRCODE 256 +#define YYBACKUP(Token, Value) \ + do \ + if (yychar == YYEMPTY) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + YYPOPSTACK (yylen); \ + yystate = *yyssp; \ + goto yybackup; \ + } \ + else \ + { \ + yyerror (YY_("syntax error: cannot back up")); \ + YYERROR; \ + } \ + while (0) +/* Backward compatibility with an undocumented macro. + Use YYerror or YYUNDEF. */ +#define YYERRCODE YYUNDEF /* Enable debugging if requested. */ @@ -1001,55 +1130,52 @@ do { \ YYFPRINTF Args; \ } while (0) -/* This macro is provided for backward compatibility. */ -#ifndef YY_LOCATION_PRINT -# define YY_LOCATION_PRINT(File, Loc) ((void) 0) -#endif -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ + +# define YY_SYMBOL_PRINT(Title, Kind, Value, Location) \ do { \ if (yydebug) \ { \ YYFPRINTF (stderr, "%s ", Title); \ yy_symbol_print (stderr, \ - Type, Value); \ + Kind, Value); \ YYFPRINTF (stderr, "\n"); \ } \ } while (0) -/*----------------------------------------. -| Print this symbol's value on YYOUTPUT. | -`----------------------------------------*/ +/*-----------------------------------. +| Print this symbol's value on YYO. | +`-----------------------------------*/ static void -yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +yy_symbol_value_print (FILE *yyo, + yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep) { - FILE *yyo = yyoutput; - YYUSE (yyo); + FILE *yyoutput = yyo; + YY_USE (yyoutput); if (!yyvaluep) return; -# ifdef YYPRINT - if (yytype < YYNTOKENS) - YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); -# endif - YYUSE (yytype); + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + YY_USE (yykind); + YY_IGNORE_MAYBE_UNINITIALIZED_END } -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ +/*---------------------------. +| Print this symbol on YYO. | +`---------------------------*/ static void -yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +yy_symbol_print (FILE *yyo, + yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep) { - YYFPRINTF (yyoutput, "%s %s (", - yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]); + YYFPRINTF (yyo, "%s %s (", + yykind < YYNTOKENS ? "token" : "nterm", yysymbol_name (yykind)); - yy_symbol_value_print (yyoutput, yytype, yyvaluep); - YYFPRINTF (yyoutput, ")"); + yy_symbol_value_print (yyo, yykind, yyvaluep); + YYFPRINTF (yyo, ")"); } /*------------------------------------------------------------------. @@ -1058,7 +1184,7 @@ yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) `------------------------------------------------------------------*/ static void -yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) +yy_stack_print (yy_state_t *yybottom, yy_state_t *yytop) { YYFPRINTF (stderr, "Stack now"); for (; yybottom <= yytop; yybottom++) @@ -1081,21 +1207,21 @@ do { \ `------------------------------------------------*/ static void -yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule) +yy_reduce_print (yy_state_t *yyssp, YYSTYPE *yyvsp, + int yyrule) { - unsigned long yylno = yyrline[yyrule]; + int yylno = yyrline[yyrule]; int yynrhs = yyr2[yyrule]; int yyi; - YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", + YYFPRINTF (stderr, "Reducing stack by rule %d (line %d):\n", yyrule - 1, yylno); /* The symbols being reduced. */ for (yyi = 0; yyi < yynrhs; yyi++) { YYFPRINTF (stderr, " $%d = ", yyi + 1); yy_symbol_print (stderr, - yystos[yyssp[yyi + 1 - yynrhs]], - &(yyvsp[(yyi + 1) - (yynrhs)]) - ); + YY_ACCESSING_SYMBOL (+yyssp[yyi + 1 - yynrhs]), + &yyvsp[(yyi + 1) - (yynrhs)]); YYFPRINTF (stderr, "\n"); } } @@ -1110,8 +1236,8 @@ do { \ multiple parsers can coexist. */ int yydebug; #else /* !YYDEBUG */ -# define YYDPRINTF(Args) -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) +# define YYDPRINTF(Args) ((void) 0) +# define YY_SYMBOL_PRINT(Title, Kind, Value, Location) # define YY_STACK_PRINT(Bottom, Top) # define YY_REDUCE_PRINT(Rule) #endif /* !YYDEBUG */ @@ -1134,250 +1260,30 @@ int yydebug; #endif -#if YYERROR_VERBOSE -# ifndef yystrlen -# if defined __GLIBC__ && defined _STRING_H -# define yystrlen strlen -# else -/* Return the length of YYSTR. */ -static YYSIZE_T -yystrlen (const char *yystr) -{ - YYSIZE_T yylen; - for (yylen = 0; yystr[yylen]; yylen++) - continue; - return yylen; -} -# endif -# endif -# ifndef yystpcpy -# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE -# define yystpcpy stpcpy -# else -/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in - YYDEST. */ -static char * -yystpcpy (char *yydest, const char *yysrc) -{ - char *yyd = yydest; - const char *yys = yysrc; - while ((*yyd++ = *yys++) != '\0') - continue; - - return yyd - 1; -} -# endif -# endif - -# ifndef yytnamerr -/* Copy to YYRES the contents of YYSTR after stripping away unnecessary - quotes and backslashes, so that it's suitable for yyerror. The - heuristic is that double-quoting is unnecessary unless the string - contains an apostrophe, a comma, or backslash (other than - backslash-backslash). YYSTR is taken from yytname. If YYRES is - null, do not copy; instead, return the length of what the result - would have been. */ -static YYSIZE_T -yytnamerr (char *yyres, const char *yystr) -{ - if (*yystr == '"') - { - YYSIZE_T yyn = 0; - char const *yyp = yystr; - - for (;;) - switch (*++yyp) - { - case '\'': - case ',': - goto do_not_strip_quotes; - - case '\\': - if (*++yyp != '\\') - goto do_not_strip_quotes; - /* Fall through. */ - default: - if (yyres) - yyres[yyn] = *yyp; - yyn++; - break; - - case '"': - if (yyres) - yyres[yyn] = '\0'; - return yyn; - } - do_not_strip_quotes: ; - } - - if (! yyres) - return yystrlen (yystr); - - return yystpcpy (yyres, yystr) - yyres; -} -# endif - -/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message - about the unexpected token YYTOKEN for the state stack whose top is - YYSSP. - - Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is - not large enough to hold the message. In that case, also set - *YYMSG_ALLOC to the required number of bytes. Return 2 if the - required number of bytes is too large to store. */ -static int -yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, - yytype_int16 *yyssp, int yytoken) -{ - YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]); - YYSIZE_T yysize = yysize0; - enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; - /* Internationalized format string. */ - const char *yyformat = YY_NULLPTR; - /* Arguments of yyformat. */ - char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; - /* Number of reported tokens (one for the "unexpected", one per - "expected"). */ - int yycount = 0; - - /* There are many possibilities here to consider: - - If this state is a consistent state with a default action, then - the only way this function was invoked is if the default action - is an error action. In that case, don't check for expected - tokens because there are none. - - The only way there can be no lookahead present (in yychar) is if - this state is a consistent state with a default action. Thus, - detecting the absence of a lookahead is sufficient to determine - that there is no unexpected or expected token to report. In that - case, just report a simple "syntax error". - - Don't assume there isn't a lookahead just because this state is a - consistent state with a default action. There might have been a - previous inconsistent state, consistent state with a non-default - action, or user semantic action that manipulated yychar. - - Of course, the expected token list depends on states to have - correct lookahead information, and it depends on the parser not - to perform extra reductions after fetching a lookahead from the - scanner and before detecting a syntax error. Thus, state merging - (from LALR or IELR) and default reductions corrupt the expected - token list. However, the list is correct for canonical LR with - one exception: it will still contain any token that will not be - accepted due to an error action in a later state. - */ - if (yytoken != YYEMPTY) - { - int yyn = yypact[*yyssp]; - yyarg[yycount++] = yytname[yytoken]; - if (!yypact_value_is_default (yyn)) - { - /* Start YYX at -YYN if negative to avoid negative indexes in - YYCHECK. In other words, skip the first -YYN actions for - this state because they are default actions. */ - int yyxbegin = yyn < 0 ? -yyn : 0; - /* Stay within bounds of both yycheck and yytname. */ - int yychecklim = YYLAST - yyn + 1; - int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; - int yyx; - - for (yyx = yyxbegin; yyx < yyxend; ++yyx) - if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR - && !yytable_value_is_error (yytable[yyx + yyn])) - { - if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) - { - yycount = 1; - yysize = yysize0; - break; - } - yyarg[yycount++] = yytname[yyx]; - { - YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]); - if (! (yysize <= yysize1 - && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) - return 2; - yysize = yysize1; - } - } - } - } - - switch (yycount) - { -# define YYCASE_(N, S) \ - case N: \ - yyformat = S; \ - break - default: /* Avoid compiler warnings. */ - YYCASE_(0, YY_("syntax error")); - YYCASE_(1, YY_("syntax error, unexpected %s")); - YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); - YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); - YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); - YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); -# undef YYCASE_ - } - - { - YYSIZE_T yysize1 = yysize + yystrlen (yyformat); - if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) - return 2; - yysize = yysize1; - } - - if (*yymsg_alloc < yysize) - { - *yymsg_alloc = 2 * yysize; - if (! (yysize <= *yymsg_alloc - && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) - *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; - return 1; - } - - /* Avoid sprintf, as that infringes on the user's name space. - Don't have undefined behavior even if the translation - produced a string with the wrong number of "%s"s. */ - { - char *yyp = *yymsg; - int yyi = 0; - while ((*yyp = *yyformat) != '\0') - if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) - { - yyp += yytnamerr (yyp, yyarg[yyi++]); - yyformat += 2; - } - else - { - yyp++; - yyformat++; - } - } - return 0; -} -#endif /* YYERROR_VERBOSE */ /*-----------------------------------------------. | Release the memory associated to this symbol. | `-----------------------------------------------*/ static void -yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) +yydestruct (const char *yymsg, + yysymbol_kind_t yykind, YYSTYPE *yyvaluep) { - YYUSE (yyvaluep); + YY_USE (yyvaluep); if (!yymsg) yymsg = "Deleting"; - YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + YY_SYMBOL_PRINT (yymsg, yykind, yyvaluep, yylocationp); YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - YYUSE (yytype); + YY_USE (yykind); YY_IGNORE_MAYBE_UNINITIALIZED_END } - - -/* The lookahead symbol. */ +/* Lookahead token kind. */ int yychar; /* The semantic value of the lookahead symbol. */ @@ -1386,6 +1292,8 @@ YYSTYPE yylval; int yynerrs; + + /*----------. | yyparse. | `----------*/ @@ -1393,43 +1301,36 @@ int yynerrs; int yyparse (void) { - int yystate; + yy_state_fast_t yystate = 0; /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; + int yyerrstatus = 0; - /* The stacks and their tools: - 'yyss': related to states. - 'yyvs': related to semantic values. - - Refer to the stacks through separate pointers, to allow yyoverflow + /* Refer to the stacks through separate pointers, to allow yyoverflow to reallocate them elsewhere. */ - /* The state stack. */ - yytype_int16 yyssa[YYINITDEPTH]; - yytype_int16 *yyss; - yytype_int16 *yyssp; + /* Their size. */ + YYPTRDIFF_T yystacksize = YYINITDEPTH; - /* The semantic value stack. */ + /* The state stack: array, bottom, top. */ + yy_state_t yyssa[YYINITDEPTH]; + yy_state_t *yyss = yyssa; + yy_state_t *yyssp = yyss; + + /* The semantic value stack: array, bottom, top. */ YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs; - YYSTYPE *yyvsp; - - YYSIZE_T yystacksize; + YYSTYPE *yyvs = yyvsa; + YYSTYPE *yyvsp = yyvs; int yyn; + /* The return value of yyparse. */ int yyresult; - /* Lookahead token as an internal (translated) token number. */ - int yytoken = 0; + /* Lookahead symbol kind. */ + yysymbol_kind_t yytoken = YYSYMBOL_YYEMPTY; /* The variables used to return semantic value and location from the action routines. */ YYSTYPE yyval; -#if YYERROR_VERBOSE - /* Buffer for error messages, and its allocated size. */ - char yymsgbuf[128]; - char *yymsg = yymsgbuf; - YYSIZE_T yymsg_alloc = sizeof yymsgbuf; -#endif + #define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) @@ -1437,71 +1338,75 @@ yyparse (void) Keep to zero when no symbol should be popped. */ int yylen = 0; - yyssp = yyss = yyssa; - yyvsp = yyvs = yyvsa; - yystacksize = YYINITDEPTH; - YYDPRINTF ((stderr, "Starting parse\n")); - yystate = 0; - yyerrstatus = 0; - yynerrs = 0; yychar = YYEMPTY; /* Cause a token to be read. */ + goto yysetstate; + /*------------------------------------------------------------. -| yynewstate -- Push a new state, which is found in yystate. | +| yynewstate -- push a new state, which is found in yystate. | `------------------------------------------------------------*/ - yynewstate: +yynewstate: /* In all cases, when you get here, the value and location stacks have just been pushed. So pushing a state here evens the stacks. */ yyssp++; - yysetstate: - *yyssp = yystate; + +/*--------------------------------------------------------------------. +| yysetstate -- set current state (the top of the stack) to yystate. | +`--------------------------------------------------------------------*/ +yysetstate: + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + YY_ASSERT (0 <= yystate && yystate < YYNSTATES); + YY_IGNORE_USELESS_CAST_BEGIN + *yyssp = YY_CAST (yy_state_t, yystate); + YY_IGNORE_USELESS_CAST_END + YY_STACK_PRINT (yyss, yyssp); if (yyss + yystacksize - 1 <= yyssp) +#if !defined yyoverflow && !defined YYSTACK_RELOCATE + YYNOMEM; +#else { /* Get the current used size of the three stacks, in elements. */ - YYSIZE_T yysize = yyssp - yyss + 1; + YYPTRDIFF_T yysize = yyssp - yyss + 1; -#ifdef yyoverflow +# if defined yyoverflow { /* Give user a chance to reallocate the stack. Use copies of these so that the &'s don't force the real ones into memory. */ + yy_state_t *yyss1 = yyss; YYSTYPE *yyvs1 = yyvs; - yytype_int16 *yyss1 = yyss; /* Each stack pointer address is followed by the size of the data in use in that stack, in bytes. This used to be a conditional around just the two extra args, but that might be undefined if yyoverflow is a macro. */ yyoverflow (YY_("memory exhausted"), - &yyss1, yysize * sizeof (*yyssp), - &yyvs1, yysize * sizeof (*yyvsp), + &yyss1, yysize * YYSIZEOF (*yyssp), + &yyvs1, yysize * YYSIZEOF (*yyvsp), &yystacksize); - yyss = yyss1; yyvs = yyvs1; } -#else /* no yyoverflow */ -# ifndef YYSTACK_RELOCATE - goto yyexhaustedlab; -# else +# else /* defined YYSTACK_RELOCATE */ /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) - goto yyexhaustedlab; + YYNOMEM; yystacksize *= 2; if (YYMAXDEPTH < yystacksize) yystacksize = YYMAXDEPTH; { - yytype_int16 *yyss1 = yyss; + yy_state_t *yyss1 = yyss; union yyalloc *yyptr = - (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + YY_CAST (union yyalloc *, + YYSTACK_ALLOC (YY_CAST (YYSIZE_T, YYSTACK_BYTES (yystacksize)))); if (! yyptr) - goto yyexhaustedlab; + YYNOMEM; YYSTACK_RELOCATE (yyss_alloc, yyss); YYSTACK_RELOCATE (yyvs_alloc, yyvs); # undef YYSTACK_RELOCATE @@ -1509,30 +1414,31 @@ yyparse (void) YYSTACK_FREE (yyss1); } # endif -#endif /* no yyoverflow */ yyssp = yyss + yysize - 1; yyvsp = yyvs + yysize - 1; - YYDPRINTF ((stderr, "Stack size increased to %lu\n", - (unsigned long) yystacksize)); + YY_IGNORE_USELESS_CAST_BEGIN + YYDPRINTF ((stderr, "Stack size increased to %ld\n", + YY_CAST (long, yystacksize))); + YY_IGNORE_USELESS_CAST_END if (yyss + yystacksize - 1 <= yyssp) YYABORT; } +#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */ - YYDPRINTF ((stderr, "Entering state %d\n", yystate)); if (yystate == YYFINAL) YYACCEPT; goto yybackup; + /*-----------. | yybackup. | `-----------*/ yybackup: - /* Do appropriate processing given the current state. Read a lookahead token if we need one and don't already have one. */ @@ -1543,18 +1449,29 @@ yybackup: /* Not known => get a lookahead token if don't already have one. */ - /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ + /* YYCHAR is either empty, or end-of-input, or a valid lookahead. */ if (yychar == YYEMPTY) { - YYDPRINTF ((stderr, "Reading a token: ")); + YYDPRINTF ((stderr, "Reading a token\n")); yychar = yylex (); } if (yychar <= YYEOF) { - yychar = yytoken = YYEOF; + yychar = YYEOF; + yytoken = YYSYMBOL_YYEOF; YYDPRINTF ((stderr, "Now at end of input.\n")); } + else if (yychar == YYerror) + { + /* The scanner already issued an error message, process directly + to error recovery. But do not keep the error token as + lookahead, it is too special and may lead us to an endless + loop in error recovery. */ + yychar = YYUNDEF; + yytoken = YYSYMBOL_YYerror; + goto yyerrlab1; + } else { yytoken = YYTRANSLATE (yychar); @@ -1582,15 +1499,13 @@ yybackup: /* Shift the lookahead token. */ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); - - /* Discard the shifted token. */ - yychar = YYEMPTY; - yystate = yyn; YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN *++yyvsp = yylval; YY_IGNORE_MAYBE_UNINITIALIZED_END + /* Discard the shifted token. */ + yychar = YYEMPTY; goto yynewstate; @@ -1605,7 +1520,7 @@ yydefault: /*-----------------------------. -| yyreduce -- Do a reduction. | +| yyreduce -- do a reduction. | `-----------------------------*/ yyreduce: /* yyn is the number of a rule to reduce with. */ @@ -1625,17 +1540,17 @@ yyreduce: YY_REDUCE_PRINT (yyn); switch (yyn) { - case 4: -#line 177 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 4: /* grammar: START_PARAMETER_DESCRIPTION parameter_description */ +#line 177 "direct/src/dcparser/dcParser.yxx" +{ parameter_description = (yyvsp[0].u.field); } -#line 1634 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 1549 "built/tmp/dcParser.yxx.c" break; - case 7: -#line 186 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 7: /* dc: dc dclass_or_struct */ +#line 186 "direct/src/dcparser/dcParser.yxx" +{ if (!dc_file->add_class((yyvsp[0].u.dclass))) { DCClass *old_class = dc_file->get_class_by_name((yyvsp[0].u.dclass)->get_name()); if (old_class != nullptr && old_class->is_bogus_class()) { @@ -1645,78 +1560,78 @@ yyreduce: } } } -#line 1649 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 1564 "built/tmp/dcParser.yxx.c" break; - case 8: -#line 197 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 8: /* dc: dc switch */ +#line 197 "direct/src/dcparser/dcParser.yxx" +{ if (!dc_file->add_switch((yyvsp[0].u.dswitch))) { yyerror("Duplicate class name: " + (yyvsp[0].u.dswitch)->get_name()); } } -#line 1659 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 1574 "built/tmp/dcParser.yxx.c" break; - case 13: -#line 210 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 13: /* slash_identifier: slash_identifier '/' IDENTIFIER */ +#line 210 "direct/src/dcparser/dcParser.yxx" +{ (yyval.str) = (yyvsp[-2].str) + string("/") + (yyvsp[0].str); } -#line 1667 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 1582 "built/tmp/dcParser.yxx.c" break; - case 15: -#line 218 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 15: /* import_identifier: import_identifier '.' slash_identifier */ +#line 218 "direct/src/dcparser/dcParser.yxx" +{ (yyval.str) = (yyvsp[-2].str) + string(".") + (yyvsp[0].str); } -#line 1675 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 1590 "built/tmp/dcParser.yxx.c" break; - case 16: -#line 225 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 16: /* import: KW_IMPORT import_identifier */ +#line 225 "direct/src/dcparser/dcParser.yxx" +{ dc_file->add_import_module((yyvsp[0].str)); } -#line 1683 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 1598 "built/tmp/dcParser.yxx.c" break; - case 17: -#line 229 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 17: /* $@1: %empty */ +#line 229 "direct/src/dcparser/dcParser.yxx" +{ dc_file->add_import_module((yyvsp[-1].str)); } -#line 1691 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 1606 "built/tmp/dcParser.yxx.c" break; - case 20: -#line 238 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 20: /* import_symbol_list_or_star: '*' */ +#line 238 "direct/src/dcparser/dcParser.yxx" +{ dc_file->add_import_symbol("*"); } -#line 1699 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 1614 "built/tmp/dcParser.yxx.c" break; - case 21: -#line 245 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 21: /* import_symbol_list: slash_identifier */ +#line 245 "direct/src/dcparser/dcParser.yxx" +{ dc_file->add_import_symbol((yyvsp[0].str)); } -#line 1707 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 1622 "built/tmp/dcParser.yxx.c" break; - case 22: -#line 249 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 22: /* import_symbol_list: import_symbol_list ',' slash_identifier */ +#line 249 "direct/src/dcparser/dcParser.yxx" +{ dc_file->add_import_symbol((yyvsp[0].str)); } -#line 1715 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 1630 "built/tmp/dcParser.yxx.c" break; - case 23: -#line 256 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 23: /* typedef_decl: KW_TYPEDEF parameter_with_default */ +#line 256 "direct/src/dcparser/dcParser.yxx" +{ if ((yyvsp[0].u.parameter) != nullptr) { DCTypedef *dtypedef = new DCTypedef((yyvsp[0].u.parameter)); @@ -1730,49 +1645,50 @@ yyreduce: } } } -#line 1734 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 1649 "built/tmp/dcParser.yxx.c" break; - case 26: -#line 279 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 26: /* keyword_decl_list: keyword_decl_list IDENTIFIER */ +#line 279 "direct/src/dcparser/dcParser.yxx" +{ dc_file->add_keyword((yyvsp[0].str)); } -#line 1742 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 1657 "built/tmp/dcParser.yxx.c" break; - case 27: -#line 283 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 27: /* keyword_decl_list: keyword_decl_list KEYWORD */ +#line 283 "direct/src/dcparser/dcParser.yxx" +{ // This keyword has already been defined. But since we are now // explicitly defining it, clear its bitmask, so that we will have a // new hash code--doing this will allow us to phase out the // historical hash code support later. ((DCKeyword *)(yyvsp[0].u.keyword))->clear_historical_flag(); } -#line 1754 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 1669 "built/tmp/dcParser.yxx.c" break; - case 30: -#line 299 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 30: /* @2: %empty */ +#line 299 "direct/src/dcparser/dcParser.yxx" +{ + (yyval.u.dclass) = current_class; current_class = new DCClass(dc_file, (yyvsp[0].str), false, false); } -#line 1762 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 1678 "built/tmp/dcParser.yxx.c" break; - case 31: -#line 303 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 31: /* dclass: KW_DCLASS optional_name @2 dclass_derivation '{' dclass_fields '}' */ +#line 304 "direct/src/dcparser/dcParser.yxx" +{ (yyval.u.dclass) = current_class; current_class = (yyvsp[-4].u.dclass); } -#line 1771 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 1687 "built/tmp/dcParser.yxx.c" break; - case 32: -#line 311 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 32: /* dclass_name: IDENTIFIER */ +#line 312 "direct/src/dcparser/dcParser.yxx" +{ if (dc_file == nullptr) { yyerror("No DCFile available, so no class names are predefined."); (yyval.u.dclass) = nullptr; @@ -1791,22 +1707,22 @@ yyreduce: (yyval.u.dclass) = dclass; } } -#line 1795 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 1711 "built/tmp/dcParser.yxx.c" break; - case 35: -#line 339 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 35: /* dclass_base_list: dclass_name */ +#line 340 "direct/src/dcparser/dcParser.yxx" +{ if ((yyvsp[0].u.dclass) != nullptr) { current_class->add_parent((yyvsp[0].u.dclass)); } } -#line 1805 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 1721 "built/tmp/dcParser.yxx.c" break; - case 36: -#line 345 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 36: /* dclass_base_list: dclass_base_list ',' dclass_name */ +#line 346 "direct/src/dcparser/dcParser.yxx" +{ if (!dc_multiple_inheritance) { yyerror("Multiple inheritance is not supported without \"dc-multiple-inheritance 1\" in your Config.prc file."); @@ -1816,12 +1732,12 @@ yyreduce: } } } -#line 1820 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 1736 "built/tmp/dcParser.yxx.c" break; - case 39: -#line 361 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 39: /* dclass_fields: dclass_fields dclass_field ';' */ +#line 362 "direct/src/dcparser/dcParser.yxx" +{ if ((yyvsp[-1].u.field) == nullptr) { // Pass this error up. } else if (!current_class->add_field((yyvsp[-1].u.field))) { @@ -1830,12 +1746,12 @@ yyreduce: yyerror("A non-network field cannot be stored on a dclass"); } } -#line 1834 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 1750 "built/tmp/dcParser.yxx.c" break; - case 40: -#line 374 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 40: /* dclass_field: atomic_field keyword_list */ +#line 375 "direct/src/dcparser/dcParser.yxx" +{ if ((yyvsp[-1].u.field) != nullptr) { if ((yyvsp[-1].u.field)->get_name().empty()) { yyerror("Field name required."); @@ -1844,52 +1760,53 @@ yyreduce: } (yyval.u.field) = (yyvsp[-1].u.field); } -#line 1848 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 1764 "built/tmp/dcParser.yxx.c" break; - case 42: -#line 385 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 42: /* dclass_field: unnamed_parameter_with_default keyword_list */ +#line 386 "direct/src/dcparser/dcParser.yxx" +{ yyerror("Unnamed parameters are not allowed on a dclass"); if ((yyvsp[-1].u.parameter) != nullptr) { (yyvsp[-1].u.parameter)->copy_keywords(current_keyword_list); } (yyval.u.field) = (yyvsp[-1].u.parameter); } -#line 1860 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 1776 "built/tmp/dcParser.yxx.c" break; - case 43: -#line 393 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 43: /* dclass_field: named_parameter_with_default keyword_list */ +#line 394 "direct/src/dcparser/dcParser.yxx" +{ if ((yyvsp[-1].u.parameter) != nullptr) { (yyvsp[-1].u.parameter)->copy_keywords(current_keyword_list); } (yyval.u.field) = (yyvsp[-1].u.parameter); } -#line 1871 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 1787 "built/tmp/dcParser.yxx.c" break; - case 44: -#line 403 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 44: /* @3: %empty */ +#line 404 "direct/src/dcparser/dcParser.yxx" +{ + (yyval.u.dclass) = current_class; current_class = new DCClass(dc_file, (yyvsp[0].str), true, false); } -#line 1879 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 1796 "built/tmp/dcParser.yxx.c" break; - case 45: -#line 407 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 45: /* struct: KW_STRUCT optional_name @3 struct_derivation '{' struct_fields '}' */ +#line 409 "direct/src/dcparser/dcParser.yxx" +{ (yyval.u.dclass) = current_class; current_class = (yyvsp[-4].u.dclass); } -#line 1888 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 1805 "built/tmp/dcParser.yxx.c" break; - case 46: -#line 415 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 46: /* struct_name: IDENTIFIER */ +#line 417 "direct/src/dcparser/dcParser.yxx" +{ if (dc_file == nullptr) { yyerror("No DCFile available, so no struct names are predefined."); (yyval.u.dclass) = nullptr; @@ -1908,71 +1825,72 @@ yyreduce: (yyval.u.dclass) = dstruct; } } -#line 1912 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 1829 "built/tmp/dcParser.yxx.c" break; - case 49: -#line 443 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 49: /* struct_base_list: struct_name */ +#line 445 "direct/src/dcparser/dcParser.yxx" +{ if ((yyvsp[0].u.dclass) != nullptr) { current_class->add_parent((yyvsp[0].u.dclass)); } } -#line 1922 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 1839 "built/tmp/dcParser.yxx.c" break; - case 50: -#line 449 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 50: /* struct_base_list: struct_base_list ',' struct_name */ +#line 451 "direct/src/dcparser/dcParser.yxx" +{ if ((yyvsp[0].u.dclass) != nullptr) { current_class->add_parent((yyvsp[0].u.dclass)); } } -#line 1932 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 1849 "built/tmp/dcParser.yxx.c" break; - case 53: -#line 460 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 53: /* struct_fields: struct_fields struct_field ';' */ +#line 462 "direct/src/dcparser/dcParser.yxx" +{ if ((yyvsp[-1].u.field) == nullptr) { // Pass this error up. } else if (!current_class->add_field((yyvsp[-1].u.field))) { yyerror("Duplicate field name: " + (yyvsp[-1].u.field)->get_name()); } } -#line 1944 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 1861 "built/tmp/dcParser.yxx.c" break; - case 54: -#line 471 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 54: /* struct_field: atomic_field no_keyword_list */ +#line 473 "direct/src/dcparser/dcParser.yxx" +{ if ((yyvsp[-1].u.field)->get_name().empty()) { yyerror("Field name required."); } (yyval.u.field) = (yyvsp[-1].u.field); } -#line 1955 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 1872 "built/tmp/dcParser.yxx.c" break; - case 56: -#line 479 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 56: /* struct_field: unnamed_parameter_with_default no_keyword_list */ +#line 481 "direct/src/dcparser/dcParser.yxx" +{ (yyval.u.field) = (yyvsp[-1].u.parameter); } -#line 1963 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 1880 "built/tmp/dcParser.yxx.c" break; - case 57: -#line 483 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 57: /* struct_field: named_parameter_with_default no_keyword_list */ +#line 485 "direct/src/dcparser/dcParser.yxx" +{ (yyval.u.field) = (yyvsp[-1].u.parameter); } -#line 1971 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 1888 "built/tmp/dcParser.yxx.c" break; - case 58: -#line 490 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 58: /* @4: %empty */ +#line 492 "direct/src/dcparser/dcParser.yxx" +{ + (yyval.u.atomic) = current_atomic; if (current_class == nullptr) { yyerror("Cannot define a method outside of a struct or class."); DCClass *temp_class = new DCClass(dc_file, "temp", false, false); // memory leak. @@ -1981,59 +1899,59 @@ yyreduce: current_atomic = new DCAtomicField((yyvsp[-1].str), current_class, false); } } -#line 1985 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 1903 "built/tmp/dcParser.yxx.c" break; - case 59: -#line 500 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 59: /* atomic_field: optional_name '(' @4 parameter_list ')' */ +#line 503 "direct/src/dcparser/dcParser.yxx" +{ (yyval.u.field) = current_atomic; current_atomic = (yyvsp[-2].u.atomic); } -#line 1994 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 1912 "built/tmp/dcParser.yxx.c" break; - case 64: -#line 518 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 64: /* atomic_element: parameter_with_default */ +#line 521 "direct/src/dcparser/dcParser.yxx" +{ if ((yyvsp[0].u.parameter) != nullptr) { current_atomic->add_element((yyvsp[0].u.parameter)); } } -#line 2004 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 1922 "built/tmp/dcParser.yxx.c" break; - case 65: -#line 527 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 65: /* $@5: %empty */ +#line 530 "direct/src/dcparser/dcParser.yxx" +{ current_parameter = (yyvsp[0].u.parameter); } -#line 2012 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 1930 "built/tmp/dcParser.yxx.c" break; - case 66: -#line 531 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 66: /* named_parameter: type_definition $@5 parameter_definition */ +#line 534 "direct/src/dcparser/dcParser.yxx" +{ (yyval.u.parameter) = (yyvsp[0].u.parameter); } -#line 2020 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 1938 "built/tmp/dcParser.yxx.c" break; - case 69: -#line 543 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 69: /* $@6: %empty */ +#line 546 "direct/src/dcparser/dcParser.yxx" +{ current_packer = &default_packer; current_packer->clear_data(); if ((yyvsp[-1].u.parameter) != nullptr) { current_packer->begin_pack((yyvsp[-1].u.parameter)); } } -#line 2032 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 1950 "built/tmp/dcParser.yxx.c" break; - case 70: -#line 551 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 70: /* named_parameter_with_default: named_parameter '=' $@6 parameter_value */ +#line 554 "direct/src/dcparser/dcParser.yxx" +{ bool is_valid = false; if ((yyvsp[-3].u.parameter) != nullptr) { is_valid = (yyvsp[-3].u.parameter)->is_valid(); @@ -2050,24 +1968,24 @@ yyreduce: // just ignore the default value in this case. } } -#line 2054 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 1972 "built/tmp/dcParser.yxx.c" break; - case 72: -#line 573 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 72: /* $@7: %empty */ +#line 576 "direct/src/dcparser/dcParser.yxx" +{ current_packer = &default_packer; current_packer->clear_data(); if ((yyvsp[-1].u.parameter) != nullptr) { current_packer->begin_pack((yyvsp[-1].u.parameter)); } } -#line 2066 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 1984 "built/tmp/dcParser.yxx.c" break; - case 73: -#line 581 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 73: /* unnamed_parameter_with_default: unnamed_parameter '=' $@7 parameter_value */ +#line 584 "direct/src/dcparser/dcParser.yxx" +{ bool is_valid = false; if ((yyvsp[-3].u.parameter) != nullptr) { is_valid = (yyvsp[-3].u.parameter)->is_valid(); @@ -2084,60 +2002,60 @@ yyreduce: // just ignore the default value in this case. } } -#line 2088 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2006 "built/tmp/dcParser.yxx.c" break; - case 78: -#line 612 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 78: /* parameter_or_atomic: parameter */ +#line 615 "direct/src/dcparser/dcParser.yxx" +{ (yyval.u.field) = (yyvsp[0].u.parameter); } -#line 2096 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2014 "built/tmp/dcParser.yxx.c" break; - case 79: -#line 616 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 79: /* parameter_or_atomic: atomic_field */ +#line 619 "direct/src/dcparser/dcParser.yxx" +{ (yyval.u.field) = (yyvsp[0].u.field); } -#line 2104 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2022 "built/tmp/dcParser.yxx.c" break; - case 80: -#line 623 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 80: /* parameter_description: atomic_field no_keyword_list */ +#line 626 "direct/src/dcparser/dcParser.yxx" +{ (yyval.u.field) = (yyvsp[-1].u.field); } -#line 2112 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2030 "built/tmp/dcParser.yxx.c" break; - case 81: -#line 627 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 81: /* parameter_description: unnamed_parameter_with_default no_keyword_list */ +#line 630 "direct/src/dcparser/dcParser.yxx" +{ (yyval.u.field) = (yyvsp[-1].u.parameter); } -#line 2120 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2038 "built/tmp/dcParser.yxx.c" break; - case 82: -#line 631 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 82: /* parameter_description: named_parameter_with_default no_keyword_list */ +#line 634 "direct/src/dcparser/dcParser.yxx" +{ (yyval.u.field) = (yyvsp[-1].u.parameter); } -#line 2128 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2046 "built/tmp/dcParser.yxx.c" break; - case 83: -#line 638 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 83: /* simple_type_name: type_token */ +#line 641 "direct/src/dcparser/dcParser.yxx" +{ (yyval.u.parameter) = new DCSimpleParameter((yyvsp[0].u.subatomic)); } -#line 2136 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2054 "built/tmp/dcParser.yxx.c" break; - case 84: -#line 642 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 84: /* simple_type_name: simple_type_name '(' double_range ')' */ +#line 645 "direct/src/dcparser/dcParser.yxx" +{ DCSimpleParameter *simple_param = (yyvsp[-3].u.parameter)->as_simple_parameter(); nassertr(simple_param != nullptr, 0); if (!simple_param->set_range(double_range)) { @@ -2145,12 +2063,12 @@ yyreduce: } (yyval.u.parameter) = simple_param; } -#line 2149 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2067 "built/tmp/dcParser.yxx.c" break; - case 85: -#line 651 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 85: /* simple_type_name: simple_type_name '/' small_unsigned_integer */ +#line 654 "direct/src/dcparser/dcParser.yxx" +{ DCSimpleParameter *simple_param = (yyvsp[-2].u.parameter)->as_simple_parameter(); nassertr(simple_param != nullptr, 0); if (!simple_param->is_numeric_type()) { @@ -2165,12 +2083,12 @@ yyreduce: } (yyval.u.parameter) = simple_param; } -#line 2169 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2087 "built/tmp/dcParser.yxx.c" break; - case 86: -#line 667 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 86: /* simple_type_name: simple_type_name '%' number */ +#line 670 "direct/src/dcparser/dcParser.yxx" +{ DCSimpleParameter *simple_param = (yyvsp[-2].u.parameter)->as_simple_parameter(); nassertr(simple_param != nullptr, 0); if (!simple_param->is_numeric_type()) { @@ -2181,12 +2099,12 @@ yyreduce: } (yyval.u.parameter) = simple_param; } -#line 2185 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2103 "built/tmp/dcParser.yxx.c" break; - case 88: -#line 683 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 88: /* type_name: IDENTIFIER */ +#line 686 "direct/src/dcparser/dcParser.yxx" +{ if (dc_file == nullptr) { yyerror("Invalid type."); (yyval.u.parameter) = nullptr; @@ -2217,12 +2135,12 @@ yyreduce: (yyval.u.parameter) = dtypedef->make_new_parameter(); } } -#line 2221 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2139 "built/tmp/dcParser.yxx.c" break; - case 89: -#line 715 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 89: /* type_name: struct */ +#line 718 "direct/src/dcparser/dcParser.yxx" +{ // This is an inline struct definition. if ((yyvsp[0].u.dclass) == nullptr) { (yyval.u.parameter) = nullptr; @@ -2237,12 +2155,12 @@ yyreduce: (yyval.u.parameter) = new DCClassParameter((yyvsp[0].u.dclass)); } } -#line 2241 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2159 "built/tmp/dcParser.yxx.c" break; - case 90: -#line 731 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 90: /* type_name: switch */ +#line 734 "direct/src/dcparser/dcParser.yxx" +{ // This is an inline switch definition. if ((yyvsp[0].u.dswitch) == nullptr) { (yyval.u.parameter) = nullptr; @@ -2257,42 +2175,42 @@ yyreduce: (yyval.u.parameter) = new DCSwitchParameter((yyvsp[0].u.dswitch)); } } -#line 2261 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2179 "built/tmp/dcParser.yxx.c" break; - case 91: -#line 750 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 91: /* double_range: empty */ +#line 753 "direct/src/dcparser/dcParser.yxx" +{ double_range.clear(); } -#line 2269 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2187 "built/tmp/dcParser.yxx.c" break; - case 92: -#line 754 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 92: /* double_range: char_or_number */ +#line 757 "direct/src/dcparser/dcParser.yxx" +{ double_range.clear(); if (!double_range.add_range((yyvsp[0].u.real), (yyvsp[0].u.real))) { yyerror("Overlapping range"); } } -#line 2280 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2198 "built/tmp/dcParser.yxx.c" break; - case 93: -#line 761 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 93: /* double_range: char_or_number '-' char_or_number */ +#line 764 "direct/src/dcparser/dcParser.yxx" +{ double_range.clear(); if (!double_range.add_range((yyvsp[-2].u.real), (yyvsp[0].u.real))) { yyerror("Overlapping range"); } } -#line 2291 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2209 "built/tmp/dcParser.yxx.c" break; - case 94: -#line 768 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 94: /* double_range: char_or_number number */ +#line 771 "direct/src/dcparser/dcParser.yxx" +{ double_range.clear(); if ((yyvsp[0].u.real) >= 0) { yyerror("Syntax error"); @@ -2300,136 +2218,136 @@ yyreduce: yyerror("Overlapping range"); } } -#line 2304 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2222 "built/tmp/dcParser.yxx.c" break; - case 95: -#line 777 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 95: /* double_range: double_range ',' char_or_number */ +#line 780 "direct/src/dcparser/dcParser.yxx" +{ if (!double_range.add_range((yyvsp[0].u.real), (yyvsp[0].u.real))) { yyerror("Overlapping range"); } } -#line 2314 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2232 "built/tmp/dcParser.yxx.c" break; - case 96: -#line 783 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 96: /* double_range: double_range ',' char_or_number '-' char_or_number */ +#line 786 "direct/src/dcparser/dcParser.yxx" +{ if (!double_range.add_range((yyvsp[-2].u.real), (yyvsp[0].u.real))) { yyerror("Overlapping range"); } } -#line 2324 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2242 "built/tmp/dcParser.yxx.c" break; - case 97: -#line 789 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 97: /* double_range: double_range ',' char_or_number number */ +#line 792 "direct/src/dcparser/dcParser.yxx" +{ if ((yyvsp[0].u.real) >= 0) { yyerror("Syntax error"); } else if (!double_range.add_range((yyvsp[-1].u.real), -(yyvsp[0].u.real))) { yyerror("Overlapping range"); } } -#line 2336 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2254 "built/tmp/dcParser.yxx.c" break; - case 98: -#line 800 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 98: /* uint_range: empty */ +#line 803 "direct/src/dcparser/dcParser.yxx" +{ uint_range.clear(); } -#line 2344 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2262 "built/tmp/dcParser.yxx.c" break; - case 99: -#line 804 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 99: /* uint_range: char_or_uint */ +#line 807 "direct/src/dcparser/dcParser.yxx" +{ uint_range.clear(); if (!uint_range.add_range((yyvsp[0].u.s_uint), (yyvsp[0].u.s_uint))) { yyerror("Overlapping range"); } } -#line 2355 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2273 "built/tmp/dcParser.yxx.c" break; - case 100: -#line 811 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 100: /* uint_range: char_or_uint '-' char_or_uint */ +#line 814 "direct/src/dcparser/dcParser.yxx" +{ uint_range.clear(); if (!uint_range.add_range((yyvsp[-2].u.s_uint), (yyvsp[0].u.s_uint))) { yyerror("Overlapping range"); } } -#line 2366 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2284 "built/tmp/dcParser.yxx.c" break; - case 101: -#line 818 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 101: /* uint_range: char_or_uint small_negative_integer */ +#line 821 "direct/src/dcparser/dcParser.yxx" +{ uint_range.clear(); if (!uint_range.add_range((yyvsp[-1].u.s_uint), (yyvsp[0].u.s_uint))) { yyerror("Overlapping range"); } } -#line 2377 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2295 "built/tmp/dcParser.yxx.c" break; - case 102: -#line 825 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 102: /* uint_range: uint_range ',' char_or_uint */ +#line 828 "direct/src/dcparser/dcParser.yxx" +{ if (!uint_range.add_range((yyvsp[0].u.s_uint), (yyvsp[0].u.s_uint))) { yyerror("Overlapping range"); } } -#line 2387 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2305 "built/tmp/dcParser.yxx.c" break; - case 103: -#line 831 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 103: /* uint_range: uint_range ',' char_or_uint '-' char_or_uint */ +#line 834 "direct/src/dcparser/dcParser.yxx" +{ if (!uint_range.add_range((yyvsp[-2].u.s_uint), (yyvsp[0].u.s_uint))) { yyerror("Overlapping range"); } } -#line 2397 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2315 "built/tmp/dcParser.yxx.c" break; - case 104: -#line 837 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 104: /* uint_range: uint_range ',' char_or_uint small_negative_integer */ +#line 840 "direct/src/dcparser/dcParser.yxx" +{ if (!uint_range.add_range((yyvsp[-1].u.s_uint), (yyvsp[0].u.s_uint))) { yyerror("Overlapping range"); } } -#line 2407 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2325 "built/tmp/dcParser.yxx.c" break; - case 106: -#line 847 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 106: /* type_definition: type_definition '[' uint_range ']' */ +#line 850 "direct/src/dcparser/dcParser.yxx" +{ if ((yyvsp[-3].u.parameter) == nullptr) { (yyval.u.parameter) = nullptr; } else { (yyval.u.parameter) = (yyvsp[-3].u.parameter)->append_array_specification(uint_range); } } -#line 2419 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2337 "built/tmp/dcParser.yxx.c" break; - case 107: -#line 858 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 107: /* parameter_definition: IDENTIFIER */ +#line 861 "direct/src/dcparser/dcParser.yxx" +{ current_parameter->set_name((yyvsp[0].str)); (yyval.u.parameter) = current_parameter; } -#line 2428 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2346 "built/tmp/dcParser.yxx.c" break; - case 108: -#line 863 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 108: /* parameter_definition: parameter_definition '/' small_unsigned_integer */ +#line 866 "direct/src/dcparser/dcParser.yxx" +{ DCSimpleParameter *simple_param = (yyvsp[-2].u.parameter)->as_simple_parameter(); if (simple_param == nullptr || simple_param->get_typedef() != nullptr) { yyerror("A divisor is only allowed on a primitive type."); @@ -2443,12 +2361,12 @@ yyreduce: } } } -#line 2447 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2365 "built/tmp/dcParser.yxx.c" break; - case 109: -#line 878 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 109: /* parameter_definition: parameter_definition '%' number */ +#line 881 "direct/src/dcparser/dcParser.yxx" +{ DCSimpleParameter *simple_param = (yyvsp[-2].u.parameter)->as_simple_parameter(); if (simple_param == nullptr || simple_param->get_typedef() != nullptr) { yyerror("A modulus is only allowed on a primitive type."); @@ -2462,20 +2380,20 @@ yyreduce: } } } -#line 2466 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2384 "built/tmp/dcParser.yxx.c" break; - case 110: -#line 893 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 110: /* parameter_definition: parameter_definition '[' uint_range ']' */ +#line 896 "direct/src/dcparser/dcParser.yxx" +{ (yyval.u.parameter) = (yyvsp[-3].u.parameter)->append_array_specification(uint_range); } -#line 2474 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2392 "built/tmp/dcParser.yxx.c" break; - case 111: -#line 900 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 111: /* char_or_uint: STRING */ +#line 903 "direct/src/dcparser/dcParser.yxx" +{ if ((yyvsp[0].str).length() != 1) { yyerror("Single character required."); (yyval.u.s_uint) = 0; @@ -2483,24 +2401,24 @@ yyreduce: (yyval.u.s_uint) = (unsigned char)(yyvsp[0].str)[0]; } } -#line 2487 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2405 "built/tmp/dcParser.yxx.c" break; - case 113: -#line 913 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 113: /* small_unsigned_integer: UNSIGNED_INTEGER */ +#line 916 "direct/src/dcparser/dcParser.yxx" +{ (yyval.u.s_uint) = (unsigned int)(yyvsp[0].u.uint64); if ((yyval.u.s_uint) != (yyvsp[0].u.uint64)) { yyerror("Number out of range."); (yyval.u.s_uint) = 1; } } -#line 2499 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2417 "built/tmp/dcParser.yxx.c" break; - case 114: -#line 924 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 114: /* small_negative_integer: SIGNED_INTEGER */ +#line 927 "direct/src/dcparser/dcParser.yxx" +{ (yyval.u.s_uint) = (unsigned int)-(yyvsp[0].u.int64); if ((yyvsp[0].u.int64) >= 0) { yyerror("Syntax error."); @@ -2510,28 +2428,28 @@ yyreduce: (yyval.u.s_uint) = 1; } } -#line 2514 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2432 "built/tmp/dcParser.yxx.c" break; - case 117: -#line 946 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 117: /* number: unsigned_integer */ +#line 949 "direct/src/dcparser/dcParser.yxx" +{ (yyval.u.real) = (double)(yyvsp[0].u.uint64); } -#line 2522 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2440 "built/tmp/dcParser.yxx.c" break; - case 118: -#line 950 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 118: /* number: signed_integer */ +#line 953 "direct/src/dcparser/dcParser.yxx" +{ (yyval.u.real) = (double)(yyvsp[0].u.int64); } -#line 2530 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2448 "built/tmp/dcParser.yxx.c" break; - case 120: -#line 958 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 120: /* char_or_number: STRING */ +#line 961 "direct/src/dcparser/dcParser.yxx" +{ if ((yyvsp[0].str).length() != 1) { yyerror("Single character required."); (yyval.u.real) = 0; @@ -2539,19 +2457,19 @@ yyreduce: (yyval.u.real) = (double)(unsigned char)(yyvsp[0].str)[0]; } } -#line 2543 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2461 "built/tmp/dcParser.yxx.c" break; - case 122: -#line 972 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 122: /* parameter_value: parameter_actual_value */ +#line 975 "direct/src/dcparser/dcParser.yxx" +{ } -#line 2550 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2468 "built/tmp/dcParser.yxx.c" break; - case 123: -#line 975 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 123: /* $@8: %empty */ +#line 978 "direct/src/dcparser/dcParser.yxx" +{ if ((yyvsp[-1].str) != current_packer->get_current_field_name()) { ostringstream strm; strm << "Got '" << (yyvsp[-1].str) << "', expected '" @@ -2559,349 +2477,349 @@ yyreduce: yyerror(strm.str()); } } -#line 2563 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2481 "built/tmp/dcParser.yxx.c" break; - case 124: -#line 984 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 124: /* parameter_value: IDENTIFIER '=' $@8 parameter_actual_value */ +#line 987 "direct/src/dcparser/dcParser.yxx" +{ } -#line 2570 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2488 "built/tmp/dcParser.yxx.c" break; - case 125: -#line 990 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 125: /* parameter_actual_value: signed_integer */ +#line 993 "direct/src/dcparser/dcParser.yxx" +{ current_packer->pack_int64((yyvsp[0].u.int64)); } -#line 2578 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2496 "built/tmp/dcParser.yxx.c" break; - case 126: -#line 994 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 126: /* parameter_actual_value: unsigned_integer */ +#line 997 "direct/src/dcparser/dcParser.yxx" +{ current_packer->pack_uint64((yyvsp[0].u.uint64)); } -#line 2586 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2504 "built/tmp/dcParser.yxx.c" break; - case 127: -#line 998 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 127: /* parameter_actual_value: REAL */ +#line 1001 "direct/src/dcparser/dcParser.yxx" +{ current_packer->pack_double((yyvsp[0].u.real)); } -#line 2594 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2512 "built/tmp/dcParser.yxx.c" break; - case 128: -#line 1002 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 128: /* parameter_actual_value: STRING */ +#line 1005 "direct/src/dcparser/dcParser.yxx" +{ current_packer->pack_string((yyvsp[0].str)); } -#line 2602 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2520 "built/tmp/dcParser.yxx.c" break; - case 129: -#line 1006 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 129: /* parameter_actual_value: HEX_STRING */ +#line 1009 "direct/src/dcparser/dcParser.yxx" +{ current_packer->pack_literal_value((yyvsp[0].bytes)); } -#line 2610 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2528 "built/tmp/dcParser.yxx.c" break; - case 130: -#line 1010 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 130: /* $@9: %empty */ +#line 1013 "direct/src/dcparser/dcParser.yxx" +{ current_packer->push(); } -#line 2618 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2536 "built/tmp/dcParser.yxx.c" break; - case 131: -#line 1014 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 131: /* parameter_actual_value: '{' $@9 array '}' */ +#line 1017 "direct/src/dcparser/dcParser.yxx" +{ current_packer->pop(); } -#line 2626 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2544 "built/tmp/dcParser.yxx.c" break; - case 132: -#line 1018 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 132: /* $@10: %empty */ +#line 1021 "direct/src/dcparser/dcParser.yxx" +{ current_packer->push(); } -#line 2634 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2552 "built/tmp/dcParser.yxx.c" break; - case 133: -#line 1022 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 133: /* parameter_actual_value: '[' $@10 array ']' */ +#line 1025 "direct/src/dcparser/dcParser.yxx" +{ current_packer->pop(); } -#line 2642 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2560 "built/tmp/dcParser.yxx.c" break; - case 134: -#line 1026 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 134: /* $@11: %empty */ +#line 1029 "direct/src/dcparser/dcParser.yxx" +{ current_packer->push(); } -#line 2650 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2568 "built/tmp/dcParser.yxx.c" break; - case 135: -#line 1030 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 135: /* parameter_actual_value: '(' $@11 array ')' */ +#line 1033 "direct/src/dcparser/dcParser.yxx" +{ current_packer->pop(); } -#line 2658 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2576 "built/tmp/dcParser.yxx.c" break; - case 136: -#line 1034 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 136: /* parameter_actual_value: signed_integer '*' small_unsigned_integer */ +#line 1037 "direct/src/dcparser/dcParser.yxx" +{ for (unsigned int i = 0; i < (yyvsp[0].u.s_uint); i++) { current_packer->pack_int64((yyvsp[-2].u.int64)); } } -#line 2668 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2586 "built/tmp/dcParser.yxx.c" break; - case 137: -#line 1040 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 137: /* parameter_actual_value: unsigned_integer '*' small_unsigned_integer */ +#line 1043 "direct/src/dcparser/dcParser.yxx" +{ for (unsigned int i = 0; i < (yyvsp[0].u.s_uint); i++) { current_packer->pack_uint64((yyvsp[-2].u.uint64)); } } -#line 2678 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2596 "built/tmp/dcParser.yxx.c" break; - case 138: -#line 1046 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 138: /* parameter_actual_value: REAL '*' small_unsigned_integer */ +#line 1049 "direct/src/dcparser/dcParser.yxx" +{ for (unsigned int i = 0; i < (yyvsp[0].u.s_uint); i++) { current_packer->pack_double((yyvsp[-2].u.real)); } } -#line 2688 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2606 "built/tmp/dcParser.yxx.c" break; - case 139: -#line 1052 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 139: /* parameter_actual_value: HEX_STRING '*' small_unsigned_integer */ +#line 1055 "direct/src/dcparser/dcParser.yxx" +{ for (unsigned int i = 0; i < (yyvsp[0].u.s_uint); i++) { current_packer->pack_literal_value((yyvsp[-2].bytes)); } } -#line 2698 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2616 "built/tmp/dcParser.yxx.c" break; - case 146: -#line 1076 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 146: /* type_token: KW_INT8 */ +#line 1079 "direct/src/dcparser/dcParser.yxx" +{ (yyval.u.subatomic) = ST_int8; } -#line 2706 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2624 "built/tmp/dcParser.yxx.c" break; - case 147: -#line 1080 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 147: /* type_token: KW_INT16 */ +#line 1083 "direct/src/dcparser/dcParser.yxx" +{ (yyval.u.subatomic) = ST_int16; } -#line 2714 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2632 "built/tmp/dcParser.yxx.c" break; - case 148: -#line 1084 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 148: /* type_token: KW_INT32 */ +#line 1087 "direct/src/dcparser/dcParser.yxx" +{ (yyval.u.subatomic) = ST_int32; } -#line 2722 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2640 "built/tmp/dcParser.yxx.c" break; - case 149: -#line 1088 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 149: /* type_token: KW_INT64 */ +#line 1091 "direct/src/dcparser/dcParser.yxx" +{ (yyval.u.subatomic) = ST_int64; } -#line 2730 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2648 "built/tmp/dcParser.yxx.c" break; - case 150: -#line 1092 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 150: /* type_token: KW_UINT8 */ +#line 1095 "direct/src/dcparser/dcParser.yxx" +{ (yyval.u.subatomic) = ST_uint8; } -#line 2738 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2656 "built/tmp/dcParser.yxx.c" break; - case 151: -#line 1096 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 151: /* type_token: KW_UINT16 */ +#line 1099 "direct/src/dcparser/dcParser.yxx" +{ (yyval.u.subatomic) = ST_uint16; } -#line 2746 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2664 "built/tmp/dcParser.yxx.c" break; - case 152: -#line 1100 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 152: /* type_token: KW_UINT32 */ +#line 1103 "direct/src/dcparser/dcParser.yxx" +{ (yyval.u.subatomic) = ST_uint32; } -#line 2754 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2672 "built/tmp/dcParser.yxx.c" break; - case 153: -#line 1104 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 153: /* type_token: KW_UINT64 */ +#line 1107 "direct/src/dcparser/dcParser.yxx" +{ (yyval.u.subatomic) = ST_uint64; } -#line 2762 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2680 "built/tmp/dcParser.yxx.c" break; - case 154: -#line 1108 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 154: /* type_token: KW_FLOAT64 */ +#line 1111 "direct/src/dcparser/dcParser.yxx" +{ (yyval.u.subatomic) = ST_float64; } -#line 2770 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2688 "built/tmp/dcParser.yxx.c" break; - case 155: -#line 1112 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 155: /* type_token: KW_STRING */ +#line 1115 "direct/src/dcparser/dcParser.yxx" +{ (yyval.u.subatomic) = ST_string; } -#line 2778 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2696 "built/tmp/dcParser.yxx.c" break; - case 156: -#line 1116 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 156: /* type_token: KW_BLOB */ +#line 1119 "direct/src/dcparser/dcParser.yxx" +{ (yyval.u.subatomic) = ST_blob; } -#line 2786 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2704 "built/tmp/dcParser.yxx.c" break; - case 157: -#line 1120 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 157: /* type_token: KW_BLOB32 */ +#line 1123 "direct/src/dcparser/dcParser.yxx" +{ (yyval.u.subatomic) = ST_blob32; } -#line 2794 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2712 "built/tmp/dcParser.yxx.c" break; - case 158: -#line 1124 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 158: /* type_token: KW_INT8ARRAY */ +#line 1127 "direct/src/dcparser/dcParser.yxx" +{ (yyval.u.subatomic) = ST_int8array; } -#line 2802 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2720 "built/tmp/dcParser.yxx.c" break; - case 159: -#line 1128 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 159: /* type_token: KW_INT16ARRAY */ +#line 1131 "direct/src/dcparser/dcParser.yxx" +{ (yyval.u.subatomic) = ST_int16array; } -#line 2810 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2728 "built/tmp/dcParser.yxx.c" break; - case 160: -#line 1132 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 160: /* type_token: KW_INT32ARRAY */ +#line 1135 "direct/src/dcparser/dcParser.yxx" +{ (yyval.u.subatomic) = ST_int32array; } -#line 2818 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2736 "built/tmp/dcParser.yxx.c" break; - case 161: -#line 1136 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 161: /* type_token: KW_UINT8ARRAY */ +#line 1139 "direct/src/dcparser/dcParser.yxx" +{ (yyval.u.subatomic) = ST_uint8array; } -#line 2826 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2744 "built/tmp/dcParser.yxx.c" break; - case 162: -#line 1140 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 162: /* type_token: KW_UINT16ARRAY */ +#line 1143 "direct/src/dcparser/dcParser.yxx" +{ (yyval.u.subatomic) = ST_uint16array; } -#line 2834 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2752 "built/tmp/dcParser.yxx.c" break; - case 163: -#line 1144 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 163: /* type_token: KW_UINT32ARRAY */ +#line 1147 "direct/src/dcparser/dcParser.yxx" +{ (yyval.u.subatomic) = ST_uint32array; } -#line 2842 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2760 "built/tmp/dcParser.yxx.c" break; - case 164: -#line 1148 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 164: /* type_token: KW_UINT32UINT8ARRAY */ +#line 1151 "direct/src/dcparser/dcParser.yxx" +{ (yyval.u.subatomic) = ST_uint32uint8array; } -#line 2850 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2768 "built/tmp/dcParser.yxx.c" break; - case 165: -#line 1152 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 165: /* type_token: KW_CHAR */ +#line 1155 "direct/src/dcparser/dcParser.yxx" +{ (yyval.u.subatomic) = ST_char; } -#line 2858 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2776 "built/tmp/dcParser.yxx.c" break; - case 166: -#line 1159 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 166: /* keyword_list: empty */ +#line 1162 "direct/src/dcparser/dcParser.yxx" +{ current_keyword_list.clear_keywords(); } -#line 2866 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2784 "built/tmp/dcParser.yxx.c" break; - case 167: -#line 1163 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 167: /* keyword_list: keyword_list KEYWORD */ +#line 1166 "direct/src/dcparser/dcParser.yxx" +{ current_keyword_list.add_keyword((yyvsp[0].u.keyword)); } -#line 2874 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2792 "built/tmp/dcParser.yxx.c" break; - case 168: -#line 1170 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 168: /* no_keyword_list: keyword_list */ +#line 1173 "direct/src/dcparser/dcParser.yxx" +{ if (current_keyword_list.get_num_keywords() != 0) { yyerror("Communication keywords are not allowed here."); } } -#line 2884 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2802 "built/tmp/dcParser.yxx.c" break; - case 169: -#line 1179 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 169: /* $@12: %empty */ +#line 1182 "direct/src/dcparser/dcParser.yxx" +{ current_molecular = new DCMolecularField((yyvsp[-1].str), current_class); } -#line 2892 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2810 "built/tmp/dcParser.yxx.c" break; - case 170: -#line 1183 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 170: /* molecular_field: IDENTIFIER ':' $@12 molecular_atom_list */ +#line 1186 "direct/src/dcparser/dcParser.yxx" +{ (yyval.u.field) = current_molecular; } -#line 2900 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2818 "built/tmp/dcParser.yxx.c" break; - case 171: -#line 1190 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 171: /* atomic_name: IDENTIFIER */ +#line 1193 "direct/src/dcparser/dcParser.yxx" +{ DCField *field = current_class->get_field_by_name((yyvsp[0].str)); (yyval.u.atomic) = nullptr; if (field == nullptr) { @@ -2924,22 +2842,22 @@ yyreduce: } } } -#line 2928 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2846 "built/tmp/dcParser.yxx.c" break; - case 172: -#line 1217 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 172: /* molecular_atom_list: atomic_name */ +#line 1220 "direct/src/dcparser/dcParser.yxx" +{ if ((yyvsp[0].u.atomic) != nullptr) { current_molecular->add_atomic((yyvsp[0].u.atomic)); } } -#line 2938 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2856 "built/tmp/dcParser.yxx.c" break; - case 173: -#line 1223 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 173: /* molecular_atom_list: molecular_atom_list ',' atomic_name */ +#line 1226 "direct/src/dcparser/dcParser.yxx" +{ if ((yyvsp[0].u.atomic) != nullptr) { current_molecular->add_atomic((yyvsp[0].u.atomic)); if (!(yyvsp[0].u.atomic)->is_bogus_field() && !current_molecular->compare_keywords(*(yyvsp[0].u.atomic))) { @@ -2949,37 +2867,38 @@ yyreduce: } } } -#line 2953 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2871 "built/tmp/dcParser.yxx.c" break; - case 174: -#line 1237 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 174: /* optional_name: empty */ +#line 1240 "direct/src/dcparser/dcParser.yxx" +{ (yyval.str) = ""; } -#line 2961 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2879 "built/tmp/dcParser.yxx.c" break; - case 176: -#line 1245 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 176: /* @13: %empty */ +#line 1248 "direct/src/dcparser/dcParser.yxx" +{ + (yyval.u.dswitch) = current_switch; current_switch = new DCSwitch((yyvsp[-4].str), (yyvsp[-2].u.field)); } -#line 2969 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2888 "built/tmp/dcParser.yxx.c" break; - case 177: -#line 1249 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 177: /* switch: KW_SWITCH optional_name '(' parameter_or_atomic ')' '{' @13 switch_fields '}' */ +#line 1253 "direct/src/dcparser/dcParser.yxx" +{ (yyval.u.dswitch) = current_switch; - current_switch = (DCSwitch *)(yyvsp[-2].u.parameter); + current_switch = (yyvsp[-2].u.dswitch); } -#line 2978 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2897 "built/tmp/dcParser.yxx.c" break; - case 183: -#line 1263 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 183: /* switch_fields: switch_fields switch_field ';' */ +#line 1267 "direct/src/dcparser/dcParser.yxx" +{ if (!current_switch->is_field_valid()) { yyerror("case declaration required before first element"); } else if ((yyvsp[-1].u.field) != nullptr) { @@ -2988,22 +2907,22 @@ yyreduce: } } } -#line 2992 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2911 "built/tmp/dcParser.yxx.c" break; - case 184: -#line 1276 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 184: /* $@14: %empty */ +#line 1280 "direct/src/dcparser/dcParser.yxx" +{ current_packer = &default_packer; current_packer->clear_data(); current_packer->begin_pack(current_switch->get_key_parameter()); } -#line 3002 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2921 "built/tmp/dcParser.yxx.c" break; - case 185: -#line 1282 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 185: /* switch_case: KW_CASE $@14 parameter_value ':' */ +#line 1286 "direct/src/dcparser/dcParser.yxx" +{ if (!current_packer->end_pack()) { yyerror("Invalid value for switch parameter"); current_switch->add_invalid_case(); @@ -3014,45 +2933,46 @@ yyreduce: } } } -#line 3018 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2937 "built/tmp/dcParser.yxx.c" break; - case 186: -#line 1297 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 186: /* switch_default: KW_DEFAULT ':' */ +#line 1301 "direct/src/dcparser/dcParser.yxx" +{ if (!current_switch->add_default()) { yyerror("Default case already defined"); } } -#line 3028 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2947 "built/tmp/dcParser.yxx.c" break; - case 187: -#line 1306 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 187: /* switch_break: KW_BREAK */ +#line 1310 "direct/src/dcparser/dcParser.yxx" +{ current_switch->add_break(); } -#line 3036 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2955 "built/tmp/dcParser.yxx.c" break; - case 188: -#line 1313 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 188: /* switch_field: unnamed_parameter_with_default */ +#line 1317 "direct/src/dcparser/dcParser.yxx" +{ (yyval.u.field) = (yyvsp[0].u.parameter); } -#line 3044 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2963 "built/tmp/dcParser.yxx.c" break; - case 189: -#line 1317 "direct/src/dcparser/dcParser.yxx" /* yacc.c:1651 */ - { + case 189: /* switch_field: named_parameter_with_default */ +#line 1321 "direct/src/dcparser/dcParser.yxx" +{ (yyval.u.field) = (yyvsp[0].u.parameter); } -#line 3052 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2971 "built/tmp/dcParser.yxx.c" break; -#line 3056 "built/tmp/dcParser.yxx.c" /* yacc.c:1651 */ +#line 2975 "built/tmp/dcParser.yxx.c" + default: break; } /* User semantic actions sometimes alter yychar, and that requires @@ -3066,25 +2986,23 @@ yyreduce: case of YYERROR or YYBACKUP, subsequent parser actions might lead to an incorrect destructor call or verbose syntax error message before the lookahead is translated. */ - YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); + YY_SYMBOL_PRINT ("-> $$ =", YY_CAST (yysymbol_kind_t, yyr1[yyn]), &yyval, &yyloc); YYPOPSTACK (yylen); yylen = 0; - YY_STACK_PRINT (yyss, yyssp); *++yyvsp = yyval; /* Now 'shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ - - yyn = yyr1[yyn]; - - yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; - if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) - yystate = yytable[yystate]; - else - yystate = yydefgoto[yyn - YYNTOKENS]; + { + const int yylhs = yyr1[yyn] - YYNTOKENS; + const int yyi = yypgoto[yylhs] + *yyssp; + yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp + ? yytable[yyi] + : yydefgoto[yylhs]); + } goto yynewstate; @@ -3095,50 +3013,14 @@ yyreduce: yyerrlab: /* Make sure we have latest lookahead translation. See comments at user semantic actions for why this is necessary. */ - yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); - + yytoken = yychar == YYEMPTY ? YYSYMBOL_YYEMPTY : YYTRANSLATE (yychar); /* If not already recovering from an error, report this error. */ if (!yyerrstatus) { ++yynerrs; -#if ! YYERROR_VERBOSE yyerror (YY_("syntax error")); -#else -# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ - yyssp, yytoken) - { - char const *yymsgp = YY_("syntax error"); - int yysyntax_error_status; - yysyntax_error_status = YYSYNTAX_ERROR; - if (yysyntax_error_status == 0) - yymsgp = yymsg; - else if (yysyntax_error_status == 1) - { - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); - yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc); - if (!yymsg) - { - yymsg = yymsgbuf; - yymsg_alloc = sizeof yymsgbuf; - yysyntax_error_status = 2; - } - else - { - yysyntax_error_status = YYSYNTAX_ERROR; - yymsgp = yymsg; - } - } - yyerror (yymsgp); - if (yysyntax_error_status == 2) - goto yyexhaustedlab; - } -# undef YYSYNTAX_ERROR -#endif } - - if (yyerrstatus == 3) { /* If just tried and failed to reuse lookahead token after an @@ -3167,12 +3049,11 @@ yyerrlab: | yyerrorlab -- error raised explicitly by YYERROR. | `---------------------------------------------------*/ yyerrorlab: - - /* Pacify compilers like GCC when the user code never invokes - YYERROR and the label yyerrorlab therefore never appears in user - code. */ - if (/*CONSTCOND*/ 0) - goto yyerrorlab; + /* Pacify compilers when the user code never invokes YYERROR and the + label yyerrorlab therefore never appears in user code. */ + if (0) + YYERROR; + ++yynerrs; /* Do not reclaim the symbols of the rule whose action triggered this YYERROR. */ @@ -3189,13 +3070,14 @@ yyerrorlab: yyerrlab1: yyerrstatus = 3; /* Each real token shifted decrements this. */ + /* Pop stack until we find a state that shifts the error token. */ for (;;) { yyn = yypact[yystate]; if (!yypact_value_is_default (yyn)) { - yyn += YYTERROR; - if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + yyn += YYSYMBOL_YYerror; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYSYMBOL_YYerror) { yyn = yytable[yyn]; if (0 < yyn) @@ -3209,7 +3091,7 @@ yyerrlab1: yydestruct ("Error: popping", - yystos[yystate], yyvsp); + YY_ACCESSING_SYMBOL (yystate), yyvsp); YYPOPSTACK (1); yystate = *yyssp; YY_STACK_PRINT (yyss, yyssp); @@ -3221,7 +3103,7 @@ yyerrlab1: /* Shift the error token. */ - YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); + YY_SYMBOL_PRINT ("Shifting", YY_ACCESSING_SYMBOL (yyn), yyvsp, yylsp); yystate = yyn; goto yynewstate; @@ -3232,26 +3114,30 @@ yyerrlab1: `-------------------------------------*/ yyacceptlab: yyresult = 0; - goto yyreturn; + goto yyreturnlab; + /*-----------------------------------. | yyabortlab -- YYABORT comes here. | `-----------------------------------*/ yyabortlab: yyresult = 1; - goto yyreturn; + goto yyreturnlab; -#if !defined yyoverflow || YYERROR_VERBOSE -/*-------------------------------------------------. -| yyexhaustedlab -- memory exhaustion comes here. | -`-------------------------------------------------*/ + +/*-----------------------------------------------------------. +| yyexhaustedlab -- YYNOMEM (memory exhaustion) comes here. | +`-----------------------------------------------------------*/ yyexhaustedlab: yyerror (YY_("memory exhausted")); yyresult = 2; - /* Fall through. */ -#endif + goto yyreturnlab; -yyreturn: + +/*----------------------------------------------------------. +| yyreturnlab -- parsing is finished, clean up and return. | +`----------------------------------------------------------*/ +yyreturnlab: if (yychar != YYEMPTY) { /* Make sure we have latest lookahead translation. See comments at @@ -3267,16 +3153,14 @@ yyreturn: while (yyssp != yyss) { yydestruct ("Cleanup: popping", - yystos[*yyssp], yyvsp); + YY_ACCESSING_SYMBOL (+*yyssp), yyvsp); YYPOPSTACK (1); } #ifndef yyoverflow if (yyss != yyssa) YYSTACK_FREE (yyss); #endif -#if YYERROR_VERBOSE - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); -#endif + return yyresult; } + diff --git a/direct/src/dcparser/dcParser.h.prebuilt b/direct/src/dcparser/dcParser.h.prebuilt index 8880652bb0..b360dc3f19 100644 --- a/direct/src/dcparser/dcParser.h.prebuilt +++ b/direct/src/dcparser/dcParser.h.prebuilt @@ -1,8 +1,9 @@ -/* A Bison parser, made by GNU Bison 3.1. */ +/* A Bison parser, made by GNU Bison 3.8.2. */ /* Bison interface for Yacc-like parsers in C - Copyright (C) 1984, 1989-1990, 2000-2015, 2018 Free Software Foundation, Inc. + Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation, + Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -15,7 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program. If not, see . */ + along with this program. If not, see . */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work @@ -30,6 +31,10 @@ This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ +/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual, + especially those whose name start with YY_ or yy_. They are + private implementation details that can be changed or removed. */ + #ifndef YY_DCYY_BUILT_TMP_DCPARSER_YXX_H_INCLUDED # define YY_DCYY_BUILT_TMP_DCPARSER_YXX_H_INCLUDED /* Debug traces. */ @@ -40,54 +45,63 @@ extern int dcyydebug; #endif -/* Token type. */ +/* Token kinds. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE enum yytokentype { - UNSIGNED_INTEGER = 258, - SIGNED_INTEGER = 259, - REAL = 260, - STRING = 261, - IDENTIFIER = 262, - HEX_STRING = 263, - KEYWORD = 264, - KW_DCLASS = 265, - KW_STRUCT = 266, - KW_FROM = 267, - KW_IMPORT = 268, - KW_TYPEDEF = 269, - KW_KEYWORD = 270, - KW_SWITCH = 271, - KW_CASE = 272, - KW_DEFAULT = 273, - KW_BREAK = 274, - KW_INT8 = 275, - KW_INT16 = 276, - KW_INT32 = 277, - KW_INT64 = 278, - KW_UINT8 = 279, - KW_UINT16 = 280, - KW_UINT32 = 281, - KW_UINT64 = 282, - KW_FLOAT64 = 283, - KW_STRING = 284, - KW_BLOB = 285, - KW_BLOB32 = 286, - KW_INT8ARRAY = 287, - KW_INT16ARRAY = 288, - KW_INT32ARRAY = 289, - KW_UINT8ARRAY = 290, - KW_UINT16ARRAY = 291, - KW_UINT32ARRAY = 292, - KW_UINT32UINT8ARRAY = 293, - KW_CHAR = 294, - START_DC = 295, - START_PARAMETER_VALUE = 296, - START_PARAMETER_DESCRIPTION = 297 + YYEMPTY = -2, + YYEOF = 0, /* "end of file" */ + YYerror = 256, /* error */ + YYUNDEF = 257, /* "invalid token" */ + UNSIGNED_INTEGER = 258, /* UNSIGNED_INTEGER */ + SIGNED_INTEGER = 259, /* SIGNED_INTEGER */ + REAL = 260, /* REAL */ + STRING = 261, /* STRING */ + IDENTIFIER = 262, /* IDENTIFIER */ + HEX_STRING = 263, /* HEX_STRING */ + KEYWORD = 264, /* KEYWORD */ + KW_DCLASS = 265, /* KW_DCLASS */ + KW_STRUCT = 266, /* KW_STRUCT */ + KW_FROM = 267, /* KW_FROM */ + KW_IMPORT = 268, /* KW_IMPORT */ + KW_TYPEDEF = 269, /* KW_TYPEDEF */ + KW_KEYWORD = 270, /* KW_KEYWORD */ + KW_SWITCH = 271, /* KW_SWITCH */ + KW_CASE = 272, /* KW_CASE */ + KW_DEFAULT = 273, /* KW_DEFAULT */ + KW_BREAK = 274, /* KW_BREAK */ + KW_INT8 = 275, /* KW_INT8 */ + KW_INT16 = 276, /* KW_INT16 */ + KW_INT32 = 277, /* KW_INT32 */ + KW_INT64 = 278, /* KW_INT64 */ + KW_UINT8 = 279, /* KW_UINT8 */ + KW_UINT16 = 280, /* KW_UINT16 */ + KW_UINT32 = 281, /* KW_UINT32 */ + KW_UINT64 = 282, /* KW_UINT64 */ + KW_FLOAT64 = 283, /* KW_FLOAT64 */ + KW_STRING = 284, /* KW_STRING */ + KW_BLOB = 285, /* KW_BLOB */ + KW_BLOB32 = 286, /* KW_BLOB32 */ + KW_INT8ARRAY = 287, /* KW_INT8ARRAY */ + KW_INT16ARRAY = 288, /* KW_INT16ARRAY */ + KW_INT32ARRAY = 289, /* KW_INT32ARRAY */ + KW_UINT8ARRAY = 290, /* KW_UINT8ARRAY */ + KW_UINT16ARRAY = 291, /* KW_UINT16ARRAY */ + KW_UINT32ARRAY = 292, /* KW_UINT32ARRAY */ + KW_UINT32UINT8ARRAY = 293, /* KW_UINT32UINT8ARRAY */ + KW_CHAR = 294, /* KW_CHAR */ + START_DC = 295, /* START_DC */ + START_PARAMETER_VALUE = 296, /* START_PARAMETER_VALUE */ + START_PARAMETER_DESCRIPTION = 297 /* START_PARAMETER_DESCRIPTION */ }; + typedef enum yytokentype yytoken_kind_t; #endif -/* Tokens. */ +/* Token kinds. */ +#define YYEMPTY -2 +#define YYEOF 0 +#define YYerror 256 +#define YYUNDEF 257 #define UNSIGNED_INTEGER 258 #define SIGNED_INTEGER 259 #define REAL 260 @@ -134,6 +148,8 @@ extern int dcyydebug; extern YYSTYPE dcyylval; + int dcyyparse (void); + #endif /* !YY_DCYY_BUILT_TMP_DCPARSER_YXX_H_INCLUDED */ diff --git a/direct/src/dcparser/dcParser.yxx b/direct/src/dcparser/dcParser.yxx index b283c3314b..9918ea99ba 100644 --- a/direct/src/dcparser/dcParser.yxx +++ b/direct/src/dcparser/dcParser.yxx @@ -297,6 +297,7 @@ dclass_or_struct: dclass: KW_DCLASS optional_name { + $$ = current_class; current_class = new DCClass(dc_file, $2, false, false); } dclass_derivation '{' dclass_fields '}' @@ -401,6 +402,7 @@ dclass_field: struct: KW_STRUCT optional_name { + $$ = current_class; current_class = new DCClass(dc_file, $2, true, false); } struct_derivation '{' struct_fields '}' @@ -488,6 +490,7 @@ struct_field: atomic_field: optional_name '(' { + $$ = current_atomic; if (current_class == nullptr) { yyerror("Cannot define a method outside of a struct or class."); DCClass *temp_class = new DCClass(dc_file, "temp", false, false); // memory leak. @@ -1243,12 +1246,13 @@ optional_name: switch: KW_SWITCH optional_name '(' parameter_or_atomic ')' '{' { + $$ = current_switch; current_switch = new DCSwitch($2, $4); } switch_fields '}' { $$ = current_switch; - current_switch = (DCSwitch *)$7; + current_switch = $7; } ; From f80cd0899309d6b1431f3fa1befb9d8717c46619 Mon Sep 17 00:00:00 2001 From: rdb Date: Fri, 4 Aug 2023 14:20:59 +0200 Subject: [PATCH 56/84] Remove support for EOL Python versions 3.6 and 3.7 --- .github/workflows/ci.yml | 46 -------------------- direct/src/showbase/ContainerLeakDetector.py | 3 +- direct/src/showbase/ContainerReport.py | 3 +- makepanda/makepanda.py | 4 +- makepanda/makepandacore.py | 19 ++------ makepanda/makewheel.py | 19 ++------ panda/src/event/asyncFuture_ext.cxx | 20 --------- setup.cfg | 2 - tests/dtoolutil/test_filename.py | 2 - tests/event/test_futures.py | 6 +-- tests/pgraph/test_loader_types.py | 1 - 11 files changed, 11 insertions(+), 114 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bfddcd515e..f6ffb17719 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -180,38 +180,6 @@ jobs: run: cmake --build . --config ${{ matrix.config }} --parallel 4 # END A - - name: Setup Python (Python 3.7) - if: contains(matrix.python, 'YES') - uses: actions/setup-python@v4 - with: - python-version: '3.7' - - name: Configure (Python 3.7) - if: contains(matrix.python, 'YES') - working-directory: build - shell: bash - run: > - cmake -DWANT_PYTHON_VERSION=3.7 -DHAVE_PYTHON=YES - -DPython_FIND_REGISTRY=NEVER -DPython_ROOT="$pythonLocation" . - - name: Build (Python 3.7) - if: contains(matrix.python, 'YES') - # BEGIN A - working-directory: build - run: cmake --build . --config ${{ matrix.config }} --parallel 4 - # END A - - name: Test (Python 3.7) - # BEGIN B - if: contains(matrix.python, 'YES') - working-directory: build - shell: bash - env: - PYTHONPATH: ${{ matrix.config }} - run: | - PYTHON_EXECUTABLE=$(grep 'Python_EXECUTABLE:' CMakeCache.txt | sed 's/.*=//') - $PYTHON_EXECUTABLE -m pip install -r ../requirements-test.txt - export COVERAGE_FILE=.coverage.$RANDOM LLVM_PROFILE_FILE=$PWD/pid-%p.profraw - $PYTHON_EXECUTABLE -m pytest ../tests --cov=. - # END B - - name: Setup Python (Python 3.8) if: contains(matrix.python, 'YES') uses: actions/setup-python@v4 @@ -443,20 +411,6 @@ jobs: python -m pip install -r requirements-test.txt PYTHONPATH=built LD_LIBRARY_PATH=built/lib DYLD_LIBRARY_PATH=built/lib python -m pytest - - name: Set up Python 3.7 - uses: actions/setup-python@v4 - with: - python-version: '3.7' - - name: Build Python 3.7 - shell: bash - run: | - python makepanda/makepanda.py --git-commit=${{github.sha}} --outputdir=built --everything --no-eigen --python-incdir="$pythonLocation/include" --python-libdir="$pythonLocation/lib" --verbose --threads=4 --windows-sdk=10 - - name: Test Python 3.7 - shell: bash - run: | - python -m pip install -r requirements-test.txt - PYTHONPATH=built LD_LIBRARY_PATH=built/lib DYLD_LIBRARY_PATH=built/lib python -m pytest - - name: Make installer run: | python makepanda/makepackage.py --verbose --lzma diff --git a/direct/src/showbase/ContainerLeakDetector.py b/direct/src/showbase/ContainerLeakDetector.py index b172cbb4e3..ef1949f33c 100755 --- a/direct/src/showbase/ContainerLeakDetector.py +++ b/direct/src/showbase/ContainerLeakDetector.py @@ -11,7 +11,6 @@ import types import weakref import random import builtins -import sys deadEndTypes = frozenset(( @@ -566,7 +565,7 @@ class FindContainers(Job): curObjRef = None # types.CellType was added in Python 3.8 - if sys.version_info >= (3, 8) and type(curObj) is types.CellType: + if type(curObj) is types.CellType: child = curObj.cell_contents hasLength = self._hasLength(child) notDeadEnd = not self._isDeadEnd(child) diff --git a/direct/src/showbase/ContainerReport.py b/direct/src/showbase/ContainerReport.py index 6ceca73d07..71468bfbf6 100755 --- a/direct/src/showbase/ContainerReport.py +++ b/direct/src/showbase/ContainerReport.py @@ -5,7 +5,6 @@ from direct.showbase.Job import Job from direct.showbase.JobManagerGlobal import jobMgr from direct.showbase.ContainerLeakDetector import deadEndTypes import types -import sys import io @@ -122,7 +121,7 @@ class ContainerReport(Job): continue # types.CellType was added in Python 3.8 - if sys.version_info >= (3, 8) and type(parentObj) is types.CellType: + if type(parentObj) is types.CellType: child = parentObj.cell_contents if self._examine(child): assert (self._queue.back() is child) diff --git a/makepanda/makepanda.py b/makepanda/makepanda.py index 3ee9778097..1efb46cf21 100755 --- a/makepanda/makepanda.py +++ b/makepanda/makepanda.py @@ -9,8 +9,8 @@ ######################################################################## import sys -if sys.version_info < (3, 6): - print("This version of Python is not supported, use version 3.6 or higher.") +if sys.version_info < (3, 8): + print("This version of Python is not supported, use version 3.8 or higher.") exit(1) try: diff --git a/makepanda/makepandacore.py b/makepanda/makepandacore.py index 8096af175c..964914c1fb 100644 --- a/makepanda/makepandacore.py +++ b/makepanda/makepandacore.py @@ -3390,20 +3390,7 @@ def GetPythonABI(): if soabi: return soabi - soabi = 'cpython-%d%d' % (sys.version_info[:2]) - - if sys.version_info >= (3, 8): - return soabi - - debug_flag = sysconfig.get_config_var('Py_DEBUG') - if (debug_flag is None and hasattr(sys, 'gettotalrefcount')) or debug_flag: - soabi += 'd' - - malloc_flag = sysconfig.get_config_var('WITH_PYMALLOC') - if malloc_flag is None or malloc_flag: - soabi += 'm' - - return soabi + return 'cpython-%d%d' % (sys.version_info[:2]) def CalcLocation(fn, ipath): if fn.startswith("panda3d/") and fn.endswith(".py"): @@ -3545,7 +3532,7 @@ def UpdatePythonVersionInfoFile(new_info): version_info["soabi"] == new_info["soabi"] or \ not os.path.isfile(core_pyd) or \ version_info["version"].split(".", 1)[0] == "2" or \ - version_info["version"] in ("3.0", "3.1", "3.2", "3.3", "3.4", "3.5"): + version_info["version"] in ("3.0", "3.1", "3.2", "3.3", "3.4", "3.5", "3.6", "3.7"): json_data.remove(version_info) if not PkgSkip("PYTHON"): @@ -3570,7 +3557,7 @@ def ReadPythonVersionInfoFile(): # Don't include unsupported versions of Python. for version_info in json_data[:]: - if version_info["version"] in ("2.6", "2.7", "3.0", "3.1", "3.2", "3.3", "3.4"): + if version_info["version"] in ("2.6", "2.7", "3.0", "3.1", "3.2", "3.3", "3.4", "3.5", "3.6", "3.7"): json_data.remove(version_info) return json_data diff --git a/makepanda/makewheel.py b/makepanda/makewheel.py index d770fd2a4e..5b647e6a7c 100644 --- a/makepanda/makewheel.py +++ b/makepanda/makewheel.py @@ -24,20 +24,7 @@ def get_abi_tag(): elif soabi: return soabi.replace('.', '_').replace('-', '_') - soabi = 'cp%d%d' % (sys.version_info[:2]) - - if sys.version_info >= (3, 8): - return soabi - - debug_flag = get_config_var('Py_DEBUG') - if (debug_flag is None and hasattr(sys, 'gettotalrefcount')) or debug_flag: - soabi += 'd' - - malloc_flag = get_config_var('WITH_PYMALLOC') - if malloc_flag is None or malloc_flag: - soabi += 'm' - - return soabi + return 'cp%d%d' % (sys.version_info[:2]) def is_exe_file(path): @@ -635,8 +622,8 @@ def makewheel(version, output_dir, platform=None): if not LocateBinary("patchelf"): raise Exception("patchelf is required when building a Linux wheel.") - if sys.version_info < (3, 6): - raise Exception("Python 3.6 or higher is required to produce a wheel.") + if sys.version_info < (3, 8): + raise Exception("Python 3.8 or higher is required to produce a wheel.") if platform is None: # Determine the platform from the build. diff --git a/panda/src/event/asyncFuture_ext.cxx b/panda/src/event/asyncFuture_ext.cxx index 45a736fe19..eaed216bfe 100644 --- a/panda/src/event/asyncFuture_ext.cxx +++ b/panda/src/event/asyncFuture_ext.cxx @@ -275,11 +275,7 @@ result(PyObject *self, PyObject *timeout) const { static PyObject *exc_type = nullptr; if (exc_type == nullptr) { // Get the TimeoutError that asyncio uses, too. -#if PY_VERSION_HEX >= 0x03080000 PyObject *module = PyImport_ImportModule("asyncio.exceptions"); -#else - PyObject *module = PyImport_ImportModule("concurrent.futures._base"); -#endif if (module != nullptr) { exc_type = PyObject_GetAttrString(module, "TimeoutError"); Py_DECREF(module); @@ -289,15 +285,9 @@ result(PyObject *self, PyObject *timeout) const { } // If we can't get that, we should pretend and make our own. if (exc_type == nullptr) { -#if PY_VERSION_HEX >= 0x03080000 exc_type = PyErr_NewExceptionWithDoc((char*)"asyncio.exceptions.TimeoutError", (char*)"The operation exceeded the given deadline.", nullptr, nullptr); -#else - exc_type = PyErr_NewExceptionWithDoc((char*)"concurrent.futures._base.TimeoutError", - (char*)"The operation exceeded the given deadline.", - nullptr, nullptr); -#endif } } PyErr_SetNone(exc_type); @@ -403,11 +393,7 @@ get_cancelled_error_type() { PyErr_Fetch(&curexc_type, &curexc_value, &curexc_traceback); // Get the CancelledError that asyncio uses, too. -#if PY_VERSION_HEX >= 0x03080000 PyObject *module = PyImport_ImportModule("asyncio.exceptions"); -#else - PyObject *module = PyImport_ImportModule("concurrent.futures._base"); -#endif if (module != nullptr) { exc_type = PyObject_GetAttrString(module, "CancelledError"); Py_DECREF(module); @@ -415,15 +401,9 @@ get_cancelled_error_type() { // If we can't get that, we should pretend and make our own. if (exc_type == nullptr) { -#if PY_VERSION_HEX >= 0x03080000 exc_type = PyErr_NewExceptionWithDoc((char *)"asyncio.exceptions.CancelledError", (char *)"The Future or Task was cancelled.", PyExc_BaseException, nullptr); -#else - exc_type = PyErr_NewExceptionWithDoc((char *)"concurrent.futures._base.CancelledError", - (char *)"The Future was cancelled.", - nullptr, nullptr); -#endif } PyErr_Restore(curexc_type, curexc_value, curexc_traceback); diff --git a/setup.cfg b/setup.cfg index 993e2f1108..50078db334 100644 --- a/setup.cfg +++ b/setup.cfg @@ -14,8 +14,6 @@ classifiers = Programming Language :: C++ Programming Language :: Python Programming Language :: Python :: 3 - Programming Language :: Python :: 3.6 - Programming Language :: Python :: 3.7 Programming Language :: Python :: 3.8 Programming Language :: Python :: 3.9 Programming Language :: Python :: 3.10 diff --git a/tests/dtoolutil/test_filename.py b/tests/dtoolutil/test_filename.py index d1a6fe5dd4..13692e0784 100644 --- a/tests/dtoolutil/test_filename.py +++ b/tests/dtoolutil/test_filename.py @@ -3,13 +3,11 @@ import sys, os import pytest -@pytest.mark.skipif(sys.version_info < (3, 6), reason="Requires Python 3.6") def test_filename_fspath(): fn = Filename.from_os_specific(__file__) assert os.fspath(fn) == fn.to_os_specific_w() -@pytest.mark.skipif(sys.version_info < (3, 6), reason="Requires Python 3.6") def test_filename_open(): fn = Filename.from_os_specific(__file__) open(fn, 'rb') diff --git a/tests/event/test_futures.py b/tests/event/test_futures.py index 3bc1ede617..fb5c1626cf 100644 --- a/tests/event/test_futures.py +++ b/tests/event/test_futures.py @@ -2,11 +2,7 @@ from panda3d import core import pytest import time import sys - -if sys.version_info >= (3, 8): - from asyncio.exceptions import TimeoutError, CancelledError -else: - from concurrent.futures._base import TimeoutError, CancelledError +from asyncio.exceptions import TimeoutError, CancelledError class MockFuture: diff --git a/tests/pgraph/test_loader_types.py b/tests/pgraph/test_loader_types.py index 2a0114852f..672cf94680 100644 --- a/tests/pgraph/test_loader_types.py +++ b/tests/pgraph/test_loader_types.py @@ -221,7 +221,6 @@ def test_loader_ram_cache(test_filename): ModelPool.release_model(model2) -@pytest.mark.skipif(sys.version_info < (3, 4), reason="Requires Python 3.4") def test_loader_file_type_registry_pickle(): from direct.stdpy.pickle import dumps, loads From ab93d88f1baa265f79f32e60442569a804bde3e6 Mon Sep 17 00:00:00 2001 From: rdb Date: Fri, 4 Aug 2023 14:28:52 +0200 Subject: [PATCH 57/84] stdpy: Remove obsolete check for None function on module shutdown This behaviour was removed in Python 3.4 so should no longer be an issue --- direct/src/stdpy/threading.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/direct/src/stdpy/threading.py b/direct/src/stdpy/threading.py index 96effd86b5..e4e7a1d24f 100644 --- a/direct/src/stdpy/threading.py +++ b/direct/src/stdpy/threading.py @@ -123,10 +123,7 @@ class Thread(ThreadBase): self.__dict__['ident'] = threadId def __del__(self): - # On interpreter shutdown, the _thread module might have - # already been cleaned up. - if _thread and _thread._remove_thread_id: - _thread._remove_thread_id(self.ident) + _thread._remove_thread_id(self.ident) def is_alive(self): thread = self.__thread From 32edfa43fd6dca3055030e8d9410a7e01584a3a3 Mon Sep 17 00:00:00 2001 From: WMOkiishi Date: Fri, 4 Aug 2023 14:31:11 +0200 Subject: [PATCH 58/84] direct: Get direct to pass a mypy check Closes #1476 --- .github/workflows/mypy.yml | 23 ++ direct/src/directbase/DirectStart.py | 2 +- direct/src/directbase/TestStart.py | 2 +- direct/src/directbase/ThreeUpStart.py | 2 +- direct/src/directdevices/DirectJoybox.py | 8 +- direct/src/distributed/AsyncRequest.py | 4 +- direct/src/distributed/CachedDOData.py | 7 + direct/src/distributed/DistributedObjectAI.py | 4 +- direct/src/distributed/DistributedObjectUD.py | 2 +- direct/src/distributed/DoInterestManager.py | 6 +- direct/src/distributed/GridParent.py | 6 +- direct/src/distributed/MsgTypes.py | 252 +++++++++--------- direct/src/distributed/MsgTypesCMU.py | 33 ++- direct/src/fsm/ClassicFSM.py | 4 +- direct/src/fsm/State.py | 4 +- direct/src/fsm/StatePush.py | 2 + direct/src/gui/DirectDialog.py | 4 +- direct/src/gui/DirectGuiBase.py | 4 +- direct/src/gui/DirectGuiGlobals.py | 2 +- direct/src/interval/FunctionInterval.py | 4 +- direct/src/interval/IntervalTest.py | 12 +- direct/src/leveleditor/LevelEditorStart.py | 2 +- direct/src/leveleditor/testData.py | 3 +- direct/src/motiontrail/MotionTrail.py | 4 +- direct/src/showbase/ContainerLeakDetector.py | 4 +- direct/src/showbase/ContainerReport.py | 4 +- direct/src/showbase/DConfig.py | 2 +- direct/src/showbase/DistancePhasedNode.py | 4 +- direct/src/showbase/ExceptionVarDump.py | 2 +- direct/src/showbase/ObjectReport.py | 6 +- direct/src/showbase/PythonUtil.py | 103 +++---- direct/src/showbase/ShowBase.py | 2 +- direct/src/showbase/ShowBaseGlobal.py | 6 +- direct/src/showbase/VerboseImport.py | 2 +- direct/src/stdpy/pickle.py | 4 +- direct/src/stdpy/threading.py | 4 +- direct/src/stdpy/threading2.py | 2 +- direct/src/task/Task.py | 2 +- direct/src/tkwidgets/AppShell.py | 4 +- direct/src/wxwidgets/ViewPort.py | 6 +- direct/src/wxwidgets/WxPandaStart.py | 3 +- direct/src/wxwidgets/WxPandaWindow.py | 2 +- mypy.ini | 13 + tests/run_mypy.py | 25 ++ 44 files changed, 352 insertions(+), 244 deletions(-) create mode 100644 .github/workflows/mypy.yml create mode 100644 mypy.ini create mode 100644 tests/run_mypy.py diff --git a/.github/workflows/mypy.yml b/.github/workflows/mypy.yml new file mode 100644 index 0000000000..1266bfddfb --- /dev/null +++ b/.github/workflows/mypy.yml @@ -0,0 +1,23 @@ +name: Run Mypy +on: [push, pull_request] + +jobs: + mypy: + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, macos-latest, windows-latest] + python-version: ['3.8', '3.11'] + fail-fast: false + steps: + - uses: actions/checkout@v3 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install mypy==1.4.0 + - name: Run mypy on direct + run: python tests/run_mypy.py diff --git a/direct/src/directbase/DirectStart.py b/direct/src/directbase/DirectStart.py index ea51d43fc9..2983c0b821 100644 --- a/direct/src/directbase/DirectStart.py +++ b/direct/src/directbase/DirectStart.py @@ -15,7 +15,7 @@ to and may be replaced by the following code: base = ShowBase() """ -__all__ = [] +__all__ = () if __debug__: print('Using deprecated DirectStart interface.') diff --git a/direct/src/directbase/TestStart.py b/direct/src/directbase/TestStart.py index b3602c9127..bdbab206e5 100755 --- a/direct/src/directbase/TestStart.py +++ b/direct/src/directbase/TestStart.py @@ -6,7 +6,7 @@ from direct.showbase import ShowBase base = ShowBase.ShowBase() # Put an axis in the world: -base.loader.loadModel("models/misc/xyzAxis").reparentTo(render) +base.loader.loadModel("models/misc/xyzAxis").reparentTo(base.render) base.camera.setPosHpr(0, -10.0, 0, 0, 0, 0) base.camLens.setFov(52.0) diff --git a/direct/src/directbase/ThreeUpStart.py b/direct/src/directbase/ThreeUpStart.py index dbdf6eb88a..3ca50b34fe 100644 --- a/direct/src/directbase/ThreeUpStart.py +++ b/direct/src/directbase/ThreeUpStart.py @@ -8,7 +8,7 @@ from direct.showbase import ThreeUpShow base = ThreeUpShow.ThreeUpShow() # Put an axis in the world: -base.loader.loadModel("models/misc/xyzAxis").reparentTo(render) +base.loader.loadModel("models/misc/xyzAxis").reparentTo(base.render) base.camera.setPosHpr(0, -10.0, 0, 0, 0, 0) base.camLens.setFov(52.0) diff --git a/direct/src/directdevices/DirectJoybox.py b/direct/src/directdevices/DirectJoybox.py index 2f5026504b..45daf64ee1 100644 --- a/direct/src/directdevices/DirectJoybox.py +++ b/direct/src/directdevices/DirectJoybox.py @@ -41,8 +41,12 @@ class DirectJoybox(DirectObject): xyzMultiplier = 1.0 hprMultiplier = 1.0 - def __init__(self, device = 'CerealBox', nodePath = base.direct.camera, - headingNP = base.direct.camera): + def __init__(self, device = 'CerealBox', nodePath = None, headingNP = None): + from direct.showbase.ShowBaseGlobal import base + if nodePath is None: + nodePath = base.direct.camera + if headingNP is None: + headingNP = base.direct.camera # See if device manager has been initialized if base.direct.deviceManager is None: base.direct.deviceManager = DirectDeviceManager() diff --git a/direct/src/distributed/AsyncRequest.py b/direct/src/distributed/AsyncRequest.py index 105d83837d..113c2aa31a 100755 --- a/direct/src/distributed/AsyncRequest.py +++ b/direct/src/distributed/AsyncRequest.py @@ -1,3 +1,5 @@ +from __future__ import annotations + #from otp.ai.AIBaseGlobal import * from direct.directnotify import DirectNotifyGlobal from direct.showbase.DirectObject import DirectObject @@ -39,7 +41,7 @@ class AsyncRequest(DirectObject): will be called again when the new self.neededObjects is complete. You may repeat this as necessary. """ - _asyncRequests = {} + _asyncRequests: dict[int, AsyncRequest] = {} notify = DirectNotifyGlobal.directNotify.newCategory('AsyncRequest') diff --git a/direct/src/distributed/CachedDOData.py b/direct/src/distributed/CachedDOData.py index 99a600c05b..63afd2d9b7 100755 --- a/direct/src/distributed/CachedDOData.py +++ b/direct/src/distributed/CachedDOData.py @@ -20,3 +20,10 @@ class CachedDOData: # override and destroy the cached data # cached data is typically created by the DistributedObject and destroyed here pass + + # These next two methods tell mypy to allow arbitrary attributes. + def __getattribute__(self, name: str): + return object.__getattribute__(self, name) + + def __setattr__(self, name: str, value) -> None: + object.__setattr__(self, name, value) diff --git a/direct/src/distributed/DistributedObjectAI.py b/direct/src/distributed/DistributedObjectAI.py index 94de96abd5..b67ee57d1e 100644 --- a/direct/src/distributed/DistributedObjectAI.py +++ b/direct/src/distributed/DistributedObjectAI.py @@ -299,7 +299,7 @@ class DistributedObjectAI(DistributedObjectBase): # setLocation destroys self._zoneData if we move away to # a different zone if self._zoneData is None: - from otp.ai.AIZoneData import AIZoneData + from otp.ai.AIZoneData import AIZoneData # type: ignore[import] self._zoneData = AIZoneData(self.air, self.parentId, self.zoneId) return self._zoneData @@ -489,7 +489,7 @@ class DistributedObjectAI(DistributedObjectBase): # simultaneously on different lists of avatars, although they # should have different names. - from otp.ai import Barrier + from otp.ai import Barrier # type: ignore[import] context = self.__nextBarrierContext # We assume the context number is passed as a uint16. self.__nextBarrierContext = (self.__nextBarrierContext + 1) & 0xffff diff --git a/direct/src/distributed/DistributedObjectUD.py b/direct/src/distributed/DistributedObjectUD.py index 6874185a86..341ce41616 100755 --- a/direct/src/distributed/DistributedObjectUD.py +++ b/direct/src/distributed/DistributedObjectUD.py @@ -424,7 +424,7 @@ class DistributedObjectUD(DistributedObjectBase): # simultaneously on different lists of avatars, although they # should have different names. - from otp.ai import Barrier + from otp.ai import Barrier # type: ignore[import] context = self.__nextBarrierContext # We assume the context number is passed as a uint16. self.__nextBarrierContext = (self.__nextBarrierContext + 1) & 0xffff diff --git a/direct/src/distributed/DoInterestManager.py b/direct/src/distributed/DoInterestManager.py index 251e0b91a1..5876a7ae91 100755 --- a/direct/src/distributed/DoInterestManager.py +++ b/direct/src/distributed/DoInterestManager.py @@ -7,6 +7,8 @@ zone, remove interest in that zone. p.s. A great deal of this code is just code moved from ClientRepository.py. """ +from __future__ import annotations + from panda3d.core import ConfigVariableBool from .MsgTypes import CLIENT_ADD_INTEREST, CLIENT_ADD_INTEREST_MULTIPLE, CLIENT_REMOVE_INTEREST from direct.showbase import DirectObject @@ -98,9 +100,9 @@ class DoInterestManager(DirectObject.DirectObject): _ContextIdSerialNum = 100 _ContextIdMask = 0x3FFFFFFF # avoid making Python create a long - _interests = {} + _interests: dict[int, InterestState] = {} if __debug__: - _debug_interestHistory = [] + _debug_interestHistory: list[tuple] = [] _debug_maxDescriptionLen = 40 _SerialGen = SerialNumGen() diff --git a/direct/src/distributed/GridParent.py b/direct/src/distributed/GridParent.py index 3a38ae5d3a..2212ae39e5 100755 --- a/direct/src/distributed/GridParent.py +++ b/direct/src/distributed/GridParent.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from panda3d.core import NodePath # @@ -13,8 +15,8 @@ from panda3d.core import NodePath class GridParent: # this lets GridParents share CellOrigins - GridZone2CellOrigin = {} - GridZone2count = {} + GridZone2CellOrigin: dict[tuple, NodePath] = {} + GridZone2count: dict[tuple, int] = {} @staticmethod def getCellOrigin(grid, zoneId): tup = (grid, zoneId) diff --git a/direct/src/distributed/MsgTypes.py b/direct/src/distributed/MsgTypes.py index e595d3d88a..3e0a204a0c 100644 --- a/direct/src/distributed/MsgTypes.py +++ b/direct/src/distributed/MsgTypes.py @@ -1,143 +1,145 @@ """MsgTypes module: contains distributed object message types""" +from __future__ import annotations + from direct.showbase.PythonUtil import invertDictLossless -MsgName2Id = { - 'CLIENT_HELLO': 1, - 'CLIENT_HELLO_RESP': 2, +CLIENT_HELLO = 1 +CLIENT_HELLO_RESP = 2 - # Sent by the client when it's leaving. - 'CLIENT_DISCONNECT': 3, +# Sent by the client when it's leaving. +CLIENT_DISCONNECT = 3 - # Sent by the server when it is dropping the connection deliberately. - 'CLIENT_EJECT': 4, +# Sent by the server when it is dropping the connection deliberately. +CLIENT_EJECT = 4 - 'CLIENT_HEARTBEAT': 5, +CLIENT_HEARTBEAT = 5 - 'CLIENT_OBJECT_SET_FIELD': 120, - 'CLIENT_OBJECT_SET_FIELDS': 121, - 'CLIENT_OBJECT_LEAVING': 132, - 'CLIENT_OBJECT_LEAVING_OWNER': 161, - 'CLIENT_ENTER_OBJECT_REQUIRED': 142, - 'CLIENT_ENTER_OBJECT_REQUIRED_OTHER': 143, - 'CLIENT_ENTER_OBJECT_REQUIRED_OWNER': 172, - 'CLIENT_ENTER_OBJECT_REQUIRED_OTHER_OWNER': 173, +CLIENT_OBJECT_SET_FIELD = 120 +CLIENT_OBJECT_SET_FIELDS = 121 +CLIENT_OBJECT_LEAVING = 132 +CLIENT_OBJECT_LEAVING_OWNER = 161 +CLIENT_ENTER_OBJECT_REQUIRED = 142 +CLIENT_ENTER_OBJECT_REQUIRED_OTHER = 143 +CLIENT_ENTER_OBJECT_REQUIRED_OWNER = 172 +CLIENT_ENTER_OBJECT_REQUIRED_OTHER_OWNER = 173 - 'CLIENT_DONE_INTEREST_RESP': 204, +CLIENT_DONE_INTEREST_RESP = 204 - 'CLIENT_ADD_INTEREST': 200, - 'CLIENT_ADD_INTEREST_MULTIPLE': 201, - 'CLIENT_REMOVE_INTEREST': 203, - 'CLIENT_OBJECT_LOCATION': 140, +CLIENT_ADD_INTEREST = 200 +CLIENT_ADD_INTEREST_MULTIPLE = 201 +CLIENT_REMOVE_INTEREST = 203 +CLIENT_OBJECT_LOCATION = 140 - # These are sent internally inside the Astron cluster. +# These are sent internally inside the Astron cluster. - # Message Director control messages: - 'CONTROL_CHANNEL': 1, - 'CONTROL_ADD_CHANNEL': 9000, - 'CONTROL_REMOVE_CHANNEL': 9001, - 'CONTROL_ADD_RANGE': 9002, - 'CONTROL_REMOVE_RANGE': 9003, - 'CONTROL_ADD_POST_REMOVE': 9010, - 'CONTROL_CLEAR_POST_REMOVES': 9011, +# Message Director control messages: +CONTROL_CHANNEL = 1 +CONTROL_ADD_CHANNEL = 9000 +CONTROL_REMOVE_CHANNEL = 9001 +CONTROL_ADD_RANGE = 9002 +CONTROL_REMOVE_RANGE = 9003 +CONTROL_ADD_POST_REMOVE = 9010 +CONTROL_CLEAR_POST_REMOVES = 9011 - # State Server control messages: - 'STATESERVER_CREATE_OBJECT_WITH_REQUIRED': 2000, - 'STATESERVER_CREATE_OBJECT_WITH_REQUIRED_OTHER': 2001, - 'STATESERVER_DELETE_AI_OBJECTS': 2009, - 'STATESERVER_OBJECT_GET_FIELD': 2010, - 'STATESERVER_OBJECT_GET_FIELD_RESP': 2011, - 'STATESERVER_OBJECT_GET_FIELDS': 2012, - 'STATESERVER_OBJECT_GET_FIELDS_RESP': 2013, - 'STATESERVER_OBJECT_GET_ALL': 2014, - 'STATESERVER_OBJECT_GET_ALL_RESP': 2015, - 'STATESERVER_OBJECT_SET_FIELD': 2020, - 'STATESERVER_OBJECT_SET_FIELDS': 2021, - 'STATESERVER_OBJECT_DELETE_FIELD_RAM': 2030, - 'STATESERVER_OBJECT_DELETE_FIELDS_RAM': 2031, - 'STATESERVER_OBJECT_DELETE_RAM': 2032, - 'STATESERVER_OBJECT_SET_LOCATION': 2040, - 'STATESERVER_OBJECT_CHANGING_LOCATION': 2041, - 'STATESERVER_OBJECT_ENTER_LOCATION_WITH_REQUIRED': 2042, - 'STATESERVER_OBJECT_ENTER_LOCATION_WITH_REQUIRED_OTHER': 2043, - 'STATESERVER_OBJECT_GET_LOCATION': 2044, - 'STATESERVER_OBJECT_GET_LOCATION_RESP': 2045, - 'STATESERVER_OBJECT_SET_AI': 2050, - 'STATESERVER_OBJECT_CHANGING_AI': 2051, - 'STATESERVER_OBJECT_ENTER_AI_WITH_REQUIRED': 2052, - 'STATESERVER_OBJECT_ENTER_AI_WITH_REQUIRED_OTHER': 2053, - 'STATESERVER_OBJECT_GET_AI': 2054, - 'STATESERVER_OBJECT_GET_AI_RESP': 2055, - 'STATESERVER_OBJECT_SET_OWNER': 2060, - 'STATESERVER_OBJECT_CHANGING_OWNER': 2061, - 'STATESERVER_OBJECT_ENTER_OWNER_WITH_REQUIRED': 2062, - 'STATESERVER_OBJECT_ENTER_OWNER_WITH_REQUIRED_OTHER': 2063, - 'STATESERVER_OBJECT_GET_OWNER': 2064, - 'STATESERVER_OBJECT_GET_OWNER_RESP': 2065, - 'STATESERVER_OBJECT_GET_ZONE_OBJECTS': 2100, - 'STATESERVER_OBJECT_GET_ZONES_OBJECTS': 2102, - 'STATESERVER_OBJECT_GET_CHILDREN': 2104, - 'STATESERVER_OBJECT_GET_ZONE_COUNT': 2110, - 'STATESERVER_OBJECT_GET_ZONE_COUNT_RESP': 2111, - 'STATESERVER_OBJECT_GET_ZONES_COUNT': 2112, - 'STATESERVER_OBJECT_GET_ZONES_COUNT_RESP': 2113, - 'STATESERVER_OBJECT_GET_CHILD_COUNT': 2114, - 'STATESERVER_OBJECT_GET_CHILD_COUNT_RESP': 2115, - 'STATESERVER_OBJECT_DELETE_ZONE': 2120, - 'STATESERVER_OBJECT_DELETE_ZONES': 2122, - 'STATESERVER_OBJECT_DELETE_CHILDREN': 2124, - # DBSS-backed-object messages: - 'DBSS_OBJECT_ACTIVATE_WITH_DEFAULTS': 2200, - 'DBSS_OBJECT_ACTIVATE_WITH_DEFAULTS_OTHER': 2201, - 'DBSS_OBJECT_GET_ACTIVATED': 2207, - 'DBSS_OBJECT_GET_ACTIVATED_RESP': 2208, - 'DBSS_OBJECT_DELETE_FIELD_DISK': 2230, - 'DBSS_OBJECT_DELETE_FIELDS_DISK': 2231, - 'DBSS_OBJECT_DELETE_DISK': 2232, +# State Server control messages: +STATESERVER_CREATE_OBJECT_WITH_REQUIRED = 2000 +STATESERVER_CREATE_OBJECT_WITH_REQUIRED_OTHER = 2001 +STATESERVER_DELETE_AI_OBJECTS = 2009 +STATESERVER_OBJECT_GET_FIELD = 2010 +STATESERVER_OBJECT_GET_FIELD_RESP = 2011 +STATESERVER_OBJECT_GET_FIELDS = 2012 +STATESERVER_OBJECT_GET_FIELDS_RESP = 2013 +STATESERVER_OBJECT_GET_ALL = 2014 +STATESERVER_OBJECT_GET_ALL_RESP = 2015 +STATESERVER_OBJECT_SET_FIELD = 2020 +STATESERVER_OBJECT_SET_FIELDS = 2021 +STATESERVER_OBJECT_DELETE_FIELD_RAM = 2030 +STATESERVER_OBJECT_DELETE_FIELDS_RAM = 2031 +STATESERVER_OBJECT_DELETE_RAM = 2032 +STATESERVER_OBJECT_SET_LOCATION = 2040 +STATESERVER_OBJECT_CHANGING_LOCATION = 2041 +STATESERVER_OBJECT_ENTER_LOCATION_WITH_REQUIRED = 2042 +STATESERVER_OBJECT_ENTER_LOCATION_WITH_REQUIRED_OTHER = 2043 +STATESERVER_OBJECT_GET_LOCATION = 2044 +STATESERVER_OBJECT_GET_LOCATION_RESP = 2045 +STATESERVER_OBJECT_SET_AI = 2050 +STATESERVER_OBJECT_CHANGING_AI = 2051 +STATESERVER_OBJECT_ENTER_AI_WITH_REQUIRED = 2052 +STATESERVER_OBJECT_ENTER_AI_WITH_REQUIRED_OTHER = 2053 +STATESERVER_OBJECT_GET_AI = 2054 +STATESERVER_OBJECT_GET_AI_RESP = 2055 +STATESERVER_OBJECT_SET_OWNER = 2060 +STATESERVER_OBJECT_CHANGING_OWNER = 2061 +STATESERVER_OBJECT_ENTER_OWNER_WITH_REQUIRED = 2062 +STATESERVER_OBJECT_ENTER_OWNER_WITH_REQUIRED_OTHER = 2063 +STATESERVER_OBJECT_GET_OWNER = 2064 +STATESERVER_OBJECT_GET_OWNER_RESP = 2065 +STATESERVER_OBJECT_GET_ZONE_OBJECTS = 2100 +STATESERVER_OBJECT_GET_ZONES_OBJECTS = 2102 +STATESERVER_OBJECT_GET_CHILDREN = 2104 +STATESERVER_OBJECT_GET_ZONE_COUNT = 2110 +STATESERVER_OBJECT_GET_ZONE_COUNT_RESP = 2111 +STATESERVER_OBJECT_GET_ZONES_COUNT = 2112 +STATESERVER_OBJECT_GET_ZONES_COUNT_RESP = 2113 +STATESERVER_OBJECT_GET_CHILD_COUNT = 2114 +STATESERVER_OBJECT_GET_CHILD_COUNT_RESP = 2115 +STATESERVER_OBJECT_DELETE_ZONE = 2120 +STATESERVER_OBJECT_DELETE_ZONES = 2122 +STATESERVER_OBJECT_DELETE_CHILDREN = 2124 +# DBSS-backed-object messages: +DBSS_OBJECT_ACTIVATE_WITH_DEFAULTS = 2200 +DBSS_OBJECT_ACTIVATE_WITH_DEFAULTS_OTHER = 2201 +DBSS_OBJECT_GET_ACTIVATED = 2207 +DBSS_OBJECT_GET_ACTIVATED_RESP = 2208 +DBSS_OBJECT_DELETE_FIELD_DISK = 2230 +DBSS_OBJECT_DELETE_FIELDS_DISK = 2231 +DBSS_OBJECT_DELETE_DISK = 2232 - # Database Server control messages: - 'DBSERVER_CREATE_OBJECT': 3000, - 'DBSERVER_CREATE_OBJECT_RESP': 3001, - 'DBSERVER_OBJECT_GET_FIELD': 3010, - 'DBSERVER_OBJECT_GET_FIELD_RESP': 3011, - 'DBSERVER_OBJECT_GET_FIELDS': 3012, - 'DBSERVER_OBJECT_GET_FIELDS_RESP': 3013, - 'DBSERVER_OBJECT_GET_ALL': 3014, - 'DBSERVER_OBJECT_GET_ALL_RESP': 3015, - 'DBSERVER_OBJECT_SET_FIELD': 3020, - 'DBSERVER_OBJECT_SET_FIELDS': 3021, - 'DBSERVER_OBJECT_SET_FIELD_IF_EQUALS': 3022, - 'DBSERVER_OBJECT_SET_FIELD_IF_EQUALS_RESP': 3023, - 'DBSERVER_OBJECT_SET_FIELDS_IF_EQUALS': 3024, - 'DBSERVER_OBJECT_SET_FIELDS_IF_EQUALS_RESP': 3025, - 'DBSERVER_OBJECT_SET_FIELD_IF_EMPTY': 3026, - 'DBSERVER_OBJECT_SET_FIELD_IF_EMPTY_RESP': 3027, - 'DBSERVER_OBJECT_DELETE_FIELD': 3030, - 'DBSERVER_OBJECT_DELETE_FIELDS': 3031, - 'DBSERVER_OBJECT_DELETE': 3032, +# Database Server control messages: +DBSERVER_CREATE_OBJECT = 3000 +DBSERVER_CREATE_OBJECT_RESP = 3001 +DBSERVER_OBJECT_GET_FIELD = 3010 +DBSERVER_OBJECT_GET_FIELD_RESP = 3011 +DBSERVER_OBJECT_GET_FIELDS = 3012 +DBSERVER_OBJECT_GET_FIELDS_RESP = 3013 +DBSERVER_OBJECT_GET_ALL = 3014 +DBSERVER_OBJECT_GET_ALL_RESP = 3015 +DBSERVER_OBJECT_SET_FIELD = 3020 +DBSERVER_OBJECT_SET_FIELDS = 3021 +DBSERVER_OBJECT_SET_FIELD_IF_EQUALS = 3022 +DBSERVER_OBJECT_SET_FIELD_IF_EQUALS_RESP = 3023 +DBSERVER_OBJECT_SET_FIELDS_IF_EQUALS = 3024 +DBSERVER_OBJECT_SET_FIELDS_IF_EQUALS_RESP = 3025 +DBSERVER_OBJECT_SET_FIELD_IF_EMPTY = 3026 +DBSERVER_OBJECT_SET_FIELD_IF_EMPTY_RESP = 3027 +DBSERVER_OBJECT_DELETE_FIELD = 3030 +DBSERVER_OBJECT_DELETE_FIELDS = 3031 +DBSERVER_OBJECT_DELETE = 3032 - # Client Agent control messages: - 'CLIENTAGENT_SET_STATE': 1000, - 'CLIENTAGENT_SET_CLIENT_ID': 1001, - 'CLIENTAGENT_SEND_DATAGRAM': 1002, - 'CLIENTAGENT_EJECT': 1004, - 'CLIENTAGENT_DROP': 1005, - 'CLIENTAGENT_GET_NETWORK_ADDRESS': 1006, - 'CLIENTAGENT_GET_NETWORK_ADDRESS_RESP': 1007, - 'CLIENTAGENT_DECLARE_OBJECT': 1010, - 'CLIENTAGENT_UNDECLARE_OBJECT': 1011, - 'CLIENTAGENT_ADD_SESSION_OBJECT': 1012, - 'CLIENTAGENT_REMOVE_SESSION_OBJECT': 1013, - 'CLIENTAGENT_SET_FIELDS_SENDABLE': 1014, - 'CLIENTAGENT_OPEN_CHANNEL': 1100, - 'CLIENTAGENT_CLOSE_CHANNEL': 1101, - 'CLIENTAGENT_ADD_POST_REMOVE': 1110, - 'CLIENTAGENT_CLEAR_POST_REMOVES': 1111, - 'CLIENTAGENT_ADD_INTEREST': 1200, - 'CLIENTAGENT_ADD_INTEREST_MULTIPLE': 1201, - 'CLIENTAGENT_REMOVE_INTEREST': 1203, -} +# Client Agent control messages: +CLIENTAGENT_SET_STATE = 1000 +CLIENTAGENT_SET_CLIENT_ID = 1001 +CLIENTAGENT_SEND_DATAGRAM = 1002 +CLIENTAGENT_EJECT = 1004 +CLIENTAGENT_DROP = 1005 +CLIENTAGENT_GET_NETWORK_ADDRESS = 1006 +CLIENTAGENT_GET_NETWORK_ADDRESS_RESP = 1007 +CLIENTAGENT_DECLARE_OBJECT = 1010 +CLIENTAGENT_UNDECLARE_OBJECT = 1011 +CLIENTAGENT_ADD_SESSION_OBJECT = 1012 +CLIENTAGENT_REMOVE_SESSION_OBJECT = 1013 +CLIENTAGENT_SET_FIELDS_SENDABLE = 1014 +CLIENTAGENT_OPEN_CHANNEL = 1100 +CLIENTAGENT_CLOSE_CHANNEL = 1101 +CLIENTAGENT_ADD_POST_REMOVE = 1110 +CLIENTAGENT_CLEAR_POST_REMOVES = 1111 +CLIENTAGENT_ADD_INTEREST = 1200 +CLIENTAGENT_ADD_INTEREST_MULTIPLE = 1201 +CLIENTAGENT_REMOVE_INTEREST = 1203 + +MsgName2Id = {name: value for name, value in globals().items() if isinstance(value, int)} # create id->name table for debugging MsgId2Names = invertDictLossless(MsgName2Id) @@ -146,7 +148,7 @@ MsgId2Names = invertDictLossless(MsgName2Id) globals().update(MsgName2Id) # These messages are ignored when the client is headed to the quiet zone -QUIET_ZONE_IGNORED_LIST = [ +QUIET_ZONE_IGNORED_LIST: list[int] = [ # We mustn't ignore updates, because some updates for localToon # are always important. diff --git a/direct/src/distributed/MsgTypesCMU.py b/direct/src/distributed/MsgTypesCMU.py index ce728b3b6f..a348e01b3c 100644 --- a/direct/src/distributed/MsgTypesCMU.py +++ b/direct/src/distributed/MsgTypesCMU.py @@ -5,25 +5,22 @@ implementation. """ from direct.showbase.PythonUtil import invertDictLossless -MsgName2Id = { - 'SET_DOID_RANGE_CMU' : 9001, - 'CLIENT_OBJECT_GENERATE_CMU' : 9002, - 'OBJECT_GENERATE_CMU' : 9003, - 'OBJECT_UPDATE_FIELD_CMU' : 9004, - 'OBJECT_DISABLE_CMU' : 9005, - 'OBJECT_DELETE_CMU' : 9006, - 'REQUEST_GENERATES_CMU' : 9007, - 'CLIENT_DISCONNECT_CMU' : 9008, - 'CLIENT_SET_INTEREST_CMU' : 9009, - 'OBJECT_SET_ZONE_CMU' : 9010, - 'CLIENT_HEARTBEAT_CMU' : 9011, - 'CLIENT_OBJECT_UPDATE_FIELD_TARGETED_CMU' : 9011, +SET_DOID_RANGE_CMU = 9001 +CLIENT_OBJECT_GENERATE_CMU = 9002 +OBJECT_GENERATE_CMU = 9003 +OBJECT_UPDATE_FIELD_CMU = 9004 +OBJECT_DISABLE_CMU = 9005 +OBJECT_DELETE_CMU = 9006 +REQUEST_GENERATES_CMU = 9007 +CLIENT_DISCONNECT_CMU = 9008 +CLIENT_SET_INTEREST_CMU = 9009 +OBJECT_SET_ZONE_CMU = 9010 +CLIENT_HEARTBEAT_CMU = 9011 +CLIENT_OBJECT_UPDATE_FIELD_TARGETED_CMU = 9011 - 'CLIENT_OBJECT_UPDATE_FIELD' : 120, # Matches MsgTypes.CLIENT_OBJECT_SET_FIELD -} +CLIENT_OBJECT_UPDATE_FIELD = 120 # Matches MsgTypes.CLIENT_OBJECT_SET_FIELD + +MsgName2Id = {name: value for name, value in globals().items() if isinstance(value, int)} # create id->name table for debugging MsgId2Names = invertDictLossless(MsgName2Id) - -# put msg names in module scope, assigned to msg value -globals().update(MsgName2Id) diff --git a/direct/src/fsm/ClassicFSM.py b/direct/src/fsm/ClassicFSM.py index 6d45b5bb11..1b1be81d1d 100644 --- a/direct/src/fsm/ClassicFSM.py +++ b/direct/src/fsm/ClassicFSM.py @@ -5,6 +5,8 @@ Note: existing code. New code should use the :mod:`.FSM` module instead. """ +from __future__ import annotations + __all__ = ['ClassicFSM'] from direct.directnotify.DirectNotifyGlobal import directNotify @@ -13,7 +15,7 @@ from direct.showbase.MessengerGlobal import messenger import weakref if __debug__: - _debugFsms = {} + _debugFsms: dict[str, weakref.ref] = {} def printDebugFsmList(): for k in sorted(_debugFsms.keys()): diff --git a/direct/src/fsm/State.py b/direct/src/fsm/State.py index f80507a538..0b90ba16c7 100644 --- a/direct/src/fsm/State.py +++ b/direct/src/fsm/State.py @@ -1,5 +1,7 @@ """State module: contains State class""" +from __future__ import annotations + __all__ = ['State'] from direct.directnotify.DirectNotifyGlobal import directNotify @@ -18,7 +20,7 @@ class State(DirectObject): # should not cause any leaks. if __debug__: import weakref - States = weakref.WeakKeyDictionary() + States: weakref.WeakKeyDictionary[State, int] = weakref.WeakKeyDictionary() @classmethod def replaceMethod(cls, oldFunction, newFunction): diff --git a/direct/src/fsm/StatePush.py b/direct/src/fsm/StatePush.py index 21bed7e299..4e105e0b80 100755 --- a/direct/src/fsm/StatePush.py +++ b/direct/src/fsm/StatePush.py @@ -1,6 +1,8 @@ # classes for event-driven programming # http://en.wikipedia.org/wiki/Event-driven_programming +from __future__ import annotations + __all__ = ['StateVar', 'FunctionCall', 'EnterExit', 'Pulse', 'EventPulse', 'EventArgument', ] diff --git a/direct/src/gui/DirectDialog.py b/direct/src/gui/DirectDialog.py index 4b95dcb7f5..062b0c320c 100644 --- a/direct/src/gui/DirectDialog.py +++ b/direct/src/gui/DirectDialog.py @@ -4,6 +4,8 @@ See the :ref:`directdialog` page in the programming manual for a more in-depth explanation and an example of how to use this class. """ +from __future__ import annotations + __all__ = [ 'findDialog', 'cleanupDialog', 'DirectDialog', 'OkDialog', 'OkCancelDialog', 'YesNoDialog', 'YesNoCancelDialog', 'RetryCancelDialog', @@ -45,7 +47,7 @@ def cleanupDialog(uniqueName): class DirectDialog(DirectFrame): - AllDialogs = {} + AllDialogs: dict[str, DirectDialog] = {} PanelIndex = 0 def __init__(self, parent=None, **kw): diff --git a/direct/src/gui/DirectGuiBase.py b/direct/src/gui/DirectGuiBase.py index 24424855d0..f9bbb5b5f8 100644 --- a/direct/src/gui/DirectGuiBase.py +++ b/direct/src/gui/DirectGuiBase.py @@ -84,6 +84,8 @@ Code overview: see if any keywords are left unused. If so, an error is raised. """ +from __future__ import annotations + __all__ = ['DirectGuiBase', 'DirectGuiWidget'] @@ -680,7 +682,7 @@ class DirectGuiWidget(DirectGuiBase, NodePath): else: inactiveInitState = DGG.DISABLED - guiDict = {} + guiDict: dict[str, DirectGuiWidget] = {} def __init__(self, parent = None, **kw): # Direct gui widgets are node paths diff --git a/direct/src/gui/DirectGuiGlobals.py b/direct/src/gui/DirectGuiGlobals.py index 66d14d092c..d41199af0e 100644 --- a/direct/src/gui/DirectGuiGlobals.py +++ b/direct/src/gui/DirectGuiGlobals.py @@ -3,7 +3,7 @@ Global definitions used by Direct Gui Classes and handy constants that can be used during widget construction """ -__all__ = [] +__all__ = () from panda3d.core import ( KeyboardButton, diff --git a/direct/src/interval/FunctionInterval.py b/direct/src/interval/FunctionInterval.py index c12be80189..60c0ab7edf 100644 --- a/direct/src/interval/FunctionInterval.py +++ b/direct/src/interval/FunctionInterval.py @@ -1,5 +1,7 @@ """FunctionInterval module: contains the FunctionInterval class""" +from __future__ import annotations + __all__ = ['FunctionInterval', 'EventInterval', 'AcceptInterval', 'IgnoreInterval', 'ParentInterval', 'WrtParentInterval', 'PosInterval', 'HprInterval', 'ScaleInterval', 'PosHprInterval', 'HprScaleInterval', 'PosHprScaleInterval', 'Func', 'Wait'] from panda3d.direct import WaitInterval @@ -23,7 +25,7 @@ class FunctionInterval(Interval.Interval): # should not cause any leaks. if __debug__: import weakref - FunctionIntervals = weakref.WeakKeyDictionary() + FunctionIntervals: weakref.WeakKeyDictionary[FunctionInterval, int] = weakref.WeakKeyDictionary() @classmethod def replaceMethod(cls, oldFunction, newFunction): diff --git a/direct/src/interval/IntervalTest.py b/direct/src/interval/IntervalTest.py index db533da5c4..8705f70581 100644 --- a/direct/src/interval/IntervalTest.py +++ b/direct/src/interval/IntervalTest.py @@ -1,6 +1,6 @@ """Undocumented Module""" -__all__ = [] +__all__ = () if __name__ == "__main__": @@ -26,7 +26,7 @@ if __name__ == "__main__": base = ShowBase() boat = base.loader.loadModel('models/misc/smiley') - boat.reparentTo(render) + boat.reparentTo(base.render) donald = Actor() donald.loadModel("phase_6/models/char/donald-wheel-1000") @@ -34,7 +34,7 @@ if __name__ == "__main__": donald.reparentTo(boat) dock = base.loader.loadModel('models/misc/smiley') - dock.reparentTo(render) + dock.reparentTo(base.render) sound = base.loader.loadSfx('phase_6/audio/sfx/SZ_DD_waterlap.mp3') foghorn = base.loader.loadSfx('phase_6/audio/sfx/SZ_DD_foghorn.mp3') @@ -93,7 +93,7 @@ if __name__ == "__main__": foghornSound = SoundInterval(foghorn, name='foghorn') soundTrack2 = Track([(foghornStartTime, foghornSound)], 'soundtrack2') - mtrack = MultiTrack([boatTrack, dockTrack, soundTrack, soundTrack2, waterEventTrack, + mtrack = MultiTrack([boatTrack, dockTrack, soundTrack, soundTrack2, waterEventTrack, # type: ignore[name-defined] donaldSteerTrack]) # Print out MultiTrack parameters print(mtrack) @@ -175,11 +175,11 @@ if __name__ == "__main__": # Just to take time i2 = LerpPosInterval(base.camera, 2.0, Point3(0, 10, 5)) # This will be relative to end of camera move - i3 = FunctionInterval(printPreviousEnd) + i3 = FunctionInterval(printPreviousEnd) # type: ignore[assignment] # Just to take time i4 = LerpPosInterval(base.camera, 2.0, Point3(0, 0, 5)) # This will be relative to the start of the camera move - i5 = FunctionInterval(printPreviousStart) + i5 = FunctionInterval(printPreviousStart) # type: ignore[assignment] # This will be relative to track start i6 = FunctionInterval(printTrackStart) # This will print some arguments diff --git a/direct/src/leveleditor/LevelEditorStart.py b/direct/src/leveleditor/LevelEditorStart.py index 27a8da1c40..61c5a808b6 100644 --- a/direct/src/leveleditor/LevelEditorStart.py +++ b/direct/src/leveleditor/LevelEditorStart.py @@ -4,7 +4,7 @@ if __name__ == '__main__': from direct.showbase.ShowBase import ShowBase base = ShowBase() - base.le = LevelEditor.LevelEditor() + base.le = LevelEditor.LevelEditor() # type: ignore[attr-defined] # You should define LevelEditor instance as # base.le so it can be reached in global scope diff --git a/direct/src/leveleditor/testData.py b/direct/src/leveleditor/testData.py index 2dc05f01e6..a1dda82faa 100755 --- a/direct/src/leveleditor/testData.py +++ b/direct/src/leveleditor/testData.py @@ -1,4 +1,5 @@ from panda3d.core import Point3, VBase3 +from direct.showbase.ShowBaseGlobal import base if hasattr(base, 'le'): objectMgr = base.le.objectMgr @@ -6,7 +7,7 @@ if hasattr(base, 'le'): ui.sceneGraphUI.reset() else: - objectMgr = base.objectMgr + objectMgr = base.objectMgr # type: ignore[attr-defined] # temporary place holder for nodepath objects = {} diff --git a/direct/src/motiontrail/MotionTrail.py b/direct/src/motiontrail/MotionTrail.py index 49b429374a..75c055196b 100644 --- a/direct/src/motiontrail/MotionTrail.py +++ b/direct/src/motiontrail/MotionTrail.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from panda3d.core import ( BoundingVolume, ColorBlendAttrib, @@ -92,7 +94,7 @@ class MotionTrail(NodePath, DirectObject): notify = directNotify.newCategory("MotionTrail") task_added = False - motion_trail_list = [] + motion_trail_list: list[MotionTrail] = [] motion_trail_task_name = "motion_trail_task" global_enable = True diff --git a/direct/src/showbase/ContainerLeakDetector.py b/direct/src/showbase/ContainerLeakDetector.py index ef1949f33c..2e5ed34ce3 100755 --- a/direct/src/showbase/ContainerLeakDetector.py +++ b/direct/src/showbase/ContainerLeakDetector.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from direct.directnotify.DirectNotifyGlobal import directNotify import direct.showbase.DConfig as config from direct.showbase.PythonUtil import makeFlywheelGen, flywheel @@ -982,7 +984,7 @@ class ContainerLeakDetector(Job): """ notify = directNotify.newCategory("ContainerLeakDetector") # set of containers that should not be examined - PrivateIds = set() + PrivateIds: set[int] = set() def __init__(self, name, firstCheckDelay = None): Job.__init__(self, name) diff --git a/direct/src/showbase/ContainerReport.py b/direct/src/showbase/ContainerReport.py index 71468bfbf6..a43194ab65 100755 --- a/direct/src/showbase/ContainerReport.py +++ b/direct/src/showbase/ContainerReport.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from direct.directnotify.DirectNotifyGlobal import directNotify from direct.showbase.PythonUtil import Queue, invertDictLossless from direct.showbase.PythonUtil import safeRepr @@ -11,7 +13,7 @@ import io class ContainerReport(Job): notify = directNotify.newCategory("ContainerReport") # set of containers that should not be included in the report - PrivateIds = set() + PrivateIds: set[int] = set() def __init__(self, name, log=False, limit=None, threaded=False): Job.__init__(self, name) diff --git a/direct/src/showbase/DConfig.py b/direct/src/showbase/DConfig.py index a0331632e2..bd36ec631f 100644 --- a/direct/src/showbase/DConfig.py +++ b/direct/src/showbase/DConfig.py @@ -1,6 +1,6 @@ "This module contains a deprecated shim emulating the old DConfig API." -__all__ = [] +__all__ = () from panda3d.core import (ConfigFlags, ConfigVariableBool, ConfigVariableInt, ConfigVariableDouble, ConfigVariableString) diff --git a/direct/src/showbase/DistancePhasedNode.py b/direct/src/showbase/DistancePhasedNode.py index 0f0a426e99..fc4c5a471b 100755 --- a/direct/src/showbase/DistancePhasedNode.py +++ b/direct/src/showbase/DistancePhasedNode.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from direct.showbase.DirectObject import DirectObject from direct.directnotify.DirectNotifyGlobal import directNotify from panda3d.core import ( @@ -62,7 +64,7 @@ class DistancePhasedNode(PhasedObject, DirectObject, NodePath): notify = directNotify.newCategory("DistancePhasedObject") __InstanceSequence = 0 - __InstanceDeque = [] + __InstanceDeque: list[int] = [] @staticmethod def __allocateId(): diff --git a/direct/src/showbase/ExceptionVarDump.py b/direct/src/showbase/ExceptionVarDump.py index b2cc73f68a..aad5850e6f 100755 --- a/direct/src/showbase/ExceptionVarDump.py +++ b/direct/src/showbase/ExceptionVarDump.py @@ -69,7 +69,7 @@ oldExcepthook = None # from its main exception handler wantStackDumpLog = False wantStackDumpUpload = False -variableDumpReasons = [] +variableDumpReasons: list = [] dumpOnExceptionInit = False diff --git a/direct/src/showbase/ObjectReport.py b/direct/src/showbase/ObjectReport.py index 5362716e25..b0aec6286f 100755 --- a/direct/src/showbase/ObjectReport.py +++ b/direct/src/showbase/ObjectReport.py @@ -11,6 +11,8 @@ >>> o.diff(o2) """ +from __future__ import annotations + __all__ = ['ExclusiveObjectPool', 'ObjectReport'] from direct.directnotify.DirectNotifyGlobal import directNotify @@ -26,8 +28,8 @@ import builtins class ExclusiveObjectPool(DirectObject): # ObjectPool specialization that excludes particular objects # IDs of objects to globally exclude from reporting - _ExclObjs = [] - _ExclObjIds = {} + _ExclObjs: list[object] = [] + _ExclObjIds: dict[int, int] = {} _SyncMaster = Sync('ExclusiveObjectPool.ExcludedObjectList') _SerialNumGen = SerialNumGen() diff --git a/direct/src/showbase/PythonUtil.py b/direct/src/showbase/PythonUtil.py index 7ca1b36fe1..d9ffa2aa35 100644 --- a/direct/src/showbase/PythonUtil.py +++ b/direct/src/showbase/PythonUtil.py @@ -1,5 +1,7 @@ """Contains miscellaneous utility functions and classes.""" +from __future__ import annotations + __all__ = [ 'indent', 'doc', 'adjust', 'difference', 'intersection', 'union', @@ -39,6 +41,7 @@ import time import builtins import importlib import functools +from typing import Callable __report_indent = 3 @@ -699,9 +702,9 @@ if __debug__: return profileDecorator # intercept profile-related file operations to avoid disk access - movedOpenFuncs = [] - movedDumpFuncs = [] - movedLoadFuncs = [] + movedOpenFuncs: list[Callable] = [] + movedDumpFuncs: list[Callable] = [] + movedLoadFuncs: list[Callable] = [] profileFilenames = set() profileFilenameList = Stack() profileFilename2file = {} @@ -1899,7 +1902,7 @@ class SubframeCall: class PStatScope: - collectors = {} + collectors: dict = {} def __init__(self, level = None): self.levels = [] @@ -2618,52 +2621,52 @@ class PriorityCallbacks: callback() -builtins.Functor = Functor -builtins.Stack = Stack -builtins.Queue = Queue -builtins.SerialNumGen = SerialNumGen -builtins.SerialMaskedGen = SerialMaskedGen -builtins.ScratchPad = ScratchPad -builtins.uniqueName = uniqueName -builtins.serialNum = serialNum +builtins.Functor = Functor # type: ignore[attr-defined] +builtins.Stack = Stack # type: ignore[attr-defined] +builtins.Queue = Queue # type: ignore[attr-defined] +builtins.SerialNumGen = SerialNumGen # type: ignore[attr-defined] +builtins.SerialMaskedGen = SerialMaskedGen # type: ignore[attr-defined] +builtins.ScratchPad = ScratchPad # type: ignore[attr-defined] +builtins.uniqueName = uniqueName # type: ignore[attr-defined] +builtins.serialNum = serialNum # type: ignore[attr-defined] if __debug__: - 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 + builtins.profiled = profiled # type: ignore[attr-defined] + builtins.exceptionLogged = exceptionLogged # type: ignore[attr-defined] +builtins.itype = itype # type: ignore[attr-defined] +builtins.appendStr = appendStr # type: ignore[attr-defined] +builtins.bound = bound # type: ignore[attr-defined] +builtins.clamp = clamp # type: ignore[attr-defined] +builtins.lerp = lerp # type: ignore[attr-defined] +builtins.makeList = makeList # type: ignore[attr-defined] +builtins.makeTuple = makeTuple # type: ignore[attr-defined] if __debug__: - 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 + builtins.printStack = printStack # type: ignore[attr-defined] + builtins.printReverseStack = printReverseStack # type: ignore[attr-defined] + builtins.printVerboseStack = printVerboseStack # type: ignore[attr-defined] +builtins.DelayedCall = DelayedCall # type: ignore[attr-defined] +builtins.DelayedFunctor = DelayedFunctor # type: ignore[attr-defined] +builtins.FrameDelayedCall = FrameDelayedCall # type: ignore[attr-defined] +builtins.SubframeCall = SubframeCall # type: ignore[attr-defined] +builtins.invertDict = invertDict # type: ignore[attr-defined] +builtins.invertDictLossless = invertDictLossless # type: ignore[attr-defined] +builtins.getBase = getBase # type: ignore[attr-defined] +builtins.getRepository = getRepository # type: ignore[attr-defined] +builtins.safeRepr = safeRepr # type: ignore[attr-defined] +builtins.fastRepr = fastRepr # type: ignore[attr-defined] +builtins.nullGen = nullGen # type: ignore[attr-defined] +builtins.flywheel = flywheel # type: ignore[attr-defined] +builtins.loopGen = loopGen # type: ignore[attr-defined] if __debug__: - 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 + builtins.StackTrace = StackTrace # type: ignore[attr-defined] +builtins.report = report # type: ignore[attr-defined] +builtins.pstatcollect = pstatcollect # type: ignore[attr-defined] +builtins.MiniLog = MiniLog # type: ignore[attr-defined] +builtins.MiniLogSentry = MiniLogSentry # type: ignore[attr-defined] +builtins.logBlock = logBlock # type: ignore[attr-defined] +builtins.HierarchyException = HierarchyException # type: ignore[attr-defined] +builtins.deeptype = deeptype # type: ignore[attr-defined] +builtins.Default = Default # type: ignore[attr-defined] +builtins.configIsToday = configIsToday # type: ignore[attr-defined] +builtins.typeName = typeName # type: ignore[attr-defined] +builtins.safeTypeName = safeTypeName # type: ignore[attr-defined] +builtins.histogramDict = histogramDict # type: ignore[attr-defined] diff --git a/direct/src/showbase/ShowBase.py b/direct/src/showbase/ShowBase.py index cebe0ad639..1eb2c9aa00 100644 --- a/direct/src/showbase/ShowBase.py +++ b/direct/src/showbase/ShowBase.py @@ -120,7 +120,7 @@ from direct.extensions_native import NodePath_extensions # pylint: disable=unuse # This needs to be available early for DirectGUI imports import sys import builtins -builtins.config = DConfig +builtins.config = DConfig # type: ignore[attr-defined] from direct.directnotify.DirectNotifyGlobal import directNotify, giveNotify from .MessengerGlobal import messenger diff --git a/direct/src/showbase/ShowBaseGlobal.py b/direct/src/showbase/ShowBaseGlobal.py index 8b40d703ef..b24fca18fc 100644 --- a/direct/src/showbase/ShowBaseGlobal.py +++ b/direct/src/showbase/ShowBaseGlobal.py @@ -11,7 +11,7 @@ Note that you cannot directly import :data:`~builtins.base` from this module since ShowBase may not have been created yet; instead, ShowBase dynamically adds itself to this module's scope when instantiated.""" -__all__ = [] +__all__ = () from .ShowBase import ShowBase, WindowControls # pylint: disable=unused-import from direct.directnotify.DirectNotifyGlobal import directNotify, giveNotify # pylint: disable=unused-import @@ -23,6 +23,8 @@ import warnings __dev__ = ConfigVariableBool('want-dev', __debug__).value +base: ShowBase + #: The global instance of the :ref:`virtual-file-system`, as obtained using #: :meth:`panda3d.core.VirtualFileSystem.getGlobalPtr()`. vfs = VirtualFileSystem.getGlobalPtr() @@ -81,7 +83,7 @@ def inspect(anObject): import builtins -builtins.inspect = inspect +builtins.inspect = inspect # type: ignore[attr-defined] # this also appears in AIBaseGlobal if (not __debug__) and __dev__: diff --git a/direct/src/showbase/VerboseImport.py b/direct/src/showbase/VerboseImport.py index 9c61783ea5..181ac73c5d 100644 --- a/direct/src/showbase/VerboseImport.py +++ b/direct/src/showbase/VerboseImport.py @@ -3,7 +3,7 @@ This module hooks into Python's import mechanism to print out all imports to the standard output as they happen. """ -__all__ = [] +__all__ = () import sys diff --git a/direct/src/stdpy/pickle.py b/direct/src/stdpy/pickle.py index 4e03089f84..a44c3dd202 100644 --- a/direct/src/stdpy/pickle.py +++ b/direct/src/stdpy/pickle.py @@ -45,7 +45,7 @@ BasePickler = pickle._Pickler BaseUnpickler = pickle._Unpickler -class Pickler(BasePickler): +class Pickler(BasePickler): # type: ignore[misc, valid-type] def __init__(self, *args, **kw): self.bamWriter = BamWriter() @@ -148,7 +148,7 @@ class Pickler(BasePickler): self.save_reduce(obj=obj, *rv) -class Unpickler(BaseUnpickler): +class Unpickler(BaseUnpickler): # type: ignore[misc, valid-type] def __init__(self, *args, **kw): self.bamReader = BamReader() diff --git a/direct/src/stdpy/threading.py b/direct/src/stdpy/threading.py index e4e7a1d24f..3b82b61466 100644 --- a/direct/src/stdpy/threading.py +++ b/direct/src/stdpy/threading.py @@ -83,8 +83,8 @@ class ThreadBase: # Copy these static methods from Panda's Thread object. These are # useful if you may be running in Panda's SIMPLE_THREADS compilation # mode. -ThreadBase.forceYield = core.Thread.forceYield -ThreadBase.considerYield = core.Thread.considerYield +ThreadBase.forceYield = core.Thread.forceYield # type: ignore[attr-defined] +ThreadBase.considerYield = core.Thread.considerYield # type: ignore[attr-defined] class Thread(ThreadBase): diff --git a/direct/src/stdpy/threading2.py b/direct/src/stdpy/threading2.py index 8bdde3a27c..09d0a8d083 100644 --- a/direct/src/stdpy/threading2.py +++ b/direct/src/stdpy/threading2.py @@ -65,7 +65,7 @@ if __debug__: else: # Disable this when using "python -O" - class _Verbose(object): + class _Verbose(object): # type: ignore[no-redef] def __init__(self, verbose=None): pass def _note(self, *args): diff --git a/direct/src/task/Task.py b/direct/src/task/Task.py index 470eb73cdf..12716a6707 100644 --- a/direct/src/task/Task.py +++ b/direct/src/task/Task.py @@ -24,7 +24,7 @@ if hasattr(sys, 'getandroidapilevel'): signal = None else: try: - import _signal as signal + import _signal as signal # type: ignore[import, no-redef] except ImportError: signal = None diff --git a/direct/src/tkwidgets/AppShell.py b/direct/src/tkwidgets/AppShell.py index b5913e958e..6d4de85267 100644 --- a/direct/src/tkwidgets/AppShell.py +++ b/direct/src/tkwidgets/AppShell.py @@ -21,11 +21,11 @@ import builtins # Create toplevel widget dictionary if not hasattr(builtins, "widgetDict"): - builtins.widgetDict = {} + builtins.widgetDict = {} # type: ignore[attr-defined] # Create toplevel variable dictionary if not hasattr(builtins, "variableDict"): - builtins.variableDict = {} + builtins.variableDict = {} # type: ignore[attr-defined] def resetWidgetDict(): diff --git a/direct/src/wxwidgets/ViewPort.py b/direct/src/wxwidgets/ViewPort.py index 4c89637fb9..5e94330c76 100755 --- a/direct/src/wxwidgets/ViewPort.py +++ b/direct/src/wxwidgets/ViewPort.py @@ -6,6 +6,8 @@ Modified by gjeon. Modified by Summer 2010 Carnegie Mellon University ETC PandaLE team: fixed a bug in Viewport.Close """ +from __future__ import annotations + __all__ = ["Viewport", "ViewportManager"] from panda3d.core import ( @@ -36,7 +38,7 @@ VPPERSPECTIVE = 13 class ViewportManager: """Manages the global viewport stuff.""" - viewports = [] + viewports: list[Viewport] = [] gsg = None @staticmethod @@ -58,7 +60,7 @@ class ViewportManager: v.Layout(*args, **kwargs) -class Viewport(WxPandaWindow, DirectObject): +class Viewport(WxPandaWindow, DirectObject): # type: ignore[misc, valid-type] """Class representing a 3D Viewport.""" CREATENEW = CREATENEW VPLEFT = VPLEFT diff --git a/direct/src/wxwidgets/WxPandaStart.py b/direct/src/wxwidgets/WxPandaStart.py index 60ec8e0566..a561f24301 100755 --- a/direct/src/wxwidgets/WxPandaStart.py +++ b/direct/src/wxwidgets/WxPandaStart.py @@ -1,2 +1,3 @@ +from direct.showbase.ShowBaseGlobal import base from .WxPandaShell import WxPandaShell -base.app = WxPandaShell() +base.app = WxPandaShell() # type: ignore[attr-defined] diff --git a/direct/src/wxwidgets/WxPandaWindow.py b/direct/src/wxwidgets/WxPandaWindow.py index 4c1025f1a7..7f81c484ec 100644 --- a/direct/src/wxwidgets/WxPandaWindow.py +++ b/direct/src/wxwidgets/WxPandaWindow.py @@ -81,7 +81,7 @@ class EmbeddedPandaWindow(wx.Window): if not hasattr(wxgl, 'GLCanvas'): OpenGLPandaWindow = None else: - class OpenGLPandaWindow(wxgl.GLCanvas): + class OpenGLPandaWindow(wxgl.GLCanvas): # type: ignore[no-redef] """ This class implements a Panda3D "window" that actually draws within the wx GLCanvas object. It is supported whenever OpenGL is Panda's rendering engine, and GLCanvas is available in wx. """ diff --git a/mypy.ini b/mypy.ini new file mode 100644 index 0000000000..85a2d94031 --- /dev/null +++ b/mypy.ini @@ -0,0 +1,13 @@ +[mypy] +explicit_package_bases = True +exclude = /(dist|directscripts)/ +warn_unused_ignores = True + +[mypy-panda3d.*] +ignore_missing_imports = True + +[mypy-wx.*] +ignore_missing_imports = True + +[mypy-Pmw.*] +ignore_missing_imports = True diff --git a/tests/run_mypy.py b/tests/run_mypy.py new file mode 100644 index 0000000000..df27d80cda --- /dev/null +++ b/tests/run_mypy.py @@ -0,0 +1,25 @@ +import os +import pathlib +import shutil +import subprocess +import tempfile + + +def main(): + root = pathlib.Path(__file__).parent.parent + direct_src = root / 'direct' / 'src' + mypy_config = root / 'mypy.ini' + with tempfile.TemporaryDirectory() as temp_dir: + os.environ['MYPYPATH'] = temp_dir + direct_copy = pathlib.Path(temp_dir, 'direct') + shutil.copytree(direct_src, direct_copy) + subprocess.run([ + 'mypy', + str(direct_copy), + '--config-file', + str(mypy_config), + ]) + + +if __name__ == '__main__': + main() From d659d5fe2567cdceb1d550e9baed1c75dba1d722 Mon Sep 17 00:00:00 2001 From: rdb Date: Fri, 4 Aug 2023 16:23:18 +0200 Subject: [PATCH 59/84] workflow: Install python3-tk package --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f6ffb17719..f4bd30ac76 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -113,7 +113,7 @@ jobs: libeigen3-dev libfreetype6-dev libgl1-mesa-dev libjpeg-dev libode-dev libopenal-dev libpng-dev libssl-dev libvorbis-dev libx11-dev libxcursor-dev libxrandr-dev nvidia-cg-toolkit zlib1g-dev - python3-setuptools + python3-setuptools python3-tk - name: Cache dependencies (Windows) if: runner.os == 'Windows' From c203b0f786458e169a9238ab06af0cf411942ab6 Mon Sep 17 00:00:00 2001 From: rdb Date: Sat, 5 Aug 2023 10:29:32 +0200 Subject: [PATCH 60/84] tests: Don't require tkinter to be able to run test suite --- tests/conftest.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/conftest.py b/tests/conftest.py index 9c2a01c6ca..4735ef99bf 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,5 +1,4 @@ import sys -import tkinter as tk import pytest from panda3d import core from direct.showbase.ShowBase import ShowBase @@ -14,6 +13,8 @@ def base(): @pytest.fixture def tk_toplevel(): + tk = pytest.importorskip('tkinter') + if sys.platform == 'darwin' and not core.ConfigVariableBool('want-tk', False): pytest.skip('"want-tk" must be true to use tkinter with Panda3D on macOS') try: From e8179e489f5e1125e72550a4d49691d21fbb160c Mon Sep 17 00:00:00 2001 From: Disyer Date: Sat, 5 Aug 2023 15:44:50 +0300 Subject: [PATCH 61/84] panda: Correct header guard names (#1525) --- panda/src/express/config_express.h | 2 +- panda/src/putil/config_putil.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/panda/src/express/config_express.h b/panda/src/express/config_express.h index a3a16a51fa..309dec6152 100644 --- a/panda/src/express/config_express.h +++ b/panda/src/express/config_express.h @@ -56,4 +56,4 @@ extern EXPCL_PANDA_EXPRESS ConfigVariableDouble collect_tcp_interval; extern EXPCL_PANDA_EXPRESS void init_libexpress(); -#endif /* __CONFIG_UTIL_H__ */ +#endif /* __CONFIG_EXPRESS_H__ */ diff --git a/panda/src/putil/config_putil.h b/panda/src/putil/config_putil.h index dc8681b43c..b79c20bd12 100644 --- a/panda/src/putil/config_putil.h +++ b/panda/src/putil/config_putil.h @@ -11,8 +11,8 @@ * @date 2000-01-04 */ -#ifndef __CONFIG_UTIL_H__ -#define __CONFIG_UTIL_H__ +#ifndef __CONFIG_PUTIL_H__ +#define __CONFIG_PUTIL_H__ #include "pandabase.h" #include "notifyCategoryProxy.h" @@ -54,4 +54,4 @@ extern EXPCL_PANDA_PUTIL ConfigVariableBool cache_check_timestamps; extern EXPCL_PANDA_PUTIL void init_libputil(); -#endif /* __CONFIG_UTIL_H__ */ +#endif /* __CONFIG_PUTIL_H__ */ From 0cf2a5f38540919b0751c2414072ad0d62b86c14 Mon Sep 17 00:00:00 2001 From: Disyer Date: Sat, 5 Aug 2023 15:44:56 +0300 Subject: [PATCH 62/84] pandatool: Correct header guard names (#1525) --- pandatool/src/egg-optchar/config_egg_optchar.h | 2 +- pandatool/src/palettizer/config_palettizer.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pandatool/src/egg-optchar/config_egg_optchar.h b/pandatool/src/egg-optchar/config_egg_optchar.h index a4e84c6ddb..9d01b7fea0 100644 --- a/pandatool/src/egg-optchar/config_egg_optchar.h +++ b/pandatool/src/egg-optchar/config_egg_optchar.h @@ -18,4 +18,4 @@ void init_egg_optchar(); -#endif /* __CONFIG_UTIL_H__ */ +#endif /* CONFIG_EGG_OPTCHAR_H */ diff --git a/pandatool/src/palettizer/config_palettizer.h b/pandatool/src/palettizer/config_palettizer.h index 7754fe572d..afb2031d06 100644 --- a/pandatool/src/palettizer/config_palettizer.h +++ b/pandatool/src/palettizer/config_palettizer.h @@ -18,4 +18,4 @@ void init_palettizer(); -#endif /* __CONFIG_UTIL_H__ */ +#endif /* CONFIG_PALETTIZER_H */ From f596666b84e7ade3f9d4c747bd6d7281884e0347 Mon Sep 17 00:00:00 2001 From: Disyer Date: Sat, 5 Aug 2023 15:46:08 +0300 Subject: [PATCH 63/84] panda: Install correct config headers for pstatclient and putil Closes #1525 --- panda/src/pstatclient/CMakeLists.txt | 2 +- panda/src/pstatclient/config_pstatclient.h | 6 +++--- panda/src/putil/CMakeLists.txt | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/panda/src/pstatclient/CMakeLists.txt b/panda/src/pstatclient/CMakeLists.txt index faffec2588..ed9b431070 100644 --- a/panda/src/pstatclient/CMakeLists.txt +++ b/panda/src/pstatclient/CMakeLists.txt @@ -48,4 +48,4 @@ if(NOT BUILD_METALIBS) ARCHIVE COMPONENT CoreDevel) endif() install(FILES ${P3PSTATCLIENT_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) -install(FILES config_pstats.h COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) +install(FILES config_pstatclient.h COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) diff --git a/panda/src/pstatclient/config_pstatclient.h b/panda/src/pstatclient/config_pstatclient.h index f4a083afdd..a16967c964 100644 --- a/panda/src/pstatclient/config_pstatclient.h +++ b/panda/src/pstatclient/config_pstatclient.h @@ -11,8 +11,8 @@ * @date 2000-07-09 */ -#ifndef CONFIG_PSTATS_H -#define CONFIG_PSTATS_H +#ifndef CONFIG_PSTATCLIENT_H +#define CONFIG_PSTATCLIENT_H #include "pandabase.h" @@ -49,4 +49,4 @@ extern EXPCL_PANDA_PSTATCLIENT ConfigVariableBool pstats_mem_other; extern EXPCL_PANDA_PSTATCLIENT void init_libpstatclient(); -#endif +#endif /* CONFIG_PSTATCLIENT_H */ diff --git a/panda/src/putil/CMakeLists.txt b/panda/src/putil/CMakeLists.txt index eb312f845a..1332402586 100644 --- a/panda/src/putil/CMakeLists.txt +++ b/panda/src/putil/CMakeLists.txt @@ -162,4 +162,4 @@ if(NOT BUILD_METALIBS) ARCHIVE COMPONENT CoreDevel) endif() install(FILES ${P3PUTIL_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) -install(FILES config_util.h COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) +install(FILES config_putil.h COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) From a463f25d394ccd7382d4c6cfc7b905b561250b81 Mon Sep 17 00:00:00 2001 From: rdb Date: Sat, 5 Aug 2023 15:53:27 +0200 Subject: [PATCH 64/84] Update BACKERS.md [skip ci] --- BACKERS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/BACKERS.md b/BACKERS.md index 960141998c..d1a9dd8727 100644 --- a/BACKERS.md +++ b/BACKERS.md @@ -31,6 +31,7 @@ This is a list of all the people who are contributing financially to Panda3D. I * Gyedo Jeon * GameDev JONI * Max Rodriguez +* Jethro Schoppenhorst ## Backers From 0bc290eb2cf18ee3201d086a0fbc1cc530b488eb Mon Sep 17 00:00:00 2001 From: rdb Date: Sat, 5 Aug 2023 16:37:01 +0200 Subject: [PATCH 65/84] event: Replace _PyGen_FetchStopIterationValue in Python 3.13+ See python/cpython#106320 and python/cpython#107032 Closes #1526 --- panda/src/event/pythonTask.cxx | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/panda/src/event/pythonTask.cxx b/panda/src/event/pythonTask.cxx index f214ee73d6..b6f540fbdf 100644 --- a/panda/src/event/pythonTask.cxx +++ b/panda/src/event/pythonTask.cxx @@ -545,7 +545,17 @@ do_python_task() { Py_DECREF(_generator); _generator = nullptr; -#if PY_VERSION_HEX >= 0x03030000 +#if PY_VERSION_HEX >= 0x030D0000 // Python 3.13 + // Python 3.13 does not support _PyGen_FetchStopIterationValue anymore. + if (PyErr_ExceptionMatches(PyExc_StopIteration)) { + PyObject *exc = PyErr_GetRaisedException(); + result = ((PyStopIterationObject *)exc)->value; + if (result == nullptr) { + result = Py_None; + } + Py_INCREF(result); + Py_DECREF(exc); +#elif PY_VERSION_HEX >= 0x03030000 if (_PyGen_FetchStopIterationValue(&result) == 0) { #else if (PyErr_ExceptionMatches(PyExc_StopIteration)) { From cbfd8f45450b0af296500d9f071f44dc4d91fc58 Mon Sep 17 00:00:00 2001 From: Christopher He <25177239+hecris@users.noreply.github.com> Date: Sat, 5 Aug 2023 15:14:52 -0400 Subject: [PATCH 66/84] collide: Add CollisionHeightfield solid (#691) --- panda/src/collide/CMakeLists.txt | 2 + panda/src/collide/collisionHeightfield.I | 102 +++ panda/src/collide/collisionHeightfield.cxx | 819 +++++++++++++++++++++ panda/src/collide/collisionHeightfield.h | 180 +++++ panda/src/collide/collisionSolid.h | 1 + panda/src/collide/collisionTraverser.cxx | 2 + panda/src/collide/config_collide.cxx | 3 + panda/src/collide/p3collide_composite1.cxx | 1 + tests/collide/collisions.py | 2 +- tests/collide/test_into_heightfield.py | 92 +++ 10 files changed, 1203 insertions(+), 1 deletion(-) create mode 100644 panda/src/collide/collisionHeightfield.I create mode 100644 panda/src/collide/collisionHeightfield.cxx create mode 100644 panda/src/collide/collisionHeightfield.h create mode 100644 tests/collide/test_into_heightfield.py diff --git a/panda/src/collide/CMakeLists.txt b/panda/src/collide/CMakeLists.txt index 32ea22008f..296a40eeed 100644 --- a/panda/src/collide/CMakeLists.txt +++ b/panda/src/collide/CMakeLists.txt @@ -12,6 +12,7 @@ set(P3COLLIDE_HEADERS collisionHandlerPusher.I collisionHandlerPusher.h collisionHandlerFluidPusher.I collisionHandlerFluidPusher.h collisionHandlerQueue.h + collisionHeightfield.I collisionHeightfield.h collisionInvSphere.I collisionInvSphere.h collisionLine.I collisionLine.h collisionLevelStateBase.I collisionLevelStateBase.h @@ -46,6 +47,7 @@ set(P3COLLIDE_SOURCES collisionHandlerPusher.cxx collisionHandlerFluidPusher.cxx collisionHandlerQueue.cxx + collisionHeightfield.cxx collisionLevelStateBase.cxx collisionLevelState.cxx collisionInvSphere.cxx diff --git a/panda/src/collide/collisionHeightfield.I b/panda/src/collide/collisionHeightfield.I new file mode 100644 index 0000000000..8dd9f4b974 --- /dev/null +++ b/panda/src/collide/collisionHeightfield.I @@ -0,0 +1,102 @@ +/** + * 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 collisionHeightfield.I + * @author hecris + * @date 2019-07-01 + */ + +/** + * + */ +INLINE CollisionHeightfield:: +CollisionHeightfield() { +} + +/** + * + */ +INLINE CollisionHeightfield:: +CollisionHeightfield(const CollisionHeightfield ©) { +} + +/** + * + */ +INLINE CollisionHeightfield:: +~CollisionHeightfield() { + delete[] _nodes; + } + +/** + * + */ +INLINE void CollisionHeightfield:: +flush_level() { + _volume_pcollector.flush_level(); + _test_pcollector.flush_level(); +} + +/** + * + */ +INLINE PNMImage CollisionHeightfield:: +get_heightfield() { + return _heightfield; +} + +/** + * + */ +INLINE void CollisionHeightfield:: +set_heightfield(PNMImage heightfield) { + int r = _heightfield.get_x_size(); + int c = _heightfield.get_y_size(); + _heightfield = heightfield; + + if (_heightfield.get_x_size() == r && + _heightfield.get_y_size() == c) { + fill_quadtree_heights(); + } else { + fill_quadtree_areas(); + fill_quadtree_heights(); + } +} + +/** + * + */ +INLINE PN_stdfloat CollisionHeightfield:: +get_max_height() { + return _max_height; +} + +/** + * + */ +INLINE void CollisionHeightfield:: +set_max_height(PN_stdfloat max_height) { + _max_height = max_height; + fill_quadtree_heights(); +} + +/** + * + */ +INLINE int CollisionHeightfield:: +get_num_subdivisions() { + return _num_subdivisions; +} + +/** + * + */ +INLINE PN_stdfloat CollisionHeightfield:: +get_height(int x, int y) const { + return _heightfield.get_gray(x, y) * _max_height; +} diff --git a/panda/src/collide/collisionHeightfield.cxx b/panda/src/collide/collisionHeightfield.cxx new file mode 100644 index 0000000000..6568163d31 --- /dev/null +++ b/panda/src/collide/collisionHeightfield.cxx @@ -0,0 +1,819 @@ +/** + * 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 collisionHeightfield.cxx + * @author hecris + * @date 2019-07-01 + */ + +#include "collisionBox.h" +#include "collisionRay.h" +#include "collisionSphere.h" +#include "collisionHeightfield.h" +#include "collisionHandler.h" +#include "collisionEntry.h" +#include "cmath.h" +#include "config_collide.h" +#include "boundingBox.h" +#include "datagram.h" +#include "datagramIterator.h" +#include "bamReader.h" +#include "bamWriter.h" +#include "geom.h" +#include "geomTriangles.h" +#include "geomVertexWriter.h" +#include +#include + +using std::min; +using std::max; +using std::queue; +using std::vector; +using std::sort; + +PStatCollector CollisionHeightfield::_volume_pcollector( + "Collision Volumes:CollisionHeightfield"); +PStatCollector CollisionHeightfield::_test_pcollector( + "Collision Tests:CollisionHeightfield"); +TypeHandle CollisionHeightfield::_type_handle; + +/** + * + */ +CollisionHeightfield:: +CollisionHeightfield(PNMImage heightfield, + PN_stdfloat max_height, int num_subdivisions) { + _heightfield = heightfield; + _max_height = max_height; + _nodes_count = 0; + + set_num_subdivisions(num_subdivisions); +} + +/** + * Sets the number of quadtree subdivisions and modifies + * the quadtree accordingly. This should be called when a + * user wants to modify the number of quadtree subdivisions + * or from a constructor to initialize the quadtree. + * + * If the number of subdivisions is too high, it will + * automatically be decremented. + */ +void CollisionHeightfield:: +set_num_subdivisions(int num_subdivisions) { + // The number of subdivisions should not be negative + nassertv(num_subdivisions >= 0 && num_subdivisions <= 10); + // Determine the number of quadtree nodes needed + // for the corresponding number of subdivisions. + int nodes_count = 0; + for (int i = 0; i <= num_subdivisions; i++) { + nodes_count += 1 << (i * 2); + } + if (nodes_count == _nodes_count) { + // No changes to quadtree to be done + return; + } + // Calculate the index of the first quad tree leaf node + int leaf_first_index = nodes_count - pow(4, num_subdivisions); + // Calculate the area of a leaf node in the quadtree + PN_stdfloat heightfield_area = _heightfield.get_x_size() * + _heightfield.get_y_size(); + nassertv(heightfield_area > 0); + PN_stdfloat num_leafs = nodes_count - leaf_first_index; + // If the area is too small (less than 1), then we + // retry by decrementing the number of subdivisions. + if (heightfield_area / num_leafs < 1) { + set_num_subdivisions(num_subdivisions - 1); + return; + } + if (nodes_count < _nodes_count) { + // If the user is decreasing the number of subdivisions, then + // we need only to update the index where the quadtree leaves start. + _leaf_first_index = leaf_first_index; + } else { + // Otherwise we need to build a new quadtree + if (_nodes_count != 0) { + // There is an existing quadtree, delete it first + delete[] _nodes; + _nodes = nullptr; + } + QuadTreeNode *nodes = new QuadTreeNode[nodes_count]; + _nodes = nodes; + _nodes_count = nodes_count; + _leaf_first_index = leaf_first_index; + fill_quadtree_areas(); + fill_quadtree_heights(); + } + _num_subdivisions = num_subdivisions; +} + +/** + * + */ +void CollisionHeightfield:: +fill_quadtree_areas() { + nassertv(_heightfield.get_x_size() > 0 && + _heightfield.get_y_size() > 0); + + _nodes[0].area.min = {0, 0}; + _nodes[0].area.max = {(float)_heightfield.get_x_size(), + (float)_heightfield.get_y_size()}; + _nodes[0].index = 0; + QuadTreeNode parent; + for (int i = 1; i < _nodes_count; i += 4) { + parent = _nodes[(i-1) / 4]; + LVector2 sub_area = (parent.area.max - parent.area.min) / 2; + // SE Quadrant + _nodes[i].area.min = parent.area.min; + _nodes[i].area.max = parent.area.min + sub_area; + _nodes[i].index = i; + // SW Quadrant + _nodes[i + 1].area.min = {parent.area.min[0] + sub_area[0], + parent.area.min[1]}; + _nodes[i + 1].area.max = _nodes[i + 1].area.min + sub_area; + _nodes[i + 1].index = i + 1; + // NE Quadrant + _nodes[i + 2].area.min = {parent.area.min[0], + parent.area.min[1] + sub_area[1]}; + _nodes[i + 2].area.max = _nodes[i + 2].area.min + sub_area; + _nodes[i + 2].index = i + 2; + // NW Quadrant + _nodes[i + 3].area.min = parent.area.min + sub_area; + _nodes[i + 3].area.max = parent.area.max; + _nodes[i + 3].index = i + 3; + } +} + +/** + * Processes the heightfield image, setting the height values + * of each quadtree node. + * + * @relates set_max_height + * @relates set_heightfield + */ +void CollisionHeightfield:: +fill_quadtree_heights() { + QuadTreeNode node; + QuadTreeNode child; + for (int i = _nodes_count - 1; i >= 0; i--) { + node = _nodes[i]; + PN_stdfloat height_min = INT_MAX; + PN_stdfloat height_max = INT_MIN; + if (i >= _leaf_first_index) { + for (int x = node.area.min[0]; x < node.area.max[0]; x++) { + for (int y = node.area.min[1]; y < node.area.max[1]; y++) { + PN_stdfloat value = _heightfield.get_gray(x, + _heightfield.get_y_size() - 1 - y) * _max_height; + + height_min = min(value, height_min); + height_max = max(value, height_max); + } + } + } else { + for (int c = (i * 4) + 1, cmax = c + 4; c < cmax; c++) { + child = _nodes[c]; + height_min = min(child.height_min, height_min); + height_max = max(child.height_max, height_max); + } + } + _nodes[i].height_min = height_min; + _nodes[i].height_max = height_max; + } +} + +/** + * + */ +PT(CollisionEntry) CollisionHeightfield:: +test_intersection_from_ray(const CollisionEntry &entry) const { + const CollisionRay *ray; + DCAST_INTO_R(ray, entry.get_from(), nullptr); + const LMatrix4 &wrt_mat = entry.get_wrt_mat(); + + LPoint3 from_origin = ray->get_origin() * wrt_mat; + LPoint3 from_direction = ray->get_direction() * wrt_mat; + + IntersectionParams params; + params.from_origin = from_origin; + params.from_direction = from_direction; + vector intersections; + intersections = find_intersections(line_intersects_box, params); + + if (intersections.empty()) { + return nullptr; + } + // Sort intersections by their t1 values so we can return + // the first intersection found. + sort(intersections.begin(), intersections.end()); + + double t1, t2; + for (size_t i = 0; i < intersections.size(); i++) { + t1 = intersections[i].tmin; + t2 = intersections[i].tmax; + + if (t1 < 0.0 && t2 < 0.0) continue; + t1 = max(t1, 0.0); + + LPoint3 p1 = from_origin + from_direction * t1; + LPoint3 p2 = from_origin + from_direction * t2; + // We use Bresenhaum's Line Algorithm to directly get the heightfield + // coordinates that the line passes through. + int err = cabs(2 * (p2[1] - p1[1])); + int deltaerr = cabs(err - (p2[0] - p1[0])); + + int x = p1[0], y = p1[1]; + bool x_increasing = x < p2[0]; + bool y_increasing = y < p2[1]; + while ((x_increasing && x <= p2[0]) || (!x_increasing && x >= p2[0])) { + bool intersected = false; + Triangle int_tri; + vector triangles = get_triangles(x, y); + double min_t = DBL_MAX; + for (Triangle tri : triangles) { + double t; + if (line_intersects_triangle(t, from_origin, from_direction, tri)) { + if (t < 0) continue; + if (t < min_t) { + intersected = true; + min_t = t; + int_tri = tri; + } + } + } + // If the ray intersects this heightfield element, we can + // stop here and return the intersection. + if (intersected) { + PT(CollisionEntry) new_entry = new CollisionEntry(entry); + new_entry->set_surface_point(from_origin + from_direction * min_t); + LPlane p = LPlane(int_tri.p1, int_tri.p2, int_tri.p3); + LVector3 normal = p.get_normal(); + if (p.dist_to_plane(from_origin) < 0.0f) normal *= -1; + new_entry->set_surface_normal(normal); + return new_entry; + } + // Otherwise, go to the next heightfield element + deltaerr += err; + if (deltaerr >= 0) { + if (y_increasing) y++; + else y--; + deltaerr -= 2 * (p2[0] - p1[0]); + } + if (x_increasing) x++; + else x--; + } + } + + return nullptr; +} + +/** + * + */ +PT(CollisionEntry) CollisionHeightfield:: +test_intersection_from_sphere(const CollisionEntry &entry) const { + const CollisionSphere *sphere; + DCAST_INTO_R(sphere, entry.get_from(), nullptr); + + CPT(TransformState) wrt_space = entry.get_wrt_space(); + const LMatrix4 &wrt_mat = wrt_space->get_mat(); + + LPoint3 center = sphere->get_center() * wrt_mat; + LVector3 radius_v = LVector3(sphere->get_radius(), 0.0f, 0.0f) * wrt_mat; + PN_stdfloat radius_2 = radius_v.length_squared(); + PN_stdfloat radius = csqrt(radius_2); + + IntersectionParams params; + params.center = center; + params.radius = radius; + + vector intersections; + intersections= find_intersections(sphere_intersects_box, params); + + if (intersections.empty()) { + return nullptr; + } + + LPoint3 point; + LPoint3 closest_point; + PN_stdfloat dist; + PN_stdfloat dist_min = FLT_MAX; + + bool intersected = false; + for (size_t i = 0; i < intersections.size(); i++) { + QuadTreeNode node = _nodes[intersections[i].node_index]; + // Iterate through the circle's area and find triangle intersections, + // find the one closest to the center of the sphere. + for (int dx = -radius; dx <= radius; dx++) { + for (int dy = -radius; dy <= radius; dy++) { + int x = dx + center[0]; + int y = dy + center[1]; + if (x < node.area.min[0] || y < node.area.min[1] || + x > node.area.max[0] || y > node.area.max[1]) { + // point not contained in rectangle + continue; + } + if (dx * dx + dy * dy > radius_2) continue; + + vector triangles = get_triangles(x, y); + for (Triangle tri : triangles) { + point = closest_point_on_triangle(center, tri); + dist = (point - center).length_squared(); + if (dist > radius_2) continue; + if (dist < dist_min) { + intersected = true; + dist_min = dist; + closest_point = point; + } + } + } + } + } + if (intersected) { + PT(CollisionEntry) new_entry = new CollisionEntry(entry); + LVector3 v(center - closest_point); + PN_stdfloat v_length = v.length(); + if (IS_NEARLY_ZERO(v_length)) { + v.set(1, 0, 0); + } else { + v /= v_length; + } + new_entry->set_surface_point(closest_point); + new_entry->set_surface_normal(v); + new_entry->set_interior_point(center - radius * v); + return new_entry; + } else { + return nullptr; + } +} + +/** + * + */ +PT(CollisionEntry) CollisionHeightfield:: +test_intersection_from_box(const CollisionEntry &entry) const { + const CollisionBox *box; + DCAST_INTO_R(box, entry.get_from(), nullptr); + + const LMatrix4 &wrt_mat = entry.get_wrt_mat(); + LPoint3 box_min = box->get_min() * wrt_mat; + LPoint3 box_max = box->get_max() * wrt_mat; + + IntersectionParams params; + params.box_min = box_min; + params.box_max = box_max; + + vector intersections; + intersections = find_intersections(box_intersects_box, params); + + if (intersections.empty()) { + return nullptr; + } + + bool intersected = false; + Triangle intersected_tri; + for (size_t i = 0; i < intersections.size(); i++) { + QuadTreeNode node = _nodes[intersections[i].node_index]; + // Find the overlapping rectangle between the two boxes and + // test the heightfield elements in that area. + LVecBase2 overlap_min = LVecBase2(max(box_min[0], node.area.min[0]), + max(box_min[1], node.area.min[1])); + LVecBase2 overlap_max = LVecBase2(min(box_max[0], node.area.max[0]), + min(box_max[1], node.area.max[1])); + for (int x = overlap_min[0]; x < overlap_max[0]; x++) { + for (int y = overlap_min[1]; y < overlap_max[1]; y++) { + vector triangles = get_triangles(x, y); + for (Triangle tri : triangles) { + if (box_intersects_triangle(box_min, box_max, tri)) { + intersected = true; + intersected_tri = tri; + } + } + } + } + } + + if (intersected) { + PT(CollisionEntry) new_entry = new CollisionEntry(entry); + LPlane p = LPlane(intersected_tri.p1, intersected_tri.p2, intersected_tri.p3); + LVector3 normal = p.get_normal(); + if (p.dist_to_plane(box->get_center() * wrt_mat) < 0.0f) { + normal *= -1; + p.flip(); + } + new_entry->set_surface_normal(normal); + PN_stdfloat min_dist = 0; + LPoint3 interior_point; + // Find the deepest vertex and set it as the interior point + for (int i = 0; i < 8; i++) { + LPoint3 vertex = box->get_point(i) * wrt_mat; + PN_stdfloat dist = p.dist_to_plane(vertex); + if (dist <= min_dist) { + min_dist = dist; + interior_point = vertex; + } + } + new_entry->set_interior_point(interior_point); + new_entry->set_surface_point( + closest_point_on_triangle(interior_point, intersected_tri)); + return new_entry; + } else { + return nullptr; + } +} + +/** + * + */ +bool CollisionHeightfield:: +line_intersects_box(const LPoint3 &box_min, const LPoint3 &box_max, + IntersectionParams ¶ms) { + LPoint3 from = params.from_origin; + LPoint3 delta = params.from_direction; + + double tmin = -DBL_MAX; + double tmax = DBL_MAX; + for (int i = 0; i < 3; ++i) { + PN_stdfloat d = delta[i]; + if (!IS_NEARLY_ZERO(d)) { + double tmin2 = (box_min[i] - from[i]) / d; + double tmax2 = (box_max[i] - from[i]) / d; + if (tmin2 > tmax2) { + std::swap(tmin2, tmax2); + } + tmin = max(tmin, tmin2); + tmax = min(tmax, tmax2); + if (tmin > tmax) { + return false; + } + } else if (from[i] < box_min[i] || from[i] > box_max[i]) { + // The line is parallel + return false; + } + } + params.t1 = tmin; + params.t2 = tmax; + return true; +} + +/** + * + */ +bool CollisionHeightfield:: +line_intersects_triangle(double &t, const LPoint3 &from, + const LPoint3 &delta, + const Triangle &triangle) { + // Implementation of Möller-Trumbore algorithm + PN_stdfloat a,f,u,v; + LVector3 edge1, edge2, h, s, q; + edge1 = triangle.p2 - triangle.p1; + edge2 = triangle.p3 - triangle.p1; + h = delta.cross(edge2); + a = dot(edge1, h); + if (IS_NEARLY_ZERO(a)) { + // line parallel to triangle + return false; + } + f = 1.0 / a; + s = from - triangle.p1; + u = f * dot(s, h); + if (u < 0.0 || u > 1.0) { + return false; + } + q = s.cross(edge1); + v = f * dot(delta, q); + if (v < 0.0 || u + v > 1.0) { + return false; + } + t = f * dot(edge2, q); + return true; +} + +/** + * + */ +bool CollisionHeightfield:: +sphere_intersects_box(const LPoint3 &box_min, const LPoint3 &box_max, + IntersectionParams ¶ms) { + LPoint3 center = params.center; + double radius = params.radius; + LPoint3 p = center.fmin(box_max).fmax(box_min); + return (center - p).length_squared() <= radius * radius; +} + +/** + * + */ +bool CollisionHeightfield:: +box_intersects_triangle(const LPoint3 &box_min, const LPoint3 &box_max, + const Triangle &triangle) { + // Using the Seperating Axis Theorem, we have a maximum of 13 SAT tests + // Refer to Christer Ericson's Collision Detection book for full explanation + LPoint3 v0 = triangle.p1, v1 = triangle.p2, v2 = triangle.p3; + + PN_stdfloat p0, p1, p2, r; + LVector3 c = (box_min + box_max) * 0.5f; + PN_stdfloat e0 = (box_max[0] - box_min[0]) * 0.5f; + PN_stdfloat e1 = (box_max[1] - box_min[1]) * 0.5f; + PN_stdfloat e2 = (box_max[2] - box_min[2]) * 0.5f; + + v0 = v0 - c; + v1 = v1 - c; + v2 = v2 - c; + + LVector3 f0 = v1 - v0, f1 = v2 - v1, f2 = v0 - v2; + + r = e1 * cabs(f0[2]) + e2 * cabs(f0[1]); + p0 = v0[1]*(-v1[2] + v0[2]) + v0[2]*(v1[1] - v0[1]); + p2 = v2[1]*(-v1[2] + v0[2]) + v2[2]*(v1[1] - v0[1]); + if (max(-1 * max(p0, p2), min(p0, p2)) > r) return false; + + r = e1 * cabs(f1[2]) + e2 * cabs(f1[1]); + p0 = v0[1]*(-v2[2] + v1[2]) + v0[2]*(v2[1] - v1[1]); + p2 = v2[1]*(-v2[2] + v1[2]) + v2[2]*(v2[1] - v1[1]); + if (max(-1 * max(p0, p2), min(p0, p2)) > r) return false; + + r = e1 * cabs(f2[2]) + e2 * cabs(f2[1]); + p0 = v0[1]*(-v0[2] + v2[2]) + v0[2]*(v0[1] - v2[1]); + p1 = v1[1]*(-v0[2] + v2[2]) + v1[2]*(v0[1] - v2[1]); + if (max(-1 * max(p0, p1), min(p0, p1)) > r) return false; + + r = e0 * cabs(f0[2]) + e2 * cabs(f0[0]); + p0 = v0[0]*(v1[2] - v0[2]) + v0[2]*(-v1[0] + v0[0]); + p2 = v2[0]*(v1[2] - v0[2]) + v2[2]*(-v1[0] + v0[0]); + if (max(-1 * max(p0, p2), min(p0, p2)) > r) return false; + + r = e0 * cabs(f1[2]) + e2 * cabs(f1[0]); + p0 = v0[0]*(v2[2] - v1[2]) + v0[2]*(-v2[0] + v1[0]); + p2 = v2[0]*(v2[2] - v1[2]) + v2[2]*(-v2[0] + v1[0]); + if (max(-1 * max(p0, p2), min(p0, p2)) > r) return false; + + r = e0 * cabs(f2[2]) + e2 * cabs(f2[0]); + p0 = v0[0]*(v0[2] - v2[2]) + v0[2]*(-v0[0] + v2[0]); + p1 = v1[0]*(v0[2] - v2[2]) + v1[2]*(-v0[0] + v2[0]); + if (max(-1 * max(p0, p1), min(p0, p1)) > r) return false; + + r = e0 * cabs(f0[1]) + e1 * cabs(f0[0]); + p0 = v0[0]*(-v1[1] + v0[1]) + v0[1]*(v1[0] - v0[0]); + p2 = v2[0]*(-v1[1] + v0[1]) + v2[1]*(v1[0] - v0[0]); + if (max(-1 * max(p0, p2), min(p0, p2)) > r) return false; + + r = e0 * cabs(f1[1]) + e1 * cabs(f1[0]); + p0 = v0[0]*(-v2[1] + v1[1]) + v0[1]*(v2[0] - v1[0]); + p2 = v2[0]*(-v2[1] + v1[1]) + v2[1]*(v2[0] - v1[0]); + if (max(-1 * max(p0, p2), min(p0, p2)) > r) return false; + + r = e0 * cabs(f2[1]) + e1 * cabs(f2[0]); + p0 = v0[0]*(-v0[1] + v2[1]) + v0[1]*(v0[0] - v2[0]); + p1 = v1[0]*(-v0[1] + v2[1]) + v1[1]*(v0[0] - v2[0]); + if (max(-1 * max(p0, p1), min(p0, p1)) > r) return false; + + if (max(max(v0[0], v1[0]), v2[0]) < -e0 || + min(min(v0[0], v1[0]), v2[0]) > e0) return false; + if (max(max(v0[1], v1[1]), v2[1]) < -e1 || + min(min(v0[1], v1[1]), v2[1]) > e1) return false; + if (max(max(v0[2], v1[2]), v2[2]) < -e2 || + min(min(v0[2], v1[2]), v2[2]) > e2) return false; + + LVector3 n = f0.cross(f1); + PN_stdfloat d = dot(n, triangle.p1); + + LPoint3 e = box_max - c; + + PN_stdfloat r2 = e[0] * cabs(n[0]) + e[1] * cabs(n[1]) + e[2] * cabs(n[2]); + PN_stdfloat s = dot(n, c) - d; + return cabs(s) <= r2; +} + +/** + * + */ +bool CollisionHeightfield:: +box_intersects_box(const LPoint3 &box_min, const LPoint3 &box_max, + IntersectionParams ¶ms) { + + return (box_min[0] <= params.box_max[0] && box_max[0] >= params.box_min[0]) && + (box_min[1] <= params.box_max[1] && box_max[1] >= params.box_min[1]) && + (box_min[2] <= params.box_max[2] && box_max[2] >= params.box_min[2]); +} + +/** + * Returns the closest point on a triangle to another given point. + */ +LPoint3 CollisionHeightfield:: +closest_point_on_triangle(const LPoint3 &p, const Triangle &triangle) { + LVector3 ab = triangle.p2 - triangle.p1; + LVector3 ac = triangle.p3 - triangle.p1; + LVector3 ap = p - triangle.p1; + PN_stdfloat d1 = dot(ab, ap); + PN_stdfloat d2 = dot(ac, ap); + if (d1 <= 0.0f && d2 <= 0.0f) return triangle.p1; + + LVector3 bp = p - triangle.p2; + PN_stdfloat d3 = dot(ab, bp); + PN_stdfloat d4 = dot(ac, bp); + if (d3 >= 0.0f && d4 <= d3) return triangle.p2; + + PN_stdfloat vc = d1 * d4 - d3 * d2; + if (vc <= 0.0f && d1 >= 0.0f && d3 <= 0.0f) { + PN_stdfloat v = d1 / (d1 - d3); + return triangle.p1 + v * ab; + } + + LVector3 cp = p - triangle.p3; + PN_stdfloat d5 = dot(ab, cp); + PN_stdfloat d6 = dot(ac, cp); + if (d6 >= 0.0f && d5 <= d6) return triangle.p3; + + PN_stdfloat vb = d5 * d2 - d1 * d6; + if (vb <= 0.0f && d2 >= 0.0f && d6 <= 0.0f) { + PN_stdfloat w = d2 / (d2 - d6); + return triangle.p1 + w * ac; + } + + PN_stdfloat va = d3 * d6 - d5 * d4; + if (va <= 0.0f && (d4 - d3) >= 0.0f && (d5 - d6) >= 0.0f) { + PN_stdfloat w = (d4 - d3) / ((d4 - d3) + (d5 - d6)); + return triangle.p2 + w * (triangle.p3 - triangle.p2); + } + + PN_stdfloat denom = 1.0f / (va + vb + vc); + PN_stdfloat v = vb * denom; + PN_stdfloat w = vc * denom; + return triangle.p1 + ab * v + ac * w; +} + +/** + * Given a pointer to a function that tests for intersection between a solid + * and a box, return the quad tree nodes that are intersected by that solid. + */ +vector CollisionHeightfield:: +find_intersections(BoxIntersection intersects_box, IntersectionParams params) const { + queue q; + QuadTreeNode node = _nodes[0]; + q.push(node); + + LPoint3 box_min, box_max; + vector intersections; + + while (!q.empty()) { + node = q.front(); + q.pop(); + box_min = {node.area.min[0], node.area.min[1], node.height_min}; + box_max = {node.area.max[0], node.area.max[1], node.height_max}; + if (!intersects_box(box_min, box_max, params)) { + continue; + } + + if (node.index >= _leaf_first_index) { + QuadTreeIntersection intersection = {node.index, params.t1, params.t2}; + intersections.push_back(intersection); + } else { + int child_first_index = 4 * node.index + 1; + q.push(_nodes[child_first_index]); + q.push(_nodes[child_first_index + 1]); + q.push(_nodes[child_first_index + 2]); + q.push(_nodes[child_first_index + 3]); + } + } + + return intersections; +} + +/** + * Return the triangles that are defined at the + * given 2D coordinate. + */ +vector CollisionHeightfield:: +get_triangles(int x, int y) const { + int rows = _heightfield.get_x_size(); + int cols = _heightfield.get_y_size(); + vector triangles; + if (x < 0 || y < 0 || x >= rows || y >= cols) + return triangles; + + Triangle t; + int heightfield_y = cols - 1 - y; + bool odd = (x + heightfield_y) & 1; + t.p1 = LPoint3(x, y, get_height(x, heightfield_y)); + for (int dx = -1; dx <= 1; dx += 2) { + for (int dy = -1; dy <= 1; dy += 2) { + int x2 = x + dx; + int y2 = y - dy; + int heightfield_y2 = heightfield_y + dy; + if (x2 < 0 || heightfield_y2 < 0 || x2 >= rows || heightfield_y2 >= cols) continue; + if (odd) { + t.p2 = LPoint3(x2, y, get_height(x2, heightfield_y)); + t.p3 = LPoint3(x, y2, get_height(x, heightfield_y2)); + } else { + t.p2 = LPoint3(x2, y2, get_height(x2, heightfield_y2)); + t.p3 = LPoint3(x2, y, get_height(x2, heightfield_y)); + triangles.push_back(t); + t.p3 = LPoint3(x, y2, get_height(x, heightfield_y2)); + triangles.push_back(t); + } + } + } + + return triangles; +} + +/** + * Generic CollisionSolid member functions + */ +void CollisionHeightfield:: +fill_viz_geom() { + PT(GeomVertexData) vdata = new GeomVertexData + ("collision", GeomVertexFormat::get_v3(), + Geom::UH_static); + + GeomVertexWriter vertex(vdata, InternalName::get_vertex()); + + PT(GeomTriangles) tris = new GeomTriangles(Geom::UH_static); + + int cols = _heightfield.get_x_size(); + int rows = _heightfield.get_y_size(); + + for (int y = 0; y < rows; y++) { + for (int x = 0; x < cols; x++) { + // a point (x, y) in the heightfield image + // maps to (x, y2, height_at(x, y)) in 3D space + int y2 = rows - y - 1; + vertex.add_data3(x, y2, get_height(x, y)); + } + } + + for (int i = 0; i < rows - 1; i++) { + for (int j = 0; j < cols - 1; j++) { + int pos = i * cols + j; + if (pos & 1) { // odd + tris->add_vertices(pos, pos + cols, pos + 1); + tris->add_vertices(pos + 1, pos + cols, pos + cols + 1); + } + else { // even + tris->add_vertices(pos, pos + cols, pos + cols + 1); + tris->add_vertices(pos, pos + cols + 1, pos + 1); + } + } + } + + PT(Geom) geom = new Geom(vdata); + geom->add_primitive(tris); + + _viz_geom->add_geom(geom, get_solid_viz_state()); + _bounds_viz_geom->add_geom(geom, get_solid_bounds_viz_state()); +} + +CollisionSolid *CollisionHeightfield:: +make_copy() { + return new CollisionHeightfield(*this); +} + +LPoint3 CollisionHeightfield:: +get_collision_origin() const { + return LPoint3(0, 0, 0); +} + +PT(BoundingVolume) CollisionHeightfield:: +compute_internal_bounds() const { + QuadTreeNode node = _nodes[0]; + LPoint3 box_min = {node.area.min[0], node.area.min[1], + node.height_min}; + LPoint3 box_max = {node.area.max[0], node.area.max[1], + node.height_max}; + return new BoundingBox(box_min, box_max); +} + +PStatCollector &CollisionHeightfield:: +get_volume_pcollector() { + return _volume_pcollector; +} + +PStatCollector &CollisionHeightfield:: +get_test_pcollector() { + return _test_pcollector; +} + +TypedWritable *CollisionHeightfield:: +make_CollisionHeightfield(const FactoryParams ¶ms) { + CollisionHeightfield *me = new CollisionHeightfield; + DatagramIterator scan; + BamReader *manager; + + parse_params(params, scan, manager); + me->fillin(scan, manager); + return me; +} + +void CollisionHeightfield:: +fillin(DatagramIterator &scan, BamReader *manager) { +} + +void CollisionHeightfield:: +register_with_read_factory() { + BamReader::get_factory()->register_factory(get_class_type(), make_CollisionHeightfield); +} diff --git a/panda/src/collide/collisionHeightfield.h b/panda/src/collide/collisionHeightfield.h new file mode 100644 index 0000000000..bbeb6da34d --- /dev/null +++ b/panda/src/collide/collisionHeightfield.h @@ -0,0 +1,180 @@ +/** + * 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 collisionHeightfield.h + * @author hecris + * @date 2019-07-01 + */ + +#ifndef COLLISIONHEIGHTFIELD_H +#define COLLISIONHEIGHTFIELD_H + +#include "pandabase.h" +#include "collisionSolid.h" +#include "pnmImage.h" + +/* + * CollisionHeightfield efficiently deals with collisions on uneven + * terrain given a heightfield image. A quad tree is implemented to + * significantly reduce the amount of triangles tested. Each quad + * tree node represents a sub-rectangle of the heightfield image + * and thus a box in 3D space. + * */ +class EXPCL_PANDA_COLLIDE CollisionHeightfield : public CollisionSolid { +PUBLISHED: + CollisionHeightfield(PNMImage heightfield, + PN_stdfloat max_height, int num_subdivisions); + virtual LPoint3 get_collision_origin() const; + + INLINE PNMImage get_heightfield(); + INLINE void set_heightfield(PNMImage heightfield); + + INLINE PN_stdfloat get_max_height(); + INLINE void set_max_height(PN_stdfloat max_height); + + INLINE int get_num_subdivisions(); + void set_num_subdivisions(int num_subdivisions); + + INLINE PN_stdfloat get_height(int x, int y) const; + +protected: + struct Rect { + LVector2 min; + LVector2 max; + }; + + struct QuadTreeNode { + int index; + Rect area; + PN_stdfloat height_min; + PN_stdfloat height_max; + }; + + struct QuadTreeIntersection { + int node_index; + double tmin; + double tmax; + bool operator < (const QuadTreeIntersection& intersection) const { + return tmin < intersection.tmin; + } + }; + + struct IntersectionParams { + // From Line + double t1; + double t2; + LPoint3 from_origin; + LVector3 from_direction; + // From Sphere + LPoint3 center; + double radius; + // From Box + LPoint3 box_min; + LPoint3 box_max; + }; + + struct Triangle { + LPoint3 p1; + LPoint3 p2; + LPoint3 p3; + }; + +private: + PNMImage _heightfield; + PN_stdfloat _max_height; + int _num_subdivisions; + QuadTreeNode *_nodes; + int _nodes_count; + int _leaf_first_index; + void fill_quadtree_areas(); + void fill_quadtree_heights(); + std::vector get_triangles(int x, int y) const; + + // A pointer to a function that tests for intersection between a box and a + // solid defined by the given IntersectionParams. + typedef bool (*BoxIntersection)(const LPoint3 &box_min, const LPoint3 &box_max, + IntersectionParams ¶ms); + + std::vector find_intersections(BoxIntersection intersects_box, + IntersectionParams params) const; + +protected: + static LPoint3 closest_point_on_triangle(const LPoint3 &p, const Triangle &triangle); + + static bool line_intersects_box(const LPoint3 &box_min, const LPoint3 &box_max, + IntersectionParams ¶ms); + + static bool line_intersects_triangle(double &t, const LPoint3 &from, + const LPoint3 &delta, + const Triangle &triangle); + + static bool sphere_intersects_box(const LPoint3 &box_min, const LPoint3 &box_max, + IntersectionParams ¶ms); + + static bool box_intersects_box(const LPoint3 &box_min, const LPoint3 &box_max, + IntersectionParams ¶ms); + + static bool box_intersects_triangle(const LPoint3 &box_min, const LPoint3 &box_max, + const Triangle &triangle); + +protected: + virtual PT(CollisionEntry) + test_intersection_from_ray(const CollisionEntry &entry) const; + virtual PT(CollisionEntry) + test_intersection_from_sphere(const CollisionEntry &entry) const; + virtual PT(CollisionEntry) + test_intersection_from_box(const CollisionEntry &entry) const; + + virtual void fill_viz_geom(); + +public: + INLINE CollisionHeightfield(const CollisionHeightfield ©); + virtual CollisionSolid *make_copy(); + + virtual PStatCollector &get_volume_pcollector(); + virtual PStatCollector &get_test_pcollector(); + + INLINE static void flush_level(); + INLINE ~CollisionHeightfield(); + +protected: + virtual PT(BoundingVolume) compute_internal_bounds() const; + +private: + INLINE CollisionHeightfield(); + static PStatCollector _volume_pcollector; + static PStatCollector _test_pcollector; + +protected: + static TypedWritable *make_CollisionHeightfield(const FactoryParams ¶ms); + void fillin(DatagramIterator &scan, BamReader *manager); + +public: + static void register_with_read_factory(); + +public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type() { + CollisionSolid::init_type(); + register_type(_type_handle, "CollisionHeightfield", + CollisionSolid::get_class_type()); + } + 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; +}; + +#include "collisionHeightfield.I" + +#endif diff --git a/panda/src/collide/collisionSolid.h b/panda/src/collide/collisionSolid.h index 4721d70381..4b1d17ce15 100644 --- a/panda/src/collide/collisionSolid.h +++ b/panda/src/collide/collisionSolid.h @@ -181,6 +181,7 @@ private: friend class CollisionParabola; friend class CollisionHandlerFluidPusher; friend class CollisionBox; + friend class CollisionHeightfield; }; INLINE std::ostream &operator << (std::ostream &out, const CollisionSolid &cs) { diff --git a/panda/src/collide/collisionTraverser.cxx b/panda/src/collide/collisionTraverser.cxx index 50f187ad77..87dad21203 100644 --- a/panda/src/collide/collisionTraverser.cxx +++ b/panda/src/collide/collisionTraverser.cxx @@ -19,6 +19,7 @@ #include "collisionRecorder.h" #include "collisionVisualizer.h" #include "collisionSphere.h" +#include "collisionHeightfield.h" #include "collisionBox.h" #include "collisionCapsule.h" #include "collisionPolygon.h" @@ -354,6 +355,7 @@ traverse(const NodePath &root) { CollisionPolygon::flush_level(); CollisionPlane::flush_level(); CollisionBox::flush_level(); + CollisionHeightfield::flush_level(); } #if defined(DO_COLLISION_RECORDING) || !defined(CPPPARSER) diff --git a/panda/src/collide/config_collide.cxx b/panda/src/collide/config_collide.cxx index b9ca4e368a..88e701abe3 100644 --- a/panda/src/collide/config_collide.cxx +++ b/panda/src/collide/config_collide.cxx @@ -25,6 +25,7 @@ #include "collisionHandlerFluidPusher.h" #include "collisionHandlerQueue.h" #include "collisionInvSphere.h" +#include "collisionHeightfield.h" #include "collisionLine.h" #include "collisionLevelStateBase.h" #include "collisionGeom.h" @@ -138,6 +139,7 @@ init_libcollide() { CollisionHandlerFluidPusher::init_type(); CollisionHandlerQueue::init_type(); CollisionInvSphere::init_type(); + CollisionHeightfield::init_type(); CollisionLine::init_type(); CollisionLevelStateBase::init_type(); CollisionGeom::init_type(); @@ -164,6 +166,7 @@ init_libcollide() { CollisionBox::register_with_read_factory(); CollisionCapsule::register_with_read_factory(); CollisionInvSphere::register_with_read_factory(); + CollisionHeightfield::register_with_read_factory(); CollisionLine::register_with_read_factory(); CollisionNode::register_with_read_factory(); CollisionParabola::register_with_read_factory(); diff --git a/panda/src/collide/p3collide_composite1.cxx b/panda/src/collide/p3collide_composite1.cxx index af8ecc07d8..a105cc83f5 100644 --- a/panda/src/collide/p3collide_composite1.cxx +++ b/panda/src/collide/p3collide_composite1.cxx @@ -13,3 +13,4 @@ #include "collisionHandlerFluidPusher.cxx" #include "collisionHandlerQueue.cxx" #include "collisionInvSphere.cxx" +#include "collisionHeightfield.cxx" diff --git a/tests/collide/collisions.py b/tests/collide/collisions.py index cca2a04215..a66b03e4d1 100644 --- a/tests/collide/collisions.py +++ b/tests/collide/collisions.py @@ -2,7 +2,7 @@ from panda3d.core import CollisionNode, NodePath from panda3d.core import CollisionTraverser, CollisionHandlerQueue from panda3d.core import CollisionSphere, CollisionInvSphere, CollisionBox, CollisionPolygon, CollisionCapsule from panda3d.core import CollisionLine, CollisionRay, CollisionSegment, CollisionParabola -from panda3d.core import CollisionPlane +from panda3d.core import CollisionPlane, CollisionHeightfield from panda3d.core import Point3, Vec3, Plane, LParabola diff --git a/tests/collide/test_into_heightfield.py b/tests/collide/test_into_heightfield.py new file mode 100644 index 0000000000..fe2ab07b57 --- /dev/null +++ b/tests/collide/test_into_heightfield.py @@ -0,0 +1,92 @@ +import pytest +from collisions import * +from panda3d.core import PNMImage + +def test_sphere_into_heightfield(): + # Setup PNMImage + img = PNMImage(512, 512, 1) + img.set_gray_val(1, 1, 255) + # Make CollisionHeightfield + max_height = 10 + num_subdivisions = 1 + heightfield = CollisionHeightfield(img, max_height, num_subdivisions) + # The coordinate (1, 1) on our heightfield image + # maps to the coordinate (1, 510, Z) in 3D space + sphere = CollisionSphere((1, 510, 11), 1) + entry, np_from, np_into = make_collision(sphere, heightfield) + assert entry.get_surface_point(np_from) == (1, 510, 10) + assert entry.get_surface_normal(np_from) == (0, 0, 1) + # Set the sphere higher so it is not colliding anymore + sphere.set_center((1, 510, 11.1)) + entry = make_collision(sphere, heightfield)[0] + assert entry is None + # Set the max_height to re-collide with the sphere + max_height = 10.1 + heightfield.set_max_height(max_height) + entry, np_from, np_into = make_collision(sphere, heightfield) + assert entry.get_surface_point(np_from) == (1, 510, 10.1) + + with pytest.raises(AssertionError) as err: + assert heightfield.set_num_subdivisions(-1) == err + assert heightfield.set_num_subdivisions(11) == err + + # Use a greater number of subdivisions, should still work + num_subdivisions = 10 + heightfield.set_num_subdivisions(num_subdivisions) + entry, np_from, np_into = make_collision(sphere, heightfield) + assert entry.get_surface_point(np_from) == (1, 510, 10.1) + # Using 10 subdivisions is overkill for such a small heightfield, + # CollisionHeightfield should've automatically decreased it + assert heightfield.get_num_subdivisions() < num_subdivisions + # Zero subdivisions should work too + num_subdivisions = 0 + heightfield.set_num_subdivisions(num_subdivisions) + entry, np_from, np_into = make_collision(sphere, heightfield) + assert entry.get_surface_point(np_from) == (1, 510, 10.1) + # Modify the heightfield, no longer colliding + img.set_gray_val(1, 1, 254) + heightfield.set_heightfield(img) + entry = make_collision(sphere, heightfield)[0] + assert entry is None + + +def test_ray_into_heightfield(): + # Setup heightfield + img = PNMImage(127, 127, 1) + img.fill_val(0) + max_height = 10 + num_subdivisions = 1 + heightfield = CollisionHeightfield(img, max_height, num_subdivisions) + # Make ray + ray = CollisionRay((100, 100, 100), (-1, -1, -1)) + entry = make_collision(ray, heightfield)[0] + assert entry is not None + + # Ray with only a z component in its direction + ray.set_direction((0, 0, -5)) + entry, np_from, np_into = make_collision(ray, heightfield) + assert entry.get_surface_point(np_from) == (100, 100, 0) + + # Set coordinate (54, 38) on heightfield to gray value of 255 + # Note that coordinate (54, 38) on the heightfield + # maps to (54, 88, Z) in 3D space + img.set_gray_val(54, 38, 255) + heightfield.set_heightfield(img) + + ray.set_origin((54, 88, 10)) + entry, np_from, np_into = make_collision(ray, heightfield) + assert entry.get_surface_point(np_from) == (54, 88, 10) + + +def test_box_into_heightfield(): + # Try using a large non-square heightfield image + img = PNMImage(5023, 5130, 1) + img.set_gray_val(1, 1, 255) + # Make CollisionHeightfield + max_height = 10 + num_subdivisions = 5 + heightfield = CollisionHeightfield(img, max_height, num_subdivisions) + # Make box + box = CollisionBox((1, 5128, 10), 1, 1, 1) + entry = make_collision(box, heightfield) + assert entry is not None From 160ba090a5e80068f61f34fc3d6f49dbb6ad52c5 Mon Sep 17 00:00:00 2001 From: dakotachasesmith Date: Sun, 11 Apr 2021 12:55:33 -1000 Subject: [PATCH 67/84] clientrepositorybase: Prevent crash on handleUpdateField if updates are handled in Python and repo does not have owner view --- direct/src/distributed/ClientRepositoryBase.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/direct/src/distributed/ClientRepositoryBase.py b/direct/src/distributed/ClientRepositoryBase.py index ece578cad7..ba62bb1ee4 100644 --- a/direct/src/distributed/ClientRepositoryBase.py +++ b/direct/src/distributed/ClientRepositoryBase.py @@ -469,6 +469,9 @@ class ClientRepositoryBase(ConnectionRepository): f"Asked to update non-existent DistObj {doId} and failed to find it") def __doUpdateOwner(self, doId, di): + if not self.hasOwnerView(): + return False + ovObj = self.doId2ownerView.get(doId) if ovObj: odg = Datagram(di.getDatagram()) From 9de9b8c680cecc722bd20e540b79854a334e163f Mon Sep 17 00:00:00 2001 From: rdb Date: Sat, 26 Aug 2023 11:15:57 +0200 Subject: [PATCH 68/84] directnotify: Remove obsolete softspace attribute from RotatingLog --- direct/src/directnotify/RotatingLog.py | 1 - 1 file changed, 1 deletion(-) diff --git a/direct/src/directnotify/RotatingLog.py b/direct/src/directnotify/RotatingLog.py index d7b9b06d34..ad4bd346db 100755 --- a/direct/src/directnotify/RotatingLog.py +++ b/direct/src/directnotify/RotatingLog.py @@ -83,7 +83,6 @@ class RotatingLog: self.closed = self.file.closed self.mode = self.file.mode self.name = self.file.name - self.softspace = self.file.softspace #self.encoding = self.file.encoding # Python 2.3 #self.newlines = self.file.newlines # Python 2.3, maybe From da57279d9a71a861e7e35b8319647a864152026a Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 28 Aug 2023 13:04:05 +0200 Subject: [PATCH 69/84] pstats: Fix GTK strip chart total label and window title not updating ...when navigating around in a session that is not being updated automatically (eg. loaded from file) --- pandatool/src/gtk-stats/gtkStatsStripChart.cxx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pandatool/src/gtk-stats/gtkStatsStripChart.cxx b/pandatool/src/gtk-stats/gtkStatsStripChart.cxx index ee3fc547a1..f956cdfa9a 100644 --- a/pandatool/src/gtk-stats/gtkStatsStripChart.cxx +++ b/pandatool/src/gtk-stats/gtkStatsStripChart.cxx @@ -84,7 +84,8 @@ GtkStatsStripChart(GtkStatsMonitor *monitor, int thread_index, clear_region(); - update(); + // Update window title and total label. + new_data(0, 0); } /** @@ -204,6 +205,9 @@ on_click_label(int collector_index) { // Clicking on any other label means to focus on that. set_collector_index(collector_index); } + + // Update window title and total label. + new_data(0, 0); } /** From 577dc25130dbd100ef749c4fbb920993f7affa71 Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 29 Aug 2023 22:36:23 +0200 Subject: [PATCH 70/84] pstats: Fix erroneous highlight in strip chart before oldest frame --- pandatool/src/pstatserver/pStatStripChart.cxx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pandatool/src/pstatserver/pStatStripChart.cxx b/pandatool/src/pstatserver/pStatStripChart.cxx index 82df337bd9..f04d0b3249 100644 --- a/pandatool/src/pstatserver/pStatStripChart.cxx +++ b/pandatool/src/pstatserver/pStatStripChart.cxx @@ -229,6 +229,10 @@ get_collector_under_pixel(int xpoint, int ypoint) { // Now use that time to determine the frame. const PStatThreadData *thread_data = _view.get_thread_data(); + if (time < thread_data->get_oldest_time()) { + return -1; + } + // And now we can determine which collector within the frame, based on the // value height. if (_average_mode) { From e6f4128c0b069a41cfa080ef45bf8e4f5f7f9c8a Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 29 Aug 2023 22:37:33 +0200 Subject: [PATCH 71/84] makepanda: Add macOS SDK versions 14.0, 13.3 --- makepanda/makepandacore.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/makepanda/makepandacore.py b/makepanda/makepandacore.py index 964914c1fb..bf3c626b6c 100644 --- a/makepanda/makepandacore.py +++ b/makepanda/makepandacore.py @@ -2443,7 +2443,7 @@ def SdkLocateMacOSX(archs = []): # Prefer pre-10.14 for now so that we can keep building FMOD. sdk_versions += ["10.13", "10.12", "10.11", "10.10", "10.9"] - sdk_versions += ["13.1", "13.0", "12.3", "11.3", "11.1", "11.0"] + sdk_versions += ["14.0", "13.3", "13.1", "13.0", "12.3", "11.3", "11.1", "11.0"] if 'arm64' not in archs: sdk_versions += ["10.15", "10.14"] From b22b970d1072706924dcc5315e98699d03dff2c3 Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 29 Aug 2023 22:38:24 +0200 Subject: [PATCH 72/84] makepanda: Require macOS SDK 10.12 or higher This does not remove support for older macOS versions, they can still be targeted by newer SDKs (10.9 can still be targeted by the macOS 12 SDK) I would like to require macOS 11 SDK, but we still need 10.13 for FMOD --- makepanda/makepandacore.py | 2 +- panda/src/cocoadisplay/cocoaGraphicsWindow.mm | 14 +++++--------- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/makepanda/makepandacore.py b/makepanda/makepandacore.py index bf3c626b6c..e7a93b48df 100644 --- a/makepanda/makepandacore.py +++ b/makepanda/makepandacore.py @@ -2441,7 +2441,7 @@ def SdkLocateMacOSX(archs = []): sdk_versions = [] if 'arm64' not in archs: # Prefer pre-10.14 for now so that we can keep building FMOD. - sdk_versions += ["10.13", "10.12", "10.11", "10.10", "10.9"] + sdk_versions += ["10.13", "10.12"] sdk_versions += ["14.0", "13.3", "13.1", "13.0", "12.3", "11.3", "11.1", "11.0"] diff --git a/panda/src/cocoadisplay/cocoaGraphicsWindow.mm b/panda/src/cocoadisplay/cocoaGraphicsWindow.mm index 1b6cca2638..d212c84ebb 100644 --- a/panda/src/cocoadisplay/cocoaGraphicsWindow.mm +++ b/panda/src/cocoadisplay/cocoaGraphicsWindow.mm @@ -963,8 +963,8 @@ find_display_modes(int width, int height) { // handled. CGDisplayCopyAllDisplayModes() does not return upscaled display // mode unless explicitly asked with kCGDisplayShowDuplicateLowResolutionModes // (which is undocumented...). -#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1080 - if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_14) { + bool macos_10_15_or_higher = false; + if (@available(macOS 10.15, *)) { const CFStringRef dictkeys[] = {kCGDisplayShowDuplicateLowResolutionModes}; const CFBooleanRef dictvalues[] = {kCFBooleanTrue}; options = CFDictionaryCreate(NULL, @@ -973,8 +973,8 @@ find_display_modes(int width, int height) { 1, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + macos_10_15_or_higher = true; } -#endif CFMutableArrayRef valid_modes; valid_modes = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); @@ -994,7 +994,7 @@ find_display_modes(int width, int height) { // First check if the current mode is adequate. // This test not done for macOS 10.15 and above as the mode resolution is // not enough to identify a mode. - if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_14 && + if (!macos_10_15_or_higher && CGDisplayModeGetWidth(mode) == width && CGDisplayModeGetHeight(mode) == height) { CFArrayAppendValue(valid_modes, mode); @@ -1004,12 +1004,10 @@ find_display_modes(int width, int height) { current_pixel_encoding = CGDisplayModeCopyPixelEncoding(mode); refresh_rate = CGDisplayModeGetRefreshRate(mode); -#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1080 // Calculate the pixel width and height of the fullscreen mode we want using // the currentdisplay mode dimensions and pixel dimensions. size_t expected_pixel_width = (size_t(width) * CGDisplayModeGetPixelWidth(mode)) / CGDisplayModeGetWidth(mode); size_t expected_pixel_height = (size_t(height) * CGDisplayModeGetPixelHeight(mode)) / CGDisplayModeGetHeight(mode); -#endif CGDisplayModeRelease(mode); for (size_t i = 0; i < num_modes; ++i) { @@ -1023,11 +1021,9 @@ find_display_modes(int width, int height) { if (CGDisplayModeGetWidth(mode) == width && CGDisplayModeGetHeight(mode) == height && (int)(CGDisplayModeGetRefreshRate(mode) + 0.5) == (int)(refresh_rate + 0.5) && -#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1080 - (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_14 || + (!macos_10_15_or_higher || (CGDisplayModeGetPixelWidth(mode) == expected_pixel_width && CGDisplayModeGetPixelHeight(mode) == expected_pixel_height)) && -#endif CFStringCompare(pixel_encoding, current_pixel_encoding, 0) == kCFCompareEqualTo) { if (CGDisplayModeGetRefreshRate(mode) == refresh_rate) { From aa13953f2bdabf47346b773c334c36f1c188a23c Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 30 Aug 2023 15:05:35 +0200 Subject: [PATCH 73/84] makepanda: Fix error in plistlib.load invocation --- makepanda/makepanda.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/makepanda/makepanda.py b/makepanda/makepanda.py index 1efb46cf21..e70a0ef790 100755 --- a/makepanda/makepanda.py +++ b/makepanda/makepanda.py @@ -2155,7 +2155,7 @@ def CompileBundle(target, inputs, opts): # Now link the object files to form the bundle. if plist is None: exit("One plist file must be used when creating a bundle!") - bundleName = plistlib.load(plist)["CFBundleExecutable"] + bundleName = plistlib.load(open(plist, 'rb'))["CFBundleExecutable"] oscmd("rm -rf %s" % target) oscmd("mkdir -p %s/Contents/MacOS/" % target) From 71154492b9f56bca8ffd069dedc53b07e3144dcc Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 28 Aug 2023 20:17:02 +0200 Subject: [PATCH 74/84] pstats: Add macOS port Closes #1531 --- makepanda/makepanda.py | 10 +- pandatool/src/mac-stats/Info.plist | 47 + pandatool/src/mac-stats/cocoa_compat.h | 45 + pandatool/src/mac-stats/macStats.h | 19 + pandatool/src/mac-stats/macStats.mm | 73 ++ pandatool/src/mac-stats/macStatsAppDelegate.h | 37 + .../src/mac-stats/macStatsAppDelegate.mm | 201 ++++ pandatool/src/mac-stats/macStatsChartMenu.h | 60 ++ pandatool/src/mac-stats/macStatsChartMenu.mm | 246 +++++ .../src/mac-stats/macStatsChartMenuDelegate.h | 32 + .../mac-stats/macStatsChartMenuDelegate.mm | 61 ++ pandatool/src/mac-stats/macStatsFlameGraph.h | 88 ++ pandatool/src/mac-stats/macStatsFlameGraph.mm | 871 ++++++++++++++++ pandatool/src/mac-stats/macStatsGraph.h | 139 +++ pandatool/src/mac-stats/macStatsGraph.mm | 491 +++++++++ pandatool/src/mac-stats/macStatsGraphView.h | 31 + pandatool/src/mac-stats/macStatsGraphView.mm | 158 +++ .../mac-stats/macStatsGraphViewController.h | 42 + .../mac-stats/macStatsGraphViewController.mm | 224 ++++ pandatool/src/mac-stats/macStatsLabel.h | 58 ++ pandatool/src/mac-stats/macStatsLabel.mm | 137 +++ pandatool/src/mac-stats/macStatsLabelStack.h | 57 ++ pandatool/src/mac-stats/macStatsLabelStack.mm | 174 ++++ pandatool/src/mac-stats/macStatsMonitor.h | 117 +++ pandatool/src/mac-stats/macStatsMonitor.mm | 650 ++++++++++++ pandatool/src/mac-stats/macStatsPianoRoll.h | 84 ++ pandatool/src/mac-stats/macStatsPianoRoll.mm | 764 ++++++++++++++ pandatool/src/mac-stats/macStatsScaleArea.h | 41 + pandatool/src/mac-stats/macStatsScaleArea.mm | 50 + pandatool/src/mac-stats/macStatsServer.h | 82 ++ pandatool/src/mac-stats/macStatsServer.mm | 732 +++++++++++++ pandatool/src/mac-stats/macStatsStripChart.h | 90 ++ pandatool/src/mac-stats/macStatsStripChart.mm | 964 ++++++++++++++++++ pandatool/src/mac-stats/macStatsTimeline.h | 100 ++ pandatool/src/mac-stats/macStatsTimeline.mm | 932 +++++++++++++++++ .../src/mac-stats/macstats_composite1.mm | 16 + pandatool/src/pstatserver/pStatStripChart.cxx | 5 + 37 files changed, 7926 insertions(+), 2 deletions(-) create mode 100644 pandatool/src/mac-stats/Info.plist create mode 100644 pandatool/src/mac-stats/cocoa_compat.h create mode 100644 pandatool/src/mac-stats/macStats.h create mode 100644 pandatool/src/mac-stats/macStats.mm create mode 100644 pandatool/src/mac-stats/macStatsAppDelegate.h create mode 100644 pandatool/src/mac-stats/macStatsAppDelegate.mm create mode 100644 pandatool/src/mac-stats/macStatsChartMenu.h create mode 100644 pandatool/src/mac-stats/macStatsChartMenu.mm create mode 100644 pandatool/src/mac-stats/macStatsChartMenuDelegate.h create mode 100644 pandatool/src/mac-stats/macStatsChartMenuDelegate.mm create mode 100644 pandatool/src/mac-stats/macStatsFlameGraph.h create mode 100644 pandatool/src/mac-stats/macStatsFlameGraph.mm create mode 100644 pandatool/src/mac-stats/macStatsGraph.h create mode 100644 pandatool/src/mac-stats/macStatsGraph.mm create mode 100644 pandatool/src/mac-stats/macStatsGraphView.h create mode 100644 pandatool/src/mac-stats/macStatsGraphView.mm create mode 100644 pandatool/src/mac-stats/macStatsGraphViewController.h create mode 100644 pandatool/src/mac-stats/macStatsGraphViewController.mm create mode 100644 pandatool/src/mac-stats/macStatsLabel.h create mode 100644 pandatool/src/mac-stats/macStatsLabel.mm create mode 100644 pandatool/src/mac-stats/macStatsLabelStack.h create mode 100644 pandatool/src/mac-stats/macStatsLabelStack.mm create mode 100644 pandatool/src/mac-stats/macStatsMonitor.h create mode 100644 pandatool/src/mac-stats/macStatsMonitor.mm create mode 100644 pandatool/src/mac-stats/macStatsPianoRoll.h create mode 100644 pandatool/src/mac-stats/macStatsPianoRoll.mm create mode 100644 pandatool/src/mac-stats/macStatsScaleArea.h create mode 100644 pandatool/src/mac-stats/macStatsScaleArea.mm create mode 100644 pandatool/src/mac-stats/macStatsServer.h create mode 100644 pandatool/src/mac-stats/macStatsServer.mm create mode 100644 pandatool/src/mac-stats/macStatsStripChart.h create mode 100644 pandatool/src/mac-stats/macStatsStripChart.mm create mode 100644 pandatool/src/mac-stats/macStatsTimeline.h create mode 100644 pandatool/src/mac-stats/macStatsTimeline.mm create mode 100644 pandatool/src/mac-stats/macstats_composite1.mm diff --git a/makepanda/makepanda.py b/makepanda/makepanda.py index e70a0ef790..b90c53ec24 100755 --- a/makepanda/makepanda.py +++ b/makepanda/makepanda.py @@ -1077,6 +1077,9 @@ if (COMPILER=="GCC"): LibName("COCOA", "-framework Cocoa") # Fix for a bug in OSX Leopard: LibName("GL", "-dylib_file /System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib:/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib") + # When using pre-11.0 SDKs, for PStats + if os.path.basename(SDK["MACOSX"]).startswith("MacOSX10."): + LibName("COCOA", "-Wl,-U,_OBJC_CLASS_$_NSTrackingSeparatorToolbarItem") # Temporary exceptions to removal of this flag if not PkgSkip("FFMPEG"): @@ -5911,10 +5914,13 @@ if not PkgSkip("PANDATOOL"): # DIRECTORY: pandatool/src/gtk-stats/ # -if not PkgSkip("PANDATOOL") and (GetTarget() == 'windows' or not PkgSkip("GTK3")): +if not PkgSkip("PANDATOOL") and (GetTarget() in ('windows', 'darwin') or not PkgSkip("GTK3")): if GetTarget() == 'windows': OPTS=['DIR:pandatool/src/win-stats'] TargetAdd('pstats_composite1.obj', opts=OPTS, input='winstats_composite1.cxx') + elif GetTarget() == 'darwin': + OPTS=['DIR:pandatool/src/mac-stats'] + TargetAdd('pstats_composite1.obj', opts=OPTS, input='macstats_composite1.mm') else: OPTS=['DIR:pandatool/src/gtk-stats', 'GTK3'] TargetAdd('pstats_composite1.obj', opts=OPTS, input='gtkstats_composite1.cxx') @@ -5923,7 +5929,7 @@ if not PkgSkip("PANDATOOL") and (GetTarget() == 'windows' or not PkgSkip("GTK3") TargetAdd('pstats.exe', input='libp3progbase.lib') TargetAdd('pstats.exe', input='libp3pandatoolbase.lib') TargetAdd('pstats.exe', input=COMMON_PANDA_LIBS) - TargetAdd('pstats.exe', opts=['SUBSYSTEM:WINDOWS', 'WINCOMCTL', 'WINCOMDLG', 'WINSOCK', 'WINIMM', 'WINGDI', 'WINKERNEL', 'WINOLDNAMES', 'WINUSER', 'WINMM', 'UXTHEME', 'GTK3']) + TargetAdd('pstats.exe', opts=['SUBSYSTEM:WINDOWS', 'WINCOMCTL', 'WINCOMDLG', 'WINSOCK', 'WINIMM', 'WINGDI', 'WINKERNEL', 'WINOLDNAMES', 'WINUSER', 'WINMM', 'UXTHEME', 'GTK3', 'COCOA', 'CARBON', 'QUARTZ']) # # DIRECTORY: pandatool/src/xfileprogs/ diff --git a/pandatool/src/mac-stats/Info.plist b/pandatool/src/mac-stats/Info.plist new file mode 100644 index 0000000000..2550b7e518 --- /dev/null +++ b/pandatool/src/mac-stats/Info.plist @@ -0,0 +1,47 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleIdentifier + org.panda3d.pstats + CFBundleExecutable + pstats + CFBundleName + PStats + CFBundleDisplayName + PStats + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + APPL + LSHasLocalizedDisplayName + + NSAppleScriptEnabled + + NSPrincipalClass + NSApplication + CFBundleDocumentTypes + + + CFBundleTypeName + PStats session file + CFBundleTypeRole + Editor + LSHandlerRank + Owner + LSTypeIsPackage + + CFBundleTypeExtensions + + pstats + + CFBundleTypeMIMETypes + + application/vnd.panda3d.pstats + + + + + diff --git a/pandatool/src/mac-stats/cocoa_compat.h b/pandatool/src/mac-stats/cocoa_compat.h new file mode 100644 index 0000000000..b535b08d3c --- /dev/null +++ b/pandatool/src/mac-stats/cocoa_compat.h @@ -0,0 +1,45 @@ +/** + * 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 cocoa_compat.h + * @author rdb + * @date 2023-08-28 + */ + +#ifndef COCOA_COMPAT_H +#define COCOA_COMPAT_H + +#import + +// Allow building with older SDKs. +#if __MAC_OS_X_VERSION_MAX_ALLOWED < 110000 +typedef NS_ENUM(NSInteger, NSWindowToolbarStyle) { + NSWindowToolbarStyleAutomatic, + NSWindowToolbarStyleExpanded, + NSWindowToolbarStylePreference, + NSWindowToolbarStyleUnified, + NSWindowToolbarStyleUnifiedCompact +} API_AVAILABLE(macos(11.0)); + +API_AVAILABLE(macos(11.0)) API_UNAVAILABLE(ios) +@interface NSTrackingSeparatorToolbarItem : NSToolbarItem ++ (instancetype)trackingSeparatorToolbarItemWithIdentifier:(NSString *)identifier splitView:(NSSplitView *)splitView dividerIndex:(NSInteger)dividerIndex API_UNAVAILABLE(ios); +@property (strong) NSSplitView *splitView API_UNAVAILABLE(ios); +@property NSInteger dividerIndex API_UNAVAILABLE(ios); +@end + +#endif // __MAC_OS_X_VERSION_MAX_ALLOWED + +#if __MAC_OS_X_VERSION_MAX_ALLOWED < 101400 +@protocol NSViewToolTipOwner +- (NSString *)view:(NSView *)view stringForToolTip:(NSToolTipTag)tag point:(NSPoint)point userData:(nullable void *)data; +@end + +#endif // __MAC_OS_X_VERSION_MAX_ALLOWED + +#endif // COCOA_COMPAT_H diff --git a/pandatool/src/mac-stats/macStats.h b/pandatool/src/mac-stats/macStats.h new file mode 100644 index 0000000000..a5e2371b6a --- /dev/null +++ b/pandatool/src/mac-stats/macStats.h @@ -0,0 +1,19 @@ +/** + * 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 macStats.h + * @author rdb + * @date 2023-08-17 + */ + +#ifndef MACSTATS_H +#define MACSTATS_H + +#include "pStatServer.h" + +#endif diff --git a/pandatool/src/mac-stats/macStats.mm b/pandatool/src/mac-stats/macStats.mm new file mode 100644 index 0000000000..cbaee08265 --- /dev/null +++ b/pandatool/src/mac-stats/macStats.mm @@ -0,0 +1,73 @@ +/** + * 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 macStats.mm + * @author rdb + * @date 2023-08-17 + */ + +#include "pandatoolbase.h" +#include "macStats.h" +#include "macStatsServer.h" +#include "config_pstatclient.h" + +#include +#include + +extern "C" { + OSStatus CPSSetProcessName(ProcessSerialNumber *psn, char *name); +}; + +@implementation NSBundle(swizzle) +- (NSString *)__bundleIdentifier { + if (self == [NSBundle mainBundle]) { + return @"org.panda3d.pstats"; + } else { + return [self __bundleIdentifier]; + } +} +@end + +void +keyboard_interrupt(int sig) { + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) { + [NSApp terminate:NSApp]; + }); +} + +int +main(int argc, char *argv[]) { + // This hack is necessary to allow showing notifications when run as a console app. + Class cls = objc_getClass("NSBundle"); + if (cls) { + method_exchangeImplementations(class_getInstanceMethod(cls, @selector(bundleIdentifier)), + class_getInstanceMethod(cls, @selector(__bundleIdentifier))); + } + + // Set the bundle name of the application. + ProcessSerialNumber psn; + GetCurrentProcess(&psn); + CPSSetProcessName(&psn, (char *)"PStats"); + + @autoreleasepool { + // Create the server application. + MacStatsServer *server = new MacStatsServer; + + // Register a SIGINT handler to terminate the application correctly. + // Otherwise, notifications may linger in the notification center. + struct sigaction act = {}; + act.sa_handler = &keyboard_interrupt; + act.sa_flags = SA_RESETHAND; + sigaction(SIGINT, &act, nullptr); + + // Get lost in the Cocoa main loop. + server->run(argc, argv); + } + + return 0; +} diff --git a/pandatool/src/mac-stats/macStatsAppDelegate.h b/pandatool/src/mac-stats/macStatsAppDelegate.h new file mode 100644 index 0000000000..e79211784f --- /dev/null +++ b/pandatool/src/mac-stats/macStatsAppDelegate.h @@ -0,0 +1,37 @@ +/** + * 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 macStatsAppDelegate.h + * @author rdb + * @date 2023-08-17 + */ + +#ifndef MACSTATSAPPDELEGATE_H +#define MACSTATSAPPDELEGATE_H + +#import +#import + +class MacStatsServer; + +@interface MacStatsAppDelegate : NSObject { + @private + MacStatsServer *_server; + NSTimer *_timer; +} + +- (id)initWithServer:(MacStatsServer *)server; +- (void)applicationDidFinishLaunching:(NSApplication *)sender; +- (BOOL)applicationShouldTerminate:(NSApplication *)sender; +- (void)applicationWillTerminate:(NSApplication *)sender; +- (BOOL)userNotificationCenter:(NSUserNotificationCenter *)center + shouldPresentNotification:(NSUserNotification *)notification; + +@end + +#endif diff --git a/pandatool/src/mac-stats/macStatsAppDelegate.mm b/pandatool/src/mac-stats/macStatsAppDelegate.mm new file mode 100644 index 0000000000..7831549c17 --- /dev/null +++ b/pandatool/src/mac-stats/macStatsAppDelegate.mm @@ -0,0 +1,201 @@ +/** + * 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 macStatsAppDelegate.mm + * @author rdb + * @date 2023-08-17 + */ + +#include "macStatsAppDelegate.h" +#include "macStatsServer.h" +#include "pStatGraph.h" + +@implementation MacStatsAppDelegate + +- (id)initWithServer:(MacStatsServer *)server { + if (self = [super init]) { + _server = server; + _timer = nil; + } + + return self; +} + +- (BOOL)applicationSupportsSecureRestorableState:(NSApplication *)app { + // Squelches an annoying warning. + return YES; +} + +- (BOOL)application:(NSApplication *)sender + openFile:(NSString *)filename { + Filename fn([filename UTF8String]); + fn.set_binary(); + return _server->open_session(fn); +} + +- (void)applicationDidFinishLaunching:(NSApplication *)sender { + // Set this object as delegate for user notifications. + { + NSUserNotificationCenter *center = [NSUserNotificationCenter defaultUserNotificationCenter]; + center.delegate = self; + } + + // Register default preferences. + NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; + NSDictionary *dict = [NSDictionary + dictionaryWithObjects:@[@"", [NSNumber numberWithBool:YES], [NSNumber numberWithInt:PStatGraph::GBU_ms]] + forKeys:@[@"Appearance", @"ShowStatusItem", @"TimeUnits"]]; + [defaults registerDefaults:dict]; + + if (_server != nil) { + // Apply preferences. + [self applyDefaults:nil]; + + // Create a timer to poll the server. + _timer = [NSTimer scheduledTimerWithTimeInterval:0.2 + target:self + selector:@selector(pollServer) + userInfo:nil + repeats:YES]; + + // Start new session if we don't have one yet. + if (_server->get_monitor() == nullptr) { + _server->new_session(); + } + } + + // Watch for defaults change. + { + NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; + [center addObserver:self + selector:@selector(applyDefaults:) + name:NSUserDefaultsDidChangeNotification + object:nil]; + } +} + +- (void)applyDefaults:(NSNotification *)notification { + if (_server != nil) { + NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; + _server->set_show_status_item([defaults boolForKey:@"ShowStatusItem"]); + _server->set_appearance([defaults stringForKey:@"Appearance"]); + _server->set_time_units([defaults integerForKey:@"TimeUnits"]); + } +} + +- (void)pollServer { + _server->poll(); +} + +- (BOOL)applicationShouldTerminate:(NSApplication *)sender { + if (_server != nil) { + return _server->close_session(); + } + return YES; +} + +- (void)applicationWillTerminate:(NSApplication *)sender { + if (_timer != nil) { + [_timer invalidate]; + _timer = nil; + } + + if (_server != nil) { + delete _server; + _server = nil; + } +} + +- (BOOL)userNotificationCenter:(NSUserNotificationCenter *)center + shouldPresentNotification:(NSUserNotification *)notification { + return YES; +} + +- (void)userNotificationCenter:(NSUserNotificationCenter *)center + didActivateNotification:(NSUserNotification *)notification { + NSUserNotificationAction *action = notification.additionalActivationAction; + if (action != nil) { + NSString *ident = action.identifier; + if ([ident isEqual:@"quit"]) { + [NSApp terminate:self]; + } + else if ([ident isEqual:@"new"]) { + _server->new_session(); + } + else if ([ident isEqual:@"open"]) { + _server->open_session(); + } + else if ([ident isEqual:@"openLast"]) { + _server->open_last_session(); + } + } +} + +- (void)handleNewSession:(NSMenuItem *)item { + _server->new_session(); +} + +- (void)handleOpenSession:(NSMenuItem *)item { + _server->open_session(); +} + +- (void)handleOpenLastSession:(NSMenuItem *)item { + _server->open_last_session(); +} + +- (void)handleSaveSession:(NSMenuItem *)item { + _server->save_session(); +} + +- (void)handleCloseSession:(NSMenuItem *)item { + _server->close_session(); +} + +- (void)handleExportSession:(NSMenuItem *)item { + _server->export_session(); +} + +- (void)handleToggleSettingsBool:(NSMenuItem *)item { + [[NSUserDefaults standardUserDefaults] setBool:(item.state != NSOnState) forKey:item.representedObject]; +} + +- (void)handleSettingsInteger:(NSMenuItem *)item { + [[NSUserDefaults standardUserDefaults] setInteger:item.tag forKey:item.representedObject]; +} + +- (void)handleSettingsAppearance:(NSMenuItem *)item { + [[NSUserDefaults standardUserDefaults] setObject:item.representedObject forKey:@"Appearance"]; +} + +- (void)handleSpeed:(NSMenuItem *)item { + MacStatsMonitor *monitor = _server->get_monitor(); + if (monitor != nullptr) { + monitor->set_scroll_speed(item.tag); + } +} + +- (void)handlePause:(NSMenuItem *)item { + MacStatsMonitor *monitor = _server->get_monitor(); + if (monitor != nullptr) { + monitor->set_pause(!item.state); + } +} + +- (void)handleClickStatusItem:(id)sender { + [NSApp activateIgnoringOtherApps:YES]; +} + +- (void)handleChooseCollectorColor:(NSColorPanel *)panel { + MacStatsMonitor *monitor = _server->get_monitor(); + if (monitor != nullptr) { + NSColor *color = panel.color; + monitor->handle_choose_collector_color(LRGBColor(color.redComponent, color.greenComponent, color.blueComponent)); + } +} + +@end diff --git a/pandatool/src/mac-stats/macStatsChartMenu.h b/pandatool/src/mac-stats/macStatsChartMenu.h new file mode 100644 index 0000000000..a8b3bceaa8 --- /dev/null +++ b/pandatool/src/mac-stats/macStatsChartMenu.h @@ -0,0 +1,60 @@ +/** + * 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 macStatsChartMenu.h + * @author rdb + * @date 2023-08-18 + */ + +#ifndef MACSTATSCHARTMENU_H +#define MACSTATSCHARTMENU_H + +#include "pandatoolbase.h" +#include "macStatsMonitor.h" + +#include + +class PStatView; +class PStatViewLevel; + +/** + * A pulldown menu of charts available for a particular thread. + */ +class MacStatsChartMenu { +public: + MacStatsChartMenu(MacStatsMonitor *monitor, int thread_index); + ~MacStatsChartMenu(); + + int get_thread_index() const { return _thread_index; } + + void add_to_menu(NSMenu *menu, int position); + void remove_from_menu(NSMenu *menu); + + void check_update(); + void do_update(); + +private: + bool add_view(NSMenu *parent_menu, const PStatViewLevel *view_level, + bool show_level, int insert_at); + NSMenuItem *make_menu_item(NSMenu *parent_menu, int insert_at, + const char *label, SEL action, + int collector_index = -1); + + MacStatsMonitor *_monitor; + int _thread_index; + + int _last_level_index; + NSMenu *_menu; + + // Pair of menu item, submenu + std::vector > _collector_items; + int _time_items_end = 0; + int _level_items_end = 0; +}; + +#endif diff --git a/pandatool/src/mac-stats/macStatsChartMenu.mm b/pandatool/src/mac-stats/macStatsChartMenu.mm new file mode 100644 index 0000000000..8df12743f1 --- /dev/null +++ b/pandatool/src/mac-stats/macStatsChartMenu.mm @@ -0,0 +1,246 @@ +/** + * 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 macStatsChartMenu.mm + * @author rdb + * @date 2023-08-18 + */ + +#include "macStatsChartMenu.h" +#include "macStatsChartMenuDelegate.h" +#include "macStatsMonitor.h" + +/** + * + */ +MacStatsChartMenu:: +MacStatsChartMenu(MacStatsMonitor *monitor, int thread_index) : + _monitor(monitor), + _thread_index(thread_index) +{ + _menu = [[NSMenu alloc] init]; + _menu.delegate = [[MacStatsChartMenuDelegate alloc] initWithMonitor:monitor threadIndex:thread_index]; + + if (thread_index == 0) { + _menu.title = @"Graphs"; + + // Timeline goes first. + make_menu_item(_menu, -1, "Timeline", @selector(handleOpenTimeline:)); + + // Then the piano roll (even though it's not very useful nowadays) + make_menu_item(_menu, -1, "Piano Roll", @selector(handleOpenPianoRoll:)); + } + else { + make_menu_item(_menu, -1, "Open Strip Chart", @selector(handleOpenStripChart:), 0); + make_menu_item(_menu, -1, "Open Flame Graph", @selector(handleOpenFlameGraph:)); + } + + [_menu addItem:[NSMenuItem separatorItem]]; + _time_items_end = 3; + + // Put a separator between time items and level items. + [_menu addItem:[NSMenuItem separatorItem]]; + _level_items_end = _time_items_end + 1; + + // For the main thread menu, also some options relating to all graph windows. + if (thread_index == 0) { + [_menu addItem:[NSMenuItem separatorItem]]; + make_menu_item(_menu, -1, "Close All Graphs", @selector(handleCloseAllGraphs:)); + make_menu_item(_menu, -1, "Reopen Default Graphs", @selector(handleReopenDefaultGraphs:)); + make_menu_item(_menu, -1, "Save Current Layout as Default", @selector(handleSaveDefaultGraphs:)); + } + + do_update(); +} + +/** + * + */ +MacStatsChartMenu:: +~MacStatsChartMenu() { + MacStatsChartMenuDelegate *delegate = (MacStatsChartMenuDelegate *)_menu.delegate; + [_menu release]; + [delegate release]; +} + +/** + * Adds the menu to the end of the indicated menu bar. + */ +void MacStatsChartMenu:: +add_to_menu(NSMenu *menu, int position) { + NSMenuItem *item = [[NSMenuItem alloc] init]; + [menu insertItem:item atIndex:position]; + [menu setSubmenu:_menu forItem:item]; + [item release]; +} + +/** + * Removes the menu from the menu bar. + */ +void MacStatsChartMenu:: +remove_from_menu(NSMenu *menu) { + int index = [menu indexOfItemWithSubmenu:_menu]; + if (index >= 0) { + [menu removeItemAtIndex:index]; + } +} + +/** + * Checks to see if the menu needs to be updated (e.g. because of new data + * from the client), and updates it if necessary. + */ +void MacStatsChartMenu:: +check_update() { + PStatView &view = _monitor->get_view(_thread_index); + if (view.get_level_index() != _last_level_index) { + do_update(); + } +} + +/** + * Unconditionally updates the menu with the latest data from the client. + */ +void MacStatsChartMenu:: +do_update() { + PStatView &view = _monitor->get_view(_thread_index); + _last_level_index = view.get_level_index(); + + const PStatClientData *client_data = _monitor->get_client_data(); + if (_thread_index != 0) { + std::string thread_name = client_data->get_thread_name(_thread_index); + _menu.title = [NSString stringWithUTF8String:thread_name.c_str()]; + } + + if (client_data->get_num_collectors() > _collector_items.size()) { + _collector_items.resize(client_data->get_num_collectors(), std::make_pair(nullptr, nullptr)); + } + + // The menu item(s) for the thread's frame time goes second. + const PStatViewLevel *view_level = view.get_top_level(); + if (_thread_index == 0) { + if (add_view(_menu, view_level, false, _time_items_end)) { + ++_time_items_end; + ++_level_items_end; + } + } else { + for (int c = 0; c < view_level->get_num_children(); ++c) { + if (add_view(_menu, view_level->get_child(c), false, _time_items_end)) { + ++_time_items_end; + ++_level_items_end; + } + } + } + + // And then the menu item(s) for each of the level values. + int num_toplevel_collectors = client_data->get_num_toplevel_collectors(); + for (int tc = 0; tc < num_toplevel_collectors; tc++) { + int collector = client_data->get_toplevel_collector(tc); + if (client_data->has_collector(collector) && + client_data->get_collector_has_level(collector, _thread_index)) { + + PStatView &level_view = _monitor->get_level_view(collector, _thread_index); + add_view(_menu, level_view.get_top_level(), true, _level_items_end); + } + } +} + +/** + * Adds a new entry or entries to the menu for the indicated view and its + * children. Returns true if an item was added, false if not. + */ +bool MacStatsChartMenu:: +add_view(NSMenu *parent_menu, const PStatViewLevel *view_level, + bool show_level, int insert_at) { + int collector = view_level->get_collector(); + + NSMenuItem *&menu_item = _collector_items[collector].first; + NSMenu *&menu = _collector_items[collector].second; + + const PStatClientData *client_data = _monitor->get_client_data(); + + int num_children = view_level->get_num_children(); + if (menu == nullptr && num_children == 0) { + // For a collector without children, no point in making a submenu. We just + // have the item open a strip chart directly (no point in creating a flame + // graph if there are no children). + if (menu_item != nullptr) { + // Already exists. + return false; + } + + std::string collector_name = client_data->get_collector_name(collector); + if (show_level) { + menu_item = make_menu_item(parent_menu, insert_at, + collector_name.c_str(), @selector(handleOpenStripChartLevel:), collector); + } else { + menu_item = make_menu_item(parent_menu, insert_at, + collector_name.c_str(), @selector(handleOpenStripChart:), collector); + } + return true; + } + else if (menu_item != nullptr && menu == nullptr) { + // Unhook the signal handler, we are creating a submenu. + menu_item.action = nil; + } + + // Create a submenu. + bool added_item = false; + if (menu_item == nullptr) { + std::string collector_name = client_data->get_collector_name(collector); + menu_item = make_menu_item(parent_menu, insert_at, collector_name.c_str(), nil); + added_item = true; + } + + if (menu == nullptr) { + menu = [[NSMenu alloc] init]; + [parent_menu setSubmenu:menu forItem:menu_item]; + + if (show_level) { + make_menu_item(menu, -1, "Open Strip Chart", + @selector(handleOpenStripChartLevel:), collector); + } else { + make_menu_item(menu, -1, "Open Strip Chart", + @selector(handleOpenStripChart:), collector); + + if (collector == 0) { + collector = -1; + } + + make_menu_item(menu, -1, "Open Flame Graph", + @selector(handleOpenFlameGraph:), collector); + } + + [menu addItem:[NSMenuItem separatorItem]]; + [menu release]; + } + + for (int c = 0; c < num_children; ++c) { + add_view(menu, view_level->get_child(c), show_level, 2 + !show_level); + } + + return added_item; +} + +/** + * + */ +NSMenuItem *MacStatsChartMenu:: +make_menu_item(NSMenu *parent_menu, int insert_at, const char *label, SEL action, int collector_index) { + NSMenuItem *menu_item = [[NSMenuItem alloc] init]; + menu_item.title = [NSString stringWithUTF8String:label]; + menu_item.target = _menu.delegate; + menu_item.action = action; + menu_item.tag = collector_index; + if (insert_at >= 0) { + [parent_menu insertItem:menu_item atIndex:insert_at]; + } else { + [parent_menu addItem:menu_item]; + } + [menu_item release]; + return menu_item; +} diff --git a/pandatool/src/mac-stats/macStatsChartMenuDelegate.h b/pandatool/src/mac-stats/macStatsChartMenuDelegate.h new file mode 100644 index 0000000000..05f86302c6 --- /dev/null +++ b/pandatool/src/mac-stats/macStatsChartMenuDelegate.h @@ -0,0 +1,32 @@ +/** + * 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 macStatsChartMenuDelegate.h + * @author rdb + * @date 2023-08-18 + */ + +#ifndef MACSTATSCHARTMENUDELEGATE_H +#define MACSTATSCHARTMENUDELEGATE_H + +#import +#import + +class MacStatsMonitor; + +@interface MacStatsChartMenuDelegate : NSObject { + @private + MacStatsMonitor *_monitor; + int _thread_index; +} + +- (id)initWithMonitor:(MacStatsMonitor *)monitor threadIndex:(int)index; + +@end + +#endif diff --git a/pandatool/src/mac-stats/macStatsChartMenuDelegate.mm b/pandatool/src/mac-stats/macStatsChartMenuDelegate.mm new file mode 100644 index 0000000000..67c12fcac0 --- /dev/null +++ b/pandatool/src/mac-stats/macStatsChartMenuDelegate.mm @@ -0,0 +1,61 @@ +/** + * 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 macStatsChartMenuDelegate.mm + * @author rdb + * @date 2023-08-18 + */ + +#include "macStatsChartMenuDelegate.h" +#include "macStatsMonitor.h" + +@implementation MacStatsChartMenuDelegate + +- (id)initWithMonitor:(MacStatsMonitor *)monitor threadIndex:(int)index { + if (self = [super init]) { + _monitor = monitor; + _thread_index = index; + } + + return self; +} + +- (void)handleOpenTimeline:(NSMenuItem *)item { + _monitor->open_timeline(); +} + +- (void)handleOpenStripChart:(NSMenuItem *)item { + _monitor->open_strip_chart(_thread_index, item.tag, NO); +} + +- (void)handleOpenStripChartLevel:(NSMenuItem *)item { + _monitor->open_strip_chart(_thread_index, item.tag, YES); +} + +- (void)handleOpenFlameGraph:(NSMenuItem *)item { + _monitor->open_flame_graph(_thread_index, item.tag); +} + +- (void)handleOpenPianoRoll:(NSMenuItem *)item { + _monitor->open_piano_roll(_thread_index); +} + +- (void)handleCloseAllGraphs:(NSMenuItem *)item { + _monitor->close_all_graphs(); +} + +- (void)handleReopenDefaultGraphs:(NSMenuItem *)item { + _monitor->close_all_graphs(); + _monitor->open_default_graphs(); +} + +- (void)handleSaveDefaultGraphs:(NSMenuItem *)item { + _monitor->save_default_graphs(); +} + +@end diff --git a/pandatool/src/mac-stats/macStatsFlameGraph.h b/pandatool/src/mac-stats/macStatsFlameGraph.h new file mode 100644 index 0000000000..25df1f96c8 --- /dev/null +++ b/pandatool/src/mac-stats/macStatsFlameGraph.h @@ -0,0 +1,88 @@ +/** + * 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 macStatsFlameGraph.h + * @author rdb + * @date 2023-08-18 + */ + +#ifndef MACSTATSFLAMEGRAPH_H +#define MACSTATSFLAMEGRAPH_H + +#include "macStatsGraph.h" +#include "pStatFlameGraph.h" +#include "macStatsChartMenuDelegate.h" + +/** + * A window that draws a flame chart, which shows the collectors explicitly + * stopping and starting, one frame at a time. + */ +class MacStatsFlameGraph final : public PStatFlameGraph, public MacStatsGraph { +public: + MacStatsFlameGraph(MacStatsMonitor *monitor, int thread_index, + int collector_index=-1); + virtual ~MacStatsFlameGraph(); + + virtual void new_collector(int collector_index); + virtual void new_data(int thread_index, int frame_number); + virtual void force_redraw(); + virtual void changed_graph_size(int graph_xsize, int graph_ysize); + + virtual void set_time_units(int unit_mask); + virtual void on_click_label(int collector_index); + virtual void on_enter_label(int collector_index); + virtual void on_leave_label(int collector_index); + virtual NSMenu *get_label_menu(int collector_index) const; + +protected: + virtual void normal_guide_bars(); + + void clear_region(); + virtual void begin_draw(); + virtual void draw_bar(int depth, int from_x, int to_x, + int collector_index, int parent_index); + virtual void end_draw(); + virtual void idle(); + + virtual bool animate(double time, double dt); + + virtual bool get_window_state(int &x, int &y, int &width, int &height, + bool &maximized, bool &minimized) const; + virtual void set_window_state(int x, int y, int width, int height, + bool maximized, bool minimized); + + virtual NSMenu *get_graph_menu(int mouse_x, int mouse_y) const; + virtual std::string get_graph_tooltip(int mouse_x, int mouse_y) const; + virtual DragMode consider_drag_start(int graph_x, int graph_y); + + virtual void handle_button_press(int graph_x, int graph_y, + bool double_click, int button); + virtual void handle_button_release(int graph_x, int graph_y); + virtual void handle_motion(int graph_x, int graph_y); + virtual void handle_leave(); + virtual void handle_draw_graph(CGContextRef ctx, NSRect rect); + virtual void handle_back(); + +public: + void handle_toggle_average(bool state); + +private: + int pixel_to_depth(int y) const; + void draw_guide_bar(CGContextRef ctx, const PStatGraph::GuideBar &bar); + void draw_guide_labels(CGContextRef ctx); + void draw_guide_label(CGContextRef ctx, const PStatGraph::GuideBar &bar); + +private: + NSToolbarItem *_total_item; + + MacStatsChartMenuDelegate *_menu_delegate; + + std::vector _back_stack; +}; + +#endif diff --git a/pandatool/src/mac-stats/macStatsFlameGraph.mm b/pandatool/src/mac-stats/macStatsFlameGraph.mm new file mode 100644 index 0000000000..60314147f8 --- /dev/null +++ b/pandatool/src/mac-stats/macStatsFlameGraph.mm @@ -0,0 +1,871 @@ +/** + * 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 macStatsFlameGraph.mm + * @author rdb + * @date 2023-08-18 + */ + +#include "macStatsFlameGraph.h" +#include "macStatsMonitor.h" +#include "macStatsGraphView.h" +#include "macStatsScaleArea.h" +#include "pStatCollectorDef.h" +#include "cocoa_compat.h" + +@interface MacStatsFlameGraphViewController : MacStatsGraphViewController +@end + +static const int default_flame_graph_width = 800; +static const int default_flame_graph_height = 250; + +/** + * + */ +MacStatsFlameGraph:: +MacStatsFlameGraph(MacStatsMonitor *monitor, int thread_index, + int collector_index) : + PStatFlameGraph(monitor, thread_index, collector_index, 0, 0), + MacStatsGraph(monitor, [MacStatsFlameGraphViewController alloc]) +{ + // Used for popup menus. + _menu_delegate = [[MacStatsChartMenuDelegate alloc] initWithMonitor:monitor threadIndex:thread_index]; + + // Set the initial size of the graph. + int height = default_flame_graph_height + _window.frame.size.height - _window.contentLayoutRect.size.height; + _graph_view.frame = NSMakeRect(0, 0, default_flame_graph_width, height); + _graph_view_controller.view.frame = NSMakeRect(0, 0, default_flame_graph_width, height); + + _total_item = nil; + if (@available(macOS 11.0, *)) { + NSToolbar *toolbar = [[NSToolbar alloc] initWithIdentifier:@""]; + toolbar.delegate = _graph_view_controller; + toolbar.displayMode = NSToolbarDisplayModeIconOnly; + _window.toolbar = toolbar; + [_window setToolbarStyle:NSWindowToolbarStyleUnifiedCompact]; + + for (NSToolbarItem *item in toolbar.items) { + if ([item.itemIdentifier isEqual:@"total"]) { + _total_item = item; + break; + } + } + [toolbar release]; + } + + //MacStatsScaleAreaController *scale_area_controller = [[MacStatsScaleAreaController alloc] initWithGraph:this]; + //scale_area_controller.layoutAttribute = NSLayoutAttributeRight; + //_scale_area = scale_area_controller.view; + //[_window addTitlebarAccessoryViewController:scale_area_controller]; + + _window.contentViewController = _graph_view_controller; + + _graph_view_controller.backToolbarItemVisible = NO; + + // Let's show the units on the guide bar labels. There's room. + set_guide_bar_units(get_guide_bar_units() | GBU_show_units); + + if (get_average_mode()) { + start_animation(); + } + + if (is_title_unknown()) { + std::string window_title = get_title_text(); + if (!is_title_unknown()) { + _window.title = [NSString stringWithUTF8String:window_title.c_str()]; + } + } + + if (@available(macOS 11.0, *)) { + std::string text = format_number(get_horizontal_scale(), get_guide_bar_units(), get_guide_bar_unit_name()); + [_total_item setTitle:[NSString stringWithUTF8String:text.c_str()]]; + } + + [_window makeKeyAndOrderFront:nil]; +} + +/** + * + */ +MacStatsFlameGraph:: +~MacStatsFlameGraph() { + [_menu_delegate release]; +} + +/** + * Called whenever a new Collector definition is received from the client. + */ +void MacStatsFlameGraph:: +new_collector(int collector_index) { + MacStatsGraph::new_collector(collector_index); +} + +/** + * Called as each frame's data is made available. There is no guarantee the + * frames will arrive in order, or that all of them will arrive at all. The + * monitor should be prepared to accept frames received out-of-order or + * missing. + */ +void MacStatsFlameGraph:: +new_data(int thread_index, int frame_number) { + if (is_title_unknown()) { + std::string window_title = get_title_text(); + if (!is_title_unknown()) { + _window.title = [NSString stringWithUTF8String:window_title.c_str()]; + } + } + + if (!_pause) { + update(); + + if (@available(macOS 11.0, *)) { + std::string text = format_number(get_horizontal_scale(), get_guide_bar_units(), get_guide_bar_unit_name()); + [_total_item setTitle:[NSString stringWithUTF8String:text.c_str()]]; + } + } +} + +/** + * Called when it is necessary to redraw the entire graph. + */ +void MacStatsFlameGraph:: +force_redraw() { + if (_ctx) { + PStatFlameGraph::force_redraw(); + } +} + +/** + * Called when the user has resized the window, forcing a resize of the graph. + */ +void MacStatsFlameGraph:: +changed_graph_size(int graph_xsize, int graph_ysize) { + PStatFlameGraph::changed_size(graph_xsize, graph_ysize); +} + +/** + * Called when the user selects a new time units from the monitor pulldown + * menu, this should adjust the units for the graph to the indicated mask if + * it is a time-based graph. + */ +void MacStatsFlameGraph:: +set_time_units(int unit_mask) { + int old_unit_mask = get_guide_bar_units(); + if ((old_unit_mask & (GBU_hz | GBU_ms)) != 0) { + unit_mask = unit_mask & (GBU_hz | GBU_ms); + unit_mask |= (old_unit_mask & GBU_show_units); + set_guide_bar_units(unit_mask); + + if (@available(macOS 11.0, *)) { + std::string text = format_number(get_horizontal_scale(), get_guide_bar_units(), get_guide_bar_unit_name()); + [_total_item setTitle:[NSString stringWithUTF8String:text.c_str()]]; + } + + //_scale_area.needsDisplay = YES; + } +} + +/** + * Called when the user single-clicks on a label. + */ +void MacStatsFlameGraph:: +on_click_label(int collector_index) { + int current = get_collector_index(); + if (collector_index != current) { + if (_back_stack.empty()) { + _graph_view_controller.backToolbarItemVisible = YES; + } + _back_stack.push_back(current); + set_collector_index(collector_index); + + std::string window_title = get_title_text(); + if (!is_title_unknown()) { + _window.title = [NSString stringWithUTF8String:window_title.c_str()]; + } + } +} + +/** + * Called when the user hovers the mouse over a label. + */ +void MacStatsFlameGraph:: +on_enter_label(int collector_index) { + if (collector_index != _highlighted_index) { + _highlighted_index = collector_index; + + if (!get_average_mode()) { + PStatFlameGraph::force_redraw(); + } + } +} + +/** + * Called when the user's mouse cursor leaves a label. + */ +void MacStatsFlameGraph:: +on_leave_label(int collector_index) { + if (collector_index == _highlighted_index && collector_index != -1) { + _highlighted_index = -1; + + if (!get_average_mode()) { + PStatFlameGraph::force_redraw(); + } + } +} + +/** + * Called when the mouse right-clicks on a label, and should return the menu + * that should pop up. + */ +NSMenu *MacStatsFlameGraph:: +get_label_menu(int collector_index) const { + NSMenu *menu = [[[NSMenu alloc] init] autorelease]; + + std::string label = get_label_tooltip(collector_index); + if (!label.empty()) { + if (@available(macOS 14.0, *)) { + [menu addItem:[NSMenuItem sectionHeaderWithTitle:[NSString stringWithUTF8String:label.c_str()]]]; + } else { + NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:[NSString stringWithUTF8String:label.c_str()] action:nil keyEquivalent:@""]; + item.enabled = NO; + [menu addItem:item]; + [item release]; + } + } + + { + NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:@"Set as Focus" action:@selector(handleSetAsFocus:) keyEquivalent:@""]; + item.target = _graph_view_controller; + item.tag = collector_index; + item.enabled = (collector_index != 0 || get_collector_index() != 0); + [menu addItem:item]; + [item release]; + } + + { + NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:@"Open Strip Chart" action:@selector(handleOpenStripChart:) keyEquivalent:@""]; + item.target = _menu_delegate; + item.tag = collector_index; + [menu addItem:item]; + [item release]; + } + + { + NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:@"Open Flame Graph" action:@selector(handleOpenFlameGraph:) keyEquivalent:@""]; + item.target = _menu_delegate; + item.tag = collector_index; + [menu addItem:item]; + [item release]; + } + + [menu addItem:[NSMenuItem separatorItem]]; + + { + NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:@"Change Color\u2026" action:@selector(handleChangeColor:) keyEquivalent:@""]; + item.target = _graph_view_controller; + item.tag = collector_index; + [menu addItem:item]; + [item release]; + } + + { + NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:@"Reset Color" action:@selector(handleResetColor:) keyEquivalent:@""]; + item.target = _graph_view_controller; + item.tag = collector_index; + [menu addItem:item]; + [item release]; + } + + return menu; +} + +/** + * Calls update_guide_bars with parameters suitable to this kind of graph. + */ +void MacStatsFlameGraph:: +normal_guide_bars() { + // We want vaguely 100 pixels between guide bars. + int num_bars = get_xsize() / 100; + + _guide_bars.clear(); + + double dist = get_horizontal_scale() / num_bars; + + for (int i = 1; i < num_bars; ++i) { + _guide_bars.push_back(make_guide_bar(i * dist)); + } + + _guide_bars_changed = true; + + //nassertv_always(_scale_area != nullptr); + //_scale_area.needsDisplay = YES; +} + +/** + * Erases the chart area. + */ +void MacStatsFlameGraph:: +clear_region() { + if (_ctx) { + CGContextSetFillColorWithColor(_ctx, _background_color); + CGContextFillRect(_ctx, CGRectMake(0, 0, get_xsize(), get_ysize())); + } +} + +/** + * Erases the chart area in preparation for drawing a bunch of bars. + */ +void MacStatsFlameGraph:: +begin_draw() { + if (!_ctx) { + return; + } + + clear_region(); + + // isFlipped is true in the NSView, so flip the text again + CGContextSetTextMatrix(_ctx, CGAffineTransformMakeScale(1, -1)); + + // Draw in the guide bars. + int num_guide_bars = get_num_guide_bars(); + for (int i = 0; i < num_guide_bars; i++) { + const GuideBar &bar = get_guide_bar(i); + draw_guide_bar(_ctx, bar); + draw_guide_label(_ctx, bar); + } +} + +/** + * Should be overridden by the user class. Should draw a single bar at the + * indicated location. + */ +void MacStatsFlameGraph:: +draw_bar(int depth, int from_x, int to_x, int collector_index, int parent_index) { + double bottom = get_ysize() - depth * 4.000 * 5; + double top = bottom - 4.000 * 5; + + top += 1; + + MacStatsMonitor *monitor = MacStatsGraph::_monitor; + + bool is_highlighted = collector_index == _highlighted_index; + CGContextSetFillColorWithColor(_ctx, + monitor->get_collector_color(collector_index, is_highlighted)); + + if (to_x < from_x + 3) { + // It's just a tiny sliver. This is a more reliable way to draw it. + CGRect rect = CGRectMake(from_x, top, to_x - from_x, bottom - top); + CGContextFillRect(_ctx, rect); + } + else { + double radius = std::min((double)4.000, (to_x - from_x) / 2.0); + CGContextBeginPath(_ctx); + CGContextAddArc(_ctx, to_x - radius, top + radius, radius, -0.5 * M_PI, 0.0, NO); + CGContextAddArc(_ctx, to_x - radius, bottom - radius, radius, 0.0, 0.5 * M_PI, NO); + CGContextAddArc(_ctx, from_x + radius, bottom - radius, radius, 0.5 * M_PI, M_PI, NO); + CGContextAddArc(_ctx, from_x + radius, top + radius, radius, M_PI, 1.5 * M_PI, NO); + CGContextClosePath(_ctx); + CGContextFillPath(_ctx); + + if ((to_x - from_x) >= 4.000 * 4) { + // Only bother drawing the text if we've got some space to draw on. + int left = std::max(from_x, 0) + 4.000 / 2; + int right = std::min(to_x, get_xsize()) - 4.000 / 2; + + const PStatClientData *client_data = monitor->get_client_data(); + const PStatCollectorDef &def = client_data->get_collector_def(collector_index); + + const CFStringRef keys[] = { + (__bridge CFStringRef)NSForegroundColorAttributeName, + (__bridge CFStringRef)NSFontAttributeName, + }; + const void *values[] = { + monitor->get_collector_text_color(collector_index, is_highlighted), + [NSFont systemFontOfSize:0.0], + }; + CFDictionaryRef attribs = CFDictionaryCreate(kCFAllocatorDefault, (const void **)keys, (const void **)values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + + CFStringRef str = CFStringCreateWithCString(kCFAllocatorDefault, def._name.c_str(), kCFStringEncodingUTF8); + CFAttributedStringRef astr = CFAttributedStringCreate(kCFAllocatorDefault, str, attribs); + + CTLineRef line = CTLineCreateWithAttributedString(astr); + CGRect bounds = CTLineGetImageBounds(line, _ctx); + CFRelease(astr); + CFRelease(str); + + if (bounds.size.width < right - left) { + // We have room for more. Show the collector's actual parent, if it's + // different than the block it's shown above. + if (def._parent_index > 0 && def._parent_index != parent_index) { + const PStatCollectorDef &parent_def = client_data->get_collector_def(def._parent_index); + std::string long_name = parent_def._name + ":" + def._name; + + CFStringRef long_str = CFStringCreateWithCString(kCFAllocatorDefault, long_name.c_str(), kCFStringEncodingUTF8); + CFAttributedStringRef long_astr = CFAttributedStringCreate(kCFAllocatorDefault, long_str, attribs); + + CTLineRef long_line = CTLineCreateWithAttributedString((CFAttributedStringRef)long_astr); + CGRect long_bounds = CTLineGetImageBounds(long_line, _ctx); + + if (long_bounds.size.width < right - left) { + CFRelease(line); + line = long_line; + bounds = long_bounds; + } else { + CFRelease(long_line); + } + CFRelease(long_astr); + CFRelease(long_str); + } + } + else { + static CFStringRef token_str = CFSTR("\u2026"); + CFAttributedStringRef token_astr = CFAttributedStringCreate(kCFAllocatorDefault, token_str, attribs); + CTLineRef token_line = CTLineCreateWithAttributedString(token_astr); + CTLineRef trunc_line = CTLineCreateTruncatedLine(line, right - left, kCTLineTruncationEnd, token_line); + CFRelease(line); + CFRelease(token_astr); + CFRelease(token_line); + line = trunc_line; + } + + // Center the text vertically in the bar. + if (line != nullptr) { + CGContextSetTextPosition(_ctx, left, top + (bottom - top + bounds.size.height) / 2); + CTLineDraw(line, _ctx); + CFRelease(line); + } + CFRelease(attribs); + } + } +} + +/** + * Called after all the bars have been drawn, this triggers a refresh event to + * draw it to the window. + */ +void MacStatsFlameGraph:: +end_draw() { + _graph_view.needsDisplay = YES; +} + +/** + * Called at the end of the draw cycle. + */ +void MacStatsFlameGraph:: +idle() { +} + +/** + * Overridden by a derived class to implement an animation. If it returns + * false, the animation timer is stopped. + */ +bool MacStatsFlameGraph:: +animate(double time, double dt) { + return PStatFlameGraph::animate(time, dt); +} + +/** + * Returns the current window dimensions. + */ +bool MacStatsFlameGraph:: +get_window_state(int &x, int &y, int &width, int &height, + bool &maximized, bool &minimized) const { + MacStatsGraph::get_window_state(x, y, width, height, maximized, minimized); + return true; +} + +/** + * Called to restore the graph window to its previous dimensions. + */ +void MacStatsFlameGraph:: +set_window_state(int x, int y, int width, int height, + bool maximized, bool minimized) { + MacStatsGraph::set_window_state(x, y, width, height, maximized, minimized); +} + +/** + * Called when the mouse right-clicks on the graph, and should return the menu + * that should pop up. + */ +NSMenu *MacStatsFlameGraph:: +get_graph_menu(int mouse_x, int mouse_y) const { + int collector_index = get_bar_collector(pixel_to_depth(mouse_y), mouse_x); + if (collector_index != -1) { + return get_label_menu(collector_index); + } + return nil; +} + +/** + * Called when the mouse hovers over the graph, and should return the text that + * should appear on the tooltip. + */ +std::string MacStatsFlameGraph:: +get_graph_tooltip(int mouse_x, int mouse_y) const { + return get_bar_tooltip(pixel_to_depth(mouse_y), mouse_x); +} + +/** + * Based on the mouse position within the window's client area, look for + * draggable things the mouse might be hovering over and return the + * apprioprate DragMode enum or DM_none if nothing is indicated. + */ +MacStatsGraph::DragMode MacStatsFlameGraph:: +consider_drag_start(int graph_x, int graph_y) { + if (graph_y >= 0 && graph_y < get_ysize()) { + if (graph_x >= 0 && graph_x < get_xsize()) { + // See if the mouse is over a user-defined guide bar. + int x = graph_x; + double from_height = pixel_to_height(x - 2); + double to_height = pixel_to_height(x + 2); + _drag_guide_bar = find_user_guide_bar(from_height, to_height); + if (_drag_guide_bar >= 0) { + return DM_guide_bar; + } + + } else { + // The mouse is left or right of the graph; maybe create a new guide + // bar. + return DM_new_guide_bar; + } + } + + return DM_none; +} + +/** + * Called when the mouse button is depressed within the graph window. + */ +void MacStatsFlameGraph:: +handle_button_press(int graph_x, int graph_y, bool double_click, int button) { + if (graph_x >= 0 && graph_y >= 0 && graph_x < get_xsize() && graph_y < get_ysize()) { + int depth = pixel_to_depth(graph_y); + int collector_index = get_bar_collector(depth, graph_x); + if (double_click && button == 0) { + // Double-clicking on a color bar in the graph will zoom the graph into + // that collector. + if (collector_index >= 0) { + on_click_label(collector_index); + } else { + if (!_back_stack.empty()) { + _back_stack.clear(); + _graph_view_controller.backToolbarItemVisible = NO; + } + set_collector_index(-1); + std::string window_title = get_title_text(); + if (!is_title_unknown()) { + _window.title = [NSString stringWithUTF8String:window_title.c_str()]; + } + } + return; + } + } + + if (_potential_drag_mode == DM_none) { + set_drag_mode(DM_scale); + _drag_scale_start = pixel_to_height(graph_x); + // SetCapture(_graph_window); + return; + } + else if (_potential_drag_mode == DM_guide_bar && _drag_guide_bar >= 0) { + set_drag_mode(DM_guide_bar); + _drag_start_x = graph_x; + // SetCapture(_graph_window); + return; + } + + return MacStatsGraph::handle_button_press(graph_x, graph_y, + double_click, button); +} + +/** + * Called when the mouse button is released within the graph window. + */ +void MacStatsFlameGraph:: +handle_button_release(int graph_x, int graph_y) { + if (_drag_mode == DM_scale) { + set_drag_mode(DM_none); + // ReleaseCapture(); + return handle_motion(graph_x, graph_y); + } + else if (_drag_mode == DM_guide_bar) { + if (graph_x < 0 || graph_x >= get_xsize()) { + remove_user_guide_bar(_drag_guide_bar); + } else { + move_user_guide_bar(_drag_guide_bar, pixel_to_height(graph_x)); + } + set_drag_mode(DM_none); + // ReleaseCapture(); + return handle_motion(graph_x, graph_y); + } + + return MacStatsGraph::handle_button_release(graph_x, graph_y); +} + +/** + * Called when the mouse is moved within the graph window. + */ +void MacStatsFlameGraph:: +handle_motion(int graph_x, int graph_y) { + if (_drag_mode == DM_none && _potential_drag_mode == DM_none && + graph_x >= 0 && graph_y >= 0 && graph_x < get_xsize() && graph_y < get_ysize()) { + // When the mouse is over a color bar, highlight it. + int depth = pixel_to_depth(graph_y); + int collector_index = get_bar_collector(depth, graph_x); + on_enter_label(collector_index); + } + else { + // If the mouse is in some drag mode, stop highlighting. + _label_stack.highlight_label(-1); + on_leave_label(_highlighted_index); + } + + if (_drag_mode == DM_new_guide_bar) { + // We haven't created the new guide bar yet; we won't until the mouse + // comes within the graph's region. + if (graph_x >= 0 && graph_x < get_xsize()) { + set_drag_mode(DM_guide_bar); + _drag_guide_bar = add_user_guide_bar(pixel_to_height(graph_x)); + return; + } + } + else if (_drag_mode == DM_guide_bar) { + move_user_guide_bar(_drag_guide_bar, pixel_to_height(graph_x)); + return; + } + + return MacStatsGraph::handle_motion(graph_x, graph_y); +} + +/** + * Called when the mouse has left the graph window. + */ +void MacStatsFlameGraph:: +handle_leave() { + _label_stack.highlight_label(-1); + on_leave_label(_highlighted_index); + return; +} + +/** + * Fills in the graph window. + */ +void MacStatsFlameGraph:: +handle_draw_graph(CGContextRef ctx, NSRect rect) { + MacStatsGraph::handle_draw_graph(ctx, rect); + + CGContextSetTextMatrix(ctx, CGAffineTransformMakeScale(1, -1)); + + int num_user_guide_bars = get_num_user_guide_bars(); + for (int i = 0; i < num_user_guide_bars; i++) { + const GuideBar &bar = get_user_guide_bar(i); + draw_guide_bar(ctx, bar); + draw_guide_label(ctx, bar); + } +} + +/** + * Called when the mouse clicks the back button in the toolbar. + */ +void MacStatsFlameGraph:: +handle_back() { + if (!_back_stack.empty()) { + int collector_index = _back_stack.back(); + _back_stack.pop_back(); + set_collector_index(collector_index); + + if (_back_stack.empty()) { + _graph_view_controller.backToolbarItemVisible = NO; + } + + std::string window_title = get_title_text(); + if (!is_title_unknown()) { + _window.title = [NSString stringWithUTF8String:window_title.c_str()]; + } + } +} + +/** + * Called when the mouse toggles the "Average" checkbox in the toolbar. + */ +void MacStatsFlameGraph:: +handle_toggle_average(bool state) { + set_average_mode(state); + if (state) { + start_animation(); + } +} + + +/** + * Converts a pixel to a depth index. + */ +int MacStatsFlameGraph:: +pixel_to_depth(int y) const { + return (get_ysize() - 1 - y) / (4.000 * 5); +} + +/** + * Draws the line for the indicated guide bar on the graph. + */ +void MacStatsFlameGraph:: +draw_guide_bar(CGContextRef ctx, const PStatGraph::GuideBar &bar) { + int x = height_to_pixel(bar._height); + + if (x > 0 && x < get_xsize() - 1) { + // Only draw it if it's not too close to the top. + CGContextSetStrokeColorWithColor(ctx, [NSColor gridColor].CGColor); + /*switch (bar._style) { + case GBS_target: + CGContextSetRGBStrokeColor(ctx, rgb_light_gray[0], rgb_light_gray[1], rgb_light_gray[2], 1.0); + break; + + case GBS_user: + CGContextSetRGBStrokeColor(ctx, rgb_user_guide_bar[0], rgb_user_guide_bar[1], rgb_user_guide_bar[2], 1.0); + break; + + default: + CGContextSetRGBStrokeColor(ctx, rgb_dark_gray[0], rgb_dark_gray[1], rgb_dark_gray[2], 1.0); + break; + }*/ + CGContextBeginPath(ctx); + CGContextMoveToPoint(ctx, x, 0); + CGContextAddLineToPoint(ctx, x, get_ysize()); + CGContextStrokePath(ctx); + } +} + +/** + * This is called during the servicing of the draw event. + */ +void MacStatsFlameGraph:: +draw_guide_labels(CGContextRef ctx) { + int num_guide_bars = get_num_guide_bars(); + for (int i = 0; i < num_guide_bars; i++) { + draw_guide_label(ctx, get_guide_bar(i)); + } + + int num_user_guide_bars = get_num_user_guide_bars(); + for (int i = 0; i < num_user_guide_bars; i++) { + draw_guide_label(ctx, get_user_guide_bar(i)); + } +} + +/** + * Draws the text for the indicated guide bar label at the top of the graph. + */ +void MacStatsFlameGraph:: +draw_guide_label(CGContextRef ctx, const PStatGraph::GuideBar &bar) { + NSColor *color; + color = [NSColor tertiaryLabelColor]; + /*switch (bar._style) { + case GBS_target: + color = [NSColor colorWithDeviceRed:rgb_light_gray[0] green:rgb_light_gray[1] blue:rgb_light_gray[2] alpha:1.0]; + break; + + case GBS_user: + color = [NSColor colorWithDeviceRed:rgb_user_guide_bar[0] green:rgb_user_guide_bar[1] blue:rgb_user_guide_bar[2] alpha:1.0]; + break; + + default: + color = [NSColor colorWithDeviceRed:rgb_dark_gray[0] green:rgb_dark_gray[1] blue:rgb_dark_gray[2] alpha:1.0]; + break; + }*/ + + int x = height_to_pixel(bar._height); + const std::string &label = bar._label; + + const CFStringRef keys[] = { + (__bridge CFStringRef)NSForegroundColorAttributeName, + (__bridge CFStringRef)NSFontAttributeName, + }; + const void *values[] = { + color, + [NSFont systemFontOfSize:0.0], + }; + CFDictionaryRef attribs = CFDictionaryCreate(kCFAllocatorDefault, (const void **)keys, (const void **)values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + + CFStringRef str = CFStringCreateWithCString(kCFAllocatorDefault, label.c_str(), kCFStringEncodingUTF8); + CFAttributedStringRef astr = CFAttributedStringCreate(kCFAllocatorDefault, str, attribs); + CFRelease(attribs); + CFRelease(str); + + CTLineRef line = CTLineCreateWithAttributedString(astr); + CFRelease(astr); + CGRect bounds = CTLineGetImageBounds(line, ctx); + int width = bounds.size.width; + + if (bar._style != GBS_user) { + double from_height = pixel_to_height(x - width); + double to_height = pixel_to_height(x + width); + if (find_user_guide_bar(from_height, to_height) >= 0) { + // Omit the label: there's a user-defined guide bar in the same space. + CFRelease(line); + return; + } + } + + if (x >= 0 && x < get_xsize()) { + int y = bounds.size.height; + if (@available(macOS 11.0, *)) { + // Account for underlap of title bar + y += _window.frame.size.height - _window.contentLayoutRect.size.height; + } + CGContextSetTextPosition(ctx, x + 6, y + 6); + CTLineDraw(line, ctx); + } + + CFRelease(line); +} + +@implementation MacStatsFlameGraphViewController + +- (NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar *)toolbar { + return @[@"back", @"average", @"total"]; +} + +- (NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar *)toolbar { + return @[@"average", @"total"]; +} + +- (NSToolbarItem *) toolbar:(NSToolbar *)toolbar + itemForItemIdentifier:(NSString *)ident + willBeInsertedIntoToolbar:(BOOL)flag { + + if (@available(macOS 11.0, *)) { + if ([ident isEqual:@"average"]) { + NSButton *button = [NSButton buttonWithTitle:@"Average" target:self action:@selector(handleToggleAverage:)]; + button.image = [NSImage imageWithSystemSymbolName:@"sum" accessibilityDescription:@""]; + button.bezelStyle = NSBezelStyleTexturedRounded; + button.buttonType = NSButtonTypePushOnPushOff; + button.bordered = YES; + button.toolTip = @"Average"; + button.state = NSOffState; + NSToolbarItem *item = [[[NSToolbarItem alloc] initWithItemIdentifier:ident] autorelease]; + item.label = @"Average"; + item.view = button; + return item; + } + if ([ident isEqual:@"total"]) { + NSToolbarItem *item = [[[NSToolbarItem alloc] initWithItemIdentifier:ident] autorelease]; + item.label = @"Total"; + item.enabled = NO; + [item setBordered:YES]; + return item; + } + } + + return [super toolbar:toolbar itemForItemIdentifier:ident willBeInsertedIntoToolbar:flag]; +} + +- (void)handleToggleAverage:(NSButton *)button { + MacStatsFlameGraph *graph = (MacStatsFlameGraph *)_graph; + graph->handle_toggle_average(button.state == NSOnState); +} + +@end diff --git a/pandatool/src/mac-stats/macStatsGraph.h b/pandatool/src/mac-stats/macStatsGraph.h new file mode 100644 index 0000000000..2905f60d5a --- /dev/null +++ b/pandatool/src/mac-stats/macStatsGraph.h @@ -0,0 +1,139 @@ +/** + * 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 macStatsGraph.h + * @author rdb + * @date 2023-08-17 + */ + +#ifndef MACSTATSGRAPH_H +#define MACSTATSGRAPH_H + +#include "pandatoolbase.h" +#include "macStatsGraphViewController.h" +#include "macStatsLabelStack.h" +#include "pmap.h" +#include "luse.h" + +class MacStatsMonitor; + +/** + * This is just an abstract base class to provide a common pointer type for + * the various kinds of graphs that may be created for a MacStatsMonitor. + */ +class MacStatsGraph { +public: + // What is the user adjusting by dragging the mouse in a window? + enum DragMode { + DM_none, + DM_scale, + DM_guide_bar, + DM_new_guide_bar, + DM_sizing, + DM_pan, + }; + +public: + MacStatsGraph(MacStatsMonitor *monitor, MacStatsGraphViewController *controller); + virtual ~MacStatsGraph(); + + void close(); + + MacStatsMonitor *get_monitor() { return _monitor; } + NSSplitView *get_split_view() { return _split_view; } + + virtual void new_collector(int collector_index); + virtual void new_data(int thread_index, int frame_number); + virtual void force_redraw()=0; + virtual void changed_graph_size(int graph_xsize, int graph_ysize); + + virtual void set_time_units(int unit_mask); + virtual void set_scroll_speed(double scroll_speed); + void set_pause(bool pause); + + void user_guide_bars_changed(); + virtual void on_click_label(int collector_index); + virtual void on_enter_label(int collector_index); + virtual void on_leave_label(int collector_index); + virtual NSMenu *get_label_menu(int collector_index) const; + virtual std::string get_label_tooltip(int collector_index) const; + + void reset_collector_color(int collector_index); + +protected: + void start_animation(); + virtual bool animate(double time, double dt); + + void get_window_state(int &x, int &y, int &width, int &height, + bool &maximized, bool &minimized) const; + void set_window_state(int x, int y, int width, int height, + bool maximized, bool minimized); + +public: + // These must be public, because we can't declare Objective-C friends here. + virtual NSMenu *get_graph_menu(int mouse_x, int mouse_y) const; + virtual std::string get_graph_tooltip(int mouse_x, int mouse_y) const; + virtual DragMode consider_drag_start(int graph_x, int graph_y); + virtual void set_drag_mode(DragMode drag_mode); + + virtual bool handle_key(int graph_x, int graph_y, bool pressed, + UniChar c, unsigned short key_code); + virtual void handle_button_press(int graph_x, int graph_y, + bool double_click, int button); + virtual void handle_button_release(int graph_x, int graph_y); + virtual void handle_motion(int graph_x, int graph_y); + virtual void handle_leave(); + virtual void handle_scroll(); + virtual void handle_wheel(int graph_x, int graph_y, double dx, double dy); + virtual void handle_magnify(int graph_x, int graph_y, double scale); + virtual void handle_draw_graph(CGContextRef ctx, NSRect rect); + virtual void handle_draw_graph_overhang(CGContextRef ctx, NSRect rect); + virtual void handle_draw_scale_area(CGContextRef ctx, NSRect rect); + virtual void handle_back(); + virtual void handle_timer(); + +protected: + CGColorRef _background_color; + + MacStatsMonitor *_monitor; + NSWindow *_window; + NSView *_graph_view; + MacStatsGraphViewController *_graph_view_controller; + NSView *_scale_area = nullptr; + NSSplitView *_split_view = nullptr; + NSScrollView *_sidebar_view = nullptr; + MacStatsLabelStack _label_stack; + + CGContextRef _ctx = nullptr; + int _bitmap_xsize, _bitmap_ysize; + + DragMode _drag_mode; + DragMode _potential_drag_mode; + int _drag_start_x, _drag_start_y; + double _drag_scale_start; + int _drag_guide_bar; + + int _highlighted_index = -1; + + bool _pause; + + NSTimer *_animation_timer = nil; + double _time = 0.0; + + static const CGFloat rgb_white[4]; + static const CGFloat rgb_light_gray[4]; + static const CGFloat rgb_dark_gray[4]; + static const CGFloat rgb_black[4]; + static const CGFloat rgb_user_guide_bar[4]; + +private: + void setup_bitmap(int xsize, int ysize, double scale); + void release_bitmap(); +}; + +#endif diff --git a/pandatool/src/mac-stats/macStatsGraph.mm b/pandatool/src/mac-stats/macStatsGraph.mm new file mode 100644 index 0000000000..466d875df3 --- /dev/null +++ b/pandatool/src/mac-stats/macStatsGraph.mm @@ -0,0 +1,491 @@ +/** + * 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 macStatsGraph.mm + * @author rdb + * @date 2023-08-17 + */ + +#include "macStatsGraph.h" +#include "macStatsGraphView.h" +#include "macStatsMonitor.h" +#include "macStatsLabelStack.h" + +const CGFloat MacStatsGraph::rgb_light_gray[4] = { + 0x9a / (CGFloat)0xff, 0x9a / (CGFloat)0xff, 0x9a / (CGFloat)0xff, 1.0, +}; +const CGFloat MacStatsGraph::rgb_dark_gray[4] = { + 0xb0 / (CGFloat)0xff, 0xb0 / (CGFloat)0xff, 0xb0 / (CGFloat)0xff, 1.0, +}; +const CGFloat MacStatsGraph::rgb_user_guide_bar[4] = { + 0x82 / (CGFloat)0xff, 0x96 / (CGFloat)0xff, 0xff / (CGFloat)0xff, 1.0, +}; + +static const NSInteger style_mask = NSWindowStyleMaskTitled + | NSWindowStyleMaskClosable + | NSWindowStyleMaskMiniaturizable + | NSWindowStyleMaskResizable; + +/** + * + */ +MacStatsGraph:: +MacStatsGraph(MacStatsMonitor *monitor, MacStatsGraphViewController *controller) : + _monitor(monitor) +{ + _background_color = CGColorCreateGenericRGB(0.0, 0.0, 0.0, 0.0); + + _drag_mode = DM_none; + _potential_drag_mode = DM_none; + _drag_scale_start = 0.0f; + + _pause = false; + + NSInteger this_style_mask = style_mask; + if (@available(macOS 11.0, *)) { + this_style_mask |= NSWindowStyleMaskFullSizeContentView; + } + + _window = [NSWindow alloc]; + [_window initWithContentRect:NSMakeRect(100, 500, 500, 150) + styleMask:this_style_mask + backing:NSBackingStoreBuffered + defer:NO]; + _window.releasedWhenClosed = NO; + _window.titlebarAppearsTransparent = NO; + _window.excludedFromWindowsMenu = NO; + + _window.contentMinSize = NSMakeSize(68, _window.contentView.frame.size.height - _window.contentLayoutRect.size.height); + + _graph_view_controller = [controller initWithGraph:this]; + _graph_view = ((MacStatsGraphViewController *)_graph_view_controller).graphView; + + // Get notified when the window closes. + NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; + [center addObserver:_graph_view_controller + selector:@selector(windowWillClose:) + name:NSWindowWillCloseNotification + object:_window]; +} + +/** + * + */ +MacStatsGraph:: +~MacStatsGraph() { + if (_animation_timer != nil) { + [_animation_timer invalidate]; + [_animation_timer release]; + _animation_timer = nil; + } + + _monitor = nullptr; + release_bitmap(); + + _label_stack.clear_labels(); + + [_graph_view_controller release]; + [_window release]; + + CGColorRelease(_background_color); +} + +/** + * + */ +void MacStatsGraph:: +close() { + [_window close]; +} + +/** + * Called whenever a new Collector definition is received from the client. + */ +void MacStatsGraph:: +new_collector(int new_collector) { +} + +/** + * Called whenever new data arrives. + */ +void MacStatsGraph:: +new_data(int thread_index, int frame_number) { +} + +/** + * Called when the user has resized the window, forcing a resize of the graph. + */ +void MacStatsGraph:: +changed_graph_size(int graph_xsize, int graph_ysize) { +} + +/** + * Called when the user selects a new time units from the monitor pulldown + * menu, this should adjust the units for the graph to the indicated mask if + * it is a time-based graph. + */ +void MacStatsGraph:: +set_time_units(int unit_mask) { +} + +/** + * Called when the user selects a new scroll speed from the monitor pulldown + * menu, this should adjust the speed for the graph to the indicated value. + */ +void MacStatsGraph:: +set_scroll_speed(double scroll_speed) { +} + +/** + * Changes the pause flag for the graph. When this flag is true, the graph + * does not update in response to new data. + */ +void MacStatsGraph:: +set_pause(bool pause) { + _pause = pause; +} + +/** + * Called when the user guide bars have been changed. + */ +void MacStatsGraph:: +user_guide_bars_changed() { + if (_scale_area != nullptr) { + _scale_area.needsDisplay = YES; + } + _graph_view.needsDisplay = YES; +} + +/** + * Called when the user single-clicks on a label. + */ +void MacStatsGraph:: +on_click_label(int collector_index) { +} + +/** + * Called when the user hovers the mouse over a label. + */ +void MacStatsGraph:: +on_enter_label(int collector_index) { + if (collector_index != _highlighted_index) { + _highlighted_index = collector_index; + force_redraw(); + } +} + +/** + * Called when the user's mouse cursor leaves a label. + */ +void MacStatsGraph:: +on_leave_label(int collector_index) { + if (collector_index == _highlighted_index && collector_index != -1) { + _highlighted_index = -1; + force_redraw(); + } +} + +/** + * Called when the mouse right-clicks on a label, and should return the menu + * that should pop up. + */ +NSMenu *MacStatsGraph:: +get_label_menu(int collector_index) const { + return nil; +} + +/** + * Called when the mouse hovers over a label, and should return the text that + * should appear on the tooltip. + */ +std::string MacStatsGraph:: +get_label_tooltip(int collector_index) const { + return std::string(); +} + +/** + * Turns on the animation timer, if it hasn't already been turned on. + */ +void MacStatsGraph:: +start_animation() { + if (_animation_timer != nil) { + return; + } + + _time = 0.0; + _animation_timer = [NSTimer scheduledTimerWithTimeInterval:1 / 60.0 target:_graph_view selector:@selector(handleTimer:) userInfo:nil repeats:YES]; + [_animation_timer retain]; +} + +/** + * Overridden by a derived class to implement an animation. If it returns + * false, the animation timer is stopped. + */ +bool MacStatsGraph:: +animate(double time, double dt) { + return false; +} + +/** + * Returns the current window dimensions. + */ +void MacStatsGraph:: +get_window_state(int &x, int &y, int &width, int &height, + bool &maximized, bool &minimized) const { + + NSRect screen_frame = _window.screen.visibleFrame; + + NSRect frame = _window.frame; + x = frame.origin.x - screen_frame.origin.x; + y = (screen_frame.origin.y + screen_frame.size.height) - (frame.origin.y + frame.size.height); + width = frame.size.width; + height = frame.size.height; + maximized = _window.zoomed; + minimized = _window.miniaturized; +} + +/** + * Called to restore the graph window to its previous dimensions. + */ +void MacStatsGraph:: +set_window_state(int x, int y, int width, int height, + bool maximized, bool minimized) { + + NSRect screen_frame = _window.screen.visibleFrame; + + NSRect frame; + frame.origin.x = screen_frame.origin.x + x; + frame.origin.y = (screen_frame.origin.y + screen_frame.size.height) - (y + height); + frame.size.width = width; + frame.size.height = height; + [_window setFrame:frame display:NO]; + + if (maximized != _window.zoomed) { + [_window zoom:_window]; + } + + if (minimized != _window.miniaturized) { + if (minimized) { + [_window miniaturize:_window]; + } else { + [_window deminiaturize:_window]; + } + } +} + +/** + * Called when the given collector has changed colors. + */ +void MacStatsGraph:: +reset_collector_color(int collector_index) { + force_redraw(); + _label_stack.update_label_color(collector_index); +} + +/** + * Called when the mouse right-clicks on the graph, and should return the menu + * that should pop up. + */ +NSMenu *MacStatsGraph:: +get_graph_menu(int mouse_x, int mouse_y) const { + return nil; +} + +/** + * Called when the mouse hovers over the graph, and should return the text that + * should appear on the tooltip. + */ +std::string MacStatsGraph:: +get_graph_tooltip(int mouse_x, int mouse_y) const { + return std::string(); +} + +/** + * Based on the mouse position within the graph window, look for draggable + * things the mouse might be hovering over and return the appropriate DragMode + * enum or DM_none if nothing is indicated. + */ +MacStatsGraph::DragMode MacStatsGraph:: +consider_drag_start(int graph_x, int graph_y) { + return DM_none; +} + +/** + * This should be called whenever the drag mode needs to change state. It + * provides hooks for a derived class to do something special. + */ +void MacStatsGraph:: +set_drag_mode(MacStatsGraph::DragMode drag_mode) { + _drag_mode = drag_mode; +} + +/** + * + */ +bool MacStatsGraph:: +handle_key(int graph_x, int graph_y, bool pressed, UniChar c, unsigned short key_code) { + return false; +} + +/** + * Called when the mouse button is depressed within the window, or any nested + * window. + */ +void MacStatsGraph:: +handle_button_press(int graph_x, int graph_y, bool double_click, int button) { + if (_potential_drag_mode != DM_none && button == 1) { + set_drag_mode(_potential_drag_mode); + _drag_start_x = graph_x; + _drag_start_y = graph_y; + // SetCapture(_window); + } +} + +/** + * Called when the mouse button is released within the window, or any nested + * window. + */ +void MacStatsGraph:: +handle_button_release(int graph_x, int graph_y) { + set_drag_mode(DM_none); + // ReleaseCapture(); + + return handle_motion(graph_x, graph_y); +} + +/** + * Called when the mouse is moved within the window, or any nested window. + */ +void MacStatsGraph:: +handle_motion(int graph_x, int graph_y) { + _potential_drag_mode = consider_drag_start(graph_x, graph_y); +} + +/** + * Called when the mouse has left the graph window. + */ +void MacStatsGraph:: +handle_leave() { +} + +/** + * Called when the mouse is moved within the graph window. + */ +void MacStatsGraph:: +handle_scroll() { + force_redraw(); +} + +/** + * + */ +void MacStatsGraph:: +handle_wheel(int graph_x, int graph_y, double dx, double dy) { +} + +/** + * + */ +void MacStatsGraph:: +handle_magnify(int graph_x, int graph_y, double scale) { +} + +/** + * + */ +void MacStatsGraph:: +handle_timer() { + _time += 1.0 / 60.0; + + if (!animate(_time, 1.0 / 60.0)) { + [_animation_timer invalidate]; + [_animation_timer release]; + _animation_timer = nil; + } +} + +/** + * Fills in the graph window. + */ +void MacStatsGraph:: +handle_draw_graph(CGContextRef ctx, NSRect rect) { + CGContextSetBlendMode(ctx, kCGBlendModeCopy); + CGContextSetInterpolationQuality(ctx, kCGInterpolationNone); + + // Quantize this so that changed_graph_size will always call force_redraw() + NSRect full_rect = _graph_view.bounds; + full_rect.size.width = (int)full_rect.size.width; + full_rect.size.height = (int)full_rect.size.height; + + CGSize size = CGContextConvertSizeToDeviceSpace(ctx, full_rect.size); + int width = abs((int)size.width); + int height = abs((int)size.height); + + if (_ctx == nullptr || _bitmap_xsize != width || _bitmap_ysize != height) { + if (_ctx == nullptr && _scale_area != nullptr) { + _scale_area.needsDisplay = YES; + } + setup_bitmap(width, height, _window.backingScaleFactor); + + changed_graph_size(full_rect.size.width, full_rect.size.height); + } + + CGImageRef image = CGBitmapContextCreateImage(_ctx); + CGContextDrawImage(ctx, CGRectMake(0, 0, full_rect.size.width, full_rect.size.height), image); + CGImageRelease(image); +} + +/** + * Fills in the graph window overhang, which is the area outside the graph + * bounds that may become visible momentarily due to scroll elasticity. + */ +void MacStatsGraph:: +handle_draw_graph_overhang(CGContextRef ctx, NSRect rect) { +} + +/** + * Fills in the scale area. + */ +void MacStatsGraph:: +handle_draw_scale_area(CGContextRef ctx, NSRect rect) { +} + +/** + * Called when the mouse clicks the back button in the toolbar. + */ +void MacStatsGraph:: +handle_back() { +} + +/** + * Sets up a backing-store bitmap of the indicated size. + */ +void MacStatsGraph:: +setup_bitmap(int xsize, int ysize, double scale) { + release_bitmap(); + + _bitmap_xsize = xsize; + _bitmap_ysize = ysize; + + // Ostensibly, a layer context is more efficient, but I tried it and the + // performance was horrible compared to a bitmap context. + _ctx = CGBitmapContextCreate(nullptr, xsize, ysize, 8, 0, CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB), kCGImageAlphaPremultipliedLast); + CGContextSetBlendMode(_ctx, kCGBlendModeCopy); + CGContextScaleCTM(_ctx, scale, scale); +} + +/** + * Frees the backing-store bitmap created by setup_bitmap(). + */ +void MacStatsGraph:: +release_bitmap() { + if (_ctx != nullptr) { + CGContextRelease(_ctx); + _ctx = nullptr; + } +} diff --git a/pandatool/src/mac-stats/macStatsGraphView.h b/pandatool/src/mac-stats/macStatsGraphView.h new file mode 100644 index 0000000000..efd0d0c6b0 --- /dev/null +++ b/pandatool/src/mac-stats/macStatsGraphView.h @@ -0,0 +1,31 @@ +/** + * 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 macStatsGraphView.h + * @author rdb + * @date 2023-08-18 + */ + +#ifndef MACSTATSGRAPHVIEW_H +#define MACSTATSGRAPHVIEW_H + +#include "cocoa_compat.h" + +class MacStatsGraph; + +@interface MacStatsGraphView : NSView { + @public + MacStatsGraph *_graph; +} + +- (id)initWithGraph:(MacStatsGraph *)graph; +- (void)drawRect:(NSRect)dirtyRect; + +@end + +#endif diff --git a/pandatool/src/mac-stats/macStatsGraphView.mm b/pandatool/src/mac-stats/macStatsGraphView.mm new file mode 100644 index 0000000000..013b424139 --- /dev/null +++ b/pandatool/src/mac-stats/macStatsGraphView.mm @@ -0,0 +1,158 @@ +/** + * 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 macStatsGraphView.mm + * @author rdb + * @date 2023-08-18 + */ + +#include "macStatsGraphView.h" +#include "macStatsGraph.h" +#include "macStatsStripChart.h" +#include "macStatsFlameGraph.h" +#include "macStatsTimeline.h" +#include "macStatsScaleArea.h" + +@implementation MacStatsGraphView + +- (id)initWithGraph:(MacStatsGraph *)graph { + if (self = [super init]) { + _graph = graph; + + self.translatesAutoresizingMaskIntoConstraints = NO; + + NSTrackingArea *area = [[NSTrackingArea alloc] initWithRect:NSZeroRect options:(NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved | NSTrackingActiveInKeyWindow | NSTrackingInVisibleRect) owner:self userInfo:nil]; + [self addTrackingArea:area]; + [area release]; + + [self addToolTipRect:NSMakeRect(0, 0, 1000, 1000) owner:self userData:nil]; + } + + return self; +} + +- (BOOL)isFlipped { + return YES; +} + +- (BOOL)acceptsFirstResponder { + return YES; +} + +- (void)keyDown:(NSEvent *)event { + if (!event.isARepeat) { + NSPoint pos = [self convertPoint:event.locationInWindow fromView:nil]; + UniChar c = 0; + NSString *str = [event charactersIgnoringModifiers]; + if (str != nil && str.length == 1) { + c = [str characterAtIndex:0]; + } + _graph->handle_key(pos.x, pos.y, true, c, event.keyCode); + } +} + +- (void)keyUp:(NSEvent *)event { + NSPoint pos = [self convertPoint:event.locationInWindow fromView:nil]; + UniChar c = 0; + NSString *str = [event charactersIgnoringModifiers]; + if (str != nil && str.length == 1) { + c = [str characterAtIndex:0]; + } + _graph->handle_key(pos.x, pos.y, false, c, event.keyCode); +} + +- (void)mouseDown:(NSEvent *)event { + NSPoint pos = [self convertPoint:event.locationInWindow fromView:nil]; + _graph->handle_button_press(pos.x, pos.y, event.clickCount > 1, event.buttonNumber); +} + +- (void)mouseUp:(NSEvent *)event { + NSPoint pos = [self convertPoint:event.locationInWindow fromView:nil]; + _graph->handle_button_release(pos.x, pos.y); +} + +- (void)mouseDragged:(NSEvent *)event { + NSPoint pos = [self convertPoint:event.locationInWindow fromView:nil]; + _graph->handle_motion(pos.x, pos.y); +} + +- (void)mouseMoved:(NSEvent *)event { + NSPoint pos = [self convertPoint:event.locationInWindow fromView:nil]; + _graph->handle_motion(pos.x, pos.y); +} + +- (void)mouseExited:(NSEvent *)event { + _graph->handle_leave(); +} + +- (void)scrollWheel:(NSEvent *)event { + [super scrollWheel:event]; + if (event.deltaX != 0) { + NSPoint pos = [self convertPoint:event.locationInWindow fromView:nil]; + _graph->handle_wheel(pos.x, pos.y, event.deltaX, event.deltaY); + } +} + +- (void)magnifyWithEvent:(NSEvent *)event { + NSPoint pos = [self convertPoint:event.locationInWindow fromView:nil]; + _graph->handle_magnify(pos.x, pos.y, event.magnification); +} + +- (void)handleTimer:(NSTimer *)timer { + _graph->handle_timer(); +} + +- (void)viewDidChangeEffectiveAppearance { + if (_graph != nullptr) { + // Don't call this initially + if (self.window != nil) { + [NSAppearance setCurrentAppearance:self.effectiveAppearance]; + _graph->force_redraw(); + } + } +} + +- (void)drawRect:(NSRect)dirtyRect { + if (_graph != nullptr) { + CGContextRef ctx = [NSGraphicsContext currentContext].CGContext; + _graph->handle_draw_graph(ctx, dirtyRect); + } +} + +// Not called when building with macOS 14 SDK due to change in clipsToBounds +// (but there it simply calls drawRect with the overhang region) +#if __MAC_OS_X_VERSION_MAX_ALLOWED < 140000 +- (void)drawBackgroundOverhangInRect:(NSRect)dirtyRect { + if (_graph != nullptr) { + CGContextRef ctx = [NSGraphicsContext currentContext].CGContext; + _graph->handle_draw_graph_overhang(ctx, dirtyRect); + } +} +#endif + +- (NSMenu *)menuForEvent:(NSEvent *)event { + if (_graph != nullptr) { + NSPoint pos = [self convertPoint:event.locationInWindow fromView:nil]; + return _graph->get_graph_menu(pos.x, pos.y); + } + return nil; +} + +- (NSString *)view:(NSView *)view + stringForToolTip:(NSToolTipTag)tag + point:(NSPoint)point + userData:(void *)data { + + if (_graph != nullptr) { + std::string text = _graph->get_graph_tooltip(point.x, point.y); + return [NSString stringWithUTF8String:text.c_str()]; + } + return @""; +} + +@end diff --git a/pandatool/src/mac-stats/macStatsGraphViewController.h b/pandatool/src/mac-stats/macStatsGraphViewController.h new file mode 100644 index 0000000000..d688a656f3 --- /dev/null +++ b/pandatool/src/mac-stats/macStatsGraphViewController.h @@ -0,0 +1,42 @@ +/** + * 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 macStatsGraphViewController.h + * @author rdb + * @date 2023-08-28 + */ + +#ifndef MACSTATSGRAPHVIEWCONTROLLER_H +#define MACSTATSGRAPHVIEWCONTROLLER_H + +#include "macStatsGraphView.h" + +#import + +class MacStatsGraph; + +@interface MacStatsGraphViewController : NSViewController { + @protected + MacStatsGraph *_graph; +} + +- (id)initWithGraph:(MacStatsGraph *)graph; +- (MacStatsGraphView *)graphView; +- (BOOL)backToolbarItemVisible; +- (void)setBackToolbarItemVisible:(BOOL)show; + +@end + +@interface MacStatsScrollableGraphViewController : MacStatsGraphViewController + +- (MacStatsGraphView *)graphView; +- (NSClipView *)clipView; + +@end + +#endif diff --git a/pandatool/src/mac-stats/macStatsGraphViewController.mm b/pandatool/src/mac-stats/macStatsGraphViewController.mm new file mode 100644 index 0000000000..84f450f717 --- /dev/null +++ b/pandatool/src/mac-stats/macStatsGraphViewController.mm @@ -0,0 +1,224 @@ +/** + * 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 macStatsGraphViewController.mm + * @author rdb + * @date 2023-08-28 + */ + +#include "macStatsGraphViewController.h" +#include "macStatsGraph.h" +#include "macStatsMonitor.h" +#include "cocoa_compat.h" + +@implementation MacStatsGraphViewController + +- (id)initWithGraph:(MacStatsGraph *)graph { + if (self = [super init]) { + _graph = graph; + } + + return self; +} + +- (void)windowWillClose:(NSNotification *)notification { + MacStatsGraph *graph = _graph; + if (graph != nullptr) { + MacStatsMonitor *monitor = graph->get_monitor(); + if (monitor != nullptr) { + _graph = nullptr; + monitor->remove_graph(graph); + } + } +} + +- (void)loadView { + NSView *graph_view = [[MacStatsGraphView alloc] initWithGraph:_graph]; + NSView *background; + if (@available(macOS 10.14, *)) { + NSVisualEffectView *effect_view = [[NSVisualEffectView alloc] init]; + effect_view.material = (NSVisualEffectMaterial)18;//NSVisualEffectMaterialContentBackground; + background = effect_view; + } else { + background = [[NSView alloc] init]; + background.wantsLayer = YES; + background.layer.backgroundColor = [NSColor controlBackgroundColor].CGColor; + } + [background addSubview:graph_view]; + self.view = background; + + [graph_view.widthAnchor constraintEqualToAnchor:background.widthAnchor].active = YES; + [graph_view.heightAnchor constraintEqualToAnchor:background.heightAnchor].active = YES; + [graph_view release]; + [background release]; +} + +- (MacStatsGraphView *)graphView { + return (MacStatsGraphView *)self.view.subviews[0]; +} + +- (void)handleSplitViewResize:(NSNotification *)notification { + NSSplitView *split_view = (NSSplitView *)notification.object; + NSWindow *window = split_view.window; + NSToolbar *toolbar = window.toolbar; + if ([split_view isSubviewCollapsed:split_view.arrangedSubviews[0]]) { + if (toolbar.items[0].itemIdentifier != NSToolbarToggleSidebarItemIdentifier) { + [toolbar insertItemWithItemIdentifier:NSToolbarToggleSidebarItemIdentifier atIndex:0]; + } + } else { + if (toolbar.items[0].itemIdentifier == NSToolbarToggleSidebarItemIdentifier) { + [toolbar removeItemAtIndex:0]; + } + } +} + +- (BOOL)backToolbarItemVisible { + NSToolbar *toolbar = self.view.window.toolbar; + if ([toolbar.items[0].itemIdentifier isEqual:@"back"] || + [toolbar.items[1].itemIdentifier isEqual:@"back"]) { + return YES; + } else { + return NO; + } +} + +- (void)setBackToolbarItemVisible:(BOOL)show { + NSToolbar *toolbar = self.view.window.toolbar; + if ([toolbar.items[1].itemIdentifier isEqual:@"back"]) { + if (!show) { + [toolbar removeItemAtIndex:1]; + } + } + else if ([toolbar.items[0].itemIdentifier isEqual:@"back"]) { + if (!show) { + [toolbar removeItemAtIndex:0]; + } + } + else if (show) { + // Insert it after the sidebar toggle, if we have one. + int index = ([toolbar.items[0].itemIdentifier isEqual:NSToolbarToggleSidebarItemIdentifier]); + [toolbar insertItemWithItemIdentifier:@"back" atIndex:index]; + } +} + +- (NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar *)toolbar { + return @[]; +} + +- (NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar *)toolbar { + return @[]; +} + +- (NSToolbarItem *) toolbar:(NSToolbar *)toolbar + itemForItemIdentifier:(NSString *)ident + willBeInsertedIntoToolbar:(BOOL)flag { + + if (@available(macOS 11.0, *)) { + if ([ident isEqual:@"sep"]) { + return [NSTrackingSeparatorToolbarItem trackingSeparatorToolbarItemWithIdentifier:@"sep" splitView:_graph->get_split_view() dividerIndex:0]; + } + + if ([ident isEqual:@"back"]) { + NSToolbarItem *item = [[[NSToolbarItem alloc] initWithItemIdentifier:ident] autorelease]; + item.label = @"Back"; + item.image = [NSImage imageWithSystemSymbolName:@"chevron.left" accessibilityDescription:@""]; + item.target = self; + item.action = @selector(handleBack:); + [item setNavigational:YES]; + [item setBordered:YES]; + return item; + } + } + + return nil; +} + +- (void)handleSetAsFocus:(NSMenuItem *)item { + _graph->on_click_label(item.tag); +} + +- (void)handleChangeColor:(NSMenuItem *)item { + _graph->get_monitor()->choose_collector_color(item.tag); +} + +- (void)handleResetColor:(NSMenuItem *)item { + _graph->get_monitor()->reset_collector_color(item.tag); +} + +- (void)handleBack:(id)sender { + _graph->handle_back(); +} + +@end + +@implementation MacStatsScrollableGraphViewController + +- (void)loadView { + NSView *graph_view = [[MacStatsGraphView alloc] initWithGraph:_graph]; + NSScrollView *scroll = [[NSScrollView alloc] init]; + scroll.hasHorizontalScroller = NO; + scroll.hasVerticalScroller = YES; + scroll.horizontalScrollElasticity = NSScrollElasticityNone; + scroll.usesPredominantAxisScrolling = NO; + scroll.drawsBackground = YES; + scroll.scrollerStyle = NSScrollerStyleOverlay; + scroll.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable; + //scroll.translatesAutoresizingMaskIntoConstraints = NO; + scroll.automaticallyAdjustsContentInsets = YES; + scroll.documentView = graph_view; + self.view = scroll; + + [graph_view.widthAnchor constraintEqualToAnchor:scroll.widthAnchor].active = YES; + + if (@available(macOS 11.0, *)) { + [graph_view.heightAnchor constraintGreaterThanOrEqualToAnchor:((NSLayoutGuide *)[scroll safeAreaLayoutGuide]).heightAnchor].active = YES; + } else { + [graph_view.heightAnchor constraintGreaterThanOrEqualToAnchor:scroll.heightAnchor].active = YES; + } + + NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; + [center addObserver:self + selector:@selector(handleScroll:) + name:NSScrollViewDidLiveScrollNotification + object:scroll]; + [scroll release]; + [graph_view release]; +} + +- (MacStatsGraphView *)graphView { + return (MacStatsGraphView *)((NSScrollView *)self.view).documentView; +} + +- (NSClipView *)clipView { + return ((NSScrollView *)self.view).contentView; +} + +- (void)viewDidLayout { + if (_graph != nullptr) { + _graph->handle_scroll(); + } +} + +- (void)handleScroll:(NSNotification *)notification { + if (_graph != nullptr) { + _graph->handle_scroll(); + } +} + +- (void)handleSideScroll:(NSNotification *)notification { + // Graph view is flipped, side bar isn't, so we need to convert coordinates + NSScrollView *side_sv = ((NSScrollView *)notification.object); + NSScrollView *graph_sv = (NSScrollView *)self.view; + NSPoint point; + point.x = 0; + point.y = self.graphView.frame.size.height - (side_sv.documentVisibleRect.size.height + side_sv.documentVisibleRect.origin.y) - graph_sv.contentInsets.top; + [graph_sv.contentView scrollToPoint:point]; + [graph_sv reflectScrolledClipView:graph_sv.contentView]; +} + +@end diff --git a/pandatool/src/mac-stats/macStatsLabel.h b/pandatool/src/mac-stats/macStatsLabel.h new file mode 100644 index 0000000000..1171ba25a3 --- /dev/null +++ b/pandatool/src/mac-stats/macStatsLabel.h @@ -0,0 +1,58 @@ +/** + * 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 macStatsLabel.h + * @author rdb + * @date 2023-08-18 + */ + +#ifndef MACSTATSLABEL_H +#define MACSTATSLABEL_H + +#include "pandatoolbase.h" +#include "luse.h" + +#include "cocoa_compat.h" + +class MacStatsMonitor; +class MacStatsGraph; + +/** + * A text label that will draw in color appropriate for a particular + * collector. It also responds when the user double-clicks on it. This is + * handy for putting colored labels on strip charts. + */ +@interface MacStatsLabel : NSTextField { + @private + MacStatsGraph *_graph; + int _thread_index; + int _collector_index; + bool _highlight; + bool _mouse_within; + NSColor *_fg_color; + NSColor *_highlight_fg_color; + NSColor *_bg_color; + NSColor *_highlight_bg_color; +} + +- (id)initWithText:(NSString *)text + graph:(MacStatsGraph *)graph + threadIndex:(int)thread_index + collectorIndex:(int)collector_index; + +- (int)threadIndex; +- (int)collectorIndex; + +- (void)updateColor; + +- (BOOL)highlight; +- (void)setHighlight:(BOOL)highlight; + +@end + +#endif diff --git a/pandatool/src/mac-stats/macStatsLabel.mm b/pandatool/src/mac-stats/macStatsLabel.mm new file mode 100644 index 0000000000..3169c58f8d --- /dev/null +++ b/pandatool/src/mac-stats/macStatsLabel.mm @@ -0,0 +1,137 @@ +/** + * 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 macStatsLabel.mm + * @author rdb + * @date 2023-08-18 + */ + +#include "macStatsLabel.h" +#include "macStatsMonitor.h" +#include "macStatsGraph.h" + +@implementation MacStatsLabel + +- (id)initWithText:(NSString *)text + graph:(MacStatsGraph *)graph + threadIndex:(int)thread_index + collectorIndex:(int)collector_index { + if (self = [super init]) { + _graph = graph; + _thread_index = thread_index; + _collector_index = collector_index; + _bg_color = nil; + _highlight_bg_color = nil; + + [self setStringValue:text]; + self.bezeled = NO; + self.drawsBackground = YES; + self.selectable = NO; + self.editable = NO; + self.lineBreakMode = NSLineBreakByTruncatingTail; + //self.autoresizingMask = NSViewWidthSizable | NSViewMaxXMargin | NSViewMinXMargin; + //self.translatesAutoresizingMaskIntoConstraints = NO; + + NSTrackingArea *area = [[NSTrackingArea alloc] initWithRect:NSZeroRect options:(NSTrackingMouseEnteredAndExited | NSTrackingActiveInKeyWindow | NSTrackingInVisibleRect) owner:self userInfo:nil]; + [self addTrackingArea:area]; + [area release]; + + [self addToolTipRect:NSMakeRect(0, 0, 1000, 1000) owner:self userData:nil]; + + [self updateColor]; + } + + return self; +} + +- (void)dealloc { + [_bg_color release]; + [_highlight_bg_color release]; + [super dealloc]; +} + +- (NSSize)intrinsicContentSize { + // Allow resizing down. + NSSize size = [super intrinsicContentSize]; + return NSMakeSize(NSViewNoIntrinsicMetric, size.height); +} + +- (int)threadIndex { + return _thread_index; +} + +- (int)collectorIndex { + return _collector_index; +} + +- (void)updateColor { + if (_bg_color != nil) { + [_bg_color release]; + } + if (_highlight_bg_color != nil) { + [_highlight_bg_color release]; + } + + _bg_color = [NSColor colorWithCGColor:_graph->get_monitor()->get_collector_color(_collector_index, false)]; + _highlight_bg_color = [NSColor colorWithCGColor:_graph->get_monitor()->get_collector_color(_collector_index, true)]; + + [_bg_color retain]; + [_highlight_bg_color retain]; + + _fg_color = _graph->get_monitor()->get_collector_text_color(_collector_index, false); + _highlight_fg_color = _graph->get_monitor()->get_collector_text_color(_collector_index, true); + + [self setHighlight:_highlight]; +} + +- (BOOL)highlight { + return _highlight; +} + +- (void)setHighlight:(BOOL)highlight { + _highlight = highlight; + if (highlight || _mouse_within) { + self.backgroundColor = _highlight_bg_color; + self.textColor = _highlight_fg_color; + } else { + self.backgroundColor = _bg_color; + self.textColor = _fg_color; + } +} + +- (void)mouseEntered:(NSEvent *)event { + _mouse_within = true; + self.backgroundColor = _highlight_bg_color; + self.textColor = _highlight_fg_color; +} + +- (void)mouseExited:(NSEvent *)event { + _mouse_within = false; + [self setHighlight:_highlight]; +} + +- (void)mouseDown:(NSEvent *)event { + if (event.buttonNumber == 0 && event.clickCount == 2) { + _graph->on_click_label(_collector_index); + } +} + +- (NSMenu *)menuForEvent:(NSEvent *)event { + return _graph->get_label_menu(_collector_index); +} + +- (NSString *)view:(NSView *)view + stringForToolTip:(NSToolTipTag)tag + point:(NSPoint)point + userData:(void *)data { + + std::string text = _graph->get_label_tooltip(_collector_index); + return [NSString stringWithUTF8String:text.c_str()]; +} + +@end diff --git a/pandatool/src/mac-stats/macStatsLabelStack.h b/pandatool/src/mac-stats/macStatsLabelStack.h new file mode 100644 index 0000000000..9aabb3b2f2 --- /dev/null +++ b/pandatool/src/mac-stats/macStatsLabelStack.h @@ -0,0 +1,57 @@ +/** + * 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 macStatsLabelStack.h + * @author rdb + * @date 2023-08-17 + */ + +#ifndef MACSTATSLABELSTACK_H +#define MACSTATSLABELSTACK_H + +#include "pandatoolbase.h" +#include "pvector.h" +#include "macStatsLabel.h" + +#include + +class MacStatsMonitor; +class MacStatsGraph; + +/** + * A widget that contains a stack of labels from bottom to top. + */ +class MacStatsLabelStack { +public: + MacStatsLabelStack(); + ~MacStatsLabelStack(); + + NSView *get_view() const; + + int get_label_y(int label_index, NSView *target_view) const; + int get_label_height(int label_index) const; + int get_label_collector_index(int label_index) const; + + void clear_labels(); + int add_label(MacStatsMonitor *monitor, MacStatsGraph *graph, + int thread_index, int collector_index, bool use_fullname); + int get_num_labels() const; + + void highlight_label(int collector_index); + void update_label_color(int collector_index); + +private: + NSStackView *_stack_view; + NSLayoutConstraint *_constraint; + int _highlight_label; + + typedef pvector Labels; + Labels _labels; +}; + +#endif diff --git a/pandatool/src/mac-stats/macStatsLabelStack.mm b/pandatool/src/mac-stats/macStatsLabelStack.mm new file mode 100644 index 0000000000..6bfa9c3fb3 --- /dev/null +++ b/pandatool/src/mac-stats/macStatsLabelStack.mm @@ -0,0 +1,174 @@ +/** + * 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 macStatsLabelStack.mm + * @author rdb + * @date 2023-08-17 + */ + +#include "macStatsLabelStack.h" +#include "macStatsLabel.h" +#include "macStatsMonitor.h" + +static const NSEdgeInsets insets = {8, 8, 8, 8}; + +/** + * + */ +MacStatsLabelStack:: +MacStatsLabelStack() { + _stack_view = [[NSStackView alloc] init]; + _stack_view.edgeInsets = insets; + _stack_view.orientation = NSUserInterfaceLayoutOrientationVertical; + _stack_view.alignment = NSLayoutAttributeRight;//NSLayoutAttributeCenterX; + _stack_view.distribution = NSStackViewDistributionGravityAreas; + _stack_view.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable; + _stack_view.translatesAutoresizingMaskIntoConstraints = NO; + _stack_view.spacing = 0; + _highlight_label = -1; + + // May never be wider than the widest label, or 68, whichever is larger + //FIXME + _constraint = [_stack_view.widthAnchor constraintLessThanOrEqualToConstant:68]; + _constraint.active = NO; + [_constraint retain]; +} + +/** + * + */ +MacStatsLabelStack:: +~MacStatsLabelStack() { + clear_labels(); + [_constraint release]; + [_stack_view release]; +} + +/** + * Returns the view for this stack. + */ +NSView *MacStatsLabelStack:: +get_view() const { + return _stack_view; +} + +/** + * Returns the y position of the indicated label's bottom edge, relative to + * the indicated target widget. + */ +int MacStatsLabelStack:: +get_label_y(int label_index, NSView *target_view) const { + nassertr(label_index >= 0 && label_index < (int)_labels.size(), 0); + + MacStatsLabel *label = _labels[label_index]; + NSPoint pos = [target_view convertPoint:NSMakePoint(0, label.frame.size.height) fromView:label]; + return pos.y; +} + +/** + * Returns the height of the indicated label. + */ +int MacStatsLabelStack:: +get_label_height(int label_index) const { + nassertr(label_index >= 0 && label_index < (int)_labels.size(), 0); + return _labels[label_index].frame.size.height; +} + +/** + * Returns the collector index associated with the indicated label. + */ +int MacStatsLabelStack:: +get_label_collector_index(int label_index) const { + nassertr(label_index >= 0 && label_index < (int)_labels.size(), -1); + return _labels[label_index].collectorIndex; +} + +/** + * Removes the set of labels and starts a new set. + */ +void MacStatsLabelStack:: +clear_labels() { + for (MacStatsLabel *label : _labels) { + [_stack_view removeView:label]; + [label release]; + } + _labels.clear(); + + _constraint.constant = 68; + + NSRect frame = _stack_view.frame; + frame.size.width = 0; + _stack_view.frame = frame; +} + +/** + * Adds a new label to the top of the stack; returns the new label index. + */ +int MacStatsLabelStack:: +add_label(MacStatsMonitor *monitor, MacStatsGraph *graph, + int thread_index, int collector_index, bool use_fullname) { + const PStatClientData *client_data = monitor->get_client_data(); + std::string text; + if (use_fullname) { + text = client_data->get_collector_fullname(collector_index); + } else { + text = client_data->get_collector_name(collector_index); + } + + MacStatsLabel *label = [MacStatsLabel alloc]; + [label initWithText:[NSString stringWithUTF8String:text.c_str()] + graph:graph + threadIndex:thread_index + collectorIndex:collector_index]; + + [_stack_view insertView:label atIndex:0 inGravity:NSStackViewGravityBottom]; + [label.leadingAnchor constraintEqualToAnchor:_stack_view.leadingAnchor constant:8].active = YES; + [label.trailingAnchor constraintLessThanOrEqualToAnchor:_stack_view.trailingAnchor constant:-8].active = YES; + + _constraint.constant = std::max(_constraint.constant, label.intrinsicContentSize.width); + + int label_index = (int)_labels.size(); + _labels.push_back(label); + + return label_index; +} + +/** + * Returns the number of labels in the stack. + */ +int MacStatsLabelStack:: +get_num_labels() const { + return _labels.size(); +} + +/** + * Draws a highlight around the label representing the indicated collector, + * and removes the highlight from any other label. Specify -1 to remove the + * highlight from all labels. + */ +void MacStatsLabelStack:: +highlight_label(int collector_index) { + if (_highlight_label != collector_index) { + _highlight_label = collector_index; + for (MacStatsLabel *label : _labels) { + label.highlight = (label.collectorIndex == _highlight_label); + } + } +} + +/** + * Refreshes the color of the label with the given index. + */ +void MacStatsLabelStack:: +update_label_color(int collector_index) { + for (MacStatsLabel *label : _labels) { + if (label.collectorIndex == collector_index) { + [label updateColor]; + } + } +} diff --git a/pandatool/src/mac-stats/macStatsMonitor.h b/pandatool/src/mac-stats/macStatsMonitor.h new file mode 100644 index 0000000000..8e12677963 --- /dev/null +++ b/pandatool/src/mac-stats/macStatsMonitor.h @@ -0,0 +1,117 @@ +/** + * 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 macStatsMonitor.h + * @author rdb + * @date 2023-08-17 + */ + +#ifndef MACSTATSMONITOR_H +#define MACSTATSMONITOR_H + +#include "pandatoolbase.h" + +#include "pStatMonitor.h" +#include "pointerTo.h" +#include "pset.h" +#include "pvector.h" +#include "pmap.h" + +#import + +class MacStatsGraph; +class MacStatsServer; +class MacStatsChartMenu; + +/** + * This class represents a connection to a PStatsClient and manages the data + * exchange with the client. + */ +class MacStatsMonitor : public PStatMonitor { +public: + MacStatsMonitor(MacStatsServer *server); + virtual ~MacStatsMonitor(); + + void close(); + + virtual std::string get_monitor_name(); + + virtual void initialized(); + virtual void got_hello(); + virtual void got_bad_version(int client_major, int client_minor, + int server_major, int server_minor); + virtual void new_collector(int collector_index); + virtual void new_thread(int thread_index); + virtual void new_data(int thread_index, int frame_number); + virtual void remove_thread(int thread_index); + virtual void lost_connection(); + virtual void idle(); + virtual bool has_idle(); + + virtual void user_guide_bars_changed(); + + PStatGraph *open_timeline(); + PStatGraph *open_strip_chart(int thread_index, int collector_index, bool show_level); + PStatGraph *open_flame_graph(int thread_index, int collector_index = -1); + PStatGraph *open_piano_roll(int thread_index); + + CGColorRef get_collector_color(int collector_index, bool highlight = false); + NSColor *get_collector_text_color(int collector_index, bool highlight = false); + + void choose_collector_color(int collector_index); + void handle_choose_collector_color(const LRGBColor &color); + void reset_collector_color(int collector_index); + + void set_show_status_item(bool show); + void set_time_units(int unit_mask); + void set_scroll_speed(double scroll_speed); + void set_pause(bool pause); + + void add_graph(MacStatsGraph *graph); + void remove_graph(MacStatsGraph *graph); + void close_all_graphs(); + +private: + void setup_speed_menu(); + void update_status_bar(); + +private: + typedef pset Graphs; + Graphs _graphs; + + typedef pvector ChartMenus; + ChartMenus _chart_menus; + + NSUserNotification *_notification = nullptr; + NSMenu *_main_menu; + NSMenuItem *_speed_menu_item = nullptr; + NSMenuItem *_speed_menu_item_1; + NSMenuItem *_speed_menu_item_2; + NSMenuItem *_speed_menu_item_3; + NSMenuItem *_speed_menu_item_6; + NSMenuItem *_speed_menu_item_12; + NSMenuItem *_speed_menu_item_pause; + int _next_chart_index; + NSStatusItem *_frame_rate_status_item = nullptr; + double _scroll_speed; + bool _pause; + bool _have_data = false; + int _choosing_color_collector_index; + + struct ColorSet { + CGColorRef _bg[2]; + NSColor *_fg[2]; + }; + typedef pmap Colors; + Colors _colors; + + friend class MacStatsGraph; + friend class MacStatsServer; +}; + +#endif diff --git a/pandatool/src/mac-stats/macStatsMonitor.mm b/pandatool/src/mac-stats/macStatsMonitor.mm new file mode 100644 index 0000000000..b64ae21382 --- /dev/null +++ b/pandatool/src/mac-stats/macStatsMonitor.mm @@ -0,0 +1,650 @@ +/** + * 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 macStatsMonitor.mm + * @author rdb + * @date 2023-08-17 + */ + +#include "macStatsMonitor.h" +#include "macStats.h" +#include "macStatsServer.h" +#include "macStatsStripChart.h" +#include "macStatsChartMenu.h" +#include "macStatsPianoRoll.h" +#include "macStatsFlameGraph.h" +#include "macStatsTimeline.h" +#include "pStatGraph.h" +#include "pStatCollectorDef.h" + +#include "convert_srgb.h" + +/** + * + */ +MacStatsMonitor:: +MacStatsMonitor(MacStatsServer *server) : PStatMonitor(server) { + _main_menu = NSApp.mainMenu; + + // These will be filled in later when the menu is created. + _scroll_speed = 0.0; + _pause = false; + _next_chart_index = 2; + + setup_speed_menu(); + + if ([[NSUserDefaults standardUserDefaults] boolForKey:@"ShowStatusItem"]) { + set_show_status_item(true); + } +} + +/** + * + */ +MacStatsMonitor:: +~MacStatsMonitor() { + close(); +} + +/** + * Closes all the graphs associated with this monitor. + */ +void MacStatsMonitor:: +close() { + PStatMonitor::close(); + + if (_notification != nil) { + NSUserNotificationCenter *center = [NSUserNotificationCenter defaultUserNotificationCenter]; + [center removeDeliveredNotification:_notification]; + [_notification release]; + _notification = nil; + } + + close_all_graphs(); + + if (_speed_menu_item != nullptr) { + [_main_menu removeItem:_speed_menu_item]; + [_speed_menu_item release]; + _speed_menu_item = nullptr; + } + + for (MacStatsChartMenu *chart_menu : _chart_menus) { + chart_menu->remove_from_menu(_main_menu); + delete chart_menu; + } + _chart_menus.clear(); + + set_show_status_item(false); + + for (auto &item : _colors) { + CGColorRelease(item.second._bg[0]); + CGColorRelease(item.second._bg[1]); + } + _colors.clear(); + + _next_chart_index = 2; +} + +/** + * Should be redefined to return a descriptive name for the type of + * PStatsMonitor this is. + */ +std::string MacStatsMonitor:: +get_monitor_name() { + return "MacStats"; +} + +/** + * Called after the monitor has been fully set up. At this time, it will have + * a valid _client_data pointer, and things like is_alive() and close() will + * be meaningful. However, we may not yet know who we're connected to + * (is_client_known() may return false), and we may not know anything about + * the threads or collectors we're about to get data on. + */ +void MacStatsMonitor:: +initialized() { +} + +/** + * Called when the "hello" message has been received from the client. At this + * time, the client's hostname and program name will be known. + */ +void MacStatsMonitor:: +got_hello() { + std::string progname = get_client_progname(); + std::string hostname = get_client_hostname(); + + NSUserNotificationCenter *center = [NSUserNotificationCenter defaultUserNotificationCenter]; + _notification = [[NSUserNotification alloc] init]; + _notification.title = @"PStats Server"; + _notification.informativeText = [NSString + stringWithFormat:@"Connected to %s on %s", progname.c_str(), hostname.c_str()]; + + [center deliverNotification:_notification]; +} + +/** + * Like got_hello(), this is called when the "hello" message has been received + * from the client. At this time, the client's hostname and program name will + * be known. However, the client appears to be an incompatible version and + * the connection will be terminated; the monitor should issue a message to + * that effect. + */ +void MacStatsMonitor:: +got_bad_version(int client_major, int client_minor, + int server_major, int server_minor) { + std::ostringstream str; + str << "Unable to honor connection attempt from " + << get_client_progname() << " on " << get_client_hostname() + << ": unsupported PStats version " + << client_major << "." << client_minor; + + if (server_minor == 0) { + str << " (server understands version " << server_major + << "." << server_minor << " only)."; + } else { + str << " (server understands versions " << server_major + << ".0 through " << server_major << "." << server_minor << ")."; + } + + std::string message = str.str(); + + NSAlert *alert = [[NSAlert alloc] init]; + alert.messageText = @"PStats Error"; + alert.informativeText = [NSString stringWithUTF8String:message.c_str()]; + alert.alertStyle = NSCriticalAlertStyle; + [alert runModal]; + [alert release]; +} + +/** + * Called whenever a new Collector definition is received from the client. + * Generally, the client will send all of its collectors over shortly after + * connecting, but there's no guarantee that they will all be received before + * the first frames are received. The monitor should be prepared to accept + * new Collector definitions midstream. + */ +void MacStatsMonitor:: +new_collector(int collector_index) { + for (MacStatsGraph *graph : _graphs) { + graph->new_collector(collector_index); + } + + // We might need to update our menus. + for (MacStatsChartMenu *chart_menu : _chart_menus) { + chart_menu->check_update(); + } +} + +/** + * Called whenever a new Thread definition is received from the client. + * Generally, the client will send all of its threads over shortly after + * connecting, but there's no guarantee that they will all be received before + * the first frames are received. The monitor should be prepared to accept + * new Thread definitions midstream. + */ +void MacStatsMonitor:: +new_thread(int thread_index) { + MacStatsChartMenu *chart_menu = new MacStatsChartMenu(this, thread_index); + chart_menu->add_to_menu(_main_menu, _next_chart_index); + ++_next_chart_index; + _chart_menus.push_back(chart_menu); +} + +/** + * Called as each frame's data is made available. There is no guarantee the + * frames will arrive in order, or that all of them will arrive at all. The + * monitor should be prepared to accept frames received out-of-order or + * missing. + */ +void MacStatsMonitor:: +new_data(int thread_index, int frame_number) { + for (MacStatsGraph *graph : _graphs) { + graph->new_data(thread_index, frame_number); + } + + if (!_have_data) { + open_default_graphs(); + _have_data = true; + } +} + +/** + * Called when a thread should be removed from the list of threads. + */ +void MacStatsMonitor:: +remove_thread(int thread_index) { + for (ChartMenus::iterator it = _chart_menus.begin(); it != _chart_menus.end(); ++it) { + MacStatsChartMenu *chart_menu = *it; + if (chart_menu->get_thread_index() == thread_index) { + chart_menu->remove_from_menu(_main_menu); + delete chart_menu; + _chart_menus.erase(it); + --_next_chart_index; + return; + } + } +} + +/** + * Called whenever the connection to the client has been lost. This is a + * permanent state change. The monitor should update its display to represent + * this, and may choose to close down automatically. + */ +void MacStatsMonitor:: +lost_connection() { + NSUserNotificationCenter *center = [NSUserNotificationCenter defaultUserNotificationCenter]; + + if (_notification != nil) { + [center removeDeliveredNotification:_notification]; + [_notification release]; + } + + std::string hostname = get_client_hostname(); + + _notification = [[NSUserNotification alloc] init]; + _notification.title = @"PStats Server"; + _notification.informativeText = [NSString + stringWithFormat:@"Lost connection to %s", hostname.c_str()]; + + _notification.additionalActions = @[ + [NSUserNotificationAction actionWithIdentifier:@"new" title:@"New Session"], + [NSUserNotificationAction actionWithIdentifier:@"quit" title:@"Quit PStats"] + ]; + + [center deliverNotification:_notification]; +} + +/** + * If has_idle() returns true, this will be called periodically to allow the + * monitor to update its display or whatever it needs to do. + */ +void MacStatsMonitor:: +idle() { + // Check if any of our chart menus need updating. + for (MacStatsChartMenu *chart_menu : _chart_menus) { + chart_menu->check_update(); + } + + // Update the frame rate label from the main thread (thread 0). + if (_frame_rate_status_item != nil) { + const PStatThreadData *thread_data = get_client_data()->get_thread_data(0); + double frame_rate = thread_data->get_frame_rate(); + if (frame_rate != 0.0f) { + _frame_rate_status_item.button.title = + [NSString stringWithFormat:@"%0.1f ms / %0.1f Hz", 1000.0f / frame_rate, frame_rate]; + } + } +} + +/** + * Should be redefined to return true if you want to redefine idle() and + * expect it to be called. + */ +bool MacStatsMonitor:: +has_idle() { + return true; +} + +/** + * Called when the user guide bars have been changed. + */ +void MacStatsMonitor:: +user_guide_bars_changed() { + for (MacStatsGraph *graph : _graphs) { + graph->user_guide_bars_changed(); + } +} + +/** + * Opens a new timeline. + */ +PStatGraph *MacStatsMonitor:: +open_timeline() { + MacStatsTimeline *graph = new MacStatsTimeline(this); + add_graph(graph); + return graph; +} + +/** + * Opens a new flame graph showing the indicated data. + */ +PStatGraph *MacStatsMonitor:: +open_flame_graph(int thread_index, int collector_index) { + MacStatsFlameGraph *graph = + new MacStatsFlameGraph(this, thread_index, collector_index); + add_graph(graph); + return graph; +} + +/** + * Opens a new strip chart showing the indicated data. + */ +PStatGraph *MacStatsMonitor:: +open_strip_chart(int thread_index, int collector_index, bool show_level) { + MacStatsStripChart *graph = + new MacStatsStripChart(this, thread_index, collector_index, show_level); + add_graph(graph); + return graph; +} + +/** + * Opens a new piano roll showing the indicated data. + */ +PStatGraph *MacStatsMonitor:: +open_piano_roll(int thread_index) { + MacStatsPianoRoll *graph = new MacStatsPianoRoll(this, thread_index); + add_graph(graph); + return graph; +} + +/** + * Returns a color suitable for drawing the indicated collector. + */ +CGColorRef MacStatsMonitor:: +get_collector_color(int collector_index, bool highlight) { + Colors::iterator bi; + bi = _colors.find(collector_index); + if (bi != _colors.end()) { + return (*bi).second._bg[highlight]; + } + + LRGBColor rgb = PStatMonitor::get_collector_color(collector_index); + rgb[0] = encode_sRGB_float(rgb[0]); + rgb[1] = encode_sRGB_float(rgb[1]); + rgb[2] = encode_sRGB_float(rgb[2]); + + PN_stdfloat bright = rgb.dot(LRGBColor(0.2126, 0.7152, 0.0722)); + CGColorRef color = CGColorCreateGenericRGB(rgb[0], rgb[1], rgb[2], 1.0); + + rgb *= 0.75; + CGColorRef hcolor = CGColorCreateGenericRGB(rgb[0], rgb[1], rgb[2], 1.0); + + ColorSet &set = _colors[collector_index]; + set._bg[0] = color; + set._bg[1] = hcolor; + + if (bright >= 0.5) { + set._fg[0] = [NSColor blackColor]; + } else { + set._fg[0] = [NSColor whiteColor]; + } + + if (bright * 0.75 >= 0.5) { + set._fg[1] = [NSColor blackColor]; + } else { + set._fg[1] = [NSColor whiteColor]; + } + + return highlight ? hcolor : color; +} + +/** + * Returns a color suitable for drawing text on the indicated collector. + */ +NSColor *MacStatsMonitor:: +get_collector_text_color(int collector_index, bool highlight) { + get_collector_color(collector_index, false); + return _colors[collector_index]._fg[highlight]; +} + +/** + * Opens a dialog to change the given collector color. + */ +void MacStatsMonitor:: +choose_collector_color(int collector_index) { + _choosing_color_collector_index = collector_index; + + const LRGBColor &rgb = PStatMonitor::get_collector_color(collector_index); + NSColor *color = [NSColor colorWithSRGBRed:rgb[0] green:rgb[1] blue:rgb[2] alpha:1.0]; + + NSColorPanel *panel = [NSColorPanel sharedColorPanel]; + panel.target = [NSApp delegate]; + panel.action = @selector(handleChooseCollectorColor:); + panel.showsAlpha = NO; + panel.color = color; + [NSApp orderFrontColorPanel:panel]; +} + +/** + * Sets a custom color associated with the given collector. + */ +void MacStatsMonitor:: +handle_choose_collector_color(const LRGBColor &color) { + int collector_index = _choosing_color_collector_index; + + PStatMonitor::set_collector_color(collector_index, color); + + if (_colors.erase(collector_index)) { + for (MacStatsGraph *graph : _graphs) { + graph->reset_collector_color(collector_index); + } + } +} + +/** + * Resets the color of the given collector to the default. + */ +void MacStatsMonitor:: +reset_collector_color(int collector_index) { + PStatMonitor::clear_collector_color(collector_index); + + if (_colors.erase(collector_index)) { + for (MacStatsGraph *graph : _graphs) { + graph->reset_collector_color(collector_index); + } + } +} + +/** + * Enables the frame rate label on the right end of the menu bar. This is + * used as a text label to display the main thread's frame rate to the user, + * although it is implemented as a right-justified toplevel menu item that + * doesn't open to anything. + */ +void MacStatsMonitor:: +set_show_status_item(bool show) { + if (show && _frame_rate_status_item == nil) { + _frame_rate_status_item = [[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength]; + _frame_rate_status_item.button.action = @selector(handleClickStatusItem:); + [_frame_rate_status_item retain]; + + const PStatClientData *client_data = get_client_data(); + if (client_data != nullptr) { + const PStatThreadData *thread_data = client_data->get_thread_data(0); + if (thread_data != nullptr) { + double frame_rate = thread_data->get_frame_rate(); + if (frame_rate != 0.0f) { + _frame_rate_status_item.button.title = + [NSString stringWithFormat:@"%0.1f ms / %0.1f Hz", 1000.0f / frame_rate, frame_rate]; + } + } + } + } + if (!show && _frame_rate_status_item != nil) { + // Careful: for some reason, this can get called recursively. + NSStatusItem *status_item = _frame_rate_status_item; + _frame_rate_status_item = nil; + [[NSStatusBar systemStatusBar] removeStatusItem:status_item]; + [status_item release]; + status_item = nil; + } +} + +/** + * Called when the user selects a new time units from the monitor pulldown + * menu, this should adjust the units for all graphs to the indicated mask if + * it is a time-based graph. + */ +void MacStatsMonitor:: +set_time_units(int unit_mask) { + for (MacStatsGraph *graph : _graphs) { + graph->set_time_units(unit_mask); + } +} + +/** + * Called when the user selects a new scroll speed from the monitor pulldown + * menu, this should adjust the speeds for all graphs to the indicated value. + */ +void MacStatsMonitor:: +set_scroll_speed(double scroll_speed) { + _scroll_speed = scroll_speed; + + // First, change all of the open graphs appropriately. + for (MacStatsGraph *graph : _graphs) { + graph->set_scroll_speed(_scroll_speed); + } + + // Then, change the state of the menu items. + _speed_menu_item_1.state = (scroll_speed == 1.0); + _speed_menu_item_2.state = (scroll_speed == 2.0); + _speed_menu_item_3.state = (scroll_speed == 3.0); + _speed_menu_item_6.state = (scroll_speed == 6.0); + _speed_menu_item_12.state = (scroll_speed == 12.0); +} + +/** + * Called when the user selects a pause on or pause off option from the menu. + */ +void MacStatsMonitor:: +set_pause(bool pause) { + _pause = pause; + + // First, change all of the open graphs appropriately. + for (MacStatsGraph *graph : _graphs) { + graph->set_pause(_pause); + } + + // Then, change the state of the menu item. + _speed_menu_item_pause.state = pause; +} + +/** + * Adds the newly-created graph to the list of managed graphs. + */ +void MacStatsMonitor:: +add_graph(MacStatsGraph *graph) { + _graphs.insert(graph); + + int units = [[NSUserDefaults standardUserDefaults] integerForKey:@"TimeUnits"]; + graph->set_time_units(units); + graph->set_scroll_speed(_scroll_speed); + graph->set_pause(_pause); +} + +/** + * Deletes the indicated graph. + */ +void MacStatsMonitor:: +remove_graph(MacStatsGraph *graph) { + Graphs::iterator gi = _graphs.find(graph); + if (gi != _graphs.end()) { + _graphs.erase(gi); + delete graph; + } +} + +/** + * Asks all open graphs to close. + */ +void MacStatsMonitor:: +close_all_graphs() { + while (!_graphs.empty()) { + (*_graphs.begin())->close(); + } +} + +/** + * Creates the "Speed" pulldown menu. + */ +void MacStatsMonitor:: +setup_speed_menu() { + NSMenu *menu = [[NSMenu alloc] init]; + menu.title = @"Speed"; + menu.autoenablesItems = NO; + + { + NSMenuItem *item = [[NSMenuItem alloc] init]; + item.action = @selector(handleSpeed:); + item.title = @"1"; + item.tag = 1; + [menu addItem:item]; + [item release]; + + _speed_menu_item_1 = item; + } + + { + NSMenuItem *item = [[NSMenuItem alloc] init]; + item.action = @selector(handleSpeed:); + item.title = @"2"; + item.tag = 2; + [menu addItem:item]; + [item release]; + + _speed_menu_item_2 = item; + } + + { + NSMenuItem *item = [[NSMenuItem alloc] init]; + item.action = @selector(handleSpeed:); + item.title = @"3"; + item.tag = 3; + item.state = NSOnState; + [menu addItem:item]; + [item release]; + + _speed_menu_item_3 = item; + } + + { + NSMenuItem *item = [[NSMenuItem alloc] init]; + item.action = @selector(handleSpeed:); + item.title = @"6"; + item.tag = 6; + [menu addItem:item]; + [item release]; + + _speed_menu_item_6 = item; + } + + { + NSMenuItem *item = [[NSMenuItem alloc] init]; + item.action = @selector(handleSpeed:); + item.title = @"12"; + item.tag = 12; + [menu addItem:item]; + [item release]; + + _speed_menu_item_12 = item; + } + + [menu addItem:[NSMenuItem separatorItem]]; + + { + NSMenuItem *item = [[NSMenuItem alloc] init]; + item.action = @selector(handlePause:); + item.title = @"pause"; + [menu addItem:item]; + [item release]; + + _speed_menu_item_pause = item; + } + + NSMenuItem *item = [[NSMenuItem alloc] init]; + _speed_menu_item = item; + [_main_menu addItem:item]; + [_main_menu setSubmenu:menu forItem:item]; + [menu release]; + + set_scroll_speed(3); + set_pause(false); + + ++_next_chart_index; +} diff --git a/pandatool/src/mac-stats/macStatsPianoRoll.h b/pandatool/src/mac-stats/macStatsPianoRoll.h new file mode 100644 index 0000000000..df156619f0 --- /dev/null +++ b/pandatool/src/mac-stats/macStatsPianoRoll.h @@ -0,0 +1,84 @@ +/** + * 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 macStatsPianoRoll.h + * @author rdb + * @date 2023-08-19 + */ + +#ifndef MACSTATSPIANOROLL_H +#define MACSTATSPIANOROLL_H + +#include "macStatsGraph.h" +#include "pStatPianoRoll.h" +#include "macStatsChartMenuDelegate.h" + +class MacStatsMonitor; + +/** + * A window that draws a piano-roll style chart, which shows the collectors + * explicitly stopping and starting, one frame at a time. + */ +class MacStatsPianoRoll final : public PStatPianoRoll, public MacStatsGraph { +public: + MacStatsPianoRoll(MacStatsMonitor *monitor, int thread_index); + virtual ~MacStatsPianoRoll(); + + virtual void new_data(int thread_index, int frame_number); + virtual void force_redraw(); + virtual void changed_graph_size(int graph_xsize, int graph_ysize); + + virtual void set_time_units(int unit_mask); + virtual void on_click_label(int collector_index); + virtual NSMenu *get_label_menu(int collector_index) const; + virtual std::string get_label_tooltip(int collector_index) const; + void set_horizontal_scale(double time_width); + +protected: + void clear_region(); + virtual void begin_draw(); + virtual void begin_row(int row); + virtual void draw_bar(int row, int from_x, int to_x); + virtual void end_draw(); + virtual void idle(); + + virtual bool get_window_state(int &x, int &y, int &width, int &height, + bool &maximized, bool &minimized) const; + virtual void set_window_state(int x, int y, int width, int height, + bool maximized, bool minimized); + + virtual NSMenu *get_graph_menu(int mouse_x, int mouse_y) const; + virtual std::string get_graph_tooltip(int mouse_x, int mouse_y) const; + virtual DragMode consider_drag_start(int graph_x, int graph_y); + + virtual void handle_button_press(int graph_x, int graph_y, + bool double_click, int button); + virtual void handle_button_release(int graph_x, int graph_y); + virtual void handle_motion(int graph_x, int graph_y); + virtual void handle_leave(); + virtual void handle_scroll(); + virtual void handle_magnify(int graph_x, int graph_y, double scale); + virtual void handle_draw_graph(CGContextRef ctx, NSRect rect); + virtual void handle_draw_graph_overhang(CGContextRef ctx, NSRect rect); + virtual void handle_draw_scale_area(CGContextRef ctx, NSRect rect); + +private: + int get_collector_under_pixel(int xpoint, int ypoint) const; + void update_labels(); + void draw_guide_bars(CGContextRef ctx, int y, int height); + void draw_guide_bar(CGContextRef ctx, const PStatGraph::GuideBar &bar, + int y, int height); + void draw_guide_labels(CGContextRef ctx); + void draw_guide_label(CGContextRef ctx, const PStatGraph::GuideBar &bar); + +private: + MacStatsChartMenuDelegate *_menu_delegate; + NSScrollView *_sidebar_scroll_view; +}; + +#endif diff --git a/pandatool/src/mac-stats/macStatsPianoRoll.mm b/pandatool/src/mac-stats/macStatsPianoRoll.mm new file mode 100644 index 0000000000..fe620b7f56 --- /dev/null +++ b/pandatool/src/mac-stats/macStatsPianoRoll.mm @@ -0,0 +1,764 @@ +/** + * 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 macStatsPianoRoll.mm + * @author rdb + * @date 2023-08-19 + */ + +#include "macStatsPianoRoll.h" +#include "macStatsMonitor.h" +#include "macStatsLabelStack.h" +#include "macStatsScaleArea.h" + +static const int default_piano_roll_width = 800; +static const int default_piano_roll_height = 400; + +static const int minimum_piano_roll_sidebar_width = 68; +static const int default_piano_roll_sidebar_width = 200; + +/** + * + */ +MacStatsPianoRoll:: +MacStatsPianoRoll(MacStatsMonitor *monitor, int thread_index) : + PStatPianoRoll(monitor, thread_index, 0, 0), + MacStatsGraph(monitor, [MacStatsScrollableGraphViewController alloc]) +{ + // Used for popup menus. + _menu_delegate = [[MacStatsChartMenuDelegate alloc] initWithMonitor:monitor threadIndex:thread_index]; + + // Let's show the units on the guide bar labels. There's room. + set_guide_bar_units(get_guide_bar_units() | GBU_show_units); + + const PStatClientData *client_data = + MacStatsGraph::_monitor->get_client_data(); + std::string thread_name = client_data->get_thread_name(_thread_index); + std::string window_title = thread_name + " thread piano roll"; + _window.title = [NSString stringWithUTF8String:window_title.c_str()]; + + if (@available(macOS 11.0, *)) { + _window.titleVisibility = NSWindowTitleHidden; + } + + // Set the initial size of the graph. + _graph_view.frame = NSMakeRect(0, 0, default_piano_roll_width, default_piano_roll_height); + _graph_view_controller.view.frame = NSMakeRect(0, 0, default_piano_roll_width, default_piano_roll_height); + + // It's put inside a scroll view that tracks the main scroll view. + NSScrollView *scroll_view = [[NSScrollView alloc] initWithFrame:NSMakeRect(0, 0, default_piano_roll_sidebar_width, 0)]; + scroll_view.documentView = _label_stack.get_view(); + scroll_view.drawsBackground = NO; + scroll_view.automaticallyAdjustsContentInsets = YES; + //scroll_view.translatesAutoresizingMaskIntoConstraints = NO; + scroll_view.hasHorizontalScroller = NO; + scroll_view.hasVerticalScroller = NO; + _sidebar_scroll_view = scroll_view; + + NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; + [center addObserver:_graph_view_controller + selector:@selector(handleSideScroll:) + name:NSScrollViewDidLiveScrollNotification + object:scroll_view]; + + NSViewController *sidebar_controller = [[NSViewController alloc] init]; + sidebar_controller.view = scroll_view; + + NSSplitViewController *svc = [[NSSplitViewController alloc] init]; + [svc addSplitViewItem:[NSSplitViewItem sidebarWithViewController:sidebar_controller]]; + [svc addSplitViewItem:[NSSplitViewItem splitViewItemWithViewController:_graph_view_controller]]; + + svc.splitViewItems[0].minimumThickness = minimum_piano_roll_sidebar_width; + svc.splitViewItems[0].canCollapse = NO; + + NSSplitView *split_view = svc.splitView; + split_view.vertical = YES; + split_view.dividerStyle = NSSplitViewDividerStyleThin; + split_view.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable; + _split_view = split_view; + + _window.contentViewController = svc; + + [svc release]; + [sidebar_controller release]; + + // Scale area goes on top, as a titlebar accessory view. + MacStatsScaleAreaController *scale_area_controller = [[MacStatsScaleAreaController alloc] initWithGraph:this]; + scale_area_controller.fullScreenMinHeight = 20; + scale_area_controller.layoutAttribute = NSLayoutAttributeRight; + _scale_area = scale_area_controller.view; + [_window addTitlebarAccessoryViewController:scale_area_controller]; + [scale_area_controller release]; + + [_label_stack.get_view().widthAnchor constraintEqualToAnchor:scroll_view.widthAnchor].active = YES; + [_label_stack.get_view().heightAnchor constraintEqualToAnchor:_graph_view.heightAnchor].active = YES; + + idle(); + + [_window makeKeyAndOrderFront:nil]; +} + +/** + * + */ +MacStatsPianoRoll:: +~MacStatsPianoRoll() { + [_sidebar_scroll_view release]; + [_menu_delegate release]; +} + +/** + * Called as each frame's data is made available. There is no guarantee the + * frames will arrive in order, or that all of them will arrive at all. The + * monitor should be prepared to accept frames received out-of-order or + * missing. + */ +void MacStatsPianoRoll:: +new_data(int thread_index, int frame_number) { + if (!_pause) { + update(); + } +} + +/** + * Called when it is necessary to redraw the entire graph. + */ +void MacStatsPianoRoll:: +force_redraw() { + if (_ctx) { + PStatPianoRoll::force_redraw(); + } +} + +/** + * Called when the user has resized the window, forcing a resize of the graph. + */ +void MacStatsPianoRoll:: +changed_graph_size(int graph_xsize, int graph_ysize) { + PStatPianoRoll::changed_size(graph_xsize, graph_ysize); +} + +/** + * Called when the user selects a new time units from the monitor pulldown + * menu, this should adjust the units for the graph to the indicated mask if + * it is a time-based graph. + */ +void MacStatsPianoRoll:: +set_time_units(int unit_mask) { + int old_unit_mask = get_guide_bar_units(); + if ((old_unit_mask & (GBU_hz | GBU_ms)) != 0) { + unit_mask = unit_mask & (GBU_hz | GBU_ms); + unit_mask |= (old_unit_mask & GBU_show_units); + set_guide_bar_units(unit_mask); + } +} + +/** + * Called when the user single-clicks on a label. + */ +void MacStatsPianoRoll:: +on_click_label(int collector_index) { + if (collector_index >= 0) { + MacStatsGraph::_monitor->open_strip_chart(_thread_index, collector_index, false); + } +} + +/** + * Called when the mouse right-clicks on a label, and should return the menu + * that should pop up. + */ +NSMenu *MacStatsPianoRoll:: +get_label_menu(int collector_index) const { + NSMenu *menu = [[[NSMenu alloc] init] autorelease]; + + std::string label = get_label_tooltip(collector_index); + if (!label.empty()) { + if (@available(macOS 14.0, *)) { + [menu addItem:[NSMenuItem sectionHeaderWithTitle:[NSString stringWithUTF8String:label.c_str()]]]; + } else { + NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:[NSString stringWithUTF8String:label.c_str()] action:nil keyEquivalent:@""]; + item.enabled = NO; + [menu addItem:item]; + [item release]; + } + } + + { + NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:@"Open Strip Chart" action:@selector(handleOpenStripChart:) keyEquivalent:@""]; + item.target = _menu_delegate; + item.tag = collector_index; + [menu addItem:item]; + [item release]; + } + + { + NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:@"Open Flame Graph" action:@selector(handleOpenFlameGraph:) keyEquivalent:@""]; + item.target = _menu_delegate; + item.tag = collector_index; + [menu addItem:item]; + [item release]; + } + + [menu addItem:[NSMenuItem separatorItem]]; + + { + NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:@"Change Color\u2026" action:@selector(handleChangeColor:) keyEquivalent:@""]; + item.target = _graph_view_controller; + item.tag = collector_index; + [menu addItem:item]; + [item release]; + } + + { + NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:@"Reset Color" action:@selector(handleResetColor:) keyEquivalent:@""]; + item.target = _graph_view_controller; + item.tag = collector_index; + [menu addItem:item]; + [item release]; + } + + return menu; +} + +/** + * Called when the mouse hovers over a label, and should return the text that + * should appear on the tooltip. + */ +std::string MacStatsPianoRoll:: +get_label_tooltip(int collector_index) const { + return PStatPianoRoll::get_label_tooltip(collector_index); +} + +/** + * Changes the amount of time the width of the horizontal axis represents. + * This may force a redraw. + */ +void MacStatsPianoRoll:: +set_horizontal_scale(double time_width) { + PStatPianoRoll::set_horizontal_scale(time_width); + + _graph_view.needsDisplay = YES; +} + +/** + * Erases the chart area. + */ +void MacStatsPianoRoll:: +clear_region() { + if (_ctx) { + CGContextSetFillColorWithColor(_ctx, _background_color); + CGContextFillRect(_ctx, CGRectMake(0, 0, get_xsize(), get_ysize())); + } +} + +/** + * Erases the chart area in preparation for drawing a bunch of bars. + */ +void MacStatsPianoRoll:: +begin_draw() { + clear_region(); + + // Draw in the guide bars. + CGContextSetStrokeColorWithColor(_ctx, [NSColor gridColor].CGColor); + int num_guide_bars = get_num_guide_bars(); + for (int i = 0; i < num_guide_bars; ++i) { + draw_guide_bar(_ctx, get_guide_bar(i), 0, get_ysize()); + } +} + +/** + * Should be overridden by the user class. This hook will be called before + * drawing any one row of bars. These bars correspond to the collector whose + * index is get_row_collector(row), and in the color get_row_color(row). + */ +void MacStatsPianoRoll:: +begin_row(int row) { + int collector_index = get_label_collector(row); + bool is_highlighted = collector_index == _highlighted_index; + CGContextSetFillColorWithColor(_ctx, + MacStatsGraph::_monitor->get_collector_color(collector_index, is_highlighted)); +} + +/** + * Draws a single bar on the chart. + */ +void MacStatsPianoRoll:: +draw_bar(int row, int from_x, int to_x) { + if (row >= 0 && row < _label_stack.get_num_labels()) { + int y = _label_stack.get_label_y(row, _graph_view); + int height = _label_stack.get_label_height(row); + + CGContextFillRect(_ctx, CGRectMake(from_x, (y - height + 2), to_x - from_x, (height - 4))); + } +} + +/** + * Called after all the bars have been drawn, this triggers a refresh event to + * draw it to the window. + */ +void MacStatsPianoRoll:: +end_draw() { + _graph_view.needsDisplay = YES; + + if (_guide_bars_changed) { + _scale_area.needsDisplay = YES; + _guide_bars_changed = false; + } +} + +/** + * Called at the end of the draw cycle. + */ +void MacStatsPianoRoll:: +idle() { + if (_labels_changed) { + update_labels(); + } +} + +/** + * Returns the current window dimensions. + */ +bool MacStatsPianoRoll:: +get_window_state(int &x, int &y, int &width, int &height, + bool &maximized, bool &minimized) const { + MacStatsGraph::get_window_state(x, y, width, height, maximized, minimized); + return true; +} + +/** + * Called to restore the graph window to its previous dimensions. + */ +void MacStatsPianoRoll:: +set_window_state(int x, int y, int width, int height, + bool maximized, bool minimized) { + MacStatsGraph::set_window_state(x, y, width, height, maximized, minimized); +} + +/** + * Called when the mouse right-clicks on the graph, and should return the menu + * that should pop up. + */ +NSMenu *MacStatsPianoRoll:: +get_graph_menu(int mouse_x, int mouse_y) const { + int collector_index = get_collector_under_pixel(mouse_x, mouse_y); + if (collector_index >= 0) { + return get_label_menu(collector_index); + } + return nil; +} + +/** + * Called when the mouse hovers over the graph, and should return the text that + * should appear on the tooltip. + */ +std::string MacStatsPianoRoll:: +get_graph_tooltip(int mouse_x, int mouse_y) const { + int collector_index = get_collector_under_pixel(mouse_x, mouse_y); + if (collector_index >= 0) { + return get_label_tooltip(collector_index); + } + return std::string(); +} + +/** + * Based on the mouse position within the graph window, look for draggable + * things the mouse might be hovering over and return the appropriate DragMode + * enum or DM_none if nothing is indicated. + */ +MacStatsGraph::DragMode MacStatsPianoRoll:: +consider_drag_start(int graph_x, int graph_y) { + if (graph_y >= 0 && graph_y < get_ysize()) { + if (graph_x >= 0 && graph_x < get_xsize()) { + // See if the mouse is over a user-defined guide bar. + int x = graph_x; + double from_height = pixel_to_height(x - 2); + double to_height = pixel_to_height(x + 2); + _drag_guide_bar = find_user_guide_bar(from_height, to_height); + if (_drag_guide_bar >= 0) { + return DM_guide_bar; + } + + } else { + // The mouse is left or right of the graph; maybe create a new guide + // bar. + return DM_new_guide_bar; + } + } + + return MacStatsGraph::consider_drag_start(graph_x, graph_y); +} + +/** + * Called when the mouse button is depressed within the graph window. + */ +void MacStatsPianoRoll:: +handle_button_press(int graph_x, int graph_y, bool double_click, int button) { + if (graph_x >= 0 && graph_y >= 0 && graph_x < get_xsize() && graph_y < get_ysize()) { + if (double_click && button == 1) { + // Double-clicking on a color bar in the graph is the same as double- + // clicking on the corresponding label. + on_click_label(get_collector_under_pixel(graph_x, graph_y)); + return; + } + } + + if (_potential_drag_mode == DM_none) { + set_drag_mode(DM_scale); + _drag_scale_start = pixel_to_height(graph_x); + // SetCapture(_graph_window); + return; + + } else if (_potential_drag_mode == DM_guide_bar && _drag_guide_bar >= 0) { + set_drag_mode(DM_guide_bar); + _drag_start_x = graph_x; + // SetCapture(_graph_window); + return; + } + + return MacStatsGraph::handle_button_press(graph_x, graph_y, + double_click, button); +} + +/** + * Called when the mouse button is released within the graph window. + */ +void MacStatsPianoRoll:: +handle_button_release(int graph_x, int graph_y) { + if (_drag_mode == DM_scale) { + set_drag_mode(DM_none); + // ReleaseCapture(); + return handle_motion(graph_x, graph_y); + } + else if (_drag_mode == DM_guide_bar) { + if (graph_x < 0 || graph_x >= get_xsize()) { + remove_user_guide_bar(_drag_guide_bar); + } else { + move_user_guide_bar(_drag_guide_bar, pixel_to_height(graph_x)); + } + set_drag_mode(DM_none); + // ReleaseCapture(); + return handle_motion(graph_x, graph_y); + } + + return MacStatsGraph::handle_button_release(graph_x, graph_y); +} + +/** + * Called when the mouse is moved within the graph window. + */ +void MacStatsPianoRoll:: +handle_motion(int graph_x, int graph_y) { + if (_drag_mode == DM_none && _potential_drag_mode == DM_none) { + // When the mouse is over a color bar, highlight it. + int collector_index = get_collector_under_pixel(graph_x, graph_y); + _label_stack.highlight_label(collector_index); + on_enter_label(collector_index); + + /* + // Now we want to get a WM_MOUSELEAVE when the mouse leaves the graph + // window. + TRACKMOUSEEVENT tme = { + sizeof(TRACKMOUSEEVENT), + TME_LEAVE, + _graph_window, + 0 + }; + TrackMouseEvent(&tme); + */ + } + else { + // If the mouse is in some drag mode, stop highlighting. + _label_stack.highlight_label(-1); + on_leave_label(_highlighted_index); + } + + if (_drag_mode == DM_scale) { + double ratio = (double)graph_x / (double)get_xsize(); + if (ratio > 0.0f) { + set_horizontal_scale(_drag_scale_start / ratio); + } + return; + } + else if (_drag_mode == DM_new_guide_bar) { + // We haven't created the new guide bar yet; we won't until the mouse + // comes within the graph's region. + if (graph_x >= 0 && graph_x < get_xsize()) { + set_drag_mode(DM_guide_bar); + _drag_guide_bar = add_user_guide_bar(pixel_to_height(graph_x)); + return; + } + + } else if (_drag_mode == DM_guide_bar) { + move_user_guide_bar(_drag_guide_bar, pixel_to_height(graph_x)); + return; + } + + return MacStatsGraph::handle_motion(graph_x, graph_y); +} + +/** + * Called when the mouse has left the graph window. + */ +void MacStatsPianoRoll:: +handle_leave() { + _label_stack.highlight_label(-1); + on_leave_label(_highlighted_index); +} + +/** + * Called when the mouse is moved within the graph window. + */ +void MacStatsPianoRoll:: +handle_scroll() { + // Graph view is flipped, side bar isn't, so we need to convert coordinates + NSPoint point; + point.x = 0; + point.y = _graph_view.frame.size.height - (((NSScrollView *)_graph_view_controller.view).documentVisibleRect.size.height + ((NSScrollView *)_graph_view_controller.view).documentVisibleRect.origin.y); + [_sidebar_scroll_view.contentView scrollToPoint:point]; + [_sidebar_scroll_view reflectScrolledClipView:_sidebar_scroll_view.contentView]; +} + +/** + * + */ +void MacStatsPianoRoll:: +handle_magnify(int graph_x, int graph_y, double scale) { + set_horizontal_scale(get_horizontal_scale() * (1.0 - scale)); +} + +/** + * Fills in the graph window. + */ +void MacStatsPianoRoll:: +handle_draw_graph(CGContextRef ctx, NSRect rect) { +#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 140000 + draw_guide_bars(ctx, rect.origin.y, rect.size.height); +#endif + + // Copy the drawn bars into the graph. + MacStatsGraph::handle_draw_graph(ctx, rect); + + // Draw the scale area. +/* + CGContextSetRGBStrokeColor(ctx, rgb_dark_gray[0], rgb_dark_gray[1], rgb_dark_gray[2], 1.0); + CGContextSetStrokeColor(ctx, rgb_dark_gray); + CGContextBeginPath(ctx); + CGContextMoveToPoint(ctx, 0, header_height); + CGContextAddLineToPoint(ctx, get_xsize(), header_height); + CGContextStrokePath(ctx);*/ + + int num_user_guide_bars = get_num_user_guide_bars(); + for (int i = 0; i < num_user_guide_bars; ++i) { + draw_guide_bar(ctx, get_user_guide_bar(i), rect.origin.y, rect.size.height); + } + + NSRect scale_frame = _scale_area.frame; + NSRect graph_frame = _graph_view.frame; + if (scale_frame.size.width != graph_frame.size.width) { + scale_frame.size.width = graph_frame.size.width; + _scale_area.frame = scale_frame; + } +} + +/** + * Fills in the graph window overhang, which is the area outside the graph + * bounds that may become visible momentarily due to scroll elasticity. + */ +void MacStatsPianoRoll:: +handle_draw_graph_overhang(CGContextRef ctx, NSRect rect) { + CGContextSetFillColorWithColor(ctx, _background_color); + CGContextFillRect(ctx, rect); + + draw_guide_bars(ctx, rect.origin.y, rect.size.height); +} + +/** + * Fills in the scale area. + */ +void MacStatsPianoRoll:: +handle_draw_scale_area(CGContextRef ctx, NSRect rect) { +/* + CGContextSetRGBStrokeColor(ctx, rgb_dark_gray[0], rgb_dark_gray[1], rgb_dark_gray[2], 1.0); + CGContextSetStrokeColor(ctx, rgb_dark_gray); + CGContextBeginPath(ctx); + CGContextMoveToPoint(ctx, 0, header_height); + CGContextAddLineToPoint(ctx, get_xsize(), header_height); + CGContextStrokePath(ctx);*/ + + draw_guide_bars(ctx, rect.origin.y, rect.size.height); + draw_guide_labels(ctx); +} + +/** + * Returns the collector index associated with the indicated vertical row, or + * -1. + */ +int MacStatsPianoRoll:: +get_collector_under_pixel(int xpoint, int ypoint) const { + if (_label_stack.get_num_labels() == 0) { + return -1; + } + + // Assume all of the labels are the same height. + int origin = _label_stack.get_label_y(0, _graph_view); + int height = _label_stack.get_label_height(0); + int row = (origin - ypoint) / height; + if (row >= 0 && row < _label_stack.get_num_labels()) { + return _label_stack.get_label_collector_index(row); + } else { + return -1; + } +} + +/** + * Resets the list of labels. + */ +void MacStatsPianoRoll:: +update_labels() { + _label_stack.clear_labels(); + for (int i = 0; i < get_num_labels(); ++i) { + _label_stack.add_label(MacStatsGraph::_monitor, this, + _thread_index, + get_label_collector(i), true); + } + _labels_changed = false; +} + +/** + * + */ +void MacStatsPianoRoll:: +draw_guide_bars(CGContextRef ctx, int y, int height) { + CGContextSetStrokeColorWithColor(ctx, [NSColor gridColor].CGColor); + + int num_guide_bars = get_num_guide_bars(); + for (int i = 0; i < num_guide_bars; ++i) { + draw_guide_bar(ctx, get_guide_bar(i), y, height); + } + + int num_user_guide_bars = get_num_user_guide_bars(); + for (int i = 0; i < num_user_guide_bars; ++i) { + draw_guide_bar(ctx, get_user_guide_bar(i), y, height); + } +} + +/** + * Draws the line for the indicated guide bar on the graph. + */ +void MacStatsPianoRoll:: +draw_guide_bar(CGContextRef ctx, const PStatGraph::GuideBar &bar, + int y, int height) { + int x = height_to_pixel(bar._height); + + if (x > 0 && x < get_xsize() - 1) { + // Only draw it if it's not too close to the top. + /*switch (bar._style) { + case GBS_target: + CGContextSetRGBStrokeColor(ctx, rgb_light_gray[0], rgb_light_gray[1], rgb_light_gray[2], 1.0); + break; + + case GBS_user: + CGContextSetRGBStrokeColor(ctx, rgb_user_guide_bar[0], rgb_user_guide_bar[1], rgb_user_guide_bar[2], 1.0); + break; + + default: + CGContextSetRGBStrokeColor(ctx, rgb_dark_gray[0], rgb_dark_gray[1], rgb_dark_gray[2], 1.0); + break; + }*/ + CGContextBeginPath(ctx); + CGContextMoveToPoint(ctx, x, y); + CGContextAddLineToPoint(ctx, x, y + height); + CGContextStrokePath(ctx); + } +} + +/** + * This is called during the servicing of the draw event. + */ +void MacStatsPianoRoll:: +draw_guide_labels(CGContextRef ctx) { + int i; + int num_guide_bars = get_num_guide_bars(); + for (i = 0; i < num_guide_bars; ++i) { + draw_guide_label(ctx, get_guide_bar(i)); + } + + int num_user_guide_bars = get_num_user_guide_bars(); + for (i = 0; i < num_user_guide_bars; ++i) { + draw_guide_label(ctx, get_user_guide_bar(i)); + } +} + +/** + * Draws the text for the indicated guide bar label at the top of the graph. + */ +void MacStatsPianoRoll:: +draw_guide_label(CGContextRef ctx, const PStatGraph::GuideBar &bar) { + NSColor *color; + if (@available(macOS 11.0, *)) { + color = [NSColor tertiaryLabelColor]; + } else { + // Otherwise it's hard to see on the dark titlebars + color = [NSColor windowFrameTextColor]; + } + /* + switch (bar._style) { + case GBS_target: + color = [NSColor colorWithDeviceRed:rgb_light_gray[0] green:rgb_light_gray[1] blue:rgb_light_gray[2] alpha:1.0]; + break; + + case GBS_user: + color = [NSColor colorWithDeviceRed:rgb_user_guide_bar[0] green:rgb_user_guide_bar[1] blue:rgb_user_guide_bar[2] alpha:1.0]; + break; + + default: + color = [NSColor colorWithDeviceRed:rgb_dark_gray[0] green:rgb_dark_gray[1] blue:rgb_dark_gray[2] alpha:1.0]; + break; + }*/ + + int x = height_to_pixel(bar._height); + const std::string &label = bar._label; + + const CFStringRef keys[] = { + (__bridge CFStringRef)NSForegroundColorAttributeName, + (__bridge CFStringRef)NSFontAttributeName, + }; + const void *values[] = { + color, + [NSFont systemFontOfSize:0.0], + }; + CFDictionaryRef attribs = CFDictionaryCreate(kCFAllocatorDefault, (const void **)keys, (const void **)values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + + CFStringRef str = CFStringCreateWithCString(kCFAllocatorDefault, label.c_str(), kCFStringEncodingUTF8); + CFAttributedStringRef astr = CFAttributedStringCreate(kCFAllocatorDefault, str, attribs); + CFRelease(attribs); + CFRelease(str); + + CTLineRef line = CTLineCreateWithAttributedString(astr); + CFRelease(astr); + CGRect bounds = CTLineGetImageBounds(line, ctx); + int width = bounds.size.width; + + if (bar._style != GBS_user) { + double from_height = pixel_to_height(x - width); + double to_height = pixel_to_height(x + width); + if (find_user_guide_bar(from_height, to_height) >= 0) { + // Omit the label: there's a user-defined guide bar in the same space. + CFRelease(line); + return; + } + } + + if (x >= 0 && x < get_xsize()) { + CGContextSetTextPosition(ctx, x + 6, 6); + CTLineDraw(line, ctx); + } + + CFRelease(line); +} diff --git a/pandatool/src/mac-stats/macStatsScaleArea.h b/pandatool/src/mac-stats/macStatsScaleArea.h new file mode 100644 index 0000000000..cf7ae2f062 --- /dev/null +++ b/pandatool/src/mac-stats/macStatsScaleArea.h @@ -0,0 +1,41 @@ +/** + * 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 macStatsScaleArea.h + * @author rdb + * @date 2023-08-18 + */ + +#ifndef MACSTATSSCALEAREA_H +#define MACSTATSSCALEAREA_H + +#import + +class MacStatsGraph; + +@interface MacStatsScaleArea : NSView { + @private + MacStatsGraph *_graph; +} + +- (id)initWithGraph:(MacStatsGraph *)graph frame:(NSRect)rect; +- (void)drawRect:(NSRect)dirtyRect; + +@end + +@interface MacStatsScaleAreaController : NSTitlebarAccessoryViewController { + @private + MacStatsGraph *_graph; +} + +- (id)initWithGraph:(MacStatsGraph *)graph; +- (void)loadView; + +@end + +#endif diff --git a/pandatool/src/mac-stats/macStatsScaleArea.mm b/pandatool/src/mac-stats/macStatsScaleArea.mm new file mode 100644 index 0000000000..4502946f02 --- /dev/null +++ b/pandatool/src/mac-stats/macStatsScaleArea.mm @@ -0,0 +1,50 @@ +/** + * 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 macStatsScaleArea.mm + * @author rdb + * @date 2023-08-18 + */ + +#include "macStatsScaleArea.h" +#include "macStatsGraph.h" +#include "macStatsStripChart.h" + +@implementation MacStatsScaleArea + +- (id)initWithGraph:(MacStatsGraph *)graph frame:(NSRect)rect { + if (self = [super initWithFrame:rect]) { + _graph = graph; + + [self addTrackingArea:[[NSTrackingArea alloc] initWithRect:NSZeroRect options:(NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved | NSTrackingActiveInKeyWindow | NSTrackingInVisibleRect) owner:self userInfo:nil]]; + } + + return self; +} + +- (void)drawRect:(NSRect)dirtyRect { + _graph->handle_draw_scale_area([NSGraphicsContext currentContext].CGContext, dirtyRect); +} + +@end + +@implementation MacStatsScaleAreaController + +- (id)initWithGraph:(MacStatsGraph *)graph { + if (self = [super init]) { + _graph = graph; + } + + return self; +} + +- (void)loadView { + self.view = [[MacStatsScaleArea alloc] initWithGraph:_graph frame:NSMakeRect(0, 0, 100, 100)]; +} + +@end diff --git a/pandatool/src/mac-stats/macStatsServer.h b/pandatool/src/mac-stats/macStatsServer.h new file mode 100644 index 0000000000..8c5ba47e1e --- /dev/null +++ b/pandatool/src/mac-stats/macStatsServer.h @@ -0,0 +1,82 @@ +/** + * 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 macStatsServer.h + * @author rdb + * @date 2023-08-17 + */ + +#ifndef MACSTATSSERVER_H +#define MACSTATSSERVER_H + +#include "pandatoolbase.h" +#include "programBase.h" +#include "pStatServer.h" +#include "macStatsMonitor.h" +#include "macStatsAppDelegate.h" + +#include + +/** + * The class that owns the main loop, waiting for client connections. + */ +class MacStatsServer : public PStatServer, public ProgramBase { +public: + MacStatsServer(); + + MacStatsMonitor *get_monitor() { return _monitor; } + + void run(int argc, char *argv[]); + +protected: + virtual bool handle_args(Args &args) override; + + virtual PStatMonitor *make_monitor(const NetAddress &address) override; + virtual void lost_connection(PStatMonitor *monitor) override; + +public: + bool new_session(); + bool open_session(const Filename &fn); + bool open_session(); + bool open_last_session(); + bool save_session(); + bool export_session(); + bool close_session(); + + void set_show_status_item(bool show); + void set_appearance(NSString *name); + void set_time_units(int unit_mask); + +private: + void create_app(); + void setup_session_menu(); + +private: + PT(MacStatsMonitor) _monitor; + + Filename _last_session; + Filename _save_filename; + + int _port = -1; + NSApplication *_app = nil; + NSUserNotification *_listening_notification = nil; + NSMenu *_main_menu = nil; + NSMenuItem *_show_status_item_menu_item = nil; + NSMenuItem *_appearance_system_menu_item = nil; + NSMenuItem *_appearance_aqua_menu_item = nil; + NSMenuItem *_appearance_dark_aqua_menu_item = nil; + NSMenuItem *_units_ms_menu_item = nil; + NSMenuItem *_units_hz_menu_item = nil; + NSMenuItem *_new_session_menu_item = nil; + NSMenuItem *_open_last_session_menu_item = nil; + NSMenuItem *_save_session_menu_item = nil; + NSMenuItem *_close_session_menu_item = nil; + NSMenuItem *_export_session_menu_item = nil; +}; + +#endif diff --git a/pandatool/src/mac-stats/macStatsServer.mm b/pandatool/src/mac-stats/macStatsServer.mm new file mode 100644 index 0000000000..8b7611fe5d --- /dev/null +++ b/pandatool/src/mac-stats/macStatsServer.mm @@ -0,0 +1,732 @@ +/** + * 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 macStatsServer.mm + * @author rdb + * @date 2023-08-17 + */ + +#include "macStatsServer.h" +#include "macStatsMonitor.h" +#include "macStatsAppDelegate.h" +#include "pandaVersion.h" +#include "pStatGraph.h" +#include "config_pstatclient.h" + +#include + +/** + * + */ +MacStatsServer:: +MacStatsServer() : _port(pstats_port) { + set_program_brief("macOS PStats client"); + set_program_description + ("This is a GUI-based PStats server that listens on a TCP port for a " + "connection from a PStatClient in a Panda3D application. It offers " + "various graphs for showing the timing information sent by the client." + "\n\n" + "The full documentation is available online:\n " +#ifdef HAVE_PYTHON + "https://docs.panda3d.org/" PANDA_ABI_VERSION_STR "/python/optimization/pstats" +#else + "https://docs.panda3d.org/" PANDA_ABI_VERSION_STR "/cpp/optimization/pstats" +#endif + ""); + + add_option + ("p", "port", 0, + "Specify the TCP port to listen for connections on. By default, this " + "is taken from the pstats-port Config variable.", + &ProgramBase::dispatch_int, nullptr, &_port); + + add_runline("[-p 5185]"); + add_runline("session.pstats"); + + _last_session = Filename::expand_from( + "$HOME/Library/Caches/Panda3D-" PANDA_ABI_VERSION_STR "/last-session.pstats"); + _last_session.set_binary(); + + create_app(); +} + +/** + * Runs the server. + */ +void MacStatsServer:: +run(int argc, char *argv[]) { + if (parse_command_line(argc, argv, isatty(STDERR_FILENO)) == ProgramBase::EC_failure) { + NSAlert *alert = [[NSAlert alloc] init]; + alert.messageText = @"PStats Error"; + alert.informativeText = @"Failed to parse command-line options."; + alert.alertStyle = NSCriticalAlertStyle; + [alert runModal]; + [alert release]; + return; + } + + [_app run]; +} + +/** + * Does something with the additional arguments on the command line (after all + * the -options have been parsed). Returns true if the arguments are good, + * false otherwise. + */ +bool MacStatsServer:: +handle_args(ProgramBase::Args &args) { + if (args.empty()) { + // applicationDidFinishLaunching will call new_session(). + return true; + } + else if (args.size() == 1) { + // Handled by application:openFile: + return true; + } + else { + nout << "At most one filename may be specified on the command-line.\n"; + return false; + } +} + +/** + * + */ +PStatMonitor *MacStatsServer:: +make_monitor(const NetAddress &address) { + // Enable the "New Session", "Save Session" and "Close Session" menu items. + _new_session_menu_item.enabled = YES; + _save_session_menu_item.enabled = YES; + _close_session_menu_item.enabled = YES; + _export_session_menu_item.enabled = YES; + + NSUserNotificationCenter *center = [NSUserNotificationCenter defaultUserNotificationCenter]; + if (_listening_notification != nil) { + [center removeDeliveredNotification:_listening_notification]; + [_listening_notification release]; + _listening_notification = nil; + } + + _monitor = new MacStatsMonitor(this); + return _monitor; +} + +/** + * Called when connection has been lost. + */ +void MacStatsServer:: +lost_connection(PStatMonitor *monitor) { + if (_monitor != nullptr && !_monitor->_have_data) { + // We didn't have any data yet. Just silently restart the session. + _monitor->close(); + _monitor = nullptr; + if (new_session()) { + return; + } + } else { + // Store a backup now, in case PStats crashes or something. + _last_session.make_dir(); + if (monitor->write(_last_session)) { + nout << "Wrote to " << _last_session << "\n"; + } else { + nout << "Failed to write to " << _last_session << "\n"; + } + } + + stop_listening(); +} + +/** + * Starts a new session. + */ +bool MacStatsServer:: +new_session() { + if (!close_session()) { + return false; + } + + if (listen(_port)) { + NSUserNotification *notification = [[NSUserNotification alloc] init]; + notification.title = @"PStats Server"; + notification.informativeText = [NSString stringWithFormat:@"Waiting for client to connect on port %d\u2026", _port]; + + // Quick way to do something else if the user prefers. + notification.additionalActions = @[ + [NSUserNotificationAction actionWithIdentifier:@"open" title:@"Open Session\u2026"], + [NSUserNotificationAction actionWithIdentifier:@"openLast" title:@"Open Last Session"], + [NSUserNotificationAction actionWithIdentifier:@"quit" title:@"Quit PStats"] + ]; + + NSUserNotificationCenter *center = [NSUserNotificationCenter defaultUserNotificationCenter]; + [center deliverNotification:notification]; + _listening_notification = notification; + + _new_session_menu_item.enabled = NO; + _save_session_menu_item.enabled = NO; + _close_session_menu_item.enabled = YES; + _export_session_menu_item.enabled = NO; + + return true; + } + + NSAlert *alert = [[NSAlert alloc] init]; + alert.messageText = @"PStats Error"; + alert.informativeText = [NSString stringWithFormat:@"Unable to open port %d. Try specifying a different port number using pstats-port in your Config file or the -p option on the command-line.", _port]; + alert.alertStyle = NSCriticalAlertStyle; + [alert runModal]; + [alert release]; + + return false; +} + +/** + * Opens a session with the given filename. + */ +bool MacStatsServer:: +open_session(const Filename &fn) { + if (!close_session()) { + return false; + } + + MacStatsMonitor *monitor = new MacStatsMonitor(this); + if (!monitor->read(fn)) { + delete monitor; + return false; + } + + _save_filename = fn; + _new_session_menu_item.enabled = YES; + _save_session_menu_item.enabled = YES; + _close_session_menu_item.enabled = YES; + _export_session_menu_item.enabled = YES; + + _monitor = monitor; + + // If the file contained no graphs, open the default graphs. + if (monitor->_graphs.empty()) { + monitor->open_default_graphs(); + } + + return true; +} + +/** + * Offers to open an existing session. + */ +bool MacStatsServer:: +open_session() { + if (!close_session()) { + return false; + } + + NSOpenPanel *panel = [NSOpenPanel openPanel]; + panel.title = @"Open Session"; + + if ([panel runModal] == NSModalResponseOK) { + NSString *path = [[panel.URLs firstObject] path]; + Filename fn([path UTF8String]); + fn.set_binary(); + if (open_session(fn)) { + return true; + } + + NSAlert *alert = [[NSAlert alloc] init]; + alert.messageText = @"PStats Error"; + alert.informativeText = [NSString stringWithFormat:@"Failed to load session file: %s", fn.c_str()]; + alert.alertStyle = NSCriticalAlertStyle; + [alert runModal]; + [alert release]; + } + + return false; +} + +/** + * Opens the last session, if any. + */ +bool MacStatsServer:: +open_last_session() { + if (open_session(_last_session)) { + return true; + } + + NSAlert *alert = [[NSAlert alloc] init]; + alert.messageText = @"PStats Error"; + alert.informativeText = [NSString stringWithFormat:@"Failed to load session file: %s", _last_session.c_str()]; + alert.alertStyle = NSCriticalAlertStyle; + [alert runModal]; + [alert release]; + + return false; +} + +/** + * Offers to save the current session. + */ +bool MacStatsServer:: +save_session() { + nassertr_always(_monitor != nullptr, true); + + NSSavePanel *panel = [NSSavePanel savePanel]; + panel.title = @"Save Session"; + + if (_save_filename.empty()) { + panel.nameFieldStringValue = @"session.pstats"; + } else { + std::string dirname = _save_filename.get_dirname(); + std::string basename = _save_filename.get_basename(); + panel.nameFieldStringValue = [NSString stringWithUTF8String:basename.c_str()]; + panel.directoryURL = [NSURL fileURLWithPath:[NSString stringWithUTF8String:dirname.c_str()]]; + } + + if ([panel runModal] == NSModalResponseOK) { + NSString *path = [panel.URL path]; + Filename fn([path UTF8String]); + fn.set_binary(); + + if (!_monitor->write(fn)) { + NSAlert *alert = [[NSAlert alloc] init]; + alert.messageText = @"PStats Error"; + alert.informativeText = [NSString stringWithFormat:@"Failed to save session file: %s", fn.c_str()]; + alert.alertStyle = NSCriticalAlertStyle; + [alert runModal]; + [alert release]; + + return false; + } + _save_filename = fn; + _monitor->get_client_data()->clear_dirty(); + return true; + } + + return false; +} + +/** + * Offers to export the current session as a JSON file. + */ +bool MacStatsServer:: +export_session() { + nassertr_always(_monitor != nullptr, true); + + NSSavePanel *panel = [NSSavePanel savePanel]; + panel.title = @"Export Session"; + panel.nameFieldStringValue = @"session.json"; + + if ([panel runModal] == NSModalResponseOK) { + NSString *path = [panel.URL path]; + Filename fn([path UTF8String]); + fn.set_binary(); + + std::ofstream stream; + if (!fn.open_write(stream)) { + NSAlert *alert = [[NSAlert alloc] init]; + alert.messageText = @"PStats Error"; + alert.informativeText = [NSString stringWithFormat:@"Failed to open file for export: %s", fn.c_str()]; + alert.alertStyle = NSCriticalAlertStyle; + [alert runModal]; + [alert release]; + + return false; + } + + int pid = _monitor->get_client_pid(); + _monitor->get_client_data()->write_json(stream, std::max(0, pid)); + stream.close(); + return true; + } + + return false; +} + +/** + * Closes the current session. + */ +bool MacStatsServer:: +close_session() { + bool wrote_last_session = false; + + if (_monitor != nullptr) { + const PStatClientData *client_data = _monitor->get_client_data(); + if (client_data != nullptr && client_data->is_dirty()) { + if (!_monitor->has_read_filename()) { + _last_session.make_dir(); + if (_monitor->write(_last_session)) { + nout << "Wrote to " << _last_session << "\n"; + wrote_last_session = true; + } + else { + nout << "Failed to write to " << _last_session << "\n"; + } + } + + // Make sure the alert goes on top. + [_app activateIgnoringOtherApps:YES]; + + NSAlert *alert = [[NSAlert alloc] init]; + alert.messageText = @"Unsaved Data"; + alert.informativeText = @"Would you like to save the currently open session?"; + [alert addButtonWithTitle:@"Save\u2026"]; + [alert addButtonWithTitle:@"Don't Save"]; + [alert addButtonWithTitle:@"Cancel"]; + int response = [alert runModal]; + [alert release]; + + if ((response != 1000 && response != 1001) || + (response == 1000 && !save_session())) { + return false; + } + } + + _monitor->close(); + _monitor = nullptr; + } + + _save_filename = Filename(); + stop_listening(); + + if (_listening_notification != nil) { + NSUserNotificationCenter *center = [NSUserNotificationCenter defaultUserNotificationCenter]; + [center removeDeliveredNotification:_listening_notification]; + [_listening_notification release]; + _listening_notification = nil; + } + + _new_session_menu_item.enabled = YES; + if (wrote_last_session) { + _open_last_session_menu_item.enabled = YES; + } + _save_session_menu_item.enabled = NO; + _close_session_menu_item.enabled = NO; + _export_session_menu_item.enabled = NO; + return true; +} + +/** + * Enables the frame rate label on the right end of the menu bar. This is + * used as a text label to display the main thread's frame rate to the user, + * although it is implemented as a right-justified toplevel menu item that + * doesn't open to anything. + */ +void MacStatsServer:: +set_show_status_item(bool show) { + if (_monitor != nullptr) { + _monitor->set_show_status_item(show); + } + + _show_status_item_menu_item.state = show ? NSOnState : NSOffState; +} + +/** + * + */ +void MacStatsServer:: +set_appearance(NSString *name) { + if (@available(macOS 10.14, *)) { + if (name == nil || name.length == 0) { + [_app setAppearance:nil]; + _appearance_system_menu_item.state = NSOnState; + } else { + [_app setAppearance:[NSAppearance appearanceNamed:name]]; + _appearance_system_menu_item.state = NSOffState; + } + + _appearance_aqua_menu_item.state = (name != nil && [name isEqual:@"NSAppearanceNameAqua"]) ? NSOnState : NSOffState; + _appearance_dark_aqua_menu_item.state = (name != nil && [name isEqual:@"NSAppearanceNameDarkAqua"]) ? NSOnState : NSOffState; + } +} + +/** + * Called when the user selects a new time units from the monitor pulldown + * menu, this should adjust the units for all graphs to the indicated mask if + * it is a time-based graph. + */ +void MacStatsServer:: +set_time_units(int unit_mask) { + if (_monitor != nullptr) { + _monitor->set_time_units(unit_mask); + } + + _units_ms_menu_item.state = (unit_mask & PStatGraph::GBU_ms) ? NSOnState : NSOffState; + _units_hz_menu_item.state = (unit_mask & PStatGraph::GBU_hz) ? NSOnState : NSOffState; +} + +/** + * Creates the menu bar for this monitor. + */ +void MacStatsServer:: +create_app() { + _app = [NSApplication sharedApplication]; + + MacStatsAppDelegate *delegate = [[MacStatsAppDelegate alloc] initWithServer:this]; + [_app setDelegate:delegate]; + [_app setActivationPolicy:NSApplicationActivationPolicyRegular]; + + _main_menu = [[NSMenu alloc] init]; + + NSMenu *app_menu = [[NSMenu alloc] init]; + + NSMenu *settings_menu = [[NSMenu alloc] init]; + + { + NSMenuItem *item = [[NSMenuItem alloc] init]; + item.action = @selector(handleToggleSettingsBool:); + item.representedObject = @"ShowStatusItem"; + item.title = @"Show in Status Bar"; + item.state = NSOnState; + [settings_menu addItem:item]; + + _show_status_item_menu_item = item; + [item release]; + } + + NSMenu *units_menu; + if (@available(macOS 14.0, *)) { + // On Sonnoma, use a section with header. + [settings_menu addItem:[NSMenuItem separatorItem]]; + [settings_menu addItem:[NSMenuItem sectionHeaderWithTitle:@"Time Units"]]; + units_menu = settings_menu; + } else { + // On older versions, create a sub-menu. + units_menu = [[NSMenu alloc] init]; + units_menu.autoenablesItems = NO; + + NSMenuItem *units_item = [[NSMenuItem alloc] init]; + units_item.title = @"Time Units"; + + [settings_menu addItem:units_item]; + [settings_menu setSubmenu:units_menu forItem:units_item]; + [units_item release]; + [units_menu release]; + } + + { + NSMenuItem *item = [[NSMenuItem alloc] init]; + item.action = @selector(handleSettingsInteger:); + item.representedObject = @"TimeUnits"; + item.tag = PStatGraph::GBU_ms; + item.title = @"ms"; + item.state = NSOnState; + [units_menu addItem:item]; + + _units_ms_menu_item = item; + [item release]; + } + + { + NSMenuItem *item = [[NSMenuItem alloc] init]; + item.action = @selector(handleSettingsInteger:); + item.representedObject = @"TimeUnits"; + item.tag = PStatGraph::GBU_hz; + item.title = @"Hz"; + item.state = NSOffState; + [units_menu addItem:item]; + + _units_hz_menu_item = item; + [item release]; + } + + // Dark mode available from Mojave. + if (@available(macOS 10.14, *)) { + NSMenu *appearance_menu; + if (@available(macOS 14.0, *)) { + // On Sonnoma, use a section with header. + [settings_menu addItem:[NSMenuItem separatorItem]]; + [settings_menu addItem:[NSMenuItem sectionHeaderWithTitle:@"Appearance"]]; + appearance_menu = settings_menu; + } else { + // On older versions, create a sub-menu. + appearance_menu = [[NSMenu alloc] init]; + appearance_menu.autoenablesItems = NO; + + NSMenuItem *appearance_item = [[NSMenuItem alloc] init]; + appearance_item.title = @"Appearance"; + + [settings_menu addItem:appearance_item]; + [settings_menu setSubmenu:appearance_menu forItem:appearance_item]; + [appearance_item release]; + [appearance_menu release]; + } + + { + NSMenuItem *item = [[NSMenuItem alloc] init]; + item.action = @selector(handleSettingsAppearance:); + item.representedObject = @""; + item.title = @"System"; + item.state = NSOnState; + [appearance_menu addItem:item]; + _appearance_system_menu_item = item; + [item release]; + } + + { + NSMenuItem *item = [[NSMenuItem alloc] init]; + item.action = @selector(handleSettingsAppearance:); + item.representedObject = @"NSAppearanceNameAqua"; + item.title = @"Aqua"; + item.state = NSOffState; + [appearance_menu addItem:item]; + _appearance_aqua_menu_item = item; + [item release]; + } + + { + NSMenuItem *item = [[NSMenuItem alloc] init]; + item.action = @selector(handleSettingsAppearance:); + item.representedObject = @"NSAppearanceNameDarkAqua"; + item.title = @"Dark Aqua"; + item.state = NSOffState; + [appearance_menu addItem:item]; + _appearance_dark_aqua_menu_item = item; + [item release]; + } + } + + NSMenuItem *settings_item = [[NSMenuItem alloc] init]; + settings_item.title = @"Settings"; + [app_menu addItem:settings_item]; + [app_menu setSubmenu:settings_menu forItem:settings_item]; + [settings_item release]; + [settings_menu release]; + + [app_menu addItem:[NSMenuItem separatorItem]]; + + { + NSMenuItem *item = [[NSMenuItem alloc] init]; + item.action = @selector(hide:); + item.keyEquivalent = @"h"; + item.title = @"Hide PStats"; + [app_menu addItem:item]; + [item release]; + } + + { + NSMenuItem *item = [[NSMenuItem alloc] init]; + item.action = @selector(hideOtherApplications:); + item.keyEquivalent = @"h"; + item.keyEquivalentModifierMask |= NSAlternateKeyMask; + item.title = @"Hide Others"; + [app_menu addItem:item]; + } + + { + NSMenuItem *item = [[NSMenuItem alloc] init]; + item.action = @selector(unhideAllApplications:); + item.title = @"Show All"; + [app_menu addItem:item]; + [item release]; + } + + [app_menu addItem:[NSMenuItem separatorItem]]; + + { + NSMenuItem *item = [[NSMenuItem alloc] init]; + item.action = @selector(terminate:); + item.keyEquivalent = @"q"; + item.title = @"Quit PStats"; + [app_menu addItem:item]; + [item release]; + } + + NSMenuItem *app_menu_item = [[NSMenuItem alloc] init]; + [_main_menu addItem:app_menu_item]; + [_main_menu setSubmenu:app_menu forItem:app_menu_item]; + [app_menu_item release]; + [app_menu release]; + + setup_session_menu(); + + [_app setMainMenu:_main_menu]; + [_main_menu release]; + + //[_app activateIgnoringOtherApps:YES]; + //[_app finishLaunching]; + + set_time_units(PStatGraph::GBU_ms); +} + +/** + * Creates the "Session" pulldown menu. + */ +void MacStatsServer:: +setup_session_menu() { + NSMenu *submenu = [[NSMenu alloc] init]; + submenu.title = @"Session"; + submenu.autoenablesItems = NO; + + { + NSMenuItem *item = [[NSMenuItem alloc] init]; + item.action = @selector(handleNewSession:); + item.keyEquivalent = @"n"; + item.title = @"New Session"; + [submenu addItem:item]; + + _new_session_menu_item = item; + } + + { + NSMenuItem *item = [[NSMenuItem alloc] init]; + item.action = @selector(handleOpenSession:); + item.keyEquivalent = @"o"; + item.title = @"Open Session\u2026"; + [submenu addItem:item]; + [item release]; + } + + { + NSMenuItem *item = [[NSMenuItem alloc] init]; + item.action = @selector(handleOpenLastSession:); + item.title = @"Open Last Session"; + item.enabled = _last_session.exists(); + [submenu addItem:item]; + + _open_last_session_menu_item = item; + [item release]; + } + + { + NSMenuItem *item = [[NSMenuItem alloc] init]; + item.action = @selector(handleSaveSession:); + item.keyEquivalent = @"s"; + item.title = @"Save Session\u2026"; + item.enabled = NO; + [submenu addItem:item]; + + _save_session_menu_item = item; + [item release]; + } + + { + NSMenuItem *item = [[NSMenuItem alloc] init]; + item.action = @selector(handleCloseSession:); + item.keyEquivalent = @"w"; + item.title = @"Close Session"; + item.enabled = NO; + [submenu addItem:item]; + + _close_session_menu_item = item; + [item release]; + } + + [submenu addItem:[NSMenuItem separatorItem]]; + + { + NSMenuItem *item = [[NSMenuItem alloc] init]; + item.action = @selector(handleExportSession:); + item.title = @"Export as JSON\u2026"; + item.enabled = NO; + [submenu addItem:item]; + + _export_session_menu_item = item; + [item release]; + } + + NSMenuItem *item = [[NSMenuItem alloc] init]; + [_main_menu addItem:item]; + [_main_menu setSubmenu:submenu forItem:item]; +} diff --git a/pandatool/src/mac-stats/macStatsStripChart.h b/pandatool/src/mac-stats/macStatsStripChart.h new file mode 100644 index 0000000000..685a5f6618 --- /dev/null +++ b/pandatool/src/mac-stats/macStatsStripChart.h @@ -0,0 +1,90 @@ +/** + * 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 macStatsStripChart.h + * @author rdb + * @date 2023-08-18 + */ + +#ifndef MACSTATSSTRIPCHART_H +#define MACSTATSSTRIPCHART_H + +#include "macStatsGraph.h" +#include "pStatStripChart.h" +#include "macStatsChartMenuDelegate.h" + +class MacStatsMonitor; + +/** + * A window that draws a strip chart, given a view. + */ +class MacStatsStripChart final : public PStatStripChart, public MacStatsGraph { +public: + MacStatsStripChart(MacStatsMonitor *monitor, + int thread_index, int collector_index, bool show_level); + virtual ~MacStatsStripChart(); + + virtual void new_collector(int collector_index); + virtual void new_data(int thread_index, int frame_number); + virtual void force_redraw(); + virtual void changed_graph_size(int graph_xsize, int graph_ysize); + + virtual void set_time_units(int unit_mask); + virtual void set_scroll_speed(double scroll_speed); + virtual void on_click_label(int collector_index); + virtual NSMenu *get_label_menu(int collector_index) const; + virtual std::string get_label_tooltip(int collector_index) const; + void set_vertical_scale(double value_height); + void set_auto_vertical_scale(); + +protected: + virtual void update_labels(); + + virtual void clear_region(); + virtual void draw_slice(int x, int w, + const PStatStripChart::FrameData &fdata); + virtual void draw_empty(int x, int w); + virtual void draw_cursor(int x); + virtual void end_draw(int from_x, int to_x); + + virtual bool get_window_state(int &x, int &y, int &width, int &height, + bool &maximized, bool &minimized) const; + virtual void set_window_state(int x, int y, int width, int height, + bool maximized, bool minimized); + + virtual NSMenu *get_graph_menu(int mouse_x, int mouse_y) const; + virtual std::string get_graph_tooltip(int mouse_x, int mouse_y) const; + virtual DragMode consider_drag_start(int graph_x, int graph_y); + virtual void set_drag_mode(DragMode drag_mode); + + virtual void handle_button_press(int graph_x, int graph_y, + bool double_click, int button); + virtual void handle_button_release(int graph_x, int graph_y); + virtual void handle_motion(int graph_x, int graph_y); + virtual void handle_leave(); + virtual void handle_magnify(int graph_x, int graph_y, double scale); + virtual void handle_draw_graph(CGContextRef ctx, NSRect rect); + virtual void handle_draw_scale_area(CGContextRef ctx, NSRect rect); + virtual void handle_back(); + +private: + void draw_guide_bar(CGContextRef ctx, int from_x, int to_x, + const PStatGraph::GuideBar &bar); + void draw_guide_labels(CGContextRef ctx); + int draw_guide_label(CGContextRef ctx, const PStatGraph::GuideBar &bar, int last_y); + +private: + MacStatsChartMenuDelegate *_menu_delegate; + //NSButton *_smooth_checkbox; + //NSTextField *_total_label; + NSToolbarItem *_total_item; + + std::vector _back_stack; +}; + +#endif diff --git a/pandatool/src/mac-stats/macStatsStripChart.mm b/pandatool/src/mac-stats/macStatsStripChart.mm new file mode 100644 index 0000000000..068c41ea37 --- /dev/null +++ b/pandatool/src/mac-stats/macStatsStripChart.mm @@ -0,0 +1,964 @@ +/** + * 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 macStatsStripChart.mm + * @author rdb + * @date 2023-08-18 + */ + +#include "macStatsStripChart.h" +#include "macStatsMonitor.h" +#include "macStatsScaleArea.h" +#include "pStatCollectorDef.h" +#include "cocoa_compat.h" + +@interface MacStatsStripChartViewController : MacStatsGraphViewController +@end + +static const int default_strip_chart_width = 400; +static const int default_strip_chart_height = 200; + +static const int minimum_strip_chart_sidebar_width = 116; +static const int default_strip_chart_sidebar_width = 116; + +/** + * + */ +MacStatsStripChart:: +MacStatsStripChart(MacStatsMonitor *monitor, int thread_index, + int collector_index, bool show_level) : + PStatStripChart(monitor, thread_index, collector_index, show_level, 0, 0), + MacStatsGraph(monitor, [MacStatsStripChartViewController alloc]) +{ + // Used for popup menus. + _menu_delegate = [[MacStatsChartMenuDelegate alloc] initWithMonitor:monitor threadIndex:thread_index]; + + // Set the initial size of the graph. + int height = default_strip_chart_height + _window.frame.size.height - _window.contentLayoutRect.size.height; + _graph_view.frame = NSMakeRect(0, 0, default_strip_chart_width, height); + _graph_view_controller.view.frame = NSMakeRect(0, 0, default_strip_chart_width, height); + + // It's put inside a scroll view that tracks the main scroll view. + NSScrollView *scroll_view = [[NSScrollView alloc] initWithFrame:NSMakeRect(0, 0, default_strip_chart_sidebar_width, 0)]; + scroll_view.documentView = _label_stack.get_view(); + scroll_view.drawsBackground = NO; + scroll_view.automaticallyAdjustsContentInsets = YES; + scroll_view.hasHorizontalScroller = NO; + scroll_view.hasVerticalScroller = NO; + + NSViewController *sidebar_controller = [[NSViewController alloc] init]; + sidebar_controller.view = scroll_view; + + // Add a view to the right of the graph, to display all of the scale units. + // Calculate how wide it should be to display a typical label. + CGFloat width = [NSTextField labelWithString:@"999 ms"].frame.size.width + 8; + _scale_area = [[MacStatsScaleArea alloc] initWithGraph:this frame:NSMakeRect(0, 0, width, 0)]; + _scale_area.autoresizingMask = NSViewHeightSizable; + + NSViewController *scale_area_controller = [[NSViewController alloc] init]; + scale_area_controller.view = _scale_area; + + NSSplitViewController *svc = [[NSSplitViewController alloc] init]; + [svc addSplitViewItem:[NSSplitViewItem sidebarWithViewController:sidebar_controller]]; + [svc addSplitViewItem:[NSSplitViewItem splitViewItemWithViewController:_graph_view_controller]]; + [svc addSplitViewItem:[NSSplitViewItem splitViewItemWithViewController:scale_area_controller]]; + + svc.splitViewItems[0].minimumThickness = minimum_strip_chart_sidebar_width; + svc.splitViewItems[2].minimumThickness = width; + svc.splitViewItems[2].maximumThickness = width; + + NSSplitView *split_view = svc.splitView; + split_view.vertical = YES; + split_view.dividerStyle = NSSplitViewDividerStyleThin; + split_view.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable; + _split_view = split_view; + + // When sidebar collapses, show a sidebar icon in the menu bar + NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; + [center addObserver:_graph_view_controller + selector:@selector(handleSplitViewResize:) + name:NSSplitViewDidResizeSubviewsNotification + object:split_view]; + + _window.contentViewController = svc; + + _graph_view_controller.backToolbarItemVisible = NO; + + [svc release]; + [sidebar_controller release]; + + _total_item = nil; + if (@available(macOS 11.0, *)) { + NSToolbar *toolbar = [[NSToolbar alloc] initWithIdentifier:@""]; + toolbar.delegate = _graph_view_controller; + toolbar.displayMode = NSToolbarDisplayModeIconOnly; + _window.toolbar = toolbar; + [_window setToolbarStyle:NSWindowToolbarStyleUnifiedCompact]; + + for (NSToolbarItem *item in toolbar.items) { + if ([item.itemIdentifier isEqual:@"total"]) { + _total_item = item; + break; + } + } + [toolbar release]; + } + + /*{ + _smooth_checkbox = [NSButton checkboxWithTitle:@"Smooth" + target:_graph_view_controller + action:@selector(handleToggleAverageMode:)]; + + NSStackView *stack_view = [NSStackView stackViewWithViews:@[_smooth_checkbox]]; + stack_view.translatesAutoresizingMaskIntoConstraints = NO; + + NSTitlebarAccessoryViewController *accessory_controller = [[NSTitlebarAccessoryViewController alloc] init]; + //accessory_controller.layoutAttribute = NSLayoutAttributeLeft; + [accessory_controller.view addSubview:stack_view]; + //accessory_controller.automaticallyAdjustsSize = NO; + [_window addTitlebarAccessoryViewController:accessory_controller]; + [accessory_controller release]; + + [stack_view.leftAnchor constraintEqualToAnchor:_graph_view.leftAnchor constant:8].active = YES; + [stack_view.bottomAnchor constraintEqualToAnchor:((NSLayoutGuide *)_window.contentLayoutGuide).topAnchor constant:-8].active = YES; + //[stack_view.topAnchor constraintEqualToAnchor:svc.view.topAnchor constant:-8].active = YES; + }*/ + /*{ + _total_label = [NSTextField labelWithString:@""]; + + NSStackView *stack_view = [NSStackView stackViewWithViews:@[_total_label]]; + stack_view.translatesAutoresizingMaskIntoConstraints = NO; + + NSTitlebarAccessoryViewController *accessory_controller = [[NSTitlebarAccessoryViewController alloc] init]; + accessory_controller.layoutAttribute = NSLayoutAttributeRight; + [accessory_controller.view addSubview:stack_view]; + //accessory_controller.automaticallyAdjustsSize = NO; + [_window addTitlebarAccessoryViewController:accessory_controller]; + [accessory_controller release]; + + [stack_view.rightAnchor constraintEqualToAnchor:_graph_view.rightAnchor].active = YES; + [stack_view.bottomAnchor constraintEqualToAnchor:((NSLayoutGuide *)_window.contentLayoutGuide).topAnchor].active = YES; + [stack_view.topAnchor constraintEqualToAnchor:svc.view.topAnchor].active = YES; + }*/ + + if (show_level) { + // If it's a level-type graph, show the appropriate units. + if (_unit_name.empty()) { + set_guide_bar_units(GBU_named); + } else { + set_guide_bar_units(GBU_named | GBU_show_units); + } + } else { + // If it's a time-type graph, show the ms / Hz units. + set_guide_bar_units(get_guide_bar_units() | GBU_show_units); + } + + [_label_stack.get_view().widthAnchor constraintEqualToAnchor:scroll_view.widthAnchor].active = YES; + + // Update window title and total label. + new_data(0, 0); + + [_window makeKeyAndOrderFront:nil]; +} + +/** + * + */ +MacStatsStripChart:: +~MacStatsStripChart() { + [_menu_delegate release]; +} + +/** + * Called whenever a new Collector definition is received from the client. + */ +void MacStatsStripChart:: +new_collector(int collector_index) { + MacStatsGraph::new_collector(collector_index); +} + +/** + * Called as each frame's data is made available. There is no guarantee the + * frames will arrive in order, or that all of them will arrive at all. The + * monitor should be prepared to accept frames received out-of-order or + * missing. + */ +void MacStatsStripChart:: +new_data(int thread_index, int frame_number) { + if (is_title_unknown()) { + std::string window_title = get_title_text(); + if (!is_title_unknown()) { + _window.title = [NSString stringWithUTF8String:window_title.c_str()]; + } + } + + if (!_pause) { + update(); + + if (@available(macOS 10.15, *)) { + std::string text = get_total_text(); + [_total_item setTitle:[NSString stringWithUTF8String:text.c_str()]]; + } + } +} + +/** + * Called when it is necessary to redraw the entire graph. + */ +void MacStatsStripChart:: +force_redraw() { + if (_ctx) { + PStatStripChart::force_redraw(); + } + + _scale_area.needsDisplay = YES; +} + +/** + * Called when the user has resized the window, forcing a resize of the graph. + */ +void MacStatsStripChart:: +changed_graph_size(int graph_xsize, int graph_ysize) { + PStatStripChart::changed_size(graph_xsize, graph_ysize); +} + +/** + * Called when the user selects a new time units from the monitor pulldown + * menu, this should adjust the units for the graph to the indicated mask if + * it is a time-based graph. + */ +void MacStatsStripChart:: +set_time_units(int unit_mask) { + int old_unit_mask = get_guide_bar_units(); + if ((old_unit_mask & (GBU_hz | GBU_ms)) != 0) { + unit_mask = unit_mask & (GBU_hz | GBU_ms); + unit_mask |= (old_unit_mask & GBU_show_units); + set_guide_bar_units(unit_mask); + + if (@available(macOS 10.15, *)) { + std::string text = get_total_text(); + [_total_item setTitle:[NSString stringWithUTF8String:text.c_str()]]; + } + + _scale_area.needsDisplay = YES; + } +} + +/** + * Called when the user selects a new scroll speed from the monitor pulldown + * menu, this should adjust the speed for the graph to the indicated value. + */ +void MacStatsStripChart:: +set_scroll_speed(double scroll_speed) { + // The speed factor indicates chart widths per minute. + if (scroll_speed != 0.0f) { + set_horizontal_scale(60.0f / scroll_speed); + } +} + +/** + * Called when the user single-clicks on a label. + */ +void MacStatsStripChart:: +on_click_label(int collector_index) { + if (collector_index < 0) { + // Clicking on whitespace in the graph is the same as clicking on the top + // label. + collector_index = get_collector_index(); + } + + if (collector_index == get_collector_index()) { + // Clicking on the top label means to go up to the parent level. + if (collector_index != 0) { + const PStatClientData *client_data = + MacStatsGraph::_monitor->get_client_data(); + if (client_data->has_collector(collector_index)) { + const PStatCollectorDef &def = + client_data->get_collector_def(collector_index); + if (def._parent_index == 0 && get_view().get_show_level()) { + // Unless the parent is "Frame", and we're not a time collector. + } + else if (def._parent_index != get_collector_index()) { + // If we were previously at the parent, pop it from the stack. + if (!_back_stack.empty() && _back_stack.back() == def._parent_index) { + _back_stack.pop_back(); + if (_back_stack.empty()) { + _graph_view_controller.backToolbarItemVisible = NO; + } + } else { + if (_back_stack.empty()) { + _graph_view_controller.backToolbarItemVisible = YES; + } + _back_stack.push_back(get_collector_index()); + } + + set_collector_index(def._parent_index); + } + } + } + } + else { + if (_back_stack.empty()) { + _graph_view_controller.backToolbarItemVisible = YES; + } + _back_stack.push_back(get_collector_index()); + + // Clicking on any other label means to focus on that. + set_collector_index(collector_index); + } + + // Update window title and total label. + new_data(0, 0); + + _scale_area.needsDisplay = YES; +} + +/** + * Called when the mouse right-clicks on a label, and should return the menu + * that should pop up. + */ +NSMenu *MacStatsStripChart:: +get_label_menu(int collector_index) const { + NSMenu *menu = [[[NSMenu alloc] init] autorelease]; + + std::string label = get_label_tooltip(collector_index); + if (!label.empty()) { + if (@available(macOS 14.0, *)) { + [menu addItem:[NSMenuItem sectionHeaderWithTitle:[NSString stringWithUTF8String:label.c_str()]]]; + } else { + NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:[NSString stringWithUTF8String:label.c_str()] action:nil keyEquivalent:@""]; + item.enabled = NO; + [menu addItem:item]; + [item release]; + } + } + + { + NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:@"Set as Focus" action:@selector(handleSetAsFocus:) keyEquivalent:@""]; + item.target = _graph_view_controller; + item.tag = collector_index; + item.enabled = (collector_index != 0 || get_collector_index() != 0); + [menu addItem:item]; + [item release]; + } + + { + SEL action = get_view().get_show_level() ? @selector(handleOpenStripChartLevel:) : @selector(handleOpenStripChart:); + NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:@"Open Strip Chart" action:action keyEquivalent:@""]; + item.target = _menu_delegate; + item.tag = collector_index; + [menu addItem:item]; + [item release]; + } + + if (!get_view().get_show_level()) { + NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:@"Open Flame Graph" action:@selector(handleOpenFlameGraph:) keyEquivalent:@""]; + item.target = _menu_delegate; + item.tag = collector_index; + [menu addItem:item]; + [item release]; + } + + [menu addItem:[NSMenuItem separatorItem]]; + + { + NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:@"Change Color\u2026" action:@selector(handleChangeColor:) keyEquivalent:@""]; + item.target = _graph_view_controller; + item.tag = collector_index; + [menu addItem:item]; + [item release]; + } + + { + NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:@"Reset Color" action:@selector(handleResetColor:) keyEquivalent:@""]; + item.target = _graph_view_controller; + item.tag = collector_index; + [menu addItem:item]; + [item release]; + } + + return menu; +} + +/** + * Called when the mouse hovers over a label, and should return the text that + * should appear on the tooltip. + */ +std::string MacStatsStripChart:: +get_label_tooltip(int collector_index) const { + return PStatStripChart::get_label_tooltip(collector_index); +} + +/** + * Changes the value the height of the vertical axis represents. This may + * force a redraw. + */ +void MacStatsStripChart:: +set_vertical_scale(double value_height) { + PStatStripChart::set_vertical_scale(value_height); + + _graph_view.needsDisplay = YES; + _scale_area.needsDisplay = YES; +} + +/** + * Sets the vertical scale to make all the data visible. + */ +void MacStatsStripChart:: +set_auto_vertical_scale() { + PStatStripChart::set_auto_vertical_scale(); + set_vertical_scale(get_vertical_scale() * 1.5); + + _graph_view.needsDisplay = YES; + _scale_area.needsDisplay = YES; +} + +/** + * Resets the list of labels. + */ +void MacStatsStripChart:: +update_labels() { + PStatStripChart::update_labels(); + + _label_stack.clear_labels(); + for (int i = 0; i < get_num_labels(); i++) { + _label_stack.add_label(MacStatsGraph::_monitor, this, _thread_index, + get_label_collector(i), false); + } + _labels_changed = false; +} + +/** + * Erases the chart area. + */ +void MacStatsStripChart:: +clear_region() { + if (_ctx) { + //CGContextSetFillColorWithColor(_ctx, _background_color); + //CGContextFillRect(_ctx, CGRectMake(0, 0, get_xsize(), get_ysize())); + } +} + +/** + * Draws a single vertical slice of the strip chart, at the given pixel + * position, and corresponding to the indicated level data. + */ +void MacStatsStripChart:: +draw_slice(int x, int w, const PStatStripChart::FrameData &fdata) { + if (!_ctx) { + return; + } + + // Start by clearing the band first. + CGContextSetFillColorWithColor(_ctx, _background_color); + CGContextFillRect(_ctx, CGRectMake(x, 0, w, get_ysize())); + + double overall_time = 0.0; + int y = get_ysize(); + + FrameData::const_iterator fi; + for (fi = fdata.begin(); fi != fdata.end(); ++fi) { + const ColorData &cd = (*fi); + overall_time += cd._net_value; + + bool is_highlighted = cd._collector_index == _highlighted_index; + CGContextSetFillColorWithColor(_ctx, + MacStatsGraph::_monitor->get_collector_color(cd._collector_index, is_highlighted)); + + if (overall_time > get_vertical_scale()) { + // Off the top. Go ahead and clamp it by hand, in case it's so far off + // the top we'd overflow the 16-bit pixel value. + CGContextFillRect(_ctx, CGRectMake(x, 0, w, y)); + // And we can consider ourselves done now. + return; + } + + int top_y = height_to_pixel(overall_time); + CGContextFillRect(_ctx, CGRectMake(x, top_y, w, y - top_y)); + y = top_y; + } +} + +/** + * Draws a single vertical slice of background color. + */ +void MacStatsStripChart:: +draw_empty(int x, int w) { + if (!_ctx) { + return; + } + + CGContextSetFillColorWithColor(_ctx, _background_color); + CGContextFillRect(_ctx, CGRectMake(x, 0, w, get_ysize())); +} + +/** + * Draws a single vertical slice of foreground color. + */ +void MacStatsStripChart:: +draw_cursor(int x) { + if (!_ctx) { + return; + } + + CGContextBeginPath(_ctx); + CGContextMoveToPoint(_ctx, x, 0); + CGContextAddLineToPoint(_ctx, x, get_ysize()); + CGContextStrokePath(_ctx); +} + +/** + * Should be overridden by the user class. This hook will be called after + * drawing a series of color bars in the strip chart; it gives the pixel range + * that was just redrawn. + */ +void MacStatsStripChart:: +end_draw(int from_x, int to_x) { + _graph_view.needsDisplay = YES; +} + +/** + * Returns the current window dimensions. + */ +bool MacStatsStripChart:: +get_window_state(int &x, int &y, int &width, int &height, + bool &maximized, bool &minimized) const { + MacStatsGraph::get_window_state(x, y, width, height, maximized, minimized); + return true; +} + +/** + * Called to restore the graph window to its previous dimensions. + */ +void MacStatsStripChart:: +set_window_state(int x, int y, int width, int height, + bool maximized, bool minimized) { + MacStatsGraph::set_window_state(x, y, width, height, maximized, minimized); +} + +/** + * Called when the mouse right-clicks on the graph, and should return the menu + * that should pop up. + */ +NSMenu *MacStatsStripChart:: +get_graph_menu(int mouse_x, int mouse_y) const { + NSMenu *menu = nullptr; + if (_highlighted_index != -1) { + menu = get_label_menu(_highlighted_index); + } +/* + if (menu != nullptr) { + [menu addItem:[NSMenuItem separatorItem]]; + } else { + menu = [[[NSMenu alloc] init] autorelease]; + } + + NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:@"Smooth" action:@selector(handleToggleStripChartAverage:) keyEquivalent:@""]; + item.target = _graph_view_controller; + item.state = get_average_mode() ? NSOnState : NSOffState; + [menu addItem:item]; + [item release];*/ + return menu; +} + +/** + * Called when the mouse hovers over the graph, and should return the text that + * should appear on the tooltip. + */ +std::string MacStatsStripChart:: +get_graph_tooltip(int mouse_x, int mouse_y) const { + if (_highlighted_index != -1) { + return get_label_tooltip(_highlighted_index); + } + return std::string(); +} + +/** + * Based on the mouse position within the graph window, look for draggable + * things the mouse might be hovering over and return the appropriate DragMode + * enum or DM_none if nothing is indicated. + */ +MacStatsGraph::DragMode MacStatsStripChart:: +consider_drag_start(int graph_x, int graph_y) { + // See if the mouse is over a user-defined guide bar. + int y = graph_y; + double from_height = pixel_to_height(y + 2); + double to_height = pixel_to_height(y - 2); + _drag_guide_bar = find_user_guide_bar(from_height, to_height); + if (_drag_guide_bar >= 0) { + return DM_guide_bar; + } + + return MacStatsGraph::consider_drag_start(graph_x, graph_y); +} + +/** + * This should be called whenever the drag mode needs to change state. It + * provides hooks for a derived class to do something special. + */ +void MacStatsStripChart:: +set_drag_mode(MacStatsGraph::DragMode drag_mode) { + MacStatsGraph::set_drag_mode(drag_mode); +} + +/** + * Called when the mouse button is depressed within the graph window. + */ +void MacStatsStripChart:: +handle_button_press(int graph_x, int graph_y, bool double_click, int button) { + if (graph_x >= 0 && graph_y >= 0 && graph_x < get_xsize() && graph_y < get_ysize()) { + if (double_click && button == 0) { + // Double-clicking on a color bar in the graph is the same as double- + // clicking on the corresponding label. + on_click_label(get_collector_under_pixel(graph_x, graph_y)); + return; + } + + if (_potential_drag_mode == DM_none) { + set_drag_mode(DM_scale); + _drag_scale_start = pixel_to_height(graph_y); + // SetCapture(_graph_window); + return; + } + } + + if (_potential_drag_mode == DM_guide_bar && _drag_guide_bar >= 0) { + set_drag_mode(DM_guide_bar); + _drag_start_y = graph_y; + // SetCapture(_graph_window); + return; + } + + return MacStatsGraph::handle_button_press(graph_x, graph_y, + double_click, button); +} + +/** + * Called when the mouse button is released within the graph window. + */ +void MacStatsStripChart:: +handle_button_release(int graph_x, int graph_y) { + if (_drag_mode == DM_scale) { + set_drag_mode(DM_none); + // ReleaseCapture(); + return handle_motion(graph_x, graph_y); + } + else if (_drag_mode == DM_guide_bar) { + if (graph_y < 0 || graph_y >= get_ysize()) { + remove_user_guide_bar(_drag_guide_bar); + } else { + move_user_guide_bar(_drag_guide_bar, pixel_to_height(graph_y)); + } + set_drag_mode(DM_none); + // ReleaseCapture(); + return handle_motion(graph_x, graph_y); + } + + return MacStatsGraph::handle_button_release(graph_x, graph_y); +} + +/** + * Called when the mouse is moved within the graph window. + */ +void MacStatsStripChart:: +handle_motion(int graph_x, int graph_y) { + if (_drag_mode == DM_none && _potential_drag_mode == DM_none && + graph_x >= 0 && graph_y >= 0 && graph_x < get_xsize() && graph_y < get_ysize()) { + // When the mouse is over a color bar, highlight it. + int collector_index = get_collector_under_pixel(graph_x, graph_y); + _label_stack.highlight_label(collector_index); + on_enter_label(collector_index); + } + else { + // If the mouse is in some drag mode, stop highlighting. + _label_stack.highlight_label(-1); + on_leave_label(_highlighted_index); + } + + if (_drag_mode == DM_scale) { + double ratio = 1.0 - ((double)graph_y / (double)get_ysize()); + if (ratio > 0.0) { + double new_scale = _drag_scale_start / ratio; + if (!IS_NEARLY_EQUAL(get_vertical_scale(), new_scale)) { + // Disable smoothing while we do this expensive operation. + set_vertical_scale(_drag_scale_start / ratio); + } + } + return; + } + else if (_drag_mode == DM_new_guide_bar) { + // We haven't created the new guide bar yet; we won't until the mouse + // comes within the graph's region. + if (graph_y >= 0 && graph_y < get_ysize()) { + set_drag_mode(DM_guide_bar); + _drag_guide_bar = add_user_guide_bar(pixel_to_height(graph_y)); + return; + } + } + else if (_drag_mode == DM_guide_bar) { + move_user_guide_bar(_drag_guide_bar, pixel_to_height(graph_y)); + return; + } + + MacStatsGraph::handle_motion(graph_x, graph_y); +} + +/** + * Called when the mouse has left the graph window. + */ +void MacStatsStripChart:: +handle_leave() { + _label_stack.highlight_label(-1); + on_leave_label(_highlighted_index); + return; +} + +/** + * + */ +void MacStatsStripChart:: +handle_magnify(int graph_x, int graph_y, double scale) { + set_vertical_scale(get_vertical_scale() * (1.0 - scale)); +} + +/** + * Fills in the graph window. + */ +void MacStatsStripChart:: +handle_draw_graph(CGContextRef ctx, NSRect rect) { + MacStatsGraph::handle_draw_graph(ctx, rect); + + int width = get_xsize(); + + // Draw in the guide bars. + int num_guide_bars = get_num_guide_bars(); + for (int i = 0; i < num_guide_bars; i++) { + draw_guide_bar(ctx, 0, width, get_guide_bar(i)); + } + + int num_user_guide_bars = get_num_user_guide_bars(); + for (int i = 0; i < num_user_guide_bars; i++) { + draw_guide_bar(ctx, 0, width, get_user_guide_bar(i)); + } +} + +/** + * Fills in the scale area. + */ +void MacStatsStripChart:: +handle_draw_scale_area(CGContextRef ctx, NSRect rect) { + MacStatsGraph::handle_draw_scale_area(ctx, rect); + draw_guide_labels(ctx); +} + +/** + * Called when the mouse clicks the back button in the toolbar. + */ +void MacStatsStripChart:: +handle_back() { + if (!_back_stack.empty()) { + int collector_index = _back_stack.back(); + _back_stack.pop_back(); + set_collector_index(collector_index); + + // Update window title and total label. + new_data(0, 0); + _scale_area.needsDisplay = YES; + } + + if (_back_stack.empty()) { + _graph_view_controller.backToolbarItemVisible = NO; + } +} + +/** + * Draws the line for the indicated guide bar on the graph. + */ +void MacStatsStripChart:: +draw_guide_bar(CGContextRef ctx, int from_x, int to_x, + const PStatGraph::GuideBar &bar) { + int y = height_to_pixel(bar._height); + + if (y > 1) { + // Only draw it if it's not too close to the top. + /*switch (bar._style) { + case GBS_target: + CGContextSetRGBStrokeColor(ctx, rgb_light_gray[0], rgb_light_gray[1], rgb_light_gray[2], 1.0); + break; + + case GBS_user: + CGContextSetRGBStrokeColor(ctx, rgb_user_guide_bar[0], rgb_user_guide_bar[1], rgb_user_guide_bar[2], 1.0); + break; + + default: + CGContextSetRGBStrokeColor(ctx, rgb_dark_gray[0], rgb_dark_gray[1], rgb_dark_gray[2], 1.0); + break; + }*/ + CGContextSetStrokeColorWithColor(ctx, [NSColor gridColor].CGColor); + CGContextBeginPath(ctx); + CGContextMoveToPoint(ctx, from_x, y); + CGContextAddLineToPoint(ctx, to_x, y); + CGContextStrokePath(ctx); + } +} + +/** + * This is called during the servicing of the draw event. + */ +void MacStatsStripChart:: +draw_guide_labels(CGContextRef ctx) { + // Draw in the labels for the guide bars. + int last_y = 0; + + int i; + int num_guide_bars = get_num_guide_bars(); + for (i = 0; i < num_guide_bars; i++) { + last_y = draw_guide_label(ctx, get_guide_bar(i), last_y); + } + + GuideBar top_value = make_guide_bar(get_vertical_scale()); + draw_guide_label(ctx, top_value, last_y); + + last_y = 0; + int num_user_guide_bars = get_num_user_guide_bars(); + for (i = 0; i < num_user_guide_bars; i++) { + last_y = draw_guide_label(ctx, get_user_guide_bar(i), last_y); + } +} + +/** + * Draws the text for the indicated guide bar label to the right of the graph, + * unless it would overlap with the indicated last label, whose top pixel + * value is given. Returns the top pixel value of the new label. + */ +int MacStatsStripChart:: +draw_guide_label(CGContextRef ctx, const PStatGraph::GuideBar &bar, int last_y) { + NSColor *color; + switch (bar._style) { + case GBS_target: + color = [NSColor secondaryLabelColor]; + break; + + case GBS_user: + color = [NSColor tertiaryLabelColor]; + break; + + default: + color = [NSColor labelColor]; + break; + } + + int y = height_to_pixel(bar._height); + const std::string &label = bar._label; + + const CFStringRef keys[] = { + (__bridge CFStringRef)NSForegroundColorAttributeName, + (__bridge CFStringRef)NSFontAttributeName, + }; + const void *values[] = { + color, + [NSFont systemFontOfSize:0.0], + }; + CFDictionaryRef attribs = CFDictionaryCreate(kCFAllocatorDefault, (const void **)keys, (const void **)values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + + CFStringRef str = CFStringCreateWithCString(kCFAllocatorDefault, label.c_str(), kCFStringEncodingUTF8); + CFAttributedStringRef astr = CFAttributedStringCreate(kCFAllocatorDefault, str, attribs); + CFRelease(attribs); + CFRelease(str); + + CTLineRef line = CTLineCreateWithAttributedString(astr); + CFRelease(astr); + CGRect bounds = CTLineGetImageBounds(line, ctx); + int height = bounds.size.height; + + if (bar._style != GBS_user) { + double from_height = pixel_to_height(y + height); + double to_height = pixel_to_height(y - height); + if (find_user_guide_bar(from_height, to_height) >= 0) { + // Omit the label: there's a user-defined guide bar in the same space. + CFRelease(line); + return last_y; + } + } + + if (y > height && y < get_ysize() - height) { + // Now convert our y to a coordinate within our drawing area. + + int this_y = y - height / 2; + if (last_y < this_y || last_y > this_y + height) { + CGContextSetTextPosition(ctx, 4, get_ysize() - this_y - height); + CTLineDraw(line, ctx); + + last_y = this_y; + } + } + + CFRelease(line); + return last_y; +} + +@implementation MacStatsStripChartViewController + +- (NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar *)toolbar { + if (@available(macOS 10.15, *)) { + return @[@"smooth", @"sep", @"total"]; + } else { + return @[@"smooth", @"sep"]; + } +} + +- (NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar *)toolbar { + if (@available(macOS 10.15, *)) { + return @[@"smooth", @"sep", @"total"]; + } else { + return @[@"smooth", @"sep"]; + } +} + +- (NSToolbarItem *) toolbar:(NSToolbar *)toolbar + itemForItemIdentifier:(NSString *)ident + willBeInsertedIntoToolbar:(BOOL)flag { + + if (@available(macOS 11.0, *)) { + if ([ident isEqual:@"smooth"]) { + NSButton *button = [NSButton buttonWithTitle:@"Smooth" target:self action:@selector(handleToggleSmooth:)]; + button.image = [NSImage imageWithSystemSymbolName:@"alternatingcurrent" accessibilityDescription:@""]; + button.bezelStyle = NSBezelStyleTexturedRounded; + button.buttonType = NSButtonTypePushOnPushOff; + button.bordered = YES; + button.toolTip = @"Smooth"; + button.state = NSOffState; + NSToolbarItem *item = [[[NSToolbarItem alloc] initWithItemIdentifier:ident] autorelease]; + item.label = @"Smooth"; + item.view = button; + return item; + } + if ([ident isEqual:@"total"]) { + NSToolbarItem *item = [[[NSToolbarItem alloc] initWithItemIdentifier:ident] autorelease]; + item.label = @"Total"; + item.action = @selector(handleClickTotal:); + item.target = self; + [item setBordered:YES]; + return item; + } + } + + return [super toolbar:toolbar itemForItemIdentifier:ident willBeInsertedIntoToolbar:flag]; +} + +- (void)handleToggleSmooth:(NSMenuItem *)item { + MacStatsStripChart *graph = (MacStatsStripChart *)_graph; + graph->set_average_mode(item.state == NSOnState); +} + +- (void)handleClickTotal:(NSButton *)button { + MacStatsStripChart *graph = (MacStatsStripChart *)_graph; + graph->set_auto_vertical_scale(); +} + +@end diff --git a/pandatool/src/mac-stats/macStatsTimeline.h b/pandatool/src/mac-stats/macStatsTimeline.h new file mode 100644 index 0000000000..e26d5e7cae --- /dev/null +++ b/pandatool/src/mac-stats/macStatsTimeline.h @@ -0,0 +1,100 @@ +/** + * 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 macStatsTimeline.h + * @author rdb + * @date 2023-08-19 + */ + +#ifndef MACSTATSTIMELINE_H +#define MACSTATSTIMELINE_H + +#include "macStatsGraph.h" +#include "pStatTimeline.h" + +class MacStatsMonitor; + +/** + * A window that draws all of the start/stop event pairs on each thread on a + * horizontal scrolling timeline, with concurrent start/stop pairs stacked + * underneath each other. + */ +class MacStatsTimeline final : public PStatTimeline, public MacStatsGraph { +public: + MacStatsTimeline(MacStatsMonitor *monitor); + virtual ~MacStatsTimeline(); + + virtual void new_data(int thread_index, int frame_number); + virtual void force_redraw(); + virtual void changed_graph_size(int graph_xsize, int graph_ysize); + +protected: + virtual void clear_region(); + virtual void begin_draw(); + virtual void draw_separator(int row); + virtual void draw_guide_bar(int x, GuideBarStyle style); + virtual void draw_bar(int row, int from_x, int to_x, int collector_index, + const std::string &collector_name); + virtual void end_draw(); + virtual void idle(); + + virtual bool animate(double time, double dt); + + virtual bool get_window_state(int &x, int &y, int &width, int &height, + bool &maximized, bool &minimized) const; + virtual void set_window_state(int x, int y, int width, int height, + bool maximized, bool minimized); + + virtual NSMenu *get_graph_menu(int mouse_x, int mouse_y) const; + virtual std::string get_graph_tooltip(int mouse_x, int mouse_y) const; + virtual DragMode consider_drag_start(int graph_x, int graph_y); + + virtual bool handle_key(int graph_x, int graph_y, bool pressed, + UniChar c, unsigned short key_code); + virtual void handle_button_press(int graph_x, int graph_y, + bool double_click, int button); + virtual void handle_button_release(int graph_x, int graph_y); + virtual void handle_motion(int graph_x, int graph_y); + virtual void handle_leave(); + virtual void handle_scroll(); + virtual void handle_wheel(int graph_x, int graph_y, double dx, double dy); + virtual void handle_magnify(int graph_x, int graph_y, double scale); + virtual void handle_draw_graph(CGContextRef ctx, NSRect rect); + virtual void handle_draw_graph_overhang(CGContextRef ctx, NSRect rect); + virtual void handle_draw_scale_area(CGContextRef ctx, NSRect rect); + +public: + void handle_zoom_to(); + void handle_open_strip_chart(); + void handle_open_flame_graph(); + void handle_open_piano_roll(); + +private: + void draw_guide_bar(CGContextRef ctx, GuideBarStyle style, int x, int y, int height); + void draw_guide_labels(CGContextRef ctx); + void draw_guide_label(CGContextRef ctx, const GuideBar &bar); + + int row_to_pixel(int row) const { + return row * 4 * 5 + 4 - _scroll; + } + int pixel_to_row(int y) const { + return (y + _scroll - 4) / (4 * 5); + } + + NSView *_thread_area; + pvector > _thread_labels; + NSLayoutConstraint *_graph_height_constraint; + NSScrollView *_sidebar_scroll_view; + + int _highlighted_row = -1; + int _highlighted_x = 0; + int _scroll = 0; + mutable ColorBar _popup_bar; +}; + +#endif diff --git a/pandatool/src/mac-stats/macStatsTimeline.mm b/pandatool/src/mac-stats/macStatsTimeline.mm new file mode 100644 index 0000000000..4a971e7a2b --- /dev/null +++ b/pandatool/src/mac-stats/macStatsTimeline.mm @@ -0,0 +1,932 @@ +/** + * 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 macStatsTimeline.mm + * @author rdb + * @date 2023-08-19 + */ + +#include "macStatsTimeline.h" +#include "macStatsMonitor.h" +#include "macStatsLabelStack.h" +#include "macStatsScaleArea.h" +#include "pStatCollectorDef.h" + +@interface MacStatsTimelineViewController : MacStatsScrollableGraphViewController +@end + +static const int default_timeline_width = 1000; +static const int default_timeline_height = 300; + +static const int minimum_timeline_sidebar_width = 68; +static const int default_timeline_sidebar_width = 100; + +/** + * + */ +MacStatsTimeline:: +MacStatsTimeline(MacStatsMonitor *monitor) : + PStatTimeline(monitor, 0, 0), + MacStatsGraph(monitor, [MacStatsTimelineViewController alloc]) +{ + // Let's show the units on the guide bar labels. There's room. + set_guide_bar_units(get_guide_bar_units() | GBU_show_units); + + _window.title = @"Timeline"; + + if (@available(macOS 11.0, *)) { + _window.titleVisibility = NSWindowTitleHidden; + } + + // Set the initial size of the graph. + const ThreadRow &last_thread_row = _threads.back(); + int height = row_to_pixel(last_thread_row._row_offset + last_thread_row._rows.size()); + if (height < default_timeline_height) { + height = default_timeline_height; + } + height += _window.frame.size.height - _window.contentLayoutRect.size.height; + _graph_view.frame = NSMakeRect(0, 0, default_timeline_width, height); + _graph_view_controller.view.frame = NSMakeRect(0, 0, default_timeline_width, height); + + // Add a drawing area to the left of the graph to show the thread labels. + _thread_area = [[NSView alloc] initWithFrame:NSMakeRect(0, 0, default_timeline_sidebar_width, 0)]; + _thread_area.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable; + _thread_area.translatesAutoresizingMaskIntoConstraints = NO; + + // It's put inside a scroll view that tracks the main scroll view. + NSScrollView *scroll_view = [[NSScrollView alloc] initWithFrame:NSMakeRect(0, 0, default_timeline_sidebar_width, 0)]; + scroll_view.documentView = _thread_area; + scroll_view.drawsBackground = NO; + scroll_view.automaticallyAdjustsContentInsets = YES; + //scroll_view.translatesAutoresizingMaskIntoConstraints = NO; + scroll_view.hasHorizontalScroller = NO; + scroll_view.hasVerticalScroller = NO; + _sidebar_scroll_view = scroll_view; + + NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; + [center addObserver:_graph_view_controller + selector:@selector(handleSideScroll:) + name:NSScrollViewDidLiveScrollNotification + object:scroll_view]; + + NSViewController *sidebar_controller = [[NSViewController alloc] init]; + sidebar_controller.view = scroll_view; + + NSSplitViewController *svc = [[NSSplitViewController alloc] init]; + [svc addSplitViewItem:[NSSplitViewItem sidebarWithViewController:sidebar_controller]]; + [svc addSplitViewItem:[NSSplitViewItem splitViewItemWithViewController:_graph_view_controller]]; + + svc.splitViewItems[0].minimumThickness = minimum_timeline_sidebar_width; + svc.splitViewItems[0].canCollapse = NO; + + NSSplitView *split_view = svc.splitView; + split_view.vertical = YES; + split_view.dividerStyle = NSSplitViewDividerStyleThin; + split_view.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable; + _split_view = split_view; + + _window.contentViewController = svc; + + [svc release]; + [sidebar_controller release]; + + // Scale area goes on top, as a titlebar accessory view. + MacStatsScaleAreaController *scale_area_controller = [[MacStatsScaleAreaController alloc] initWithGraph:this]; + scale_area_controller.fullScreenMinHeight = 20; + scale_area_controller.layoutAttribute = NSLayoutAttributeRight; + _scale_area = scale_area_controller.view; + [_window addTitlebarAccessoryViewController:scale_area_controller]; + [scale_area_controller release]; + + [_thread_area.widthAnchor constraintEqualToAnchor:scroll_view.widthAnchor].active = YES; + [_thread_area.heightAnchor constraintEqualToAnchor:_graph_view.heightAnchor].active = YES; + + _graph_height_constraint = [_graph_view.heightAnchor constraintGreaterThanOrEqualToConstant:0]; + _graph_height_constraint.active = YES; + + [_window makeKeyAndOrderFront:nil]; +} + +/** + * + */ +MacStatsTimeline:: +~MacStatsTimeline() { + [_thread_area release]; + [_sidebar_scroll_view release]; +} + +/** + * Called as each frame's data is made available. There is no guarantee the + * frames will arrive in order, or that all of them will arrive at all. The + * monitor should be prepared to accept frames received out-of-order or + * missing. + */ +void MacStatsTimeline:: +new_data(int thread_index, int frame_number) { + PStatTimeline::new_data(thread_index, frame_number); +} + +/** + * Called when it is necessary to redraw the entire graph. + */ +void MacStatsTimeline:: +force_redraw() { + if (_ctx) { + PStatTimeline::force_redraw(); + } +} + +/** + * Called when the user has resized the window, forcing a resize of the graph. + */ +void MacStatsTimeline:: +changed_graph_size(int graph_xsize, int graph_ysize) { + PStatTimeline::changed_size(graph_xsize, graph_ysize); +} + +/** + * Erases the chart area. + */ +void MacStatsTimeline:: +clear_region() { + if (_ctx) { + CGContextSetFillColorWithColor(_ctx, _background_color); + CGContextFillRect(_ctx, CGRectMake(0, 0, get_xsize(), get_ysize())); + + CGContextSetTextMatrix(_ctx, CGAffineTransformMakeScale(1, -1)); + //draw_guide_labels(_ctx); + } +} + +/** + * Erases the chart area in preparation for drawing a bunch of bars. + */ +void MacStatsTimeline:: +begin_draw() { +} + +/** + * Draws a horizontal separator. + */ +void MacStatsTimeline:: +draw_separator(int row) { + if (_ctx) { + CGContextSetFillColorWithColor(_ctx, [NSColor gridColor].CGColor); + CGContextFillRect(_ctx, CGRectMake(0, (row_to_pixel(row) + row_to_pixel(row + 1)) / 2.0, get_xsize(), 4.0 / 3.0)); + } +} + +/** + * Draws a vertical guide bar. If the row is -1, draws it in all rows. + */ +void MacStatsTimeline:: +draw_guide_bar(int x, GuideBarStyle style) { + draw_guide_bar(_ctx, style, x, 0, get_ysize()); +} + +/** + * Draws a single bar in the chart for the indicated row, in the color for the + * given collector, for the indicated horizontal pixel range. + */ +void MacStatsTimeline:: +draw_bar(int row, int from_x, int to_x, int collector_index, + const std::string &collector_name) { + int top = row_to_pixel(row); + int bottom = row_to_pixel(row + 1); + int scale = 4; + + top += 1; + + MacStatsMonitor *monitor = MacStatsGraph::_monitor; + + bool is_highlighted = row == _highlighted_row && _highlighted_x >= from_x && _highlighted_x < to_x; + CGContextSetFillColorWithColor(_ctx, + monitor->get_collector_color(collector_index, is_highlighted)); + + if (to_x < from_x + 1) { + // Too tiny to draw. + } + else if (to_x < from_x + scale) { + // It's just a tiny sliver. This is a more reliable way to draw it. + CGRect rect = CGRectMake(from_x, top, to_x - from_x, bottom - top); + CGContextFillRect(_ctx, rect); + } + else { + int left = std::max(from_x, -scale - 1); + int right = std::min(std::max(to_x, from_x + 1), get_xsize() + scale); + + double radius = std::min((double)scale, (right - left) / 2.0); + CGContextBeginPath(_ctx); + CGContextAddArc(_ctx, right - radius - 0.5, top + radius, radius, -0.5 * M_PI, 0.0, NO); + CGContextAddArc(_ctx, right - radius - 0.5, bottom - radius, radius, 0.0, 0.5 * M_PI, NO); + CGContextAddArc(_ctx, left + radius, bottom - radius, radius, 0.5 * M_PI, M_PI, NO); + CGContextAddArc(_ctx, left + radius, top + radius, radius, M_PI, 1.5 * M_PI, NO); + CGContextClosePath(_ctx); + CGContextFillPath(_ctx); + + if ((to_x - from_x) >= scale * 4) { + // Only bother drawing the text if we've got some space to draw on. + const PStatClientData *client_data = monitor->get_client_data(); + const PStatCollectorDef &def = client_data->get_collector_def(collector_index); + + const CFStringRef keys[] = { + (__bridge CFStringRef)NSForegroundColorAttributeName, + (__bridge CFStringRef)NSFontAttributeName, + }; + const void *values[] = { + monitor->get_collector_text_color(collector_index, is_highlighted), + [NSFont systemFontOfSize:0.0], + }; + CFDictionaryRef attribs = CFDictionaryCreate(kCFAllocatorDefault, (const void **)keys, (const void **)values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + + CFStringRef str = CFStringCreateWithCString(kCFAllocatorDefault, def._name.c_str(), kCFStringEncodingUTF8); + CFAttributedStringRef astr = CFAttributedStringCreate(kCFAllocatorDefault, str, attribs); + + CTLineRef line = CTLineCreateWithAttributedString(astr); + CGRect bounds = CTLineGetImageBounds(line, _ctx); + CFRelease(astr); + CFRelease(str); + + int text_width = bounds.size.width; + int text_height = bounds.size.height; + + double center = (from_x + to_x) / 2.0; + double text_left = std::max(from_x, 0) + scale / 2.0; + double text_right = std::min(to_x, get_xsize()) - scale / 2.0; + double text_top = top + (bottom - top - text_height) / 2.0 + text_height; +/* + if (text_width >= text_right - text_left) { + size_t c = collector_name.rfind(':'); + if (text_right - text_left < scale * 6) { + // It's a really tiny space. Draw a single letter. + const char *ch = collector_name.data() + (c != std::string::npos ? c + 1 : 0); + pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER); + pango_layout_set_text(layout, ch, 1); + } else { + // Maybe just use everything after the last colon. + if (c != std::string::npos) { + pango_layout_set_text(layout, collector_name.data() + c + 1, + collector_name.size() - c - 1); + pango_layout_get_pixel_size(layout, &text_width, &text_height); + } + } + }*/ + + if (text_width >= text_right - text_left) { + // Have CoreText truncate to the correct length. + static CFStringRef token_str = CFSTR("\u2026"); + CFAttributedStringRef token_astr = CFAttributedStringCreate(kCFAllocatorDefault, token_str, attribs); + CTLineRef token_line = CTLineCreateWithAttributedString(token_astr); + CTLineRef trunc_line = CTLineCreateTruncatedLine(line, text_right - text_left, kCTLineTruncationEnd, token_line); + CFRelease(line); + CFRelease(token_astr); + CFRelease(token_line); + line = trunc_line; + CGContextSetTextPosition(_ctx, text_left, text_top); + } + else if (center - text_width / 2.0 < 0.0) { + // Put it against the left-most edge. + CGContextSetTextPosition(_ctx, scale, text_top); + } + else if (center + text_width / 2.0 >= get_xsize()) { + // Put it against the right-most edge. + CGContextSetTextPosition(_ctx, get_xsize() - scale - text_width, text_top); + } + else { + // It fits just fine, center it. + CGContextSetTextPosition(_ctx, center - text_width / 2.0, text_top); + } + + if (line != nullptr) { + CTLineDraw(line, _ctx); + CFRelease(line); + } + CFRelease(attribs); + } + } +} + +/** + * Called after all the bars have been drawn, this triggers a refresh event to + * draw it to the window. + */ +void MacStatsTimeline:: +end_draw() { + // Recalculate the size of the graph. + if (!_threads.empty()) { + const ThreadRow &last_thread_row = _threads.back(); + int new_height = row_to_pixel(last_thread_row._row_offset + last_thread_row._rows.size()); + _graph_height_constraint.constant = new_height; + } + + _graph_view.needsDisplay = YES; + + // If we scroll sideways while we're also scrolling vertically such that the + // overhang becomes visible due to elasticity, the overhang doesn't update. + // I could only find this private method for fixing this problem. + // Not needed as of macOS 14 and up, since the normal drawRect DTRT there. +#if __MAC_OS_X_VERSION_MAX_ALLOWED < 140000 + NSClipView *clip_view = ((MacStatsScrollableGraphViewController *)_graph_view_controller).clipView; + if ([clip_view respondsToSelector:@selector(_setNeedsDisplayInOverhang:)]) { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wobjc-method-access" + [clip_view _setNeedsDisplayInOverhang:YES]; +#pragma clang diagnostic pop + } +#endif + + if (_threads_changed) { + while (_thread_labels.size() < _threads.size()) { + NSTextField *label = [NSTextField labelWithString:@"Thread"]; + label.translatesAutoresizingMaskIntoConstraints = NO; + [_thread_area addSubview:label]; + + [label.rightAnchor constraintEqualToAnchor:_thread_area.rightAnchor constant:-8].active = YES; + [_thread_area.widthAnchor constraintGreaterThanOrEqualToAnchor:label.widthAnchor constant:16].active = YES; + + NSLayoutConstraint *constraint; + if (@available(macOS 11.0, *)) { + constraint = [label.topAnchor constraintEqualToAnchor:_thread_area.topAnchor]; + } else { + constraint = [label.topAnchor constraintEqualToAnchor:_thread_area.topAnchor]; + } + constraint.active = YES; + + _thread_labels.push_back(std::make_pair(label, constraint)); + } + + for (size_t i = 0; i < _threads.size(); ++i) { + const ThreadRow &thread_row = _threads[i]; + NSTextField *label = _thread_labels[i].first; + NSLayoutConstraint *label_constraint = _thread_labels[i].second; + + label.stringValue = [NSString stringWithUTF8String:thread_row._label.c_str()]; + label_constraint.constant = row_to_pixel(thread_row._row_offset); + } + + _thread_area.needsDisplay = YES; + _threads_changed = false; + } + + if (_guide_bars_changed) { + _scale_area.needsDisplay = YES; + _guide_bars_changed = false; + } +} + +/** + * Called at the end of the draw cycle. + */ +void MacStatsTimeline:: +idle() { +} + +/** + * Overridden by a derived class to implement an animation. If it returns + * false, the animation timer is stopped. + */ +bool MacStatsTimeline:: +animate(double time, double dt) { + return PStatTimeline::animate(time, dt); +} + +/** + * Returns the current window dimensions. + */ +bool MacStatsTimeline:: +get_window_state(int &x, int &y, int &width, int &height, + bool &maximized, bool &minimized) const { + MacStatsGraph::get_window_state(x, y, width, height, maximized, minimized); + return true; +} + +/** + * Called to restore the graph window to its previous dimensions. + */ +void MacStatsTimeline:: +set_window_state(int x, int y, int width, int height, + bool maximized, bool minimized) { + MacStatsGraph::set_window_state(x, y, width, height, maximized, minimized); +} + +/** + * Called when the mouse right-clicks on the graph, and should return the menu + * that should pop up. + */ +NSMenu *MacStatsTimeline:: +get_graph_menu(int graph_x, int graph_y) const { + int row = pixel_to_row(graph_y); + ColorBar bar; + if (!find_bar(row, graph_x, bar)) { + return nil; + } + + _popup_bar = bar; + + NSMenu *menu = [[[NSMenu alloc] init] autorelease]; + + std::string label = get_bar_tooltip(row, graph_x); + if (!label.empty()) { + if (@available(macOS 14.0, *)) { + [menu addItem:[NSMenuItem sectionHeaderWithTitle:[NSString stringWithUTF8String:label.c_str()]]]; + } else { + NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:[NSString stringWithUTF8String:label.c_str()] action:nil keyEquivalent:@""]; + item.enabled = NO; + [menu addItem:item]; + [item release]; + } + } + + { + NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:@"Zoom To" action:@selector(handleZoomTo:) keyEquivalent:@""]; + item.target = _graph_view_controller; + [menu addItem:item]; + [item release]; + } + + { + NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:@"Open Strip Chart" action:@selector(handleOpenStripChart:) keyEquivalent:@""]; + item.target = _graph_view_controller; + [menu addItem:item]; + [item release]; + } + + { + NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:@"Open Flame Graph" action:@selector(handleOpenFlameGraph:) keyEquivalent:@""]; + item.target = _graph_view_controller; + [menu addItem:item]; + [item release]; + } + + { + NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:@"Open Piano Roll" action:@selector(handleOpenPianoRoll:) keyEquivalent:@""]; + item.target = _graph_view_controller; + [menu addItem:item]; + [item release]; + } + + [menu addItem:[NSMenuItem separatorItem]]; + + { + NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:@"Change Color\u2026" action:@selector(handleChangeColor:) keyEquivalent:@""]; + item.target = _graph_view_controller; + item.tag = bar._collector_index; + [menu addItem:item]; + [item release]; + } + + { + NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:@"Reset Color" action:@selector(handleResetColor:) keyEquivalent:@""]; + item.target = _graph_view_controller; + item.tag = bar._collector_index; + [menu addItem:item]; + [item release]; + } + + return menu; +} + +/** + * Called when the mouse hovers over the graph, and should return the text that + * should appear on the tooltip. + */ +std::string MacStatsTimeline:: +get_graph_tooltip(int mouse_x, int mouse_y) const { + return PStatTimeline::get_bar_tooltip(pixel_to_row(mouse_y), mouse_x); +} + +/** + * Based on the mouse position within the graph window, look for draggable + * things the mouse might be hovering over and return the appropriate DragMode + * enum or DM_none if nothing is indicated. + */ +MacStatsGraph::DragMode MacStatsTimeline:: +consider_drag_start(int graph_x, int graph_y) { + return MacStatsGraph::consider_drag_start(graph_x, graph_y); +} + +/** + * + */ +bool MacStatsTimeline:: +handle_key(int graph_x, int graph_y, bool pressed, UniChar c, unsigned short key_code) { + // Accept WASD based on their position rather than their mapping + int flag = 0; + switch (key_code) { + case 13: + flag = F_w; + break; + case 0: + flag = F_a; + break; + case 1: + flag = F_s; + break; + case 2: + flag = F_d; + break; + } + if (flag == 0) { + switch (c) { + case 0x1c: + case NSLeftArrowFunctionKey: + flag = F_left; + break; + case 0x1d: + case NSRightArrowFunctionKey: + flag = F_right; + break; + case 'w': + flag = F_w; + break; + case 'a': + flag = F_a; + break; + case 's': + flag = F_s; + break; + case 'd': + flag = F_d; + break; + } + } + if (flag != 0) { + if (pressed) { + if (flag & (F_w | F_s)) { + _zoom_center = pixel_to_timestamp(graph_x); + } + if (_keys_held == 0) { + start_animation(); + } + _keys_held |= flag; + } + else if (_keys_held != 0) { + _keys_held &= ~flag; + } + return true; + } + return false; +} + +/** + * Called when the mouse button is depressed within the graph window. + */ +void MacStatsTimeline:: +handle_button_press(int graph_x, int graph_y, bool double_click, int button) { + if (graph_x >= 0 && graph_y >= 0 && graph_x < get_xsize() && graph_y < get_ysize()) { + if (double_click && button == 0) { + // Double-clicking on a color bar in the graph will zoom the graph into + // that collector. + int row = pixel_to_row(graph_y); + ColorBar bar; + if (find_bar(row, graph_x, bar)) { + double width = bar._end - bar._start; + zoom_to(width * 1.5, pixel_to_timestamp(graph_x)); + scroll_to(bar._start - width / 4.0); + } else { + // Double-clicking the white area zooms out. + _zoom_speed -= 100.0; + } + start_animation(); + } + + if (_potential_drag_mode == DM_none) { + set_drag_mode(DM_pan); + _drag_start_x = graph_x; + _scroll_speed = 0.0; + _zoom_center = pixel_to_timestamp(graph_x); + return; + } + } + + return MacStatsGraph::handle_button_press(graph_x, graph_y, + double_click, button); +} + +/** + * Called when the mouse button is released within the graph window. + */ +void MacStatsTimeline:: +handle_button_release(int graph_x, int graph_y) { + if (_drag_mode == DM_scale) { + set_drag_mode(DM_none); + // ReleaseCapture(); + return handle_motion(graph_x, graph_y); + } + else if (_drag_mode == DM_guide_bar) { + if (graph_x < 0 || graph_x >= get_xsize()) { + remove_user_guide_bar(_drag_guide_bar); + } else { + move_user_guide_bar(_drag_guide_bar, pixel_to_height(graph_x)); + } + set_drag_mode(DM_none); + // ReleaseCapture(); + return handle_motion(graph_x, graph_y); + } + + return MacStatsGraph::handle_button_release(graph_x, graph_y); +} + +/** + * Called when the mouse is moved within the graph window. + */ +void MacStatsTimeline:: +handle_motion(int graph_x, int graph_y) { + if (_drag_mode == DM_none && _potential_drag_mode == DM_none && + graph_x >= 0 && graph_y >= 0 && graph_x < get_xsize() && graph_y < get_ysize()) { + // When the mouse is over a color bar, highlight it. + int row = pixel_to_row(graph_y); + std::swap(_highlighted_x, graph_x); + std::swap(_highlighted_row, row); + + if (row >= 0) { + PStatTimeline::force_redraw(row, graph_x, graph_x); + } + PStatTimeline::force_redraw(_highlighted_row, _highlighted_x, _highlighted_x); + + if ((_keys_held & (F_w | F_s)) != 0) { + // Update the zoom center if we move the mouse while zooming with the + // keyboard. + _zoom_center = pixel_to_timestamp(graph_x); + } + } + else { + // If the mouse is in some drag mode, stop highlighting. + if (_highlighted_row != -1) { + int row = _highlighted_row; + _highlighted_row = -1; + PStatTimeline::force_redraw(row, _highlighted_x, _highlighted_x); + } + } + + if (_drag_mode == DM_pan) { + int delta = _drag_start_x - graph_x; + _drag_start_x = graph_x; + set_horizontal_scroll(get_horizontal_scroll() + pixel_to_height(delta)); + return; + } + + return MacStatsGraph::handle_motion(graph_x, graph_y); +} + +/** + * Called when the mouse has left the graph window. + */ +void MacStatsTimeline:: +handle_leave() { + if (_highlighted_row != -1) { + int row = _highlighted_row; + _highlighted_row = -1; + PStatTimeline::force_redraw(row, _highlighted_x, _highlighted_x); + } +} + +/** + * Called when the mouse is moved within the graph window. + */ +void MacStatsTimeline:: +handle_scroll() { + // Graph view is flipped, side bar isn't, so we need to convert coordinates + NSPoint point; + point.x = 0; + point.y = _graph_view.frame.size.height - (((NSScrollView *)_graph_view_controller.view).documentVisibleRect.size.height + ((NSScrollView *)_graph_view_controller.view).documentVisibleRect.origin.y); + [_sidebar_scroll_view.contentView scrollToPoint:point]; + [_sidebar_scroll_view reflectScrolledClipView:_sidebar_scroll_view.contentView]; +} + +/** + * + */ +void MacStatsTimeline:: +handle_wheel(int graph_x, int graph_y, double dx, double dy) { + if (dx != 0.0) { + _scroll_speed -= dx; + start_animation(); + } +} + +/** + * + */ +void MacStatsTimeline:: +handle_magnify(int graph_x, int graph_y, double scale) { + zoom_by(scale * 4.0, pixel_to_timestamp(graph_x)); + start_animation(); +} + +/** + * Fills in the graph window. + */ +void MacStatsTimeline:: +handle_draw_graph(CGContextRef ctx, NSRect rect) { +#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 140000 + for (const GuideBar &bar : _guide_bars) { + int x = timestamp_to_pixel(bar._height); + draw_guide_bar(ctx, bar._style, x, rect.origin.y, rect.size.height); + } +#endif + + MacStatsGraph::handle_draw_graph(ctx, rect); + + NSRect scale_frame = _scale_area.frame; + NSRect graph_frame = _graph_view.frame; + if (scale_frame.size.width != graph_frame.size.width) { + scale_frame.size.width = graph_frame.size.width; + _scale_area.frame = scale_frame; + } +} + +/** + * Fills in the graph window overhang, which is the area outside the graph + * bounds that may become visible momentarily due to scroll elasticity. + */ +void MacStatsTimeline:: +handle_draw_graph_overhang(CGContextRef ctx, NSRect rect) { + CGContextSetFillColorWithColor(ctx, _background_color); + CGContextFillRect(ctx, rect); + + for (const GuideBar &bar : _guide_bars) { + int x = timestamp_to_pixel(bar._height); + draw_guide_bar(ctx, bar._style, x, rect.origin.y, rect.size.height); + } +} + +/** + * Fills in the scale area. + */ +void MacStatsTimeline:: +handle_draw_scale_area(CGContextRef ctx, NSRect rect) { + MacStatsGraph::handle_draw_scale_area(ctx, rect); + + draw_guide_labels(ctx); + + CGContextSetFillColorWithColor(ctx, [NSColor gridColor].CGColor); + + for (const GuideBar &bar : _guide_bars) { + int x = timestamp_to_pixel(bar._height); + x = [_scale_area convertPoint:NSMakePoint(x, 0) fromView:_graph_view].x; + draw_guide_bar(ctx, bar._style, x, rect.origin.y, rect.size.height); + } +} + +/** + * + */ +void MacStatsTimeline:: +handle_zoom_to() { + const ColorBar &bar = _popup_bar; + double width = bar._end - bar._start; + zoom_to(width * 1.5, (bar._end + bar._start) / 2.0); + scroll_to(bar._start - width / 4.0); + start_animation(); +} + +/** + * + */ +void MacStatsTimeline:: +handle_open_strip_chart() { + const ColorBar &bar = _popup_bar; + MacStatsGraph::_monitor->open_strip_chart(bar._thread_index, bar._collector_index, false); +} + +/** + * + */ +void MacStatsTimeline:: +handle_open_flame_graph() { + const ColorBar &bar = _popup_bar; + MacStatsGraph::_monitor->open_flame_graph(bar._thread_index, bar._collector_index); +} + +/** + * + */ +void MacStatsTimeline:: +handle_open_piano_roll() { + const ColorBar &bar = _popup_bar; + MacStatsGraph::_monitor->open_piano_roll(bar._thread_index); +} + +/** + * Draws a vertical guide bar. If the row is -1, draws it in all rows. + */ +void MacStatsTimeline:: +draw_guide_bar(CGContextRef ctx, GuideBarStyle style, int x, int y, int height) { + double width = 1.0; + if (style == GBS_frame) { + width *= 2; + } + + CGContextSetFillColorWithColor(ctx, [NSColor gridColor].CGColor); + CGContextFillRect(ctx, CGRectMake(x - width / 2.0, y, width, height)); +} + +/** + * This is called during the servicing of the draw event. + */ +void MacStatsTimeline:: +draw_guide_labels(CGContextRef ctx) { + int num_guide_bars = get_num_guide_bars(); + for (int i = 0; i < num_guide_bars; i++) { + draw_guide_label(ctx, get_guide_bar(i)); + } +} + +/** + * Draws the text for the indicated guide bar label at the top of the graph. + */ +void MacStatsTimeline:: +draw_guide_label(CGContextRef ctx, const PStatGraph::GuideBar &bar) { + const std::string &label = bar._label; + if (label.empty()) { + return; + } + + NSColor *color; + if (@available(macOS 11.0, *)) { + color = [NSColor tertiaryLabelColor]; + } else { + // Otherwise it's hard to see on the dark titlebars + color = [NSColor windowFrameTextColor]; + } + /*switch (bar._style) { + case GBS_target: + color = [NSColor colorWithDeviceRed:rgb_light_gray[0] green:rgb_light_gray[1] blue:rgb_light_gray[2] alpha:1.0]; + break; + + case GBS_user: + color = [NSColor colorWithDeviceRed:rgb_user_guide_bar[0] green:rgb_user_guide_bar[1] blue:rgb_user_guide_bar[2] alpha:1.0]; + break; + + case GBS_normal: + color = [NSColor colorWithDeviceRed:rgb_light_gray[0] green:rgb_light_gray[1] blue:rgb_light_gray[2] alpha:1.0]; + break; + + case GBS_frame: + color = [NSColor colorWithDeviceRed:rgb_dark_gray[0] green:rgb_dark_gray[1] blue:rgb_dark_gray[2] alpha:1.0]; + break; + }*/ + + const CFStringRef keys[] = { + (__bridge CFStringRef)NSForegroundColorAttributeName, + (__bridge CFStringRef)NSFontAttributeName, + }; + const void *values[] = { + color, + [NSFont systemFontOfSize:0.0], + }; + CFDictionaryRef attribs = CFDictionaryCreate(kCFAllocatorDefault, (const void **)keys, (const void **)values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + + CFStringRef str = CFStringCreateWithCString(kCFAllocatorDefault, label.c_str(), kCFStringEncodingUTF8); + CFAttributedStringRef astr = CFAttributedStringCreate(kCFAllocatorDefault, str, attribs); + CFRelease(attribs); + CFRelease(str); + + CTLineRef line = CTLineCreateWithAttributedString(astr); + CFRelease(astr); + CGRect bounds = CTLineGetImageBounds(line, ctx); + //int height = bounds.size.height; + int width = bounds.size.width; + + NSRect graph_bounds = _graph_view.bounds; + + int x = timestamp_to_pixel(bar._height); + x = [_scale_area convertPoint:NSMakePoint(x, 0) fromView:_graph_view].x; + + if (x + width >= 0 && x + width < get_xsize()) { + if (x + width < graph_bounds.size.width) { + CGContextSetTextPosition(ctx, x + 6, 6); + CTLineDraw(line, ctx); + } + } + + CFRelease(line); +} + +@implementation MacStatsTimelineViewController + +- (void)handleZoomTo:(NSMenuItem *)item { + ((MacStatsTimeline *)_graph)->handle_zoom_to(); +} + +- (void)handleOpenStripChart:(NSMenuItem *)item { + ((MacStatsTimeline *)_graph)->handle_open_strip_chart(); +} + +- (void)handleOpenFlameGraph:(NSMenuItem *)item { + ((MacStatsTimeline *)_graph)->handle_open_flame_graph(); +} + +- (void)handleOpenPianoRoll:(NSMenuItem *)item { + ((MacStatsTimeline *)_graph)->handle_open_piano_roll(); +} + +@end + diff --git a/pandatool/src/mac-stats/macstats_composite1.mm b/pandatool/src/mac-stats/macstats_composite1.mm new file mode 100644 index 0000000000..5ae8136ab5 --- /dev/null +++ b/pandatool/src/mac-stats/macstats_composite1.mm @@ -0,0 +1,16 @@ +#include "macStats.mm" +#include "macStatsAppDelegate.mm" +#include "macStatsChartMenu.mm" +#include "macStatsChartMenuDelegate.mm" +#include "macStatsFlameGraph.mm" +#include "macStatsGraph.mm" +#include "macStatsGraphView.mm" +#include "macStatsGraphViewController.mm" +#include "macStatsLabel.mm" +#include "macStatsLabelStack.mm" +#include "macStatsMonitor.mm" +#include "macStatsPianoRoll.mm" +#include "macStatsScaleArea.mm" +#include "macStatsServer.mm" +#include "macStatsStripChart.mm" +#include "macStatsTimeline.mm" diff --git a/pandatool/src/pstatserver/pStatStripChart.cxx b/pandatool/src/pstatserver/pStatStripChart.cxx index f04d0b3249..7861ae8d90 100644 --- a/pandatool/src/pstatserver/pStatStripChart.cxx +++ b/pandatool/src/pstatserver/pStatStripChart.cxx @@ -988,7 +988,12 @@ draw_frames(int first_frame, int last_frame) { if (_scroll_mode) { // In scrolling mode, slide the world back. int slide_pixels = last_pixel - _xsize; + // This is really slow on macOS, just redraw instead +#ifdef __APPLE__ + draw_pixels(0, first_pixel - slide_pixels); +#else copy_region(slide_pixels, first_pixel, 0); +#endif first_pixel -= slide_pixels; last_pixel -= slide_pixels; _start_time += (double)slide_pixels / (double)_xsize * _time_width; From 144479d8e4dd67e3e5eafcfb0e5a0e14f712ca96 Mon Sep 17 00:00:00 2001 From: rdb Date: Sat, 16 Sep 2023 09:48:52 +0200 Subject: [PATCH 75/84] cocoa: squelch secure restorable state warning on macOS 14 --- panda/src/cocoadisplay/cocoaPandaAppDelegate.mm | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/panda/src/cocoadisplay/cocoaPandaAppDelegate.mm b/panda/src/cocoadisplay/cocoaPandaAppDelegate.mm index f64b2be56a..8662dc89af 100644 --- a/panda/src/cocoadisplay/cocoaPandaAppDelegate.mm +++ b/panda/src/cocoadisplay/cocoaPandaAppDelegate.mm @@ -26,6 +26,11 @@ return self; } +- (BOOL)applicationSupportsSecureRestorableState:(NSApplication *)app { + // Squelches an annoying warning. + return YES; +} + - (void)applicationDidFinishLaunching:(NSNotification *)notification { // This only seems to work when called here. [NSApp activateIgnoringOtherApps:YES]; From 8596207d8ebe51de13ae8786bdd7d3d89f9338c8 Mon Sep 17 00:00:00 2001 From: rdb Date: Sat, 16 Sep 2023 09:50:55 +0200 Subject: [PATCH 76/84] directnotify: Don't assume presence of softspace attribute --- direct/src/directnotify/RotatingLog.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/direct/src/directnotify/RotatingLog.py b/direct/src/directnotify/RotatingLog.py index d7b9b06d34..66ba5ed45f 100755 --- a/direct/src/directnotify/RotatingLog.py +++ b/direct/src/directnotify/RotatingLog.py @@ -83,7 +83,8 @@ class RotatingLog: self.closed = self.file.closed self.mode = self.file.mode self.name = self.file.name - self.softspace = self.file.softspace + if hasattr(self.file, 'softspace'): + self.softspace = self.file.softspace #self.encoding = self.file.encoding # Python 2.3 #self.newlines = self.file.newlines # Python 2.3, maybe From 27daecf030259041535c0ffb5cc42316a181769c Mon Sep 17 00:00:00 2001 From: rdb Date: Sat, 16 Sep 2023 09:52:55 +0200 Subject: [PATCH 77/84] Add .DS_Store to .gitignore --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 8dada724d7..ef35d1b86b 100644 --- a/.gitignore +++ b/.gitignore @@ -48,9 +48,10 @@ cmake_install.cmake install_manifest.txt CTestTestfile.cmake -# Windows +# Operating system Thumbs.db ehthumbs.db +.DS_Store # Python __pycache__/ From ba388e28666e28b752d326ba0e680421db3c9bb1 Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 17 Sep 2023 15:56:36 +0200 Subject: [PATCH 78/84] shader: More efficient state-based shader input fetching Previously every input was fetched as a matrix. Now, every input is fetched as a vector, with matrices taking up multiple vectors. This saves a lot of copying and a lot of space in the cache. Furthermore, integer state-based inputs can be defined (for future use) Naming still needs to be revised, since it's called the "mat part cache" etc. --- panda/src/display/graphicsStateGuardian.cxx | 586 +++++++++++--------- panda/src/display/graphicsStateGuardian.h | 8 +- panda/src/dxgsg9/dxShaderContext9.cxx | 102 +--- panda/src/dxgsg9/dxShaderContext9.h | 2 +- panda/src/glstuff/glCgShaderContext_src.cxx | 52 +- panda/src/glstuff/glCgShaderContext_src.h | 2 +- panda/src/glstuff/glShaderContext_src.cxx | 235 ++++---- panda/src/glstuff/glShaderContext_src.h | 2 +- panda/src/glstuff/glmisc_src.h | 8 - panda/src/gobj/shader.cxx | 213 +++++-- panda/src/gobj/shader.h | 48 +- 11 files changed, 649 insertions(+), 609 deletions(-) diff --git a/panda/src/display/graphicsStateGuardian.cxx b/panda/src/display/graphicsStateGuardian.cxx index 00672f6dbc..e29d48646d 100644 --- a/panda/src/display/graphicsStateGuardian.cxx +++ b/panda/src/display/graphicsStateGuardian.cxx @@ -887,12 +887,12 @@ compute_distance_to(const LPoint3 &point) const { * have changed based on the aspects of the render state that were altered. */ void GraphicsStateGuardian:: -update_shader_matrix_cache(Shader *shader, LMatrix4 *cache, int altered) { +update_shader_matrix_cache(Shader *shader, LVecBase4f *cache, int altered) { for (Shader::ShaderMatPart &part : shader->_mat_parts) { if (altered & part._dep) { fetch_specified_part(part._part, part._arg, cache, part._count); } - cache += part._count; + cache += part._count * part._size; } } @@ -921,51 +921,54 @@ update_shader_matrix_cache(Shader *shader, LMatrix4 *cache, int altered) { * This may allow data to be cached and not reevaluated. * */ -const LMatrix4 *GraphicsStateGuardian:: -fetch_specified_value(Shader::ShaderMatSpec &spec, const LMatrix4 *cache, int altered) { - LVecBase3 v; - - const LMatrix4 *cache0 = cache + spec._cache_offset[0]; - const LMatrix4 *cache1 = cache + spec._cache_offset[1]; +const LVecBase4f *GraphicsStateGuardian:: +fetch_specified_value(Shader::ShaderMatSpec &spec, const LVecBase4f *cache, int altered) { + LVecBase3f v; + const LVecBase4f *cache0 = cache + spec._cache_offset[0]; + const LVecBase4f *cache1 = cache + spec._cache_offset[1]; switch (spec._func) { + case Shader::SMF_first: + return cache0; + case Shader::SMF_compose: - spec._value.multiply((*cache0), (*cache1)); - return &spec._value; + spec._value.multiply(*(LMatrix4f *)cache0, *(LMatrix4f *)cache1); + return (LVecBase4f *)&spec._value; + case Shader::SMF_transform_dlight: - spec._value = (*cache0); - v = (*cache1).xform_vec((*cache0).get_row3(2)); + spec._value = *(LMatrix4f *)cache0; + v = (*(LMatrix4f *)cache1).xform_vec(cache0[2].get_xyz()); v.normalize(); spec._value.set_row(2, v); - v = (*cache1).xform_vec((*cache0).get_row3(3)); + v = (*(LMatrix4f *)cache1).xform_vec(cache0[3].get_xyz()); v.normalize(); spec._value.set_row(3, v); - return &spec._value; + return (LVecBase4f *)&spec._value; + case Shader::SMF_transform_plight: { // Careful not to touch the w component, which contains the near value. - spec._value = *cache0; - LPoint3 point = (*cache1).xform_point((*cache0).get_row3(2)); + spec._value = *(LMatrix4f *)cache0; + LPoint3f point = (*(LMatrix4f *)cache1).xform_point(cache0[2].get_xyz()); spec._value(2, 0) = point[0]; spec._value(2, 1) = point[1]; spec._value(2, 2) = point[2]; - return &spec._value; + return (LVecBase4f *)&spec._value; } + case Shader::SMF_transform_slight: - spec._value = *cache0; - spec._value.set_row(2, (*cache1).xform_point((*cache0).get_row3(2))); - v = (*cache1).xform_vec((*cache0).get_row3(3)); + spec._value = *(LMatrix4f *)cache0; + spec._value.set_row(2, (*(LMatrix4f *)cache1).xform_point(cache0[2].get_xyz())); + v = (*(LMatrix4f *)cache1).xform_vec(cache0[3].get_xyz()); v.normalize(); spec._value.set_row(3, v); - return &spec._value; - case Shader::SMF_first: - return cache0; - default: - // should never get here - spec._value = LMatrix4::ident_mat(); - return &spec._value; + return (LVecBase4f *)&spec._value; } + + // Should never get here + spec._value = LMatrix4f::ident_mat(); + return (LVecBase4f *)&spec._value; } /** @@ -973,30 +976,35 @@ fetch_specified_value(Shader::ShaderMatSpec &spec, const LMatrix4 *cache, int al */ void GraphicsStateGuardian:: fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, - LMatrix4 *into, int count) { + LVecBase4f *into, int count) { nassertv(count > 0); switch (part) { case Shader::SMO_identity: { for (int i = 0; i < count; ++i) { - into[i] = LMatrix4::ident_mat(); + ((LMatrix4f *)into)[i] = LMatrix4f::ident_mat(); } return; } case Shader::SMO_window_size: case Shader::SMO_pixel_size: { LVecBase2i pixel_size = _current_display_region->get_pixel_size(); - into[0] = LMatrix4::translate_mat(pixel_size[0], pixel_size[1], 0); + into[0].set(pixel_size[0], pixel_size[1], 0, 1); + return; + } + case Shader::SMO_frame_number: { + int count = ClockObject::get_global_clock()->get_frame_count(); + ((LVecBase4i *)into)[0].fill(count); return; } case Shader::SMO_frame_time: { PN_stdfloat time = ClockObject::get_global_clock()->get_frame_time(); - into[0].set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, time, time, time, time); + into[0].fill(time); return; } case Shader::SMO_frame_delta: { PN_stdfloat dt = ClockObject::get_global_clock()->get_dt(); - into[0].set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, dt, dt, dt, dt); + into[0].fill(dt); return; } case Shader::SMO_texpad_x: { @@ -1008,7 +1016,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, double cx = (sx * 0.5) / tex->get_x_size(); double cy = (sy * 0.5) / tex->get_y_size(); double cz = (sz * 0.5) / tex->get_z_size(); - into[0].set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, cx, cy, cz, 0); + into[0].set(cx, cy, cz, 0); return; } case Shader::SMO_texpix_x: { @@ -1017,7 +1025,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, double px = 1.0 / tex->get_x_size(); double py = 1.0 / tex->get_y_size(); double pz = 1.0 / tex->get_z_size(); - into[0].set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, px, py, pz, 0); + into[0].set(px, py, pz, 0); return; } case Shader::SMO_attr_material: { @@ -1025,53 +1033,52 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, _target_rs->get_attrib_def(MaterialAttrib::get_class_slot()); // Material matrix contains AMBIENT, DIFFUSE, EMISSION, SPECULAR+SHININESS if (target_material->is_off()) { - into[0].set(1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0); + into[0].set(1, 1, 1, 1); + into[1].set(1, 1, 1, 1); + into[2].set(0, 0, 0, 0); + into[3].set(0, 0, 0, 0); return; } Material *m = target_material->get_material(); - LVecBase4 const &amb = m->get_ambient(); - LVecBase4 const &dif = m->get_diffuse(); - LVecBase4 const &emm = m->get_emission(); LVecBase4 spc = m->get_specular(); spc[3] = m->get_shininess(); - into[0].set(amb[0], amb[1], amb[2], amb[3], - dif[0], dif[1], dif[2], dif[3], - emm[0], emm[1], emm[2], emm[3], - spc[0], spc[1], spc[2], spc[3]); + into[0] = LCAST(float, m->get_ambient()); + into[1] = LCAST(float, m->get_diffuse()); + into[2] = LCAST(float, m->get_emission()); + into[3] = LCAST(float, spc); return; } case Shader::SMO_attr_material2: { const MaterialAttrib *target_material = (const MaterialAttrib *) _target_rs->get_attrib_def(MaterialAttrib::get_class_slot()); if (target_material->is_off()) { - into[0].set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1); + into[0].set(0, 0, 0, 0); + into[1].set(0, 0, 0, 1); return; } Material *m = target_material->get_material(); - into[0].set_row(0, m->get_base_color()); - into[0].set_row(3, LVecBase4(m->get_metallic(), m->get_refractive_index(), 0, m->get_roughness())); + into[0] = LCAST(float, m->get_base_color()); + into[1].set(m->get_metallic(), m->get_refractive_index(), 0, m->get_roughness()); return; } case Shader::SMO_attr_color: { const ColorAttrib *target_color = (const ColorAttrib *) _target_rs->get_attrib_def(ColorAttrib::get_class_slot()); if (target_color->get_color_type() != ColorAttrib::T_flat) { - into[0] = LMatrix4::ones_mat(); + into[0].set(1, 1, 1, 1); return; } - LVecBase4 c = target_color->get_color(); - into[0].set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, c[0], c[1], c[2], c[3]); + into[0] = LCAST(float, target_color->get_color()); return; } case Shader::SMO_attr_colorscale: { const ColorScaleAttrib *target_color = (const ColorScaleAttrib *) _target_rs->get_attrib_def(ColorScaleAttrib::get_class_slot()); if (target_color->is_identity()) { - into[0] = LMatrix4::ones_mat(); + into[0].set(1, 1, 1, 1); return; } - LVecBase4 cs = target_color->get_scale(); - into[0].set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, cs[0], cs[1], cs[2], cs[3]); + into[0] = LCAST(float, target_color->get_scale()); return; } case Shader::SMO_attr_fog: { @@ -1079,13 +1086,12 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, _target_rs->get_attrib_def(FogAttrib::get_class_slot()); Fog *fog = target_fog->get_fog(); if (fog == nullptr) { - into[0].set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1); + into[0].set(0, 1, 1, 1); return; } PN_stdfloat start, end; fog->get_linear_range(start, end); - into[0].set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - fog->get_exp_density(), start, end, 1.0f / (end - start)); + into[0].set(fog->get_exp_density(), start, end, 1.0f / (end - start)); return; } case Shader::SMO_attr_fogcolor: { @@ -1093,11 +1099,10 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, _target_rs->get_attrib_def(FogAttrib::get_class_slot()); Fog *fog = target_fog->get_fog(); if (fog == nullptr) { - into[0] = LMatrix4::ones_mat(); + into[0].set(1, 1, 1, 1); return; } - LVecBase4 c = fog->get_color(); - into[0].set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, c[0], c[1], c[2], c[3]); + into[0] = LCAST(float, fog->get_color()); return; } case Shader::SMO_alight_x: { @@ -1105,8 +1110,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, nassertv(!np.is_empty()); AmbientLight *lt; DCAST_INTO_V(lt, np.node()); - LColor const &c = lt->get_color(); - into[0].set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, c[0], c[1], c[2], c[3]); + into[0] = LCAST(float, lt->get_color()); return; } case Shader::SMO_satten_x: { @@ -1116,7 +1120,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, DCAST_INTO_V(lt, np.node()); LVecBase3 const &a = lt->get_attenuation(); PN_stdfloat x = lt->get_exponent(); - into[0].set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, a[0], a[1], a[2], x); + into[0].set(a[0], a[1], a[2], x); return; } case Shader::SMO_dlight_x: { @@ -1127,16 +1131,16 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, DCAST_INTO_V(lt, np.node()); LColor const &c = lt->get_color(); LColor const &s = lt->get_specular_color(); - *into = np.get_net_transform()->get_mat() * - _scene_setup->get_world_transform()->get_mat(); - LVecBase3 d = -(into[0].xform_vec(lt->get_direction())); + LMatrix4 t = np.get_net_transform()->get_mat() * + _scene_setup->get_world_transform()->get_mat(); + LVecBase3 d = -(t.xform_vec(lt->get_direction())); d.normalize(); LVecBase3 h = d + LVecBase3(0,-1,0); h.normalize(); - into[0].set(c[0], c[1], c[2], c[3], - s[0], s[1], s[2], c[3], - d[0], d[1], d[2], 0, - h[0], h[1], h[2], 0); + into[0].set(c[0], c[1], c[2], c[3]); + into[1].set(s[0], s[1], s[2], c[3]); + into[2].set(d[0], d[1], d[2], 0); + into[3].set(h[0], h[1], h[2], 0); return; } case Shader::SMO_plight_x: { @@ -1147,17 +1151,17 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, DCAST_INTO_V(lt, np.node()); LColor const &c = lt->get_color(); LColor const &s = lt->get_specular_color(); - into[0] = np.get_net_transform()->get_mat() * - _scene_setup->get_world_transform()->get_mat(); - LVecBase3 p = (into[0].xform_point(lt->get_point())); + LMatrix4 t = np.get_net_transform()->get_mat() * + _scene_setup->get_world_transform()->get_mat(); + LVecBase3 p = (t.xform_point(lt->get_point())); LVecBase3 a = lt->get_attenuation(); Lens *lens = lt->get_lens(0); PN_stdfloat lnear = lens->get_near(); PN_stdfloat lfar = lens->get_far(); - into[0].set(c[0], c[1], c[2], c[3], - s[0], s[1], s[2], s[3], - p[0], p[1], p[2], lnear, - a[0], a[1], a[2], lfar); + into[0].set(c[0], c[1], c[2], c[3]); + into[1].set(s[0], s[1], s[2], s[3]); + into[2].set(p[0], p[1], p[2], lnear); + into[3].set(a[0], a[1], a[2], lfar); return; } case Shader::SMO_slight_x: { @@ -1171,14 +1175,14 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, LColor const &c = lt->get_color(); LColor const &s = lt->get_specular_color(); PN_stdfloat cutoff = ccos(deg_2_rad(lens->get_hfov() * 0.5f)); - into[0] = np.get_net_transform()->get_mat() * - _scene_setup->get_world_transform()->get_mat(); - LVecBase3 p = into[0].xform_point(lens->get_nodal_point()); - LVecBase3 d = -(into[0].xform_vec(lens->get_view_vector())); - into[0].set(c[0], c[1], c[2], c[3], - s[0], s[1], s[2], s[3], - p[0], p[1], p[2], 0, - d[0], d[1], d[2], cutoff); + LMatrix4 t = np.get_net_transform()->get_mat() * + _scene_setup->get_world_transform()->get_mat(); + LVecBase3 p = t.xform_point(lens->get_nodal_point()); + LVecBase3 d = -(t.xform_vec(lens->get_view_vector())); + into[0].set(c[0], c[1], c[2], c[3]); + into[1].set(s[0], s[1], s[2], s[3]); + into[2].set(p[0], p[1], p[2], 0); + into[3].set(d[0], d[1], d[2], cutoff); return; } case Shader::SMO_light_ambient: { @@ -1189,9 +1193,9 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, if (!target_light->has_any_on_light()) { // There are no lights at all. This means, to follow the fixed- // function model, we pretend there is an all-white ambient light. - into[0].set_row(3, LVecBase4(1, 1, 1, 1)); + into[0].set(1, 1, 1, 1); } else { - into[0].set_row(3, target_light->get_ambient_contribution()); + into[0] = LCAST(float, target_light->get_ambient_contribution()); } return; } @@ -1206,10 +1210,10 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, int i = 0; for (; i < num_stages; ++i) { - into[i] = tma->get_mat(ta->get_on_stage(i)); + ((LMatrix4f *)into)[i] = LCAST(float, tma->get_mat(ta->get_on_stage(i))); } for (; i < count; ++i) { - into[i] = LMatrix4::ident_mat(); + ((LMatrix4f *)into)[i] = LMatrix4f::ident_mat(); } return; } @@ -1224,10 +1228,10 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, int i = 0; for (; i < num_stages; ++i) { - into[i] = tma->get_transform(ta->get_on_stage(i))->get_inverse()->get_mat(); + ((LMatrix4f *)into)[i] = LCAST(float, tma->get_transform(ta->get_on_stage(i))->get_inverse()->get_mat()); } for (; i < count; ++i) { - into[i] = LMatrix4::ident_mat(); + ((LMatrix4f *)into)[i] = LMatrix4f::ident_mat(); } return; } @@ -1243,10 +1247,10 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, int i = 0; for (; i < num_stages; ++i) { LVecBase3 scale = tma->get_transform(ta->get_on_stage(i))->get_scale(); - into[i].set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, scale[0], scale[1], scale[2], 0); + into[i].set(scale[0], scale[1], scale[2], 0); } for (; i < count; ++i) { - into[i] = LMatrix4::ident_mat(); + into[i].set(0, 0, 0, 1); } return; } @@ -1261,10 +1265,10 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, int i = 0; for (; i < num_stages; ++i) { TextureStage *ts = ta->get_on_stage(i); - into[i].set_row(3, ts->get_color()); + into[i] = LCAST(float, ts->get_color()); } for (; i < count; ++i) { - into[i] = LMatrix4::ident_mat(); + into[i].set(0, 0, 0, 1); } return; } @@ -1280,10 +1284,10 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, int i = 0; for (; i < num_stages; ++i) { LVecBase3 value = tga->get_constant_value(ta->get_on_stage(i)); - into[i].set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, value[0], value[1], value[2], 1); + into[i].set(value[0], value[1], value[2], 1); } for (; i < count; ++i) { - into[i] = LMatrix4::ident_mat(); + into[i].set(0, 0, 0, 1); } return; } @@ -1301,10 +1305,10 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, for (; i < num_stages; ++i) { TextureStage *ts = ta->get_on_stage(i); PN_stdfloat v = (ta->get_on_texture(ts)->get_format() == Texture::F_alpha); - into[i].set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, v, v, v, 0); + into[i].set(v, v, v, 0); } for (; i < count; ++i) { - into[i] = LMatrix4::zeros_mat(); + into[i].set(0, 0, 0, 0); } return; } @@ -1313,8 +1317,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, nassertv(!np.is_empty()); const PlaneNode *plane_node; DCAST_INTO_V(plane_node, np.node()); - LPlane p = plane_node->get_plane(); - into[0].set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, p[0], p[1], p[2], p[3]); + into[0] = LCAST(float, plane_node->get_plane()); return; } case Shader::SMO_clipplane_x: { @@ -1322,7 +1325,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, _target_rs->get_attrib_def(cpa); int planenr = atoi(name->get_name().c_str()); if (planenr >= cpa->get_num_on_planes()) { - into[0] = LMatrix4::zeros_mat(); + into[0].set(0, 0, 0, 0); return; } const NodePath &np = cpa->get_on_plane(planenr); @@ -1336,7 +1339,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, if (!transform->is_identity()) { plane.xform(transform->get_mat()); } - into[0].set_row(3, plane); + into[0] = LCAST(float, plane); return; } case Shader::SMO_apiview_clipplane_i: { @@ -1356,122 +1359,125 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, plane.get_transform(_scene_setup->get_scene_root().get_parent())); LPlane xformed_plane = plane_node->get_plane() * transform->get_mat(); - into[i].set_row(3, xformed_plane); + into[i] = LCAST(float, xformed_plane); } for (; i < count; ++i) { // Fill the remainder with zeroes. - into[i] = LMatrix4::zeros_mat(); + into[i].set(0, 0, 0, 0); } return; } case Shader::SMO_mat_constant_x: { - _target_shader->get_shader_input_matrix(name, into[0]); +#ifdef STDFLOAT_DOUBLE + LMatrix4 tmp; + _target_shader->get_shader_input_matrix(name, tmp); + *(LMatrix4f *)into = LCAST(float, tmp); +#else + _target_shader->get_shader_input_matrix(name, *(LMatrix4f *)into); +#endif return; } case Shader::SMO_vec_constant_x: { - const LVecBase4 &input = _target_shader->get_shader_input_vector(name); - const PN_stdfloat *data = input.get_data(); - into[0].set(data[0], data[1], data[2], data[3], - data[0], data[1], data[2], data[3], - data[0], data[1], data[2], data[3], - data[0], data[1], data[2], data[3]); + into[0] = LCAST(float, _target_shader->get_shader_input_vector(name)); return; } case Shader::SMO_world_to_view: { - into[0] = _scene_setup->get_world_transform()->get_mat(); + *(LMatrix4f *)into = LCAST(float, _scene_setup->get_world_transform()->get_mat()); return; } case Shader::SMO_view_to_world: { - into[0] = _scene_setup->get_camera_transform()->get_mat(); + *(LMatrix4f *)into = LCAST(float, _scene_setup->get_camera_transform()->get_mat()); return; } case Shader::SMO_model_to_view: { - into[0] = _inv_cs_transform->compose(_internal_transform)->get_mat(); + *(LMatrix4f *)into = LCAST(float, _inv_cs_transform->compose(_internal_transform)->get_mat()); return; } case Shader::SMO_model_to_apiview: { - into[0] = _internal_transform->get_mat(); + *(LMatrix4f *)into = LCAST(float, _internal_transform->get_mat()); return; } case Shader::SMO_view_to_model: { - into[0] = _internal_transform->invert_compose(_cs_transform)->get_mat(); + *(LMatrix4f *)into = LCAST(float, _internal_transform->invert_compose(_cs_transform)->get_mat()); return; } case Shader::SMO_apiview_to_model: { - into[0] = _internal_transform->get_inverse()->get_mat(); + *(LMatrix4f *)into = LCAST(float, _internal_transform->get_inverse()->get_mat()); return; } case Shader::SMO_apiview_to_view: { - into[0] = _inv_cs_transform->get_mat(); + *(LMatrix4f *)into = LCAST(float, _inv_cs_transform->get_mat()); return; } case Shader::SMO_view_to_apiview: { - into[0] = _cs_transform->get_mat(); + *(LMatrix4f *)into = LCAST(float, _cs_transform->get_mat()); return; } case Shader::SMO_clip_to_view: { if (_current_lens->get_coordinate_system() == _coordinate_system) { - into[0] = _current_lens->get_projection_mat_inv(_current_stereo_channel); + *(LMatrix4f *)into = LCAST(float, _current_lens->get_projection_mat_inv(_current_stereo_channel)); } else { - into[0] = _current_lens->get_projection_mat_inv(_current_stereo_channel) * - LMatrix4::convert_mat(_current_lens->get_coordinate_system(), _coordinate_system); + *(LMatrix4f *)into = LCAST(float, + _current_lens->get_projection_mat_inv(_current_stereo_channel) * + LMatrix4::convert_mat(_current_lens->get_coordinate_system(), _coordinate_system)); } return; } case Shader::SMO_view_to_clip: { if (_current_lens->get_coordinate_system() == _coordinate_system) { - into[0] = _current_lens->get_projection_mat(_current_stereo_channel); + *(LMatrix4f *)into = LCAST(float, _current_lens->get_projection_mat(_current_stereo_channel)); } else { - into[0] = LMatrix4::convert_mat(_coordinate_system, _current_lens->get_coordinate_system()) * - _current_lens->get_projection_mat(_current_stereo_channel); + *(LMatrix4f *)into = LCAST(float, + LMatrix4::convert_mat(_coordinate_system, _current_lens->get_coordinate_system()) * + _current_lens->get_projection_mat(_current_stereo_channel)); } return; } case Shader::SMO_apiclip_to_view: { - into[0] = _projection_mat_inv->get_mat() * _inv_cs_transform->get_mat(); + *(LMatrix4f *)into = LCAST(float, _projection_mat_inv->get_mat() * _inv_cs_transform->get_mat()); return; } case Shader::SMO_view_to_apiclip: { - into[0] = _cs_transform->get_mat() * _projection_mat->get_mat(); + *(LMatrix4f *)into = LCAST(float, _cs_transform->get_mat() * _projection_mat->get_mat()); return; } case Shader::SMO_apiclip_to_apiview: { - into[0] = _projection_mat_inv->get_mat(); + *(LMatrix4f *)into = LCAST(float, _projection_mat_inv->get_mat()); return; } case Shader::SMO_apiview_to_apiclip: { - into[0] = _projection_mat->get_mat(); + *(LMatrix4f *)into = LCAST(float, _projection_mat->get_mat()); return; } case Shader::SMO_view_x_to_view: { const NodePath &np = _target_shader->get_shader_input_nodepath(name); nassertv(!np.is_empty()); - into[0] = np.get_net_transform()->get_mat() * - _scene_setup->get_world_transform()->get_mat(); + *(LMatrix4f *)into = LCAST(float, np.get_net_transform()->get_mat() * + _scene_setup->get_world_transform()->get_mat()); return; } case Shader::SMO_view_to_view_x: { const NodePath &np = _target_shader->get_shader_input_nodepath(name); nassertv(!np.is_empty()); - into[0] = _scene_setup->get_camera_transform()->get_mat() * - np.get_net_transform()->get_inverse()->get_mat(); + *(LMatrix4f *)into = LCAST(float, _scene_setup->get_camera_transform()->get_mat() * + np.get_net_transform()->get_inverse()->get_mat()); return; } case Shader::SMO_apiview_x_to_view: { const NodePath &np = _target_shader->get_shader_input_nodepath(name); nassertv(!np.is_empty()); - into[0] = LMatrix4::convert_mat(_internal_coordinate_system, _coordinate_system) * + *(LMatrix4f *)into = LCAST(float, LMatrix4::convert_mat(_internal_coordinate_system, _coordinate_system) * np.get_net_transform()->get_mat() * - _scene_setup->get_world_transform()->get_mat(); + _scene_setup->get_world_transform()->get_mat()); return; } case Shader::SMO_view_to_apiview_x: { const NodePath &np = _target_shader->get_shader_input_nodepath(name); nassertv(!np.is_empty()); - into[0] = (_scene_setup->get_camera_transform()->get_mat() * + *(LMatrix4f *)into = LCAST(float, (_scene_setup->get_camera_transform()->get_mat() * np.get_net_transform()->get_inverse()->get_mat() * - LMatrix4::convert_mat(_coordinate_system, _internal_coordinate_system)); + LMatrix4::convert_mat(_coordinate_system, _internal_coordinate_system))); return; } case Shader::SMO_clip_x_to_view: { @@ -1480,10 +1486,10 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, const LensNode *node; DCAST_INTO_V(node, np.node()); const Lens *lens = node->get_lens(); - into[0] = lens->get_projection_mat_inv(_current_stereo_channel) * + *(LMatrix4f *)into = LCAST(float, lens->get_projection_mat_inv(_current_stereo_channel) * LMatrix4::convert_mat(lens->get_coordinate_system(), _coordinate_system) * np.get_net_transform()->get_mat() * - _scene_setup->get_world_transform()->get_mat(); + _scene_setup->get_world_transform()->get_mat()); return; } case Shader::SMO_view_to_clip_x: { @@ -1492,10 +1498,10 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, const LensNode *node; DCAST_INTO_V(node, np.node()); const Lens *lens = node->get_lens(); - into[0] = _scene_setup->get_camera_transform()->get_mat() * + *(LMatrix4f *)into = LCAST(float, _scene_setup->get_camera_transform()->get_mat() * np.get_net_transform()->get_inverse()->get_mat() * LMatrix4::convert_mat(_coordinate_system, lens->get_coordinate_system()) * - lens->get_projection_mat(_current_stereo_channel); + lens->get_projection_mat(_current_stereo_channel)); return; } case Shader::SMO_apiclip_x_to_view: { @@ -1504,10 +1510,10 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, const LensNode *node; DCAST_INTO_V(node, np.node()); const Lens *lens = node->get_lens(); - into[0] = calc_projection_mat(lens)->get_inverse()->get_mat() * + *(LMatrix4f *)into = LCAST(float, calc_projection_mat(lens)->get_inverse()->get_mat() * get_cs_transform_for(lens->get_coordinate_system())->get_inverse()->get_mat() * np.get_net_transform()->get_mat() * - _scene_setup->get_world_transform()->get_mat(); + _scene_setup->get_world_transform()->get_mat()); return; } case Shader::SMO_view_to_apiclip_x: { @@ -1516,17 +1522,23 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, const LensNode *node; DCAST_INTO_V(node, np.node()); const Lens *lens = node->get_lens(); - into[0] = _scene_setup->get_camera_transform()->get_mat() * + *(LMatrix4f *)into = LCAST(float, _scene_setup->get_camera_transform()->get_mat() * np.get_net_transform()->get_inverse()->get_mat() * get_cs_transform_for(lens->get_coordinate_system())->get_mat() * - calc_projection_mat(lens)->get_mat(); + calc_projection_mat(lens)->get_mat()); return; } case Shader::SMO_mat_constant_x_attrib: { if (_target_shader->has_shader_input(name)) { // There is an input specifying precisely this whole thing, with dot and // all. Support this, even if only for backward compatibility. - _target_shader->get_shader_input_matrix(name, into[0]); +#ifdef STDFLOAT_DOUBLE + LMatrix4 tmp; + _target_shader->get_shader_input_matrix(name, tmp); + *(LMatrix4f *)into = LCAST(float, tmp); +#else + _target_shader->get_shader_input_matrix(name, *(LMatrix4f *)into); +#endif return; } @@ -1540,11 +1552,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, if (_target_shader->has_shader_input(name)) { // There is an input specifying precisely this whole thing, with dot and // all. Support this, even if only for backward compatibility. - const LVecBase4 &data = _target_shader->get_shader_input_vector(name); - into[0].set(data[0], data[1], data[2], data[3], - data[0], data[1], data[2], data[3], - data[0], data[1], data[2], data[3], - data[0], data[1], data[2], data[3]); + into[0] = LCAST(float, _target_shader->get_shader_input_vector(name)); return; } @@ -1554,7 +1562,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, fetch_specified_member(np, name->get_basename(), into[0]); return; } - case Shader::SMO_light_source_i_attrib: { + case Shader::SMO_light_source_i_vec_attrib: { const LightAttrib *target_light; _target_rs->get_attrib_def(target_light); @@ -1571,7 +1579,8 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, // Apply the default OpenGL lights otherwise. // Special exception for light 0, which defaults to white. if (i == 0) { - into[0] = LMatrix4::ones_mat(); + //FIXME: only the color attribute + into[0].set(1, 1, 1, 1); ++i; } for (; i < (size_t)count; ++i) { @@ -1579,6 +1588,45 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, } return; } + case Shader::SMO_apiview_to_apiclip_light_source_i: { + static const LMatrix4 biasmat(0.5f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.5f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.5f, 0.0f, + 0.5f, 0.5f, 0.5f, 1.0f); + + const LightAttrib *target_light; + _target_rs->get_attrib_def(target_light); + + // We don't count ambient lights, which would be pretty silly to handle + // via this mechanism. + size_t num_lights = std::min((size_t)count, target_light->get_num_non_ambient_lights()); + + size_t i = 0; + for (i = 0; i < num_lights; ++i) { + NodePath light = target_light->get_on_light(i); + nassertv(!light.is_empty()); + + LensNode *lnode; + DCAST_INTO_V(lnode, light.node()); + Lens *lens = lnode->get_lens(); + + LMatrix4 t = _inv_cs_transform->get_mat() * + _scene_setup->get_camera_transform()->get_mat() * + light.get_net_transform()->get_inverse()->get_mat() * + LMatrix4::convert_mat(_coordinate_system, lens->get_coordinate_system()); + + if (!lnode->is_of_type(PointLight::get_class_type())) { + t *= lens->get_projection_mat() * biasmat; + } + ((LMatrix4f *)into)[i] = LCAST(float, t); + } + + // Apply just the bias matrix otherwise. + for (; i < (size_t)count; ++i) { + ((LMatrix4f *)into)[i] = LCAST(float, biasmat); + } + return; + } case Shader::SMO_light_source_i_packed: { // The light matrix contains COLOR, ATTENUATION, POSITION, VIEWVECTOR const LightAttrib *target_light; @@ -1595,8 +1643,8 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, PandaNode *node = np.node(); Light *light = node->as_light(); nassertv(light != nullptr); - into[i].set_row(0, light->get_color()); - into[i].set_row(1, light->get_attenuation()); + into[0] = LCAST(float, light->get_color()); + into[1] = LVecBase4f(LCAST(float, light->get_attenuation()), 0); LMatrix4 mat = np.get_net_transform()->get_mat() * _scene_setup->get_world_transform()->get_mat(); @@ -1604,47 +1652,50 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, if (node->is_of_type(DirectionalLight::get_class_type())) { LVecBase3 d = mat.xform_vec(((const DirectionalLight *)node)->get_direction()); d.normalize(); - into[i].set_row(2, LVecBase4(d, 0)); - into[i].set_row(3, LVecBase4(-d, 0)); - - } else if (node->is_of_type(LightLensNode::get_class_type())) { + into[2] = LVecBase4f(LCAST(float, d), 0); + into[3] = LVecBase4f(-LCAST(float, d), 0); + } + else if (node->is_of_type(LightLensNode::get_class_type())) { const Lens *lens = ((const LightLensNode *)node)->get_lens(); LPoint3 p = mat.xform_point(lens->get_nodal_point()); - into[i].set_row(3, LVecBase4(p)); + into[3] = LVecBase4f(LCAST(float, p)); // For shadowed point light we need to store near/far. // For spotlight we need to store cutoff angle. if (node->is_of_type(Spotlight::get_class_type())) { PN_stdfloat cutoff = ccos(deg_2_rad(lens->get_hfov() * 0.5f)); LVecBase3 d = -(mat.xform_vec(lens->get_view_vector())); - into[i].set_cell(1, 3, ((const Spotlight *)node)->get_exponent()); - into[i].set_row(2, LVecBase4(d, cutoff)); - - } else if (node->is_of_type(PointLight::get_class_type())) { - into[i].set_cell(1, 3, lens->get_far()); - into[i].set_cell(3, 3, lens->get_near()); + into[1][3] = ((const Spotlight *)node)->get_exponent(); + into[2] = LVecBase4f(LCAST(float, d), cutoff); + } + else if (node->is_of_type(PointLight::get_class_type())) { + into[1][3] = lens->get_far(); + into[3][3] = lens->get_near(); if (node->is_of_type(SphereLight::get_class_type())) { - into[i].set_cell(2, 3, ((const SphereLight *)node)->get_radius()); + into[2][3] = ((const SphereLight *)node)->get_radius(); } } } + + into += i * 4; } // Apply the default OpenGL lights otherwise. // Special exception for light 0, which defaults to white. if (i == 0) { - into[0].set(1, 1, 1, 1, - 1, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0); + into[0].set(1, 1, 1, 1); + into[1].set(1, 0, 0, 0); + into[2].set(0, 0, 0, 0); + into[3].set(0, 0, 0, 0); ++i; } for (; i < (size_t)count; ++i) { - into[i].set(0, 0, 0, 0, - 1, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0); + into[0].set(0, 0, 0, 0); + into[1].set(1, 0, 0, 0); + into[2].set(0, 0, 0, 0); + into[3].set(0, 0, 0, 0); + into += i * 4; } return; } @@ -1672,7 +1723,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, } } - into[0].set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, thickness, catten, patten, 0.0f); + into[0].set(thickness, catten, patten, 0.0f); return; } default: @@ -1686,7 +1737,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, * the value for the given member. */ void GraphicsStateGuardian:: -fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t) { +fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LVecBase4f &v) { // This system is not ideal. It will be improved in the future. static const CPT_InternalName IN_color("color"); static const CPT_InternalName IN_ambient("ambient"); @@ -1702,7 +1753,6 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t) static const CPT_InternalName IN_constantAttenuation("constantAttenuation"); static const CPT_InternalName IN_linearAttenuation("linearAttenuation"); static const CPT_InternalName IN_quadraticAttenuation("quadraticAttenuation"); - static const CPT_InternalName IN_shadowViewMatrix("shadowViewMatrix"); PandaNode *node = nullptr; if (!np.is_empty()) { @@ -1711,68 +1761,68 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t) if (attrib == IN_color) { if (node == nullptr) { - t = LMatrix4::ident_mat(); + v.set(0, 0, 0, 1); return; } Light *light = node->as_light(); nassertv(light != nullptr); - LColor c = light->get_color(); - t.set_row(3, c); - - } else if (attrib == IN_ambient) { + v = LCAST(float, light->get_color()); + } + else if (attrib == IN_ambient) { if (node == nullptr) { - t = LMatrix4::ident_mat(); + v.set(0, 0, 0, 1); return; } Light *light = node->as_light(); nassertv(light != nullptr); if (node->is_ambient_light()) { - LColor c = light->get_color(); - t.set_row(3, c); + v = LCAST(float, light->get_color()); } else { // Non-ambient lights don't currently have an ambient color in Panda3D. - t.set_row(3, LColor(0.0f, 0.0f, 0.0f, 1.0f)); + v.set(0, 0, 0, 1); } - - } else if (attrib == IN_diffuse) { + } + else if (attrib == IN_diffuse) { if (node == nullptr) { - t = LMatrix4::ident_mat(); + v.set(0, 0, 0, 1); return; } Light *light = node->as_light(); nassertv(light != nullptr); if (node->is_ambient_light()) { // Ambient light has no diffuse color. - t.set_row(3, LColor(0.0f, 0.0f, 0.0f, 1.0f)); + v.set(0, 0, 0, 1); } else { - LColor c = light->get_color(); - t.set_row(3, c); + v = LCAST(float, light->get_color()); } - - } else if (attrib == IN_specular) { + } + else if (attrib == IN_specular) { if (node == nullptr) { - t = LMatrix4::ident_mat(); + v.set(0, 0, 0, 1); return; } Light *light = node->as_light(); nassertv(light != nullptr); - t.set_row(3, light->get_specular_color()); - - } else if (attrib == IN_position) { + v = LCAST(float, light->get_specular_color()); + } + else if (attrib == IN_position) { if (np.is_empty()) { - t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0); - } else if (node->is_ambient_light()) { + v.set(0, 0, 1, 0); + } + else if (node->is_ambient_light()) { // Ambient light has no position. - t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - } else if (node->is_of_type(DirectionalLight::get_class_type())) { + v.set(0, 0, 0, 0); + } + else if (node->is_of_type(DirectionalLight::get_class_type())) { DirectionalLight *light; DCAST_INTO_V(light, node); CPT(TransformState) transform = np.get_transform(_scene_setup->get_scene_root().get_parent()); LVector3 dir = -(light->get_direction() * transform->get_mat()); dir *= _scene_setup->get_cs_world_transform()->get_mat(); - t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, dir[0], dir[1], dir[2], 0); - } else { + v.set(dir[0], dir[1], dir[2], 0); + } + else { LightLensNode *light; DCAST_INTO_V(light, node); Lens *lens = light->get_lens(); @@ -1784,16 +1834,18 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t) const LMatrix4 &light_mat = transform->get_mat(); LPoint3 pos = lens->get_nodal_point() * light_mat; - t = LMatrix4::translate_mat(pos); + v.set(pos[0], pos[1], pos[2], 1); } - - } else if (attrib == IN_halfVector) { + } + else if (attrib == IN_halfVector) { if (np.is_empty()) { - t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0); - } else if (node->is_ambient_light()) { + v.set(0, 0, 1, 0); + } + else if (node->is_ambient_light()) { // Ambient light has no half-vector. - t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - } else if (node->is_of_type(DirectionalLight::get_class_type())) { + v.set(0, 0, 0, 0); + } + else if (node->is_of_type(DirectionalLight::get_class_type())) { DirectionalLight *light; DCAST_INTO_V(light, node); @@ -1803,8 +1855,9 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t) dir.normalize(); dir += LVector3(0, 0, 1); dir.normalize(); - t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, dir[0], dir[1], dir[2], 1); - } else { + v.set(dir[0], dir[1], dir[2], 1); + } + else { LightLensNode *light; DCAST_INTO_V(light, node); Lens *lens = light->get_lens(); @@ -1819,16 +1872,18 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t) pos.normalize(); pos += LVector3(0, 0, 1); pos.normalize(); - t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, pos[0],pos[1],pos[2], 1); + v.set(pos[0], pos[1], pos[2], 1); } - - } else if (attrib == IN_spotDirection) { + } + else if (attrib == IN_spotDirection) { if (node == nullptr) { - t.set_row(3, LVector3(0.0f, 0.0f, -1.0f)); - } else if (node->is_ambient_light()) { + v.set(0, 0, -1, 0); + } + else if (node->is_ambient_light()) { // Ambient light has no spot direction. - t.set_row(3, LVector3(0.0f, 0.0f, 0.0f)); - } else { + v.set(0, 0, 0, 0); + } + else { LightLensNode *light; DCAST_INTO_V(light, node); Lens *lens = light->get_lens(); @@ -1840,10 +1895,10 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t) const LMatrix4 &light_mat = transform->get_mat(); LVector3 dir = lens->get_view_vector() * light_mat; - t.set_row(3, dir); + v.set(dir[0], dir[1], dir[2], 0); } - - } else if (attrib == IN_spotCutoff) { + } + else if (attrib == IN_spotCutoff) { if (node != nullptr && node->is_of_type(Spotlight::get_class_type())) { LightLensNode *light; @@ -1852,13 +1907,14 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t) nassertv(lens != nullptr); float cutoff = lens->get_hfov() * 0.5f; - t.set_row(3, LVecBase4(cutoff)); - } else { - // Other lights have no cut-off. - t.set_row(3, LVecBase4(180)); + v.fill(cutoff); } - - } else if (attrib == IN_spotCosCutoff) { + else { + // Other lights have no cut-off. + v.fill(180); + } + } + else if (attrib == IN_spotCosCutoff) { if (node != nullptr && node->is_of_type(Spotlight::get_class_type())) { LightLensNode *light; @@ -1867,91 +1923,67 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t) nassertv(lens != nullptr); float cutoff = lens->get_hfov() * 0.5f; - t.set_row(3, LVecBase4(ccos(deg_2_rad(cutoff)))); + v.fill(ccos(deg_2_rad(cutoff))); } else { // Other lights have no cut-off. - t.set_row(3, LVecBase4(-1)); + v.fill(-1); } - - } else if (attrib == IN_spotExponent) { + } + else if (attrib == IN_spotExponent) { if (node == nullptr) { - t = LMatrix4::zeros_mat(); + v.fill(0); return; } Light *light = node->as_light(); nassertv(light != nullptr); - t.set_row(3, LVecBase4(light->get_exponent())); - - } else if (attrib == IN_attenuation) { + v.fill(light->get_exponent()); + } + else if (attrib == IN_attenuation) { if (node != nullptr) { Light *light = node->as_light(); nassertv(light != nullptr); - t.set_row(3, LVecBase4(light->get_attenuation(), 0)); + v = LVecBase4f(LCAST(float, light->get_attenuation()), 0); } else { - t.set_row(3, LVecBase4(1, 0, 0, 0)); + v.set(1, 0, 0, 0); } - - } else if (attrib == IN_constantAttenuation) { + } + else if (attrib == IN_constantAttenuation) { if (node == nullptr) { - t = LMatrix4::ones_mat(); + v.fill(1); return; } Light *light = node->as_light(); nassertv(light != nullptr); - t.set_row(3, LVecBase4(light->get_attenuation()[0])); - - } else if (attrib == IN_linearAttenuation) { + v.fill(light->get_attenuation()[0]); + } + else if (attrib == IN_linearAttenuation) { if (node == nullptr) { - t = LMatrix4::zeros_mat(); + v.fill(0); return; } Light *light = node->as_light(); nassertv(light != nullptr); - t.set_row(3, LVecBase4(light->get_attenuation()[1])); - - } else if (attrib == IN_quadraticAttenuation) { + v.fill(light->get_attenuation()[1]); + } + else if (attrib == IN_quadraticAttenuation) { if (node == nullptr) { - t = LMatrix4::zeros_mat(); + v.fill(0); return; } Light *light = node->as_light(); nassertv(light != nullptr); - t.set_row(3, LVecBase4(light->get_attenuation()[2])); - - } else if (attrib == IN_shadowViewMatrix) { - static const LMatrix4 biasmat(0.5f, 0.0f, 0.0f, 0.0f, - 0.0f, 0.5f, 0.0f, 0.0f, - 0.0f, 0.0f, 0.5f, 0.0f, - 0.5f, 0.5f, 0.5f, 1.0f); - - if (node == nullptr) { - t = biasmat; - return; - } - - LensNode *lnode; - DCAST_INTO_V(lnode, node); - Lens *lens = lnode->get_lens(); - - t = _inv_cs_transform->get_mat() * - _scene_setup->get_camera_transform()->get_mat() * - np.get_net_transform()->get_inverse()->get_mat() * - LMatrix4::convert_mat(_coordinate_system, lens->get_coordinate_system()); - - if (!node->is_of_type(PointLight::get_class_type())) { - t *= lens->get_projection_mat() * biasmat; - } - - } else { + v.fill(light->get_attenuation()[2]); + } + else { display_cat.error() << "Shader input requests invalid attribute " << *attrib << " from node " << np << "\n"; - t = LMatrix4::ident_mat(); + v.set(0, 0, 0, 1); } } diff --git a/panda/src/display/graphicsStateGuardian.h b/panda/src/display/graphicsStateGuardian.h index 78869cabd6..617174e667 100644 --- a/panda/src/display/graphicsStateGuardian.h +++ b/panda/src/display/graphicsStateGuardian.h @@ -336,12 +336,12 @@ public: virtual void clear(DrawableRegion *clearable); - void update_shader_matrix_cache(Shader *shader, LMatrix4 *cache, int altered); - const LMatrix4 *fetch_specified_value(Shader::ShaderMatSpec &spec, const LMatrix4 *cache, int altered); + void update_shader_matrix_cache(Shader *shader, LVecBase4f *cache, int altered); + const LVecBase4f *fetch_specified_value(Shader::ShaderMatSpec &spec, const LVecBase4f *cache, int altered); void fetch_specified_part(Shader::ShaderMatInput input, InternalName *name, - LMatrix4 *into, int count = 1); + LVecBase4f *into, int count = 1); void fetch_specified_member(const NodePath &np, CPT_InternalName member, - LMatrix4 &t); + LVecBase4f &v); PT(Texture) fetch_specified_texture(Shader::ShaderTexSpec &spec, SamplerState &sampler, int &view); const Shader::ShaderPtrData *fetch_ptr_parameter(const Shader::ShaderPtrSpec& spec); diff --git a/panda/src/dxgsg9/dxShaderContext9.cxx b/panda/src/dxgsg9/dxShaderContext9.cxx index a4f3f7e24a..5a3dd6a44d 100644 --- a/panda/src/dxgsg9/dxShaderContext9.cxx +++ b/panda/src/dxgsg9/dxShaderContext9.cxx @@ -75,7 +75,7 @@ DXShaderContext9(Shader *s, GSG *gsg) : ShaderContext(s) { } #endif - _mat_part_cache = new LMatrix4[s->cp_get_mat_cache_size()]; + _mat_part_cache = new LVecBase4f[s->cp_get_mat_cache_size()]; } /** @@ -184,14 +184,6 @@ unbind(GSG *gsg) { * the parameters were issued, no part of the render state has changed except * the external and internal transforms. */ - -#if DEBUG_SHADER -PN_stdfloat *global_data = 0; -ShaderContext::ShaderMatSpec *global_shader_mat_spec = 0; -InternalName *global_internal_name_0 = 0; -InternalName *global_internal_name_1 = 0; -#endif - void DXShaderContext9:: issue_parameters(GSG *gsg, int altered) { #ifdef HAVE_CG @@ -249,106 +241,42 @@ issue_parameters(GSG *gsg, int altered) { continue; } - const LMatrix4 *val = gsg->fetch_specified_value(spec, _mat_part_cache, altered); + const LVecBase4f *val = gsg->fetch_specified_value(spec, _mat_part_cache, altered); if (val) { - HRESULT hr; - PN_stdfloat v [4]; - LMatrix4f temp_matrix = LCAST(float, *val); + const float *data = (const float *)val + spec._offset; + LVecBase4f v; + LMatrix4f temp_matrix; LMatrix3f temp_matrix3; - hr = D3D_OK; - - const float *data; - data = temp_matrix.get_data(); - -#if DEBUG_SHADER - // DEBUG - global_data = (PN_stdfloat *)data; - global_shader_mat_spec = &spec; - global_internal_name_0 = global_shader_mat_spec->_arg[0]; - global_internal_name_1 = global_shader_mat_spec->_arg[1]; -#endif - switch (spec._piece) { - case Shader::SMP_whole: + case Shader::SMP_mat4_whole: // TRANSPOSE REQUIRED - temp_matrix.transpose_in_place(); + temp_matrix.transpose_from(*(const LMatrix4f *)data); data = temp_matrix.get_data(); - - hr = cgD3D9SetUniform(p, data); break; - case Shader::SMP_transpose: - // NO TRANSPOSE REQUIRED - hr = cgD3D9SetUniform(p, data); + case Shader::SMP_mat4_column: + v.set(data[0], data[4], data[8], data[12]); + data = v.get_data(); break; - case Shader::SMP_row0: - hr = cgD3D9SetUniform(p, data + 0); - break; - case Shader::SMP_row1: - hr = cgD3D9SetUniform(p, data + 4); - break; - case Shader::SMP_row2: - hr = cgD3D9SetUniform(p, data + 8); - break; - case Shader::SMP_row3x1: - case Shader::SMP_row3x2: - case Shader::SMP_row3x3: - case Shader::SMP_row3: - hr = cgD3D9SetUniform(p, data + 12); - break; - - case Shader::SMP_col0: - v[0] = data[0]; v[1] = data[4]; v[2] = data[8]; v[3] = data[12]; - hr = cgD3D9SetUniform(p, v); - break; - case Shader::SMP_col1: - v[0] = data[1]; v[1] = data[5]; v[2] = data[9]; v[3] = data[13]; - hr = cgD3D9SetUniform(p, v); - break; - case Shader::SMP_col2: - v[0] = data[2]; v[1] = data[6]; v[2] = data[10]; v[3] = data[14]; - hr = cgD3D9SetUniform(p, v); - break; - case Shader::SMP_col3: - v[0] = data[3]; v[1] = data[7]; v[2] = data[11]; v[3] = data[15]; - hr = cgD3D9SetUniform(p, v); - break; - - case Shader::SMP_upper3x3: + case Shader::SMP_mat4_upper3x3: // TRANSPOSE REQUIRED - temp_matrix3 = temp_matrix.get_upper_3(); - temp_matrix3.transpose_in_place(); + temp_matrix3.set(data[0], data[4], data[8], data[1], data[5], data[9], data[2], data[6], data[10]); data = temp_matrix3.get_data(); - - hr = cgD3D9SetUniform(p, data); break; - case Shader::SMP_transpose3x3: + case Shader::SMP_mat4_transpose3x3: // NO TRANSPOSE REQUIRED - temp_matrix3 = temp_matrix.get_upper_3(); + temp_matrix3.set(data[0], data[1], data[2], data[4], data[5], data[6], data[8], data[9], data[10]); data = temp_matrix3.get_data(); - - hr = cgD3D9SetUniform(p, data); break; - case Shader::SMP_cell15: - hr = cgD3D9SetUniform(p, data + 15); - continue; - case Shader::SMP_cell14: - hr = cgD3D9SetUniform(p, data + 14); - continue; - case Shader::SMP_cell13: - hr = cgD3D9SetUniform(p, data + 13); - continue; - default: - dxgsg9_cat.error() - << "issue_parameters () SMP parameter type not implemented " << spec._piece << "\n"; break; } + HRESULT hr = cgD3D9SetUniform(p, data); if (FAILED(hr)) { std::string name = "unnamed"; diff --git a/panda/src/dxgsg9/dxShaderContext9.h b/panda/src/dxgsg9/dxShaderContext9.h index c02dcea201..f9179069ab 100644 --- a/panda/src/dxgsg9/dxShaderContext9.h +++ b/panda/src/dxgsg9/dxShaderContext9.h @@ -87,7 +87,7 @@ private: pvector _cg_parameter_map; #endif - LMatrix4 *_mat_part_cache = nullptr; + LVecBase4f *_mat_part_cache = nullptr; private: void release_resources(void); diff --git a/panda/src/glstuff/glCgShaderContext_src.cxx b/panda/src/glstuff/glCgShaderContext_src.cxx index edf23b0658..daf671ce04 100644 --- a/panda/src/glstuff/glCgShaderContext_src.cxx +++ b/panda/src/glstuff/glCgShaderContext_src.cxx @@ -329,7 +329,7 @@ CLP(CgShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderConte } } - _mat_part_cache = new LMatrix4[_shader->cp_get_mat_cache_size()]; + _mat_part_cache = new LVecBase4f[_shader->cp_get_mat_cache_size()]; _glgsg->report_my_gl_errors(); } @@ -699,46 +699,36 @@ issue_parameters(int altered) { continue; } - const LMatrix4 *val = _glgsg->fetch_specified_value(spec, _mat_part_cache, altered); + const LVecBase4f *val = _glgsg->fetch_specified_value(spec, _mat_part_cache, altered); if (!val) continue; - const PN_stdfloat *data = val->get_data(); + const float *data = val->get_data(); + data += spec._offset; CGparameter p = _cg_parameter_map[spec._id._seqno]; switch (spec._piece) { - case Shader::SMP_whole: GLfc(cgGLSetMatrixParameter)(p, data); continue; - case Shader::SMP_transpose: GLfr(cgGLSetMatrixParameter)(p, data); continue; - case Shader::SMP_col0: GLf(cgGLSetParameter4)(p, data[0], data[4], data[ 8], data[12]); continue; - case Shader::SMP_col1: GLf(cgGLSetParameter4)(p, data[1], data[5], data[ 9], data[13]); continue; - case Shader::SMP_col2: GLf(cgGLSetParameter4)(p, data[2], data[6], data[10], data[14]); continue; - case Shader::SMP_col3: GLf(cgGLSetParameter4)(p, data[3], data[7], data[11], data[15]); continue; - case Shader::SMP_row0: GLfv(cgGLSetParameter4)(p, data+ 0); continue; - case Shader::SMP_row1: GLfv(cgGLSetParameter4)(p, data+ 4); continue; - case Shader::SMP_row2: GLfv(cgGLSetParameter4)(p, data+ 8); continue; - case Shader::SMP_row3: GLfv(cgGLSetParameter4)(p, data+12); continue; - case Shader::SMP_row3x1: GLfv(cgGLSetParameter1)(p, data+12); continue; - case Shader::SMP_row3x2: GLfv(cgGLSetParameter2)(p, data+12); continue; - case Shader::SMP_row3x3: GLfv(cgGLSetParameter3)(p, data+12); continue; - case Shader::SMP_upper3x3: + case Shader::SMP_float: cgGLSetParameter1f(p, data[0]); continue; + case Shader::SMP_vec2: cgGLSetParameter2fv(p, data); continue; + case Shader::SMP_vec3: cgGLSetParameter3fv(p, data); continue; + case Shader::SMP_vec4: cgGLSetParameter4fv(p, data); continue; + case Shader::SMP_mat4_whole: cgGLSetMatrixParameterfc(p, data); continue; + case Shader::SMP_mat4_transpose: cgGLSetMatrixParameterfr(p, data); continue; + case Shader::SMP_mat4_column: cgGLSetParameter4f(p, data[0], data[4], data[ 8], data[12]); continue; + case Shader::SMP_mat4_upper3x3: { - LMatrix3 upper3 = val->get_upper_3(); - GLfc(cgGLSetMatrixParameter)(p, upper3.get_data()); + LMatrix3f upper3(data[0], data[1], data[2], data[4], data[5], data[6], data[8], data[9], data[10]); + cgGLSetMatrixParameterfc(p, upper3.get_data()); continue; } - case Shader::SMP_transpose3x3: + case Shader::SMP_mat4_transpose3x3: { - LMatrix3 upper3 = val->get_upper_3(); - GLfr(cgGLSetMatrixParameter)(p, upper3.get_data()); + LMatrix3f upper3(data[0], data[1], data[2], data[4], data[5], data[6], data[8], data[9], data[10]); + cgGLSetMatrixParameterfr(p, upper3.get_data()); continue; } - case Shader::SMP_cell15: - GLf(cgGLSetParameter1)(p, data[15]); - continue; - case Shader::SMP_cell14: - GLf(cgGLSetParameter1)(p, data[14]); - continue; - case Shader::SMP_cell13: - GLf(cgGLSetParameter1)(p, data[13]); - continue; + case Shader::SMP_int: cgSetParameter1i(p, ((const int *)data)[0]); continue; + case Shader::SMP_ivec2: cgSetParameter2iv(p, (const int *)data); continue; + case Shader::SMP_ivec3: cgSetParameter3iv(p, (const int *)data); continue; + case Shader::SMP_ivec4: cgSetParameter4iv(p, (const int *)data); continue; } } } diff --git a/panda/src/glstuff/glCgShaderContext_src.h b/panda/src/glstuff/glCgShaderContext_src.h index 35a2d5dd36..587504bb68 100644 --- a/panda/src/glstuff/glCgShaderContext_src.h +++ b/panda/src/glstuff/glCgShaderContext_src.h @@ -75,7 +75,7 @@ private: long _transform_table_size; long _slider_table_size; - LMatrix4 *_mat_part_cache = nullptr; + LVecBase4f *_mat_part_cache = nullptr; pvector _cg_parameter_map; WCPT(RenderState) _state_rs; diff --git a/panda/src/glstuff/glShaderContext_src.cxx b/panda/src/glstuff/glShaderContext_src.cxx index c3af8f63fa..1d74f61c25 100644 --- a/panda/src/glstuff/glShaderContext_src.cxx +++ b/panda/src/glstuff/glShaderContext_src.cxx @@ -152,30 +152,54 @@ parse_and_set_short_hand_shader_vars(Shader::ShaderArgId &arg_id, GLenum param_t // Decide whether this is a matrix or vector. if (param_type == GL_FLOAT_MAT4) { - if (pieces[0] == "trans") bind._piece = Shader::SMP_whole; - else if (pieces[0] == "tpose") bind._piece = Shader::SMP_transpose; + if (pieces[0] == "trans") bind._piece = Shader::SMP_mat4_whole; + else if (pieces[0] == "tpose") bind._piece = Shader::SMP_mat4_transpose; else { GLCAT.error() << basename << " should be vec4, not mat3\n"; return false; } } else if (param_type == GL_FLOAT_MAT3) { - if (pieces[0] == "trans") bind._piece = Shader::SMP_upper3x3; - else if (pieces[0] == "tpose") bind._piece = Shader::SMP_transpose3x3; + if (pieces[0] == "trans") bind._piece = Shader::SMP_mat4_upper3x3; + else if (pieces[0] == "tpose") bind._piece = Shader::SMP_mat4_transpose3x3; else { GLCAT.error() << basename << " should be vec4, not mat3\n"; return false; } } else if (param_type == GL_FLOAT_VEC4) { - if (pieces[0] == "trans") bind._piece = Shader::SMP_col0; - else if (pieces[0] == "tpose") bind._piece = Shader::SMP_row0; - else if (pieces[0] == "row0") bind._piece = Shader::SMP_row0; - else if (pieces[0] == "row1") bind._piece = Shader::SMP_row1; - else if (pieces[0] == "row2") bind._piece = Shader::SMP_row2; - else if (pieces[0] == "row3") bind._piece = Shader::SMP_row3; - else if (pieces[0] == "col0") bind._piece = Shader::SMP_col0; - else if (pieces[0] == "col1") bind._piece = Shader::SMP_col1; - else if (pieces[0] == "col2") bind._piece = Shader::SMP_col2; - else if (pieces[0] == "col3") bind._piece = Shader::SMP_col3; + if (pieces[0] == "trans") bind._piece = Shader::SMP_mat4_column; + else if (pieces[0] == "tpose") bind._piece = Shader::SMP_vec4; + else if (pieces[0] == "row0") { + bind._piece = Shader::SMP_vec4; + bind._offset = 0; + } + else if (pieces[0] == "row1") { + bind._piece = Shader::SMP_vec4; + bind._offset = 4; + } + else if (pieces[0] == "row2") { + bind._piece = Shader::SMP_vec4; + bind._offset = 8; + } + else if (pieces[0] == "row3") { + bind._piece = Shader::SMP_vec4; + bind._offset = 12; + } + else if (pieces[0] == "col0") { + bind._piece = Shader::SMP_mat4_column; + bind._offset = 0; + } + else if (pieces[0] == "col1") { + bind._piece = Shader::SMP_mat4_column; + bind._offset = 1; + } + else if (pieces[0] == "col2") { + bind._piece = Shader::SMP_mat4_column; + bind._offset = 2; + } + else if (pieces[0] == "col3") { + bind._piece = Shader::SMP_mat4_column; + bind._offset = 3; + } else { GLCAT.error() << basename << " should be mat4, not vec4\n"; return false; @@ -184,13 +208,13 @@ parse_and_set_short_hand_shader_vars(Shader::ShaderArgId &arg_id, GLenum param_t // We'll permit this too, simply because we can support it. switch (param_type) { case GL_FLOAT: - bind._piece = Shader::SMP_row3x1; + bind._piece = Shader::SMP_float; break; case GL_FLOAT_VEC2: - bind._piece = Shader::SMP_row3x2; + bind._piece = Shader::SMP_vec2; break; case GL_FLOAT_VEC3: - bind._piece = Shader::SMP_row3x3; + bind._piece = Shader::SMP_vec3; break; default: GLCAT.error() << basename << " should be vec4\n"; @@ -234,7 +258,7 @@ parse_and_set_short_hand_shader_vars(Shader::ShaderArgId &arg_id, GLenum param_t if (param_size > 1) { // We support arrays of rows and arrays of columns, so we can run the // GLSL shaders that cgc spits out. - if (bind._piece == Shader::SMP_row0 || bind._piece == Shader::SMP_col0) { + if (bind._piece == Shader::SMP_vec4 || bind._piece == Shader::SMP_mat4_column) { if (param_size > 4) { GLCAT.warning() << basename << "[" << param_size << "] is too large, only the first four elements will be defined\n"; param_size = 4; @@ -396,7 +420,7 @@ CLP(ShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderContext _glgsg->_current_shader_context->bind(); } - _mat_part_cache = new LMatrix4[_shader->cp_get_mat_cache_size()]; + _mat_part_cache = new LVecBase4f[_shader->cp_get_mat_cache_size()]; } /** @@ -827,15 +851,15 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { bind._func = Shader::SMF_compose; if (param_type == GL_FLOAT_MAT3) { if (transpose) { - bind._piece = Shader::SMP_upper3x3; + bind._piece = Shader::SMP_mat4_upper3x3; } else { - bind._piece = Shader::SMP_transpose3x3; + bind._piece = Shader::SMP_mat4_transpose3x3; } } else if (param_type == GL_FLOAT_MAT4) { if (transpose) { - bind._piece = Shader::SMP_transpose; + bind._piece = Shader::SMP_mat4_transpose; } else { - bind._piece = Shader::SMP_whole; + bind._piece = Shader::SMP_mat4_whole; } } else { GLCAT.error() @@ -941,13 +965,15 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { // A matrix member of a p3d_LightSource struct. if (strncmp(name_buffer, "shadowViewMatrix", 127) == 0) { if (inverse) { - // Tack inverse back onto the end. - strcpy(name_buffer + strlen(name_buffer), "Inverse"); + GLCAT.error() + << "p3d_LightSource struct does not provide a matrix named " + << name_buffer << "Inverse!\n"; + return; } bind._func = Shader::SMF_first; - bind._part[0] = Shader::SMO_light_source_i_attrib; - bind._arg[0] = InternalName::make(name_buffer); + bind._part[0] = Shader::SMO_apiview_to_apiclip_light_source_i; + bind._arg[0] = nullptr; bind._part[1] = Shader::SMO_identity; bind._arg[1] = nullptr; @@ -957,8 +983,8 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { bind._func = Shader::SMF_compose; bind._part[0] = Shader::SMO_model_to_apiview; bind._arg[0] = nullptr; - bind._part[1] = Shader::SMO_light_source_i_attrib; - bind._arg[1] = InternalName::make("shadowViewMatrix"); + bind._part[1] = Shader::SMO_apiview_to_apiclip_light_source_i; + bind._arg[1] = nullptr; static bool warned = false; if (!warned) { @@ -1061,7 +1087,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { << "p3d_Material.baseColor should be vec4\n"; } bind._part[0] = Shader::SMO_attr_material2; - bind._piece = Shader::SMP_row0; + bind._piece = Shader::SMP_vec4; _shader->cp_add_mat_spec(bind); return; @@ -1070,7 +1096,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { GLCAT.error() << "p3d_Material.ambient should be vec4\n"; } - bind._piece = Shader::SMP_row0; + bind._piece = Shader::SMP_vec4; _shader->cp_add_mat_spec(bind); return; @@ -1079,7 +1105,8 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { GLCAT.error() << "p3d_Material.diffuse should be vec4\n"; } - bind._piece = Shader::SMP_row1; + bind._piece = Shader::SMP_vec4; + bind._offset = 4; _shader->cp_add_mat_spec(bind); return; @@ -1088,7 +1115,8 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { GLCAT.error() << "p3d_Material.emission should be vec4\n"; } - bind._piece = Shader::SMP_row2; + bind._piece = Shader::SMP_vec4; + bind._offset = 8; _shader->cp_add_mat_spec(bind); return; @@ -1097,7 +1125,8 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { GLCAT.error() << "p3d_Material.specular should be vec3\n"; } - bind._piece = Shader::SMP_row3x3; + bind._piece = Shader::SMP_vec3; + bind._offset = 12; _shader->cp_add_mat_spec(bind); return; @@ -1106,7 +1135,8 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { GLCAT.error() << "p3d_Material.shininess should be float\n"; } - bind._piece = Shader::SMP_cell15; + bind._piece = Shader::SMP_float; + bind._offset = 15; _shader->cp_add_mat_spec(bind); return; @@ -1116,7 +1146,8 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { << "p3d_Material.roughness should be float\n"; } bind._part[0] = Shader::SMO_attr_material2; - bind._piece = Shader::SMP_cell15; + bind._piece = Shader::SMP_float; + bind._offset = 7; _shader->cp_add_mat_spec(bind); return; @@ -1126,7 +1157,8 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { << "p3d_Material.metallic should be bool or float\n"; } bind._part[0] = Shader::SMO_attr_material2; - bind._piece = Shader::SMP_row3x1; + bind._piece = Shader::SMP_float; + bind._offset = 4; _shader->cp_add_mat_spec(bind); return; @@ -1136,7 +1168,8 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { << "p3d_Material.refractiveIndex should be float\n"; } bind._part[0] = Shader::SMO_attr_material2; - bind._piece = Shader::SMP_cell13; + bind._piece = Shader::SMP_float; + bind._offset = 5; _shader->cp_add_mat_spec(bind); return; } @@ -1151,9 +1184,9 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { bind._arg[1] = nullptr; if (param_type == GL_FLOAT_VEC3) { - bind._piece = Shader::SMP_row3x3; + bind._piece = Shader::SMP_vec3; } else if (param_type == GL_FLOAT_VEC4) { - bind._piece = Shader::SMP_row3; + bind._piece = Shader::SMP_vec4; } else { GLCAT.error() << "p3d_ColorScale should be vec3 or vec4\n"; @@ -1172,9 +1205,9 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { bind._arg[1] = nullptr; if (param_type == GL_FLOAT_VEC3) { - bind._piece = Shader::SMP_row3x3; + bind._piece = Shader::SMP_vec3; } else if (param_type == GL_FLOAT_VEC4) { - bind._piece = Shader::SMP_row3; + bind._piece = Shader::SMP_vec3; } else { GLCAT.error() << "p3d_Color should be vec3 or vec4\n"; @@ -1193,7 +1226,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { Shader::ShaderMatSpec bind; bind._id = arg_id; bind._id._seqno = p + i; - bind._piece = Shader::SMP_row3; + bind._piece = Shader::SMP_vec4; bind._func = Shader::SMF_first; bind._index = i; bind._part[0] = Shader::SMO_apiview_clipplane_i; @@ -1216,9 +1249,9 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { bind._part[0] = Shader::SMO_attr_fogcolor; if (param_type == GL_FLOAT_VEC3) { - bind._piece = Shader::SMP_row3x3; + bind._piece = Shader::SMP_vec4; } else if (param_type == GL_FLOAT_VEC4) { - bind._piece = Shader::SMP_row3; + bind._piece = Shader::SMP_vec4; } else { GLCAT.error() << "p3d_Fog.color should be vec3 or vec4\n"; @@ -1229,7 +1262,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { bind._part[0] = Shader::SMO_attr_fog; if (param_type == GL_FLOAT) { - bind._piece = Shader::SMP_row3x1; + bind._piece = Shader::SMP_float; } else { GLCAT.error() << "p3d_Fog.density should be float\n"; @@ -1240,7 +1273,8 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { bind._part[0] = Shader::SMO_attr_fog; if (param_type == GL_FLOAT) { - bind._piece = Shader::SMP_cell13; + bind._piece = Shader::SMP_float; + bind._offset = 13; } else { GLCAT.error() << "p3d_Fog.start should be float\n"; @@ -1251,7 +1285,8 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { bind._part[0] = Shader::SMO_attr_fog; if (param_type == GL_FLOAT) { - bind._piece = Shader::SMP_cell14; + bind._piece = Shader::SMP_float; + bind._offset = 14; } else { GLCAT.error() << "p3d_Fog.end should be float\n"; @@ -1262,7 +1297,8 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { bind._part[0] = Shader::SMO_attr_fog; if (param_type == GL_FLOAT) { - bind._piece = Shader::SMP_cell15; + bind._piece = Shader::SMP_float; + bind._offset = 15; } else { GLCAT.error() << "p3d_Fog.scale should be float\n"; @@ -1283,9 +1319,9 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { bind._arg[1] = nullptr; if (param_type == GL_FLOAT_VEC3) { - bind._piece = Shader::SMP_row3x3; + bind._piece = Shader::SMP_vec3; } else if (param_type == GL_FLOAT_VEC4) { - bind._piece = Shader::SMP_row3; + bind._piece = Shader::SMP_vec4; } else { GLCAT.error() << "p3d_LightModel.ambient should be vec3 or vec4\n"; @@ -1329,26 +1365,26 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { bind._id = arg_id; bind._func = Shader::SMF_first; bind._index = index; - bind._part[0] = Shader::SMO_light_source_i_attrib; + bind._part[0] = Shader::SMO_light_source_i_vec_attrib; bind._arg[0] = InternalName::make(member_name); bind._part[1] = Shader::SMO_identity; bind._arg[1] = nullptr; switch (param_type) { case GL_FLOAT: - bind._piece = Shader::SMP_row3x1; + bind._piece = Shader::SMP_float; break; case GL_FLOAT_VEC2: - bind._piece = Shader::SMP_row3x2; + bind._piece = Shader::SMP_vec2; break; case GL_FLOAT_VEC3: - bind._piece = Shader::SMP_row3x3; + bind._piece = Shader::SMP_vec3; break; case GL_FLOAT_VEC4: - bind._piece = Shader::SMP_row3; + bind._piece = Shader::SMP_vec4; break; default: @@ -1390,7 +1426,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { bind._arg[0] = nullptr; bind._part[1] = Shader::SMO_identity; bind._arg[1] = nullptr; - bind._piece = Shader::SMP_row3; + bind._piece = Shader::SMP_vec4; _shader->cp_add_mat_spec(bind); return; } @@ -1408,7 +1444,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { bind._arg[1] = nullptr; if (noprefix == "ViewMatrix") { - bind._piece = Shader::SMP_whole; + bind._piece = Shader::SMP_mat4_whole; bind._func = Shader::SMF_compose; bind._part[0] = Shader::SMO_world_to_view; bind._part[1] = Shader::SMO_view_to_apiview; @@ -1416,7 +1452,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { return; } else if (noprefix == "InverseViewMatrix" || noprefix == "ViewMatrixInverse") { - bind._piece = Shader::SMP_whole; + bind._piece = Shader::SMP_mat4_whole; bind._func = Shader::SMF_compose; bind._part[0] = Shader::SMO_apiview_to_view; bind._part[1] = Shader::SMO_view_to_world; @@ -1424,7 +1460,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { return; } else if (noprefix == "FrameTime") { - bind._piece = Shader::SMP_row3x1; + bind._piece = Shader::SMP_float; bind._func = Shader::SMF_first; bind._part[0] = Shader::SMO_frame_time; bind._part[1] = Shader::SMO_identity; @@ -1432,7 +1468,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { return; } else if (noprefix == "DeltaFrameTime") { - bind._piece = Shader::SMP_row3x1; + bind._piece = Shader::SMP_float; bind._func = Shader::SMF_first; bind._part[0] = Shader::SMO_frame_delta; bind._part[1] = Shader::SMO_identity; @@ -1516,7 +1552,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { case GL_FLOAT_MAT3: { Shader::ShaderMatSpec bind; bind._id = arg_id; - bind._piece = Shader::SMP_upper3x3; + bind._piece = Shader::SMP_mat4_upper3x3; bind._func = Shader::SMF_first; bind._part[0] = Shader::SMO_mat_constant_x; bind._arg[0] = InternalName::make(param_name); @@ -1528,7 +1564,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { case GL_FLOAT_MAT4: { Shader::ShaderMatSpec bind; bind._id = arg_id; - bind._piece = Shader::SMP_whole; + bind._piece = Shader::SMP_mat4_whole; bind._func = Shader::SMF_first; bind._part[1] = Shader::SMO_identity; bind._arg[1] = nullptr; @@ -1552,8 +1588,8 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { bind._func = Shader::SMF_compose; bind._part[0] = Shader::SMO_model_to_apiview; bind._arg[0] = nullptr; - bind._part[1] = Shader::SMO_mat_constant_x_attrib; - bind._arg[1] = iname->get_parent()->append("shadowViewMatrix"); + bind._part[1] = Shader::SMO_apiview_to_apiclip_light_source_i; + bind._arg[1] = nullptr; } else { bind._part[0] = Shader::SMO_mat_constant_x_attrib; bind._arg[0] = InternalName::make(param_name); @@ -1578,16 +1614,16 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { bind._id = arg_id; switch (param_type) { case GL_FLOAT: - bind._piece = Shader::SMP_row3x1; + bind._piece = Shader::SMP_float; break; case GL_FLOAT_VEC2: - bind._piece = Shader::SMP_row3x2; + bind._piece = Shader::SMP_vec2; break; case GL_FLOAT_VEC3: - bind._piece = Shader::SMP_row3x3; + bind._piece = Shader::SMP_vec3; break; default: - bind._piece = Shader::SMP_row3; + bind._piece = Shader::SMP_vec4; } bind._func = Shader::SMF_first; bind._part[0] = Shader::SMO_vec_constant_x_attrib; @@ -2263,61 +2299,36 @@ issue_parameters(int altered) { continue; } - const LMatrix4 *val = _glgsg->fetch_specified_value(spec, _mat_part_cache, altered); + const LVecBase4f *val = _glgsg->fetch_specified_value(spec, _mat_part_cache, altered); if (!val) continue; -#ifndef STDFLOAT_DOUBLE - // In this case, the data is already single-precision. - const PN_float32 *data = val->get_data(); -#else - // In this case, we have to convert it. - LMatrix4f valf = LCAST(PN_float32, *val); - const PN_float32 *data = valf.get_data(); -#endif + const float *data = val->get_data(); + data += spec._offset; GLint p = spec._id._seqno; switch (spec._piece) { - case Shader::SMP_whole: _glgsg->_glUniformMatrix4fv(p, 1, GL_FALSE, data); continue; - case Shader::SMP_transpose: _glgsg->_glUniformMatrix4fv(p, 1, GL_TRUE, data); continue; - case Shader::SMP_col0: _glgsg->_glUniform4f(p, data[0], data[4], data[ 8], data[12]); continue; - case Shader::SMP_col1: _glgsg->_glUniform4f(p, data[1], data[5], data[ 9], data[13]); continue; - case Shader::SMP_col2: _glgsg->_glUniform4f(p, data[2], data[6], data[10], data[14]); continue; - case Shader::SMP_col3: _glgsg->_glUniform4f(p, data[3], data[7], data[11], data[15]); continue; - case Shader::SMP_row0: _glgsg->_glUniform4fv(p, 1, data+ 0); continue; - case Shader::SMP_row1: _glgsg->_glUniform4fv(p, 1, data+ 4); continue; - case Shader::SMP_row2: _glgsg->_glUniform4fv(p, 1, data+ 8); continue; - case Shader::SMP_row3: _glgsg->_glUniform4fv(p, 1, data+12); continue; - case Shader::SMP_row3x1: _glgsg->_glUniform1fv(p, 1, data+12); continue; - case Shader::SMP_row3x2: _glgsg->_glUniform2fv(p, 1, data+12); continue; - case Shader::SMP_row3x3: _glgsg->_glUniform3fv(p, 1, data+12); continue; - case Shader::SMP_upper3x3: + case Shader::SMP_float: _glgsg->_glUniform1fv(p, 1, data); continue; + case Shader::SMP_vec2: _glgsg->_glUniform2fv(p, 1, data); continue; + case Shader::SMP_vec3: _glgsg->_glUniform3fv(p, 1, data); continue; + case Shader::SMP_vec4: _glgsg->_glUniform4fv(p, 1, data); continue; + case Shader::SMP_mat4_whole: _glgsg->_glUniformMatrix4fv(p, 1, GL_FALSE, data); continue; + case Shader::SMP_mat4_transpose: _glgsg->_glUniformMatrix4fv(p, 1, GL_TRUE, data); continue; + case Shader::SMP_mat4_column: _glgsg->_glUniform4f(p, data[0], data[4], data[8], data[12]); continue; + case Shader::SMP_mat4_upper3x3: { -#ifndef STDFLOAT_DOUBLE - LMatrix3f upper3 = val->get_upper_3(); -#else - LMatrix3f upper3 = valf.get_upper_3(); -#endif + LMatrix3f upper3(data[0], data[1], data[2], data[4], data[5], data[6], data[8], data[9], data[10]); _glgsg->_glUniformMatrix3fv(p, 1, false, upper3.get_data()); continue; } - case Shader::SMP_transpose3x3: + case Shader::SMP_mat4_transpose3x3: { -#ifndef STDFLOAT_DOUBLE - LMatrix3f upper3 = val->get_upper_3(); -#else - LMatrix3f upper3 = valf.get_upper_3(); -#endif + LMatrix3f upper3(data[0], data[1], data[2], data[4], data[5], data[6], data[8], data[9], data[10]); _glgsg->_glUniformMatrix3fv(p, 1, true, upper3.get_data()); continue; } - case Shader::SMP_cell15: - _glgsg->_glUniform1fv(p, 1, data+15); - continue; - case Shader::SMP_cell14: - _glgsg->_glUniform1fv(p, 1, data+14); - continue; - case Shader::SMP_cell13: - _glgsg->_glUniform1fv(p, 1, data+13); - continue; + case Shader::SMP_int: _glgsg->_glUniform1i(p, ((int *)data)[0]); + case Shader::SMP_ivec2: _glgsg->_glUniform2iv(p, 1, (int *)data); + case Shader::SMP_ivec3: _glgsg->_glUniform3iv(p, 1, (int *)data); + case Shader::SMP_ivec4: _glgsg->_glUniform4iv(p, 1, (int *)data); } } } diff --git a/panda/src/glstuff/glShaderContext_src.h b/panda/src/glstuff/glShaderContext_src.h index 878941c114..7e63c1a611 100644 --- a/panda/src/glstuff/glShaderContext_src.h +++ b/panda/src/glstuff/glShaderContext_src.h @@ -112,7 +112,7 @@ private: }; pvector _glsl_img_inputs; - LMatrix4 *_mat_part_cache = nullptr; + LVecBase4f *_mat_part_cache = nullptr; CLP(GraphicsStateGuardian) *_glgsg; diff --git a/panda/src/glstuff/glmisc_src.h b/panda/src/glstuff/glmisc_src.h index 6568c1b2ef..1cc96726fe 100644 --- a/panda/src/glstuff/glmisc_src.h +++ b/panda/src/glstuff/glmisc_src.h @@ -24,16 +24,8 @@ #ifndef STDFLOAT_DOUBLE #define GLf(name) name ## f -#define GLfv(name) name ## fv -#define GLfc(name) name ## fc -#define GLfr(name) name ## fr -#define GLf_str "f" #else // STDFLOAT_DOUBLE #define GLf(name) name ## d -#define GLfv(name) name ## dv -#define GLfc(name) name ## dc -#define GLfr(name) name ## dr -#define GLf_str "d" #endif // STDFLOAT_DOUBLE #endif // GLf diff --git a/panda/src/gobj/shader.cxx b/panda/src/gobj/shader.cxx index 93e7df92d5..628445e4dc 100644 --- a/panda/src/gobj/shader.cxx +++ b/panda/src/gobj/shader.cxx @@ -459,11 +459,13 @@ cp_dependency(ShaderMatInput inp) { } } if ((inp == SMO_light_ambient) || - (inp == SMO_light_source_i_attrib) || + (inp == SMO_light_source_i_vec_attrib) || + (inp == SMO_apiview_to_apiclip_light_source_i) || (inp == SMO_light_source_i_packed)) { dep |= SSD_light | SSD_frame; } - if (inp == SMO_light_source_i_attrib || + if (inp == SMO_light_source_i_vec_attrib || + inp == SMO_apiview_to_apiclip_light_source_i || inp == SMO_light_source_i_packed || inp == SMO_mat_constant_x_attrib || inp == SMO_vec_constant_x_attrib) { @@ -579,14 +581,13 @@ cp_add_mat_spec(ShaderMatSpec &spec) { for (int i = 0; i < 2; ++i) { if (spec._part[i] == SMO_texmat_i || spec._part[i] == SMO_inv_texmat_i || - spec._part[i] == SMO_light_source_i_attrib || + spec._part[i] == SMO_light_source_i_vec_attrib || + spec._part[i] == SMO_apiview_to_apiclip_light_source_i || spec._part[i] == SMO_light_product_i_ambient || spec._part[i] == SMO_light_product_i_diffuse || spec._part[i] == SMO_light_product_i_specular || spec._part[i] == SMO_apiview_clipplane_i || spec._part[i] == SMO_tex_is_alpha_i || - spec._part[i] == SMO_transform_i || - spec._part[i] == SMO_slider_i || spec._part[i] == SMO_light_source_i_packed || spec._part[i] == SMO_texscale_i || spec._part[i] == SMO_texcolor_i) { @@ -610,6 +611,9 @@ cp_add_mat_spec(ShaderMatSpec &spec) { for (i = 0; i < _mat_parts.size(); ++i) { ShaderMatPart &part = _mat_parts[i]; if (part._part == spec._part[p] && part._arg == spec._arg[p]) { + if (spec._func != SMF_first) { + assert(part._size == 4); + } int diff = end[p] - part._count; if (diff <= 0) { // The existing cache entry is big enough. @@ -618,18 +622,18 @@ cp_add_mat_spec(ShaderMatSpec &spec) { // It's not big enough. Enlarge it, which means we have to change the // offset of some of the other spec entries. for (ShaderMatSpec &spec : _mat_spec) { - if (spec._cache_offset[0] >= offset + part._count) { - spec._cache_offset[0] += diff; + if (spec._cache_offset[0] >= offset + part._size * part._count) { + spec._cache_offset[0] += diff * part._size; } - if (spec._cache_offset[1] >= offset + part._count) { - spec._cache_offset[1] += diff; + if (spec._cache_offset[1] >= offset + part._size * part._count) { + spec._cache_offset[1] += diff * part._size; } } part._count = end[p]; break; } } - offset += part._count; + offset += part._count * part._size; } if (i == _mat_parts.size()) { // Didn't find this part yet, create a new one. @@ -638,6 +642,88 @@ cp_add_mat_spec(ShaderMatSpec &spec) { part._count = end[p]; part._arg = spec._arg[p]; part._dep = dep; + + switch (part._part) { + case SMO_INVALID: + part._size = 0; + break; + + case SMO_window_size: + case SMO_pixel_size: + case SMO_texpad_x: + case SMO_texpix_x: + case SMO_attr_material: + case SMO_attr_color: + case SMO_attr_colorscale: + case SMO_satten_x: + case SMO_plane_x: + case SMO_clipplane_x: + case SMO_vec_constant_x: + case SMO_attr_fog: + case SMO_attr_fogcolor: + case SMO_frame_number: + case SMO_frame_time: + case SMO_frame_delta: + case SMO_vec_constant_x_attrib: + case SMO_light_ambient: + case SMO_light_source_i_vec_attrib: + case SMO_light_product_i_ambient: + case SMO_light_product_i_diffuse: + case SMO_light_product_i_specular: + case SMO_apiview_clipplane_i: + case SMO_tex_is_alpha_i: + case SMO_texscale_i: + case SMO_texcolor_i: + case SMO_texconst_i: + case SMO_attr_pointparams: + part._size = 1; + break; + + case SMO_attr_material2: + part._size = 2; + break; + + case SMO_identity: + case SMO_alight_x: + case SMO_dlight_x: + case SMO_plight_x: + case SMO_slight_x: + case SMO_texmat_i: + case SMO_mat_constant_x: + case SMO_world_to_view: + case SMO_view_to_world: + case SMO_model_to_view: + case SMO_view_to_model: + case SMO_apiview_to_view: + case SMO_view_to_apiview: + case SMO_clip_to_view: + case SMO_view_to_clip: + case SMO_apiclip_to_view: + case SMO_view_to_apiclip: + case SMO_view_x_to_view: + case SMO_view_to_view_x: + case SMO_apiview_x_to_view: + case SMO_view_to_apiview_x: + case SMO_clip_x_to_view: + case SMO_view_to_clip_x: + case SMO_apiclip_x_to_view: + case SMO_view_to_apiclip_x: + case SMO_mat_constant_x_attrib: + case SMO_apiview_to_apiclip_light_source_i: + case SMO_model_to_apiview: + case SMO_apiview_to_model: + case SMO_apiview_to_apiclip: + case SMO_apiclip_to_apiview: + case SMO_inv_texmat_i: + case SMO_light_source_i_packed: + part._size = 4; + break; + } + + if (spec._func != SMF_first) { + assert(part._size == 4); + } + _mat_parts.push_back(std::move(part)); } spec._cache_offset[p] = offset + begin[p]; @@ -648,13 +734,14 @@ cp_add_mat_spec(ShaderMatSpec &spec) { } /** - * Returns the total size of the matrix part cache. + * Returns the total size of the matrix part cache in terms of number of + * vectors. */ size_t Shader:: cp_get_mat_cache_size() const { size_t size = 0; for (const ShaderMatPart &part : _mat_parts) { - size += part._count; + size += part._size * part._count; } return size; } @@ -858,12 +945,12 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { } ShaderMatSpec bind; bind._id = p._id; - bind._piece = SMP_whole; + bind._piece = SMP_mat4_whole; bind._func = SMF_compose; - bind._part[1] = SMO_light_source_i_attrib; - bind._arg[1] = InternalName::make("shadowViewMatrix"); bind._part[0] = SMO_view_to_apiview; bind._arg[0] = nullptr; + bind._part[1] = SMO_apiview_to_apiclip_light_source_i; + bind._arg[1] = nullptr; bind._index = atoi(pieces[2].c_str()); cp_add_mat_spec(bind); @@ -969,42 +1056,46 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { ShaderMatSpec bind; bind._id = p._id; - bind._piece = SMP_whole; + bind._piece = SMP_mat4_whole; bind._func = SMF_compose; - bind._part[1] = SMO_light_source_i_attrib; - bind._arg[1] = InternalName::make("shadowViewMatrix"); bind._part[0] = SMO_view_to_apiview; bind._arg[0] = nullptr; + bind._part[1] = SMO_apiview_to_apiclip_light_source_i; + bind._arg[1] = nullptr; bind._index = atoi(pieces[2].c_str()); int next = 1; pieces.push_back(""); // Decide whether this is a matrix or vector. - if (pieces[0]=="trans") bind._piece = SMP_whole; - else if (pieces[0]=="tpose") bind._piece = SMP_transpose; - else if (pieces[0]=="row0") bind._piece = SMP_row0; - else if (pieces[0]=="row1") bind._piece = SMP_row1; - else if (pieces[0]=="row2") bind._piece = SMP_row2; - else if (pieces[0]=="row3") bind._piece = SMP_row3; - else if (pieces[0]=="col0") bind._piece = SMP_col0; - else if (pieces[0]=="col1") bind._piece = SMP_col1; - else if (pieces[0]=="col2") bind._piece = SMP_col2; - else if (pieces[0]=="col3") bind._piece = SMP_col3; - if ((bind._piece == SMP_whole)||(bind._piece == SMP_transpose)) { + if (pieces[0][0] == 't') { // trans or tpose + bool tpose = (pieces[0][1] == 'p'); if (p._type == SAT_mat3x3) { - if (!cp_errchk_parameter_float(p, 9, 9)) return false; - - if (bind._piece == SMP_transpose) { - bind._piece = SMP_transpose3x3; - } else { - bind._piece = SMP_upper3x3; + if (!cp_errchk_parameter_float(p, 9, 9)) { + return false; } - } else if (!cp_errchk_parameter_float(p, 16, 16)) { + bind._piece = tpose ? SMP_mat4_transpose3x3 : SMP_mat4_upper3x3; + } + else { + if (!cp_errchk_parameter_float(p, 16, 16)) { + return false; + } + bind._piece = tpose ? SMP_mat4_transpose : SMP_mat4_whole; + } + } + else if (pieces[0][0] == 'r') { // row0, row1, row2, row3 + if (!cp_errchk_parameter_float(p, 4, 4)) { return false; } - } else { - if (!cp_errchk_parameter_float(p, 4, 4)) return false; + bind._piece = SMP_vec4; + bind._offset = (pieces[0][3] - '0') * 4; + } + else if (pieces[0][0] == 'c') { // col0, col1, col2, col3 + if (!cp_errchk_parameter_float(p, 4, 4)) { + return false; + } + bind._piece = SMP_mat4_column; + bind._offset = pieces[0][3] - '0'; } if (!cp_parse_coord_sys(p, pieces, next, bind, true)) { @@ -1037,7 +1128,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { return false; } bind._id = p._id; - bind._piece = SMP_transpose; + bind._piece = SMP_mat4_transpose; bind._func = SMF_first; bind._part[0] = SMO_attr_material; bind._arg[0] = nullptr; @@ -1048,7 +1139,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { return false; } bind._id = p._id; - bind._piece = SMP_row3; + bind._piece = SMP_vec4; bind._func = SMF_first; bind._part[0] = SMO_attr_color; bind._arg[0] = nullptr; @@ -1059,7 +1150,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { return false; } bind._id = p._id; - bind._piece = SMP_row3; + bind._piece = SMP_vec4; bind._func = SMF_first; bind._part[0] = SMO_attr_colorscale; bind._arg[0] = nullptr; @@ -1070,7 +1161,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { return false; } bind._id = p._id; - bind._piece = SMP_row3; + bind._piece = SMP_vec4; bind._func = SMF_first; bind._part[0] = SMO_attr_fog; bind._arg[0] = nullptr; @@ -1081,7 +1172,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { return false; } bind._id = p._id; - bind._piece = SMP_row3; + bind._piece = SMP_vec4; bind._func = SMF_first; bind._part[0] = SMO_attr_fogcolor; bind._arg[0] = nullptr; @@ -1092,7 +1183,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { return false; } bind._id = p._id; - bind._piece = SMP_row3; + bind._piece = SMP_vec4; bind._func = SMF_first; bind._part[0] = SMO_light_ambient; bind._arg[0] = nullptr; @@ -1103,7 +1194,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { return false; } bind._id = p._id; - bind._piece = SMP_transpose; + bind._piece = SMP_mat4_transpose; bind._func = SMF_first; bind._part[0] = SMO_light_source_i_packed; bind._arg[0] = nullptr; @@ -1115,9 +1206,9 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { return false; } bind._id = p._id; - bind._piece = SMP_row3; + bind._piece = SMP_vec4; bind._func = SMF_first; - bind._part[0] = SMO_light_source_i_attrib; + bind._part[0] = SMO_light_source_i_vec_attrib; bind._arg[0] = InternalName::make("specular"); bind._part[1] = SMO_identity; bind._arg[1] = nullptr; @@ -1127,7 +1218,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { return false; } bind._id = p._id; - bind._piece = SMP_row3; + bind._piece = SMP_vec4; bind._func = SMF_first; bind._part[0] = SMO_attr_pointparams; bind._arg[0] = nullptr; @@ -1165,7 +1256,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { } ShaderMatSpec bind; bind._id = p._id; - bind._piece = SMP_row3; + bind._piece = SMP_vec4; bind._func = SMF_first; bind._part[0] = SMO_alight_x; bind._arg[0] = InternalName::make(pieces[1]); @@ -1185,7 +1276,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { } ShaderMatSpec bind; bind._id = p._id; - bind._piece = SMP_row3; + bind._piece = SMP_vec4; bind._func = SMF_first; bind._part[0] = SMO_satten_x; bind._arg[0] = InternalName::make(pieces[1]); @@ -1204,7 +1295,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { } ShaderMatSpec bind; bind._id = p._id; - bind._piece = SMP_transpose; + bind._piece = SMP_mat4_transpose; int next = 1; pieces.push_back(""); if (pieces[next] == "") { @@ -1245,7 +1336,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { } ShaderMatSpec bind; bind._id = p._id; - bind._piece = SMP_whole; + bind._piece = SMP_mat4_whole; bind._func = SMF_first; bind._part[0] = SMO_texmat_i; bind._arg[0] = nullptr; @@ -1266,7 +1357,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { } ShaderMatSpec bind; bind._id = p._id; - bind._piece = SMP_row3; + bind._piece = SMP_vec4; bind._func = SMF_first; bind._part[0] = SMO_texscale_i; bind._arg[0] = nullptr; @@ -1287,7 +1378,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { } ShaderMatSpec bind; bind._id = p._id; - bind._piece = SMP_row3; + bind._piece = SMP_vec4; bind._func = SMF_first; bind._part[0] = SMO_texcolor_i; bind._arg[0] = nullptr; @@ -1308,7 +1399,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { } ShaderMatSpec bind; bind._id = p._id; - bind._piece = SMP_row3; + bind._piece = SMP_vec4; bind._func = SMF_first; bind._part[0] = SMO_texconst_i; bind._arg[0] = nullptr; @@ -1329,7 +1420,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { } ShaderMatSpec bind; bind._id = p._id; - bind._piece = SMP_row3; + bind._piece = SMP_vec4; bind._func = SMF_first; bind._part[0] = SMO_plane_x; bind._arg[0] = InternalName::make(pieces[1]); @@ -1349,7 +1440,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { } ShaderMatSpec bind; bind._id = p._id; - bind._piece = SMP_row3; + bind._piece = SMP_vec4; bind._func = SMF_first; bind._part[0] = SMO_clipplane_x; bind._arg[0] = InternalName::make(pieces[1]); @@ -1370,7 +1461,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { } ShaderMatSpec bind; bind._id = p._id; - bind._piece = SMP_row3; + bind._piece = SMP_vec4; bind._func = SMF_first; bind._part[1] = SMO_identity; bind._arg[1] = nullptr; @@ -1392,7 +1483,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { if (!cp_errchk_parameter_float(p, 1, 1)) { return false; } - bind._piece = SMP_row3x1; + bind._piece = SMP_float; bind._part[0] = SMO_frame_time; bind._arg[0] = nullptr; @@ -1479,7 +1570,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { } ShaderMatSpec bind; bind._id = p._id; - bind._piece = SMP_row3; + bind._piece = SMP_vec4; bind._func = SMF_first; bind._part[0] = SMO_texpad_x; bind._arg[0] = InternalName::make(pieces[1]); @@ -1498,7 +1589,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { } ShaderMatSpec bind; bind._id = p._id; - bind._piece = SMP_row3; + bind._piece = SMP_vec4; bind._func = SMF_first; bind._part[0] = SMO_texpix_x; bind._arg[0] = InternalName::make(pieces[1]); diff --git a/panda/src/gobj/shader.h b/panda/src/gobj/shader.h index 4f8687fa00..fc7e49ae55 100644 --- a/panda/src/gobj/shader.h +++ b/panda/src/gobj/shader.h @@ -183,7 +183,8 @@ public: SMO_vec_constant_x_attrib, SMO_light_ambient, - SMO_light_source_i_attrib, + SMO_light_source_i_vec_attrib, + SMO_apiview_to_apiclip_light_source_i, SMO_light_product_i_ambient, SMO_light_product_i_diffuse, @@ -205,9 +206,6 @@ public: // Hack for text rendering. Don't use in user shaders. SMO_tex_is_alpha_i, - SMO_transform_i, - SMO_slider_i, - SMO_light_source_i_packed, // Texture scale component of texture matrix. @@ -294,24 +292,19 @@ public: }; enum ShaderMatPiece { - SMP_whole, - SMP_transpose, - SMP_row0, - SMP_row1, - SMP_row2, - SMP_row3, - SMP_col0, - SMP_col1, - SMP_col2, - SMP_col3, - SMP_row3x1, - SMP_row3x2, - SMP_row3x3, - SMP_upper3x3, - SMP_transpose3x3, - SMP_cell15, - SMP_cell14, - SMP_cell13, + SMP_float, + SMP_vec2, + SMP_vec3, + SMP_vec4, + SMP_mat4_whole, + SMP_mat4_transpose, + SMP_mat4_column, + SMP_mat4_upper3x3, + SMP_mat4_transpose3x3, + SMP_int, + SMP_ivec2, + SMP_ivec3, + SMP_ivec4, }; enum ShaderStateDep { @@ -339,11 +332,11 @@ public: }; enum ShaderMatFunc { + SMF_first, SMF_compose, SMF_transform_dlight, SMF_transform_plight, SMF_transform_slight, - SMF_first, }; struct ShaderArgId { @@ -422,12 +415,14 @@ public: /** * Describes a matrix making up a single part of the ShaderMatInput cache. - * The cache is made up of a continuous array of matrices, as described by - * a successive list of ShaderMatPart (each of which takes up _count matrices) + * The cache is made up of a continuous array of vectors, as described by + * a successive list of ShaderMatPart (each of which takes up _count times + * _size vectors) */ struct ShaderMatPart { ShaderMatInput _part; PT(InternalName) _arg; + int _size = 1; int _count = 1; int _dep = SSD_NONE; }; @@ -441,10 +436,11 @@ public: ShaderMatFunc _func; ShaderMatInput _part[2]; PT(InternalName) _arg[2]; - LMatrix4 _value; + LMatrix4f _value; int _dep = SSD_NONE; int _index = 0; ShaderMatPiece _piece; + int _offset = 0; }; struct ShaderTexSpec { From cb4597ebb84fe7228c7039e2f54c545b63d60046 Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 17 Sep 2023 19:12:33 +0200 Subject: [PATCH 79/84] shader: Pass built-in array shader input in one go This applies to `p3d_TextureMatrix[]` and `p3d_ClipPlane[]` This is more efficient and also works around Apple driver bugs (like #846) Fixes #883 --- panda/src/glstuff/glCgShaderContext_src.cxx | 2 + panda/src/glstuff/glShaderContext_src.cxx | 44 +++++++-------------- panda/src/gobj/shader.cxx | 4 +- panda/src/gobj/shader.h | 3 ++ 4 files changed, 21 insertions(+), 32 deletions(-) diff --git a/panda/src/glstuff/glCgShaderContext_src.cxx b/panda/src/glstuff/glCgShaderContext_src.cxx index daf671ce04..3f42461c3d 100644 --- a/panda/src/glstuff/glCgShaderContext_src.cxx +++ b/panda/src/glstuff/glCgShaderContext_src.cxx @@ -710,7 +710,9 @@ issue_parameters(int altered) { case Shader::SMP_vec2: cgGLSetParameter2fv(p, data); continue; case Shader::SMP_vec3: cgGLSetParameter3fv(p, data); continue; case Shader::SMP_vec4: cgGLSetParameter4fv(p, data); continue; + case Shader::SMP_vec4_array: cgGLSetParameterArray4f(p, 0, spec._array_count, data); continue; case Shader::SMP_mat4_whole: cgGLSetMatrixParameterfc(p, data); continue; + case Shader::SMP_mat4_array: cgGLSetMatrixParameterArrayfc(p, 0, spec._array_count, data); continue; case Shader::SMP_mat4_transpose: cgGLSetMatrixParameterfr(p, data); continue; case Shader::SMP_mat4_column: cgGLSetParameter4f(p, data[0], data[4], data[ 8], data[12]); continue; case Shader::SMP_mat4_upper3x3: diff --git a/panda/src/glstuff/glShaderContext_src.cxx b/panda/src/glstuff/glShaderContext_src.cxx index 1d74f61c25..c45ab59972 100644 --- a/panda/src/glstuff/glShaderContext_src.cxx +++ b/panda/src/glstuff/glShaderContext_src.cxx @@ -937,27 +937,12 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { return; } + bind._piece = Shader::SMP_mat4_array; bind._func = Shader::SMF_first; bind._part[0] = inverse ? Shader::SMO_inv_texmat_i : Shader::SMO_texmat_i; bind._part[1] = Shader::SMO_identity; - - // Add it once for each index. - for (bind._index = 0; bind._index < param_size; ++bind._index) { - // It was discovered in #846, that GLSL 4.10 and lower don't seem to - // guarantee that matrices occupy successive locations, and on macOS - // they indeed occupy four locations per element. - // As a big fat hack, we multiply by four on macOS, because this is - // hard to fix on the 1.10 branch. We'll have a proper fix on the - // master branch. -#ifdef __APPLE__ - bind._id._seqno = p + bind._index * 4; -#else - bind._id._seqno = p + bind._index; -#endif - _shader->cp_add_mat_spec(bind); - } - return; + bind._array_count = param_size; } else if (matrix_name.size() > 15 && matrix_name.substr(0, 12) == "LightSource[" && @@ -1222,19 +1207,16 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { << "p3d_ClipPlane should be vec4 or vec4[]\n"; return; } - for (int i = 0; i < param_size; ++i) { - Shader::ShaderMatSpec bind; - bind._id = arg_id; - bind._id._seqno = p + i; - bind._piece = Shader::SMP_vec4; - bind._func = Shader::SMF_first; - bind._index = i; - bind._part[0] = Shader::SMO_apiview_clipplane_i; - bind._arg[0] = nullptr; - bind._part[1] = Shader::SMO_identity; - bind._arg[1] = nullptr; - _shader->cp_add_mat_spec(bind); - } + Shader::ShaderMatSpec bind; + bind._id = arg_id; + bind._piece = Shader::SMP_vec4_array; + bind._func = Shader::SMF_first; + bind._part[0] = Shader::SMO_apiview_clipplane_i; + bind._arg[0] = nullptr; + bind._part[1] = Shader::SMO_identity; + bind._arg[1] = nullptr; + bind._array_count = param_size; + _shader->cp_add_mat_spec(bind); return; } if (size > 4 && noprefix.substr(0, 4) == "Fog.") { @@ -2310,7 +2292,9 @@ issue_parameters(int altered) { case Shader::SMP_vec2: _glgsg->_glUniform2fv(p, 1, data); continue; case Shader::SMP_vec3: _glgsg->_glUniform3fv(p, 1, data); continue; case Shader::SMP_vec4: _glgsg->_glUniform4fv(p, 1, data); continue; + case Shader::SMP_vec4_array: _glgsg->_glUniform4fv(p, spec._array_count, data); continue; case Shader::SMP_mat4_whole: _glgsg->_glUniformMatrix4fv(p, 1, GL_FALSE, data); continue; + case Shader::SMP_mat4_array: _glgsg->_glUniformMatrix4fv(p, spec._array_count, GL_FALSE, data); continue; case Shader::SMP_mat4_transpose: _glgsg->_glUniformMatrix4fv(p, 1, GL_TRUE, data); continue; case Shader::SMP_mat4_column: _glgsg->_glUniform4f(p, data[0], data[4], data[8], data[12]); continue; case Shader::SMP_mat4_upper3x3: diff --git a/panda/src/gobj/shader.cxx b/panda/src/gobj/shader.cxx index 628445e4dc..55fec70437 100644 --- a/panda/src/gobj/shader.cxx +++ b/panda/src/gobj/shader.cxx @@ -577,7 +577,7 @@ cp_add_mat_spec(ShaderMatSpec &spec) { // index refer to. (It can't be the case that both parts are arrays.) int begin[2] = {0, 0}; int end[2] = {1, 1}; - if (spec._index > 0) { + if (spec._index > 0 || spec._array_count > 1) { for (int i = 0; i < 2; ++i) { if (spec._part[i] == SMO_texmat_i || spec._part[i] == SMO_inv_texmat_i || @@ -592,7 +592,7 @@ cp_add_mat_spec(ShaderMatSpec &spec) { spec._part[i] == SMO_texscale_i || spec._part[i] == SMO_texcolor_i) { begin[i] = spec._index; - end[i] = spec._index + 1; + end[i] = spec._index + spec._array_count; } } nassertv(end[0] == 1 || end[1] == 1); diff --git a/panda/src/gobj/shader.h b/panda/src/gobj/shader.h index fc7e49ae55..1b87d51c31 100644 --- a/panda/src/gobj/shader.h +++ b/panda/src/gobj/shader.h @@ -296,7 +296,9 @@ public: SMP_vec2, SMP_vec3, SMP_vec4, + SMP_vec4_array, SMP_mat4_whole, + SMP_mat4_array, SMP_mat4_transpose, SMP_mat4_column, SMP_mat4_upper3x3, @@ -441,6 +443,7 @@ public: int _index = 0; ShaderMatPiece _piece; int _offset = 0; + int _array_count = 1; }; struct ShaderTexSpec { From 2c727940ae5364cb5a5aa2b28c0fa4b5dd28c931 Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 18 Sep 2023 14:11:22 +0200 Subject: [PATCH 80/84] glgsg: Fix code issue with new integer ShaderMatSpec --- panda/src/glstuff/glShaderContext_src.cxx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/panda/src/glstuff/glShaderContext_src.cxx b/panda/src/glstuff/glShaderContext_src.cxx index c45ab59972..77bba57166 100644 --- a/panda/src/glstuff/glShaderContext_src.cxx +++ b/panda/src/glstuff/glShaderContext_src.cxx @@ -2309,10 +2309,10 @@ issue_parameters(int altered) { _glgsg->_glUniformMatrix3fv(p, 1, true, upper3.get_data()); continue; } - case Shader::SMP_int: _glgsg->_glUniform1i(p, ((int *)data)[0]); - case Shader::SMP_ivec2: _glgsg->_glUniform2iv(p, 1, (int *)data); - case Shader::SMP_ivec3: _glgsg->_glUniform3iv(p, 1, (int *)data); - case Shader::SMP_ivec4: _glgsg->_glUniform4iv(p, 1, (int *)data); + case Shader::SMP_int: _glgsg->_glUniform1i(p, ((int *)data)[0]); continue; + case Shader::SMP_ivec2: _glgsg->_glUniform2iv(p, 1, (int *)data); continue; + case Shader::SMP_ivec3: _glgsg->_glUniform3iv(p, 1, (int *)data); continue; + case Shader::SMP_ivec4: _glgsg->_glUniform4iv(p, 1, (int *)data); continue; } } } From c63a92bdec8043ec883ae8afc57ecf1670325d70 Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 8 Oct 2023 17:10:40 +0200 Subject: [PATCH 81/84] directnotify: Fix RotatingLog filePath error when sizeLimit is None --- direct/src/directnotify/RotatingLog.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/direct/src/directnotify/RotatingLog.py b/direct/src/directnotify/RotatingLog.py index ad4bd346db..e47b60cee6 100755 --- a/direct/src/directnotify/RotatingLog.py +++ b/direct/src/directnotify/RotatingLog.py @@ -55,10 +55,11 @@ class RotatingLog: return 0 def filePath(self): - dateString=time.strftime("%Y_%m_%d_%H", time.localtime()) + dateString = time.strftime("%Y_%m_%d_%H", time.localtime()) for i in range(26): - path="%s_%s_%s.log"%(self.path, dateString, chr(i+97)) - if not os.path.exists(path) or os.stat(path)[6] < self.sizeLimit: + limit = self.sizeLimit + path = "%s_%s_%s.log" % (self.path, dateString, chr(i+97)) + if limit is None not os.path.exists(path) or os.stat(path)[6] < limit: return path # Hmm, 26 files are full? throw the rest in z: # Maybe we should clear the self.sizeLimit here... maybe. From b99b3dc7d458e0d6f206b4f6bb4025b88968bd1a Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 8 Oct 2023 17:22:37 +0200 Subject: [PATCH 82/84] directnotify: Fix invalid syntax --- direct/src/directnotify/RotatingLog.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/direct/src/directnotify/RotatingLog.py b/direct/src/directnotify/RotatingLog.py index e47b60cee6..1502ad8994 100755 --- a/direct/src/directnotify/RotatingLog.py +++ b/direct/src/directnotify/RotatingLog.py @@ -59,7 +59,7 @@ class RotatingLog: for i in range(26): limit = self.sizeLimit path = "%s_%s_%s.log" % (self.path, dateString, chr(i+97)) - if limit is None not os.path.exists(path) or os.stat(path)[6] < limit: + if limit is None or not os.path.exists(path) or os.stat(path)[6] < limit: return path # Hmm, 26 files are full? throw the rest in z: # Maybe we should clear the self.sizeLimit here... maybe. From e5869ac7505c86f1ed2abd3fa588fd7934ec8163 Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 8 Oct 2023 23:30:00 +0200 Subject: [PATCH 83/84] pview: Fix camera positioning differences with offscreen window --- panda/src/framework/windowFramework.cxx | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/panda/src/framework/windowFramework.cxx b/panda/src/framework/windowFramework.cxx index f28c05f3d7..69a84db74c 100644 --- a/panda/src/framework/windowFramework.cxx +++ b/panda/src/framework/windowFramework.cxx @@ -468,20 +468,24 @@ setup_trackball() { return; } + _trackball = new Trackball("trackball"); + _trackball->set_pos(LVector3::forward() * 50.0); + if (_window->is_of_type(GraphicsWindow::get_class_type()) && DCAST(GraphicsWindow, _window)->get_num_input_devices() > 0) { NodePath mouse = get_mouse(); - NodePath camera = get_camera_group(); - - _trackball = new Trackball("trackball"); - _trackball->set_pos(LVector3::forward() * 50.0); mouse.attach_new_node(_trackball); - - PT(Transform2SG) tball2cam = new Transform2SG("tball2cam"); - tball2cam->set_node(camera.node()); - _trackball->add_child(tball2cam); + } else { + // Still need to have a Trackball so that the camera positioning works the + // same way when we're rendering offscreen. + _panda_framework->get_data_root().attach_new_node(_trackball); } + NodePath camera = get_camera_group(); + PT(Transform2SG) tball2cam = new Transform2SG("tball2cam"); + tball2cam->set_node(camera.node()); + _trackball->add_child(tball2cam); + _got_trackball = true; } From 526994c3021b30112d1e3cc84bec24b88b64aa32 Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 8 Oct 2023 23:36:59 +0200 Subject: [PATCH 84/84] pview: Don't require a window in screenshot mode --- panda/src/testbed/pview.cxx | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/panda/src/testbed/pview.cxx b/panda/src/testbed/pview.cxx index fcb88a05c0..e656af4b45 100644 --- a/panda/src/testbed/pview.cxx +++ b/panda/src/testbed/pview.cxx @@ -428,7 +428,16 @@ main(int argc, char **argv) { argc -= (optind - 1); argv += (optind - 1); - WindowFramework *window = framework.open_window(pipe, nullptr); + WindowProperties props(WindowProperties::get_default()); + props.set_title("Panda Viewer"); + + // Don't require a window in screenshot mode + int flags = 0; + if (!auto_screenshot) { + flags |= GraphicsPipe::BF_require_window; + } + + WindowFramework *window = framework.open_window(props, flags, pipe, nullptr); if (window != nullptr) { // We've successfully opened a window.