Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Port SFML do androida krok po kroku

Ostatnio zmodyfikowano 2016-02-03 20:05
Autor Wiadomość
doman100
Temat założony przez niniejszego użytkownika
Port SFML do androida krok po kroku
» 2016-02-02 15:03:23
Witam, czy jest ktoś w stanie powiedzieć jak krok po kroku sprawić,że aplikację z SFMLa będą się uruchamiały na androida? I mógłby ktoś nakreślić jak wygląda obsługa zdarzeń ekranu dotykowego?
P-144342
DejaVu
» 2016-02-02 21:08:24
https://github.com/SFML/SFML​/wiki​/Tutorial:-Building-SFML-for-Android
http://www.sfml-dev.org​/documentation/2.2​/classsf_1_1Touch.php

/edit:
Z opisu jaki jest w dokumentacji wynika, że korzystanie z funkcjonalności sf::Touch::getPosition jest zawsze UB, ponieważ nawet zaraz po sprawdzeniu czy sf::Touch::isDown może zajść zmiana stanu, która spowoduje UB z chwilą wywołania sf::Touch::getPosition :)
P-144364
jankowalski25
» 2016-02-02 23:26:06
C/C++
////////////////////////////////////////////////////////////
bool InputImpl::isTouchDown( unsigned int finger )
{
    ALooper_pollAll( 0, NULL, NULL, NULL );
   
    priv::ActivityStates * states = priv::getActivity( NULL );
    Lock lock( states->mutex );
   
    return states->touchEvents.find( finger ) != states->touchEvents.end();
}


////////////////////////////////////////////////////////////
Vector2i InputImpl::getTouchPosition( unsigned int finger )
{
    ALooper_pollAll( 0, NULL, NULL, NULL );
   
    priv::ActivityStates * states = priv::getActivity( NULL );
    Lock lock( states->mutex );
   
    return states->touchEvents.find( finger )->second;
}


////////////////////////////////////////////////////////////
Vector2i InputImpl::getTouchPosition( unsigned int finger, const Window & relativeTo )
{
    return getTouchPosition( finger );
}
@DejaVu: Czy ten kod rzeczywiście może powodować UB? I czy poniższy kod rozwiązuje problem?
C/C++
////////////////////////////////////////////////////////////
Vector2i InputImpl::getTouchPosition( unsigned int finger )
{
    ALooper_pollAll( 0, NULL, NULL, NULL );
   
    priv::ActivityStates * states = priv::getActivity( NULL );
    Lock lock( states->mutex );
   
    //tutaj zmiana!
    if( states->touchEvents.find( finger ) != states->touchEvents.end() ) return states->touchEvents.find( finger )->second;
   
    return Vector2i();
}
P-144393
pekfos
» 2016-02-02 23:46:06
Czy ten kod rzeczywiście może powodować UB?
Tak.

I czy poniższy kod rozwiązuje problem?
Niezupełnie.. Nie wiem, czym się kierowali deweloperzy SFML, bo to nie powinno tak działać. Masz blokadę zaciąganą osobno przy sprawdzaniu, czy istnieje poprawna informacja i osobno przy pobieraniu tej informacji. Twoja modyfikacja tylko usuwa UB, ale kod dalej będzie działał nieprawidłowo, bo jeśli stan się zmieni, to dostaniesz 0,0 nieodróżnialne od informacji, która ma sens. Poza tym, twoja modyfikacja nie świeci przykładem poprawnego programowania ;)
P-144397
jankowalski25
» 2016-02-02 23:49:04
dostaniesz 0,0 nieodróżnialne od informacji, która ma sens
Jeśli użyjesz tej funkcji poza Androidem, to i tak dostaniesz 0,0.
P-144398
pekfos
» 2016-02-02 23:52:26
Jeśli użyjesz tej funkcji poza Androidem, to i tak dostaniesz 0,0.
To samo można powiedzieć o każdej funkcjonalności użytej niezgodnie z przeznaczeniem, gdy sama biblioteka ci mówi, że masz czegoś nie robić. Chyba nie łapiesz, w czym jest problem.

//edit:
Tu może w ogóle nie być UB, poza przypadkiem podania w ogóle złego argumentu do metody. To zależy od sposobu wykorzystania tej mapy. Dokumentacja mówi bardziej o niezdefiniowanym wyniku, a nie zachowaniu, co może w praktyce znaczyć, że odczytana zostanie stara wartość, lub śmieci. Trzeba by przeanalizować znacznie więcej kodu.

//edit2:
Z metody WindowImplAndroid::processPointerEvent():
C/C++
if( device == AINPUT_SOURCE_TOUCHSCREEN )
{
    event.type = Event::TouchEnded;
    event.touch.finger = id;
    event.touch.x = x;
    event.touch.y = y;
   
    states->touchEvents.erase( id );
}
Zaraz po odebraniu komunikatu, że puszczono ekran, punkt dotknięcia jest usuwany. Stąd wychodzi, że faktycznie UB.
P-144399
jankowalski25
» 2016-02-03 00:48:06
To zależy od sposobu wykorzystania tej mapy.
C/C++
if( sf::Touch::isDown( 0 ) )
{
    sf::Vector2i globalPos = sf::Touch::getPosition( 0 );
    //...
}
1. Użytkownik wciska przycisk.
2. Funkcja isDown zwraca
true
.
3. Użytkownik puszcza przycisk.
4. Co zwróci funkcja getPosition?
Zaraz po odebraniu komunikatu, że puszczono ekran, punkt dotknięcia jest usuwany. Stąd wychodzi, że faktycznie UB.
Czyli przy obecnym kodzie biblioteki powyższy przypadek na pewno daje UB? Skoro tak, to czy zapamiętywanie ostatniego punktu oraz przerobienie funkcji
getPosition
 w taki sposób, aby go zwracała rozwiąże problem?

//edit: Czy przechwytywanie zdarzeń typu TouchEvent może całkowicie zastąpić funkcjonalność dostarczaną przez klasę Touch?
P-144400
pekfos
» 2016-02-03 01:07:33
Skoro tak, to czy zapamiętywanie ostatniego punktu oraz przerobienie funkcji
getPosition
 w taki sposób, aby go zwracała rozwiąże problem?
Łatwiej powiedzieć, niż zrobić. Lepszym rozwiązaniem byłoby zwracanie pary bool, sf::Vector2i, lub czegoś podobnego z metody getPosition(). Zmiany stanu będą bez znaczenia, jeśli będziesz mieć informacje pobrane w tym samym momencie. isDown() zachowaj na przypadek, gdy interesuje cię tylko czy, a nie gdzie.

Czy przechwytywanie zdarzeń typu TouchEvent może całkowicie zastąpić funkcjonalność dostarczaną przez klasę Touch?
Compared to the TouchBegan, TouchMoved and TouchEnded events, sf::Touch can retrieve the state of the touches at any time (you don't need to store and update a boolean on your side in order to know if a touch is down), and you always get the real state of the touches, even if they happen when your window is out of focus and no event is triggered.
P-144401
« 1 » 2
  Strona 1 z 2 Następna strona