Witajcie :)
Stworzyłem sobie klase Window
reprezentującą okno w SFMLu (dokładniej teksturke okna, czyli co sie tam chce).
Klasa dziedziczy z klas sf::Transformable
oraz sf::Drawable
, miała być tylko interfejsem, ale jednak jest zwykłą klasą przeznaczoną do dziedziczenia (działa poprawnie).
Następnie, w osobnym projekcie testowałem sobie to okienko i działało poprawnie (konstruktor też).
Stworzyłem instancje klasy w projekcie głównym w którym troche kodu już jest i bardzo sie zdziwiłem, mianowicie aplikacja wywala sie gdy przekazuje coś przez konstruktor.
W tym testowym projekcie teksturke do okna podawałem w konstruktorze w taki sposób Window(sf::Texture* _tex, sf::Vector2f posit)
i bylo ok, działało.
W tym "właściwym" jak już nadmieniłem, przekazanie czegokolwiek przez konstruktor kończy się fiaskiem, z problemem poradziłem sobie tworząc setter setTexture(sf::Texture* _tex)
ale zaciekawił mnie na tyle że sie o to pytam( no i w przypadku gdyby zdarzyło mi sie kiedyś coś podobnego - będe wiedział )
Kodu nie daje bo jest go mało i raczej nie jest istotny, podejrzewam że chodzi o jakąś (bardzo zawiłą :D)zawiłość c++a.
- Rejestracja:około 11 lat
- Ostatnio:4 miesiące
- Lokalizacja:Pomorskie (Stare Kabaty)
- Rejestracja:około 11 lat
- Ostatnio:4 miesiące
- Lokalizacja:Pomorskie (Stare Kabaty)
HPP
#pragma once
#include <SFML/Graphics.hpp>
class Window : public sf::Drawable, public sf::Transformable
{
public:
Window();
void setTexture(sf::Texture*);
virtual void draw(sf::RenderTarget &, sf::RenderStates) const;
protected:
sf::Texture *_bg1 = nullptr;
sf::Sprite _background;
sf::Vector2f position;
sf::Vector2f size;
};
CPP
Window::Window(sf::Texture *tex,sf::Vector2f _position)
: _bg1(tex)
, _background(*tex)
, position(_position)
, size(tex->getSize().x, tex->getSize().y)
{
setPosition(_position);
}
void Window::draw(sf::RenderTarget& target, sf::RenderStates states) const{
states.transform *= getTransform();
states.texture = _bg1;
target.draw(_background,states);
}
@spartanPAGE Cóż, też byłem tego święcie przekonany że literówka czy coś takiego ale nope, było ok.
Problem objawiał sie przy wykonywaniu w innym kontekscie co mi sie jescze nie zdarzyło.
- Rejestracja:prawie 16 lat
- Ostatnio:5 miesięcy
- Postów:2514
jesli gdziekolwiek zrobiles cos takiego, to sie predzej czy pozniej sypnie:
class A {
Window* wnd;
public:
A() {
sf::Texture tex = ....;
sf::Vector2f pos = ...;
wnd = new Window(&tex, pos);
}
void foo() {
// jakakolwiek operacja na oknie ktora dotyka tekstury = sypnie sie
}
- Rejestracja:około 11 lat
- Ostatnio:4 miesiące
- Lokalizacja:Pomorskie (Stare Kabaty)
Wywołuje tak
Window win;
win.setTexture(&t);
Wczesniej było
Window win(&texturka, pozycja);
Resource manager jest w budowie i dlatego textury są hard-coded.
A co do kopiowania to z założenia obiekt nie jest przeznaczony do kopiowania (Uznałem to za nie potrzebne, bo nie widze potrzeby kopiowania okna ale fakt - rule of three mi sie kłania ).

- Rejestracja:prawie 12 lat
- Ostatnio:28 dni
Jeśli nie chcesz, żeby można było takowy obiekt kopiować - musisz co nie co oznaczyć jako delete
.
Co do menadżera to podsyłałem Ci już gotowe rozwiązanie, które możesz ewentualnie okroić do swoich potrzeb.

std::map
wiąże się niepotrzebny narzut, który z czasem zacznie dawać się we znaki. A boost jest użyty po to, żeby wiele wątków mogło pracować na jednym zarządcy.

O(1)
jest tym czego potrzebujesz. A jak wielowątkowości nie potrzebujesz - mówię, okrój i masz gotowca :P
std::map
i shared_ptr
poszedł w piz.. Jakby Siara powiedział.

- Rejestracja:prawie 16 lat
- Ostatnio:5 miesięcy
- Postów:2514
Pokaz skad sie wzielo t tutaj:
Proxima napisał(a):
Wywołuje tak
Window win;
win.setTexture(&t);
Wczesniej było
Window win(&texturka, pozycja);
Resource manager jest w budowie i dlatego textury są hard-coded.
A co do kopiowania to z założenia obiekt nie jest przeznaczony do kopiowania (Uznałem to za nie potrzebne, bo nie widze potrzeby kopiowania okna ale fakt - rule of three mi sie kłania ).
To jest bardzo podobne do tego przykladu co pozkazalem. Jesli t jest na stosie to obiekt zostanie zniszczony w tym samym momencie co skonczy sie scope w ktorym zostal wrzucony na stos, a to najczesciej dzieje sie dosc szybko. Zaraz po zniszczeniu obiektu Twoj wskaznik wskazuje na przypadkowe miejsce na stosie i jesli to Ci sie nie sypnie od razu to bedziesz w dosc nieciekawej sytuacji gdzie moze Ci sie cos sypnac w zupelnie losowym miejscu
- Rejestracja:około 11 lat
- Ostatnio:4 miesiące
- Lokalizacja:Pomorskie (Stare Kabaty)
@krwq
Właśnie to sie nie dzieje bo teksturka jest deklarowana w main (normalnie, nie wskaźnik) i istnieje do końca programu, a ja przekazuje tylko jej adres.
Najdziwniejsze jest to, że nieistotne co przekaże (np typ wbudowany w sfma sf::Vector2f
) i też sie wywala właśnie to mnie mocno zdziwiło (na tyle że aż odpaliłem debugiera ale sie zbytnio nie lubimy i wiele nie wykumałem).
- Rejestracja:około 11 lat
- Ostatnio:4 miesiące
- Lokalizacja:Pomorskie (Stare Kabaty)
Hihoo!
Nie dało mi to spokoju i wczoraj w nocy zastanawiałem się co tam było źle, częściowo problem odnalazłem, niestety, nie udało mi sie odtworzyć błędu związanego z wywalaniem po przekazaniu byle czego przez argumenty, ale znalazłem błąd z teksturą który był banalny i wynikał z mojej nieuwagi.
Opowiem dokładnie jak to było.
Przypadek testowy czyli ten który chodził nie był kompilowany w IDE tylko w zwykłym edytorze komendą z palca g++ ......
i tam pliki tj. teksturki były położone w tym samym folderze co exe, działało.
Natomiast po przeniesieniu do "innego kontekstu" czyli w tym przypadku IDE, mechanizm ten nie wiem czemu działa nieco inaczej, mimo że w execu wpisane są nazwy plików "na luźno" czyli że pliki powinny być w tym samym folderze co exec, natomiast tak sie nie dzieje, code::blocks nie wiadomo czemu (i jak to w ogóle możliwe) szuka tych plików w głównym katalogu projektu (może jakieś dowiązanie tworzy, idk) czyli nie bin/Debug/
.
Co dziwne, sfml w tamtym przypadku nie wypisywał na stdout "Unable to open file", natomiast program kończył sie SIGFPE
, sprawdziłem debugerem gdzie dokładnie i jedną z przyczyn była (podczas korzystania z podklasy klasy Window)
sf::Int32 tv = GID / (_tex->getSize().x / tile_height);
Gdzie _tex->getSize().x
wynosiło zero, w wyniku czego wykonywane było dzielenie przez zero.
To tak pokrótce, wiem że to jescze nie jest rozwiązanie, ale cośniecoś jestem już dalej :)


satirev