Commit 70a88892 authored by Ian Vollick's avatar Ian Vollick Committed by Commit Bot

[vr] Display bindings from the test app

With this change, pressing "b" in the test app will dump the scene
hierarchy with a text representation of the bindings.

The extra strings are not included in release builds.

Bug: None
Cq-Include-Trybots: master.tryserver.chromium.android:android_optional_gpu_tests_rel;master.tryserver.chromium.linux:linux_optional_gpu_tests_rel;master.tryserver.chromium.mac:mac_optional_gpu_tests_rel;master.tryserver.chromium.win:win_optional_gpu_tests_rel
Change-Id: Iab31e5d81ad7c594c903555fad28e8eae978205d
Reviewed-on: https://chromium-review.googlesource.com/847278
Commit-Queue: Ian Vollick <vollick@chromium.org>
Reviewed-by: default avatarChristopher Grant <cjgrant@chromium.org>
Cr-Commit-Position: refs/heads/master@{#526486}
parent 8cd107ec
......@@ -8,6 +8,7 @@
#include "base/bind.h"
#include "base/macros.h"
#include "base/optional.h"
#include "base/strings/stringprintf.h"
#include "chrome/browser/vr/databinding/binding_base.h"
namespace vr {
......@@ -23,9 +24,18 @@ namespace vr {
template <typename T>
class Binding : public BindingBase {
public:
Binding(const base::Callback<T()>& getter,
const base::Callback<void(const T&)>& setter)
Binding(const base::RepeatingCallback<T()>& getter,
const base::RepeatingCallback<void(const T&)>& setter)
: getter_(getter), setter_(setter) {}
Binding(const base::RepeatingCallback<T()>& getter,
const std::string& getter_text,
const base::RepeatingCallback<void(const T&)>& setter,
const std::string& setter_text)
: getter_(getter),
setter_(setter),
getter_text_(getter_text),
setter_text_(setter_text) {}
~Binding() override = default;
// This function will check if the getter is producing a different value than
......@@ -40,11 +50,22 @@ class Binding : public BindingBase {
return true;
}
std::string ToString() override {
if (getter_text_.empty() && setter_text_.empty())
return "";
return base::StringPrintf("%s => %s", getter_text_.c_str(),
setter_text_.c_str());
}
private:
base::Callback<T()> getter_;
base::Callback<void(const T&)> setter_;
base::RepeatingCallback<T()> getter_;
base::RepeatingCallback<void(const T&)> setter_;
base::Optional<T> last_value_;
std::string getter_text_;
std::string setter_text_;
DISALLOW_COPY_AND_ASSIGN(Binding);
};
......@@ -82,11 +103,23 @@ class Binding : public BindingBase {
// auto binding =
// VR_BIND_FUNC(int, MyModel, &m, source, MyView, &v, SetAwesomeness);
//
#define VR_BIND(T, M, m, Get, V, v, Set) \
base::MakeUnique<Binding<T>>( \
base::Bind([](M* model) { return model->Get; }, base::Unretained(m)), \
base::Bind([](V* view, const T& value) { view->Set; }, \
base::Unretained(v)))
#ifndef NDEBUG
#define VR_BIND(T, M, m, Get, V, v, Set) \
base::MakeUnique<Binding<T>>( \
base::BindRepeating([](M* model) { return model->Get; }, \
base::Unretained(m)), \
#Get, \
base::BindRepeating([](V* view, const T& value) { view->Set; }, \
base::Unretained(v)), \
#Set)
#else
#define VR_BIND(T, M, m, Get, V, v, Set) \
base::MakeUnique<Binding<T>>( \
base::BindRepeating([](M* model) { return model->Get; }, \
base::Unretained(m)), \
base::BindRepeating([](V* view, const T& value) { view->Set; }, \
base::Unretained(v)))
#endif
#define VR_BIND_FUNC(T, M, m, Get, V, v, f) \
VR_BIND(T, M, m, Get, V, v, f(value))
......@@ -94,6 +127,8 @@ class Binding : public BindingBase {
#define VR_BIND_FIELD(T, M, m, Get, V, v, f) \
VR_BIND(T, M, m, Get, V, v, f = value)
#define VR_BIND_LAMBDA(...) base::BindRepeating(__VA_ARGS__), #__VA_ARGS__
} // namespace vr
#endif // CHROME_BROWSER_VR_DATABINDING_BINDING_H_
......@@ -5,6 +5,8 @@
#ifndef CHROME_BROWSER_VR_DATABINDING_BINDING_BASE_H_
#define CHROME_BROWSER_VR_DATABINDING_BINDING_BASE_H_
#include <string>
namespace vr {
// Bindings are used to tie models to views. You may, for example, want to bind
......@@ -20,6 +22,8 @@ class BindingBase {
// Returns true if the binding was updated.
virtual bool Update() = 0;
virtual std::string ToString() = 0;
private:
DISALLOW_COPY_AND_ASSIGN(BindingBase);
};
......
......@@ -5,6 +5,7 @@
#ifndef CHROME_BROWSER_VR_DATABINDING_VECTOR_BINDING_H_
#define CHROME_BROWSER_VR_DATABINDING_VECTOR_BINDING_H_
#include <sstream>
#include <vector>
#include "base/bind.h"
......@@ -61,6 +62,15 @@ class VectorBinding : public BindingBase {
return updated;
}
std::string ToString() override {
std::ostringstream os;
for (size_t i = 0; i < bindings_.size(); ++i) {
auto& binding = bindings_[i];
os << i << ": " << binding->ToString() << std::endl;
}
return os.str();
}
private:
std::vector<M>* models_ = nullptr;
std::vector<std::unique_ptr<ElementBinding>> bindings_;
......
......@@ -5,6 +5,7 @@
#ifndef CHROME_BROWSER_VR_DATABINDING_VECTOR_ELEMENT_BINDING_H_
#define CHROME_BROWSER_VR_DATABINDING_VECTOR_ELEMENT_BINDING_H_
#include <sstream>
#include <vector>
#include "base/bind.h"
......@@ -41,6 +42,14 @@ class VectorElementBinding : public BindingBase {
std::vector<std::unique_ptr<BindingBase>>& bindings() { return bindings_; }
std::string ToString() override {
std::ostringstream os;
for (auto& binding : bindings_) {
os << std::endl << " " << binding->ToString();
}
return os.str();
}
private:
std::vector<M>* models_ = nullptr;
size_t index_ = 0;
......
......@@ -9,6 +9,7 @@
#include "base/logging.h"
#include "base/numerics/ranges.h"
#include "base/stl_util.h"
#include "base/strings/string_split.h"
#include "base/strings/stringprintf.h"
#include "base/time/time.h"
#include "chrome/browser/vr/model/camera_model.h"
......@@ -390,8 +391,26 @@ std::string UiElement::DebugName() const {
type() == kTypeNone ? "" : UiElementTypeToString(type()).c_str());
}
void DumpLines(const std::vector<size_t>& counts,
const std::vector<const UiElement*>& ancestors,
std::ostringstream* os) {
for (size_t i = 0; i < counts.size(); ++i) {
size_t current_count = counts[i];
if (i + 1 < counts.size()) {
current_count++;
}
if (ancestors[ancestors.size() - i - 1]->children().size() >
current_count) {
*os << "| ";
} else {
*os << " ";
}
}
}
void UiElement::DumpHierarchy(std::vector<size_t> counts,
std::ostringstream* os) const {
std::ostringstream* os,
bool include_bindings) const {
// Put our ancestors in a vector for easy reverse traversal.
std::vector<const UiElement*> ancestors;
for (const UiElement* ancestor = parent(); ancestor;
......@@ -427,11 +446,35 @@ void UiElement::DumpHierarchy(std::vector<size_t> counts,
*os << kGreen;
DumpGeometry(os);
*os << kReset << std::endl;
counts.push_back(0u);
if (include_bindings) {
std::ostringstream binding_stream;
for (auto& binding : bindings_) {
std::string binding_text = binding->ToString();
if (binding_text.empty())
continue;
binding_stream << binding->ToString() << std::endl;
}
auto split_bindings =
base::SplitString(binding_stream.str(), "\n", base::TRIM_WHITESPACE,
base::SPLIT_WANT_NONEMPTY);
if (!split_bindings.empty()) {
ancestors.insert(ancestors.begin(), this);
}
for (const auto& split : split_bindings) {
*os << std::endl << kBlue;
DumpLines(counts, ancestors, os);
*os << kGreen << split;
}
}
*os << kReset << std::endl;
for (auto& child : children_) {
child->DumpHierarchy(counts, os);
child->DumpHierarchy(counts, os, include_bindings);
counts.back()++;
}
}
......
......@@ -423,7 +423,11 @@ class UiElement : public cc::AnimationTarget {
// situated in its parent's list of children. This is used to determine
// whether each ancestor is the last child (which affects the lines we draw in
// the tree).
void DumpHierarchy(std::vector<size_t> counts, std::ostringstream* os) const;
// TODO(vollick): generalize the configuration of the dump to selectively turn
// off or on a variety of features.
void DumpHierarchy(std::vector<size_t> counts,
std::ostringstream* os,
bool include_bindings) const;
virtual void DumpGeometry(std::ostringstream* os) const;
protected:
......
......@@ -153,8 +153,10 @@ void VrTestContext::HandleInput(ui::Event* event) {
ui_->SetIncognito(incognito_);
break;
case ui::DomCode::US_D:
ui_->Dump();
ui_->Dump(false);
break;
case ui::DomCode::US_B:
ui_->Dump(true);
case ui::DomCode::US_V:
CreateFakeVoiceSearchResult();
break;
......
......@@ -304,11 +304,12 @@ bool Ui::SkipsRedrawWhenNotDirty() const {
return model_->skips_redraw_when_not_dirty;
}
void Ui::Dump() {
void Ui::Dump(bool include_bindings) {
std::ostringstream os;
os << std::setprecision(3);
os << std::endl;
scene_->root_element().DumpHierarchy(std::vector<size_t>(), &os);
scene_->root_element().DumpHierarchy(std::vector<size_t>(), &os,
include_bindings);
LOG(ERROR) << os.str();
}
......
......@@ -114,7 +114,7 @@ class Ui : public BrowserUiInterface, public KeyboardUiInterface {
void ReinitializeForTest(const UiInitialState& ui_initial_state);
void Dump();
void Dump(bool include_bindings);
void SetBackgroundImage(std::unique_ptr<SkBitmap> bitmap);
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment