А как же Reference Counting?
Вместо глобальных переменных система, которая сама считает ссылки. В SourceMod autoexecconfig.inc
Создаем хранилище счетчиков
Глобальный StringMap, который хранит, сколько раз была зарегистрирована каждая библиотека.
Код
static StringMap g_hLibReferences;
public void OnPluginStart()
{
g_hLibReferences = new StringMap();
}
Гибкий обработчик событий
Код
void OnLibraryChange(const char[] name, bool bAdded)
{
int iRefCount;
if (bAdded)
{
// Пытаемся получить текущий счетчик
if (g_hLibReferences.GetValue(name, iRefCount))
{
iRefCount++; // Увеличиваем на 1
}
else
{
iRefCount = 1; // Первое упоминание
// Библиотека появилась ВПЕРВЫЕ (реально полезно!)
OnFirstLibraryAdded(name);
}
g_hLibReferences.SetValue(name, iRefCount);
}
else
{
// Удаление: проверяем, что счетчик существует и больше нуля
if (g_hLibReferences.GetValue(name, iRefCount) && iRefCount > 0)
{
iRefCount--;
if (iRefCount == 0)
{
g_hLibReferences.Remove(name);
// Библиотека исчезла ПОЛНОСТЬЮ
OnLastLibraryRemoved(name);
}
else
{
g_hLibReferences.SetValue(name, iRefCount);
}
}
}
}
public void OnLibraryAdded(const char[] name)
{
OnLibraryChange(name, true);
}
public void OnLibraryRemoved(const char[] name)
{
OnLibraryChange(name, false);
}
Управление:
Код
// Проверка, доступна ли библиотека прямо сейчас
bool IsLibraryAvailable(const char[] name)
{
int iRefCount;
return (g_hLibReferences.GetValue(name, iRefCount) && iRefCount > 0);
}
// Ваши кастомные обработчики (заглушки)
void OnFirstLibraryAdded(const char[] name)
{
PrintToServer("[System] Library '%s' is now AVAILABLE (first registration)", name);
// Здесь можно безопасно подключать хуки или создавать ресурсы
}
void OnLastLibraryRemoved(const char[] name)
{
PrintToServer("[System] Library '%s' is now GONE (last unregistered)", name);
// Здесь можно чистить ресурсы, только когда они точно никому не нужны
}