add callback support

This commit is contained in:
David Rose 2004-03-02 02:46:15 +00:00
parent 5b3bf0efbd
commit abd0db5458
3 changed files with 174 additions and 0 deletions

View File

@ -93,3 +93,39 @@ INLINE void GraphicsEngine::
close_gsg(GraphicsPipe *pipe, GraphicsStateGuardian *gsg) {
pipe->close_gsg(gsg);
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsEngine::Callback::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE GraphicsEngine::Callback::
Callback(CallbackFunction *func, void *data) :
_func(func),
_data(data)
{
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsEngine::Callback::operator <
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE bool GraphicsEngine::Callback::
operator < (const GraphicsEngine::Callback &other) const {
if (_func != other._func) {
return _func < other._func;
}
return _data < other._data;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsEngine::Callback::do_callback
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE void GraphicsEngine::Callback::
do_callback() const {
(*_func)(_data);
}

View File

@ -564,6 +564,51 @@ render_subframe(GraphicsStateGuardian *gsg, DisplayRegion *dr,
}
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsEngine::add_callback
// Access: Public
// Description: Adds the indicated C/C++ function and an arbitrary
// associated data pointer to the list of functions that
// will be called in the indicated thread at the
// indicated point of the frame.
//
// The thread name may be one of the cull or draw names
// specified in set_threading_model(), or it may be the
// empty string to indicated the app or main thread.
//
// The return value is true if the function and data
// pointer are successfully added to the appropriate
// callback list, or false if the same function and data
// pointer were already there.
////////////////////////////////////////////////////////////////////
bool GraphicsEngine::
add_callback(const string &thread_name,
GraphicsEngine::CallbackTime callback_time,
GraphicsEngine::CallbackFunction *func, void *data) {
WindowRenderer *wr = get_window_renderer(thread_name);
return wr->add_callback(callback_time, Callback(func, data));
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsEngine::remove_callback
// Access: Public
// Description: Removes a callback added by a previous call to
// add_callback(). All parameters must match the same
// parameters passed to add_callback(). The return
// value is true if the callback is successfully
// removed, or false if it was not on the list (either
// one or more of the parameters did not match the call
// to add_callback(), or the callback has already been
// removed).
////////////////////////////////////////////////////////////////////
bool GraphicsEngine::
remove_callback(const string &thread_name,
GraphicsEngine::CallbackTime callback_time,
GraphicsEngine::CallbackFunction *func, void *data) {
WindowRenderer *wr = get_window_renderer(thread_name);
return wr->remove_callback(callback_time, Callback(func, data));
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsEngine::set_window_sort
// Access: Private
@ -1248,6 +1293,9 @@ resort_windows() {
void GraphicsEngine::WindowRenderer::
do_frame(GraphicsEngine *engine) {
MutexHolder holder(_wl_lock);
do_callbacks(CB_pre_frame);
engine->cull_bin_draw(_cull);
engine->cull_and_draw_together(_cdraw);
engine->process_events(_window);
@ -1271,6 +1319,8 @@ do_frame(GraphicsEngine *engine) {
_gsgs.swap(new_gsgs);
}
do_callbacks(CB_post_frame);
}
////////////////////////////////////////////////////////////////////
@ -1393,6 +1443,60 @@ any_done_gsgs() const {
return false;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsEngine::WindowRenderer::add_callback
// Access: Public
// Description: Adds the indicated callback to this renderer's list
// for the indicated callback time. Returns true if it
// is successfully added, false if it was already there.
////////////////////////////////////////////////////////////////////
bool GraphicsEngine::WindowRenderer::
add_callback(GraphicsEngine::CallbackTime callback_time,
const GraphicsEngine::Callback &callback) {
nassertr(callback_time >= 0 && callback_time < CB_len, false);
MutexHolder holder(_wl_lock);
return _callbacks[callback_time].insert(callback).second;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsEngine::WindowRenderer::remove_callback
// Access: Public
// Description: Removes the indicated callback from this renderer's
// list for the indicated callback time. Returns true
// if it is successfully removed, or false if it was not
// on the list.
////////////////////////////////////////////////////////////////////
bool GraphicsEngine::WindowRenderer::
remove_callback(GraphicsEngine::CallbackTime callback_time,
const GraphicsEngine::Callback &callback) {
nassertr(callback_time >= 0 && callback_time < CB_len, false);
MutexHolder holder(_wl_lock);
Callbacks::iterator cbi = _callbacks[callback_time].find(callback);
if (cbi != _callbacks[callback_time].end()) {
_callbacks[callback_time].erase(cbi);
return true;
}
return false;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsEngine::WindowRenderer::do_callbacks
// Access: Private
// Description: Calls all of the callback functions on the indicated
// list. Intended to be called internally when we have
// reached the indicated point on the frame.
////////////////////////////////////////////////////////////////////
void GraphicsEngine::WindowRenderer::
do_callbacks(GraphicsEngine::CallbackTime callback_time) {
nassertv(callback_time >= 0 && callback_time < CB_len);
Callbacks::const_iterator cbi;
for (cbi = _callbacks[callback_time].begin();
cbi != _callbacks[callback_time].end();
++cbi) {
(*cbi).do_callback();
}
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsEngine::RenderThread::Constructor
// Access: Public

View File

@ -103,9 +103,34 @@ public:
TS_terminate
};
enum CallbackTime {
CB_pre_frame,
CB_post_frame,
CB_len // Not an option; just indicates the size of the list.
};
typedef void CallbackFunction(void *data);
bool add_callback(const string &thread_name, CallbackTime callback_time,
CallbackFunction *func, void *data);
bool remove_callback(const string &thread_name, CallbackTime callback_time,
CallbackFunction *func, void *data);
private:
class Callback {
public:
INLINE Callback(CallbackFunction *func, void *data);
INLINE bool operator < (const Callback &other) const;
INLINE void do_callback() const;
private:
CallbackFunction *_func;
void *_data;
};
typedef ov_multiset< PT(GraphicsOutput), IndirectLess<GraphicsOutput> > Windows;
typedef pset< PT(GraphicsStateGuardian) > GSGs;
typedef pset< Callback > Callbacks;
void set_window_sort(GraphicsOutput *window, int sort);
@ -152,6 +177,13 @@ private:
void do_pending(GraphicsEngine *engine);
bool any_done_gsgs() const;
bool add_callback(CallbackTime callback_time, const Callback &callback);
bool remove_callback(CallbackTime callback_time, const Callback &callback);
private:
void do_callbacks(CallbackTime callback_time);
public:
Windows _cull; // cull stage
Windows _cdraw; // cull-and-draw-together stage
Windows _draw; // draw stage
@ -162,6 +194,8 @@ private:
Windows _pending_close; // moved from _window, pending close.
GSGs _gsgs; // draw stage
Callbacks _callbacks[CB_len];
Mutex _wl_lock;
};