Skip to content

Commit abcc059

Browse files
committed
revert(natives): String changes
1 parent 20bbfb7 commit abcc059

30 files changed

+5198
-4496
lines changed

generator/native_generator/main.py

Lines changed: 75 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ def __init__(self):
5151

5252
def add_line(self, text: str = ""):
5353
if text.strip():
54-
self.lines.append(" " * self.indent_level + text)
54+
self.lines.append(" " * self.indent_level + text)
5555
else:
5656
self.lines.append("")
5757

@@ -62,15 +62,14 @@ def dedent(self):
6262
self.indent_level = max(0, self.indent_level - 1)
6363

6464
def add_block(self, header: str, content_func):
65-
self.add_line(header)
66-
self.add_line("{")
65+
self.add_line(header + " {")
6766
self.indent()
6867
content_func()
6968
self.dedent()
7069
self.add_line("}")
7170

7271
def get_code(self) -> str:
73-
return "\r\n".join(self.lines)
72+
return "\n".join(self.lines)
7473

7574

7675
def split_by_last_dot(value: str):
@@ -95,6 +94,7 @@ def parse_native(lines: list[str]):
9594
writer.add_line("#pragma warning disable CS0649")
9695
writer.add_line("#pragma warning disable CS0169")
9796
writer.add_line()
97+
writer.add_line("using System.Buffers;")
9898
writer.add_line("using System.Text;")
9999
writer.add_line("using System.Threading;")
100100
writer.add_line("using SwiftlyS2.Shared.Natives;")
@@ -158,68 +158,24 @@ def write_method_content():
158158
if is_marked_sync:
159159
writer.add_block("if (Thread.CurrentThread.ManagedThreadId != _MainThreadID)", lambda: writer.add_line('throw new InvalidOperationException("This method can only be called from the main thread.");'))
160160

161-
string_params = [n for t, n in param_signatures if t == "string"]
162-
bytes_params = [n for t, n in param_signatures if t == "byte[]"]
163-
164-
for param in bytes_params:
165-
writer.add_line(f"var {param}Length = {param}.Length;")
166-
167-
if not string_params:
168-
fixed_blocks = []
169-
for param in bytes_params:
170-
fixed_blocks.append(f"fixed (byte* {param}BufferPtr = {param})")
171-
172-
def write_simple_call():
173-
call_args = []
174-
for t, n in param_signatures:
175-
if t == "byte[]":
176-
call_args.extend([f"{n}BufferPtr", f"{n}Length"])
177-
elif t == "bool":
178-
call_args.append(f"{n} ? (byte)1 : (byte)0")
179-
else:
180-
call_args.append(n)
181-
182-
if is_buffer_return(return_type):
183-
first_call_args = ["null"] + call_args
184-
writer.add_line(f"var ret = _{function_name}({', '.join(first_call_args)});")
185-
if return_type == "string":
186-
writer.add_line("var retBuffer = new byte[ret + 1];")
187-
else:
188-
writer.add_line("var retBuffer = new byte[ret];")
189-
190-
def write_ret_fixed():
191-
second_call_args = ["retBufferPtr"] + call_args
192-
writer.add_line(f"ret = _{function_name}({', '.join(second_call_args)});")
193-
if return_type == "string":
194-
writer.add_line("return Encoding.UTF8.GetString(retBufferPtr, ret);")
195-
else:
196-
writer.add_line("var retBytes = new byte[ret];")
197-
writer.add_line("for (int i = 0; i < ret; i++) retBytes[i] = retBufferPtr[i];")
198-
writer.add_line("return retBytes;")
199-
200-
writer.add_block("fixed (byte* retBufferPtr = retBuffer)", write_ret_fixed)
201-
else:
202-
if return_type == "void":
203-
writer.add_line(f"_{function_name}({', '.join(call_args)});")
204-
else:
205-
writer.add_line(f"var ret = _{function_name}({', '.join(call_args)});")
206-
writer.add_line("return ret == 1;" if return_type == "bool" else "return ret;")
207-
208-
def write_with_fixed_blocks(blocks, index=0):
209-
if index < len(blocks):
210-
writer.add_block(blocks[index], lambda: write_with_fixed_blocks(blocks, index + 1))
211-
else:
212-
write_simple_call()
213-
214-
if fixed_blocks:
215-
write_with_fixed_blocks(fixed_blocks)
216-
else:
217-
write_simple_call()
218-
return
219-
220-
for param in string_params:
221-
writer.add_line(f"byte[] {param}Buffer = Encoding.UTF8.GetBytes({param} + \"\\0\");")
161+
string_params = []
162+
bytes_params = []
163+
pool_declared = False
222164

165+
for t, n in param_signatures:
166+
if t == "string":
167+
if not pool_declared:
168+
writer.add_line("var pool = ArrayPool<byte>.Shared;")
169+
pool_declared = True
170+
writer.add_line(f"var {n}Length = Encoding.UTF8.GetByteCount({n});")
171+
writer.add_line(f"var {n}Buffer = pool.Rent({n}Length + 1);")
172+
writer.add_line(f"Encoding.UTF8.GetBytes({n}, {n}Buffer);")
173+
writer.add_line(f"{n}Buffer[{n}Length] = 0;")
174+
string_params.append(n)
175+
elif t == "byte[]":
176+
writer.add_line(f"var {n}Length = {n}.Length;")
177+
bytes_params.append(n)
178+
223179
fixed_blocks = []
224180
for param in string_params:
225181
fixed_blocks.append(f"fixed (byte* {param}BufferPtr = {param}Buffer)")
@@ -228,42 +184,77 @@ def write_with_fixed_blocks(blocks, index=0):
228184

229185
def write_native_call():
230186
call_args = []
231-
for t, n in param_signatures:
232-
if t == "string":
233-
call_args.append(f"{n}BufferPtr")
234-
elif t == "byte[]":
235-
call_args.extend([f"{n}BufferPtr", f"{n}Length"])
236-
elif t == "bool":
237-
call_args.append(f"{n} ? (byte)1 : (byte)0")
238-
else:
239-
call_args.append(n)
240187

241188
if is_buffer_return(return_type):
242-
first_call_args = ["null"] + call_args
189+
first_call_args = ["null"]
190+
for t, n in param_signatures:
191+
if t == "string":
192+
first_call_args.append(f"{n}BufferPtr")
193+
elif t == "byte[]":
194+
first_call_args.extend([f"{n}BufferPtr", f"{n}Length"])
195+
elif t == "bool":
196+
first_call_args.append(f"{n} ? (byte)1 : (byte)0")
197+
else:
198+
first_call_args.append(n)
199+
243200
writer.add_line(f"var ret = _{function_name}({', '.join(first_call_args)});")
244-
if return_type == "string":
245-
writer.add_line("var retBuffer = new byte[ret + 1];")
246-
else:
247-
writer.add_line("var retBuffer = new byte[ret];")
201+
202+
if not pool_declared:
203+
writer.add_line("var pool = ArrayPool<byte>.Shared;")
204+
writer.add_line("var retBuffer = pool.Rent(ret + 1);")
248205

249206
def write_ret_fixed():
250-
second_call_args = ["retBufferPtr"] + call_args
207+
second_call_args = ["retBufferPtr"]
208+
for t, n in param_signatures:
209+
if t == "string":
210+
second_call_args.append(f"{n}BufferPtr")
211+
elif t == "byte[]":
212+
second_call_args.extend([f"{n}BufferPtr", f"{n}Length"])
213+
elif t == "bool":
214+
second_call_args.append(f"{n} ? (byte)1 : (byte)0")
215+
else:
216+
second_call_args.append(n)
217+
251218
writer.add_line(f"ret = _{function_name}({', '.join(second_call_args)});")
219+
252220
if return_type == "string":
253-
writer.add_line("return Encoding.UTF8.GetString(retBufferPtr, ret);")
221+
writer.add_line("var retString = Encoding.UTF8.GetString(retBufferPtr, ret);")
222+
writer.add_line("pool.Return(retBuffer);")
223+
for param in string_params:
224+
writer.add_line(f"pool.Return({param}Buffer);")
225+
writer.add_line("return retString;")
254226
else:
255227
writer.add_line("var retBytes = new byte[ret];")
256228
writer.add_line("for (int i = 0; i < ret; i++) retBytes[i] = retBufferPtr[i];")
229+
writer.add_line("pool.Return(retBuffer);")
230+
for param in string_params:
231+
writer.add_line(f"pool.Return({param}Buffer);")
257232
writer.add_line("return retBytes;")
258233

259234
writer.add_block("fixed (byte* retBufferPtr = retBuffer)", write_ret_fixed)
235+
260236
else:
237+
for t, n in param_signatures:
238+
if t == "string":
239+
call_args.append(f"{n}BufferPtr")
240+
elif t == "byte[]":
241+
call_args.extend([f"{n}BufferPtr", f"{n}Length"])
242+
elif t == "bool":
243+
call_args.append(f"{n} ? (byte)1 : (byte)0")
244+
else:
245+
call_args.append(n)
246+
261247
if return_type == "void":
262248
writer.add_line(f"_{function_name}({', '.join(call_args)});")
263249
else:
264250
writer.add_line(f"var ret = _{function_name}({', '.join(call_args)});")
265-
writer.add_line("return ret == 1;" if return_type == "bool" else "return ret;")
266-
251+
252+
for param in string_params:
253+
writer.add_line(f"pool.Return({param}Buffer);")
254+
255+
if return_type != "void":
256+
writer.add_line("return ret == 1;" if return_type == "bool" else f"return ret;")
257+
267258
def write_with_fixed_blocks(blocks, index=0):
268259
if index < len(blocks):
269260
writer.add_block(blocks[index], lambda: write_with_fixed_blocks(blocks, index + 1))
@@ -276,10 +267,7 @@ def write_with_fixed_blocks(blocks, index=0):
276267
write_native_call()
277268

278269
writer.add_block(f"public unsafe static {RETURN_TYPE_MAP[return_type]} {function_name}({method_signature})", write_method_content)
279-
280-
# Benchmark class should be public for external access
281-
access_modifier = "public" if class_name == "Benchmark" else "internal"
282-
writer.add_block(f"{access_modifier} static class Native{class_name}", write_class_content)
270+
writer.add_block(f"internal static class Native{class_name}", write_class_content)
283271

284272
with open(out_path, "w", encoding="utf-8", newline="") as f:
285273
f.write(writer.get_code())

managed/managed.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
<OutputPath>$(BaseOutputPath)Release\SwiftlyS2</OutputPath>
2323
<AssemblyName>SwiftlyS2.CS2</AssemblyName>
2424
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
25+
<PlatformTarget>x64</PlatformTarget>
2526
<NoWarn>$(NoWarn);CS1591</NoWarn>
2627

2728
</PropertyGroup>

managed/src/SwiftlyS2.Core/Modules/Convars/ConVar.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using SwiftlyS2.Core.Extensions;
55
using System.Runtime.InteropServices;
66
using System.Runtime.CompilerServices;
7+
using SwiftlyS2.Core.Services;
78

89
namespace SwiftlyS2.Core.Convars;
910

@@ -86,6 +87,7 @@ public T Value {
8687
get => GetValue();
8788
set => SetValue(value);
8889
}
90+
8991
public void ReplicateToClient( int clientId, T value )
9092
{
9193
var val = "";

0 commit comments

Comments
 (0)