PDA

Просмотр полной версии : [Вопрос] Проверка существования инклуда



m1n1vv
29.11.2018, 11:26
По очереди подключены 2 инклуда. Как в верхнем проверить существование нижнего, а в нижнем - верхнего, через директивы? Чтобы без посредника.

DeimoS
29.11.2018, 11:55
Не думаю, что директивами нормально получится сделать проверку существования нижнего инклуда в верхнем, так как препроцессор всего раз проходит по скрипту, как я знаю. Хотя вообще непонятно зачем это. Достаточно просто в нижнем проверять существование верхнего, а в верхнем всё объявлять через stock, чтоб если нижний инклуд исчез, то и код верхнего сам по себе "отключался".

Ну так же, как вариант - создать функцию в каждом инклуде и вызывать функцию одного инклуда в другом. Будет ошибка о том, что функции нет - инклуд не подключён :D Хотя можно просто ошибку выдавать не при компиляции, а при запуске сервера, например, объявляя в инклудах GVar, а потом проверяя их наличие

m1n1vv
29.11.2018, 12:04
В верхнем:

#if defined PROTOCOLS
GivePlayerProtocolPoints(playerid, PROTOCOL_MANAGER, 5);
#endif

В нижнем:

#if defined BIGMONEY
pvar = GetPVarInt(playerid, !"BigMoneyPlayer");
#endif

DeimoS
29.11.2018, 12:19
Я говорю о чём-то таком
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

m1n1vv
29.11.2018, 12:29
Если нужного инклуда нет, часть код связанная с ним условно будет в памяти.

DeimoS
29.11.2018, 12:52
Во-первых, это никакой особой погоды не сделает (ты же не на калькуляторе собрался сервер запускать).
Во-вторых, в моих вариантах подразумевается, что ты вырубаешь сервер через SendRconCommand("exit"), если инклуд не найден.

Хотя всё ещё не вижу в этом большого смысла. Паблик-моды и с большими проблемами существуют, работая, при этом.

Daniel_Cortez
29.11.2018, 13:09
Не думаю, что директивами нормально получится сделать проверку существования нижнего инклуда в верхнем, так как препроцессор всего раз проходит по скрипту, как я знаю.
Компилятор проходит по скрипту как минимум 2 раза. Первый проход нужен в основном для того, чтобы собрать информацию обо всех глобальных идентификаторах (переменных, функциях, константах). Кроме того, на 1-м проходе возникает много ошибок (например, когда функция где-то вызывается, но ещё не объявлена/реализована), но все они подавляются и не выводятся в консоль.
Сама же компиляция происходит на 2-м проходе, когда компилятор уже один раз "просмотрел" содержимое скрипта и знает о существовании всех констант/переменных/функций. Как пример, именно за счёт такого принципа работает оператор defined, которым можно проверить существование функции до её объявления (что часто можно увидеть при перехвате функций).

m1n1vv
29.11.2018, 13:22
Так какой выход из ситуации?

Daniel_Cortez
29.11.2018, 13:31
В верхнем:

#if defined PROTOCOLS
GivePlayerProtocolPoints(playerid, PROTOCOL_MANAGER, 5);
#endif

В нижнем:

#if defined BIGMONEY
pvar = GetPVarInt(playerid, !"BigMoneyPlayer");
#endif
ИМХО, по-хорошему таких ситуаций с перекрёстными ссылками не должно быть, проблема здесь именно в проектировании. Как вариант, можно указанные вами части кода "двойного назначения", т.е. которые работают и с серверными деньгами, и с протоколами, вынести в третий инклуд.

m1n1vv
29.11.2018, 13:40
ИМХО, по-хорошему таких ситуаций с перекрёстными ссылками не должно быть, проблема здесь именно в проектировании. Как вариант, можно указанные вами части кода "двойного назначения", т.е. которые работают и с серверными деньгами, и с протоколами, вынести в третий инклуд.

В первом посте написал:

Чтобы без посредника.

- - - Добавлено - - -


#include <SFCR/player/protocols.inc>
#include <SFCR/player/bigmoney.inc>

В первом объявить директиву PROTOCOL_SET_BIGMONEY, и через нее проверять сам protocols и bigmoney