Browse Source

ввести Уведомитель и Мир

master
commit
2dade96308
3 changed files with 195 additions and 0 deletions
  1. +182
    -0
      001.мир.js
  2. +1
    -0
      090.проверка.js
  3. +12
    -0
      index.html

+ 182
- 0
001.мир.js View File

@@ -0,0 +1,182 @@
/*
*
* Реализация шаблона "издатель-подписчик"
*
*/

function Уведомитель()
{
function Подписка(id, отклик, уведомитель)
{
this.id = id;
this.отклик = отклик;
this.уведомитель = уведомитель;
};

this.уведомить = function()
{
// Попутно собираем подписки без отклика.
var безотклика = [];
for (var номер in this.подписки)
{
var подписка = this.подписки[номер];
if (подписка.отклик)
{
подписка.отклик();
}
else
{
безотклика.push(подписка);
}
}

// И удаляем их.
if (безотклика.length)
{
this._удалитьПодпискиБезОтклика(безотклика);
}
};

this.подписать = function(отклик)
{
var id = this._сгенерироватьUUID();
var подписка = new Подписка(id, отклик, this);
this.подписки.push(подписка);
return подписка;
};

this.отписать = function(подписка)
{
подписка.отклик = null;
};

this._удалитьПодпискиБезОтклика = function(удалить)
{
var подписка = удалить.shift()
while (подписка)
{
var индекс = this.подписки.indexOf(подписка);
if (индекс !== -1)
{
this.подписки.splice(индекс, 1);
}
var подписка = удалить.shift()
}
};

this._сгенерироватьUUID = function()
{
// https://stackoverflow.com/a/2117523
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(
/[xy]/g,
function(c)
{
var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
}
);
};

// Конструктор.
this.подписки = [];
}

/*
*
* Связь событий и реакций в виде последовательности (череды)
*
*/

function Мир()
{
// Разобрать события и реакции, выраженные в тексте.
this.разобрать = function(череда)
{
var соответствия = this._событияРеакции(череда);
for (var событие in соответствия)
{
if (!(событие in this.события))
{
this.события[событие] = new Уведомитель();
}
var реакции = соответствия[событие];
for (var номер in реакции)
{
const реакция = реакции[номер];
const название = this._имяФункцииИзРеакции(реакция);
const функция = eval(название);
var тут = this;
this.события[событие].подписать(function(){
функция(тут);
});
}
}
};
// Уведомить о событии при его наличии.
this.уведомить = function(событие)
{
if (событие in this.события)
{
this.события[событие].уведомить();
}
};

// Разобрать текст с событиями и реакциями, вернуть словарь их соответствия.
this._событияРеакции = function(текст)
{
var соответствие = {};
var элементы = текст.split("\n");
var имяСобытия = null;
for (var номер in элементы)
{
var элемент = элементы[номер];
// Пропускаем комментарии.
if (элемент.charAt(0) == "#")
{
continue;
}
var имя = элемент.trim();
// Пропускаем пустые строки.
if (!имя.length)
{
continue;
}
// Событие.
if (имя == элемент)
{
if (!(имя in соответствие))
{
имяСобытия = имя;
соответствие[имя] = [];
}
}
// Реакция.
else
{
соответствие[имяСобытия].push(имя);
}
}
return соответствие;
};

// Преобразовать имя реакции в название функции.
this._имяФункцииИзРеакции = function(реакция)
{
var имя = "";
var части = реакция.split(" ");
for (var номер in части)
{
var часть = части[номер];
имя += часть.charAt(0).toUpperCase() + часть.slice(1);
}
return имя;
};

// Конструктор.
this.события = {};
}

+ 1
- 0
090.проверка.js View File

@@ -0,0 +1 @@
console.debug("090")

+ 12
- 0
index.html View File

@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>КОЛОБОК</title>
<script src="https://cdn.jsdelivr.net/npm/phaser@3.54.0/dist/phaser.min.js"></script>
<script src="001.мир.js"></script>
<script src="090.проверка.js"></script>
</head>
<body>
</body>
</html>

Loading…
Cancel
Save