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

[C++\CLI + SFML] Zdarzenia zapewniające komunikację w obie strony między różnymi oknami programu

Ostatnio zmodyfikowano 2016-05-23 21:26
Autor Wiadomość
Raccoon
Temat założony przez niniejszego użytkownika
[C++\CLI + SFML] Zdarzenia zapewniające komunikację w obie strony między różnymi oknami programu
» 2016-05-22 23:38:15
Witam!

 Piszę prosty edytor do gier platformowych, który posiada kilka osobnych okien. Jedno z nich wyświetla mapę i umożliwia jej edycję, podczas gdy drugie umożliwia modyfikację dostępnych warstw mapy. W tym celu zdecydowałem
się na napisanie kilku własnych zdarzeń. Jedno z nich jest wywoływane, gdy zostanie zmieniona ilość dostępnych warstw mapy (jest to pierwsze zdarzenie własne z tego edytora, jak i również pierwsze jakie napisałem).

Cały program jest podzielony na kilka klas. Pierwsza z nich jest rdzeniem - obiekt tworzony na jej podstawie jest fundamentem programu i przechowuje jego wszystkie dane. Klasa ta nosi nazwę "Core". Kolejną klasą jest klasa "ForDrawing" - obiekt z tej klasy jest odpowiedzialny głównie za wyświetlanie grafik i utrzymywanie głównego okna (z biblioteki SFML, wersji zgodnej z CLI), jest przechowywany w obiekcie z klasy "Core" i nosi nazwę "drawing". Następną klasą jest klasa "Layers" - tworzone jest na jej podstawie okno modyfikacji warstw mapy (Windows Forms), sam obiekt przechowywany jest w obiekcie z klasy "ForDrawing" i nosi nazwę "layerSelector". Zdarzenie znajduje się w pliku "Layers.h". Klasy znajdują się w plikach o tych samych nazwach co klasy.

Kod kompiluje się bezbłędnie, program pada zaraz po starcie, w trakcie inicjalizacji zdarzeń. Wg. Visuala próba powiązania napisanego przeze mnie zdarzenia z funkcją, która ma być wykonana po jego wystąpieniu,
jest niemożliwa, gdyż "Odwołanie do obiektu nie zostało ustawione na wystąpienie obiektu.". Sprawdziłem powyższą sytuację - obiekt "layerSelector" jest wg. Visuala niezdefiniowany, pomimo że jego konstruktor zostaje wywołany przed próbą powiązania zdarzeń, a program działa bez zarzutu w trybie release (jeżeli usunie się wadliwą linijkę kodu).

Oto kod:

Deklaracja Core:
main.cpp:
C/C++
Core ^ core = gcnew Core;
//ponizsza metoda laduje ustawienia zapisane w pliku konfiguracyjnym. Jak na razie tylko rozmiar okna
core->loadData();

Core.h:
C/C++
private:
ForDrawing ^ drawing;
//dodano warstwy
System::Void addLayers();

//inicjalizacja zdarzen
void initializeComponents();

Core.cpp (konstruktor):

C/C++
drawing = gcnew ForDrawing;
drawing->setWindow( screenDimensions );
//...ustawianie zmiennych...
//ponizsza metoda powiazuje zdarzenia z funkcjami
initializeComponents();

ForDrawing.h:

C/C++
//selektor warstw i dodatkowych opcji ich dotyczacych
Layers ^ layerSelector;
//metoda ustawiajaca dane obiektu
void setWindow( SFML::System::Vector2i screenDimensions );

ForDrawing.cpp (setWindow(...)):
C/C++
Layers ^ layerSelector = gcnew Layers;
layerSelector->Show();

Layers.h (zdarzenie):

C/C++
//dodano warstwy
delegate void AddedDel();

interface struct AddI
{
public:
    event AddedDel ^ E;
    //layer's been added
    void addedLayers();
};

// class that implements the interface event and function
//dodano warstwy
ref class EventSourceAdd
    : public AddI
{
public:
    virtual event AddedDel ^ E;
    virtual void addedLayers()
    {
        E();
    }
};

// class that defines the event handler
//dodano warstwy
ref class EventReceiverAdd
{
public:
    void Handler()
    {
    }
};
Deklaracja:
C/C++
AddI ^ esAdd;
//
EventReceiverAdd ^ erAdd;
Stworzenie obiektów w konstruktorze:
C/C++
//create event source
this->esAdd = gcnew EventSourceAdd();

//create event receiver
this->erAdd = gcnew EventReceiverAdd();


Przypisanie zdarzenia do funkcji (miejsce, w którym napotykany jest błąd. Core.cpp, initializeComponents()):

C/C++
this->drawing->layerSelector->esAdd->E += gcnew MultiPurposeMapEditor::AddedDel( this, & Core::addLayers );


Siedziałem nad tym już parę godzin i nie mam pojęcia dlaczego, rzekomo, obiekt "layerSelector" nie został zdefiniowany.

Używane środowisko: Visual Studio C++ 2015
P-148505
darko202
» 2016-05-23 09:37:27
komunikat błędu sugeruje, ze ma wartość nieokreśloną, czyli null.

sprawdź debug'erem
to że coś teoretycznie powinno być nie oznacza, że coś tam jest :-) 
P-148509
Raccoon
Temat założony przez niniejszego użytkownika
» 2016-05-23 21:26:51
Wiem już.
C/C++
Layers ^ layerSelector = gcnew Layers;
W pliku ForDrawing.cpp powinno wyglądać tak:
C/C++
layerSelector = gcnew Layers;

Nie wiem czemu deklarowałem na nowo ten obiekt w konstruktorze... xD Dziękuję za pomoc. Temat do zamknięcia.
P-148529
« 1 »
  Strona 1 z 1