TEST_F( TestCommandFixture, creatMacro ) { auto & controller = getReflectionController(); auto objHandle = klass_->createManagedObject(); PropertyAccessor counter = klass_->bindProperty("counter", objHandle ); CHECK(counter.isValid()); const int TEST_VALUE = 57; { int value = TEST_VALUE; controller.setValue( counter, value ); } { // TODO: wait on controller controller.getValue( counter ); } { auto & commandSystemProvider = getCommandSystemProvider(); auto & history = commandSystemProvider.getHistory(); commandSystemProvider.createMacro( history ); CHECK(commandSystemProvider.getMacros().empty() == false ); } }
//============================================================================== bool CompoundCommand::validateArguments(const ObjectHandle& arguments) const { ICommandManager* cmdSysProvider = getCommandSystemProvider(); if (cmdSysProvider == nullptr) { return false; } MacroEditObject* ccArgs = arguments.getBase<MacroEditObject>(); if (ccArgs == nullptr) { return false; } if (ccArgs->getArgCount() != subCommands_.size()) { return false; } for (SubCommandCollection::size_type i = 0; i < subCommands_.size(); ++i) { Command* command = cmdSysProvider->findCommand(subCommands_[i].first.c_str()); if (command == nullptr) { return false; } if (!command->validateArguments(ccArgs->getCommandArgument(i))) { return false; } } return true; }
//============================================================================== void CompoundCommand::initDisplayData(IDefinitionManager& defManager, IReflectionController* controller) { auto cmdSysProvider = getCommandSystemProvider(); assert(cmdSysProvider != nullptr); const auto pDefinition = defManager.getDefinition(getClassIdentifier<MacroObject>()); assert(pDefinition != nullptr); macroObject_ = defManager.create<MacroObject>(false); macroObject_->init(*cmdSysProvider, defManager, controller, id_.c_str()); }
TEST_F( TestCommandFixture, undo_redo ) { auto & controller = getReflectionController(); auto objHandle = klass_->createManagedObject(); PropertyAccessor counter = klass_->bindProperty("counter", objHandle ); CHECK(counter.isValid()); int oldValue = -1; { Variant variant = counter.getValue(); CHECK(variant.tryCast( oldValue )); } auto & commandSystemProvider = getCommandSystemProvider(); const int TEST_VALUE = 57; { int value = TEST_VALUE; controller.setValue( counter, value ); } { int value = 0; Variant variant = controller.getValue( counter ); CHECK(variant.tryCast( value )); CHECK_EQUAL(TEST_VALUE, value); } { commandSystemProvider.undo(); CHECK(!commandSystemProvider.canUndo()); CHECK(commandSystemProvider.canRedo()); int value = 0; Variant variant = controller.getValue( counter ); CHECK(variant.tryCast( value )); CHECK_EQUAL(oldValue, value); } { commandSystemProvider.redo(); CHECK(commandSystemProvider.canUndo()); CHECK(!commandSystemProvider.canRedo()); int value = 0; Variant variant = controller.getValue( counter ); CHECK(variant.tryCast( value )); CHECK_EQUAL(TEST_VALUE, value); } }
TEST_F( TestCommandFixture, threadCommands ) { // This test attempts to verify commands do not deadlock. // TODO: waitForInstance need to take a timeout to properly handle when this test fails auto & commandManager = getCommandSystemProvider(); auto command = commandManager.queueCommand( TestThreadCommand::generateId( CommandThreadAffinity::UI_THREAD ).c_str() ); commandManager.waitForInstance( command ); command = commandManager.queueCommand( TestThreadCommand::generateId( CommandThreadAffinity::COMMAND_THREAD ).c_str() ); commandManager.waitForInstance( command ); command = commandManager.queueCommand( TestThreadCommand::generateId( CommandThreadAffinity::ANY_THREAD ).c_str() ); commandManager.waitForInstance( command ); }
TEST_F( TestCommandFixture, executeMacro ) { auto & controller = getReflectionController(); auto objHandle = klass_->createManagedObject(); PropertyAccessor counter = klass_->bindProperty("counter", objHandle ); CHECK(counter.isValid()); const int TEST_VALUE = 57; { int value = TEST_VALUE; controller.setValue( counter, value ); } { // TODO: wait on controller controller.getValue( counter ); } { auto & commandSystemProvider = getCommandSystemProvider(); commandSystemProvider.undo(); auto & history = commandSystemProvider.getHistory(); commandSystemProvider.createMacro( history, "Macro1" ); CHECK(commandSystemProvider.getMacros().empty() == false ); auto macroObj = static_cast<CompoundCommand*>( commandSystemProvider.findCommand( "Macro1" ) )->getMacroObject(); auto instObj = macroObj.getBase<MacroObject>()->executeMacro(); CommandInstancePtr inst = instObj.getBase<CommandInstance>(); commandSystemProvider.waitForInstance( inst ); { PropertyAccessor counter = klass_->bindProperty("counter", objHandle ); int value = 0; Variant variant = controller.getValue( counter ); CHECK(variant.tryCast( value )); CHECK_EQUAL(TEST_VALUE, value); } } }
//============================================================================== ObjectHandle CompoundCommand::execute(const ObjectHandle& arguments) const { auto cmdSysProvider = getCommandSystemProvider(); assert(cmdSysProvider != nullptr); MacroEditObject* ccArgs = arguments.getBase<MacroEditObject>(); assert(ccArgs); std::vector<CommandInstance*> subInstances; subInstances.reserve(subCommands_.size()); CommandInstancePtr instance; for (SubCommandCollection::size_type i = 0; i < subCommands_.size(); ++i) { ccArgs->resolveDependecy(i, subInstances); instance = cmdSysProvider->queueCommand(subCommands_[i].first.c_str(), ccArgs->getCommandArgument(i)); assert(instance != nullptr); cmdSysProvider->waitForInstance(instance); subInstances.push_back(instance.get()); } return instance->getReturnValue(); }
TEST_F( TestCommandFixture, runBatchCommand ) { auto & controller = getReflectionController(); auto objHandle = klass_->createManagedObject(); const int TEST_VALUE = 57; const char * TEST_TEXT = "HelloCommand"; PropertyAccessor counter = klass_->bindProperty("counter", objHandle ); CHECK(counter.isValid()); PropertyAccessor text = klass_->bindProperty( "text", objHandle ); CHECK(text.isValid()); PropertyAccessor incrementCounter = klass_->bindProperty("incrementCounter", objHandle ); CHECK(incrementCounter.isValid()); { int value = 0; Variant variantValue = controller.getValue( counter ); CHECK( variantValue.tryCast( value ) ); CHECK( TEST_VALUE != value ); std::string text_value; Variant variantText = controller.getValue( text ); CHECK( variantText.tryCast( text_value ) ); CHECK( TEST_TEXT != text_value ); } { int value = TEST_VALUE; auto & commandSystemProvider = getCommandSystemProvider(); commandSystemProvider.beginBatchCommand(); controller.setValue( counter, value ); std::string text_value = TEST_TEXT; controller.setValue( text, text_value ); commandSystemProvider.abortBatchCommand(); } { int value = 0; Variant variantValue = controller.getValue( counter ); CHECK(variantValue.tryCast( value )); CHECK(TEST_VALUE != value); std::string text_value; Variant variantText = controller.getValue( text ); CHECK(variantText.tryCast( text_value )); CHECK(TEST_TEXT != text_value); } { int value = TEST_VALUE; auto & commandSystemProvider = getCommandSystemProvider(); commandSystemProvider.beginBatchCommand(); controller.setValue( counter, value ); std::string text_value = TEST_TEXT; controller.setValue( text, text_value ); commandSystemProvider.endBatchCommand(); } { int value = 0; Variant variantValue = controller.getValue( counter ); CHECK(variantValue.tryCast( value )); CHECK_EQUAL(TEST_VALUE, value); std::string text_value; Variant variantText = controller.getValue( text ); CHECK(variantText.tryCast( text_value )); CHECK_EQUAL(TEST_TEXT, text_value); } { Variant variantValue; int value = 0; auto & commandSystemProvider = getCommandSystemProvider(); commandSystemProvider.beginBatchCommand(); controller.setValue( counter, 0 ); commandSystemProvider.beginBatchCommand(); controller.setValue( counter, 1 ); commandSystemProvider.beginBatchCommand(); controller.setValue( counter, 2 ); commandSystemProvider.beginBatchCommand(); controller.setValue( counter, 3 ); variantValue = controller.getValue( counter ); CHECK( variantValue.tryCast( value ) ); CHECK( value == 3 ); commandSystemProvider.abortBatchCommand(); variantValue = controller.getValue( counter ); CHECK( variantValue.tryCast( value ) ); CHECK( value == 2 ); commandSystemProvider.abortBatchCommand(); variantValue = controller.getValue( counter ); CHECK( variantValue.tryCast( value ) ); CHECK( value == 1); commandSystemProvider.abortBatchCommand(); variantValue = controller.getValue( counter ); CHECK( variantValue.tryCast( value ) ); CHECK( value == 0); commandSystemProvider.endBatchCommand(); variantValue = controller.getValue( counter ); CHECK( variantValue.tryCast( value ) ); CHECK( value == 0); } { int value = 0; controller.setValue( counter, value ); Variant variantValue = controller.getValue( counter ); CHECK(variantValue.tryCast( value )); CHECK_EQUAL(0, value); auto & commandSystemProvider = getCommandSystemProvider(); commandSystemProvider.beginBatchCommand(); controller.invoke( incrementCounter, ReflectedMethodParameters() ); controller.invoke( incrementCounter, ReflectedMethodParameters() ); commandSystemProvider.endBatchCommand(); variantValue = controller.getValue( counter ); CHECK(variantValue.tryCast( value )); CHECK_EQUAL(2, value); commandSystemProvider.beginBatchCommand(); controller.invoke( incrementCounter, ReflectedMethodParameters() ); controller.invoke( incrementCounter, ReflectedMethodParameters() ); commandSystemProvider.abortBatchCommand(); variantValue = controller.getValue( counter ); CHECK(variantValue.tryCast( value )); CHECK_EQUAL(2, value); } }