//========================================================================== // LOGBUFFER.H - part of // // OMNeT++/OMNEST // Discrete System Simulation in C++ // //========================================================================== /*--------------------------------------------------------------* Copyright (C) 1992-2017 Andras Varga Copyright (C) 2006-2017 OpenSim Ltd. This file is distributed WITHOUT ANY WARRANTY. See the file `license' for details on this and other legal matters. *--------------------------------------------------------------*/ #ifndef __OMNETPP_QTENV_LOGBUFFER_H #define __OMNETPP_QTENV_LOGBUFFER_H #include #include #include "omnetpp/simtime_t.h" #include "circularbuffer.h" #include "qtenvdefs.h" #include namespace omnetpp { class cModule; namespace qtenv { /** * Stores textual debug output from modules. */ class QTENV_API LogBuffer : public QObject { Q_OBJECT // for signals public: struct Line { int contextComponentId; const char *prefix; const char *line; // including newline Line(int contextComponentId, const char *prefix, const char *line) : contextComponentId(contextComponentId), prefix(prefix), line(line) {} }; struct MessageSend { cMessage *msg; std::vector hopModuleIds; //TODO also: txStartTime, propagationDelay, duration for each hop bool discarded = false; }; struct Entry { eventnumber_t eventNumber = 0; // 0 for initialization, >0 afterwards simtime_t simtime = 0; int componentId = 0; // 0 for info log lines //TODO msg name, class, kind, previousEventNumber const char *banner = nullptr; std::vector lines; std::vector msgs; bool isEvent(); ~Entry(); }; protected: circular_buffer entries; int maxNumEntries = 100000; int entriesDiscarded = 0; void discardEventsIfLimitExceeded(); void fillEntry(Entry *entry, eventnumber_t e, simtime_t t, cModule *mod, const char *banner); // Makes our privateDups of the logged messages easily accessible. // Every message is duplicated once each time it is sent. std::multimap messageDups; public: ~LogBuffer() { clear(); } void addInitialize(cComponent *component, const char *banner); void addEvent(eventnumber_t e, simtime_t t, cModule *moduleIds, const char *banner); void addLogLine(const char *prefix, const char *text) { addLogLine(prefix, text, strlen(text)); } void addLogLine(const char *prefix, const char *text, int len); void addInfo(const char *text) { addInfo(text, strlen(text)); } void addInfo(const char *text, int len); void beginSend(cMessage *msg); void messageSendDirect(cMessage *msg, cGate *toGate, simtime_t propagationDelay, simtime_t transmissionDelay); void messageSendHop(cMessage *msg, cGate *srcGate); void messageSendHop(cMessage *msg, cGate *srcGate, simtime_t propagationDelay, simtime_t transmissionDelay, bool discard); void endSend(cMessage *msg); void delivery(cMessage *msg); // doesn't matter if direct or not void setMaxNumEntries(int limit); // when exceeded, oldest entries are discarded int getMaxNumEntries() {return maxNumEntries;} const circular_buffer& getEntries() const {return entries;} int getNumEntries() const {return entries.size();} int getNumEntriesDiscarded() const {return entriesDiscarded;} int findEntryByEventNumber(eventnumber_t eventNumber); Entry *getEntryByEventNumber(eventnumber_t eventNumber); // Returns the last private copy we made of a given message, // ot nullptr if no copy is found. The parameter doesn't have // to point to an existing message, or be valid at all. cMessage *getLastMessageDup(cMessage *of); void clear(); void dump() const; signals: void logEntryAdded(); void logLineAdded(); void messageSendAdded(); // When this signal is fired, the entry in the parameter is // no longer in the buffer, but is not deleted yet. void entryDiscarded(LogBuffer::Entry *discardedEntry); }; } // namespace qtenv } // namespace omnetpp #endif