Index: Source/modules/webmidi/MIDIPort.cpp |
diff --git a/Source/modules/webmidi/MIDIPort.cpp b/Source/modules/webmidi/MIDIPort.cpp |
index 519de7fa4cc98b9707f8da8b4ae30b82768f1b8a..3fc72a648e0f492a693a89adf9bbbbe909ed1bc9 100644 |
--- a/Source/modules/webmidi/MIDIPort.cpp |
+++ b/Source/modules/webmidi/MIDIPort.cpp |
@@ -40,37 +40,48 @@ namespace blink { |
using PortState = MIDIAccessor::MIDIPortState; |
-MIDIPort::MIDIPort(MIDIAccess* access, const String& id, const String& manufacturer, const String& name, MIDIPortTypeCode type, const String& version, PortState state) |
+MIDIPort::MIDIPort(MIDIAccess* access, const String& id, const String& manufacturer, const String& name, TypeCode type, const String& version, PortState state) |
: m_id(id) |
, m_manufacturer(manufacturer) |
, m_name(name) |
, m_type(type) |
, m_version(version) |
, m_access(access) |
+ , m_connection(ConnectionStateClosed) |
{ |
ASSERT(access); |
- ASSERT(type == MIDIPortTypeInput || type == MIDIPortTypeOutput); |
+ ASSERT(type == TypeInput || type == TypeOutput); |
ASSERT(state == PortState::MIDIPortStateDisconnected |
|| state == PortState::MIDIPortStateConnected |
|| state == PortState::MIDIPortStateOpened); |
- // FIXME: Remove following code once blink API has a real open and close |
- // operations. |
+ // TODO(toyoshim): Remove following code once blink API has a real open and |
+ // close operations. |
if (state == PortState::MIDIPortStateOpened) |
state = PortState::MIDIPortStateConnected; |
m_state = state; |
} |
+String MIDIPort::connection() const |
+{ |
+ switch (m_connection) { |
+ case ConnectionStateOpen: |
+ return "open"; |
+ case ConnectionStateClosed: |
+ return "closed"; |
+ case ConnectionStatePending: |
+ return "pending"; |
+ } |
+ return emptyString(); |
+} |
+ |
String MIDIPort::state() const |
{ |
switch (m_state) { |
case PortState::MIDIPortStateDisconnected: |
return "disconnected"; |
case PortState::MIDIPortStateConnected: |
- return "connected"; |
case PortState::MIDIPortStateOpened: |
- return "opened"; |
- default: |
- ASSERT_NOT_REACHED(); |
+ return "connected"; |
} |
return emptyString(); |
} |
@@ -78,28 +89,25 @@ String MIDIPort::state() const |
String MIDIPort::type() const |
{ |
switch (m_type) { |
- case MIDIPortTypeInput: |
+ case TypeInput: |
return "input"; |
- case MIDIPortTypeOutput: |
+ case TypeOutput: |
return "output"; |
- default: |
- ASSERT_NOT_REACHED(); |
} |
return emptyString(); |
} |
ScriptPromise MIDIPort::open(ScriptState* scriptState) |
{ |
+ // TODO(toyoshim): Implement the latest open() algorithm. |
switch (m_state) { |
case PortState::MIDIPortStateDisconnected: |
return reject(scriptState, InvalidStateError, "The port has been disconnected."); |
case PortState::MIDIPortStateConnected: |
- // FIXME: Add blink API to perform a real open operation. |
- setState(PortState::MIDIPortStateOpened); |
- // fall through |
+ // TODO(toyoshim): Add blink API to perform a real open operation. |
+ return setStates(m_state, ConnectionStateOpen)->accept(scriptState); |
case PortState::MIDIPortStateOpened: |
- return accept(scriptState); |
- default: |
+ // TODO(toyoshim): Remove PortState::MIDIPortStateOpened. |
ASSERT_NOT_REACHED(); |
} |
return reject(scriptState, InvalidStateError, "The port is in unknown state."); |
@@ -107,16 +115,15 @@ ScriptPromise MIDIPort::open(ScriptState* scriptState) |
ScriptPromise MIDIPort::close(ScriptState* scriptState) |
{ |
+ // TODO(toyoshim): Implement the latest close() algorithm. |
switch (m_state) { |
case PortState::MIDIPortStateDisconnected: |
return reject(scriptState, InvalidStateError, "The port has been disconnected."); |
- case PortState::MIDIPortStateOpened: |
- // FIXME: Add blink API to perform a real close operation. |
- setState(PortState::MIDIPortStateConnected); |
- // fall through |
case PortState::MIDIPortStateConnected: |
- return accept(scriptState); |
- default: |
+ // TODO(toyoshim): Add blink API to perform a real close operation. |
+ return setStates(m_state, ConnectionStateClosed)->accept(scriptState); |
+ case PortState::MIDIPortStateOpened: |
+ // TODO(toyoshim): Remove PortState::MIDIPortStateOpened. |
ASSERT_NOT_REACHED(); |
} |
return reject(scriptState, InvalidStateError, "The port is in unknown state."); |
@@ -124,10 +131,7 @@ ScriptPromise MIDIPort::close(ScriptState* scriptState) |
void MIDIPort::setState(PortState state) |
{ |
- if (m_state == state) |
- return; |
- m_state = state; |
- dispatchEvent(MIDIConnectionEvent::create(this)); |
+ setStates(state, m_connection); |
} |
ExecutionContext* MIDIPort::executionContext() const |
@@ -151,4 +155,19 @@ ScriptPromise MIDIPort::reject(ScriptState* scriptState, ExceptionCode ec, const |
return ScriptPromise::rejectWithDOMException(scriptState, DOMException::create(ec, message)); |
} |
+// Note: setStates() dispatches a event and JavaScript may release this object |
+// inside the handler. Caller should consider to retain |this|. |
+MIDIPort* MIDIPort::setStates(PortState state, ConnectionState connection) |
+{ |
+ // Retain |this| since an event handler may release it inside setStates(). |
+ MIDIPort* self = this; |
tkent
2015/03/31 01:26:10
Ah, MIDIPort is already on Oilpan. Then you need
yhirano
2015/03/31 02:23:37
But I think we should protect the wrapper in order
|
+ |
+ if (m_state == state && m_connection == connection) |
+ return self; |
+ m_state = state; |
+ m_connection = connection; |
+ dispatchEvent(MIDIConnectionEvent::create(this)); |
+ return self; |
+} |
+ |
} // namespace blink |