nlve/tests/progress/progtest.lpr
4aiman 44c0a5de24 Показатель работы: число и полоса показывают одно и то же
Полоса ползла по догадке, а подпись показывала замер — и человек видел
полосу, заполненную на девять десятых, рядом с нулём процентов. Что в
этот момент происходит, по такой паре понять нельзя.

Теперь доля одна на обоих. Берётся она у самого ffmpeg: сборка участка с
затуханием идёт минуту и дольше, а «кусок 1 из 1» всё это время не
меняется, поэтому ffmpeg спрашивают ключом -progress, докуда он дошёл.
Пока он не ответил ни разу, полоса трогается с места на пару процентов и
там стоит — пустая полоса и есть правда о только что начатой работе.

Догадка заодно перестала закрывать промежуток до вехи целиком: предел —
девять десятых, остаток виден глазом. Проверка на это добавлена в
tests/progress.

Полоса в окне сборки была системной, и под gtk2 заполнялась ступенями по
восемь кусков на ширину. Теперь там та же своя полоса, что и внизу
главного окна, — заполняется сплошь. Чтобы она читалась из файла формы,
у неё опубликованы Anchors, Align и Visible: читатель формы берёт только
опубликованные свойства, и без этого окно падало при открытии.

Проверено глазами на невидимом экране: «Собираю наложение 1 из 1 — 2%»
при полосе в 2%, через четыре секунды 69% при полосе в 69%.
2026-10-01 15:50:10 +03:00

126 lines
4.7 KiB
ObjectPascal
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{
Проверка того, как ползёт полоска выполнения.
Проверяется не картинка, а поведение: назад не идёт, между вехами
замедляется, при затянувшейся работе не упирается в конец.
Отдельная программа, а не проверка внутри редактора: расчёт вынесен в
uAppTypes именно затем, чтобы его можно было прогнать числами.
}
program progtest;
{$mode objfpc}{$H+}
uses
SysUtils, uAppTypes;
const
Step = 0.07;
var
Failed: Integer = 0;
procedure Check(const AName: string; ACondition: Boolean);
begin
if ACondition then
WriteLn(' ok ', AName)
else
begin
WriteLn(' ПЛОХО ', AName);
Inc(Failed);
end;
end;
{ Сколько шагов таймера пройдёт, пока полоска идёт от одного значения к
другому при неизменных вехах. }
function StepsFrom(AShown, AReal, ANext, ATarget: Double): Integer;
var
V: Double;
begin
Result := 0;
V := AShown;
while (V < ATarget) and (Result < 100000) do
begin
V := AdvanceProgress(V, AReal, ANext, Step);
Inc(Result);
end;
end;
var
V, Prev: Double;
I, N1, N2: Integer;
begin
WriteLn('Ход полоски выполнения');
WriteLn;
{ 1. Назад не идёт никогда, даже если настоящая доля вдруг меньше.
Сравнение с запасом: константа в исходнике считается в расширенной
точности, а значение хранится как Double, и точное равенство между
ними не выполняется никогда. }
V := AdvanceProgress(0.6, 0.2, 0.25, Step);
Check('назад не идёт', V >= 0.6 - 1E-9);
{ 2. Веха достигнута — прыгаем к ней сразу. }
V := AdvanceProgress(0.1, 0.5, 0.75, Step);
Check('до настоящей доли догоняет сразу', V >= 0.5);
{ 3. Между вехами ползёт, но следующей не достигает. }
V := 0;
for I := 1 to 200 do
V := AdvanceProgress(V, 0, 0.25, Step);
Check('между вехами движется', V > 0.2);
Check('следующую веху не переступает', V < 0.25);
{ 4. Замедление: вторая половина пути до вехи занимает столько же шагов,
сколько первая. Это и значит «чем дольше, тем медленнее». }
N1 := StepsFrom(0, 0, 1, 0.5);
N2 := StepsFrom(0.5, 0, 1, 0.75);
Check('вторая половина пути не быстрее первой', N2 >= N1);
WriteLn(Format(' шагов до половины: %d, до трёх четвертей: %d',
[N1, N1 + N2]));
{ 5. В конец не упирается, сколько ни жди. }
V := 0;
for I := 1 to 100000 do
V := AdvanceProgress(V, 0, 1, Step);
Check('полной не становится без настоящего конца', V <= 0.999);
{ 6. Ход монотонный. }
V := 0;
Prev := -1;
for I := 1 to 500 do
begin
V := AdvanceProgress(V, 0, 1, Step);
if V < Prev then
Break;
Prev := V;
end;
Check('ход монотонный', V >= Prev);
{ 7. Одна-единственная веха — и та конец.
Так выглядит сборка одного куска: сделано ноль из одного. Полоса
ползёт к единице и раньше подбиралась к ней вплотную — заполненная
полоса у работы, которая ещё идёт, читается как зависшая программа.
Теперь догадка не закрывает промежуток целиком, и остаток виден. }
V := 0;
for I := 1 to 1000 do
V := AdvanceProgress(V, 0, 1, Step);
Check('без замеров полоса не доходит до края: ' +
FloatToStrF(V, ffFixed, 8, 3), V <= 0.91);
{ А как только приходит настоящий замер, полоса слушается его. }
V := AdvanceProgress(V, 0.95, 1, Step);
Check('настоящий замер перекрывает догадку', V >= 0.95);
WriteLn;
if Failed = 0 then
WriteLn('ВЕРДИКТ: все проверки пройдены')
else
begin
WriteLn('ВЕРДИКТ: не пройдено проверок: ', Failed);
Halt(1);
end;
end.