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

Поиск:

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


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


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

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



Цитата(boostcoder @  4.12.2010,  14:53 Найти цитируемый пост)
и? 

пока времени не было продолжить размышления smile



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


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


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

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



Цитата(mes @  4.12.2010,  12:34 Найти цитируемый пост)
метод может иметь прототип и определение..
первого достаточно для вызова, второе необходимо для выполнения.. 

нам даже важно не это..
есть вызов метода, и его исполнение.. ну а также перенос данных.. 

можно заменить на такие стадии :
формирование пакета метода, передача пакета и исполнение.. 

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

попробую для начала набросать вариант такого пакета..

Добавлено @ 22:11
ну пусть выглядит так :
Код

struct login {
 login (std::string const& name
       ,std::string const& pass ) : _name (name), _pass (pass) {}

  typedef std::function<void(std::string const&, std::string const&)> executor_t;
  void invoke (executor_t e)  const
  {
     e (_name, _pass);
  }

  std::string _name;
  std::string _pass;
         
};

тогда нам нужен адаптер позволяющий вызывать invoke с подходящим ехecutor`ом..


Это сообщение отредактировал(а) mes - 5.12.2010, 22:24


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


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


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

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



Цитата(mes @  5.12.2010,  21:04 Найти цитируемый пост)
тогда нам нужен адаптер позволяющий вызывать invoke с подходящим ехecutor`ом..

примерно может выглядить так :
Код

struct i_exec_visitor
{
      virtual void accept (void const*) =0; // либо (packet_t &)
};

template <typename T, Fn>
struct exec_visitor : i_exec_visitor
{ 
      exec_visitor (Fn fn) : _fn(fn) {}
      virtual void accept (void const* pack) 
      {
           static_cast<T const*>(pack)->invoke (_fn);
      }
      Fn _fn;      
};


template <T>
void exec<T> (map_of_executors_t& map, T const& pack)
{
    auto it = map.find(pack::method_id);
    if (it != map.end())
      it->accept (pack);
}


1. типобезопасное составление таблицы виртуальных методов  (map_of_executors_t) решается шаблоной функцией добавления в таблицу.. 
2. также таблица естественно внутренность класса, и exec<Т> его метод..
3. производство exec_visitor тоже внутрение, при добавлении в таблицу.. для безопасности каста.. 



Это сообщение отредактировал(а) mes - 5.12.2010, 22:31


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


pattern`щик
****


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

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



Цитата(mes @  5.12.2010,  22:27 Найти цитируемый пост)
1. типобезопасное составление таблицы виртуальных методов  (map_of_executors_t) решается шаблоной функцией добавления в таблицу.. 
2. также таблица естественно внутренность класса, и exec<Т> его метод..
3. производство exec_visitor тоже внутрение, при добавлении в таблицу.. для безопасности каста.. 

простите, конечно, но ни один из пунктов не понял на 100% smile 
PM WWW   Вверх
mes
Дата 6.12.2010, 00:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(boostcoder @  5.12.2010,  21:39 Найти цитируемый пост)
простите, конечно, но ни один из пунктов не понял на 100% 

соответствие пакета экзекутору определяет ид метода.. если в таблице по индексу будет расположен не подходящий экзекутор, то smile 
для этого запись в карту, ну и соответственно, чтение должны происходить только в соответсвии с ид.. 
для того чтоб обеспечить такую гарантию методы работы с картой 
1. должны быть шаблонами от типа сообщения
2. должны быть членами классами, приватной частью которого является карта..

Добавлено через 51 секунду
но это опять таки реализации, и в принципе к сути происходящего отношения не имеет.. разве что объясняет гарантию на безопасность кастов.. 



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


pattern`щик
****


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

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



понял.

Цитата(mes @  6.12.2010,  00:05 Найти цитируемый пост)
но это опять таки реализации, и в принципе к сути происходящего отношения не имеет..

вот уже несколько дней, меня мучает один вопрос:  к чему Вы это? чего хотите добиться? невъезжаю..

Это сообщение отредактировал(а) boostcoder - 6.12.2010, 00:10
PM WWW   Вверх
mes
Дата 6.12.2010, 00:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



в результате.. вызов происходит так

out << login (name, pass);

составление таблицы:

map[T::method_id] = new exec_visitor<login>(fn);
где fn - bind или lambda <void (string,string)>

Добавлено через 1 минуту и 2 секунды
Цитата(boostcoder @  5.12.2010,  23:10 Найти цитируемый пост)
  к чему Вы это? чего хотите добиться? невъезжаю..

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

Добавлено через 3 минуты и 25 секунд
в прошлых примерах вас не устраивало передача посредством сообщениям, и хотелось развернутого вида..
так вот в последнем сообщении пакет описывается именно так :
 login (std::string const& name
       ,std::string const& pass ) : _name (name), _pass (pass) {}
  typedef std::function<void(std::string const&, std::string const&)> executor_t;

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

Добавлено через 4 минуты и 59 секунд
дело в том что с этим пакетом можно многое еще делать прежде чем доставить пользователю.. или другими словами можно по разному доставить пользователю.. вот тут и вопросы, что вообще должно уметь дисколи ? вот над этим и думаю smile

Добавлено через 10 минут и 14 секунд
если взять  пример с прошлой страницы, то заметно что мы в нашей схеме теряем параметр _client передаваемый серверу..,
но параметр должен входить в состав пакета, либо он не нужен при использовании юзер_контекста- любой из этих случаев протоколозависим и отношения к дисколи не имеет.. но говорит нам о том, что пример для теста мы выбрали не подходящий.. 



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


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


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

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



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

namespace client_side {
struct client
{
    struct auth 
    {
       void login  (..) { _remote << cts::user (..); }
       void logout (..) { _remote << cts::quit (..); }
       void on_welcome  (..) {  }
       void on_quit (..) {  }
     private:
       remote<cts::user, cts::quit> _remote;
    } _auth;

};
}

аналогично выглядит представитель на серверной стороне :
Код

namespace server_side {
struct user_context 
{
    struct auth 
    {
       void on_user (..) { _remote << ((cond)? stc::welcome (..) : stc::quit (..)); }
       void on_quit (..) { _remote << stc::quit (..); }
    private:
       remote<stc::welcome, stc::quit> _remote;
  
    } _auth;

};
}

1. как происходит передача сообщения я умолчал.. пока допустим что smile 
2.  вместо структуры auth может быть например auth_window

если смысл примера понятен, то вопрос , устраивает ли подобный вид кода ? 


Это сообщение отредактировал(а) mes - 6.12.2010, 01:07


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


pattern`щик
****


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

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



Цитата(mes @  6.12.2010,  00:44 Найти цитируемый пост)
устраивает ли подобный вид кода ?

вполне.
а Вас устраивает?
PM WWW   Вверх
mes
Дата 6.12.2010, 01:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(boostcoder @  6.12.2010,  00:09 Найти цитируемый пост)
а Вас устраивает? 

пока вроде да.. пойдем думать дальше..

Добавлено @ 01:18
терь нам нужно в пример добавить диспетчер..

Добавлено @ 01:25
допустим такой :
Код

struct dispatcher
{
    template<typename P, typename Fn>
    void set_handler (Fn fn)
    {
          _map[P::method_id] = new exec_visitor<P, Fn> (fn);
    }
    void exec (discoly::packet const& pack); // packet - база всех пакетов
    {
         if (auto it = _map.find (..) )
          .. it->accept(pack);
    }
    .. _map;
};


Это сообщение отредактировал(а) mes - 6.12.2010, 01:36


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


pattern`щик
****


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

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



для ассоциации команд реальным методам, нам все равно нужен meta_proxy<> с промежуточными методами и списком команд. в таком случае, у нас получается ситуация которую я уже приводил: http://liveworkspace.org/code/a14dee96202f...0567a3f20507540
что в таком способе неудобно - это то, что meta_proxy<> должен располагать именами реальных методов в то время, как самой реализации и ее методов еще не существует. чтоб такой код компилировался, нужно воротить шаблонную реализацию. это тоже своего рода неудобность. но удобнее и реальнее способа я не нашел.

Добавлено через 1 минуту
Цитата(mes @  6.12.2010,  01:17 Найти цитируемый пост)
new exec_visitor<Packet, Fn> (fn);

Packet - это P ?
PM WWW   Вверх
mes
Дата 6.12.2010, 01:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



тогда клиент будет:
Код

namespace client_side {
struct client
{
    struct auth 
    {
       void login  (..) { _remote << cts::user (..); }
       void logout (..) { _remote << cts::quit (..); }
       void on_welcome  (..) {  }
       void on_quit (..) {  }

        auth (discoly::connection _conn)  : _remote (_conn) {}
     private:
       remote<cts::user, cts::quit> _remote;
    } _auth;

    void connect (..) {..}
    void disconnect () {..}

    client () : _auth(_connection)
   {
        _connection.set_responder( bind(&discoly::dispatcher::exec, _auth_map, _1) );

        _auth_map.set_handler<stc::welcome> (bind (auth::on_welcome, _auth, _1, _2 ));
        _auth_map.set_handler<stc::quit>    (bind (auth::on_quit,    _auth, _1 ));
   }

  private:
    discoly::tcp_connection _conn;
    discoly::dispatcher<stc::welcome, stc::quit> _auth_map;
};
}


Добавлено @ 01:36
Цитата(boostcoder @  6.12.2010,  00:28 Найти цитируемый пост)

Packet - это P ? 

ага P - исправил..

Добавлено @ 01:40
мне в этом примере не нравится слишком длинная строка 

Цитата(mes @  6.12.2010,  00:36 Найти цитируемый пост)
_auth_map.set_handler<stc::welcome> (bind (auth::on_welcome, _auth, _1, _2 ));

которую в принципе можно  заменить на такую 
Код

_auth_map
    .on<stc::welcome> (auth::on_welcome, _auth, _1, _2 )
    .on<stc::quit>    (auth::on_quit,    _auth, _1 );
// где аргументы .on связываются bind`ом.. 


Это сообщение отредактировал(а) mes - 6.12.2010, 09:13


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


pattern`щик
****


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

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



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


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


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

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



Цитата(boostcoder @  6.12.2010,  02:36 Найти цитируемый пост)
кто такой _auth_dispatcher ? 

его я переименовал в _auth_map (исправил в коде)



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


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


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

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



терь, судя по коду, явно видно, что _auth_map должна быть внутри auth, но, в отличии (от ремоте) не должна быть подключена к соединению..

Добавлено @ 09:43
Код

struct auth 
{
      auth (discoly::connection _conn)  : _remote (_conn) { reg (); }
 
      void dispatch (i_packet const& pack)
      {
           _mtd_map.dispatch (pack);
      }
     
       void reg () {
             _mtd_map
                  .on<stc::welcome> (auth::on_welcome, _auth, _1, _2 )
                  .on<stc::quit>    (auth::on_quit,    _auth, _1 );
       }   
 

       void login  (..) { _remote << cts::user (..); }
       void logout (..) { _remote << cts::quit (..); }

   protected:
       void on_welcome  (..) {  }
       void on_quit (..) {  }

   private:
      discoly::remote<cts::user, cts::quit> _remote;
      discoly::mtd_map<stc::welcome, stc::quit>  _mtd_map;    // раньше _auth_map
}

Код


struct client
{

    client () : _auth(_connection)
    {
         _connection.set_responder( 
               [this](discoly::i_packet const& pack)
               {
                      auth.dispatch (pack);
               } 
             );
    }
       
    void connect (..) {..}
    void disconnect () {..}

    auth _auth; 
   
  private:

    discoly::tcp_connection _conn;
  
};


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


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

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

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

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

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


 




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


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

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