#include <stdlib.h> #include <stdarg.h> #include <vector> #include <algorithm> #include <omnetpp.h> #ifdef _WIN32 #ifndef vsnprintf #define vsnprintf _vsnprintf #endif #endif using namespace omnetpp; std::string stringf(const char *format, ...) { const int BUFLEN = 1024; char buffer[BUFLEN]; va_list va; va_start(va, format); vsnprintf(buffer, BUFLEN, format, va); buffer[BUFLEN-1] = '\0'; va_end(va); return buffer; } class Controller2 : public cSimpleModule { protected: int step; cModuleType *type; std::vector<cModule *> nodes; std::vector<cGate *> connections; protected: virtual void initialize() override; virtual void handleMessage(cMessage *msg) override; }; Define_Module(Controller2); void Controller2::initialize() { step = 0; type = cModuleType::find("Node"); scheduleAt(0, new cMessage("timer")); } void Controller2::handleMessage(cMessage *msg) { // create a node if (intuniform(0, 20) == 0) { cModule *node = type->createScheduleInit(stringf("node%d", step).c_str(), getParentModule()); nodes.push_back(node); EV << "node CREATED as node " << (nodes.size()-1) << "\n"; cDisplayString& d = node->getDisplayString(); d.setTagArg("p", 0, intuniform(0, 600)); d.setTagArg("p", 1, intuniform(0, 400)); d.setTagArg("t", 0, "NEW"); } // delete a node if (!nodes.empty() && intuniform(0, 20) == 0) { int k = intuniform(0, nodes.size()-1); cModule *node = nodes[k]; EV << "node " << node->getFullName() << ": DELETED\n"; for (unsigned int i = 0; i < connections.size(); i++) { if (connections[i]->getOwnerModule() == node || connections[i]->getNextGate()->getOwnerModule() == node) { connections.erase(connections.begin()+i); i--; } } node->deleteModule(); nodes.erase(nodes.begin()+k); } // create connection if ((int)nodes.size() >= 2 && intuniform(0, 5) == 0) { int s = intuniform(0, nodes.size()-1); int t = intuniform(0, nodes.size()-2); if (t >= s) t++; EV << "creating connection: " << nodes[s]->getFullName() << " --> " << nodes[t]->getFullName() << "\n"; cGate *gs = nodes[s]->addGate(stringf("gate%do", step).c_str(), cGate::OUTPUT); cGate *gt = nodes[t]->addGate(stringf("gate%di", step).c_str(), cGate::INPUT); gs->connectTo(gt); connections.push_back(gs); } // delete connection if (!connections.empty() && intuniform(0, 5) == 0) { int k = intuniform(0, connections.size()-1); EV << "connection " << connections[k]->getFullPath() << ": DELETED\n"; connections[k]->disconnect(); connections.erase(connections.begin()+k); } // move if (!nodes.empty() && intuniform(0, 1) == 0) { int k = intuniform(0, nodes.size()-1); EV << "node " << nodes[k]->getFullName() << ": position change\n"; cDisplayString& d = nodes[k]->getDisplayString(); int x = atoi(d.getTagArg("p", 0)); int y = atoi(d.getTagArg("p", 1)); int newX = std::max(0, std::min(600, x + intuniform(-20, 20))); int newY = std::max(0, std::min(400, y + intuniform(-20, 20))); d.setTagArg("p", 0, newX); d.setTagArg("p", 1, newY); } // change text if (!nodes.empty() && intuniform(0, 5) == 0) { int k = intuniform(0, nodes.size()-1); EV << "node " << nodes[k]->getFullName() << ": text change\n"; cDisplayString& d = nodes[k]->getDisplayString(); d.setTagArg("t", 0, stringf("rng=%d", intuniform(0, 100000)).c_str()); } // change icon size if (!nodes.empty() && intuniform(0, 10) == 0) { int k = intuniform(0, nodes.size()-1); EV << "node " << nodes[k]->getFullName() << ": icon size change\n"; cDisplayString& d = nodes[k]->getDisplayString(); static const char *sizes[] = {"vs", "s", ""}; d.setTagArg("is", 0, sizes[intuniform(0, 2)]); } // change color if (!nodes.empty() && intuniform(0, 3) == 0) { int k = intuniform(0, nodes.size()-1); EV << "node " << nodes[k]->getFullName() << ": color change\n"; cDisplayString& d = nodes[k]->getDisplayString(); static const char *colors[] = {"", "red", "green", "blue", "yellow"}; d.setTagArg("step", 1, colors[intuniform(0, 4)]); } // change i2 if (!nodes.empty() && intuniform(0, 3) == 0) { int k = intuniform(0, nodes.size()-1); EV << "node " << nodes[k]->getFullName() << ": i2 change\n"; cDisplayString& d = nodes[k]->getDisplayString(); static const char *images[] = {"", "status/ctrl", "status/busy"}; d.setTagArg("i2", 0, images[intuniform(0, 2)]); } step++; scheduleAt(simTime()+0.2, msg); }