This primitive has thse values below:
/vardata
var/can_write
var/can_read
var/implied_type
var/write_restriction
var/can_be_null
var/list/typepath_restriction
var/is_global
var/is_static
var/is_final
var/is_tmp
- [can_write / can_read] can have 3 flags:
VAR_ACCESS_NEW 1 // only New() can access this
VAR_ACCESS_DEL 2 // only Del() can access this
VAR_ACCESS_PRIVATE 4 // only src.proc can access this
VAR_ACCESS_PUBLIC 8 // it can be access from a datum proc call which isn't its source
VAR_ACCESS_GLOBAL 16 // it can be access from a global proc call
(a few flags might be missing, like mob login, mob logout. not sure if we would want this.)
default value has everything: "VAR_ACCESS_NEW | VAR_ACCESS_DEL | VAR_ACCESS_PRIVATE | VAR_ACCESS_PUBLIC | VAR_ACCESS_GLOBAL"
You can guess which practice it would be If a variable's can_write flag has "VAR_ACCESS_NEW | VAR_ACCESS_DEL". Obviously it's protected.
- [implied_type] is a read only string. It returns which typepath it has.
- [write_restriction] can have flags:
VAR_TYPE_NUMBER [1]: accepts numbers
VAR_TYPE_STRINGS [2]: accepts strings
VAR_TYPE_LIST [4]: accepts a list
VAR_TYPE_PATH [8]: accepts a path (but only limited by typepath_restriction)
VAR_TYPE_INSTANCE [16]: accepts a type (but only limited by typepath_restriction)
VAR_TYPE_OTHER [32]: accepts other cases that aren't covered by above.
- [can_be_null] write_restriction having VAR_TYPE_NULL is annoying to control. Default 1.
- [list/typepath_restriction] is a list that checks which path/type instance can be written.
- [is_xxx] are read-only that returns TRUE/FALSE. literally what it is.
/datum/user_data
var/real_name
@real_name.can_write = VAR_ACCESS_NEW
@real_name.can_read = VAR_ACCESS_PRIVATE
@real_name.write_restriction = VAR_TYPE_STRINGS // only accept strings
var/client/connected_client
@real_name.can_write = VAR_ACCESS_PRIVATE
@connected_client.write_restriction = VAR_TYPE_INSTANCE
@connected_client.typepath_restriction = /client // list(/client) works the same
var/static/datum/random_datum
@random_datum.can_be_null = 0 // This will throw an error because random_datum is null
/datum/user_data/New()
real_name = "John Doe" // Works. This has VAR_ACCESS_NEW
real_name = /datum // by write_restriction = VAR_TYPE_STRINGS, this doesn't work
world.log << "Real name: [real_name]" // This throws an error because can_read has not VAR_ACCESS_NEW
connected_client = null // Error. This has no VAR_ACCESS_NEW
/datum/user_data/proc/connect_client(client/client)
connected_client = client // Works. This has VAR_ACCESS_PRIVATE
world.log << "Client: [connected_client]" // Works.
/proc/main()
var/datum/user_data/userData = new()
/* can_write practice */
// world.log << "can_write: [@userData.real_name.can_write]" // this is wrong. too ambiguous.
world.log << "can_write: [userData.@real_name.can_write]" // this is correct
world.log << "can_write: [@(userData.real_name).can_write]" // this works too? I hate this syntax.
// world.log << "can_write: [userData.@real_name.@can_write.can_write]" // why the fuck do you do this
/* other practices */
world.log << "implied type: [userData.@connected_data.implied_type]" // this will return "/client"
userData.@random_datum.can_be_null = 0 // I believe this is a bad idea if it's allowed.
This maybe can be potentially compatible to a proc..?
/procdata
var/can_call // flag example: PROC_ACCESS_PRIVATE. similar to var version
var/proc_type // read_only
var/proc_name // read_only
/datum/proc/foo()
// in a proc, @proc is the self-reference.
@proc.can_call = PROC_ACCESS_PRIVATE // only src can call this proc
world.log << "This proc type: [@proc.proc_type]" // returns /datum
world.log << "This proc name: [@proc.proc_name]" // returns foo
/datum/proc/boo()
src.foo() // no error
/proc/doo()
var/datum/D = new()
D.foo() // causes error - this proc can't be called from anywhere that isn't src.
----
What we gets?:
obviously type strict to make shits less buggy.
although I feel this is too much... maybe some variables can be cull down.
Setting var write restrictions also can't work. The language is loosely typed, and apart from special internal "hard" vars, there's no way to restrict the values that can be assigned to a var.
Restricting vars to only be readable from some procs is a no-go for similar reasons. The checking that would have to be done at runtime would be prohibitive and would result in a slowdown across the board.
Even something as simple as "Before assigning a value to this var, check if there are any flags indicating we need to do something more complex" would add overhead. This is one reason getters and setters aren't implemented.