Домашняя страница
Арго Фреймворк Википедия
Содержание
- Введение *
- Назначение и Основные Принципы Арго Фреймворка
- Архитектура Фреймворка
- Модуль Ядра (Кернел)
- Менеджер Приложений
- Менеджер Установки
- Сокет Приложений
- Плеер
- Менеджер Ресурсов
- Менеджер Данных
- Менеджер Файловой Системы
- Менеджер Событий
- Установка Фреймворка
- Приложения Фреймворка
Назначение и Основные Принципы Арго Фреймворка
Назначение Арго фреймворка - это создание насыщенного графического пользовательского интерфейса с минимальными затратами времени на разработку. Также, фреймворк требует минимальных затрат ресурсов системы для отображения и управления пользовательским интерфейсом. Фреймворк разрабатывается как мультиплатформенное решение и способен работать на различных операционных системах и аппаратных платформах. Требования к операционной системе минимальны: Наличие дисплея и соответствующих драйверов, наличие системы пользовательского ввода (сенсорный экран, мышь, клавиатура и т.д.) и возможность получать события от этих устройств. Фреймворк позволяет реализовать пользовательский интерфейс на устройствах в условиях очень ограниченных ресурсов по быстродействию процессора и оперативной памяти.
Основные архитектурные принципы определяют мультиплатформенность фреймворка, адаптивность к различным областям применения, отказоустойчивость системы на базе фреймворка и многие другие свойства. К основным принципам относятся использование языка “Си” вкупе с компонентной объектой моделью (COM - Component Object Model). Это позволяет сделать весьма компактный и удобочитаемый код с минимальным количеством ошибок. Отдельные модули могут быть глубоко протестированы автоматическими тестами с целью выявления багов и обеспечения масимального кодового покрытия (Line Coverage).
Вторым базовым принципом фреймворка является отказ от использования каких либо стандартных заголовочных файлов и стандартных библиотек в коде ядра фреймворка и сопутствующих библиотек. Все внутренние операциии производятся исключительно средствами фреймворка. Общение с операционной системой выполняется через специальный интеграционный уровень (Integration Layer) который транслирует вызовы ядра в вызовы операционной системы или стандартных библиотек. Интеграционный уровень обеспечивает адаптацию фреймворка к операционной системе. Основная адаптация долна быть выполнена для отрисовки фреймбуфера на дисплее и получениея событий пользовательского ввода. Остальная часть интеграционного уровня написана с использованием POSIX стандарта и требуются лишь минимальные изменения на разных ОС.
Основной возможностью фреймворка является полноценный уровень приложений, который позволяет предустанавливать некий набор приложений, устанавливать новые в процессе работы или удалять ранее установленные приложения. Разумеется, уровень приложений отвечает за запуск приложений (автоматически или по вызову от пользователя), взаимодействие приложения с подсистемами фреймворка, выгрузку или перевод приложения в фоновое состояние.
Второй основной возможностью является поддержка нескольких дисплеев на уровне ядра фреймворка (Количество дисплеев не ограничивается). Разумеется, при этом требуется поддержка дисплеев и на интеграционном уровне. В терминах фреймворка дисплеем может считаться любое устройство ввода/вывода: физический дисплей, сенсорная панель (touch pad), клавиатура. Это позволяет легко настраивать фреймворк под различные конфигурации оборудования и обрабатывать события от него унифицированным методом. Например, мы хотим использовать клавиатуру как некий виртуальный дисплей (Это не обязательно, конечно. Фреймворк может получать события от клавиатуры напрямую). Все кнопки при этом представляюся как некие “пикселы” в матрице. Нажатие на кнопку будет интерпретировано как некое событие эквивалентное нажатию на сенсорный экран. Такие события перенаправляются фреймфорком в приложение-сервис, которое обслуживает события в этом виртуальном дисплее и трансформирует их в стандартные события соответствующие нажатию кнопок - по сути так работает и виртуальная клавиатура отображаемая на физическом дисплее.
Каждый дисплей содержит один или несколько виртуальных суб-дисплеев. Виртуальными они являются потому что не содержат физической памяти для отрисовки изображений и определяют лишь границы в которых будет отрисовываться окно приложения привязанное к этому суб-дисплею. Суб-дисплеи могут занимать все пространство дисплея или только часть его, перекрываться друг с другом. Основное назначение суб-дисплеев - это определение приоритетов окон приложений. Например, на экране присутствует приложение с нормальным приоритетом (приоритетом по умолчанию). В этот момент происходит некое событие которое вызывает запуск системного предупреждения и на экране должно отобразится соответствующее окно. Это окно будет запущено в высоко приоритетном суб-дисплее который полностью перекрывает суб-дисплей с нормальным приоритетом. В результате окно предупреждения перекроет текущее приложение и оно будет недоступно до тех пор пока пользователь не отреагирует на это предупреждение. Любой высокоприоритетный суб-дисплей прозрачен если в нем нет активированных окон и становиться непрозрачным как только в нем активируется привязанное к нему окно. Этот механизм позволяет очень легко управлять приоритетами окон.
Помимо конфигурации интеграционного уровня фреймворк обеспечивает еще несколько механизмов конфигурирования. Первый, конфигурирование начальных стартовых параметров через специальный файл или через переменные окружения или опции командной строки запуска. Эти механизмы имеют свои приоритеты: параметры установленные в конфигурационном файле могут быть переопределены переменными окружения, те-же в свою очередь, могут быть переопределены параметрами командной строки. Второй механизм - это конфигурационное XML описание, это основной механизм. Какое конфигурационное описание будет использовано определяется стартовыми параметрами. Конфигурационное XML описание определяет все параметры системы: дисплеи и их размеры, виртуальные суб-дисплеи; графические и прочие ресурсы системы (точнее определяет файлы в которых ресурсы описаны); системные базы данных для хранения каких либо параметров/переменных; список предустановленных приложений и их параметры; пути к файловым системам, которые доступны приложениям; стили окон приложений и доступные языки системы. Также в описании могут быть переопределены некоторые глубинные параметры системы - это третий механизм конфигурации системы. Конфигурационные параметры содержат некоторые значения по умолчанию и используются при старте системы: определяют размеры внутренних буферов или глубину очередей для передачи событий - т.е. позволяют производить тонкую настройку системы. Значения по умолчанию могут быть переопределены в системном XML описании.
Архитектура Фреймворка
На самом верхнем архитектурном уровне фреймворк состоит из следующих компонент: библиотека ядра фреймворка, модуль системы (Там по сути только функция main()), библиотеки интеграционного уровня и набор вспомогательных библиотек (библиотека для формирования бинарных файлов и их загрузки, библиотеки приложений, библиотека для отрисовки графики, библиотека для управления оперативной памятью и некоторые другие).
Библиотека ядра фреймворка состоит из двух частей: Собственно операционное ядро системы и SDK библиотеки. Операционное ядро выполняет все операции внутри фреймворка за исключением парсинга XML описаний. Большая часть обработки сосредоточена непосредственно в ядре, но некоторые процедуры вынесены в сопутствующие библиотеки, перечисленные выше. SDK библиотека предназначена для парсинга XML описаний, проверки корректности описаний и формирования внутреннего бинарного описания. Бинарное описание используется ядном и может быть выгружено в бинарный файл. Такой бинарный файл далее может использоваться вместо XML описаний. SDK версия фреймворка содержит обе эти части и поэтому может использовать XML описания на этапе разработки. Продуктовая версия не содержит SDK библиотеки и поэтому может использовать только подготовленные бинарные описания. Бинарные описания обеспечивают большой выигрыш по времени загрузки по сравнению с XML (загрузка в десятки раз быстрее) поэтому использование XML в конечном продукте нецелесообразно. Исходный код компонентов ядра недоступен в SDK и представлен в виде набора построенных библиотек.
Как уже упоминалось, модуль системы содержит только функцию main() и выполняет две основные и простые операции: создает экземпляр (объект) интеграционного уровня и производит вызов функции sysmain() ядра фреймворка. Реализация модуля системы зависит от OS (Например в Windows должна быть функция winmain()), поэтому код системного модуля открыт в SDK. По мере дальнейшего развития фреймворка модуль может быть усложнен, допустим система запускается под root пользователем, а фреймворк под другим. На данный момент, для SDK, рутовый пользователь для запуска не требуется.
Интеграционный уровень содержит некоторый набор библиотек: Основную (common) библиотеку для реализации необходимого фреймворку API за исключением механизмов ввода/вывода; библиотеку для реализации ввода/вывода - обслуживание дисплея и получения событий пользовательского ввода; библиотеку для логирования (logger); отдельные библиотеки для работы с сокетами и терминальным вводом/выводом - эти библиотеки не используются фреймворком и нужны только для SDK утилит фреймворка. Весь исходный код интеграционного уровня открыт и может модифицироваться разработчиком в соответствии с его запросами. Однако модифицировать API не позволяется, только его реализацию. Также, надо учитывать, что модификации могут вызвать сбой ядра фреймворка.
Ниже кратко рассмотрим основные модули операционного ядра фреймворка.
Модуль Ядра (Кернел)
Модуль ядра, или далее везде кернел, отвечает за запуск и выгрузку модулей ядра в определенном порядке и в соответствии с базовыми параметрами и конфигурационным описанием. По базовым параметрам он определяет где ему взять конфигурационное описание (XML или бинарный файл), получает бинарное описание системы (Через SDK библиотеку или через библиотеку загрузки бинарных файлов) и производит загрузку в соответствии с этим описанием. Когда фреймворк выгружается кернел производит выгрузку модулей в соответствии с заданным порядком.
Менеджер Приложений
Менеджер приложений предназначен для реализации всех операций связанных с запуском приложений, переводом приложений в фоновое состояние и обратно, закрытием приложений. Также он отвечает за взаимодействие приложения с графической подсистемой ядра и взаимодествие с другими модулями и с другими приложениями. Менеджер относится к приложению как к некоторой абстрактной сущности - он знает как его запустить, он может получать от него события и отправлять ему сообщения, у него есть информация активно приложение или нет. Вся эта информация сосредоточена в единой структуре экземпляра приложения и менеджер оперирует только этой информацией и иформацией сообщений. Для запуска приложения он получает начальную информацию от менеджера установки, создает структуру экземпляра приложения и запускает так называемый сокет приложения - собственно механизм общения менеджера с приложением. Также, в соответствии с установочной информацией, менеджер активирует графическую подсистему для отрисовки окон приложения. Выгрузка приложения выполняется удалением структуры экземпляра из списка запущенных приложений и последующей выгрузкой сокета и окон приложения (делается автоматически при удалении из списка).
Менеджер Установки
Менеджер установки отвечает за сохранение параметров приложения при их установке и удалением установочной записи если приложение удалено. Приложения разделяются на предустановленные или иначе системные, т.е. прописанные в системной конфигурации и размещенные на файловой системе по определенным правилам (Core applications) и на пользовательские, установленные по запросу от пользователя (User applications). Существует три главных и единственных отличия между этими группами: Системные приложения не могут быть удалены, системные приложения могут иметь специальные привилегии доступа к подсистемам фреймворка, пользовательские приложения имеют ограничения в многодисплейной системе (только основной и выделенный суб-дисплей могут использоваться по умолчанию). При установке нового приложения менеджер добавляет информацию в специальный файл и она будет далее доступна даже после перезагрузки системы. По запросу от менеджера приложений установочная информация ему будет предоставлена для запуска приложения.
Сокет Приложений
Когда менеджер приложений запускает новое приложение он создает экземпляр сокета приложения. Сокет приложения в первую очередь отвечает за передачу событий от фреймворка к приложению (Downlink messages) и от приложения к фреймворку (Uplink messages). Сокет также отвечает за трансляцию событий в обоих направлениях (это некоторое преобразование изначального события - добавление или удаление служебной информации в зависимости от направления передачи). Также сокет создает экземпляр библиотеки приложения, которая непосредственно взаимодействует с приложением и предоставляет ему API для взаимодействия с фреймворком.
Плеер
Плеер это корневой модуль графической системы и предназначен собственно для отрисовки окон приложений, обработки пользовательского ввода (обработка событий с сенсорного экрана или событий от клавиатуры, например). Для каждого дисплея создается свой экземпляр плеера и он обслуживает все операции с данным дисплеем. Это крайне сложный модуль, который обслуживает все графические операции с окнами приложений:
- Поддерживает оконный стек и работу виртуальных суб-дисплеев.
- Обслуживает все встроенные виджеты (встроенные виджеты также легко кастомизуются, термин “встроенный” обозначает лишь то, что фреймворк знает как обрабатывать поведение таких виджетов) и выполняет все графические операции с такими виджетами (нажатие/отжатие кнопки, ввод текста в поле ввода).
- Поддерживает работу с кастомными виджетами используя специальные DLL для обработки поведения (в отличие от встроенных).
- Детектирует пользовательский ввод и отправляет в приложение соответствующие события (например нажатие или отжатие кнопки). Плеер имеет специальную архитектуру, которая позволяет легко добавлять новые встроенные виджеты в виде новых суб-модулей плеера.
Для отрисовки графических элементов плеер запрашивает графические ресурсы у менеджера ресурсов. Также плеер плотно взаимодействует с менеджером приложений: создание и удаление окон, передача сообщений в приложение и получение запросов от приложений. Окна приложений, графические виджеты создаются с использованием соответствующих XML описаний и после парсинга этих описаний обрабатываются плеером (Парсинг, как уже говорилось выше, выполняется SDK библиотекой).
Плеер выполняет отрисовки графических элементов в специальном фрейм буфере. Как только все операции с этим буфером завершены, плеер запускает механизм рендеринга дисплея - обновление содержимого экрана из этого фрейм буфера.
Менеджер Ресурсов
Менеджер ресурсов предназначен для управления различными типами графических ресурсов системы и отдельных приложений. В общем случае фреймворк использует идентификаторы ресурсов, прописанные в специальных конфигурационных XML файлах. Менеджер ресурсов обеспечивает:
- Загрузку ресурсных файлов с файловой системы в оперативную память, конвертацию различных файловых форматов во внутренний универсальный формат (плеер не может обрабатывать графические файлы в каком-либо формате, кроме этого внутреннего формата, поэтому, например, bmp файлы конвертируются в этот формат),
- Управение загрузкой/выгрузкой ресурсов по запросу от системы или приложения.
- Оптимизацию расхода оперативной памяти для ресурсных файлов. Например, если некий ресурс уже загружен в память и если этот ресурс потребуется другому приложению, то повторно он уже загружаться не будет, и менеджер просто отдаст ссылку на уже загруженный экземпляр ресурса. Разумеется, менеджер обладает всеми средствами для выгрузки и очистки ОП при выгрузке приложений и системы в целом.
Ресурсы находятся в двух доменах: системные ресурсы и ресурсы приложений. Системные ресурсы могут использоватся явно или неявно любыми приложениями (например, стиль окна по умолчанию - это неявное использование системных ресурсов). Напрямую системными ресурсами могут пользоватся только системные приложения. Пользовательские приложения могут использовать только стиль окна по умолчанию или обходиться собственными ресурсами. Ресурсы приложения могут использоваться только данным приложением, точнее, всеми экземплярами этого приложения.
Менеджер позволяет также создавать динамические ресурсы по запросу от приложения, например, для отображения пользовательских фотографий или пользовательских иконок.
Менеджер Данных
Менеджер данных предназначен для сохранения некоторых строковых или целочисленных данных для различных целей: обмена данными между приложениями, сохранения данных при перезагрузке системы, оповещения о событиях в системе и тому подобное. Другие типы данных (с плавающей точкой, массивы) пока поддерживаются не в полной мере.
По аналогии с менеджером ресурсов есть два домена для хранения данных: системные и данные приложений. Также, в целом, действуют и правила доступа к ним. Однако, есть и разница. Фреймворк создает две дополнительные базы данных - автоматическую и общую, это делается независимо от пожеланий разработчика системы.
Автоматическая база данных предназначена для хранения параметров системы, таких как количество дисплеев, язык системы и других внутренних данных. Переменные в этой базе имеют предустановленные имена (или формат имен) и доступны только для чтения системными приложениями. Пользовательские приложения читать их не могут. Разработчик системы может только сконфигурировать этот механизм, чтобы сохранять эти данные между перезагрузками системы или отключить это сохранение.
Общая база данных позволяет читать переменные любому приложению, но создавать и записывать переменные могут только системные приложения. Эти переменные, в первую очередь, предназначены для обмена данными между приложениями и посылки уведомлений. Общая база данных никогда их не сохраняет между перезагрузками системы.
Системные базы данных определяются в конфигурационном XML файле системы и предназначены для общей информации нужной системным приложениям. Пользовательские приложения к ним доступа не имеют. Системные приложения могут записывать, читать или включать для себя уведомления из этих переменных. Также переменные могут сохраняться на файловой системе.
Базы данных приложений доступны только приложению и могут быть использованы для обмена данными для нескольких экземпляров приложения. Также могут сохранятся данные которые нужны после перезагрузки системы.
Менеджер данных также поддерживает создание локальных баз данных по запросу от плеера. Эти данные создаются и используются плеером и недоступны извне.
Менеджер Файловой Системы
Менеджер файловой системы управляет доступом фреймворка и приложений к определенным директориям на файловой системе. Каждая такая директория представляется как некая виртуальная файловая система и так же будет отображаться в пользовательском интерфейсе. Список таких файловых систем определяется в конфигурационном XML файле.
Менеджер собирает информацию о файлах внутри таких директорий и предоставляет полную информацию по запросу от системных приложений. Пользовательские приложения эту информацию получить не могут (механизм еще не доработан, чтобы скрывать системные папки).
Менеджер создает две дополнительные виртуальные файловые системы:
- Систему для хранения системной информации (var), которая используется исключительно фреймворком для хранения внутренней информации (например, для хранения автоматической базы данных).
- Домашнюю папку (home) для размещения файлов приложений.
Создание и управление этими папками управляемо через системное XML описание.
Менеджер может получать и обрабатывать уведомления о подключении новых реальных файловых систем, например, USB флешки. При получении уведомления менеджер зарегистрирует такую файловую систему, и она будет доступна приложениям. Также он обеспечивает уведомление для подписанных приложений, что файловая система была добавлена или удалена. Уведомление о подключении/отключении может быть отправлено только системным приложением. Нотификация о состоянии файловых систем тоже может быть доставлена только системному приложению.
Менеджер Событий
Фреймворк является системой, которая реагирует только на события от пользователя или от приложений. Сам по себе никаких событий (events) он не генерирует. Но поступившие события должны быть обработаны быстро и правильно. Для этой цели существует менеджер событий, который отвечает за передачу сообщений между модулями системы.
Это довольно простой модуль, шутка… Сам по себе модуль весьма прост, но, в целом, механизмы внутреннего мессаджинга не так тривиальны. Все модули-менеджеры объединены в единую сеть, которую и поддерживает менеджер событий. Модуль-передатчик создает тело сообщения и отсылает по адресу/идентификатору того модуля, куда он сообщение передает. Адресация, выбор, пересылка и доставка ответа полностью лежат на менеджере событий. Сообщения могут быть синхронными, т.е. происходит прямой вызов интерфейсов вызванного модуля (это используется редко) или асинхронными, когда событие попадает в очередь на обработку, и вызывающий модуль не блокируется. В последнем случае модуль-передатчик сам должен позаботиться о том, чтобы получить ответ, если ему надо.
С точки зрения приложений эти внутренние механизмы могут повлиять только на быстродействие. Разработчик системы может ограниченно влиять на эти процессы через конфигурационные параметры (резервирование памяти для очередей событий, например). С точки зрения разработчика приложений таких механизмов вообще нет.