Трябва да емулирам стратегията за разположение на прозореца на мениджъра на прозорци Fluxbox.
Като грубо ръководство, визуализирайте прозорци с произволен размер, запълващи екрана един по един, като грубият размер на всеки води до средно 80 прозореца на екрана, без нито един прозорец да се припокрива с друг.
Ако имате инсталирани Fluxbox и Xterm на вашата система, можете да опитате xwinmidiarptoy BASH скрипт, за да видя груб прототип на това, което искам да се случи. Вижте бележките xwinmidiarptoy.txt, които имах написано за него, обясняващо какво прави и как трябва да се използва.
Важно е да се отбележи, че прозорците ще се затворят и пространството, което затворените прозорци са заемали преди, става отново достъпно за поставяне на нови прозорци.
Алгоритъмът трябва да бъде Онлайн алгоритъм, обработващ данните "на части -част по сериен начин, т.е. в реда, в който входът се подава към алгоритъма, без целият вход да е наличен от самото начало."
Стратегията за поставяне на прозорец на Fluxbox има три бинарни опции, които искам да емулирам:
Windows изгражда хоризонтални редове или вертикални колони (потенциално)
Прозорците се поставят отляво надясноили отдясно наляво
Прозорците се поставят отгоре надолуили отдолу нагоре
Разлики между целевия алгоритъм и алгоритъма за поставяне на прозорец
Координатните единици не са пиксели. Решетката, в която ще бъдат поставени блоковете, ще бъде 128 x 128 единици. Освен това зоната за поставяне може да бъде допълнително свита от гранична зона, поставена в мрежата.
Защо алгоритъмът е проблем?
Трябва да работи в съответствие със сроковете на нишка в реално време в аудио приложение.
В този момент загрижен съм само за получаването на бърз алгоритъм, не се тревожете за последиците от нишките в реално време и всички препятствия в програмирането, които това носи.
И въпреки че алгоритъмът никога няма да постави прозорец, който припокрива друг, потребителят ще може да поставя и премества определени типове блокове, припокриващи се прозорци ще съществуват. Структурата на данните, използвана за съхраняване на прозорците и/или свободното пространство, трябва да може да се справи с това припокриване.
Досега имам два избора, за които съм създал свободни прототипи:
1) Порт на алгоритъма за поставяне на Fluxbox в моя код.
Проблемът с това е, че клиентът (моята програма) се изхвърля от аудио сървъра (JACK), когато се опитам да поставя най-лошият сценарий от 256 блока, използвайки алгоритъма. Този алгоритъм извършва над 14 000 пълни (линейни) сканирания на списъка с вече поставени блокове при поставянето на 256-ия прозорец.
За демонстрация на това създадох програма, наречена text_boxer-0.0.2.tar.bz2, който приема текстов файл като вход и го подрежда в ASCII полета. Издаване make
, за да го изградите. Малко недружелюбно, използвайте --help
(или друга невалидна опция) за списък с опции на командния ред. Трябва да посочите текстовия файл, като използвате опцията.
2) Моят алтернативен подход.
Приложен само частично, този подход използва структура от данни за всяка област от правоъгълно свободно неизползвано пространство (списъкът с прозорци може да бъде напълно отделен и не е необходим за тестване на този алгоритъм). Структурата на данните действа като възел в двойно свързан списък (със сортирано вмъкване), както и като съдържа координатите на горния ляв ъгъл, както и ширината и височината.
Освен това всяка блокова структура от данни също съдържа четири връзки, които се свързват с всеки непосредствено съседен (докосващ се) блок от всяка от четирите страни.
ВАЖНО ПРАВИЛО: Всеки блок може да се докосва само с един блок на страна. Това е правило, специфично за начина на алгоритъма за съхраняване на свободно неизползвано пространство и не влияе върху това колко действителни прозореца могат да се допират един до друг.
Проблемът с този подход е, че е много сложен. Приложих простите случаи, при които 1) пространството се премахва от единия ъгъл на блок, 2) разделям съседните блокове, така че да се спазва ВАЖНОТО ПРАВИЛО.
По-малко лесният случай, при който пространството, което трябва да бъде премахнато, може да бъде намерено само в рамките на колона или ред от кутии, се прилага само частично - ако един от блоковете, които трябва да бъдат премахнати, отговаря точно на ширина (т.е. колона) или височина (т.е. ред), тогава възникват проблеми. И дори не споменавайте факта, че това проверява само колони с ширина на едно поле и редове с височина на едно поле.
Приложих този алгоритъм в C - езикът, който използвам за този проект (не съм използвал C++ от няколко години и ми е неудобно да го използвам, след като съсредоточих цялото си внимание върху разработката на C, това е хоби). Реализацията е 700+ реда код (включително много празни редове, скоби, коментари и т.н.). Внедряването работи само за стратегията за поставяне на хоризонтални редове + ляво-дясно + горе-долу.
Така че или трябва да добавя някакъв начин да накарам тези +700 реда код да работят за другите 7 опции за стратегия за разположение, или ще трябва да дублирам тези +700 реда код за останалите седем опции. Нито едно от тях не е привлекателно, първото, защото съществуващият код е достатъчно сложен, второто, поради раздуването.
Алгоритъмът дори не е на етап, в който мога да го използвам в най-лошия сценарий в реално време поради липсваща функционалност, така че все още не знам дали действително се представя по-добре или по-лошо от първия подход.
Текущото състояние на изпълнението на C на този алгоритъм е freespace.c. Използвам gcc -O0 -ggdb freespace.c
за изграждане и го стартирам в xterm с размер най-малко 124 x 60 знака.
Какво друго има?
Прегледах набързо и отстъпих:
Алгоритми за опаковане в контейнери: техният акцент върху оптималното прилягане не съответства на изискванията на този алгоритъм.
Алгоритми за рекурсивно разполовяване: звучи обещаващо, но те са за проектиране на верига. Техният акцент е оптималната дължина на проводника.
И при двете, особено при последната, всички елементи, които трябва да бъдат поставени/пакети, са известни преди алгоритъма да започне.
Какво мислите по този въпрос? Как бихте подходили? Какви други алгоритми трябва да гледам? Или дори какви концепции трябва да проуча, тъй като не съм учил компютърни науки/софтуерно инженерство?
Моля, задавайте въпроси в коментарите, ако е необходима допълнителна информация.
Допълнителни идеи, развити след задаването на този въпрос
- Някаква комбинация от моя „алтернативен алгоритъм“ с пространствена хеш карта за идентифициране дали голям прозорец, който трябва да бъде поставен, ще покрие няколко блока свободно пространство.