Skip to content

Commit

Permalink
DataTypes for BufferUtil
Browse files Browse the repository at this point in the history
  • Loading branch information
Sleitnick committed Dec 1, 2023
1 parent eb4edec commit c884161
Show file tree
Hide file tree
Showing 8 changed files with 348 additions and 60 deletions.
34 changes: 17 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,28 @@

| Module | Dependency | Description |
| -- | -- | -- |
| [BufferUtil](https://sleitnick.github.io/RbxUtil/api/BufferUtil) | `BufferUtil = "sleitnick/[email protected]"` | Buffer utilities |
| [Tree](https://sleitnick.github.io/RbxUtil/api/Tree) | `Tree = "sleitnick/[email protected]"` | Utility functions for accessing instances in the game hierarchy |
| [Silo](https://sleitnick.github.io/RbxUtil/api/Silo) | `Silo = "sleitnick/[email protected]"` | State container class |
| [TableUtil](https://sleitnick.github.io/RbxUtil/api/TableUtil) | `TableUtil = "sleitnick/[email protected]"` | Table utility functions |
| [Net](https://sleitnick.github.io/RbxUtil/api/Net) | `Net = "sleitnick/[email protected]"` | Static networking module |
| [Streamable](https://sleitnick.github.io/RbxUtil/api/Streamable) | `Streamable = "sleitnick/[email protected]"` | Streamable class and StreamableUtil |
| [TaskQueue](https://sleitnick.github.io/RbxUtil/api/TaskQueue) | `TaskQueue = "sleitnick/[email protected]"` | Batches tasks that occur on the same execution step |
| [Shake](https://sleitnick.github.io/RbxUtil/api/Shake) | `Shake = "sleitnick/[email protected]"` | Shake class for making things shake |
| [Input](https://sleitnick.github.io/RbxUtil/api/Input) | `Input = "sleitnick/[email protected]"` | Basic input classes |
| [Timer](https://sleitnick.github.io/RbxUtil/api/Timer) | `Timer = "sleitnick/[email protected]"` | Timer class |
| [Sequent](https://sleitnick.github.io/RbxUtil/api/Sequent) | `Sequent = "sleitnick/[email protected]"` | Sequent class |
| [Trove](https://sleitnick.github.io/RbxUtil/api/Trove) | `Trove = "sleitnick/[email protected]"` | Trove class for tracking and cleaning up objects |
| [Comm](https://sleitnick.github.io/RbxUtil/api/Comm) | `Comm = "sleitnick/[email protected]"` | Comm library for remote communication |
| [Component](https://sleitnick.github.io/RbxUtil/api/Component) | `Component = "sleitnick/[email protected]"` | Component class |
| [Concur](https://sleitnick.github.io/RbxUtil/api/Concur) | `Concur = "sleitnick/[email protected]"` | Concurrent task handler |
| [Symbol](https://sleitnick.github.io/RbxUtil/api/Symbol) | `Symbol = "sleitnick/[email protected]"` | Symbol |
| [Option](https://sleitnick.github.io/RbxUtil/api/Option) | `Option = "sleitnick/[email protected]"` | Represent optional values in Lua |
| [EnumList](https://sleitnick.github.io/RbxUtil/api/EnumList) | `EnumList = "sleitnick/[email protected]"` | Enum List class |
| [Input](https://sleitnick.github.io/RbxUtil/api/Input) | `Input = "sleitnick/[email protected]"` | Basic input classes |
| [BufferUtil](https://sleitnick.github.io/RbxUtil/api/BufferUtil) | `BufferUtil = "sleitnick/[email protected]"` | Buffer utilities |
| [PID](https://sleitnick.github.io/RbxUtil/api/PID) | `PID = "sleitnick/[email protected]"` | PID Controller class |
| [Loader](https://sleitnick.github.io/RbxUtil/api/Loader) | `Loader = "sleitnick/[email protected]"` | Requires all modules within a given instance |
| [Concur](https://sleitnick.github.io/RbxUtil/api/Concur) | `Concur = "sleitnick/[email protected]"` | Concurrent task handler |
| [Log](https://sleitnick.github.io/RbxUtil/api/Log) | `Log = "sleitnick/[email protected]"` | Log class for logging to PlayFab |
| [Net](https://sleitnick.github.io/RbxUtil/api/Net) | `Net = "sleitnick/[email protected]"` | Static networking module |
| [Option](https://sleitnick.github.io/RbxUtil/api/Option) | `Option = "sleitnick/[email protected]"` | Represent optional values in Lua |
| [PID](https://sleitnick.github.io/RbxUtil/api/PID) | `PID = "sleitnick/[email protected]"` | PID Controller class |
| [Quaternion](https://sleitnick.github.io/RbxUtil/api/Quaternion) | `Quaternion = "sleitnick/[email protected]"` | Quaternion class |
| [Sequent](https://sleitnick.github.io/RbxUtil/api/Sequent) | `Sequent = "sleitnick/[email protected]"` | Sequent class |
| [Ser](https://sleitnick.github.io/RbxUtil/api/Ser) | `Ser = "sleitnick/[email protected]"` | Ser class for serialization and deserialization |
| [Shake](https://sleitnick.github.io/RbxUtil/api/Shake) | `Shake = "sleitnick/[email protected]"` | Shake class for making things shake |
| [Signal](https://sleitnick.github.io/RbxUtil/api/Signal) | `Signal = "sleitnick/[email protected]"` | Signal class |
| [Silo](https://sleitnick.github.io/RbxUtil/api/Silo) | `Silo = "sleitnick/[email protected]"` | State container class |
| [Streamable](https://sleitnick.github.io/RbxUtil/api/Streamable) | `Streamable = "sleitnick/[email protected]"` | Streamable class and StreamableUtil |
| [Symbol](https://sleitnick.github.io/RbxUtil/api/Symbol) | `Symbol = "sleitnick/[email protected]"` | Symbol |
| [TableUtil](https://sleitnick.github.io/RbxUtil/api/TableUtil) | `TableUtil = "sleitnick/[email protected]"` | Table utility functions |
| [TaskQueue](https://sleitnick.github.io/RbxUtil/api/TaskQueue) | `TaskQueue = "sleitnick/[email protected]"` | Batches tasks that occur on the same execution step |
| [Timer](https://sleitnick.github.io/RbxUtil/api/Timer) | `Timer = "sleitnick/[email protected]"` | Timer class |
| [Tree](https://sleitnick.github.io/RbxUtil/api/Tree) | `Tree = "sleitnick/[email protected]"` | Utility functions for accessing instances in the game hierarchy |
| [Trove](https://sleitnick.github.io/RbxUtil/api/Trove) | `Trove = "sleitnick/[email protected]"` | Trove class for tracking and cleaning up objects |
| [WaitFor](https://sleitnick.github.io/RbxUtil/api/WaitFor) | `WaitFor = "sleitnick/[email protected]"` | WaitFor class for awaiting instances |
| [Signal](https://sleitnick.github.io/RbxUtil/api/Signal) | `Signal = "sleitnick/[email protected]"` | Signal class |
32 changes: 13 additions & 19 deletions modules/buffer-util/BufferReader.lua
Original file line number Diff line number Diff line change
@@ -1,24 +1,8 @@
--!native

export type BufferReader = {
ReadInt8: (self: BufferReader) -> number,
ReadUInt8: (self: BufferReader) -> number,
ReadInt16: (self: BufferReader) -> number,
ReadUInt16: (self: BufferReader) -> number,
ReadInt32: (self: BufferReader) -> number,
ReadUInt32: (self: BufferReader) -> number,
ReadFloat32: (self: BufferReader) -> number,
ReadFloat64: (self: BufferReader) -> number,
ReadString: (self: BufferReader) -> string,
ReadStringRaw: (self: BufferReader, length: number) -> string,
GetSize: (self: BufferReader) -> number,
ResetCursor: (self: BufferReader) -> (),
SetCursor: (self: BufferReader, cursorPosition: number) -> (),
GetCursor: (self: BufferReader) -> number,
GetBuffer: (self: BufferReader) -> buffer,
}

local BufferWriter = require(script.Parent.BufferWriter)
local DataTypeBuffer = require(script.Parent.DataTypeBuffer)
local Types = require(script.Parent.Types)

--[=[
@class BufferReader
Expand All @@ -29,7 +13,7 @@ local BufferWriter = require(script.Parent.BufferWriter)
local BufferReader = {}
BufferReader.__index = BufferReader

function BufferReader.new(buf: string | buffer | BufferWriter.BufferWriter): BufferReader
function BufferReader.new(buf: string | buffer | Types.BufferWriter): Types.BufferReader
if typeof(buf) == "string" then
return BufferReader.fromString(buf)
elseif typeof(buf) == "buffer" then
Expand Down Expand Up @@ -170,6 +154,16 @@ function BufferReader:ReadStringRaw(length: number): string
return s
end

function BufferReader:ReadDataType<T>(dataType: T): T
local name = DataTypeBuffer.DataTypesToString[dataType]
if not name then
error("unsupported data type", 2)
end

local readWrite = DataTypeBuffer.ReadWrite[name]
return readWrite.read(self)
end

--[=[
Sets the position of the cursor.
]=]
Expand Down
35 changes: 13 additions & 22 deletions modules/buffer-util/BufferWriter.lua
Original file line number Diff line number Diff line change
@@ -1,28 +1,10 @@
--!native

export type BufferWriter = {
WriteInt8: (self: BufferWriter, int8: number) -> (),
WriteUInt8: (self: BufferWriter, uint8: number) -> (),
WriteInt16: (self: BufferWriter, int16: number) -> (),
WriteUInt16: (self: BufferWriter, uint16: number) -> (),
WriteInt32: (self: BufferWriter, int32: number) -> (),
WriteUInt32: (self: BufferWriter, uint32: number) -> (),
WriteFloat32: (self: BufferWriter, f32: number) -> (),
WriteFloat64: (self: BufferWriter, f64: number) -> (),
WriteString: (self: BufferWriter, str: string, length: number?) -> (),
WriteStringRaw: (self: BufferWriter, str: string, length: number?) -> (),
GetSize: (self: BufferWriter) -> number,
GetCapacity: (self: BufferWriter) -> number,
ResetCursor: (self: BufferWriter) -> (),
SetCursor: (self: BufferWriter, cursorPosition: number) -> (),
GetCursor: (self: BufferWriter) -> number,
Shrink: (self: BufferWriter) -> (),
GetBuffer: (self: BufferWriter) -> buffer,
ToString: (self: BufferWriter) -> string,
}

local MAX_SIZE = 1073741824

local DataTypeBuffer = require(script.Parent.DataTypeBuffer)
local Types = require(script.Parent.Types)

--[=[
@class BufferWriter
Expand All @@ -35,7 +17,7 @@ local MAX_SIZE = 1073741824
local BufferWriter = {}
BufferWriter.__index = BufferWriter

function BufferWriter.new(initialSize: number?)
function BufferWriter.new(initialSize: number?): Types.BufferWriter
local size = if typeof(initialSize) == "number" then math.clamp(initialSize, 0, MAX_SIZE) else 0

local self = setmetatable({
Expand Down Expand Up @@ -180,6 +162,15 @@ function BufferWriter:WriteStringRaw(str: string, length: number?)
self._cursor += len
end

function BufferWriter:WriteDataType(value: any)
local t = typeof(value)
local readWrite = DataTypeBuffer.ReadWrite[t]
if not readWrite then
error(`unsupported data type "{t}"`, 2)
end
readWrite.write(self, value)
end

--[=[
Shrinks the capacity of the buffer to the current data size.
]=]
Expand Down
223 changes: 223 additions & 0 deletions modules/buffer-util/DataTypeBuffer.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,223 @@
--!native

local Types = require(script.Parent.Types)

type ReadWritePair = {
read: <T>(reader: Types.BufferReader) -> T,
write: <T>(writer: Types.BufferWriter, value: T) -> (),
}

local DataTypeBuffer = {}

DataTypeBuffer.DataTypesToString = {
[BrickColor] = "BrickColor",
[CFrame] = "CFrame",
[Color3] = "Color3",
[DateTime] = "DateTime",
[Ray] = "Ray",
[Rect] = "Rect",
[Region3] = "Region3",
[Region3int16] = "Region3int16",
[UDim] = "UDim",
[UDim2] = "UDim2",
[Vector2] = "Vector2",
[Vector3] = "Vector3",
[Vector2int16] = "Vector2int16",
[Vector3int16] = "Vector3int16",
}

DataTypeBuffer.ReadWrite = {} :: { [string]: ReadWritePair }

DataTypeBuffer.ReadWrite.BrickColor = {
write = function(writer: Types.BufferWriter, brickColor: BrickColor)
writer:WriteUInt16(brickColor.Number)
end,

read = function(reader: Types.BufferReader): BrickColor
local number = reader:ReadUInt16()
return BrickColor.new(number)
end,
}

DataTypeBuffer.ReadWrite.CFrame = {
write = function(writer: Types.BufferWriter, cf: CFrame)
DataTypeBuffer.ReadWrite.Vector3.write(writer, cf.Position)
DataTypeBuffer.ReadWrite.Vector3.write(writer, cf.XVector)
DataTypeBuffer.ReadWrite.Vector3.write(writer, cf.YVector)
DataTypeBuffer.ReadWrite.Vector3.write(writer, cf.ZVector)
end,

read = function(reader: Types.BufferReader): CFrame
local pos = DataTypeBuffer.ReadWrite.Vector3.read(reader)
local vx = DataTypeBuffer.ReadWrite.Vector3.read(reader)
local vy = DataTypeBuffer.ReadWrite.Vector3.read(reader)
local vz = DataTypeBuffer.ReadWrite.Vector3.read(reader)
return CFrame.fromMatrix(pos, vx, vy, vz)
end,
}

DataTypeBuffer.ReadWrite.Color3 = {
write = function(writer: Types.BufferWriter, c: Color3)
writer:WriteFloat32(c.R)
writer:WriteFloat32(c.G)
writer:WriteFloat32(c.B)
end,

read = function(reader: Types.BufferReader): Color3
local r = reader:ReadFloat32()
local g = reader:ReadFloat32()
local b = reader:ReadFloat32()
return Color3.new(r, g, b)
end,
}

DataTypeBuffer.ReadWrite.DateTime = {
write = function(writer: Types.BufferWriter, dt: DateTime)
writer:WriteFloat64(dt.UnixTimestampMillis)
end,

read = function(reader: Types.BufferReader): DateTime
local millis = reader:ReadFloat64()
return DateTime.fromUnixTimestampMillis(millis)
end,
}

DataTypeBuffer.ReadWrite.Ray = {
write = function(writer: Types.BufferWriter, ray: Ray)
DataTypeBuffer.ReadWrite.Vector3.write(writer, ray.Origin)
DataTypeBuffer.ReadWrite.Vector3.write(writer, ray.Direction)
end,

read = function(reader: Types.BufferReader): Ray
local origin = DataTypeBuffer.ReadWrite.Vector3.read(reader)
local direction = DataTypeBuffer.ReadWrite.Vector3.read(reader)
return Ray.new(origin, direction)
end,
}

DataTypeBuffer.ReadWrite.Rect = {
write = function(writer: Types.BufferWriter, rect: Rect)
DataTypeBuffer.ReadWrite.Vector3.write(writer, rect.Min)
DataTypeBuffer.ReadWrite.Vector3.write(writer, rect.Max)
end,

read = function(reader: Types.BufferReader): Rect
local min = DataTypeBuffer.ReadWrite.Vector3.read(reader)
local max = DataTypeBuffer.ReadWrite.Vector3.read(reader)
return Rect.new(min, max)
end,
}

DataTypeBuffer.ReadWrite.Region3 = {
write = function(writer: Types.BufferWriter, region3: Region3)
local pos = region3.CFrame.Position
local sizeHalf = region3.Size * 0.5
local min = pos - sizeHalf
local max = pos + sizeHalf
DataTypeBuffer.ReadWrite.Vector3.write(writer, min)
DataTypeBuffer.ReadWrite.Vector3.write(writer, max)
end,

read = function(reader: Types.BufferReader): Region3
local min = DataTypeBuffer.ReadWrite.Vector3.read(reader)
local max = DataTypeBuffer.ReadWrite.Vector3.read(reader)
return Region3.new(min, max)
end,
}

DataTypeBuffer.ReadWrite.Region3int16 = {
write = function(writer: Types.BufferWriter, region3int16: Region3int16)
DataTypeBuffer.ReadWrite.Vector3int16.write(writer, region3int16.Min)
DataTypeBuffer.ReadWrite.Vector3int16.write(writer, region3int16.Max)
end,

read = function(reader: Types.BufferReader): Region3int16
local min = DataTypeBuffer.ReadWrite.Vector3int16.read(reader)
local max = DataTypeBuffer.ReadWrite.Vector3int16.read(reader)
return Region3int16.new(min, max)
end,
}

DataTypeBuffer.ReadWrite.UDim = {
write = function(writer: Types.BufferWriter, udim: UDim)
writer:WriteFloat32(udim.Scale)
writer:WriteInt32(udim.Offset)
end,

read = function(reader: Types.BufferReader): UDim
local scale = reader:ReadFloat32()
local offset = reader:ReadInt32()
return UDim.new(scale, offset)
end,
}

DataTypeBuffer.ReadWrite.UDim2 = {
write = function(writer: Types.BufferWriter, udim2: UDim2)
DataTypeBuffer.ReadWrite.UDim.write(writer, udim2.X)
DataTypeBuffer.ReadWrite.UDim.write(writer, udim2.Y)
end,

read = function(reader: Types.BufferReader): UDim2
local x = DataTypeBuffer.ReadWrite.UDim.read(reader)
local y = DataTypeBuffer.ReadWrite.UDim.read(reader)
return UDim2.new(x, y)
end,
}

DataTypeBuffer.ReadWrite.Vector2 = {
write = function(writer: Types.BufferWriter, v2: Vector2)
writer:WriteFloat32(v2.X)
writer:WriteFloat32(v2.Y)
end,

read = function(reader: Types.BufferReader): Vector2
local x = reader:ReadFloat32()
local y = reader:ReadFloat32()
return Vector2.new(x, y)
end,
}

DataTypeBuffer.ReadWrite.Vector3 = {
write = function(writer: Types.BufferWriter, v3: Vector3)
writer:WriteFloat32(v3.X)
writer:WriteFloat32(v3.Y)
writer:WriteFloat32(v3.Z)
end,

read = function(reader: Types.BufferReader): Vector3
local x = reader:ReadFloat32()
local y = reader:ReadFloat32()
local z = reader:ReadFloat32()
return Vector3.new(x, y, z)
end,
}

DataTypeBuffer.ReadWrite.Vector2int16 = {
write = function(writer: Types.BufferWriter, v2: Vector2int16)
writer:WriteInt16(v2.X)
writer:WriteInt16(v2.Y)
end,

read = function(reader: Types.BufferReader): Vector2int16
local x = reader:ReadInt16()
local y = reader:ReadInt16()
return Vector2int16.new(x, y)
end,
}

DataTypeBuffer.ReadWrite.Vector3int16 = {
write = function(writer: Types.BufferWriter, v3: Vector3int16)
writer:WriteInt16(v3.X)
writer:WriteInt16(v3.Y)
writer:WriteInt16(v3.Z)
end,

read = function(reader: Types.BufferReader): Vector3int16
local x = reader:ReadInt16()
local y = reader:ReadInt16()
local z = reader:ReadInt16()
return Vector3int16.new(x, y, z)
end,
}

return DataTypeBuffer
Loading

0 comments on commit c884161

Please sign in to comment.