blob: 91e51f9b0796cbba31fc663ec6b4e4a0a5db81ef [file] [log] [blame]
// 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 "lib/async-loop/cpp/loop.h"
#include "lib/component/cpp/exposed_object.h"
#include "lib/component/cpp/startup_context.h"
const char* VALUE = "value";
class Item : public component::ExposedObject {
public:
Item() : ExposedObject(UniqueName("item-")) {
object_dir().set_metric(VALUE, component::IntMetric(0));
}
uint64_t size() { return object_dir().name().size() + 8; }
void add_value(int64_t value) { object_dir().add_metric(VALUE, value); }
};
class Table : public component::ExposedObject {
public:
Table(const std::string& name) : ExposedObject("table-" + name) {
object_dir().set_metric(
{"item_size"},
component::CallbackMetric([this](component::Metric* out_metric) {
uint64_t sum = 0;
for (const auto& item : items_) {
sum += item->size();
}
out_metric->SetUInt(sum);
}));
object_dir().set_prop("version", "1.0");
// Try binary values and keys.
object_dir().set_prop("frame", std::vector<uint8_t>({0x10, 0x00, 0x10}));
object_dir().set_prop(std::string("\x10\x10", 2),
std::vector<uint8_t>({0, 0, 0}));
object_dir().set_metric(std::string("\x10", 1), component::IntMetric(-10));
}
std::shared_ptr<Item> NewItem(int64_t value) {
auto ret = std::make_shared<Item>();
items_.emplace_back(ret);
ret->add_value(value);
add_child(ret.get());
return ret;
}
private:
std::vector<std::shared_ptr<Item>> items_;
};
int main(int argc, const char** argv) {
async::Loop loop(&kAsyncLoopConfigAttachToThread);
auto context = component::StartupContext::CreateFromStartupInfo();
Table t1("t1"), t2("t2");
t1.set_parent(*context->outgoing().object_dir());
t2.set_parent(*context->outgoing().object_dir());
t1.NewItem(10);
t1.NewItem(100);
t2.NewItem(4);
// It is not an error to use an invalid ObjectDir, but it will not have an
// effect.
component::ObjectDir invalid;
invalid.find({"test", "a"});
invalid.set_prop("test1", "...");
invalid.set_metric("test2", component::IntMetric(10));
invalid.set_child(fbl::MakeRefCounted<component::Object>("temp"));
invalid.set_children_callback(
[](std::vector<fbl::RefPtr<component::Object>>* out) {});
invalid.add_metric("test2", 2);
invalid.sub_metric("test2", 2);
// Check that setting and moving parents works correctly.
Table subtable("subtable");
subtable.set_parent(t1.object_dir());
subtable.NewItem(10)->add_value(10);
subtable.set_parent(t2.object_dir());
// Remove a child to unlink it from its parent.
Table subtable2("subtable2");
subtable2.set_parent(t1.object_dir());
subtable2.remove_from_parent();
subtable2.remove_from_parent(); // Repeated remove has no effect.
// Set parent to invalid, which will unlink from parent.
Table subtable3("subtable3");
subtable2.set_parent(t1.object_dir());
subtable2.set_parent(invalid);
context->outgoing().object_dir()->set_children_callback(
[](component::Object::ObjectVector* out) {
auto obj = fbl::MakeRefCounted<component::Object>("lazy_child");
auto dir = component::ObjectDir::Wrap(obj.get());
dir.set_prop("version", "1");
out->push_back(obj);
});
loop.Run();
return 0;
}