| // Copyright 2018 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| #include "peridot/bin/sessionmgr/puppet_master/command_runners/operation_calls/initialize_chain_call.h" |
| #include "peridot/bin/sessionmgr/puppet_master/command_runners/operation_calls/set_link_value_call.h" |
| |
| #include <lib/fsl/vmo/strings.h> |
| |
| namespace modular { |
| |
| namespace { |
| |
| // Populates a fuchsia::modular::ModuleParameterMap struct from a |
| // fuchsia::modular::CreateModuleParameterMapInfo struct. May create new Links |
| // for any fuchsia::modular::CreateModuleParameterMapInfo.property_info if |
| // property_info[i].is_create_link_info(). |
| class InitializeChainCall |
| : public Operation<fuchsia::modular::ExecuteResult, |
| fuchsia::modular::ModuleParameterMapPtr> { |
| public: |
| InitializeChainCall(StoryStorage* const story_storage, |
| std::vector<std::string> module_path, |
| fuchsia::modular::CreateModuleParameterMapInfoPtr |
| create_parameter_map_info, |
| ResultCall result_call) |
| : Operation("InitializeChainCall", std::move(result_call)), |
| story_storage_(story_storage), |
| module_path_(std::move(module_path)), |
| create_parameter_map_info_(std::move(create_parameter_map_info)) {} |
| |
| private: |
| void Run() override { |
| FlowToken flow{this, &result_, ¶meter_map_}; |
| |
| parameter_map_ = fuchsia::modular::ModuleParameterMap::New(); |
| parameter_map_->entries.resize(0); |
| |
| if (!create_parameter_map_info_) { |
| return; |
| } |
| |
| // For each property in |create_parameter_map_info_|, either: |
| // a) Copy the |link_path| to |result_| directly or |
| // b) Create & populate a new Link and add the correct mapping to |
| // |result_|. |
| for (auto& entry : *create_parameter_map_info_->property_info) { |
| const auto& key = entry.key; |
| const auto& info = entry.value; |
| |
| auto mapping = fuchsia::modular::ModuleParameterMapEntry::New(); |
| mapping->name = key; |
| if (info.is_link_path()) { |
| info.link_path().Clone(&mapping->link_path); |
| } else { // info->is_create_link() |
| mapping->link_path.module_path.resize(0); |
| for (const auto& i : module_path_) { |
| mapping->link_path.module_path.push_back(i); |
| } |
| mapping->link_path.link_name = key; |
| |
| // We issue N UpdateLinkValue calls and capture |flow| on each. We rely |
| // on the fact that once all refcounted instances of |flow| are |
| // destroyed, the InitializeChainCall will automatically finish. |
| std::string initial_json; |
| if (info.create_link().initial_data.size > 0) { |
| FXL_CHECK(fsl::StringFromVmo(info.create_link().initial_data, |
| &initial_json)); |
| } |
| fuchsia::modular::LinkPath out_path; |
| mapping->link_path.Clone(&out_path); |
| AddSetLinkValueOperation( |
| &operations_, story_storage_, std::move(out_path), |
| [initial_json](fidl::StringPtr* value) { *value = initial_json; }, |
| [this, flow](fuchsia::modular::ExecuteResult result) { |
| if (result.status != fuchsia::modular::ExecuteStatus::OK) { |
| result_ = std::move(result); |
| } |
| }); |
| } |
| |
| parameter_map_->entries.push_back(std::move(*mapping)); |
| } |
| } |
| |
| StoryStorage* const story_storage_; |
| const std::vector<std::string> module_path_; |
| const fuchsia::modular::CreateModuleParameterMapInfoPtr |
| create_parameter_map_info_; |
| fuchsia::modular::ModuleParameterMapPtr parameter_map_; |
| fuchsia::modular::ExecuteResult result_; |
| OperationCollection operations_; |
| |
| FXL_DISALLOW_COPY_AND_ASSIGN(InitializeChainCall); |
| }; |
| |
| } // namespace |
| |
| void AddInitializeChainOperation( |
| OperationContainer* const operation_container, |
| StoryStorage* const story_storage, |
| std::vector<std::string> module_path, |
| fuchsia::modular::CreateModuleParameterMapInfoPtr create_parameter_map_info, |
| std::function<void(fuchsia::modular::ExecuteResult, |
| fuchsia::modular::ModuleParameterMapPtr)> |
| result_call) { |
| operation_container->Add(new InitializeChainCall( |
| story_storage, std::move(module_path), |
| std::move(create_parameter_map_info), std::move(result_call))); |
| } |
| |
| } // namespace modular |