blob: 8d21190490fcf4dc4abf047eb50b1ae1bdec7410 [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"
#include "lib/fxl/command_line.h"
#include "lib/fxl/log_settings_command_line.h"
#include "lib/fxl/strings/string_printf.h"
#include <vector>
// A single cell in the table.
// Cells expose a string property, an int metric, and a double metric.
class Cell : public component::ExposedObject {
public:
Cell(const std::string& name, int64_t value, double double_value)
: ExposedObject(UniqueName("cell")) {
object_dir().set_prop("name", name);
object_dir().set_metric("value", component::IntMetric(value));
object_dir().set_metric("double_value",
component::DoubleMetric(double_value));
}
};
// A row in the table, contains cells.
class Row : public component::ExposedObject {
public:
Row() : ExposedObject(UniqueName("row")) {}
Row(Row&&) = default;
Row& operator=(Row&&) = default;
Cell* AddCell(const std::string& name, int64_t value, double double_value) {
// Construct a new cell in-place, and expose it as a child of this object in
// the Inspect output.
cells_.push_back(Cell(name, value, double_value));
auto ret = &(*cells_.rbegin());
add_child(ret);
return ret;
}
private:
std::vector<Cell> cells_;
};
// A table, contains rows.
class Table : public component::ExposedObject {
public:
Table() : ExposedObject(UniqueName("table")) {}
Row* AddRow() {
// Construct a new row in-place, and expose it as a child of this object in
// the Inspect output.
rows_.push_back(Row());
auto ret = rows_.rbegin();
ret->set_parent(object_dir());
return &(*ret);
}
private:
std::vector<Row> rows_;
};
int main(int argc, char** argv) {
auto command_line = fxl::CommandLineFromArgcArgv(argc, argv);
fxl::SetLogSettingsFromCommandLine(command_line);
// Construct a demo table with the rows and columns given on the command line.
auto rows = command_line.GetOptionValueWithDefault("rows", "");
auto columns = command_line.GetOptionValueWithDefault("columns", "");
if (rows.empty() || columns.empty() || atoi(rows.c_str()) == 0 ||
atoi(columns.c_str()) == 0) {
fprintf(stderr, R"text(Usage: %s --rows=N --columns=M
Example component to showcase Inspect API objects, including an NxM
nested table.
)text",
argv[0]);
return 1;
}
// Exposing objects requires a loop and the startup context.
async::Loop loop(&kAsyncLoopConfigAttachToThread);
auto startup_context = component::StartupContext::CreateFromStartupInfo();
Table table;
const int row_count = atoi(rows.c_str());
const int col_count = atoi(columns.c_str());
const int total = row_count * col_count;
int idx = 0;
for (int i = 0; i < row_count; ++i) {
Row* row = table.AddRow();
for (int j = 0; j < col_count; ++j) {
// name is "(row,col)", value is i*j, and double_value is percentage done.
row->AddCell(fxl::StringPrintf("(%d,%d)", i, j), i * j,
100.0 * (++idx) / total);
}
}
// Set a property directly on the table.
table.object_dir().set_prop("object_name", "Example Table");
table.object_dir().set_prop("binary_data",
std::string("\x20\x00\x11\x12\x05", 5));
table.object_dir().set_prop(std::string("\x05\x01\x02", 3),
"The key of this value is a binary value.");
table.object_dir().set_prop(std::string("\x05\x01\x02", 3),
std::string("\x01\x02", 2));
// Finally, expose the table itself as an object in the top-level directory.
// This appears under out/objects/ in the hub for this component.
table.set_parent(*startup_context->outgoing().object_dir());
loop.Run();
return 0;
}