Dla każdego programisty błogosławieństwem są (a przynajmniej powinny być) gotowe biblioteki. Sam regularnie korzystam z STL# ;) , czyli System.Collections.Generic. Są to skompilowane klasy, jednak .NET 3.5 (a dokładniej C# 3.0) dostarcza możliwość dodania do nich własnoręcznie zaimplementowane metody. Konstrukcja ta nosi nazwę Extension Methods, a korzysta się z niej w następujący sposób: Czytaj dalej »

Tagi: , ,

Autor: czoper w kategorii/kategoriach: Programowanie

17.03.2010 miałem okazję uczestniczyć w konferencji Warszawskie Dni Informatyki 2010. Program co prawda był dwudniowy, ale ograniczenia czasowe oraz indywidualne preferencje dotyczące tematów poszczególnych sesji zaważyły na wyborze właśnie środy. Po wyborze dnia odbył się dalszy “odsiew” – z pięciu proponowanych sesji uczestniczyłem w czterech, krótkie podsumowanie każdej z nich poniżej.

  1. “BitLocker i BitLocker To Go w Windows 7 – DeepDive” Paula Januszkiewicz
    Z Bitlockerem miałem do tej pory kontakt, powiedzmy, pośredni tzn. wiedziałem, że takie coś jest, bo ktoś inny go używa. W trakcie tej sesji został on zaprezentowany od strony sposobu działania i mechanizmów, z których korzysta. Prelegentka na początku uprzedziła o wysokim poziomie sesji, więc jako początkujący w tym temacie zdarzyło mi się parę razy zgubić. Na plus należy zaliczyć sposób prowadzenia – bardzo interaktywny i skierowany głównie do publiczności, a nie jak się czasem zdarza “w przestrzeń”.
  2. “IntelliTrace – Nowość w Visual Studio 2010″ Michał Komorowski
    Bardzo byłem ciekawy tej sesji, ze względu na specyfikę narzędzia. Najprościej mówiąc, IntelliTrace to dużo bardziej rozbudowany Debugger dostępny w Visual Studio 2010. Lista możliwości jest imponująca: rejestrowanie ścieżki wykonania programu, zapisywanie kolejnych zdarzeń, wywołań metod, wartości parametrów do nich przekazanych oraz wartości zwracanych przez metody. Możliwość definiowania własnych typów przechwytywanych zdarzeń. Zapisywanie konkretnego przebiegu programu do pliku i odtworzenie stanu na innym komputerze. W końcu znikną odwieczne wojny między deweloperami a testerami o zdanie “u mnie działa” – tester po prostu prześle swoje nagrane wykonanie programu programiście. Dla testerów udostępnione zostanie też inne narzędzie: Microsoft Test & Lab Manager, który umożliwia rejestrowanie błędów i dołączanie logów IntelliTrace. Do bycia w pełni idealnym brakuje IntelliTrace kilku elementów, śledzenie programów w językach innych niż C# / Visual Basic.NET, możliwość rejestrowania aplikacji na systemy 64-bitowe a przede wszystkim przenosiny z Visual Studio 2010 Ultimate na wersje bardziej “dla przeciętnego programisty”, chociażby Professional dostępne dla studentów w ramach MSDNAA.
  3. “ASP.NET WebForms vs. ASP.NET MVC” Michiel van Otegem
    Z ASP.NET miałem styczność jedynie w ramach projektów studenckich, więc temat uznałem za interesujący. Sesja ta była wg mnie przeznaczona dla ludzi, którzy z ASP.NET MVC nie mieli do tej pory styczności, Michel omówił główne różnice tej technologii w stosunku do ASP.NET WebForms. Nie jestem jednak aż takim pasjonatem programowania storn internetowych, żeby w pełni docenić zawarte w tej prezentacji informacje.
  4. “Gra w augmented reality – wstęp do XNA. (XBOX, C#).” Mateusz Kierepka
    Zdecydowanie najbardziej interesująca część konferencji. Po pierwszych kilku minutach wystraszyłem się, że będzie to prelekcja pod tytułem “zobaczmy w punktach co można zrobić z kolejnymi wersjami biblioteki XNA”, ale na szczęście autor przygotował mnóstwo interaktywnych przykładów. Świetnie pokazało to możliwości biblioteki – ten sam projekt był w trakcie prezentacji uruchamiany na PC, XBox 360, na Windows 7 Phone (emulowanym na PC, ale zawsze coś). Na stoliku obok leżał też odtwarzacz Zune i według zapewnień, na nim też działają. Po tym co zobaczyłem wierzę na słowo. Bardzo dynamiczna prezentacja, sporo treści, dużo przykładów, szkoda że nie dało się jej przedłużyć. Czas teraz nabyć sprzęt typu XBox 360 do domowych zastosowań.. oczywiście związanych z programowaniem ;)

Myślę, że nie trzeba nikogo przekonywać, ze na konferencje jeździć / chodzić / uczestniczyć warto. Może dowiesz się o technologii, która od zawsze była Ci pisana. Może dowiesz się, że to, co od zawsze pisałeś sam jest już o wiele lepiej zrobione w jakiejś opensource’owej bibliotece? A może po prostu wyjdziesz na środek i zaczniesz:

“Witam państwa, nazywam się tak i tak i dzisiaj zaprezentuję możliwości technologii..”

Tagi: ,

Autor: czoper w kategorii/kategoriach: Inne

Stare chińskie przysłowie mówi, że “Krótki fragment kodu wart jest więcej niż tysiąc słów.” Nie przedłużając więc:

class MyClass
{
    private int _member;
    public int Member
    {
        get { return _member; }
        set { _member = value; }
    }
    public MyClass(int value) { _member = value; }
}

Uściślając: w przykładowej klasie jest prywatna zmienna _member, do której odwołujemy się z zewnątrz przez publiczną właściwość (ang. Property) Member. Mechanika obsługi tej zmiennej przez właściwość nie jest zbyt wyszukana, więc możemy zastąpić ją tzw. Auto-Implemented Property (lub krócej Auto-Property). Poniżej tysiąc słów na ten temat:

class MyClass
{
    public int Member { get; set; }
    public MyClass(int value) { Member = value; }
}

Z poziomu kodu używającego klasy MyClass nic się nie zmieniło (nadal odwołujemy się do pola Member przez właściwość), ale w tym przypadku nie mamy explicite obiektu _member wewnątrz klasy, kompilator wygeneruje go anonimowo, pozwalając na dostęp jedynie przez metody get i set.

Aby uczynić pole Member polem “tylko do odczytu” należy:

  • w pierwszym przypadku usunąć metodę set z właściwości:
    class MyClass
    {
        private int _member;
        public int Member
        {
            get { return _member; }
        }
        public MyClass(int value) { _member = value; }
    }
    
  • w drugim przypadku dołożyć przed set słowo kluczowe private:
    class MyClass
    {
        public int Member { get; private set; }
        public MyClass(int value) { Member = value; }
    }
    
  • Przez ten zabieg otrzymujemy pole “tylko do odczytu” dla kodu z zewnątrz klasy.

Tagi: , ,

Autor: czoper w kategorii/kategoriach: Programowanie

Poniżej krótki sposób jak pozbyć się ze swojego kodu pewnych potworków.

Bardzo częstą konstrukcją if (..) then .. else .., jednak niech Was ręka boska broni od napisania czegoś takiego:

private MyType ChooseSomething()
{
    MyType possibleResult1;
    MyType possibleResult2;

    // do some operations

    if (someCondition)
        return possibleResult1;
    else
        return possibleResult2;
}

Zamiast tego proponuję użycie operatora “?” (znak zapytania), o następującej składni:

condition ? expression1 : expression2;

który zwraca expression1, jeżeli warunek condition jest prawdziwy lub expression2 w przeciwnym przypadku.

Refactoring potworka z początku posta daje następujący rezultat:

private MyType ChooseSomething()
{
    MyType possibleResult1;
    MyType possibleResult2;

    // do some operations

    return someCondition ? possibleResult1 : possibleResult2;
}

Kolejny przypadek pojawia się, gdy następuje sprawdzenie czy dany obiekt nie jest null-em. Poniżej przykładowy kod (już po refactoringu z zastosowaniem operatora ?: )

private MyType ComputeSomething()
{
    MyType possibleResult = null;
    // do some operations
    return (possibleResult != null) ? possibleResult : defaultValue;
}

Wprowadzenie kolejnego operatora “??” (podwójny znak zapytania) jeszcze bardziej skróci zapis. Operator ten zwraca wartość po swojej lewej stronie wtedy, gdy nie jest ona równa null, w przeciwnym przypadku zwróci wartość po prawej stronie. Zastosowanie powyższego operatora do metody ComputeSomething() da następujący rezultat:

private MyType ComputeSomething()
{
    MyType possibleResult = null;
    // do some operations
    return possibleResult ?? defaultValue;
}

Przez użycie odpowiednich konstrukcji ilość tzw. “spaghetti code” znacznie się zmniejsza.

P.S. “Short Tip” to w założeniu regularny cykl krótkich artykułów przybliżających niewielkich rozmiarów zagadnienia składniowe/ideowe/estetyczne

Tagi: , ,

Autor: czoper w kategorii/kategoriach: Programowanie

notyfikacje

02-03-10

Sposobów na komunikację aplikacji z użytkownikiem jest kilka. Powiadomieniem o zakończeniu długo trwającej operacji (np. ściąganie pliku, filtrowanie obrazu, wykonywanie złożonych obliczeń matematycznych) może być informacja na pasku statusu, tzw. “balloon tip”, odegranie dźwięku lub wyświetlenie okna modalnego (nie zalecam).
Co jednak w przypadku, gdy użytkownik zminimalizował okno? Może dowiedzieć się o zakończeniu operacji gdy przypomni sobie o jej wykonywaniu (co w dobie portali społecznościowych i gier flash może trwać długo). Wspomniane wcześniej modalne okno dialogowe skutecznie powiadomi użytkownika o zakończeniu operacji, jednocześnie niwecząc plany uzyskania rekordu w kolejnym klonie Tower Defense.

Poniżej prosty sposób (zamknięty w statyczną klasę) jak (tak jak najczęściej komunikatory sieciowe, typu GG lub AQQ)  “migać” oknem aplikacji, procedura i opisy struktur zaczerpnięte z serwisu pinvoke.net.

using System.Runtime.InteropServices;
using System;

namespace MardiGras
{
    public static class FlashWindow
    {
        [DllImport("user32.dll")]
        private static extern bool FlashWindowEx(ref FLASHWINFO pwfi);

        private struct FLASHWINFO
        {
            public uint cbSize;
            public IntPtr hwnd;
            public uint dwFlags;
            public uint uCount;
            public uint dwTimeout;
        }

        /// <summary>
        /// Stop flashing. The system restores the window to its original stae.
        /// </summary>
        public const uint FLASHW_STOP = 0;

        /// <summary>
        /// Flash the window caption.
        /// </summary>
        public const uint FLASHW_CAPTION = 1;

        /// <summary>
        /// Flash the taskbar button.
        /// </summary>
        public const uint FLASHW_TRAY = 2;

        /// <summary>
        /// Flash both the window caption and taskbar button.
        /// This is equivalent to setting the FLASHW_CAPTION | FLASHW_TRAY flags.
        /// </summary>
        public const uint FLASHW_ALL = 3;

        /// <summary>
        /// Flash continuously, until the FLASHW_STOP flag is set.
        /// </summary>
        public const uint FLASHW_TIMER = 4;

        /// <summary>
        /// Flash continuously until the window comes to the foreground.
        /// </summary>
        public const uint FLASHW_TIMERNOFG = 12;

        /// <summary>
        /// Flash the spacified Window (Form) until it recieves focus.
        /// </summary>
        /// <param name="form">The Form (Window) to Flash.</param>
        /// <returns></returns>
        public static bool Flash(System.Windows.Forms.Form form)
        {
            FLASHWINFO fi = Create_FLASHWINFO(form.Handle, FLASHW_ALL | FLASHW_TIMERNOFG, uint.MaxValue, 0);
            return FlashWindowEx(ref fi);
        }

        private static FLASHWINFO Create_FLASHWINFO(IntPtr handle, uint flags, uint count, uint timeout)
        {
            FLASHWINFO fi = new FLASHWINFO();
            fi.cbSize = Convert.ToUInt32(Marshal.SizeOf(fi));
            fi.hwnd = handle;
            fi.dwFlags = flags;
            fi.uCount = count;
            fi.dwTimeout = timeout;
            return fi;
        }

        /// <summary>
        /// Flash the specified Window (form) for the specified number of times
        /// </summary>
        /// <param name="form">The Form (Window) to Flash.</param>
        /// <param name="count">The number of times to Flash.</param>
        /// <returns></returns>
        public static bool Flash(System.Windows.Forms.Form form, uint count)
        {
            FLASHWINFO fi = Create_FLASHWINFO(form.Handle, FLASHW_ALL, count, 0);
            return FlashWindowEx(ref fi);
        }

        /// <summary>
        /// Start Flashing the specified Window (form)
        /// </summary>
        /// <param name="form">The Form (Window) to Flash.</param>
        /// <returns></returns>
        public static bool Start(System.Windows.Forms.Form form)
        {
            FLASHWINFO fi = Create_FLASHWINFO(form.Handle, FLASHW_ALL, uint.MaxValue, 0);
            return FlashWindowEx(ref fi);
        }

        /// <summary>
        /// Stop Flashing the specified Window (form)
        /// </summary>
        /// <param name="form"></param>
        /// <returns></returns>
        public static bool Stop(System.Windows.Forms.Form form)
        {
            FLASHWINFO fi = Create_FLASHWINFO(form.Handle, FLASHW_STOP, uint.MaxValue, 0);
            return FlashWindowEx(ref fi);
        }
    }
}

Wodotryski tego rodzaju należy stosować z umiarem, w końcu nawet najlepsze ciastko ze zbyt dużą ilością lukru staje się nie do przełknięcia. Tą cukierniczo-inżynieryjną uwagą żegnam.

Tagi: , ,

Autor: czoper w kategorii/kategoriach: Programowanie

Po pierwsze, krótki wstęp teoretyczny: CAPTCHA to “Completely Automated Public Turing test to tell Computers and Humans Apart” czyli automatyczny test na sprawdzenie, czy do danego formularza/danych/whatever dobiera się człowiek czy bot. O sensowności zastosowania tego rodzaju mechanizmów nie będę pisał, nie mnie to oceniać, przedstawię jednak problem, z którym się ostatnio zetknąłem. Czytaj dalej »

Tagi: ,

Autor: czoper w kategorii/kategoriach: Programowanie

Podobno pierwszymi dwoma zdaniami, jakie wypowiada każdy programista są: “Będę zwalniał pamięć.” oraz “Nigdy, przenigdy nie będę używał instrukcji GOTO (oprócz języków assemblerowych)”. Wpojone zasady dobrze mieć na uwadze, ale czy zdarzają się sytuacje, w których użycie Instrukcji-Której-Nazwy-Nie-Wolno-Wymawiać jest konieczne? Przychodzą mi do głowy dwa przypadki: Czytaj dalej »

Tagi: ,

Autor: czoper w kategorii/kategoriach: Programowanie

Bycie programistą ma swoje zalety. Największą z nich jest możliwość tworzenia. Pomysł, doprawiony technologią i umiejętnościami przeradza się w nierzadko spory kawałek kodu, który po kompilacji spełnia swoje zadanie jako pełnoprawna aplikacja. Po co ten przydługi wstęp? Żeby zauważyć, że na aplikacji się kończy. Efekt pracy pozostaje wyłącznie ciągiem zer i jedynek zapisanym na twardym dysku. Choć dobrze napisany (i przede wszystkim ukończony) program daje olbrzymią satysfakcję, to przez ostatni rok brałem udział w ciągu przedsięwzięć, które dały (dosłownie) namacalny efekt. Czytaj dalej »

Tagi: , , , ,

Autor: czoper w kategorii/kategoriach: PUSN, Programowanie, Projekty, Studia

Symulacja ma niezliczoną wręcz ilość zalet:

  • pozwala zaobserwować i przeanalizować zjawiska fizyczne bez konieczności przygotowywania realnego środowiska
  • zmiana parametrów na bieżąco, pozwala obserwować jednoczesną zmianę zachowania środowiska
  • świetnie wygląda ;)

Kierując się powyższymi plusami jako wytycznymi, powstał symulator galaretki. Założenia projektowe:

  • symulacja ruchu sprężystego układu 64 mas połączonego sprężyście ze sztywną ramą, którą steruje użytkownik
  • ruch ramki sterującej jest nieograniczony, masy pozostają w granicach większego sześcianu
  • wyświetlanie cieniowanej kostki Beziera (każda ściana sześcianu definiuje płatek Beziera)
  • możliwość zaburzenia kostki przez przyłożenie losowych prędkości do mas
  • zmiana wszystkich możliwych parametrów: masy, współczynników sprężystości między poprzecznymi oraz skośnymi sprężynami, współczynnika sprężystości sprężyn łączących kostkę z ramką sterującą, współczynnika tłumienia (lepkość ośrodka)

Efekt pracy widoczny jest na filmie poniżej:

Jeżeli ktoś chce pobawić się żelkiem – aplikacja do ściągnięcia.

Sterowanie:

  • lewy przycisk myszy + ruch myszy – obroty sceny
  • lewy Ctrl + lewy przycisk myszy + ruch myszy – przesuwanie ramki sterującej
  • lewy Shift + lewy przycisk myszy + ruch myszy – obracanie ramki sterującej
  • kółko myszy – zoom in/out

Kwestie techniczne:

Niedługo symulacja płynów, wirująca bryła sztywna i art o algorytmie triangulacji 3D.

Autor: czoper w kategorii/kategoriach: Programowanie, Projekty, Rzeczywistość wirtualna, Studia

Budowanie wirtualnych, trójwymiarowych modeli obiektów codziennego użytku nie jest zadaniem trywialnym. Sam jeszcze parę miesięcy temu spędziłem niejedną godzinę, aby zaprojektować zwykły młotek przy pomocy powierzchni B-Spline. Tak dokładnie opisane obiekty nie są jednak potrzebne, gdy chodzi o gry komputerowe. Osoby zajmujące się 3D Studio Max’em, Blender’em lub aplikacją Maya, mające na celu wykonanie modelu do gry komputerowej skupiają swoją uwagę na tym, żeby wynikowy produkt w miarę dokładnie odzwierciedlał rzeczywisty obiekt przy zachowaniu możliwie małej ilości wierzchołków / trójkątów (low-poly model).

Bardzo ciekawa okazała się wiadomość z Uniwersytetu Cambridge. W ramach studenckiego projektu powstała tam biblioteka umożliwiająca przenoszenie na model cyfrowy realnie istniejących obiektów. Wykonywanie zdjęć, triangulacja i budowanie modelu są prowadzone w czasie rzeczywistym. Projekt nazywa się ProFORMA (Probabilistic Feature-based On-line Rapid Model Acquisition) i umożliwia trójwymiarowe skanowanie obiektów przy użyciu domowej internetowej kamery.

Krótki film prezentujący możliwości biblioteki (film linkowany ze strony projektu):

Proces tworzenia modelu (opisany na filmie) jest bardzo interesujący: skanowanie modelu -> tworzenie chmury punktów -> trójwymiarowa triangulacja Delaunay -> tworzenie siatki powierzchni modelu -> nakładanie tekstur (bezpośrednio ze zrobionych zdjęć). Podejrzewam, że wynikową siatkę można zapisać w jednym z popularnych formatów (.3ds, .x lub chociaż .md5) i poprawić ręcznie w dedykowanym do tego narzędziu. To daje nadzieję na szczęśliwszych grafików, którzy będą mogli prototyp modelu zeskanować trójwymiarowo, natomiast do ręcznego “wyrzeźbienia” pozostaną jedynie mniejsze szczegóły.

Do tej pory zagadnieniem reverse engineering (rekonstrukcja obiektu z chmury punktów pochodzącej ze skanera 3D) zajmowałem się jedynie od strony triangulacji siatki przybliżającej powłokę modelu (algorytm Ball-Pivoting) i muszę przyznać, że jest to całkiem wymagające zagadnienie. Tym większe gratulacje należą się autorowi biblioteki za pomyślne ukończenie pracy.