From: <sv...@ww...> - 2005-02-07 03:28:01
|
Author: mkrose Date: 2005-02-06 19:27:53 -0800 (Sun, 06 Feb 2005) New Revision: 1466 Modified: trunk/CSP/CSPSim/Tools/Layout/UI.py trunk/CSP/CSPSim/Tools/Layout/View.cpp trunk/CSP/CSPSim/Tools/Layout/View.h trunk/CSP/CSPSim/Tools/Layout/csplayout Log: Clean up some platform dependency problems in related to threading in CSPLayout. Browse at: https://www.zerobar.net/viewcvs/viewcvs.cgi?view=rev&rev=1466 Modified: trunk/CSP/CSPSim/Tools/Layout/UI.py =================================================================== --- trunk/CSP/CSPSim/Tools/Layout/UI.py 2005-02-05 19:25:19 UTC (rev 1465) +++ trunk/CSP/CSPSim/Tools/Layout/UI.py 2005-02-07 03:27:53 UTC (rev 1466) @@ -801,7 +801,12 @@ wxMessageDialog(self, 'Inserting "%s" into the active group would create an infinite recursion.' % path, "Load", style = wxOK|wxICON_ERROR).ShowModal() return None + # stop the 3d rendering loop while we modify the scene graph + self._view.lock(); feature_layout.realizeAsChild(parent, node_map) + # restart the 3d rendering loop + self._view.unlock(); + model = node_map.getRoot() self.UpdateTree(model) @@ -878,7 +883,6 @@ self.Close() def OnItemActivated(self, event): - print 'activated' id = event.GetItem() path = self.GetItemPath(id) if path: @@ -991,11 +995,15 @@ wxMessageDialog(self, "Cannot open leaf node FeatureModels; use insert instead.", "Error loading feature", style = wxOK|wxICON_ERROR).ShowModal() return 0 + # stop the 3d rendering loop while we load the new scene graph + self._view.lock(); node_map = graph.realize() self._node_map = node_map node = node_map.getRoot() assert(node is not None and node.isGroup()) self._view.graph().setRoot(node) + # restart the 3d rendering loop + self._view.unlock(); node.thisown = 0 self.UpdateTree(node) Modified: trunk/CSP/CSPSim/Tools/Layout/View.cpp =================================================================== --- trunk/CSP/CSPSim/Tools/Layout/View.cpp 2005-02-05 19:25:19 UTC (rev 1465) +++ trunk/CSP/CSPSim/Tools/Layout/View.cpp 2005-02-07 03:27:53 UTC (rev 1466) @@ -63,6 +63,7 @@ #include <osg/Drawable> #include <osg/ref_ptr> #include <osg/Vec3> +#include <OpenThreads/Thread> #include <iostream> #include <cstdio> @@ -70,6 +71,8 @@ View::View(): m_Viewer(0), m_FeatureGraph(0), m_Manipulator(0) { + // TODO move elsewhere in startup logic + OpenThreads::Thread::Init(); } int View::init(int argc, char **argv) { @@ -157,20 +160,29 @@ #endif m_Viewer->realize(); while (!m_Viewer->done() && !m_Quit) { - m_Viewer->sync(); - m_Viewer->update(); - m_Viewer->frame(); - m_DynamicGrid->setLook(getCameraTarget(), getCameraPosition()); + if (trylock() == 0) { + m_Viewer->sync(); + m_Viewer->update(); + m_Viewer->frame(); + m_DynamicGrid->setLook(getCameraTarget(), getCameraPosition()); + unlock(); + } Py_BEGIN_ALLOW_THREADS; -#ifndef _MSC_VER - nanosleep(&sleeptime, 0); -#else - Sleep(1); -#endif + OpenThreads::Thread::YieldCurrentThread(); Py_END_ALLOW_THREADS; } - //m_Viewer->sync(); - delete m_Viewer; + + // XXX + // Intentionally leak Viewer to prevent an xlib error on exit: + // + // Xlib: unexpected async reply (sequence 0x2e)! + // + // More likely than not we are only masking the problem, which + // probably results from asynchronous xlib access from the 2d + // and 3d threads. This hasn't caused any other noticible problems + // and by not deleting the viewer we get a clean exit. + // + //delete m_Viewer; m_Viewer = 0; } @@ -190,6 +202,7 @@ } Producer::Matrix view_matrix; view_matrix.makeLookAt(from ,to, up); + assert(m_Viewer); m_Viewer->setViewByMatrix(view_matrix); } @@ -221,6 +234,7 @@ } osg::Vec3 View::getCameraPosition() const { + assert(m_Viewer); const Producer::Matrix::value_type *view_matrix = m_Viewer->getCamera(0)->getPositionAndAttitudeMatrix(); Producer::Matrix matrix(view_matrix); Producer::Vec3 offset(matrix(3, 0), matrix(3, 1), matrix(3, 2)); @@ -247,6 +261,7 @@ void View::screenToSurface(float x, float y, float &surface_x, float &surface_y) { surface_x = surface_y = 0.0; float pixel_x, pixel_y; + assert(m_Viewer); if (m_Viewer->computePixelCoords(x, y, 0 /*camera_num*/, pixel_x, pixel_y)) { Producer::Camera *camera = m_Viewer->getCamera(0); int pr_wx, pr_wy; @@ -278,6 +293,7 @@ } bool View::computePixelCoords(float x, float y, float& pixel_x, float& pixel_y) { + assert(m_Viewer); return m_Viewer->computePixelCoords(x, y, 0 /*camera_num*/, pixel_x, pixel_y); } @@ -345,6 +361,7 @@ } void View::prepareScene() { + assert(m_Viewer); osg::Group *group = new osg::Group; makeLights(group); makeGround(group); Modified: trunk/CSP/CSPSim/Tools/Layout/View.h =================================================================== --- trunk/CSP/CSPSim/Tools/Layout/View.h 2005-02-05 19:25:19 UTC (rev 1465) +++ trunk/CSP/CSPSim/Tools/Layout/View.h 2005-02-07 03:27:53 UTC (rev 1466) @@ -171,6 +171,21 @@ */ float getGridScale() const; + /** Mutex synchronization for 2d and 3d threads. */ + int trylock() { + return m_Mutex.trylock(); + } + + /** Mutex synchronization for 2d and 3d threads. */ + int lock() { + return m_Mutex.lock(); + } + + /** Mutex synchronization for 2d and 3d threads. */ + int unlock() { + return m_Mutex.unlock(); + } + private: void setViewAxis(osg::Vec3 const &axis, osg::Vec3 const &up); void prepareScene(); @@ -190,6 +205,7 @@ typedef std::list< osg::ref_ptr<ViewCallback> > ViewCallbackList; ViewCallbackList m_ViewCallbacks; + OpenThreads::Mutex m_Mutex; }; Modified: trunk/CSP/CSPSim/Tools/Layout/csplayout =================================================================== --- trunk/CSP/CSPSim/Tools/Layout/csplayout 2005-02-05 19:25:19 UTC (rev 1465) +++ trunk/CSP/CSPSim/Tools/Layout/csplayout 2005-02-07 03:27:53 UTC (rev 1466) @@ -21,7 +21,7 @@ """ import sys -import threading +import thread import os.path import cLayout @@ -29,34 +29,23 @@ from CSP.base import app +def run(view, ui): + view.run() + ui.ExitMainLoop() -class UIThread(threading.Thread): - def __init__(self, view, xml_path, model_path): - threading.Thread.__init__(self) - self.setDaemon(1) - self._view = view - self._ui = UI.Init(view, xml_path, model_path) - - def run(self): - print "Combat Simulator Project Theater Layout Tool" - print "============================================" - self._ui.MainLoop() - self._view.quit() - - def main(args): + print "Combat Simulator Project Theater Layout Tool" + print "============================================" view = cLayout.View() - # was sys.argv, now argument parsing handled in python. at some point - # we may want to declare options for some of the flags that the osg - # ArgumentParser accepts and pass them explicitly (e.g. --stereo). - argv = [app.programName()] + argv = [app.programName()] + list(args) if view.init(argv): sys.exit(1) - ui = UIThread(view, app.options.xml, app.options.model) - ui.start() - view.run() + ui = UI.Init(view, app.options.xml, app.options.model) + thread.start_new_thread(run, (view, ui)) + ui.MainLoop() + view.quit() # find the root of the CSP workspace base = os.path.dirname(os.path.dirname(app.__file__)) @@ -70,4 +59,4 @@ app.addOption('--xml', default=xml_path, type='string', help='path to theater data') app.addOption('--model', default=model_path, type='string', help='path to 3d models') app.start() - +print 'end' |