.. _ref-first-step: Первые шаги в написании собственного приложения =============================================== Вы можете писать свои приложения для управления сетью. Введиение --------- Так как RUNOS написан на языке с++, то для эффективности приложения дописываются к существующему коду, то есть после написания вашего приложения вам придется пересобирать RUNOS. Предполгается, что вы хорошо владете языком C++ и `фреймворком qt `_. Так же полезны базовые знанияе утилиты `cmake `_. Все файлы, которые вы создаете вам необходимо указывать в подходящем CMakeList.txt, в соответсвии с тем в какой директории находится ваш модуль. После этого RUNOS будет компилироваться с вашими файлами. .. _ref-application: класс Application ------------------ Приложение в RUNOS это класс, который наследован от абстрактного класса Application, который объявлен в файле Application.hh: .. cpp:class:: Application : public QObject .. Вам надо будет перегразуить некоторые виртуальные функции для корректной работы (См. AIP Reference). Методы, необходимые для перегрузки : * .. cpp:function:: DependencyList Application::DependsOn(const Config& config) const Список приложений, от которых зависит ваше приложение. * .. cpp:function:: std::string Application::provides() const Уникальная строка, которая идентифицирует ваше приложение и может быть использовано остальными для получения доступа к вашему приложению. * .. cpp:function:: void Application::init(class Loader*) Метод, который инициализирует ваше приложение. Вам необходимо вставить макрос внутрь вашего класса (как в `Q_OBJECT `_), для того, чтобы ваш класс удовлетоврял необходимым требованиям : .. c:function:: SIMPLE_APPLICATION(your_klass, provides_val) your_klass -- Ваш класс. provides_val -- имя вашего класса. Данный макрос так же добавит в ваш класс статический метод ``get(Loader *)`` который позволит остальным приложениями получать доступ к вашему приложению. Например:: #include "Application.hh" #include "Loader.hh" class YourApp : public Application { SIMPLE_APPLICATION(YourApp, "your-application-name") public: void init(Loader*, const Config&) override; }; Инициализация ------------- .. cpp:function:: void Application::init(Loader* ,const Config&) Вам необходимо переопредилить данный метод, который вызывается при запуске контроллера, и приложение готово к инициализации, т.е. все зависимости готовы к старту. Данный метод должен реализовывать все связи вашего приложения с остальными приложением (Например `connect сигналов `_ или регистрации обработчиков) Пример:: #include "Common.hh" void YourApp::init(Loader *, const Config& ) { LOG(INFO) << "Hello World"; } Старт приложения ---------------- .. cpp:function:: void Application::startUp(Loader *) Данный метод вызывается, когда все приложения проиницилизированы. В нем вам необходимо выполнить все побочные эффекты вашего приложения, напиример прослушание портов. Пример:: #include "Common.hh" // For log void YourApp::startUp(Loader *) { LOG(INFO) << "All services inited"; } Регестрация приложения ----------------------- После того, как вы создали класс для вашего приложения, вам необходимо сообщить ядру контроллера о сущестовании вашего приложения. Для этого необходимо зарегестрировать ваше приложение с помощью макроса .. c:function:: REGISTER_APPLICATION(your_class, list_of_dependeces) your_class -- имя вашего класса. list_of_depenedeces -- Список, приложений, от которых заваисит ваше приложение. Последним необходимо указать ``""``. .. attention:: Данный макрос нельзя прописывать в заголовочном файле! .. warning:: Нельзя зацикиливать зависимости. Теперь будет создаваться объект вашего приложения, однако все еще не будут вызываться методы :cpp:func:`Application::init` и :cpp:func:`Application::startUp`, потому что контроллер не считает нужным запускать ваше приложение. Вам необходимо указать имя своего приложения в ``network-settings.json`` в списке ``services``, чтобы ваше приложение запустилось. После этого ваше приложение запуститься и может управлять сетью. Loader ------ .. cpp:class:: Loader Методы :cpp:func:`Application::init` и :cpp:func:`Application::startUp` принимают как парметр указатель на :cpp:class:`Loader`. :cpp:class:`Loader` это загрузчик приложений, который и инициализирует ваши приложения. .. cpp:function:`Application* Loader::app(std::string interface)` Данным методом можно получить указатели на стороние приложения. interface -- имя стороннего приолжения. Вы можете получать объекты других приложений с помощью статического метода ``get`` этих приложений, и передав им :cpp:class:`Loader` как аргумент. Например:: #include "Controller.hh" #include "Loader.hh" #include "SwitchConnection.hh" #include "Common.hh" REGISTER_APPLICATION(YourApp, {"controller", ""}) ... void YourApp::init(Loader *loader, const Config& ) { Controller *ctrl = Controller::get(loader); QObject::connect(ctrl, &Controller::switchUp, [](SwitchConnectionPtr conn, of13::FeaturesReply fr) { LOG(INFO) << "This is SWITCH!!!!"; };) } .. attention:: Добавляйте приложения, которые вы используется в список зависимостей! Это гарантирует, то что эти приложения будут проиницилизированы. .. .. note:: Чтобы ваше приложение имело хоть какую-нибудь практическую пользу, вам придется взаимодействовать с другими приложениями, чтобы от них узнавать о событиях в сети. Работа с конфигурационным файлом -------------------------------- Ваше приложение может считывать настройки из конфигурационного файла. .. cpp:type: json11:Json::object Config С помощью этого класса, вы можете считываать настройки из файла ``network-settings.json``. .. cpp:function:: Type config_get(const Config& config,\ const std::string& key,\ const Type& defval) Считать из файла настроек ``network-settings.json`` значение по ключу. Если данный ключ не найдет, будет возвращен defval. На данный момент поддерживаются следующие типы : * ``std::string`` * ``int`` * ``double`` * ``bool`` .. cpp:function:: Config config_cd(const Config& config,\ const std::string& key) получить описание объекта json по ключу. Дополнительные возможности см в `документации по json11 `_.