eaglercraft-1.8/sources/wasm-gc-teavm/js/platformNetworking.js

366 lines
7.6 KiB
JavaScript

/*
* Copyright (c) 2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
const platfNetworkingName = "platformNetworking";
(function() {
const WS_CLOSED = 0;
const WS_CONNECTING = 1;
const WS_CONNECTED = 2;
const WS_FAILED = 3;
function closeSocketImpl() {
this["_socket"].close();
}
/**
* @param {string} str
*/
function sendStringFrameImpl(str) {
this["_socket"].send(str);
}
/**
* @param {Uint8Array} bin
*/
function sendBinaryFrameImpl(bin) {
this["_socket"].send(bin);
}
/**
* @return {number}
*/
function availableFramesImpl() {
return this["_frameCountStr"] + this["_frameCountBin"];
}
/**
* @return {Object}
*/
function getNextFrameImpl() {
const f = this["_queue"];
if(f) {
if(f["_next"] === f && f["_prev"] === f) {
this["_queue"] = null;
}else {
this["_queue"] = f["_next"];
f["_prev"]["_next"] = f["_next"];
f["_next"]["_prev"] = f["_prev"];
}
f["_next"] = null;
f["_prev"] = null;
if(f["type"] === 0) {
--this["_frameCountStr"];
}else {
--this["_frameCountBin"];
}
return f;
}else {
return null;
}
}
/**
* @return {Array}
*/
function getAllFramesImpl() {
const len = this["_frameCountStr"] + this["_frameCountBin"];
if(len === 0) {
return null;
}
const ret = new Array(len);
var idx = 0;
var f = this["_queue"];
var g;
const ff = f;
do {
ret[idx++] = f;
g = f["_next"];
f["_next"] = null;
f["_prev"] = null;
f = g;
}while(f !== ff);
this["_queue"] = null;
this["_frameCountStr"] = 0;
this["_frameCountBin"] = 0;
return ret;
}
function clearFramesImpl() {
this["_queue"] = null;
this["_frameCountStr"] = 0;
this["_frameCountBin"] = 0;
}
/**
* @param {Object} thisObj
* @param {number} type
* @return {Object}
*/
function getNextTypedFrameImpl(thisObj, type) {
var f = thisObj["_queue"];
if(!f) {
return null;
}
var g, h;
const ff = f;
do {
g = f["_next"];
if(f["type"] === type) {
h = f["_prev"];
if(g === f && h === f) {
thisObj["_queue"] = null;
}else {
if(f === ff) {
thisObj["_queue"] = g;
}
h["_next"] = g;
g["_prev"] = h;
}
f["_next"] = null;
f["_prev"] = null;
return f;
}
f = g;
}while(f !== ff);
return null;
}
/**
* @param {Object} thisObj
* @param {number} type
* @param {Array} ret
*/
function getAllTypedFrameImpl(thisObj, type, ret) {
var idx = 0;
var f = thisObj["_queue"];
var g, h;
const ff = f;
do {
g = f["_next"];
if(f["type"] === type) {
ret[idx++] = f;
}
f = g;
}while(f !== ff);
ret.length = idx;
for(var i = 0; i < idx; ++i) {
f = ret[i];
g = f["_next"];
h = f["_prev"];
if(g === f && h === f) {
thisObj["_queue"] = null;
}else {
if(f === thisObj["_queue"]) {
thisObj["_queue"] = g;
}
h["_next"] = g;
g["_prev"] = h;
}
}
}
/**
* @return {number}
*/
function availableStringFramesImpl() {
return this["_frameCountStr"];
}
/**
* @return {Object}
*/
function getNextStringFrameImpl() {
const len = this["_frameCountStr"];
if(len === 0) {
return null;
}
const ret = getNextTypedFrameImpl(this, 0);
if(!ret) {
this["_frameCountStr"] = 0;
}else {
--this["_frameCountStr"];
}
return ret;
}
/**
* @return {Array}
*/
function getAllStringFramesImpl() {
const len = this["_frameCountStr"];
if(len === 0) {
return null;
}
const ret = new Array(len);
getAllTypedFrameImpl(this, 0, ret);
this["_frameCountStr"] = 0;
return ret;
}
function clearStringFramesImpl() {
const len = this["_frameCountStr"];
if(len === 0) {
return null;
}
const ret = new Array(len);
getAllTypedFrameImpl(this, 0, ret);
this["_frameCountStr"] = 0;
}
/**
* @return {number}
*/
function availableBinaryFramesImpl() {
return this["_frameCountBin"];
}
/**
* @return {Object}
*/
function getNextBinaryFrameImpl() {
const len = this["_frameCountBin"];
if(len === 0) {
return null;
}
const ret = getNextTypedFrameImpl(this, 1);
if(!ret) {
this["_frameCountBin"] = 0;
}else {
--this["_frameCountBin"];
}
return ret;
}
/**
* @return {Array}
*/
function getAllBinaryFramesImpl() {
const len = this["_frameCountBin"];
if(len === 0) {
return null;
}
const ret = new Array(len);
getAllTypedFrameImpl(this, 1, ret);
this["_frameCountBin"] = 0;
return ret;
}
function clearBinaryFramesImpl() {
const len = this["_frameCountBin"];
if(len === 0) {
return null;
}
const ret = new Array(len);
getAllTypedFrameImpl(this, 1, ret);
this["_frameCountBin"] = 0;
}
function addRecievedFrameImpl(dat) {
const isStr = (typeof dat === "string");
const itm = {
"type": (isStr ? 0 : 1),
"data": dat,
"timestamp": performance.now(),
"_next": null,
"_prev": null
};
const first = this["_queue"];
if(!first) {
this["_queue"] = itm;
itm["_next"] = itm;
itm["_prev"] = itm;
}else {
const last = first["_prev"];
last["_next"] = itm;
itm["_prev"] = last;
itm["_next"] = first;
first["_prev"] = itm;
}
if(isStr) {
++this["_frameCountStr"];
}else {
++this["_frameCountBin"];
}
}
/**
* @param {string} socketURI
* @return {Object}
*/
eagruntimeImpl.platformNetworking["createWebSocketHandle"] = function(socketURI) {
let sock;
try {
sock = new WebSocket(socketURI);
}catch(ex) {
eagError("Failed to create WebSocket: {}", socketURI);
eagStackTrace(ERROR, "Exception Caught", ex);
return null;
}
sock.binaryType = "arraybuffer";
const ret = {
"state": WS_CONNECTING,
"_socket": sock,
"_queue": null,
"_frameCountStr": 0,
"_frameCountBin": 0,
"_addRecievedFrame": addRecievedFrameImpl,
"closeSocket": closeSocketImpl,
"sendStringFrame": sendStringFrameImpl,
"sendBinaryFrame": sendBinaryFrameImpl,
"availableFrames": availableFramesImpl,
"getNextFrame": getNextFrameImpl,
"getAllFrames": getAllFramesImpl,
"clearFrames": clearFramesImpl,
"availableStringFrames": availableStringFramesImpl,
"getNextStringFrame": getNextStringFrameImpl,
"getAllStringFrames": getAllStringFramesImpl,
"clearStringFrames": clearStringFramesImpl,
"availableBinaryFrames": availableBinaryFramesImpl,
"getNextBinaryFrame": getNextBinaryFrameImpl,
"getAllBinaryFrames": getAllBinaryFramesImpl,
"clearBinaryFrames": clearBinaryFramesImpl
};
sock.addEventListener("open", function(evt) {
ret["state"] = WS_CONNECTED;
});
sock.addEventListener("message", function(evt) {
ret["_addRecievedFrame"](evt.data);
});
sock.addEventListener("close", function(evt) {
if(ret["state"] !== WS_FAILED) {
ret["state"] = WS_CLOSED;
}
});
sock.addEventListener("error", function(evt) {
if(ret["state"] === WS_CONNECTING) {
ret["state"] = WS_FAILED;
}
});
return ret;
};
})();