@@ -100,61 +100,73 @@ pub fn Options(comptime T: type) type {
100100const ParameterType = enum { float , int , uint , bool };
101101
102102pub const Parameter = union (ParameterType ) {
103- fn Inner (comptime Type : type ) type {
103+ fn Inner (comptime T : type ) type {
104104 return struct {
105- value : std .atomic .Value (Type ),
106- options : Options (Type ),
105+ value : std .atomic .Value (f64 ),
106+ options : Options (T ),
107+
108+ pub const param_type : ParameterType = switch (@typeInfo (T )) {
109+ .float = > .float ,
110+ .int = > | info | switch (info .signedness ) {
111+ .signed = > .int ,
112+ .unsigned = > .uint ,
113+ },
114+ .bool = > .bool ,
115+ else = > @compileError ("unsupported parameter type: " ++ @typeName (T )),
116+ };
107117
108- pub fn init (comptime options : Options (Type )) @This () {
109- if (options .special == .bypass and Type != bool )
110- @compileError ("Bypass parameter type must be bool, got " ++ @typeName (Type ));
118+ pub fn init (comptime options : Options (T )) @This () {
119+ if (options .special == .bypass and T != bool )
120+ @compileError ("Bypass parameter type must be bool, got " ++ @typeName (T ));
111121
112122 if (options .unit != null and options .format != null )
113123 @compileError ("Parameter '" ++ options .name ++ "' has both `format` and `unit`, which are mutually exclusive" );
114124
115125 return .{
116- .value = .init (options .default ),
126+ .value = .init (toFloat ( options .default ) ),
117127 .options = options ,
118128 };
119129 }
120130
121131 pub fn set (self : * @This (), value : anytype ) void {
122132 self .value .store (switch (@typeInfo (@TypeOf (value ))) {
123- .@"enum" = > @intFromEnum (value ),
124- else = > value ,
133+ .@"enum" = > @floatFromInt ( @ intFromEnum (value ) ),
134+ else = > toFloat ( value ) ,
125135 }, .unordered );
126136 }
127137
128138 // TODO: this for enums
129- pub fn get (self : * const @This ()) Type {
130- return self .value .load (.unordered );
139+ pub fn get (self : * const @This ()) T {
140+ return fromFloat ( self .value .load (.unordered ) );
131141 }
132142
133- pub fn fromFloat (value : f64 ) Type {
134- return switch (@typeInfo ( Type ) ) {
143+ pub fn fromFloat (value : f64 ) T {
144+ return switch (param_type ) {
135145 .float = > @floatCast (value ),
136- .int = > @intFromFloat (value ),
146+ .int , .uint = > @intFromFloat (value ),
137147 .bool = > value == 1 ,
138- else = > unreachable ,
139148 };
140149 }
141150
142- pub fn toFloat (value : Type ) f64 {
143- return switch (@typeInfo ( @TypeOf ( value )) ) {
151+ pub fn toFloat (value : T ) f64 {
152+ return switch (param_type ) {
144153 .float = > @floatCast (value ),
145- .int = > @floatFromInt (value ),
146- .bool = > if (value ) 1 else 0 ,
147- else = > unreachable ,
154+ .int , .uint = > @floatFromInt (value ),
155+ .bool = > @floatFromInt (@intFromBool (value )),
148156 };
149157 }
150158
151- pub fn format (self : * const @This (), writer : * std .Io .Writer , value : Type ) std .Io .Writer .Error ! void {
159+ pub fn modulate (self : * @This (), amount : f64 ) void {
160+ _ = self .value .fetchAdd (amount , .monotonic );
161+ }
162+
163+ pub fn format (self : * const @This (), writer : * std .Io .Writer , value : T ) std .Io .Writer .Error ! void {
152164 if (self .options .format ) | f |
153165 try f (value , writer )
154166 else
155167 try writer .print (
156- switch (@typeInfo ( @TypeOf ( value )) ) {
157- .float , .comptime_float = > "{d}{s}" ,
168+ switch (param_type ) {
169+ .float = > "{d}{s}" ,
158170 else = > "{}{s}" ,
159171 },
160172 .{ value , self .options .unit orelse "" },
@@ -163,7 +175,7 @@ pub const Parameter = union(ParameterType) {
163175 try writer .flush ();
164176 }
165177
166- pub fn parse (self : * const @This (), value : []const u8 ) ! Type {
178+ pub fn parse (self : * const @This (), value : []const u8 ) ! T {
167179 if (self .options .parse ) | f |
168180 return f (value );
169181
@@ -172,14 +184,11 @@ pub const Parameter = union(ParameterType) {
172184 else
173185 value ;
174186
175- return switch (comptime @typeInfo (Type )) {
176- .float = > std .fmt .parseFloat (Type , str ),
177- .int = > | t | try (switch (t .signedness ) {
178- .signed = > std .fmt .parseInt ,
179- .unsigned = > std .fmt .parseUnsigned ,
180- })(Type , str , 10 ),
187+ return switch (param_type ) {
188+ .float = > std .fmt .parseFloat (T , str ),
189+ .int = > std .fmt .parseInt (T , str , 10 ),
190+ .uint = > std .fmt .parseUnsigned (T , str , 10 ),
181191 .bool = > std .mem .eql (u8 , str , "true" ),
182- else = > unreachable ,
183192 };
184193 }
185194 };
0 commit comments