Технологический прорыв
Устанавливаю сегодня Visual Studio 2010. Прогресс заметен – процесс установки идет уже три часа, за которые компьютер перезагружался четыре раза.
Думаю, наконец-то программы начнут писаться сами.
Устанавливаю сегодня Visual Studio 2010. Прогресс заметен – процесс установки идет уже три часа, за которые компьютер перезагружался четыре раза.
Думаю, наконец-то программы начнут писаться сами.
Еще один фото псто.

Давненько мне кукабарры не попадались. Или, с их точки зрения, я им не попадался.
Все относительно.
Тут только что супер-пупер шеф распальцатого ресторана с видом на Оперу давал мастер-класс.
Делал закуску. В начинку для закуски положил готовый хрен из банки, добавив, что лучше всего использовать свежий хрен (!). Живо представил себе шеф-повара с хреновым корневищем в своей шеф-кухне.
Потом еще заявил, что красная икра – это вообще не икра.
Думаю, не отправить ли этому добывателю творога из вареников килограмм настоящего хрена? Чтобы попробовал, почем фунт настоящего, свежего продукта. Может, после химической атаки на кухне и перестанет фигню всякую нести.
In the software development, the pattern when one object has send a message to another object, where the object that has to be called is given to the first class somehow (usually in constructor), is quite common. In C#, the delegates serve exactly this purpose, but in C++ it is a different story.
The most common way of implementing the class-to-class callback in C++ is to define an interface, which the class that receives the event must implement:
class IInterface
{
public:
virtual void CallbackMethod() = 0;
}
class MyClass:
public IInterface
{
public:
virtual void CallbackMethod()
{
// do something useful
}
class Publisher
{
private:
IInterface* m_pCallee;
public:
Publisher(IInterface* pCallee):
m_pCallee(pCallee)
{
}
private:
void SomeMethod()
{
m_pCallee->CallbackMethod();
}
}
}
It isn’t exactly rocket science, but this method has some downsides, and some of them are quite nasty and not obvious at all. Those are:
The last one could make you wish you never become a software programmer. The architecture, which seemed so beautiful just moments before, starts to fall into pieces once you find yourself in situation when you realize that your class-subscriber needs to receive same callbacks from different sources and act differently depending on who the caller is.
Let me explain it on the example. Imagine you have a class that implements that callback interface. You also have a lot of providers that take that interface to inform the subscribers, for example, about quote changes. But in your class, you need to track changes on, say, 10 quotes, and depending on which of those 10 changes, take different actions. So, what ’s your options?
Of course, you could just add an additional parameter to callback method that specifies the sender, but it is not pretty at all, as the subscriber class now faces a new challenge of keeping track of all publishers it is subscribed too. Not mentioning the mess in the callback method needed to get all stuff to work!
Ideally, you want each of those providers to call different methods of your subscriber class, but in a general case it would mean 10 different interfaces and changes in all publishers, which may not be possible and I don’t even want to talk about it. The other option would be to write the proxy, which implements the basic callback interface, subscribes to the only provider and then re-routes the call to certain method on your class.
Thankfully, there is the far better option. boost::bind and boost::function are here to help.
class Publisher{
public:
typedef boost::function<void (int)> typeCallbackType;
void Subscribe(typeCallbackType cb)
{
m_cb = cb;
}
private:
typeCallbackType m_cb;
void SomeDataProcessingMethod()
{
// ....
m_cb(currentPrice);
}
}
And here is a good thing: your subscriber class does not have to implement any custom interface anymore:
class MySubscriber
{
public:
void CalledWhenPriceChanges(int newPrice)
{
// make profit here
}
}
to establish a subscription, simply use boost::bind:
Publisher* pPublisher = GetPublisherFor("someTicker");
MySubscriber Subscriber;
pPublisher->Subscribe(boost::bind(&MySubscriber::CalledWhenPriceChanges, &Subscriber, _1));
That’s all, folks!
Now, once the pPublisher has a new data, a CalledWhenPriceChanged() method of Subscriber instance of a class MySubscriber will be called. It is easy to see how additional publisher could be added if you want to monitor two tickers.
It would not only help solving the problem of multiple publishers-one subscriber. This approach will also do a great job saving you time from not having to define numbers of callback interfaces for different types of data that needs to be passed from publisher to subscriber.
Только что реализовал поддержку новой фичи в протоколе одного устройства.
Устройства самого еще в железе нет. Зато есть спеки. Благодаря им поддержка фичи уже есть где надо и как часы работает с симулятором, который тоже я реализовал по спекам.
Инверсия ответственности тут в том, что теперь в случае всяких непредвиденных обстоятельств (хотя какие они непредвиденные? Очень даже предвиденные – где это видано,чтбы железка на 100% соответствовала спекам?), это именно железячные программеры будут допиливать свою железку, чтобы уже мой софт смог с ним работать. А не наоборот, как это чаще всего бывает при разработке клиентского софта для железок.
Чувствую себя по меньшей мере Доктором Зло.
Кажется, австралийское телевидение транслирует вирусы по цЫфровым каналам.
Бо мой MythTV стал почему-то молча падать. Молча падать, когда включаем TEN. Это сегодня TEN, вчера он работал, зато не работала его версия из Newcastle. А сегодня наоборот.
Остальные каналы работают.
Отладчиком ковыряццо лениво. С бубном что ли попрыгать?
Предварительные результаты этой недели показали, что
Думаю, стоит попробовать себя в игре на рояле.
Петров, в дождь обгоняющий Шумахера за четыре круга до финиша. Картина маслом по сыру. Шесть очков.
Интересная гонка получилась.
P.S. Пресса подтянулась.
Тут случайно выпал повод оказаться на дальнем полустанке. С фотоаппаратом. Там, как водится, трава ровно по пояс. А еще туда прибылъ поездъ.

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