i4T4e

Введение
........

Старожилы еще помнят, как Java писалась для унификации управления гаджетами в помощь горе-программистам (ГП). На гаджетах Java слишком сильно тормозила, а вот апплеты писали с охотой. Одновременно Микрософт начала борьбу с командной строкой, закончившуюся крахом Windows Millenium (винтажный синтаксис Powershell также не поможет).

Апплеты вышли из моды благодаря злобным хакерам, зомбировавшим через них чужие компьютеры. С целью занять безработных ГП хоть чем-нибудь полезным, очень другой язык Mocha* был переименован в Javascript, а написанный код беспрепятственно пересылался всем клиентам.

В ответ ГП придумали обфускаторы, JSP и nodejs, окружения WEB, WORKER, NODE и SHELL. Часть ГП сохранила верность гаджетам, уйдя в программирование на C++ для микроконтроллеров. Микроконтроллеры мужали, и ГП вновь остались без дела.

Коварный ход с созданием LLVM и стандарта webAssembly для браузеров (на сегодня это Google Chrome, Mozilla Firefox Quantum, Apple Safari и Microsoft Edge бывший `Spartan') открыл возможность отправить безработных ГП на создание веб-страниц с помощью С++, Emscripten и webAssembly, одновременно сделав попытку закопать C методом дискредитации (вспомним миллениум).

------
*) https://en.wikipedia.org/wiki/JavaScript#History
------

Кнопки и переключатели
----------------------

  Кнопка без фиксации.
  Кнопка с фиксацией.
  Тумблер-переключатель*.
  Тумблер на три положения.
  Группа с фиксацией последнего нажатия ((*) radio-buttons)

------
*) https://www.translate.ru/
    toggle key - клавиша-переключатель
    toggle off - выключать
    toggle on - включать
------

Do-More
.......

Build LD based solution for 3 channel LastToggled monitor using Do-More Designer Suite (v2.2.1)

  https://www.automationdirect.com/do-more/index
  https://support.automationdirect.com/products/domore.html

  |---|M1F|-----------------------------(M1R)--|  ^
  |---| S1|-----------------------------(M1F)--|  |
  |---|M1F|----|/M1R|-------------------(MS1)--|  |
  |                    |                       |  |
  |---|/M1F|----|M1R|--                        |  | Toggle S1
  |---|MS1F|---------------------------(MS1R)--|  |
  |---|MS1|----------------------------(MS1F)--|  |
  |---|MS1F|----|/MS1R|-----------------( F1)--|  |
  |---|/MS1F|----|MS1R|-----------------( R1)--|  v
  |--[[[ Toggle S2: R2 F2 ]]]]-----------------|
  |--[[[ Toggle S3: R3 F3 ]]]]-----------------|
  |--|R1|-----|/F1|----|/F2|----|/F3|----(Q1)--|  ^
  |        |                                   |  | flip-flop RS1
  |--|Q1|--                                    |  v
  |--[[[ flip-flop RS2: R2 F2 ]]]]-------------|
  |--[[[ flip-flop RS3: R3 F3 ]]]]-------------|

LastToggled tips
----------------

Toggle event -- changing the state of the switch, no matter from `OFF' to `ON' or from `ON' to `OFF'

    \ OFF                ON /
     \                     /
   ---o---             ---o---
  |       |           |       |
   -+-+-+-             -+-+-+-
    | | |               | | |
    1 2 3               1 2 3

  OFF: 2 and 3        ON: 1 and 2
  are connected       are connected

Changing the state on single arbitrary input causes interrupt (simultaneous toggles should put interrupts into queue in inputs enumeration order).

Each toggle event is a pulse with 3 stages:

           -------
         /         \
        /           \
       /             \
  ----                 ---- time
      |<F>|<--D-->|<R>|

  F -- front
  D -- duration
  R -- rear

In timerless LD designs F=R=`main controller loop' duration. Within `front' time gap -- register is reset. `rear' -- causes to write `1' to a proper cell.

  #include <stdio.h>
  #include <mem.h>

  #define N 8
  typedef unsigned char bool;

  int toggled( bool* anow) {
    int i;
    static bool was[N] = {0}; // *
    for( i=0; i<N; i++) if (anow[i] != was[i]) break;
    if (i < N) was[i] = anow[i];
    // i == N means state is not changed
    return i;
  }

  int main() {
    int i;
    bool sw[N];
    memset(sw, 0, N); // [1].
             i=toggled(sw); i<N?printf("on %d\n",i):printf("none\n");
    sw[2]=1; i=toggled(sw); i<N?printf("on %d\n",i):printf("none\n");
    sw[5]=1; i=toggled(sw); i<N?printf("on %d\n",i):printf("none\n");
    sw[5]=1; i=toggled(sw); i<N?printf("on %d\n",i):printf("none\n");
    sw[5]=0; i=toggled(sw); i<N?printf("on %d\n",i):printf("none\n");
    sw[3]=1; i=toggled(sw); i<N?printf("on %d\n",i):printf("none\n");
    return 0;
  }

------
*) You can use this approach to initialize a large array
   to zero as well: int nScores[100] = {0};
   http://www.dummies.com/programming/cpp/initializing-an-array-in-c/
------

Links:
......

  1. https://www.tutorialspoint.com
       /c_standard_library/c_function_memset.htm

  2. https://www.automationdirect.com/do-more/index


