blob: d068b464f50960a169c9cf5474b5b6a2c2def861 [file]
// Copyright 2022 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "controller/scene_controller.h"
#include <cmath>
#include <cstddef>
#include "controller/device_notify_manager.h"
namespace netsim {
namespace controller {
/* static */
SceneController &SceneController::Singleton() {
static SceneController *kInstance = new SceneController();
return *kInstance;
}
void SceneController::Add(std::shared_ptr<Device> &device) {
std::unique_lock<std::mutex> lock(this->mutex_);
devices_.push_back(device);
}
const std::vector<std::shared_ptr<Device>> SceneController::Copy() {
std::unique_lock<std::mutex> lock(this->mutex_);
return devices_;
}
std::shared_ptr<Device> SceneController::GetOrCreate(
const std::string &serial) {
std::unique_lock<std::mutex> lock(this->mutex_);
auto device = GetDevice(serial);
if (device != nullptr) {
return device;
}
device = std::make_shared<Device>(serial);
devices_.push_back(device);
return device;
}
std::shared_ptr<Device> SceneController::GetDevice(const std::string &serial) {
for (auto device : devices_) {
if (device->model.device_serial() == serial) return device;
}
return {nullptr};
}
// Returns a Device shared_ptr or nullptr
std::shared_ptr<Device> SceneController::MatchDevice(const std::string &serial,
const std::string &name) {
std::shared_ptr<Device> found = nullptr;
if (serial.empty() && name.empty()) {
return nullptr;
}
for (auto &device : devices_) {
// serial && name -> rename, only match by serial
// serial && !name -> match by serial
// !serial && name -> match by name
auto pos = (serial.empty()) ? device->model.name().find(name)
: device->model.device_serial().find(serial);
if (pos != std::string::npos) {
// check for multiple matches
if (found != nullptr) return nullptr;
found = device;
}
}
return found;
}
// UI requesting a change in device info
bool SceneController::UpdateDevice(const netsim::model::Device &request) {
std::unique_lock<std::mutex> lock(this->mutex_);
if (request.device_serial().empty()) {
return false;
}
auto device = MatchDevice(request.device_serial(), request.name());
if (device == nullptr) return false;
device->Update(request);
DeviceNotifyManager::Get().Notify();
return true;
}
// Euclidian distance between two devices.
float SceneController::GetDistance(const Device &a, const Device &b) {
return sqrt((pow(a.model.position().x() - b.model.position().x(), 2) +
pow(a.model.position().y() - b.model.position().y(), 2) +
pow(a.model.position().z() - b.model.position().z(), 2)));
}
void SceneController::Reset() {
std::unique_lock<std::mutex> lock(this->mutex_);
for (auto &device : devices_) {
device->Reset();
}
DeviceNotifyManager::Get().Notify();
}
} // namespace controller
} // namespace netsim