Index: src/Variable.h ================================================================== --- src/Variable.h +++ src/Variable.h @@ -3,18 +3,20 @@ OF_ASSUME_NONNULL_BEGIN @interface Variable : Identifier @property (readonly, nonatomic) int min, max; @property (readonly, nonatomic) int *storage; -@property (readonly, nonatomic) void (*function)(); +@property (readonly, nonatomic) void (*__cdecl function)(); @property (readonly, nonatomic) bool persisted; - (instancetype)initWithName:(OFString *)name OF_UNAVAILABLE; - (instancetype)initWithName:(OFString *)name min:(int)min max:(int)max storage:(int *)storage - function:(void (*)())function + function:(void (*__cdecl)())function persisted:(bool)persisted; +- (void)printValue; +- (void)setValue:(int)value; @end OF_ASSUME_NONNULL_END DELETED src/Variable.m Index: src/Variable.m ================================================================== --- src/Variable.m +++ /dev/null @@ -1,21 +0,0 @@ -#import "Variable.h" - -@implementation Variable -- (instancetype)initWithName:(OFString *)name - min:(int)min - max:(int)max - storage:(int *)storage - function:(void (*)())function - persisted:(bool)persisted -{ - self = [super initWithName:name]; - - _min = min; - _max = max; - _storage = storage; - _function = function; - _persisted = persisted; - - return self; -} -@end ADDED src/Variable.mm Index: src/Variable.mm ================================================================== --- /dev/null +++ src/Variable.mm @@ -0,0 +1,57 @@ +#import "Variable.h" + +#include "cube.h" + +@implementation Variable +- (instancetype)initWithName:(OFString *)name + min:(int)min + max:(int)max + storage:(int *)storage + function:(void (*__cdecl)())function + persisted:(bool)persisted +{ + self = [super initWithName:name]; + + _min = min; + _max = max; + _storage = storage; + _function = function; + _persisted = persisted; + + return self; +} + +- (void)printValue +{ + conoutf(@"%@ = %d", self.name, *_storage); +} + +- (void)setValue:(int)value +{ + bool outOfRange = false; + + if (_min > _max) { + conoutf(@"variable is read-only"); + return; + } + + if (value < _min) { + value = _min; + outOfRange = true; + } + + if (value > _max) { + value = _max; + outOfRange = true; + } + + if (outOfRange) + conoutf(@"valid range for %@ is %d..%d", self.name, _min, _max); + + *_storage = value; + + if (_function != NULL) + // call trigger function if available + _function(); +} +@end Index: src/commands.mm ================================================================== --- src/commands.mm +++ src/commands.mm @@ -241,93 +241,15 @@ isKindOfClass:[Variable class]]) { // game defined variables if (isdown) { if (!w[1][0]) - // var with no value - // just prints its - // current value - conoutf(@"%s = %d", c, - *[identifier - storage]); - else { - if ([identifier min] > - [identifier max]) { - conoutf( - @"variable " - @"is " - @"read-" - @"only"); - } else { - int i1 = - ATOI(w[1]); - if (i1 < - [identifier - min] || - i1 > - [identifier - max]) { - // clamp - // to - // valid - // range - i1 = - i1 < [identifier - min] - ? [identifier - min] - : [identifier - max]; - conoutf( - @"v" - @"a" - @"l" - @"i" - @"d" - @" " - @"r" - @"a" - @"n" - @"g" - @"e" - @" " - @"f" - @"o" - @"r" - @" " - @"%" - @"s" - @" " - @"i" - @"s" - @" " - @"%" - @"d" - @"." - @"." - @"%" - @"d", - c, - [identifier - min], - [identifier - max]); - } - *[identifier - storage] = - i1; - } - if ([identifier - function] != - NULL) - // call trigger - // function if - // available - ((void(__cdecl - *)())[identifier - function])(); - } + [identifier printValue]; + else + [identifier + setValue:ATOI( + w[1])]; } } else if ([identifier isKindOfClass:[Alias class]]) { // alias, also used as functions and // (global) variables Index: src/meson.build ================================================================== --- src/meson.build +++ src/meson.build @@ -7,11 +7,11 @@ 'KeyMapping.m', 'MD2.mm', 'MapModelInfo.m', 'Menu.m', 'MenuItem.m', - 'Variable.m', + 'Variable.mm', 'client.mm', 'clientextras.mm', 'clientgame.mm', 'clients2c.mm', 'commands.mm',