jarg

Форум для проектов, находящихся на стадии Альфа и Бета. В них ещё не реализована вся задуманная автором функциональность, а значит идёт активная разработка.

Модераторы: Sanja, Максим Кич

Аватара пользователя
Cfyz
Сообщения: 776
Зарегистрирован: 30 ноя 2006, 10:03
Откуда: Санкт-Петербург
Контактная информация:

Re: jarg

Сообщение Cfyz » 28 янв 2016, 14:36

Jesus05 писал(а):если придумать систему непересекающихся номеров событий
Если уникальность номеров нужна только в рантайме и только в рамках одного приложения, то можно воспользоваться стандартными средствами С++11:

Код: Выделить всё

#include <typeinfo>
struct Event {
    virtual ~Event() { }
    size_t getTypeId() {
        return typeid(*this).hash_code();
    }
};
[/s]

Все вычеркнуть. hash_code это действительно хеш и в теории может вернуть один код для разных типов.
Пытается раскуклиться

Аватара пользователя
Cfyz
Сообщения: 776
Зарегистрирован: 30 ноя 2006, 10:03
Откуда: Санкт-Петербург
Контактная информация:

Re: jarg

Сообщение Cfyz » 28 янв 2016, 15:35

ishellstrike писал(а):ну это сильное заявление, у хеша, конечно бывают коллизии, но шанс этого довольно маленький.
Маленький он или нет, это уже какое-то стохастическое программирование получается; может, значит полагаться нельзя =(
ishellstrike писал(а):А вообще проще сделать штуку, вроде
Ага, я даже начал писать об этом в качестве работы над ошибками, но вы успели раньше. Тут только нюанс, что шаблон не получится использовать полиморфно в рантайме: например, нельзя вызвать метод базового класса, который сам проинспектирует объект и вернет идентификатор. Пришлось бы переопределять этот медод и его возвращаемое значание в каждом наследнике (или да, заполнять дополнительное поле в конструкторе каждого наследника), что определенно утомительно. Самое опрятное, что у меня получалось сделать, это использовать CRTP:

Код: Выделить всё

struct Event {
	virtual ~Event() { }
	virtual int getId() = 0;
};

template<typename T> struct NumberedEvent: Event {
	int getId() {
		return getNumericTypeId<T>();
	}
};

struct UpdateEvent: NumberedEvent<UpdateEvent> {
    // ...
};
Как минимум, это переносит "инициализацию" значения в объявление типа и все-таки использует имена вместо дополнительного списка констант.

Also, саму функцию NextTid нельзя объявлять static, потому что тогда получится несколько независимых next_id. Зато ее можно объявить inline и это гарантирует, что static size_t next_id будет одна на все приложение.
Пытается раскуклиться

Аватара пользователя
Cfyz
Сообщения: 776
Зарегистрирован: 30 ноя 2006, 10:03
Откуда: Санкт-Петербург
Контактная информация:

Re: jarg

Сообщение Cfyz » 28 янв 2016, 16:18

ishellstrike писал(а):Не пойму почему нельзя, другое дело, что сейчас (этот кусок довольно старый) бы я ее лучше объявил отдельно от класса в каком нибудь анонимном неймспейсе, но все же не ясно, почему в случае со static будет ошибка
Проблема в использовании NextTid в нескольких файлах. Если только все события не будут определены в одном-единственном месте, получится что в нескольких объектных файлах окажется по собственной копии со всеми потрохами, включая счетчик.
Пытается раскуклиться

Аватара пользователя
Jesus05
Сообщения: 1840
Зарегистрирован: 02 дек 2009, 07:50
Откуда: Норильск, сейчас Санкт-петербург.
Контактная информация:

Re: jarg

Сообщение Jesus05 » 28 янв 2016, 16:24

Cfyz писал(а):
Jesus05 писал(а):если придумать систему непересекающихся номеров событий
Если уникальность номеров нужна только в рантайме и только в рамках одного приложения, то можно воспользоваться стандартными средствами С++11:

Код: Выделить всё

#include <typeinfo>
struct Event {
    virtual ~Event() { }
    size_t getTypeId() {
        return typeid(*this).hash_code();
    }
};
[/s]

Все вычеркнуть. hash_code это действительно хеш и в теории может вернуть один код для разных типов.
На самом деле уникальность думаю должна быть на уровне компиляции.
т.е. уникальный тип событий должен быть с уникальным префиксом.
думаю можно что-то типа const char* name = typeid(*this).name(); использовать вроде MsVc и GСС всем классам дают уникальные имена (GCC их манглит конечно :) но они все равно остаются уникальными)

адд: продолжая размышления :) о именах класса.... насколко я понимаю typeid(*this).name(); фактически вернет указатель на константную строку. можно помнить и сранивать не саму строку а просто хранить адрес куда указывает typeid(*this).name(); итого будем иметь 4-8 байт лишних в событии которые будут уникально указывать тип события. + подтип определенный enum-омо в пределах класса.

Аватара пользователя
Jesus05
Сообщения: 1840
Зарегистрирован: 02 дек 2009, 07:50
Откуда: Норильск, сейчас Санкт-петербург.
Контактная информация:

Re: jarg

Сообщение Jesus05 » 28 янв 2016, 16:55

Я тоже уже вычитал что есть type_index в с++11 http://www.cplusplus.com/reference/type ... ype_index/

Аватара пользователя
Cfyz
Сообщения: 776
Зарегистрирован: 30 ноя 2006, 10:03
Откуда: Санкт-Петербург
Контактная информация:

Re: jarg

Сообщение Cfyz » 28 янв 2016, 17:24

Идея со сравнением адресов type_info::name() или самих объектов type_info очень занимательна. Хотя чисто технически, компилятор вправе выдать по одному и тому же типу два разных объекта (или две разные строки имен) с идентичным содержанием =). Я затрудняюсь предположить как это будет работать между несколькими динамическими библиотеками. Но в пределах одного модуля наверняка можно пользоваться.
Jesus05 писал(а):Я тоже уже вычитал что есть type_index в с++11
Но type_index скорее всего лишь обертка над type_info: в GCC 4.6.3 он только хранит указатель и форвардит операции сравнения. А сравнение type_info много где реализовано неоптимально, например в том же 4.6.3 это сделано через strcmp, наверняка как раз чтобы работало с динамической линковкой.
Пытается раскуклиться

Аватара пользователя
Jesus05
Сообщения: 1840
Зарегистрирован: 02 дек 2009, 07:50
Откуда: Норильск, сейчас Санкт-петербург.
Контактная информация:

Re: jarg

Сообщение Jesus05 » 01 фев 2016, 07:46

захожу сегодня на геймдев а там.... http://www.gamedev.ru/code/articles/eve ... cpp_eleven "Простая система событий на С++11"

Аватара пользователя
kipar
Сообщения: 2120
Зарегистрирован: 10 мар 2010, 13:16
Откуда: Москва

Re: jarg

Сообщение kipar » 01 фев 2016, 09:21

Главное комментарии не читай, там толпа икспертов и систему и ее автора с грязью мешают.

Аватара пользователя
Jesus05
Сообщения: 1840
Зарегистрирован: 02 дек 2009, 07:50
Откуда: Норильск, сейчас Санкт-петербург.
Контактная информация:

Re: jarg

Сообщение Jesus05 » 01 фев 2016, 11:02

Когда постил ссылку статью еще не прочитал :) ну и коментарии прочитал позже... все равно думаю что посмотреть можно. хотя кажется основные тезисы мы и здесь уже обсудили.

Аватара пользователя
Jesus05
Сообщения: 1840
Зарегистрирован: 02 дек 2009, 07:50
Откуда: Норильск, сейчас Санкт-петербург.
Контактная информация:

Re: jarg

Сообщение Jesus05 » 01 фев 2016, 12:23

А почему безумный? 1000 монстров походив сообщает 1000-чей событий "мы походили, новые координаты X,Y". 10000 травы просмотрели событие на простой фильтр "а касается ли это нас?" если касается как-то отреагировали.
Это если обработчик событий общий и на него все подписаны... а если монстр наступая на траву вызывает ее личное OnEvent с событием "Я пришел на тебя". твоя старая система же примерно так работала, там-же не было общего обработчика событий. (ну там и событий не было, точнее они были жестко закодированны)

Аватара пользователя
karagy
Сообщения: 1271
Зарегистрирован: 10 янв 2007, 14:13

Re: jarg

Сообщение karagy » 01 фев 2016, 17:26

Смотрел я намедни псевдокод Инкуршена, с тамошними

Код: Выделить всё

On Event ...
On Event EV_PREREQ
PRE(EV_PRAY)
GODWATCH(PRE(EV_HIT))
GODWATCH(POST(EV_EFFECT))
...
- а в голове упорно вертелась мысль - что иногда (иногда!) имеет смысл держать фильтрующие функции не в диспетчере или получателе, но при самом эвенте.

Аватара пользователя
Jesus05
Сообщения: 1840
Зарегистрирован: 02 дек 2009, 07:50
Откуда: Норильск, сейчас Санкт-петербург.
Контактная информация:

Re: jarg

Сообщение Jesus05 » 02 фев 2016, 06:45

karagy писал(а):Смотрел я намедни псевдокод Инкуршена, с тамошними

Код: Выделить всё

On Event ...
On Event EV_PREREQ
PRE(EV_PRAY)
GODWATCH(PRE(EV_HIT))
GODWATCH(POST(EV_EFFECT))
...
- а в голове упорно вертелась мысль - что иногда (иногда!) имеет смысл держать фильтрующие функции не в диспетчере или получателе, но при самом эвенте.
Ты имеешь ввиду что-бы было:

Код: Выделить всё

Event->isHit();
Event->isEffect();

Аватара пользователя
karagy
Сообщения: 1271
Зарегистрирован: 10 янв 2007, 14:13

Re: jarg

Сообщение karagy » 02 фев 2016, 08:26

Инкуршен - это только фон к размышлениям. Внутри там всё по-своему хорошо.

Я имею ввиду группировку нетривиальных фильтров при эвенте. Пока не могу придумать яркий пример когда удобней вынести фильтр в эвент (для производительности, либо для группировки кода).

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

Ответить

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 5 гостей