Полоса ползла по догадке, а подпись показывала замер — и человек видел полосу, заполненную на девять десятых, рядом с нулём процентов. Что в этот момент происходит, по такой паре понять нельзя. Теперь доля одна на обоих. Берётся она у самого ffmpeg: сборка участка с затуханием идёт минуту и дольше, а «кусок 1 из 1» всё это время не меняется, поэтому ffmpeg спрашивают ключом -progress, докуда он дошёл. Пока он не ответил ни разу, полоса трогается с места на пару процентов и там стоит — пустая полоса и есть правда о только что начатой работе. Догадка заодно перестала закрывать промежуток до вехи целиком: предел — девять десятых, остаток виден глазом. Проверка на это добавлена в tests/progress. Полоса в окне сборки была системной, и под gtk2 заполнялась ступенями по восемь кусков на ширину. Теперь там та же своя полоса, что и внизу главного окна, — заполняется сплошь. Чтобы она читалась из файла формы, у неё опубликованы Anchors, Align и Visible: читатель формы берёт только опубликованные свойства, и без этого окно падало при открытии. Проверено глазами на невидимом экране: «Собираю наложение 1 из 1 — 2%» при полосе в 2%, через четыре секунды 69% при полосе в 69%.
126 lines
4.7 KiB
ObjectPascal
126 lines
4.7 KiB
ObjectPascal
{
|
||
Проверка того, как ползёт полоска выполнения.
|
||
|
||
Проверяется не картинка, а поведение: назад не идёт, между вехами
|
||
замедляется, при затянувшейся работе не упирается в конец.
|
||
|
||
Отдельная программа, а не проверка внутри редактора: расчёт вынесен в
|
||
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.
|