Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/9: Рейтинг темы: голосов - 9, средняя оценка - 4.67
Заблокирован

Оконный менеджер. Как лучше хранить указатели на элементы менеджера?

08.11.2014, 13:34. Показов 1886. Ответов 9
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Привет! Делаю тут 3D движок
В общем есть главный класс движка mgeSystem, так же есть класс окна mgeWindow, который не наследуется от класса mgeWindow.
В общем в эти классы окна представляют функционал по работе с окнами Windows, их может быть много.
Я создаю окно так сказать
C++
1
mgeWindow* window = new mgeWindow;
для включения этого окна в главный евент луп системы, я добавляю это окно в главный класс движка:
C++
1
2
3
4
//Это клиентский код, НЕ код движка
mgeSystem* system = new mgeSystem;
mgeWindow* window = new mgeWindow;
system->AddWindow(window );
Всё, теперь моё окно показано на экране и обрабатывает сообщения каким - то образом...:
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
int mgeSystem::RunSystemLoop()
{   
    bool exit = false;
    while (!exit)
    {
        for (auto it = engineWindows.begin(); it != engineWindows.end();)
        {
            if (!(*it)->ProcessMessage())
            {
                delete *it;
                it = engineWindows.erase(it);
                if (engineWindows.empty())
                {
                    exit = true;
                    break;
                }               
            }
            else
                it++;
        }
    }
    return 0;
}

В общем, юзер может нажать мышкой на крестик закрытия окна, чтоб окно закрыть и окно должно будет закрыться (именно это окно, окон может быть много)
В классе движка mgeSystem храниться std::set с указателями на окна для прорисовки и обработки сообщений:
C++
1
std::set<mgeWindow*> engineWindows;
В главном классе движка есть собственно две функции - для добавления окна в список обработки сообщений и удаления из него:
C++
1
2
void AddWindow(mgeWindow* window);
void RemoveWindow(mgeWindow* window);
Тут собственно и вопрос. Как лучше хранить указатели на эти окна и стоит ли вообще это делать, но если не хранить, то как с ними работать?

Смотрите. Вот в коде игры ( в клиентском коде ), я создал окно поредствам new, добавил его в систему, всё тип топ, окно отображается и у меня на него есть указатель. Но вот если юзер нажимает допустим на крестик и хочет закрыть окно, то что я делаю... Я удаляю его из списка для обработки в главном классе движка, так же удаляю его по указателю, который храниться в это списке, но в таком случае указатель во внешнем коде, в клиентском, на это окно становится не валидным, ну то есть если я удаляю окно внутри движка, то указатель на него в клиентском коде соответственно становится "левым".
Можно конечно в движке не удалять это окно, а просто удалять его из списка, НО:
По скольку класс mgeWindow - это класс - оболочка над стандартным окном HWND ОС Windows, то после того, как юзер его закроет крестиком, я уничтожу само виндусовское окно DestroyWindow-вом, инкапсулированное в классе mgeWindow и вроде всё ок, но сам данный экземпляр класса mgeWindow по сути станет бесполезным, т.к. внутри него окно уже уничтожено. Как же быть... ?
Как организовать удаление окна из системы? Может вообще не давать юзеру указателя на новое окно, создавая его в системном классе, ну как то так: system->CreateWindow, но как тогда юзер сможет работать с этим окном в клиентском коде?
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
08.11.2014, 13:34
Ответы с готовыми решениями:

Оконный менеджер
Добрый день, граждане. Возник вопрос, скорее архитектурный, может подскажете. Разрабатываю клиент-серверное приложение, в котором...

Зависает оконный менеджер
У меня на работе стоит Windows 7 x86, Домашняя базовая, и вот когда долго ПК работает часа 4 примерно, начинает тормозит ужасно проводник,...

Как лучше закодировать app.config connectionStrings? Или лучше не здесь хранить подключение к бд?
Я знаю, что app.config можно кодировать через консоль или же с помощью...

9
3258 / 2060 / 351
Регистрация: 24.11.2012
Сообщений: 4,909
08.11.2014, 14:00
Лучший ответ Сообщение было отмечено -THE_MASTER666- как решение

Решение

Пусть во внутренних структурах движка хранятся указатели shared_ptr на окна, а пользователю отдаются weak_ptr.
1
Заблокирован
08.11.2014, 14:05  [ТС]
Цитата Сообщение от 0x10 Посмотреть сообщение
пользователю отдаются weak_ptr
Ух ты, классная штуковина, я о такой даже не знал! то что надо, спасибо!
Как будут первые успехи по игре - кину ссылку на тред с ней и демкой
0
Студент
 Аватар для MickeyBlueEyes
121 / 132 / 39
Регистрация: 07.04.2011
Сообщений: 503
08.11.2014, 14:08
Шаред птр могуч
0
08.11.2014, 14:10  [ТС]

Не по теме:

Цитата Сообщение от MickeyBlueEyes Посмотреть сообщение
Шаред птр могуч
Да, только может порой обнулить указатель в самом неожиданном месте:)

0
3258 / 2060 / 351
Регистрация: 24.11.2012
Сообщений: 4,909
08.11.2014, 14:12
Цитата Сообщение от -THE_MASTER666- Посмотреть сообщение
Да, только может порой обнулить указатель в самом неожиданном месте
Это как так?
0
Заблокирован
08.11.2014, 14:22  [ТС]
Цитата Сообщение от 0x10 Посмотреть сообщение
Это как так?
Да....долго рассказывать.
Навёл тут справки про weak_ptr, на самом деле это не какой - то сказочное средство, на что я понадеялся сначала
Если посмотреть на стандартный пример:
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
#include <iostream>
#include <memory>
 
std::weak_ptr<int> gw;
 
void f()
{
    if (auto spt = gw.lock()) { // необходимо скопировать в shared_ptr перед использованием
        std::cout << *spt << "\n";
    }
    else {
        std::cout << "gw is expired\n";
    }
}
 
int main()
{
    {
        auto sp = std::make_shared<int>(42);
        gw = sp;
 
        f();
    }
 
    f();
}
то можно заметить, что перед использованием этого слабого указателя нужно вызвать его функцию:
if (auto spt = gw.lock()) ... Хмм, но ведь с таким же успехом, я мог бы в своём экземпляре класса mgeWindow так же проверять его "хорошесть" То есть в движке ничего не удалять, а выставлять в классы окна какой - то флаг - мол окно удалено, а перед использованием какой - то функции этого окна проверять:
C++
1
2
if(window->IsGood())
    windows->DoAweSome();
0
3258 / 2060 / 351
Регистрация: 24.11.2012
Сообщений: 4,909
08.11.2014, 14:27
Цитата Сообщение от -THE_MASTER666- Посмотреть сообщение
То есть в движке ничего не удалять
1. Обязывает клиента всегда проверять валидность объекта. В случае с weak_ptr нельзя обойти lock.
2. В памяти остаются болтаться окна-"пустышки". Только ради флагов.
0
08.11.2014, 14:31

Не по теме:

Цитата Сообщение от -THE_MASTER666- Посмотреть сообщение
По скольку класс mgeWindow - это класс - оболочка над стандартным окном HWND ОС Windows
Меня эта строчка смутила, или я ничего не шарю? Мне казалось что в главном окне просто рисуют все(окна чисто виртуальные, а не физические реальные окна).

0
Заблокирован
08.11.2014, 14:38  [ТС]
Цитата Сообщение от 0x10 Посмотреть сообщение
1. Обязывает клиента всегда проверять валидность объекта. В случае с weak_ptr нельзя обойти lock.
2. В памяти остаются болтаться окна-"пустышки". Только ради флагов.
Ну да да .. Наверное всё верно. Но я тут подумал, что я не совсем правильно проектирую движок.
Нужно делать главный класс движка в модуле движка (DLL), а в клиентском коде от него наследоваться и всю работу с игрой делать в рамках этого саб класса, в котором можно будет переопределить некоторые защищённые функции, например windowsEvent(), в который бы прилетал указатель на окно, которое нужно удалить...

Добавлено через 3 минуты
Цитата Сообщение от greenlight Посмотреть сообщение
Мне казалось что в главном окне просто рисуют все(окна чисто виртуальные, а не физические реальные окна).
Та же самая история повториться и для виртуальных окон на самом деле.
Но для общего развития сообщу, что например, в том же 3DS Max есть в стандартной раскладке 4 окна проекций.
То есть есть главное окно с GUI (кнопки и пр) + дополнительных отдельных 4 окна, которые просто напросто являются дочерними. А в других программах эти окна можно вообще хоть на втором мониторе открывать.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
08.11.2014, 14:38
Помогаю со студенческими работами здесь

Установлены xfce4 и оконный менеджер blackbox
Установлены xfce4 и оконный менеджер blackbox По команде startx запускается xfce4. Как запустить blackbox, не удаляя xfce4?

Какой оконный менеджер меньше всего жрет ресурсов компьютера, FluxBox, OpenBox, BlackBox или IceWM?
Привет всем. Собственно вопрос в заголовке. Есть слабое железо Пентиум 2 , ОЗУ 64 Мб. Надо чтоб не тормозило. Дистрибутив будет SlackWare....

Как лучше хранить массив?
Есть 3 многомерных массива. два из них тип int один strig в каждом около 1000 записей они не будут меняться. Подскажите кто как их хранит...

Как лучше хранить товары в БД?
Добрый день. Скажите, плз, кто знает, как лучше хранить товары в БД? Товары разбиты на категории. В некоторые категориях есть...

Как лучше хранить данные
Имеется клиент и сервер с БД. После авторизации клиент получает данные из БД. Данные приходят в виде текста ( примерно 30 000 строк )....


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Новые блоги и статьи
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru