Чтобы не прослыть фантазером, решил изучить вопрос сам. Скачал исходники, любезно предоставленные Smoky555, отсюда:
http://forums.ttdrussia.net/viewtopic.php?p=22337#22337 . Долго медитировал. К сожалению, Microsoft Visual Studio .NET у меня нету (стоит MSVS 6.0), поэтому сам поправить код пока не могу. Собираюсь попробовать Cygwin. Но можно ли там дебаггерить? И можно ли обойтись моей версией MSVS?
В Сях профан, хотя Дельфи или там Asm знаю. Но кое-что докумекал. В результате появилость следующее развитие идеи.
Назовем "контактную" часть некоторого сигнала -
триггером. Сам сигнал в этом случае - Зависимый Сигнал (
ЗС).
-
Триггер цепляется на любой существующий сигнал, без различия его типа.
- Также вводится отдельный тип сигнала в enum SignalType - SIGTYPE_TRIGGER. Данный тип сигнала сам по себе НЕ влияет на движение поездов (не запрещает въезд в сигнальный блок, не влияет на состояние пресигналов и PBS), а влияет только на контролируемые им
ЗС. Короче, обычный контакт на рельсах, срабатывающий при прохождении поезда.
-
ЗС может быть также ЛЮБЫМ сигналом. Т.е. добавляется лишняя проверка для его
триггеров в перечень обновления состояний сигналов в signal.cpp.
- Каждый
триггер имеет состояние вкл/выкл. Срабатывает, при срабатывании сигнала, на который повешан - т.е. при прохождении
через него поезда и/или нахождении поезда в сигнальном блоке (далее
СБ).
Триггеры могут быть обычные (включается при входе поезда в
СБ, выключается при выходе; аналог например обычная кнопка в Win) и с фиксацией - срабатывает ТОЛЬКО при вхождении поезда в
СБ, при выходе состояние НЕ меняется. Для изменения состояния требуется повторное вхождение поезда в
СБ. Аналог - RadioButton.
- В массивы сигналов в signal.cpp - struct SmallSet (если правильно понял) добавить свойство - массив
триггеров для данного
ЗС.
- Каждый
триггер самостоятелен, может влиять на n
ЗС. БЕЗ различия физического местоположения, наличия связи через клетки с путями или станциями. Даже на разных типах рельс!
- Поэтому каждый
ЗС имеет список ссылок на свои
триггеры. Если я правильно понял код, сейчас сигнальный блок обсчитывается поклеточно и в комплексе графа связей между сигналами.
ЗС придется обрабатывать отдельно, поочередно, после того, как обсчитаны состояния всех обычных сигналов (некоторые из которых являются
триггерами). Добавляются функции добавления, исключения, модификации списка
триггеров, как пользователем, так и в случае уничтожения имеющихся.
- Каждый
ЗС имеет маску состояний своих
триггеров, настраиваемую пользователем. Логика двоичная, банальная - И, ИЛИ, НЕ. Принцип визуального управления логикой - по аналогии любого редактора запросов SQL ;) (если уж в TTDP сделали управление сигналами по переменным, то здесь такой вариант будет ИМХО попрощще). Для каждого
триггера отображается кнопка "Показать" (перемещает камеру на карте, либо в отдельном окне); при редактировании списка для
ЗС на карте подсвечиваются его
триггеры (ну хоть и белой рамкой).
Триггеры в списке обозначаются, например, координатами клетки.
-
ЗС при изменении своего состояния влияют на другие сигналы соответственно их типу. Проблема возникает в том, что а) возникает рекурсия; б) затем может возникнуть зацикленность - устраняется принудительным сбросом
ЗС в состояние "красный". Или проверять на рекурсию по мере постройки сигналов и/или установки логики
ЗС.
-
ЗС можно сделать "безопасными" - в логику его
триггеров включается по умолчанию также состояние
СБ, следующего за самим
ЗС. Т.е. при любых комбинациях,
ЗС будет реагировать также на нахождение поезда в сигнальном блоке, куда
ЗС является входом. Короче, работать, как обычный сигнал соответствующего типа.
- Либо для полноты контроля сделать это настраиваемым -
ЗС ведет себя, как обычный сигнал соотв. типа ТОЛЬКО при отсутствии у него
триггеров. Иначе - пользователь сам разруливает затыки и старается предупредить возможные столкновения.
- Короче, ЛЮБОЙ сигнал является по умолчанию зависимым; только при отсутствии
триггеров он работает стандартно, а при наличии - уже в зависимости от состояния
триггеров.
Это была описательная часть. Теперь как это будет выглядеть в коде.
- КАЖДЫЙ сигнал АВТОМАТИЧЕСКИ становится
триггером для некоторых других ПО МЕРЕ УСТАНОВКИ. А именно, согласно связи между ними по ходу ж\д пути, при прокладке пути и при изменении уже установленных сигналов. Ссылки сигналов друг на друга при этом становятся АБСОЛЮТНЫМИ. Это позволяет сохранить логику пресигналов и PBS, только обсчитываться она будет не по графу связей, как сейчас, а линейно-рекурсивно - для каждого сигнала обсчитывается состояние его
триггеров, при возникновении цикла сигнал блокируется в некотором состоянии (вкл. или выкл.). Обсчет по моим прикидкам будет на порядок быстрее.
- Стандартный сигнал имеет в качестве
триггера сам себя. Точнее, состояние
СБ, в который он вход.
- Пресигнал "вход" имеет
триггерами "выходы" и "комбо" (с логикой ИЛИ). И сам себя, при наличии поезда в блоке. Т.е. пресигналы становятся готовыми шаблонами триггерной логики для постройки.
- PBS... Его логику я пока и сам не понимаю, к тому же есть разные варианты реализации. К примеру, здесь
триггер будет срабатывать ТОЛЬКО при прохождении поезда через сигнал, но НЕ при нахождении поезда в
СБ. Причем
триггером будет сигнал, ведущий ИЗ развязки, а контролировать он будет вход в развязку и альтернативные выходы! Но это еще недостаточно, надо додумывать по PBS...
-
ЗС добавляется также в логику входа в депо.
- "Логические"
триггеры, не являюшиеся сигналами, добавляются пользователем по вкусу. Строятся как обычные сигналы, как из общего меню, так и из меню логики
ЗС.
- Графика... Больной вопрос. Синий фонарь для "логического"
триггера, синяя лампочка у сигнала, включенного в триггерную схему. Или соотв. полоска. Пресигналы отображаются как обычно, для ясности.
- Поскольку
триггеры вряд ли будут расстанавливаться пользователем слишком часто, скорость обработки уменьшится непринципиально, зато старая логика обработки пресигналов станет более линейной, т.е. быстрой!
- В настройках патча, ессно все это можно отключить.
- Насколько я понимаю, меняется только 2 файла - signal.cpp и rail_map.h (ну и соответствующие GUI). Т.к. логика обработки сигнала поездом (красный/зеленый) сохраняется.
Дальнейшее развитие логики триггеров:
-
Триггер, без различия его типа, реагирует на: 1) массу прошедшего через него состава; 2) скорость его прохождения (через
СБ или через сам
триггер). Это сразу решает проблему разделения путей по скорости и отчасти - по типу груза.
- То же, но указывается при настройке
ЗС. Нечто вроде АЦП, когда некий
ЗС сам имеет критерии состояния своих
триггеров по вышеуказанным параметрам.
- Но это приведет к уменьшению скорости обработки :( Зато понадобится меньше триггеров.
Пока у меня все.
Просьба покритиковать и указать на недочеты. Если подсоветуете с компилером, попробую закодить.