Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> удаленный вызов. детали, реализация, архитектура, у темы новое название! 
:(
    Опции темы
boostcoder
  Дата 6.10.2010, 11:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



всем доброго дня.
имеем тип T:
Код

template<typename T>
struct any_type {
   enum { id = unique_id };
   typedef ... get_type;
   typedef ... set_type;
};

в runtime мы получаем id`ы.
хочу реализовать что-то вроде типозависимого прокси callable`ра(хз как правильно назвать).

сигнатура методов/объектов такая:
Код

void method(T::set_type& set, const T::get_type& get);


нужна возможность регистрировать методы/объекты имея в runtime только id, и ин compile_time T::id.
т.е. зная T::id ат compile_time и id в runtime, назначать методы/объекты принимающие соответствующие им типы.

пример конечного использования:
Код

// any types
struct type1 { id = ... };
struct type2 { id = ... };
struct type3 { id = ... };
...
struct proxy { // registrator
   template<typename T>
   void reg(method_with_needed_signature_ptr);
};
// methods impl
...
void method1(type1::set_type& set, const type1::get_type& get) {}

void method2(type2::set_type& set, const type2::get_type& get) {}

void method3(type3::set_type& set, const type3::get_type& get) {}
...
// reg in proxy
proxy.reg<type1>(method1);
proxy.reg<type2>(method2);
proxy.reg<type3>(method3);

...
// call proxy
int id = ...
type1 arg = ...
proxy(id)(arg.set_type, arg.get_type);


как-то так...
запутался, и ничего в голову не лезет...

Это сообщение отредактировал(а) boostcoder - 3.4.2011, 01:58
PM WWW   Вверх
xvr
Дата 6.10.2010, 11:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(boostcoder @  6.10.2010,  11:23 Найти цитируемый пост)
нужна возможность регистрировать методы/объекты имея в runtime только id, и ин compile_time T::id.

IMHO сие невозможно. Либо id должен быть известен в compile time, либо реализация proxy вообще не должна зависеть от id

Либо я не понял требования задачи - что с чем и по каким признакам надо связать? Во что должен развернуться
Код

proxy(id)(arg.set_type, arg.get_type);
?


PM MAIL   Вверх
mes
Дата 6.10.2010, 11:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(boostcoder @  6.10.2010,  10:23 Найти цитируемый пост)
зная T::id ат compile_time и id в runtime

это разные числа , или одно и то же ? 



--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 6.10.2010, 17:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(xvr @  6.10.2010,  11:32 Найти цитируемый пост)
Во что должен развернуться

если id == type1::id, то должен произойти вызов method1(...)


Цитата(mes @  6.10.2010,  11:46 Найти цитируемый пост)
это разные числа , или одно и то же ?

int id имеет диапазон type1::id ... typeN::id

два уточнения:
1. typeN::id - это enum. так что можно использовать в mpl.
2. у всех typeN общий предок.


Это сообщение отредактировал(а) boostcoder - 6.10.2010, 17:21
PM WWW   Вверх
mes
Дата 7.10.2010, 01:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



было б лучше если б дали немного сведений и о задачи, а именно какие требования предъявляются к рантайм..

вот на полусне : http://liveworkspace.org/code/c8cf16a805aa...0bc837af0545038
в том хоть направлении ?

Добавлено через 3 минуты и 27 секунд
это Вы удаленный вызов реализуете ?

Добавлено через 5 минут и 19 секунд
Цитата(boostcoder @  6.10.2010,  16:19 Найти цитируемый пост)
2. у всех typeN общий предок.

Цитата(boostcoder @  6.10.2010,  10:23 Найти цитируемый пост)
(type1::set_type& set, const type1::get_type& get) 

а что ж тогда не объект класса typeN передается  ?





--------------------
PM MAIL WWW   Вверх
maxim1000
Дата 7.10.2010, 08:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 3334
Регистрация: 11.1.2003
Где: Киев

Репутация: 17
Всего: 110



Цитата(boostcoder @  6.10.2010,  11:23 Найти цитируемый пост)
proxy(id)(arg.set_type, arg.get_type);

в параметрах должны быть типы или значения соответствующих типов?



--------------------
qqq
PM WWW   Вверх
boostcoder
Дата 7.10.2010, 08:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(mes @  7.10.2010,  01:02 Найти цитируемый пост)
это Вы удаленный вызов реализуете ?

да.

Цитата(mes @  7.10.2010,  01:02 Найти цитируемый пост)
в том хоть направлении ?

похоже на то. покурю...

Цитата(mes @  7.10.2010,  01:02 Найти цитируемый пост)
а что ж тогда не объект класса typeN передается  ?

можно и тип. но задача не упростится. я для пользователя удобней и понятней.

Цитата(maxim1000 @  7.10.2010,  08:44 Найти цитируемый пост)
в параметрах должны быть типы или значения соответствующих типов?

значения.
PM WWW   Вверх
mes
Дата 7.10.2010, 09:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(boostcoder @  7.10.2010,  07:50 Найти цитируемый пост)
можно и тип. но задача не упростится. я для пользователя удобней и понятней.

при использовании структуры кол-во аргументов функции постоянно.


--------------------
PM MAIL WWW   Вверх
mes
Дата 7.10.2010, 15:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



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

template <class T> 
void register_handler ( void (*fn)(const T&) )
{
     arr[T::id] = (fn_t)fn;    
}
 

register_handler (&f1);



подправленная версия :  http://liveworkspace.org/code/3b42cd08948e...84cf01e63c3374e



--------------------
PM MAIL WWW   Вверх
maxim1000
Дата 8.10.2010, 00:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 3334
Регистрация: 11.1.2003
Где: Киев

Репутация: 17
Всего: 110



можно упаковывать полученные аргументы в boost::any
а методы оборачивать во что-то шаблонное, унаследованное от общего интерфейса (который и принимает эти boost::any)

Добавлено через 55 секунд
(правда, не получится пользоваться неявными преобразованиями)


--------------------
qqq
PM WWW   Вверх
mes
Дата 8.10.2010, 09:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



в примере обработчиками выступают функции, но у конечному пользователь захочется иметь что либо более универсальное..поможет класс Dispatchera, для конвертации параметра и класс функции (напр boost::function)
http://liveworkspace.org/code/09b6daf1e59d...aee0c15a1aff76d

на "ляпы"  не относящиеся к сути проблемы (такие как неподходящий способ хранения) внимания не обращать smile



--------------------
PM MAIL WWW   Вверх
mes
Дата 8.10.2010, 22:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



кстати вспомнил, goldfinch  одно время на форуме разбирал темы связанные с удаленными вызовами..
не помню к чему он там конкретно пришел, но думаю Вам будет тематически полезно ознакомиться с этим материалом.. 
если найдете прикрепите ссылки к теме, плиз
smile


--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 9.10.2010, 03:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(mes @  8.10.2010,  22:23 Найти цитируемый пост)
кстати вспомнил, goldfinch

я даже аккаунта такого не могу найти. и функцию поиска аккаунтов тоже :(

пока курю ваш пример. хочется автоматизировать это все.
написать кодогенератор на препроцессоре - не проблема. но есть несколько неудобных моментов. думаю...

Это сообщение отредактировал(а) boostcoder - 9.10.2010, 03:12
PM WWW   Вверх
boostcoder
Дата 9.10.2010, 07:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



mes, сделал так, как вы предложили:
Код

/***************************************************************************/

struct i_dispatcher {
   virtual ~i_dispatcher() {}
   virtual void dispatch(constants::header_packet&, constants::body_packet&) = 0;
};

/***************************************************************************/

template<typename C, typename T>
struct methods_dispatcher: i_dispatcher {
   typedef void(C::*handler_t)(typename T::result_type&, const typename T::query_type&);
   /**  */
   methods_dispatcher(C& p, handler_t h):_this(p),_handler(h) {}

   virtual void dispatch(constants::header_packet& h, constants::body_packet& b) {
      typename T::query_type query = deserializer(h, b);
      typename T::result_type result;
      (_this.*_handler)(result, query);
      serializer(h, b, result);
   }

private:
   C& _this;
   handler_t _handler;
};

/***************************************************************************/

template<typename C>
struct proxy_caller {
   proxy_caller(C* p, constants::header_packet& h, constants::body_packet& b)
      :_parent(p),_header(h),_body(b)
   {}

   template<typename T>
   void register_handler(typename methods_dispatcher<C, T>::handler_t handler) {
      if ( _map.find(T::id) != _map.end() ) {
         throw std::runtime_error("id(" +  boost::lexical_cast<std::string>((int)T::id) + ") already registered");
      }
      _map[T::id] = dispatcher_ptr(new methods_dispatcher<C, T>(*_parent, handler));
   }

   void call() {
      constants::header hdr = constants::decode_header(_header);
      _map[hdr.id]->dispatch(_header, _body);
   }

private:
   C* _parent;
   constants::header_packet& _header;
   constants::body_packet& _body;
   typedef boost::shared_ptr<i_dispatcher> dispatcher_ptr;
   std::map<int, dispatcher_ptr> _map;
};

/***************************************************************************/


используется это дело так:
Код

struct implementation {
   implementation():_proxy(this, ....) {
      _proxy.register_handler<type1>(&implementation::method1);
      _proxy.register_handler<type2>(&implementation::method2);
   }

   void method1(type1::result_type& r, const type1::query_type& q) {
   }
   void method2(type2::result_type& r, const type2::query_type& q) {
   }

   proxy_caller<implementation> _proxy;
};


метод proxy_caller::call() вызывается из сетевой части после того, как буфера на которые ссылается proxy_caller заполнены.
как видно из реализации метода methods_dispatcher::dispatch(), ответ отправляется обратно при выходе из тела этого метода.
не худшая реализация RPC из тех что я видел smile 
но хочется большего.
а именно: скрыть от юзера все, кроме самого implementation.

в идеале, цель хочу видеть такой:
Код

// декларация интерфейса некоторого типа.
INTERFACE_BEGIN(transaction_type)
   METHOD(
      std::string, // ret
      login, // method name
      std::string, // method arg
      std::string // method arg
   )
   METHOD(
      std::string, // ret
      get_balance, // method name
      std::string, // method arg
      std::string // method arg
   )
INTERFACE_END()

// код клиента
client<transaction_type> client(host, port);
std::string ret = client.login("nick", "pass");
ret = client.get_balance("date from", "date to");

но тут есть непонятка...
т.к. клиент, всего лишь дергает методы сервера, ему их реализация не нужна. но она нужна серверу.
вот и непонятка: что на самом деле нужно на стороне клиента, чтоб дергать методы сервера? и что нужно знать серверу, чтоб понять, какой именно метод вызывает клиент?
PM WWW   Вверх
mes
Дата 9.10.2010, 10:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(boostcoder @  9.10.2010,  02:12 Найти цитируемый пост)
я даже аккаунта такого не могу найти. 

ну проще было искать тему, и поставить ограничение по юзеру..
вобщем вот об этой я говорил :
http://forum.vingrad.ru/forum/topic-269086...tml#st_0_view_0


Это сообщение отредактировал(а) mes - 9.10.2010, 10:53


--------------------
PM MAIL WWW   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1549 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.