Files
tankz/src/common/haxe/ru/m/connect/PacketQueue.hx
2018-03-01 12:05:06 +03:00

76 lines
2.0 KiB
Haxe
Executable File

package ru.m.connect;
import haxe.io.Bytes;
import haxe.io.BytesBuffer;
import haxe.io.BytesInput;
import protohx.Message;
class PacketQueue<P:Message> {
public var packetClass(default, null):Class<P>;
private var bytesBuff:Bytes;
private var msgs:List<P>;
public function new(packetClass:Class<P>) {
this.packetClass = packetClass;
msgs = new List<P>();
}
public inline function hasMsg():Bool {
return !msgs.isEmpty();
}
public inline function popMsg():P {
return msgs.pop();
}
public inline function addMsg(msg:P):Void {
msgs.add(msg);
}
public function addBytes(bytes:Bytes):Void {
if (bytes == null) {
return;
}
if (bytesBuff == null) {
bytesBuff = bytes;
} else {
var buffer = new BytesBuffer();
buffer.add(bytesBuff);
buffer.add(bytes);
bytesBuff = buffer.getBytes();
}
if (bytesBuff == null || bytesBuff.length < 1) {
return;
}
var available = bytesBuff.length;
var bi = new BytesInput(bytesBuff);
bi.bigEndian = false;
while (available > 0) {
var packetSize = bi.readUInt16();
available -= 2;
if (packetSize <= available) {
var msgBytes = bi.read(packetSize);
var packet:P = Type.createInstance(packetClass, []);
packet.mergeFrom(msgBytes);
addMsg(packet);
available -= packetSize;
} else {
break;
}
}
if (available == 0) {
bytesBuff = null;
} else if (available > 0) {
if (bytesBuff.length != available) {
var pos = bytesBuff.length - available;
bytesBuff = bytesBuff.sub(pos, available);
}
} else {
throw "Wrong available: " + available;
}
}
}