Форум программистов, компьютерный форум, киберфорум
Наши страницы

Пишу игровой движок на C++. 022. события

Войти
Регистрация
Восстановить пароль
Исходные коды движка - https://github.com/532235/GoST
Документация

Другой хобби-проект в группе в вк https://vk.com/club154291467
Рейтинг: 5.00. Голосов: 1.

Пишу игровой движок на C++. 022. события

Запись от 532235 размещена 23.12.2017 в 23:09

Для чего нужны события.

Для того, чтобы можно было понять, что происходит в программе.
Изменилось ли положение окна, была ли нажата клавиша(мышь, геймпад, клавиатура), была ли нажата кнопка на экране и т.д.


Должен быть сам объект события.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
/* события будут пополнятся по мере необходимости */
#define GT_EVENT_WINDOW_SIZING   1u
#define GT_EVENT_WINDOW_RESTORE  2u
#define GT_EVENT_WINDOW_MAXIMIZE 3u
#define GT_EVENT_WINDOW_MINIMIZE 4u
#define GT_EVENT_WINDOW_MOVE     5u
#define GT_EVENT_WINDOW_PAINT    6u
 
    //  событие
    struct gtEvent{
 
        gtEvent( void ):
            type( ET_NONE ),
            value1( -1 ),
            value2( -1 ),
            dataSize( 0u ),
            data( nullptr )
        {}
 
        enum type_t{
            ET_NONE,
            ET_KEY,
            ET_CHAR,
            ET_MOUSE,
            ET_JOY,
            ET_GUI,
            ET_SYSTEM
        }type;
        
        s32 value1;
        s32 value2;
 
        u32 dataSize;
        void* data;
 
    };
    
    class gtEventConsumer{
    public:
 
        virtual void processEvent( const gtEvent& ev ) = 0;
 
    };
Например, нажали на клавишу
type = ET_KEY
value1 = id клавиши
value2 = что-то ещё, возможно символ

gtEventConsumer будет получать события.


В движке создам класс gtEventSystem, который будет хранить все события и вызывать gtEventConsumer

Туда же добавлю реализацию gtEventConsumer для движка - gtEngineEventConsumer
Думаю, вполне возможно может понадобится получать сообщения внутри движка.
Но пока будет только класс, пока события обрабатываются пользовательским gtEventConsumer
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#pragma once
#ifndef __GT_EVENT_SYSTEM_H__
#define __GT_EVENT_SYSTEM_H__
 
/*
*/
 
namespace gost{
 
    /* идея взята у Doom 3 */
    constexpr u32 EventMax = 64u;
 
    class gtEventSystem : public gtRefObject{
 
 
        gtEventConsumer * m_engineConsumer;
        gtEventConsumer * m_userConsumer;
 
        gtEvent m_events[ EventMax ];
        u32 m_numOfEvents;
        u32 m_currentEvent;
 
 
    public:
 
        gtEventSystem( gtEventConsumer* ec, gtEventConsumer* uc = nullptr );
        virtual ~gtEventSystem( void );
 
        void runEventLoop( void );
 
        void addEvent( const gtEvent&, u8 prior );
    };
 
    //  =============================================================
 
    class gtEngineEventConsumer : public gtEventConsumer{
    public:
 
        gtEngineEventConsumer();
        ~gtEngineEventConsumer();
        
        void processEvent( const gtEvent& ev );
 
    };
 
}
 
 
#endif
реализация gtEventSystem.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
gtEventSystem::gtEventSystem( gtEventConsumer* ec, gtEventConsumer* uc ):
    m_engineConsumer( ec ),
    m_userConsumer( uc ),
    m_numOfEvents( 0u ),
    m_currentEvent( 0u )
{}
 
gtEventSystem::~gtEventSystem( void ){
}
 
void gtEventSystem::runEventLoop( void ){
    while( true ){
 
        if( m_events[ m_currentEvent ].type == gtEvent::ET_NONE )
            break;
 
        if( m_userConsumer )
            m_userConsumer->processEvent( m_events[ m_currentEvent ] );
 
        m_events[ m_currentEvent ].type = gtEvent::ET_NONE;
 
 
        m_currentEvent++;
        if( m_currentEvent == m_numOfEvents )
            m_currentEvent = 0u;
    }
 
    m_numOfEvents = 0u;
}
 
void gtEventSystem::addEvent( const gtEvent& ev, u8 prior ){
    if( m_numOfEvents < EventMax ){
        m_events[ m_numOfEvents ] = ev;
        m_numOfEvents++;
    }
}
 
//  =============================================================
 
gtEngineEventConsumer::gtEngineEventConsumer(){
}
 
gtEngineEventConsumer::~gtEngineEventConsumer(){
}
 
void gtEngineEventConsumer::processEvent( const gtEvent& ev ){
 
}

сам объект gtEventSystem ноходится в gtMainSystemCommon
C++
1
2
3
4
5
6
gtPtr<gtEventSystem> m_events;
public:
void initEventSystem( void );
 
    //  добавить событие. inFront если вперёд.
void        addEvent( const gtEvent&, u8 prior = 0u );
C++
1
2
3
4
5
6
7
8
void gtMainSystemCommon::initEventSystem( void ){
    m_events        = gtPtrNew<gtEventSystem>( new gtEventSystem( &m_engineConsumer, m_params.m_consumer ) );
}
 
    //  добавить событие. inFront если вперёд.
void        gtMainSystemCommon::addEvent( const gtEvent& ev, u8 prior ){
    m_events->addEvent( ev, prior );
}

В gtMainSystem.h надо добавит метод для добавления события
C++
1
2
    //  добавить событие. prior - приоритет - 0 обычный, 1 самый важный
virtual void        addEvent( const gtEvent&, u8 prior = 0u ) = 0;
В том же файле нужно изменить структуру для запуска движка. Надо добавить указатель на пользовательский обработчик событий.
gtDeviceCreationParameters
C++
1
2
3
4
5
6
gtDeviceCreationParameters( void ):
            m_outputWindow( nullptr ),
            m_consumer( nullptr )
            ...
            
gtEventConsumer*    m_consumer;


В gtMainSystemWin32 нужно инициализировать EventSystem
::init
C++
1
this->initEventSystem();

В gtMainSystemWin32::update добавить
C++
1
this->m_events->runEventLoop();

Осталось послать события окна.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
LRESULT CALLBACK gtWindowWin32::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){
    PAINTSTRUCT ps;
    HDC hdc;
    gtWindowWin32* pD = nullptr;
 
    s32 wmId    = LOWORD(wParam);
    s32 wmEvent = HIWORD(wParam);
 
 
    gtEvent ev;
    ev.type = gtEvent::ET_SYSTEM;
 
    if( !pD ){
        if (message == WM_NCCREATE)   {
            pD = static_cast<gtWindowWin32*>(reinterpret_cast<CREATESTRUCT*>(lParam)->lpCreateParams);
            SetLastError(0);
            if (!SetWindowLongPtr(hWnd, -21, reinterpret_cast<LONG_PTR>(pD)))
                if (GetLastError() != 0)             return FALSE;
            return DefWindowProc(hWnd, message, wParam, lParam);
        }
        else{
            pD = reinterpret_cast<gtWindowWin32*>(GetWindowLongPtr(hWnd, -21));
        }
    }
 
    switch( message ){
    case WM_COMMAND:
        // Parse the menu selections:
        switch (wmId)
        {
        
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
        }
        break;
    case WM_QUIT:
        PostQuitMessage( 0 );
        break;
 
    case WM_MOVE:
        ev.value1 = GT_EVENT_WINDOW_MOVE;
    break;
    case WM_PAINT:
        ev.value1 = GT_EVENT_WINDOW_PAINT;
        break;
    case WM_SIZE:{
        switch( wmId ){
        case SIZE_MAXIMIZED:
            ev.value1 = GT_EVENT_WINDOW_MAXIMIZE;
            break;
        case SIZE_MINIMIZED:
            ev.value1 = GT_EVENT_WINDOW_MINIMIZE;
            break;
        case SIZE_RESTORED:
            ev.value1 = GT_EVENT_WINDOW_RESTORE;
            break;
        }
    }break;
    case WM_SIZING:
            ev.value1 = GT_EVENT_WINDOW_SIZING;
        break;
    case WM_DESTROY:
        PostQuitMessage( 0 );
        break;
    }
 
    gtMainSystem::getInstance()->addEvent( ev );
 
    return DefWindowProc( hWnd, message, wParam, lParam );
}

ПРОГРАММА
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
class eventConsumer : public gtEventConsumer{
public:
 
    void processEvent( const gtEvent& ev ){
 
        switch( ev.type ){
            case gtEvent::ET_SYSTEM:{
                switch( ev.value1 ){
                case GT_EVENT_WINDOW_MAXIMIZE:
                    gtLogWriter::printInfo( u"Window maximized" );
                    break;
                case GT_EVENT_WINDOW_MINIMIZE:
                    gtLogWriter::printInfo( u"Window minimized" );
                    break;
                case GT_EVENT_WINDOW_MOVE:
                    gtLogWriter::printInfo( u"Window moved" );
                    break;
                case GT_EVENT_WINDOW_PAINT:
                    gtLogWriter::printInfo( u"Window painted" );
                    break;
                case GT_EVENT_WINDOW_RESTORE:
                    gtLogWriter::printInfo( u"Window restored" );
                    break;
                case GT_EVENT_WINDOW_SIZING:
                    gtLogWriter::printInfo( u"Change size" );
                    break;
                }
            }break;
        }
        
    }
};
 
 
....
 
int main(){
 
    eventConsumer   events;
 
    gtDeviceCreationParameters params;
    params.m_consumer = &events;
 
     
    gtPtr<gtMainSystem> my_system( gtPtrNew<gtMainSystem>( InitializeGoSTEngine(params) ) );


https://github.com/532235/GoST
Размещено в Игровой движок
Просмотров 196 Комментарии 0
Всего комментариев 0

Комментарии

 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.