Подклассы, которые могут выбирать из различных вариантов выбора - PullRequest
0 голосов
/ 17 марта 2019

Я использую и Arduino для проекта светодиодной ленты. Я определяю классы LEDPattern и LEDColourScheme для управления поведением / внешним видом светодиодов.

Подклассы шаблонов наследуются от родительского класса LEDPattern и управляют включением светодиодов и яркостью.

Подклассы цветовой схемы наследуются от родительского класса LEDcolourScheme и управляют цветами.

Я хочу иметь возможность настроить каждый подкласс LEDPattern так, чтобы у него был уникальный выбор ColourSchemes на выбор. LEDPatterns и LEDColourSchemes можно инициализировать с помощью атрибутов конфигурации. Они оба определяют виртуальные методы, которые управляют их собственным поведением.

Для шаблонов я использовал массив экземпляров классов:

#define NUM_PATTERNS 7
LedPattern* led_patterns[] = {
  new patternBeatPulseGenerator(true),  //Has a boolean configurable attribute that changes behaviour
  new patternBeatPulseGenerator(false), 
  new patternMovingSineWave(),
  new patternSolidBeatPulse(),
  new patternMovingSegments(),
  new patternRandomSparkle(),
  new patternSineWavePulse(),      
};

А затем время от времени выбирайте новый случайный:

static LedPattern* pattern;
pattern_id = random(0,NUM_PATTERNS);
pattern = led_patterns[pattern_id];
patttern->initialise(); //Custom initialise method to 'reset' pattern each time it is selected (since instance is only initialized once when defined in array above)

Теперь я хочу иметь возможность сделать аналогичную вещь для ColourSchemes, иметь возможность определять выбор ColourSchemes для каждого шаблона и иметь метод класса Pattern, который возвращает случайный:

static ColourScheme* colour_scheme;
colour_scheme = pattern->GetColourScheme();
colour_scheme->initialise();

Затем для каждого «кадра» анимации вызываются методы Pattern и ColourScheme:

pattern->newFrame();
colour_scheme->newFrame();

Я пытался определить это так:

class LedPattern : public BaseLEDController {
  protected:
  ColourScheme* colour_schemes[6] = {
    new colourRainbow(0, 3), 
    new colourCycleBeatRed(),  
    new colourChangeOnBeat(),
    new colourRedHeart(),
    new colourRandom(),  
    new colourRainbow(3, 3),   
  };
  byte num_colour_schemes = 6;
  public:    
  virtual ColourScheme* getColourMode() {
    ColourScheme* colour_scheme;
    byte choice = random(0, num_colour_schemes );
    colour_scheme = colour_schemes[choice];
    colour_scheme->initialise();
    return colour_scheme;
  }
  ...
}

И затем переопределение массива colour_schemes [] в подклассах, однако, похоже, он не работает, он продолжает использовать конфигурацию базового класса. И я думаю, что экземпляры в массиве colour_schemes создаются заново для каждого экземпляра класса PAttern, поэтому он занимает кучу памяти .. Кроме того, я знаю, что не идеально иметь все LEDPatterns и ColourSchemes в качестве инициализированных экземпляров, занимающих память, когда только один из них фактически используется одновременно. Итак, еще один способ, которым я подумываю, - использовать оператор условных выражений / switch в качестве фабрики методов для генерации таких примеров:

virtual ColourScheme* getColourMode() {
byte choice = random(0, num_colour_schemes );
static ColourScheme* colour_scheme;
delete[] colour_scheme;  //Delete old one to free up memory
switch (choice) {
  case 0:
    colour_scheme= new colourRainbow(0, 3); //Static rainbow
    break;
  case 1:
    colour_scheme= new colourCycleBeatRed();
    break;
  case 2:
    colour_scheme= new colourChangeOnBeat();
    break;
  case 3:
    colour_scheme= new colourRedHeart();
    break;
  case 4:
    colour_scheme= new colourRandom();
    break;
  case 5:
    colour_scheme= new colourRainbow(3, 3); //Moving rainbow
    break;
  default:
    colour_scheme= new colourRainbow(3, 3); 
    break;
}
return colour_scheme;
}

Это означает, что будет когда-либо только один экземпляр ColourScheme (и LEDPattern, если я тоже там сделаю то же самое) одновременно, что хорошо для памяти, и означает, что мне не понадобится пользовательский метод initialise () для сброса экземпляр каждый раз, когда он выбран (может интегрироваться в стандартный конструктор класса).

Однако изменение конфигурации ColourScheme на подклассах LEDPattern становится беспорядочным ...

Буду очень признателен, если у кого-нибудь есть идеи о том, как наилучшим образом реализовать эту функциональность !! Бонусные баллы, если возможно связать взвешивание с каждым шаблоном / ColourScheme, что влияет на вероятность его случайного выбора.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...