Exemplo n.º 1
0
//
// When a Receiver gets a new label, it has to disconnect from its existing
// transmitter, and connect to the new one.  This will work even if it's
// the transmitter that's changing our label.
boolean ReceiverNode::setLabelString(const char *label)
{
    if (EqualString(label, this->getLabelString()))
        return TRUE;

    if (initializing && this->getNetwork()->isReadingNetwork())
        return this->UniqueNameNode::setLabelString(label);

    if (!this->verifyRestrictedLabel(label))
        return FALSE;

    //
    // Skip the conflict check when reading in a newer style net since
    // there can't be any conflict in these nets.
    //
    const char* conflict = NUL(char*);
    if (this->getNetwork()->isReadingNetwork()) {
        int net_major = this->getNetwork()->getNetMajorVersion();
        int net_minor = this->getNetwork()->getNetMinorVersion();
        int net_micro = this->getNetwork()->getNetMicroVersion();
        int net_version =   VERSION_NUMBER( net_major, net_minor, net_micro);
        if (net_version < VERSION_NUMBER(3,1,1))
            conflict = this->getNetwork()->nameConflictExists(this, label);
    }

    //
    // If there is a name conflict while reading a network, it's important to try
    // to continue in spite of the conflict and fix things up later.  Reason: older
    // versions of dx allowed the name conflict and we would like to try and fix
    // things and report what happened rather than read the net incorrectly.
    //
    if ((conflict) && (this->getNetwork()->isReadingNetwork() == FALSE)) {
        ErrorMessage("A %s with name \"%s\" already exists.", conflict, label);
        return FALSE;
    }

    boolean found = FALSE;
    List *ia = (List*)this->getInputArks(1);
    if ((ia) && (ia->getSize() > 0)) {
        Ark *a = (Ark*)ia->getElement(1);
        int dummy;
        if (EqualString(a->getSourceNode(dummy)->getLabelString(), label))
            found = TRUE;
        else
            delete a;
    }
    ia = NUL(List*);


    if (!found) {
        List* l = this->getNetwork()->makeClassifiedNodeList(ClassTransmitterNode, FALSE);
        ListIterator iterator;
        Node *n;

        if ((l) && (this->getNetwork()->isReadingNetwork() == FALSE)) {
            //
            // Before creating any Arks, check for cycles.
            //
            iterator.setList(*l);
            while ( (n = (Node*)iterator.getNext()) ) {
                if (EqualString(label, n->getLabelString())) {
                    Network* net = this->getNetwork();
                    if (net->checkForCycle(n, this)) {
                        ErrorMessage (
                            "Unable to rename Receiver \"%s\" to \"%s\"\n"
                            "because that would cause a cyclic connection.",
                            this->getLabelString(), label
                        );
                        delete l;
                        return FALSE;
                    }
                }
            }
        }

        if (l) {
            iterator.setList(*l);
            while ( (n = (Node*)iterator.getNext()) ) {
                if (EqualString(label, n->getLabelString()))
                {
                    found = TRUE;
                    // link me to transmitter
                    new Ark(n, 1, this, 1);
                }
            }
            delete l;
        }
    }

    //
    // There was a name conflict because earlier versions of dx were less restrictive.
    // Record the transmitter for later fixup.  When the transmitter is fixed up,
    // then we'll automatically get fixed up also.  Caveat:  if there is no transmitter
    // connected, then it's cool to refuse the name because then we're not breaking
    // anything.
    //
    if (conflict) {
        ASSERT (this->getNetwork()->isReadingNetwork());
        if (this->isTransmitterConnected() == FALSE) {
            ErrorMessage("A %s with name \"%s\" already exists.", conflict, label);
            return FALSE;
        }
        List *l = (List*)this->getInputArks(1);
        ASSERT (l->getSize() > 0);
        Ark *a = (Ark*)l->getElement(1);
        int dummy;
        TransmitterNode* tn = (TransmitterNode*)a->getSourceNode(dummy);
        this->getNetwork()->fixupTransmitter(tn);
    }

    return this->UniqueNameNode::setLabelString(label);

}