I have a GDScript file, and I would like to be able to run a block of code whenever the script is loaded. I know _init will run whenever an instance is constructed and _ready will run when it's added to the scene tree. I want to run code before either of those events happens; when the preload or load that brings it into memory first happens.
In Java, this would be a static initializer block, like so
public class Example {
public static ArrayList<Integer> example = new ArrayList<Integer>;
static {
// Pretend this is a complicated algorithm to compute the example array ...
example.add(1);
example.add(2);
example.add(3);
}
}
I want to do the same thing with a GDScript file in Godot, where some top-level constant or other configuration data is calculated when the script is first loaded, something like (I realize this is not valid GDScript)
extends Node
class_name Example
const EXAMPLE = []
static:
EXAMPLE.push_back(1)
EXAMPLE.push_back(2)
EXAMPLE.push_back(3)
Is there some way to get a feature like this or even to approximate it?
Background Information: The reason I care (aside from a general academic interest in problems like these) is that I'm working on a scripting language that uses GDScript as a compile target, and in my language there are certain initialization and registration procedures that need to happen to keep my language's runtime happy, and this needs to happen whenever a new script from my language is loaded.
In reality the thing I want to do is basically going to be
static:
MyLanguageRuntime.register_class_file(this_file, ...)
where MyLanguageRuntime is a singleton node that exists at the top of the scene tree to keep everything running smoothly.
Related
I am trying to create a topdown shooter with a player and a bullet on a separate scene. But whenever I run the game it says
Attempt to call function 'get_position' in base 'null instance' on a null instance.
BTW I am new to Godot.
The problem seems to be in this function:
const SPEED = 300
var bullet = preload("res://Mini-Scenes/Bullet.tscn")
func shoot():
var b = bullet.instance()
add_child(b)
b.set_position(position)
b.move_and_slide(Vector2(1, 0).rotated(rotation) * SPEED)
And I also don't think that I understand how instancing works,
so my questions are:
How does Instancing work?
What makes the above function fail?
Alright, in order:
Instancing is simple in principle. Godot takes the base Node of a scene and all its children, and copy-and-pastes them into memory. Then, when you add this Node as child to another in the scene, _ready is called, the Nodes begin to _process and _physics_process, as well as a few other things like receive events (as a Node must be within a SceneTree in order to interact with other nodes, and the most common way to add one to a tree is making it the child of another).
For more information, see the documentation on Instancing
The above function actually works flawlessly, I just created a new project in Godot 3.1.1 and duplicated your setup, no errors occur. The problem must be somewhere else in your code or your scene setup, and we'd need to see your full script and scene layout to determine the cause of the problem. If you update your question with that information, or shoot me a message on Discord (Mantissa#2558), I'll be able to fully answer your question.
First of, here is a little bit of a background story. I am using the Game Engine Stencyl (the interface can be compared to Scratch) to teach basic gamedevelopment with. Unfortunately, since this is a rather small team, I am still missing a couple of useful build in functions, thus I decided to create my own extensions for it. I know my way around C#, Java and UnityScript, but these extensions will have to be written in Haxe. I've already tried a couple of days of finding my answers on their API page, but that is way beyond my level of experience.
The first issue is that I am simply trying to use a couple of map functions, but the methods are all static. Everytime I try to use a function like mapCount() in line 16, it will throw me an error saying: Cannot access controls in static function. So far I have managed to figure out that this is because I am not able to call non-static functions from a static method, but I have no idea how to tackle this (and probably more issues like this in the future).
The second issue is that when I un-comment line 14, and comment out line 16, the game will compile just fine, but will crash with an stackoverflow error. The arguments for this function are: createRecycledActor(actorType, x, y, layerPosition)
Here is the current state of my script, not doing a lot right now, but I'm taking babysteps to learn my way around this new language. If you require any more info, just let me know!
Ps, the trace function in line 15 works fine btw.
import com.stencyl.behavior.Script;
import com.stencyl.behavior.Script.*;
import com.stencyl.utils.Utils;
import com.stencyl.models.Actor;
import com.stencyl.models.actor.ActorType;
class MobileGameKit
{
public var controls:Map<String,Actor> = new Map();
public static function CreateThumbstick(mActorType:ActorType, mLocation:Int, mDirectionLock:Int)
{
//createRecycledActor(mActorType, 0, 0, Script.FRONT);
trace("created thumbstick at position: "+mLocation+" with directionlock: "+mDirectionLock);
trace("items in control map: " + Utils.mapCount(controls));
}
}
Because controls is a member variable. i.e. each class instance has its own controls.
While a static function is a function at class level. i.e. each class (among all instances) has only one copy of the function.
So in a static function, you cannot access member variables because it won't be able to know from which instance to look for that member.
To solve your problem, either make controls a static var, or pass the member controls as a parameter to your static function.
btw, the language has been officially named as Haxe (instead haXe) for years already.
I have a Groovy script that lets the user define some dynamic properties and methods and later executes a user-defined closure. A script would look like this:
// init properties and methods dynamically at runtime
context.prop1 = "Some test value"
context.method1 = { String input ->
"exec " + input.toUpperCase()
}
// "this" is set to the context variable from above
run {
println method1( prop1 )
}
So in the beginning of the script, a context is initialized with user-defined properties (e.g. prop1) and methods (e.g. method1). The context is then used as this pointer in the run closure. I have achieved this by dynamically extending the meta class of the context and setting the context as delegate of the run closure (with DELEGATE_FIRST as resolves strategy).
Currently I am struggling at type checking. Before executing the run closure, I would like to check if method1 really expects prop1. I have looked into the DelegatesTo annotation, but that doesn't seem to work for dynamically extended objects. I have also played with the AST, but since my knowledge on that topic is limited, I haven't come up with a solution. If what I want to achieve is possible, any pointers in the right direction would be greatly appreciated.
You want to add a method to a context at runtime and then type check this before execution of that method.
Type checking is done at compile time. That is before anything of your program is executed. There is normally no chance this can ever check anything that will only happen at runtime, unless you have a way to statically declare it and give the compiler the power to do the check. But this means normally, you will have to do static compilation.
One way would be to use type checking extensions, but I think in your case that might be overkill. A more simple way would be to use extension modules. And the most simple way would be to use custom script base class.
But for any of these solution you will need static compilation to really have type checking, same for DelegatesTo (which is more used in combination with extension modules). For a type checked DSL a mix of type checking extensions and extension modules can work very well. But you will of course loose more dynamic features of the language and some simplicity.
I've recently started working on a non-trivial project in CoffeeScript and I'm struggling with how best to deal with registering exports etc. I'm writing it in a very 'pythonesque' manner, with individual files effectively being 'modules' of related classes and functions. What I'm looking for is the best way to define classes and functions locally AND in exports/window with as little repetition as possible.
At the moment, I'm using the following in every file, to save writing exports.X = X for everything in the file:
class module
# All classes/functions to be included in exports should be defined with `#`
# E.g.
class #DatClass
exports[name] = item for own name, item of module
I've also looked at the possibility of using a function (say, publish) that puts the passed class in exports/window depending on its name:
publish = (f) ->
throw new Error 'publish only works with named functions' unless f.name?
((exports ? window).namespace ?= {})[f.name] = f
publish class A
# A is now available in the local scope and in `exports.namespace`
# or `window.namespace`
This, however, does not work with functions as, as far as I know, they cannot be 'named' in CoffeeScript (e.g. f.name is always '') and so publish cannot determine the correct name.
Is there any method that works like publish but works with functions? Or any alternative ways of handling this?
It's an ugly hack but you can use the following :
class module.exports
class #foo
#bar = 3
And then :
require(...).foo.bar // 3
The old
(function (exports) {
// my code
exports.someLib = ...
})(typeof exports === "undefined" ? window : exports);
Is a neat trick that should do what you want.
If writing that wrapper boilerplate is a pain then automate it with a build script.
What I'm looking for is the best way to define classes and functions locally AND in exports/window with as little repetition as possible.
It's impossible to do something like
exports.x = var x = ...;
without writing x twice in JavaScript (without resorting to black magicks, i.e. eval), and the same goes for CoffeeScript. Bummer, I know, but that's how it is.
My advice would be to not get too hung up on it; that kind of repetition is common. But do ask yourself: "Do I really need to export this function or variable and make it locally available?" Cleanly decoupled code doesn't usually work that way.
There's an exception to the "no named functions" rule: classes. This works: http://jsfiddle.net/PxBgn/
exported = (clas) ->
console.log clas.name
window[clas.name] = clas
...
exported class Snake extends Animal
move: ->
alert "Slithering..."
super 5
When I enabled code contracts on my WPF control project I ran into a problem with an auto generated file which was created at compile time (XamlNamespace.GeneratedInternalTypeHelper). Note, the generated file is called GeneratedInternalTypeHelper.g.cs and is not the same as the GeneratedInternalTypeHelper.g.i.cs which there are several obsolete blog posts about.
I'm not exactly sure what its purpose is, but I am assuming it is important for some internal reflection to resolve XAML. The problem is that it does not have code contracts, nor is the code contract system smart enough to recognize it as an auto generated file. This leads to a bunch of errors from the static checker.
I tried searching for a solution to this problem, but it seems like nobody is developing WPF controls and using code contracts. I did come across an interesting attribute, ContractVerificationAttribute, which takes a boolean value to set whether the assembly or class is to be verified. This allows you to decorate a class as not verified. Sadly the GeneratedInternalTypeHelper is regenerated with every compile, so it is not possible to exclude just this one class. The inverse scenario is possible though, decorate the assembly as not verified and then opt in for every class.
To mitigate the obvious hack I wanted to create a test that would at least verify that the exposed classes have code contract verification with a test like the following to ensure that own classes were at least being verified:
[Fact]
public void AllAssemblyTypesAreDecoratedWithContractVerificationTrue()
{
var assembly = typeof(someType).Assembly;
var exposedTypes = assembly.GetTypes().Where(t=>!string.IsNullOrWhiteSpace(t.Namespace) && t.Namespace.StartsWith("MyNamespace") && !t.Name.StartsWith("<>"));
var areAnyNotContractVerified = exposedTypes.Any(t =>
{
var verificationAttribute = t.GetCustomAttributes(typeof(ContractVerificationAttribute), true).OfType<ContractVerificationAttribute>();
return verificationAttribute.Any() && verificationAttribute.First().Value;
});
Assert.False(areAnyNotContractVerified);
}
As you can see it takes all classes in the controls assembly and finds the one from the company namespace which are not also auto generated anonymous types (<>WeirdClassName).
(I also need to exclude Resources and settings, but I hope you get the idea).
I'm not loving the solution since there are ways of avoiding contract verification, but currently it's the best I can come up with. If anyone has a better solution, please let me know.
So you can treat this class exactly like you would treat any other "3rd party" class or library. I'm sure certain assumptions would hold with the interaction with this generated class so at the interaction points, decorate your own code with Contract.Assume(result != null) or similar.
var result = new GennedClass().GetSomeValue();
Contract.Assume(result != null);
What this does is translate into an assertion that is checked at run time, but it allows the static analyzer to reason about the rest of the code that you do control.