Monthly archive for November, 2007

W poszukiwaniu komunikatora idealnego

2007-11-21 10:12

Czy pamięta ktoś aplikację, która w Windows XP ma dość irytujący zwyczaj instalowania się, okazjonalnego włączania i działania przez cały czas w tle – nawet jeśli użytkownik nie za bardzo sobie tego życzy? Mam tu na myśli komunikator MSN Messenger. W Viście nie jest on już aczkolwiek składnikiem systemu i w razie potrzeby należy go osobno pobrać.
Logo Windows Live MessengeraTo właśnie zrobiłem za namową kolegi Asmodeusza i celem przyjrzenia się temu programowi, który obecnie zwie się zresztą Windows Live Messenger. Wnioski są takie, że w sumie jest to jeden z lepszych komunikatorów, jakich miałem okazję używać. Zwłaszcza dwie rzeczy zrobiły w nim na mnie pozytywne wrażenie. Pierwsza to rozbudowane możliwości zarządzania kontaktami i ustawiania różnych wzajemnych uprawnień, jak np. osób, które mogą nas widzieć niezależnie od naszego statusu. Drugą jest istniejąca obok zwykłego wysyłania plików funkcja ich współdzielenia, pozwalająca tworzyć katalogi dostępne dla nas i wybranych przez nas osób. Może nie jest to rozwiązanie na miarę rozbudowanego systemu kontroli wersji, ale kto wie – do prostych zastosowań może być wystarczające.
Wszystko byłoby dobrze, gdyby nie to, że w tym komunikatorze lista kontaktów zionie pustką :) W Polsce niestety tkwi on w tym zamkniętym, błędnym kole: (prawie) nikt go nie używa, bowiem… (prawie) nikt go nie używa. Raczej nie zanosi się więc, by mogło się to zmienić.

Logo Gadu-GaduZ kolei znane skądinąd Gadu-Gadu “cierpi” na podobną przypadłość. Tyle że tutaj owo sprzężenie zwrotne jest dodatnie i duża liczba użytkowników jest świetnym podłożem dla dalszego wzrostu liczby użytkowników. Tak się nadal dzieje mimo wręcz przysłowiowej niestabilności serwerów, mechanizmu przesyłania plików który częściej nie działa niż działa oraz braku jakichkolwiek zaawansowanych funkcji, zwłaszcza związanych z zarządzaniem kontaktami.
Na Gadu-Gadu wszyscy lubią więc narzekać, lecz mało kto poszukuje alternatywy. Dlaczego? Ano właśnie dlatego, że… mało kto to robi :) “Logika” instynktu lemingów jest niestety nieubłagana.

Logo SkypeA alternatywą mógłby być na przykład Skype, który nie przegrywa już na starcie z powodu małej liczby użytkowników. Przeciwnie, jest ich całkiem sporo, ale utarło się już, że program ten służy w zasadzie wyłącznie do rozmów głosowych. Otóż nie: ten sposób porozumiewania się oferuje dzisiaj każdy szanujący się komunikator, a Skype posiada też wszystkie inne funkcje, które są potrzebne w programie tego typu.
Lecz to oczywiście nie gwarantuje sukcesu. Wiele bardzo funkcjonalnych komunikatorów o sporych możliwościach nie przebiło się do szerszej świadomości, gdyż najwyraźniej najważniejszym kryterium decydującym o wyborze jest tutaj przyzwyczajenie. A te, jak wiadomo, bardzo trudno się zmienia.

Tags: , ,
Author: Xion, posted under Applications, Internet » 18 comments

Finalne demo Rega

2007-11-20 0:31

Regedit zaprezentował dzisiaj w końcu demko prezentujące możliwości jego silnika, który – jak sam utrzymuje – niedawno ukończył. Wprawdzie ja nadal mam wątpliwości, czy wyrazy ‘silnik’ i ‘ukończony’ w ogóle powinny pojawiać się obok siebie, ale nie zmienia to faktu, że przynajmniej aktualnie istniejąca część jego engine‘u prezentuje się imponująco. Moje gratulacje!

The Final Quest by Regedit - screen z dema The Final Quest by Regedit - screen z dema The Final Quest by Regedit - screen z dema

Po więcej szczegółów zapraszam tutaj:

The Final Quest

A ja w międzyczasie mogę dumać nad tym, ile to jeszcze miesięcy i lat zajmie mi dojście do podobnego poziomu ;)

Tags: , , ,
Author: Xion, posted under Internet, Programming » Comments Off on Finalne demo Rega

Szare shadery

2007-11-19 19:58

Dawno, dawno temu – co w dziedzinie programowania grafiki oznacza perspektywę kilkuletnią – większość przetwarzania odbywała się we wbudowanym, stałym potoku graficznym. Shadery wprawdzie były, ale oferowane przez nie możliwości były dosyć ubogie (zwłaszcza jeśli chodzi o te do pikseli), a poza tym należało kodować je w niezbyt przyjaznym języku podobnym do asemblera. Pewnie dlatego, a dodatkowo także z powodu małego wsparcia kart graficznych, większość efektów realizowano przy pomocy odpowiednich tekstur, stanów ich faz i tym podobnych wynalazków. Bardzo często tak było po prostu łatwiej.
Zadziwiające jest to, że teraz nierzadko bywa dokładnie odwrotnie :) Chociaż na początku można jeszcze uważać, że ustawianie przeróżnych stanów stałego potoku i poleganie wbudowanie jest łatwiejsze, a shadery dają “tylko” większe możliwości, to jednak z czasem to myślenie zawsze powinno się zmienić. W końcu przecież napisanie algorytmu określającego dokładnie krok po kroku, co się dzieje z wierzchołkiem lub pikselem, dla programisty z założenia musi być łatwiejsze niż ustawianie jakichś dziwnych flag, będącymi swoistymi wytrychami do standardowego sposobu przetwarzania.

Zresztą nie wszystko można tymi wytrychami łatwo osiągnąć. Weźmy niezwykle prosty efekt wyświetlania w skali szarości, jak na czarno-białym zdjęciu. Jeżeli chodzi o realizację tego efektu na fixed pipeline, to chwilowo nie mam na to żadnego sensownego pomysłu – oczywiście poza podmianą wszystkich tekstur na ich ‘szare’ wersje.
A wystarczyłoby tylko użyć prostego pixel shadera, który jawnie implementuje wzór na obliczenie natężenia koloru:

  1. float3 PS(float4 cl : COLOR0, /* itd */)
  2. {
  3.    float gray = 0.3f * cl.r + 0.59f * cl.g + 0.11f * cl.b;
  4.    return float3(gray, gray, gray);
  5. }

I już, efekt gotowy. Nietrudno byłoby też połączyć go z jakimkolwiek innym. W ogólności jest jednak ‘trochę’ trudniej – ale to już temat na inną okazję ;P

Tags: , ,
Author: Xion, posted under Programming » 6 comments

Nietypowe licencje

2007-11-17 13:27

Programy – zwłaszcza te do znalezienia w Internecie – są dostępne na wielu różnych rodzajach licencji. Do tych najbardziej znanych należą chociażby wszelakie licencje typu open source (na czele ze znaną i (nie)lubianą GNU GPL), freeware i shareware. Ale hakerska wyobraźnia nie zna granic i nawet w tak “poważnym” temacie pojawiły się żartobliwe wynalazki.
Wśród takich zdecydowanie nieszablonowych licencji mamy na przykład:

  • postcardware, wedle której użytkownik może korzystać z programu pod warunkiem, że prześle autorowi kartkę pocztową ze swojego miasta. W innych wariantach może to być też e-mail, chociaż osobiście uważam, że możliwość pochwalenia się imponującą kolekcją pocztówek jest o wiele bardziej zachęcająca niż perspektywa zapychającej się skrzynki mailowej :)
  • guiltware, charakteryzująca się tym, że program co jakiś czas wyświetla komunikat o tym, jak wiele wysiłku autor włożył w tworzenie danej aplikacji. Rzeczony komunikat ma wywołać w użytkowniku poczucie winy (stąd nazwa) i spowodować przesłanie autorowi drobnej sumy pieniędzy. To oczywiście dość drastyczna forma donationware i wydaje mi się, że skutek, jaki by odniosła, byłby raczej odwrotny do zamierzonego ;]
  • linkware, zakładającą że użytkownicy powinni w widocznym miejscu zamieścić link do strony internetowej autora. Jak nietrudno się domyślić, ten typ licencji stosuje się głównie do bibliotek programistycznych lub do treści możliwych do zamieszczenia na stronach WWW (np. obrazków), i generalnie nie wydaje się specjalnie dolegliwy.
  • beerware, która jest prawdopodobnie najlepsza z nich wszystkich :) Otóż według niej użytkownik w zasadzie może bez ograniczeń korzystać z programu – pod jednym warunkiem. Jeśli mianowicie kiedyś zdarzy mu się spotkać jego autora, ma kategoryczny obowiązek… postawić mu piwo :D Inne wersje zakładają wręcz wysłanie autorowi skrzynki chmielowego napoju lub tylko wypicie za jego zdrowie. No cóż, na pewno jest to praktyczniejsze niż wysyłanie pocztówek, a przy odrobinie szczęścia też może zostać pamiątka w postaci podstawki lub w ostateczności butelki ;]
  • otherware to z kolei cała masa różnych rodzajów “licencji” (cudzysłów jest tu już chyba uzasadniony), które proszą użytkownika o różne rzeczy nieprzynoszące żadnych bezpośrednich korzyści autorowi. Są to przykładowo:
    • careware (charityware) – użytkownik powinien wpłacić drobną (lub niekoniecznie drobną) sumę pieniędzy na konto wskazanej organizacji charytatywnej. Przykładem programu, który o to prosi, jest edytor vim.
    • greenware – tutaj w zamian za możliwość korzystania z programu, user jest zobowiązany zadbać jakoś o środowisko naturalne, a więc np. zacząć segregować śmieci, przestać używać jednorazowych opakowań, korzystać ze środku transportu publicznego, itd.
    • Garfield!

    • catware -w tym wariancie możliwe jest bezpłatne korzystanie z programu, o ile jego użytkownik poświęci przynajmniej jedną godzinę na… zabawę z jednym lub kilkoma kotami, niekoniecznie własnymi. Zapewne gdyby ta licencja była powszechnie stosowana, spowodowałoby to protesty właścicieli psów i chomików :)

Wniosek z tej listy jest taki, że określanie swoich programów jako po prostu freeware to marnotrawienie wielkiej okazji, aby zrobić coś dobrego. Nie mówię już nawet o wspomaganiu pożytecznych organizacji czy propagowaniu ekologii. Pomyślmy raczej o kotach! ;))

Tags: , ,
Author: Xion, posted under Applications » 6 comments

Sprzątanie śmieci

2007-11-15 23:22

Pamięcią operacyjną można w programowaniu zarządzać na dwa sposoby. Pierwszy to ręczne tworzenie obiektów i niszczenie ich, gdy nie są już potrzebne. Daje to kontrolę nad czasem ich życia, ale dopuszcza też możliwość powstawania błędów, jak wycieki pamięci czy próby podwójnego jej zwalniania. Aby im zapobiec, każdy obiekt musi mieć ściśle określonego właściciela, odpowiedzialnego za jego zniszczenie.
Drugi sposób to użycie mechanizmu odśmiecania pamięci (garbage collecting), które powinien sam wykrywać “porzucone” obiekty i je zwalniać, kiedy zachodzi ku temu potrzeba. Pozwala to oczywiście przestać martwić się o ich niszczenie. Zwykle nie oznacza to jednak, że wszystkie wyciekające fragmenty pamięci zostaną zwolnione natychmiast. Tracimy więc kontrolę nad czasem życia obiektów.

Nie da się jednak ukryć, że od kiedy komputery mają dość mocy obliczeniowej, aby wyświetlać miękkie cienie pod okienkami, mogą też z powodzeniem zajmować się automatycznym porządkowaniem sterty w swoim wolnym czasie. Dlatego zdecydowana większość nowych języków programowania jest wyposażona w odśmiecacze, które na dodatek są zawsze włączone i zwykle nie da się z nich zrezygnować. Najlepiej byłoby naturalnie mieć tutaj wybór, lecz rzadko jest on nam dany.
Nie inaczej jest w C++, tyle że tutaj mamy chyba jednak tę gorszą opcję – czyli konieczność ręcznego zarządzania alokacją i zwalnianiem. Można aczkolwiek to zmienić, lecz nie odbędzie się to w sposób przezroczysty dla programisty.

Odśmiecanie można przeprowadzić dwiema podstawowymi metodami, które mają naturalnie wiele wariantów. Są to:

    Referencje cykliczne

  • Śledzenie odwołań. Oznacza to posługiwanie się strukturą grafu w celu oznaczania elementów nieosiągalnych z bieżącego miejsca w programie, a następnie ich sukcesywnego zwalniania. Wymaga to wiedzy o tym, jak jeden obiekt może odwoływać się do drugiego i w C++ wymagałoby na przykład dziedziczenia po ustalonej klasie bazowej połączonego z kilkoma innymi wymaganiami.
  • Zliczanie referencji. Polega to na trzymaniu obok każdego obiektu licznika odwołań do tego właśnie obiektu. Każde kopiowanie i przypisywanie wskaźnika zmienia ten licznik i jeśli spadnie on do zera, obiekt kwalifikuje się do usunięcia. W C++ metodę tę można zaimplementować chociażby przy pomocy inteligentnych wskaźników.

W swoim pierwszym (działającym :)) ośmiecaczu dla C++ zastosowałem drugą metodę – oczywiście ze względu na jej prostotę. Jak wiadomo jednak nie jest ona doskonała, gdyż jej piętą achillesową są odwołania cykliczne. Można jej zaradzić na przykład poprzez tak zwane słabe referencje… Ale na szczęście póki co nie potrzebuję jeszcze takich “zakręconych” (dosłownie i przenośni) relacji między obiektami ;P

Tags:
Author: Xion, posted under Programming » Comments Off on Sprzątanie śmieci

Tablice bardzo dynamiczne

2007-11-15 10:32

W każdym poważnym języku programowania mamy do dyspozycji tablice o zmiennym rozmiarze, możliwym do ustalenia w czasie działania programu. Teoretycznie można by się bez nich obyć, jeżeli język posiada jakąś formę wskaźnika czy referencji, lecz konieczność ciągłego używania list na pewno nie byłaby przyjemna.
Z drugiej strony tablice mogą też być indeksowane więcej niż jednym indeksem, czyli być wielowymiarowe. Niekiedy wszystkie podtablice w danym wymiarze muszą mieć ten sam rozmiar (czyli całość być prostokątem, prostopadłościanem, itd.), ale np. C++ i C# pozwalają na dowolność i tworzenie chociażby macierzy trójkątnych zawierających tylko interesujące nas komórki.

To całkiem nieźle, lecz nie spotkałem jeszcze żadnego języka, który osiągnąłby zen w kwestii dynamicznych tablic, a mianowicie umożliwiał zmianę liczby wymiarów w trakcie działania programu. Być może powodem jest fakt, że w przypadku takich wybitnie elastycznych tablic nie da się już zapewnić dostępu do pojedynczego elementu w czasie stałym. Dla n wymiarów może on bowiem wynieść O(n2).
Jak więc można taką bardzo dynamiczną tablicę symulować? Ano trzeba samemu przeprowadzić jej linearyzację, czyli ponumerowanie wszystkich elementów tak, by można było obliczyć adres każdego w – liniowej przecież – pamięci operacyjnej. Przykładowo dla tablicy dwuwymiarowej element (x, y) będzie miał zlinearyzowany indeks równy zwykle x + y * width. Numerując z kolei trójwymiarową “kostkę”, otrzymalibyśmy formułę: x + y * width + z * height * width.

I tak dalej… W przypadku ogólnym aczkolwiek wzór może być trochę straszny :) Dla n-wymiarów o rozmiarach c1, …, cn, element opisany indeksami a1, …, an (liczonymi od zera) w wersji zlinearyzowanej znajdzie się na miejscu l:

Wzór na linearyzację tablicy wielowymiarowej

Formuła przekłada się oczywiście na dwie zagnieżdżone pętle – stąd więc jej oczekiwana złożoność. Można ją jednak łatwo zoptymalizować, przechowując wartość wewnętrznego iloczynu dla każdego z n wymiarów. Wtedy dostęp będzie już w czasie liniowym – oczywiście cały czas względem liczby wymiarów, a nie rozmiaru tablicy, więc nie jest aż tak źle :)
Taką dynamicznie wielowymiarową tablicę prawdopodobnie najłatwiej i najlepiej jest zaimplementować C++. I, co ciekawsze, nie będzie to wcale odkrywanie koła na nowo – czegoś takiego nie ma bowiem ani STL (daleko jej do tego), ani nawet boski boost ;]

Tags: ,
Author: Xion, posted under Programming » 3 comments

Mniejsze zło debugowania

2007-11-13 12:44

Banałem będzie stwierdzenie, że szukanie błędów w kodzie bywa wkurzające. Odpowiedź na proste pytanie – dlaczego coś nie działa? – to czasami długie godziny dłubania w programie, mało przyjemnych rendez-vous z debuggerem czy nawet stosowania bardziej drastycznych metod. Ale ponieważ w programowaniu nic nie dzieje się bez powodu (a przynajmniej chcemy w to wierzyć ;D) i przy założeniu, że dysponujemy odpowiednio dużymi zasobami: czasu, samozaparcia, a przede wszystkim umiejętności, w końcu uda się znaleźć tę upragnioną przyczynę błędu…

Bug :)A przyczyny mogą być trywialne. Pomyłka o jedynkę, nieopacznie wstawione x zamiast y, pomylenie plusa z minusem , i tak dalej. Takie błahostki zgodnie z prawem Murphy’ego mają wybitną skłonność do pojawiania się akurat w tych newralgicznych miejscach, które mają największy wpływ na działanie całego kodu – i oczywiście całkowicie je rozstrajają. A co gorsza, z bliżej niewiadomych przyczyn programistę uważnie oglądającego fragmenty z takimi “literówkami” ogarnia najczęściej chwilowa ślepota tudzież niewytłumaczalny zanik spostrzegawczości. Dopiero za n-tą inspekcją, przeprowadzoną najlepiej po długim odpoczynku od kodu, da się cokolwiek znaleźć.
Z drugiej strony poważne i trudne do znalezienia błędy mogą mieć poważne i trudne do usunięcia przyczyny. Inżynieria oprogramowania mówi, że im wcześniej w cyklu tworzenia programu błąd się pojawił, tym trudniej jest go potem wyeliminować. Jeżeli więc kruczek tkwił w założeniach projektowych, w modelu programu lub, co gorsza, w określeniu funkcjonalności, to nie będzie łatwo poradzić sobie z nim na etapie implementacji. Wyburzenie kilku ścian nie pomoże, jeśli fundamenty położono na niestabilnym gruncie.

Którego z tych dwóch rodzajów błędów oczekiwalibyśmy, jeżeli spędziliśmy już na debugowaniu dużo, naprawdę dużo czasu? Błąd drugiego typu to sprawa ciężkiego kalibru. Można wówczas powiedzieć, to oto odkryliśmy problem, który rzeczywiście jest adekwatny do tych godzin czy dni spędzonych na polowaniu na niego. Inaczej mówiąc, możemy uznać, że faktycznie zrobiliśmy wszystko, co w naszej mocy, i że cały ten wysiłek był naprawdę potrzebny, gdyż nie było innej drogi.
Z kolei pierwszy typ błędu to właściwie przeciwny biegun. Teoretycznie można było go załatwić w najwyżej kilkanaście minut, po prostu przeglądając jeszcze raz kod i dopisując ten zapomniany przecinek czy cokolwiek innego. Jak mogliśmy w ogóle spędzić nad tym tyle czasu, który przecież powinno się wykorzystać bardziej produktywnie?

Jeżeli kiedykolwiek ktoś odkryje przyczynę owej chwilowej ślepoty programistów na drobne omyłki, to osobiście uważam, że zasługuje przynajmniej na Ig Nobla :) Sądzę też jednak, że o wiele lepiej jednak paść jej ofiarą niż stwierdzić, że znaleziony błąd jest ową “ciężką sprawą”. Może i obniży to nieco naszą samoocenę, ale przynajmniej oszczędzi mnóstwa roboty.

Tags:
Author: Xion, posted under Programming, Thoughts » 7 comments
 


© 2017 Karol Kuczmarski "Xion". Layout by Urszulka. Powered by WordPress with QuickLaTeX.com.