Получается, чтоДРАКОНскрывает (инкапсулирует) реализацию веточного цикла в схеме "силуэт", аДАЛВЯЗ 2всё это демострирует программисту, загромождая схему...
В чём тогда преимущества для программиста?
Мною в 2008 году (8 лет назад) был предоставлен трансляторДРАКОН-схем в исходный код на языкеАктивный Оберон.http://sage.com.ua/ru.shtml?e6l0Транслятор автоматически генерировал в том числе и код веточного цикла. Эта операция и должна делаться автоматически!
Всё что делается автоматически облегчает труд программиста и исключает ошибки человека (человеческий фактор), предоставляя программисту лишь приятное занятие по наполнению основной алгоритмической части схемы.
Сгенерированный код веточного цикла:
## Код:
```
CONST
  Dr018VtkExit = 0;
  Dr018Vtk0143 = 143;
  Dr018Vtk0154 = 154;
  Dr018Vtk0168 = 168;
  Dr018Vtk0177 = 177;
  Dr018Vtk0149 = 149;

...

VAR
  Dr018Vtk: INTEGER;

...

  BEGIN {ACTIVE}
    Dr018Vtk := Dr018Vtk0143;
    WHILE Dr018Vtk # Dr018VtkExit DO
      CASE Dr018Vtk OF
      | Dr018Vtk0143: (* Init *)
        NEW(receiveBuf, Base.MaxUDPDataLen);
        NEW(sendBuf, 0);
        NEW(clients);
        NEW (users);
        running := TRUE;
        terminated := FALSE;
        Dr018Vtk := Dr018Vtk0154
      | Dr018Vtk0154: (* Packet receive *)
        IF running THEN
          CheckKeepAlive(clients);
          s.Receive (receiveBuf^, 0, Base.MaxUDPDataLen, 1, ip, port, len, res);
          IF (res = UDP.Ok) & (len > 0) THEN
            receiveBufOffset := 0;
            (* Version check *)
            IF Base.BufGetInt(receiveBuf, receiveBufOffset) = Base.VERSION THEN
              Dr018Vtk := Dr018Vtk0168
            ELSE
              Dr018Vtk := Dr018Vtk0154
            END; (* IF *)
          ELSE
            Dr018Vtk := Dr018Vtk0154
          END; (* IF *)
        ELSE
          Dr018Vtk := Dr018Vtk0149
        END; (* IF *)
      | Dr018Vtk0168: (* Authentication *)
        command := Base.BufGetInt(receiveBuf, receiveBufOffset);
        seqNum := Base.BufGetInt(receiveBuf, receiveBufOffset);
        uin := Base.BufGetLInt(receiveBuf, receiveBufOffset);
        Utilities.IntToStr(seqNum, str1);
        Utilities.Concat(" SeqNum: ", str1, str1);
        Utilities.Concat(str1, " Command: ", str1);
        Utilities.IntToStr(uin, str2);
        Utilities.Concat("User ID: ", str2, str2);
        Utilities.Concat(str2, str1, str1);
        Base.CommandDecode(command, str2);
        Utilities.Concat(str1, str2, str1);
        Log(AosEvents.Information, 0, str1, FALSE);
        IF FindClient(clients, uin, client) THEN
          (* Additional check *)
          IF (IP.AdrsEqual(client.ip, ip)) & (client.port = port) THEN
            Dr018Vtk := Dr018Vtk0177
          ELSE
            Dr018Vtk := Dr018Vtk0154
          END; (* IF *)
        ELSE
          CASE command OF
          | Base.LOGIN:
            password := Base.BufGetString(receiveBuf, receiveBufOffset);
            IF users.PasswordCorrect(uin, password) THEN
              NEW(client);
              client.ip := ip;
              client.port := port;
              client.uin := uin;
              client.inSeqNum := seqNum;
              client.outSeqNum := 0;
              Kernel.SetTimer(client.keepAliveTimer, Base.clientKeepAliveAwait);
              clients.Add(client);
              Server_LoginReply(client, sendBuf, s);
              MulticastStatus(clients, client, Base.USER_ONLINE, sendBuf, s);
            END; (* IF *)
          | Base.NEW_USER_REG:
            password := Base.BufGetString(receiveBuf, receiveBufOffset);
            shortName := Base.BufGetString(receiveBuf, receiveBufOffset);
            fullName := Base.BufGetString(receiveBuf, receiveBufOffset);
            eMail := Base.BufGetString(receiveBuf, receiveBufOffset);
            user := users.Add(password, shortName, fullName, eMail);
            Server_NewUserReply(ip, port, user.uin, seqNum, sendBuf, s);
          ELSE (* CASE *)
          END; (* CASE *)
          Dr018Vtk := Dr018Vtk0154
        END; (* IF *)
      | Dr018Vtk0177: (* Packet handle *)
        IF command = Base.ACK THEN
          IF Base.SeqNumInACKList(client.ACKList, seqNum, ACKReq) THEN
            client.ACKList.Remove(ACKReq);
          END; (* IF *)
        ELSE
          IF Base.isNextSeqNum(seqNum, client.inSeqNum) THEN
            client.inSeqNum := seqNum;
            CASE command OF
            | Base.SEND_MESSAGE:
              Server_ACK(client, sendBuf, s);
              receiverUin := Base.BufGetLInt(receiveBuf, receiveBufOffset);
              messageType := Base.BufGetInt(receiveBuf, receiveBufOffset);
              message := Base.BufGetString(receiveBuf, receiveBufOffset);
              dt := Dates.Now();
              IF receiverUin = 0 THEN
                MulticastMessage(clients, client, dt, messageType, message, sendBuf, s);
              ELSE
                IF FindClient(clients, receiverUin, receiver) THEN
                  Server_ReceiveMessage(client, receiver, dt, messageType, message, sendBuf, s);
                END; (* IF *)
              END; (* IF *)
            | Base.KEEP_ALIVE:
              Server_ACK(client, sendBuf, s);
              Kernel.SetTimer(client.keepAliveTimer, Base.clientKeepAliveAwait);
            | Base.INFO_REQ:
              receiverUin := Base.BufGetLInt(receiveBuf, receiveBufOffset);
              user := users.Find(receiverUin);
              IF user # NIL THEN
                Server_InfoReply(client, user, sendBuf, s);
              END; (* IF *)
            | Base.SEND_TEXT_CODE:
              Server_ACK(client, sendBuf, s);
              textCode := Base.BufGetString(receiveBuf, receiveBufOffset);
              IF textCode^ = "USER_DISCONNECTED" THEN
                MulticastStatus(clients, client, Base.USER_OFFLINE, sendBuf, s);
                clients.Remove(client);
              END; (* IF *)
            ELSE (* CASE *)
            END; (* CASE *)
          END; (* IF *)
        END; (* IF *)
        Dr018Vtk := Dr018Vtk0154
      | Dr018Vtk0149: (* End *)
        users.Store;
        FinalizeClients(clients);
        clients.Clear;
        BEGIN {EXCLUSIVE} terminated := TRUE END;
        Dr018Vtk := Dr018VtkExit
      ELSE (* CASE *)
      END (* CASE *)
    END (* WHILE *)

  END Instance;
```
