mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-02 09:52:27 -04:00
Merge branch 'master' into deploy-ng
This commit is contained in:
commit
bf1b486e5a
@ -2672,15 +2672,18 @@ class ShowBase(DirectObject.DirectObject):
|
|||||||
output file name (e.g. if sd = 4, movie_0001.png)
|
output file name (e.g. if sd = 4, movie_0001.png)
|
||||||
- source is the Window, Buffer, DisplayRegion, or Texture from which
|
- source is the Window, Buffer, DisplayRegion, or Texture from which
|
||||||
to save the resulting images. The default is the main window.
|
to save the resulting images. The default is the main window.
|
||||||
|
|
||||||
|
The task is returned, so that it can be awaited.
|
||||||
"""
|
"""
|
||||||
globalClock.setMode(ClockObject.MNonRealTime)
|
globalClock.setMode(ClockObject.MNonRealTime)
|
||||||
globalClock.setDt(1.0/float(fps))
|
globalClock.setDt(1.0/float(fps))
|
||||||
t = taskMgr.add(self._movieTask, namePrefix + '_task')
|
t = self.taskMgr.add(self._movieTask, namePrefix + '_task')
|
||||||
t.frameIndex = 0 # Frame 0 is not captured.
|
t.frameIndex = 0 # Frame 0 is not captured.
|
||||||
t.numFrames = int(duration * fps)
|
t.numFrames = int(duration * fps)
|
||||||
t.source = source
|
t.source = source
|
||||||
t.outputString = namePrefix + '_%0' + repr(sd) + 'd.' + format
|
t.outputString = namePrefix + '_%0' + repr(sd) + 'd.' + format
|
||||||
t.setUponDeath(lambda state: globalClock.setMode(ClockObject.MNormal))
|
t.setUponDeath(lambda state: globalClock.setMode(ClockObject.MNormal))
|
||||||
|
return t
|
||||||
|
|
||||||
def _movieTask(self, state):
|
def _movieTask(self, state):
|
||||||
if state.frameIndex != 0:
|
if state.frameIndex != 0:
|
||||||
|
@ -23,7 +23,9 @@ class Transitions:
|
|||||||
scale=3.0,
|
scale=3.0,
|
||||||
pos=Vec3(0, 0, 0)):
|
pos=Vec3(0, 0, 0)):
|
||||||
self.transitionIval = None
|
self.transitionIval = None
|
||||||
|
self.__transitionFuture = None
|
||||||
self.letterboxIval = None
|
self.letterboxIval = None
|
||||||
|
self.__letterboxFuture = None
|
||||||
self.iris = None
|
self.iris = None
|
||||||
self.fade = None
|
self.fade = None
|
||||||
self.letterbox = None
|
self.letterbox = None
|
||||||
@ -94,7 +96,9 @@ class Transitions:
|
|||||||
"""
|
"""
|
||||||
#self.noTransitions() masad: this creates a one frame pop, is it necessary?
|
#self.noTransitions() masad: this creates a one frame pop, is it necessary?
|
||||||
self.loadFade()
|
self.loadFade()
|
||||||
transitionIval = Sequence(Func(self.fade.reparentTo, aspect2d, DGG.FADE_SORT_INDEX),
|
|
||||||
|
parent = aspect2d if self.fadeModel else render2d
|
||||||
|
transitionIval = Sequence(Func(self.fade.reparentTo, parent, DGG.FADE_SORT_INDEX),
|
||||||
Func(self.fade.showThrough), # in case aspect2d is hidden for some reason
|
Func(self.fade.showThrough), # in case aspect2d is hidden for some reason
|
||||||
self.lerpFunc(self.fade, t,
|
self.lerpFunc(self.fade, t,
|
||||||
self.alphaOff,
|
self.alphaOff,
|
||||||
@ -115,7 +119,8 @@ class Transitions:
|
|||||||
self.noTransitions()
|
self.noTransitions()
|
||||||
self.loadFade()
|
self.loadFade()
|
||||||
|
|
||||||
transitionIval = Sequence(Func(self.fade.reparentTo,aspect2d,DGG.FADE_SORT_INDEX),
|
parent = aspect2d if self.fadeModel else render2d
|
||||||
|
transitionIval = Sequence(Func(self.fade.reparentTo, parent, DGG.FADE_SORT_INDEX),
|
||||||
Func(self.fade.showThrough), # in case aspect2d is hidden for some reason
|
Func(self.fade.showThrough), # in case aspect2d is hidden for some reason
|
||||||
self.lerpFunc(self.fade, t,
|
self.lerpFunc(self.fade, t,
|
||||||
self.alphaOn,
|
self.alphaOn,
|
||||||
@ -148,11 +153,17 @@ class Transitions:
|
|||||||
self.noTransitions()
|
self.noTransitions()
|
||||||
self.loadFade()
|
self.loadFade()
|
||||||
self.fade.detachNode()
|
self.fade.detachNode()
|
||||||
|
fut = AsyncFuture()
|
||||||
|
fut.setResult(None)
|
||||||
|
return fut
|
||||||
else:
|
else:
|
||||||
# Create a sequence that lerps the color out, then
|
# Create a sequence that lerps the color out, then
|
||||||
# parents the fade to hidden
|
# parents the fade to hidden
|
||||||
self.transitionIval = self.getFadeInIval(t, finishIval)
|
self.transitionIval = self.getFadeInIval(t, finishIval)
|
||||||
|
self.transitionIval.append(Func(self.__finishTransition))
|
||||||
|
self.__transitionFuture = AsyncFuture()
|
||||||
self.transitionIval.start()
|
self.transitionIval.start()
|
||||||
|
return self.__transitionFuture
|
||||||
|
|
||||||
def fadeOut(self, t=0.5, finishIval=None):
|
def fadeOut(self, t=0.5, finishIval=None):
|
||||||
"""
|
"""
|
||||||
@ -167,7 +178,9 @@ class Transitions:
|
|||||||
# Fade out immediately with no lerp
|
# Fade out immediately with no lerp
|
||||||
self.noTransitions()
|
self.noTransitions()
|
||||||
self.loadFade()
|
self.loadFade()
|
||||||
self.fade.reparentTo(aspect2d, DGG.FADE_SORT_INDEX)
|
|
||||||
|
parent = aspect2d if self.fadeModel else render2d
|
||||||
|
self.fade.reparentTo(parent, DGG.FADE_SORT_INDEX)
|
||||||
self.fade.setColor(self.alphaOn)
|
self.fade.setColor(self.alphaOn)
|
||||||
elif ConfigVariableBool('no-loading-screen', False):
|
elif ConfigVariableBool('no-loading-screen', False):
|
||||||
if finishIval:
|
if finishIval:
|
||||||
@ -176,8 +189,16 @@ class Transitions:
|
|||||||
else:
|
else:
|
||||||
# Create a sequence that lerps the color out, then
|
# Create a sequence that lerps the color out, then
|
||||||
# parents the fade to hidden
|
# parents the fade to hidden
|
||||||
self.transitionIval = self.getFadeOutIval(t,finishIval)
|
self.transitionIval = self.getFadeOutIval(t, finishIval)
|
||||||
|
self.transitionIval.append(Func(self.__finishTransition))
|
||||||
|
self.__transitionFuture = AsyncFuture()
|
||||||
self.transitionIval.start()
|
self.transitionIval.start()
|
||||||
|
return self.__transitionFuture
|
||||||
|
|
||||||
|
# Immediately done, so return a dummy future.
|
||||||
|
fut = AsyncFuture()
|
||||||
|
fut.setResult(None)
|
||||||
|
return fut
|
||||||
|
|
||||||
def fadeOutActive(self):
|
def fadeOutActive(self):
|
||||||
return self.fade and self.fade.getColor()[3] > 0
|
return self.fade and self.fade.getColor()[3] > 0
|
||||||
@ -191,7 +212,9 @@ class Transitions:
|
|||||||
#print "transitiosn: fadeScreen"
|
#print "transitiosn: fadeScreen"
|
||||||
self.noTransitions()
|
self.noTransitions()
|
||||||
self.loadFade()
|
self.loadFade()
|
||||||
self.fade.reparentTo(aspect2d, DGG.FADE_SORT_INDEX)
|
|
||||||
|
parent = aspect2d if self.fadeModel else render2d
|
||||||
|
self.fade.reparentTo(parent, DGG.FADE_SORT_INDEX)
|
||||||
self.fade.setColor(self.alphaOn[0],
|
self.fade.setColor(self.alphaOn[0],
|
||||||
self.alphaOn[1],
|
self.alphaOn[1],
|
||||||
self.alphaOn[2],
|
self.alphaOn[2],
|
||||||
@ -206,7 +229,9 @@ class Transitions:
|
|||||||
#print "transitiosn: fadeScreenColor"
|
#print "transitiosn: fadeScreenColor"
|
||||||
self.noTransitions()
|
self.noTransitions()
|
||||||
self.loadFade()
|
self.loadFade()
|
||||||
self.fade.reparentTo(aspect2d, DGG.FADE_SORT_INDEX)
|
|
||||||
|
parent = aspect2d if self.fadeModel else render2d
|
||||||
|
self.fade.reparentTo(parent, DGG.FADE_SORT_INDEX)
|
||||||
self.fade.setColor(color)
|
self.fade.setColor(color)
|
||||||
|
|
||||||
def noFade(self):
|
def noFade(self):
|
||||||
@ -217,6 +242,9 @@ class Transitions:
|
|||||||
if self.transitionIval:
|
if self.transitionIval:
|
||||||
self.transitionIval.pause()
|
self.transitionIval.pause()
|
||||||
self.transitionIval = None
|
self.transitionIval = None
|
||||||
|
if self.__transitionFuture:
|
||||||
|
self.__transitionFuture.cancel()
|
||||||
|
self.__transitionFuture = None
|
||||||
if self.fade:
|
if self.fade:
|
||||||
# Make sure to reset the color, since fadeOutActive() is looking at it
|
# Make sure to reset the color, since fadeOutActive() is looking at it
|
||||||
self.fade.setColor(self.alphaOff)
|
self.fade.setColor(self.alphaOff)
|
||||||
@ -247,18 +275,25 @@ class Transitions:
|
|||||||
self.loadIris()
|
self.loadIris()
|
||||||
if (t == 0):
|
if (t == 0):
|
||||||
self.iris.detachNode()
|
self.iris.detachNode()
|
||||||
|
fut = AsyncFuture()
|
||||||
|
fut.setResult(None)
|
||||||
|
return fut
|
||||||
else:
|
else:
|
||||||
self.iris.reparentTo(aspect2d, DGG.FADE_SORT_INDEX)
|
self.iris.reparentTo(aspect2d, DGG.FADE_SORT_INDEX)
|
||||||
|
|
||||||
|
scale = 0.18 * max(base.a2dRight, base.a2dTop)
|
||||||
self.transitionIval = Sequence(LerpScaleInterval(self.iris, t,
|
self.transitionIval = Sequence(LerpScaleInterval(self.iris, t,
|
||||||
scale = 0.18,
|
scale = scale,
|
||||||
startScale = 0.01),
|
startScale = 0.01),
|
||||||
Func(self.iris.detachNode),
|
Func(self.iris.detachNode),
|
||||||
|
Func(self.__finishTransition),
|
||||||
name = self.irisTaskName,
|
name = self.irisTaskName,
|
||||||
)
|
)
|
||||||
|
self.__transitionFuture = AsyncFuture()
|
||||||
if finishIval:
|
if finishIval:
|
||||||
self.transitionIval.append(finishIval)
|
self.transitionIval.append(finishIval)
|
||||||
self.transitionIval.start()
|
self.transitionIval.start()
|
||||||
|
return self.__transitionFuture
|
||||||
|
|
||||||
def irisOut(self, t=0.5, finishIval=None):
|
def irisOut(self, t=0.5, finishIval=None):
|
||||||
"""
|
"""
|
||||||
@ -274,20 +309,27 @@ class Transitions:
|
|||||||
if (t == 0):
|
if (t == 0):
|
||||||
self.iris.detachNode()
|
self.iris.detachNode()
|
||||||
self.fadeOut(0)
|
self.fadeOut(0)
|
||||||
|
fut = AsyncFuture()
|
||||||
|
fut.setResult(None)
|
||||||
|
return fut
|
||||||
else:
|
else:
|
||||||
self.iris.reparentTo(aspect2d, DGG.FADE_SORT_INDEX)
|
self.iris.reparentTo(aspect2d, DGG.FADE_SORT_INDEX)
|
||||||
|
|
||||||
|
scale = 0.18 * max(base.a2dRight, base.a2dTop)
|
||||||
self.transitionIval = Sequence(LerpScaleInterval(self.iris, t,
|
self.transitionIval = Sequence(LerpScaleInterval(self.iris, t,
|
||||||
scale = 0.01,
|
scale = 0.01,
|
||||||
startScale = 0.18),
|
startScale = scale),
|
||||||
Func(self.iris.detachNode),
|
Func(self.iris.detachNode),
|
||||||
# Use the fade to cover up the hole that the iris would leave
|
# Use the fade to cover up the hole that the iris would leave
|
||||||
Func(self.fadeOut, 0),
|
Func(self.fadeOut, 0),
|
||||||
|
Func(self.__finishTransition),
|
||||||
name = self.irisTaskName,
|
name = self.irisTaskName,
|
||||||
)
|
)
|
||||||
|
self.__transitionFuture = AsyncFuture()
|
||||||
if finishIval:
|
if finishIval:
|
||||||
self.transitionIval.append(finishIval)
|
self.transitionIval.append(finishIval)
|
||||||
self.transitionIval.start()
|
self.transitionIval.start()
|
||||||
|
return self.__transitionFuture
|
||||||
|
|
||||||
def noIris(self):
|
def noIris(self):
|
||||||
"""
|
"""
|
||||||
@ -311,6 +353,11 @@ class Transitions:
|
|||||||
# Letterbox is not really a transition, it is a screen overlay
|
# Letterbox is not really a transition, it is a screen overlay
|
||||||
# self.noLetterbox()
|
# self.noLetterbox()
|
||||||
|
|
||||||
|
def __finishTransition(self):
|
||||||
|
if self.__transitionFuture:
|
||||||
|
self.__transitionFuture.setResult(None)
|
||||||
|
self.__transitionFuture = None
|
||||||
|
|
||||||
##################################################
|
##################################################
|
||||||
# Letterbox
|
# Letterbox
|
||||||
##################################################
|
##################################################
|
||||||
@ -383,9 +430,17 @@ class Transitions:
|
|||||||
if self.letterboxIval:
|
if self.letterboxIval:
|
||||||
self.letterboxIval.pause()
|
self.letterboxIval.pause()
|
||||||
self.letterboxIval = None
|
self.letterboxIval = None
|
||||||
|
if self.__letterboxFuture:
|
||||||
|
self.__letterboxFuture.cancel()
|
||||||
|
self.__letterboxFuture = None
|
||||||
if self.letterbox:
|
if self.letterbox:
|
||||||
self.letterbox.stash()
|
self.letterbox.stash()
|
||||||
|
|
||||||
|
def __finishLetterbox(self):
|
||||||
|
if self.__letterboxFuture:
|
||||||
|
self.__letterboxFuture.setResult(None)
|
||||||
|
self.__letterboxFuture = None
|
||||||
|
|
||||||
def letterboxOn(self, t=0.25, finishIval=None):
|
def letterboxOn(self, t=0.25, finishIval=None):
|
||||||
"""
|
"""
|
||||||
Move black bars in over t seconds.
|
Move black bars in over t seconds.
|
||||||
@ -396,7 +451,11 @@ class Transitions:
|
|||||||
if (t == 0):
|
if (t == 0):
|
||||||
self.letterboxBottom.setPos(0, 0, -1)
|
self.letterboxBottom.setPos(0, 0, -1)
|
||||||
self.letterboxTop.setPos(0, 0, 0.8)
|
self.letterboxTop.setPos(0, 0, 0.8)
|
||||||
|
fut = AsyncFuture()
|
||||||
|
fut.setResult(None)
|
||||||
|
return fut
|
||||||
else:
|
else:
|
||||||
|
self.__letterboxFuture = AsyncFuture()
|
||||||
self.letterboxIval = Sequence(Parallel(
|
self.letterboxIval = Sequence(Parallel(
|
||||||
LerpPosInterval(self.letterboxBottom,
|
LerpPosInterval(self.letterboxBottom,
|
||||||
t,
|
t,
|
||||||
@ -409,11 +468,13 @@ class Transitions:
|
|||||||
# startPos = Vec3(0, 0, 1),
|
# startPos = Vec3(0, 0, 1),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
Func(self.__finishLetterbox),
|
||||||
name = self.letterboxTaskName,
|
name = self.letterboxTaskName,
|
||||||
)
|
)
|
||||||
if finishIval:
|
if finishIval:
|
||||||
self.letterboxIval.append(finishIval)
|
self.letterboxIval.append(finishIval)
|
||||||
self.letterboxIval.start()
|
self.letterboxIval.start()
|
||||||
|
return self.__letterboxFuture
|
||||||
|
|
||||||
def letterboxOff(self, t=0.25, finishIval=None):
|
def letterboxOff(self, t=0.25, finishIval=None):
|
||||||
"""
|
"""
|
||||||
@ -424,7 +485,11 @@ class Transitions:
|
|||||||
self.letterbox.unstash()
|
self.letterbox.unstash()
|
||||||
if (t == 0):
|
if (t == 0):
|
||||||
self.letterbox.stash()
|
self.letterbox.stash()
|
||||||
|
fut = AsyncFuture()
|
||||||
|
fut.setResult(None)
|
||||||
|
return fut
|
||||||
else:
|
else:
|
||||||
|
self.__letterboxFuture = AsyncFuture()
|
||||||
self.letterboxIval = Sequence(Parallel(
|
self.letterboxIval = Sequence(Parallel(
|
||||||
LerpPosInterval(self.letterboxBottom,
|
LerpPosInterval(self.letterboxBottom,
|
||||||
t,
|
t,
|
||||||
@ -438,9 +503,11 @@ class Transitions:
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
Func(self.letterbox.stash),
|
Func(self.letterbox.stash),
|
||||||
|
Func(self.__finishLetterbox),
|
||||||
Func(messenger.send,'letterboxOff'),
|
Func(messenger.send,'letterboxOff'),
|
||||||
name = self.letterboxTaskName,
|
name = self.letterboxTaskName,
|
||||||
)
|
)
|
||||||
if finishIval:
|
if finishIval:
|
||||||
self.letterboxIval.append(finishIval)
|
self.letterboxIval.append(finishIval)
|
||||||
self.letterboxIval.start()
|
self.letterboxIval.start()
|
||||||
|
return self.__letterboxFuture
|
||||||
|
@ -122,6 +122,11 @@ typedef ios::seekdir ios_seekdir;
|
|||||||
// Apple has an outdated libstdc++. Not all is lost, though, as we can fill
|
// Apple has an outdated libstdc++. Not all is lost, though, as we can fill
|
||||||
// in some important missing functions.
|
// in some important missing functions.
|
||||||
#if defined(__GLIBCXX__) && __GLIBCXX__ <= 20070719
|
#if defined(__GLIBCXX__) && __GLIBCXX__ <= 20070719
|
||||||
|
#include <tr1/tuple>
|
||||||
|
|
||||||
|
using std::tr1::tuple;
|
||||||
|
using std::tr1::tie;
|
||||||
|
|
||||||
typedef decltype(nullptr) nullptr_t;
|
typedef decltype(nullptr) nullptr_t;
|
||||||
|
|
||||||
template<class T> struct remove_reference {typedef T type;};
|
template<class T> struct remove_reference {typedef T type;};
|
||||||
|
@ -119,6 +119,7 @@ protected:
|
|||||||
double _wake_time;
|
double _wake_time;
|
||||||
int _sort;
|
int _sort;
|
||||||
int _priority;
|
int _priority;
|
||||||
|
unsigned int _implicit_sort;
|
||||||
|
|
||||||
State _state;
|
State _state;
|
||||||
Thread *_servicing_thread;
|
Thread *_servicing_thread;
|
||||||
|
@ -51,7 +51,8 @@ AsyncTaskChain(AsyncTaskManager *manager, const string &name) :
|
|||||||
_needs_cleanup(false),
|
_needs_cleanup(false),
|
||||||
_current_frame(0),
|
_current_frame(0),
|
||||||
_time_in_frame(0.0),
|
_time_in_frame(0.0),
|
||||||
_block_till_next_frame(false)
|
_block_till_next_frame(false),
|
||||||
|
_next_implicit_sort(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -418,6 +419,9 @@ do_add(AsyncTask *task) {
|
|||||||
task->_start_time = now;
|
task->_start_time = now;
|
||||||
task->_start_frame = _manager->_clock->get_frame_count();
|
task->_start_frame = _manager->_clock->get_frame_count();
|
||||||
|
|
||||||
|
// Remember the order in which tasks were added to the chain.
|
||||||
|
task->_implicit_sort = _next_implicit_sort++;
|
||||||
|
|
||||||
_manager->add_task_by_name(task);
|
_manager->add_task_by_name(task);
|
||||||
|
|
||||||
if (task->has_delay()) {
|
if (task->has_delay()) {
|
||||||
|
@ -146,8 +146,13 @@ protected:
|
|||||||
if (a->get_priority() != b->get_priority()) {
|
if (a->get_priority() != b->get_priority()) {
|
||||||
return a->get_priority() < b->get_priority();
|
return a->get_priority() < b->get_priority();
|
||||||
}
|
}
|
||||||
|
if (a->get_start_time() != b->get_start_time()) {
|
||||||
return a->get_start_time() > b->get_start_time();
|
return a->get_start_time() > b->get_start_time();
|
||||||
}
|
}
|
||||||
|
// Failing any other ordering criteria, we sort the tasks based on the
|
||||||
|
// order in which they were added to the task chain.
|
||||||
|
return a->_implicit_sort > b->_implicit_sort;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef pvector< PT(AsyncTaskChainThread) > Threads;
|
typedef pvector< PT(AsyncTaskChainThread) > Threads;
|
||||||
@ -186,6 +191,8 @@ protected:
|
|||||||
double _time_in_frame;
|
double _time_in_frame;
|
||||||
bool _block_till_next_frame;
|
bool _block_till_next_frame;
|
||||||
|
|
||||||
|
unsigned int _next_implicit_sort;
|
||||||
|
|
||||||
static PStatCollector _task_pcollector;
|
static PStatCollector _task_pcollector;
|
||||||
static PStatCollector _wait_pcollector;
|
static PStatCollector _wait_pcollector;
|
||||||
|
|
||||||
|
@ -94,6 +94,9 @@ PythonTask::
|
|||||||
PyErr_Restore(_exception, _exc_value, _exc_traceback);
|
PyErr_Restore(_exception, _exc_value, _exc_traceback);
|
||||||
PyErr_Print();
|
PyErr_Print();
|
||||||
PyErr_Restore(nullptr, nullptr, nullptr);
|
PyErr_Restore(nullptr, nullptr, nullptr);
|
||||||
|
_exception = nullptr;
|
||||||
|
_exc_value = nullptr;
|
||||||
|
_exc_traceback = nullptr;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -12647,7 +12647,7 @@ upload_texture_image(CLP(TextureContext) *gtc, bool needs_reload,
|
|||||||
int depth = tex->get_expected_mipmap_z_size(mipmap_bias);
|
int depth = tex->get_expected_mipmap_z_size(mipmap_bias);
|
||||||
|
|
||||||
// Determine the number of images to upload.
|
// Determine the number of images to upload.
|
||||||
int num_levels = 1;
|
int num_levels = mipmap_bias + 1;
|
||||||
if (uses_mipmaps) {
|
if (uses_mipmaps) {
|
||||||
num_levels = tex->get_expected_num_mipmap_levels();
|
num_levels = tex->get_expected_num_mipmap_levels();
|
||||||
}
|
}
|
||||||
|
@ -94,6 +94,10 @@ BamWriter::
|
|||||||
for (si = _state_map.begin(); si != _state_map.end(); ++si) {
|
for (si = _state_map.begin(); si != _state_map.end(); ++si) {
|
||||||
TypedWritable *object = (TypedWritable *)(*si).first;
|
TypedWritable *object = (TypedWritable *)(*si).first;
|
||||||
object->remove_bam_writer(this);
|
object->remove_bam_writer(this);
|
||||||
|
|
||||||
|
if ((*si).second._refcount != nullptr) {
|
||||||
|
unref_delete((*si).second._refcount);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -529,6 +533,9 @@ object_destructs(TypedWritable *object) {
|
|||||||
// we're in trouble when we do write it out.
|
// we're in trouble when we do write it out.
|
||||||
nassertv(!(*si).second._written_seq.is_initial());
|
nassertv(!(*si).second._written_seq.is_initial());
|
||||||
|
|
||||||
|
// This cannot be called if we are still holding a reference to it.
|
||||||
|
nassertv((*si).second._refcount == nullptr);
|
||||||
|
|
||||||
int object_id = (*si).second._object_id;
|
int object_id = (*si).second._object_id;
|
||||||
_freed_object_ids.push_back(object_id);
|
_freed_object_ids.push_back(object_id);
|
||||||
|
|
||||||
@ -606,8 +613,10 @@ enqueue_object(const TypedWritable *object) {
|
|||||||
// No, it hasn't, so assign it the next number in sequence arbitrarily.
|
// No, it hasn't, so assign it the next number in sequence arbitrarily.
|
||||||
object_id = _next_object_id;
|
object_id = _next_object_id;
|
||||||
|
|
||||||
bool inserted =
|
StateMap::iterator si;
|
||||||
_state_map.insert(StateMap::value_type(object, StoreState(_next_object_id))).second;
|
bool inserted;
|
||||||
|
tie(si, inserted) =
|
||||||
|
_state_map.insert(StateMap::value_type(object, StoreState(_next_object_id)));
|
||||||
nassertr(inserted, false);
|
nassertr(inserted, false);
|
||||||
|
|
||||||
// Store ourselves on the TypedWritable so that we get notified when it
|
// Store ourselves on the TypedWritable so that we get notified when it
|
||||||
@ -615,6 +624,14 @@ enqueue_object(const TypedWritable *object) {
|
|||||||
(const_cast<TypedWritable*>(object))->add_bam_writer(this);
|
(const_cast<TypedWritable*>(object))->add_bam_writer(this);
|
||||||
_next_object_id++;
|
_next_object_id++;
|
||||||
|
|
||||||
|
// Increase the reference count if this inherits from ReferenceCount,
|
||||||
|
// until we get a chance to write this object for the first time.
|
||||||
|
const ReferenceCount *rc = ((TypedWritable *)object)->as_reference_count();
|
||||||
|
if (rc != nullptr) {
|
||||||
|
rc->ref();
|
||||||
|
(*si).second._refcount = rc;
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// Yes, it has; get the object ID.
|
// Yes, it has; get the object ID.
|
||||||
object_id = (*si).second._object_id;
|
object_id = (*si).second._object_id;
|
||||||
@ -703,6 +720,15 @@ flush_queue() {
|
|||||||
(*si).second._written_seq = _writing_seq;
|
(*si).second._written_seq = _writing_seq;
|
||||||
(*si).second._modified = object->get_bam_modified();
|
(*si).second._modified = object->get_bam_modified();
|
||||||
|
|
||||||
|
// Now release any reference we hold to it, so that it may destruct.
|
||||||
|
const ReferenceCount *rc = (*si).second._refcount;
|
||||||
|
if (rc != nullptr) {
|
||||||
|
// We need to assign this pointer to null before deleting the object,
|
||||||
|
// since that may end up calling object_destructs.
|
||||||
|
(*si).second._refcount = nullptr;
|
||||||
|
unref_delete(rc);
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// On subsequent times when we write a particular object, we write
|
// On subsequent times when we write a particular object, we write
|
||||||
// simply TypeHandle::none(), followed by the object ID. The occurrence
|
// simply TypeHandle::none(), followed by the object ID. The occurrence
|
||||||
|
@ -140,8 +140,9 @@ private:
|
|||||||
int _object_id;
|
int _object_id;
|
||||||
UpdateSeq _written_seq;
|
UpdateSeq _written_seq;
|
||||||
UpdateSeq _modified;
|
UpdateSeq _modified;
|
||||||
|
const ReferenceCount *_refcount;
|
||||||
|
|
||||||
StoreState(int object_id) : _object_id(object_id) {}
|
StoreState(int object_id) : _object_id(object_id), _refcount(nullptr) {}
|
||||||
};
|
};
|
||||||
typedef phash_map<const TypedWritable *, StoreState, pointer_hash> StateMap;
|
typedef phash_map<const TypedWritable *, StoreState, pointer_hash> StateMap;
|
||||||
StateMap _state_map;
|
StateMap _state_map;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user