/** @test verify the allocation/de-allocation handling as * embedded into the CommandRegistry operation. * Simulates on low level what normally happens * during command lifecycle. */ void checkAllocation (CommandRegistry& registry) { // simulate what normally happens within a CommandDef typedef void Sig_oper(int); typedef long Sig_capt(int); typedef void Sig_undo(int,long); function<Sig_oper> o_Fun (command1::operate); function<Sig_capt> c_Fun (command1::capture); function<Sig_undo> u_Fun (command1::undoIt); CHECK (o_Fun && c_Fun && u_Fun); CHECK (cnt_inst == registry.instance_count()); // when the CommandDef is complete, it issues the // allocation call to the registry behind the scenes.... typedef shared_ptr<CommandImpl> PImpl; PImpl pImpl = registry.newCommandImpl(o_Fun,c_Fun,u_Fun); CHECK (1+cnt_inst == registry.instance_count()); CHECK (pImpl); CHECK (pImpl->isValid()); CHECK (!pImpl->canExec()); CHECK (1 == pImpl.use_count()); // no magic involved, we hold the only instance PImpl clone = registry.createCloneImpl(*pImpl); CHECK (clone->isValid()); CHECK (!clone->canExec()); CHECK (1 == clone.use_count()); CHECK (1 == pImpl.use_count()); CHECK (2+cnt_inst == registry.instance_count()); CHECK (!isSameObject (*pImpl, *clone)); CHECK (*pImpl == *clone); CHECK (!pImpl->canExec()); typedef Types<int> ArgType; TypedArguments<Tuple<ArgType>> arg{Tuple<ArgType>(98765)}; pImpl->setArguments(arg); CHECK (pImpl->canExec()); CHECK (!clone->canExec()); // this proves the clone has indeed a separate identity CHECK (*pImpl != *clone); // discard the first clone and overwrite with a new one clone = registry.createCloneImpl(*pImpl); CHECK (2+cnt_inst == registry.instance_count()); CHECK (*pImpl == *clone); CHECK (clone->canExec()); clone.reset(); pImpl.reset(); // corresponding allocation slots cleared automatically CHECK (cnt_inst == registry.instance_count()); }
/** @test verify the index operation. * Add, search, remove, store copy. */ void checkRegistration (CommandRegistry& registry) { CHECK (cnt_inst == registry.instance_count()); Command cmd1 = registry.queryIndex (TEST_CMD); CHECK (cmd1); CHECK (TEST_CMD == registry.findDefinition(cmd1)); Command nonexistant = registry.queryIndex("miraculous"); CHECK (!nonexistant); // now create a clone, registered under a different ID Command cmd2 = cmd1.storeDef(TEST_CMD2); CHECK (cmd2 == cmd1); cmd2.bind(54321); CHECK (cmd2 != cmd1); // this created exactly one additional instance allocation: CHECK (1+cnt_inst == registry.instance_count()); CHECK (1+cnt_defs == registry.index_size()); // ...and another index entry Command cmdX = registry.queryIndex(TEST_CMD2); CHECK (cmdX == cmd2); CHECK (cmdX != cmd1); CHECK (registry.remove(TEST_CMD2)); CHECK (!registry.queryIndex(TEST_CMD2)); CHECK (cnt_defs == registry.index_size()); // removed from index CHECK (1+cnt_inst == registry.instance_count()); //...but still alive // create a new registration.. registry.track(TEST_CMD2, cmd2); CHECK (registry.queryIndex(TEST_CMD2)); CHECK (1+cnt_defs == registry.index_size()); // again holding two distinct entries CHECK (cmdX == cmd2); CHECK (cmdX != cmd1); CHECK (TEST_CMD == registry.findDefinition(cmd1)); CHECK (TEST_CMD2 == registry.findDefinition(cmd2)); CHECK (TEST_CMD2 == registry.findDefinition(cmdX)); CHECK ( registry.remove(TEST_CMD2)); CHECK (!registry.remove("miraculous")); CHECK (!registry.queryIndex(TEST_CMD2)); CHECK ( registry.queryIndex(TEST_CMD)); CHECK (cnt_defs == registry.index_size()); // the index entry is gone, CHECK (1+cnt_inst == registry.instance_count()); // but the allocation still lives cmdX.close(); CHECK (1+cnt_inst == registry.instance_count()); cmd2.close(); CHECK (0+cnt_inst == registry.instance_count()); // ...as long as it's still referred }