для этого тема и создана.Ведь может родиться русский Е У Ноль Семь, и даже круче!
OK, перемещаемЗЫ Повторяю еще раз, взаимные наезды через приват
Исходник одной ДЛЛ, которыми ты собираешься заменить скрипты.Конкретней спроси что нужно - ни весь исходник ни какую-то рабочую часть не вышлю, часть исходника демонстрирующую решение проблемы могу показать.
Так делай для себя, молча. Если на сообщество срать, на кой тогда тема на форуме?а не потому что делаю сим для сообщества...
break писал(а):Вода в ступе 2
Что значит похоже? Есть поля - в них хранятся значения - на поля вешаются листенеры.
TRam_ писал(а):OK, перемещаемЗЫ Повторяю еще раз, взаимные наезды через приват
Есть поля - в них хранятся значения - на поля вешаются листенеры.
include "xlse_base.gs"
include "xlse_analogscheme.gs"
class XCHS4_Locomotive isclass LseLocomotive
{
public void Init(Asset asset);
void InitFinal(void)
{
inherited();
AnalogScheme gs = new AnalogScheme();
SetGraphScheme(gs);
gs.SetCircuit("GV1.A, R2.A, R2.B, GV1.B, GV1.A");
gs.SetCircuit("R2.A, R3.A, R3.B, R2.B");
gs.SetCircuit("R3.A R4.A, R4.B GV1.B");
gs.SetCircuit("R2.A R1.A, R1.B GV2.A, GV2.B GV1.B");
gs.SetObject(new AS_BasicBipolar(), "GV1", "V = 5, R = 0", null);
gs.SetObject(new AS_BasicBipolar(), "GV2", "V = 1, R = 0", null);
gs.SetObject(new AS_BasicBipolar(), "R1", "R = 1", null);
gs.SetObject(new AS_BasicBipolar(), "R2", "R = 2", null);
gs.SetObject(new AS_BasicBipolar(), "R3", "R = 2", null);
gs.SetObject(new AS_BasicBipolar(), "R4", "R = 4", null);
GraphSchemeMain(gs);
}
public void Init(Asset asset)
{
inherited(asset);
}
};
1. Какой используется движок и каков планируется графический уровень?
2. Какой планируется метод распространения?
3. Открыт ли будет исходный код?
Ну ок, поговорим, когда сим станет радикально лучше ТРС, КРС и МСТС во всем.Очень сложный вопрос не зависящий от меня одного. И основная зацепка - надо ли это тем кто его делает.
Ведь может родиться русский Е У Ноль Семь, и даже круче!
EU07 вроде с открытым кодом
- ну да хотя бы до 2000 года в 2010Да и по графике его можно хотя бы до МСТС подтянуть.
а не ломаными линиями.
И в EU07 тяговые характеристики сделаны через сопротивления якорей, реостатов и шунтов
Это более производительно и проще реализуется в движке.
Но взамен мы получаем недостатки С++,
F это важно в случае с пользовательским контентом, так как ошибка в скрипте — исключение, максимум вылет из игры, а в С++ может привести к краху всей системы.
Также, я не уверен в переносимости таких ДЛЛ. К примеру, потребуется делать оболочку над АПИ ОС, ведь тот же КЛУБ должен иметь возможность писать в файл.
P.S. Вот, к примеру, задание простой схемы и вход в поток ее расчета на АГС:
Я считаю оптимальным такой подход, при котором классы, представляющие объекты в игре, связаны в иерархию: к примеру MeshObject — класс, имеющий модели и реализующий необходимый интерфейс для управления ими, к примеру, показать/скрыть лампочку, запустить анимацию, сменить текстуру и т.д.
Класс Vehicle — производный от MeshObject и, возможно, других — зависит от реализации. Такая иерархия полностью соответствует тому, что мы видим в реальном мир
Другое дело, что в эту базовую функциональность вполне вписываются базовые модули — КЛУБы, САУТы, ВРы и т.д. Элементарно просто реализовывать свои объекты — пишем наследника от базового абстрактного класса, чуть-чуть исправить логику по умолчанию — пишем наследника от конкретного класса, КЛУБа и т. п.
Элементарно просто реализовывать свои объекты — пишем наследника от базового абстрактного класса, чуть-чуть исправить логику по умолчанию — пишем наследника от конкретного класса, КЛУБа и т. п.
Устройства, наподобие фазорасщепителя, удобно рассматривать не как полностью независимые модули, а как части электрической схемы
К примеру, класс Светофор может быть наследником класса Путевой объект, наследника MeshObject, впрочем, это детали.
По-моему, такая архитектура полностью вписывается в твои пункты, при этом обладая большим потенциалом по расширяемости, и решает проблему обособленности других объектов.
Еще одно преимущество такого похода — в строгом контроле типов. Если я использую для моего КЛУБа ЭПК программиста Пети, я буду иметь перед глазами точный его интерфейс и строгий контроль типов со стороны компилятора, что гарантирует мне, что никакой другой ЭПК не сможет неявно работать с моим КЛУБом и являться источником потенциальных ошибок. Конечно, этот пример кажется немного неудачным — ведь если я делаю вагон, то и знаю какой на нем стоит ЭПК. Но представим, что моему КЛУБу нужно обратиться к ЭПК на другом вагоне — и тут возможные различия могут сыграть свою роковую роль. Особенно если вместо ЭПК и КЛУБа будут стоять объекты, обладающие более сложной логикой взаимодействия.
#include "BC_395.h"
#include <QDebug>
#include "PhUtils.h"
#include "XmlSettings.h"
#include "ServerTrainController.h"
#include "ServerTrainWagonController.h"
#include "AirConnection.h"
#include "AirVolume.h"
#define DEFAULT_OVER_EQHOLE_TO_EQ_K (0.0016 / 27.0)
#define DEFAULT_GM_TO_OVER_EQHOLE_1_K (0.005 / 27.0)
#define DEFAULT_GM_TO_TM_1_K (0.007 / 10.0)
#define DEFAULT_GM_TO_OVER_EQHOLE_2_K (0.003 / 27.0)
#define DEFAULT_RES_EQ_TO_TM_3_K (0.010)
#define DEFAULT_RES_EQ_TO_ATM_51_K (0.00075 / 37.0)
#define DEFAULT_RES_EQ_TO_ATM_5_K (0.0023 / 10.0)
#define DEFAULT_OVER_EQHOLE_TO_ATM_6_K (0.0035)
#define DEFAULT_RES_EQ_TO_ATM_6_K (0.003)
#define DEFAULT_TM_TO_ATM_6_K (0.016)
#define DEFAULT_GM_TO_TM_K (0.018 / 27.0)
#define DEFAULT_TM_TO_ATM_K (0.018 / 17.0)
#define DEFAULT_VENT_2S_MIN_P 0.001f
#define DEFAULT_VENT_2S_MAX_P 0.1f
#define DEFAULT_REDUCT_P 4.7
#define DEFAULT_RES_EQ_P 4.7
#define DEFAULT_GM_CHARGE_P 8.0
#define DEFAULT_ENTER_GM "BC_395_GM_Pipe__head"
#define DEFAULT_ENTER_TM "BC_395_TM_Pipe__head"
CBC_395::CBC_395()
{
m_pOverEQHole_Vol = 0;
m_pResEQ_Vol = 0;
m_pOverEQHole_to_EQ_Conn = 0;
m_pGM_to_OverEQHole_1_Conn = 0;
m_pGM_to_TM_1_Conn = 0;
m_pGM_to_OverEQHole_2_Conn = 0;
m_pResEQ_to_TM_3_Conn = 0;
m_pResEQ_to_Atm_51_Conn = 0;
m_pResEQ_to_Atm_5_Conn = 0;
m_pOverEQHole_to_Atm_6_Conn = 0;
m_pResEQ_to_Atm_6_Conn = 0;
m_pTM_to_Atm_6_Conn = 0;
m_pGM_to_TM_Trigger = 0;
m_pTM_to_Atm_Trigger = 0;
}
CBC_395::~CBC_395()
{
}
void CBC_395::onValueChanged( CSharedVariant& Value )
{
IWagDev::onValueChanged( Value );
if ( &Value == m_CDP.m_pGear_BC_395 )
{
updateHoles();
return;
};
if ( &Value == m_CDP.m_pGear_EPT )
{
updateEPT_Switches();
};
}
void CBC_395::onTick( double fSec )
{
m_pGM_to_OverEQHole_2_Conn->setK( 0 );
switch ( m_CDP.m_pGear_BC_395->asInt() )
{
case (1):
{
m_CDP.setSndGain( m_CDP.m_pSound_BC_395_GM_to_TM_1, (getEnter_GM_P()-getEnter_TM_P()) / (m_fGM_Charge_P-m_fReductP) );
break;
};
case (2):
{
// разность давлений на кот. отрегулирован редуктор и Ур. рез.
float delta = PascalToKgF_SQcm( m_fReductP - getEQ_P() );
if (delta > 0.001) // дозарядка до зарядного 0.003
m_pGM_to_OverEQHole_2_Conn->setK( 1 );
else if (delta < -0.001) // ликвидация сверхзарядки постоянным темпом
m_pResEQ_Vol->setPressure( getEQ_P() - 150*fSec );
// пока звук редуктора + стабилизатора хаком
m_CDP.setSndGain( m_CDP.m_pSound_BC_395_GM_to_TM_2, (getEnter_GM_P()-getEnter_TM_P()) / (m_fGM_Charge_P-m_fReductP) );
//m_CDP.setSndGain( m_CDP.m_pSound_BC_395_GM_to_TM_2, 1 );
break;
};
case (51):
{
float gain = getEnter_TM_P() / m_fReductP;
m_CDP.setSndGain( m_CDP.m_pSound_BC_395_TM_to_ATM_5A, gain );
m_CDP.playSnd( m_CDP.m_pSound_BC_395_TM_to_ATM_5A );
break;
};
case (5):
{
float gain = getEnter_TM_P() / m_fReductP;
m_CDP.setSndGain( m_CDP.m_pSound_BC_395_TM_to_ATM_5, gain );
m_CDP.playSnd( m_CDP.m_pSound_BC_395_TM_to_ATM_5 );
break;
};
case (6):
{
float gain = getEnter_TM_P() / m_fReductP;
m_CDP.setSndGain( m_CDP.m_pSound_BC_395_TM_to_ATM_6, gain );
m_CDP.playSnd( m_CDP.m_pSound_BC_395_TM_to_ATM_6 );
break;
};
default: break;
};
// обновление параметров для передачи в сеть
m_CDP.m_pBC_395_EQ_P-> setFloat( PascalToKgF_SQcm( getEQ_P() ), satNormal, 0.01f );
//m_CDP.m_pBoard_OverEQHole_P->setFloat( PascalToKgF_SQcm( getOverEQHole_P() ), satNormal, 0.01f );
// В 3-м положении крана необходимо обеспечить перекрышу без питания ТМ
// воздух должен выйти через обратный клапан из полости над Ур.Поршнем в ТМ
// и двухседельчатый клапан должен быть закрыт в обоих направлениях
// но если темп утечки из ТМ больше чем m_Vent_2S_min_P(значение при кот. клапан полностью закрыт)
// то происходит подпитка ТМ из ГМ, вероятно из-за того что в пневмосистеме не учитывается порядок
// обработки соединений... В связи с этим блокируем работу двухседельчатого клапана
// при 3-ем положении крана принудительно!!!
m_pGM_to_TM_Trigger -> setState( m_CDP.m_pGear_BC_395->asInt() != 3 );
m_pTM_to_Atm_Trigger -> setState( m_CDP.m_pGear_BC_395->asInt() != 3 );
}
void CBC_395::initLogicParams()
{
// Инициализация логических параметров устройства
m_fOverEQHole_to_EQ_K = DEFAULT_OVER_EQHOLE_TO_EQ_K;
m_fGM_to_overEQHole_1_K = DEFAULT_GM_TO_OVER_EQHOLE_1_K;
m_fGM_to_TM_1_K = DEFAULT_GM_TO_TM_1_K;
m_fGM_to_overEQHole_2_K = DEFAULT_GM_TO_OVER_EQHOLE_2_K;
m_fResEQ_to_TM_3_K = DEFAULT_RES_EQ_TO_TM_3_K;
m_fResEQ_to_Atm_51_K = DEFAULT_RES_EQ_TO_ATM_51_K;
m_fResEQ_to_Atm_5_K = DEFAULT_RES_EQ_TO_ATM_5_K;
m_fOverEQHole_to_Atm_6_K = DEFAULT_OVER_EQHOLE_TO_ATM_6_K;
m_fResEQ_to_Atm_6_K = DEFAULT_RES_EQ_TO_ATM_6_K;
m_fTM_to_Atm_6_K = DEFAULT_TM_TO_ATM_6_K;
m_fGM_to_TM_K = DEFAULT_GM_TO_TM_K;
m_fTM_to_Atm_K = DEFAULT_TM_TO_ATM_K;
m_fVent_2S_min_P = KgF_SQcmToPascal( DEFAULT_VENT_2S_MIN_P );
m_fVent_2S_max_P = KgF_SQcmToPascal( DEFAULT_VENT_2S_MAX_P );
m_fReductP = KgF_SQcmToPascal( initParam( DEFAULT_REDUCT_P, "TM_Charge_P" ).toDouble() );
m_fResEQ_P = KgF_SQcmToPascal( initParam( DEFAULT_RES_EQ_P, "TM_P" ).toDouble() );
m_fGM_Charge_P = KgF_SQcmToPascal( initParam( DEFAULT_GM_CHARGE_P, "GM_Charge_P" ).toDouble() );
m_sEnter_GM = DEFAULT_ENTER_GM;
m_sEnter_TM = DEFAULT_ENTER_TM;
m_processType = TrainConsts::adptChargeAndRelease;
}
void CBC_395::loadFromXML( QString sFName )
{
CXmlSettings xml( sFName );
xml.settings().beginGroup( "Options" );
m_fOverEQHole_to_EQ_K = readParamFromXML( xml, "OverEQHole_to_EQ_K",
QString::fromUtf8("отверстие 1.6 мм соед. полость над поршнем с Уравнительным рез."),
DEFAULT_OVER_EQHOLE_TO_EQ_K ).toDouble();
// положение 1 - Зарядка и отпуск
m_fGM_to_overEQHole_1_K = readParamFromXML( xml, "GM_to_overEQHole_1_K",
QString::fromUtf8("отверстие 5 мм из ГМ для зарядки полости над уравнительным поршнем при 1 положении"),
DEFAULT_GM_TO_OVER_EQHOLE_1_K ).toDouble();
m_fGM_to_TM_1_K = readParamFromXML( xml, "GM_to_TM_1_K",
QString::fromUtf8("прямое соединение ГМ и ТМ при 1 положении"),
DEFAULT_GM_TO_TM_1_K ).toDouble();
// положение 2 - Поездное
m_fGM_to_overEQHole_2_K = readParamFromXML( xml, "GM_to_overEQHole_2_K",
QString::fromUtf8("дозарядка до зарядного - через редуктор 3 мм - при 2 положении"),
DEFAULT_GM_TO_OVER_EQHOLE_2_K ).toDouble();
// положение 3 - Перекрыша без питания ТМ
m_fResEQ_to_TM_3_K = readParamFromXML( xml, "ResEQ_to_TM_3_K",
QString::fromUtf8("соед. Ур. поршня с ТМ для выравн давлений через обратный клапан при 3 положении"),
DEFAULT_RES_EQ_TO_TM_3_K ).toDouble();
// положение 4 - Перекрыша с питанием ТМ
// никаких соединений не открывается
m_fResEQ_to_Atm_51_K = readParamFromXML( xml, "ResEQ_to_Atm_51_K",
QString::fromUtf8("положение 5А - Служебное положение длинносоставного поезда или ЭПТ 0.75 мм"),
DEFAULT_RES_EQ_TO_ATM_51_K ).toDouble();
m_fResEQ_to_Atm_5_K = readParamFromXML( xml, "ResEQ_to_Atm_5_K",
QString::fromUtf8("положение 5 - Служебное торможение 2.3 мм"),
DEFAULT_RES_EQ_TO_ATM_5_K ).toDouble();
// положение 6 - Экстренное торможение
m_fOverEQHole_to_Atm_6_K = readParamFromXML( xml, "OverEQHole_to_Atm_6_K",
QString::fromUtf8("соединение полости над Ур. поршнем с АТМ"),
DEFAULT_OVER_EQHOLE_TO_ATM_6_K ).toDouble();
m_fResEQ_to_Atm_6_K = readParamFromXML( xml, "OverEQHole_to_Atm_6_K",
QString::fromUtf8("соединение полости Ур. поршня с АТМ"),
DEFAULT_RES_EQ_TO_ATM_6_K ).toDouble();
m_fTM_to_Atm_6_K = readParamFromXML( xml, "TM_to_Atm_6_K",
QString::fromUtf8("соединение ТМ с АТМ"),
DEFAULT_TM_TO_ATM_6_K ).toDouble();
// соединения для зарядки и разрядки ТМ с пом. двухседельчатого клапана
m_fGM_to_TM_K = readParamFromXML( xml, "GM_to_TM_K",
QString::fromUtf8("соединение ГМ с ТМ через двухседельчатый клапан"),
DEFAULT_GM_TO_TM_K ).toDouble();
m_fTM_to_Atm_K = readParamFromXML( xml, "TM_to_Atm_K",
QString::fromUtf8("соединение ТМ с АТМ через двухседельчатый клапан"),
DEFAULT_TM_TO_ATM_K ).toDouble();
//*************************************************************************
double fVal;
fVal = readParamFromXML( xml, "Vent_2S_min_P",
QString::fromUtf8("минимальное значение разницы - ниже которого двухседельчатый клапан закрыт полностью"),
DEFAULT_VENT_2S_MIN_P ).toDouble();
m_fVent_2S_min_P = KgF_SQcmToPascal( fVal );
fVal = readParamFromXML( xml, "Vent_2S_max_P",
QString::fromUtf8("максимальное значение разницы - выше которого двухседельчатый клапан открыт полностью"),
DEFAULT_VENT_2S_MAX_P ).toDouble();
m_fVent_2S_max_P = KgF_SQcmToPascal( fVal );
fVal = readParamFromXML( xml, "Reduct_P",
QString::fromUtf8("Давление на которое отрегулирован редуктор"),
DEFAULT_REDUCT_P, "TM_Charge_P" ).toDouble();
m_fReductP = KgF_SQcmToPascal( fVal );
fVal = readParamFromXML( xml, "ResEQ_P",
QString::fromUtf8("Давление в Ур. резервуаре"),
DEFAULT_RES_EQ_P, "TM_P" ).toDouble();
m_fResEQ_P = KgF_SQcmToPascal( fVal );
fVal = readParamFromXML( xml, "GM_Charge_P",
QString::fromUtf8("Зарядное давление ГМ"),
DEFAULT_GM_CHARGE_P, "GM_Charge_P" ).toDouble();
m_fGM_Charge_P = KgF_SQcmToPascal( fVal );
//*************************************************************************
m_sEnter_GM = readParamFromXML( xml, "Enter_GM",
QString::fromUtf8("подключение к ГМ"),
DEFAULT_ENTER_GM ).toString();
m_sEnter_TM = readParamFromXML( xml, "Enter_TM",
QString::fromUtf8("подключение к ГМ"),
DEFAULT_ENTER_TM ).toString();
xml.settings().endGroup();
}
void CBC_395::init()
{
m_TDP.assign_connect_TrainProps( getServerTrain()->getTrainType(), satWeak );
m_CDP.assignGears( getServerTrain()->getTrainType(), satWeak );
m_CDP.m_pGear_BC_395->connectTo( this );
m_CDP.m_pGear_EPT->connectTo( this );
m_CDP.assignBC_395_Data();
m_CDP.connectBC_395_Data( this );
m_CDP.assignSounds( getServerTrain()->getTrainType(), satWeak );
m_CDP.assignEPT_Props( satWeak );
// создание резервуаров
// уравнительный резервуар - 20л
m_pResEQ_Vol = getAirManager()->addReservoir( 0.02, m_fResEQ_P );
// 0,2л камера над поршнем
m_pOverEQHole_Vol = getAirManager()->addReservoir( 0.0002, m_fResEQ_P );
// создание пневмо соединений
// отверстие 1.6 мм соед. полость над поршнем с Уравнительным рез.
m_pOverEQHole_to_EQ_Conn = getAirManager()->addConnection( m_pOverEQHole_Vol, m_pResEQ_Vol,
m_fOverEQHole_to_EQ_K, m_fOverEQHole_to_EQ_K, 1.0f );
// положение 1 - Зарядка и отпуск
// отверстие 5 мм из ГМ для зарядки полости над уравнительным поршнем при 1 положении
m_pGM_to_OverEQHole_1_Conn = getAirManager()->addConnection( getEnter_GM(), m_pOverEQHole_Vol,
m_fGM_to_overEQHole_1_K,
m_fGM_to_overEQHole_1_K, 0 );
// прямое соединение ГМ и ТМ при 1 положении
m_pGM_to_TM_1_Conn = getAirManager()->addConnection( getEnter_GM(), getEnter_TM(),
m_fGM_to_TM_1_K,
m_fGM_to_TM_1_K, 0 );
// положение 2 - Поездное
// дозарядка до зарядного - через редуктор 3 мм - при 2 положении
m_pGM_to_OverEQHole_2_Conn = getAirManager()->addConnection( getEnter_GM(), m_pOverEQHole_Vol,
m_fGM_to_overEQHole_2_K,
m_fGM_to_overEQHole_2_K, 0 );
// положение 3 - Перекрыша без питания ТМ
// соед. Ур. поршня с ТМ для выравн давлений через обратный клапан при 3 положении
m_pResEQ_to_TM_3_Conn = getAirManager()->addConnection( m_pResEQ_Vol, getEnter_TM(),
m_fResEQ_to_TM_3_K, 0, 0 );
// положение 4 - Перекрыша с питанием ТМ
// положение 5А - Служебное положение длинносоставного поезда или ЭПТ 0.75 мм
m_pResEQ_to_Atm_51_Conn = getAirManager()->addConnection( m_pResEQ_Vol, getAirManager()->atmosphere(),
m_fResEQ_to_Atm_51_K, 0, 0 );
// положение 5 - Служебное торможение
m_pResEQ_to_Atm_5_Conn = getAirManager()->addConnection( m_pResEQ_Vol, getAirManager()->atmosphere(),
m_fResEQ_to_Atm_5_K, m_fResEQ_to_Atm_5_K, 0); // 2.3 мм
// положение 6 - Экстренное положение
m_pOverEQHole_to_Atm_6_Conn = getAirManager()->addConnection( m_pOverEQHole_Vol, getAirManager()->atmosphere(),
m_fOverEQHole_to_Atm_6_K, 0, 0 ); // 3.5 мм
m_pResEQ_to_Atm_6_Conn = getAirManager()->addConnection( m_pResEQ_Vol, getAirManager()->atmosphere(),
m_fResEQ_to_Atm_6_K, 0, 0 ); // 3 мм
m_pTM_to_Atm_6_Conn = getAirManager()->addConnection( getEnter_TM(), getAirManager()->atmosphere(),
m_fTM_to_Atm_6_K, 0, 0 ); //16 мм
// триггеры двухседельчатого клапана
m_pGM_to_TM_Trigger = getAirManager()->addTrigger( getEnter_GM(), getEnter_TM(),
getEnter_TM(), m_pOverEQHole_Vol,
m_fVent_2S_min_P, m_fVent_2S_max_P,
m_fGM_to_TM_K );
m_pTM_to_Atm_Trigger = getAirManager()->addTrigger( getEnter_TM(), getAirManager()->atmosphere(),
m_pOverEQHole_Vol, getEnter_TM(),
m_fVent_2S_min_P, m_fVent_2S_max_P,
m_fTM_to_Atm_K );
//test leak//getAirManager()->addConnection( getEnter_TM(), getAirManager()->atmosphere(), 0.0001, 0.0001, 1.0 );
}
void CBC_395::updateHoles()
{
closeSomeConnections();
switch ( m_CDP.m_pGear_BC_395->asInt() )
{
case 1:
{
m_processType = TrainConsts::adptChargeAndRelease;
// отверстие 5 мм из ГМ для зарядки полости над уравнительным поршнем при 1 положении
m_pGM_to_OverEQHole_1_Conn->setK( 1 );
// прямое соединение ГМ и ТМ
m_pGM_to_TM_1_Conn->setK( 1 );
// озвучка
m_CDP.playSnd( m_CDP.m_pSound_BC_395_GM_to_TM_1 );
break;
};
case 2:
{
m_processType = TrainConsts::adptChargeAndRelease;
// код в onAirStep() т.к. зависит от давлений
// озвучка
m_CDP.playSnd( m_CDP.m_pSound_BC_395_GM_to_TM_2 );
break;
};
case 3:
{
m_processType = TrainConsts::adptCover;
m_pResEQ_to_TM_3_Conn->setK( 1 );
break;
};
case 4:
{
m_processType = TrainConsts::adptCover;
break;
};
case 51:
{
m_processType = TrainConsts::adptBrake;
m_pResEQ_to_Atm_51_Conn->setK( 1 ); // 0.00075
break;
};
case 5:
{
m_processType = TrainConsts::adptBrake;
m_pResEQ_to_Atm_5_Conn->setK( 1 ); // 0.0023
break;
};
case 6:
{
m_processType = TrainConsts::adptExtraBrake;
m_pOverEQHole_to_Atm_6_Conn->setK( 1 );
m_pResEQ_to_Atm_6_Conn->setK( 1 );
m_pTM_to_Atm_6_Conn->setK( 1 );
break;
};
};
CBC_395::updateEPT_Switches();
}
void CBC_395::updateEPT_Switches()
{
// тумблер ЭПТ выключен, питание на вентили не подается с крана машиниста
if ( !m_CDP.m_pGear_EPT->asInt() )
{
m_CDP.m_pEPT_OV_BrakeCrane->setInt( 0 );
m_CDP.m_pEPT_TV_BrakeCrane->setInt( 0 );
return;
};
// если тумблер включен, питание подается в соответствие с положением ручки крана
switch ( m_CDP.m_pGear_BC_395->asInt() )
{
case (1):
case (2):
{
m_CDP.m_pEPT_OV_BrakeCrane->setInt( 0 );
m_CDP.m_pEPT_TV_BrakeCrane->setInt( 0 );
break;
};
case (3):
case (4):
{
m_CDP.m_pEPT_OV_BrakeCrane->setInt( 1 );
m_CDP.m_pEPT_TV_BrakeCrane->setInt( 0 );
break;
};
case (51):
case (5):
case (6):
{
m_CDP.m_pEPT_OV_BrakeCrane->setInt( 1 );
m_CDP.m_pEPT_TV_BrakeCrane->setInt( 1 );
break;
};
};
}
void CBC_395::closeSomeConnections()
{
// закрываем все соединения определяемые положением ручки крана
m_pGM_to_OverEQHole_1_Conn -> setK( 0 );
m_pGM_to_TM_1_Conn -> setK( 0 );
m_pGM_to_OverEQHole_2_Conn -> setK( 0 );
m_pResEQ_to_TM_3_Conn -> setK( 0 );
m_pResEQ_to_Atm_51_Conn -> setK( 0 );
m_pResEQ_to_Atm_5_Conn -> setK( 0 );
m_pOverEQHole_to_Atm_6_Conn -> setK( 0 );
m_pResEQ_to_Atm_6_Conn -> setK( 0 );
m_pTM_to_Atm_6_Conn -> setK( 0 );
// выключаем все звуки крана
m_CDP.stopSnd( m_CDP.m_pSound_BC_395_GM_to_TM_1 );
m_CDP.stopSnd( m_CDP.m_pSound_BC_395_GM_to_TM_2 );
m_CDP.stopSnd( m_CDP.m_pSound_BC_395_TM_to_ATM_5A );
m_CDP.stopSnd( m_CDP.m_pSound_BC_395_TM_to_ATM_5 );
m_CDP.stopSnd( m_CDP.m_pSound_BC_395_TM_to_ATM_6 );
}
float CBC_395::getOverEQHole_P()
{
return m_pOverEQHole_Vol->pressure();
}
float CBC_395::getEQ_P()
{
Q_ASSERT( m_pResEQ_Vol );
return m_pResEQ_Vol->pressure();
}
CAirVolume * CBC_395::getEnter_GM()
{
CAirVolume * pVolume = checkVolume( m_sEnter_GM );
return pVolume;
}
CAirVolume * CBC_395::getEnter_TM()
{
CAirVolume * pVolume = checkVolume( m_sEnter_TM );
return pVolume;
}
float CBC_395::getEnter_GM_P()
{
CAirVolume * pVolume = checkVolume( m_sEnter_GM );
return pVolume->pressure();
}
float CBC_395::getEnter_TM_P()
{
CAirVolume * pVolume = checkVolume( m_sEnter_TM );
return pVolume->pressure();
}
2. Какой планируется метод распространения?
Очень сложный вопрос не зависящий от меня одного. И основная зацепка - надо ли это тем кто его делает.
Ну ок, поговорим, когда сим станет радикально лучше ТРС, КРС и МСТС во всем.
Возможность экспорта функций из ДЛЛ vs. возможность полного применения ООП? Дело явно не в пользу ДЛЛ. Я в ВЛ10, например, из кабины напрямую вызываю в локомотиве методы, безо всяких интерфейсов. КЛУБ-У я реализовал как прослойку между стандартным классом кабины и пользовательским — интеграция осуществляется в десять строчек. Опять же, никаких интерфейсов и возможность использования КЛУБа абсолютно везде без внесения изменений.не ограниченные никакими интерфейсами, скриптами и т.д. можно делать дополнения.
Задается граф, описывающий электрическую цепь, создаются объекты, описывающие её элементы и запускается расчет. Опять же, можно откуда угодно получить доступ к чему угодно — ко всему графу, или к конкретной вершине, или перенастроить некие общие параметры моделиющего объекта.Ну к сож. оценить не могу - может и круто, но мало что из исходника можно уловить - задаются параметры и все.
Уже есть, очень удобно.Этот подход однажды приведет в тупик, потребуется использовать множественное наследование
Класс Путь (независимый), классы ПутевойОбъект>Стрелка.Стрелка стоит на опр. линейной координате - значит Путевой объект, но она является частью Пути - Значит Путь? Опять двойное наследование?
Плохой пример.А если потом нужно поставить Светофор на стрелку?
Тем-тем. Могу дерево классов предоставить.но не факт что тем способом (бесконечное наследование одного от другого) о котором вы говорите
Вот в этом случае, если выражаться метафорически, при отсутствии хидерных файлов, придется делать интерфейсы. Но у нас есть стандартная вещь, называемая Soup, фактически — база данных, которая есть у 95% всех объектов. Петя просто указывает в своем Супе некий параметр под определенным именем, дальше с ним может работать кто угодно. Если я правильно понял, это то же, что предлагаешь ты — публичные поля с заранее известными именами.А в вашем случае вы просто не сможете написать Клуб который будет работать с "ЭПК программиста Пети" на другом вагоне. Т.к. Программист Петя не дал вам исходник своего ЭПК и компилятор не может осуществить контроль типов и т.д.
Я бы с радостью в него перешелИ что бы изменилось если бы он стал таким?
А какая цель? Сделать сим, который чуть лучше в одном, но безнадежно отстает во всем остальном?Вообще не было цели сделать "самый лучший сим"
Возможность экспорта функций из ДЛЛ vs. возможность полного применения ООП? Дело явно не в пользу ДЛЛ. Я в ВЛ10, например, из кабины напрямую вызываю в локомотиве методы, безо всяких интерфейсов. КЛУБ-У я реализовал как прослойку между стандартным классом кабины и пользовательским — интеграция осуществляется в десять строчек. Опять же, никаких интерфейсов и возможность использования КЛУБа абсолютно везде без внесения изменений.
В библиотеке я не понял один момент — если симу от нее что-то нужно, тут понятно — он вызывает экспортированную функцию. А если библиотека хочет что-то сделать в симе? Звук проиграть, например? Тут всплывает непонятный объект m_CDP. И где объявлены функции getServerTrain() и иже с ними?
m_CDP. И где объявлены функции getServerTrain()
КЛУБ-У я реализовал как прослойку между стандартным классом кабины и пользовательским — интеграция осуществляется в десять строчек.
Тем-тем. Могу дерево классов предоставить.
Вот в этом случае, если выражаться метафорически, при отсутствии хидерных файлов, придется делать интерфейсы. Но у нас есть стандартная вещь, называемая Soup, фактически — база данных, которая есть у 95% всех объектов. Петя просто указывает в своем Супе некий параметр под определенным именем, дальше с ним может работать кто угодно. Если я правильно понял, это то же, что предлагаешь ты — публичные поля с заранее известными именами.
break писал(а):Я бы скорее подумал о достоинствах С++ - и о том какие исходя из этого не ограниченные никакими интерфейсами, скриптами и т.д. можно делать дополнения.
Это вы сами себе напридумывали - ошибка в любой программе должна приводить в крайнем случае только к ее вылету, и к коректному освобождению всех ресурсов после этого самой ОС. Если при ошибке программы вылетае ОС или еще хуже перестает запускаться - это ошибка или охрененный недостаток самой ОС. Мне такие случаи даже не известны! Не путайте с тем когда вирус стирает на вашем диске системные файлы - это не ошибка вируса и не ошибка ОС - а все работает так как и задумал автор вируса!
Кроме того в C++ достаточно средств для контроля таких возможных вылетов - например "умные указатели" - кто-то удалил объект - указатель сам себя очищает - при следующей попытке не произойдет обращение по старому адресу, где объекта уже нет. В современных скриптовых языках тоже есть подобные вещи - даже на уровне самого языка.
С платформонезависимостью в объектах хранящихся в DLL все в порядке, они читают из файла и пишут в него тоже, абсолютно независимо от платформы.
Ну к сож. оценить не могу - может и круто, но мало что из исходника можно уловить - задаются параметры и все.
Этот подход однажды приведет в тупик, потребуется использовать множественное наследование а потом и виртуальное наследование от которого больше проблем чем пользы.
Наследование в реальном мире? Если вы имеете ввиду что с пом. этого подхода можно сделать то что мы видим в реальном мире - то да, но есть и другие более гибкие методы.
Как то совсем голословно - и так есть базовый класс - в скрипте которого достаточно что-то прописать - и он сможет двигаться(вашит слова). Стоит сделать наследника - и он уже КЛУБ? (ну чуть-чуть подправиив логику?) А вас не смущает что клуб и тот класс который едет имеют мало общего (даже из вашего описания).
Если я вас понял (если нет поправьте) - то вы предлагаете например написать класс "УСТРОЙСТВО БЕЗОПАСНОСТИ" - которое унаследовано от базовго виртуального класса (вроде того самого который умеет ездить через указание параметров скрипта) и потом делаем класс КЛУБ, САУТ, САВП его наследниками?. Так вот - я был на этом пути и заметил что КЛУБ, САУТ, САВП имеют столько же общего как и "двигатель" и "кран машиниста". Они имеют общее название - но работают по разному - у каждого своя логика, базовый класс для них и получился на уровне "базовое вагонное устройство". А много ли общего у "Крана 395" и "Крана 254" - они подключаются к магистралям - внутри какие-то поршни - и все. Но работают совершенно по разному, неужели их тоже делать на уровне базового класса "Базовый кран машиниста". Аналогично ВР-ры. Тут вдруг появляется мысль - о "Базовое пневматическое устройство" - все его наследники - краны, ВР-ы и т.д. "Базовое электрическое устройство" - его наследники "двигатель, фаз-тель или что-то еще". И соответственно разнести функциональность по этим базовым классам. И тут вдруг надо сделать "Пневматический контактор" - который 100% пневмоустройство и 100% электроустройство - делаем двойное наследование? Мало того - в каждом из 2-х предков еще и предок "Виртуальное устройство которое может ездить скриптом" - нам будет палки в колеса совать. А если часть методов была одинаковой - даже простые - типа "setWagonNum()" - как быть? Какой из двух методов предков вернее использовать?
Согласен так и делаю пока не потребуется задать для него неисправность - а это фактически добавить пару трпойку свойств - не логичнее чтобы св-ства объекта хранились в нем самом.
К примеру, класс Светофор может быть наследником класса Путевой объект, наследника MeshObject, впрочем, это детали.
По-моему, такая архитектура полностью вписывается в твои пункты, при этом обладая большим потенциалом по расширяемости, и решает проблему обособленности других объектов.
Очень хороший пример - только доказывает проблему вашей концепции а не моей - смотрите сами - я обращаюсь через свойства, и не знаю "Класс ЭПК другого вагона" - если у того нет такого свойства к которому я обращаюсь, или он с ним не работает -то в моей структуре - как я и говорил уже несуществующее свойство создасться, работать правильно не будет и все. А в вашем случае вы просто не сможете написать Клуб который будет работать с "ЭПК программиста Пети" на другом вагоне. Т.к. Программист Петя не дал вам исходник своего ЭПК и компилятор не может осуществить контроль типов и т.д. А если вы скомпиляете со своим классом ЭПК - а подсунете класс ЭПК Пети - то здесь то и возможны проблемы вылета из игры.. Это и есть пример демонструрующий выгодность обособленности объектов. Кроме того далеко не все захотят делиться исходниками - а вот сказать какимим свойствами нужно пользоваться для правильной работы и выложить скомпиленную DLL не проблема - вы же свободно обмениваетесь "скомпиленными" моделями 3D.
break писал(а):И через 5 страниц выясняется что все спорили с тем же, чем сами пользуетесь.
Ограничение аналогичны варианту с Моно — экспорт функций игры.
Возможно я переборщил с последствиями, но при программировании ПС приятнее видеть исключение и указанием номера строки, а не вылет из игры.
Я и хотел показать, что если программирование и есть, то оно декларативно по большей мере. Если интересует исходник, я могу прислать их все в ЛС, так как объем все же велик.
Вернуться в Другие ЖД симуляторы
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 8