PPI: Implement PPI dump
g0dil [Wed, 12 Aug 2009 12:50:50 +0000 (12:50 +0000)]
git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@1290 270642c3-0616-0410-b53a-bc976706d245

PPI/Connectors.cc
PPI/ModuleManager.cc
PPI/ModuleManager.cci
PPI/ModuleManager.hh
PPI/drawmodules.py [new file with mode: 0644]

index 46c762e..cf241d5 100644 (file)
@@ -84,10 +84,9 @@ prefix_ void senf::ppi::connector::Connector::trace(Packet const & p, char const
         return;
     SENF_LOG_BLOCK(({
                 std::string type (prettyName(p.typeId().id()));
-                log << "PPI trace: 0x" << std::hex << p.id() << " " 
-                    << type.substr(21, type.size()-22) << " " << label
-                    << " on " << & module() << " " << prettyName(typeid(module()))
-                    << " connector 0x" << this << "\n";
+                log << "PPI trace: " << label << " 0x" << std::hex << p.id() << " " 
+                    << type.substr(21, type.size()-22) << " on " << & module() << " " 
+                    << prettyName(typeid(module())) << " connector 0x" << this << "\n";
                 if (traceState_ == TRACE_CONTENTS)
                     p.dump(log);
             }));
@@ -109,9 +108,9 @@ namespace {
 
     ConsoleRegister::ConsoleRegister()
     {
-        senf::console::sysdir()
-            .add("ppiTracing", SENF_FNP(senf::ppi::connector::Connector::TraceState,
-                                         senf::ppi::connector::Connector::tracing, ()))
+        senf::ppi::ModuleManager::instance().consoleDir()
+            .add("tracing", SENF_FNP(senf::ppi::connector::Connector::TraceState,
+                                     senf::ppi::connector::Connector::tracing, ()))
             .doc("Log every packet sent or received by any module.\n"
                  "There are three different tracing levels:\n"
                  "\n"
@@ -137,9 +136,9 @@ namespace {
                  "    module-type     Type of the module the packet is sent to/from\n"
                  "    connector-id    Unique connector id\n");
 
-        senf::console::sysdir()
-            .add("ppiTracing", SENF_FNP(void, senf::ppi::connector::Connector::tracing,
-                                         (senf::ppi::connector::Connector::TraceState)))
+        senf::ppi::ModuleManager::instance().consoleDir()
+            .add("tracing", SENF_FNP(void, senf::ppi::connector::Connector::tracing,
+                                     (senf::ppi::connector::Connector::TraceState)))
             .arg("state", "new tracing state");
     }
 
index f72cab1..9e890b7 100644 (file)
@@ -30,6 +30,7 @@
 #include "../Scheduler/Scheduler.hh"
 #include "../Utils/membind.hh"
 #include "Module.hh"
+#include "../Utils/Console/Console.hh"
 
 //#include "ModuleManager.mpp"
 #define prefix_
@@ -72,7 +73,31 @@ prefix_ senf::ppi::ModuleManager::ModuleManager()
     : running_(false), terminate_(false), 
       initRunner_ ("senf::ppi::init", membind(&ModuleManager::init, this),
                    scheduler::EventHook::PRE, false)
-{}
+{
+    senf::console::sysdir().add("ppi", consoleDir_);
+
+    consoleDir_
+        .add("dump", senf::membind(&ModuleManager::dumpModules, this))
+        .doc("Dump complete PPI structure\n"
+             "The dump will contain one paragraph for each module. The first line gives module\n"
+             "information, additional lines list all connectors and their peers (if connected).");
+}
+
+prefix_ void senf::ppi::ModuleManager::dumpModules(std::ostream & os)
+{
+    for (ModuleRegistry::const_iterator i (moduleRegistry_.begin()), i_end (moduleRegistry_.end());
+         i != i_end; ++i) {
+        os << *i << " " << prettyName(typeid(**i)) << "\n";
+        for (module::Module::ConnectorRegistry::iterator j ((*i)->connectorRegistry_.begin()),
+                 j_end ((*i)->connectorRegistry_.end()); j != j_end; ++j) {
+            os << "  " << *j << " " << prettyName(typeid(**j));
+            if ((**j).connected())
+                os << " " << & (*j)->peer();
+            os << "\n";
+        }
+        os << "\n";
+    }
+}
 
 ///////////////////////////////cc.e////////////////////////////////////////
 #undef prefix_
index 9bdc778..a71d72a 100644 (file)
@@ -81,6 +81,12 @@ prefix_ bool senf::ppi::ModuleManager::running()
     return running_;
 }
 
+prefix_ senf::console::DirectoryNode & senf::ppi::ModuleManager::consoleDir()
+    const
+{
+    return consoleDir_.node();
+}
+
 ///////////////////////////////////////////////////////////////////////////
 // senf::ppi::ModuleManager::Initializable
 
index 14ad1a9..c8b411d 100644 (file)
@@ -31,6 +31,7 @@
 #include <deque>
 #include "predecl.hh"
 #include "../Scheduler/Scheduler.hh"
+#include "../Utils/Console/ScopedDirectory.hh"
 
 //#include "ModuleManager.mpp"
 ///////////////////////////////hh.p////////////////////////////////////////
@@ -82,6 +83,8 @@ namespace ppi {
 
         bool running() const;           ///< \c true, if the network is running
 
+        senf::console::DirectoryNode & consoleDir() const;
+
     private:
         ModuleManager();
 
@@ -92,6 +95,8 @@ namespace ppi {
         void unregisterInitializable(Initializable & i);
         bool initializableRegistered(Initializable const & i) const;
 
+        void dumpModules(std::ostream & os);
+
         typedef std::vector<module::Module *> ModuleRegistry;
         typedef std::deque<Initializable *> InitQueue;
 
@@ -108,6 +113,8 @@ namespace ppi {
 
         scheduler::EventHook initRunner_;
 
+        senf::console::ScopedDirectory<> consoleDir_;
+
         friend class module::Module;
         friend class Initializable;
     };
diff --git a/PPI/drawmodules.py b/PPI/drawmodules.py
new file mode 100644 (file)
index 0000000..103431d
--- /dev/null
@@ -0,0 +1,63 @@
+#!/usr/bin/python
+
+import sys
+
+mode = "MODULE"
+
+sys.stdout.write("""
+digraph Modules {
+node [shape=box, fontsize=10, fontname="Helvetica", height=.2];
+edge [labelfontsize=8, labelfontname="Helvetica"]
+""")
+
+modules = {}
+connectors = {}
+
+for line in sys.stdin:
+    line = line.strip()
+    if line == "":
+        mode = "MODULE"
+    elif mode == "MODULE":
+        moduleid, module = line.split(' ',1);
+        connectorid = type = peerid = None
+        modules[moduleid] = (module, []);
+        mode = "CONNECTOR"
+    else:
+        connectorid, type = line.split(' ',1);
+        elts = type.rsplit(' ',1);
+        if elts[-1].startswith('0x'):
+            type, peerid = elts
+        else:
+            peerid = None
+        modules[moduleid][1].append((connectorid, type, peerid))
+        connectors[connectorid] = moduleid
+
+for moduleid, (type, cs) in modules.iteritems():
+    type = type.split('<',1)[0]
+    type = type.rsplit('::',1)[-1]
+    sys.stdout.write('"%s" [label="%s (%s)"]\n' % (moduleid,  type, moduleid))
+
+anonid = 0
+
+for moduleid, (type, cs) in modules.iteritems():
+    for connectorid, type, peerid in cs:
+        opts = []
+        if "Passive" in type:
+            opts.append("arrowtail=odot");
+        if peerid:
+            opts.append('headlabel="%s"' % peerid)
+        opts.append('taillabel="%s"' % connectorid)
+        opts = ",".join(opts)
+        if opts:
+            opts = " [%s]" % opts
+        if "Output" in type and peerid is not None:
+            sys.stdout.write('"%s" -> "%s"%s\n' % (moduleid, connectors[peerid],opts))
+        elif peerid is None:
+            sys.stdout.write('anon%d [label="", shape=point, height=.05];\n' % anonid)
+            if "Output" in type:
+                sys.stdout.write('"%s" -> anon%d%s;\n' % (moduleid, anonid, opts))
+            else:
+                sys.stdout.write('anon%d -> "%s"%s;\n' % (anonid, moduleid, opts))
+            anonid += 1
+
+sys.stdout.write("}\n")