В продолжении темы Аргументы за и против длинных имён функций. Я вот сидел и думал как организовывать для себя API с учётом что пользоваться буду только я один и пришёл к выводам что
- 1- Функции должны быть маленькими и делать только что-то одно и делать это хорошо.
- 2-Имена функций должны быть явными и исключить неоднозначности длинна именования не является важной
- 3-Имена функций должны быть единообразными, они не должны выглядеть чужеродными внутри одного проекта
- 4-Обработка ошибок должна быть заложена в сами функции и производится автоматически
- 5-Если возможно избежать побочных эффектов, констант,флагов и прочего это избегается ибо пункт 1
Я решил, жёстко следовать этим правилам, по итогу у меня человеко читаемые функции которые не надо помнить ибо их имя это имя + глагол + дополнение в зависимости от контекста и всё. Да , длинно функции плодятся, но было всё здорово... пока я не пришёл к обработке клавиатуры и там у меня более 500 функций Карл! на каждую клавишу и символ, типа так
bool keyboard_event_keydown_shift();
bool keyboard_event_keyup_shift();
bool keyboard_state_key_shift();
bool keyboard_bind_key_shift(void(*callback)(bool));
bool keyboard_unbind_key_shift(void(*callback)(bool));
Блин, оно всё удобно, имена явные, можно убрать shift в аргумены сведя сотни функций к одной,но усложнится реализация,а длинна останется той же ибо shift как аргумент никуда не денется,и да если что состояние клавиши и эвенты нажал/отпустил это разное если что, я не знаю, я что-то делаю не так...
Я хочу при построении API явность, единообразность, простоту, с тем как я к этому подхожу выходидят побочки в виде очень большого API и порой очень длинных функций. Я хотел сделать всё по иному, но каждый раз прихожу к вот этому. Ну вот к примеру полностью законченная обработка мышки
#ifndef cmouse_h
#define cmouse_h
#include "cgraphics.h"
#include "cengine.h"
#include "cevent.h"
typedef struct mouse mouse;
typedef struct mouse
{
struct{
int position_x;
int position_y;
vec2 position;
int relative_x;
int relative_y;
vec2 relative;
bool keydown_left;
bool keydown_right;
bool keydown_middle;
bool keyup_left;
bool keyup_right;
bool keyup_middle;
bool wheel_up;
bool wheel_down;
bool wheel_left;
bool wheel_right;
bool evented_key;
bool evented_wheel;
bool evented_position;
bool evented;
}event;
struct{
int position_x;
int position_y;
vec2 position;
bool key_left;
bool key_right;
bool key_middle;
bool relative_mode;
}state;
}mouse;
/* ==debug== */
mouse mouse_get();
void mouse_print(mouse mou);
/* ==events== */
bool mouse_evented();
bool mouse_evented_position();
vec2 mouse_event_position();
int mouse_event_position_x();
int mouse_event_position_y();
vec2 mouse_event_relative();
int mouse_event_relative_x();
int mouse_event_relative_y();
bool mouse_evented_key();
bool mouse_event_keydown_left();
bool mouse_event_keydown_right();
bool mouse_event_keydown_middle();
bool mouse_event_keyup_left();
bool mouse_event_keyup_right();
bool mouse_event_keyup_middle();
bool mouse_evented_wheel();
bool mouse_event_wheel_up();
bool mouse_event_wheel_down();
bool mouse_event_wheel_left();
bool mouse_event_wheel_right();
/* ==states== */
bool mouse_state_key_left();
bool mouse_state_key_right();
bool mouse_state_key_middle();
vec2 mouse_state_position();
int mouse_state_position_x();
int mouse_state_position_y();
vec2 mouse_state_relative();
bool mouse_state_relative_mode();
/* ==setters event+state== */
void mouse_set_position(int x, int y);
void mouse_set_position_x(int x);
void mouse_set_position_y(int y);
void mouse_set_relative_mode(bool rel);
void mouse_set_relative(int x, int y);
void mouse_set_relative_x(int x);
void mouse_set_relative_y(int y);
void mouse_set_keydown_left();
void mouse_set_keydown_right();
void mouse_set_keydown_middle();
void mouse_set_keyup_left();
void mouse_set_keyup_right();
void mouse_set_keyup_middle();
void mouse_set_wheel_up();
void mouse_set_wheel_down();
void mouse_set_wheel_left();
void mouse_set_wheel_right();
/*if you need nonconflict relative status mouse
use this template
--------------------------------------------
static int curr_x=0;
static int curr_y=0;
int prev_x=0;
int prev_y=0;
prev_x = curr_x;
prev_y = curr_y;
curr_x = mouse_state_position_x();
curr_y = mouse_state_position_y();
int rel_x = curr_x - prev_x;
int rel_y = curr_y - prev_y;
---------------------------------------------
rel_x and rel_y it actual relative
value for current frame time
*/
/* ==binds== */
bool mouse_bind(void(*callback)(mouse));
void mouse_unbind(void(*callback)(mouse));
void mouse_bind_update(void);
bool mouse_bind_evented(void(*callback)(bool));
bool mouse_bind_evented_key(void(*callback)(bool));
bool mouse_bind_evented_wheel(void(*callback)(bool));
bool mouse_bind_evented_position(void(*callback)(bool));
bool mouse_bind_event_position(void(*callback)(vec2));
bool mouse_bind_event_position_x(void(*callback)(int));
bool mouse_bind_event_position_y(void(*callback)(int));
bool mouse_bind_event_relative(void(*callback)(vec2));
bool mouse_bind_event_relative_x(void(*callback)(int));
bool mouse_bind_event_relative_y(void(*callback)(int));
bool mouse_bind_event_keydown_left(void(*callback)(bool));
bool mouse_bind_event_keydown_right(void(*callback)(bool));
bool mouse_bind_event_keydown_middle(void(*callback)(bool));
bool mouse_bind_event_keyup_left(void(*callback)(bool));
bool mouse_bind_event_keyup_right(void(*callback)(bool));
bool mouse_bind_event_keyup_middle(void(*callback)(bool));
bool mouse_bind_event_wheel_up(void(*callback)(bool));
bool mouse_bind_event_wheel_down(void(*callback)(bool));
bool mouse_bind_event_wheel_left(void(*callback)(bool));
bool mouse_bind_event_wheel_right(void(*callback)(bool));
bool mouse_bind_state_key_left(void(*callback)(bool));
bool mouse_bind_state_key_right(void(*callback)(bool));
bool mouse_bind_state_key_middle(void(*callback)(bool));
bool mouse_bind_state_position(void(*callback)(vec2));
bool mouse_bind_state_position_x(void(*callback)(int));
bool mouse_bind_state_position_y(void(*callback)(int));
/* ==unbinds== */
void mouse_unbind_event_position(void(*callback)(vec2));
void mouse_unbind_event_position_x(void(*callback)(int));
void mouse_unbind_event_position_y(void(*callback)(int));
void mouse_unbind_event_relative(void(*callback)(vec2));
void mouse_unbind_event_relative_x(void(*callback)(int));
void mouse_unbind_event_relative_y(void(*callback)(int));
void mouse_unbind_event_keydown_left(void(*callback)(bool));
void mouse_unbind_event_keydown_right(void(*callback)(bool));
void mouse_unbind_event_keydown_middle(void(*callback)(bool));
void mouse_unbind_event_keyup_left(void(*callback)(bool));
void mouse_unbind_event_keyup_right(void(*callback)(bool));
void mouse_unbind_event_keyup_middle(void(*callback)(bool));
void mouse_unbind_event_wheel_up(void(*callback)(bool));
void mouse_unbind_event_wheel_down(void(*callback)(bool));
void mouse_unbind_event_wheel_left(void(*callback)(bool));
void mouse_unbind_event_wheel_right(void(*callback)(bool));
void mouse_unbind_state_key_left(void(*callback)(bool));
void mouse_unbind_state_key_right(void(*callback)(bool));
void mouse_unbind_state_key_middle(void(*callback)(bool));
void mouse_unbind_state_position(void(*callback)(vec2));
void mouse_unbind_state_position_x(void(*callback)(int));
void mouse_unbind_state_position_y(void(*callback)(int));
#endif
Это уже звоночек в клиннику (повторюсь, я решил попробовать придерживаться одной идеи и глянуть что выходит).
Короче, я хочу просто идей,как сделать по иному, не частных случаев типа «нуууу можно заменить position на pos» или «ну можно вынести всё в аргументы и завести 100500 флагов и констант»,а хочется принципиальных изменений где сочетаются пункты которые я выше указал, то как я сделал мне очень удобно, но одновременно очень не нравится ибо оно громоздко и по итогу уродливо вот чисто визуально.