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);
}));
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"
" 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");
}
#include "../Scheduler/Scheduler.hh"
#include "../Utils/membind.hh"
#include "Module.hh"
+#include "../Utils/Console/Console.hh"
//#include "ModuleManager.mpp"
#define prefix_
: 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_
return running_;
}
+prefix_ senf::console::DirectoryNode & senf::ppi::ModuleManager::consoleDir()
+ const
+{
+ return consoleDir_.node();
+}
+
///////////////////////////////////////////////////////////////////////////
// senf::ppi::ModuleManager::Initializable
#include <deque>
#include "predecl.hh"
#include "../Scheduler/Scheduler.hh"
+#include "../Utils/Console/ScopedDirectory.hh"
//#include "ModuleManager.mpp"
///////////////////////////////hh.p////////////////////////////////////////
bool running() const; ///< \c true, if the network is running
+ senf::console::DirectoryNode & consoleDir() const;
+
private:
ModuleManager();
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;
scheduler::EventHook initRunner_;
+ senf::console::ScopedDirectory<> consoleDir_;
+
friend class module::Module;
friend class Initializable;
};
--- /dev/null
+#!/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")