blob: 18c2fa46aceec90c1b5fb185655a3e02c459fe49 [file] [log] [blame]
// Copyright 2014 The Chromium 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 "components/test_runner/gamepad_controller.h"
#include <string.h>
#include "base/macros.h"
#include "components/test_runner/web_test_delegate.h"
#include "gin/arguments.h"
#include "gin/handle.h"
#include "gin/object_template_builder.h"
#include "gin/wrappable.h"
#include "third_party/WebKit/public/platform/WebGamepadListener.h"
#include "third_party/WebKit/public/web/WebFrame.h"
#include "third_party/WebKit/public/web/WebKit.h"
#include "v8/include/v8.h"
using blink::WebFrame;
using blink::WebGamepad;
using blink::WebGamepads;
namespace test_runner {
class GamepadControllerBindings
: public gin::Wrappable<GamepadControllerBindings> {
public:
static gin::WrapperInfo kWrapperInfo;
static void Install(base::WeakPtr<GamepadController> controller,
blink::WebFrame* frame);
private:
explicit GamepadControllerBindings(
base::WeakPtr<GamepadController> controller);
~GamepadControllerBindings() override;
// gin::Wrappable.
gin::ObjectTemplateBuilder GetObjectTemplateBuilder(
v8::Isolate* isolate) override;
void Connect(int index);
void DispatchConnected(int index);
void Disconnect(int index);
void SetId(int index, const std::string& src);
void SetButtonCount(int index, int buttons);
void SetButtonData(int index, int button, double data);
void SetAxisCount(int index, int axes);
void SetAxisData(int index, int axis, double data);
base::WeakPtr<GamepadController> controller_;
DISALLOW_COPY_AND_ASSIGN(GamepadControllerBindings);
};
gin::WrapperInfo GamepadControllerBindings::kWrapperInfo = {
gin::kEmbedderNativeGin};
// static
void GamepadControllerBindings::Install(
base::WeakPtr<GamepadController> controller,
WebFrame* frame) {
v8::Isolate* isolate = blink::mainThreadIsolate();
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context = frame->mainWorldScriptContext();
if (context.IsEmpty())
return;
v8::Context::Scope context_scope(context);
gin::Handle<GamepadControllerBindings> bindings =
gin::CreateHandle(isolate, new GamepadControllerBindings(controller));
if (bindings.IsEmpty())
return;
v8::Local<v8::Object> global = context->Global();
global->Set(gin::StringToV8(isolate, "gamepadController"), bindings.ToV8());
}
GamepadControllerBindings::GamepadControllerBindings(
base::WeakPtr<GamepadController> controller)
: controller_(controller) {}
GamepadControllerBindings::~GamepadControllerBindings() {}
gin::ObjectTemplateBuilder GamepadControllerBindings::GetObjectTemplateBuilder(
v8::Isolate* isolate) {
return gin::Wrappable<GamepadControllerBindings>::GetObjectTemplateBuilder(
isolate)
.SetMethod("connect", &GamepadControllerBindings::Connect)
.SetMethod("dispatchConnected",
&GamepadControllerBindings::DispatchConnected)
.SetMethod("disconnect", &GamepadControllerBindings::Disconnect)
.SetMethod("setId", &GamepadControllerBindings::SetId)
.SetMethod("setButtonCount", &GamepadControllerBindings::SetButtonCount)
.SetMethod("setButtonData", &GamepadControllerBindings::SetButtonData)
.SetMethod("setAxisCount", &GamepadControllerBindings::SetAxisCount)
.SetMethod("setAxisData", &GamepadControllerBindings::SetAxisData);
}
void GamepadControllerBindings::Connect(int index) {
if (controller_)
controller_->Connect(index);
}
void GamepadControllerBindings::DispatchConnected(int index) {
if (controller_)
controller_->DispatchConnected(index);
}
void GamepadControllerBindings::Disconnect(int index) {
if (controller_)
controller_->Disconnect(index);
}
void GamepadControllerBindings::SetId(int index, const std::string& src) {
if (controller_)
controller_->SetId(index, src);
}
void GamepadControllerBindings::SetButtonCount(int index, int buttons) {
if (controller_)
controller_->SetButtonCount(index, buttons);
}
void GamepadControllerBindings::SetButtonData(int index,
int button,
double data) {
if (controller_)
controller_->SetButtonData(index, button, data);
}
void GamepadControllerBindings::SetAxisCount(int index, int axes) {
if (controller_)
controller_->SetAxisCount(index, axes);
}
void GamepadControllerBindings::SetAxisData(int index, int axis, double data) {
if (controller_)
controller_->SetAxisData(index, axis, data);
}
// static
base::WeakPtr<GamepadController> GamepadController::Create(
WebTestDelegate* delegate) {
CHECK(delegate);
GamepadController* controller = new GamepadController();
delegate->SetGamepadProvider(controller);
return controller->weak_factory_.GetWeakPtr();
}
GamepadController::GamepadController()
: listener_(nullptr), weak_factory_(this) {
Reset();
}
GamepadController::~GamepadController() {
}
void GamepadController::Reset() {
memset(&gamepads_, 0, sizeof(gamepads_));
}
void GamepadController::Install(WebFrame* frame) {
GamepadControllerBindings::Install(weak_factory_.GetWeakPtr(), frame);
}
void GamepadController::SampleGamepads(blink::WebGamepads& gamepads) {
memcpy(&gamepads, &gamepads_, sizeof(blink::WebGamepads));
}
void GamepadController::SetListener(blink::WebGamepadListener* listener) {
listener_ = listener;
}
void GamepadController::Connect(int index) {
if (index < 0 || index >= static_cast<int>(WebGamepads::itemsLengthCap))
return;
gamepads_.items[index].connected = true;
gamepads_.length = 0;
for (unsigned i = 0; i < WebGamepads::itemsLengthCap; ++i) {
if (gamepads_.items[i].connected)
gamepads_.length = i + 1;
}
}
void GamepadController::DispatchConnected(int index) {
if (index < 0 || index >= static_cast<int>(WebGamepads::itemsLengthCap)
|| !gamepads_.items[index].connected)
return;
const WebGamepad& pad = gamepads_.items[index];
if (listener_)
listener_->didConnectGamepad(index, pad);
}
void GamepadController::Disconnect(int index) {
if (index < 0 || index >= static_cast<int>(WebGamepads::itemsLengthCap))
return;
WebGamepad& pad = gamepads_.items[index];
pad.connected = false;
gamepads_.length = 0;
for (unsigned i = 0; i < WebGamepads::itemsLengthCap; ++i) {
if (gamepads_.items[i].connected)
gamepads_.length = i + 1;
}
if (listener_)
listener_->didDisconnectGamepad(index, pad);
}
void GamepadController::SetId(int index, const std::string& src) {
if (index < 0 || index >= static_cast<int>(WebGamepads::itemsLengthCap))
return;
const char* p = src.c_str();
memset(gamepads_.items[index].id, 0, sizeof(gamepads_.items[index].id));
for (unsigned i = 0; *p && i < WebGamepad::idLengthCap - 1; ++i)
gamepads_.items[index].id[i] = *p++;
}
void GamepadController::SetButtonCount(int index, int buttons) {
if (index < 0 || index >= static_cast<int>(WebGamepads::itemsLengthCap))
return;
if (buttons < 0 || buttons >= static_cast<int>(WebGamepad::buttonsLengthCap))
return;
gamepads_.items[index].buttonsLength = buttons;
}
void GamepadController::SetButtonData(int index, int button, double data) {
if (index < 0 || index >= static_cast<int>(WebGamepads::itemsLengthCap))
return;
if (button < 0 || button >= static_cast<int>(WebGamepad::buttonsLengthCap))
return;
gamepads_.items[index].buttons[button].value = data;
gamepads_.items[index].buttons[button].pressed = data > 0.1f;
}
void GamepadController::SetAxisCount(int index, int axes) {
if (index < 0 || index >= static_cast<int>(WebGamepads::itemsLengthCap))
return;
if (axes < 0 || axes >= static_cast<int>(WebGamepad::axesLengthCap))
return;
gamepads_.items[index].axesLength = axes;
}
void GamepadController::SetAxisData(int index, int axis, double data) {
if (index < 0 || index >= static_cast<int>(WebGamepads::itemsLengthCap))
return;
if (axis < 0 || axis >= static_cast<int>(WebGamepad::axesLengthCap))
return;
gamepads_.items[index].axes[axis] = data;
}
} // namespace test_runner