Missing feature in NED inheritance (submodule overwriting)

373 views
Skip to first unread message

Till

unread,
Apr 27, 2014, 6:22:11 AM4/27/14
to omn...@googlegroups.com
Dear all,

I'm missing a feature in the NED inheritance functionality. I need to extend a module and overwrite a submodule with an extended submodule. Please see this example:

module Foo {
    gates:
        input in;
    submodules:
        sub: Submodule;
    connections:
        in <--> sub.in;
}

module Bar extends Foo {
    gates:
        output out;
    submodules:
        sub: ExtendedSubmodule; // syntax could also be something like "sub: ExtendedSubmodule @override;"
    connections:
        out <--> sub.out;
}

simplemodule Submodule{
    gates:
        input in;
}

simplemodule ExtendedSubmodule extends Submodule{
    gates:
        input out;
}

In this example I have a compound module Foo that has a submodule Submodule with a gate in connected to the submodules in. Now I want an extended version of Foo, called Bar that has another gate out. Bar should use an extended version of Submodule called ExtendedSubmodule with a connection from gate out to the submodules gate out. The connection from in to sub.in should be kept.

This situation would be totally legal but I think I currently cannot describe it with NED. The nededitor would have to check that ExtendedSubmodule is a subclass of Submodule to ensure that the redefinition of sub in Bar would not break Foo.


I would love to hear your opinions! To Andras and the Team: Would that be possible with reasonable effort?

Best regards
Till

Rudolf Hornig

unread,
Apr 28, 2014, 12:02:48 PM4/28/14
to omn...@googlegroups.com
It's indeed not possible to do it this way. The same scenario would be problematic in C++, too, but you can work around this. It's not the most beautiful solution, but should work:

Instead of a submodule, you should use module interfaces to describe the Submodule and ExtendedSubmodule's gates.

Obviously you will need also the two submodules that implement these interfaces. i.e. You would have something like this:

moduleinterface ISubmodule {
    gates:
        input in;
}

moduleinterface IExtendedSubmodule extends ISubmodule {
    gates:
        output out;
}

module Submodule like ISubmodule {
    gates:
        input in;
}

module ExtendedSubmodule extends Submodule like IExtendedSubmodule {
    gates:
        output out;
    connections:
        in --> out;  // just to avoid unconnected error
}


of course Submodule and ExtendedSubmodule should implement ISubmodule and IExtendedSubmodule respectively.

finally in module Foo you should have something like this:

    submodules:
        sub: <default("Submodule")> like ISubmodule;


in module Bar, you would be able to override the submodule type with ExtendedSubmodule just as you would be able to override any parameter in a derived module. i.e. putting something like this in the Bar's parameter section would do the trick:
        sub.typename="ExtendedSubmodule"

module Foo {
    gates:
        input in;
    submodules:
        sub: <default("Submodule")> like ISubmodule;
    connections:
        in --> sub.in;
}

network Bar extends Foo {
        sub.typename="ExtendedSubmodule";
    gates:
        output out;
    connections:
        out <-- sub.out;  // this generates an error in the IDE, but the runtime still works fine with it
}

Unfortunately the last line ( out <-- sub.out ) throws an error in the IDE. You should ignore this as it is just that the IDE is not up to the task to figure out all the hacking magic we are doing here... Maybe an @supresserror and @supresswarning property would be useful...

Hope this helps, Rudolf

Till

unread,
Apr 28, 2014, 4:21:15 PM4/28/14
to omn...@googlegroups.com
Dear Rudolf,

thank you very much for your thoughts! Exactly this solution I already had in mind, but I did not test it because of the errors. It seems it is always worth trying :)

I understand that (when seeing a submodule as a member variable) in C++ this is not possible as well. But I cannot think of a situation where this could go wrong with a ned module. Your solution (that I tried for our usecase) demonstrates that it is (in general) possible.

Your solution for the problem does not work for all (and especially for our) situation. Think of someone extending a module of another framework. In our case we extend modules from INET. We cannot add an Interface to the existing module, though we cannot use the "<Module> like Interface" syntax. Also (in the cases where it is possible) it is very inconvenient to add Interfaces to all modules just to allow the syntax.

I would still love to see the possibility to overwrite (when I think about it it is more overloading) modules. Perhaps something like: "sub: <default("Submodule")> extends Submodule;" would be a possible way as well, but why not allow the definition of a module with the same name when it extends the overwritten module? Of cause it would require to collect the gate, connection and parameter definitions of the overwritten module as well.

I think such a possibility has the potential to save a lot of (ned)code that would be otherwise defined in several modules, and thus reduce the maintenance effort significantly.
I hope I'm not the only one who would require that feature :)

Best regards from Hamburg
Till

Rudolf Hornig

unread,
Apr 29, 2014, 11:39:11 AM4/29/14
to omn...@googlegroups.com
Sure, in theory this would be possible. We just had to make some shortcuts to minimize the effort during the NED development. After that, we tried to keep NED as stable as possible.

As OMNET 5.0 is on the table now, I would suggest to submit this as a feature request in the bugtracker. We may add some tweaks here and there...

Rudolf

Timo Haeckel

unread,
Apr 22, 2021, 10:21:26 AM4/22/21
to OMNeT++ Users
I know this is a very old post, but I have a similar situation.
I am perfectly happy with the solution to use the interface syntax and everything works as expected, but I find the error very misleading for users of the model.
Is there an option to suppress the error or an even better solution in the current omnet version?
Best regards
Timo

Rudolf Hornig

unread,
May 4, 2021, 8:09:19 AM5/4/21
to OMNeT++ Users
I'm not sure about your requirements but would not be enough to use the @reconnect syntax?
https://doc.omnetpp.org/omnetpp/manual/#sec:ned-lang:reconnecting-gates

We are using @reconnect in INET and we were able to solve all problems to date where various extension points were needed.
With that, you can either insert new or remove existing connections between submodules defined in a superclass. Insert new modules between any other two submodules etc.

There is also a pattern we are using where we know in advance that some modules might be replaced but the default implementation does nothing, we are using a module that uses the OmittedModule as a C++ implementation. The extension point is defined as a submodule with a module interface type like in the above, but if it is not replaced by something other during the network setup it will self destruct and remove itself from the NED topology, re-connecting it's connections. This means that it would still do nothing during runtime, but you would not see it in the Qtenv and it would not consume resources (i.e. the dummy module optimizes itself out).

Still, I admit the above error is indeed annoying so we will look into this. 

Timo Haeckel

unread,
May 5, 2021, 3:50:57 AM5/5/21
to OMNeT++ Users
Dear Rudolf,
thank you very much for your reply and suggestions.
Unfortunately, I could not solve our problem with @reconnect syntax yet, and I don't know exactly how the OmittedModule works and could solve our problem.

In our case, we have a compound base module with a submodule of the IWiredNic interface that uses the parametric submodule syntax to define the type of the NIC.
In an extension that inherits from the base compound module, we add some modules and require a specific NIC implementation that has additional input and output gates not specified in the IWiredNic interface.
We want to connect the new modules to the additional gates and as you mentioned above, this procedure works but throws an error in the IDE.

We will probably find a workaround for this or just duplicate the code for the extending compound module. However, since this does work, it would be great if there was no error in the IDE.

Kind regards
Timo
Reply all
Reply to author
Forward
0 new messages