Просмотр полной версии : [Вопрос] Проверка существования инклуда
По очереди подключены 2 инклуда. Как в верхнем проверить существование нижнего, а в нижнем - верхнего, через директивы? Чтобы без посредника.
Не думаю, что директивами нормально получится сделать проверку существования нижнего инклуда в верхнем, так как препроцессор всего раз проходит по скрипту, как я знаю. Хотя вообще непонятно зачем это. Достаточно просто в нижнем проверять существование верхнего, а в верхнем всё объявлять через stock, чтоб если нижний инклуд исчез, то и код верхнего сам по себе "отключался".
Ну так же, как вариант - создать функцию в каждом инклуде и вызывать функцию одного инклуда в другом. Будет ошибка о том, что функции нет - инклуд не подключён :D Хотя можно просто ошибку выдавать не при компиляции, а при запуске сервера, например, объявляя в инклудах GVar, а потом проверяя их наличие
В верхнем:
#if defined PROTOCOLS
GivePlayerProtocolPoints(playerid, PROTOCOL_MANAGER, 5);
#endif
В нижнем:
#if defined BIGMONEY
pvar = GetPVarInt(playerid, !"BigMoneyPlayer");
#endif
Я говорю о чём-то таком
https://i.imgur.com/boFDOWw.png (https://i.imgur.com/boFDOWw.png)
Или таком
/*
Инклуд 1
*/
public OnGameModeInit()
{
SetSVarInt("CheckInc1", 1);
SetTimer("@_CheckInc", 5000, false);
#if defined checkinc1_OnGameModeInit
return checkinc1_OnGameModeInit();
#else
return 1;
#endif
}
#if defined _ALS_OnGameModeInit
#undef OnGameModeInit
#else
#define _ALS_OnGameModeInit
#endif
#define OnGameModeInit checkinc1_OnGameModeInit
#if defined checkinc1_OnGameModeInit
forward checkinc1_OnGameModeInit();
#endif
@_CheckInc();
@_CheckInc()
{
if(GetSVarType("CheckInc2") == SERVER_VARTYPE_NONE)
{
//Второй инклуд не подключён
}
DeleteSVar("CheckInc1");
DeleteSVar("CheckInc2");
return;
}
/*
Инклуд 2
*/
public OnGameModeInit()
{
if(GetSVarType("CheckInc1") == SERVER_VARTYPE_NONE)
{
//Первый инклуд не подключён
DeleteSVar("CheckInc1");
DeleteSVar("CheckInc2");
}
else
SetSVarInt("CheckInc2", 1);
#if defined checkinc2_OnGameModeInit
return checkinc2_OnGameModeInit();
#else
return 1;
#endif
}
#if defined _ALS_OnGameModeInit
#undef OnGameModeInit
#else
#define _ALS_OnGameModeInit
#endif
#define OnGameModeInit checkinc2_OnGameModeInit
#if defined checkinc2_OnGameModeInit
forward checkinc2_OnGameModeInit();
#endif
Если нужного инклуда нет, часть код связанная с ним условно будет в памяти.
Во-первых, это никакой особой погоды не сделает (ты же не на калькуляторе собрался сервер запускать).
Во-вторых, в моих вариантах подразумевается, что ты вырубаешь сервер через SendRconCommand("exit"), если инклуд не найден.
Хотя всё ещё не вижу в этом большого смысла. Паблик-моды и с большими проблемами существуют, работая, при этом.
Daniel_Cortez
29.11.2018, 13:09
Не думаю, что директивами нормально получится сделать проверку существования нижнего инклуда в верхнем, так как препроцессор всего раз проходит по скрипту, как я знаю.
Компилятор проходит по скрипту как минимум 2 раза. Первый проход нужен в основном для того, чтобы собрать информацию обо всех глобальных идентификаторах (переменных, функциях, константах). Кроме того, на 1-м проходе возникает много ошибок (например, когда функция где-то вызывается, но ещё не объявлена/реализована), но все они подавляются и не выводятся в консоль.
Сама же компиляция происходит на 2-м проходе, когда компилятор уже один раз "просмотрел" содержимое скрипта и знает о существовании всех констант/переменных/функций. Как пример, именно за счёт такого принципа работает оператор defined, которым можно проверить существование функции до её объявления (что часто можно увидеть при перехвате функций).
Так какой выход из ситуации?
Daniel_Cortez
29.11.2018, 13:31
В верхнем:
#if defined PROTOCOLS
GivePlayerProtocolPoints(playerid, PROTOCOL_MANAGER, 5);
#endif
В нижнем:
#if defined BIGMONEY
pvar = GetPVarInt(playerid, !"BigMoneyPlayer");
#endif
ИМХО, по-хорошему таких ситуаций с перекрёстными ссылками не должно быть, проблема здесь именно в проектировании. Как вариант, можно указанные вами части кода "двойного назначения", т.е. которые работают и с серверными деньгами, и с протоколами, вынести в третий инклуд.
ИМХО, по-хорошему таких ситуаций с перекрёстными ссылками не должно быть, проблема здесь именно в проектировании. Как вариант, можно указанные вами части кода "двойного назначения", т.е. которые работают и с серверными деньгами, и с протоколами, вынести в третий инклуд.
В первом посте написал:
Чтобы без посредника.
- - - Добавлено - - -
#include <SFCR/player/protocols.inc>
#include <SFCR/player/bigmoney.inc>
В первом объявить директиву PROTOCOL_SET_BIGMONEY, и через нее проверять сам protocols и bigmoney
Powered by vBulletin® Version 4.2.0 Copyright © 2024 vBulletin Solutions, Inc. All rights reserved. Перевод: zCarot