[ AmberSkyNet VR ]

После того, как загрузка Engine была отделена от загрузки плагинов в отдельный модуль (EngineStarter) системе плагинов оказалось грузить соверешнно нечего.
Но сейчас мы исправим этот недостаток написанием модуля лог-файла. Заодно продемонстрирую как просто добавлять новые классы менеджеров при подобной архитектуре - интерфейс IEngine остаётся практически без изменений :), а также как просто включать и настраивать различные менеджеры логов используя ini-файл.

ILog

Лог-файл может использоваться многими классами, поэтому для начала к нему пишем интерфейс. Ну, примерно вот такого вида:


class ILog {
public:
// обычное сообщение кидаем в лог-файл
virtual void LogMsg(const std::string& Msg)=0;
// вывод в специальный лог - требуется указать имя лог-файла
virtual void ExtLogMsg(const std::string& LogName, const std::string& Msg)=0;
// сообщение об ошибке, level - уровень ошибки
virtual void ErrMsg(int level,const std::string& Msg)=0;
};

CLog, CLogNo

Реализация класса логов CLogNo - заглушка, никуда ничего не выводящая.
Столкнулся с такой ситуацией, когда демка, созданная на предыдущей версии движка (AmberSkyNet-3000) была записана на CD и по идее должна запускаться с него. Но она не запускалась, т.к. запись в папку logs на CD была невозможна, а класс логов не был вынесен в отдельную dll, как здесь. Поэтому всё вываливалось (хорошо, была запись не на CD-R а на CD-RW) Пришлось на скорую руку писать инсталлятор (обошёлся обычным RAR-SFX).

Реализация класса логов СLog - уже нормальный менеджер логов, выводящий сообщения в текстовые файлы.
Конструктор CLog (на вход которому подаётся указатель на IEgine) читает из IEngine путь к папке логов (переменная окружения [Paths]LogPath) и пытается создать там файл с названием YYYYMMDDHHMiSS.log, где YYYYMMDDHHMiSS - это текущие ГодМесяцДеньЧасМинутаСекунда. Это имя файла он заносит в переменную окружения [LogManager]LogName.

Еще конструктор CLog читает из переменных окружения значения [LogManager]ShowTime - надо ли к сообщениям в лог добавлять время, когда они были записаны, и [LogManager]ErrorLevel - уровень вывода ошибок. Например, если уровень вывода задан в 9, то ошибки 8-го уровня будут заноситься в лог-файл, а 10-го - нет. Меняя эти значения в ini-файле мы можем разнообразить вид лога без перекомпиляции исходников :)

Плагин asnLog реализует генератор классов CLog и CLogNo, о чём говорит строчка

GeneratorInfo.type="LogTxt,LogNo";
в исходниках asnLog.cpp. При вызове функции класса-генератора GetClass() с параметром "LogTxt" будет создан экземпляр класса CLog, а при параметре "LogNo" - экземпляр класса CLogNo.

Engine после разбора ini-файла читает значение переменной окружения [Modules]LogManager, в которой хранится имя класса лог-файла, который будет использован при текущем старте движка, и вызывает у менеджера плагинов функцию GetClass() с этим параметром, надеясь получить от него указатель на созданный экземпляр класса такого типа. Полученный указатель запоминается в указателях окружения с именем "LogManager", получить извне доступ к нему можно например вот так:

(ILog*)ENGINE->GetPtrParam("LogManager");
или воспользоваться макросами, определёнными в файле ILog.h :)
LOGGER->LOG("Тестовое сообщение в лог-файл");
, но при этом каждый раз в указателях окружения будет искаться указатель на экземпляр класса менеджера логов, что, возможно, не есть хорошо - это небольшой недостаток подобной архитектуры :) Отказаться от поиска можно, если в Engine хранить указатель на менеджер логов в отдельной переменной, а получать его вызовом функции GetLog()...

Подключение менеджеров

А теперь - насколько просто включать различные менеджеры логов (да и не только логов) при такой архитектуре:
Если в ini-файле в разделе [Modules] задать например вот так:

...
[Modules]
...
LogManager=LogTxt
...
то Engine, прочитав данную строчку подаст на вход менеджеру плагинов параметр "LogTxt" получит от него указатель на экземпляр класса CLog.
Если нам надо вообще отключить лог - пользуемся классом-заглушкой CLogNo, написав в ini-файле строчку:
...
[Modules]
...
LogManager=LogNo
...
Тогда Engine примет как менеджер логов экземпляр класса-заглушки CLogNo и логов у нас вестись не будет. Причём создаваемые экземпляры классов менеджера логов видны как интерфейсный класс ILog, их внутреннее строение от всех скрыто.

Можно будет написать также и менеджеры логов в HTML или XML. Причём имеется возможность вынести их в отдельные плагины, "обвязав" соответствующими классами-генераторами.

Адаптация под Linux

После 4го шага и до начала 5го проведена небольшая адаптация движка под Linux (проверялась на ASP Linux 11), поэтому в исходниках появилась папка CMake - для работы утилиты cmake в Linux. Пользовать СMake просто - в папке CMake запускаем эту утилиту следующим образом :

>cmake .
После чего в случае успешной обработки файла CMakeLists.txt будет создан make-файл, который обработаем обычным образом - набрав в консоли команду:
>make all
Исходники 5го шага под Linux пока не компилил ;)

Изменения в исходниках

include/: Добавлен интерфейс к менеджеру логов ILog.h

src/asnCommon/: В файле утилитарных функций добавлены функции StrToInt (инлайновая :) и IntToStr

src/asnMain/: демонстрация работы лог-файла

src/asnLog/: Новый (а вообще-то первый, т.к. asnEngine.dll грузится по-особому) плагин!

Исходники этого шага выложены в SVN. Скачать их можно набрав команду:

svn co https://svn.sourceforge.net/svnroot/ambernet/tags/AmberSkyNet-0.5 ambernet_0.5
Powered by: SourceForge.net Logo