• ↓
  • ↑
  • ⇑
 
Записи с темой: программистское (список заголовков)
23:34 

Очередная мысль

Йа волосат и бородат!
// интерфейс метода
class Some_method_interface {
public:
virtual void do_something (...) = 0;
};

// класс, для которого создается реализация
class Some_class {
private:
// Реализация метода
class Method_implementation : public Some_method_interface {
public:
virtual void do_something (...) { /*...*/ }
};
public:
/* прочие методы */
};

@темы: программистское

23:37 

Ы!

Йа волосат и бородат!
Написал тестовое приложение, которое ловит системные эвенты разных устройств. Прикольно.
Завтра попробую на работе с вебкой к которой есть дрова.

Если получится - будет круто, сделаю подобие виндового hal+udev. Можно будет прибить кучу ненужных вызовов и прочей бНОПНИ.

Сегодня в метро поймал за хвост оч удачную и умную мысль. Жаль, что я ее забыл.

@темы: программистское

14:00 

Исключение из.

Йа волосат и бородат!
Решил таки нарушить свое решение не писать больше.
Нарушить ради только одной цели - мне нужно заявить об этой мысли. И только.

Программизм

@настроение: .

@темы: программистское, личное

09:49 

Брррр...

Йа волосат и бородат!
Ушел вчера с работы в 9 вечера. Вот обьясните мне, дураку, какого черта DirectX в режиме Unicode (вызов функции с концовочкой W) возвращает строки хоть и 2-байтовые, но в кодировке ANSI? Звучит дико, но однако работает вот такое:
// вызов DirectX, передает в DSoundEnumCallback описание каждого звукового устройства
DirectSoundCaptureEnumerateW((LPDSENUMCALLBACKW)DSoundEnumCallback,(void*)&devices);

/* внутри DSoundEnumCallback:
    char* strDesc - описание устройства, при указанном вызове будет указывать на мультибайтную строку.*/
size_t wlen = wcslen((wchar_t*)strDesc);
size_t len = (wlen+1) * sizeof(char);
char * buf = new char[len];

/*WideCharToMultiByte переводит строчку из 2-байтовой в однобайтовую с использованием указанной кодировки.
    CP_ACP - ANSI-кодировка, для UTF8 надо использовать CP_UTF8*/
int n = WideCharToMultiByte(CP_ACP, 0, (wchar_t*)strDesc, wlen, buf, wlen, NULL, NULL);

А в используемой нами библиотеке вызов при конвертации правильный, с правильной кодовой страницей...

@темы: программистское, работа

21:47 

Очередное

Йа волосат и бородат!
Пришла в голову мысля, что пора бы написать себе сервис для винды, который будет писать логи. Ибо когда надо отлаживать многопоточное приложение - бывает полезно оч.

@темы: программистское

23:37 

Вот вам еще жирчику!

Йа волосат и бородат!
Итак, продолжение предыдущего поста.

Собственно, сам адаптер

Пример использования

Я опубликовал, а вы раскуривайте. :)

@темы: личное, программистское

17:03 

Хы! И вот снова!

Йа волосат и бородат!
Понадобилось мне сегодня вынести мозг сделать так, чтобы наследный класс в некоторой иерархии скрывал часть методов интерфейса родителя. Т.е. для кода, который с родителем работает - чтоб все было как прежде, а вот тот код, который с дитем связан, видеть этого кошмара не должен. Ну или должен видеть только часть интерфейса из родительской иерархии. Да, можно было бы отправить часть в private. Однако тогда у нас будет скрыт не интерфейс, а реализация метода и через тот же интерфейс можно будет до реализации достучаться.

Пример ситуации

Можно попробовать в некотором классе иерархии (не корневом, т.к. надо только на 1 подкласс) обьявить скрываемый метод невиртуальным, но толку от этого все равно не будет, если в корневом классе метод объявлен виртуальным.

В результате народилась следующая идея:

Идея, надо отметить, совершенно не новая. Адаптер в его чистом виде. Скрываемые вызовы перехватываются в классе Adaptive, остальные - банально делегируются классу Adapter, где они при необходимости уходят в реализацию классов-наследников вроде Concrete_adapter.
Adaptive сделан внутренним классом, чтоб никто до него не достучался извне, ибо его задача - исключительно делегировать вызовы по виртуальным методам.

@темы: программистское, работа

09:15 

Итак, "продолжаем продолжать" (с)

Йа волосат и бородат!
Я обещал описать как работает конструкция вот тут. Итак, были объявлены структуры ассоциируемых наборов параметров и обьявлены 2 макроса.
В нужном месте cpp-файла соответствующим макросом обьявляется структура описания, которая сразу же обьявляет свой экземпляр. Так как экземпляр обьявляется статическим, вызывается соответствующий конструктор, добавляющий себя в карту ассоциаций. Т.к. структура обьявлена макросом, то препроцессор генерирует ключ и все нужные параметры.

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

Еще пример для самых упоротых

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

@темы: программистское, работа

00:11 

И снова рабочее.

Йа волосат и бородат!
Сегодня столкнулся с интересной задачкой.
Есть сторонняя библиотека, регламентирующая вид своих плагинов. Есть набор плагинов как "вшитых" в код намертво, так и отдельных (часть из них - сторонние).
Требуется прицепить к некоторым классам из плагинов некоторые одинаковые по составу наборы данных, в соответствии один класс к многим. Причем интерфейс классов этого проводить не позволяет и даже больше - некоторые конечные классы в плагинах обьявлены только в cpp-шниках, а значит в основном приложении недоступны. Чтобы стало совсем хорошо - укажем ограничение, что в некоторых из них набор определяется параметром из режима исполнения. Клиентский код работает с объектами исключительно через интерфейсы.
Единственное, что есть у классов - аналог оператора typeid, который позволяет получить строку с именем класса.

Менять интерфейс - плохо, ибо будут проблемы с обновлением, т.к. менять надо чуть ли не в корневых классах иерархии. Строить же в использующем доп. данные коде какие-то адопостроения с различием по классам тоже не хочется, ибо нагромождение и никто не может сказать, сколько кодеков будет дальше. Было решено сделать примерно следующее:

Каждый набор представляем структурой с некоторым интерфейсом, которую будем определять по строковому ключу. Ключ будет представлять собой строчку с именем класса.
Единственное, что представляет проблему - ассоциирование класса и нескольких наборов в зависимости от некоторого условия. Ввиду того, что такая ситуация была обнаружена только во "втроенных" в код плагинах, так что в таких случаях добавляем некий метод, по которому будем различать значения. Ограничение - должна быть возможна конвертация в строку. Я в своем подходе возвращал прямо строки.

Пример для самых упоротых. :)

Как оно работает - опишу позже. :)

@темы: работа, программистское

18:03 

Более для старой работы актуально

Йа волосат и бородат!
Вместо того, чтобы тратиться на операции создания-удаления контейнеров для данных в пуле, стоило бы завести стек неиспользуемых контейнеров. И чистить его, скажем, если используется только треть отзарезервированного. Контейнеры же выдавать прям из стека, готовые.

@темы: программистское

10:57 

А в голове - каша и бардак

Йа волосат и бородат!
"И как пчелы в улье опустелом, дурно пахнут мертвые слова".
...Мертвая музыка или нерожденное полотно смердят не меньше.


(с) Княжна и неКняжна


Да, черт побери, я требую от себя идеальный код. Идеальный в плане работы, в плане понятности и в плане глубины. Но только так я могу требовать от других высококачественного кода, ворчать и критиковать.

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

Для меня такое состояние - есть полноценная депрессия, да.

@музыка: Infected Mushroom - Gamma goblins

@настроение: mad|depr|apathy

@темы: программистское, личное

20:13 

Таки интересно, что думают другие программисты

Йа волосат и бородат!
Как бы вы писали - ориентированно для понимания человеком или оптимизированно для машины (в плане бинарного кода)?

@темы: личное, программистское

18:30 

Оммм...

Йа волосат и бородат!
Будем петь и плясать индийские мантры...

for (int v = 0; v < 256; ++v) {
int s = (v << 24) >> 24;
// ...
}


(с) один из плагинов к H323plus.

UPD: А я ступил. Это оптимизация, однако.
Это эквивалентно коду:
for (int v = 0; v < 256; ++v) {
int s = (v > 127) ? -(v & 0x7f) : v;
// ...
}

Т.н. "продвижение знакового бита". По кр. мере для линуксов.
И да, этот код мягко говоря небезопасен, т.к. в 64-хбитной системе улетит к чертовой матери. Ибо sizeof (int) = 64. Ну и некоторые компиляторы могут начудить.
Так-то. (с)

@настроение: ыыы...

@темы: работа, программистское

11:08 

Ложка меда

Йа волосат и бородат!
Вот я все ругаюсь на авторов библиотеки, а нашел в коде момент, которого даже не знал.
// прототип функции
// PDynaLink::Function - typedef указателя на функцию
void foo( PDynaLink::Function & );

// FunctionPtr - typedef указателя на функцию (сигнатура отлична от PDynaLink::Function)
FunctionPtr getSmth;

// пример кастования
foo( (PDynaLink::Function &) getSmth );

Вот честно скажу - никогда доселе не видел, чтобы объект одного типа кастовали к ссылке другого типа.
Но подход оригинален.

@темы: программистское, работа

14:43 

Нашел вот в хедере вот такой коммент

Йа волосат и бородат!
// NOTE!!!!! Due to an error in judgement, you cannot add ANY more fields
// to this structure without an API version change!!!!

ЩИТО? "error in judgement"?.. Какой еще, нахрен, judgement?!

А еще мне нравится тип const void *. Выглядит даедрически.

@темы: программистское, работа

22:43 

Таки лирика. Наверное...

Йа волосат и бородат!
Давно я не писал сюда ничего кроме кода, да мелких мыслей-одиночек. А это - неправильно таки.

Начнем с того, что писать практически нечего. Да, тут несколько недель у меня тусили Трин, Мозг, Тами, Орл и Степа. Но право-дело писать об этом я не хочу ровно ничего, ибо пересказывать много, да и неупомню уже. Но лулзов было много. А писать отрывками не хочется.

Помнится, пару недель назад, я посмотрел на резюме автора centericq и был неприятно для себя удивлен. Разница в возрасте небольшая, а вот достижений больше. (Да-да, я, сцуко, завистливый!) Вот и задумался в очередной раз о необходимости дальнейшего просвещения. Не, в аспирантуру я не хочу идти - как ни крути, а защита диплома наложила свой неприятный отпечаток. И да, я знаю, что это глупо.
А думать я начал ни о чем ином, как о самообразовании путем чтения умных книг. Только вот незадача: читать их особо некогда, ибо дома у мя и так занятий полно, а на работе - тем более. Есть вариант - метро, но для этого они должны быть бумажными, а это дорого. Таскать с собой ноут совсем не хочется.
Посему подумал я о покупке кпк/ебука... но, цена кусается оч. Есть еще вариант распечатывать на работе, но боюсь огрести за это по голове от начальства. :)

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

Думал-думал... и все ж не удержусь я от кормления троллей рабочего. Ну, где же ваши розовые тапки? Из рабочего будут только личные выводы из обзора чужого кода.
Памятка на будущее

В общем, авторам библиотеки ptlib от меня - громадный disrespect. И я еще ни от одного своего сотрудника не слышал хорошего слова об этой библиотеке.

@музыка: Infected Mushroom - The Beauty and the Beat

@настроение: Мыслефлуд

@темы: домашнее, личное, программистское

11:47 

Перл, достойный code_wtf

Йа волосат и бородат!
Про порождение нового класса, хотя можно было обойтись typedef, я уже писал тут.

Теперь я столкнулся с куском кода, которым вчера заспамил знакомых программистов, ибо сам понять просто не в состоянии:
Перво-наперво есть класс и вот такие макросы (указано в порядке обьявления в хедере!):
template <class _Abstract_T, typename _Key_T = PDefaultPFactoryKey>
class PFactory {
    template <class _Concrete_T>
    class Worker { /*...*/ };
    /*...*/
};

//
// this macro is used to initialise the static member variable used to force factories to instantiate
//
#define PLOAD_FACTORY(AbstractType, KeyType) \
  namespace PWLibFactoryLoader { \
    extern int AbstractType##_##KeyType##_loader; \
    static int AbstractType##_##KeyType##_loader_instance = AbstractType##_##KeyType##_loader; \
  };

//
// this macro is used to instantiate a static variable that accesses the static member variable
// in a factory forcing it to load
//
#define PINSTANTIATE_FACTORY(AbstractType, KeyType) \
  namespace PWLibFactoryLoader { int AbstractType##_##KeyType##_loader; }

Используется вся эта радость следующим образом:
/* Файл cpp */
class PProcessStartup { /*...*/ };
class PluginLoaderStartup : public PProcessStartup { /*...*/ };

static PFactory<PProcessStartup>::Worker<PluginLoaderStartup> pluginLoaderStartupFactory("PluginLoader", true);

// PString - внутренний аналог std::string
PINSTANTIATE_FACTORY(PluginLoaderStartup, PString)


Вопросы - как работают макросы? Каким образом происходит принудительное инстанцирование шаблона?
Да, возможно это ни что иное, как рога и копыта (а, говорят, разработчики этим очень грешат), но блин... Уж такое можно было бы и подчистить.

ЗЫ: куски взяты из свободной библиотеки ptlib 2.4.5.

@темы: программистское, работа

15:30 

Код, за который убить не жалко:

Йа волосат и бородат!
while(i --> 10) { }

(с) Прислал Тами :)

Правильный код

@темы: программистское

15:15 

Гм... удивлен я.

Йа волосат и бородат!
Вот есть класс:
class PFactoryBase
{
protected:
PFactoryBase()
{ }
public:
virtual ~PFactoryBase()
{ }

// Вот почему тут сделано наследование, а не
// typedef std::map<std::string, PFactoryBase *> FactoryMap; ?
class FactoryMap : public std::map<std::string, PFactoryBase *>
{
public:
FactoryMap() { }
~FactoryMap();
};

static FactoryMap & GetFactories();

private:
PFactoryBase(const PFactoryBase &) {}
void operator=(const PFactoryBase &) {}
};

У кого-нить есть идеи? )

@темы: программистское, работа

13:02 

Таки работа, ага

Йа волосат и бородат!
На случай, если кого интересует, чем я прям сейчас занимаюсь... так это reverse-engineering пары открытых библиотек.

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

Знаю, что "reverse-engineering пары открытых библиотек" звучит весьма странно, но "любой каприз за ваши деньги!" :)

ЗЫ: поздно заметил, что одна зависимость немного "уехала", да пофиг, в общем-то.

@темы: программистское, работа

void main()

главная