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