From f833549c454be9a588d0f1441e3d4ee8d0195891 Mon Sep 17 00:00:00 2001 From: Jiri Kalvoda <jirikalvoda@kam.mff.cuni.cz> Date: Fri, 12 Aug 2022 19:01:31 +0200 Subject: [PATCH] Add Developer documentation --- README.md | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 87 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3178247..b6ead55 100644 --- a/README.md +++ b/README.md @@ -10,8 +10,6 @@ (c) 2022 Jiri Kalvoda <jirikalvoda@kam.mff.cuni.cz> -=================================================================== - This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -33,3 +31,90 @@ User documentation See output of `i3csstatus -h` and documented configuration file at `sample.conf`. + +Developer documentation +======================= + +Overview +-------- + +Main class of the program is `RootStatusBar`. This class will parse the configuration and then it start main loop. +Main loop is responsible for constructing status bar and printing it. Output formats are defined in `RootStatusBar` +sub classes. Waiting for print the status bar could be interrupted from other threads. + +Status bar block +---------------- + +Each state of the status bar is a sequence of blocks. +Blocks correspond almost one to one to i3bar blocks. +See i3bar protocol documentation: +<https://i3wm.org/docs/i3bar-protocol.html> +In addition to i3bar block there is `OnClick` member. +You can store there a function which will be called when somebody +clicks on the buttton. Function will receive `ClickEvent` as its only argument. +Note that this function can be called from a different thread. +Please write it thread safe. + +Modules +------- + +A module is responsible for preparing part of the status bar. +It can handle more than one block (or zero blocks if the module should be hidden). + +It should be easy to add your own modules. +Before that please check that any of the next possibilities is not better for your use case: + + - Write some extra program and then use exec module with some parser + For some of languages (As python or bash) you can write program directly in config. + - Write only parser, not whole module + Good if you want read some file / pipe / HTTP API and then process it. + Your parser will be available for all modules using parsers. + +A module must implement `Module` interface and have `[ModuleName(string)]` attribute. +Any other registration is not needed. + +You can configure and prepare module via `Init` function. +This function receives a part of configuration file and `ModuleParent` object (see below). + +On `Get` method the module should return a list (exactly `IEnumerable`) of Blocks to show. +Note that the return value should be immutable! + +It is possible to use `ModuleParent` to schedule next render of the status bar +(Schedule method). This function is thread safe. + +For module cooperation it is possible to use `ModuleParent.GetGlobal<T>`. +It will return an instance of `T` shared across all modules in status bar. +`T` should implement `GlobalModuleResource` interface. There are methods +which are called before and after status bar initialization and generation. +For excepted behavior it is important to call `GetGlobal` from `Init`. + +It is possible to create a bar as a part of the module. +See `InnerStatusBar` class and usage. It is a viable option to +show some user specified constant blocks. + +Parsers +------- + +Parser is an object for translating string to a part of the status bar. +It is often used as part of modules fetching some text. +Normally parsers share part of configuration file with the module. + +If module uses is multithreaded, it must call parser from the main thread for each `Get`. +Parse could have different output for the same text (for example based on current time). + +Each parser must implement `Parser` interface. +If the parser is allowed to be used in the configuration file by typing its name +then it must have `[ParserName(string)]` attribute. + +Parser can be configured via `Init` function. In such case, it must return part of bar on each call of `Parse` method. + +Output formats +-------------- + +Each format is represented as `RootStatusBar` subclass. +It must implement `format(TextWriter w, List<Block> elements)` method, +which outputs `elements` to `w`. + +Configuration of the output formats is done using command line arguments. +Configuration file must be output independent. +For adding an output format you need to add new `Command` in the `Program.Main` function. -- GitLab