Action List
От: explorer Украина  
Дата: 16.08.03 14:22
Оценка:
Здравствуйте.
Вопрос такой: есть Action List со списком действий. Пользователь выбирает в базе данных поле, которому соответствует другое поле (строка) с названием действия. Как запустить действие из списка Action List, используя это название?
Re: Action List
От: Kluev  
Дата: 16.08.03 17:32
Оценка:
Здравствуйте, explorer, Вы писали:

E> Здравствуйте.

E> Вопрос такой: есть Action List со списком действий. Пользователь выбирает в базе данных поле, которому соответствует другое поле (строка) с названием действия. Как запустить действие из списка Action List, используя это название?

А что за действия то? "Наливай и пей" или "шагом марш"?
Re[2]: Action List
От: explorer Украина  
Дата: 16.08.03 21:08
Оценка:
Здравствуйте, Kluev, Вы писали:
K>А что за действия то? "Наливай и пей" или "шагом марш"?

Действия разные, например — движение мыши в указанном напрвлении, запуск программ, в общем — разные функции API. То есть в Action Liste уже есть определенные действия, написаны их обрабаотчики. Мне нужно "сопоставить" этим обработчикам выбранные из списка комманды, которые могут называться как угодно, хоть "наливай и пей"
Re: Action List
От: MaximE Великобритания  
Дата: 17.08.03 09:55
Оценка:
Здравствуйте, explorer, Вы писали:

E> Вопрос такой: есть Action List со списком действий. Пользователь выбирает в базе данных поле, которому соответствует другое поле (строка) с названием действия. Как запустить действие из списка Action List, используя это название?


Если я тебя правильно понял, и тебе необходимо вызывать функции, имена которых ты получаешь в runtime в виде строки, то это можно сделать так:

////////////////////////////////////////////////////////////////////////////////

#include <iostream>
#include <string>
#include <map>
#include <stdexcept>

#include <boost/function.hpp>
#include <boost/bind.hpp>

////////////////////////////////////////////////////////////////////////////////

using boost::function;
using boost::bind;

using namespace std;

////////////////////////////////////////////////////////////////////////////////

class executor
{
public:
    typedef function<void()> command;

    void register_command(const string& command_name, const command& cmd)
    {
        commands_[command_name] = cmd;
    }

    void unregister_command(const string& command_name)
    {
        commands_.erase(command_name);
    }

    command::result_type execute(const string& command_name)
    {
        command_map::const_iterator i(commands_.find(command_name));
        if(commands_.end() != i)
            return i->second();
        else
            throw logic_error("command is not registered");
    }

private:
    typedef map<string, command> command_map;
    command_map commands_;
};

////////////////////////////////////////////////////////////////////////////////

void on_command_abc()
{
    cout << "executing command \"abc\"\n";
}

void on_command_def()
{
    cout << "executing command \"def\"\n";
}

struct some
{
    void on_command_ghi()
    {
        cout << "executing command \"ghi\"\n";
    }

    void on_command_jkl()
    {
        cout << "executing command \"jkl\"\n";
    }
};

////////////////////////////////////////////////////////////////////////////////

int main()
{
    executor e;

    // команды "abc" и "def" выполняют функции
    e.register_command("abc", &on_command_abc);
    e.register_command("def", &on_command_def);
    // команды "ghi" и "jkl" выполняют функции-члены объекта s
    some s;
    e.register_command("ghi", bind(&some::on_command_ghi, &s));
    e.register_command("jkl", bind(&some::on_command_jkl, &s));

    e.execute("abc");
    e.execute("def");
    e.execute("ghi");
    e.execute("jkl");

    e.execute("cba"); // oops - такая команда не зарегистрирована

    return 0;
}

////////////////////////////////////////////////////////////////////////////////
Re[2]: Action List
От: explorer Украина  
Дата: 17.08.03 12:38
Оценка:
Здравствуйте, MaximE, Вы писали:

ME>Если я тебя правильно понял, и тебе необходимо вызывать функции, имена которых ты получаешь в runtime в виде строки, то это можно сделать так...


Совершенно верно! Это мне и нужно. Но у меня возник вопрос (прошу прощения, если он покажется глупым ), — я не совсем разобрался в вашем коде. Компилятор (Borland C++ builder 6) недоволен этими строками:

ME>#include <boost/function.hpp>

ME>#include <boost/bind.hpp>

И еще, если не трудно, объясните в двух словах работу класса executor.
Re[3]: Action List
От: MaximE Великобритания  
Дата: 18.08.03 07:51
Оценка:
Здравствуйте, explorer, Вы писали:

E>Совершенно верно! Это мне и нужно. Но у меня возник вопрос (прошу прощения, если он покажется глупым ), — я не совсем разобрался в вашем коде. Компилятор (Borland C++ builder 6) недоволен этими строками:


ME>>#include <boost/function.hpp>

ME>>#include <boost/bind.hpp>

Похоже, что у тебя не установлена библиотека boost. Ее можно скачать с www.boost.org

Кроме того, так как ты используешь BCB, то видимо, надо использовать синтаксис не function<void()>, а function0<void>.

E>И еще, если не трудно, объясните в двух словах работу класса executor.


Имя command немного непродумано, надо его зареплейсить на handler (обработчик).

Класс executor — небольшая обертка (я бы сказал, комментарий ) над ассоциативным массивом commands_, в котором ключами являются строки (имена команд), а значениями — обработчики этих команд (boost::function<> — обобщенный указатель на функцию). Т.е. имея строчку мы можем попытаться вызвать связанный с этой строчкой обработчик, чем и занимается функция execute. Если commands_ не содержит элемента (обработчика) с таким ключом (строчкой), будет сгенерировано исключение. Соответственно, функция register_command() принимает строчку и обобщенный указатель на функцию, и помещает их в ассоциативный массив commands_. Функция unregister_command() принимает строчку и удаляют из массива элемент с данным ключом.
Re[4]: Action List
От: explorer Украина  
Дата: 18.08.03 14:41
Оценка:
Здравствуйте, MaximE.

Огромное спасибо!!! Вы мне очень поиогли. Сегодня вечером скачаю библиотеку и буду разбираться.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.