249 lines
6.8 KiB
Plaintext
249 lines
6.8 KiB
Plaintext
// cell config - Manage system and actor configurations
|
|
|
|
var toml = use('toml')
|
|
var pkg = use('package')
|
|
|
|
function print_help() {
|
|
log.console("Usage: cell config <command> [options]")
|
|
log.console("")
|
|
log.console("Commands:")
|
|
log.console(" get <key> Get a configuration value")
|
|
log.console(" set <key> <value> Set a configuration value")
|
|
log.console(" list List all configurations")
|
|
log.console(" actor <name> get <key> Get actor-specific config")
|
|
log.console(" actor <name> set <key> <val> Set actor-specific config")
|
|
log.console(" actor <name> list List actor configurations")
|
|
log.console("")
|
|
log.console("Examples:")
|
|
log.console(" cell config get system.ar_timer")
|
|
log.console(" cell config set system.net_service 0.2")
|
|
log.console(" cell config actor prosperon/_sdl_video set resolution 1920x1080")
|
|
log.console(" cell config actor extramath/spline set precision high")
|
|
log.console("")
|
|
log.console("System keys:")
|
|
log.console(" system.ar_timer - Seconds before idle actor reclamation")
|
|
log.console(" system.actor_memory - MB of memory an actor can use (0=unbounded)")
|
|
log.console(" system.net_service - Seconds per network service pull")
|
|
log.console(" system.reply_timeout - Seconds to hold callback for replies (0=unbounded)")
|
|
log.console(" system.actor_max - Max number of simultaneous actors")
|
|
log.console(" system.stack_max - MB of memory each actor's stack can grow to")
|
|
}
|
|
|
|
// Parse a dot-notation key into path segments
|
|
function parse_key(key) {
|
|
return array(key, '.')
|
|
}
|
|
|
|
// Get a value from nested object using path
|
|
function get_nested(obj, path) {
|
|
var current = obj
|
|
arrfor(path, function(segment) {
|
|
if (is_null(current) || !is_object(current)) return null
|
|
current = current[segment]
|
|
})
|
|
return current
|
|
}
|
|
|
|
// Set a value in nested object using path
|
|
function set_nested(obj, path, value) {
|
|
var current = obj
|
|
for (var i = 0; i < length(path) - 1; i++) {
|
|
var segment = path[i]
|
|
if (is_null(current[segment]) || !is_object(current[segment])) {
|
|
current[segment] = {}
|
|
}
|
|
current = current[segment]
|
|
}
|
|
current[path[length(path) - 1]] = value
|
|
}
|
|
|
|
// Parse value string into appropriate type
|
|
function parse_value(str) {
|
|
// Boolean
|
|
if (str == 'true') return true
|
|
if (str == 'false') return false
|
|
|
|
// Number (including underscores)
|
|
var num_str = replace(str, /_/g, '')
|
|
if (/^-?\d+$/.test(num_str)) return parseInt(num_str)
|
|
if (/^-?\d*\.\d+$/.test(num_str)) return parseFloat(num_str)
|
|
|
|
// String
|
|
return str
|
|
}
|
|
|
|
// Format value for display
|
|
function format_value(val) {
|
|
if (is_text(val)) return '"' + val + '"'
|
|
if (is_number(val) && val >= 1000) {
|
|
// Add underscores to large numbers
|
|
return replace(val.toString(), /\B(?=(\d{3})+(?!\d))/g, '_')
|
|
}
|
|
return text(val)
|
|
}
|
|
|
|
// Print configuration tree recursively
|
|
function print_config(obj, prefix = '') {
|
|
arrfor(array(obj), function(key) {
|
|
var val = obj[key]
|
|
var full_key = prefix ? prefix + '.' + key : key
|
|
|
|
if (is_object(val))
|
|
print_config(val, full_key)
|
|
else
|
|
log.console(full_key + ' = ' + format_value(val))
|
|
})
|
|
}
|
|
|
|
// Main command handling
|
|
if (length(args) == 0) {
|
|
print_help()
|
|
$stop()
|
|
return
|
|
}
|
|
|
|
var config = pkg.load_config()
|
|
if (!config) {
|
|
log.error("Failed to load cell.toml")
|
|
$stop()
|
|
return
|
|
}
|
|
|
|
var command = args[0]
|
|
var key
|
|
var path
|
|
var value
|
|
|
|
switch (command) {
|
|
case 'help':
|
|
case '-h':
|
|
case '--help':
|
|
print_help()
|
|
break
|
|
|
|
case 'list':
|
|
log.console("# Cell Configuration")
|
|
log.console("")
|
|
print_config(config)
|
|
break
|
|
|
|
case 'get':
|
|
if (length(args) < 2) {
|
|
log.error("Usage: cell config get <key>")
|
|
$stop()
|
|
return
|
|
}
|
|
key = args[1]
|
|
path = parse_key(key)
|
|
value = get_nested(config, path)
|
|
|
|
if (value == null) {
|
|
log.error("Key not found: " + key)
|
|
} else if (isa(value, object)) {
|
|
// Print all nested values
|
|
print_config(value, key)
|
|
} else {
|
|
log.console(key + ' = ' + format_value(value))
|
|
}
|
|
break
|
|
|
|
case 'set':
|
|
if (length(args) < 3) {
|
|
log.error("Usage: cell config set <key> <value>")
|
|
$stop()
|
|
return
|
|
}
|
|
var key = args[1]
|
|
var value_str = args[2]
|
|
var path = parse_key(key)
|
|
var value = parse_value(value_str)
|
|
|
|
// Validate system keys
|
|
if (path[0] == 'system') {
|
|
var valid_system_keys = [
|
|
'ar_timer', 'actor_memory', 'net_service',
|
|
'reply_timeout', 'actor_max', 'stack_max'
|
|
]
|
|
if (find(valid_system_keys, path[1]) == null) {
|
|
log.error("Invalid system key. Valid keys: " + text(valid_system_keys, ', '))
|
|
$stop()
|
|
return
|
|
}
|
|
}
|
|
|
|
set_nested(config, path, value)
|
|
pkg.save_config(config)
|
|
log.console("Set " + key + " = " + format_value(value))
|
|
break
|
|
|
|
case 'actor':
|
|
// Handle actor-specific configuration
|
|
if (length(args) < 3) {
|
|
log.error("Usage: cell config actor <name> <command> [options]")
|
|
$stop()
|
|
return
|
|
}
|
|
|
|
var actor_name = args[1]
|
|
var actor_cmd = args[2]
|
|
|
|
// Initialize actors section if needed
|
|
config.actors = config.actors || {}
|
|
config.actors[actor_name] = config.actors[actor_name] || {}
|
|
|
|
switch (actor_cmd) {
|
|
case 'list':
|
|
if (length(array(config.actors[actor_name])) == 0) {
|
|
log.console("No configuration for actor: " + actor_name)
|
|
} else {
|
|
log.console("# Configuration for actor: " + actor_name)
|
|
log.console("")
|
|
print_config(config.actors[actor_name], 'actors.' + actor_name)
|
|
}
|
|
break
|
|
|
|
case 'get':
|
|
if (length(args) < 4) {
|
|
log.error("Usage: cell config actor <name> get <key>")
|
|
$stop()
|
|
return
|
|
}
|
|
key = args[3]
|
|
path = parse_key(key)
|
|
value = get_nested(config.actors[actor_name], path)
|
|
|
|
if (value == null) {
|
|
log.error("Key not found for actor " + actor_name + ": " + key)
|
|
} else {
|
|
log.console('actors.' + actor_name + '.' + key + ' = ' + format_value(value))
|
|
}
|
|
break
|
|
|
|
case 'set':
|
|
if (length(args) < 5) {
|
|
log.error("Usage: cell config actor <name> set <key> <value>")
|
|
$stop()
|
|
return
|
|
}
|
|
key = args[3]
|
|
var value_str = args[4]
|
|
path = parse_key(key)
|
|
value = parse_value(value_str)
|
|
|
|
set_nested(config.actors[actor_name], path, value)
|
|
pkg.save_config(config)
|
|
log.console("Set actors." + actor_name + "." + key + " = " + format_value(value))
|
|
break
|
|
|
|
default:
|
|
log.error("Unknown actor command: " + actor_cmd)
|
|
log.console("Valid commands: list, get, set")
|
|
}
|
|
break
|
|
|
|
default:
|
|
log.error("Unknown command: " + command)
|
|
print_help()
|
|
}
|
|
|
|
$stop() |