1 /* 2 * Copyright (C) 2013 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #include "config.h" 32 #include "modules/webmidi/MIDIAccessPromise.h" 33 34 #include "core/dom/DOMError.h" 35 #include "modules/webmidi/MIDIAccess.h" 36 #include "modules/webmidi/MIDIErrorCallback.h" 37 #include "modules/webmidi/MIDISuccessCallback.h" 38 39 namespace WebCore { 40 41 PassRefPtr<MIDIAccessPromise> MIDIAccessPromise::create(ExecutionContext* context, const Dictionary& options) 42 { 43 RefPtr<MIDIAccessPromise> midiAccessPromise(adoptRef(new MIDIAccessPromise(context, options))); 44 midiAccessPromise->suspendIfNeeded(); 45 return midiAccessPromise.release(); 46 } 47 48 MIDIAccessPromise::MIDIAccessPromise(ExecutionContext* context, const Dictionary& options) 49 : ActiveDOMObject(context) 50 , m_state(Pending) 51 , m_options(adoptPtr(new MIDIOptions(options))) 52 { 53 ScriptWrappable::init(this); 54 } 55 56 MIDIAccessPromise::~MIDIAccessPromise() 57 { 58 stop(); 59 } 60 61 bool MIDIAccessPromise::hasPendingActivity() const 62 { 63 return !!m_access && m_state != Accepted && m_state != Rejected; 64 } 65 66 void MIDIAccessPromise::stop() 67 { 68 m_state = Invoked; 69 if (!!m_access) 70 m_access->stop(); 71 clear(); 72 } 73 74 void MIDIAccessPromise::fulfill() 75 { 76 if (m_state == Pending) { 77 if (m_successCallback) { 78 m_state = Invoked; 79 ASSERT(m_access); 80 m_successCallback->handleEvent(m_access.get(), m_options->sysex); 81 clear(); 82 } else { 83 m_state = Accepted; 84 } 85 } 86 } 87 88 void MIDIAccessPromise::reject(PassRefPtr<DOMError> error) 89 { 90 if (m_state == Pending) { 91 if (m_errorCallback) { 92 m_state = Invoked; 93 m_errorCallback->handleEvent(error.get()); 94 clear(); 95 } else { 96 m_state = Rejected; 97 m_error = error; 98 } 99 } 100 } 101 102 void MIDIAccessPromise::then(PassOwnPtr<MIDISuccessCallback> successCallback, PassOwnPtr<MIDIErrorCallback> errorCallback) 103 { 104 // Lazily request access. 105 if (!m_access) 106 m_access = MIDIAccess::create(executionContext(), this); 107 108 switch (m_state) { 109 case Accepted: 110 m_state = Invoked; 111 successCallback->handleEvent(m_access.get(), m_options->sysex); 112 clear(); 113 break; 114 case Rejected: 115 m_state = Invoked; 116 errorCallback->handleEvent(m_error.get()); 117 clear(); 118 break; 119 case Pending: 120 m_successCallback = successCallback; 121 m_errorCallback = errorCallback; 122 break; 123 case Invoked: 124 break; 125 default: 126 ASSERT_NOT_REACHED(); 127 } 128 } 129 130 void MIDIAccessPromise::clear() 131 { 132 ASSERT(m_state == Invoked); 133 m_access.clear(); 134 m_error.clear(); 135 m_options.clear(); 136 m_successCallback.clear(); 137 m_errorCallback.clear(); 138 } 139 140 } // namespace WebCore 141