Fuzzy no-dice
Well as promised, I recorded my last TDD session on tape. Unfortunately NOT as promised... it is undeliverable as is... er... the words were too fuzzy (analog VCR tape... shoulda known).
I was hopin to have a nice y00t00b link or something today... oh well [smile]
If I weren't getting ready to go back to The U of U CS School, I'd have this done already.
What I will do is watch the tapes and put everything down on paper ... and then HERE... for you instead. In written form.
Some Big, Fat Policies
We're done with the "Tile Loading" iteration, and ready for some integration testing now. Just to give you a TASTE of the pain that is "policy-based" design... here is the exact rough-up of the typedefs we'll have to use to get our newly TDD'ed objects off the ground:
typedef MS::dx::ddraw::Tile tile_t; typedef bawd::graphics::_TileSet tileset_t; typedef MS::dx::ddraw::TileImplCreator tile_impl_creator_t; typedef MS::win32::graphics::bitmap::GetSourceBits get_source_bits_t; typedef MS::win32::graphics::bitmap::ParseHeader parse_header_t; typedef MS::dx::ddraw::bitmap::ConvertHeaderToScreen convert_header_t; typedef MS::win32::graphics::utility::ConvertPixelToX1R5G5B5 convert_pixel_16_t; typedef bawd::graphics::utility::colors::Bit24Alpha bit_24_alpha_t; typedef bawd::graphics::utility::colors::OpaqueAlpha opaque_alpha_t; typedef MS::win32::graphics::bitmap::GetPalette get_palette_t; typedef MS::win32::system::api::callers::LoadLibrary_ load_library_t; // not tested typedef MS::win32::system::api::callers::FreeLibrary_ free_library_t; // not tested typedef MS::win32::system::api::callers::memcpy_ memcpy_t; // not tested typedef MS::win32::system::api::callers::FindResource_ find_resource_t; // not tested typedef MS::win32::system::api::callers::LoadResource_ load_resource_t; // not tested typedef MS::win32::system::api::callers::LockResource_ lock_resource_t; // not tested typedef MS::win32::system::api::callers::DeleteObject_ delete_object_t; // not tested typedef MS::win32::system::policies::_OpenDLL open_dll_t; typedef MS::win32::system::policies::_CloseDLL close_dll_t; typedef MS::dx::ddraw::_DataBlit data_blit_t; typedef MS::win32::graphics::bitmap::_CreateEmptyBitmap create_bitmap_t; typedef MS::win32::system::memory::_GetAvailableMemory<int> get_available_memory_t; typedef MS::win32::graphics::utility::_ConvertPixelToA8R8G8B8 convert_pixel_24_t; typedef MS::win32::graphics::utility::_ConvertPixelToA8R8G8B8 convert_pixel_32_t; typedef bawd::graphics::bitmap::_BitmapBuilder bitmap_builder_t; typedef MS::win32::system::_ResourceOpener resource_opener_t; typedef bawd::graphics::bitmap::_Parse bitmap_parser_t; typedef bawd::graphics::bitmap::_ExtractData data_extractor_t; typedef MS::win32::graphics::bitmap::transform::_Flip bitmap_flip_t; typedef bawd::graphics::bitmap::_PixelConverter pixel_converter_t; typedef bawd::graphics::bitmap::transform::_BitdepthToScreen bitdepth_to_screen_t; typedef bawd::graphics::bitmap::_ConvertLoadedBitmapvoid
typedef MS::win32::system::resource::_GetBitmapResourceunsigned int> get_bitmap_resource_t;
typedef MS::dx::ddraw::_TileExtractorunsigned int, void *> tile_extractor_t;
typedef bawd::graphics::_TileLoader tile_loader_t;
Yikes!
Validated After a Battle
Isn't it extremely weird that sometimes... that you can battle mightily for something... expecting the worst... and, after all you can do... you are proven right in the end?
It was like that today when trying to "instantiate" the main monstrosity shown above (the "tile_loader_t" type).
Loki en la cabeza
I've been using Andrei Alexandrescu's "Loki Library" for some time now. Even found a bug that they ended up fixing once.
Well... today... it seemed like Loki's "ClassLevelLockable" wasn't about to let me get away with instantiating a "tile_loader_t" without bitching and popping up one of them ugly dialog boxes (ASSERT)
After tracing through... and noticing that I had had plenty of success using very similar code for Loki in the past... I felt like the problem had to be inside Loki.
Divide and Divide
So yeah... divide and conquer... got down to the smallest pieces I could (policy classes) and found that the assert was happening when instantiating a Loki::Functor template that used "Loki::ClassLevelLockable" as a policy.
But it didn't make sense. Then one of my dumb mistakes made me realize that I wasn't really testing it right.
I was actually putting test code at the end of a source file as if it were global data...... I actually tried using an "if()" statement outside of a function block... and the compiler complained.
That woke me up to what Loki was actually doing. Maybe the assert inside Loki would happen if and only if you used a Functor in the global namespace.
Proof positive
So I mocked up a trivial example that tested that theory... which can be found here... and tried it out.Yep. Vindicated. The assert happened only in the global namespace outside of a function definition... in "global" variables.
So I happily went back and fixed my test code so that it ran inside of a small, trivial test... and was able to get a "tile_loader_t" instantiated (woo hoo!) without any asserts.
Pudding
The real treat was in realizing that none of my code had to change one IOTA. I did spend a helluva lot of time tracking down Loki's dumb bug, which I submitted to them... but my TDD'ed code kicked ass all the way.
On to integration!...
(psst... this means I've now found TWO bugs in LOKI all by myself. I must be hella awesome [wink])
C