3

I'd like to create SKSpriteNodes with a WallType (please see code below), and only if that WallType is .Corner pass it a Side value for its orientation. The enums have raw values because I need to load them as numbers from a plist and be able to create them randomly.

enum Side: Int {
  case Left = 0, Right
}

enum WallType: Int {
  case Straight = 0
  case Corner(orientation: Side)
}

I get the error: "Enum with raw type cannot have cases with arguments"

Is there a workaround where I can pass the SKSpriteNode a value for its orientation only when its WallType is .Corner? At the moment I'm initialising it with a value for orientation every time, even when it is not necessary because its WallType is .Straight.

I guess I could make Side optional but then I would have to change a lot of other code where I'm using Side as well. And then, I'd still have to pass in nil.

I'd like to initialise the wall like that:

let wall = Wall(ofType type: WallType)

The information about it's orientation should be inside the WallType, but only if it is .Corner. Is there a way to extend WallType to fit my needs?

The suggestion made in this thread doesn't really seem to apply in my case: Can associated values and raw values coexist in Swift enumeration?

Alternatively, if I decided to take away the raw value from the WallType enum, how would I go about loading it form a plist?

I hope that makes sense! Thanks for any suggestions!

Community
  • 1
  • 1
nontomatic
  • 2,003
  • 2
  • 24
  • 38
  • Since you have only two sides, have you considered having an enum value for a left corner and another enum value for a right corner? – zneak Jun 11 '15 at 21:13
  • Thanks zneak, that's certainly a workaround! I'd prefer to keep the WallType enum with the 2 cases since I'm using it in other places as well, but if there's no reasonable other solution, I will do that. – nontomatic Jun 11 '15 at 21:45

1 Answers1

0

You can make it so that you leave the Side enum to subclass from Int but you would want to pass this enum to Wall, so make sure that it takes the rawValue or index and side as the argument for creating the Wall.

Something like this,

enum Side: Int {
    case Left = 0, Right
}

enum Wall {
    case Straight(Int)
    case Corner(Int,Side)
}

let straight = Wall.Straight(0)
let corner = Wall.Corner(1, .Left)

switch straight {
    case .Straight(let index):
        print("Value is \(index)")
    case .Corner(let index, let side):
        print("Index is: \(index), Side is: \(side)")
}
Sandeep
  • 20,908
  • 7
  • 66
  • 106
  • Thanks a lot for your help! Please forgive me if I misunderstand but wouldn't I still have to pass my instance wall of the class Wall the argument for the side on top of the wallType? Because that's what I wanted to avoid. Is "switch straight" in your example a typo? – nontomatic Jun 11 '15 at 21:42
  • Well you have to do that even if your code above would work ? Anyway, if you want wall to have Side, why would you avoid to pass an instance of Side while building Wall ? straight is not a typo. I just wanted to show you, how you could test your instance of wall for .Corner or .Straight type. – Sandeep Jun 11 '15 at 21:48
  • Ok, I see. I just noticed a typo in my own code sample. The enum's name is "WallType", as referred to in my text, not "Wall". Sorry! I'm trying to initialise an instance "wall" of a class "Wall" that needs the above mentioned "WallType" as an argument. I was hoping that I wouldn't need to initialise that wall with anything other than the WallType, so that the information about the Side is included in that WallType already. Thanks for explaining your code, I will try it out in the morning and get back here. – nontomatic Jun 11 '15 at 22:16