- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
static enum rc (*request_functions[])(void) = {
ko,
koko,
kokoko,
illegal_request
};
static inline enum rc illegal_request(void) { return ILLEGAL_REQUEST; }
reply.rc = request_functions[cmd.opcode < NKEYS(request_functions) ? cmd.opcode : ILLEGAL_REQUEST]();
Но вообще молодцы что возвращают ILLEGAL_REQUEST а не выполняют какой-то случайный код на который там дальше в памяти указатель случайно оказался
лэйбл "poor man's" неприменим. потому что в С нет другуго способа. только свитч/кейс и таблица функций. на практике, таблица функций 20-30% быстрее.
Для сишников наверное годно собрать в памяти указатели на функции и по ним скакать
Ты так говоришь, как-будто питонисты не собирают функции в мап, чтобы по ним скакать.
В конце концов можно сделать так
Чтобы из разных мест понарегать туда 100500 функций-обработчиков. Может быть даже в рантайме их добавлять при подгрузке каких-нибудь плагинов или конфигов...
А ваш вариант, простите, вообще какое-то говно. Ибо позволяет дергать любые методы MessageServer'а - и "приватные" и унаследованные...
для кода сверху
ну ок, я напишу так:
всё еще джсвей?
1) лишние функции/свойства недоступны (что спасёт от уязвимостей, если в accept прилетают внешние данные)
2) класс используется по назначению и содержит мап, а не используетя в качестве оного
3) можно прикрутить декоратор для удобной регистрации (см. ниже)
4) можно получить список доступных обработчиков (что при использовании класса как мапа превращается в говнище)
5) у этого объекта могут быть нормальные методы, которые не смешиваются в кучу с обработчиками
P.S. Я надеюсь,что install_new_handler не написан через setattr? :)
Ну или хотябы манглит методы добавляя пару подчеркиваний. На самом деле даже одного подчеркивания бы хватило, потому что уже тогда они не засирали бы публичный контракт. А в непубличном можно гусе что угодно делать
... называется энтерпрайз!!!
При старте демон сканил папку, искал в ней модули и загружал их. Каждый модуль регал один или несколько хендлеров в глобальную мапу.
При запросе демон искал хендлер в мапе и исполнял его.
Говно, как считаете?
Да там и кода то ненамного больше. Строчек 50-100 от силы в main'е. Остальное в тех самых модулях.
P.S. Сейчас бы я поюзал flask и не ебал бы мозг с самодельным RPC. А тогда бакой был ;(
Блин, а ведь выглядит как обращение. Походу, я лох и обосрался с пунктуацией. Сорри :)
Оно и на современных языках часто оказывается нужно. Например, С++ vs Object Pascal, диспатч через С++ виртуальный метод был на порядок быстрее чем в Дельфе, почему приходилось в узких местах в ручную таблицы указателей на методы делать, с диспатчем не сильно отличающимся от того как в ГК.
Ну хотя бы тайпдеф то можно было сделать... Чтобы enum не писать каждый раз, и была возможность перепилить на uint32_t...
Например у атмела:
видимо считают что так удобнее, сразу видно где у нас запись, а где енум. Других объяснений не вижу.
но делать сам тип кода возврата enum'ом это совсем другое.
с другой стороны, у "сраных дефайнов" есть Н-ое количество преимуществ, в оссобенности для больших проектов. например можно проверить определен ли уже код ошибки или нет. в добавок, синтакс не требует этих грёбаных запятых, которые при переливании кодов из одного языка в другой надо выкидывать. распилить кучу дефайнов я могу и на шелле - но что бы распилить кучу enum'ов как минимум перл желателен.
Обоснуйте.
это работает только на простых проектах, на которых внутренний rc это просто overdesign.
на больших проектах это значит что объявление энума будет жутким хаком, потому что должно содержать коды с большого количества файлов/модулей/подмодулей. что в принципе сделать одним централизованым определением часто просто невозможно. если даже какими инклюдами извращатся, то либо определение будет зависеть от порядка инклюдов, или просто нельзя полагатся на численное значение кода. (ну и двоичная совместимость с либами в ж вылетает.) либо надо все значения прописывать в ручную - и в этот момент ты оказываешься в том же самом корыте что и со сраными дефайнами.
ёбаная ритчи уебанское это опять объявление сука
сишные enum/struct/union (захардкоженые в язык) это прародители современных нэймспэйсов (юзер дефайнабл).
на практике весьмя удобно (хотя и очень ограничено), потому что нет конфликта между именами переменных и именами типов.
enum[ТИП]{}
[ТИП] в данном случае есть указатель на функцию которая ничего не принимает (void)
Не совсем. В энуме опкодов его нет.
Кстати, ваш код идентичен ГК если раз-inline-ить функцию illegal_request.
Но, тем не менее, он равен числу опкодов + 1. И вот это уже пиздец...
В енуме rc лежит такое значение, которое равно количеству элементов +1 в енуме опкодов.
Вариант gumbert'а лучше, т.к. не вносит неявной связи между двумя енумами.