/** @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()); }
/** create a command implementation frame usable for tests. * This simulates what normally happens within a CommandDef. * The created CommandImpl isn't registered, and thus will * just go away when the smart-ptr leaves scope. */ PCommandImpl buildTestCommand (CommandRegistry& registry) { 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); // when the CommandDef is complete, it issues the // allocation call to the registry behind the scenes.... PCommandImpl pImpl = registry.newCommandImpl(o_Fun,c_Fun,u_Fun); CHECK (pImpl); CHECK (*pImpl); return pImpl; }