diff --git a/direct/src/showbase/Loader.py b/direct/src/showbase/Loader.py index 924b396616..270b537078 100644 --- a/direct/src/showbase/Loader.py +++ b/direct/src/showbase/Loader.py @@ -27,6 +27,42 @@ class Loader(DirectObject): # This indicates that this class behaves like a Future. _asyncio_future_blocking = False + class ResultAwaiter(object): + """Reinvents generators because of PEP 479, sigh. See #513.""" + + __slots__ = 'requestList', 'index' + + def __init__(self, requestList): + self.requestList = requestList + self.index = 0 + + def __await__(self): + return self + + def __anext__(self): + if self.index >= len(self.requestList): + raise StopAsyncIteration + return self + + def __iter__(self): + return self + + def __next__(self): + i = self.index + request = self.requestList[i] + if not request.done(): + return request + + self.index = i + 1 + + result = request.result() + if isinstance(result, PandaNode): + result = NodePath(result) + + exc = StopIteration(result) + exc.value = result + raise exc + def __init__(self, loader, numObjects, gotList, callback, extraArgs): self._loader = loader self.objects = [None] * numObjects @@ -81,16 +117,14 @@ class Loader(DirectObject): def __await__(self): """ Returns a generator that raises StopIteration when the loading is complete. This allows this class to be used with 'await'.""" + if self.requests: self._asyncio_future_blocking = True - yield self - # This should be a simple return, but older versions of Python - # don't allow return statements with arguments. - result = self.result() - exc = StopIteration(result) - exc.value = result - raise exc + if self.gotList: + return self.ResultAwaiter([self]) + else: + return self.ResultAwaiter(self.requestList) def __aiter__(self): """ This allows using `async for` to iterate asynchronously over @@ -100,19 +134,7 @@ class Loader(DirectObject): requestList = self.requestList assert requestList is not None, "Request was cancelled." - class AsyncIter: - index = 0 - def __anext__(self): - if self.index < len(requestList): - i = self.index - self.index = i + 1 - return requestList[i] - else: - raise StopAsyncIteration - - iter = AsyncIter() - iter.objects = self.objects - return iter + return self.ResultAwaiter(requestList) # special methods def __init__(self, base): diff --git a/direct/src/tkwidgets/Valuator.py b/direct/src/tkwidgets/Valuator.py index 8b88d98680..39e0c8d73f 100644 --- a/direct/src/tkwidgets/Valuator.py +++ b/direct/src/tkwidgets/Valuator.py @@ -7,6 +7,7 @@ from direct.showbase.TkGlobal import * from . import WidgetPropertiesDialog import Pmw from direct.directtools.DirectUtil import getTkColorString +from panda3d.core import Vec4 if sys.version_info >= (3, 0): from tkinter.colorchooser import askcolor diff --git a/makepanda/makepackage.py b/makepanda/makepackage.py index daf0877544..ed20117d10 100755 --- a/makepanda/makepackage.py +++ b/makepanda/makepackage.py @@ -473,7 +473,7 @@ def MakeInstallerOSX(version, runtime=False, python_versions=[], **kwargs): dmg_name = "Panda3D-" + version if len(python_versions) == 1 and not python_versions[0]["version"].startswith("2."): - dmg_name += "-py" + pyver + dmg_name += "-py" + python_versions[0]["version"] dmg_name += ".dmg" if (os.path.isfile(dmg_name)): oscmd("rm -f %s" % dmg_name) diff --git a/panda/src/event/asyncTaskChain.cxx b/panda/src/event/asyncTaskChain.cxx index 34e458691e..1d511bce45 100644 --- a/panda/src/event/asyncTaskChain.cxx +++ b/panda/src/event/asyncTaskChain.cxx @@ -788,18 +788,17 @@ cleanup_task(AsyncTask *task, bool upon_death, bool clean_exit) { _manager->remove_task_by_name(task); - if (upon_death && task->set_future_state(clean_exit ? AsyncFuture::FS_finished - : AsyncFuture::FS_cancelled)) { - task->notify_done(clean_exit); - } - - task->_manager = nullptr; - if (upon_death) { _manager->_lock.unlock(); + if (task->set_future_state(clean_exit ? AsyncFuture::FS_finished + : AsyncFuture::FS_cancelled)) { + task->notify_done(clean_exit); + } task->upon_death(_manager, clean_exit); _manager->_lock.lock(); } + + task->_manager = nullptr; } /** diff --git a/panda/src/event/pythonTask.cxx b/panda/src/event/pythonTask.cxx index 554e1368e7..86200802a9 100644 --- a/panda/src/event/pythonTask.cxx +++ b/panda/src/event/pythonTask.cxx @@ -598,7 +598,9 @@ do_python_task() { // directly instead of having to do: // await taskMgr.add(Task.pause(1.0)) AsyncTask *task = (AsyncTask *)fut; - _manager->add(task); + if (!task->is_alive()) { + _manager->add(task); + } } if (fut->add_waiting_task(this)) { if (task_cat.is_debug()) { diff --git a/panda/src/glstuff/glGraphicsBuffer_src.cxx b/panda/src/glstuff/glGraphicsBuffer_src.cxx index ebb038de7a..bdeb26345f 100644 --- a/panda/src/glstuff/glGraphicsBuffer_src.cxx +++ b/panda/src/glstuff/glGraphicsBuffer_src.cxx @@ -1162,12 +1162,6 @@ bind_slot_multisample(bool rb_resize, Texture **attach, RenderTexturePlane slot, GLuint gl_format = GL_RGBA; #ifndef OPENGLES switch (slot) { - case RTP_aux_rgba_0: - case RTP_aux_rgba_1: - case RTP_aux_rgba_2: - case RTP_aux_rgba_3: - gl_format = GL_RGBA; - break; case RTP_aux_hrgba_0: case RTP_aux_hrgba_1: case RTP_aux_hrgba_2: @@ -1180,8 +1174,18 @@ bind_slot_multisample(bool rb_resize, Texture **attach, RenderTexturePlane slot, case RTP_aux_float_3: gl_format = GL_RGBA32F_ARB; break; + case RTP_aux_rgba_0: + case RTP_aux_rgba_1: + case RTP_aux_rgba_2: + case RTP_aux_rgba_3: default: - gl_format = GL_RGBA; + if (_fb_properties.get_srgb_color()) { + gl_format = GL_SRGB8_ALPHA8; + } else if (_fb_properties.get_float_color()) { + gl_format = GL_RGBA32F_ARB; + } else { + gl_format = GL_RGBA; + } break; } #endif diff --git a/panda/src/glstuff/glShaderContext_src.cxx b/panda/src/glstuff/glShaderContext_src.cxx index ae7a845efc..a2ac21cbc4 100644 --- a/panda/src/glstuff/glShaderContext_src.cxx +++ b/panda/src/glstuff/glShaderContext_src.cxx @@ -2042,10 +2042,6 @@ set_state_and_transform(const RenderState *target_rs, target_rs->get_attrib(MaterialAttrib::get_class_slot())) { altered |= Shader::SSD_material; } - if (state_rs->get_attrib(ShaderAttrib::get_class_slot()) != - target_rs->get_attrib(ShaderAttrib::get_class_slot())) { - altered |= Shader::SSD_shaderinputs; - } if (state_rs->get_attrib(FogAttrib::get_class_slot()) != target_rs->get_attrib(FogAttrib::get_class_slot())) { altered |= Shader::SSD_fog; @@ -2069,6 +2065,11 @@ set_state_and_transform(const RenderState *target_rs, _state_rs = target_rs; } + if (_shader_attrib.get_orig() != _glgsg->_target_shader || _shader_attrib.was_deleted()) { + altered |= Shader::SSD_shaderinputs; + _shader_attrib = _glgsg->_target_shader; + } + // Is this the first time this shader is used this frame? int frame_number = ClockObject::get_global_clock()->get_frame_count(); if (frame_number != _frame_number) { diff --git a/panda/src/glstuff/glShaderContext_src.h b/panda/src/glstuff/glShaderContext_src.h index 91130e9224..0ccb99fe90 100644 --- a/panda/src/glstuff/glShaderContext_src.h +++ b/panda/src/glstuff/glShaderContext_src.h @@ -76,6 +76,7 @@ private: CPT(TransformState) _camera_transform; CPT(TransformState) _projection_transform; CPT(ColorAttrib) _color_attrib; + WCPT(ShaderAttrib) _shader_attrib; /* * struct ParamContext { CPT(InternalName) _name; GLint _location; GLsizei diff --git a/panda/src/putil/datagramInputFile.cxx b/panda/src/putil/datagramInputFile.cxx index c4802ceed2..600f699635 100644 --- a/panda/src/putil/datagramInputFile.cxx +++ b/panda/src/putil/datagramInputFile.cxx @@ -109,7 +109,7 @@ read_header(std::string &header, size_t num_bytes) { nassertr(buffer != nullptr, false); _in->read(buffer, num_bytes); - if (_in->fail() || _in->eof()) { + if (_in->fail()) { return false; } @@ -130,7 +130,7 @@ get_datagram(Datagram &data) { // First, get the size of the upcoming datagram. StreamReader reader(_in, false); uint32_t num_bytes_32 = reader.get_uint32(); - if (_in->fail() || _in->eof()) { + if (_in->fail()) { return false; } @@ -141,16 +141,29 @@ get_datagram(Datagram &data) { return true; } + if (_in->eof()) { + return false; + } + size_t num_bytes = (size_t)num_bytes_32; if (num_bytes_32 == (uint32_t)-1) { // Another special case for a value larger than 32 bits. uint64_t num_bytes_64 = reader.get_uint64(); - if (_in->fail() || _in->eof()) { + if (_in->fail()) { _error = true; return false; } + if (num_bytes_64 == 0) { + data.clear(); + return false; + } + + if (_in->eof()) { + return false; + } + num_bytes = (size_t)num_bytes_64; // Make sure we have a reasonable datagram size for putting into memory. @@ -169,6 +182,11 @@ get_datagram(Datagram &data) { while (bytes_read < num_bytes) { size_t bytes_left = num_bytes - bytes_read; + if (_in->eof()) { + _error = true; + return false; + } + // Hold up a second - datagrams >4MB are pretty large by bam/network // standards. Let's take it 4MB at a time just in case the length is // corrupt, so we don't allocate potentially a few GBs of RAM only to @@ -180,7 +198,7 @@ get_datagram(Datagram &data) { unsigned char *ptr = &buffer.p()[bytes_read]; _in->read((char *)ptr, (streamsize)bytes_left); - if (_in->fail() || _in->eof()) { + if (_in->fail()) { _error = true; return false; } @@ -210,7 +228,7 @@ save_datagram(SubfileInfo &info) { // First, get the size of the upcoming datagram. StreamReader reader(_in, false); size_t num_bytes_32 = reader.get_uint32(); - if (_in->fail() || _in->eof()) { + if (_in->fail() || (_in->eof() && num_bytes_32 > 0)) { return false; } diff --git a/pandatool/src/flt/fltRecordReader.cxx b/pandatool/src/flt/fltRecordReader.cxx index c999001d64..eb3ba94840 100644 --- a/pandatool/src/flt/fltRecordReader.cxx +++ b/pandatool/src/flt/fltRecordReader.cxx @@ -131,20 +131,21 @@ advance(bool ok_eof) { // And now read the full record based on the length. int length = _next_record_length - header_size; - char *buffer = new char[length]; if (length > 0) { - _in.read(buffer, length); - } - _datagram = Datagram(buffer, length); - delete[] buffer; - - if (_in.eof()) { - _state = S_eof; - assert(!flt_error_abort); - return FE_end_of_file; + vector_uchar data((size_t)length); + _in.read((char *)&data[0], length); + _datagram = Datagram(std::move(data)); + } else { + _datagram = Datagram(); } if (_in.fail()) { + if (_in.eof()) { + _state = S_eof; + assert(!flt_error_abort); + return FE_end_of_file; + } + _state = S_error; assert(!flt_error_abort); return FE_read_error; @@ -162,20 +163,20 @@ advance(bool ok_eof) { _record_length += _next_record_length; length = _next_record_length - header_size; - buffer = new char[length]; if (length > 0) { + char *buffer = new char[length]; _in.read(buffer, length); - } - _datagram.append_data(buffer, length); - delete[] buffer; - - if (_in.eof()) { - _state = S_eof; - assert(!flt_error_abort); - return FE_end_of_file; + _datagram.append_data(buffer, length); + delete[] buffer; } if (_in.fail()) { + if (_in.eof()) { + _state = S_eof; + assert(!flt_error_abort); + return FE_end_of_file; + } + _state = S_error; assert(!flt_error_abort); return FE_read_error; @@ -221,11 +222,11 @@ read_next_header() { char bytes[header_size]; _in.read(bytes, header_size); - if (_in.eof()) { - _next_error = FE_end_of_file; - return; - - } else if (_in.fail()) { + if (_in.fail()) { + if (_in.eof()) { + _next_error = FE_end_of_file; + return; + } _next_error = FE_read_error; return; }