mirror of
https://github.com/PixelGuys/Cubyz.git
synced 2025-08-03 03:06:55 -04:00
Add utility functions to make function pointer casting more safe.
It's now only changing the self parameter, everything else will be checked at compile-time. fixes #1223
This commit is contained in:
parent
5845da7ca9
commit
ac9f00cb32
@ -125,10 +125,10 @@ const MusicLoadTask = struct {
|
||||
musicId: []const u8,
|
||||
|
||||
const vtable = utils.ThreadPool.VTable{
|
||||
.getPriority = @ptrCast(&getPriority),
|
||||
.isStillNeeded = @ptrCast(&isStillNeeded),
|
||||
.run = @ptrCast(&run),
|
||||
.clean = @ptrCast(&clean),
|
||||
.getPriority = main.utils.castFunctionSelfToAnyopaque(getPriority),
|
||||
.isStillNeeded = main.utils.castFunctionSelfToAnyopaque(isStillNeeded),
|
||||
.run = main.utils.castFunctionSelfToAnyopaque(run),
|
||||
.clean = main.utils.castFunctionSelfToAnyopaque(clean),
|
||||
.taskType = .misc,
|
||||
};
|
||||
|
||||
|
@ -130,10 +130,10 @@ pub const Gamepad = struct {
|
||||
curTimestamp: i128,
|
||||
var running = std.atomic.Value(bool).init(false);
|
||||
const vtable = main.utils.ThreadPool.VTable{
|
||||
.getPriority = @ptrCast(&getPriority),
|
||||
.isStillNeeded = @ptrCast(&isStillNeeded),
|
||||
.run = @ptrCast(&run),
|
||||
.clean = @ptrCast(&clean),
|
||||
.getPriority = main.utils.castFunctionSelfToAnyopaque(getPriority),
|
||||
.isStillNeeded = main.utils.castFunctionSelfToAnyopaque(isStillNeeded),
|
||||
.run = main.utils.castFunctionSelfToAnyopaque(run),
|
||||
.clean = main.utils.castFunctionSelfToAnyopaque(clean),
|
||||
};
|
||||
|
||||
pub fn schedule(curTimestamp: i128) void {
|
||||
|
@ -1816,10 +1816,10 @@ const ProtocolTask = struct {
|
||||
data: []const u8,
|
||||
|
||||
const vtable = utils.ThreadPool.VTable{
|
||||
.getPriority = @ptrCast(&getPriority),
|
||||
.isStillNeeded = @ptrCast(&isStillNeeded),
|
||||
.run = @ptrCast(&run),
|
||||
.clean = @ptrCast(&clean),
|
||||
.getPriority = main.utils.castFunctionSelfToAnyopaque(getPriority),
|
||||
.isStillNeeded = main.utils.castFunctionSelfToAnyopaque(isStillNeeded),
|
||||
.run = main.utils.castFunctionSelfToAnyopaque(run),
|
||||
.clean = main.utils.castFunctionSelfToAnyopaque(clean),
|
||||
.taskType = .misc,
|
||||
};
|
||||
|
||||
|
@ -707,10 +707,10 @@ pub const ChunkMesh = struct { // MARK: ChunkMesh
|
||||
mesh: *ChunkMesh,
|
||||
|
||||
pub const vtable = main.utils.ThreadPool.VTable{
|
||||
.getPriority = @ptrCast(&getPriority),
|
||||
.isStillNeeded = @ptrCast(&isStillNeeded),
|
||||
.run = @ptrCast(&run),
|
||||
.clean = @ptrCast(&clean),
|
||||
.getPriority = main.utils.castFunctionSelfToAnyopaque(getPriority),
|
||||
.isStillNeeded = main.utils.castFunctionSelfToAnyopaque(isStillNeeded),
|
||||
.run = main.utils.castFunctionSelfToAnyopaque(run),
|
||||
.clean = main.utils.castFunctionSelfToAnyopaque(clean),
|
||||
.taskType = .misc,
|
||||
};
|
||||
|
||||
|
@ -896,10 +896,10 @@ pub const MeshGenerationTask = struct { // MARK: MeshGenerationTask
|
||||
mesh: *chunk.Chunk,
|
||||
|
||||
pub const vtable = utils.ThreadPool.VTable{
|
||||
.getPriority = @ptrCast(&getPriority),
|
||||
.isStillNeeded = @ptrCast(&isStillNeeded),
|
||||
.run = @ptrCast(&run),
|
||||
.clean = @ptrCast(&clean),
|
||||
.getPriority = main.utils.castFunctionSelfToAnyopaque(getPriority),
|
||||
.isStillNeeded = main.utils.castFunctionSelfToAnyopaque(isStillNeeded),
|
||||
.run = main.utils.castFunctionSelfToAnyopaque(run),
|
||||
.clean = main.utils.castFunctionSelfToAnyopaque(clean),
|
||||
.taskType = .meshgenAndLighting,
|
||||
};
|
||||
|
||||
|
@ -60,9 +60,9 @@ pub const SimpleStructureModel = struct { // MARK: SimpleStructureModel
|
||||
|
||||
pub fn registerGenerator(comptime Generator: type) void {
|
||||
var self: VTable = undefined;
|
||||
self.loadModel = @ptrCast(&Generator.loadModel);
|
||||
self.generate = @ptrCast(&Generator.generate);
|
||||
self.hashFunction = @ptrCast(&struct {
|
||||
self.loadModel = main.utils.castFunctionReturnToAnyopaque(Generator.loadModel);
|
||||
self.generate = main.utils.castFunctionSelfToAnyopaque(Generator.generate);
|
||||
self.hashFunction = main.utils.castFunctionSelfToAnyopaque(struct {
|
||||
fn hash(ptr: *Generator) u64 {
|
||||
return hashGeneric(ptr.*);
|
||||
}
|
||||
|
@ -134,10 +134,10 @@ const ChunkManager = struct { // MARK: ChunkManager
|
||||
source: Source,
|
||||
|
||||
const vtable = utils.ThreadPool.VTable{
|
||||
.getPriority = @ptrCast(&getPriority),
|
||||
.isStillNeeded = @ptrCast(&isStillNeeded),
|
||||
.run = @ptrCast(&run),
|
||||
.clean = @ptrCast(&clean),
|
||||
.getPriority = main.utils.castFunctionSelfToAnyopaque(getPriority),
|
||||
.isStillNeeded = main.utils.castFunctionSelfToAnyopaque(isStillNeeded),
|
||||
.run = main.utils.castFunctionSelfToAnyopaque(run),
|
||||
.clean = main.utils.castFunctionSelfToAnyopaque(clean),
|
||||
.taskType = .chunkgen,
|
||||
};
|
||||
|
||||
@ -194,10 +194,10 @@ const ChunkManager = struct { // MARK: ChunkManager
|
||||
source: ?*User,
|
||||
|
||||
const vtable = utils.ThreadPool.VTable{
|
||||
.getPriority = @ptrCast(&getPriority),
|
||||
.isStillNeeded = @ptrCast(&isStillNeeded),
|
||||
.run = @ptrCast(&run),
|
||||
.clean = @ptrCast(&clean),
|
||||
.getPriority = main.utils.castFunctionSelfToAnyopaque(getPriority),
|
||||
.isStillNeeded = main.utils.castFunctionSelfToAnyopaque(isStillNeeded),
|
||||
.run = main.utils.castFunctionSelfToAnyopaque(run),
|
||||
.clean = main.utils.castFunctionSelfToAnyopaque(clean),
|
||||
.taskType = .misc,
|
||||
};
|
||||
|
||||
@ -583,10 +583,10 @@ pub const ServerWorld = struct { // MARK: ServerWorld
|
||||
storeMaps: bool,
|
||||
|
||||
const vtable = utils.ThreadPool.VTable{
|
||||
.getPriority = @ptrCast(&getPriority),
|
||||
.isStillNeeded = @ptrCast(&isStillNeeded),
|
||||
.run = @ptrCast(&run),
|
||||
.clean = @ptrCast(&clean),
|
||||
.getPriority = main.utils.castFunctionSelfToAnyopaque(getPriority),
|
||||
.isStillNeeded = main.utils.castFunctionSelfToAnyopaque(isStillNeeded),
|
||||
.run = main.utils.castFunctionSelfToAnyopaque(run),
|
||||
.clean = main.utils.castFunctionSelfToAnyopaque(clean),
|
||||
.taskType = .chunkgen,
|
||||
};
|
||||
|
||||
|
@ -1494,3 +1494,32 @@ pub const BinaryWriter = struct {
|
||||
self.data.append(delimiter);
|
||||
}
|
||||
};
|
||||
|
||||
// MARK: functionPtrCast()
|
||||
fn CastFunctionSelfToAnyopaqueType(Fn: type) type {
|
||||
var typeInfo = @typeInfo(Fn);
|
||||
var params = typeInfo.@"fn".params[0..typeInfo.@"fn".params.len].*;
|
||||
if(@sizeOf(params[0].type.?) != @sizeOf(*anyopaque) or @alignOf(params[0].type.?) != @alignOf(*anyopaque)) {
|
||||
@compileError(std.fmt.comptimePrint("Cannot convert {} to *anyopaque", .{params[0].type.?}));
|
||||
}
|
||||
params[0].type = *anyopaque;
|
||||
typeInfo.@"fn".params = params[0..];
|
||||
return @Type(typeInfo);
|
||||
}
|
||||
/// Turns the first parameter into a anyopaque*
|
||||
pub fn castFunctionSelfToAnyopaque(function: anytype) *const CastFunctionSelfToAnyopaqueType(@TypeOf(function)) {
|
||||
return @ptrCast(&function);
|
||||
}
|
||||
|
||||
fn CastFunctionReturnToAnyopaqueType(Fn: type) type {
|
||||
var typeInfo = @typeInfo(Fn);
|
||||
if(@sizeOf(typeInfo.@"fn".return_type.?) != @sizeOf(*anyopaque) or @alignOf(typeInfo.@"fn".return_type.?) != @alignOf(*anyopaque)) {
|
||||
@compileError(std.fmt.comptimePrint("Cannot convert {} to *anyopaque", .{typeInfo.@"fn".return_type.?}));
|
||||
}
|
||||
typeInfo.@"fn".return_type = *anyopaque;
|
||||
return @Type(typeInfo);
|
||||
}
|
||||
/// Turns the return parameter into a anyopaque*
|
||||
pub fn castFunctionReturnToAnyopaque(function: anytype) *const CastFunctionReturnToAnyopaqueType(@TypeOf(function)) {
|
||||
return @ptrCast(&function);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user