When using struct inheritance in GML, how do you make a call to the parent's version of a function? - gml

In most languages with a class system, there's some way to call the "base" version of a method from within an overriding method. It's usually called something like super or base. I know GML's "object-oriented" features are new and still not entirely there, but I was wondering whether there was a way to do the same thing in GML.
To be clear, I know how to do this with event inheritance (the event_inherited function), but here we're talking about the functions of structs, not the event responses of game objects. I also know that this can be done with struct constructors; I'm wondering if there's an equivalent for the struct's other functions.
An example of what I'm talking about. Let's say I have the following two kinds of structs:
function Animal(_name) constructor {
name = _name;
static Speak = function() {
show_debug_message(name + " makes noise");
}
}
function Dog(_name) : Animal(_name + " the dog") constructor {
static Speak = function() {
base.Speak(); // <-- THIS DOESN'T WORK, OBVIOUSLY
show_debug_message("(The kind of noise a dog would make)");
}
}
And I do this:
var bonzo = new Dog("Bonzo");
bonzo.Speak();
Then the output I'm looking for would be:
Bonzo the dog makes noise
(The kind of noise a dog would make)

GameMaker does not have a conventional base keyword, but static variables are still variables, so you can get the parent field before you "override" it in a child constructor:
function Animal(_name) constructor {
name = _name;
static Speak = function() {
show_debug_message(name + " makes noise");
}
}
function Dog(_name) : Animal(_name + " the dog") constructor {
static Animal_Speak = Speak;
static Speak = function() {
Animal_Speak(); // <-- THIS DOESN'T WORK, OBVIOUSLY
show_debug_message("(The kind of noise a dog would make)");
}
}
function SmallDog(_name) : Dog(_name + " (small)") constructor {
static Dog_Speak = Speak;
static Speak = function() {
Dog_Speak();
show_debug_message("(except high-pitched)");
}
}
var dog = new SmallDog("Bonzo");
dog.Speak();
Bonzo (small) the dog makes noise
(The kind of noise a dog would make)
(except high-pitched)

Related

I can't create a new instance of a ClassMirror by calling the defaullt constructor

I have two classes
class ESVAPI extends BibleProvider {
ESVAPI() : super('esvapi', true, {'esv'});
...methods
}
abstract class BibleProvider {
...fields
BibleProvider(this.name, this._requiresKey, this._versions) {
Bible.addProvider(this, _versions.toList());
}
}
I intend to have multiple classes extend the abstract class, so I want to create a method that creates an instances of each of BibleProvider's subclasses, I created one here:
ClassMirror classMirror = reflectClass(BibleProvider);
List<DeclarationMirror> subClassMirrors = currentMirrorSystem()
.libraries
.values
.expand((lib) => lib.declarations.values)
.where((lib) {
return lib is ClassMirror &&
lib.isSubclassOf(classMirror) &&
lib != classMirror;
}).toList();
DeclarationMirror subClassDec = subClassMirrors[0];
ClassMirror ESVCLASS = reflectClass(subClassDec.runtimeType);
var esvObj = ESVCLASS.newInstance(const Symbol(''), []);
But on ESVCLASS.newInstance I receive this exception:
No constructor '_ClassMirror' declared in class '_ClassMirror'
I'm thinking that this may have to do with how I call the superclass in the Constructor with "hard coded" values. If this is the case, is there a way to call the subclass' constructor and have it call the super constructor? I'm not entirely sure. Anyone familiar with reflections know what may be the case?
Change the last three lines to:
ClassMirror subClassDec = subClassMirrors[0] as ClassMirror;
var esvObj = subClassDec.newInstance(const Symbol(''), []);
...
print(esvObj.reflectee.runtimeType); // ESVAPI
You are reflecting on something that is already a mirror, so your ESVCLASS becomes the class mirror of the class _ClassMirror itself, not the subclass of BibleProvider you found above.
Just use the subClassDec class mirror directly.

What is the use of open properties in Kotlin?

I have been learning Kotlin and have come across the concept of open properties. Coming from C++, the concept of "open" makes sense, and extending that logic to properties does as well. However, I can't think of any case where an open val/var is actually necessary or useful. I understand when they make sense for interfaces, but not concrete classes. Furthermore, overriding getters/setters makes sense, but not redefining the property with a new backing field. For example, say you have this kind of class structure:
open class Foo {
open var str = "Hello"
}
class Bar : Foo() {
override var str = "world"
init {
println(str)
println(super.str) // Shows that Bar actually contains "hello" and "world"
}
}
To me, it would seem to be a far better design to make Foo take str as a constructor argument, for instance:
open class Foo(var str = "Hello") // Maybe make a secondary constructor
class Bar : Foo("world") // Bar has only 1 string
This is both more concise, and seems to often be a better design. This is also the way it tends to be done in C++, so maybe I just don't see the benefit of the other way. The only possible time I can see overriding a val/var with a new one is if it for some reason needs to use super's value, like in
override val foo = super.foo * 2
Which still seems pretty contrived.
When have you found this useful? Does it allow for greater efficiency or ease of use?
open fields let you re-define getter and setter methods. It's practically pointless if you just return constants. However altering getter / setter behavior has (infinite) potential, so I'll just throw some ideas:
// propagate get/set to parent class
class Bar : Foo() {
override var str
get() = super.str.toUpperCase()
set(value) {
super.str = value
}
}
// creates a backing field for this property
class Bar : Foo() {
override var str = "World"
get() = field.toLowerCase()
// no need to define custom set if we don't need it in this case
// set(value) { field = value }
}
// instead of writing custom get/set, you can also use delegates
class Bar : Foo() {
override var str by Delegates.observable("world"){ prop, old, new ->
println("${prop.name} changed from $old to $new")
}
}

Can I update a deeply nested immutable object without making it aware of its context?

Let's imagine I have a nested immutable object graph, along these lines (using Kotlin syntax, but hopefully it's clear):
data class House(val bedroom: Bedroom, val bathroom: Bathroom, val kitchen: Kitchen)
class Bedroom
class Bathroom
data class Kitchen(val oven: Oven, val kettle: Kettle)
class Oven
data class Kettle(val on: Boolean)
var house = House(Bedroom(), Bathroom(), Kitchen(Oven(), Kettle(false)))
Now, I want to switch the kettle on. If the objects were mutable I would just write:
data class Kettle(var on: Boolean) {
fun activate() {
this.on = true
}
}
house.kitchen.kettle.activate()
But because they are immutable I have to write:
data class Kettle(val on: Boolean) {
fun activate(house: House): House {
return house.copy(kitchen = kitchen.copy(kettle = kettle.copy(on = true)))
}
}
house = house.kitchen.kettle.activate(house)
(Actually, it's slightly more complicated, but this pseudo-code will do).
I don't like this, not because it's long, per se, but because the Kettle now needs to know not just about its own internal state, but about the full context it exists in.
How can I rewrite this so that each object can be responsible for providing its own mutation logic, without having to be aware of the full object graph? Or am I just trying to marry object-oriented and functional concepts in an impossible way?
This is where functional lenses show their power. For example, using poetix/klenses,
val kettleLens = +House::kitchen + Kitchen::kettle
var house = House(...)
house = kettleLens(house) { copy(on = true) }
One possible approach I thought of (this is the question asker, by the way) was like this:
data class Kettle(val on: Boolean) {
fun activate() {
return Transform(this, Kettle(on = true))
}
}
class Transform<T>(val what: T, val replacement: T) {
fun <U> apply(x: U): U {
if (x is T && x == what) {
return replacement as U
} else {
return x
}
}
}
The idea here is that a transform is a function you can apply to every object in the graph and it will only modify the what you told it to modify.
So you use it like this:
val transform = house.kitchen.kettle.activate()
house = house.transformEverything(transform)
Where every class has an implementation like this:
data class House(val bedroom: Bedroom, val bathroom: Bathroom, val kitchen: Kitchen) {
fun transformEverything(transform: Transform): House {
return transform(this).copy(
bedroom = bedroom.transformEverything(transform),
bathroom = bathroom.transformEverything(transform),
kitchen = kitchen.transformEverything(transform)
)
}
}
Which recursively gives the transform a chance to modify every object it wants to, and it will only apply it to one.
This approach is bad because:
Tons of boiler-plate giving everything its own dumb version of the transformEverything method
It seems weird (and inefficient) to have to call an function on every object in the graph just to change one.
But it does achieve my goal of the Kettle not needing to know anything about its context, and it's pretty straightforward to write the activate function. Thoughts?

Describing a function parameter that takes a class as an argument in TypeScript

I want to write a function where you parse the class type (the class, not an instance) then the function will instantiate an instance based on that parameter.
This is best explained by example:
//All possible paramter types must inherit from this base class
class Base { public name : string = ''; }
//These are possible classes that could be parsed to the function
class Foo extends Base { constructor() { super(); console.log("Foo instance created"); } }
class Bar extends Base { constructor() { super(); console.log("Bar instance created"); } }
//This function should take a class that inherits from 'Base' as a paramter - then it will create an instance
function Example(param : ?????????) : Base //I don't know what type the 'param' should be
{
return new param(); //Create instance?? How do I do this
}
//This should be the output - if it worked (but it doesn't)
Example(Foo); //Logs "Foo instance created""
Example(Bar); //Logs "Foo instance created""
//So if this worked, it would become possible to do this:
let b : Foo = Example(Foo);
let c : Bar = Example(Bar);
So my questions is: what type would the param for the 'Example' function be? And how would I create an instance of param from within the function.
Note, if this question is a duplicate I apologise - but I don't know the technical name for this process so it is difficult to research.
You want something like this.
function Example<T extends Base>(param: new () => T): T {
return new param();
}
We know that you'll have some type that is a Base. We're going to name it T, and we'll say that T extends Base to enforce that.
We also know that param will construct a T with no parameters. We can write new () => T to describe that.
Basically the way to think about this is that a class has both an instance side and a static side (also called the "constructor" side). In your example, Base, Foo, and Bar on their own have the static side.
The static side for each of them consists of all the static members you specify (and there aren't any in this case), along with the construct signature. In your case, Example takes a constructor expects no arguments, and produces some subtype of Base.

code in the middle is different, everything else the same

I often have a situation where I need to do:
function a1() {
a = getA;
b = getB;
b.doStuff();
.... // do some things
b.send()
return a - b;
}
function a2() {
a = getA;
b = getB;
b.doStuff();
.... // do some things, but different to above
b.send()
return a - b;
}
I feel like I am repeating myself, yet where I have ...., the methods are different, have different signatures, etc..
What do people normally do? Add an if (this type) do this stuff, else do the other stuff that is different? It doesn't seem like a very good solution either.
Polymorphism and possibly abstraction and encapsulation are your friends here.
You should specify better what kind of instructions you have on the .... // do some things part. If you're always using the same information, but doing different things with it, the solution is fairly easy using simple polymorphism. See my first revision of this answer. I'll assume you need different information to do the specific tasks in each case.
You also didn't specify if those functions are in the same class/module or not. If they are not, you can use inheritance to share the common parts and polymorphism to introduce different behavior in the specific part. If they are in the same class you don't need inheritance nor polymorphism.
In different classes
Taking into account you're stating in the question that you might need to make calls to functions with different signature depending on the implementation subclass (for instance, passing a or b as parameter depending on the case), and assuming you need to do something with the intermediate local variables (i.e. a and b) in the specific implementations:
Short version: Polymorphism+Encapsulation: Pass all the possible in & out parameters that every subclass might need to the abstract function. Might be less painful if you encapsulate them in an object.
Long Version
I'd store intermediate state in generic class' member, and pass it to the implementation methods. Alternatively you could grab the State from the implementation methods instead of passing it as an argument. Then, you can make two subclasses of it implementing the doSpecificStuff(State) method, and grabbing the needed parameters from the intermediate state in the superclass. If needed by the superclass, subclasses might also modify state.
(Java specifics next, sorry)
public abstract class Generic {
private State state = new State();
public void a() {
preProcess();
prepareState();
doSpecificStuf(state);
clearState();
return postProcess();
}
protected void preProcess(){
a = getA;
b = getB;
b.doStuff();
}
protected Object postProcess(){
b.send()
return a - b;
}
protected void prepareState(){
state.prepareState(a,b);
}
private void clearState() {
state.clear();
}
protected abstract doSpecificStuf(State state);
}
public class Specific extends Generic {
protected doSpecificStuf(State state) {
state.getA().doThings();
state.setB(someCalculation);
}
}
public class Specific2 extends Generic {
protected doSpecificStuf(State state) {
state.getB().doThings();
}
}
In the same class
Another possibility would be making the preProcess() method return a State variable, and use it inthe implementations of a1() and a2().
public class MyClass {
protected State preProcess(){
a = getA;
b = getB;
b.doStuff();
return new State(a,b);
}
protected Object postProcess(){
b.send()
return a - b;
}
public void a1(){
State st = preProcess();
st.getA().doThings();
State.clear(st);
return postProcess();
}
public void a2(){
State st = preProcess();
st.getB().doThings();
State.clear(st);
return postProcess();
}
}
Well, don't repeat yourself. My golden rule (which admittedly I break from time on time) is based on the ZOI rule: all code must live exactly zero, one or infinite times. If you see code repeated, you should refactor that into a common ancestor.
That said, it is not possible to give you a definite answer how to refactor your code; there are infinite ways to do this. For example, if a1() and a2() reside in different classes then you can use polymorphism. If they live in the same class, you can create a function that receives an anonymous function as parameter and then a1() and a2() are just wrappers to that function. Using a (shudder) parameter to change the function behavior can be used, too.
You can solve this in one of 2 ways. Both a1 and a2 will call a3. a3 will do the shared code, and:
1. call a function that it receives as a parameter, which does either the middle part of a1 or the middle part of a2 (and they will pass the correct parameter),
- or -
2. receive a flag (e.g. boolean), which will tell it which part it needs to do, and using an if statement will execute the correct code.
This screams out loud for the design pattern "Template Method"
The general part is in the super class:
package patterns.templatemethod;
public abstract class AbstractSuper {
public Integer doTheStuff(Integer a, Integer b) {
Integer x = b.intValue() + a.intValue();
Integer y = doSpecificStuff(x);
return b.intValue() * y;
}
protected abstract Integer doSpecificStuff(Integer x);
}
The spezific part is in the subclass:
package patterns.templatemethod;
public class ConcreteA extends AbstractSuper {
#Override
protected Integer doSpecificStuff(Integer x) {
return x.intValue() * x.intValue();
}
}
For every spezific solution you implement a subclass, with the specific behavior.
If you put them all in an Collection, you can iterate over them and call always the common method and evry class does it's magic. ;)
hope this helps