I want to keep a pointer to my GameViewController in a scene in order to be able to transition between scenes from it. I come from C++ and this is a topic I'm struggling to understand in swift. How can this be done?
This is what I'm trying:
class SplashScene: SKScene
{
var view = SKView()
override func didMoveToView(view: SKView) {
self.view = &view
NSTimer.scheduledTimerWithTimeInterval(2, target: self, selector: Selector("transitionToGameScene"), userInfo: nil, repeats: false)
}
func transitionToGameScene() {
let scene = GameScene()
view.ignoresSiblingOrder = true
view.presentScene(scene, transition: SKTransition.crossFadeWithDuration(1))
}
}
SKScene already has a view property that is its containing SKView so, for that part of your question, just use the already existing property:
class SplashScene: SKScene
{
override func didMoveToView(view: SKView) {
NSTimer.scheduledTimerWithTimeInterval(2, target: self, selector: Selector("transitionToGameScene"), userInfo: nil, repeats: false)
}
func transitionToGameScene() {
let scene = GameScene()
view.ignoresSiblingOrder = true
view.presentScene(scene, transition: SKTransition.crossFadeWithDuration(1))
}
}
As for your question about pointers: Swift doesn't really have them, at least not pointers to memory locations the ones in c++. You can do what your original code was trying to do, just don't use the & operator; Swift will store a reference to your object instance internally (similar to a c++ pointer, but not something you can mess with directly).
You do have to be careful when it comes to structs vs classes though. Swift will store references to class instances, but with structs it will actually make a copy of the entire data structure instead of storing a reference to it. See "Structures and Enumerations Are Value Types", and "Classes Are Reference Types" in the Swift language reference.
Also the & operator is used from time to time in Swift. It's main use is with In-Out Parameters. You can think of it in pretty much the same way that you do in c++ in that case.
Related
I've been trying some stuff from kotlin.reflection during my project, and got stuck on something what occurs to me as hard to understand, I have declared object as follows:
object WebsiteMapping
{
const val ADMIN = "/admin"
}
once I call:
Arrays
.stream(WebsiteMapping::class.java.declaredFields)
.forEach { field -> println(field.type) }
what I get is:
class java.lang.String
class mapping.WebsiteMapping
When I looked a little bit into what is behind declaredFields invocation I grasped why it works as it is, but is there any convenient way of taking only declared consts within that object without getting also root of the whole structure?
The field with the type class mapping.WebsiteMapping is, basically, not the root of the structure but a special field generated in the object type that holds the reference to the singleton object.
In Kotlin, this field is named INSTANCE by convention. You can therefore filter the fields that you get from the class as follows:
WebsiteMapping::class.java.declaredFields
.filter { it.name != "INSTANCE" }
.forEach { println(it.type) }
Another solution is to switch from java.reflect.* to the Kotlin reflection API kotlin.reflect (needs a dependency on the kotlin-reflect module), which automatically filters the property:
WebsiteMapping::class.memberProperties
.forEach { println(it.returnType) }
This code correctly compiles. It has a few unused code warnings, but that's okay for now.
use std::collections::BTreeMap;
enum Object<'a> {
Str(String),
Int(i32),
Float(f32),
Vector(Vec<&'a Object<'a>>),
Prim(fn(State) -> State)
}
struct State<'a> {
named: BTreeMap<String, &'a Object<'a>>,
stack: Vec<Object<'a>>
}
impl<'a> State<'a> {
fn push_int(&mut self, x: i32) {
self.stack.push(Object::Int(x));
}
}
fn main() {
println!("Hello, world!");
let obj = Object::Str("this is a test".to_string());
}
The important part of this code is push_int and stack: Vec<Object<'a>>.
I'm sort of trying to make a stack-based VM.
I want to pass the state to functions, which can take stuff off the stack, manipulate the stuff, and then put some stuff back on the stack; the named field is going to hold named objects.
I have a hunch that it would be better to have the stack represented as a Vec<&'a Object<'a>> instead.
The way I have it now, I fear I'm committing some inefficiency error. Is my hunch correct?
The second part of the problem is that I don't know how to get the vector of references version to work. Creating new value with the right lifetimes to push onto the stack is not working for me.
I'm a bit vague about this issue, so if I've been unclear, ask me questions to clear stuff up.
The reason you could not get it to work is that structs cannot have fields that refer to other fields. (See supporting links at the bottom.)
What you can do, is put all the Objects into your Vec, and have the HashMap contain the indices of the named elements it references.
struct State {
named: BTreeMap<String, usize>,
stack: Vec<Object>
}
I'd also remove all lifetimes from your example, as this can be done completely with owned objects.
enum Object {
Str(String),
Int(i32),
Float(f32),
Vector(Vec<Object>),
Prim(fn(State) -> State)
}
You can try out a working implementation in the Playground
Supporting links:
How to initialize struct fields which reference each other
using self in new constructor
How to design a struct when I need to reference to itself
How to store HashMap and its Values iterator in the same struct?
What lifetimes do I use to create Rust structs that reference each other cyclically?
How to store a SqliteConnection and SqliteStatement objects in the same struct in Rust?
Why can't I store a value and a reference to that value in the same struct?
https://stackoverflow.com/questions/33123634/reference-inside-struct-to-object-it-owns
Is there any way to observe additions to and removals from ES6 Maps and Sets? Object.observe doesn't work because it is only applies to direct properties of the observed object. Hypothetically the size property could be observed, but no indication would be provided of exactly what has changed. Another idea would be to replace the object's set and get functions with proxified versions. Is there a better way? If not, I'm surprised that nobody thought of this when the proposals were being written for ES6.
No, there is no way to do this with a vanilla Map/Set. In general observation of object properties alone is controversial (that is why Object.observe is only a proposal, and not an accepted part of the spec). Observing private state, like the internals of a Map or Set (or Date or Promise, for that matter), is definitely not on the table.
Note also that since size is a getter, not a data property, Object.observe will not notify you of changes to it.
As you mention, you can achieve such "observation" via collaboration between the mutator and the observer. You could either do this with a normal Map/Set plus a side-channel (e.g. a function returning a { Map, EventEmitter } object), or via a subclass tailored for the purpose, or a specific instance created for that purpose.
Subclassing for Set/Map is not working at the moment. How about this method (just hasty example)?
//ECMAScript 2015
class XMap
{
constructor(iterable, observer = null)
{
this._map = new Map(iterable);
this._observer = observer;
this._changes = {};
}
set(key, value)
{
this._changes.prev = this._map.get(key);
this._changes.new = value;
this._map.set(key, value);
if(this._observer !== null)
{
this._observer(this._changes);
}
}
get(key)
{
return this._map.get(key);
}
}
var m = new XMap([[0, 1]], changes => console.log(changes));
m.set(0,5); // console: Object {prev: 1, new: 5}
m.set(0,15); // console: Object {prev: 5, new: 15}
The below does not work obviously:
Arbitrary := struct {
field1 string
field2 string
}{"a", "b"}
fmap := make(map[string]func(string) string)
fmap["fone"] = func(s string) string { fmt.Printf("function fone: %s", s) }
fmap["ftwo"] = func(s string) string { fmt.Printf("function ftwo: %s", s) }
// probably ok, as simple examples go, to this point where reflection needs to be used
// the below does not work
Arbitrary.fone = fmap["fone"]
Arbitrary.fone("hello")
The above is the core of what I'm trying to do: create a struct with values, and then create methods on the struct from a map of functions, or functions passed in. Basically I have a structure with data & ambiguous behavior that needs to be extended with methods unknown until creating the type.
I'm looking for the obvious & inevitable:
How to do this in Go
Why this shouldn't be done, or can't be done in Go (its possible with the reflect package, I just haven't found examples or reasoned thorough it yet)
How this should be done in Go (some sort of interface construct I've not figured out wholly. I've tried an interface which can handle the behavior; but it doesn't account for other behaviors that might be added, at the least I haven't figured out interface usage fully yet which is part of the issue)
If you're a person needing complexity here is the start of the actual task I'm trying to accomplish, making that structs behavior extendable.
I completely misunderstood the question.
NO, you can't create a new struct out of thin air and assign fields to it, also even if you could, for the love of everything that's holy, don't do that.
You can use multiple interfaces for example:
type Base interface {
Id() int //all structs must implement this
}
type Foo interface {
Base
Foo()
}
type Bar interface {
Base
Bar()
}
then make a map[string]Base, and you can assert the value later.
//leaving the original answer as a different approach to the problem.
While usually that kind of stuff is done using reflection, if you have a limited number of accepted "callbacks" you can use type assertion and an interface{} map, dropping the need for reflection.
var ctx = &Ctx{"Hello"}
var funcs = map[string]interface{}{
"m3": ctx.Do,
"m4": func(c *Ctx) { fmt.Println("ctx:", c) },
}
type Ctx struct {
Name string
}
func (c *Ctx) Do() {
fmt.Printf("Do: %+v\n", c)
}
func call(m string) {
if f, ok := funcs[m]; ok {
switch fn := f.(type) {
case func():
fn()
case func(*Ctx):
fn(&Ctx{"Hello world"})
default:
panic(fn)
}
}
}
playground
I want to contain all my commands in a map and map from the command to a function doing the job (just a standard dispatch table). I started with the following code:
package main
import "fmt"
func hello() {
fmt.Print("Hello World!")
}
func list() {
for key, _ := range whatever {
fmt.Print(key)
}
}
var whatever = map[string](func()) {
"hello": hello,
"list": list,
}
However, it fails to compile because there is a recursive reference between the function and the structure. Trying to forward-declare the function fails with an error about re-definition when it is defined, and the map is at top-level. How do you define structures like this and initialize them on top level without having to use an init() function.
I see no good explanation in the language definition.
The forward-reference that exists is for "external" functions and it does not compile when I try to forward-declare the function.
I find no way to forward-declare the variable either.
Update: I'm looking for a solution that do not require you to populate the variable explicitly when you start the program nor in an init() function. Not sure if that is possible at all, but it works in all comparable languages I know of.
Update 2: FigmentEngine suggested an approach that I gave as answer below. It can handle recursive types and also allow static initialization of the map of all commands.
As you might already have found, the Go specifications states (my emphasis):
if the initializer of A depends on B, A will be set after B. Dependency analysis does not depend on the actual values of the items being initialized, only on their appearance in the source. A depends on B if the value of A contains a mention of B, contains a value whose initializer mentions B, or mentions a function that mentions B, recursively. It is an error if such dependencies form a cycle.
So, no, it is not possible to do what you are trying to do. Issue 1817 mentions this problem, and Russ Cox does say that the approach in Go might occasionally be over-restrictive. But it is clear and well defined, and workarounds are available.
So, the way to go around it is still by using init(). Sorry.
Based on the suggestion by FigmentEngine above, it is actually possible to create a statically initialized array of commands. You have, however, to pre-declare a type that you pass to the functions. I give the re-written example below, since it is likely to be useful to others.
Let's call the new type Context. It can contain a circular reference as below.
type Context struct {
commands map[string]func(Context)
}
Once that is done, it is possible to declare the array on top level like this:
var context = Context {
commands: map[string]func(Context) {
"hello": hello,
"list": list,
},
}
Note that it is perfectly OK to refer to functions defined later in the file, so we can now introduce the functions:
func hello(ctx Context) {
fmt.Print("Hello World!")
}
func list(ctx Context) {
for key, _ := range ctx.commands {
fmt.Print(key)
}
}
With that done, we can create a main function that will call each of the functions in the declared context:
func main() {
for key, fn := range context.commands {
fmt.Printf("Calling %q\n", key)
fn(context)
}
}
Just populate the map inside a function before using list(). Like that.
Sry I did not see that you wrote "without init()": that is not possible.