Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

'static var' to go with 'static func' #6840

Closed
raould opened this issue Oct 16, 2016 · 48 comments
Closed

'static var' to go with 'static func' #6840

raould opened this issue Oct 16, 2016 · 48 comments

Comments

@raould
Copy link

raould commented Oct 16, 2016

Operating system or device - Godot version:
ubuntu 16.04 lts 64 bit
godot 2.1 stable

i would like to have static vars for use by my static func()s.

@akien-mga
Copy link
Member

This is not C, care to explain what they would have that a normal global scope var wouldn't have?

@bojidar-bg
Copy link
Contributor

I disagree -- thinking without global variables makes things much cleaner.

@Zylann
Copy link
Contributor

Zylann commented Oct 16, 2016

Global vars are a tempting plague IMO, they always bite you back. Also, the documentation states it's because of thread-safety: http://docs.godotengine.org/en/latest/reference/gdscript.html?highlight=static#classes

If you really need global variables, you can have a look at auto-load scripts: http://docs.godotengine.org/en/latest/tutorials/step_by_step/singletons_autoload.html

@raould
Copy link
Author

raould commented Oct 16, 2016

i am confused by this thread. :-) i don't want globals. i want class-level-variables. (of course on the other hand i agree that objects are little computers and class level variables as well as instance members are all in a sense global from the perspective of the methods, so "global" as a pejorative is true depending on what level of scale one is talking about.)

i might be utterly misunderstanding what static means in gdscript but it looks to me more like class-members instead of the c static keyword. oh wait i am misunderstanding...

(i see the bit about thread safety but actually how that reads is "we'll take away something you would expect to have especially since there's static functions, because our internal workings are too mysterious and haven't been thought out well enough to let static variables exist.)

so now that i see the example at http://docs.godotengine.org/en/latest/reference/gdscript.html#classes i am super confused. :-) well super surprised anyway. to quote the hhgtth: "this is obviously some new meaning of the word static i wasn't previously aware of..."

it might work such that i can do what i wanted to do in the first place :-)

@akien-mga
Copy link
Member

akien-mga commented Oct 16, 2016

Isn't this sufficient?

class MyClass:
    var my_var = "hello"

func _ready():
    var my_inst = MyClass.new()
    my_inst.my_var = "world"
    print(my_inst.my_var)

or

var my_var = "hello"

func _ready():
    my_var = "world"
    print(my_var)

Those are "class-level" variables as far as I understand. Would you give an example of what you're looking for exactly?

@vnen
Copy link
Member

vnen commented Oct 16, 2016

Class-level static variables are globals. More specifically, they store a global state independent of any object.

Any reason why you can't use autoloads for this?

@eon-s
Copy link
Contributor

eon-s commented Oct 16, 2016

With class levels mean those variables that belongs to a class (globals for the class), not to instances or any scope, these are used sometimes like for global behaviour change or static pool of things.

Of course that tends to make a mess here and there, autoload scripts or nodes can be better organized and call groups for mass changes.

Is kind of pointless for the way Godot works but could be nice to have them as option some day.

@bojidar-bg
Copy link
Contributor

What about just using const? Its the closes GDScript has to static on-class (vs. on-instance) "variables".

@ghost
Copy link

ghost commented Apr 7, 2018

First of all thank you for your report and sorry for the delay.

We released Godot 3.0 in January 2018 after 18 months of work, fixing many old issues either directly, or by obsoleting/replacing the features they were referring to.

We still have hundreds of issues whose relevance/reproducibility needs to be checked against the current stable version, and that's where you can help us.
Could you check if the issue that you described initially is still relevant/reproducible in Godot 3.0 or any newer version, and comment about it here?

For bug reports, please also make sure that the issue contains detailed steps to reproduce the bug and, if possible, a zipped project that can be used to reproduce it right away. This greatly speeds up debugging and bugfixing tasks for our contributors.

Our Bugsquad will review this issue more in-depth in 15 days, and potentially close it if its relevance could not be confirmed.

Thanks in advance.

Note: This message is being copy-pasted to many "stale" issues (90+ days without activity). It might happen that it is not meaningful for this specific issue or appears oblivious of the issue's context, if so please comment to notify the Bugsquad about it.

@bevinhex
Copy link

I have the feeling @raould 's idea is not understood well, for example I have a function for calculating perlin noise here which starts with:

static func noise(x, y, z):	
	var p = [ 151,160,137,91,90,15,
   131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
   190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
   88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
   77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
   102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
   135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
   5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
   223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
   129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
   251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
   49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
   138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180,
   151,160,137,91,90,15,
   131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
   190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
   88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
   77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
   102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
   135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
   5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
   223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
   129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
   251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
   49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
   138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180]
		
	#find unit cube that contains points
	var X = int(floor(x)) & 255
	var Y = int(floor(y)) & 255
	var Z = int(floor(z)) & 255
	
	#find relative x,y,z of point i ncube

The problem here is whenever I call this function it has to create the variable p , then removes it from memory after finish, however I am calling this function very frequently, but this function is taking almost 1 seconds to finish, I am trying to optimize the function , first thing came to my mind is, remove the variable out side of the function, which does NOT make it global variable, it still will be static variable belongs to the class, the thing is, at least my IDE is not allowing me to define

static var p = [ 151,160,137,91,90,15,
   131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
   190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
   88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
   77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
   102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
   135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
   5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
   223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
   129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
   251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
   49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
   138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180,
   151,160,137,91,90,15,
   131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
   190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
   88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
   77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
   102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
   135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
   5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
   223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
   129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
   251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
   49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
   138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180]

static func noise(x, y, z):		
	#find unit cube that contains points
	var X = int(floor(x)) & 255
	var Y = int(floor(y)) & 255
	var Z = int(floor(z)) & 255
	
	#find relative x,y,z of point i ncube

So so far I don't see the point of implementing new script language with custom grammer, but it would be an improvement to allow static variables

@vnen
Copy link
Member

vnen commented May 21, 2018

@bevinhex why not use a const in this case? Constants are "static" by nature.

In any case, if you need local state, create a new object. I don't see it a problem to use objects when you need more persistent data.

@bevinhex
Copy link

@vnen, seems to be working as you said, I thought I tried const already, anyway as long as const is "static", I sure can use it in my case,
However what about some variable that I would like to be shared between multiple static functions? in which case I think we still will be needing static variables, since "var" cannot be accessed inside static function. we could pass use some other methods as a workaround though.

@eon-s
Copy link
Contributor

eon-s commented May 22, 2018

Something like that looks good for a custom resource more than a constant/static value, for a more godotish approach.

@Zylann
Copy link
Contributor

Zylann commented May 22, 2018

@bevinhex const is shared across static functions, and auto-load nodes can be used for other cases it doesn't cover.

@bevinhex
Copy link

bevinhex commented May 22, 2018

That is whould be one way of "workaround" , we do have workarounds to share some variable between static functions, but to be honest, to most programmers, it feels natural to want to try to use static variables for sharing data between static functions, I can use const to represent data for the static functions in my case, but when it comes to variables, I cannot just define it similar way
my first intuition usually would be to write

static queue=[1,2,3]
static func func0():
    queue.append(4)

static func func1():
    queue.append(5)

I think we kind of can put 'static variable' feature to somewhere as proposition for gdscript, maybe low priority, since we have workarounds.

@Zylann
Copy link
Contributor

Zylann commented May 22, 2018

Why is it a workaround? It's not const?
If static vars existed in GDScript, I guess they would exist within the script resource (aka the unnamed class that makes up one GDScript), and they won't be editable on objects where you put them (but rather on the script resource itself). Also, all warnings about thread safety and memory management would apply (beware of leaks and circular references if you reference such vars).
However, if that was the approach, given the nature of resources, it would mean the value of such variables would have the same lifetime as their script: it would reset if the script gets unloaded (i.e not present and not referenced on any object or script, which was fine so far for consts). That can happen when you switch scenes for example, unless... used in auto-load :) (which again solves your use case currently).
If vars lifetime were to be extended further, they would become global vars... basically^^
So maybe the solution, at the moment, is to simply not use static, because functions share a state, which makes your class... an object.

@bevinhex
Copy link

bevinhex commented May 22, 2018

So unless I put the static class in autoload , the class I use gets unloaded when I switch scene, so it does not make sense to have static variable? if that is the case, true, static variables messes thing up a bit, unless static variables made to stays in memory and does not get unload.

@vnen
Copy link
Member

vnen commented May 23, 2018

If static vars are made part of the script, then yes: they'll be destroyed as soon as the script is unloaded (which is very easy to happen, if you don't have persistent references to it). Thread safety also gets in the way.

There's no true concept of "Global" in Godot (in userland at least). Autoload is not truly global, it's just added to the scene tree. So adding persistent static variables would require a new setup just for that, which IMO is not worth it. If you need persistent state that is always available, just make an autoload.

@Geequlim
Copy link
Contributor

@vnen I don't think there's trouble with static vars about the life cycle of the script. If we want to access a static variable we have to get the script instance first (A variable that persistent references to it or a variable just preloaded). That will keep the script is not freed so the static variables should be OK.

Maybe I forgot something or something mis-understand. But the static variable is really an important feature to make the language better for organizations.

@eon-s
Copy link
Contributor

eon-s commented Aug 19, 2018

With named scripts, static vars may be finally useful.

@vnen
Copy link
Member

vnen commented Aug 19, 2018

If we want to access a static variable we have to get the script instance first

If that's the case then it's not so "static" anymore. The idea of having static variables is to not have to create any instance.

That will keep the script is not freed so the static variables should be OK.

Well, only if you keep the instance forever. But that does not really solve the problem, because users will most likely be unaware of this requirement and will get unexpected behavior. If that's a valid solution you don't even need instances, just keep a reference to the script resource.

Also, I think the most problematic issue is thread safety. IINM this is why static variables were never introduced.


With named scripts, static vars may be finally useful.

I'm not sure about that. It feels to me that it's replacing the use of a singleton. In which case it's much simpler and safer to use an autoload.

@eon-s
Copy link
Contributor

eon-s commented Aug 19, 2018

Static vars will allow to make real singletons, autoloaded scripts and scenes are not singletons and won't be replaced by one (because are used in the tree), it may also help to translate quickly structures from other engines/frameworks.

@Geequlim
Copy link
Contributor

Geequlim commented Aug 25, 2018

If that's the case then it's not so "static" anymore. The idea of having static variables is to not have to create any instance.

In fact we don't need something so static like other programing languages. But we really need a way to share variables in same class. For now only constants can be shared.

Here is an example of the static variable usecase:
A utility function avoid making script instance by static function.

Time.gd

const _iso_datetime_regex = null # private static variable

# Parse ISO datetime string to a datetime dictionary 
# - - - - - - - - - -  
# *Parameters*  
# * [datetime: String] ISO formated datetime text 
# - - - - - - - - - -  
# *Returns* Dictionary  
# * Return the datetime dictionary
# * Return `ERR_PARSE_ERROR` if parse failed
static func parse_iso_datetime(datetime):
	if _iso_datetime_regex == null:
		_iso_datetime_regex = RegEx.new()
		_iso_datetime_regex.compile("^(-?(?:[1-9][0-9]*)?[0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])(.[0-9]+)?(Z)?$")
	var result = _iso_datetime_regex.search(datetime)
	if result.strings.size() >= 7:
		return {
			'year':  int(result.strings[1]),
			'month': int(result.strings[2]),
			'day': int(result.strings[3]),
			'hour': int(result.strings[4]),
			'minute': int(result.strings[5]),
			'second': int(result.strings[6]),
		}
	return ERR_PARSE_ERROR

I use this method in following way

const Time = preload('time.gd')

func _ready():
    var time = Time.parse_iso_datetime('2018-08-25T02:17:26Z')

Also, I think the most problematic issue is thread safety. IINM this is why static variables were never introduced.

I don't think there are too much differences between static variables and constants in GDScript. If they are both stored in the Script resource instance why the constants are safe with threads but static variables not ?

@Zylann
Copy link
Contributor

Zylann commented Aug 25, 2018

Because thread safety becomes a concern when a variable can change. Constants don't change.

@vnen
Copy link
Member

vnen commented Aug 25, 2018

I talked to @reduz and he said static variables aren't available to encourage the use of singletons. He proposed to add a system similar to the autoload that doesn't require the script to be a Node (so they wouldn't need to be on the tree). That is my preference as well.

@Zireael07
Copy link
Contributor

@vnen: Really nice idea.

@vnen
Copy link
Member

vnen commented Aug 25, 2018

Did a short test on 3.0.6 since you can change the value of constants there. It seems there's not a problem changing the value from multiple threads (apparently Object has a locking mechanism).

However, losing the reference to the script makes the value reset as expected. This is really a problem if you expect static variables to "just work". A singleton in this case would be much more useful because the engine keeps the reference for you.

@aaronfranke
Copy link
Member

aaronfranke commented Mar 6, 2019

I'm trying to create data types inside of GDScript, and the non-existence of static vars makes it impossible to create pre-set objects like Vector3.one in the form of a var. I expected to be able to do this:

static var one = MyVector3.new(1, 1, 1)

But I think that currently the closest equivalent is this:

static func one():
	return MyVector3.new(1, 1, 1)

@Zylann
Copy link
Contributor

Zylann commented Mar 6, 2019

@aaronfranke I think it should be doable this way:

one.gd

class_name MyVector3

const one = Vector3(1, 1, 1)

@ericdsw
Copy link

ericdsw commented Apr 7, 2019

Hi @Zylann, quick question:
Is the fact that const makes the variable static a bug, or is this intended behavior?

@Zylann
Copy link
Contributor

Zylann commented Apr 7, 2019

@ericdsw it's intended. If a variable is always the same there is no reason to copy it in every instance, so it happens to be available without an instance, which is actually useful too (same happens in C#).

@mnn
Copy link

mnn commented Sep 4, 2019

const is very limiting, it is more like a macro in C than for example const in JavaScript (a variable which cannot be reassigned to) or readonly in TypeScript (a field which can be assigned to only in constructor) or final in Java (same as in TS). Here is the problem:

extends Resource

class_name MyDataClass

var _data

func _init(data) -> void: _data = data

func get_data(): return _data
extends Node2D

class_name Main

const data = MyDataClass.new(1)

Last line produces an error: Expected constant expression. Notice that MyDataClass is immutable (if user respects "private" fields, I don't think GDScript supports true private or final fields), such class should be possible to assign into GDScript's const which is supposed (at least I think it is) to represent never-changing data.

And to the autoload - it is a very cumbersome "solution" for libraries, telling users they must add this things to autoload. It should be, in my opinion, possible to specify this from code.

PS: From a user perspective, autoloaded singleton contains global variables anyway...

@Zylann
Copy link
Contributor

Zylann commented Sep 4, 2019

@mnn the thing with const is that it's like C# const. Your example doesn't work either when translated to C#, because it can't be guaranteed to be fully constant at compile time. However, it works with static readonly, meaning the variable holding data can't be changed, but the contents of the object can. GDScript implementation is closer to the second case, but aimed at the first case 🤷 (i.e you can put a dictionary in there, and modify that dictionary later on).

@mnn
Copy link

mnn commented Sep 4, 2019

Was wondering about other languages and it would seem const in C++ behaves exactly how I would expect a "constant" to work:

#include <iostream>

using namespace std;

struct MyData {
    int data;
};

const auto myData = MyData{1};

int main() {
    cout << myData.data; // ok

    // compilation error: assignment of member ‘MyData::data’ in read-only object
    myData.data = 4; 

    return 0;
}

I find it a bit strange that a dynamic language like GDScript has const defined as fully evaluated during compilation, yet lacks features to actually define a class which could be used in the const.

you can put a dictionary in there, and modify that dictionary later on

Eh, I found it hard to believe this, but apparently it's correct:

const data = {a = 1}

func _init() -> void:
	data.a = 2
	print("data.a = %s" % data.a)

it successfully compiles (even though const is fully evaluated during compilation and thus can be checked) and prints data.a = 2 (so not even runtime checks) 😕. Why is there the limitation to forbid using instances of user defined classes when dictionary can be used and mutated? It doesn't make any sense to me...

@aaronfranke
Copy link
Member

Further discussion about the behavior of const might be more relevant in #23695

@Geequlim
Copy link
Contributor

Geequlim commented Sep 5, 2019

@mnn Yes it works but this is not a perfect way.

The member of the data will be reset afer the script is free and reloaded.

@malucard
Copy link

My use case is that I have a list of packet classes, and I want to assign IDs to them at runtime so that later I can insert classes between others without changing the IDs. With any kind of static vars, I could assign them in a loop to an "id" field in the classes.
Since GDScript doesn't have that, I worked around that by making an enum in a singleton and using that in the classes, that works too, though it's a bit less nice

@jwatte
Copy link

jwatte commented Dec 25, 2019

I have a few performance counters I want to update across all instances of my class.
"How many times was the frobnicate() method called across all Widget instances?"
With a class static that could be modified (which const cannot) this would be easy.
As it is, I have to create some singleton object instance on the scene root or something, and try to update that, which is ... ugly.

@Calinou
Copy link
Member

Calinou commented Dec 26, 2019

I'll close this issue as we've decided not to implement static variables. Quoting @reduz on IRC:

<reduz> Calinou: even though it maaaay be doable, the main problem with this is that, if the script is unloaded and reloaded, this variable will be reset
<reduz> and it will be super confusing

(Remember that Godot supports live script editing and reloading.)

Moreover, there are also concerns about thread safety. As a result, implementing static variables in GDScript would likely prove more trouble than it's worth. A parent node or a singleton can provide similar functionality, but without the downsides of static variables (and without the added complexity of implementing them in Godot's codebase).

@dalexeev
Copy link
Member

I talked to @reduz and he said static variables aren't available to encourage the use of singletons. He proposed to add a system similar to the autoload that doesn't require the script to be a Node (so they wouldn't need to be on the tree). That is my preference as well.

@vnen Is this still in the plans?

@vnen
Copy link
Member

vnen commented Sep 13, 2020

@vnen Is this still in the plans?

I do want to do it, just not sure when.

@cgbeutler
Copy link

cgbeutler commented Oct 29, 2020

I am working in a project that is getting large fast. Because godot doesn't really do namespaces, autoloads (and class_name for that matter) quickly bloat the global space and make autocomplete lame and globally seize identifiers so they can never be used safely again. Static variables are nice cuz they are scoped.
Maybe i'll just be a terrible, horrible person:

const __converter := []
static func get_converter() -> Converter:
	if len(__converter) > 0:  return __converter[0]
	var c = Converter.new()
	__converter.append(c)
	return c

@Zylann
Copy link
Contributor

Zylann commented Oct 29, 2020

Static variables are nice cuz they are scoped.

Is that because the class get_converter is defined is NOT a global class? If yes, then it kinda makes sense as a private/internal static variable (but in any case, the behavior of resources mentionned earlier still applies so your variable might get erased if nothing references the script). But if your class has a global name, it's no different than yet another autoload.

@cgbeutler
Copy link

cgbeutler commented Oct 29, 2020

Is that because the class get_converter is defined is NOT a global class?

Yeah, my converters are sub-classes that I use for some homespun json conversion. I only really put the static hack in the big class at the top that has a global name, so, yeah, it's should behave just like a lazy-init static var (Though I'd prefer a static constructor like C#.)
I like to use statics for class metadata type stuff. Working sample converter:

class_name Binding
class Converter:
	extends ObjectJsonConverter
	func _init():
		.with_property( "name", StringJsonConverter.new().with_default("unnamed") )
		.with_property( "device_names", ArrayJsonConverter.new( StringJsonConverter.new() ) )
		.with_property( "device_name_contains", ArrayJsonConverter.new( StringJsonConverter.new() ) )
		.with_property( "binding_contexts", DictionaryJsonConverter.new(
			StringJsonConverter.new(),
			BindingContext.Converter.new()
		) )

@vnen
Copy link
Member

vnen commented Nov 3, 2020

Not sure why this is brought up again. I know you can find some uses for static variables, but it still have the same issue: a script may be unloaded and then the value is lost. So this cannot be implemented. It's a technical limitation.

We could do this anyway. Then scripts would break (even if we document because people in general don't read docs) so we would get many complaints.

We could cache all scripts with static values. Then you might be consuming a lot of memory if you abuse preload because those resources will also not be freed.

So we prefer to not do any of those and let users make some workaround, because at this point they'll have to be aware of limitation and consequences. I know it's not ideal but it's what we have.

@cgbeutler
Copy link

cgbeutler commented Nov 3, 2020

Yeah, I was mostly just sharing another workaround that wasn't too bad.
I don't expect stat to be added, based on the discussion above. I am confused, though, cuz when a script is loaded up, doesn't it have to load a dictionary of all consts? Those would have all the same issues, really. It's gonna have to reallocate all const strings and arrays and stuff every time the class is recreated. I think in my mind, const should be renamed to static and reference types (or at least resource types with exports for serialization) should be added. You could then do a compile warning for static reference types (and arrays and dictionaries, for that matter) that aren't in a class_name script.
I don't expect it to happen, though, hence sharing a workaround.

@vnen
Copy link
Member

vnen commented Nov 4, 2020

I don't expect stat to be added, based on the discussion above. I am confused, though, cuz when a script is loaded up, doesn't it have to load a dictionary of all consts? Those would have all the same issues, really.

Those are supposed to be constant. If you are relying on them to keep the state you changed it's up to you because there's no such guarantee. If we call them static then it would need to have keep the state.

In any case, if anyone wants to ask for a feature or change of behavior they need to go the the proposals repository.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests