Created Kotatogram Settings: Quick developer reference (markdown)

Eric Kotato 2022-02-14 23:55:21 +03:00
parent 1e05bfd7d4
commit a418b8589f

@ -0,0 +1,241 @@
## Step 1: add setting to definition map
_File: Telegram/SourceFiles/kotato/kotato_settings.cpp_
Find the following:
```cpp
const std::map<QString, Definition, std::greater<QString>> DefinitionMap
```
and add new definition to it:
```cpp
{ "my_custom_setting", {
.scope = SettingScope::Global,
.storage = SettingStorage::MainJson,
.type = SettingType::BoolSetting,
.defaultValue = false,
.fillerValue = false,
.limitHandler = nullptr }},
```
- key (in this example `"my_custom_setting"`, `QString`): this is the name of option that will be used both in code and in JSON file.
- `scope` (`enum SettingScope`): `SettingScope::Global` will apply setting to all accounts, `SettingScope::Account` will apply to current account only. If not set, `SettingScope::Global` is assumed.
- `storage` (`enum SettingStorage`): `SettingStorage::MainJson` will save it to JSON settings file, `SettingStorage::None` can be used in app, but changes won't be saved. If not set, `SettingStorage::MainJson` is assumed.
- `type` (`enum SettingType`): values `SettingType::BoolSetting`, `SettingType::IntSetting`, `SettingType::QStringSetting`, `SettingType::QJsonArraySetting` resemble the types `bool`, `int`, `QString` and `QJsonArray`. If not set, `SettingType::BoolSetting` is assumed.
- `defaultValue` (`QVariant`): sets default value that will be used if it wasn't set earlier. Will be null if it's not set.
- `fillerValue` (`QVariant`): used in default settings file as an example. If not set, it will use `defaultValue`.
- `limitHandler` (`CheckHandler`, defined as `Fn<QVariant(QVariant)>`): this function takes user-provided value (`QVariant`) and returns filtered version of this value (`QVariant`). If it's `nullptr`, only basic type will be checked. If not set, `nullptr` is assumed.
### Handler generators
Some handler generator functions that you can use as an example or value:
```cpp
CheckHandler IntLimit(int min, int max, int defaultValue)
```
`IntLimit` generates handler that sets number to `min` if it's lower than `min`, and sets number to `max` if it's higher than `max`. If value can't be converted to `int`, sets it to `defaultValue`.
---
```cpp
inline CheckHandler IntLimit(int min, int max)
```
Same `IntLimit` as previous one, but uses `min` instead of `defaultValue`.
---
```cpp
CheckHandler IntLimitMin(int min)
```
Version of `IntLimit` that limits only from one side: it sets number to `min` if it's lower than `min`. If value can't be converted to `int`, sets it to `min`.
---
```cpp
CheckHandler ScalesLimit()
```
Handler generator used specifically in `"scales"` option. Limits array to 6 values, and scales to range from `style::kScaleMin` to `style::kScaleMax`.
---
```cpp
CheckHandler ReplacesLimit()
```
Handler generator used specifically in `"replaces"` option. Checks if sub-values are `QJsonArray`'s with two `QString` elements (from, to).
---
```cpp
CheckHandler FileDialogLimit()
```
Handler generator used specifically in `"file_dialog_type"` option. Converts integer values to Platform::FileDialog::ImplementationType enum.
---
```cpp
CheckHandler NetSpeedBoostConv(CheckHandler wrapped = nullptr)
```
Handler generator used specifically in `"net_speed_boost"` option. Maps string values (`low`, `medium`, `high`) to integer values. `wrapped` used as post-filter. In `"net_speed_boost"` it's used `NetSpeedBoostConv(IntLimit(0, 3))`.
## Step 2: use your option in code
First, you must include settings header file, if it's not included:
```cpp
#include "kotato/kotato_settings.h"
```
### Getting the value
To get the value, you can use this:
```cpp
::Kotato::JsonSettings::Get("my_custom_setting")
```
There are also two additonal parameters: account id (`uint64`, default is `0`, which means "all accounts"), and "is test server" (`bool`, default is `false`, but it is used only when account id is not `0`).
Example for account id `777` on test server:
```cpp
::Kotato::JsonSettings::Get("my_custom_setting", 777, true)
```
Example for account id `555` on production server:
```cpp
::Kotato::JsonSettings::Get("my_custom_setting", 555)
```
or
```cpp
::Kotato::JsonSettings::Get("my_custom_setting", 555, false)
```
Usually you don't need to set those by hand, these examples are just for demonstration.
### `Get` function caveat
There's the one caveat. `::Kotato::JsonSettings::Get`, returns `QVariant`, so to use it correctly you should use `QVariant`'s methods `.toBool()`, `.toInt()`, `.toString()` and `.toJsonArray()`, depending on type. You can also use shorthand methods:
```cpp
::Kotato::JsonSettings::GetBool("my_custom_setting"); // returns bool
::Kotato::JsonSettings::GetInt("my_custom_setting"); // returns int
::Kotato::JsonSettings::GetString("my_custom_setting"); // returns QString
::Kotato::JsonSettings::GetJsonArray("my_custom_setting"); // returns QJsonArray
```
Parameters are the same as in original `Get`, only difference is that shorthands return type you need.
### Setting the value
To set an option you can use a following method:
```cpp
::Kotato::JsonSettings::Set("my_custom_setting", true);
```
In that case true is the value (`QVariant`). `QVariant` will accept any supported value.
> **Warning!** `Set` is **not** doing type checks, so it's the developer responsiblity to use the correct type. You have been warned.
`Set` also supports account id and test server check parameters, explained in "Getting the value":
```cpp
::Kotato::JsonSettings::Set("my_custom_setting", true /* value */, 777 /* account id */, true /* is test server */);
```
Don't forget to save your options after you've changed them:
```cpp
::Kotato::JsonSettings::Write();
```
If called multiple times in short period of time, writing to file is delayed for 5 seconds to reduce file I/O operations, unless app is restarting.
### Resetting the value to default
To reset an option you can use a following method:
```cpp
::Kotato::JsonSettings::Reset("my_custom_setting");
```
Like with `Set`, account id and test server check parameters are also supported:
```cpp
::Kotato::JsonSettings::Reset("my_custom_setting", 777 /* account id */, true /* is test server */);
```
Don't forget to save your options after you've changed them:
```cpp
::Kotato::JsonSettings::Write();
```
### After-restart options
Some options must be applied only after restart, because there are too many dependencies to change it on the go.
To set an option after restart you can use a following method:
```cpp
::Kotato::JsonSettings::SetAfterRestart("my_custom_setting", true);
```
`Reset` also has `AfterRestart` version:
```cpp
::Kotato::JsonSettings::ResetAfterRestart("my_custom_setting");
```
Note that `Get` method (along with shorthands) will return the value that was loaded on app start. If you want to know what value will be applied after restart, you can use `GetWithPending` method:
```cpp
::Kotato::JsonSettings::GetWithPending("my_custom_setting");
```
Note that it returns `QVariant` that is needed to convert. Instead of that, you can use shorthands:
```cpp
::Kotato::JsonSettings::GetBoolWithPending("my_custom_setting"); // returns bool
::Kotato::JsonSettings::GetIntWithPending("my_custom_setting"); // returns int
::Kotato::JsonSettings::GetStringWithPending("my_custom_setting"); // returns QString
::Kotato::JsonSettings::GetJsonArrayWithPending("my_custom_setting"); // returns QJsonArray
```
Account id and test server check parameters are also supported in all these methods.
### RPL
TDesktop heavily relies on self-written RPL library. This library allows to listen to events, and do actions in widgets after they're triggered.
While RPL itself is out of scope of this page, there are methods that you can use.
---
```cpp
::Kotato::JsonSettings::Events("my_custom_setting") // returns rpl::producer<QString>
```
This method, combined with, for example, `rpl::start_with_next`, will allow to run actions after it's changed. Actual implementation may be harder, so it's better to study code that already uses RPL. Also note that QString is not a value: it's a combined settings map key. Value should be obtained yourself by calling `Get` or `GetWithPending` (or their shorthands).
`Events` also supports account id and test server check parameters, explained in "Getting the value":
```cpp
::Kotato::JsonSettings::Events("my_custom_setting", 777 /* account id */, true /* is test server */);
```
---
```cpp
::Kotato::JsonSettings::RestartEvents() // returns rpl::producer<bool>
```
Triggers when `SetAfterRestart`/`ResetAfterRestart` is used. Contained value shows if restart is needed: `true`: needs restart, `false`: doesn't need restart.
> This function is currently unused and may be changed or removed.