swiftbit-masksoptionsettype

Swift protocol with member that is of 'ObjectSetType'


I'm currently writing a game in swift and I'm trying to make use of protocols to define things such as Chapters and Levels etc.

So a chapter might have the following structure:

   protocol Chapter {
       var title:String {get}
       var levels:[Level] {get}
       var choices:[OptionSetType]
   }

Each Chapter is composed of multiple levels and each level can only be accessed if certain 'choices' have been met.

To accomplish this I will track those choices and use a bit mask to see if conditions have been met. However the choices can be different for each Chapter but I want to build my game mechanics so they don't have to worry about working out which Chapter the user is actually on.

The idea being that each level has a 'Points' value and I just work out if the Points value contains the relevant choices bit mask.

So for 'Level' I tried to define a protocol such as

   protocol Level {
    var text:String {get}
    var score:OptionSetType {get} // this is what determines if a level can be shown if the right chapter 'choices' have been set
   }

which gives an error of

 Protocol 'OptionSetType' can only be used as a generic constraint because it has Self or associated type requirements

Now each chapter will in theory have it's own set of options, but I'm wondering how I can make this generic enough so that I can almost code the engine around this, rather than coding to each specific chapter. Which is why I thought I'd create the protocols. The trouble is how can I do the bit masking work when I will need to define set OptionSetType values and can't say the properties will be of a type of OptionSetType. Hope that makes sense?


Solution

  • [In Swift 3, OptionSetType is now OptionSet.] Your error occurs because OptionSet is a protocol and can't be used directly (it 'has Self or ... requirements).

    Your design would likely benefit by creating abstractions for Choice and Score - just as you created an abstraction for Level. Then, if you choose to implement Score as an OptionSet, the 'self requirement' will be met. Like such:

    struct Score : OptionSet { ... }
    struct Choice : OptionSet { ... }
    

    and then:

    protocol Chapter {
      var title:String {get}
      var levels:[Level] {get}
      var choices:[Choice]
    }
    
    protocol Level {
      var text:String {get}
      var score:Score {get}
    }