Compare commits
22 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8851908207 | |||
| c1890216c5 | |||
| 281af49d27 | |||
| 3b543e9b63 | |||
| cebe84bce1 | |||
| 433afeaaa3 | |||
| 9bda871e7c | |||
| cf2e095fbe | |||
| be703e4a10 | |||
| 57f3d9e976 | |||
| 330e6bd692 | |||
| b4ddf5dd6e | |||
| ec840f7db2 | |||
| 6f8e6bd735 | |||
| 23121a4741 | |||
| 14ef3cf2c5 | |||
| db2ba03a47 | |||
| d41cef5576 | |||
| 40b81de08d | |||
| fe70aa5404 | |||
| f490b7383b | |||
| 5d6e46dc7e |
@@ -0,0 +1,99 @@
|
||||
name: Tests
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main, master ]
|
||||
pull_request:
|
||||
branches: [ main, master ]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: ['1.25', '1.26']
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: ${{ matrix.go-version }}
|
||||
|
||||
- name: Cache Go modules
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/go/pkg/mod
|
||||
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-go-
|
||||
|
||||
- name: Download dependencies
|
||||
run: go mod download
|
||||
|
||||
- name: Run full Go test suite
|
||||
run: make test
|
||||
|
||||
- name: Run benchmarks (short)
|
||||
run: go test -bench=. -benchtime=100ms -run=^$ ./benchmarks/...
|
||||
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.23'
|
||||
|
||||
- name: golangci-lint
|
||||
uses: golangci/golangci-lint-action@v7
|
||||
with:
|
||||
version: latest
|
||||
args: --timeout=5m
|
||||
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.23'
|
||||
|
||||
- name: Build arpack CLI
|
||||
run: go build -v ./cmd/arpack
|
||||
|
||||
- name: Test code generation
|
||||
run: |
|
||||
go run ./cmd/arpack -in testdata/sample.go -out-go /tmp/gen-go -out-ts /tmp/gen-ts
|
||||
go run ./cmd/arpack -in testdata/lua/sample.go -out-lua /tmp/gen-lua
|
||||
test -f /tmp/gen-go/sample_gen.go
|
||||
test -f /tmp/gen-ts/Sample.gen.ts
|
||||
test -f /tmp/gen-lua/sample_gen.lua
|
||||
|
||||
e2e:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.23'
|
||||
|
||||
- name: Set up .NET
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: '9.0.x'
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20'
|
||||
|
||||
- name: Run E2E tests
|
||||
run: go test -v ./e2e/...
|
||||
@@ -3,6 +3,12 @@
|
||||
.codex
|
||||
.DS_Store
|
||||
|
||||
Library
|
||||
Logs
|
||||
Packages
|
||||
Temp
|
||||
UserSettings
|
||||
|
||||
.idea
|
||||
bin
|
||||
obj
|
||||
|
||||
+1
-6
@@ -15,9 +15,4 @@ linters:
|
||||
|
||||
formatters:
|
||||
enable:
|
||||
- goimports
|
||||
|
||||
linters-settings:
|
||||
goimports:
|
||||
local-prefixes:
|
||||
- gorena/server
|
||||
- goimports
|
||||
@@ -0,0 +1,10 @@
|
||||
FROM golang:1.21-bookworm
|
||||
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
protobuf-compiler \
|
||||
flatbuffers-compiler \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.36.11
|
||||
|
||||
WORKDIR /workspace
|
||||
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2026 Eduard Kargin
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -0,0 +1,38 @@
|
||||
UNITY_ASSETS := benchmarks/unity/Assets
|
||||
|
||||
.PHONY: test bench-image generate bench size gen-unity
|
||||
|
||||
IMAGE := arpack-bench
|
||||
|
||||
test:
|
||||
go test ./...
|
||||
|
||||
bench-image:
|
||||
docker build -f Dockerfile.bench -t $(IMAGE) .
|
||||
|
||||
generate:
|
||||
go run ./cmd/arpack -in benchmarks/arpackmsg/messages.go -out-go benchmarks/arpackmsg
|
||||
protoc --go_out=. --go_opt=paths=source_relative benchmarks/proto/move.proto
|
||||
|
||||
generate-docker: bench-image
|
||||
docker run --rm -v "$(PWD):/workspace" -w /workspace $(IMAGE) make generate
|
||||
|
||||
bench:
|
||||
go test ./benchmarks/... -bench=. -benchmem -count=1 -run=^$$
|
||||
|
||||
size:
|
||||
go test ./benchmarks/... -run=TestMessageSize -v
|
||||
|
||||
bench-docker: bench-image
|
||||
docker run --rm -v "$(PWD):/workspace" -w /workspace $(IMAGE) make bench
|
||||
|
||||
gen-unity:
|
||||
mkdir -p "$(UNITY_ASSETS)/Benchmarks"
|
||||
go run ./cmd/arpack \
|
||||
-in benchmarks/arpackmsg/messages.go \
|
||||
-out-cs "$(UNITY_ASSETS)/Benchmarks/" \
|
||||
-cs-namespace Arpack.Messages
|
||||
protoc -I benchmarks/proto \
|
||||
--csharp_out="$(UNITY_ASSETS)/Benchmarks/" \
|
||||
benchmarks/proto/move.proto
|
||||
@echo "Done. Attach BenchmarkRunner to a GameObject in SampleScene and press Play."
|
||||
@@ -4,18 +4,34 @@
|
||||
|
||||
# ArPack
|
||||
|
||||
Binary serialization code generator for Go and C#. Define messages once as Go structs — get zero-allocation `Marshal`/`Unmarshal` for Go and `unsafe` pointer-based `Serialize`/`Deserialize` for C#.
|
||||

|
||||

|
||||

|
||||
|
||||
Built for game networking where every byte and allocation matters.
|
||||
|
||||
Binary serialization code generator for Go, C#, TypeScript, and Lua. Define messages once as Go structs — get zero-allocation `Marshal`/`Unmarshal` for Go, `unsafe` pointer-based `Serialize`/`Deserialize` for C#, `DataView`-based serialization for TypeScript/browser, and pure Lua implementation for Defold/LuaJIT.
|
||||
|
||||
## Features
|
||||
|
||||
- **Single source of truth** — define messages in Go, generate both Go and C# code
|
||||
- **Single source of truth** — define messages in Go, generate code for Go, C#, TypeScript, and Lua
|
||||
- **Float quantization** — compress `float32`/`float64` to 8 or 16 bits with a `pack` struct tag
|
||||
- **Boolean packing** — consecutive `bool` fields are packed into single bytes (up to 8 per byte)
|
||||
- **Enums** — `type Opcode uint16` + `const` block becomes a C# `enum`
|
||||
- **Enums** — `type Opcode uint16` + `const` block becomes C#/TypeScript enums
|
||||
- **Nested types, fixed arrays, slices** — full support for complex message structures
|
||||
- **Cross-language binary compatibility** — Go and C# produce identical wire formats
|
||||
- **Cross-language binary compatibility** — Go, C#, TypeScript, and Lua produce identical wire formats
|
||||
- **Browser support** — TypeScript target uses native DataView API for zero-dependency serialization
|
||||
|
||||
## When to use
|
||||
|
||||
ArPack is designed for real-time multiplayer games and other latency-sensitive systems where a Go backend talks to a C# client over a binary protocol.
|
||||
|
||||
Typical setups:
|
||||
|
||||
- **[Nakama](https://heroiclabs.com/nakama/) + Unity** — define all network messages in Go, generate C# structs for Unity. Both sides share the exact same wire format with no reflection or boxing.
|
||||
- **Custom Go game server + Unity** — roll your own server without pulling in a serialization framework. ArPack generates plain `Marshal`/`Unmarshal` methods with zero allocations on the hot path.
|
||||
- **Any Go service + .NET client** — works anywhere you control both ends and want a compact binary protocol without Protobuf's runtime overhead or code-gen complexity.
|
||||
- **Go backend + Browser/WebSocket** — generate TypeScript classes for browser-based clients. Uses native DataView API with zero dependencies.
|
||||
- **Go backend + Defold/Lua** — generate Lua modules for Defold game engine. Pure Lua implementation compatible with LuaJIT.
|
||||
|
||||
## Installation
|
||||
|
||||
@@ -26,7 +42,14 @@ go install github.com/edmand46/arpack/cmd/arpack@latest
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
arpack -in messages.go -out-go ./gen -out-cs ../Unity/Assets/Scripts
|
||||
# Generate Go + C# + TypeScript
|
||||
arpack -in messages.go -out-go ./gen -out-cs ../Unity/Assets/Scripts -out-ts ./web/src/messages
|
||||
|
||||
# Generate only TypeScript
|
||||
arpack -in messages.go -out-ts ./web/src/messages
|
||||
|
||||
# Generate only Lua (for Defold)
|
||||
arpack -in messages.go -out-lua ./defold/scripts/messages
|
||||
```
|
||||
|
||||
| Flag | Description |
|
||||
@@ -34,13 +57,26 @@ arpack -in messages.go -out-go ./gen -out-cs ../Unity/Assets/Scripts
|
||||
| `-in` | Input Go file with struct definitions (required) |
|
||||
| `-out-go` | Output directory for generated Go code |
|
||||
| `-out-cs` | Output directory for generated C# code |
|
||||
| `-out-ts` | Output directory for generated TypeScript code |
|
||||
| `-out-lua` | Output directory for generated Lua code |
|
||||
| `-cs-namespace` | C# namespace (default: `Arpack.Messages`) |
|
||||
|
||||
At least one of `-out-go` or `-out-cs` is required.
|
||||
|
||||
**Output files:**
|
||||
- Go: `{name}_gen.go`
|
||||
- C#: `{Name}.gen.cs`
|
||||
- TypeScript: `{Name}.gen.ts`
|
||||
- Lua: `{name}_gen.lua` (snake_case for Lua `require()` compatibility)
|
||||
|
||||
## v1 Contract
|
||||
|
||||
ArPack `v1` intentionally supports a narrow schema model:
|
||||
|
||||
- Input is a single Go source file.
|
||||
- Message types must be defined in that same file.
|
||||
- External package types, pointers, and platform-dependent integer aliases (`int`, `uint`, `uintptr`) are not supported.
|
||||
- Wire format is stable within `v1.x` for unchanged schemas.
|
||||
|
||||
This is a deliberate product boundary for predictable code generation and cross-language compatibility.
|
||||
|
||||
## Schema Definition
|
||||
|
||||
@@ -79,16 +115,21 @@ type MoveMessage struct {
|
||||
|
||||
### Supported Types
|
||||
|
||||
| Type | Wire Size |
|
||||
|---|---|
|
||||
| `bool` (packed) | 1 bit (up to 8 per byte) |
|
||||
| `int8`, `uint8` | 1 byte |
|
||||
| `int16`, `uint16` | 2 bytes |
|
||||
| `int32`, `uint32`, `float32` | 4 bytes |
|
||||
| `int64`, `uint64`, `float64` | 8 bytes |
|
||||
| `string` | 2-byte length prefix + UTF-8 |
|
||||
| `[N]T` | N × sizeof(T) |
|
||||
| `[]T` | 2-byte length prefix + N × sizeof(T) |
|
||||
| Type | Wire Size | Lua Support |
|
||||
|---|---|---|
|
||||
| `bool` (packed) | 1 bit (up to 8 per byte) | ✓ (uses BitOp library) |
|
||||
| `int8`, `uint8` | 1 byte | ✓ |
|
||||
| `int16`, `uint16` | 2 bytes | ✓ |
|
||||
| `int32`, `uint32`, `float32` | 4 bytes | ✓ |
|
||||
| `int64`, `uint64` | 8 bytes | ✗ (LuaJIT limitation) |
|
||||
| `float64` | 8 bytes | ✓ |
|
||||
| `string` | 2-byte length prefix + UTF-8 | ✓ |
|
||||
| `[N]T` | N × sizeof(T) | ✓ |
|
||||
| `[]T` | 2-byte length prefix + N × sizeof(T) | ✓ |
|
||||
|
||||
**Note:** platform-dependent `int`, `uint`, and `uintptr` are not supported. Use explicit widths like `int32`, `uint32`, `int64`, or `uint64`.
|
||||
|
||||
**Note:** `int64`/`uint64` are not supported in Lua target. LuaJIT (used by Defold) represents numbers as double-precision floats, which can only safely represent integers up to 2^53. Use `int32`/`uint32` instead.
|
||||
|
||||
### Float Quantization
|
||||
|
||||
@@ -107,6 +148,8 @@ Y float32 `pack:"min=0,max=1,bits=8"` // 1 byte instead of 4
|
||||
|
||||
Values are linearly mapped: `encoded = (value - min) / (max - min) * maxUint`.
|
||||
|
||||
Quantized values must stay within the declared `[min, max]` range. Generated serializers fail fast on out-of-range or `NaN` inputs instead of silently truncating them.
|
||||
|
||||
## Generated Code
|
||||
|
||||
### Go
|
||||
@@ -118,6 +161,8 @@ func (m *MoveMessage) Unmarshal(data []byte) (int, error)
|
||||
|
||||
`Marshal` appends to the buffer and returns it. `Unmarshal` reads from the buffer and returns bytes consumed.
|
||||
|
||||
**Failure behavior:** generated `Marshal` panics if a string/slice exceeds the `uint16` wire limit or if a quantized value is outside its declared range.
|
||||
|
||||
### C#
|
||||
|
||||
```csharp
|
||||
@@ -127,6 +172,60 @@ public static unsafe int Deserialize(byte* buffer, out MoveMessage msg)
|
||||
|
||||
Uses unsafe pointers for zero-copy serialization. Returns bytes written/consumed.
|
||||
|
||||
**Failure behavior:** generated `Serialize` throws if a string/slice exceeds the `uint16` wire limit or if a quantized value is outside its declared range.
|
||||
|
||||
### TypeScript
|
||||
|
||||
```typescript
|
||||
export class MoveMessage {
|
||||
position: Vector3 = new Vector3();
|
||||
velocity: number[] = new Array<number>(3).fill(0);
|
||||
waypoints: Vector3[] = [];
|
||||
playerId: number = 0;
|
||||
active: boolean = false;
|
||||
visible: boolean = false;
|
||||
ghost: boolean = false;
|
||||
name: string = "";
|
||||
|
||||
serialize(view: DataView, offset: number): number
|
||||
static deserialize(view: DataView, offset: number): [MoveMessage, number]
|
||||
}
|
||||
```
|
||||
|
||||
Uses native DataView API for browser-compatible serialization with zero dependencies. Returns bytes written/consumed.
|
||||
|
||||
**Note:** TypeScript field names are converted to camelCase (e.g., `PlayerID` → `playerId`).
|
||||
|
||||
**Failure behavior:** generated `serialize(...)` throws `RangeError` if a string/slice exceeds the `uint16` wire limit or if a quantized value is outside its declared range.
|
||||
|
||||
### Lua
|
||||
|
||||
```lua
|
||||
local messages = require("messages.messages_gen")
|
||||
|
||||
-- Create message
|
||||
local msg = messages.new_move_message()
|
||||
msg.player_id = 123
|
||||
msg.active = true
|
||||
|
||||
-- Serialize
|
||||
local data = messages.serialize_move_message(msg)
|
||||
|
||||
-- Deserialize
|
||||
local decoded, bytes_read = messages.deserialize_move_message(data, 1)
|
||||
```
|
||||
|
||||
Uses pure Lua with inline helper functions for byte manipulation. Compatible with LuaJIT (Defold). All identifiers use snake_case (e.g., `MoveMessage` → `move_message`, `PlayerID` → `player_id`).
|
||||
|
||||
**Requirements:** The generated Lua code requires the [BitOp library](https://bitop.luajit.org/) for bit manipulation. This library is included in LuaJIT (used by Defold).
|
||||
|
||||
**Limitations:**
|
||||
- Lua target does not support `int64`/`uint64` types. Use `int32`/`uint32` instead. This is because LuaJIT represents numbers as double-precision floats, which can only safely represent integers up to 2^53.
|
||||
- Variable-length fields use `uint16` length prefixes, so `string` byte length and `[]T` element count must not exceed `65535`. Serialization raises an error if the limit is exceeded.
|
||||
- Quantized values must stay within the declared `[min, max]` range. Serialization raises a Lua error on out-of-range or `NaN` inputs.
|
||||
- Deserialization raises Lua errors on malformed or truncated input. If you need a recoverable boundary, wrap decode calls in `pcall(...)`.
|
||||
- Generated file uses snake_case naming (e.g., `messages_gen.lua`) for proper Lua `require()` resolution.
|
||||
|
||||
## Wire Format
|
||||
|
||||
- Little-endian byte order
|
||||
@@ -135,12 +234,80 @@ Uses unsafe pointers for zero-copy serialization. Returns bytes written/consumed
|
||||
- Booleans packed as bitfields (LSB first, up to 8 per byte)
|
||||
- Quantized floats stored as `uint8` or `uint16`
|
||||
|
||||
## Compatibility Guarantees
|
||||
|
||||
Within `v1.x`, the following are considered compatibility guarantees for a fixed schema:
|
||||
|
||||
- Same field declaration order produces the same wire layout.
|
||||
- Go, C#, TypeScript, and Lua generators produce identical wire bytes for supported types.
|
||||
- `string` and `[]T` always use `uint16` length prefixes.
|
||||
- Consecutive `bool` fields are bit-packed in declaration order, least-significant bit first.
|
||||
- Enum fields use their declared underlying integer type on the wire.
|
||||
|
||||
The following are breaking changes:
|
||||
|
||||
- changing field order
|
||||
- changing a field type
|
||||
- changing quantization parameters
|
||||
- changing enum underlying types
|
||||
- changing how booleans are grouped or how lengths are encoded
|
||||
|
||||
## Benchmarks
|
||||
|
||||
### Go Results (M3 Max)
|
||||
```
|
||||
BenchmarkArPack_Marshal-16 382568360 9.5 ns/op 5065 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkArPack_Unmarshal-16 98895892 34.6 ns/op 1388 MB/s 40 B/op 2 allocs/op
|
||||
BenchmarkProto_Marshal-16 21989466 163.6 ns/op 416 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkProto_Unmarshal-16 13950333 256.9 ns/op 265 MB/s 248 B/op 7 allocs/op
|
||||
BenchmarkFlatBuffers_Marshal-16 16297458 221.4 ns/op 687 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkFlatBuffers_Unmarshal-16 56095480 64.8 ns/op 2345 MB/s 24 B/op 1 allocs/op
|
||||
```
|
||||
|
||||
| Format | Size |
|
||||
|---|---|
|
||||
| ArPack | 48 bytes |
|
||||
| Protobuf | 68 bytes |
|
||||
| FlatBuffers | 152 bytes |
|
||||
|
||||
```bash
|
||||
go test ./benchmarks/... -bench=. -benchmem
|
||||
```
|
||||
|
||||
### Unity Mono (M3 Max)
|
||||
|
||||
```
|
||||
ArPack Serialize: 96.7 ns/op | 0 B/op
|
||||
ArPack Deserialize: 205.4 ns/op | 0 B/op
|
||||
Proto Serialize (alloc): 930.2 ns/op | 0 B/op
|
||||
Proto Deserialize (alloc): 1621.2 ns/op | 29 B/op
|
||||
Proto Serialize (reuse): 652.7 ns/op | 0 B/op
|
||||
```
|
||||
|
||||
ArPack serialize is ~10× faster than Protobuf in Unity. Protobuf deserialize allocates on every call — a GC pressure source in hot game loops. ArPack deserialize is zero-alloc.
|
||||
|
||||
```bash
|
||||
make gen-unity
|
||||
# then attach BenchmarkRunner to any GameObject in SampleScene and press Play
|
||||
```
|
||||
|
||||
## Running Tests
|
||||
|
||||
```bash
|
||||
# Unit tests (parser + generator)
|
||||
go test ./parser/... ./generator/...
|
||||
# Full test suite
|
||||
make test
|
||||
|
||||
# End-to-end cross-language tests (requires dotnet SDK)
|
||||
go test ./e2e/...
|
||||
# Benchmarks
|
||||
go test ./benchmarks/... -bench=. -benchmem
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
- `unknown type "..."`
|
||||
The field type is not a supported primitive and is not defined in the same schema file.
|
||||
- `external package types not supported`
|
||||
Copy the wire-facing type definition into the schema file instead of referencing another package.
|
||||
- `... exceeds uint16 limit`
|
||||
A `string` encoded to more than `65535` bytes, or a slice contains more than `65535` elements.
|
||||
- `quantized value out of range`
|
||||
The runtime value does not satisfy the declared `pack:"min=...,max=..."` bounds.
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
package arpackmsg
|
||||
|
||||
type Vector3 struct {
|
||||
X float32 `pack:"min=-500,max=500,bits=16"`
|
||||
Y float32 `pack:"min=-500,max=500,bits=16"`
|
||||
Z float32 `pack:"min=-500,max=500,bits=16"`
|
||||
}
|
||||
|
||||
type Opcode uint16
|
||||
|
||||
const (
|
||||
OpcodeUnknown Opcode = iota
|
||||
OpcodeAuthorize
|
||||
OpcodeJoinRoom
|
||||
)
|
||||
|
||||
type MoveMessage struct {
|
||||
Position Vector3
|
||||
Velocity [3]float32
|
||||
Waypoints []Vector3
|
||||
PlayerID uint32
|
||||
Active bool
|
||||
Visible bool
|
||||
Ghost bool
|
||||
Name string
|
||||
}
|
||||
|
||||
type SpawnMessage struct {
|
||||
EntityID uint64
|
||||
Position Vector3
|
||||
Health int16
|
||||
Tags []string
|
||||
Data []uint8
|
||||
}
|
||||
|
||||
type EnvelopeMessage struct {
|
||||
Code Opcode
|
||||
Counter uint8
|
||||
}
|
||||
@@ -0,0 +1,237 @@
|
||||
// Code generated by arpack. DO NOT EDIT.
|
||||
|
||||
package arpackmsg
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"math"
|
||||
)
|
||||
|
||||
func arpackEnsureUint16Length(length int, context string) uint16 {
|
||||
if length > 65535 {
|
||||
panic("arpack: " + context + " exceeds uint16 limit")
|
||||
}
|
||||
return uint16(length)
|
||||
}
|
||||
|
||||
func arpackEnsureQuantizedRange(value float64, min float64, max float64, context string) {
|
||||
if value != value || value < min || value > max {
|
||||
panic("arpack: quantized value out of range for " + context)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Vector3) Marshal(buf []byte) []byte {
|
||||
arpackEnsureQuantizedRange(float64(m.X), -500, 500, "X")
|
||||
_qm_X := uint16((m.X - (-500)) / (500 - (-500)) * 65535)
|
||||
buf = binary.LittleEndian.AppendUint16(buf, _qm_X)
|
||||
arpackEnsureQuantizedRange(float64(m.Y), -500, 500, "Y")
|
||||
_qm_Y := uint16((m.Y - (-500)) / (500 - (-500)) * 65535)
|
||||
buf = binary.LittleEndian.AppendUint16(buf, _qm_Y)
|
||||
arpackEnsureQuantizedRange(float64(m.Z), -500, 500, "Z")
|
||||
_qm_Z := uint16((m.Z - (-500)) / (500 - (-500)) * 65535)
|
||||
buf = binary.LittleEndian.AppendUint16(buf, _qm_Z)
|
||||
return buf
|
||||
}
|
||||
|
||||
func (m *Vector3) Unmarshal(data []byte) (int, error) {
|
||||
if len(data) < 6 {
|
||||
return 0, errors.New("arpack: buffer too short for Vector3")
|
||||
}
|
||||
offset := 0
|
||||
if len(data) < offset+2 {
|
||||
return 0, errors.New("arpack: buffer too short")
|
||||
}
|
||||
_qm_X := binary.LittleEndian.Uint16(data[offset:])
|
||||
offset += 2
|
||||
m.X = float32(_qm_X)/65535*(500-(-500)) + (-500)
|
||||
if len(data) < offset+2 {
|
||||
return 0, errors.New("arpack: buffer too short")
|
||||
}
|
||||
_qm_Y := binary.LittleEndian.Uint16(data[offset:])
|
||||
offset += 2
|
||||
m.Y = float32(_qm_Y)/65535*(500-(-500)) + (-500)
|
||||
if len(data) < offset+2 {
|
||||
return 0, errors.New("arpack: buffer too short")
|
||||
}
|
||||
_qm_Z := binary.LittleEndian.Uint16(data[offset:])
|
||||
offset += 2
|
||||
m.Z = float32(_qm_Z)/65535*(500-(-500)) + (-500)
|
||||
return offset, nil
|
||||
}
|
||||
|
||||
func (m *MoveMessage) Marshal(buf []byte) []byte {
|
||||
buf = m.Position.Marshal(buf)
|
||||
for _iVelocity := 0; _iVelocity < 3; _iVelocity++ {
|
||||
buf = binary.LittleEndian.AppendUint32(buf, math.Float32bits(m.Velocity[_iVelocity]))
|
||||
}
|
||||
buf = binary.LittleEndian.AppendUint16(buf, arpackEnsureUint16Length(len(m.Waypoints), "slice length for Waypoints"))
|
||||
for _iWaypoints := range m.Waypoints {
|
||||
buf = m.Waypoints[_iWaypoints].Marshal(buf)
|
||||
}
|
||||
buf = binary.LittleEndian.AppendUint32(buf, m.PlayerID)
|
||||
var _boolByte4 uint8
|
||||
if m.Active {
|
||||
_boolByte4 |= 1 << 0
|
||||
}
|
||||
if m.Visible {
|
||||
_boolByte4 |= 1 << 1
|
||||
}
|
||||
if m.Ghost {
|
||||
_boolByte4 |= 1 << 2
|
||||
}
|
||||
buf = append(buf, _boolByte4)
|
||||
buf = binary.LittleEndian.AppendUint16(buf, arpackEnsureUint16Length(len(m.Name), "string length for Name"))
|
||||
buf = append(buf, m.Name...)
|
||||
return buf
|
||||
}
|
||||
|
||||
func (m *MoveMessage) Unmarshal(data []byte) (int, error) {
|
||||
if len(data) < 23 {
|
||||
return 0, errors.New("arpack: buffer too short for MoveMessage")
|
||||
}
|
||||
offset := 0
|
||||
_nPosition, _err := m.Position.Unmarshal(data[offset:])
|
||||
if _err != nil {
|
||||
return 0, _err
|
||||
}
|
||||
offset += _nPosition
|
||||
for _iVelocity := 0; _iVelocity < 3; _iVelocity++ {
|
||||
if len(data) < offset+4 {
|
||||
return 0, errors.New("arpack: buffer too short")
|
||||
}
|
||||
m.Velocity[_iVelocity] = math.Float32frombits(binary.LittleEndian.Uint32(data[offset:]))
|
||||
offset += 4
|
||||
}
|
||||
if len(data) < offset+2 {
|
||||
return 0, errors.New("arpack: buffer too short")
|
||||
}
|
||||
_lenWaypoints := int(binary.LittleEndian.Uint16(data[offset:]))
|
||||
offset += 2
|
||||
m.Waypoints = make([]Vector3, _lenWaypoints)
|
||||
for _iWaypoints := 0; _iWaypoints < _lenWaypoints; _iWaypoints++ {
|
||||
_nWaypoints__iWaypoints_, _err := m.Waypoints[_iWaypoints].Unmarshal(data[offset:])
|
||||
if _err != nil {
|
||||
return 0, _err
|
||||
}
|
||||
offset += _nWaypoints__iWaypoints_
|
||||
}
|
||||
if len(data) < offset+4 {
|
||||
return 0, errors.New("arpack: buffer too short")
|
||||
}
|
||||
m.PlayerID = binary.LittleEndian.Uint32(data[offset:])
|
||||
offset += 4
|
||||
if len(data) < offset+1 {
|
||||
return 0, errors.New("arpack: buffer too short")
|
||||
}
|
||||
_boolByte4 := data[offset]
|
||||
offset++
|
||||
m.Active = _boolByte4&(1<<0) != 0
|
||||
m.Visible = _boolByte4&(1<<1) != 0
|
||||
m.Ghost = _boolByte4&(1<<2) != 0
|
||||
if len(data) < offset+2 {
|
||||
return 0, errors.New("arpack: buffer too short")
|
||||
}
|
||||
_slenm_Name := int(binary.LittleEndian.Uint16(data[offset:]))
|
||||
offset += 2
|
||||
if len(data) < offset+_slenm_Name {
|
||||
return 0, errors.New("arpack: buffer too short")
|
||||
}
|
||||
m.Name = string(data[offset : offset+_slenm_Name])
|
||||
offset += _slenm_Name
|
||||
return offset, nil
|
||||
}
|
||||
|
||||
func (m *SpawnMessage) Marshal(buf []byte) []byte {
|
||||
buf = binary.LittleEndian.AppendUint64(buf, m.EntityID)
|
||||
buf = m.Position.Marshal(buf)
|
||||
buf = binary.LittleEndian.AppendUint16(buf, uint16(m.Health))
|
||||
buf = binary.LittleEndian.AppendUint16(buf, arpackEnsureUint16Length(len(m.Tags), "slice length for Tags"))
|
||||
for _iTags := range m.Tags {
|
||||
buf = binary.LittleEndian.AppendUint16(buf, arpackEnsureUint16Length(len(m.Tags[_iTags]), "string length for Tags[_iTags]"))
|
||||
buf = append(buf, m.Tags[_iTags]...)
|
||||
}
|
||||
buf = binary.LittleEndian.AppendUint16(buf, arpackEnsureUint16Length(len(m.Data), "slice length for Data"))
|
||||
for _iData := range m.Data {
|
||||
buf = append(buf, m.Data[_iData])
|
||||
}
|
||||
return buf
|
||||
}
|
||||
|
||||
func (m *SpawnMessage) Unmarshal(data []byte) (int, error) {
|
||||
if len(data) < 16 {
|
||||
return 0, errors.New("arpack: buffer too short for SpawnMessage")
|
||||
}
|
||||
offset := 0
|
||||
if len(data) < offset+8 {
|
||||
return 0, errors.New("arpack: buffer too short")
|
||||
}
|
||||
m.EntityID = binary.LittleEndian.Uint64(data[offset:])
|
||||
offset += 8
|
||||
_nPosition, _err := m.Position.Unmarshal(data[offset:])
|
||||
if _err != nil {
|
||||
return 0, _err
|
||||
}
|
||||
offset += _nPosition
|
||||
if len(data) < offset+2 {
|
||||
return 0, errors.New("arpack: buffer too short")
|
||||
}
|
||||
m.Health = int16(binary.LittleEndian.Uint16(data[offset:]))
|
||||
offset += 2
|
||||
if len(data) < offset+2 {
|
||||
return 0, errors.New("arpack: buffer too short")
|
||||
}
|
||||
_lenTags := int(binary.LittleEndian.Uint16(data[offset:]))
|
||||
offset += 2
|
||||
m.Tags = make([]string, _lenTags)
|
||||
for _iTags := 0; _iTags < _lenTags; _iTags++ {
|
||||
if len(data) < offset+2 {
|
||||
return 0, errors.New("arpack: buffer too short")
|
||||
}
|
||||
_slenm_Tags__iTags_ := int(binary.LittleEndian.Uint16(data[offset:]))
|
||||
offset += 2
|
||||
if len(data) < offset+_slenm_Tags__iTags_ {
|
||||
return 0, errors.New("arpack: buffer too short")
|
||||
}
|
||||
m.Tags[_iTags] = string(data[offset : offset+_slenm_Tags__iTags_])
|
||||
offset += _slenm_Tags__iTags_
|
||||
}
|
||||
if len(data) < offset+2 {
|
||||
return 0, errors.New("arpack: buffer too short")
|
||||
}
|
||||
_lenData := int(binary.LittleEndian.Uint16(data[offset:]))
|
||||
offset += 2
|
||||
m.Data = make([]uint8, _lenData)
|
||||
for _iData := 0; _iData < _lenData; _iData++ {
|
||||
if len(data) < offset+1 {
|
||||
return 0, errors.New("arpack: buffer too short")
|
||||
}
|
||||
m.Data[_iData] = data[offset]
|
||||
offset += 1
|
||||
}
|
||||
return offset, nil
|
||||
}
|
||||
|
||||
func (m *EnvelopeMessage) Marshal(buf []byte) []byte {
|
||||
buf = binary.LittleEndian.AppendUint16(buf, uint16(m.Code))
|
||||
buf = append(buf, m.Counter)
|
||||
return buf
|
||||
}
|
||||
|
||||
func (m *EnvelopeMessage) Unmarshal(data []byte) (int, error) {
|
||||
if len(data) < 3 {
|
||||
return 0, errors.New("arpack: buffer too short for EnvelopeMessage")
|
||||
}
|
||||
offset := 0
|
||||
if len(data) < offset+2 {
|
||||
return 0, errors.New("arpack: buffer too short")
|
||||
}
|
||||
m.Code = Opcode(binary.LittleEndian.Uint16(data[offset:]))
|
||||
offset += 2
|
||||
if len(data) < offset+1 {
|
||||
return 0, errors.New("arpack: buffer too short")
|
||||
}
|
||||
m.Counter = data[offset]
|
||||
offset += 1
|
||||
return offset, nil
|
||||
}
|
||||
@@ -0,0 +1,217 @@
|
||||
package bench_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/edmand46/arpack/benchmarks/arpackmsg"
|
||||
benchfbs "github.com/edmand46/arpack/benchmarks/flatbuffers"
|
||||
benchpb "github.com/edmand46/arpack/benchmarks/proto"
|
||||
flatbuffers "github.com/google/flatbuffers/go"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
// testMoveArpack returns a fully populated arpackmsg.MoveMessage for benchmarks.
|
||||
func testMoveArpack() arpackmsg.MoveMessage {
|
||||
return arpackmsg.MoveMessage{
|
||||
Position: arpackmsg.Vector3{X: 100, Y: -50, Z: 0},
|
||||
Velocity: [3]float32{1.5, -2.5, 0},
|
||||
Waypoints: []arpackmsg.Vector3{{X: 10, Y: 20, Z: 0}, {X: -10, Y: 0, Z: 100}},
|
||||
PlayerID: 999,
|
||||
Active: true,
|
||||
Visible: false,
|
||||
Ghost: true,
|
||||
Name: "PlayerOne",
|
||||
}
|
||||
}
|
||||
|
||||
// testMoveProto returns a fully populated proto MoveMessage for benchmarks.
|
||||
func testMoveProto() *benchpb.MoveMessage {
|
||||
return &benchpb.MoveMessage{
|
||||
Position: &benchpb.Vector3{X: 100, Y: -50, Z: 0},
|
||||
Velocity: []float32{1.5, -2.5, 0},
|
||||
Waypoints: []*benchpb.Vector3{
|
||||
{X: 10, Y: 20, Z: 0},
|
||||
{X: -10, Y: 0, Z: 100},
|
||||
},
|
||||
PlayerId: 999,
|
||||
Active: true,
|
||||
Visible: false,
|
||||
Ghost: true,
|
||||
Name: "PlayerOne",
|
||||
}
|
||||
}
|
||||
|
||||
// testMoveFbs returns a fully populated benchfbs.MoveMsg for benchmarks.
|
||||
func testMoveFbs() *benchfbs.MoveMsg {
|
||||
return &benchfbs.MoveMsg{
|
||||
Position: benchfbs.Vec3{X: 100, Y: -50, Z: 0},
|
||||
Velocity: [3]float32{1.5, -2.5, 0},
|
||||
Waypoints: []benchfbs.Vec3{{X: 10, Y: 20, Z: 0}, {X: -10, Y: 0, Z: 100}},
|
||||
PlayerID: 999,
|
||||
Active: true,
|
||||
Visible: false,
|
||||
Ghost: true,
|
||||
Name: "PlayerOne",
|
||||
}
|
||||
}
|
||||
|
||||
// TestMessageSize prints the wire size for each serialization format.
|
||||
func TestMessageSize(t *testing.T) {
|
||||
// ArPack
|
||||
apMsg := testMoveArpack()
|
||||
apBuf := apMsg.Marshal(nil)
|
||||
fmt.Printf("ArPack wire size: %d bytes\n", len(apBuf))
|
||||
|
||||
// Protobuf
|
||||
pbMsg := testMoveProto()
|
||||
pbBuf, err := proto.Marshal(pbMsg)
|
||||
if err != nil {
|
||||
t.Fatalf("proto.Marshal: %v", err)
|
||||
}
|
||||
fmt.Printf("Protobuf wire size: %d bytes\n", len(pbBuf))
|
||||
|
||||
// FlatBuffers
|
||||
fbMsg := testMoveFbs()
|
||||
b := flatbuffers.NewBuilder(256)
|
||||
fbBuf := benchfbs.Marshal(b, fbMsg)
|
||||
fmt.Printf("FlatBuf wire size: %d bytes\n", len(fbBuf))
|
||||
|
||||
// Sanity-check round-trips
|
||||
var apOut arpackmsg.MoveMessage
|
||||
if _, err := apOut.Unmarshal(apBuf); err != nil {
|
||||
t.Fatalf("ArPack Unmarshal: %v", err)
|
||||
}
|
||||
if apOut.PlayerID != 999 || apOut.Name != "PlayerOne" {
|
||||
t.Errorf("ArPack round-trip mismatch: %+v", apOut)
|
||||
}
|
||||
|
||||
var pbOut benchpb.MoveMessage
|
||||
if err := proto.Unmarshal(pbBuf, &pbOut); err != nil {
|
||||
t.Fatalf("proto.Unmarshal: %v", err)
|
||||
}
|
||||
if pbOut.PlayerId != 999 || pbOut.Name != "PlayerOne" {
|
||||
t.Errorf("Proto round-trip mismatch: PlayerId=%d Name=%s", pbOut.PlayerId, pbOut.Name)
|
||||
}
|
||||
|
||||
var fbOut benchfbs.MoveMsg
|
||||
benchfbs.Unmarshal(fbBuf, &fbOut)
|
||||
if fbOut.PlayerID != 999 || fbOut.Name != "PlayerOne" {
|
||||
t.Errorf("FlatBuffers round-trip mismatch: %+v", fbOut)
|
||||
}
|
||||
}
|
||||
|
||||
// --- ArPack benchmarks ---
|
||||
|
||||
func BenchmarkArPack_Marshal(b *testing.B) {
|
||||
msg := testMoveArpack()
|
||||
buf := msg.Marshal(nil)
|
||||
wireSize := len(buf)
|
||||
|
||||
b.ReportAllocs()
|
||||
b.SetBytes(int64(wireSize))
|
||||
b.ResetTimer()
|
||||
|
||||
var out []byte
|
||||
for i := 0; i < b.N; i++ {
|
||||
out = msg.Marshal(out[:0])
|
||||
}
|
||||
_ = out
|
||||
}
|
||||
|
||||
func BenchmarkArPack_Unmarshal(b *testing.B) {
|
||||
msg := testMoveArpack()
|
||||
buf := msg.Marshal(nil)
|
||||
wireSize := len(buf)
|
||||
|
||||
b.ReportAllocs()
|
||||
b.SetBytes(int64(wireSize))
|
||||
b.ResetTimer()
|
||||
|
||||
var out arpackmsg.MoveMessage
|
||||
for i := 0; i < b.N; i++ {
|
||||
if _, err := out.Unmarshal(buf); err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --- Protobuf benchmarks ---
|
||||
|
||||
func BenchmarkProto_Marshal(b *testing.B) {
|
||||
msg := testMoveProto()
|
||||
buf, err := proto.Marshal(msg)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
wireSize := len(buf)
|
||||
|
||||
b.ReportAllocs()
|
||||
b.SetBytes(int64(wireSize))
|
||||
b.ResetTimer()
|
||||
|
||||
var out []byte
|
||||
for i := 0; i < b.N; i++ {
|
||||
out, err = proto.MarshalOptions{}.MarshalAppend(out[:0], msg)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
}
|
||||
_ = out
|
||||
}
|
||||
|
||||
func BenchmarkProto_Unmarshal(b *testing.B) {
|
||||
msg := testMoveProto()
|
||||
buf, err := proto.Marshal(msg)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
wireSize := len(buf)
|
||||
|
||||
b.ReportAllocs()
|
||||
b.SetBytes(int64(wireSize))
|
||||
b.ResetTimer()
|
||||
|
||||
var out benchpb.MoveMessage
|
||||
for i := 0; i < b.N; i++ {
|
||||
out.Reset()
|
||||
if err := proto.Unmarshal(buf, &out); err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --- FlatBuffers benchmarks ---
|
||||
|
||||
func BenchmarkFlatBuffers_Marshal(b *testing.B) {
|
||||
msg := testMoveFbs()
|
||||
builder := flatbuffers.NewBuilder(256)
|
||||
buf := benchfbs.Marshal(builder, msg)
|
||||
wireSize := len(buf)
|
||||
|
||||
b.ReportAllocs()
|
||||
b.SetBytes(int64(wireSize))
|
||||
b.ResetTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
benchfbs.Marshal(builder, msg)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkFlatBuffers_Unmarshal(b *testing.B) {
|
||||
msg := testMoveFbs()
|
||||
builder := flatbuffers.NewBuilder(256)
|
||||
buf := benchfbs.Marshal(builder, msg)
|
||||
wireSize := len(buf)
|
||||
|
||||
b.ReportAllocs()
|
||||
b.SetBytes(int64(wireSize))
|
||||
b.ResetTimer()
|
||||
|
||||
var out benchfbs.MoveMsg
|
||||
for i := 0; i < b.N; i++ {
|
||||
out = benchfbs.MoveMsg{}
|
||||
benchfbs.Unmarshal(buf, &out)
|
||||
}
|
||||
_ = out
|
||||
}
|
||||
@@ -0,0 +1,174 @@
|
||||
package benchfbs
|
||||
|
||||
import (
|
||||
flatbuffers "github.com/google/flatbuffers/go"
|
||||
)
|
||||
|
||||
// Vec3 mirrors the MoveMessage's Vector3 fields for FlatBuffers encoding.
|
||||
type Vec3 struct {
|
||||
X, Y, Z float32
|
||||
}
|
||||
|
||||
// MoveMsg is the Go struct used in the FlatBuffers benchmark.
|
||||
type MoveMsg struct {
|
||||
Position Vec3
|
||||
Velocity [3]float32
|
||||
Waypoints []Vec3
|
||||
PlayerID uint32
|
||||
Active, Visible, Ghost bool
|
||||
Name string
|
||||
}
|
||||
|
||||
// vtable slot indices for MoveMessage fields (0-based slot -> vtable offset = 4 + 2*slot)
|
||||
// slot 0 -> position (vtable offset 4)
|
||||
// slot 1 -> velocity (vtable offset 6)
|
||||
// slot 2 -> waypoints (vtable offset 8)
|
||||
// slot 3 -> player_id (vtable offset 10)
|
||||
// slot 4 -> active (vtable offset 12)
|
||||
// slot 5 -> visible (vtable offset 14)
|
||||
// slot 6 -> ghost (vtable offset 16)
|
||||
// slot 7 -> name (vtable offset 18)
|
||||
const (
|
||||
slotPosition = 0
|
||||
slotVelocity = 1
|
||||
slotWaypoints = 2
|
||||
slotPlayerID = 3
|
||||
slotActive = 4
|
||||
slotVisible = 5
|
||||
slotGhost = 6
|
||||
slotName = 7
|
||||
)
|
||||
|
||||
// buildVec3 writes a Vec3 as a table with 3 float32 fields and returns its offset.
|
||||
// Vec3 slots: x=0, y=1, z=2
|
||||
func buildVec3(b *flatbuffers.Builder, v Vec3) flatbuffers.UOffsetT {
|
||||
b.StartObject(3)
|
||||
b.PrependFloat32Slot(0, v.X, 0)
|
||||
b.PrependFloat32Slot(1, v.Y, 0)
|
||||
b.PrependFloat32Slot(2, v.Z, 0)
|
||||
return b.EndObject()
|
||||
}
|
||||
|
||||
// Marshal serialises msg into a FlatBuffer using b and returns the finished bytes.
|
||||
// The builder is reset before use, so callers can reuse it across calls.
|
||||
func Marshal(b *flatbuffers.Builder, msg *MoveMsg) []byte {
|
||||
b.Reset()
|
||||
|
||||
// 1. Build all variable-length data first (must be done outside object construction).
|
||||
|
||||
// name string
|
||||
nameOff := b.CreateString(msg.Name)
|
||||
|
||||
// velocity vector: 3 × float32
|
||||
b.StartVector(4, 3, 4)
|
||||
for i := 2; i >= 0; i-- {
|
||||
b.PrependFloat32(msg.Velocity[i])
|
||||
}
|
||||
velOff := b.EndVector(3)
|
||||
|
||||
// waypoints vector: repeated Vec3 tables (build each table first, collect offsets)
|
||||
wpOffsets := make([]flatbuffers.UOffsetT, len(msg.Waypoints))
|
||||
for i, wp := range msg.Waypoints {
|
||||
wpOffsets[i] = buildVec3(b, wp)
|
||||
}
|
||||
b.StartVector(4, len(wpOffsets), 4)
|
||||
for i := len(wpOffsets) - 1; i >= 0; i-- {
|
||||
b.PrependUOffsetT(wpOffsets[i])
|
||||
}
|
||||
wpVecOff := b.EndVector(len(wpOffsets))
|
||||
|
||||
// position table
|
||||
posOff := buildVec3(b, msg.Position)
|
||||
|
||||
// 2. Build the MoveMessage table.
|
||||
b.StartObject(8)
|
||||
b.PrependUOffsetTSlot(slotPosition, posOff, 0)
|
||||
b.PrependUOffsetTSlot(slotVelocity, velOff, 0)
|
||||
b.PrependUOffsetTSlot(slotWaypoints, wpVecOff, 0)
|
||||
b.PrependUint32Slot(slotPlayerID, msg.PlayerID, 0)
|
||||
b.PrependBoolSlot(slotActive, msg.Active, false)
|
||||
b.PrependBoolSlot(slotVisible, msg.Visible, false)
|
||||
b.PrependBoolSlot(slotGhost, msg.Ghost, false)
|
||||
b.PrependUOffsetTSlot(slotName, nameOff, 0)
|
||||
root := b.EndObject()
|
||||
|
||||
b.Finish(root)
|
||||
return b.FinishedBytes()
|
||||
}
|
||||
|
||||
// readVec3 reads a Vec3 from a table at the given absolute position in buf.
|
||||
func readVec3(buf []byte, tablePos flatbuffers.UOffsetT) Vec3 {
|
||||
tab := flatbuffers.Table{Bytes: buf, Pos: tablePos}
|
||||
var v Vec3
|
||||
if o := tab.Offset(4); o != 0 { // slot 0 -> vtable offset 4
|
||||
v.X = tab.GetFloat32(tab.Pos + flatbuffers.UOffsetT(o))
|
||||
}
|
||||
if o := tab.Offset(6); o != 0 { // slot 1 -> vtable offset 6
|
||||
v.Y = tab.GetFloat32(tab.Pos + flatbuffers.UOffsetT(o))
|
||||
}
|
||||
if o := tab.Offset(8); o != 0 { // slot 2 -> vtable offset 8
|
||||
v.Z = tab.GetFloat32(tab.Pos + flatbuffers.UOffsetT(o))
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// Unmarshal reads all fields from a finished FlatBuffer into out.
|
||||
func Unmarshal(buf []byte, out *MoveMsg) {
|
||||
// The root offset is stored at byte 0 of the finished buffer.
|
||||
rootPos := flatbuffers.GetUOffsetT(buf)
|
||||
tab := flatbuffers.Table{Bytes: buf, Pos: rootPos}
|
||||
|
||||
// position (slot 0, vtable offset 4)
|
||||
if o := tab.Offset(4); o != 0 {
|
||||
absOff := tab.Pos + flatbuffers.UOffsetT(o)
|
||||
posPos := tab.Indirect(absOff)
|
||||
out.Position = readVec3(buf, posPos)
|
||||
}
|
||||
|
||||
// velocity vector (slot 1, vtable offset 6)
|
||||
if o := tab.Offset(6); o != 0 {
|
||||
vecStart := tab.Vector(flatbuffers.UOffsetT(o))
|
||||
for i := 0; i < 3; i++ {
|
||||
out.Velocity[i] = flatbuffers.GetFloat32(buf[int(vecStart)+i*4:])
|
||||
}
|
||||
}
|
||||
|
||||
// waypoints vector (slot 2, vtable offset 8)
|
||||
if o := tab.Offset(8); o != 0 {
|
||||
n := tab.VectorLen(flatbuffers.UOffsetT(o))
|
||||
out.Waypoints = make([]Vec3, n)
|
||||
vecStart := tab.Vector(flatbuffers.UOffsetT(o))
|
||||
for i := 0; i < n; i++ {
|
||||
// Each element is an UOffsetT pointing to the table.
|
||||
elemOff := vecStart + flatbuffers.UOffsetT(i*4)
|
||||
tablePos := elemOff + flatbuffers.GetUOffsetT(buf[elemOff:])
|
||||
out.Waypoints[i] = readVec3(buf, tablePos)
|
||||
}
|
||||
}
|
||||
|
||||
// player_id (slot 3, vtable offset 10)
|
||||
if o := tab.Offset(10); o != 0 {
|
||||
out.PlayerID = tab.GetUint32(tab.Pos + flatbuffers.UOffsetT(o))
|
||||
}
|
||||
|
||||
// active (slot 4, vtable offset 12)
|
||||
if o := tab.Offset(12); o != 0 {
|
||||
out.Active = tab.GetBool(tab.Pos + flatbuffers.UOffsetT(o))
|
||||
}
|
||||
|
||||
// visible (slot 5, vtable offset 14)
|
||||
if o := tab.Offset(14); o != 0 {
|
||||
out.Visible = tab.GetBool(tab.Pos + flatbuffers.UOffsetT(o))
|
||||
}
|
||||
|
||||
// ghost (slot 6, vtable offset 16)
|
||||
if o := tab.Offset(16); o != 0 {
|
||||
out.Ghost = tab.GetBool(tab.Pos + flatbuffers.UOffsetT(o))
|
||||
}
|
||||
|
||||
// name (slot 7, vtable offset 18)
|
||||
if o := tab.Offset(18); o != 0 {
|
||||
absOff := tab.Pos + flatbuffers.UOffsetT(o)
|
||||
out.Name = tab.String(absOff)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,253 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.36.10
|
||||
// protoc v6.33.0
|
||||
// source: benchmarks/proto/move.proto
|
||||
|
||||
package proto
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
unsafe "unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type Vector3 struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
X float32 `protobuf:"fixed32,1,opt,name=x,proto3" json:"x,omitempty"`
|
||||
Y float32 `protobuf:"fixed32,2,opt,name=y,proto3" json:"y,omitempty"`
|
||||
Z float32 `protobuf:"fixed32,3,opt,name=z,proto3" json:"z,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *Vector3) Reset() {
|
||||
*x = Vector3{}
|
||||
mi := &file_benchmarks_proto_move_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *Vector3) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Vector3) ProtoMessage() {}
|
||||
|
||||
func (x *Vector3) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_benchmarks_proto_move_proto_msgTypes[0]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Vector3.ProtoReflect.Descriptor instead.
|
||||
func (*Vector3) Descriptor() ([]byte, []int) {
|
||||
return file_benchmarks_proto_move_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *Vector3) GetX() float32 {
|
||||
if x != nil {
|
||||
return x.X
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *Vector3) GetY() float32 {
|
||||
if x != nil {
|
||||
return x.Y
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *Vector3) GetZ() float32 {
|
||||
if x != nil {
|
||||
return x.Z
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type MoveMessage struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Position *Vector3 `protobuf:"bytes,1,opt,name=position,proto3" json:"position,omitempty"`
|
||||
Velocity []float32 `protobuf:"fixed32,2,rep,packed,name=velocity,proto3" json:"velocity,omitempty"`
|
||||
Waypoints []*Vector3 `protobuf:"bytes,3,rep,name=waypoints,proto3" json:"waypoints,omitempty"`
|
||||
PlayerId uint32 `protobuf:"varint,4,opt,name=player_id,json=playerId,proto3" json:"player_id,omitempty"`
|
||||
Active bool `protobuf:"varint,5,opt,name=active,proto3" json:"active,omitempty"`
|
||||
Visible bool `protobuf:"varint,6,opt,name=visible,proto3" json:"visible,omitempty"`
|
||||
Ghost bool `protobuf:"varint,7,opt,name=ghost,proto3" json:"ghost,omitempty"`
|
||||
Name string `protobuf:"bytes,8,opt,name=name,proto3" json:"name,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *MoveMessage) Reset() {
|
||||
*x = MoveMessage{}
|
||||
mi := &file_benchmarks_proto_move_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *MoveMessage) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*MoveMessage) ProtoMessage() {}
|
||||
|
||||
func (x *MoveMessage) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_benchmarks_proto_move_proto_msgTypes[1]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use MoveMessage.ProtoReflect.Descriptor instead.
|
||||
func (*MoveMessage) Descriptor() ([]byte, []int) {
|
||||
return file_benchmarks_proto_move_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *MoveMessage) GetPosition() *Vector3 {
|
||||
if x != nil {
|
||||
return x.Position
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *MoveMessage) GetVelocity() []float32 {
|
||||
if x != nil {
|
||||
return x.Velocity
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *MoveMessage) GetWaypoints() []*Vector3 {
|
||||
if x != nil {
|
||||
return x.Waypoints
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *MoveMessage) GetPlayerId() uint32 {
|
||||
if x != nil {
|
||||
return x.PlayerId
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *MoveMessage) GetActive() bool {
|
||||
if x != nil {
|
||||
return x.Active
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *MoveMessage) GetVisible() bool {
|
||||
if x != nil {
|
||||
return x.Visible
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *MoveMessage) GetGhost() bool {
|
||||
if x != nil {
|
||||
return x.Ghost
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *MoveMessage) GetName() string {
|
||||
if x != nil {
|
||||
return x.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
var File_benchmarks_proto_move_proto protoreflect.FileDescriptor
|
||||
|
||||
const file_benchmarks_proto_move_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"\x1bbenchmarks/proto/move.proto\x12\n" +
|
||||
"benchproto\"3\n" +
|
||||
"\aVector3\x12\f\n" +
|
||||
"\x01x\x18\x01 \x01(\x02R\x01x\x12\f\n" +
|
||||
"\x01y\x18\x02 \x01(\x02R\x01y\x12\f\n" +
|
||||
"\x01z\x18\x03 \x01(\x02R\x01z\"\x86\x02\n" +
|
||||
"\vMoveMessage\x12/\n" +
|
||||
"\bposition\x18\x01 \x01(\v2\x13.benchproto.Vector3R\bposition\x12\x1a\n" +
|
||||
"\bvelocity\x18\x02 \x03(\x02R\bvelocity\x121\n" +
|
||||
"\twaypoints\x18\x03 \x03(\v2\x13.benchproto.Vector3R\twaypoints\x12\x1b\n" +
|
||||
"\tplayer_id\x18\x04 \x01(\rR\bplayerId\x12\x16\n" +
|
||||
"\x06active\x18\x05 \x01(\bR\x06active\x12\x18\n" +
|
||||
"\avisible\x18\x06 \x01(\bR\avisible\x12\x14\n" +
|
||||
"\x05ghost\x18\a \x01(\bR\x05ghost\x12\x12\n" +
|
||||
"\x04name\x18\b \x01(\tR\x04nameB-Z+github.com/edmand46/arpack/benchmarks/protob\x06proto3"
|
||||
|
||||
var (
|
||||
file_benchmarks_proto_move_proto_rawDescOnce sync.Once
|
||||
file_benchmarks_proto_move_proto_rawDescData []byte
|
||||
)
|
||||
|
||||
func file_benchmarks_proto_move_proto_rawDescGZIP() []byte {
|
||||
file_benchmarks_proto_move_proto_rawDescOnce.Do(func() {
|
||||
file_benchmarks_proto_move_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_benchmarks_proto_move_proto_rawDesc), len(file_benchmarks_proto_move_proto_rawDesc)))
|
||||
})
|
||||
return file_benchmarks_proto_move_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_benchmarks_proto_move_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
|
||||
var file_benchmarks_proto_move_proto_goTypes = []any{
|
||||
(*Vector3)(nil), // 0: benchproto.Vector3
|
||||
(*MoveMessage)(nil), // 1: benchproto.MoveMessage
|
||||
}
|
||||
var file_benchmarks_proto_move_proto_depIdxs = []int32{
|
||||
0, // 0: benchproto.MoveMessage.position:type_name -> benchproto.Vector3
|
||||
0, // 1: benchproto.MoveMessage.waypoints:type_name -> benchproto.Vector3
|
||||
2, // [2:2] is the sub-list for method output_type
|
||||
2, // [2:2] is the sub-list for method input_type
|
||||
2, // [2:2] is the sub-list for extension type_name
|
||||
2, // [2:2] is the sub-list for extension extendee
|
||||
0, // [0:2] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_benchmarks_proto_move_proto_init() }
|
||||
func file_benchmarks_proto_move_proto_init() {
|
||||
if File_benchmarks_proto_move_proto != nil {
|
||||
return
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_benchmarks_proto_move_proto_rawDesc), len(file_benchmarks_proto_move_proto_rawDesc)),
|
||||
NumEnums: 0,
|
||||
NumMessages: 2,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_benchmarks_proto_move_proto_goTypes,
|
||||
DependencyIndexes: file_benchmarks_proto_move_proto_depIdxs,
|
||||
MessageInfos: file_benchmarks_proto_move_proto_msgTypes,
|
||||
}.Build()
|
||||
File_benchmarks_proto_move_proto = out.File
|
||||
file_benchmarks_proto_move_proto_goTypes = nil
|
||||
file_benchmarks_proto_move_proto_depIdxs = nil
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
syntax = "proto3";
|
||||
package benchproto;
|
||||
option go_package = "github.com/edmand46/arpack/benchmarks/proto";
|
||||
|
||||
message Vector3 {
|
||||
float x = 1;
|
||||
float y = 2;
|
||||
float z = 3;
|
||||
}
|
||||
|
||||
message MoveMessage {
|
||||
Vector3 position = 1;
|
||||
repeated float velocity = 2;
|
||||
repeated Vector3 waypoints = 3;
|
||||
uint32 player_id = 4;
|
||||
bool active = 5;
|
||||
bool visible = 6;
|
||||
bool ghost = 7;
|
||||
string name = 8;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7b9f947cf50f547f08cabcd88b87750e
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,141 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using Google.Protobuf;
|
||||
using UnityEngine;
|
||||
|
||||
public class BenchmarkRunner : MonoBehaviour
|
||||
{
|
||||
private const int N = 10_000;
|
||||
private const int Warmup = 1_000;
|
||||
|
||||
private unsafe void Start()
|
||||
{
|
||||
var apMsg = new Arpack.Messages.MoveMessage
|
||||
{
|
||||
Position = new Arpack.Messages.Vector3 { X = 100, Y = -50, Z = 0 },
|
||||
Velocity = new float[] { 1.5f, -2.5f, 0f },
|
||||
Waypoints = new Arpack.Messages.Vector3[]
|
||||
{
|
||||
new Arpack.Messages.Vector3 { X = 10, Y = 20, Z = 0 },
|
||||
new Arpack.Messages.Vector3 { X = -10, Y = 0, Z = 100 },
|
||||
},
|
||||
PlayerID = 999,
|
||||
Active = true,
|
||||
Visible = false,
|
||||
Ghost = true,
|
||||
Name = "PlayerOne",
|
||||
};
|
||||
|
||||
var pbMsg = new Benchproto.MoveMessage
|
||||
{
|
||||
Position = new Benchproto.Vector3 { X = 100, Y = -50, Z = 0 },
|
||||
PlayerId = 999,
|
||||
Active = true,
|
||||
Visible = false,
|
||||
Ghost = true,
|
||||
Name = "PlayerOne",
|
||||
};
|
||||
pbMsg.Velocity.AddRange(new float[] { 1.5f, -2.5f, 0f });
|
||||
pbMsg.Waypoints.Add(new Benchproto.Vector3 { X = 10, Y = 20, Z = 0 });
|
||||
pbMsg.Waypoints.Add(new Benchproto.Vector3 { X = -10, Y = 0, Z = 100 });
|
||||
|
||||
byte[] apBuf = new byte[256];
|
||||
int apWireSize;
|
||||
fixed (byte* ptr = apBuf) { apWireSize = apMsg.Serialize(ptr); }
|
||||
|
||||
byte[] apBytes = new byte[apWireSize];
|
||||
Array.Copy(apBuf, apBytes, apWireSize);
|
||||
|
||||
byte[] pbBytes = pbMsg.ToByteArray();
|
||||
int pbWireSize = pbBytes.Length;
|
||||
byte[] protoOutputBuf = new byte[256];
|
||||
|
||||
// Warmup (JIT)
|
||||
for (int i = 0; i < Warmup; i++)
|
||||
{
|
||||
fixed (byte* ptr = apBuf) { apMsg.Serialize(ptr); }
|
||||
fixed (byte* ptr = apBytes) { Arpack.Messages.MoveMessage.Deserialize(ptr, out _); }
|
||||
_ = pbMsg.ToByteArray();
|
||||
_ = Benchproto.MoveMessage.Parser.ParseFrom(pbBytes);
|
||||
var cos = new CodedOutputStream(protoOutputBuf);
|
||||
pbMsg.WriteTo(cos);
|
||||
cos.Flush();
|
||||
}
|
||||
|
||||
Stopwatch sw;
|
||||
long gcBefore, gcAfter;
|
||||
|
||||
// ArPack Serialize
|
||||
GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect();
|
||||
gcBefore = GC.GetTotalMemory(false);
|
||||
sw = Stopwatch.StartNew();
|
||||
for (int i = 0; i < N; i++)
|
||||
{
|
||||
fixed (byte* ptr = apBuf) { apMsg.Serialize(ptr); }
|
||||
}
|
||||
sw.Stop();
|
||||
gcAfter = GC.GetTotalMemory(false);
|
||||
Log("ArPack Serialize ", sw, N, gcAfter - gcBefore);
|
||||
|
||||
// ArPack Deserialize
|
||||
GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect();
|
||||
gcBefore = GC.GetTotalMemory(false);
|
||||
sw = Stopwatch.StartNew();
|
||||
for (int i = 0; i < N; i++)
|
||||
{
|
||||
fixed (byte* ptr = apBytes) { Arpack.Messages.MoveMessage.Deserialize(ptr, out _); }
|
||||
}
|
||||
sw.Stop();
|
||||
gcAfter = GC.GetTotalMemory(false);
|
||||
Log("ArPack Deserialize ", sw, N, gcAfter - gcBefore);
|
||||
|
||||
// Proto Serialize (alloc)
|
||||
GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect();
|
||||
gcBefore = GC.GetTotalMemory(false);
|
||||
sw = Stopwatch.StartNew();
|
||||
byte[] pbOut = null;
|
||||
for (int i = 0; i < N; i++)
|
||||
{
|
||||
pbOut = pbMsg.ToByteArray();
|
||||
}
|
||||
sw.Stop();
|
||||
gcAfter = GC.GetTotalMemory(false);
|
||||
Log("Proto Serialize (alloc) ", sw, N, gcAfter - gcBefore);
|
||||
_ = pbOut;
|
||||
|
||||
// Proto Deserialize (alloc)
|
||||
GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect();
|
||||
gcBefore = GC.GetTotalMemory(false);
|
||||
sw = Stopwatch.StartNew();
|
||||
for (int i = 0; i < N; i++)
|
||||
{
|
||||
_ = Benchproto.MoveMessage.Parser.ParseFrom(pbBytes);
|
||||
}
|
||||
sw.Stop();
|
||||
gcAfter = GC.GetTotalMemory(false);
|
||||
Log("Proto Deserialize (alloc)", sw, N, gcAfter - gcBefore);
|
||||
|
||||
// Proto Serialize (reuse buffer)
|
||||
GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect();
|
||||
gcBefore = GC.GetTotalMemory(false);
|
||||
sw = Stopwatch.StartNew();
|
||||
for (int i = 0; i < N; i++)
|
||||
{
|
||||
var cos = new CodedOutputStream(protoOutputBuf);
|
||||
pbMsg.WriteTo(cos);
|
||||
cos.Flush();
|
||||
}
|
||||
sw.Stop();
|
||||
gcAfter = GC.GetTotalMemory(false);
|
||||
Log("Proto Serialize (reuse) ", sw, N, gcAfter - gcBefore);
|
||||
|
||||
UnityEngine.Debug.Log($"[Bench] Wire sizes — ArPack: {apWireSize} bytes | Protobuf: {pbWireSize} bytes");
|
||||
}
|
||||
|
||||
private static void Log(string label, Stopwatch sw, int n, long gcDelta)
|
||||
{
|
||||
double nsPerOp = sw.Elapsed.TotalMilliseconds * 1_000_000.0 / n;
|
||||
long bPerOp = Math.Max(0, gcDelta) / n;
|
||||
UnityEngine.Debug.Log($"[Bench] {label}: {nsPerOp,8:F1} ns/op | {bPerOp,6} B/op");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ac4456ca45dd64092a7c26b7fc6cff0f
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"name": "Benchmarks",
|
||||
"rootNamespace": "",
|
||||
"references": [],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": true,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [
|
||||
"Google.Protobuf"
|
||||
],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 20a66c82a93d34a489c40c5f81b4a203
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,229 @@
|
||||
// <auto-generated> arpack </auto-generated>
|
||||
// Code generated by arpack. DO NOT EDIT.
|
||||
#pragma warning disable CS8500
|
||||
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace Arpack.Messages
|
||||
{
|
||||
internal static class ArpackGenerated
|
||||
{
|
||||
internal static ushort EnsureU16Length(int length, string context)
|
||||
{
|
||||
if (length > 65535)
|
||||
{
|
||||
throw new InvalidOperationException("arpack: " + context + " exceeds uint16 limit");
|
||||
}
|
||||
return (ushort)length;
|
||||
}
|
||||
|
||||
internal static void EnsureQuantizedRange(double value, double min, double max, string context)
|
||||
{
|
||||
if (double.IsNaN(value) || value < min || value > max)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(context, "arpack: quantized value out of range for " + context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum Opcode : ushort
|
||||
{
|
||||
Unknown = 0,
|
||||
Authorize = 1,
|
||||
JoinRoom = 2
|
||||
}
|
||||
|
||||
public unsafe struct Vector3
|
||||
{
|
||||
public float X;
|
||||
public float Y;
|
||||
public float Z;
|
||||
|
||||
public int Serialize(byte* buffer)
|
||||
{
|
||||
byte* ptr = buffer;
|
||||
ArpackGenerated.EnsureQuantizedRange(X, -500, 500, "X");
|
||||
*(ushort*)ptr = (ushort)((X - (-500f)) / (500f - (-500f)) * 65535f); ptr += 2;
|
||||
ArpackGenerated.EnsureQuantizedRange(Y, -500, 500, "Y");
|
||||
*(ushort*)ptr = (ushort)((Y - (-500f)) / (500f - (-500f)) * 65535f); ptr += 2;
|
||||
ArpackGenerated.EnsureQuantizedRange(Z, -500, 500, "Z");
|
||||
*(ushort*)ptr = (ushort)((Z - (-500f)) / (500f - (-500f)) * 65535f); ptr += 2;
|
||||
return (int)(ptr - buffer);
|
||||
}
|
||||
|
||||
public static int Deserialize(byte* buffer, out Vector3 msg)
|
||||
{
|
||||
byte* ptr = buffer;
|
||||
msg = default;
|
||||
msg.X = (float)(*(ushort*)ptr) / 65535f * (500f - (-500f)) + (-500f); ptr += 2;
|
||||
msg.Y = (float)(*(ushort*)ptr) / 65535f * (500f - (-500f)) + (-500f); ptr += 2;
|
||||
msg.Z = (float)(*(ushort*)ptr) / 65535f * (500f - (-500f)) + (-500f); ptr += 2;
|
||||
return (int)(ptr - buffer);
|
||||
}
|
||||
}
|
||||
|
||||
public unsafe struct MoveMessage
|
||||
{
|
||||
public Vector3 Position;
|
||||
public float[] Velocity;
|
||||
public Vector3[] Waypoints;
|
||||
public uint PlayerID;
|
||||
public bool Active;
|
||||
public bool Visible;
|
||||
public bool Ghost;
|
||||
public string Name;
|
||||
|
||||
public int Serialize(byte* buffer)
|
||||
{
|
||||
byte* ptr = buffer;
|
||||
ptr += Position.Serialize(ptr);
|
||||
for (int _iVelocity = 0; _iVelocity < 3; _iVelocity++)
|
||||
{
|
||||
*(float*)ptr = Velocity[_iVelocity]; ptr += 4;
|
||||
}
|
||||
ushort _lenWaypoints = ArpackGenerated.EnsureU16Length(Waypoints?.Length ?? 0, "slice length for Waypoints"); *(ushort*)ptr = _lenWaypoints; ptr += 2;
|
||||
if (Waypoints != null)
|
||||
{
|
||||
for (int _iWaypoints = 0; _iWaypoints < Waypoints.Length; _iWaypoints++)
|
||||
{
|
||||
ptr += Waypoints[_iWaypoints].Serialize(ptr);
|
||||
}
|
||||
}
|
||||
*(uint*)ptr = PlayerID; ptr += 4;
|
||||
byte _boolByte4 = 0;
|
||||
if (Active) _boolByte4 |= (byte)(1 << 0);
|
||||
if (Visible) _boolByte4 |= (byte)(1 << 1);
|
||||
if (Ghost) _boolByte4 |= (byte)(1 << 2);
|
||||
*ptr = _boolByte4; ptr++;
|
||||
int _slenName = Name != null ? Encoding.UTF8.GetByteCount(Name) : 0;
|
||||
*(ushort*)ptr = ArpackGenerated.EnsureU16Length(_slenName, "string length for Name"); ptr += 2;
|
||||
if (Name != null && _slenName > 0)
|
||||
{
|
||||
fixed (char* _charsName = Name)
|
||||
{
|
||||
Encoding.UTF8.GetBytes(_charsName, Name.Length, ptr, _slenName);
|
||||
}
|
||||
}
|
||||
ptr += _slenName;
|
||||
return (int)(ptr - buffer);
|
||||
}
|
||||
|
||||
public static int Deserialize(byte* buffer, out MoveMessage msg)
|
||||
{
|
||||
byte* ptr = buffer;
|
||||
msg = default;
|
||||
ptr += Vector3.Deserialize(ptr, out msg.Position);
|
||||
msg.Velocity = new float[3];
|
||||
for (int _iVelocity = 0; _iVelocity < 3; _iVelocity++)
|
||||
{
|
||||
msg.Velocity[_iVelocity] = *(float*)ptr; ptr += 4;
|
||||
}
|
||||
int _lenWaypoints = *(ushort*)ptr; ptr += 2;
|
||||
msg.Waypoints = new Vector3[_lenWaypoints];
|
||||
for (int _iWaypoints = 0; _iWaypoints < _lenWaypoints; _iWaypoints++)
|
||||
{
|
||||
ptr += Vector3.Deserialize(ptr, out msg.Waypoints[_iWaypoints]);
|
||||
}
|
||||
msg.PlayerID = *(uint*)ptr; ptr += 4;
|
||||
byte _boolByte4 = *ptr; ptr++;
|
||||
msg.Active = (_boolByte4 & (1 << 0)) != 0;
|
||||
msg.Visible = (_boolByte4 & (1 << 1)) != 0;
|
||||
msg.Ghost = (_boolByte4 & (1 << 2)) != 0;
|
||||
int _slenmsg_Name = *(ushort*)ptr; ptr += 2;
|
||||
msg.Name = _slenmsg_Name > 0 ? Encoding.UTF8.GetString(ptr, _slenmsg_Name) : string.Empty;
|
||||
ptr += _slenmsg_Name;
|
||||
return (int)(ptr - buffer);
|
||||
}
|
||||
}
|
||||
|
||||
public unsafe struct SpawnMessage
|
||||
{
|
||||
public ulong EntityID;
|
||||
public Vector3 Position;
|
||||
public short Health;
|
||||
public string[] Tags;
|
||||
public byte[] Data;
|
||||
|
||||
public int Serialize(byte* buffer)
|
||||
{
|
||||
byte* ptr = buffer;
|
||||
*(ulong*)ptr = EntityID; ptr += 8;
|
||||
ptr += Position.Serialize(ptr);
|
||||
*(short*)ptr = Health; ptr += 2;
|
||||
ushort _lenTags = ArpackGenerated.EnsureU16Length(Tags?.Length ?? 0, "slice length for Tags"); *(ushort*)ptr = _lenTags; ptr += 2;
|
||||
if (Tags != null)
|
||||
{
|
||||
for (int _iTags = 0; _iTags < Tags.Length; _iTags++)
|
||||
{
|
||||
int _slenTags__iTags_ = Tags[_iTags] != null ? Encoding.UTF8.GetByteCount(Tags[_iTags]) : 0;
|
||||
*(ushort*)ptr = ArpackGenerated.EnsureU16Length(_slenTags__iTags_, "string length for Tags[_iTags]"); ptr += 2;
|
||||
if (Tags[_iTags] != null && _slenTags__iTags_ > 0)
|
||||
{
|
||||
fixed (char* _charsTags__iTags_ = Tags[_iTags])
|
||||
{
|
||||
Encoding.UTF8.GetBytes(_charsTags__iTags_, Tags[_iTags].Length, ptr, _slenTags__iTags_);
|
||||
}
|
||||
}
|
||||
ptr += _slenTags__iTags_;
|
||||
}
|
||||
}
|
||||
ushort _lenData = ArpackGenerated.EnsureU16Length(Data?.Length ?? 0, "slice length for Data"); *(ushort*)ptr = _lenData; ptr += 2;
|
||||
if (Data != null)
|
||||
{
|
||||
for (int _iData = 0; _iData < Data.Length; _iData++)
|
||||
{
|
||||
*ptr = Data[_iData]; ptr += 1;
|
||||
}
|
||||
}
|
||||
return (int)(ptr - buffer);
|
||||
}
|
||||
|
||||
public static int Deserialize(byte* buffer, out SpawnMessage msg)
|
||||
{
|
||||
byte* ptr = buffer;
|
||||
msg = default;
|
||||
msg.EntityID = *(ulong*)ptr; ptr += 8;
|
||||
ptr += Vector3.Deserialize(ptr, out msg.Position);
|
||||
msg.Health = *(short*)ptr; ptr += 2;
|
||||
int _lenTags = *(ushort*)ptr; ptr += 2;
|
||||
msg.Tags = new string[_lenTags];
|
||||
for (int _iTags = 0; _iTags < _lenTags; _iTags++)
|
||||
{
|
||||
int _slenmsg_Tags__iTags_ = *(ushort*)ptr; ptr += 2;
|
||||
msg.Tags[_iTags] = _slenmsg_Tags__iTags_ > 0 ? Encoding.UTF8.GetString(ptr, _slenmsg_Tags__iTags_) : string.Empty;
|
||||
ptr += _slenmsg_Tags__iTags_;
|
||||
}
|
||||
int _lenData = *(ushort*)ptr; ptr += 2;
|
||||
msg.Data = new byte[_lenData];
|
||||
for (int _iData = 0; _iData < _lenData; _iData++)
|
||||
{
|
||||
msg.Data[_iData] = *ptr; ptr += 1;
|
||||
}
|
||||
return (int)(ptr - buffer);
|
||||
}
|
||||
}
|
||||
|
||||
public unsafe struct EnvelopeMessage
|
||||
{
|
||||
public Opcode Code;
|
||||
public byte Counter;
|
||||
|
||||
public int Serialize(byte* buffer)
|
||||
{
|
||||
byte* ptr = buffer;
|
||||
*(ushort*)ptr = (ushort)Code; ptr += 2;
|
||||
*ptr = Counter; ptr += 1;
|
||||
return (int)(ptr - buffer);
|
||||
}
|
||||
|
||||
public static int Deserialize(byte* buffer, out EnvelopeMessage msg)
|
||||
{
|
||||
byte* ptr = buffer;
|
||||
msg = default;
|
||||
msg.Code = (Opcode)(*(ushort*)ptr); ptr += 2;
|
||||
msg.Counter = *ptr; ptr += 1;
|
||||
return (int)(ptr - buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9755692abdaf54daf912862821fb9fd6
|
||||
@@ -0,0 +1,768 @@
|
||||
// <auto-generated>
|
||||
// Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
// source: move.proto
|
||||
// </auto-generated>
|
||||
#pragma warning disable 1591, 0612, 3021, 8981
|
||||
#region Designer generated code
|
||||
|
||||
using pb = global::Google.Protobuf;
|
||||
using pbc = global::Google.Protobuf.Collections;
|
||||
using pbr = global::Google.Protobuf.Reflection;
|
||||
using scg = global::System.Collections.Generic;
|
||||
namespace Benchproto {
|
||||
|
||||
/// <summary>Holder for reflection information generated from move.proto</summary>
|
||||
public static partial class MoveReflection {
|
||||
|
||||
#region Descriptor
|
||||
/// <summary>File descriptor for move.proto</summary>
|
||||
public static pbr::FileDescriptor Descriptor {
|
||||
get { return descriptor; }
|
||||
}
|
||||
private static pbr::FileDescriptor descriptor;
|
||||
|
||||
static MoveReflection() {
|
||||
byte[] descriptorData = global::System.Convert.FromBase64String(
|
||||
string.Concat(
|
||||
"Cgptb3ZlLnByb3RvEgpiZW5jaHByb3RvIioKB1ZlY3RvcjMSCQoBeBgBIAEo",
|
||||
"AhIJCgF5GAIgASgCEgkKAXoYAyABKAIivwEKC01vdmVNZXNzYWdlEiUKCHBv",
|
||||
"c2l0aW9uGAEgASgLMhMuYmVuY2hwcm90by5WZWN0b3IzEhAKCHZlbG9jaXR5",
|
||||
"GAIgAygCEiYKCXdheXBvaW50cxgDIAMoCzITLmJlbmNocHJvdG8uVmVjdG9y",
|
||||
"MxIRCglwbGF5ZXJfaWQYBCABKA0SDgoGYWN0aXZlGAUgASgIEg8KB3Zpc2li",
|
||||
"bGUYBiABKAgSDQoFZ2hvc3QYByABKAgSDAoEbmFtZRgIIAEoCUItWitnaXRo",
|
||||
"dWIuY29tL2VkbWFuZDQ2L2FycGFjay9iZW5jaG1hcmtzL3Byb3RvYgZwcm90",
|
||||
"bzM="));
|
||||
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
|
||||
new pbr::FileDescriptor[] { },
|
||||
new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] {
|
||||
new pbr::GeneratedClrTypeInfo(typeof(global::Benchproto.Vector3), global::Benchproto.Vector3.Parser, new[]{ "X", "Y", "Z" }, null, null, null, null),
|
||||
new pbr::GeneratedClrTypeInfo(typeof(global::Benchproto.MoveMessage), global::Benchproto.MoveMessage.Parser, new[]{ "Position", "Velocity", "Waypoints", "PlayerId", "Active", "Visible", "Ghost", "Name" }, null, null, null, null)
|
||||
}));
|
||||
}
|
||||
#endregion
|
||||
|
||||
}
|
||||
#region Messages
|
||||
[global::System.Diagnostics.DebuggerDisplayAttribute("{ToString(),nq}")]
|
||||
public sealed partial class Vector3 : pb::IMessage<Vector3>
|
||||
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
|
||||
, pb::IBufferMessage
|
||||
#endif
|
||||
{
|
||||
private static readonly pb::MessageParser<Vector3> _parser = new pb::MessageParser<Vector3>(() => new Vector3());
|
||||
private pb::UnknownFieldSet _unknownFields;
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public static pb::MessageParser<Vector3> Parser { get { return _parser; } }
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public static pbr::MessageDescriptor Descriptor {
|
||||
get { return global::Benchproto.MoveReflection.Descriptor.MessageTypes[0]; }
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
pbr::MessageDescriptor pb::IMessage.Descriptor {
|
||||
get { return Descriptor; }
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public Vector3() {
|
||||
OnConstruction();
|
||||
}
|
||||
|
||||
partial void OnConstruction();
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public Vector3(Vector3 other) : this() {
|
||||
x_ = other.x_;
|
||||
y_ = other.y_;
|
||||
z_ = other.z_;
|
||||
_unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public Vector3 Clone() {
|
||||
return new Vector3(this);
|
||||
}
|
||||
|
||||
/// <summary>Field number for the "x" field.</summary>
|
||||
public const int XFieldNumber = 1;
|
||||
private float x_;
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public float X {
|
||||
get { return x_; }
|
||||
set {
|
||||
x_ = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Field number for the "y" field.</summary>
|
||||
public const int YFieldNumber = 2;
|
||||
private float y_;
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public float Y {
|
||||
get { return y_; }
|
||||
set {
|
||||
y_ = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Field number for the "z" field.</summary>
|
||||
public const int ZFieldNumber = 3;
|
||||
private float z_;
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public float Z {
|
||||
get { return z_; }
|
||||
set {
|
||||
z_ = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public override bool Equals(object other) {
|
||||
return Equals(other as Vector3);
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public bool Equals(Vector3 other) {
|
||||
if (ReferenceEquals(other, null)) {
|
||||
return false;
|
||||
}
|
||||
if (ReferenceEquals(other, this)) {
|
||||
return true;
|
||||
}
|
||||
if (!pbc::ProtobufEqualityComparers.BitwiseSingleEqualityComparer.Equals(X, other.X)) return false;
|
||||
if (!pbc::ProtobufEqualityComparers.BitwiseSingleEqualityComparer.Equals(Y, other.Y)) return false;
|
||||
if (!pbc::ProtobufEqualityComparers.BitwiseSingleEqualityComparer.Equals(Z, other.Z)) return false;
|
||||
return Equals(_unknownFields, other._unknownFields);
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public override int GetHashCode() {
|
||||
int hash = 1;
|
||||
if (X != 0F) hash ^= pbc::ProtobufEqualityComparers.BitwiseSingleEqualityComparer.GetHashCode(X);
|
||||
if (Y != 0F) hash ^= pbc::ProtobufEqualityComparers.BitwiseSingleEqualityComparer.GetHashCode(Y);
|
||||
if (Z != 0F) hash ^= pbc::ProtobufEqualityComparers.BitwiseSingleEqualityComparer.GetHashCode(Z);
|
||||
if (_unknownFields != null) {
|
||||
hash ^= _unknownFields.GetHashCode();
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public override string ToString() {
|
||||
return pb::JsonFormatter.ToDiagnosticString(this);
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public void WriteTo(pb::CodedOutputStream output) {
|
||||
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
|
||||
output.WriteRawMessage(this);
|
||||
#else
|
||||
if (X != 0F) {
|
||||
output.WriteRawTag(13);
|
||||
output.WriteFloat(X);
|
||||
}
|
||||
if (Y != 0F) {
|
||||
output.WriteRawTag(21);
|
||||
output.WriteFloat(Y);
|
||||
}
|
||||
if (Z != 0F) {
|
||||
output.WriteRawTag(29);
|
||||
output.WriteFloat(Z);
|
||||
}
|
||||
if (_unknownFields != null) {
|
||||
_unknownFields.WriteTo(output);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
|
||||
if (X != 0F) {
|
||||
output.WriteRawTag(13);
|
||||
output.WriteFloat(X);
|
||||
}
|
||||
if (Y != 0F) {
|
||||
output.WriteRawTag(21);
|
||||
output.WriteFloat(Y);
|
||||
}
|
||||
if (Z != 0F) {
|
||||
output.WriteRawTag(29);
|
||||
output.WriteFloat(Z);
|
||||
}
|
||||
if (_unknownFields != null) {
|
||||
_unknownFields.WriteTo(ref output);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public int CalculateSize() {
|
||||
int size = 0;
|
||||
if (X != 0F) {
|
||||
size += 1 + 4;
|
||||
}
|
||||
if (Y != 0F) {
|
||||
size += 1 + 4;
|
||||
}
|
||||
if (Z != 0F) {
|
||||
size += 1 + 4;
|
||||
}
|
||||
if (_unknownFields != null) {
|
||||
size += _unknownFields.CalculateSize();
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public void MergeFrom(Vector3 other) {
|
||||
if (other == null) {
|
||||
return;
|
||||
}
|
||||
if (other.X != 0F) {
|
||||
X = other.X;
|
||||
}
|
||||
if (other.Y != 0F) {
|
||||
Y = other.Y;
|
||||
}
|
||||
if (other.Z != 0F) {
|
||||
Z = other.Z;
|
||||
}
|
||||
_unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public void MergeFrom(pb::CodedInputStream input) {
|
||||
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
|
||||
input.ReadRawMessage(this);
|
||||
#else
|
||||
uint tag;
|
||||
while ((tag = input.ReadTag()) != 0) {
|
||||
if ((tag & 7) == 4) {
|
||||
// Abort on any end group tag.
|
||||
return;
|
||||
}
|
||||
switch(tag) {
|
||||
default:
|
||||
_unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
|
||||
break;
|
||||
case 13: {
|
||||
X = input.ReadFloat();
|
||||
break;
|
||||
}
|
||||
case 21: {
|
||||
Y = input.ReadFloat();
|
||||
break;
|
||||
}
|
||||
case 29: {
|
||||
Z = input.ReadFloat();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) {
|
||||
uint tag;
|
||||
while ((tag = input.ReadTag()) != 0) {
|
||||
if ((tag & 7) == 4) {
|
||||
// Abort on any end group tag.
|
||||
return;
|
||||
}
|
||||
switch(tag) {
|
||||
default:
|
||||
_unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
|
||||
break;
|
||||
case 13: {
|
||||
X = input.ReadFloat();
|
||||
break;
|
||||
}
|
||||
case 21: {
|
||||
Y = input.ReadFloat();
|
||||
break;
|
||||
}
|
||||
case 29: {
|
||||
Z = input.ReadFloat();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerDisplayAttribute("{ToString(),nq}")]
|
||||
public sealed partial class MoveMessage : pb::IMessage<MoveMessage>
|
||||
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
|
||||
, pb::IBufferMessage
|
||||
#endif
|
||||
{
|
||||
private static readonly pb::MessageParser<MoveMessage> _parser = new pb::MessageParser<MoveMessage>(() => new MoveMessage());
|
||||
private pb::UnknownFieldSet _unknownFields;
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public static pb::MessageParser<MoveMessage> Parser { get { return _parser; } }
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public static pbr::MessageDescriptor Descriptor {
|
||||
get { return global::Benchproto.MoveReflection.Descriptor.MessageTypes[1]; }
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
pbr::MessageDescriptor pb::IMessage.Descriptor {
|
||||
get { return Descriptor; }
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public MoveMessage() {
|
||||
OnConstruction();
|
||||
}
|
||||
|
||||
partial void OnConstruction();
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public MoveMessage(MoveMessage other) : this() {
|
||||
position_ = other.position_ != null ? other.position_.Clone() : null;
|
||||
velocity_ = other.velocity_.Clone();
|
||||
waypoints_ = other.waypoints_.Clone();
|
||||
playerId_ = other.playerId_;
|
||||
active_ = other.active_;
|
||||
visible_ = other.visible_;
|
||||
ghost_ = other.ghost_;
|
||||
name_ = other.name_;
|
||||
_unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public MoveMessage Clone() {
|
||||
return new MoveMessage(this);
|
||||
}
|
||||
|
||||
/// <summary>Field number for the "position" field.</summary>
|
||||
public const int PositionFieldNumber = 1;
|
||||
private global::Benchproto.Vector3 position_;
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public global::Benchproto.Vector3 Position {
|
||||
get { return position_; }
|
||||
set {
|
||||
position_ = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Field number for the "velocity" field.</summary>
|
||||
public const int VelocityFieldNumber = 2;
|
||||
private static readonly pb::FieldCodec<float> _repeated_velocity_codec
|
||||
= pb::FieldCodec.ForFloat(18);
|
||||
private readonly pbc::RepeatedField<float> velocity_ = new pbc::RepeatedField<float>();
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public pbc::RepeatedField<float> Velocity {
|
||||
get { return velocity_; }
|
||||
}
|
||||
|
||||
/// <summary>Field number for the "waypoints" field.</summary>
|
||||
public const int WaypointsFieldNumber = 3;
|
||||
private static readonly pb::FieldCodec<global::Benchproto.Vector3> _repeated_waypoints_codec
|
||||
= pb::FieldCodec.ForMessage(26, global::Benchproto.Vector3.Parser);
|
||||
private readonly pbc::RepeatedField<global::Benchproto.Vector3> waypoints_ = new pbc::RepeatedField<global::Benchproto.Vector3>();
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public pbc::RepeatedField<global::Benchproto.Vector3> Waypoints {
|
||||
get { return waypoints_; }
|
||||
}
|
||||
|
||||
/// <summary>Field number for the "player_id" field.</summary>
|
||||
public const int PlayerIdFieldNumber = 4;
|
||||
private uint playerId_;
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public uint PlayerId {
|
||||
get { return playerId_; }
|
||||
set {
|
||||
playerId_ = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Field number for the "active" field.</summary>
|
||||
public const int ActiveFieldNumber = 5;
|
||||
private bool active_;
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public bool Active {
|
||||
get { return active_; }
|
||||
set {
|
||||
active_ = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Field number for the "visible" field.</summary>
|
||||
public const int VisibleFieldNumber = 6;
|
||||
private bool visible_;
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public bool Visible {
|
||||
get { return visible_; }
|
||||
set {
|
||||
visible_ = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Field number for the "ghost" field.</summary>
|
||||
public const int GhostFieldNumber = 7;
|
||||
private bool ghost_;
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public bool Ghost {
|
||||
get { return ghost_; }
|
||||
set {
|
||||
ghost_ = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Field number for the "name" field.</summary>
|
||||
public const int NameFieldNumber = 8;
|
||||
private string name_ = "";
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public string Name {
|
||||
get { return name_; }
|
||||
set {
|
||||
name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public override bool Equals(object other) {
|
||||
return Equals(other as MoveMessage);
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public bool Equals(MoveMessage other) {
|
||||
if (ReferenceEquals(other, null)) {
|
||||
return false;
|
||||
}
|
||||
if (ReferenceEquals(other, this)) {
|
||||
return true;
|
||||
}
|
||||
if (!object.Equals(Position, other.Position)) return false;
|
||||
if(!velocity_.Equals(other.velocity_)) return false;
|
||||
if(!waypoints_.Equals(other.waypoints_)) return false;
|
||||
if (PlayerId != other.PlayerId) return false;
|
||||
if (Active != other.Active) return false;
|
||||
if (Visible != other.Visible) return false;
|
||||
if (Ghost != other.Ghost) return false;
|
||||
if (Name != other.Name) return false;
|
||||
return Equals(_unknownFields, other._unknownFields);
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public override int GetHashCode() {
|
||||
int hash = 1;
|
||||
if (position_ != null) hash ^= Position.GetHashCode();
|
||||
hash ^= velocity_.GetHashCode();
|
||||
hash ^= waypoints_.GetHashCode();
|
||||
if (PlayerId != 0) hash ^= PlayerId.GetHashCode();
|
||||
if (Active != false) hash ^= Active.GetHashCode();
|
||||
if (Visible != false) hash ^= Visible.GetHashCode();
|
||||
if (Ghost != false) hash ^= Ghost.GetHashCode();
|
||||
if (Name.Length != 0) hash ^= Name.GetHashCode();
|
||||
if (_unknownFields != null) {
|
||||
hash ^= _unknownFields.GetHashCode();
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public override string ToString() {
|
||||
return pb::JsonFormatter.ToDiagnosticString(this);
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public void WriteTo(pb::CodedOutputStream output) {
|
||||
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
|
||||
output.WriteRawMessage(this);
|
||||
#else
|
||||
if (position_ != null) {
|
||||
output.WriteRawTag(10);
|
||||
output.WriteMessage(Position);
|
||||
}
|
||||
velocity_.WriteTo(output, _repeated_velocity_codec);
|
||||
waypoints_.WriteTo(output, _repeated_waypoints_codec);
|
||||
if (PlayerId != 0) {
|
||||
output.WriteRawTag(32);
|
||||
output.WriteUInt32(PlayerId);
|
||||
}
|
||||
if (Active != false) {
|
||||
output.WriteRawTag(40);
|
||||
output.WriteBool(Active);
|
||||
}
|
||||
if (Visible != false) {
|
||||
output.WriteRawTag(48);
|
||||
output.WriteBool(Visible);
|
||||
}
|
||||
if (Ghost != false) {
|
||||
output.WriteRawTag(56);
|
||||
output.WriteBool(Ghost);
|
||||
}
|
||||
if (Name.Length != 0) {
|
||||
output.WriteRawTag(66);
|
||||
output.WriteString(Name);
|
||||
}
|
||||
if (_unknownFields != null) {
|
||||
_unknownFields.WriteTo(output);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
|
||||
if (position_ != null) {
|
||||
output.WriteRawTag(10);
|
||||
output.WriteMessage(Position);
|
||||
}
|
||||
velocity_.WriteTo(ref output, _repeated_velocity_codec);
|
||||
waypoints_.WriteTo(ref output, _repeated_waypoints_codec);
|
||||
if (PlayerId != 0) {
|
||||
output.WriteRawTag(32);
|
||||
output.WriteUInt32(PlayerId);
|
||||
}
|
||||
if (Active != false) {
|
||||
output.WriteRawTag(40);
|
||||
output.WriteBool(Active);
|
||||
}
|
||||
if (Visible != false) {
|
||||
output.WriteRawTag(48);
|
||||
output.WriteBool(Visible);
|
||||
}
|
||||
if (Ghost != false) {
|
||||
output.WriteRawTag(56);
|
||||
output.WriteBool(Ghost);
|
||||
}
|
||||
if (Name.Length != 0) {
|
||||
output.WriteRawTag(66);
|
||||
output.WriteString(Name);
|
||||
}
|
||||
if (_unknownFields != null) {
|
||||
_unknownFields.WriteTo(ref output);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public int CalculateSize() {
|
||||
int size = 0;
|
||||
if (position_ != null) {
|
||||
size += 1 + pb::CodedOutputStream.ComputeMessageSize(Position);
|
||||
}
|
||||
size += velocity_.CalculateSize(_repeated_velocity_codec);
|
||||
size += waypoints_.CalculateSize(_repeated_waypoints_codec);
|
||||
if (PlayerId != 0) {
|
||||
size += 1 + pb::CodedOutputStream.ComputeUInt32Size(PlayerId);
|
||||
}
|
||||
if (Active != false) {
|
||||
size += 1 + 1;
|
||||
}
|
||||
if (Visible != false) {
|
||||
size += 1 + 1;
|
||||
}
|
||||
if (Ghost != false) {
|
||||
size += 1 + 1;
|
||||
}
|
||||
if (Name.Length != 0) {
|
||||
size += 1 + pb::CodedOutputStream.ComputeStringSize(Name);
|
||||
}
|
||||
if (_unknownFields != null) {
|
||||
size += _unknownFields.CalculateSize();
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public void MergeFrom(MoveMessage other) {
|
||||
if (other == null) {
|
||||
return;
|
||||
}
|
||||
if (other.position_ != null) {
|
||||
if (position_ == null) {
|
||||
Position = new global::Benchproto.Vector3();
|
||||
}
|
||||
Position.MergeFrom(other.Position);
|
||||
}
|
||||
velocity_.Add(other.velocity_);
|
||||
waypoints_.Add(other.waypoints_);
|
||||
if (other.PlayerId != 0) {
|
||||
PlayerId = other.PlayerId;
|
||||
}
|
||||
if (other.Active != false) {
|
||||
Active = other.Active;
|
||||
}
|
||||
if (other.Visible != false) {
|
||||
Visible = other.Visible;
|
||||
}
|
||||
if (other.Ghost != false) {
|
||||
Ghost = other.Ghost;
|
||||
}
|
||||
if (other.Name.Length != 0) {
|
||||
Name = other.Name;
|
||||
}
|
||||
_unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public void MergeFrom(pb::CodedInputStream input) {
|
||||
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
|
||||
input.ReadRawMessage(this);
|
||||
#else
|
||||
uint tag;
|
||||
while ((tag = input.ReadTag()) != 0) {
|
||||
if ((tag & 7) == 4) {
|
||||
// Abort on any end group tag.
|
||||
return;
|
||||
}
|
||||
switch(tag) {
|
||||
default:
|
||||
_unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
|
||||
break;
|
||||
case 10: {
|
||||
if (position_ == null) {
|
||||
Position = new global::Benchproto.Vector3();
|
||||
}
|
||||
input.ReadMessage(Position);
|
||||
break;
|
||||
}
|
||||
case 18:
|
||||
case 21: {
|
||||
velocity_.AddEntriesFrom(input, _repeated_velocity_codec);
|
||||
break;
|
||||
}
|
||||
case 26: {
|
||||
waypoints_.AddEntriesFrom(input, _repeated_waypoints_codec);
|
||||
break;
|
||||
}
|
||||
case 32: {
|
||||
PlayerId = input.ReadUInt32();
|
||||
break;
|
||||
}
|
||||
case 40: {
|
||||
Active = input.ReadBool();
|
||||
break;
|
||||
}
|
||||
case 48: {
|
||||
Visible = input.ReadBool();
|
||||
break;
|
||||
}
|
||||
case 56: {
|
||||
Ghost = input.ReadBool();
|
||||
break;
|
||||
}
|
||||
case 66: {
|
||||
Name = input.ReadString();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) {
|
||||
uint tag;
|
||||
while ((tag = input.ReadTag()) != 0) {
|
||||
if ((tag & 7) == 4) {
|
||||
// Abort on any end group tag.
|
||||
return;
|
||||
}
|
||||
switch(tag) {
|
||||
default:
|
||||
_unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
|
||||
break;
|
||||
case 10: {
|
||||
if (position_ == null) {
|
||||
Position = new global::Benchproto.Vector3();
|
||||
}
|
||||
input.ReadMessage(Position);
|
||||
break;
|
||||
}
|
||||
case 18:
|
||||
case 21: {
|
||||
velocity_.AddEntriesFrom(ref input, _repeated_velocity_codec);
|
||||
break;
|
||||
}
|
||||
case 26: {
|
||||
waypoints_.AddEntriesFrom(ref input, _repeated_waypoints_codec);
|
||||
break;
|
||||
}
|
||||
case 32: {
|
||||
PlayerId = input.ReadUInt32();
|
||||
break;
|
||||
}
|
||||
case 40: {
|
||||
Active = input.ReadBool();
|
||||
break;
|
||||
}
|
||||
case 48: {
|
||||
Visible = input.ReadBool();
|
||||
break;
|
||||
}
|
||||
case 56: {
|
||||
Ghost = input.ReadBool();
|
||||
break;
|
||||
}
|
||||
case 66: {
|
||||
Name = input.ReadString();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
#endregion Designer generated code
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c7457f233226e42568ebd6ff92de57fc
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3590b91b4603b465dbb4216d601bff33
|
||||
ScriptedImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
script: {fileID: 11500000, guid: 8404be70184654265930450def6a9037, type: 3}
|
||||
generateWrapperCode: 0
|
||||
wrapperCodePath:
|
||||
wrapperClassName:
|
||||
wrapperCodeNamespace:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f4bc80e0b96da47f3bbcaed7aa3fcb27
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Binary file not shown.
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f7d8cfb8b4c854ef88343739cde5f7d6
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c2528068817984550af33837b73bee36
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,231 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!29 &1
|
||||
OcclusionCullingSettings:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 2
|
||||
m_OcclusionBakeSettings:
|
||||
smallestOccluder: 5
|
||||
smallestHole: 0.25
|
||||
backfaceThreshold: 100
|
||||
m_SceneGUID: 00000000000000000000000000000000
|
||||
m_OcclusionCullingData: {fileID: 0}
|
||||
--- !u!104 &2
|
||||
RenderSettings:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 10
|
||||
m_Fog: 0
|
||||
m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
|
||||
m_FogMode: 3
|
||||
m_FogDensity: 0.01
|
||||
m_LinearFogStart: 0
|
||||
m_LinearFogEnd: 300
|
||||
m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1}
|
||||
m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1}
|
||||
m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
|
||||
m_AmbientIntensity: 1
|
||||
m_AmbientMode: 3
|
||||
m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
|
||||
m_SkyboxMaterial: {fileID: 0}
|
||||
m_HaloStrength: 0.5
|
||||
m_FlareStrength: 1
|
||||
m_FlareFadeSpeed: 3
|
||||
m_HaloTexture: {fileID: 0}
|
||||
m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
|
||||
m_DefaultReflectionMode: 0
|
||||
m_DefaultReflectionResolution: 128
|
||||
m_ReflectionBounces: 1
|
||||
m_ReflectionIntensity: 1
|
||||
m_CustomReflection: {fileID: 0}
|
||||
m_Sun: {fileID: 0}
|
||||
m_UseRadianceAmbientProbe: 0
|
||||
--- !u!157 &3
|
||||
LightmapSettings:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 13
|
||||
m_BakeOnSceneLoad: 0
|
||||
m_GISettings:
|
||||
serializedVersion: 2
|
||||
m_BounceScale: 1
|
||||
m_IndirectOutputScale: 1
|
||||
m_AlbedoBoost: 1
|
||||
m_EnvironmentLightingMode: 0
|
||||
m_EnableBakedLightmaps: 0
|
||||
m_EnableRealtimeLightmaps: 0
|
||||
m_LightmapEditorSettings:
|
||||
serializedVersion: 12
|
||||
m_Resolution: 2
|
||||
m_BakeResolution: 40
|
||||
m_AtlasSize: 1024
|
||||
m_AO: 0
|
||||
m_AOMaxDistance: 1
|
||||
m_CompAOExponent: 1
|
||||
m_CompAOExponentDirect: 0
|
||||
m_ExtractAmbientOcclusion: 0
|
||||
m_Padding: 2
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_LightmapsBakeMode: 1
|
||||
m_TextureCompression: 1
|
||||
m_ReflectionCompression: 2
|
||||
m_MixedBakeMode: 2
|
||||
m_BakeBackend: 0
|
||||
m_PVRSampling: 1
|
||||
m_PVRDirectSampleCount: 32
|
||||
m_PVRSampleCount: 500
|
||||
m_PVRBounces: 2
|
||||
m_PVREnvironmentSampleCount: 500
|
||||
m_PVREnvironmentReferencePointCount: 2048
|
||||
m_PVRFilteringMode: 2
|
||||
m_PVRDenoiserTypeDirect: 0
|
||||
m_PVRDenoiserTypeIndirect: 0
|
||||
m_PVRDenoiserTypeAO: 0
|
||||
m_PVRFilterTypeDirect: 0
|
||||
m_PVRFilterTypeIndirect: 0
|
||||
m_PVRFilterTypeAO: 0
|
||||
m_PVREnvironmentMIS: 0
|
||||
m_PVRCulling: 1
|
||||
m_PVRFilteringGaussRadiusDirect: 1
|
||||
m_PVRFilteringGaussRadiusIndirect: 5
|
||||
m_PVRFilteringGaussRadiusAO: 2
|
||||
m_PVRFilteringAtrousPositionSigmaDirect: 0.5
|
||||
m_PVRFilteringAtrousPositionSigmaIndirect: 2
|
||||
m_PVRFilteringAtrousPositionSigmaAO: 1
|
||||
m_ExportTrainingData: 0
|
||||
m_TrainingDataDestination: TrainingData
|
||||
m_LightProbeSampleCountMultiplier: 4
|
||||
m_LightingDataAsset: {fileID: 0}
|
||||
m_LightingSettings: {fileID: 0}
|
||||
--- !u!196 &4
|
||||
NavMeshSettings:
|
||||
serializedVersion: 2
|
||||
m_ObjectHideFlags: 0
|
||||
m_BuildSettings:
|
||||
serializedVersion: 3
|
||||
agentTypeID: 0
|
||||
agentRadius: 0.5
|
||||
agentHeight: 2
|
||||
agentSlope: 45
|
||||
agentClimb: 0.4
|
||||
ledgeDropHeight: 0
|
||||
maxJumpAcrossDistance: 0
|
||||
minRegionArea: 2
|
||||
manualCellSize: 0
|
||||
cellSize: 0.16666667
|
||||
manualTileSize: 0
|
||||
tileSize: 256
|
||||
buildHeightMesh: 0
|
||||
maxJobWorkers: 0
|
||||
preserveTilesOutsideBounds: 0
|
||||
debug:
|
||||
m_Flags: 0
|
||||
m_NavMeshData: {fileID: 0}
|
||||
--- !u!1 &519420028
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 519420032}
|
||||
- component: {fileID: 519420031}
|
||||
- component: {fileID: 519420029}
|
||||
- component: {fileID: 519420033}
|
||||
m_Layer: 0
|
||||
m_Name: Main Camera
|
||||
m_TagString: MainCamera
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!81 &519420029
|
||||
AudioListener:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 519420028}
|
||||
m_Enabled: 1
|
||||
--- !u!20 &519420031
|
||||
Camera:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 519420028}
|
||||
m_Enabled: 1
|
||||
serializedVersion: 2
|
||||
m_ClearFlags: 2
|
||||
m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0}
|
||||
m_projectionMatrixMode: 1
|
||||
m_GateFitMode: 2
|
||||
m_FOVAxisMode: 0
|
||||
m_Iso: 200
|
||||
m_ShutterSpeed: 0.005
|
||||
m_Aperture: 16
|
||||
m_FocusDistance: 10
|
||||
m_FocalLength: 50
|
||||
m_BladeCount: 5
|
||||
m_Curvature: {x: 2, y: 11}
|
||||
m_BarrelClipping: 0.25
|
||||
m_Anamorphism: 0
|
||||
m_SensorSize: {x: 36, y: 24}
|
||||
m_LensShift: {x: 0, y: 0}
|
||||
m_NormalizedViewPortRect:
|
||||
serializedVersion: 2
|
||||
x: 0
|
||||
y: 0
|
||||
width: 1
|
||||
height: 1
|
||||
near clip plane: 0.3
|
||||
far clip plane: 1000
|
||||
field of view: 60
|
||||
orthographic: 1
|
||||
orthographic size: 5
|
||||
m_Depth: -1
|
||||
m_CullingMask:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
m_RenderingPath: -1
|
||||
m_TargetTexture: {fileID: 0}
|
||||
m_TargetDisplay: 0
|
||||
m_TargetEye: 0
|
||||
m_HDR: 1
|
||||
m_AllowMSAA: 0
|
||||
m_AllowDynamicResolution: 0
|
||||
m_ForceIntoRT: 0
|
||||
m_OcclusionCulling: 0
|
||||
m_StereoConvergence: 10
|
||||
m_StereoSeparation: 0.022
|
||||
--- !u!4 &519420032
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 519420028}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: -10}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 0}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!114 &519420033
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 519420028}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: ac4456ca45dd64092a7c26b7fc6cff0f, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier: Benchmarks::BenchmarkRunner
|
||||
--- !u!1660057539 &9223372036854775807
|
||||
SceneRoots:
|
||||
m_ObjectHideFlags: 0
|
||||
m_Roots:
|
||||
- {fileID: 519420032}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2cda990e2423bbf4892e6590ba056729
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,887 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<LangVersion>9.0</LangVersion>
|
||||
<_TargetFrameworkDirectories>non_empty_path_generated_by_unity.rider.package</_TargetFrameworkDirectories>
|
||||
<_FullFrameworkReferenceAssemblyPaths>non_empty_path_generated_by_unity.rider.package</_FullFrameworkReferenceAssemblyPaths>
|
||||
<DisableHandlePackageFileConflicts>true</DisableHandlePackageFileConflicts>
|
||||
<ResolveNuGetPackages>false</ResolveNuGetPackages>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>10.0.20506</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<RootNamespace></RootNamespace>
|
||||
<ProjectGuid>{b6ce87c6-d606-93b9-b8b1-3b520c8d6bae}</ProjectGuid>
|
||||
<ProjectTypeGuids>{E097FAD1-6243-4DAD-9C02-E9B9EFC3FFC1};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<AssemblyName>Benchmarks</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.7.1</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<BaseDirectory>.</BaseDirectory>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>Temp\Bin\Debug\Benchmarks\</OutputPath>
|
||||
<DefineConstants>UNITY_6000_3_11;UNITY_6000_3;UNITY_6000;UNITY_5_3_OR_NEWER;UNITY_5_4_OR_NEWER;UNITY_5_5_OR_NEWER;UNITY_5_6_OR_NEWER;UNITY_2017_1_OR_NEWER;UNITY_2017_2_OR_NEWER;UNITY_2017_3_OR_NEWER;UNITY_2017_4_OR_NEWER;UNITY_2018_1_OR_NEWER;UNITY_2018_2_OR_NEWER;UNITY_2018_3_OR_NEWER;UNITY_2018_4_OR_NEWER;UNITY_2019_1_OR_NEWER;UNITY_2019_2_OR_NEWER;UNITY_2019_3_OR_NEWER;UNITY_2019_4_OR_NEWER;UNITY_2020_1_OR_NEWER;UNITY_2020_2_OR_NEWER;UNITY_2020_3_OR_NEWER;UNITY_2021_1_OR_NEWER;UNITY_2021_2_OR_NEWER;UNITY_2021_3_OR_NEWER;UNITY_2022_1_OR_NEWER;UNITY_2022_2_OR_NEWER;UNITY_2022_3_OR_NEWER;UNITY_2023_1_OR_NEWER;UNITY_2023_2_OR_NEWER;UNITY_2023_3_OR_NEWER;UNITY_6000_0_OR_NEWER;UNITY_6000_1_OR_NEWER;UNITY_6000_2_OR_NEWER;UNITY_6000_3_OR_NEWER;PLATFORM_ARCH_64;UNITY_64;UNITY_INCLUDE_TESTS;ENABLE_AR;ENABLE_AUDIO;ENABLE_AUDIO_SCRIPTABLE_PIPELINE;ENABLE_CACHING;ENABLE_CLOTH;ENABLE_MICROPHONE;ENABLE_MULTIPLE_DISPLAYS;ENABLE_PHYSICS;ENABLE_TEXTURE_STREAMING;ENABLE_VIRTUALTEXTURING;ENABLE_LZMA;ENABLE_UNITYEVENTS;ENABLE_VR;ENABLE_WEBCAM;ENABLE_UNITYWEBREQUEST;ENABLE_WWW;ENABLE_CLOUD_SERVICES;ENABLE_CLOUD_SERVICES_ADS;ENABLE_CLOUD_SERVICES_USE_WEBREQUEST;ENABLE_UNITY_CONSENT;ENABLE_UNITY_CLOUD_IDENTIFIERS;ENABLE_CLOUD_SERVICES_CRASH_REPORTING;ENABLE_CLOUD_SERVICES_NATIVE_CRASH_REPORTING;ENABLE_CLOUD_SERVICES_PURCHASING;ENABLE_CLOUD_SERVICES_ANALYTICS;ENABLE_CLOUD_SERVICES_BUILD;ENABLE_EDITOR_GAME_SERVICES;ENABLE_UNITY_GAME_SERVICES_ANALYTICS_SUPPORT;ENABLE_CLOUD_LICENSE;ENABLE_EDITOR_HUB_LICENSE;ENABLE_WEBSOCKET_CLIENT;ENABLE_GENERATE_NATIVE_PLUGINS_FOR_ASSEMBLIES_API;ENABLE_DIRECTOR_AUDIO;ENABLE_DIRECTOR_TEXTURE;ENABLE_MANAGED_JOBS;ENABLE_MANAGED_TRANSFORM_JOBS;ENABLE_MANAGED_ANIMATION_JOBS;ENABLE_MANAGED_AUDIO_JOBS;ENABLE_MANAGED_UNITYTLS;INCLUDE_DYNAMIC_GI;ENABLE_SCRIPTING_GC_WBARRIERS;PLATFORM_SUPPORTS_MONO;RENDER_SOFTWARE_CURSOR;ENABLE_MARSHALLING_TESTS;ENABLE_VIDEO;ENABLE_NAVIGATION_OFFMESHLINK_TO_NAVMESHLINK;ENABLE_ACCELERATOR_CLIENT_DEBUGGING;ENABLE_ACCESSIBILITY_SCREEN_READER;TEXTCORE_1_0_OR_NEWER;EDITOR_ONLY_NAVMESH_BUILDER_DEPRECATED;PLATFORM_STANDALONE_OSX;PLATFORM_STANDALONE;UNITY_STANDALONE_OSX;UNITY_STANDALONE;ENABLE_GAMECENTER;ENABLE_RUNTIME_GI;ENABLE_MOVIES;ENABLE_NETWORK;ENABLE_CRUNCH_TEXTURE_COMPRESSION;ENABLE_CLOUD_SERVICES_ENGINE_DIAGNOSTICS;ENABLE_CLUSTER_SYNC;ENABLE_CLUSTERINPUT;ENABLE_SPATIALTRACKING;PLATFORM_HAS_CUSTOM_MUTEX;PLATFORM_UPDATES_TIME_OUTSIDE_OF_PLAYER_LOOP;PLATFORM_SUPPORTS_SPLIT_GRAPHICS_JOBS;ENABLE_MONO;NET_STANDARD_2_0;NET_STANDARD;NET_STANDARD_2_1;NETSTANDARD;NETSTANDARD2_1;ENABLE_PROFILER;DEBUG;TRACE;UNITY_ASSERTIONS;UNITY_EDITOR;UNITY_EDITOR_64;UNITY_EDITOR_OSX;ENABLE_UNITY_COLLECTIONS_CHECKS;ENABLE_BURST_AOT;UNITY_TEAM_LICENSE;ENABLE_CUSTOM_RENDER_TEXTURE;ENABLE_DIRECTOR;ENABLE_LOCALIZATION;ENABLE_SPRITES;ENABLE_TERRAIN;ENABLE_TILEMAP;ENABLE_TIMELINE;ENABLE_INPUT_SYSTEM;TEXTCORE_FONT_ENGINE_1_5_OR_NEWER;TEXTCORE_TEXT_ENGINE_1_5_OR_NEWER;TEXTCORE_FONT_ENGINE_1_6_OR_NEWER;CSHARP_7_OR_LATER;CSHARP_7_3_OR_NEWER</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<NoWarn>0169,0649</NoWarn>
|
||||
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
|
||||
<TreatWarningsAsErrors>False</TreatWarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<NoConfig>true</NoConfig>
|
||||
<NoStdLib>true</NoStdLib>
|
||||
<AddAdditionalExplicitAssemblyReferences>false</AddAdditionalExplicitAssemblyReferences>
|
||||
<ImplicitlyExpandNETStandardFacades>false</ImplicitlyExpandNETStandardFacades>
|
||||
<ImplicitlyExpandDesignTimeFacades>false</ImplicitlyExpandDesignTimeFacades>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Analyzer Include="/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/BuildPipeline/Unity.SourceGenerators/Unity.SourceGenerators.dll" />
|
||||
<Analyzer Include="/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/BuildPipeline/Unity.SourceGenerators/Unity.Properties.SourceGenerator.dll" />
|
||||
<Analyzer Include="/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/BuildPipeline/Unity.SourceGenerators/Unity.UIToolkit.SourceGenerator.dll" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Assets/Benchmarks/Messages.gen.cs" />
|
||||
<Compile Include="Assets/Benchmarks/BenchmarkRunner.cs" />
|
||||
<Compile Include="Assets/Benchmarks/Move.cs" />
|
||||
<None Include="Assets/Benchmarks/Benchmarks.asmdef" />
|
||||
<Reference Include="UnityEngine">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.AIModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.AIModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ARModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.ARModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.AccessibilityModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.AccessibilityModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.AdaptivePerformanceModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.AdaptivePerformanceModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.AndroidJNIModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.AndroidJNIModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.AnimationModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.AnimationModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.AssetBundleModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.AssetBundleModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.AudioModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.AudioModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ClothModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.ClothModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ClusterInputModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.ClusterInputModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ClusterRendererModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.ClusterRendererModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ContentLoadModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.ContentLoadModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.CoreModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.CoreModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.CrashReportingModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.CrashReportingModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.DSPGraphModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.DSPGraphModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.DirectorModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.DirectorModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.GIModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.GIModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.GameCenterModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.GameCenterModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.GraphicsStateCollectionSerializerModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.GraphicsStateCollectionSerializerModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.GridModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.GridModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.HierarchyCoreModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.HierarchyCoreModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.HotReloadModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.HotReloadModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.IMGUIModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.IMGUIModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.IdentifiersModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.IdentifiersModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ImageConversionModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.ImageConversionModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.InputModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.InputModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.InputForUIModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.InputForUIModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.InputLegacyModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.InputLegacyModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.InsightsModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.InsightsModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.JSONSerializeModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.JSONSerializeModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.LocalizationModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.LocalizationModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.MarshallingModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.MarshallingModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.MultiplayerModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.MultiplayerModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ParticleSystemModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.ParticleSystemModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.PerformanceReportingModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.PerformanceReportingModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.PhysicsModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.PhysicsModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.Physics2DModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.Physics2DModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.PhysicsBackendPhysXModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.PhysicsBackendPhysXModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.PropertiesModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.PropertiesModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.RenderAs2DModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.RenderAs2DModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.RuntimeInitializeOnLoadManagerInitializerModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.RuntimeInitializeOnLoadManagerInitializerModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ScreenCaptureModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.ScreenCaptureModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ShaderRuntimeModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.ShaderRuntimeModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ShaderVariantAnalyticsModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.ShaderVariantAnalyticsModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.SharedInternalsModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.SharedInternalsModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.SpriteMaskModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.SpriteMaskModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.SpriteShapeModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.SpriteShapeModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.StreamingModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.StreamingModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.SubstanceModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.SubstanceModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.SubsystemsModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.SubsystemsModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.TLSModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.TLSModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.TerrainModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.TerrainModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.TerrainPhysicsModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.TerrainPhysicsModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.TextCoreFontEngineModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.TextCoreFontEngineModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.TextCoreTextEngineModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.TextCoreTextEngineModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.TextRenderingModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.TextRenderingModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.TilemapModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.TilemapModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UIModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.UIModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UIElementsModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.UIElementsModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UmbraModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.UmbraModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityAnalyticsModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.UnityAnalyticsModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityAnalyticsCommonModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.UnityAnalyticsCommonModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityConnectModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.UnityConnectModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityConsentModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.UnityConsentModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityCurlModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.UnityCurlModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityWebRequestModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.UnityWebRequestModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityWebRequestAssetBundleModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.UnityWebRequestAssetBundleModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityWebRequestAudioModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.UnityWebRequestAudioModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityWebRequestTextureModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.UnityWebRequestTextureModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityWebRequestWWWModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.UnityWebRequestWWWModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.VFXModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.VFXModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.VRModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.VRModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.VectorGraphicsModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.VectorGraphicsModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.VehiclesModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.VehiclesModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.VideoModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.VideoModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.VirtualTexturingModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.VirtualTexturingModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.WindModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.WindModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.XRModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEngine.XRModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEditor.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.AccessibilityModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEditor.AccessibilityModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.AdaptivePerformanceModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEditor.AdaptivePerformanceModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.AssetComplianceModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEditor.AssetComplianceModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.BuildProfileModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEditor.BuildProfileModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.ClothModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEditor.ClothModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.CoreBusinessMetricsModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEditor.CoreBusinessMetricsModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.CoreModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEditor.CoreModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.DeviceSimulatorModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEditor.DeviceSimulatorModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.DiagnosticsModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEditor.DiagnosticsModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.EditorToolbarModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEditor.EditorToolbarModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.EmbreeModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEditor.EmbreeModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.GIModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEditor.GIModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.GraphViewModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEditor.GraphViewModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.GraphicsStateCollectionSerializerModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEditor.GraphicsStateCollectionSerializerModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.GridAndSnapModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEditor.GridAndSnapModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.GridModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEditor.GridModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.HierarchyModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEditor.HierarchyModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.MediaModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEditor.MediaModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.MultiplayerModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEditor.MultiplayerModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.Physics2DModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEditor.Physics2DModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.PhysicsModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEditor.PhysicsModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.PlayModeModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEditor.PlayModeModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.PresetsUIModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEditor.PresetsUIModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.PropertiesModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEditor.PropertiesModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.QuickInstallModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEditor.QuickInstallModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.QuickSearchModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEditor.QuickSearchModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.SafeModeModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEditor.SafeModeModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.SceneTemplateModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEditor.SceneTemplateModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.SceneViewModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEditor.SceneViewModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.ShaderBuildSettingsModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEditor.ShaderBuildSettingsModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.ShaderCompilationModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEditor.ShaderCompilationModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.ShaderFoundryModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEditor.ShaderFoundryModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.SketchUpModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEditor.SketchUpModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.SpriteMaskModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEditor.SpriteMaskModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.SpriteShapeModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEditor.SpriteShapeModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.SubstanceModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEditor.SubstanceModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.TerrainModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEditor.TerrainModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.TextCoreFontEngineModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEditor.TextCoreFontEngineModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.TextCoreTextEngineModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEditor.TextCoreTextEngineModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.TextRenderingModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEditor.TextRenderingModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.TilemapModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEditor.TilemapModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.TreeModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEditor.TreeModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.UIAutomationModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEditor.UIAutomationModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.UIBuilderModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEditor.UIBuilderModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.UIElementsModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEditor.UIElementsModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.UIElementsSamplesModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEditor.UIElementsSamplesModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.UIToolkitAuthoringModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEditor.UIToolkitAuthoringModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.UmbraModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEditor.UmbraModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.UnityConnectModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEditor.UnityConnectModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.VFXModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEditor.VFXModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.VectorGraphicsModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEditor.VectorGraphicsModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.VideoModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEditor.VideoModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.XRModule">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEngine/UnityEditor.XRModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.Graphs">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/Managed/UnityEditor.Graphs.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.OSXStandalone.Extensions">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/PlaybackEngines/MacStandaloneSupport/UnityEditor.OSXStandalone.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.VisualScripting.YamlDotNet">
|
||||
<HintPath>/Users/edmand46/GolandProjects/arpack/benchmarks/unity/Library/PackageCache/com.unity.visualscripting@eb6004dcc707/Editor/VisualScripting.Core/Dependencies/YamlDotNet/Unity.VisualScripting.YamlDotNet.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.Collections.LowLevel.ILSupport">
|
||||
<HintPath>/Users/edmand46/GolandProjects/arpack/benchmarks/unity/Library/PackageCache/com.unity.collections@aea9d3bd5e19/Unity.Collections.LowLevel.ILSupport/Unity.Collections.LowLevel.ILSupport.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="nunit.framework">
|
||||
<HintPath>/Users/edmand46/GolandProjects/arpack/benchmarks/unity/Library/PackageCache/com.unity.ext.nunit@d8c07649098d/net40/unity-custom/nunit.framework.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.Plastic.Antlr3.Runtime">
|
||||
<HintPath>/Users/edmand46/GolandProjects/arpack/benchmarks/unity/Library/PackageCache/com.unity.collab-proxy@a5329f833fa8/Lib/Editor/Unity.Plastic.Antlr3.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.Plastic.Newtonsoft.Json">
|
||||
<HintPath>/Users/edmand46/GolandProjects/arpack/benchmarks/unity/Library/PackageCache/com.unity.collab-proxy@a5329f833fa8/Lib/Editor/Unity.Plastic.Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="log4netPlastic">
|
||||
<HintPath>/Users/edmand46/GolandProjects/arpack/benchmarks/unity/Library/PackageCache/com.unity.collab-proxy@a5329f833fa8/Lib/Editor/log4netPlastic.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.VisualScripting.IonicZip">
|
||||
<HintPath>/Users/edmand46/GolandProjects/arpack/benchmarks/unity/Library/PackageCache/com.unity.visualscripting@eb6004dcc707/Editor/VisualScripting.Core/Dependencies/DotNetZip/Unity.VisualScripting.IonicZip.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.Hashing">
|
||||
<HintPath>/Users/edmand46/GolandProjects/arpack/benchmarks/unity/Library/PackageCache/com.unity.collections@aea9d3bd5e19/Unity.Collections.Tests/System.IO.Hashing/System.IO.Hashing.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="unityplastic">
|
||||
<HintPath>/Users/edmand46/GolandProjects/arpack/benchmarks/unity/Library/PackageCache/com.unity.collab-proxy@a5329f833fa8/Lib/Editor/unityplastic.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.VisualScripting.Antlr3.Runtime">
|
||||
<HintPath>/Users/edmand46/GolandProjects/arpack/benchmarks/unity/Library/PackageCache/com.unity.visualscripting@eb6004dcc707/Runtime/VisualScripting.Flow/Dependencies/NCalc/Unity.VisualScripting.Antlr3.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.VisualScripting.TextureAssets">
|
||||
<HintPath>/Users/edmand46/GolandProjects/arpack/benchmarks/unity/Library/PackageCache/com.unity.visualscripting@eb6004dcc707/Editor/VisualScripting.Core/EditorAssetResources/Unity.VisualScripting.TextureAssets.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Mono.Cecil">
|
||||
<HintPath>/Users/edmand46/GolandProjects/arpack/benchmarks/unity/Library/PackageCache/com.unity.nuget.mono-cecil@ecb9724e46ff/Mono.Cecil.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.CompilerServices.Unsafe">
|
||||
<HintPath>/Users/edmand46/GolandProjects/arpack/benchmarks/unity/Library/PackageCache/com.unity.collections@aea9d3bd5e19/Unity.Collections.Tests/System.Runtime.CompilerServices.Unsafe/System.Runtime.CompilerServices.Unsafe.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Google.Protobuf">
|
||||
<HintPath>/Users/edmand46/GolandProjects/arpack/benchmarks/unity/Assets/Plugins/Google.Protobuf.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.iOS.Extensions.Xcode">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/PlaybackEngines/MacStandaloneSupport/UnityEditor.iOS.Extensions.Xcode.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="netstandard">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/ref/2.1.0/netstandard.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Win32.Primitives">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/Microsoft.Win32.Primitives.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.AppContext">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.AppContext.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Buffers">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Buffers.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Collections.Concurrent">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Collections.Concurrent.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Collections.NonGeneric">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Collections.NonGeneric.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Collections.Specialized">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Collections.Specialized.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Collections">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Collections.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ComponentModel.EventBasedAsync">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.ComponentModel.EventBasedAsync.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ComponentModel.Primitives">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.ComponentModel.Primitives.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ComponentModel.TypeConverter">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.ComponentModel.TypeConverter.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ComponentModel">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.ComponentModel.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Console">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Console.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Data.Common">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Data.Common.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Diagnostics.Contracts">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Diagnostics.Contracts.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Diagnostics.Debug">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Diagnostics.Debug.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Diagnostics.FileVersionInfo">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Diagnostics.FileVersionInfo.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Diagnostics.Process">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Diagnostics.Process.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Diagnostics.StackTrace">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Diagnostics.StackTrace.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Diagnostics.TextWriterTraceListener">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Diagnostics.TextWriterTraceListener.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Diagnostics.Tools">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Diagnostics.Tools.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Diagnostics.TraceSource">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Diagnostics.TraceSource.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Diagnostics.Tracing">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Diagnostics.Tracing.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Drawing.Primitives">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Drawing.Primitives.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Dynamic.Runtime">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Dynamic.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Globalization.Calendars">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Globalization.Calendars.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Globalization.Extensions">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Globalization.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Globalization">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Globalization.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.Compression.ZipFile">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.IO.Compression.ZipFile.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.Compression">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.IO.Compression.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.FileSystem.DriveInfo">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.IO.FileSystem.DriveInfo.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.FileSystem.Primitives">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.IO.FileSystem.Primitives.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.FileSystem.Watcher">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.IO.FileSystem.Watcher.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.FileSystem">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.IO.FileSystem.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.IsolatedStorage">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.IO.IsolatedStorage.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.MemoryMappedFiles">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.IO.MemoryMappedFiles.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.Pipes">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.IO.Pipes.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.UnmanagedMemoryStream">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.IO.UnmanagedMemoryStream.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.IO.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Linq.Expressions">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Linq.Expressions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Linq.Parallel">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Linq.Parallel.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Linq.Queryable">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Linq.Queryable.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Linq">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Linq.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Memory">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Memory.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.Http">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Net.Http.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.NameResolution">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Net.NameResolution.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.NetworkInformation">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Net.NetworkInformation.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.Ping">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Net.Ping.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.Primitives">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Net.Primitives.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.Requests">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Net.Requests.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.Security">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Net.Security.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.Sockets">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Net.Sockets.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.WebHeaderCollection">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Net.WebHeaderCollection.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.WebSockets.Client">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Net.WebSockets.Client.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.WebSockets">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Net.WebSockets.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Numerics.Vectors">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Numerics.Vectors.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ObjectModel">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.ObjectModel.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Reflection.DispatchProxy">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Reflection.DispatchProxy.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Reflection.Emit.ILGeneration">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Reflection.Emit.ILGeneration.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Reflection.Emit.Lightweight">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Reflection.Emit.Lightweight.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Reflection.Emit">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Reflection.Emit.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Reflection.Extensions">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Reflection.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Reflection.Primitives">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Reflection.Primitives.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Reflection">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Reflection.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Resources.Reader">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Resources.Reader.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Resources.ResourceManager">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Resources.ResourceManager.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Resources.Writer">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Resources.Writer.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.CompilerServices.VisualC">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Runtime.CompilerServices.VisualC.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.Extensions">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Runtime.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.Handles">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Runtime.Handles.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.InteropServices.RuntimeInformation">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Runtime.InteropServices.RuntimeInformation.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.InteropServices">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Runtime.InteropServices.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.Numerics">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Runtime.Numerics.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.Serialization.Formatters">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Runtime.Serialization.Formatters.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.Serialization.Json">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Runtime.Serialization.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.Serialization.Primitives">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Runtime.Serialization.Primitives.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.Serialization.Xml">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Runtime.Serialization.Xml.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.Claims">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Security.Claims.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.Cryptography.Algorithms">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Security.Cryptography.Algorithms.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.Cryptography.Csp">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Security.Cryptography.Csp.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.Cryptography.Encoding">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Security.Cryptography.Encoding.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.Cryptography.Primitives">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Security.Cryptography.Primitives.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.Cryptography.X509Certificates">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Security.Cryptography.X509Certificates.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.Principal">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Security.Principal.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.SecureString">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Security.SecureString.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Text.Encoding.Extensions">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Text.Encoding.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Text.Encoding">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Text.Encoding.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Text.RegularExpressions">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Text.RegularExpressions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Threading.Overlapped">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Threading.Overlapped.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Threading.Tasks.Extensions">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Threading.Tasks.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Threading.Tasks.Parallel">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Threading.Tasks.Parallel.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Threading.Tasks">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Threading.Tasks.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Threading.Thread">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Threading.Thread.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Threading.ThreadPool">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Threading.ThreadPool.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Threading.Timer">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Threading.Timer.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Threading">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Threading.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ValueTuple">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.ValueTuple.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.ReaderWriter">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Xml.ReaderWriter.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.XDocument">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Xml.XDocument.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.XPath.XDocument">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Xml.XPath.XDocument.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.XPath">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Xml.XPath.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.XmlDocument">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Xml.XmlDocument.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.XmlSerializer">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netstandard/System.Xml.XmlSerializer.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.InteropServices.WindowsRuntime">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/Extensions/2.0.0/System.Runtime.InteropServices.WindowsRuntime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ComponentModel.Composition">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netfx/System.ComponentModel.Composition.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Core">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netfx/System.Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Data">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netfx/System.Data.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Drawing">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netfx/System.Drawing.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.Compression.FileSystem">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netfx/System.IO.Compression.FileSystem.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netfx/System.Net.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Numerics">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netfx/System.Numerics.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.Serialization">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netfx/System.Runtime.Serialization.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ServiceModel.Web">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netfx/System.ServiceModel.Web.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Transactions">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netfx/System.Transactions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Web">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netfx/System.Web.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Windows">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netfx/System.Windows.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.Linq">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netfx/System.Xml.Linq.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.Serialization">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netfx/System.Xml.Serialization.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netfx/System.Xml.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netfx/System.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="mscorlib">
|
||||
<HintPath>/Applications/Unity/Hub/Editor/6000.3.11f1/Unity.app/Contents/Resources/Scripting/NetStandard/compat/2.1.0/shims/netfx/mscorlib.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.UI">
|
||||
<HintPath>/Users/edmand46/GolandProjects/arpack/benchmarks/unity/Library/ScriptAssemblies/UnityEditor.UI.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UI">
|
||||
<HintPath>/Users/edmand46/GolandProjects/arpack/benchmarks/unity/Library/ScriptAssemblies/UnityEngine.UI.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
@@ -0,0 +1,19 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!11 &1
|
||||
AudioManager:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 2
|
||||
m_Volume: 1
|
||||
Rolloff Scale: 1
|
||||
Doppler Factor: 1
|
||||
Default Speaker Mode: 2
|
||||
m_SampleRate: 0
|
||||
m_DSPBufferSize: 1024
|
||||
m_VirtualVoiceCount: 512
|
||||
m_RealVoiceCount: 32
|
||||
m_SpatializerPlugin:
|
||||
m_AmbisonicDecoderPlugin:
|
||||
m_DisableAudio: 0
|
||||
m_VirtualizeEffects: 1
|
||||
m_RequestedDSPBufferSize: 0
|
||||
@@ -0,0 +1,6 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!236 &1
|
||||
ClusterInputManager:
|
||||
m_ObjectHideFlags: 0
|
||||
m_Inputs: []
|
||||
@@ -0,0 +1,37 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!55 &1
|
||||
PhysicsManager:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 13
|
||||
m_Gravity: {x: 0, y: -9.81, z: 0}
|
||||
m_DefaultMaterial: {fileID: 0}
|
||||
m_BounceThreshold: 2
|
||||
m_DefaultMaxDepenetrationVelocity: 10
|
||||
m_SleepThreshold: 0.005
|
||||
m_DefaultContactOffset: 0.01
|
||||
m_DefaultSolverIterations: 6
|
||||
m_DefaultSolverVelocityIterations: 1
|
||||
m_QueriesHitBackfaces: 0
|
||||
m_QueriesHitTriggers: 1
|
||||
m_EnableAdaptiveForce: 0
|
||||
m_ClothInterCollisionDistance: 0.1
|
||||
m_ClothInterCollisionStiffness: 0.2
|
||||
m_ContactsGeneration: 1
|
||||
m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||
m_AutoSimulation: 1
|
||||
m_AutoSyncTransforms: 0
|
||||
m_ReuseCollisionCallbacks: 1
|
||||
m_ClothInterCollisionSettingsToggle: 0
|
||||
m_ClothGravity: {x: 0, y: -9.81, z: 0}
|
||||
m_ContactPairsMode: 0
|
||||
m_BroadphaseType: 0
|
||||
m_WorldBounds:
|
||||
m_Center: {x: 0, y: 0, z: 0}
|
||||
m_Extent: {x: 250, y: 250, z: 250}
|
||||
m_WorldSubdivisions: 8
|
||||
m_FrictionType: 0
|
||||
m_EnableEnhancedDeterminism: 0
|
||||
m_EnableUnifiedHeightmaps: 1
|
||||
m_SolverType: 0
|
||||
m_DefaultMaxAngularSpeed: 50
|
||||
@@ -0,0 +1,13 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1045 &1
|
||||
EditorBuildSettings:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 2
|
||||
m_Scenes:
|
||||
- enabled: 1
|
||||
path: Assets/Scenes/SampleScene.unity
|
||||
guid: 2cda990e2423bbf4892e6590ba056729
|
||||
m_configObjects:
|
||||
com.unity.input.settings.actions: {fileID: -944628639613478452, guid: 3590b91b4603b465dbb4216d601bff33, type: 3}
|
||||
m_UseUCBPForAssetBundles: 0
|
||||
@@ -0,0 +1,50 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!159 &1
|
||||
EditorSettings:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 15
|
||||
m_SerializationMode: 2
|
||||
m_LineEndingsForNewScripts: 0
|
||||
m_DefaultBehaviorMode: 1
|
||||
m_PrefabRegularEnvironment: {fileID: 0}
|
||||
m_PrefabUIEnvironment: {fileID: 0}
|
||||
m_SpritePackerMode: 5
|
||||
m_SpritePackerCacheSize: 10
|
||||
m_SpritePackerPaddingPower: 1
|
||||
m_Bc7TextureCompressor: 0
|
||||
m_EtcTextureCompressorBehavior: 1
|
||||
m_EtcTextureFastCompressor: 1
|
||||
m_EtcTextureNormalCompressor: 2
|
||||
m_EtcTextureBestCompressor: 4
|
||||
m_ProjectGenerationIncludedExtensions: txt;xml;fnt;cd;asmdef;asmref;rsp
|
||||
m_ProjectGenerationRootNamespace:
|
||||
m_EnableTextureStreamingInEditMode: 1
|
||||
m_EnableTextureStreamingInPlayMode: 1
|
||||
m_EnableEditorAsyncCPUTextureLoading: 0
|
||||
m_AsyncShaderCompilation: 1
|
||||
m_PrefabModeAllowAutoSave: 1
|
||||
m_EnterPlayModeOptionsEnabled: 1
|
||||
m_EnterPlayModeOptions: 0
|
||||
m_GameObjectNamingDigits: 1
|
||||
m_GameObjectNamingScheme: 0
|
||||
m_AssetNamingUsesSpace: 1
|
||||
m_InspectorUseIMGUIDefaultInspector: 0
|
||||
m_UseLegacyProbeSampleCount: 0
|
||||
m_SerializeInlineMappingsOnOneLine: 1
|
||||
m_DisableCookiesInLightmapper: 1
|
||||
m_ShadowmaskStitching: 0
|
||||
m_AssetPipelineMode: 1
|
||||
m_RefreshImportMode: 0
|
||||
m_CacheServerMode: 0
|
||||
m_CacheServerEndpoint:
|
||||
m_CacheServerNamespacePrefix: default
|
||||
m_CacheServerEnableDownload: 1
|
||||
m_CacheServerEnableUpload: 1
|
||||
m_CacheServerEnableAuth: 0
|
||||
m_CacheServerEnableTls: 0
|
||||
m_CacheServerValidationMode: 2
|
||||
m_CacheServerDownloadBatchSize: 128
|
||||
m_EnableEnlightenBakedGI: 0
|
||||
m_ReferencedClipsExactNaming: 1
|
||||
m_ForceAssetUnloadAndGCOnSceneLoad: 1
|
||||
@@ -0,0 +1,64 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!30 &1
|
||||
GraphicsSettings:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 13
|
||||
m_Deferred:
|
||||
m_Mode: 1
|
||||
m_Shader: {fileID: 69, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_DeferredReflections:
|
||||
m_Mode: 1
|
||||
m_Shader: {fileID: 74, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_ScreenSpaceShadows:
|
||||
m_Mode: 1
|
||||
m_Shader: {fileID: 64, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_LegacyDeferred:
|
||||
m_Mode: 1
|
||||
m_Shader: {fileID: 63, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_DepthNormals:
|
||||
m_Mode: 1
|
||||
m_Shader: {fileID: 62, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_MotionVectors:
|
||||
m_Mode: 1
|
||||
m_Shader: {fileID: 75, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_LightHalo:
|
||||
m_Mode: 1
|
||||
m_Shader: {fileID: 105, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_LensFlare:
|
||||
m_Mode: 1
|
||||
m_Shader: {fileID: 102, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_VideoShadersIncludeMode: 2
|
||||
m_AlwaysIncludedShaders:
|
||||
- {fileID: 7, guid: 0000000000000000f000000000000000, type: 0}
|
||||
- {fileID: 15104, guid: 0000000000000000f000000000000000, type: 0}
|
||||
- {fileID: 15105, guid: 0000000000000000f000000000000000, type: 0}
|
||||
- {fileID: 15106, guid: 0000000000000000f000000000000000, type: 0}
|
||||
- {fileID: 10753, guid: 0000000000000000f000000000000000, type: 0}
|
||||
- {fileID: 10770, guid: 0000000000000000f000000000000000, type: 0}
|
||||
- {fileID: 10783, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_PreloadedShaders: []
|
||||
m_SpritesDefaultMaterial: {fileID: 10754, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_CustomRenderPipeline: {fileID: 0}
|
||||
m_TransparencySortMode: 0
|
||||
m_TransparencySortAxis: {x: 0, y: 0, z: 1}
|
||||
m_DefaultRenderingPath: 1
|
||||
m_DefaultMobileRenderingPath: 1
|
||||
m_TierSettings: []
|
||||
m_LightmapStripping: 0
|
||||
m_FogStripping: 0
|
||||
m_InstancingStripping: 0
|
||||
m_LightmapKeepPlain: 1
|
||||
m_LightmapKeepDirCombined: 1
|
||||
m_LightmapKeepDynamicPlain: 1
|
||||
m_LightmapKeepDynamicDirCombined: 1
|
||||
m_LightmapKeepShadowMask: 1
|
||||
m_LightmapKeepSubtractive: 1
|
||||
m_FogKeepLinear: 1
|
||||
m_FogKeepExp: 1
|
||||
m_FogKeepExp2: 1
|
||||
m_AlbedoSwatchInfos: []
|
||||
m_LightsUseLinearIntensity: 0
|
||||
m_LightsUseColorTemperature: 0
|
||||
m_DefaultRenderingLayerMask: 1
|
||||
m_LogWhenShaderIsCompiled: 0
|
||||
@@ -0,0 +1,487 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!13 &1
|
||||
InputManager:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 2
|
||||
m_Axes:
|
||||
- serializedVersion: 3
|
||||
m_Name: Horizontal
|
||||
descriptiveName:
|
||||
descriptiveNegativeName:
|
||||
negativeButton: left
|
||||
positiveButton: right
|
||||
altNegativeButton: a
|
||||
altPositiveButton: d
|
||||
gravity: 3
|
||||
dead: 0.001
|
||||
sensitivity: 3
|
||||
snap: 1
|
||||
invert: 0
|
||||
type: 0
|
||||
axis: 0
|
||||
joyNum: 0
|
||||
- serializedVersion: 3
|
||||
m_Name: Vertical
|
||||
descriptiveName:
|
||||
descriptiveNegativeName:
|
||||
negativeButton: down
|
||||
positiveButton: up
|
||||
altNegativeButton: s
|
||||
altPositiveButton: w
|
||||
gravity: 3
|
||||
dead: 0.001
|
||||
sensitivity: 3
|
||||
snap: 1
|
||||
invert: 0
|
||||
type: 0
|
||||
axis: 0
|
||||
joyNum: 0
|
||||
- serializedVersion: 3
|
||||
m_Name: Fire1
|
||||
descriptiveName:
|
||||
descriptiveNegativeName:
|
||||
negativeButton:
|
||||
positiveButton: left ctrl
|
||||
altNegativeButton:
|
||||
altPositiveButton: mouse 0
|
||||
gravity: 1000
|
||||
dead: 0.001
|
||||
sensitivity: 1000
|
||||
snap: 0
|
||||
invert: 0
|
||||
type: 0
|
||||
axis: 0
|
||||
joyNum: 0
|
||||
- serializedVersion: 3
|
||||
m_Name: Fire2
|
||||
descriptiveName:
|
||||
descriptiveNegativeName:
|
||||
negativeButton:
|
||||
positiveButton: left alt
|
||||
altNegativeButton:
|
||||
altPositiveButton: mouse 1
|
||||
gravity: 1000
|
||||
dead: 0.001
|
||||
sensitivity: 1000
|
||||
snap: 0
|
||||
invert: 0
|
||||
type: 0
|
||||
axis: 0
|
||||
joyNum: 0
|
||||
- serializedVersion: 3
|
||||
m_Name: Fire3
|
||||
descriptiveName:
|
||||
descriptiveNegativeName:
|
||||
negativeButton:
|
||||
positiveButton: left shift
|
||||
altNegativeButton:
|
||||
altPositiveButton: mouse 2
|
||||
gravity: 1000
|
||||
dead: 0.001
|
||||
sensitivity: 1000
|
||||
snap: 0
|
||||
invert: 0
|
||||
type: 0
|
||||
axis: 0
|
||||
joyNum: 0
|
||||
- serializedVersion: 3
|
||||
m_Name: Jump
|
||||
descriptiveName:
|
||||
descriptiveNegativeName:
|
||||
negativeButton:
|
||||
positiveButton: space
|
||||
altNegativeButton:
|
||||
altPositiveButton:
|
||||
gravity: 1000
|
||||
dead: 0.001
|
||||
sensitivity: 1000
|
||||
snap: 0
|
||||
invert: 0
|
||||
type: 0
|
||||
axis: 0
|
||||
joyNum: 0
|
||||
- serializedVersion: 3
|
||||
m_Name: Mouse X
|
||||
descriptiveName:
|
||||
descriptiveNegativeName:
|
||||
negativeButton:
|
||||
positiveButton:
|
||||
altNegativeButton:
|
||||
altPositiveButton:
|
||||
gravity: 0
|
||||
dead: 0
|
||||
sensitivity: 0.1
|
||||
snap: 0
|
||||
invert: 0
|
||||
type: 1
|
||||
axis: 0
|
||||
joyNum: 0
|
||||
- serializedVersion: 3
|
||||
m_Name: Mouse Y
|
||||
descriptiveName:
|
||||
descriptiveNegativeName:
|
||||
negativeButton:
|
||||
positiveButton:
|
||||
altNegativeButton:
|
||||
altPositiveButton:
|
||||
gravity: 0
|
||||
dead: 0
|
||||
sensitivity: 0.1
|
||||
snap: 0
|
||||
invert: 0
|
||||
type: 1
|
||||
axis: 1
|
||||
joyNum: 0
|
||||
- serializedVersion: 3
|
||||
m_Name: Mouse ScrollWheel
|
||||
descriptiveName:
|
||||
descriptiveNegativeName:
|
||||
negativeButton:
|
||||
positiveButton:
|
||||
altNegativeButton:
|
||||
altPositiveButton:
|
||||
gravity: 0
|
||||
dead: 0
|
||||
sensitivity: 0.1
|
||||
snap: 0
|
||||
invert: 0
|
||||
type: 1
|
||||
axis: 2
|
||||
joyNum: 0
|
||||
- serializedVersion: 3
|
||||
m_Name: Horizontal
|
||||
descriptiveName:
|
||||
descriptiveNegativeName:
|
||||
negativeButton:
|
||||
positiveButton:
|
||||
altNegativeButton:
|
||||
altPositiveButton:
|
||||
gravity: 0
|
||||
dead: 0.19
|
||||
sensitivity: 1
|
||||
snap: 0
|
||||
invert: 0
|
||||
type: 2
|
||||
axis: 0
|
||||
joyNum: 0
|
||||
- serializedVersion: 3
|
||||
m_Name: Vertical
|
||||
descriptiveName:
|
||||
descriptiveNegativeName:
|
||||
negativeButton:
|
||||
positiveButton:
|
||||
altNegativeButton:
|
||||
altPositiveButton:
|
||||
gravity: 0
|
||||
dead: 0.19
|
||||
sensitivity: 1
|
||||
snap: 0
|
||||
invert: 1
|
||||
type: 2
|
||||
axis: 1
|
||||
joyNum: 0
|
||||
- serializedVersion: 3
|
||||
m_Name: Fire1
|
||||
descriptiveName:
|
||||
descriptiveNegativeName:
|
||||
negativeButton:
|
||||
positiveButton: joystick button 0
|
||||
altNegativeButton:
|
||||
altPositiveButton:
|
||||
gravity: 1000
|
||||
dead: 0.001
|
||||
sensitivity: 1000
|
||||
snap: 0
|
||||
invert: 0
|
||||
type: 0
|
||||
axis: 0
|
||||
joyNum: 0
|
||||
- serializedVersion: 3
|
||||
m_Name: Fire2
|
||||
descriptiveName:
|
||||
descriptiveNegativeName:
|
||||
negativeButton:
|
||||
positiveButton: joystick button 1
|
||||
altNegativeButton:
|
||||
altPositiveButton:
|
||||
gravity: 1000
|
||||
dead: 0.001
|
||||
sensitivity: 1000
|
||||
snap: 0
|
||||
invert: 0
|
||||
type: 0
|
||||
axis: 0
|
||||
joyNum: 0
|
||||
- serializedVersion: 3
|
||||
m_Name: Fire3
|
||||
descriptiveName:
|
||||
descriptiveNegativeName:
|
||||
negativeButton:
|
||||
positiveButton: joystick button 2
|
||||
altNegativeButton:
|
||||
altPositiveButton:
|
||||
gravity: 1000
|
||||
dead: 0.001
|
||||
sensitivity: 1000
|
||||
snap: 0
|
||||
invert: 0
|
||||
type: 0
|
||||
axis: 0
|
||||
joyNum: 0
|
||||
- serializedVersion: 3
|
||||
m_Name: Jump
|
||||
descriptiveName:
|
||||
descriptiveNegativeName:
|
||||
negativeButton:
|
||||
positiveButton: joystick button 3
|
||||
altNegativeButton:
|
||||
altPositiveButton:
|
||||
gravity: 1000
|
||||
dead: 0.001
|
||||
sensitivity: 1000
|
||||
snap: 0
|
||||
invert: 0
|
||||
type: 0
|
||||
axis: 0
|
||||
joyNum: 0
|
||||
- serializedVersion: 3
|
||||
m_Name: Submit
|
||||
descriptiveName:
|
||||
descriptiveNegativeName:
|
||||
negativeButton:
|
||||
positiveButton: return
|
||||
altNegativeButton:
|
||||
altPositiveButton: joystick button 0
|
||||
gravity: 1000
|
||||
dead: 0.001
|
||||
sensitivity: 1000
|
||||
snap: 0
|
||||
invert: 0
|
||||
type: 0
|
||||
axis: 0
|
||||
joyNum: 0
|
||||
- serializedVersion: 3
|
||||
m_Name: Submit
|
||||
descriptiveName:
|
||||
descriptiveNegativeName:
|
||||
negativeButton:
|
||||
positiveButton: enter
|
||||
altNegativeButton:
|
||||
altPositiveButton: space
|
||||
gravity: 1000
|
||||
dead: 0.001
|
||||
sensitivity: 1000
|
||||
snap: 0
|
||||
invert: 0
|
||||
type: 0
|
||||
axis: 0
|
||||
joyNum: 0
|
||||
- serializedVersion: 3
|
||||
m_Name: Cancel
|
||||
descriptiveName:
|
||||
descriptiveNegativeName:
|
||||
negativeButton:
|
||||
positiveButton: escape
|
||||
altNegativeButton:
|
||||
altPositiveButton: joystick button 1
|
||||
gravity: 1000
|
||||
dead: 0.001
|
||||
sensitivity: 1000
|
||||
snap: 0
|
||||
invert: 0
|
||||
type: 0
|
||||
axis: 0
|
||||
joyNum: 0
|
||||
- serializedVersion: 3
|
||||
m_Name: Enable Debug Button 1
|
||||
descriptiveName:
|
||||
descriptiveNegativeName:
|
||||
negativeButton:
|
||||
positiveButton: left ctrl
|
||||
altNegativeButton:
|
||||
altPositiveButton: joystick button 8
|
||||
gravity: 0
|
||||
dead: 0
|
||||
sensitivity: 0
|
||||
snap: 0
|
||||
invert: 0
|
||||
type: 0
|
||||
axis: 0
|
||||
joyNum: 0
|
||||
- serializedVersion: 3
|
||||
m_Name: Enable Debug Button 2
|
||||
descriptiveName:
|
||||
descriptiveNegativeName:
|
||||
negativeButton:
|
||||
positiveButton: backspace
|
||||
altNegativeButton:
|
||||
altPositiveButton: joystick button 9
|
||||
gravity: 0
|
||||
dead: 0
|
||||
sensitivity: 0
|
||||
snap: 0
|
||||
invert: 0
|
||||
type: 0
|
||||
axis: 0
|
||||
joyNum: 0
|
||||
- serializedVersion: 3
|
||||
m_Name: Debug Reset
|
||||
descriptiveName:
|
||||
descriptiveNegativeName:
|
||||
negativeButton:
|
||||
positiveButton: left alt
|
||||
altNegativeButton:
|
||||
altPositiveButton: joystick button 1
|
||||
gravity: 0
|
||||
dead: 0
|
||||
sensitivity: 0
|
||||
snap: 0
|
||||
invert: 0
|
||||
type: 0
|
||||
axis: 0
|
||||
joyNum: 0
|
||||
- serializedVersion: 3
|
||||
m_Name: Debug Next
|
||||
descriptiveName:
|
||||
descriptiveNegativeName:
|
||||
negativeButton:
|
||||
positiveButton: page down
|
||||
altNegativeButton:
|
||||
altPositiveButton: joystick button 5
|
||||
gravity: 0
|
||||
dead: 0
|
||||
sensitivity: 0
|
||||
snap: 0
|
||||
invert: 0
|
||||
type: 0
|
||||
axis: 0
|
||||
joyNum: 0
|
||||
- serializedVersion: 3
|
||||
m_Name: Debug Previous
|
||||
descriptiveName:
|
||||
descriptiveNegativeName:
|
||||
negativeButton:
|
||||
positiveButton: page up
|
||||
altNegativeButton:
|
||||
altPositiveButton: joystick button 4
|
||||
gravity: 0
|
||||
dead: 0
|
||||
sensitivity: 0
|
||||
snap: 0
|
||||
invert: 0
|
||||
type: 0
|
||||
axis: 0
|
||||
joyNum: 0
|
||||
- serializedVersion: 3
|
||||
m_Name: Debug Validate
|
||||
descriptiveName:
|
||||
descriptiveNegativeName:
|
||||
negativeButton:
|
||||
positiveButton: return
|
||||
altNegativeButton:
|
||||
altPositiveButton: joystick button 0
|
||||
gravity: 0
|
||||
dead: 0
|
||||
sensitivity: 0
|
||||
snap: 0
|
||||
invert: 0
|
||||
type: 0
|
||||
axis: 0
|
||||
joyNum: 0
|
||||
- serializedVersion: 3
|
||||
m_Name: Debug Persistent
|
||||
descriptiveName:
|
||||
descriptiveNegativeName:
|
||||
negativeButton:
|
||||
positiveButton: right shift
|
||||
altNegativeButton:
|
||||
altPositiveButton: joystick button 2
|
||||
gravity: 0
|
||||
dead: 0
|
||||
sensitivity: 0
|
||||
snap: 0
|
||||
invert: 0
|
||||
type: 0
|
||||
axis: 0
|
||||
joyNum: 0
|
||||
- serializedVersion: 3
|
||||
m_Name: Debug Multiplier
|
||||
descriptiveName:
|
||||
descriptiveNegativeName:
|
||||
negativeButton:
|
||||
positiveButton: left shift
|
||||
altNegativeButton:
|
||||
altPositiveButton: joystick button 3
|
||||
gravity: 0
|
||||
dead: 0
|
||||
sensitivity: 0
|
||||
snap: 0
|
||||
invert: 0
|
||||
type: 0
|
||||
axis: 0
|
||||
joyNum: 0
|
||||
- serializedVersion: 3
|
||||
m_Name: Debug Horizontal
|
||||
descriptiveName:
|
||||
descriptiveNegativeName:
|
||||
negativeButton: left
|
||||
positiveButton: right
|
||||
altNegativeButton:
|
||||
altPositiveButton:
|
||||
gravity: 1000
|
||||
dead: 0.001
|
||||
sensitivity: 1000
|
||||
snap: 0
|
||||
invert: 0
|
||||
type: 0
|
||||
axis: 0
|
||||
joyNum: 0
|
||||
- serializedVersion: 3
|
||||
m_Name: Debug Vertical
|
||||
descriptiveName:
|
||||
descriptiveNegativeName:
|
||||
negativeButton: down
|
||||
positiveButton: up
|
||||
altNegativeButton:
|
||||
altPositiveButton:
|
||||
gravity: 1000
|
||||
dead: 0.001
|
||||
sensitivity: 1000
|
||||
snap: 0
|
||||
invert: 0
|
||||
type: 0
|
||||
axis: 0
|
||||
joyNum: 0
|
||||
- serializedVersion: 3
|
||||
m_Name: Debug Vertical
|
||||
descriptiveName:
|
||||
descriptiveNegativeName:
|
||||
negativeButton: down
|
||||
positiveButton: up
|
||||
altNegativeButton:
|
||||
altPositiveButton:
|
||||
gravity: 1000
|
||||
dead: 0.001
|
||||
sensitivity: 1000
|
||||
snap: 0
|
||||
invert: 0
|
||||
type: 2
|
||||
axis: 6
|
||||
joyNum: 0
|
||||
- serializedVersion: 3
|
||||
m_Name: Debug Horizontal
|
||||
descriptiveName:
|
||||
descriptiveNegativeName:
|
||||
negativeButton: left
|
||||
positiveButton: right
|
||||
altNegativeButton:
|
||||
altPositiveButton:
|
||||
gravity: 1000
|
||||
dead: 0.001
|
||||
sensitivity: 1000
|
||||
snap: 0
|
||||
invert: 0
|
||||
type: 2
|
||||
axis: 5
|
||||
joyNum: 0
|
||||
@@ -0,0 +1,35 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!387306366 &1
|
||||
MemorySettings:
|
||||
m_ObjectHideFlags: 0
|
||||
m_EditorMemorySettings:
|
||||
m_MainAllocatorBlockSize: -1
|
||||
m_ThreadAllocatorBlockSize: -1
|
||||
m_MainGfxBlockSize: -1
|
||||
m_ThreadGfxBlockSize: -1
|
||||
m_CacheBlockSize: -1
|
||||
m_TypetreeBlockSize: -1
|
||||
m_ProfilerBlockSize: -1
|
||||
m_ProfilerEditorBlockSize: -1
|
||||
m_BucketAllocatorGranularity: -1
|
||||
m_BucketAllocatorBucketsCount: -1
|
||||
m_BucketAllocatorBlockSize: -1
|
||||
m_BucketAllocatorBlockCount: -1
|
||||
m_ProfilerBucketAllocatorGranularity: -1
|
||||
m_ProfilerBucketAllocatorBucketsCount: -1
|
||||
m_ProfilerBucketAllocatorBlockSize: -1
|
||||
m_ProfilerBucketAllocatorBlockCount: -1
|
||||
m_TempAllocatorSizeMain: -1
|
||||
m_JobTempAllocatorBlockSize: -1
|
||||
m_BackgroundJobTempAllocatorBlockSize: -1
|
||||
m_JobTempAllocatorReducedBlockSize: -1
|
||||
m_TempAllocatorSizeGIBakingWorker: -1
|
||||
m_TempAllocatorSizeNavMeshWorker: -1
|
||||
m_TempAllocatorSizeAudioWorker: -1
|
||||
m_TempAllocatorSizeCloudWorker: -1
|
||||
m_TempAllocatorSizeGfx: -1
|
||||
m_TempAllocatorSizeJobWorker: -1
|
||||
m_TempAllocatorSizeBackgroundWorker: -1
|
||||
m_TempAllocatorSizePreloadManager: -1
|
||||
m_PlatformMemorySettings: {}
|
||||
@@ -0,0 +1,7 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!655991488 &1
|
||||
MultiplayerManager:
|
||||
m_ObjectHideFlags: 0
|
||||
m_EnableMultiplayerRoles: 0
|
||||
m_StrippingTypes: {}
|
||||
@@ -0,0 +1,93 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!126 &1
|
||||
NavMeshProjectSettings:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 2
|
||||
areas:
|
||||
- name: Walkable
|
||||
cost: 1
|
||||
- name: Not Walkable
|
||||
cost: 1
|
||||
- name: Jump
|
||||
cost: 2
|
||||
- name:
|
||||
cost: 1
|
||||
- name:
|
||||
cost: 1
|
||||
- name:
|
||||
cost: 1
|
||||
- name:
|
||||
cost: 1
|
||||
- name:
|
||||
cost: 1
|
||||
- name:
|
||||
cost: 1
|
||||
- name:
|
||||
cost: 1
|
||||
- name:
|
||||
cost: 1
|
||||
- name:
|
||||
cost: 1
|
||||
- name:
|
||||
cost: 1
|
||||
- name:
|
||||
cost: 1
|
||||
- name:
|
||||
cost: 1
|
||||
- name:
|
||||
cost: 1
|
||||
- name:
|
||||
cost: 1
|
||||
- name:
|
||||
cost: 1
|
||||
- name:
|
||||
cost: 1
|
||||
- name:
|
||||
cost: 1
|
||||
- name:
|
||||
cost: 1
|
||||
- name:
|
||||
cost: 1
|
||||
- name:
|
||||
cost: 1
|
||||
- name:
|
||||
cost: 1
|
||||
- name:
|
||||
cost: 1
|
||||
- name:
|
||||
cost: 1
|
||||
- name:
|
||||
cost: 1
|
||||
- name:
|
||||
cost: 1
|
||||
- name:
|
||||
cost: 1
|
||||
- name:
|
||||
cost: 1
|
||||
- name:
|
||||
cost: 1
|
||||
- name:
|
||||
cost: 1
|
||||
m_LastAgentTypeID: -887442657
|
||||
m_Settings:
|
||||
- serializedVersion: 2
|
||||
agentTypeID: 0
|
||||
agentRadius: 0.5
|
||||
agentHeight: 2
|
||||
agentSlope: 45
|
||||
agentClimb: 0.75
|
||||
ledgeDropHeight: 0
|
||||
maxJumpAcrossDistance: 0
|
||||
minRegionArea: 2
|
||||
manualCellSize: 0
|
||||
cellSize: 0.16666667
|
||||
manualTileSize: 0
|
||||
tileSize: 256
|
||||
accuratePlacement: 0
|
||||
maxJobWorkers: 0
|
||||
preserveTilesOutsideBounds: 0
|
||||
debug:
|
||||
m_Flags: 0
|
||||
m_SettingNames:
|
||||
- Humanoid
|
||||
@@ -0,0 +1,8 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!149 &1
|
||||
NetworkManager:
|
||||
m_ObjectHideFlags: 0
|
||||
m_DebugLevel: 0
|
||||
m_Sendrate: 15
|
||||
m_AssetToPrefab: {}
|
||||
@@ -0,0 +1,44 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!114 &1
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 61
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 13964, guid: 0000000000000000e000000000000000, type: 0}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_EnablePreReleasePackages: 0
|
||||
m_EnablePackageDependencies: 0
|
||||
m_AdvancedSettingsExpanded: 1
|
||||
m_ScopedRegistriesSettingsExpanded: 1
|
||||
m_SeeAllPackageVersions: 0
|
||||
oneTimeWarningShown: 0
|
||||
m_Registries:
|
||||
- m_Id: main
|
||||
m_Name:
|
||||
m_Url: https://packages.unity.com
|
||||
m_Scopes: []
|
||||
m_IsDefault: 1
|
||||
m_Capabilities: 7
|
||||
m_UserSelectedRegistryName:
|
||||
m_UserAddingNewScopedRegistry: 0
|
||||
m_RegistryInfoDraft:
|
||||
m_ErrorMessage:
|
||||
m_Original:
|
||||
m_Id:
|
||||
m_Name:
|
||||
m_Url:
|
||||
m_Scopes: []
|
||||
m_IsDefault: 0
|
||||
m_Capabilities: 0
|
||||
m_Modified: 0
|
||||
m_Name:
|
||||
m_Url:
|
||||
m_Scopes:
|
||||
-
|
||||
m_SelectedScopeIndex: 0
|
||||
@@ -0,0 +1,56 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!19 &1
|
||||
Physics2DSettings:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 5
|
||||
m_Gravity: {x: 0, y: -9.81}
|
||||
m_DefaultMaterial: {fileID: 0}
|
||||
m_VelocityIterations: 8
|
||||
m_PositionIterations: 3
|
||||
m_VelocityThreshold: 1
|
||||
m_MaxLinearCorrection: 0.2
|
||||
m_MaxAngularCorrection: 8
|
||||
m_MaxTranslationSpeed: 100
|
||||
m_MaxRotationSpeed: 360
|
||||
m_BaumgarteScale: 0.2
|
||||
m_BaumgarteTimeOfImpactScale: 0.75
|
||||
m_TimeToSleep: 0.5
|
||||
m_LinearSleepTolerance: 0.01
|
||||
m_AngularSleepTolerance: 2
|
||||
m_DefaultContactOffset: 0.01
|
||||
m_JobOptions:
|
||||
serializedVersion: 2
|
||||
useMultithreading: 0
|
||||
useConsistencySorting: 0
|
||||
m_InterpolationPosesPerJob: 100
|
||||
m_NewContactsPerJob: 30
|
||||
m_CollideContactsPerJob: 100
|
||||
m_ClearFlagsPerJob: 200
|
||||
m_ClearBodyForcesPerJob: 200
|
||||
m_SyncDiscreteFixturesPerJob: 50
|
||||
m_SyncContinuousFixturesPerJob: 50
|
||||
m_FindNearestContactsPerJob: 100
|
||||
m_UpdateTriggerContactsPerJob: 100
|
||||
m_IslandSolverCostThreshold: 100
|
||||
m_IslandSolverBodyCostScale: 1
|
||||
m_IslandSolverContactCostScale: 10
|
||||
m_IslandSolverJointCostScale: 10
|
||||
m_IslandSolverBodiesPerJob: 50
|
||||
m_IslandSolverContactsPerJob: 50
|
||||
m_SimulationMode: 0
|
||||
m_QueriesHitTriggers: 1
|
||||
m_QueriesStartInColliders: 1
|
||||
m_CallbacksOnDisable: 1
|
||||
m_ReuseCollisionCallbacks: 1
|
||||
m_AutoSyncTransforms: 0
|
||||
m_AlwaysShowColliders: 0
|
||||
m_ShowColliderSleep: 1
|
||||
m_ShowColliderContacts: 0
|
||||
m_ShowColliderAABB: 0
|
||||
m_ContactArrowScale: 0.2
|
||||
m_ColliderAwakeColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.7529412}
|
||||
m_ColliderAsleepColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.36078432}
|
||||
m_ColliderContactColor: {r: 1, g: 0, b: 1, a: 0.6862745}
|
||||
m_ColliderAABBColor: {r: 1, g: 1, b: 0, a: 0.2509804}
|
||||
m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||
@@ -0,0 +1,7 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1386491679 &1
|
||||
PresetManager:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 2
|
||||
m_DefaultPresets: {}
|
||||
@@ -0,0 +1,737 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!129 &1
|
||||
PlayerSettings:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 28
|
||||
productGUID: 347ef167e38f44dd4ad3618bb9e1a4f9
|
||||
AndroidProfiler: 0
|
||||
AndroidFilterTouchesWhenObscured: 0
|
||||
AndroidEnableSustainedPerformanceMode: 0
|
||||
defaultScreenOrientation: 4
|
||||
targetDevice: 2
|
||||
useOnDemandResources: 0
|
||||
accelerometerFrequency: 60
|
||||
companyName: DefaultCompany
|
||||
productName: unity
|
||||
defaultCursor: {fileID: 0}
|
||||
cursorHotspot: {x: 0, y: 0}
|
||||
m_SplashScreenBackgroundColor: {r: 0.13725491, g: 0.12156863, b: 0.1254902, a: 1}
|
||||
m_ShowUnitySplashScreen: 1
|
||||
m_ShowUnitySplashLogo: 1
|
||||
m_SplashScreenOverlayOpacity: 1
|
||||
m_SplashScreenAnimation: 1
|
||||
m_SplashScreenLogoStyle: 1
|
||||
m_SplashScreenDrawMode: 0
|
||||
m_SplashScreenBackgroundAnimationZoom: 1
|
||||
m_SplashScreenLogoAnimationZoom: 1
|
||||
m_SplashScreenBackgroundLandscapeAspect: 1
|
||||
m_SplashScreenBackgroundPortraitAspect: 1
|
||||
m_SplashScreenBackgroundLandscapeUvs:
|
||||
serializedVersion: 2
|
||||
x: 0
|
||||
y: 0
|
||||
width: 1
|
||||
height: 1
|
||||
m_SplashScreenBackgroundPortraitUvs:
|
||||
serializedVersion: 2
|
||||
x: 0
|
||||
y: 0
|
||||
width: 1
|
||||
height: 1
|
||||
m_SplashScreenLogos: []
|
||||
m_VirtualRealitySplashScreen: {fileID: 0}
|
||||
m_HolographicTrackingLossScreen: {fileID: 0}
|
||||
defaultScreenWidth: 1920
|
||||
defaultScreenHeight: 1080
|
||||
defaultScreenWidthWeb: 960
|
||||
defaultScreenHeightWeb: 600
|
||||
m_StereoRenderingPath: 0
|
||||
m_ActiveColorSpace: 1
|
||||
unsupportedMSAAFallback: 0
|
||||
m_SpriteBatchMaxVertexCount: 65535
|
||||
m_SpriteBatchVertexThreshold: 300
|
||||
m_MTRendering: 1
|
||||
mipStripping: 0
|
||||
numberOfMipsStripped: 0
|
||||
numberOfMipsStrippedPerMipmapLimitGroup: {}
|
||||
m_StackTraceTypes: 010000000100000001000000010000000100000001000000
|
||||
iosShowActivityIndicatorOnLoading: -1
|
||||
androidShowActivityIndicatorOnLoading: -1
|
||||
iosUseCustomAppBackgroundBehavior: 0
|
||||
allowedAutorotateToPortrait: 1
|
||||
allowedAutorotateToPortraitUpsideDown: 1
|
||||
allowedAutorotateToLandscapeRight: 1
|
||||
allowedAutorotateToLandscapeLeft: 1
|
||||
useOSAutorotation: 1
|
||||
use32BitDisplayBuffer: 1
|
||||
preserveFramebufferAlpha: 0
|
||||
disableDepthAndStencilBuffers: 0
|
||||
androidStartInFullscreen: 1
|
||||
androidRenderOutsideSafeArea: 1
|
||||
androidUseSwappy: 1
|
||||
androidDisplayOptions: 1
|
||||
androidBlitType: 0
|
||||
androidResizeableActivity: 1
|
||||
androidDefaultWindowWidth: 1920
|
||||
androidDefaultWindowHeight: 1080
|
||||
androidMinimumWindowWidth: 400
|
||||
androidMinimumWindowHeight: 300
|
||||
androidFullscreenMode: 1
|
||||
androidAutoRotationBehavior: 1
|
||||
androidPredictiveBackSupport: 0
|
||||
androidApplicationEntry: 2
|
||||
defaultIsNativeResolution: 1
|
||||
macRetinaSupport: 1
|
||||
runInBackground: 0
|
||||
muteOtherAudioSources: 0
|
||||
Prepare IOS For Recording: 0
|
||||
Force IOS Speakers When Recording: 0
|
||||
audioSpatialExperience: 0
|
||||
deferSystemGesturesMode: 0
|
||||
hideHomeButton: 0
|
||||
submitAnalytics: 1
|
||||
usePlayerLog: 1
|
||||
dedicatedServerOptimizations: 1
|
||||
bakeCollisionMeshes: 0
|
||||
forceSingleInstance: 0
|
||||
useFlipModelSwapchain: 1
|
||||
resizableWindow: 0
|
||||
useMacAppStoreValidation: 0
|
||||
macAppStoreCategory: public.app-category.games
|
||||
gpuSkinning: 0
|
||||
meshDeformation: 0
|
||||
xboxPIXTextureCapture: 0
|
||||
xboxEnableAvatar: 0
|
||||
xboxEnableKinect: 0
|
||||
xboxEnableKinectAutoTracking: 0
|
||||
xboxEnableFitness: 0
|
||||
visibleInBackground: 1
|
||||
allowFullscreenSwitch: 1
|
||||
fullscreenMode: 1
|
||||
xboxSpeechDB: 0
|
||||
xboxEnableHeadOrientation: 0
|
||||
xboxEnableGuest: 0
|
||||
xboxEnablePIXSampling: 0
|
||||
metalFramebufferOnly: 0
|
||||
metalUseMetalDisplayLink: 0
|
||||
xboxOneResolution: 0
|
||||
xboxOneSResolution: 0
|
||||
xboxOneXResolution: 3
|
||||
xboxOneMonoLoggingLevel: 0
|
||||
xboxOneLoggingLevel: 1
|
||||
xboxOneDisableEsram: 0
|
||||
xboxOneEnableTypeOptimization: 0
|
||||
xboxOnePresentImmediateThreshold: 0
|
||||
switchQueueCommandMemory: 1048576
|
||||
switchQueueControlMemory: 16384
|
||||
switchQueueComputeMemory: 262144
|
||||
switchNVNShaderPoolsGranularity: 33554432
|
||||
switchNVNDefaultPoolsGranularity: 16777216
|
||||
switchNVNOtherPoolsGranularity: 16777216
|
||||
switchGpuScratchPoolGranularity: 2097152
|
||||
switchAllowGpuScratchShrinking: 0
|
||||
switchNVNMaxPublicTextureIDCount: 0
|
||||
switchNVNMaxPublicSamplerIDCount: 0
|
||||
switchMaxWorkerMultiple: 8
|
||||
switchNVNGraphicsFirmwareMemory: 32
|
||||
switchGraphicsJobsSyncAfterKick: 1
|
||||
vulkanNumSwapchainBuffers: 3
|
||||
vulkanEnableSetSRGBWrite: 0
|
||||
vulkanEnablePreTransform: 0
|
||||
vulkanEnableLateAcquireNextImage: 0
|
||||
vulkanEnableCommandBufferRecycling: 1
|
||||
loadStoreDebugModeEnabled: 0
|
||||
visionOSBundleVersion: 1.0
|
||||
tvOSBundleVersion: 1.0
|
||||
bundleVersion: 1.0
|
||||
preloadedAssets: []
|
||||
metroInputSource: 0
|
||||
wsaTransparentSwapchain: 0
|
||||
m_HolographicPauseOnTrackingLoss: 1
|
||||
xboxOneDisableKinectGpuReservation: 1
|
||||
xboxOneEnable7thCore: 1
|
||||
vrSettings:
|
||||
enable360StereoCapture: 0
|
||||
isWsaHolographicRemotingEnabled: 0
|
||||
enableFrameTimingStats: 0
|
||||
enableOpenGLProfilerGPURecorders: 1
|
||||
allowHDRDisplaySupport: 0
|
||||
useHDRDisplay: 0
|
||||
hdrBitDepth: 0
|
||||
m_ColorGamuts: 00000000
|
||||
targetPixelDensity: 30
|
||||
resolutionScalingMode: 0
|
||||
resetResolutionOnWindowResize: 0
|
||||
androidSupportedAspectRatio: 1
|
||||
androidMaxAspectRatio: 2.4
|
||||
androidMinAspectRatio: 1
|
||||
applicationIdentifier:
|
||||
Standalone: com.DefaultCompany.2D-Project
|
||||
buildNumber:
|
||||
Standalone: 0
|
||||
VisionOS: 0
|
||||
iPhone: 0
|
||||
tvOS: 0
|
||||
overrideDefaultApplicationIdentifier: 1
|
||||
AndroidBundleVersionCode: 1
|
||||
AndroidMinSdkVersion: 25
|
||||
AndroidTargetSdkVersion: 0
|
||||
AndroidPreferredInstallLocation: 1
|
||||
AndroidPreferredDataLocation: 1
|
||||
aotOptions:
|
||||
stripEngineCode: 1
|
||||
iPhoneStrippingLevel: 0
|
||||
iPhoneScriptCallOptimization: 0
|
||||
ForceInternetPermission: 0
|
||||
ForceSDCardPermission: 0
|
||||
CreateWallpaper: 0
|
||||
androidSplitApplicationBinary: 0
|
||||
keepLoadedShadersAlive: 0
|
||||
StripUnusedMeshComponents: 0
|
||||
strictShaderVariantMatching: 0
|
||||
VertexChannelCompressionMask: 4054
|
||||
iPhoneSdkVersion: 988
|
||||
iOSSimulatorArchitecture: 0
|
||||
iOSTargetOSVersionString: 15.0
|
||||
tvOSSdkVersion: 0
|
||||
tvOSSimulatorArchitecture: 0
|
||||
tvOSRequireExtendedGameController: 0
|
||||
tvOSTargetOSVersionString: 15.0
|
||||
VisionOSSdkVersion: 0
|
||||
VisionOSTargetOSVersionString: 1.0
|
||||
uIPrerenderedIcon: 0
|
||||
uIRequiresPersistentWiFi: 0
|
||||
uIRequiresFullScreen: 1
|
||||
uIStatusBarHidden: 1
|
||||
uIExitOnSuspend: 0
|
||||
uIStatusBarStyle: 0
|
||||
appleTVSplashScreen: {fileID: 0}
|
||||
appleTVSplashScreen2x: {fileID: 0}
|
||||
tvOSSmallIconLayers: []
|
||||
tvOSSmallIconLayers2x: []
|
||||
tvOSLargeIconLayers: []
|
||||
tvOSLargeIconLayers2x: []
|
||||
tvOSTopShelfImageLayers: []
|
||||
tvOSTopShelfImageLayers2x: []
|
||||
tvOSTopShelfImageWideLayers: []
|
||||
tvOSTopShelfImageWideLayers2x: []
|
||||
iOSLaunchScreenType: 0
|
||||
iOSLaunchScreenPortrait: {fileID: 0}
|
||||
iOSLaunchScreenLandscape: {fileID: 0}
|
||||
iOSLaunchScreenBackgroundColor:
|
||||
serializedVersion: 2
|
||||
rgba: 0
|
||||
iOSLaunchScreenFillPct: 100
|
||||
iOSLaunchScreenSize: 100
|
||||
iOSLaunchScreeniPadType: 0
|
||||
iOSLaunchScreeniPadImage: {fileID: 0}
|
||||
iOSLaunchScreeniPadBackgroundColor:
|
||||
serializedVersion: 2
|
||||
rgba: 0
|
||||
iOSLaunchScreeniPadFillPct: 100
|
||||
iOSLaunchScreeniPadSize: 100
|
||||
iOSLaunchScreenCustomStoryboardPath:
|
||||
iOSLaunchScreeniPadCustomStoryboardPath:
|
||||
iOSDeviceRequirements: []
|
||||
iOSURLSchemes: []
|
||||
macOSURLSchemes: []
|
||||
iOSBackgroundModes: 0
|
||||
iOSMetalForceHardShadows: 0
|
||||
metalEditorSupport: 1
|
||||
metalAPIValidation: 1
|
||||
metalCompileShaderBinary: 0
|
||||
iOSRenderExtraFrameOnPause: 0
|
||||
iosCopyPluginsCodeInsteadOfSymlink: 0
|
||||
appleDeveloperTeamID:
|
||||
iOSManualSigningProvisioningProfileID:
|
||||
tvOSManualSigningProvisioningProfileID:
|
||||
VisionOSManualSigningProvisioningProfileID:
|
||||
iOSManualSigningProvisioningProfileType: 0
|
||||
tvOSManualSigningProvisioningProfileType: 0
|
||||
VisionOSManualSigningProvisioningProfileType: 0
|
||||
appleEnableAutomaticSigning: 0
|
||||
iOSRequireARKit: 0
|
||||
iOSAutomaticallyDetectAndAddCapabilities: 1
|
||||
appleEnableProMotion: 0
|
||||
shaderPrecisionModel: 0
|
||||
clonedFromGUID: 10ad67313f4034357812315f3c407484
|
||||
templatePackageId: com.unity.template.2d@11.0.0
|
||||
templateDefaultScene: Assets/Scenes/SampleScene.unity
|
||||
useCustomMainManifest: 0
|
||||
useCustomLauncherManifest: 0
|
||||
useCustomMainGradleTemplate: 0
|
||||
useCustomLauncherGradleManifest: 0
|
||||
useCustomBaseGradleTemplate: 0
|
||||
useCustomGradlePropertiesTemplate: 0
|
||||
useCustomGradleSettingsTemplate: 0
|
||||
useCustomProguardFile: 0
|
||||
AndroidTargetArchitectures: 2
|
||||
AndroidAllowedArchitectures: -13
|
||||
AndroidSplashScreenScale: 0
|
||||
androidSplashScreen: {fileID: 0}
|
||||
AndroidKeystoreName:
|
||||
AndroidKeyaliasName:
|
||||
AndroidEnableArmv9SecurityFeatures: 0
|
||||
AndroidEnableArm64MTE: 0
|
||||
AndroidBuildApkPerCpuArchitecture: 0
|
||||
AndroidTVCompatibility: 0
|
||||
AndroidIsGame: 1
|
||||
androidAppCategory: 3
|
||||
useAndroidAppCategory: 1
|
||||
androidAppCategoryOther:
|
||||
AndroidEnableTango: 0
|
||||
androidEnableBanner: 1
|
||||
androidUseLowAccuracyLocation: 0
|
||||
androidUseCustomKeystore: 0
|
||||
m_AndroidBanners:
|
||||
- width: 320
|
||||
height: 180
|
||||
banner: {fileID: 0}
|
||||
androidGamepadSupportLevel: 0
|
||||
AndroidMinifyRelease: 0
|
||||
AndroidMinifyDebug: 0
|
||||
AndroidValidateAppBundleSize: 1
|
||||
AndroidAppBundleSizeToValidate: 150
|
||||
AndroidReportGooglePlayAppDependencies: 1
|
||||
androidSymbolsSizeThreshold: 800
|
||||
m_BuildTargetIcons: []
|
||||
m_BuildTargetPlatformIcons: []
|
||||
m_BuildTargetBatching: []
|
||||
m_BuildTargetShaderSettings: []
|
||||
m_BuildTargetGraphicsJobs:
|
||||
- m_BuildTarget: MacStandaloneSupport
|
||||
m_GraphicsJobs: 0
|
||||
- m_BuildTarget: Switch
|
||||
m_GraphicsJobs: 0
|
||||
- m_BuildTarget: MetroSupport
|
||||
m_GraphicsJobs: 0
|
||||
- m_BuildTarget: AppleTVSupport
|
||||
m_GraphicsJobs: 0
|
||||
- m_BuildTarget: BJMSupport
|
||||
m_GraphicsJobs: 0
|
||||
- m_BuildTarget: LinuxStandaloneSupport
|
||||
m_GraphicsJobs: 0
|
||||
- m_BuildTarget: PS4Player
|
||||
m_GraphicsJobs: 0
|
||||
- m_BuildTarget: iOSSupport
|
||||
m_GraphicsJobs: 0
|
||||
- m_BuildTarget: WindowsStandaloneSupport
|
||||
m_GraphicsJobs: 0
|
||||
- m_BuildTarget: XboxOnePlayer
|
||||
m_GraphicsJobs: 0
|
||||
- m_BuildTarget: LuminSupport
|
||||
m_GraphicsJobs: 0
|
||||
- m_BuildTarget: AndroidPlayer
|
||||
m_GraphicsJobs: 0
|
||||
- m_BuildTarget: WebGLSupport
|
||||
m_GraphicsJobs: 0
|
||||
m_BuildTargetGraphicsJobMode: []
|
||||
m_BuildTargetGraphicsAPIs:
|
||||
- m_BuildTarget: AndroidPlayer
|
||||
m_APIs: 150000000b000000
|
||||
m_Automatic: 1
|
||||
- m_BuildTarget: iOSSupport
|
||||
m_APIs: 10000000
|
||||
m_Automatic: 1
|
||||
m_BuildTargetVRSettings: []
|
||||
m_DefaultShaderChunkSizeInMB: 16
|
||||
m_DefaultShaderChunkCount: 0
|
||||
openGLRequireES31: 0
|
||||
openGLRequireES31AEP: 0
|
||||
openGLRequireES32: 0
|
||||
m_TemplateCustomTags: {}
|
||||
mobileMTRendering:
|
||||
Android: 1
|
||||
iPhone: 1
|
||||
tvOS: 1
|
||||
m_BuildTargetGroupLightmapEncodingQuality: []
|
||||
m_BuildTargetGroupHDRCubemapEncodingQuality: []
|
||||
m_BuildTargetGroupLightmapSettings: []
|
||||
m_BuildTargetGroupLoadStoreDebugModeSettings: []
|
||||
m_BuildTargetNormalMapEncoding: []
|
||||
m_BuildTargetDefaultTextureCompressionFormat:
|
||||
- serializedVersion: 3
|
||||
m_BuildTarget: Android
|
||||
m_Formats: 03000000
|
||||
playModeTestRunnerEnabled: 0
|
||||
runPlayModeTestAsEditModeTest: 0
|
||||
actionOnDotNetUnhandledException: 1
|
||||
editorGfxJobOverride: 1
|
||||
enableInternalProfiler: 0
|
||||
logObjCUncaughtExceptions: 1
|
||||
enableCrashReportAPI: 0
|
||||
cameraUsageDescription:
|
||||
locationUsageDescription:
|
||||
microphoneUsageDescription:
|
||||
bluetoothUsageDescription:
|
||||
macOSTargetOSVersion: 12.0
|
||||
switchNMETAOverride:
|
||||
switchNetLibKey:
|
||||
switchSocketMemoryPoolSize: 6144
|
||||
switchSocketAllocatorPoolSize: 128
|
||||
switchSocketConcurrencyLimit: 14
|
||||
switchScreenResolutionBehavior: 2
|
||||
switchUseCPUProfiler: 0
|
||||
switchEnableFileSystemTrace: 0
|
||||
switchLTOSetting: 0
|
||||
switchApplicationID: 0x01004b9000490000
|
||||
switchNSODependencies:
|
||||
switchCompilerFlags:
|
||||
switchTitleNames_0:
|
||||
switchTitleNames_1:
|
||||
switchTitleNames_2:
|
||||
switchTitleNames_3:
|
||||
switchTitleNames_4:
|
||||
switchTitleNames_5:
|
||||
switchTitleNames_6:
|
||||
switchTitleNames_7:
|
||||
switchTitleNames_8:
|
||||
switchTitleNames_9:
|
||||
switchTitleNames_10:
|
||||
switchTitleNames_11:
|
||||
switchTitleNames_12:
|
||||
switchTitleNames_13:
|
||||
switchTitleNames_14:
|
||||
switchTitleNames_15:
|
||||
switchPublisherNames_0:
|
||||
switchPublisherNames_1:
|
||||
switchPublisherNames_2:
|
||||
switchPublisherNames_3:
|
||||
switchPublisherNames_4:
|
||||
switchPublisherNames_5:
|
||||
switchPublisherNames_6:
|
||||
switchPublisherNames_7:
|
||||
switchPublisherNames_8:
|
||||
switchPublisherNames_9:
|
||||
switchPublisherNames_10:
|
||||
switchPublisherNames_11:
|
||||
switchPublisherNames_12:
|
||||
switchPublisherNames_13:
|
||||
switchPublisherNames_14:
|
||||
switchPublisherNames_15:
|
||||
switchIcons_0: {fileID: 0}
|
||||
switchIcons_1: {fileID: 0}
|
||||
switchIcons_2: {fileID: 0}
|
||||
switchIcons_3: {fileID: 0}
|
||||
switchIcons_4: {fileID: 0}
|
||||
switchIcons_5: {fileID: 0}
|
||||
switchIcons_6: {fileID: 0}
|
||||
switchIcons_7: {fileID: 0}
|
||||
switchIcons_8: {fileID: 0}
|
||||
switchIcons_9: {fileID: 0}
|
||||
switchIcons_10: {fileID: 0}
|
||||
switchIcons_11: {fileID: 0}
|
||||
switchIcons_12: {fileID: 0}
|
||||
switchIcons_13: {fileID: 0}
|
||||
switchIcons_14: {fileID: 0}
|
||||
switchIcons_15: {fileID: 0}
|
||||
switchSmallIcons_0: {fileID: 0}
|
||||
switchSmallIcons_1: {fileID: 0}
|
||||
switchSmallIcons_2: {fileID: 0}
|
||||
switchSmallIcons_3: {fileID: 0}
|
||||
switchSmallIcons_4: {fileID: 0}
|
||||
switchSmallIcons_5: {fileID: 0}
|
||||
switchSmallIcons_6: {fileID: 0}
|
||||
switchSmallIcons_7: {fileID: 0}
|
||||
switchSmallIcons_8: {fileID: 0}
|
||||
switchSmallIcons_9: {fileID: 0}
|
||||
switchSmallIcons_10: {fileID: 0}
|
||||
switchSmallIcons_11: {fileID: 0}
|
||||
switchSmallIcons_12: {fileID: 0}
|
||||
switchSmallIcons_13: {fileID: 0}
|
||||
switchSmallIcons_14: {fileID: 0}
|
||||
switchSmallIcons_15: {fileID: 0}
|
||||
switchManualHTML:
|
||||
switchAccessibleURLs:
|
||||
switchLegalInformation:
|
||||
switchMainThreadStackSize: 1048576
|
||||
switchPresenceGroupId:
|
||||
switchLogoHandling: 0
|
||||
switchReleaseVersion: 0
|
||||
switchDisplayVersion: 1.0.0
|
||||
switchStartupUserAccount: 0
|
||||
switchSupportedLanguagesMask: 0
|
||||
switchLogoType: 0
|
||||
switchApplicationErrorCodeCategory:
|
||||
switchUserAccountSaveDataSize: 0
|
||||
switchUserAccountSaveDataJournalSize: 0
|
||||
switchApplicationAttribute: 0
|
||||
switchCardSpecSize: -1
|
||||
switchCardSpecClock: -1
|
||||
switchRatingsMask: 0
|
||||
switchRatingsInt_0: 0
|
||||
switchRatingsInt_1: 0
|
||||
switchRatingsInt_2: 0
|
||||
switchRatingsInt_3: 0
|
||||
switchRatingsInt_4: 0
|
||||
switchRatingsInt_5: 0
|
||||
switchRatingsInt_6: 0
|
||||
switchRatingsInt_7: 0
|
||||
switchRatingsInt_8: 0
|
||||
switchRatingsInt_9: 0
|
||||
switchRatingsInt_10: 0
|
||||
switchRatingsInt_11: 0
|
||||
switchRatingsInt_12: 0
|
||||
switchLocalCommunicationIds_0:
|
||||
switchLocalCommunicationIds_1:
|
||||
switchLocalCommunicationIds_2:
|
||||
switchLocalCommunicationIds_3:
|
||||
switchLocalCommunicationIds_4:
|
||||
switchLocalCommunicationIds_5:
|
||||
switchLocalCommunicationIds_6:
|
||||
switchLocalCommunicationIds_7:
|
||||
switchParentalControl: 0
|
||||
switchAllowsScreenshot: 1
|
||||
switchAllowsVideoCapturing: 1
|
||||
switchAllowsRuntimeAddOnContentInstall: 0
|
||||
switchDataLossConfirmation: 0
|
||||
switchUserAccountLockEnabled: 0
|
||||
switchSystemResourceMemory: 16777216
|
||||
switchSupportedNpadStyles: 22
|
||||
switchNativeFsCacheSize: 32
|
||||
switchIsHoldTypeHorizontal: 0
|
||||
switchSupportedNpadCount: 8
|
||||
switchEnableTouchScreen: 1
|
||||
switchSocketConfigEnabled: 0
|
||||
switchTcpInitialSendBufferSize: 32
|
||||
switchTcpInitialReceiveBufferSize: 64
|
||||
switchTcpAutoSendBufferSizeMax: 256
|
||||
switchTcpAutoReceiveBufferSizeMax: 256
|
||||
switchUdpSendBufferSize: 9
|
||||
switchUdpReceiveBufferSize: 42
|
||||
switchSocketBufferEfficiency: 4
|
||||
switchSocketInitializeEnabled: 1
|
||||
switchNetworkInterfaceManagerInitializeEnabled: 1
|
||||
switchDisableHTCSPlayerConnection: 0
|
||||
switchUseNewStyleFilepaths: 0
|
||||
switchUseLegacyFmodPriorities: 0
|
||||
switchUseMicroSleepForYield: 1
|
||||
switchEnableRamDiskSupport: 0
|
||||
switchMicroSleepForYieldTime: 25
|
||||
switchRamDiskSpaceSize: 12
|
||||
switchUpgradedPlayerSettingsToNMETA: 0
|
||||
ps4NPAgeRating: 12
|
||||
ps4NPTitleSecret:
|
||||
ps4NPTrophyPackPath:
|
||||
ps4ParentalLevel: 11
|
||||
ps4ContentID: ED1633-NPXX51362_00-0000000000000000
|
||||
ps4Category: 0
|
||||
ps4MasterVersion: 01.00
|
||||
ps4AppVersion: 01.00
|
||||
ps4AppType: 0
|
||||
ps4ParamSfxPath:
|
||||
ps4VideoOutPixelFormat: 0
|
||||
ps4VideoOutInitialWidth: 1920
|
||||
ps4VideoOutBaseModeInitialWidth: 1920
|
||||
ps4VideoOutReprojectionRate: 60
|
||||
ps4PronunciationXMLPath:
|
||||
ps4PronunciationSIGPath:
|
||||
ps4BackgroundImagePath:
|
||||
ps4StartupImagePath:
|
||||
ps4StartupImagesFolder:
|
||||
ps4IconImagesFolder:
|
||||
ps4SaveDataImagePath:
|
||||
ps4SdkOverride:
|
||||
ps4BGMPath:
|
||||
ps4ShareFilePath:
|
||||
ps4ShareOverlayImagePath:
|
||||
ps4PrivacyGuardImagePath:
|
||||
ps4ExtraSceSysFile:
|
||||
ps4NPtitleDatPath:
|
||||
ps4RemotePlayKeyAssignment: -1
|
||||
ps4RemotePlayKeyMappingDir:
|
||||
ps4PlayTogetherPlayerCount: 0
|
||||
ps4EnterButtonAssignment: 2
|
||||
ps4ApplicationParam1: 0
|
||||
ps4ApplicationParam2: 0
|
||||
ps4ApplicationParam3: 0
|
||||
ps4ApplicationParam4: 0
|
||||
ps4DownloadDataSize: 0
|
||||
ps4GarlicHeapSize: 2048
|
||||
ps4ProGarlicHeapSize: 2560
|
||||
playerPrefsMaxSize: 32768
|
||||
ps4Passcode: ARLRRL59bcfuU0C9AGuPDYRMsZlDaGMq
|
||||
ps4pnSessions: 1
|
||||
ps4pnPresence: 1
|
||||
ps4pnFriends: 1
|
||||
ps4pnGameCustomData: 1
|
||||
playerPrefsSupport: 0
|
||||
enableApplicationExit: 0
|
||||
resetTempFolder: 1
|
||||
restrictedAudioUsageRights: 0
|
||||
ps4UseResolutionFallback: 0
|
||||
ps4ReprojectionSupport: 0
|
||||
ps4UseAudio3dBackend: 0
|
||||
ps4UseLowGarlicFragmentationMode: 1
|
||||
ps4SocialScreenEnabled: 0
|
||||
ps4ScriptOptimizationLevel: 2
|
||||
ps4Audio3dVirtualSpeakerCount: 14
|
||||
ps4attribCpuUsage: 0
|
||||
ps4PatchPkgPath:
|
||||
ps4PatchLatestPkgPath:
|
||||
ps4PatchChangeinfoPath:
|
||||
ps4PatchDayOne: 0
|
||||
ps4attribUserManagement: 0
|
||||
ps4attribMoveSupport: 0
|
||||
ps4attrib3DSupport: 0
|
||||
ps4attribShareSupport: 0
|
||||
ps4attribExclusiveVR: 0
|
||||
ps4disableAutoHideSplash: 0
|
||||
ps4videoRecordingFeaturesUsed: 0
|
||||
ps4contentSearchFeaturesUsed: 0
|
||||
ps4CompatibilityPS5: 0
|
||||
ps4AllowPS5Detection: 0
|
||||
ps4GPU800MHz: 1
|
||||
ps4attribEyeToEyeDistanceSettingVR: 0
|
||||
ps4IncludedModules: []
|
||||
ps4attribVROutputEnabled: 0
|
||||
monoEnv:
|
||||
splashScreenBackgroundSourceLandscape: {fileID: 0}
|
||||
splashScreenBackgroundSourcePortrait: {fileID: 0}
|
||||
blurSplashScreenBackground: 1
|
||||
spritePackerPolicy:
|
||||
webGLMemorySize: 32
|
||||
webGLExceptionSupport: 1
|
||||
webGLNameFilesAsHashes: 0
|
||||
webGLShowDiagnostics: 0
|
||||
webGLDataCaching: 1
|
||||
webGLDebugSymbols: 0
|
||||
webGLEmscriptenArgs:
|
||||
webGLModulesDirectory:
|
||||
webGLTemplate: APPLICATION:Default
|
||||
webGLAnalyzeBuildSize: 0
|
||||
webGLUseEmbeddedResources: 0
|
||||
webGLCompressionFormat: 0
|
||||
webGLWasmArithmeticExceptions: 0
|
||||
webGLLinkerTarget: 1
|
||||
webGLThreadsSupport: 0
|
||||
webGLDecompressionFallback: 0
|
||||
webGLInitialMemorySize: 32
|
||||
webGLMaximumMemorySize: 2048
|
||||
webGLMemoryGrowthMode: 2
|
||||
webGLMemoryLinearGrowthStep: 16
|
||||
webGLMemoryGeometricGrowthStep: 0.2
|
||||
webGLMemoryGeometricGrowthCap: 96
|
||||
webGLPowerPreference: 2
|
||||
webGLWebAssemblyTable: 0
|
||||
webGLWebAssemblyBigInt: 0
|
||||
webGLCloseOnQuit: 0
|
||||
webWasm2023: 0
|
||||
webEnableSubmoduleStrippingCompatibility: 0
|
||||
scriptingDefineSymbols: {}
|
||||
additionalCompilerArguments: {}
|
||||
platformArchitecture: {}
|
||||
scriptingBackend:
|
||||
Android: 1
|
||||
Standalone: 1
|
||||
il2cppCompilerConfiguration: {}
|
||||
il2cppCodeGeneration: {}
|
||||
il2cppStacktraceInformation: {}
|
||||
managedStrippingLevel: {}
|
||||
incrementalIl2cppBuild: {}
|
||||
suppressCommonWarnings: 1
|
||||
allowUnsafeCode: 0
|
||||
useDeterministicCompilation: 1
|
||||
additionalIl2CppArgs:
|
||||
scriptingRuntimeVersion: 1
|
||||
gcIncremental: 1
|
||||
gcWBarrierValidation: 0
|
||||
apiCompatibilityLevelPerPlatform: {}
|
||||
editorAssembliesCompatibilityLevel: 1
|
||||
m_RenderingPath: 1
|
||||
m_MobileRenderingPath: 1
|
||||
metroPackageName: unity
|
||||
metroPackageVersion:
|
||||
metroCertificatePath:
|
||||
metroCertificatePassword:
|
||||
metroCertificateSubject:
|
||||
metroCertificateIssuer:
|
||||
metroCertificateNotAfter: 0000000000000000
|
||||
metroApplicationDescription: unity
|
||||
wsaImages: {}
|
||||
metroTileShortName:
|
||||
metroTileShowName: 0
|
||||
metroMediumTileShowName: 0
|
||||
metroLargeTileShowName: 0
|
||||
metroWideTileShowName: 0
|
||||
metroSupportStreamingInstall: 0
|
||||
metroLastRequiredScene: 0
|
||||
metroDefaultTileSize: 1
|
||||
metroTileForegroundText: 2
|
||||
metroTileBackgroundColor: {r: 0.13333334, g: 0.17254902, b: 0.21568628, a: 0}
|
||||
metroSplashScreenBackgroundColor: {r: 0.12941177, g: 0.17254902, b: 0.21568628, a: 1}
|
||||
metroSplashScreenUseBackgroundColor: 0
|
||||
syncCapabilities: 0
|
||||
platformCapabilities: {}
|
||||
metroTargetDeviceFamilies: {}
|
||||
metroFTAName:
|
||||
metroFTAFileTypes: []
|
||||
metroProtocolName:
|
||||
vcxProjDefaultLanguage:
|
||||
XboxOneProductId:
|
||||
XboxOneUpdateKey:
|
||||
XboxOneSandboxId:
|
||||
XboxOneContentId:
|
||||
XboxOneTitleId:
|
||||
XboxOneSCId:
|
||||
XboxOneGameOsOverridePath:
|
||||
XboxOnePackagingOverridePath:
|
||||
XboxOneAppManifestOverridePath:
|
||||
XboxOneVersion: 1.0.0.0
|
||||
XboxOnePackageEncryption: 0
|
||||
XboxOnePackageUpdateGranularity: 2
|
||||
XboxOneDescription:
|
||||
XboxOneLanguage:
|
||||
- enus
|
||||
XboxOneCapability: []
|
||||
XboxOneGameRating: {}
|
||||
XboxOneIsContentPackage: 0
|
||||
XboxOneEnhancedXboxCompatibilityMode: 0
|
||||
XboxOneEnableGPUVariability: 1
|
||||
XboxOneSockets: {}
|
||||
XboxOneSplashScreen: {fileID: 0}
|
||||
XboxOneAllowedProductIds: []
|
||||
XboxOnePersistentLocalStorageSize: 0
|
||||
XboxOneXTitleMemory: 8
|
||||
XboxOneOverrideIdentityName:
|
||||
XboxOneOverrideIdentityPublisher:
|
||||
vrEditorSettings: {}
|
||||
cloudServicesEnabled: {}
|
||||
luminIcon:
|
||||
m_Name:
|
||||
m_ModelFolderPath:
|
||||
m_PortalFolderPath:
|
||||
luminCert:
|
||||
m_CertPath:
|
||||
m_SignPackage: 1
|
||||
luminIsChannelApp: 0
|
||||
luminVersion:
|
||||
m_VersionCode: 1
|
||||
m_VersionName:
|
||||
hmiPlayerDataPath:
|
||||
hmiForceSRGBBlit: 0
|
||||
embeddedLinuxEnableGamepadInput: 0
|
||||
hmiCpuConfiguration:
|
||||
hmiLogStartupTiming: 0
|
||||
qnxGraphicConfPath:
|
||||
apiCompatibilityLevel: 6
|
||||
captureStartupLogs: {}
|
||||
activeInputHandler: 1
|
||||
windowsGamepadBackendHint: 0
|
||||
cloudProjectId:
|
||||
framebufferDepthMemorylessMode: 0
|
||||
qualitySettingsNames: []
|
||||
projectName:
|
||||
organizationId:
|
||||
cloudEnabled: 0
|
||||
legacyClampBlendShapeWeights: 0
|
||||
hmiLoadingImage: {fileID: 0}
|
||||
platformRequiresReadableAssets: 0
|
||||
virtualTexturingSupportEnabled: 0
|
||||
insecureHttpOption: 0
|
||||
androidVulkanDenyFilterList: []
|
||||
androidVulkanAllowFilterList: []
|
||||
androidVulkanDeviceFilterListAsset: {fileID: 0}
|
||||
d3d12DeviceFilterListAsset: {fileID: 0}
|
||||
allowedHttpConnections: 3
|
||||
@@ -0,0 +1,2 @@
|
||||
m_EditorVersion: 6000.3.11f1
|
||||
m_EditorVersionWithRevision: 6000.3.11f1 (3000ef702840)
|
||||
@@ -0,0 +1,239 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!47 &1
|
||||
QualitySettings:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 5
|
||||
m_CurrentQuality: 5
|
||||
m_QualitySettings:
|
||||
- serializedVersion: 2
|
||||
name: Very Low
|
||||
pixelLightCount: 0
|
||||
shadows: 0
|
||||
shadowResolution: 0
|
||||
shadowProjection: 1
|
||||
shadowCascades: 1
|
||||
shadowDistance: 15
|
||||
shadowNearPlaneOffset: 3
|
||||
shadowCascade2Split: 0.33333334
|
||||
shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
|
||||
shadowmaskMode: 0
|
||||
skinWeights: 1
|
||||
textureQuality: 1
|
||||
anisotropicTextures: 0
|
||||
antiAliasing: 0
|
||||
softParticles: 0
|
||||
softVegetation: 0
|
||||
realtimeReflectionProbes: 0
|
||||
billboardsFaceCameraPosition: 0
|
||||
vSyncCount: 0
|
||||
lodBias: 0.3
|
||||
maximumLODLevel: 0
|
||||
streamingMipmapsActive: 0
|
||||
streamingMipmapsAddAllCameras: 1
|
||||
streamingMipmapsMemoryBudget: 512
|
||||
streamingMipmapsRenderersPerFrame: 512
|
||||
streamingMipmapsMaxLevelReduction: 2
|
||||
streamingMipmapsMaxFileIORequests: 1024
|
||||
particleRaycastBudget: 4
|
||||
asyncUploadTimeSlice: 2
|
||||
asyncUploadBufferSize: 16
|
||||
asyncUploadPersistentBuffer: 1
|
||||
resolutionScalingFixedDPIFactor: 1
|
||||
customRenderPipeline: {fileID: 0}
|
||||
excludedTargetPlatforms: []
|
||||
- serializedVersion: 2
|
||||
name: Low
|
||||
pixelLightCount: 0
|
||||
shadows: 0
|
||||
shadowResolution: 0
|
||||
shadowProjection: 1
|
||||
shadowCascades: 1
|
||||
shadowDistance: 20
|
||||
shadowNearPlaneOffset: 3
|
||||
shadowCascade2Split: 0.33333334
|
||||
shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
|
||||
shadowmaskMode: 0
|
||||
skinWeights: 2
|
||||
textureQuality: 0
|
||||
anisotropicTextures: 0
|
||||
antiAliasing: 0
|
||||
softParticles: 0
|
||||
softVegetation: 0
|
||||
realtimeReflectionProbes: 0
|
||||
billboardsFaceCameraPosition: 0
|
||||
vSyncCount: 0
|
||||
lodBias: 0.4
|
||||
maximumLODLevel: 0
|
||||
streamingMipmapsActive: 0
|
||||
streamingMipmapsAddAllCameras: 1
|
||||
streamingMipmapsMemoryBudget: 512
|
||||
streamingMipmapsRenderersPerFrame: 512
|
||||
streamingMipmapsMaxLevelReduction: 2
|
||||
streamingMipmapsMaxFileIORequests: 1024
|
||||
particleRaycastBudget: 16
|
||||
asyncUploadTimeSlice: 2
|
||||
asyncUploadBufferSize: 16
|
||||
asyncUploadPersistentBuffer: 1
|
||||
resolutionScalingFixedDPIFactor: 1
|
||||
customRenderPipeline: {fileID: 0}
|
||||
excludedTargetPlatforms: []
|
||||
- serializedVersion: 2
|
||||
name: Medium
|
||||
pixelLightCount: 1
|
||||
shadows: 1
|
||||
shadowResolution: 0
|
||||
shadowProjection: 1
|
||||
shadowCascades: 1
|
||||
shadowDistance: 20
|
||||
shadowNearPlaneOffset: 3
|
||||
shadowCascade2Split: 0.33333334
|
||||
shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
|
||||
shadowmaskMode: 0
|
||||
skinWeights: 2
|
||||
textureQuality: 0
|
||||
anisotropicTextures: 1
|
||||
antiAliasing: 0
|
||||
softParticles: 0
|
||||
softVegetation: 0
|
||||
realtimeReflectionProbes: 0
|
||||
billboardsFaceCameraPosition: 0
|
||||
vSyncCount: 1
|
||||
lodBias: 0.7
|
||||
maximumLODLevel: 0
|
||||
streamingMipmapsActive: 0
|
||||
streamingMipmapsAddAllCameras: 1
|
||||
streamingMipmapsMemoryBudget: 512
|
||||
streamingMipmapsRenderersPerFrame: 512
|
||||
streamingMipmapsMaxLevelReduction: 2
|
||||
streamingMipmapsMaxFileIORequests: 1024
|
||||
particleRaycastBudget: 64
|
||||
asyncUploadTimeSlice: 2
|
||||
asyncUploadBufferSize: 16
|
||||
asyncUploadPersistentBuffer: 1
|
||||
resolutionScalingFixedDPIFactor: 1
|
||||
customRenderPipeline: {fileID: 0}
|
||||
excludedTargetPlatforms: []
|
||||
- serializedVersion: 2
|
||||
name: High
|
||||
pixelLightCount: 2
|
||||
shadows: 2
|
||||
shadowResolution: 1
|
||||
shadowProjection: 1
|
||||
shadowCascades: 2
|
||||
shadowDistance: 40
|
||||
shadowNearPlaneOffset: 3
|
||||
shadowCascade2Split: 0.33333334
|
||||
shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
|
||||
shadowmaskMode: 1
|
||||
skinWeights: 2
|
||||
textureQuality: 0
|
||||
anisotropicTextures: 1
|
||||
antiAliasing: 0
|
||||
softParticles: 0
|
||||
softVegetation: 1
|
||||
realtimeReflectionProbes: 1
|
||||
billboardsFaceCameraPosition: 1
|
||||
vSyncCount: 1
|
||||
lodBias: 1
|
||||
maximumLODLevel: 0
|
||||
streamingMipmapsActive: 0
|
||||
streamingMipmapsAddAllCameras: 1
|
||||
streamingMipmapsMemoryBudget: 512
|
||||
streamingMipmapsRenderersPerFrame: 512
|
||||
streamingMipmapsMaxLevelReduction: 2
|
||||
streamingMipmapsMaxFileIORequests: 1024
|
||||
particleRaycastBudget: 256
|
||||
asyncUploadTimeSlice: 2
|
||||
asyncUploadBufferSize: 16
|
||||
asyncUploadPersistentBuffer: 1
|
||||
resolutionScalingFixedDPIFactor: 1
|
||||
customRenderPipeline: {fileID: 0}
|
||||
excludedTargetPlatforms: []
|
||||
- serializedVersion: 2
|
||||
name: Very High
|
||||
pixelLightCount: 3
|
||||
shadows: 2
|
||||
shadowResolution: 2
|
||||
shadowProjection: 1
|
||||
shadowCascades: 2
|
||||
shadowDistance: 70
|
||||
shadowNearPlaneOffset: 3
|
||||
shadowCascade2Split: 0.33333334
|
||||
shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
|
||||
shadowmaskMode: 1
|
||||
skinWeights: 4
|
||||
textureQuality: 0
|
||||
anisotropicTextures: 2
|
||||
antiAliasing: 2
|
||||
softParticles: 1
|
||||
softVegetation: 1
|
||||
realtimeReflectionProbes: 1
|
||||
billboardsFaceCameraPosition: 1
|
||||
vSyncCount: 1
|
||||
lodBias: 1.5
|
||||
maximumLODLevel: 0
|
||||
streamingMipmapsActive: 0
|
||||
streamingMipmapsAddAllCameras: 1
|
||||
streamingMipmapsMemoryBudget: 512
|
||||
streamingMipmapsRenderersPerFrame: 512
|
||||
streamingMipmapsMaxLevelReduction: 2
|
||||
streamingMipmapsMaxFileIORequests: 1024
|
||||
particleRaycastBudget: 1024
|
||||
asyncUploadTimeSlice: 2
|
||||
asyncUploadBufferSize: 16
|
||||
asyncUploadPersistentBuffer: 1
|
||||
resolutionScalingFixedDPIFactor: 1
|
||||
customRenderPipeline: {fileID: 0}
|
||||
excludedTargetPlatforms: []
|
||||
- serializedVersion: 2
|
||||
name: Ultra
|
||||
pixelLightCount: 4
|
||||
shadows: 2
|
||||
shadowResolution: 2
|
||||
shadowProjection: 1
|
||||
shadowCascades: 4
|
||||
shadowDistance: 150
|
||||
shadowNearPlaneOffset: 3
|
||||
shadowCascade2Split: 0.33333334
|
||||
shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
|
||||
shadowmaskMode: 1
|
||||
skinWeights: 255
|
||||
textureQuality: 0
|
||||
anisotropicTextures: 2
|
||||
antiAliasing: 2
|
||||
softParticles: 1
|
||||
softVegetation: 1
|
||||
realtimeReflectionProbes: 1
|
||||
billboardsFaceCameraPosition: 1
|
||||
vSyncCount: 1
|
||||
lodBias: 2
|
||||
maximumLODLevel: 0
|
||||
streamingMipmapsActive: 0
|
||||
streamingMipmapsAddAllCameras: 1
|
||||
streamingMipmapsMemoryBudget: 512
|
||||
streamingMipmapsRenderersPerFrame: 512
|
||||
streamingMipmapsMaxLevelReduction: 2
|
||||
streamingMipmapsMaxFileIORequests: 1024
|
||||
particleRaycastBudget: 4096
|
||||
asyncUploadTimeSlice: 2
|
||||
asyncUploadBufferSize: 16
|
||||
asyncUploadPersistentBuffer: 1
|
||||
resolutionScalingFixedDPIFactor: 1
|
||||
customRenderPipeline: {fileID: 0}
|
||||
excludedTargetPlatforms: []
|
||||
m_PerPlatformDefaultQuality:
|
||||
Android: 2
|
||||
Lumin: 5
|
||||
GameCoreScarlett: 5
|
||||
GameCoreXboxOne: 5
|
||||
Nintendo Switch: 5
|
||||
PS4: 5
|
||||
PS5: 5
|
||||
Stadia: 5
|
||||
Standalone: 5
|
||||
WebGL: 3
|
||||
Windows Store Apps: 5
|
||||
XboxOne: 5
|
||||
iPhone: 2
|
||||
tvOS: 2
|
||||
@@ -0,0 +1,121 @@
|
||||
{
|
||||
"templatePinStates": [],
|
||||
"dependencyTypeInfos": [
|
||||
{
|
||||
"userAdded": false,
|
||||
"type": "UnityEngine.AnimationClip",
|
||||
"defaultInstantiationMode": 0
|
||||
},
|
||||
{
|
||||
"userAdded": false,
|
||||
"type": "UnityEditor.Animations.AnimatorController",
|
||||
"defaultInstantiationMode": 0
|
||||
},
|
||||
{
|
||||
"userAdded": false,
|
||||
"type": "UnityEngine.AnimatorOverrideController",
|
||||
"defaultInstantiationMode": 0
|
||||
},
|
||||
{
|
||||
"userAdded": false,
|
||||
"type": "UnityEditor.Audio.AudioMixerController",
|
||||
"defaultInstantiationMode": 0
|
||||
},
|
||||
{
|
||||
"userAdded": false,
|
||||
"type": "UnityEngine.ComputeShader",
|
||||
"defaultInstantiationMode": 1
|
||||
},
|
||||
{
|
||||
"userAdded": false,
|
||||
"type": "UnityEngine.Cubemap",
|
||||
"defaultInstantiationMode": 0
|
||||
},
|
||||
{
|
||||
"userAdded": false,
|
||||
"type": "UnityEngine.GameObject",
|
||||
"defaultInstantiationMode": 0
|
||||
},
|
||||
{
|
||||
"userAdded": false,
|
||||
"type": "UnityEditor.LightingDataAsset",
|
||||
"defaultInstantiationMode": 0
|
||||
},
|
||||
{
|
||||
"userAdded": false,
|
||||
"type": "UnityEngine.LightingSettings",
|
||||
"defaultInstantiationMode": 0
|
||||
},
|
||||
{
|
||||
"userAdded": false,
|
||||
"type": "UnityEngine.Material",
|
||||
"defaultInstantiationMode": 0
|
||||
},
|
||||
{
|
||||
"userAdded": false,
|
||||
"type": "UnityEditor.MonoScript",
|
||||
"defaultInstantiationMode": 1
|
||||
},
|
||||
{
|
||||
"userAdded": false,
|
||||
"type": "UnityEngine.PhysicsMaterial",
|
||||
"defaultInstantiationMode": 0
|
||||
},
|
||||
{
|
||||
"userAdded": false,
|
||||
"type": "UnityEngine.PhysicsMaterial2D",
|
||||
"defaultInstantiationMode": 0
|
||||
},
|
||||
{
|
||||
"userAdded": false,
|
||||
"type": "UnityEngine.Rendering.PostProcessing.PostProcessProfile",
|
||||
"defaultInstantiationMode": 0
|
||||
},
|
||||
{
|
||||
"userAdded": false,
|
||||
"type": "UnityEngine.Rendering.PostProcessing.PostProcessResources",
|
||||
"defaultInstantiationMode": 0
|
||||
},
|
||||
{
|
||||
"userAdded": false,
|
||||
"type": "UnityEngine.Rendering.VolumeProfile",
|
||||
"defaultInstantiationMode": 0
|
||||
},
|
||||
{
|
||||
"userAdded": false,
|
||||
"type": "UnityEditor.SceneAsset",
|
||||
"defaultInstantiationMode": 1
|
||||
},
|
||||
{
|
||||
"userAdded": false,
|
||||
"type": "UnityEngine.Shader",
|
||||
"defaultInstantiationMode": 1
|
||||
},
|
||||
{
|
||||
"userAdded": false,
|
||||
"type": "UnityEngine.ShaderVariantCollection",
|
||||
"defaultInstantiationMode": 1
|
||||
},
|
||||
{
|
||||
"userAdded": false,
|
||||
"type": "UnityEngine.Texture",
|
||||
"defaultInstantiationMode": 0
|
||||
},
|
||||
{
|
||||
"userAdded": false,
|
||||
"type": "UnityEngine.Texture2D",
|
||||
"defaultInstantiationMode": 0
|
||||
},
|
||||
{
|
||||
"userAdded": false,
|
||||
"type": "UnityEngine.Timeline.TimelineAsset",
|
||||
"defaultInstantiationMode": 0
|
||||
}
|
||||
],
|
||||
"defaultDependencyTypeInfo": {
|
||||
"userAdded": false,
|
||||
"type": "<default_scene_template_dependencies>",
|
||||
"defaultInstantiationMode": 1
|
||||
},
|
||||
"newSceneOverride": 0
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!78 &1
|
||||
TagManager:
|
||||
serializedVersion: 2
|
||||
tags: []
|
||||
layers:
|
||||
- Default
|
||||
- TransparentFX
|
||||
- Ignore Raycast
|
||||
-
|
||||
- Water
|
||||
- UI
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
m_SortingLayers:
|
||||
- name: Default
|
||||
uniqueID: 0
|
||||
locked: 0
|
||||
@@ -0,0 +1,9 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!5 &1
|
||||
TimeManager:
|
||||
m_ObjectHideFlags: 0
|
||||
Fixed Timestep: 0.02
|
||||
Maximum Allowed Timestep: 0.33333334
|
||||
m_TimeScale: 1
|
||||
Maximum Particle Timestep: 0.03
|
||||
@@ -0,0 +1,40 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!310 &1
|
||||
UnityConnectSettings:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 1
|
||||
m_Enabled: 0
|
||||
m_TestMode: 0
|
||||
m_EventOldUrl: https://api.uca.cloud.unity3d.com/v1/events
|
||||
m_EventUrl: https://cdp.cloud.unity3d.com/v1/events
|
||||
m_ConfigUrl: https://config.uca.cloud.unity3d.com
|
||||
m_DashboardUrl: https://dashboard.unity3d.com
|
||||
m_TestInitMode: 0
|
||||
InsightsSettings:
|
||||
m_EngineDiagnosticsEnabled: 1
|
||||
m_Enabled: 0
|
||||
CrashReportingSettings:
|
||||
serializedVersion: 2
|
||||
m_EventUrl: https://perf-events.cloud.unity3d.com
|
||||
m_EnableCloudDiagnosticsReporting: 0
|
||||
m_LogBufferSize: 10
|
||||
m_CaptureEditorExceptions: 1
|
||||
UnityPurchasingSettings:
|
||||
m_Enabled: 0
|
||||
m_TestMode: 0
|
||||
UnityAnalyticsSettings:
|
||||
m_Enabled: 0
|
||||
m_TestMode: 0
|
||||
m_InitializeOnStartup: 1
|
||||
m_PackageRequiringCoreStatsPresent: 0
|
||||
UnityAdsSettings:
|
||||
m_Enabled: 0
|
||||
m_InitializeOnStartup: 1
|
||||
m_TestMode: 0
|
||||
m_IosGameId:
|
||||
m_AndroidGameId:
|
||||
m_GameIds: {}
|
||||
m_GameId:
|
||||
PerformanceReportingSettings:
|
||||
m_Enabled: 0
|
||||
@@ -0,0 +1,14 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!937362698 &1
|
||||
VFXManager:
|
||||
m_ObjectHideFlags: 0
|
||||
m_IndirectShader: {fileID: 0}
|
||||
m_CopyBufferShader: {fileID: 0}
|
||||
m_SortShader: {fileID: 0}
|
||||
m_StripUpdateShader: {fileID: 0}
|
||||
m_RenderPipeSettingsPath:
|
||||
m_FixedTimeStep: 0.016666668
|
||||
m_MaxDeltaTime: 0.05
|
||||
m_CompiledVersion: 0
|
||||
m_RuntimeVersion: 0
|
||||
@@ -0,0 +1,8 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!890905787 &1
|
||||
VersionControlSettings:
|
||||
m_ObjectHideFlags: 0
|
||||
m_Mode: Visible Meta Files
|
||||
m_CollabEditorSettings:
|
||||
inProgressEnabled: 1
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"m_SettingKeys": [
|
||||
"VR Device Disabled",
|
||||
"VR Device User Alert"
|
||||
],
|
||||
"m_SettingValues": [
|
||||
"False",
|
||||
"False"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 11.00
|
||||
# Visual Studio 2010
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Benchmarks", "Benchmarks.csproj", "{b6ce87c6-d606-93b9-b8b1-3b520c8d6bae}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{b6ce87c6-d606-93b9-b8b1-3b520c8d6bae}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{b6ce87c6-d606-93b9-b8b1-3b520c8d6bae}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
+75
-4
@@ -1,28 +1,32 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/edmand46/arpack/generator"
|
||||
"github.com/edmand46/arpack/parser"
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/edmand46/arpack/generator"
|
||||
"github.com/edmand46/arpack/parser"
|
||||
)
|
||||
|
||||
func main() {
|
||||
in := flag.String("in", "", "input Go file with struct definitions")
|
||||
outGo := flag.String("out-go", "", "output directory for generated Go code")
|
||||
outCS := flag.String("out-cs", "", "output directory for generated C# code")
|
||||
outTS := flag.String("out-ts", "", "output directory for generated TypeScript code")
|
||||
outLua := flag.String("out-lua", "", "output directory for generated Lua code")
|
||||
namespace := flag.String("cs-namespace", "Arpack.Messages", "C# namespace")
|
||||
flag.Parse()
|
||||
|
||||
if *in == "" {
|
||||
log.Fatal("arpack: -in is required")
|
||||
}
|
||||
if *outGo == "" && *outCS == "" {
|
||||
log.Fatal("arpack: at least one of -out-go or -out-cs is required")
|
||||
|
||||
if *outGo == "" && *outCS == "" && *outTS == "" && *outLua == "" {
|
||||
log.Fatal("arpack: at least one of -out-go, -out-cs, -out-ts, or -out-lua is required")
|
||||
}
|
||||
|
||||
schema, err := parser.ParseSchemaFile(*in)
|
||||
@@ -41,6 +45,8 @@ func main() {
|
||||
if pkgName == "." || pkgName == "" {
|
||||
pkgName = msgs[0].PackageName
|
||||
}
|
||||
// Replace hyphens with underscores for valid Go package names
|
||||
pkgName = strings.ReplaceAll(pkgName, "-", "_")
|
||||
|
||||
src, err := generator.GenerateGoSchema(schema, pkgName)
|
||||
if err != nil {
|
||||
@@ -74,8 +80,73 @@ func main() {
|
||||
|
||||
fmt.Printf("arpack: wrote %s\n", outPath)
|
||||
}
|
||||
|
||||
if *outTS != "" {
|
||||
src, err := generator.GenerateTypeScriptSchema(schema, "Arpack.Messages")
|
||||
if err != nil {
|
||||
log.Fatalf("arpack: TypeScript generation error: %v", err)
|
||||
}
|
||||
|
||||
outPath := filepath.Join(*outTS, toTitle(baseName)+".gen.ts")
|
||||
if err := os.MkdirAll(*outTS, 0755); err != nil {
|
||||
log.Fatalf("arpack: mkdir %s: %v", *outTS, err)
|
||||
}
|
||||
if err := os.WriteFile(outPath, src, 0644); err != nil {
|
||||
log.Fatalf("arpack: write %s: %v", outPath, err)
|
||||
}
|
||||
|
||||
fmt.Printf("arpack: wrote %s\n", outPath)
|
||||
}
|
||||
|
||||
if *outLua != "" {
|
||||
src, err := generator.GenerateLuaSchema(schema, baseName)
|
||||
if err != nil {
|
||||
log.Fatalf("arpack: Lua generation error: %v", err)
|
||||
}
|
||||
|
||||
// Use snake_case filename for Lua require() compatibility
|
||||
outPath := filepath.Join(*outLua, toSnakeCase(baseName)+"_gen.lua")
|
||||
if err := os.MkdirAll(*outLua, 0755); err != nil {
|
||||
log.Fatalf("arpack: mkdir %s: %v", *outLua, err)
|
||||
}
|
||||
if err := os.WriteFile(outPath, src, 0644); err != nil {
|
||||
log.Fatalf("arpack: write %s: %v", outPath, err)
|
||||
}
|
||||
|
||||
fmt.Printf("arpack: wrote %s\n", outPath)
|
||||
}
|
||||
}
|
||||
|
||||
func toTitle(s string) string {
|
||||
return strings.ToUpper(s[:1]) + strings.ToLower(s[1:])
|
||||
}
|
||||
|
||||
func toSnakeCase(s string) string {
|
||||
if s == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
var b strings.Builder
|
||||
var prevUpper bool
|
||||
|
||||
for i, c := range s {
|
||||
isUpper := c >= 'A' && c <= 'Z'
|
||||
|
||||
if i > 0 && isUpper {
|
||||
nextLower := false
|
||||
if i+1 < len(s) {
|
||||
nextChar := rune(s[i+1])
|
||||
nextLower = nextChar >= 'a' && nextChar <= 'z'
|
||||
}
|
||||
|
||||
if !prevUpper || nextLower {
|
||||
b.WriteByte('_')
|
||||
}
|
||||
}
|
||||
|
||||
b.WriteRune(c)
|
||||
prevUpper = isUpper
|
||||
}
|
||||
|
||||
return strings.ToLower(b.String())
|
||||
}
|
||||
|
||||
+495
-43
@@ -2,9 +2,6 @@ package e2e
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"github.com/edmand46/arpack/generator"
|
||||
"github.com/edmand46/arpack/parser"
|
||||
"fmt"
|
||||
"math"
|
||||
"os"
|
||||
"os/exec"
|
||||
@@ -12,16 +9,14 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/edmand46/arpack/generator"
|
||||
"github.com/edmand46/arpack/parser"
|
||||
)
|
||||
|
||||
const samplePath = "../testdata/sample.go"
|
||||
|
||||
// TestE2E_CrossLanguage гоняет сериализацию в обе стороны: Go → C# и C# → Go.
|
||||
func TestE2E_CrossLanguage(t *testing.T) {
|
||||
if _, err := exec.LookPath("dotnet"); err != nil {
|
||||
t.Skip("dotnet not found, skipping cross-language e2e test")
|
||||
}
|
||||
|
||||
schema, err := parser.ParseSchemaFile(samplePath)
|
||||
if err != nil {
|
||||
t.Fatalf("parse: %v", err)
|
||||
@@ -32,13 +27,7 @@ func TestE2E_CrossLanguage(t *testing.T) {
|
||||
t.Fatalf("GenerateGoSchema: %v", err)
|
||||
}
|
||||
|
||||
csSrc, err := generator.GenerateCSharpSchema(schema, "Ragono.Messages")
|
||||
if err != nil {
|
||||
t.Fatalf("GenerateCSharpSchema: %v", err)
|
||||
}
|
||||
|
||||
goDir := buildGoHarness(t, goSrc)
|
||||
csDir := buildCSHarness(t, csSrc)
|
||||
|
||||
cases := []struct {
|
||||
name string
|
||||
@@ -51,34 +40,171 @@ func TestE2E_CrossLanguage(t *testing.T) {
|
||||
{"EnvelopeMessage", "EnvelopeMessage", 0},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run("Go_to_CS/"+tc.name, func(t *testing.T) {
|
||||
hex := runHarness(t, goDir, "go", "ser", tc.typ, "")
|
||||
out := runHarness(t, csDir, "cs", "deser", tc.typ, hex)
|
||||
checkOutput(t, tc.typ, out, tc.epsilon)
|
||||
})
|
||||
t.Run("CS_to_Go/"+tc.name, func(t *testing.T) {
|
||||
hex := runHarness(t, csDir, "cs", "ser", tc.typ, "")
|
||||
out := runHarness(t, goDir, "go", "deser", tc.typ, hex)
|
||||
checkOutput(t, tc.typ, out, tc.epsilon)
|
||||
})
|
||||
if _, err := exec.LookPath("dotnet"); err == nil {
|
||||
csSrc, err := generator.GenerateCSharpSchema(schema, "Ragono.Messages")
|
||||
if err != nil {
|
||||
t.Fatalf("GenerateCSharpSchema: %v", err)
|
||||
}
|
||||
csDir := buildCSHarness(t, csSrc)
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run("Wire/Go_EQ_CS/"+tc.name, func(t *testing.T) {
|
||||
goHex := strings.TrimSpace(runHarness(t, goDir, "go", "ser", tc.typ, ""))
|
||||
csHex := strings.TrimSpace(runHarness(t, csDir, "cs", "ser", tc.typ, ""))
|
||||
if goHex != csHex {
|
||||
t.Fatalf("wire drift between Go and C# for %s:\ngo=%s\ncs=%s", tc.typ, goHex, csHex)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run("Go_to_CS/"+tc.name, func(t *testing.T) {
|
||||
hex := runHarness(t, goDir, "go", "ser", tc.typ, "")
|
||||
out := runHarness(t, csDir, "cs", "deser", tc.typ, hex)
|
||||
checkOutput(t, tc.typ, out, tc.epsilon)
|
||||
})
|
||||
t.Run("CS_to_Go/"+tc.name, func(t *testing.T) {
|
||||
hex := runHarness(t, csDir, "cs", "ser", tc.typ, "")
|
||||
out := runHarness(t, goDir, "go", "deser", tc.typ, hex)
|
||||
checkOutput(t, tc.typ, out, tc.epsilon)
|
||||
})
|
||||
}
|
||||
} else {
|
||||
t.Log("dotnet not found, skipping C# cross-language e2e tests")
|
||||
}
|
||||
|
||||
if _, err := exec.LookPath("node"); err == nil {
|
||||
tsSrc, err := generator.GenerateTypeScriptSchema(schema, "Arpack.Messages")
|
||||
if err != nil {
|
||||
t.Fatalf("GenerateTypeScriptSchema: %v", err)
|
||||
}
|
||||
tsDir := buildTSHarness(t, tsSrc)
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run("Wire/Go_EQ_TS/"+tc.name, func(t *testing.T) {
|
||||
goHex := strings.TrimSpace(runHarness(t, goDir, "go", "ser", tc.typ, ""))
|
||||
tsHex := strings.TrimSpace(runHarness(t, tsDir, "ts", "ser", tc.typ, ""))
|
||||
if goHex != tsHex {
|
||||
t.Fatalf("wire drift between Go and TS for %s:\ngo=%s\nts=%s", tc.typ, goHex, tsHex)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run("Go_to_TS/"+tc.name, func(t *testing.T) {
|
||||
hex := runHarness(t, goDir, "go", "ser", tc.typ, "")
|
||||
out := runHarness(t, tsDir, "ts", "deser", tc.typ, hex)
|
||||
checkOutput(t, tc.typ, out, tc.epsilon)
|
||||
})
|
||||
t.Run("TS_to_Go/"+tc.name, func(t *testing.T) {
|
||||
hex := runHarness(t, tsDir, "ts", "ser", tc.typ, "")
|
||||
out := runHarness(t, goDir, "go", "deser", tc.typ, hex)
|
||||
checkOutput(t, tc.typ, out, tc.epsilon)
|
||||
})
|
||||
}
|
||||
} else {
|
||||
t.Log("node not found, skipping TypeScript cross-language e2e tests")
|
||||
}
|
||||
|
||||
if _, err := exec.LookPath("luajit"); err == nil {
|
||||
// Use a simpler test schema without int64/uint64 for Lua
|
||||
luaSchema := parser.Schema{
|
||||
Messages: []parser.Message{
|
||||
{
|
||||
Name: "Vector3",
|
||||
Fields: []parser.Field{
|
||||
{Name: "X", Kind: parser.KindPrimitive, Primitive: parser.KindFloat32, Quant: &parser.QuantInfo{Min: -500, Max: 500, Bits: 16}},
|
||||
{Name: "Y", Kind: parser.KindPrimitive, Primitive: parser.KindFloat32, Quant: &parser.QuantInfo{Min: -500, Max: 500, Bits: 16}},
|
||||
{Name: "Z", Kind: parser.KindPrimitive, Primitive: parser.KindFloat32, Quant: &parser.QuantInfo{Min: -500, Max: 500, Bits: 16}},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "MoveMessage",
|
||||
Fields: []parser.Field{
|
||||
{Name: "Position", Kind: parser.KindNested, TypeName: "Vector3"},
|
||||
{Name: "Velocity", Kind: parser.KindFixedArray, FixedLen: 3, Elem: &parser.Field{Kind: parser.KindPrimitive, Primitive: parser.KindFloat32}},
|
||||
{Name: "Waypoints", Kind: parser.KindSlice, Elem: &parser.Field{Kind: parser.KindNested, TypeName: "Vector3"}},
|
||||
{Name: "PlayerID", Kind: parser.KindPrimitive, Primitive: parser.KindUint32},
|
||||
{Name: "Active", Kind: parser.KindPrimitive, Primitive: parser.KindBool},
|
||||
{Name: "Visible", Kind: parser.KindPrimitive, Primitive: parser.KindBool},
|
||||
{Name: "Ghost", Kind: parser.KindPrimitive, Primitive: parser.KindBool},
|
||||
{Name: "Name", Kind: parser.KindPrimitive, Primitive: parser.KindString},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "EnvelopeMessage",
|
||||
Fields: []parser.Field{
|
||||
{Name: "Code", Kind: parser.KindPrimitive, Primitive: parser.KindUint16},
|
||||
{Name: "Counter", Kind: parser.KindPrimitive, Primitive: parser.KindUint8},
|
||||
},
|
||||
},
|
||||
},
|
||||
Enums: []parser.Enum{
|
||||
{
|
||||
Name: "Opcode",
|
||||
Primitive: parser.KindUint16,
|
||||
Values: []parser.EnumValue{
|
||||
{Name: "Unknown", Value: "0"},
|
||||
{Name: "Join", Value: "1"},
|
||||
{Name: "Leave", Value: "2"},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
luaSrc, err := generator.GenerateLuaSchema(luaSchema, "messages")
|
||||
if err != nil {
|
||||
t.Fatalf("GenerateLuaSchema: %v", err)
|
||||
}
|
||||
luaDir := buildLuaHarness(t, luaSrc)
|
||||
|
||||
luaCases := []struct {
|
||||
name string
|
||||
typ string
|
||||
epsilon float64
|
||||
}{
|
||||
{"Vector3", "Vector3", 0.02},
|
||||
{"MoveMessage", "MoveMessage", 0.02},
|
||||
{"EnvelopeMessage", "EnvelopeMessage", 0},
|
||||
}
|
||||
|
||||
for _, tc := range luaCases {
|
||||
t.Run("Wire/Go_EQ_Lua/"+tc.name, func(t *testing.T) {
|
||||
goHex := strings.TrimSpace(runHarness(t, goDir, "go", "ser", tc.typ, ""))
|
||||
luaHex := strings.TrimSpace(runHarness(t, luaDir, "lua", "ser", tc.typ, ""))
|
||||
if goHex != luaHex {
|
||||
t.Fatalf("wire drift between Go and Lua for %s:\ngo=%s\nlua=%s", tc.typ, goHex, luaHex)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
for _, tc := range luaCases {
|
||||
t.Run("Go_to_Lua/"+tc.name, func(t *testing.T) {
|
||||
hex := runHarness(t, goDir, "go", "ser", tc.typ, "")
|
||||
out := runHarness(t, luaDir, "lua", "deser", tc.typ, hex)
|
||||
checkOutput(t, tc.typ, out, tc.epsilon)
|
||||
})
|
||||
t.Run("Lua_to_Go/"+tc.name, func(t *testing.T) {
|
||||
hex := runHarness(t, luaDir, "lua", "ser", tc.typ, "")
|
||||
out := runHarness(t, goDir, "go", "deser", tc.typ, hex)
|
||||
checkOutput(t, tc.typ, out, tc.epsilon)
|
||||
})
|
||||
}
|
||||
} else {
|
||||
t.Log("luajit not found, skipping Lua cross-language e2e tests")
|
||||
}
|
||||
}
|
||||
|
||||
// --- Build helpers ---
|
||||
|
||||
func buildGoHarness(t *testing.T, generatedSrc []byte) string {
|
||||
t.Helper()
|
||||
dir := t.TempDir()
|
||||
|
||||
// Читаем sample.go и меняем package на main
|
||||
sampleSrc, err := os.ReadFile(samplePath)
|
||||
if err != nil {
|
||||
t.Fatalf("read sample: %v", err)
|
||||
}
|
||||
sampleSrc = bytes.Replace(sampleSrc, []byte("package messages"), []byte("package main"), 1)
|
||||
|
||||
// Generated код уже имеет package main (мы передали "main" в GenerateGo)
|
||||
write(t, filepath.Join(dir, "messages.go"), sampleSrc)
|
||||
write(t, filepath.Join(dir, "messages_arpack.go"), generatedSrc)
|
||||
write(t, filepath.Join(dir, "main.go"), []byte(goHarnessSource))
|
||||
@@ -100,23 +226,64 @@ func buildCSHarness(t *testing.T, generatedSrc []byte) string {
|
||||
return dir
|
||||
}
|
||||
|
||||
// --- Harness runners ---
|
||||
func buildTSHarness(t *testing.T, generatedSrc []byte) string {
|
||||
t.Helper()
|
||||
dir := t.TempDir()
|
||||
|
||||
srcDir := filepath.Join(dir, "src")
|
||||
if err := os.MkdirAll(srcDir, 0755); err != nil {
|
||||
t.Fatalf("mkdir %s: %v", srcDir, err)
|
||||
}
|
||||
|
||||
write(t, filepath.Join(srcDir, "messages.gen.ts"), generatedSrc)
|
||||
write(t, filepath.Join(srcDir, "harness.ts"), []byte(tsHarnessSource))
|
||||
write(t, filepath.Join(dir, "package.json"), []byte(tsPackageSource))
|
||||
write(t, filepath.Join(dir, "tsconfig.json"), []byte(tsConfigSource))
|
||||
|
||||
mustRun(t, dir, "npm", "install")
|
||||
mustRun(t, dir, "npx", "tsc")
|
||||
|
||||
return dir
|
||||
}
|
||||
|
||||
func buildLuaHarness(t *testing.T, generatedSrc []byte) string {
|
||||
t.Helper()
|
||||
dir := t.TempDir()
|
||||
|
||||
write(t, filepath.Join(dir, "messages_gen.lua"), generatedSrc)
|
||||
write(t, filepath.Join(dir, "harness.lua"), []byte(luaHarnessSource))
|
||||
|
||||
return dir
|
||||
}
|
||||
|
||||
func runHarness(t *testing.T, dir, lang, op, typ, hexInput string) string {
|
||||
t.Helper()
|
||||
var cmd *exec.Cmd
|
||||
if lang == "go" {
|
||||
switch lang {
|
||||
case "go":
|
||||
args := []string{op, typ}
|
||||
if hexInput != "" {
|
||||
args = append(args, hexInput)
|
||||
}
|
||||
cmd = exec.Command(filepath.Join(dir, "harness"), args...)
|
||||
} else {
|
||||
case "cs":
|
||||
args := []string{op, typ}
|
||||
if hexInput != "" {
|
||||
args = append(args, hexInput)
|
||||
}
|
||||
cmd = exec.Command("dotnet", append([]string{filepath.Join(dir, "out", "E2EHarness.dll")}, args...)...)
|
||||
case "ts":
|
||||
args := []string{op, typ}
|
||||
if hexInput != "" {
|
||||
args = append(args, hexInput)
|
||||
}
|
||||
cmd = exec.Command("node", append([]string{filepath.Join(dir, "dist", "harness.js")}, args...)...)
|
||||
case "lua":
|
||||
args := []string{filepath.Join(dir, "harness.lua"), op, typ}
|
||||
if hexInput != "" {
|
||||
args = append(args, hexInput)
|
||||
}
|
||||
cmd = exec.Command("luajit", args...)
|
||||
}
|
||||
cmd.Dir = dir
|
||||
out, err := cmd.CombinedOutput()
|
||||
@@ -126,9 +293,6 @@ func runHarness(t *testing.T, dir, lang, op, typ, hexInput string) string {
|
||||
return strings.TrimSpace(string(out))
|
||||
}
|
||||
|
||||
// --- Output verification ---
|
||||
|
||||
// checkOutput парсит key=value вывод и сравнивает с ожидаемыми значениями.
|
||||
func checkOutput(t *testing.T, typ, output string, epsilon float64) {
|
||||
t.Helper()
|
||||
t.Logf("output for %s:\n%s", typ, output)
|
||||
@@ -222,8 +386,6 @@ func assertStr(t *testing.T, kv map[string]string, key, want string) {
|
||||
}
|
||||
}
|
||||
|
||||
// --- Utilities ---
|
||||
|
||||
func write(t *testing.T, path string, data []byte) {
|
||||
t.Helper()
|
||||
if err := os.WriteFile(path, data, 0644); err != nil {
|
||||
@@ -240,8 +402,6 @@ func mustRun(t *testing.T, dir string, name string, args ...string) {
|
||||
}
|
||||
}
|
||||
|
||||
// --- Go harness source ---
|
||||
|
||||
const goHarnessSource = `package main
|
||||
|
||||
import (
|
||||
@@ -337,8 +497,6 @@ func main() {
|
||||
}
|
||||
`
|
||||
|
||||
// --- C# harness source ---
|
||||
|
||||
const csHarnessSource = `using System;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
@@ -509,7 +667,7 @@ unsafe class Program
|
||||
}
|
||||
`
|
||||
|
||||
var csProjSource = fmt.Sprintf(`<Project Sdk="Microsoft.NET.Sdk">
|
||||
var csProjSource = `<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
@@ -518,4 +676,298 @@ var csProjSource = fmt.Sprintf(`<Project Sdk="Microsoft.NET.Sdk">
|
||||
<ImplicitUsings>disable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
`)
|
||||
`
|
||||
|
||||
const tsPackageSource = `{
|
||||
"name": "arpack-e2e-harness",
|
||||
"version": "1.0.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"build": "tsc"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^5.3.0",
|
||||
"@types/node": "^20.0.0"
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
const tsConfigSource = `{
|
||||
"compilerOptions": {
|
||||
"target": "ES2022",
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "bundler",
|
||||
"lib": ["ES2022", "DOM"],
|
||||
"strict": true,
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"outDir": "./dist",
|
||||
"rootDir": "./src"
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
||||
`
|
||||
|
||||
const tsHarnessSource = `import { readFileSync } from 'fs';
|
||||
import { argv } from 'process';
|
||||
|
||||
// Import generated messages
|
||||
import { Vector3, MoveMessage, SpawnMessage, EnvelopeMessage, Opcode } from './messages.gen.js';
|
||||
|
||||
// Hex encoding/decoding utilities
|
||||
function encodeHex(data: Uint8Array): string {
|
||||
return Array.from(data)
|
||||
.map(b => b.toString(16).padStart(2, '0'))
|
||||
.join('');
|
||||
}
|
||||
|
||||
function decodeHex(hex: string): Uint8Array {
|
||||
const bytes = new Uint8Array(hex.length / 2);
|
||||
for (let i = 0; i < hex.length; i += 2) {
|
||||
bytes[i / 2] = parseInt(hex.substr(i, 2), 16);
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
// Main harness
|
||||
function main() {
|
||||
const args = argv.slice(2);
|
||||
const op = args[0]; // 'ser' or 'deser'
|
||||
const typ = args[1]; // message type
|
||||
const hexInput = args[2]; // for deser
|
||||
|
||||
switch (` + "`${op}:${typ}`" + `) {
|
||||
case 'ser:Vector3': {
|
||||
const msg = new Vector3();
|
||||
msg.x = 123.45;
|
||||
msg.y = -200.0;
|
||||
msg.z = 0.0;
|
||||
const buf = new ArrayBuffer(64);
|
||||
const view = new DataView(buf);
|
||||
const n = msg.serialize(view, 0);
|
||||
const bytes = new Uint8Array(buf, 0, n);
|
||||
console.log(encodeHex(bytes));
|
||||
break;
|
||||
}
|
||||
|
||||
case 'deser:Vector3': {
|
||||
const data = decodeHex(hexInput);
|
||||
const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
|
||||
const [msg] = Vector3.deserialize(view, 0);
|
||||
console.log(` + "`X=${msg.x.toPrecision(9)}`" + `);
|
||||
console.log(` + "`Y=${msg.y.toPrecision(9)}`" + `);
|
||||
console.log(` + "`Z=${msg.z.toPrecision(9)}`" + `);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'ser:SpawnMessage': {
|
||||
const msg = new SpawnMessage();
|
||||
msg.entityID = 42n;
|
||||
msg.position = new Vector3();
|
||||
msg.position.x = 10.0;
|
||||
msg.position.y = 20.0;
|
||||
msg.position.z = 30.0;
|
||||
msg.health = -100;
|
||||
msg.tags = ['hero', 'player'];
|
||||
msg.data = [1, 2, 3];
|
||||
const buf = new ArrayBuffer(512);
|
||||
const view = new DataView(buf);
|
||||
const n = msg.serialize(view, 0);
|
||||
const bytes = new Uint8Array(buf, 0, n);
|
||||
console.log(encodeHex(bytes));
|
||||
break;
|
||||
}
|
||||
|
||||
case 'deser:SpawnMessage': {
|
||||
const data = decodeHex(hexInput);
|
||||
const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
|
||||
const [msg] = SpawnMessage.deserialize(view, 0);
|
||||
console.log(` + "`EntityID=${msg.entityID.toString()}`" + `);
|
||||
console.log(` + "`Position.X=${msg.position.x.toPrecision(9)}`" + `);
|
||||
console.log(` + "`Position.Y=${msg.position.y.toPrecision(9)}`" + `);
|
||||
console.log(` + "`Position.Z=${msg.position.z.toPrecision(9)}`" + `);
|
||||
console.log(` + "`Health=${msg.health}`" + `);
|
||||
for (let i = 0; i < msg.tags.length; i++) {
|
||||
console.log(` + "`Tags[${i}]=${msg.tags[i]}`" + `);
|
||||
}
|
||||
for (let i = 0; i < msg.data.length; i++) {
|
||||
console.log(` + "`Data[${i}]=${msg.data[i]}`" + `);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'ser:MoveMessage': {
|
||||
const msg = new MoveMessage();
|
||||
msg.position = new Vector3();
|
||||
msg.position.x = 50.0;
|
||||
msg.position.y = -100.0;
|
||||
msg.position.z = 0.0;
|
||||
msg.velocity = [1.5, -2.5, 0.0];
|
||||
msg.waypoints = [new Vector3()];
|
||||
msg.waypoints[0].x = 10.0;
|
||||
msg.waypoints[0].y = 20.0;
|
||||
msg.waypoints[0].z = 0.0;
|
||||
msg.playerID = 777;
|
||||
msg.active = true;
|
||||
msg.visible = false;
|
||||
msg.ghost = true;
|
||||
msg.name = 'TestPlayer';
|
||||
const buf = new ArrayBuffer(512);
|
||||
const view = new DataView(buf);
|
||||
const n = msg.serialize(view, 0);
|
||||
const bytes = new Uint8Array(buf, 0, n);
|
||||
console.log(encodeHex(bytes));
|
||||
break;
|
||||
}
|
||||
|
||||
case 'deser:MoveMessage': {
|
||||
const data = decodeHex(hexInput);
|
||||
const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
|
||||
const [msg] = MoveMessage.deserialize(view, 0);
|
||||
console.log(` + "`PlayerID=${msg.playerID}`" + `);
|
||||
console.log(` + "`Active=${msg.active.toString().toLowerCase()}`" + `);
|
||||
console.log(` + "`Visible=${msg.visible.toString().toLowerCase()}`" + `);
|
||||
console.log(` + "`Ghost=${msg.ghost.toString().toLowerCase()}`" + `);
|
||||
console.log(` + "`Name=${msg.name}`" + `);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'ser:EnvelopeMessage': {
|
||||
const msg = new EnvelopeMessage();
|
||||
msg.code = 2; // Opcode.JoinRoom
|
||||
msg.counter = 7;
|
||||
const buf = new ArrayBuffer(64);
|
||||
const view = new DataView(buf);
|
||||
const n = msg.serialize(view, 0);
|
||||
const bytes = new Uint8Array(buf, 0, n);
|
||||
console.log(encodeHex(bytes));
|
||||
break;
|
||||
}
|
||||
|
||||
case 'deser:EnvelopeMessage': {
|
||||
const data = decodeHex(hexInput);
|
||||
const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
|
||||
const [msg] = EnvelopeMessage.deserialize(view, 0);
|
||||
console.log(` + "`Code=${msg.code}`" + `);
|
||||
console.log(` + "`Counter=${msg.counter}`" + `);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
console.error(` + "`Unknown op:type ${op}:${typ}`" + `);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
`
|
||||
|
||||
const luaHarnessSource = `-- Lua E2E Harness
|
||||
-- Usage: luajit harness.lua <op> <type> [hex_input]
|
||||
-- op: 'ser' or 'deser'
|
||||
-- type: message type name
|
||||
|
||||
local messages = require("messages_gen")
|
||||
|
||||
local function hexToBytes(hex)
|
||||
local bytes = {}
|
||||
for i = 1, #hex, 2 do
|
||||
local byte = tonumber(hex:sub(i, i+1), 16)
|
||||
table.insert(bytes, string.char(byte))
|
||||
end
|
||||
return table.concat(bytes)
|
||||
end
|
||||
|
||||
local function bytesToHex(data)
|
||||
local hex = {}
|
||||
for i = 1, #data do
|
||||
table.insert(hex, string.format("%02x", string.byte(data, i)))
|
||||
end
|
||||
return table.concat(hex)
|
||||
end
|
||||
|
||||
local function serializeVector3()
|
||||
local msg = messages.new_vector3()
|
||||
msg.x = 123.45
|
||||
msg.y = -200.0
|
||||
msg.z = 0.0
|
||||
return bytesToHex(messages.serialize_vector3(msg))
|
||||
end
|
||||
|
||||
local function deserializeVector3(hex)
|
||||
local data = hexToBytes(hex)
|
||||
local msg = messages.deserialize_vector3(data, 1)
|
||||
print(string.format("X=%.10g", msg.x))
|
||||
print(string.format("Y=%.10g", msg.y))
|
||||
print(string.format("Z=%.10g", msg.z))
|
||||
end
|
||||
|
||||
local function serializeMoveMessage()
|
||||
local msg = messages.new_move_message()
|
||||
msg.position = messages.new_vector3()
|
||||
msg.position.x = 50.0
|
||||
msg.position.y = -100.0
|
||||
msg.position.z = 0.0
|
||||
msg.velocity = {1.5, -2.5, 0.0}
|
||||
msg.waypoints = {}
|
||||
local wp = messages.new_vector3()
|
||||
wp.x = 10.0
|
||||
wp.y = 20.0
|
||||
wp.z = 0.0
|
||||
table.insert(msg.waypoints, wp)
|
||||
msg.player_id = 777
|
||||
msg.active = true
|
||||
msg.visible = false
|
||||
msg.ghost = true
|
||||
msg.name = "TestPlayer"
|
||||
return bytesToHex(messages.serialize_move_message(msg))
|
||||
end
|
||||
|
||||
local function deserializeMoveMessage(hex)
|
||||
local data = hexToBytes(hex)
|
||||
local msg = messages.deserialize_move_message(data, 1)
|
||||
print(string.format("PlayerID=%d", msg.player_id))
|
||||
print(string.format("Active=%s", tostring(msg.active)))
|
||||
print(string.format("Visible=%s", tostring(msg.visible)))
|
||||
print(string.format("Ghost=%s", tostring(msg.ghost)))
|
||||
print(string.format("Name=%s", msg.name))
|
||||
end
|
||||
|
||||
local function serializeEnvelopeMessage()
|
||||
local msg = messages.new_envelope_message()
|
||||
msg.code = 2 -- Join
|
||||
msg.counter = 7
|
||||
return bytesToHex(messages.serialize_envelope_message(msg))
|
||||
end
|
||||
|
||||
local function deserializeEnvelopeMessage(hex)
|
||||
local data = hexToBytes(hex)
|
||||
local msg = messages.deserialize_envelope_message(data, 1)
|
||||
print(string.format("Code=%d", msg.code))
|
||||
print(string.format("Counter=%d", msg.counter))
|
||||
end
|
||||
|
||||
local op = arg[1]
|
||||
local typ = arg[2]
|
||||
local hexInput = arg[3]
|
||||
|
||||
local key = op .. ":" .. typ
|
||||
|
||||
if key == "ser:Vector3" then
|
||||
print(serializeVector3())
|
||||
elseif key == "deser:Vector3" then
|
||||
deserializeVector3(hexInput)
|
||||
elseif key == "ser:MoveMessage" then
|
||||
print(serializeMoveMessage())
|
||||
elseif key == "deser:MoveMessage" then
|
||||
deserializeMoveMessage(hexInput)
|
||||
elseif key == "ser:EnvelopeMessage" then
|
||||
print(serializeEnvelopeMessage())
|
||||
elseif key == "deser:EnvelopeMessage" then
|
||||
deserializeEnvelopeMessage(hexInput)
|
||||
else
|
||||
error("Unknown op:type " .. key)
|
||||
end
|
||||
`
|
||||
|
||||
+36
-4
@@ -1,9 +1,10 @@
|
||||
package generator
|
||||
|
||||
import (
|
||||
"github.com/edmand46/arpack/parser"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/edmand46/arpack/parser"
|
||||
)
|
||||
|
||||
func GenerateCSharp(messages []parser.Message, namespace string) ([]byte, error) {
|
||||
@@ -13,6 +14,8 @@ func GenerateCSharp(messages []parser.Message, namespace string) ([]byte, error)
|
||||
func GenerateCSharpSchema(schema parser.Schema, namespace string) ([]byte, error) {
|
||||
messages := schema.Messages
|
||||
var b strings.Builder
|
||||
needsLengthGuards := schemaNeedsLengthGuards(messages)
|
||||
needsQuantGuards := schemaNeedsQuantRangeGuards(messages)
|
||||
|
||||
b.WriteString("// <auto-generated> arpack </auto-generated>\n")
|
||||
b.WriteString("// Code generated by arpack. DO NOT EDIT.\n")
|
||||
@@ -26,6 +29,30 @@ func GenerateCSharpSchema(schema parser.Schema, namespace string) ([]byte, error
|
||||
|
||||
fmt.Fprintf(&b, "namespace %s\n{\n", namespace)
|
||||
|
||||
if needsLengthGuards || needsQuantGuards {
|
||||
b.WriteString(" internal static class ArpackGenerated\n {\n")
|
||||
if needsLengthGuards {
|
||||
b.WriteString(" internal static ushort EnsureU16Length(int length, string context)\n")
|
||||
b.WriteString(" {\n")
|
||||
b.WriteString(" if (length > 65535)\n")
|
||||
b.WriteString(" {\n")
|
||||
b.WriteString(" throw new InvalidOperationException(\"arpack: \" + context + \" exceeds uint16 limit\");\n")
|
||||
b.WriteString(" }\n")
|
||||
b.WriteString(" return (ushort)length;\n")
|
||||
b.WriteString(" }\n\n")
|
||||
}
|
||||
if needsQuantGuards {
|
||||
b.WriteString(" internal static void EnsureQuantizedRange(double value, double min, double max, string context)\n")
|
||||
b.WriteString(" {\n")
|
||||
b.WriteString(" if (double.IsNaN(value) || value < min || value > max)\n")
|
||||
b.WriteString(" {\n")
|
||||
b.WriteString(" throw new ArgumentOutOfRangeException(context, \"arpack: quantized value out of range for \" + context);\n")
|
||||
b.WriteString(" }\n")
|
||||
b.WriteString(" }\n")
|
||||
}
|
||||
b.WriteString(" }\n\n")
|
||||
}
|
||||
|
||||
enumNames := make(map[string]struct{}, len(schema.Enums))
|
||||
for _, enum := range schema.Enums {
|
||||
enumNames[enum.Name] = struct{}{}
|
||||
@@ -150,7 +177,9 @@ func writeCSharpSerializeField(b *strings.Builder, f parser.Field, indent string
|
||||
}
|
||||
fmt.Fprintf(b, "%s}\n", indent)
|
||||
case parser.KindSlice:
|
||||
fmt.Fprintf(b, "%s*(ushort*)ptr = (ushort)(%s?.Length ?? 0); ptr += 2;\n", indent, f.Name)
|
||||
lenVar := "_len" + sanitizeVarName(f.Name)
|
||||
fmt.Fprintf(b, "%sushort %s = ArpackGenerated.EnsureU16Length(%s?.Length ?? 0, %q); *(ushort*)ptr = %s; ptr += 2;\n",
|
||||
indent, lenVar, f.Name, lengthContext(f), lenVar)
|
||||
fmt.Fprintf(b, "%sif (%s != null)\n%s{\n", indent, f.Name, indent)
|
||||
iVar := "_i" + f.Name
|
||||
fmt.Fprintf(b, "%s for (int %s = 0; %s < %s.Length; %s++)\n%s {\n",
|
||||
@@ -211,7 +240,8 @@ func writeCSharpSerializePrimitive(
|
||||
lenVar := "_slen" + sanitizeVarName(access)
|
||||
fmt.Fprintf(b, "%sint %s = %s != null ? Encoding.UTF8.GetByteCount(%s) : 0;\n",
|
||||
indent, lenVar, valueExpr, valueExpr)
|
||||
fmt.Fprintf(b, "%s*(ushort*)ptr = (ushort)%s; ptr += 2;\n", indent, lenVar)
|
||||
fmt.Fprintf(b, "%s*(ushort*)ptr = ArpackGenerated.EnsureU16Length(%s, %q); ptr += 2;\n",
|
||||
indent, lenVar, lengthContext(f))
|
||||
fmt.Fprintf(b, "%sif (%s != null && %s > 0)\n%s{\n", indent, valueExpr, lenVar, indent)
|
||||
fmt.Fprintf(b, "%s fixed (char* _chars%s = %s)\n%s {\n",
|
||||
indent, sanitizeVarName(access), valueExpr, indent)
|
||||
@@ -227,6 +257,8 @@ func writeCSharpSerializePrimitive(
|
||||
func writeCSharpSerializeQuant(b *strings.Builder, access string, f parser.Field, indent string) error {
|
||||
q := f.Quant
|
||||
maxUint := q.MaxUint()
|
||||
fmt.Fprintf(b, "%sArpackGenerated.EnsureQuantizedRange(%s, %g, %g, %q);\n",
|
||||
indent, access, q.Min, q.Max, quantContext(f))
|
||||
if q.Bits == 8 {
|
||||
fmt.Fprintf(b, "%s*ptr = (byte)((%s - (%gf)) / (%gf - (%gf)) * %gf); ptr += 1;\n",
|
||||
indent, access, q.Min, q.Max, q.Min, maxUint)
|
||||
@@ -455,7 +487,7 @@ func csharpEnumValueName(enumName, valueName string) string {
|
||||
}
|
||||
|
||||
first := suffix[0]
|
||||
if !((first >= 'A' && first <= 'Z') || (first >= '0' && first <= '9') || first == '_') {
|
||||
if (first < 'A' || first > 'Z') && (first < '0' || first > '9') && first != '_' {
|
||||
return valueName
|
||||
}
|
||||
|
||||
|
||||
+101
-1
@@ -1,12 +1,13 @@
|
||||
package generator
|
||||
|
||||
import (
|
||||
"github.com/edmand46/arpack/parser"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/edmand46/arpack/parser"
|
||||
)
|
||||
|
||||
const samplePath = "../testdata/sample.go"
|
||||
@@ -253,10 +254,109 @@ func TestGenerateCSharp_Output(t *testing.T) {
|
||||
if !strings.Contains(code, "public Opcode Code;") {
|
||||
t.Error("EnvelopeMessage.Code should use generated enum type")
|
||||
}
|
||||
if !strings.Contains(code, "internal static class ArpackGenerated") {
|
||||
t.Error("missing shared ArpackGenerated helper class")
|
||||
}
|
||||
if !strings.Contains(code, "EnsureU16Length") {
|
||||
t.Error("missing uint16 length guard helper")
|
||||
}
|
||||
if !strings.Contains(code, "EnsureQuantizedRange") {
|
||||
t.Error("missing quantized range guard helper")
|
||||
}
|
||||
|
||||
t.Logf("Generated C# (%d bytes):\n%s", len(src), code)
|
||||
}
|
||||
|
||||
func TestGenerateGo_RuntimeGuards(t *testing.T) {
|
||||
schemaSrc := `package messages
|
||||
|
||||
type Quantized struct {
|
||||
Value float32 ` + "`" + `pack:"min=0,max=1,bits=8"` + "`" + `
|
||||
}
|
||||
|
||||
type LengthLimited struct {
|
||||
Name string
|
||||
Items []uint8
|
||||
}
|
||||
`
|
||||
|
||||
schema, err := parser.ParseSchemaSource(schemaSrc)
|
||||
if err != nil {
|
||||
t.Fatalf("ParseSchemaSource: %v", err)
|
||||
}
|
||||
|
||||
src, err := GenerateGoSchema(schema, "messages")
|
||||
if err != nil {
|
||||
t.Fatalf("GenerateGoSchema: %v", err)
|
||||
}
|
||||
|
||||
dir := t.TempDir()
|
||||
if err := os.WriteFile(filepath.Join(dir, "messages.go"), []byte(schemaSrc), 0644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := os.WriteFile(filepath.Join(dir, "messages_arpack.go"), src, 0644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
runtimeTests := `package messages
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func expectPanicContaining(t *testing.T, want string, fn func()) {
|
||||
t.Helper()
|
||||
defer func() {
|
||||
r := recover()
|
||||
if r == nil {
|
||||
t.Fatalf("expected panic containing %q, got nil", want)
|
||||
}
|
||||
if !strings.Contains(r.(string), want) {
|
||||
t.Fatalf("expected panic containing %q, got %v", want, r)
|
||||
}
|
||||
}()
|
||||
fn()
|
||||
}
|
||||
|
||||
func TestLengthGuard_String(t *testing.T) {
|
||||
expectPanicContaining(t, "string length for Name exceeds uint16 limit", func() {
|
||||
msg := LengthLimited{Name: strings.Repeat("a", 65536)}
|
||||
_ = msg.Marshal(nil)
|
||||
})
|
||||
}
|
||||
|
||||
func TestLengthGuard_Slice(t *testing.T) {
|
||||
expectPanicContaining(t, "slice length for Items exceeds uint16 limit", func() {
|
||||
msg := LengthLimited{Items: make([]uint8, 65536)}
|
||||
_ = msg.Marshal(nil)
|
||||
})
|
||||
}
|
||||
|
||||
func TestQuantizedRangeGuard(t *testing.T) {
|
||||
expectPanicContaining(t, "quantized value out of range for Value", func() {
|
||||
msg := Quantized{Value: 1.5}
|
||||
_ = msg.Marshal(nil)
|
||||
})
|
||||
}
|
||||
`
|
||||
if err := os.WriteFile(filepath.Join(dir, "guards_test.go"), []byte(runtimeTests), 0644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
goMod := "module messages\n\ngo 1.21\n"
|
||||
if err := os.WriteFile(filepath.Join(dir, "go.mod"), []byte(goMod), 0644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
cmd := exec.Command("go", "test", "./...")
|
||||
cmd.Dir = dir
|
||||
out, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
t.Fatalf("go test failed:\n%s", out)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBoolPacking_GoCode(t *testing.T) {
|
||||
msgs, err := parser.ParseFile(samplePath)
|
||||
if err != nil {
|
||||
|
||||
+27
-3
@@ -1,10 +1,11 @@
|
||||
package generator
|
||||
|
||||
import (
|
||||
"github.com/edmand46/arpack/parser"
|
||||
"fmt"
|
||||
"go/format"
|
||||
"strings"
|
||||
|
||||
"github.com/edmand46/arpack/parser"
|
||||
)
|
||||
|
||||
func GenerateGo(messages []parser.Message, pkgName string) ([]byte, error) {
|
||||
@@ -14,6 +15,8 @@ func GenerateGo(messages []parser.Message, pkgName string) ([]byte, error) {
|
||||
func GenerateGoSchema(schema parser.Schema, pkgName string) ([]byte, error) {
|
||||
messages := schema.Messages
|
||||
var b strings.Builder
|
||||
needsLengthGuards := schemaNeedsLengthGuards(messages)
|
||||
needsQuantGuards := schemaNeedsQuantRangeGuards(messages)
|
||||
|
||||
b.WriteString("// Code generated by arpack. DO NOT EDIT.\n\n")
|
||||
fmt.Fprintf(&b, "package %s\n\n", pkgName)
|
||||
@@ -26,6 +29,23 @@ func GenerateGoSchema(schema parser.Schema, pkgName string) ([]byte, error) {
|
||||
}
|
||||
b.WriteString(")\n\n")
|
||||
|
||||
if needsLengthGuards {
|
||||
b.WriteString("func arpackEnsureUint16Length(length int, context string) uint16 {\n")
|
||||
b.WriteString("\tif length > 65535 {\n")
|
||||
b.WriteString("\t\tpanic(\"arpack: \" + context + \" exceeds uint16 limit\")\n")
|
||||
b.WriteString("\t}\n")
|
||||
b.WriteString("\treturn uint16(length)\n")
|
||||
b.WriteString("}\n\n")
|
||||
}
|
||||
|
||||
if needsQuantGuards {
|
||||
b.WriteString("func arpackEnsureQuantizedRange(value float64, min float64, max float64, context string) {\n")
|
||||
b.WriteString("\tif value != value || value < min || value > max {\n")
|
||||
b.WriteString("\t\tpanic(\"arpack: quantized value out of range for \" + context)\n")
|
||||
b.WriteString("\t}\n")
|
||||
b.WriteString("}\n\n")
|
||||
}
|
||||
|
||||
for _, msg := range messages {
|
||||
if err := writeGoMessage(&b, msg); err != nil {
|
||||
return nil, fmt.Errorf("message %s: %w", msg.Name, err)
|
||||
@@ -119,7 +139,8 @@ func writeGoMarshalField(b *strings.Builder, recv string, f parser.Field, indent
|
||||
}
|
||||
fmt.Fprintf(b, "%s}\n", indent)
|
||||
case parser.KindSlice:
|
||||
fmt.Fprintf(b, "%sbuf = binary.LittleEndian.AppendUint16(buf, uint16(len(%s)))\n", indent, access)
|
||||
fmt.Fprintf(b, "%sbuf = binary.LittleEndian.AppendUint16(buf, arpackEnsureUint16Length(len(%s), %q))\n",
|
||||
indent, access, lengthContext(f))
|
||||
fmt.Fprintf(b, "%sfor _i%s := range %s {\n", indent, f.Name, access)
|
||||
elemField := parser.Field{
|
||||
Name: f.Name + "[_i" + f.Name + "]",
|
||||
@@ -168,7 +189,8 @@ func writeGoMarshalPrimitive(b *strings.Builder, access string, f parser.Field,
|
||||
case parser.KindUint64:
|
||||
fmt.Fprintf(b, "%sbuf = binary.LittleEndian.AppendUint64(buf, %s)\n", indent, valueExpr)
|
||||
case parser.KindString:
|
||||
fmt.Fprintf(b, "%sbuf = binary.LittleEndian.AppendUint16(buf, uint16(len(%s)))\n", indent, valueExpr)
|
||||
fmt.Fprintf(b, "%sbuf = binary.LittleEndian.AppendUint16(buf, arpackEnsureUint16Length(len(%s), %q))\n",
|
||||
indent, valueExpr, lengthContext(f))
|
||||
fmt.Fprintf(b, "%sbuf = append(buf, %s...)\n", indent, valueExpr)
|
||||
}
|
||||
return nil
|
||||
@@ -178,6 +200,8 @@ func writeGoMarshalQuant(b *strings.Builder, access string, f parser.Field, inde
|
||||
q := f.Quant
|
||||
varName := "_q" + sanitizeVarName(access)
|
||||
valueExpr := goMarshalValueExpr(access, f)
|
||||
fmt.Fprintf(b, "%sarpackEnsureQuantizedRange(float64(%s), %g, %g, %q)\n",
|
||||
indent, valueExpr, q.Min, q.Max, quantContext(f))
|
||||
if q.Bits == 8 {
|
||||
fmt.Fprintf(b, "%s%s := uint8((%s - (%g)) / (%g - (%g)) * %g)\n",
|
||||
indent, varName, valueExpr, q.Min, q.Max, q.Min, q.MaxUint())
|
||||
|
||||
@@ -0,0 +1,780 @@
|
||||
package generator
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/edmand46/arpack/parser"
|
||||
)
|
||||
|
||||
func GenerateLuaSchema(schema parser.Schema, moduleName string) ([]byte, error) {
|
||||
if err := checkLuaUnsupportedTypes(schema); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
messages := schema.Messages
|
||||
var b strings.Builder
|
||||
|
||||
b.WriteString("-- <auto-generated> arpack </auto-generated>\n")
|
||||
b.WriteString("-- Code generated by arpack. DO NOT EDIT.\n\n")
|
||||
|
||||
b.WriteString("local M = {}\n\n")
|
||||
b.WriteString("-- Load BitOp library for bit operations (Defold/LuaJIT)\n")
|
||||
b.WriteString("local bit = require('bit')\n\n")
|
||||
|
||||
writeLuaHelpers(&b)
|
||||
|
||||
enumNames := make(map[string]struct{}, len(schema.Enums))
|
||||
for _, enum := range schema.Enums {
|
||||
enumNames[enum.Name] = struct{}{}
|
||||
}
|
||||
|
||||
for _, enum := range schema.Enums {
|
||||
writeLuaEnum(&b, enum)
|
||||
b.WriteString("\n")
|
||||
}
|
||||
|
||||
for _, msg := range messages {
|
||||
writeLuaConstructor(&b, msg, enumNames)
|
||||
b.WriteString("\n")
|
||||
}
|
||||
|
||||
for _, msg := range messages {
|
||||
if err := writeLuaSerializer(&b, msg, enumNames); err != nil {
|
||||
return nil, fmt.Errorf("message %s: %w", msg.Name, err)
|
||||
}
|
||||
b.WriteString("\n")
|
||||
}
|
||||
|
||||
for _, msg := range messages {
|
||||
if err := writeLuaDeserializer(&b, msg, enumNames); err != nil {
|
||||
return nil, fmt.Errorf("message %s: %w", msg.Name, err)
|
||||
}
|
||||
b.WriteString("\n")
|
||||
}
|
||||
|
||||
b.WriteString("return M\n")
|
||||
|
||||
return []byte(b.String()), nil
|
||||
}
|
||||
|
||||
func writeLuaHelpers(b *strings.Builder) {
|
||||
b.WriteString("-- Inline helpers for little-endian byte operations\n\n")
|
||||
|
||||
b.WriteString("-- Error handling for truncated data\n")
|
||||
b.WriteString("local function check_bounds(data, offset, needed, context)\n")
|
||||
b.WriteString(" local available = #data - offset + 1\n")
|
||||
b.WriteString(" if available < needed then\n")
|
||||
b.WriteString(" error(string.format(\"arpack: buffer too short for %s: need %d bytes, have %d\", context, needed, available))\n")
|
||||
b.WriteString(" end\n")
|
||||
b.WriteString("end\n\n")
|
||||
|
||||
b.WriteString("local function ensure_u16_limit(n, context)\n")
|
||||
b.WriteString(" if n < 0 or n > 65535 then\n")
|
||||
b.WriteString(" error(string.format(\"arpack: %s exceeds uint16 limit: %d\", context, n))\n")
|
||||
b.WriteString(" end\n")
|
||||
b.WriteString(" return n\n")
|
||||
b.WriteString("end\n\n")
|
||||
|
||||
b.WriteString("local function ensure_quant_range(value, min, max, context)\n")
|
||||
b.WriteString(" if value ~= value or value < min or value > max then\n")
|
||||
b.WriteString(" error(string.format(\"arpack: quantized value out of range for %s\", context))\n")
|
||||
b.WriteString(" end\n")
|
||||
b.WriteString(" return value\n")
|
||||
b.WriteString("end\n\n")
|
||||
|
||||
b.WriteString("local function read_u8(data, offset)\n")
|
||||
b.WriteString(" if offset > #data then error(\"arpack: buffer too short for u8\") end\n")
|
||||
b.WriteString(" return string.byte(data, offset), 1\n")
|
||||
b.WriteString("end\n\n")
|
||||
|
||||
b.WriteString("local function write_u8(n)\n")
|
||||
b.WriteString(" return string.char(n)\n")
|
||||
b.WriteString("end\n\n")
|
||||
|
||||
b.WriteString("local function read_u16_le(data, offset)\n")
|
||||
b.WriteString(" local b1, b2 = string.byte(data, offset, offset + 1)\n")
|
||||
b.WriteString(" if not b2 then error(\"arpack: buffer too short for u16\") end\n")
|
||||
b.WriteString(" return b1 + b2 * 256, 2\n")
|
||||
b.WriteString("end\n\n")
|
||||
|
||||
b.WriteString("local function write_u16_le(n)\n")
|
||||
b.WriteString(" return string.char(n % 256, math.floor(n / 256))\n")
|
||||
b.WriteString("end\n\n")
|
||||
|
||||
b.WriteString("local function read_u32_le(data, offset)\n")
|
||||
b.WriteString(" local b1, b2, b3, b4 = string.byte(data, offset, offset + 3)\n")
|
||||
b.WriteString(" if not b4 then error(\"arpack: buffer too short for u32\") end\n")
|
||||
b.WriteString(" return b1 + b2 * 256 + b3 * 65536 + b4 * 16777216, 4\n")
|
||||
b.WriteString("end\n\n")
|
||||
|
||||
b.WriteString("local function write_u32_le(n)\n")
|
||||
b.WriteString(" return string.char(\n")
|
||||
b.WriteString(" n % 256,\n")
|
||||
b.WriteString(" math.floor(n / 256) % 256,\n")
|
||||
b.WriteString(" math.floor(n / 65536) % 256,\n")
|
||||
b.WriteString(" math.floor(n / 16777216) % 256\n")
|
||||
b.WriteString(" )\n")
|
||||
b.WriteString("end\n\n")
|
||||
|
||||
b.WriteString("local function read_i8(data, offset)\n")
|
||||
b.WriteString(" if offset > #data then error(\"arpack: buffer too short for i8\") end\n")
|
||||
b.WriteString(" local v = string.byte(data, offset)\n")
|
||||
b.WriteString(" if v >= 128 then v = v - 256 end\n")
|
||||
b.WriteString(" return v, 1\n")
|
||||
b.WriteString("end\n\n")
|
||||
|
||||
b.WriteString("local function write_i8(n)\n")
|
||||
b.WriteString(" if n < 0 then n = n + 256 end\n")
|
||||
b.WriteString(" return string.char(n)\n")
|
||||
b.WriteString("end\n\n")
|
||||
|
||||
b.WriteString("local function read_i16_le(data, offset)\n")
|
||||
b.WriteString(" local v = read_u16_le(data, offset)\n")
|
||||
b.WriteString(" if v >= 32768 then v = v - 65536 end\n")
|
||||
b.WriteString(" return v, 2\n")
|
||||
b.WriteString("end\n\n")
|
||||
|
||||
b.WriteString("local function write_i16_le(n)\n")
|
||||
b.WriteString(" if n < 0 then n = n + 65536 end\n")
|
||||
b.WriteString(" return write_u16_le(n)\n")
|
||||
b.WriteString("end\n\n")
|
||||
|
||||
b.WriteString("local function read_i32_le(data, offset)\n")
|
||||
b.WriteString(" local v = read_u32_le(data, offset)\n")
|
||||
b.WriteString(" if v >= 2147483648 then v = v - 4294967296 end\n")
|
||||
b.WriteString(" return v, 4\n")
|
||||
b.WriteString("end\n\n")
|
||||
|
||||
b.WriteString("local function write_i32_le(n)\n")
|
||||
b.WriteString(" if n < 0 then n = n + 4294967296 end\n")
|
||||
b.WriteString(" return write_u32_le(n)\n")
|
||||
b.WriteString("end\n\n")
|
||||
|
||||
b.WriteString("local function read_f32_le(data, offset)\n")
|
||||
b.WriteString(" local u32 = read_u32_le(data, offset)\n")
|
||||
b.WriteString(" if u32 == 0 then return 0.0, 4 end\n")
|
||||
b.WriteString(" local sign = (u32 >= 2147483648) and -1 or 1\n")
|
||||
b.WriteString(" if sign < 0 then u32 = u32 - 2147483648 end\n")
|
||||
b.WriteString(" local exp = math.floor(u32 / 8388608) % 256\n")
|
||||
b.WriteString(" local mant = u32 % 8388608\n")
|
||||
b.WriteString(" if exp == 0 then\n")
|
||||
b.WriteString(" if mant == 0 then\n")
|
||||
b.WriteString(" return sign < 0 and (-1 / math.huge) or 0.0, 4\n")
|
||||
b.WriteString(" end\n")
|
||||
b.WriteString(" return sign * (mant / 8388608) * math.pow(2, -126), 4\n")
|
||||
b.WriteString(" elseif exp == 255 then\n")
|
||||
b.WriteString(" if mant == 0 then return sign * math.huge, 4\n")
|
||||
b.WriteString(" else return 0.0 / 0.0, 4 end\n")
|
||||
b.WriteString(" end\n")
|
||||
b.WriteString(" return sign * (1 + mant / 8388608) * math.pow(2, exp - 127), 4\n")
|
||||
b.WriteString("end\n\n")
|
||||
|
||||
b.WriteString("local function write_f32_le(n)\n")
|
||||
b.WriteString(" if n ~= n then return write_u32_le(2143289344) end\n")
|
||||
b.WriteString(" if n == math.huge then return write_u32_le(2139095040) end\n")
|
||||
b.WriteString(" if n == -math.huge then return write_u32_le(4286578688) end\n")
|
||||
b.WriteString(" -- Check for negative zero: 1/-0.0 == -math.huge\n")
|
||||
b.WriteString(" if n == 0 then\n")
|
||||
b.WriteString(" if 1/n == -math.huge then return write_u32_le(2147483648) end\n")
|
||||
b.WriteString(" return write_u32_le(0)\n")
|
||||
b.WriteString(" end\n")
|
||||
b.WriteString(" local sign = 0\n")
|
||||
b.WriteString(" if n < 0 then sign = 2147483648; n = -n end\n")
|
||||
b.WriteString(" local exp\n")
|
||||
b.WriteString(" local mant\n")
|
||||
b.WriteString(" if n < math.pow(2, -126) then\n")
|
||||
b.WriteString(" mant = math.floor(n / math.pow(2, -149) + 0.5)\n")
|
||||
b.WriteString(" if mant <= 0 then return write_u32_le(sign) end\n")
|
||||
b.WriteString(" if mant >= 8388608 then\n")
|
||||
b.WriteString(" exp = 1\n")
|
||||
b.WriteString(" mant = 0\n")
|
||||
b.WriteString(" else\n")
|
||||
b.WriteString(" exp = 0\n")
|
||||
b.WriteString(" end\n")
|
||||
b.WriteString(" else\n")
|
||||
b.WriteString(" exp = math.floor(math.log(n, 2))\n")
|
||||
b.WriteString(" mant = math.floor((n / math.pow(2, exp) - 1) * 8388608 + 0.5)\n")
|
||||
b.WriteString(" if mant >= 8388608 then\n")
|
||||
b.WriteString(" exp = exp + 1\n")
|
||||
b.WriteString(" mant = 0\n")
|
||||
b.WriteString(" end\n")
|
||||
b.WriteString(" exp = exp + 127\n")
|
||||
b.WriteString(" if exp >= 255 then\n")
|
||||
b.WriteString(" return write_u32_le(sign + 2139095040)\n")
|
||||
b.WriteString(" end\n")
|
||||
b.WriteString(" end\n")
|
||||
b.WriteString(" return write_u32_le(sign + exp * 8388608 + mant)\n")
|
||||
b.WriteString("end\n\n")
|
||||
|
||||
b.WriteString("local function read_f64_le(data, offset)\n")
|
||||
b.WriteString(" -- Read 8 bytes directly to avoid precision loss from 64-bit arithmetic\n")
|
||||
b.WriteString(" local b1, b2, b3, b4, b5, b6, b7, b8 = string.byte(data, offset, offset + 7)\n")
|
||||
b.WriteString(" if not b8 then error(\"arpack: buffer too short for f64\") end\n")
|
||||
b.WriteString(" local low = b1 + b2 * 256 + b3 * 65536 + b4 * 16777216\n")
|
||||
b.WriteString(" local high = b5 + b6 * 256 + b7 * 65536 + b8 * 16777216\n")
|
||||
b.WriteString(" -- Decode IEEE 754 double from low/high parts separately\n")
|
||||
b.WriteString(" if low == 0 and high == 0 then return 0.0, 8 end\n")
|
||||
b.WriteString(" local sign = (high >= 2147483648) and -1 or 1\n")
|
||||
b.WriteString(" if sign < 0 then high = high - 2147483648 end\n")
|
||||
b.WriteString(" local exp = math.floor(high / 1048576) % 2048\n")
|
||||
b.WriteString(" local high_mant = high % 1048576\n")
|
||||
b.WriteString(" if exp == 0 then\n")
|
||||
b.WriteString(" local mant = high_mant * 4294967296 + low\n")
|
||||
b.WriteString(" if mant == 0 then\n")
|
||||
b.WriteString(" return sign < 0 and (-1 / math.huge) or 0.0, 8\n")
|
||||
b.WriteString(" end\n")
|
||||
b.WriteString(" return sign * (mant / 4503599627370496) * math.pow(2, -1022), 8\n")
|
||||
b.WriteString(" elseif exp == 2047 then\n")
|
||||
b.WriteString(" if high_mant == 0 and low == 0 then return sign * math.huge, 8\n")
|
||||
b.WriteString(" else return 0.0 / 0.0, 8 end\n")
|
||||
b.WriteString(" end\n")
|
||||
b.WriteString(" local mant = high_mant * 4294967296 + low\n")
|
||||
b.WriteString(" return sign * (1 + mant / 4503599627370496) * math.pow(2, exp - 1023), 8\n")
|
||||
b.WriteString("end\n\n")
|
||||
|
||||
b.WriteString("local function write_f64_le(n)\n")
|
||||
b.WriteString(" -- Handle special values\n")
|
||||
b.WriteString(" if n ~= n then -- NaN\n")
|
||||
b.WriteString(" return string.char(0, 0, 0, 0, 0, 0, 248, 127)\n")
|
||||
b.WriteString(" end\n")
|
||||
b.WriteString(" if n == math.huge then\n")
|
||||
b.WriteString(" return string.char(0, 0, 0, 0, 0, 0, 240, 127)\n")
|
||||
b.WriteString(" end\n")
|
||||
b.WriteString(" if n == -math.huge then\n")
|
||||
b.WriteString(" return string.char(0, 0, 0, 0, 0, 0, 240, 255)\n")
|
||||
b.WriteString(" end\n")
|
||||
b.WriteString(" -- Check for negative zero: 1/-0.0 == -math.huge\n")
|
||||
b.WriteString(" if n == 0 then\n")
|
||||
b.WriteString(" if 1/n == -math.huge then\n")
|
||||
b.WriteString(" return string.char(0, 0, 0, 0, 0, 0, 0, 128)\n")
|
||||
b.WriteString(" end\n")
|
||||
b.WriteString(" return string.char(0, 0, 0, 0, 0, 0, 0, 0)\n")
|
||||
b.WriteString(" end\n")
|
||||
b.WriteString(" local sign = 0\n")
|
||||
b.WriteString(" if n < 0 then sign = 2147483648; n = -n end\n")
|
||||
b.WriteString(" local exp\n")
|
||||
b.WriteString(" local mant\n")
|
||||
b.WriteString(" if n < math.pow(2, -1022) then\n")
|
||||
b.WriteString(" mant = math.floor(n / math.pow(2, -1074) + 0.5)\n")
|
||||
b.WriteString(" if mant <= 0 then\n")
|
||||
b.WriteString(" local high = sign\n")
|
||||
b.WriteString(" return string.char(0, 0, 0, 0, high % 256, math.floor(high / 256) % 256, math.floor(high / 65536) % 256, math.floor(high / 16777216) % 256)\n")
|
||||
b.WriteString(" end\n")
|
||||
b.WriteString(" if mant >= 4503599627370496 then\n")
|
||||
b.WriteString(" exp = 1\n")
|
||||
b.WriteString(" mant = 0\n")
|
||||
b.WriteString(" else\n")
|
||||
b.WriteString(" exp = 0\n")
|
||||
b.WriteString(" end\n")
|
||||
b.WriteString(" else\n")
|
||||
b.WriteString(" exp = math.floor(math.log(n, 2))\n")
|
||||
b.WriteString(" mant = (n / math.pow(2, exp) - 1) * 4503599627370496\n")
|
||||
b.WriteString(" mant = math.floor(mant + 0.5)\n")
|
||||
b.WriteString(" if mant >= 4503599627370496 then\n")
|
||||
b.WriteString(" exp = exp + 1\n")
|
||||
b.WriteString(" mant = 0\n")
|
||||
b.WriteString(" end\n")
|
||||
b.WriteString(" exp = exp + 1023\n")
|
||||
b.WriteString(" if exp >= 2047 then\n")
|
||||
b.WriteString(" exp = 2047\n")
|
||||
b.WriteString(" mant = 0\n")
|
||||
b.WriteString(" end\n")
|
||||
b.WriteString(" end\n")
|
||||
b.WriteString(" local high_mant = math.floor(mant / 4294967296)\n")
|
||||
b.WriteString(" local low = mant % 4294967296\n")
|
||||
b.WriteString(" local high = sign + exp * 1048576 + high_mant\n")
|
||||
b.WriteString(" return string.char(\n")
|
||||
b.WriteString(" low % 256,\n")
|
||||
b.WriteString(" math.floor(low / 256) % 256,\n")
|
||||
b.WriteString(" math.floor(low / 65536) % 256,\n")
|
||||
b.WriteString(" math.floor(low / 16777216) % 256,\n")
|
||||
b.WriteString(" high % 256,\n")
|
||||
b.WriteString(" math.floor(high / 256) % 256,\n")
|
||||
b.WriteString(" math.floor(high / 65536) % 256,\n")
|
||||
b.WriteString(" math.floor(high / 16777216) % 256\n")
|
||||
b.WriteString(" )\n")
|
||||
b.WriteString("end\n\n")
|
||||
|
||||
b.WriteString("local function read_bool(data, offset)\n")
|
||||
b.WriteString(" if offset > #data then error(\"arpack: buffer too short for bool\") end\n")
|
||||
b.WriteString(" return string.byte(data, offset) ~= 0, 1\n")
|
||||
b.WriteString("end\n\n")
|
||||
|
||||
b.WriteString("local function write_bool(v)\n")
|
||||
b.WriteString(" return string.char(v and 1 or 0)\n")
|
||||
b.WriteString("end\n\n")
|
||||
|
||||
b.WriteString("local function read_string(data, offset)\n")
|
||||
b.WriteString(" local len, header_bytes = read_u16_le(data, offset)\n")
|
||||
b.WriteString(" if len == 0 then return '', header_bytes end\n")
|
||||
b.WriteString(" local available = #data - offset - header_bytes + 1\n")
|
||||
b.WriteString(" if available < len then\n")
|
||||
b.WriteString(" error(string.format(\"arpack: buffer too short for string: need %d bytes, have %d\", len, available))\n")
|
||||
b.WriteString(" end\n")
|
||||
b.WriteString(" -- string.sub is 1-based; data starts at offset + header_bytes\n")
|
||||
b.WriteString(" return string.sub(data, offset + header_bytes, offset + header_bytes + len - 1), header_bytes + len\n")
|
||||
b.WriteString("end\n\n")
|
||||
|
||||
b.WriteString("local function write_string(s)\n")
|
||||
b.WriteString(" local len = #s\n")
|
||||
b.WriteString(" ensure_u16_limit(len, \"string length\")\n")
|
||||
b.WriteString(" return write_u16_le(len) .. s\n")
|
||||
b.WriteString("end\n\n")
|
||||
}
|
||||
|
||||
func writeLuaEnum(b *strings.Builder, enum parser.Enum) {
|
||||
fmt.Fprintf(b, "M.%s = {\n", enum.Name)
|
||||
for i, value := range enum.Values {
|
||||
fmt.Fprintf(b, " %s = %s", value.Name, value.Value)
|
||||
if i < len(enum.Values)-1 {
|
||||
b.WriteString(",")
|
||||
}
|
||||
b.WriteString("\n")
|
||||
}
|
||||
b.WriteString("}\n")
|
||||
}
|
||||
|
||||
func writeLuaConstructor(b *strings.Builder, msg parser.Message, enumNames map[string]struct{}) {
|
||||
fmt.Fprintf(b, "function M.new_%s()\n", toSnakeCase(msg.Name))
|
||||
b.WriteString(" return {\n")
|
||||
for _, f := range msg.Fields {
|
||||
defaultValue := luaDefaultValue(f, enumNames)
|
||||
fmt.Fprintf(b, " %s = %s,\n", luaFieldName(f.Name), defaultValue)
|
||||
}
|
||||
b.WriteString(" }\n")
|
||||
b.WriteString("end\n")
|
||||
}
|
||||
|
||||
func writeLuaSerializer(b *strings.Builder, msg parser.Message, enumNames map[string]struct{}) error {
|
||||
segs := segmentFields(msg.Fields)
|
||||
|
||||
fmt.Fprintf(b, "function M.serialize_%s(msg)\n", toSnakeCase(msg.Name))
|
||||
b.WriteString(" local parts = {}\n")
|
||||
b.WriteString(" local part_idx = 0\n")
|
||||
|
||||
for i, seg := range segs {
|
||||
if seg.single != nil {
|
||||
if err := writeLuaSerializeField(b, "msg", *seg.single, " ", enumNames); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
writeLuaBoolGroupSerialize(b, "msg", seg.bools, i, " ")
|
||||
}
|
||||
}
|
||||
|
||||
b.WriteString(" return table.concat(parts)\n")
|
||||
b.WriteString("end\n")
|
||||
return nil
|
||||
}
|
||||
|
||||
func writeLuaDeserializer(b *strings.Builder, msg parser.Message, enumNames map[string]struct{}) error {
|
||||
segs := segmentFields(msg.Fields)
|
||||
minSize := packedMinWireSize(msg.Fields)
|
||||
|
||||
fmt.Fprintf(b, "function M.deserialize_%s(data, offset)\n", toSnakeCase(msg.Name))
|
||||
b.WriteString(" offset = offset or 1\n")
|
||||
fmt.Fprintf(b, " local msg = M.new_%s()\n", toSnakeCase(msg.Name))
|
||||
b.WriteString(" local start_offset = offset\n")
|
||||
b.WriteString(" local bytes_read = 0\n")
|
||||
fmt.Fprintf(b, " if #data < offset + %d - 1 then\n", minSize)
|
||||
fmt.Fprintf(b, " error(\"arpack: buffer too short for %s\")\n", msg.Name)
|
||||
b.WriteString(" end\n")
|
||||
|
||||
for i, seg := range segs {
|
||||
if seg.single != nil {
|
||||
if err := writeLuaDeserializeField(b, "msg", *seg.single, " ", enumNames); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
writeLuaBoolGroupDeserialize(b, "msg", seg.bools, i, " ")
|
||||
}
|
||||
}
|
||||
|
||||
b.WriteString(" return msg, offset - start_offset\n")
|
||||
b.WriteString("end\n")
|
||||
return nil
|
||||
}
|
||||
|
||||
func writeLuaBoolGroupSerialize(b *strings.Builder, recv string, bools []parser.Field, groupIdx int, indent string) {
|
||||
varName := fmt.Sprintf("_bool_byte_%d", groupIdx)
|
||||
fmt.Fprintf(b, "%slocal %s = 0\n", indent, varName)
|
||||
for bit, f := range bools {
|
||||
fmt.Fprintf(b, "%sif %s.%s then %s = bit.bor(%s, %d) end\n",
|
||||
indent, recv, luaFieldName(f.Name), varName, varName, 1<<bit)
|
||||
}
|
||||
fmt.Fprintf(b, "%spart_idx = part_idx + 1; parts[part_idx] = write_u8(%s)\n", indent, varName)
|
||||
}
|
||||
|
||||
func writeLuaBoolGroupDeserialize(b *strings.Builder, recv string, bools []parser.Field, groupIdx int, indent string) {
|
||||
varName := fmt.Sprintf("_bool_byte_%d", groupIdx)
|
||||
fmt.Fprintf(b, "%sif #data < offset then error(\"arpack: buffer too short for bool group\") end\n", indent)
|
||||
fmt.Fprintf(b, "%slocal %s = string.byte(data, offset)\n", indent, varName)
|
||||
fmt.Fprintf(b, "%soffset = offset + 1\n", indent)
|
||||
for bit, f := range bools {
|
||||
fmt.Fprintf(b, "%s%s.%s = bit.band(%s, %d) ~= 0\n",
|
||||
indent, recv, luaFieldName(f.Name), varName, 1<<bit)
|
||||
}
|
||||
}
|
||||
|
||||
func writeLuaSerializeField(b *strings.Builder, recv string, f parser.Field, indent string, enumNames map[string]struct{}) error {
|
||||
access := recv + "." + luaFieldName(f.Name)
|
||||
switch f.Kind {
|
||||
case parser.KindPrimitive:
|
||||
return writeLuaSerializePrimitive(b, access, f, indent, enumNames)
|
||||
case parser.KindNested:
|
||||
fmt.Fprintf(b, "%slocal _nested_%s = M.serialize_%s(%s)\n", indent, f.Name, toSnakeCase(f.TypeName), access)
|
||||
fmt.Fprintf(b, "%spart_idx = part_idx + 1; parts[part_idx] = _nested_%s\n", indent, f.Name)
|
||||
case parser.KindFixedArray:
|
||||
iVar := "_i_" + strings.ToLower(f.Name)
|
||||
fmt.Fprintf(b, "%sfor %s = 1, %d do\n", indent, iVar, f.FixedLen)
|
||||
elemField := parser.Field{
|
||||
Name: f.Name + "[" + iVar + "]",
|
||||
Kind: f.Elem.Kind,
|
||||
Primitive: f.Elem.Primitive,
|
||||
NamedType: f.Elem.NamedType,
|
||||
Quant: f.Elem.Quant,
|
||||
TypeName: f.Elem.TypeName,
|
||||
Elem: f.Elem.Elem,
|
||||
FixedLen: f.Elem.FixedLen,
|
||||
}
|
||||
if err := writeLuaSerializeField(b, recv, elemField, indent+" ", enumNames); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Fprintf(b, "%send\n", indent)
|
||||
case parser.KindSlice:
|
||||
lenVar := "_len_" + strings.ToLower(f.Name)
|
||||
fmt.Fprintf(b, "%slocal %s = #(%s or {})\n", indent, lenVar, access)
|
||||
fmt.Fprintf(b, "%s%s = ensure_u16_limit(%s, %q)\n", indent, lenVar, lenVar, "slice length for "+luaFieldName(f.Name))
|
||||
fmt.Fprintf(b, "%spart_idx = part_idx + 1; parts[part_idx] = write_u16_le(%s)\n", indent, lenVar)
|
||||
iVar := "_i_" + strings.ToLower(f.Name)
|
||||
fmt.Fprintf(b, "%sfor %s = 1, %s do\n", indent, iVar, lenVar)
|
||||
|
||||
if f.Elem.Kind == parser.KindNested {
|
||||
// For nested types in slices, serialize directly
|
||||
fmt.Fprintf(b, "%slocal _nested_%s = M.serialize_%s(%s[%s])\n",
|
||||
indent, f.Name, toSnakeCase(f.Elem.TypeName), access, iVar)
|
||||
fmt.Fprintf(b, "%spart_idx = part_idx + 1; parts[part_idx] = _nested_%s\n",
|
||||
indent, f.Name)
|
||||
} else {
|
||||
elemField := parser.Field{
|
||||
Name: f.Name + "[" + iVar + "]",
|
||||
Kind: f.Elem.Kind,
|
||||
Primitive: f.Elem.Primitive,
|
||||
NamedType: f.Elem.NamedType,
|
||||
Quant: f.Elem.Quant,
|
||||
TypeName: f.Elem.TypeName,
|
||||
Elem: f.Elem.Elem,
|
||||
FixedLen: f.Elem.FixedLen,
|
||||
}
|
||||
if err := writeLuaSerializeField(b, recv, elemField, indent+" ", enumNames); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
fmt.Fprintf(b, "%send\n", indent)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func writeLuaSerializePrimitive(b *strings.Builder, access string, f parser.Field, indent string, enumNames map[string]struct{}) error {
|
||||
if f.Quant != nil {
|
||||
return writeLuaSerializeQuant(b, access, f, indent)
|
||||
}
|
||||
|
||||
valueExpr := luaSerializeValueExpr(access, f, enumNames)
|
||||
switch f.Primitive {
|
||||
case parser.KindFloat32:
|
||||
fmt.Fprintf(b, "%spart_idx = part_idx + 1; parts[part_idx] = write_f32_le(%s)\n", indent, valueExpr)
|
||||
case parser.KindFloat64:
|
||||
fmt.Fprintf(b, "%spart_idx = part_idx + 1; parts[part_idx] = write_f64_le(%s)\n", indent, valueExpr)
|
||||
case parser.KindInt8:
|
||||
fmt.Fprintf(b, "%spart_idx = part_idx + 1; parts[part_idx] = write_i8(%s)\n", indent, valueExpr)
|
||||
case parser.KindUint8:
|
||||
fmt.Fprintf(b, "%spart_idx = part_idx + 1; parts[part_idx] = write_u8(%s)\n", indent, valueExpr)
|
||||
case parser.KindBool:
|
||||
fmt.Fprintf(b, "%spart_idx = part_idx + 1; parts[part_idx] = write_bool(%s)\n", indent, valueExpr)
|
||||
case parser.KindInt16:
|
||||
fmt.Fprintf(b, "%spart_idx = part_idx + 1; parts[part_idx] = write_i16_le(%s)\n", indent, valueExpr)
|
||||
case parser.KindUint16:
|
||||
fmt.Fprintf(b, "%spart_idx = part_idx + 1; parts[part_idx] = write_u16_le(%s)\n", indent, valueExpr)
|
||||
case parser.KindInt32:
|
||||
fmt.Fprintf(b, "%spart_idx = part_idx + 1; parts[part_idx] = write_i32_le(%s)\n", indent, valueExpr)
|
||||
case parser.KindUint32:
|
||||
fmt.Fprintf(b, "%spart_idx = part_idx + 1; parts[part_idx] = write_u32_le(%s)\n", indent, valueExpr)
|
||||
case parser.KindInt64, parser.KindUint64:
|
||||
return fmt.Errorf("int64/uint64 serialization not supported in Lua")
|
||||
case parser.KindString:
|
||||
fmt.Fprintf(b, "%spart_idx = part_idx + 1; parts[part_idx] = write_string(%s or '')\n", indent, valueExpr)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func writeLuaSerializeQuant(b *strings.Builder, access string, f parser.Field, indent string) error {
|
||||
q := f.Quant
|
||||
maxUint := q.MaxUint()
|
||||
varName := "_q_" + sanitizeLuaVarName(access)
|
||||
valueVar := "_quant_value_" + sanitizeLuaVarName(access)
|
||||
fmt.Fprintf(b, "%slocal %s = ensure_quant_range(%s, %g, %g, %q)\n",
|
||||
indent, valueVar, access, q.Min, q.Max, quantContext(f))
|
||||
fmt.Fprintf(b, "%slocal %s = math.floor(((%s - (%g)) / (%g - (%g))) * %g)\n",
|
||||
indent, varName, valueVar, q.Min, q.Max, q.Min, maxUint)
|
||||
if q.Bits == 8 {
|
||||
fmt.Fprintf(b, "%spart_idx = part_idx + 1; parts[part_idx] = write_u8(%s)\n", indent, varName)
|
||||
} else {
|
||||
fmt.Fprintf(b, "%spart_idx = part_idx + 1; parts[part_idx] = write_u16_le(%s)\n", indent, varName)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func writeLuaDeserializeField(b *strings.Builder, recv string, f parser.Field, indent string, enumNames map[string]struct{}) error {
|
||||
access := recv + "." + luaFieldName(f.Name)
|
||||
switch f.Kind {
|
||||
case parser.KindPrimitive:
|
||||
return writeLuaDeserializePrimitive(b, access, f, indent, enumNames)
|
||||
case parser.KindNested:
|
||||
fmt.Fprintf(b, "%slocal _nested_%s, _n_%s = M.deserialize_%s(data, offset)\n", indent, f.Name, f.Name, toSnakeCase(f.TypeName))
|
||||
fmt.Fprintf(b, "%s%s = _nested_%s\n", indent, access, f.Name)
|
||||
fmt.Fprintf(b, "%soffset = offset + _n_%s\n", indent, f.Name)
|
||||
case parser.KindFixedArray:
|
||||
iVar := "_i_" + strings.ToLower(f.Name)
|
||||
fmt.Fprintf(b, "%s%s = {}\n", indent, access)
|
||||
fmt.Fprintf(b, "%sfor %s = 1, %d do\n", indent, iVar, f.FixedLen)
|
||||
elemField := parser.Field{
|
||||
Name: f.Name + "[" + iVar + "]",
|
||||
Kind: f.Elem.Kind,
|
||||
Primitive: f.Elem.Primitive,
|
||||
NamedType: f.Elem.NamedType,
|
||||
Quant: f.Elem.Quant,
|
||||
TypeName: f.Elem.TypeName,
|
||||
Elem: f.Elem.Elem,
|
||||
FixedLen: f.Elem.FixedLen,
|
||||
}
|
||||
if err := writeLuaDeserializeField(b, recv, elemField, indent+" ", enumNames); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Fprintf(b, "%send\n", indent)
|
||||
case parser.KindSlice:
|
||||
lenVar := "_len_" + strings.ToLower(f.Name)
|
||||
fmt.Fprintf(b, "%slocal %s = read_u16_le(data, offset)\n", indent, lenVar)
|
||||
fmt.Fprintf(b, "%soffset = offset + 2\n", indent)
|
||||
fmt.Fprintf(b, "%s%s = {}\n", indent, access)
|
||||
iVar := "_i_" + strings.ToLower(f.Name)
|
||||
fmt.Fprintf(b, "%sfor %s = 1, %s do\n", indent, iVar, lenVar)
|
||||
|
||||
if f.Elem.Kind == parser.KindNested {
|
||||
// For nested types in slices, deserialize directly
|
||||
fmt.Fprintf(b, "%slocal _nested_%s, _n_%s = M.deserialize_%s(data, offset)\n",
|
||||
indent, f.Name, f.Name, toSnakeCase(f.Elem.TypeName))
|
||||
fmt.Fprintf(b, "%s%s[%s] = _nested_%s\n",
|
||||
indent, access, iVar, f.Name)
|
||||
fmt.Fprintf(b, "%soffset = offset + _n_%s\n",
|
||||
indent, f.Name)
|
||||
} else {
|
||||
elemField := parser.Field{
|
||||
Name: f.Name + "[" + iVar + "]",
|
||||
Kind: f.Elem.Kind,
|
||||
Primitive: f.Elem.Primitive,
|
||||
NamedType: f.Elem.NamedType,
|
||||
Quant: f.Elem.Quant,
|
||||
TypeName: f.Elem.TypeName,
|
||||
Elem: f.Elem.Elem,
|
||||
FixedLen: f.Elem.FixedLen,
|
||||
}
|
||||
if err := writeLuaDeserializeField(b, recv, elemField, indent+" ", enumNames); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
fmt.Fprintf(b, "%send\n", indent)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func writeLuaDeserializePrimitive(b *strings.Builder, access string, f parser.Field, indent string, enumNames map[string]struct{}) error {
|
||||
if f.Quant != nil {
|
||||
return writeLuaDeserializeQuant(b, access, f, indent, enumNames)
|
||||
}
|
||||
|
||||
varName := "_v_" + sanitizeLuaVarName(access)
|
||||
switch f.Primitive {
|
||||
case parser.KindFloat32:
|
||||
fmt.Fprintf(b, "%slocal %s, _n = read_f32_le(data, offset)\n", indent, varName)
|
||||
fmt.Fprintf(b, "%s%s = %s\n", indent, access, luaDeserializeValueExpr(varName, f, enumNames))
|
||||
fmt.Fprintf(b, "%soffset = offset + _n\n", indent)
|
||||
case parser.KindFloat64:
|
||||
fmt.Fprintf(b, "%slocal %s, _n = read_f64_le(data, offset)\n", indent, varName)
|
||||
fmt.Fprintf(b, "%s%s = %s\n", indent, access, luaDeserializeValueExpr(varName, f, enumNames))
|
||||
fmt.Fprintf(b, "%soffset = offset + _n\n", indent)
|
||||
case parser.KindInt8:
|
||||
fmt.Fprintf(b, "%slocal %s, _n = read_i8(data, offset)\n", indent, varName)
|
||||
fmt.Fprintf(b, "%s%s = %s\n", indent, access, luaDeserializeValueExpr(varName, f, enumNames))
|
||||
fmt.Fprintf(b, "%soffset = offset + _n\n", indent)
|
||||
case parser.KindUint8:
|
||||
fmt.Fprintf(b, "%slocal %s, _n = read_u8(data, offset)\n", indent, varName)
|
||||
fmt.Fprintf(b, "%s%s = %s\n", indent, access, luaDeserializeValueExpr(varName, f, enumNames))
|
||||
fmt.Fprintf(b, "%soffset = offset + _n\n", indent)
|
||||
case parser.KindBool:
|
||||
fmt.Fprintf(b, "%slocal %s, _n = read_bool(data, offset)\n", indent, varName)
|
||||
fmt.Fprintf(b, "%s%s = %s\n", indent, access, luaDeserializeValueExpr(varName, f, enumNames))
|
||||
fmt.Fprintf(b, "%soffset = offset + _n\n", indent)
|
||||
case parser.KindInt16:
|
||||
fmt.Fprintf(b, "%slocal %s, _n = read_i16_le(data, offset)\n", indent, varName)
|
||||
fmt.Fprintf(b, "%s%s = %s\n", indent, access, luaDeserializeValueExpr(varName, f, enumNames))
|
||||
fmt.Fprintf(b, "%soffset = offset + _n\n", indent)
|
||||
case parser.KindUint16:
|
||||
fmt.Fprintf(b, "%slocal %s, _n = read_u16_le(data, offset)\n", indent, varName)
|
||||
fmt.Fprintf(b, "%s%s = %s\n", indent, access, luaDeserializeValueExpr(varName, f, enumNames))
|
||||
fmt.Fprintf(b, "%soffset = offset + _n\n", indent)
|
||||
case parser.KindInt32:
|
||||
fmt.Fprintf(b, "%slocal %s, _n = read_i32_le(data, offset)\n", indent, varName)
|
||||
fmt.Fprintf(b, "%s%s = %s\n", indent, access, luaDeserializeValueExpr(varName, f, enumNames))
|
||||
fmt.Fprintf(b, "%soffset = offset + _n\n", indent)
|
||||
case parser.KindUint32:
|
||||
fmt.Fprintf(b, "%slocal %s, _n = read_u32_le(data, offset)\n", indent, varName)
|
||||
fmt.Fprintf(b, "%s%s = %s\n", indent, access, luaDeserializeValueExpr(varName, f, enumNames))
|
||||
fmt.Fprintf(b, "%soffset = offset + _n\n", indent)
|
||||
case parser.KindInt64, parser.KindUint64:
|
||||
return fmt.Errorf("int64/uint64 deserialization not supported in Lua")
|
||||
case parser.KindString:
|
||||
fmt.Fprintf(b, "%slocal %s, _n = read_string(data, offset)\n", indent, varName)
|
||||
fmt.Fprintf(b, "%s%s = %s\n", indent, access, luaDeserializeValueExpr(varName, f, enumNames))
|
||||
fmt.Fprintf(b, "%soffset = offset + _n\n", indent)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func writeLuaDeserializeQuant(b *strings.Builder, access string, f parser.Field, indent string, enumNames map[string]struct{}) error {
|
||||
q := f.Quant
|
||||
maxUint := q.MaxUint()
|
||||
varName := "_q_" + sanitizeLuaVarName(access)
|
||||
if q.Bits == 8 {
|
||||
fmt.Fprintf(b, "%slocal %s = read_u8(data, offset)\n", indent, varName)
|
||||
fmt.Fprintf(b, "%soffset = offset + 1\n", indent)
|
||||
} else {
|
||||
fmt.Fprintf(b, "%slocal %s = read_u16_le(data, offset)\n", indent, varName)
|
||||
fmt.Fprintf(b, "%soffset = offset + 2\n", indent)
|
||||
}
|
||||
expr := fmt.Sprintf("%s / %g * (%g - (%g)) + (%g)", varName, maxUint, q.Max, q.Min, q.Min)
|
||||
fmt.Fprintf(b, "%s%s = %s\n", indent, access, luaDeserializeValueExpr(expr, f, enumNames))
|
||||
return nil
|
||||
}
|
||||
|
||||
func luaFieldName(name string) string {
|
||||
return toSnakeCase(name)
|
||||
}
|
||||
|
||||
func toSnakeCase(s string) string {
|
||||
if s == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
var b strings.Builder
|
||||
var prevUpper bool
|
||||
|
||||
for i, c := range s {
|
||||
isUpper := c >= 'A' && c <= 'Z'
|
||||
|
||||
// Add underscore before uppercase letter if:
|
||||
// - It's not the first character
|
||||
// - Previous character was lowercase, OR
|
||||
// - Previous character was uppercase AND next character (if exists) is lowercase
|
||||
// (this handles cases like "PlayerID" -> "player_id", not "player_i_d")
|
||||
if i > 0 && isUpper {
|
||||
nextLower := false
|
||||
if i+1 < len(s) {
|
||||
nextChar := rune(s[i+1])
|
||||
nextLower = nextChar >= 'a' && nextChar <= 'z'
|
||||
}
|
||||
|
||||
if !prevUpper || nextLower {
|
||||
b.WriteByte('_')
|
||||
}
|
||||
}
|
||||
|
||||
b.WriteRune(c)
|
||||
prevUpper = isUpper
|
||||
}
|
||||
|
||||
return strings.ToLower(b.String())
|
||||
}
|
||||
|
||||
func luaDefaultValue(f parser.Field, enumNames map[string]struct{}) string {
|
||||
switch f.Kind {
|
||||
case parser.KindPrimitive:
|
||||
if luaIsEnumType(f, enumNames) {
|
||||
return "0"
|
||||
}
|
||||
switch f.Primitive {
|
||||
case parser.KindFloat32, parser.KindFloat64, parser.KindInt8, parser.KindInt16, parser.KindInt32,
|
||||
parser.KindUint8, parser.KindUint16, parser.KindUint32, parser.KindInt64, parser.KindUint64:
|
||||
return "0"
|
||||
case parser.KindBool:
|
||||
return "false"
|
||||
case parser.KindString:
|
||||
return "''"
|
||||
}
|
||||
case parser.KindNested:
|
||||
return fmt.Sprintf("M.new_%s()", toSnakeCase(f.TypeName))
|
||||
case parser.KindFixedArray, parser.KindSlice:
|
||||
return "{}"
|
||||
}
|
||||
return "nil"
|
||||
}
|
||||
|
||||
func luaSerializeValueExpr(access string, f parser.Field, enumNames map[string]struct{}) string {
|
||||
if !luaIsEnumType(f, enumNames) {
|
||||
return access
|
||||
}
|
||||
return access
|
||||
}
|
||||
|
||||
func luaDeserializeValueExpr(expr string, f parser.Field, enumNames map[string]struct{}) string {
|
||||
if !luaIsEnumType(f, enumNames) {
|
||||
return expr
|
||||
}
|
||||
return expr
|
||||
}
|
||||
|
||||
func luaIsEnumType(f parser.Field, enumNames map[string]struct{}) bool {
|
||||
if f.NamedType == "" || enumNames == nil {
|
||||
return false
|
||||
}
|
||||
_, ok := enumNames[f.NamedType]
|
||||
return ok
|
||||
}
|
||||
|
||||
func sanitizeLuaVarName(s string) string {
|
||||
var b strings.Builder
|
||||
for _, c := range s {
|
||||
if (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') {
|
||||
b.WriteRune(c)
|
||||
} else {
|
||||
b.WriteRune('_')
|
||||
}
|
||||
}
|
||||
return strings.ToLower(b.String())
|
||||
}
|
||||
|
||||
func checkLuaUnsupportedTypes(schema parser.Schema) error {
|
||||
for _, msg := range schema.Messages {
|
||||
for _, f := range msg.Fields {
|
||||
if err := checkFieldLuaSupport(msg.Name, f); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkFieldLuaSupport(msgName string, f parser.Field) error {
|
||||
switch f.Kind {
|
||||
case parser.KindPrimitive:
|
||||
if f.Primitive == parser.KindInt64 || f.Primitive == parser.KindUint64 {
|
||||
return fmt.Errorf("lua target does not support int64/uint64: field %s in message %s (LuaJIT/Defold uses double-precision floats which can only safely represent integers up to 2^53)", f.Name, msgName)
|
||||
}
|
||||
case parser.KindFixedArray, parser.KindSlice:
|
||||
if f.Elem != nil {
|
||||
return checkFieldLuaSupport(msgName, *f.Elem)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,767 @@
|
||||
package generator
|
||||
|
||||
import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/edmand46/arpack/parser"
|
||||
)
|
||||
|
||||
func TestGenerateLua_BasicTypes(t *testing.T) {
|
||||
schema := parser.Schema{
|
||||
Messages: []parser.Message{
|
||||
{
|
||||
Name: "BasicTypes",
|
||||
Fields: []parser.Field{
|
||||
{Name: "Int8Field", Kind: parser.KindPrimitive, Primitive: parser.KindInt8},
|
||||
{Name: "Int16Field", Kind: parser.KindPrimitive, Primitive: parser.KindInt16},
|
||||
{Name: "Int32Field", Kind: parser.KindPrimitive, Primitive: parser.KindInt32},
|
||||
{Name: "Uint8Field", Kind: parser.KindPrimitive, Primitive: parser.KindUint8},
|
||||
{Name: "Uint16Field", Kind: parser.KindPrimitive, Primitive: parser.KindUint16},
|
||||
{Name: "Uint32Field", Kind: parser.KindPrimitive, Primitive: parser.KindUint32},
|
||||
{Name: "Float32Field", Kind: parser.KindPrimitive, Primitive: parser.KindFloat32},
|
||||
{Name: "Float64Field", Kind: parser.KindPrimitive, Primitive: parser.KindFloat64},
|
||||
{Name: "BoolField", Kind: parser.KindPrimitive, Primitive: parser.KindBool},
|
||||
{Name: "StringField", Kind: parser.KindPrimitive, Primitive: parser.KindString},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
lua, err := GenerateLuaSchema(schema, "test")
|
||||
if err != nil {
|
||||
t.Fatalf("GenerateLuaSchema failed: %v", err)
|
||||
}
|
||||
|
||||
luaStr := string(lua)
|
||||
|
||||
if !strings.Contains(luaStr, "function M.new_basic_types()") {
|
||||
t.Error("Missing constructor for BasicTypes")
|
||||
}
|
||||
if !strings.Contains(luaStr, "function M.serialize_basic_types(msg)") {
|
||||
t.Error("Missing serializer for BasicTypes")
|
||||
}
|
||||
if !strings.Contains(luaStr, "function M.deserialize_basic_types(data, offset)") {
|
||||
t.Error("Missing deserializer for BasicTypes")
|
||||
}
|
||||
|
||||
if !strings.Contains(luaStr, "int8_field = 0") {
|
||||
t.Error("Missing int8_field in constructor")
|
||||
}
|
||||
if !strings.Contains(luaStr, "string_field = ''") {
|
||||
t.Error("Missing string_field default value")
|
||||
}
|
||||
if !strings.Contains(luaStr, "bool_field = false") {
|
||||
t.Error("Missing bool_field default value")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateLua_Enum(t *testing.T) {
|
||||
schema := parser.Schema{
|
||||
Enums: []parser.Enum{
|
||||
{
|
||||
Name: "Opcode",
|
||||
Primitive: parser.KindUint16,
|
||||
Values: []parser.EnumValue{
|
||||
{Name: "Unknown", Value: "0"},
|
||||
{Name: "Join", Value: "1"},
|
||||
{Name: "Leave", Value: "2"},
|
||||
},
|
||||
},
|
||||
},
|
||||
Messages: []parser.Message{
|
||||
{
|
||||
Name: "MessageWithEnum",
|
||||
Fields: []parser.Field{
|
||||
{Name: "Op", Kind: parser.KindPrimitive, Primitive: parser.KindUint16, NamedType: "Opcode"},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
enumNames := map[string]struct{}{"Opcode": {}}
|
||||
_ = enumNames
|
||||
|
||||
lua, err := GenerateLuaSchema(schema, "test")
|
||||
if err != nil {
|
||||
t.Fatalf("GenerateLuaSchema failed: %v", err)
|
||||
}
|
||||
|
||||
luaStr := string(lua)
|
||||
|
||||
if !strings.Contains(luaStr, "M.Opcode = {") {
|
||||
t.Error("Missing Opcode enum table")
|
||||
}
|
||||
if !strings.Contains(luaStr, "Unknown = 0") {
|
||||
t.Error("Missing Unknown enum value")
|
||||
}
|
||||
if !strings.Contains(luaStr, "Join = 1") {
|
||||
t.Error("Missing Join enum value")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateLua_NestedMessage(t *testing.T) {
|
||||
schema := parser.Schema{
|
||||
Messages: []parser.Message{
|
||||
{
|
||||
Name: "Vector3",
|
||||
Fields: []parser.Field{
|
||||
{Name: "X", Kind: parser.KindPrimitive, Primitive: parser.KindFloat32},
|
||||
{Name: "Y", Kind: parser.KindPrimitive, Primitive: parser.KindFloat32},
|
||||
{Name: "Z", Kind: parser.KindPrimitive, Primitive: parser.KindFloat32},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "Player",
|
||||
Fields: []parser.Field{
|
||||
{Name: "Position", Kind: parser.KindNested, TypeName: "Vector3"},
|
||||
{Name: "Health", Kind: parser.KindPrimitive, Primitive: parser.KindInt32},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
lua, err := GenerateLuaSchema(schema, "test")
|
||||
if err != nil {
|
||||
t.Fatalf("GenerateLuaSchema failed: %v", err)
|
||||
}
|
||||
|
||||
luaStr := string(lua)
|
||||
|
||||
if !strings.Contains(luaStr, "function M.new_vector3()") {
|
||||
t.Error("Missing constructor for Vector3")
|
||||
}
|
||||
if !strings.Contains(luaStr, "function M.new_player()") {
|
||||
t.Error("Missing constructor for Player")
|
||||
}
|
||||
if !strings.Contains(luaStr, "position = M.new_vector3()") {
|
||||
t.Error("Missing nested initialization in Player constructor")
|
||||
}
|
||||
if !strings.Contains(luaStr, "M.serialize_vector3") {
|
||||
t.Error("Missing Vector3 serializer call")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateLua_FixedArray(t *testing.T) {
|
||||
schema := parser.Schema{
|
||||
Messages: []parser.Message{
|
||||
{
|
||||
Name: "WithFixedArray",
|
||||
Fields: []parser.Field{
|
||||
{
|
||||
Name: "Values",
|
||||
Kind: parser.KindFixedArray,
|
||||
FixedLen: 3,
|
||||
Elem: &parser.Field{
|
||||
Kind: parser.KindPrimitive,
|
||||
Primitive: parser.KindFloat32,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
lua, err := GenerateLuaSchema(schema, "test")
|
||||
if err != nil {
|
||||
t.Fatalf("GenerateLuaSchema failed: %v", err)
|
||||
}
|
||||
|
||||
luaStr := string(lua)
|
||||
|
||||
if !strings.Contains(luaStr, "values = {}") {
|
||||
t.Error("Missing values array initialization")
|
||||
}
|
||||
if !strings.Contains(luaStr, "for _i_values = 1, 3 do") {
|
||||
t.Error("Missing fixed array loop in serializer")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateLua_Slice(t *testing.T) {
|
||||
schema := parser.Schema{
|
||||
Messages: []parser.Message{
|
||||
{
|
||||
Name: "WithSlice",
|
||||
Fields: []parser.Field{
|
||||
{
|
||||
Name: "Items",
|
||||
Kind: parser.KindSlice,
|
||||
Elem: &parser.Field{
|
||||
Kind: parser.KindPrimitive,
|
||||
Primitive: parser.KindInt32,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
lua, err := GenerateLuaSchema(schema, "test")
|
||||
if err != nil {
|
||||
t.Fatalf("GenerateLuaSchema failed: %v", err)
|
||||
}
|
||||
|
||||
luaStr := string(lua)
|
||||
|
||||
if !strings.Contains(luaStr, "items = {}") {
|
||||
t.Error("Missing items slice initialization")
|
||||
}
|
||||
if !strings.Contains(luaStr, "local _len_items = #(msg.items or {})") {
|
||||
t.Error("Missing slice length serialization")
|
||||
}
|
||||
if !strings.Contains(luaStr, "for _i_items = 1, _len_items do") {
|
||||
t.Error("Missing slice iteration in serializer")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateLua_BoolPacking(t *testing.T) {
|
||||
schema := parser.Schema{
|
||||
Messages: []parser.Message{
|
||||
{
|
||||
Name: "WithBools",
|
||||
Fields: []parser.Field{
|
||||
{Name: "A", Kind: parser.KindPrimitive, Primitive: parser.KindBool},
|
||||
{Name: "B", Kind: parser.KindPrimitive, Primitive: parser.KindBool},
|
||||
{Name: "C", Kind: parser.KindPrimitive, Primitive: parser.KindBool},
|
||||
{Name: "Value", Kind: parser.KindPrimitive, Primitive: parser.KindInt32},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
lua, err := GenerateLuaSchema(schema, "test")
|
||||
if err != nil {
|
||||
t.Fatalf("GenerateLuaSchema failed: %v", err)
|
||||
}
|
||||
|
||||
luaStr := string(lua)
|
||||
|
||||
if !strings.Contains(luaStr, "local _bool_byte_0 = 0") {
|
||||
t.Error("Missing bool byte packing variable")
|
||||
}
|
||||
if !strings.Contains(luaStr, "if msg.a then _bool_byte_0 = bit.bor(_bool_byte_0, 1) end") {
|
||||
t.Error("Missing first bool packing check with bit.bor")
|
||||
}
|
||||
if !strings.Contains(luaStr, "if msg.b then _bool_byte_0 = bit.bor(_bool_byte_0, 2) end") {
|
||||
t.Error("Missing second bool packing check with bit.bor")
|
||||
}
|
||||
if !strings.Contains(luaStr, "msg.a = bit.band(_bool_byte_0, 1) ~= 0") {
|
||||
t.Error("Missing bit.band for bool deserialization")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateLua_QuantizedFloat(t *testing.T) {
|
||||
schema := parser.Schema{
|
||||
Messages: []parser.Message{
|
||||
{
|
||||
Name: "WithQuantized",
|
||||
Fields: []parser.Field{
|
||||
{
|
||||
Name: "Position",
|
||||
Kind: parser.KindPrimitive,
|
||||
Primitive: parser.KindFloat32,
|
||||
Quant: &parser.QuantInfo{
|
||||
Min: -500,
|
||||
Max: 500,
|
||||
Bits: 16,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
lua, err := GenerateLuaSchema(schema, "test")
|
||||
if err != nil {
|
||||
t.Fatalf("GenerateLuaSchema failed: %v", err)
|
||||
}
|
||||
|
||||
luaStr := string(lua)
|
||||
|
||||
if !strings.Contains(luaStr, "math.floor(((_quant_value_msg_position - (-500)) / (500 - (-500))) * 65535)") {
|
||||
t.Error("Missing truncating quantization code for Lua")
|
||||
}
|
||||
if !strings.Contains(luaStr, `ensure_quant_range(msg.position, -500, 500, "Position")`) {
|
||||
t.Error("Missing quantized range guard for Lua")
|
||||
}
|
||||
if strings.Contains(luaStr, "math.floor(((msg.position - (-500)) / (500 - (-500))) * 65535 + 0.5)") {
|
||||
t.Error("Lua quantization should not round to nearest")
|
||||
}
|
||||
if !strings.Contains(luaStr, "write_u16_le") {
|
||||
t.Error("Missing u16 write for 16-bit quantization")
|
||||
}
|
||||
}
|
||||
|
||||
func TestToSnakeCase(t *testing.T) {
|
||||
tests := []struct {
|
||||
input string
|
||||
expected string
|
||||
}{
|
||||
{"", ""},
|
||||
{"A", "a"},
|
||||
{"AB", "ab"},
|
||||
{"AbCd", "ab_cd"},
|
||||
{"ABC", "abc"},
|
||||
{"PlayerID", "player_id"},
|
||||
{"HTTPResponse", "http_response"},
|
||||
{"XMLHttpRequest", "xml_http_request"},
|
||||
{"getHTTPResponse", "get_http_response"},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
result := toSnakeCase(tt.input)
|
||||
if result != tt.expected {
|
||||
t.Errorf("toSnakeCase(%q) = %q, want %q", tt.input, result, tt.expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestLuaHelpersGenerated(t *testing.T) {
|
||||
schema := parser.Schema{
|
||||
Messages: []parser.Message{
|
||||
{
|
||||
Name: "Empty",
|
||||
Fields: []parser.Field{},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
lua, err := GenerateLuaSchema(schema, "test")
|
||||
if err != nil {
|
||||
t.Fatalf("GenerateLuaSchema failed: %v", err)
|
||||
}
|
||||
|
||||
luaStr := string(lua)
|
||||
|
||||
helpers := []string{
|
||||
"local bit = require('bit')",
|
||||
"buffer too short for u8",
|
||||
"buffer too short for bool",
|
||||
"local function ensure_u16_limit(n, context)",
|
||||
"local function ensure_quant_range(value, min, max, context)",
|
||||
"local function write_u8(n)",
|
||||
"buffer too short for u16",
|
||||
"local function write_u16_le(n)",
|
||||
"buffer too short for u32",
|
||||
"local function write_u32_le(n)",
|
||||
"local function read_f32_le(data, offset)",
|
||||
"local function write_f32_le(n)",
|
||||
"local function read_f64_le(data, offset)",
|
||||
"local function write_f64_le(n)",
|
||||
"local function write_bool(v)",
|
||||
"buffer too short for string",
|
||||
"local function write_string(s)",
|
||||
}
|
||||
|
||||
for _, helper := range helpers {
|
||||
if !strings.Contains(luaStr, helper) {
|
||||
t.Errorf("Missing helper: %s", helper)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateLua_Int64NotSupported(t *testing.T) {
|
||||
schema := parser.Schema{
|
||||
Messages: []parser.Message{
|
||||
{
|
||||
Name: "WithInt64",
|
||||
Fields: []parser.Field{
|
||||
{Name: "Value", Kind: parser.KindPrimitive, Primitive: parser.KindInt64},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
_, err := GenerateLuaSchema(schema, "test")
|
||||
if err == nil {
|
||||
t.Fatal("Expected error for int64 field, got nil")
|
||||
}
|
||||
if !strings.Contains(err.Error(), "int64/uint64") {
|
||||
t.Errorf("Expected error mentioning int64/uint64, got: %v", err)
|
||||
}
|
||||
if !strings.Contains(err.Error(), "LuaJIT/Defold") {
|
||||
t.Errorf("Expected error mentioning LuaJIT/Defold, got: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateLua_Uint64NotSupported(t *testing.T) {
|
||||
schema := parser.Schema{
|
||||
Messages: []parser.Message{
|
||||
{
|
||||
Name: "WithUint64",
|
||||
Fields: []parser.Field{
|
||||
{Name: "Value", Kind: parser.KindPrimitive, Primitive: parser.KindUint64},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
_, err := GenerateLuaSchema(schema, "test")
|
||||
if err == nil {
|
||||
t.Fatal("Expected error for uint64 field, got nil")
|
||||
}
|
||||
if !strings.Contains(err.Error(), "int64/uint64") {
|
||||
t.Errorf("Expected error mentioning int64/uint64, got: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateLua_Int64InSliceNotSupported(t *testing.T) {
|
||||
schema := parser.Schema{
|
||||
Messages: []parser.Message{
|
||||
{
|
||||
Name: "WithInt64Slice",
|
||||
Fields: []parser.Field{
|
||||
{
|
||||
Name: "Values",
|
||||
Kind: parser.KindSlice,
|
||||
Elem: &parser.Field{
|
||||
Kind: parser.KindPrimitive,
|
||||
Primitive: parser.KindInt64,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
_, err := GenerateLuaSchema(schema, "test")
|
||||
if err == nil {
|
||||
t.Fatal("Expected error for int64 in slice, got nil")
|
||||
}
|
||||
if !strings.Contains(err.Error(), "int64/uint64") {
|
||||
t.Errorf("Expected error mentioning int64/uint64, got: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateLua_BoundsChecks(t *testing.T) {
|
||||
schema := parser.Schema{
|
||||
Messages: []parser.Message{
|
||||
{
|
||||
Name: "SimpleMessage",
|
||||
Fields: []parser.Field{
|
||||
{Name: "ID", Kind: parser.KindPrimitive, Primitive: parser.KindUint32},
|
||||
{Name: "Name", Kind: parser.KindPrimitive, Primitive: parser.KindString},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
lua, err := GenerateLuaSchema(schema, "test")
|
||||
if err != nil {
|
||||
t.Fatalf("GenerateLuaSchema failed: %v", err)
|
||||
}
|
||||
|
||||
luaStr := string(lua)
|
||||
|
||||
// Check that bounds check function exists
|
||||
if !strings.Contains(luaStr, "check_bounds") {
|
||||
t.Error("Missing check_bounds function")
|
||||
}
|
||||
|
||||
if !strings.Contains(luaStr, "ensure_u16_limit") {
|
||||
t.Error("Missing uint16 overflow helper")
|
||||
}
|
||||
|
||||
// Check that read_u16_le has bounds check
|
||||
if !strings.Contains(luaStr, "buffer too short for u16") {
|
||||
t.Error("Missing bounds check in read_u16_le")
|
||||
}
|
||||
|
||||
// Check that read_u32_le has bounds check
|
||||
if !strings.Contains(luaStr, "buffer too short for u32") {
|
||||
t.Error("Missing bounds check in read_u32_le")
|
||||
}
|
||||
|
||||
// Check that read_string has bounds check
|
||||
if !strings.Contains(luaStr, "buffer too short for string") {
|
||||
t.Error("Missing bounds check in read_string")
|
||||
}
|
||||
|
||||
// Check that deserialize function has min size check (message name is preserved in error)
|
||||
if !strings.Contains(luaStr, "buffer too short for SimpleMessage") {
|
||||
t.Error("Missing min size check in deserialize function")
|
||||
}
|
||||
|
||||
// Check that read_u8 has bounds check
|
||||
if !strings.Contains(luaStr, "buffer too short for u8") {
|
||||
t.Error("Missing bounds check in read_u8")
|
||||
}
|
||||
|
||||
// Check that read_bool has bounds check
|
||||
if !strings.Contains(luaStr, "buffer too short for bool") {
|
||||
t.Error("Missing bounds check in read_bool")
|
||||
}
|
||||
|
||||
// Check that read_i8 has bounds check
|
||||
if !strings.Contains(luaStr, "buffer too short for i8") {
|
||||
t.Error("Missing bounds check in read_i8")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateLua_LengthOverflowGuards(t *testing.T) {
|
||||
schema := parser.Schema{
|
||||
Messages: []parser.Message{
|
||||
{
|
||||
Name: "LengthLimited",
|
||||
Fields: []parser.Field{
|
||||
{Name: "Name", Kind: parser.KindPrimitive, Primitive: parser.KindString},
|
||||
{
|
||||
Name: "Items",
|
||||
Kind: parser.KindSlice,
|
||||
Elem: &parser.Field{
|
||||
Kind: parser.KindPrimitive,
|
||||
Primitive: parser.KindUint8,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
lua, err := GenerateLuaSchema(schema, "test")
|
||||
if err != nil {
|
||||
t.Fatalf("GenerateLuaSchema failed: %v", err)
|
||||
}
|
||||
|
||||
luaStr := string(lua)
|
||||
|
||||
if !strings.Contains(luaStr, `ensure_u16_limit(len, "string length")`) {
|
||||
t.Error("Missing string length overflow guard")
|
||||
}
|
||||
|
||||
if !strings.Contains(luaStr, `ensure_u16_limit(_len_items, "slice length for items")`) {
|
||||
t.Error("Missing slice length overflow guard")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateLua_RuntimeLengthLimits(t *testing.T) {
|
||||
if _, err := exec.LookPath("luajit"); err != nil {
|
||||
t.Skip("luajit not found")
|
||||
}
|
||||
|
||||
schema := parser.Schema{
|
||||
Messages: []parser.Message{
|
||||
{
|
||||
Name: "LengthLimited",
|
||||
Fields: []parser.Field{
|
||||
{Name: "Name", Kind: parser.KindPrimitive, Primitive: parser.KindString},
|
||||
{
|
||||
Name: "Items",
|
||||
Kind: parser.KindSlice,
|
||||
Elem: &parser.Field{
|
||||
Kind: parser.KindPrimitive,
|
||||
Primitive: parser.KindUint8,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
lua, err := GenerateLuaSchema(schema, "messages")
|
||||
if err != nil {
|
||||
t.Fatalf("GenerateLuaSchema failed: %v", err)
|
||||
}
|
||||
|
||||
dir := t.TempDir()
|
||||
modulePath := filepath.Join(dir, "messages_gen.lua")
|
||||
if err := os.WriteFile(modulePath, lua, 0o600); err != nil {
|
||||
t.Fatalf("write module: %v", err)
|
||||
}
|
||||
|
||||
scriptPath := filepath.Join(dir, "check.lua")
|
||||
script := `local messages = require("messages_gen")
|
||||
|
||||
local function emit(label, ok, value)
|
||||
if ok then
|
||||
print(label .. ":OK")
|
||||
else
|
||||
print(label .. ":" .. tostring(value))
|
||||
end
|
||||
end
|
||||
|
||||
local msg = messages.new_length_limited()
|
||||
|
||||
local ok, res = pcall(messages.serialize_length_limited, msg)
|
||||
emit("EMPTY", ok, res)
|
||||
|
||||
msg.name = string.rep("a", 65535)
|
||||
ok, res = pcall(messages.serialize_length_limited, msg)
|
||||
emit("STR_MAX", ok, res)
|
||||
|
||||
msg.name = string.rep("a", 65536)
|
||||
ok, res = pcall(messages.serialize_length_limited, msg)
|
||||
emit("STR_OVER", ok, res)
|
||||
|
||||
msg.name = ""
|
||||
msg.items = {}
|
||||
for i = 1, 65535 do
|
||||
msg.items[i] = 0
|
||||
end
|
||||
ok, res = pcall(messages.serialize_length_limited, msg)
|
||||
emit("SLICE_MAX", ok, res)
|
||||
|
||||
msg.items[65536] = 0
|
||||
ok, res = pcall(messages.serialize_length_limited, msg)
|
||||
emit("SLICE_OVER", ok, res)
|
||||
`
|
||||
if err := os.WriteFile(scriptPath, []byte(script), 0o600); err != nil {
|
||||
t.Fatalf("write script: %v", err)
|
||||
}
|
||||
|
||||
cmd := exec.Command("luajit", "check.lua")
|
||||
cmd.Dir = dir
|
||||
out, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
t.Fatalf("luajit failed: %v\n%s", err, out)
|
||||
}
|
||||
|
||||
lines := strings.Split(strings.TrimSpace(string(out)), "\n")
|
||||
if len(lines) != 5 {
|
||||
t.Fatalf("expected 5 output lines, got %d: %q", len(lines), string(out))
|
||||
}
|
||||
|
||||
if lines[0] != "EMPTY:OK" {
|
||||
t.Fatalf("expected empty serialization to succeed, got %q", lines[0])
|
||||
}
|
||||
if lines[1] != "STR_MAX:OK" {
|
||||
t.Fatalf("expected 65535-byte string serialization to succeed, got %q", lines[1])
|
||||
}
|
||||
if !strings.Contains(lines[2], "string length exceeds uint16 limit") {
|
||||
t.Fatalf("expected string overflow guard, got %q", lines[2])
|
||||
}
|
||||
if lines[3] != "SLICE_MAX:OK" {
|
||||
t.Fatalf("expected 65535-element slice serialization to succeed, got %q", lines[3])
|
||||
}
|
||||
if !strings.Contains(lines[4], "slice length for items exceeds uint16 limit") {
|
||||
t.Fatalf("expected slice overflow guard, got %q", lines[4])
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateLua_RuntimeFloatEdgeCases(t *testing.T) {
|
||||
if _, err := exec.LookPath("luajit"); err != nil {
|
||||
t.Skip("luajit not found")
|
||||
}
|
||||
|
||||
schema := parser.Schema{
|
||||
Messages: []parser.Message{
|
||||
{
|
||||
Name: "FloatEdges",
|
||||
Fields: []parser.Field{
|
||||
{Name: "F32", Kind: parser.KindPrimitive, Primitive: parser.KindFloat32},
|
||||
{Name: "F64", Kind: parser.KindPrimitive, Primitive: parser.KindFloat64},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
lua, err := GenerateLuaSchema(schema, "messages")
|
||||
if err != nil {
|
||||
t.Fatalf("GenerateLuaSchema failed: %v", err)
|
||||
}
|
||||
|
||||
dir := t.TempDir()
|
||||
modulePath := filepath.Join(dir, "messages_gen.lua")
|
||||
if err := os.WriteFile(modulePath, lua, 0o600); err != nil {
|
||||
t.Fatalf("write module: %v", err)
|
||||
}
|
||||
|
||||
scriptPath := filepath.Join(dir, "check.lua")
|
||||
script := `local messages = require("messages_gen")
|
||||
|
||||
local function bytes_to_hex(s)
|
||||
return (s:gsub(".", function(c) return string.format("%02x", string.byte(c)) end))
|
||||
end
|
||||
|
||||
local neg_zero = string.char(0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 128)
|
||||
local msg = messages.deserialize_float_edges(neg_zero, 1)
|
||||
print(bytes_to_hex(messages.serialize_float_edges(msg)))
|
||||
|
||||
local subnormal = string.char(1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0)
|
||||
msg = messages.deserialize_float_edges(subnormal, 1)
|
||||
print(bytes_to_hex(messages.serialize_float_edges(msg)))
|
||||
`
|
||||
if err := os.WriteFile(scriptPath, []byte(script), 0o600); err != nil {
|
||||
t.Fatalf("write script: %v", err)
|
||||
}
|
||||
|
||||
cmd := exec.Command("luajit", "check.lua")
|
||||
cmd.Dir = dir
|
||||
out, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
t.Fatalf("luajit failed: %v\n%s", err, out)
|
||||
}
|
||||
|
||||
lines := strings.Split(strings.TrimSpace(string(out)), "\n")
|
||||
if len(lines) != 2 {
|
||||
t.Fatalf("expected 2 output lines, got %d: %q", len(lines), string(out))
|
||||
}
|
||||
|
||||
if lines[0] != "000000800000000000000080" {
|
||||
t.Fatalf("negative zero roundtrip mismatch: %s", lines[0])
|
||||
}
|
||||
if lines[1] != "010000000100000000000000" {
|
||||
t.Fatalf("subnormal roundtrip mismatch: %s", lines[1])
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateLua_RuntimeQuantizedRangeGuard(t *testing.T) {
|
||||
if _, err := exec.LookPath("luajit"); err != nil {
|
||||
t.Skip("luajit not found")
|
||||
}
|
||||
|
||||
schema := parser.Schema{
|
||||
Messages: []parser.Message{
|
||||
{
|
||||
Name: "WithQuantized",
|
||||
Fields: []parser.Field{
|
||||
{
|
||||
Name: "Position",
|
||||
Kind: parser.KindPrimitive,
|
||||
Primitive: parser.KindFloat32,
|
||||
Quant: &parser.QuantInfo{Min: -500, Max: 500, Bits: 16},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
lua, err := GenerateLuaSchema(schema, "messages")
|
||||
if err != nil {
|
||||
t.Fatalf("GenerateLuaSchema failed: %v", err)
|
||||
}
|
||||
|
||||
dir := t.TempDir()
|
||||
if err := os.WriteFile(filepath.Join(dir, "messages_gen.lua"), lua, 0o600); err != nil {
|
||||
t.Fatalf("write module: %v", err)
|
||||
}
|
||||
|
||||
script := `local messages = require("messages_gen")
|
||||
local msg = messages.new_with_quantized()
|
||||
msg.position = 501
|
||||
local ok, res = pcall(messages.serialize_with_quantized, msg)
|
||||
if ok then
|
||||
print("OK")
|
||||
else
|
||||
print(res)
|
||||
end
|
||||
`
|
||||
if err := os.WriteFile(filepath.Join(dir, "check.lua"), []byte(script), 0o600); err != nil {
|
||||
t.Fatalf("write script: %v", err)
|
||||
}
|
||||
|
||||
cmd := exec.Command("luajit", "check.lua")
|
||||
cmd.Dir = dir
|
||||
out, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
t.Fatalf("luajit failed: %v\n%s", err, out)
|
||||
}
|
||||
|
||||
got := strings.TrimSpace(string(out))
|
||||
if !strings.Contains(got, "quantized value out of range for Position") {
|
||||
t.Fatalf("expected quantized range guard, got %q", got)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package generator
|
||||
|
||||
import "github.com/edmand46/arpack/parser"
|
||||
|
||||
func lengthContext(f parser.Field) string {
|
||||
switch {
|
||||
case f.Kind == parser.KindSlice:
|
||||
if f.Name != "" {
|
||||
return "slice length for " + f.Name
|
||||
}
|
||||
return "slice length"
|
||||
case f.Kind == parser.KindPrimitive && f.Primitive == parser.KindString:
|
||||
if f.Name != "" {
|
||||
return "string length for " + f.Name
|
||||
}
|
||||
return "string length"
|
||||
default:
|
||||
return "length"
|
||||
}
|
||||
}
|
||||
|
||||
func quantContext(f parser.Field) string {
|
||||
if f.Name != "" {
|
||||
return f.Name
|
||||
}
|
||||
return "value"
|
||||
}
|
||||
|
||||
func schemaNeedsLengthGuards(messages []parser.Message) bool {
|
||||
for _, msg := range messages {
|
||||
for _, f := range msg.Fields {
|
||||
if fieldNeedsLengthGuard(f) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func fieldNeedsLengthGuard(f parser.Field) bool {
|
||||
switch f.Kind {
|
||||
case parser.KindPrimitive:
|
||||
return f.Primitive == parser.KindString
|
||||
case parser.KindFixedArray, parser.KindSlice:
|
||||
if f.Kind == parser.KindSlice {
|
||||
return true
|
||||
}
|
||||
if f.Elem != nil {
|
||||
return fieldNeedsLengthGuard(*f.Elem)
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func schemaNeedsQuantRangeGuards(messages []parser.Message) bool {
|
||||
for _, msg := range messages {
|
||||
for _, f := range msg.Fields {
|
||||
if fieldNeedsQuantRangeGuard(f) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func fieldNeedsQuantRangeGuard(f parser.Field) bool {
|
||||
switch f.Kind {
|
||||
case parser.KindPrimitive:
|
||||
return f.Quant != nil
|
||||
case parser.KindFixedArray, parser.KindSlice:
|
||||
if f.Elem != nil {
|
||||
return fieldNeedsQuantRangeGuard(*f.Elem)
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
+669
@@ -0,0 +1,669 @@
|
||||
package generator
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/edmand46/arpack/parser"
|
||||
)
|
||||
|
||||
// GenerateTypeScript generates TypeScript code for the given messages
|
||||
func GenerateTypeScript(messages []parser.Message, namespace string) ([]byte, error) {
|
||||
return GenerateTypeScriptSchema(parser.Schema{Messages: messages}, namespace)
|
||||
}
|
||||
|
||||
// GenerateTypeScriptSchema generates TypeScript code from a schema
|
||||
func GenerateTypeScriptSchema(schema parser.Schema, namespace string) ([]byte, error) {
|
||||
messages := schema.Messages
|
||||
var b strings.Builder
|
||||
needsLengthGuards := schemaNeedsLengthGuards(messages)
|
||||
needsQuantGuards := schemaNeedsQuantRangeGuards(messages)
|
||||
|
||||
b.WriteString("// <auto-generated> arpack </auto-generated>\n")
|
||||
b.WriteString("// Code generated by arpack. DO NOT EDIT.\n\n")
|
||||
|
||||
if needsLengthGuards {
|
||||
b.WriteString("const arpackTextEncoder = new TextEncoder();\n")
|
||||
b.WriteString("const arpackTextDecoder = new TextDecoder();\n\n")
|
||||
b.WriteString("function arpackEnsureUint16Length(length: number, context: string): number {\n")
|
||||
b.WriteString(" if (length > 65535) {\n")
|
||||
b.WriteString(" throw new RangeError(\"arpack: \" + context + \" exceeds uint16 limit\");\n")
|
||||
b.WriteString(" }\n")
|
||||
b.WriteString(" return length;\n")
|
||||
b.WriteString("}\n\n")
|
||||
}
|
||||
|
||||
if needsQuantGuards {
|
||||
b.WriteString("function arpackEnsureQuantizedRange(value: number, min: number, max: number, context: string): void {\n")
|
||||
b.WriteString(" if (Number.isNaN(value) || value < min || value > max) {\n")
|
||||
b.WriteString(" throw new RangeError(\"arpack: quantized value out of range for \" + context);\n")
|
||||
b.WriteString(" }\n")
|
||||
b.WriteString("}\n\n")
|
||||
}
|
||||
|
||||
enumNames := make(map[string]struct{}, len(schema.Enums))
|
||||
for _, enum := range schema.Enums {
|
||||
enumNames[enum.Name] = struct{}{}
|
||||
}
|
||||
|
||||
// Generate enums
|
||||
for _, enum := range schema.Enums {
|
||||
writeTSEnum(&b, enum)
|
||||
b.WriteString("\n")
|
||||
}
|
||||
|
||||
// Generate messages
|
||||
for i, msg := range messages {
|
||||
if err := writeTSMessage(&b, msg, enumNames); err != nil {
|
||||
return nil, fmt.Errorf("message %s: %w", msg.Name, err)
|
||||
}
|
||||
if i < len(messages)-1 {
|
||||
b.WriteString("\n")
|
||||
}
|
||||
}
|
||||
|
||||
return []byte(b.String()), nil
|
||||
}
|
||||
|
||||
func writeTSEnum(b *strings.Builder, enum parser.Enum) {
|
||||
fmt.Fprintf(b, "export enum %s {\n", enum.Name)
|
||||
for i, value := range enum.Values {
|
||||
fmt.Fprintf(b, " %s = %s", value.Name, value.Value)
|
||||
if i < len(enum.Values)-1 {
|
||||
b.WriteString(",")
|
||||
}
|
||||
b.WriteString("\n")
|
||||
}
|
||||
b.WriteString("}\n")
|
||||
}
|
||||
|
||||
func writeTSMessage(b *strings.Builder, msg parser.Message, enumNames map[string]struct{}) error {
|
||||
segs := segmentFields(msg.Fields)
|
||||
|
||||
fmt.Fprintf(b, "export class %s {\n", msg.Name)
|
||||
|
||||
// Field declarations with defaults
|
||||
for _, f := range msg.Fields {
|
||||
defaultValue := tsDefaultValue(f)
|
||||
fmt.Fprintf(b, " %s: %s = %s;\n", toCamelCase(f.Name), tsTypeName(f, enumNames), defaultValue)
|
||||
}
|
||||
b.WriteString("\n")
|
||||
|
||||
// Serialize method
|
||||
b.WriteString(" serialize(view: DataView, offset: number): number {\n")
|
||||
b.WriteString(" let pos = offset;\n")
|
||||
for i, seg := range segs {
|
||||
if seg.single != nil {
|
||||
if err := writeTSSerializeField(b, "this", *seg.single, " ", enumNames); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
writeTSBoolGroupSerialize(b, "this", seg.bools, i, " ")
|
||||
}
|
||||
}
|
||||
b.WriteString(" return pos - offset;\n")
|
||||
b.WriteString(" }\n\n")
|
||||
|
||||
// Deserialize method
|
||||
fmt.Fprintf(b, " static deserialize(view: DataView, offset: number): [%s, number] {\n", msg.Name)
|
||||
b.WriteString(" let pos = offset;\n")
|
||||
fmt.Fprintf(b, " const msg = new %s();\n", msg.Name)
|
||||
for i, seg := range segs {
|
||||
if seg.single != nil {
|
||||
if err := writeTSDeserializeField(b, "msg", *seg.single, " ", enumNames); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
writeTSBoolGroupDeserialize(b, "msg", seg.bools, i, " ")
|
||||
}
|
||||
}
|
||||
b.WriteString(" return [msg, pos - offset];\n")
|
||||
b.WriteString(" }\n")
|
||||
|
||||
b.WriteString("}\n")
|
||||
return nil
|
||||
}
|
||||
|
||||
func writeTSBoolGroupSerialize(b *strings.Builder, recv string, bools []parser.Field, groupIdx int, indent string) {
|
||||
varName := fmt.Sprintf("_boolByte%d", groupIdx)
|
||||
fmt.Fprintf(b, "%slet %s = 0;\n", indent, varName)
|
||||
for bit, f := range bools {
|
||||
fmt.Fprintf(b, "%sif (%s.%s) %s |= 1 << %d;\n", indent, recv, toCamelCase(f.Name), varName, bit)
|
||||
}
|
||||
fmt.Fprintf(b, "%sview.setUint8(pos, %s);\n", indent, varName)
|
||||
fmt.Fprintf(b, "%spos += 1;\n", indent)
|
||||
}
|
||||
|
||||
func writeTSBoolGroupDeserialize(b *strings.Builder, recv string, bools []parser.Field, groupIdx int, indent string) {
|
||||
varName := fmt.Sprintf("_boolByte%d", groupIdx)
|
||||
fmt.Fprintf(b, "%sconst %s = view.getUint8(pos);\n", indent, varName)
|
||||
fmt.Fprintf(b, "%spos += 1;\n", indent)
|
||||
for bit, f := range bools {
|
||||
fmt.Fprintf(b, "%s%s.%s = (%s & (1 << %d)) !== 0;\n", indent, recv, toCamelCase(f.Name), varName, bit)
|
||||
}
|
||||
}
|
||||
|
||||
func writeTSSerializeField(b *strings.Builder, recv string, f parser.Field, indent string, enumNames map[string]struct{}) error {
|
||||
access := recv + "." + toCamelCase(f.Name)
|
||||
switch f.Kind {
|
||||
case parser.KindPrimitive:
|
||||
return writeTSSerializePrimitive(b, access, f, indent, enumNames)
|
||||
case parser.KindNested:
|
||||
fmt.Fprintf(b, "%spos += %s.serialize(view, pos);\n", indent, access)
|
||||
case parser.KindFixedArray:
|
||||
iVar := "_i" + f.Name
|
||||
fmt.Fprintf(b, "%sfor (let %s = 0; %s < %d; %s++) {\n",
|
||||
indent, iVar, iVar, f.FixedLen, iVar)
|
||||
elemField := parser.Field{
|
||||
Name: f.Name + "[" + iVar + "]",
|
||||
Kind: f.Elem.Kind,
|
||||
Primitive: f.Elem.Primitive,
|
||||
NamedType: f.Elem.NamedType,
|
||||
Quant: f.Elem.Quant,
|
||||
TypeName: f.Elem.TypeName,
|
||||
Elem: f.Elem.Elem,
|
||||
FixedLen: f.Elem.FixedLen,
|
||||
}
|
||||
if err := writeTSSerializeField(b, recv, elemField, indent+" ", enumNames); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Fprintf(b, "%s}\n", indent)
|
||||
case parser.KindSlice:
|
||||
lenVar := "_len" + sanitizeVarName(access)
|
||||
fmt.Fprintf(b, "%sconst %s = arpackEnsureUint16Length(%s.length, %q);\n",
|
||||
indent, lenVar, access, lengthContext(f))
|
||||
fmt.Fprintf(b, "%sview.setUint16(pos, %s, true);\n", indent, lenVar)
|
||||
fmt.Fprintf(b, "%spos += 2;\n", indent)
|
||||
iVar := "_i" + f.Name
|
||||
fmt.Fprintf(b, "%sfor (const %s of %s) {\n", indent, iVar, access)
|
||||
elemField := parser.Field{
|
||||
Name: iVar,
|
||||
Kind: f.Elem.Kind,
|
||||
Primitive: f.Elem.Primitive,
|
||||
NamedType: f.Elem.NamedType,
|
||||
Quant: f.Elem.Quant,
|
||||
TypeName: f.Elem.TypeName,
|
||||
Elem: f.Elem.Elem,
|
||||
FixedLen: f.Elem.FixedLen,
|
||||
}
|
||||
if err := writeTSSerializeFieldElement(b, iVar, elemField, indent+" ", enumNames); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Fprintf(b, "%s}\n", indent)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func writeTSSerializeFieldElement(b *strings.Builder, access string, f parser.Field, indent string, enumNames map[string]struct{}) error {
|
||||
switch f.Kind {
|
||||
case parser.KindPrimitive:
|
||||
return writeTSSerializePrimitiveElement(b, access, f, indent, enumNames)
|
||||
case parser.KindNested:
|
||||
fmt.Fprintf(b, "%spos += %s.serialize(view, pos);\n", indent, access)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func writeTSSerializePrimitiveElement(b *strings.Builder, access string, f parser.Field, indent string, enumNames map[string]struct{}) error {
|
||||
if f.Quant != nil {
|
||||
return writeTSSerializeQuantElement(b, access, f, indent)
|
||||
}
|
||||
|
||||
valueExpr := tsSerializeValueExpr(access, f, enumNames)
|
||||
switch f.Primitive {
|
||||
case parser.KindFloat32:
|
||||
fmt.Fprintf(b, "%sview.setFloat32(pos, %s, true);\n", indent, valueExpr)
|
||||
fmt.Fprintf(b, "%spos += 4;\n", indent)
|
||||
case parser.KindFloat64:
|
||||
fmt.Fprintf(b, "%sview.setFloat64(pos, %s, true);\n", indent, valueExpr)
|
||||
fmt.Fprintf(b, "%spos += 8;\n", indent)
|
||||
case parser.KindInt8:
|
||||
fmt.Fprintf(b, "%sview.setInt8(pos, %s);\n", indent, valueExpr)
|
||||
fmt.Fprintf(b, "%spos += 1;\n", indent)
|
||||
case parser.KindUint8:
|
||||
fmt.Fprintf(b, "%sview.setUint8(pos, %s);\n", indent, valueExpr)
|
||||
fmt.Fprintf(b, "%spos += 1;\n", indent)
|
||||
case parser.KindBool:
|
||||
fmt.Fprintf(b, "%sview.setUint8(pos, %s ? 1 : 0);\n", indent, valueExpr)
|
||||
fmt.Fprintf(b, "%spos += 1;\n", indent)
|
||||
case parser.KindInt16:
|
||||
fmt.Fprintf(b, "%sview.setInt16(pos, %s, true);\n", indent, valueExpr)
|
||||
fmt.Fprintf(b, "%spos += 2;\n", indent)
|
||||
case parser.KindUint16:
|
||||
fmt.Fprintf(b, "%sview.setUint16(pos, %s, true);\n", indent, valueExpr)
|
||||
fmt.Fprintf(b, "%spos += 2;\n", indent)
|
||||
case parser.KindInt32:
|
||||
fmt.Fprintf(b, "%sview.setInt32(pos, %s, true);\n", indent, valueExpr)
|
||||
fmt.Fprintf(b, "%spos += 4;\n", indent)
|
||||
case parser.KindUint32:
|
||||
fmt.Fprintf(b, "%sview.setUint32(pos, %s, true);\n", indent, valueExpr)
|
||||
fmt.Fprintf(b, "%spos += 4;\n", indent)
|
||||
case parser.KindInt64:
|
||||
fmt.Fprintf(b, "%sview.setBigInt64(pos, %s, true);\n", indent, valueExpr)
|
||||
fmt.Fprintf(b, "%spos += 8;\n", indent)
|
||||
case parser.KindUint64:
|
||||
fmt.Fprintf(b, "%sview.setBigUint64(pos, %s, true);\n", indent, valueExpr)
|
||||
fmt.Fprintf(b, "%spos += 8;\n", indent)
|
||||
case parser.KindString:
|
||||
lenVar := "_slen" + sanitizeVarName(access)
|
||||
guardVar := "_slenChecked" + sanitizeVarName(access)
|
||||
fmt.Fprintf(b, "%sconst %s = arpackTextEncoder.encode(%s);\n", indent, lenVar, valueExpr)
|
||||
fmt.Fprintf(b, "%sconst %s = arpackEnsureUint16Length(%s.length, %q);\n",
|
||||
indent, guardVar, lenVar, lengthContext(f))
|
||||
fmt.Fprintf(b, "%sview.setUint16(pos, %s, true);\n", indent, guardVar)
|
||||
fmt.Fprintf(b, "%spos += 2;\n", indent)
|
||||
fmt.Fprintf(b, "%snew Uint8Array(view.buffer, pos, %s.length).set(%s);\n", indent, lenVar, lenVar)
|
||||
fmt.Fprintf(b, "%spos += %s.length;\n", indent, lenVar)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func writeTSSerializePrimitive(b *strings.Builder, access string, f parser.Field, indent string, enumNames map[string]struct{}) error {
|
||||
if f.Quant != nil {
|
||||
return writeTSSerializeQuant(b, access, f, indent)
|
||||
}
|
||||
|
||||
valueExpr := tsSerializeValueExpr(access, f, enumNames)
|
||||
switch f.Primitive {
|
||||
case parser.KindFloat32:
|
||||
fmt.Fprintf(b, "%sview.setFloat32(pos, %s, true);\n", indent, valueExpr)
|
||||
fmt.Fprintf(b, "%spos += 4;\n", indent)
|
||||
case parser.KindFloat64:
|
||||
fmt.Fprintf(b, "%sview.setFloat64(pos, %s, true);\n", indent, valueExpr)
|
||||
fmt.Fprintf(b, "%spos += 8;\n", indent)
|
||||
case parser.KindInt8:
|
||||
fmt.Fprintf(b, "%sview.setInt8(pos, %s);\n", indent, valueExpr)
|
||||
fmt.Fprintf(b, "%spos += 1;\n", indent)
|
||||
case parser.KindUint8:
|
||||
fmt.Fprintf(b, "%sview.setUint8(pos, %s);\n", indent, valueExpr)
|
||||
fmt.Fprintf(b, "%spos += 1;\n", indent)
|
||||
case parser.KindBool:
|
||||
fmt.Fprintf(b, "%sview.setUint8(pos, %s ? 1 : 0);\n", indent, valueExpr)
|
||||
fmt.Fprintf(b, "%spos += 1;\n", indent)
|
||||
case parser.KindInt16:
|
||||
fmt.Fprintf(b, "%sview.setInt16(pos, %s, true);\n", indent, valueExpr)
|
||||
fmt.Fprintf(b, "%spos += 2;\n", indent)
|
||||
case parser.KindUint16:
|
||||
fmt.Fprintf(b, "%sview.setUint16(pos, %s, true);\n", indent, valueExpr)
|
||||
fmt.Fprintf(b, "%spos += 2;\n", indent)
|
||||
case parser.KindInt32:
|
||||
fmt.Fprintf(b, "%sview.setInt32(pos, %s, true);\n", indent, valueExpr)
|
||||
fmt.Fprintf(b, "%spos += 4;\n", indent)
|
||||
case parser.KindUint32:
|
||||
fmt.Fprintf(b, "%sview.setUint32(pos, %s, true);\n", indent, valueExpr)
|
||||
fmt.Fprintf(b, "%spos += 4;\n", indent)
|
||||
case parser.KindInt64:
|
||||
fmt.Fprintf(b, "%sview.setBigInt64(pos, %s, true);\n", indent, valueExpr)
|
||||
fmt.Fprintf(b, "%spos += 8;\n", indent)
|
||||
case parser.KindUint64:
|
||||
fmt.Fprintf(b, "%sview.setBigUint64(pos, %s, true);\n", indent, valueExpr)
|
||||
fmt.Fprintf(b, "%spos += 8;\n", indent)
|
||||
case parser.KindString:
|
||||
lenVar := "_slen" + sanitizeVarName(access)
|
||||
guardVar := "_slenChecked" + sanitizeVarName(access)
|
||||
fmt.Fprintf(b, "%sconst %s = arpackTextEncoder.encode(%s);\n", indent, lenVar, valueExpr)
|
||||
fmt.Fprintf(b, "%sconst %s = arpackEnsureUint16Length(%s.length, %q);\n",
|
||||
indent, guardVar, lenVar, lengthContext(f))
|
||||
fmt.Fprintf(b, "%sview.setUint16(pos, %s, true);\n", indent, guardVar)
|
||||
fmt.Fprintf(b, "%spos += 2;\n", indent)
|
||||
fmt.Fprintf(b, "%snew Uint8Array(view.buffer, pos, %s.length).set(%s);\n", indent, lenVar, lenVar)
|
||||
fmt.Fprintf(b, "%spos += %s.length;\n", indent, lenVar)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func writeTSSerializeQuant(b *strings.Builder, access string, f parser.Field, indent string) error {
|
||||
q := f.Quant
|
||||
maxUint := q.MaxUint()
|
||||
varName := "_q" + sanitizeVarName(access)
|
||||
fmt.Fprintf(b, "%sarpackEnsureQuantizedRange(%s, %g, %g, %q);\n",
|
||||
indent, access, q.Min, q.Max, quantContext(f))
|
||||
if q.Bits == 8 {
|
||||
fmt.Fprintf(b, "%sconst %s = Math.trunc((%s - (%g)) / (%g - (%g)) * %g);\n",
|
||||
indent, varName, access, q.Min, q.Max, q.Min, maxUint)
|
||||
fmt.Fprintf(b, "%sview.setUint8(pos, %s);\n", indent, varName)
|
||||
fmt.Fprintf(b, "%spos += 1;\n", indent)
|
||||
} else {
|
||||
fmt.Fprintf(b, "%sconst %s = Math.trunc((%s - (%g)) / (%g - (%g)) * %g);\n",
|
||||
indent, varName, access, q.Min, q.Max, q.Min, maxUint)
|
||||
fmt.Fprintf(b, "%sview.setUint16(pos, %s, true);\n", indent, varName)
|
||||
fmt.Fprintf(b, "%spos += 2;\n", indent)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func writeTSSerializeQuantElement(b *strings.Builder, access string, f parser.Field, indent string) error {
|
||||
q := f.Quant
|
||||
maxUint := q.MaxUint()
|
||||
varName := "_q" + sanitizeVarName(access)
|
||||
fmt.Fprintf(b, "%sarpackEnsureQuantizedRange(%s, %g, %g, %q);\n",
|
||||
indent, access, q.Min, q.Max, quantContext(f))
|
||||
if q.Bits == 8 {
|
||||
fmt.Fprintf(b, "%sconst %s = Math.trunc((%s - (%g)) / (%g - (%g)) * %g);\n",
|
||||
indent, varName, access, q.Min, q.Max, q.Min, maxUint)
|
||||
fmt.Fprintf(b, "%sview.setUint8(pos, %s);\n", indent, varName)
|
||||
fmt.Fprintf(b, "%spos += 1;\n", indent)
|
||||
} else {
|
||||
fmt.Fprintf(b, "%sconst %s = Math.trunc((%s - (%g)) / (%g - (%g)) * %g);\n",
|
||||
indent, varName, access, q.Min, q.Max, q.Min, maxUint)
|
||||
fmt.Fprintf(b, "%sview.setUint16(pos, %s, true);\n", indent, varName)
|
||||
fmt.Fprintf(b, "%spos += 2;\n", indent)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func writeTSDeserializeField(b *strings.Builder, recv string, f parser.Field, indent string, enumNames map[string]struct{}) error {
|
||||
access := recv + "." + toCamelCase(f.Name)
|
||||
switch f.Kind {
|
||||
case parser.KindPrimitive:
|
||||
return writeTSDeserializePrimitive(b, access, f, indent, enumNames)
|
||||
case parser.KindNested:
|
||||
fmt.Fprintf(b, "%sconst [_%s, _n%s] = %s.deserialize(view, pos);\n", indent, f.Name, f.Name, f.TypeName)
|
||||
fmt.Fprintf(b, "%s%s = _%s;\n", indent, access, f.Name)
|
||||
fmt.Fprintf(b, "%spos += _n%s;\n", indent, f.Name)
|
||||
case parser.KindFixedArray:
|
||||
iVar := "_i" + f.Name
|
||||
fmt.Fprintf(b, "%s%s = new Array(%d);\n", indent, access, f.FixedLen)
|
||||
fmt.Fprintf(b, "%sfor (let %s = 0; %s < %d; %s++) {\n",
|
||||
indent, iVar, iVar, f.FixedLen, iVar)
|
||||
elemField := parser.Field{
|
||||
Name: f.Name + "[" + iVar + "]",
|
||||
Kind: f.Elem.Kind,
|
||||
Primitive: f.Elem.Primitive,
|
||||
NamedType: f.Elem.NamedType,
|
||||
Quant: f.Elem.Quant,
|
||||
TypeName: f.Elem.TypeName,
|
||||
Elem: f.Elem.Elem,
|
||||
FixedLen: f.Elem.FixedLen,
|
||||
}
|
||||
if err := writeTSDeserializeField(b, recv, elemField, indent+" ", enumNames); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Fprintf(b, "%s}\n", indent)
|
||||
case parser.KindSlice:
|
||||
lenVar := "_len" + f.Name
|
||||
fmt.Fprintf(b, "%sconst %s = view.getUint16(pos, true);\n", indent, lenVar)
|
||||
fmt.Fprintf(b, "%spos += 2;\n", indent)
|
||||
fmt.Fprintf(b, "%s%s = new Array(%s);\n", indent, access, lenVar)
|
||||
iVar := "_i" + f.Name
|
||||
fmt.Fprintf(b, "%sfor (let %s = 0; %s < %s; %s++) {\n", indent, iVar, iVar, lenVar, iVar)
|
||||
elemField := parser.Field{
|
||||
Name: f.Name + "[" + iVar + "]",
|
||||
Kind: f.Elem.Kind,
|
||||
Primitive: f.Elem.Primitive,
|
||||
NamedType: f.Elem.NamedType,
|
||||
Quant: f.Elem.Quant,
|
||||
TypeName: f.Elem.TypeName,
|
||||
Elem: f.Elem.Elem,
|
||||
FixedLen: f.Elem.FixedLen,
|
||||
}
|
||||
if err := writeTSDeserializeFieldElement(b, recv, elemField, indent+" ", enumNames); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Fprintf(b, "%s}\n", indent)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func writeTSDeserializeFieldElement(b *strings.Builder, recv string, f parser.Field, indent string, enumNames map[string]struct{}) error {
|
||||
access := recv + "." + toCamelCase(f.Name)
|
||||
switch f.Kind {
|
||||
case parser.KindPrimitive:
|
||||
return writeTSDeserializePrimitiveElement(b, access, f, indent, enumNames)
|
||||
case parser.KindNested:
|
||||
fmt.Fprintf(b, "%sconst [_elem, _nElem] = %s.deserialize(view, pos);\n", indent, f.TypeName)
|
||||
fmt.Fprintf(b, "%s%s = _elem;\n", indent, access)
|
||||
fmt.Fprintf(b, "%spos += _nElem;\n", indent)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func writeTSDeserializePrimitiveElement(b *strings.Builder, access string, f parser.Field, indent string, enumNames map[string]struct{}) error {
|
||||
if f.Quant != nil {
|
||||
return writeTSDeserializeQuantElement(b, access, f, indent)
|
||||
}
|
||||
|
||||
switch f.Primitive {
|
||||
case parser.KindFloat32:
|
||||
expr := "view.getFloat32(pos, true)"
|
||||
fmt.Fprintf(b, "%s%s = %s;\n", indent, access, tsDeserializeValueExpr(expr, f, enumNames))
|
||||
fmt.Fprintf(b, "%spos += 4;\n", indent)
|
||||
case parser.KindFloat64:
|
||||
expr := "view.getFloat64(pos, true)"
|
||||
fmt.Fprintf(b, "%s%s = %s;\n", indent, access, tsDeserializeValueExpr(expr, f, enumNames))
|
||||
fmt.Fprintf(b, "%spos += 8;\n", indent)
|
||||
case parser.KindInt8:
|
||||
expr := "view.getInt8(pos)"
|
||||
fmt.Fprintf(b, "%s%s = %s;\n", indent, access, tsDeserializeValueExpr(expr, f, enumNames))
|
||||
fmt.Fprintf(b, "%spos += 1;\n", indent)
|
||||
case parser.KindUint8:
|
||||
expr := "view.getUint8(pos)"
|
||||
fmt.Fprintf(b, "%s%s = %s;\n", indent, access, tsDeserializeValueExpr(expr, f, enumNames))
|
||||
fmt.Fprintf(b, "%spos += 1;\n", indent)
|
||||
case parser.KindBool:
|
||||
expr := "view.getUint8(pos) !== 0"
|
||||
fmt.Fprintf(b, "%s%s = %s;\n", indent, access, tsDeserializeValueExpr(expr, f, enumNames))
|
||||
fmt.Fprintf(b, "%spos += 1;\n", indent)
|
||||
case parser.KindInt16:
|
||||
expr := "view.getInt16(pos, true)"
|
||||
fmt.Fprintf(b, "%s%s = %s;\n", indent, access, tsDeserializeValueExpr(expr, f, enumNames))
|
||||
fmt.Fprintf(b, "%spos += 2;\n", indent)
|
||||
case parser.KindUint16:
|
||||
expr := "view.getUint16(pos, true)"
|
||||
fmt.Fprintf(b, "%s%s = %s;\n", indent, access, tsDeserializeValueExpr(expr, f, enumNames))
|
||||
fmt.Fprintf(b, "%spos += 2;\n", indent)
|
||||
case parser.KindInt32:
|
||||
expr := "view.getInt32(pos, true)"
|
||||
fmt.Fprintf(b, "%s%s = %s;\n", indent, access, tsDeserializeValueExpr(expr, f, enumNames))
|
||||
fmt.Fprintf(b, "%spos += 4;\n", indent)
|
||||
case parser.KindUint32:
|
||||
expr := "view.getUint32(pos, true)"
|
||||
fmt.Fprintf(b, "%s%s = %s;\n", indent, access, tsDeserializeValueExpr(expr, f, enumNames))
|
||||
fmt.Fprintf(b, "%spos += 4;\n", indent)
|
||||
case parser.KindInt64:
|
||||
expr := "view.getBigInt64(pos, true)"
|
||||
fmt.Fprintf(b, "%s%s = %s;\n", indent, access, tsDeserializeValueExpr(expr, f, enumNames))
|
||||
fmt.Fprintf(b, "%spos += 8;\n", indent)
|
||||
case parser.KindUint64:
|
||||
expr := "view.getBigUint64(pos, true)"
|
||||
fmt.Fprintf(b, "%s%s = %s;\n", indent, access, tsDeserializeValueExpr(expr, f, enumNames))
|
||||
fmt.Fprintf(b, "%spos += 8;\n", indent)
|
||||
case parser.KindString:
|
||||
lenVar := "_slen" + sanitizeVarName(access)
|
||||
fmt.Fprintf(b, "%sconst %s = view.getUint16(pos, true);\n", indent, lenVar)
|
||||
fmt.Fprintf(b, "%spos += 2;\n", indent)
|
||||
expr := fmt.Sprintf("arpackTextDecoder.decode(new Uint8Array(view.buffer, pos, %s))", lenVar)
|
||||
fmt.Fprintf(b, "%s%s = %s;\n", indent, access, tsDeserializeValueExpr(expr, f, enumNames))
|
||||
fmt.Fprintf(b, "%spos += %s;\n", indent, lenVar)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func writeTSDeserializePrimitive(b *strings.Builder, access string, f parser.Field, indent string, enumNames map[string]struct{}) error {
|
||||
if f.Quant != nil {
|
||||
return writeTSDeserializeQuant(b, access, f, indent)
|
||||
}
|
||||
|
||||
switch f.Primitive {
|
||||
case parser.KindFloat32:
|
||||
expr := "view.getFloat32(pos, true)"
|
||||
fmt.Fprintf(b, "%s%s = %s;\n", indent, access, tsDeserializeValueExpr(expr, f, enumNames))
|
||||
fmt.Fprintf(b, "%spos += 4;\n", indent)
|
||||
case parser.KindFloat64:
|
||||
expr := "view.getFloat64(pos, true)"
|
||||
fmt.Fprintf(b, "%s%s = %s;\n", indent, access, tsDeserializeValueExpr(expr, f, enumNames))
|
||||
fmt.Fprintf(b, "%spos += 8;\n", indent)
|
||||
case parser.KindInt8:
|
||||
expr := "view.getInt8(pos)"
|
||||
fmt.Fprintf(b, "%s%s = %s;\n", indent, access, tsDeserializeValueExpr(expr, f, enumNames))
|
||||
fmt.Fprintf(b, "%spos += 1;\n", indent)
|
||||
case parser.KindUint8:
|
||||
expr := "view.getUint8(pos)"
|
||||
fmt.Fprintf(b, "%s%s = %s;\n", indent, access, tsDeserializeValueExpr(expr, f, enumNames))
|
||||
fmt.Fprintf(b, "%spos += 1;\n", indent)
|
||||
case parser.KindBool:
|
||||
expr := "view.getUint8(pos) !== 0"
|
||||
fmt.Fprintf(b, "%s%s = %s;\n", indent, access, tsDeserializeValueExpr(expr, f, enumNames))
|
||||
fmt.Fprintf(b, "%spos += 1;\n", indent)
|
||||
case parser.KindInt16:
|
||||
expr := "view.getInt16(pos, true)"
|
||||
fmt.Fprintf(b, "%s%s = %s;\n", indent, access, tsDeserializeValueExpr(expr, f, enumNames))
|
||||
fmt.Fprintf(b, "%spos += 2;\n", indent)
|
||||
case parser.KindUint16:
|
||||
expr := "view.getUint16(pos, true)"
|
||||
fmt.Fprintf(b, "%s%s = %s;\n", indent, access, tsDeserializeValueExpr(expr, f, enumNames))
|
||||
fmt.Fprintf(b, "%spos += 2;\n", indent)
|
||||
case parser.KindInt32:
|
||||
expr := "view.getInt32(pos, true)"
|
||||
fmt.Fprintf(b, "%s%s = %s;\n", indent, access, tsDeserializeValueExpr(expr, f, enumNames))
|
||||
fmt.Fprintf(b, "%spos += 4;\n", indent)
|
||||
case parser.KindUint32:
|
||||
expr := "view.getUint32(pos, true)"
|
||||
fmt.Fprintf(b, "%s%s = %s;\n", indent, access, tsDeserializeValueExpr(expr, f, enumNames))
|
||||
fmt.Fprintf(b, "%spos += 4;\n", indent)
|
||||
case parser.KindInt64:
|
||||
expr := "view.getBigInt64(pos, true)"
|
||||
fmt.Fprintf(b, "%s%s = %s;\n", indent, access, tsDeserializeValueExpr(expr, f, enumNames))
|
||||
fmt.Fprintf(b, "%spos += 8;\n", indent)
|
||||
case parser.KindUint64:
|
||||
expr := "view.getBigUint64(pos, true)"
|
||||
fmt.Fprintf(b, "%s%s = %s;\n", indent, access, tsDeserializeValueExpr(expr, f, enumNames))
|
||||
fmt.Fprintf(b, "%spos += 8;\n", indent)
|
||||
case parser.KindString:
|
||||
lenVar := "_slen" + sanitizeVarName(access)
|
||||
fmt.Fprintf(b, "%sconst %s = view.getUint16(pos, true);\n", indent, lenVar)
|
||||
fmt.Fprintf(b, "%spos += 2;\n", indent)
|
||||
expr := fmt.Sprintf("arpackTextDecoder.decode(new Uint8Array(view.buffer, pos, %s))", lenVar)
|
||||
fmt.Fprintf(b, "%s%s = %s;\n", indent, access, tsDeserializeValueExpr(expr, f, enumNames))
|
||||
fmt.Fprintf(b, "%spos += %s;\n", indent, lenVar)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func writeTSDeserializeQuant(b *strings.Builder, access string, f parser.Field, indent string) error {
|
||||
q := f.Quant
|
||||
maxUint := q.MaxUint()
|
||||
varName := "_q" + sanitizeVarName(access)
|
||||
if q.Bits == 8 {
|
||||
fmt.Fprintf(b, "%sconst %s = view.getUint8(pos);\n", indent, varName)
|
||||
fmt.Fprintf(b, "%spos += 1;\n", indent)
|
||||
expr := fmt.Sprintf("%s / %g * (%g - (%g)) + (%g)", varName, maxUint, q.Max, q.Min, q.Min)
|
||||
fmt.Fprintf(b, "%s%s = %s;\n", indent, access, tsDeserializeValueExpr(expr, f, nil))
|
||||
} else {
|
||||
fmt.Fprintf(b, "%sconst %s = view.getUint16(pos, true);\n", indent, varName)
|
||||
fmt.Fprintf(b, "%spos += 2;\n", indent)
|
||||
expr := fmt.Sprintf("%s / %g * (%g - (%g)) + (%g)", varName, maxUint, q.Max, q.Min, q.Min)
|
||||
fmt.Fprintf(b, "%s%s = %s;\n", indent, access, tsDeserializeValueExpr(expr, f, nil))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func writeTSDeserializeQuantElement(b *strings.Builder, access string, f parser.Field, indent string) error {
|
||||
q := f.Quant
|
||||
maxUint := q.MaxUint()
|
||||
varName := "_q" + sanitizeVarName(access)
|
||||
if q.Bits == 8 {
|
||||
fmt.Fprintf(b, "%sconst %s = view.getUint8(pos);\n", indent, varName)
|
||||
fmt.Fprintf(b, "%spos += 1;\n", indent)
|
||||
expr := fmt.Sprintf("%s / %g * (%g - (%g)) + (%g)", varName, maxUint, q.Max, q.Min, q.Min)
|
||||
fmt.Fprintf(b, "%s%s = %s;\n", indent, access, tsDeserializeValueExpr(expr, f, nil))
|
||||
} else {
|
||||
fmt.Fprintf(b, "%sconst %s = view.getUint16(pos, true);\n", indent, varName)
|
||||
fmt.Fprintf(b, "%spos += 2;\n", indent)
|
||||
expr := fmt.Sprintf("%s / %g * (%g - (%g)) + (%g)", varName, maxUint, q.Max, q.Min, q.Min)
|
||||
fmt.Fprintf(b, "%s%s = %s;\n", indent, access, tsDeserializeValueExpr(expr, f, nil))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func tsTypeName(f parser.Field, enumNames map[string]struct{}) string {
|
||||
switch f.Kind {
|
||||
case parser.KindPrimitive:
|
||||
if tsIsEnumType(f, enumNames) {
|
||||
return f.NamedType
|
||||
}
|
||||
return tsPrimitiveTypeName(f.Primitive)
|
||||
case parser.KindNested:
|
||||
return f.TypeName
|
||||
case parser.KindFixedArray, parser.KindSlice:
|
||||
return tsTypeName(*f.Elem, enumNames) + "[]"
|
||||
}
|
||||
return "unknown"
|
||||
}
|
||||
|
||||
func tsPrimitiveTypeName(k parser.PrimitiveKind) string {
|
||||
switch k {
|
||||
case parser.KindFloat32, parser.KindFloat64:
|
||||
return "number"
|
||||
case parser.KindInt8, parser.KindInt16, parser.KindInt32, parser.KindUint8, parser.KindUint16, parser.KindUint32:
|
||||
return "number"
|
||||
case parser.KindInt64, parser.KindUint64:
|
||||
return "bigint"
|
||||
case parser.KindBool:
|
||||
return "boolean"
|
||||
case parser.KindString:
|
||||
return "string"
|
||||
}
|
||||
return "unknown"
|
||||
}
|
||||
|
||||
func tsDefaultValue(f parser.Field) string {
|
||||
switch f.Kind {
|
||||
case parser.KindPrimitive:
|
||||
if tsIsEnumType(f, nil) {
|
||||
return "0"
|
||||
}
|
||||
switch f.Primitive {
|
||||
case parser.KindFloat32, parser.KindFloat64, parser.KindInt8, parser.KindInt16, parser.KindInt32,
|
||||
parser.KindUint8, parser.KindUint16, parser.KindUint32:
|
||||
return "0"
|
||||
case parser.KindInt64, parser.KindUint64:
|
||||
return "0n"
|
||||
case parser.KindBool:
|
||||
return "false"
|
||||
case parser.KindString:
|
||||
return `""`
|
||||
}
|
||||
case parser.KindNested:
|
||||
return fmt.Sprintf("new %s()", f.TypeName)
|
||||
case parser.KindFixedArray:
|
||||
elemDefault := tsDefaultValue(*f.Elem)
|
||||
elemType := tsTypeName(*f.Elem, nil)
|
||||
return fmt.Sprintf("new Array<%s>(%d).fill(%s)", elemType, f.FixedLen, elemDefault)
|
||||
case parser.KindSlice:
|
||||
return "[]"
|
||||
}
|
||||
return "undefined"
|
||||
}
|
||||
|
||||
func tsSerializeValueExpr(access string, f parser.Field, enumNames map[string]struct{}) string {
|
||||
if !tsIsEnumType(f, enumNames) {
|
||||
return access
|
||||
}
|
||||
return access + " as " + tsPrimitiveTypeName(f.Primitive)
|
||||
}
|
||||
|
||||
func tsDeserializeValueExpr(expr string, f parser.Field, enumNames map[string]struct{}) string {
|
||||
if !tsIsEnumType(f, enumNames) {
|
||||
return expr
|
||||
}
|
||||
return "(" + expr + " as " + f.NamedType + ")"
|
||||
}
|
||||
|
||||
func tsIsEnumType(f parser.Field, enumNames map[string]struct{}) bool {
|
||||
if f.NamedType == "" || enumNames == nil {
|
||||
return false
|
||||
}
|
||||
_, ok := enumNames[f.NamedType]
|
||||
return ok
|
||||
}
|
||||
|
||||
// toCamelCase converts PascalCase to camelCase (e.g., EntityID -> entityID)
|
||||
func toCamelCase(s string) string {
|
||||
if s == "" {
|
||||
return ""
|
||||
}
|
||||
// First character to lowercase
|
||||
result := strings.ToLower(s[:1]) + s[1:]
|
||||
return result
|
||||
}
|
||||
@@ -0,0 +1,467 @@
|
||||
package generator
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/edmand46/arpack/parser"
|
||||
)
|
||||
|
||||
func TestGenerateTypeScript_Primitives(t *testing.T) {
|
||||
schema := parser.Schema{
|
||||
Messages: []parser.Message{
|
||||
{
|
||||
PackageName: "test",
|
||||
Name: "PrimitiveMessage",
|
||||
Fields: []parser.Field{
|
||||
{Name: "F32", Kind: parser.KindPrimitive, Primitive: parser.KindFloat32},
|
||||
{Name: "F64", Kind: parser.KindPrimitive, Primitive: parser.KindFloat64},
|
||||
{Name: "I8", Kind: parser.KindPrimitive, Primitive: parser.KindInt8},
|
||||
{Name: "I16", Kind: parser.KindPrimitive, Primitive: parser.KindInt16},
|
||||
{Name: "I32", Kind: parser.KindPrimitive, Primitive: parser.KindInt32},
|
||||
{Name: "I64", Kind: parser.KindPrimitive, Primitive: parser.KindInt64},
|
||||
{Name: "U8", Kind: parser.KindPrimitive, Primitive: parser.KindUint8},
|
||||
{Name: "U16", Kind: parser.KindPrimitive, Primitive: parser.KindUint16},
|
||||
{Name: "U32", Kind: parser.KindPrimitive, Primitive: parser.KindUint32},
|
||||
{Name: "U64", Kind: parser.KindPrimitive, Primitive: parser.KindUint64},
|
||||
{Name: "B", Kind: parser.KindPrimitive, Primitive: parser.KindBool},
|
||||
{Name: "S", Kind: parser.KindPrimitive, Primitive: parser.KindString},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
src, err := GenerateTypeScriptSchema(schema, "Test")
|
||||
if err != nil {
|
||||
t.Fatalf("GenerateTypeScriptSchema: %v", err)
|
||||
}
|
||||
|
||||
code := string(src)
|
||||
|
||||
// Check field declarations (now using camelCase)
|
||||
if !strings.Contains(code, "f32: number = 0;") {
|
||||
t.Error("Missing f32 field")
|
||||
}
|
||||
if !strings.Contains(code, "i64: bigint = 0n;") {
|
||||
t.Error("Missing i64 field with bigint type")
|
||||
}
|
||||
if !strings.Contains(code, "u64: bigint = 0n;") {
|
||||
t.Error("Missing u64 field with bigint type")
|
||||
}
|
||||
if !strings.Contains(code, "b: boolean = false;") {
|
||||
t.Error("Missing b field")
|
||||
}
|
||||
if !strings.Contains(code, "s: string = \"\";") {
|
||||
t.Error("Missing s field")
|
||||
}
|
||||
|
||||
// Check serialize method exists
|
||||
if !strings.Contains(code, "serialize(view: DataView, offset: number): number") {
|
||||
t.Error("Missing serialize method")
|
||||
}
|
||||
|
||||
// Check deserialize method exists
|
||||
if !strings.Contains(code, "static deserialize(view: DataView, offset: number): [PrimitiveMessage, number]") {
|
||||
t.Error("Missing deserialize method")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateTypeScript_QuantizedFloats(t *testing.T) {
|
||||
schema := parser.Schema{
|
||||
Messages: []parser.Message{
|
||||
{
|
||||
PackageName: "test",
|
||||
Name: "QuantMessage",
|
||||
Fields: []parser.Field{
|
||||
{
|
||||
Name: "Q8",
|
||||
Kind: parser.KindPrimitive,
|
||||
Primitive: parser.KindFloat32,
|
||||
Quant: &parser.QuantInfo{Min: 0, Max: 100, Bits: 8},
|
||||
},
|
||||
{
|
||||
Name: "Q16",
|
||||
Kind: parser.KindPrimitive,
|
||||
Primitive: parser.KindFloat32,
|
||||
Quant: &parser.QuantInfo{Min: -500, Max: 500, Bits: 16},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
src, err := GenerateTypeScriptSchema(schema, "Test")
|
||||
if err != nil {
|
||||
t.Fatalf("GenerateTypeScriptSchema: %v", err)
|
||||
}
|
||||
|
||||
code := string(src)
|
||||
|
||||
// Check 8-bit quantization (using camelCase field names)
|
||||
if !strings.Contains(code, "Math.trunc((this.q8 - (0)) / (100 - (0)) * 255)") {
|
||||
t.Error("Missing 8-bit quantization code")
|
||||
}
|
||||
if !strings.Contains(code, `arpackEnsureQuantizedRange(this.q8, 0, 100, "Q8");`) {
|
||||
t.Error("Missing 8-bit quantized range guard")
|
||||
}
|
||||
|
||||
// Check 16-bit quantization (using camelCase field names)
|
||||
if !strings.Contains(code, "Math.trunc((this.q16 - (-500)) / (500 - (-500)) * 65535)") {
|
||||
t.Error("Missing 16-bit quantization code")
|
||||
}
|
||||
if !strings.Contains(code, `arpackEnsureQuantizedRange(this.q16, -500, 500, "Q16");`) {
|
||||
t.Error("Missing 16-bit quantized range guard")
|
||||
}
|
||||
|
||||
// Check deserialization with dequantization
|
||||
if !strings.Contains(code, "/ 255 * (100 - (0)) + (0)") {
|
||||
t.Error("Missing 8-bit dequantization")
|
||||
}
|
||||
if !strings.Contains(code, "/ 65535 * (500 - (-500)) + (-500)") {
|
||||
t.Error("Missing 16-bit dequantization")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateTypeScript_BoolPacking(t *testing.T) {
|
||||
schema := parser.Schema{
|
||||
Messages: []parser.Message{
|
||||
{
|
||||
PackageName: "test",
|
||||
Name: "BoolMessage",
|
||||
Fields: []parser.Field{
|
||||
{Name: "A", Kind: parser.KindPrimitive, Primitive: parser.KindBool},
|
||||
{Name: "B", Kind: parser.KindPrimitive, Primitive: parser.KindBool},
|
||||
{Name: "C", Kind: parser.KindPrimitive, Primitive: parser.KindBool},
|
||||
{Name: "X", Kind: parser.KindPrimitive, Primitive: parser.KindUint32},
|
||||
{Name: "D", Kind: parser.KindPrimitive, Primitive: parser.KindBool},
|
||||
{Name: "E", Kind: parser.KindPrimitive, Primitive: parser.KindBool},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
src, err := GenerateTypeScriptSchema(schema, "Test")
|
||||
if err != nil {
|
||||
t.Fatalf("GenerateTypeScriptSchema: %v", err)
|
||||
}
|
||||
|
||||
code := string(src)
|
||||
|
||||
// Check that consecutive bools are packed (using camelCase field names)
|
||||
if !strings.Contains(code, "let _boolByte0 = 0;") {
|
||||
t.Error("Missing first bool group packing")
|
||||
}
|
||||
if !strings.Contains(code, "if (this.a) _boolByte0 |= 1 << 0;") {
|
||||
t.Error("Missing a bool packing")
|
||||
}
|
||||
if !strings.Contains(code, "if (this.b) _boolByte0 |= 1 << 1;") {
|
||||
t.Error("Missing b bool packing")
|
||||
}
|
||||
if !strings.Contains(code, "if (this.c) _boolByte0 |= 1 << 2;") {
|
||||
t.Error("Missing c bool packing")
|
||||
}
|
||||
|
||||
// Check second bool group after uint32 (index is 2, not 4, based on segment index)
|
||||
if !strings.Contains(code, "let _boolByte2 = 0;") {
|
||||
t.Error("Missing second bool group packing")
|
||||
}
|
||||
|
||||
// Check deserialization (using camelCase field names)
|
||||
if !strings.Contains(code, "msg.a = (_boolByte0 & (1 << 0)) !== 0;") {
|
||||
t.Error("Missing a bool unpacking")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateTypeScript_NestedTypes(t *testing.T) {
|
||||
schema := parser.Schema{
|
||||
Messages: []parser.Message{
|
||||
{
|
||||
PackageName: "test",
|
||||
Name: "Inner",
|
||||
Fields: []parser.Field{
|
||||
{Name: "Value", Kind: parser.KindPrimitive, Primitive: parser.KindInt32},
|
||||
},
|
||||
},
|
||||
{
|
||||
PackageName: "test",
|
||||
Name: "Outer",
|
||||
Fields: []parser.Field{
|
||||
{Name: "Inner", Kind: parser.KindNested, TypeName: "Inner"},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
src, err := GenerateTypeScriptSchema(schema, "Test")
|
||||
if err != nil {
|
||||
t.Fatalf("GenerateTypeScriptSchema: %v", err)
|
||||
}
|
||||
|
||||
code := string(src)
|
||||
|
||||
// Check nested type default value (using camelCase field name)
|
||||
if !strings.Contains(code, "inner: Inner = new Inner();") {
|
||||
t.Error("Missing nested type field with default")
|
||||
}
|
||||
|
||||
// Check serialize calls nested serialize (using camelCase field name)
|
||||
if !strings.Contains(code, "pos += this.inner.serialize(view, pos);") {
|
||||
t.Error("Missing nested serialize call")
|
||||
}
|
||||
|
||||
// Check deserialize calls nested deserialize
|
||||
if !strings.Contains(code, "const [_Inner, _nInner] = Inner.deserialize(view, pos);") {
|
||||
t.Error("Missing nested deserialize call")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateTypeScript_FixedArrays(t *testing.T) {
|
||||
schema := parser.Schema{
|
||||
Messages: []parser.Message{
|
||||
{
|
||||
PackageName: "test",
|
||||
Name: "ArrayMessage",
|
||||
Fields: []parser.Field{
|
||||
{
|
||||
Name: "Values",
|
||||
Kind: parser.KindFixedArray,
|
||||
FixedLen: 3,
|
||||
Elem: &parser.Field{
|
||||
Kind: parser.KindPrimitive,
|
||||
Primitive: parser.KindFloat32,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
src, err := GenerateTypeScriptSchema(schema, "Test")
|
||||
if err != nil {
|
||||
t.Fatalf("GenerateTypeScriptSchema: %v", err)
|
||||
}
|
||||
|
||||
code := string(src)
|
||||
|
||||
// Check default value (using camelCase field name)
|
||||
if !strings.Contains(code, "values: number[] = new Array<number>(3).fill(0);") {
|
||||
t.Error("Missing fixed array field with default")
|
||||
}
|
||||
|
||||
// Check serialization loop (using camelCase field name)
|
||||
if !strings.Contains(code, "for (let _iValues = 0; _iValues < 3; _iValues++)") {
|
||||
t.Error("Missing fixed array serialization loop")
|
||||
}
|
||||
|
||||
// Check deserialization loop (using camelCase field name)
|
||||
if !strings.Contains(code, "msg.values = new Array(3);") {
|
||||
t.Error("Missing fixed array allocation in deserialize")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateTypeScript_Slices(t *testing.T) {
|
||||
schema := parser.Schema{
|
||||
Messages: []parser.Message{
|
||||
{
|
||||
PackageName: "test",
|
||||
Name: "SliceMessage",
|
||||
Fields: []parser.Field{
|
||||
{
|
||||
Name: "Items",
|
||||
Kind: parser.KindSlice,
|
||||
Elem: &parser.Field{
|
||||
Kind: parser.KindPrimitive,
|
||||
Primitive: parser.KindInt32,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
src, err := GenerateTypeScriptSchema(schema, "Test")
|
||||
if err != nil {
|
||||
t.Fatalf("GenerateTypeScriptSchema: %v", err)
|
||||
}
|
||||
|
||||
code := string(src)
|
||||
|
||||
// Check default value (using camelCase field name)
|
||||
if !strings.Contains(code, "items: number[] = [];") {
|
||||
t.Error("Missing slice field with default")
|
||||
}
|
||||
|
||||
// Check length prefix in serialize (using camelCase field name)
|
||||
if !strings.Contains(code, `arpackEnsureUint16Length(this.items.length, "slice length for Items")`) {
|
||||
t.Error("Missing slice length guard in serialize")
|
||||
}
|
||||
if !strings.Contains(code, "view.setUint16(pos, _lenthis_items, true);") {
|
||||
t.Error("Missing guarded slice length prefix in serialize")
|
||||
}
|
||||
|
||||
// Check length reading in deserialize
|
||||
if !strings.Contains(code, "const _lenItems = view.getUint16(pos, true);") {
|
||||
t.Error("Missing slice length reading in deserialize")
|
||||
}
|
||||
|
||||
// Check array allocation in deserialize (using camelCase field name)
|
||||
if !strings.Contains(code, "msg.items = new Array(_lenItems);") {
|
||||
t.Error("Missing slice allocation in deserialize")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateTypeScript_Enums(t *testing.T) {
|
||||
schema := parser.Schema{
|
||||
Enums: []parser.Enum{
|
||||
{
|
||||
Name: "Status",
|
||||
Primitive: parser.KindUint16,
|
||||
Values: []parser.EnumValue{
|
||||
{Name: "Pending", Value: "0"},
|
||||
{Name: "Active", Value: "1"},
|
||||
{Name: "Done", Value: "2"},
|
||||
},
|
||||
},
|
||||
},
|
||||
Messages: []parser.Message{
|
||||
{
|
||||
PackageName: "test",
|
||||
Name: "EnumMessage",
|
||||
Fields: []parser.Field{
|
||||
{
|
||||
Name: "Status",
|
||||
Kind: parser.KindPrimitive,
|
||||
Primitive: parser.KindUint16,
|
||||
NamedType: "Status",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
src, err := GenerateTypeScriptSchema(schema, "Test")
|
||||
if err != nil {
|
||||
t.Fatalf("GenerateTypeScriptSchema: %v", err)
|
||||
}
|
||||
|
||||
code := string(src)
|
||||
|
||||
// Check enum definition
|
||||
if !strings.Contains(code, "export enum Status {") {
|
||||
t.Error("Missing enum definition")
|
||||
}
|
||||
if !strings.Contains(code, "Pending = 0,") {
|
||||
t.Error("Missing Pending enum value")
|
||||
}
|
||||
if !strings.Contains(code, "Active = 1,") {
|
||||
t.Error("Missing Active enum value")
|
||||
}
|
||||
|
||||
// Check enum field type (using camelCase field name)
|
||||
if !strings.Contains(code, "status: Status = 0;") {
|
||||
t.Error("Missing enum field with correct type")
|
||||
}
|
||||
|
||||
// Check enum serialization (cast to number, using camelCase field name)
|
||||
if !strings.Contains(code, "view.setUint16(pos, this.status as number, true);") {
|
||||
t.Error("Missing enum cast in serialize")
|
||||
}
|
||||
|
||||
// Check enum deserialization (cast from number, using camelCase field name)
|
||||
if !strings.Contains(code, "msg.status = (view.getUint16(pos, true) as Status);") {
|
||||
t.Error("Missing enum cast in deserialize")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateTypeScript_Strings(t *testing.T) {
|
||||
schema := parser.Schema{
|
||||
Messages: []parser.Message{
|
||||
{
|
||||
PackageName: "test",
|
||||
Name: "StringMessage",
|
||||
Fields: []parser.Field{
|
||||
{Name: "Name", Kind: parser.KindPrimitive, Primitive: parser.KindString},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
src, err := GenerateTypeScriptSchema(schema, "Test")
|
||||
if err != nil {
|
||||
t.Fatalf("GenerateTypeScriptSchema: %v", err)
|
||||
}
|
||||
|
||||
code := string(src)
|
||||
|
||||
// Check TextEncoder usage
|
||||
if !strings.Contains(code, "const arpackTextEncoder = new TextEncoder();") {
|
||||
t.Error("Missing shared TextEncoder helper")
|
||||
}
|
||||
|
||||
// Check length prefix
|
||||
if !strings.Contains(code, "view.setUint16(pos, _slen") {
|
||||
t.Error("Missing string length prefix in serialize")
|
||||
}
|
||||
if !strings.Contains(code, `arpackEnsureUint16Length(_slen`) {
|
||||
t.Error("Missing string length guard in serialize")
|
||||
}
|
||||
|
||||
// Check TextDecoder usage
|
||||
if !strings.Contains(code, "const arpackTextDecoder = new TextDecoder();") {
|
||||
t.Error("Missing shared TextDecoder helper")
|
||||
}
|
||||
if !strings.Contains(code, "arpackTextDecoder.decode(") {
|
||||
t.Error("Missing shared TextDecoder in deserialize")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateTypeScript_LengthAndRangeHelpers(t *testing.T) {
|
||||
schema := parser.Schema{
|
||||
Messages: []parser.Message{
|
||||
{
|
||||
PackageName: "test",
|
||||
Name: "LengthAndQuant",
|
||||
Fields: []parser.Field{
|
||||
{Name: "Name", Kind: parser.KindPrimitive, Primitive: parser.KindString},
|
||||
{
|
||||
Name: "Items",
|
||||
Kind: parser.KindSlice,
|
||||
Elem: &parser.Field{
|
||||
Kind: parser.KindPrimitive,
|
||||
Primitive: parser.KindUint8,
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "Ratio",
|
||||
Kind: parser.KindPrimitive,
|
||||
Primitive: parser.KindFloat32,
|
||||
Quant: &parser.QuantInfo{Min: 0, Max: 1, Bits: 8},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
src, err := GenerateTypeScriptSchema(schema, "Test")
|
||||
if err != nil {
|
||||
t.Fatalf("GenerateTypeScriptSchema: %v", err)
|
||||
}
|
||||
|
||||
code := string(src)
|
||||
|
||||
if !strings.Contains(code, "function arpackEnsureUint16Length(length: number, context: string): number") {
|
||||
t.Error("Missing uint16 length helper")
|
||||
}
|
||||
if !strings.Contains(code, "function arpackEnsureQuantizedRange(value: number, min: number, max: number, context: string): void") {
|
||||
t.Error("Missing quantized range helper")
|
||||
}
|
||||
if !strings.Contains(code, `arpackEnsureUint16Length(this.items.length, "slice length for Items")`) {
|
||||
t.Error("Missing slice length guard")
|
||||
}
|
||||
if !strings.Contains(code, `arpackEnsureUint16Length(_slen`) {
|
||||
t.Error("Missing string length helper call")
|
||||
}
|
||||
if !strings.Contains(code, `arpackEnsureQuantizedRange(this.ratio, 0, 1, "Ratio");`) {
|
||||
t.Error("Missing quantized range helper call")
|
||||
}
|
||||
}
|
||||
@@ -1 +1,8 @@
|
||||
module github.com/edmand46/arpack
|
||||
|
||||
go 1.23
|
||||
|
||||
require (
|
||||
github.com/google/flatbuffers v25.2.10+incompatible
|
||||
google.golang.org/protobuf v1.36.11
|
||||
)
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
github.com/google/flatbuffers v25.2.10+incompatible h1:F3vclr7C3HpB1k9mxCGRMXq6FdUalZ6H/pNX4FP1v0Q=
|
||||
github.com/google/flatbuffers v25.2.10+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
|
||||
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
||||
+69
-13
@@ -55,6 +55,8 @@ func parseASTFile(fset *token.FileSet, f *ast.File) (Schema, error) {
|
||||
|
||||
knownStructs := map[string]bool{}
|
||||
namedPrimitives := map[string]PrimitiveKind{}
|
||||
unsupportedNamedPrimitives := map[string]string{}
|
||||
unresolvedNamedPrimitives := map[string]string{}
|
||||
var enumOrder []string
|
||||
|
||||
for _, decl := range f.Decls {
|
||||
@@ -73,8 +75,14 @@ func parseASTFile(fset *token.FileSet, f *ast.File) (Schema, error) {
|
||||
case *ast.StructType:
|
||||
knownStructs[typeSpec.Name.Name] = true
|
||||
case *ast.Ident:
|
||||
switch t.Name {
|
||||
case "int", "uint", "uintptr":
|
||||
unsupportedNamedPrimitives[typeSpec.Name.Name] = t.Name
|
||||
continue
|
||||
}
|
||||
primKind, isPrimitive := goPrimitiveKind(t.Name)
|
||||
if !isPrimitive {
|
||||
unresolvedNamedPrimitives[typeSpec.Name.Name] = t.Name
|
||||
continue
|
||||
}
|
||||
namedPrimitives[typeSpec.Name.Name] = primKind
|
||||
@@ -85,6 +93,19 @@ func parseASTFile(fset *token.FileSet, f *ast.File) (Schema, error) {
|
||||
}
|
||||
}
|
||||
|
||||
for changed := true; changed; {
|
||||
changed = false
|
||||
for name, target := range unresolvedNamedPrimitives {
|
||||
if _, ok := unsupportedNamedPrimitives[name]; ok {
|
||||
continue
|
||||
}
|
||||
if baseType, ok := unsupportedNamedPrimitives[target]; ok {
|
||||
unsupportedNamedPrimitives[name] = baseType
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
info, err := typeCheckFile(fset, f)
|
||||
if err != nil {
|
||||
return Schema{}, err
|
||||
@@ -119,7 +140,14 @@ func parseASTFile(fset *token.FileSet, f *ast.File) (Schema, error) {
|
||||
continue
|
||||
}
|
||||
|
||||
msg, err := parseStruct(pkgName, typeSpec.Name.Name, structType, knownStructs, namedPrimitives)
|
||||
msg, err := parseStruct(
|
||||
pkgName,
|
||||
typeSpec.Name.Name,
|
||||
structType,
|
||||
knownStructs,
|
||||
namedPrimitives,
|
||||
unsupportedNamedPrimitives,
|
||||
)
|
||||
if err != nil {
|
||||
return Schema{}, fmt.Errorf("struct %s: %w", typeSpec.Name.Name, err)
|
||||
}
|
||||
@@ -127,9 +155,7 @@ func parseASTFile(fset *token.FileSet, f *ast.File) (Schema, error) {
|
||||
schema.Messages = append(schema.Messages, msg)
|
||||
}
|
||||
case token.CONST:
|
||||
if err := parseConstDecls(genDecl, info, enumIndex, &schema); err != nil {
|
||||
return Schema{}, err
|
||||
}
|
||||
parseConstDecls(genDecl, info, enumIndex, &schema)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,7 +178,7 @@ func typeCheckFile(fset *token.FileSet, f *ast.File) (*types.Info, error) {
|
||||
return info, nil
|
||||
}
|
||||
|
||||
func parseConstDecls(genDecl *ast.GenDecl, info *types.Info, enumIndex map[string]int, schema *Schema) error {
|
||||
func parseConstDecls(genDecl *ast.GenDecl, info *types.Info, enumIndex map[string]int, schema *Schema) {
|
||||
for _, spec := range genDecl.Specs {
|
||||
valueSpec, ok := spec.(*ast.ValueSpec)
|
||||
if !ok {
|
||||
@@ -181,8 +207,6 @@ func parseConstDecls(genDecl *ast.GenDecl, info *types.Info, enumIndex map[strin
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func parseStruct(
|
||||
@@ -191,6 +215,7 @@ func parseStruct(
|
||||
st *ast.StructType,
|
||||
knownStructs map[string]bool,
|
||||
namedPrimitives map[string]PrimitiveKind,
|
||||
unsupportedNamedPrimitives map[string]string,
|
||||
) (Message, error) {
|
||||
msg := Message{PackageName: pkg, Name: name}
|
||||
|
||||
@@ -206,7 +231,14 @@ func parseStruct(
|
||||
}
|
||||
|
||||
for _, fieldName := range astField.Names {
|
||||
field, err := parseFieldType(fieldName.Name, astField.Type, rawTag, knownStructs, namedPrimitives)
|
||||
field, err := parseFieldType(
|
||||
fieldName.Name,
|
||||
astField.Type,
|
||||
rawTag,
|
||||
knownStructs,
|
||||
namedPrimitives,
|
||||
unsupportedNamedPrimitives,
|
||||
)
|
||||
if err != nil {
|
||||
return Message{}, fmt.Errorf("field %s: %w", fieldName.Name, err)
|
||||
}
|
||||
@@ -223,14 +255,22 @@ func parseFieldType(
|
||||
rawTag string,
|
||||
knownStructs map[string]bool,
|
||||
namedPrimitives map[string]PrimitiveKind,
|
||||
unsupportedNamedPrimitives map[string]string,
|
||||
) (Field, error) {
|
||||
switch t := expr.(type) {
|
||||
case *ast.Ident:
|
||||
return parsePrimitiveOrNested(name, t.Name, rawTag, knownStructs, namedPrimitives)
|
||||
return parsePrimitiveOrNested(
|
||||
name,
|
||||
t.Name,
|
||||
rawTag,
|
||||
knownStructs,
|
||||
namedPrimitives,
|
||||
unsupportedNamedPrimitives,
|
||||
)
|
||||
|
||||
case *ast.ArrayType:
|
||||
if t.Len == nil {
|
||||
elem, err := parseFieldType("", t.Elt, rawTag, knownStructs, namedPrimitives)
|
||||
elem, err := parseFieldType("", t.Elt, rawTag, knownStructs, namedPrimitives, unsupportedNamedPrimitives)
|
||||
if err != nil {
|
||||
return Field{}, fmt.Errorf("slice element: %w", err)
|
||||
}
|
||||
@@ -247,7 +287,7 @@ func parseFieldType(
|
||||
return Field{}, fmt.Errorf("array length: %w", err)
|
||||
}
|
||||
|
||||
elem, err := parseFieldType("", t.Elt, rawTag, knownStructs, namedPrimitives)
|
||||
elem, err := parseFieldType("", t.Elt, rawTag, knownStructs, namedPrimitives, unsupportedNamedPrimitives)
|
||||
if err != nil {
|
||||
return Field{}, fmt.Errorf("array element: %w", err)
|
||||
}
|
||||
@@ -275,9 +315,25 @@ func parsePrimitiveOrNested(
|
||||
rawTag string,
|
||||
knownStructs map[string]bool,
|
||||
namedPrimitives map[string]PrimitiveKind,
|
||||
unsupportedNamedPrimitives map[string]string,
|
||||
) (Field, error) {
|
||||
switch typeName {
|
||||
case "int", "uint", "uintptr":
|
||||
return Field{}, fmt.Errorf(
|
||||
"platform-dependent type %q is not supported; use int32/int64, uint32/uint64, or fixed-size integer IDs instead",
|
||||
typeName,
|
||||
)
|
||||
}
|
||||
|
||||
primKind, isPrimitive := goPrimitiveKind(typeName)
|
||||
if !isPrimitive {
|
||||
if baseType, ok := unsupportedNamedPrimitives[typeName]; ok {
|
||||
return Field{}, fmt.Errorf(
|
||||
"type %q aliases unsupported platform-dependent %q; use int32/int64, uint32/uint64, or fixed-size integer IDs instead",
|
||||
typeName,
|
||||
baseType,
|
||||
)
|
||||
}
|
||||
if namedPrimitive, ok := namedPrimitives[typeName]; ok {
|
||||
return buildPrimitiveField(name, typeName, namedPrimitive, rawTag)
|
||||
}
|
||||
@@ -389,7 +445,7 @@ func goPrimitiveKind(name string) (PrimitiveKind, bool) {
|
||||
return KindInt8, true
|
||||
case "int16":
|
||||
return KindInt16, true
|
||||
case "int32", "int":
|
||||
case "int32":
|
||||
return KindInt32, true
|
||||
case "int64":
|
||||
return KindInt64, true
|
||||
@@ -397,7 +453,7 @@ func goPrimitiveKind(name string) (PrimitiveKind, bool) {
|
||||
return KindUint8, true
|
||||
case "uint16":
|
||||
return KindUint16, true
|
||||
case "uint32", "uint":
|
||||
case "uint32":
|
||||
return KindUint32, true
|
||||
case "uint64":
|
||||
return KindUint64, true
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package parser
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
@@ -266,3 +267,92 @@ type Msg struct {
|
||||
t.Fatal("expected error for unknown nested type, got nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnsupportedPlatformDependentIntTypes(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
src string
|
||||
wantErr string
|
||||
}{
|
||||
{
|
||||
name: "direct int field",
|
||||
src: `package p
|
||||
type Msg struct {
|
||||
X int
|
||||
}
|
||||
`,
|
||||
wantErr: `platform-dependent type "int" is not supported`,
|
||||
},
|
||||
{
|
||||
name: "direct uint field",
|
||||
src: `package p
|
||||
type Msg struct {
|
||||
X uint
|
||||
}
|
||||
`,
|
||||
wantErr: `platform-dependent type "uint" is not supported`,
|
||||
},
|
||||
{
|
||||
name: "direct uintptr field",
|
||||
src: `package p
|
||||
type Msg struct {
|
||||
X uintptr
|
||||
}
|
||||
`,
|
||||
wantErr: `platform-dependent type "uintptr" is not supported`,
|
||||
},
|
||||
{
|
||||
name: "alias of int",
|
||||
src: `package p
|
||||
type Counter int
|
||||
type Msg struct {
|
||||
X Counter
|
||||
}
|
||||
`,
|
||||
wantErr: `type "Counter" aliases unsupported platform-dependent "int"`,
|
||||
},
|
||||
{
|
||||
name: "alias of uint",
|
||||
src: `package p
|
||||
type Counter uint
|
||||
type Msg struct {
|
||||
X Counter
|
||||
}
|
||||
`,
|
||||
wantErr: `type "Counter" aliases unsupported platform-dependent "uint"`,
|
||||
},
|
||||
{
|
||||
name: "alias of uintptr",
|
||||
src: `package p
|
||||
type Handle uintptr
|
||||
type Msg struct {
|
||||
X Handle
|
||||
}
|
||||
`,
|
||||
wantErr: `type "Handle" aliases unsupported platform-dependent "uintptr"`,
|
||||
},
|
||||
{
|
||||
name: "transitive alias of int",
|
||||
src: `package p
|
||||
type Base int
|
||||
type Counter Base
|
||||
type Msg struct {
|
||||
X Counter
|
||||
}
|
||||
`,
|
||||
wantErr: `type "Counter" aliases unsupported platform-dependent "int"`,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
_, err := ParseSource(tc.src)
|
||||
if err == nil {
|
||||
t.Fatal("expected error, got nil")
|
||||
}
|
||||
if !strings.Contains(err.Error(), tc.wantErr) {
|
||||
t.Fatalf("expected error containing %q, got %v", tc.wantErr, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+39
@@ -0,0 +1,39 @@
|
||||
package lua
|
||||
|
||||
type Vector3 struct {
|
||||
X float32 `pack:"min=-500,max=500,bits=16"`
|
||||
Y float32 `pack:"min=-500,max=500,bits=16"`
|
||||
Z float32 `pack:"min=-500,max=500,bits=16"`
|
||||
}
|
||||
|
||||
type Opcode uint16
|
||||
|
||||
const (
|
||||
OpcodeUnknown Opcode = iota
|
||||
OpcodeAuthorize
|
||||
OpcodeJoinRoom
|
||||
)
|
||||
|
||||
type MoveMessage struct {
|
||||
Position Vector3
|
||||
Velocity [3]float32
|
||||
Waypoints []Vector3
|
||||
PlayerID uint32
|
||||
Active bool
|
||||
Visible bool
|
||||
Ghost bool
|
||||
Name string
|
||||
}
|
||||
|
||||
type SpawnMessage struct {
|
||||
EntityID uint32
|
||||
Position Vector3
|
||||
Health int16
|
||||
Tags []string
|
||||
Data []uint8
|
||||
}
|
||||
|
||||
type EnvelopeMessage struct {
|
||||
Code Opcode
|
||||
Counter uint8
|
||||
}
|
||||
Vendored
+7
-11
@@ -1,6 +1,5 @@
|
||||
package messages
|
||||
|
||||
// Vector3 — трёхмерный вектор с квантизацией.
|
||||
type Vector3 struct {
|
||||
X float32 `pack:"min=-500,max=500,bits=16"`
|
||||
Y float32 `pack:"min=-500,max=500,bits=16"`
|
||||
@@ -15,20 +14,17 @@ const (
|
||||
OpcodeJoinRoom
|
||||
)
|
||||
|
||||
// MoveMessage содержит всё многообразие поддерживаемых типов.
|
||||
type MoveMessage struct {
|
||||
Position Vector3 // вложенный тип
|
||||
Velocity [3]float32 // фиксированный массив без квантизации
|
||||
Waypoints []Vector3 // слайс вложенных типов
|
||||
Position Vector3
|
||||
Velocity [3]float32
|
||||
Waypoints []Vector3
|
||||
PlayerID uint32
|
||||
// 3 подряд bool → упаковываются в 1 байт
|
||||
Active bool
|
||||
Visible bool
|
||||
Ghost bool
|
||||
Name string
|
||||
Active bool
|
||||
Visible bool
|
||||
Ghost bool
|
||||
Name string
|
||||
}
|
||||
|
||||
// SpawnMessage — пример с целочисленными полями и массивами примитивов.
|
||||
type SpawnMessage struct {
|
||||
EntityID uint64
|
||||
Position Vector3
|
||||
|
||||
Reference in New Issue
Block a user