2009-02-05 7 views
5

Chcę utworzyć pakiet danych obiektów światła do przejścia między aplikacjami klienta i serwera.W jaki sposób używać operatora bit/bit do sterowania stanem obiektu?

Jest to tak proste zadanie, które można kontrolować tylko 1 bajt, więc każdy bit w bajcie będzie mieć inne znaczenie,

Korzystanie tylko trochę

0 = False 
1 = True 

itens I trzeba teraz:

1 - Loaded from database 
2 - Persisted 
3 - Changed 
4 - Marked to Delete 
5 - 
6 - 
7 - Null Value 
8 - Read Only 


1) How do I use bit operators in Delphi to check each bit value? 
2) How do I set the bit Values? 

Rozwiązanie

Po wszelką pomoc, Ill użyć następnego zestawu

TStateType = (
    stLoaded = 0, // loaded from persistance 
    stNative = 2, // value loaded and converted to native type 
    stPersisted = 3, // saved 
    stChanged = 4, // object or member changed 
    stToDelete = 5, // marked to delete 
    stReadOnly = 6, // read only object, will not allow changes 
    stNull  = 7 // value is null 
); 
    TState = Set of TStateType; 

a dla strumienia -> oporność, to będzie rekord należy używać:

TDataPackage = record 
    Data: TBytes; 
    TypeInfo: TMetaInfo; 
    State: Byte; 
    Instance: TBuffer; 
    end; 

Dziękuję facetów, dla wszystkich odpowiedzi i komentarze.

+1

Zestawy są lepszą techniką niż bezpośrednie operatory bitowe. Są nie mniej "lekkie", ponieważ operacje setowe kompilują się do tego samego kodu maszynowego, co operacje binarne. Zaletą jest to, że są one bezpieczne i sprawdzane przez kompilator, podczas gdy operacje bitowe są na liczbach całkowitych. –

+1

Jeśli masz zestaw zawierający maksymalnie 8 możliwych elementów, typ będzie miał 1 bajt. –

+0

Zadałem pokrewne pytanie tutaj: "[Czy szybsze jest korzystanie z tablicy lub dostępu do bitów dla wielu wartości boolowskich?] (Http://stackoverflow.com/questions/517138/is-it-faster-to-use-an -array-lub-bit-access-for-multiple-boolean-values ​​/ 517184 # 517184) " –

Odpowiedz

7

Naprawdę użyłbym do tego zestawu. Jednak widzę, że naprawdę chcesz bajt. Użyj zestawów wszędzie, a potem wpisz bajt na końcu.

To rozwiązanie będzie wymagać znacznie mniejszej pisowni, ma obsługę standardowych operatorów delphi i nie ponosi żadnej kary za wydajność, jak zauważył Barry Kelly.

procedure Test; 
type 
    TSetValues = (
    TSetValue1 = 0, 
    TSetValue2 = 1, 
    TSetValue4 = 2, 
    TSetValue8 = 3, 
    TSetValue16 = 4, 
    TSetValue32 = 5, 
    TSetValue64 = 6, 
    TSetValue128 = 7 
); 

    TMySet = set of TSetValues; 
var 
    myValue: byte; 
    mySet: TMySet; 
begin 
    mySet := [TSetValue2, TSetValue16, TSetValue128]; 
    myValue := byte(mySet); 
    ShowMessage(IntToStr(myValue)); // <-- shows 146 
end; 
+0

@PEtriW, Ill spróbuj tego. –

+0

To jest zwycięzca, myślę, że trochę refactory pomoże mi poprawić mój istniejący kod. –

1

This page opisuje operatory Delphi, w tym operatory bitowe.

Wygląda na to, że musisz użyć operatora i. Na przykład:

const 
    LOADED_FROM_DATABASE = 1; 
    PERSISTED = 2; 
    CHANGED = 4; 
    // etc... 

//... 

if (bitFlags and LOADED_FROM_DATABASE) <> 0 then 
begin 
    // handle LOADED FROM DATABASE 
end; 

if (bitFlags and PERSISTED) <> 0 then 
begin 
    // handle PERSISTED 
end; 

// etc... 

Aby ustawić flagi, można użyć OR:

bitFlags := LOADED_FROM_DATABASE or PERSISTED or CHANGED; 
+0

@Scott, excellent. Dziękuję Ci! –

+0

Zestawy są lepszym prymitywem dla tego w Delphi, ponieważ są częścią składni i semantyki języka, a jednocześnie kompilują się do tych samych operacji kodu maszynowego. –

+0

@ Barry, dzięki. Używam Ustawia i przesyła do bajtu w strumieniu. –

6

chciałbym użyć zestawu dla tego:

type 
    TMyDatum = (mdLoaded, mdPersisted, mdChanged, mdMarkedToDelete, ...); 
    TMyData = set of TMyDatum; 

var 
    Foo: TMyData; 
begin 
    Foo := [mdLoaded, mdChanged]; 
    if (mdPersisted in Foo) then ... 

te realizowane są jako liczby całkowite, więc możesz je łatwo przekazać. I uważam, że kod jest znacznie bardziej czytelny niż operatory bitowe.

+0

@Craig, to jest to, co mam dzisiaj. Jak wskazałem w moim pytaniu, to musi być więcej światła, a nie jestem pewien co do rozmiaru wyliczonego typu. Również strumieniowanie 1 bajta jest łatwiejsze niż strumieniowe typy wyliczeniowe. Kod do przetestowania wartości bitowych zostanie osadzony wewnątrz obiektu TStatus, np. Status.IsLoaded –

+1

Cesar - zestaw ma rozmiar 1, 2, 3, 4 itd. Bajtów, jednak wiele z nich jest niezbędnych do zmieszczenia wszystkich wymaganych bitów, jeden bit na każdy możliwy element zestawu. Zestawy są bezpośrednio równoważne bitowym operacjom binarnym. –

+0

Cesar: To nie jest zepsucie. Nie "naprawiaj" tego! –