TheLeftExit
Участник
- 35
- 15
Как "правильно" читать чат? Мне нужно читать все входящие строки (я их добавляю в вектор-очередь, и затем обрабатываю в другом коде), и иногда строки не регистрируются. У меня впечатление, что игра пишет чат в каком-то другом потоке, и она может это делать пока выполняется мой код из SF-ного mainloop. Проблема была заметнее когда мой код работал прямо с буфером из
SF->getSAMP()->getChat()->chatEntry
, и стала полегче (но всё равно проявляется) когда я начал копировать буфер в массив и работать с массивом.
C#:
// Вызывается внутри mainloop (SF->initPlugin(&mainloop, hModule))
internal static async void StartChatLoop()
{
var chat = new ChatEntry[100]; // stChatInfo::stChatEntry[100]
var lastEntry = default(ChatEntry); // Инициализируем stChatInfo::stChatEntry нулями
while (true)
{
SFCore.GetChat() // SF->getSAMP()->getChat()->chatEntry;
.CopyTo(chat); // Копируем в локальный буфер, на случай если соседний поток начнёт писать пока мы читаем
for (int i = 99; i > 0 && !chat[i].Equals(lastEntry); i--) // .Equals сранивает побитно
{
var entry = DecodeEntry(chat[i]);
_entryStack.Push(entry);
}
while (_entryStack.Count > 0)
{
var entry = _entryStack.Pop();
SFDebug.Log(entry.Text ?? "<empty>"); // Сюда попадают не все строки; пропускаются по одной либо по две
foreach (var queue in _queues)
{
queue.Enqueue(entry);
}
}
lastEntry = chat[99]; // Сохраняем последний элемент, чтобы в следующий раз читать строки до него, не включительно
await Task.Yield(); // Дальнейший код выполняется в следующем вызове mainloop, локальные переменные сохраняются
}
}