Fresco/Berlin/src GraphDebugger.cc,NONE,1.1 GraphicDictionary.cc,NONE,1.1 GraphicImpl.cc,1.57,1.58 KitImpl.cc,1.12,1.13 Makefile.in,1.40,1.41

Tobias Hunger <[email protected]>
Newsgroups gmane.comp.video.fresco.cvs
Message-ID <[email protected]>
Update of /cvs/fresco/Fresco/Berlin/src
In directory purcel:/tmp/cvs-serv1225/Berlin/src

Modified Files:
	GraphicImpl.cc KitImpl.cc Makefile.in 
Added Files:
	GraphDebugger.cc GraphicDictionary.cc 
Log Message:
Initial checkin of a scene graph debugging framework.

To activate run the server with the -D option (and -l if you want to
see the log output of course). To get a dot-file of the current
scene graph send a USR1 signal to the server process. It will then 
dump the graph into /tmp/debug.dot. Use graphviz's dot-tool to turn that
file into a PS-drawing of the scene graph (cat /tmp/debug.dot | dot -Tps).

TODO: * add more information to the output (transformation, allocation, etc.)
      * make sure all graphics get registered. We have a couple of "unknowns"
        in the dump as of now.


--- NEW FILE: GraphDebugger.cc ---
/*$Id: GraphDebugger.cc,v 1.1 2003/02/26 00:19:09 tobias Exp $
 *
 * This source file is a part of the Fresco Project.
 * Copyright (C) 2003 Tobias Hunger <[email protected]>
 * http://www.fresco.org
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
 * MA 02139, USA.
 */

#include <Fresco/Controller.hh>

#include <Berlin/GraphDebugger.hh>
#include <Berlin/GraphicImpl.hh>
#include <Berlin/GraphicDictionary.hh>

#include <limits>
#include <iostream>
#include <fstream>
#include <typeinfo>

unsigned long Berlin::GraphDebugger::my_current_id = 0;


Berlin::GraphDebugger::GraphDebugger(Fresco::Graphic_ptr r) :
    my_root(r),
    my_known_graphics()
{
    Berlin::GraphicDictionary::instance()->activate();
}

Berlin::GraphDebugger::~GraphDebugger()
{ }

void Berlin::GraphDebugger::debug()
{
    my_current_id = 0;
    std::ofstream out("/tmp/debug.dot");
    
    out << "digraph SceneGraph {" << std::endl;
    dump_graphic(my_root, out);
    out << "}" << std::endl;
    
    my_known_graphics.clear();
}

void Berlin::GraphDebugger::dump_graphic(Fresco::Graphic_ptr g,
					 std::ostream & out)
{
    if (CORBA::is_nil(g)) return;
    
    graphic_info & info = find_or_insert(g);
    if (info.dumped) return;
    
    // dump output:
    
    // node id:
    out << "    n" << info.id << " ";
    
    // label: name
    out << "[label=\"" << info.name << "(n" << info.id << ")\","
	<< std::endl;
    
    // shape (depending on type of g)
    out << "        shape=\"";
    if (CORBA::is_nil(Fresco::Controller::_narrow(g)))
	out << "ellipse";
    else
	out << "box";
    out << "\"]" << std::endl;
    
    
    info.dumped = true;
    
    
    // recursion:
    // calculate graphics to traverse:
    std::vector<Fresco::Graphic_ptr> children;

    if (CORBA::is_nil(g->body()))
    {
	Fresco::GraphicIterator_var i = g->first_child_graphic();
	if (CORBA::is_nil(i)) return; // leaf graphic!

	for ( ; !CORBA::is_nil(i->child()); i->next())
	{
	    children.push_back(i->child());
	}
    }
    else
	children.push_back(g->body());

    // children contain all childgraphics now!
    for (std::vector<Fresco::Graphic_ptr>::const_iterator i = children.begin();
	 i != children.end();
	 ++i)
    {
	graphic_info & target = find_or_insert(*i);
	out << "    n" << info.id << " -> n" << target.id << std::endl;
    }

    for (std::vector<Fresco::Graphic_ptr>::const_iterator i = children.begin();
	 i != children.end();
	 ++i)
	dump_graphic(*i, out);
}


Berlin::GraphDebugger::graphic_info &
Berlin::GraphDebugger::find_or_insert(Fresco::Graphic_ptr g)
{
    unsigned long hash =
	g->_hash(std::numeric_limits<unsigned int>::max());
    const GraphicImpl * const p(Berlin::GraphicDictionary::instance()->
				implementation(g));

    for (std::vector<graphic_info>::iterator i =
	     my_known_graphics.begin();
	 i != my_known_graphics.end();
	 ++i)
	if ((hash == i->hash) &&
	    (p == i->impl ||
	     g->is_identical(i->graphic)))
		return *i; // we allready know this one

    // the graphic is unknown: register it and return a reference to it.
    my_known_graphics.push_back(
	graphic_info(g, p, hash, my_current_id,
		     Berlin::GraphicDictionary::instance()->name(g)));
    ++my_current_id;

    return my_known_graphics.back();
}

--- NEW FILE: GraphicDictionary.cc ---
/*$Id: GraphicDictionary.cc,v 1.1 2003/02/26 00:19:09 tobias Exp $
 *
 * This source file is a part of the Berlin Project.
 * Copyright (C) 2003 Tobias Hunger <[email protected]> 
 * http://www.fresco.org
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
 * MA 02139, USA.
 */

#include <Berlin/GraphicDictionary.hh>
#include <Berlin/Logger.hh>

#include <limits>

// ----------------------------------------------------------------------
// static variables:
// ----------------------------------------------------------------------

Berlin::GraphicDictionary * Berlin::GraphicDictionary::my_self;
Prague::Mutex Berlin::GraphicDictionary::my_singleton_mutex;


// ----------------------------------------------------------------------
// Helper classes
// ----------------------------------------------------------------------

Berlin::GraphicDictionary::word_equal::word_equal(const Fresco::Graphic_ptr g,
					   const GraphicImpl * i) :
    my_hash(g->_hash(std::numeric_limits<unsigned int>::max())),
    my_impl(i),
    my_graphic(g)
{ }
bool
Berlin::GraphicDictionary::word_equal::operator() (const Berlin::GraphicDictionary::word & w)
{
    if (CORBA::is_nil(my_graphic))
	if (my_impl == w.impl) return true;
	else return false;
	    
    if ((w.hash == my_hash) &&
	((my_impl != 0 && my_impl == w.impl) ||
	 (my_impl == 0 && my_graphic->is_identical(w.graphic))))
	return true;
    return false;
    
}


// ----------------------------------------------------------------------
// GraphicDictionary
// ----------------------------------------------------------------------

Berlin::GraphicDictionary::word::word() :
    name(),
    graphic(Fresco::Graphic::_nil()),
    impl(0),
    hash(0)
{ }

Berlin::GraphicDictionary::word::word(const Fresco::Graphic_ptr g,
				      const GraphicImpl * const p,
				      const std::string & n) :
    name(n),
    graphic(Fresco::Graphic::_duplicate(g)),
    impl(const_cast<GraphicImpl *>(p)),
    hash(g->_hash(std::numeric_limits<unsigned int>::max()))
{ }

Berlin::GraphicDictionary::word::word(const word & w) :
    name(w.name),
    graphic(Fresco::Graphic::_duplicate(w.graphic)),
    impl(w.impl),
    hash(w.hash)
{ }

Berlin::GraphicDictionary::word &
Berlin::GraphicDictionary::word::operator = (const word & w)
{
    name = w.name;
    graphic = Fresco::Graphic::_duplicate(w.graphic);
    impl = w.impl;
    hash = w.hash;
}


Berlin::GraphicDictionary::GraphicDictionary() :
    my_dictionary(),
    my_active(false)
{ }


Berlin::GraphicDictionary::~GraphicDictionary() { }

void Berlin::GraphicDictionary::activate()
{
    my_active = true;
}

Berlin::GraphicDictionary * Berlin::GraphicDictionary::instance() {
    // Create GraphicDictionary just once
    Prague::Guard<Prague::Mutex> guard(my_singleton_mutex);
    if (!my_self) my_self = new GraphicDictionary;
    return my_self;
} // instance


void Berlin::GraphicDictionary::add(const Fresco::Graphic_ptr g,
				    const GraphicImpl * const p,
				    const std::string & n)
{
    if (!p) return;

    Prague::Guard<Prague::Mutex> guard(my_mutex);

    // Is the Graphic allready known?
    dictionary_type::iterator i(find_if(my_dictionary.begin(),
					my_dictionary.end(),
					word_equal(g, p)));
    word w(g, p, n);
    if (my_dictionary.end() == i && my_active)
    {
	// register new graphic
	my_dictionary.push_back(w);
	i = my_dictionary.end() - 1; // works, we just added one element.
    }

    Logger::log(Logger::lifecycle)
	<< "GraphicDictionary: \"" << w.name
	<< "\" (#" << w.hash
	<< ") registered." << std::endl;

    return;
}


void Berlin::GraphicDictionary::remove(const GraphicImpl * const p)
{
    Prague::Guard<Prague::Mutex> guard(my_mutex);

    dictionary_type::iterator i(find_if(my_dictionary.begin(),
					my_dictionary.end(),
					word_equal(Fresco::Graphic::_nil(), p)));
    if (my_dictionary.end() != i)
    {
	Logger::log(Logger::lifecycle)
	    << "GraphicDictionary: \"" << i->name
	    << "\" (#" << i->hash
	    << ") removed." << std::endl;
	my_dictionary.erase(i);
    }
    else
	Logger::log(Logger::lifecycle)
	    << "GraphicDictionary: unknown graphic removed." << std::endl;
    return;
}



std::string
Berlin::GraphicDictionary::name(const Fresco::Graphic_ptr g) const
{
    std::string result("unknown");

    Prague::Guard<Prague::Mutex> guard(my_mutex);
    dictionary_type::const_iterator i(find_if(my_dictionary.begin(),
					      my_dictionary.end(),
					      word_equal(g, 0)));
    if (my_dictionary.end() != i)
	result = i->name;

    return result;
}

const GraphicImpl * const
Berlin::GraphicDictionary::implementation(const Fresco::Graphic_ptr g) const
{
    Prague::Guard<Prague::Mutex> guard(my_mutex);
    dictionary_type::const_iterator i(find_if(my_dictionary.begin(),
					      my_dictionary.end(),
					      word_equal(g, 0)));
    if (my_dictionary.end() != i)
	return i->impl;
    else
	return 0;
}

Index: GraphicImpl.cc
===================================================================
RCS file: /cvs/fresco/Fresco/Berlin/src/GraphicImpl.cc,v
retrieving revision 1.57
retrieving revision 1.58
diff -u -d -r1.57 -r1.58
--- GraphicImpl.cc	18 Dec 2002 06:00:07 -0000	1.57
+++ GraphicImpl.cc	26 Feb 2003 00:19:09 -0000	1.58
@@ -24,12 +24,13 @@
 #include <Fresco/Traversal.hh>
 #include <Fresco/Screen.hh>
 #include <Fresco/IO.hh>
-#include "Berlin/Provider.hh"
-#include "Berlin/GraphicImpl.hh"
-#include "Berlin/RegionImpl.hh"
-#include "Berlin/AllocationImpl.hh"
-#include "Berlin/TransformImpl.hh"
-#include "Berlin/Math.hh"
+#include <Berlin/Provider.hh>
+#include <Berlin/GraphicImpl.hh>
+#include <Berlin/RegionImpl.hh>
+#include <Berlin/AllocationImpl.hh>
+#include <Berlin/TransformImpl.hh>
+#include <Berlin/Math.hh>
+#include <Berlin/GraphicDictionary.hh>
 #include <Prague/Sys/Tracer.hh>
 #include <Prague/Sys/Stopwatch.hh>
 #include <algorithm>
@@ -263,6 +264,7 @@
 
 GraphicImpl::GraphicImpl() {}
 GraphicImpl::~GraphicImpl() {}
+
 void GraphicImpl::deactivate()
 {
   Trace trace(this, "GraphicImpl::deactivate");
@@ -277,6 +279,7 @@
     }
   my_parents.clear();
   ServantBase::deactivate(this);
+  Berlin::GraphicDictionary::instance()->remove(this);
 }
 
 Graphic_ptr GraphicImpl::body() { return Fresco::Graphic::_nil();}

Index: KitImpl.cc
===================================================================
RCS file: /cvs/fresco/Fresco/Berlin/src/KitImpl.cc,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- KitImpl.cc	18 Feb 2003 07:26:39 -0000	1.12
+++ KitImpl.cc	26 Feb 2003 00:19:09 -0000	1.13
@@ -24,8 +24,8 @@
 #include <Berlin/config.hh>
 #include <Berlin/Logger.hh>
 #include <Berlin/KitImpl.hh>
-#include "Berlin/ServantBase.hh"
-#include "Berlin/ServerContextImpl.hh"
+#include <Berlin/ServantBase.hh>
+#include <Berlin/ServerContextImpl.hh>
 #include <typeinfo>
 
 using namespace Prague;
@@ -46,18 +46,21 @@
 {
   Trace trace("KitImpl::KitImpl");
 #ifdef LCLOG
-  Logger::log(Logger::lifecycle) << "KitImpl::KitImpl: " << this << " constructed" << std::endl;
+  Logger::log(Logger::lifecycle)
+      << "KitImpl::KitImpl: " << this << " constructed" << std::endl;
 #endif
 }
 
 KitImpl::~KitImpl()
 {
-  Trace trace("KitImpl::~KitImpl");  
-  Logger::log(Logger::lifecycle) << "destroying POA... " << my_poa << std::endl;
+  Logger::log(Logger::lifecycle)
+      << "destroying POA... " << my_poa << std::endl;
   my_poa->destroy(true, false);
-  Logger::log(Logger::lifecycle) << "destroying POA done " << my_poa << std::endl;
+  Logger::log(Logger::lifecycle)
+      << "destroying POA done " << my_poa << std::endl;
 #ifdef LCLOG
-  Logger::log(Logger::lifecycle) << "KitImpl::~KitImpl: " << this << " destructed" << std::endl;
+  Logger::log(Logger::lifecycle) 
+      << "KitImpl::~KitImpl: " << this << " destructed" << std::endl;
 #endif
   delete my_props;
   if (my_context) my_context->erase(this);
@@ -68,7 +71,8 @@
   Trace trace("KitImpl::supports");
   const Fresco::Kit::Property *begin2 = p.get_buffer();
   const Fresco::Kit::Property *end2 = begin2 + p.length();
-  for (const Fresco::Kit::Property *property2 = begin2; property2 != end2; property2++)
+  for (const Fresco::Kit::Property *property2 = begin2;
+       property2 != end2; property2++)
   {
     const Fresco::Kit::Property *begin1 = my_props->get_buffer();
     const Fresco::Kit::Property *end1 = begin1 + my_props->length();
@@ -88,7 +92,9 @@
 {
   Trace trace("KitImpl::activate(PortableServer::Servant)");
 #ifdef LCLOG
-  Logger::log(Logger::lifecycle) << "activating " << servant << " (" << typeid(*servant).name() << ")" << std::endl;
+  Logger::log(Logger::lifecycle)
+      << "activating " << servant << " (" << typeid(*servant).name() << ")"
+      << std::endl;
 #endif
   PortableServer::ObjectId *oid = my_poa->activate_object(servant);
   servant->_poa = PortableServer::POA::_duplicate(my_poa);
@@ -102,7 +108,9 @@
   Trace trace("KitImpl::deactivate(PortableServer::Servant)");
   PortableServer::ObjectId *oid = my_poa->servant_to_id(servant);
 #ifdef LCLOG
-  Logger::log(Logger::lifecycle) << "deactivating " << servant << " (" << typeid(*servant).name() << ")" << std::endl;
+  Logger::log(Logger::lifecycle)
+      << "deactivating " << servant << " (" << typeid(*servant).name() << ")"
+      << std::endl;
 #endif
   my_poa->deactivate_object(*oid);
   delete oid;
@@ -114,7 +122,9 @@
   Prague::Guard<Mutex> guard(mutex);
   ++my_refcount;
 #ifdef LCLOG
-  Logger::log(Logger::lifecycle) << "KitImpl::increment on " << this << " (" << typeid(*this).name() << "): new count is " << _refcount << std::endl;
+  Logger::log(Logger::lifecycle)
+      << "KitImpl::increment on " << this << " (" << typeid(*this).name()
+      << "): new count is " << _refcount << std::endl;
 #endif
 }
 
@@ -126,7 +136,9 @@
     Prague::Guard<Mutex> guard(mutex);
     done = --my_refcount;
 #ifdef LCLOG
-    Logger::log(Logger::lifecycle) << "KitImpl::decrement on " << this << " (" << typeid(*this).name() << "): new count is " << _refcount << std::endl;
+    Logger::log(Logger::lifecycle)
+	<< "KitImpl::decrement on " << this << " (" << typeid(*this).name()
+	<< "): new count is " << _refcount << std::endl;
 #endif
   }
   if (done) return;

Index: Makefile.in
===================================================================
RCS file: /cvs/fresco/Fresco/Berlin/src/Makefile.in,v
retrieving revision 1.40
retrieving revision 1.41
diff -u -d -r1.40 -r1.41
--- Makefile.in	18 Feb 2003 07:26:40 -0000	1.40
+++ Makefile.in	26 Feb 2003 00:19:09 -0000	1.41
@@ -34,15 +34,16 @@
 LDFLAGS	+= $(SO_LDFLAGS)
 LIBS	+= -lpng
 
-SRC	:= Console.cc Logger.cc DefaultPOA.cc ServantBase.cc IdentifiableImpl.cc \
-	   RefCountBaseImpl.cc RegionImpl.cc TransformImpl.cc TraversalImpl.cc \
-	   AllocationImpl.cc GraphicImpl.cc MonoGraphic.cc \
-	   PolyGraphic.cc Allocator.cc Requestor.cc DebugGraphic.cc \
-	   DrawTraversalImpl.cc PickTraversalImpl.cc ControllerImpl.cc \
-	   DesktopImpl.cc ScreenImpl.cc ScreenManager.cc EventManager.cc \
-	   PositionalFocus.cc NonPositionalFocus.cc FilterImpl.cc SubjectImpl.cc \
-	   PNG.cc RasterImpl.cc \
-	   KitImpl.cc RCManager.cc ServerContextImpl.cc ServerImpl.cc
+SRC	:= Console.cc Logger.cc DefaultPOA.cc ServantBase.cc \
+	   IdentifiableImpl.cc RefCountBaseImpl.cc RegionImpl.cc \
+	   TransformImpl.cc TraversalImpl.cc AllocationImpl.cc \
+	   GraphicImpl.cc MonoGraphic.cc PolyGraphic.cc Allocator.cc \
+	   Requestor.cc DebugGraphic.cc DrawTraversalImpl.cc \
+	   PickTraversalImpl.cc ControllerImpl.cc DesktopImpl.cc \
+	   ScreenImpl.cc ScreenManager.cc EventManager.cc PositionalFocus.cc \
+	   NonPositionalFocus.cc FilterImpl.cc SubjectImpl.cc PNG.cc \
+	   RasterImpl.cc KitImpl.cc RCManager.cc ServerContextImpl.cc \
+	   ServerImpl.cc GraphDebugger.cc GraphicDictionary.cc
 
 DEP	:= $(patsubst %.cc, %.d, $(SRC))
 HDR	:= Console.hh Color.hh Event.hh GapBuffer.hh Geometry.hh \
@@ -57,7 +58,7 @@
 	   ScreenManager.hh EventManager.hh PositionalFocus.hh \
 	   NonPositionalFocus.hh FilterImpl.hh SubjectImpl.hh KitImpl.hh \
 	   RCManager.hh DefaultPOA.hh ObserverImpl.hh config.hh \
-           ServerContextImpl.hh ServerImpl.hh
+           ServerContextImpl.hh ServerImpl.hh GraphDebugger.hh Dictionary.hh
 
 CHDR	:= DirectBuffer.hh Renderer.hh GLContext.hh SHMDrawableFactory.hh GGIDrawableFactory.hh
 OBJ	:= $(patsubst %.cc, %.o, $(SRC))
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.