MasterMotifエンティティとMixerエンティティを作る【実践的Macintoshプログラミング解説】

印刷用表示 |テキストサイズ 小 |中 |大 |

CoreData版 Repeating Motif Generator の開発 Repeating Motif Wonderland CoreData 実践的 Macintosh プログラミング解説

LinkIconホーム

更新日 2009-05-24

原図とミキサーのモデルを作る

MasterMotifエンティティとMixerエンティティを作る

MasterMotifEntityPicture2.png リサージュ図形に高調波をのせて原図に拡張する作業を開始します。まずエンティティの設計から始めます。

 繰返し紋様の原図は六つの発振器出力を組み合わせて作ります。X軸三つ、Y軸三つを合わせて六つです。三つの発振器出力を合成して各軸の出力にするので、波形合成の機能を持つMixerを追加します。原図のエンティティはMasterMotifとします。

 MasterMotifもMixerも波形に対応するベジエパスを持つので、PathHolderエンティティを親とする事にします。

 完成したエンティティは、Xcodeのモデルエディタで右の様に表示されます。

MasterMotifエンティティとMixerエンティティを追加する

MasterMotifEntityList.png モデルエディタのエンティティパネル左下のプラスボタンをクリックして、エンティティを追加します。エンティティ名をMasterMotif、クラス名をMasterMotifCDとします。

 そしてもう一つのエンティティMixerを追加します。エンティティ名をMixer、クラス名をMixerCDとします。

 MasterMotifとMixerの親エンティティをPathHolderに変更します。

 Lissajousエンティティは削除します。

MasterMotifEntityPanel.pngMixerEntityPanel.png

MasterMotifの属性

resolution

  •  resolutionは発振器出力の波形をどの程度細かくするのかを決めるパラメータです。一周期を何分割するのかを表す数で、大きければそれだけ滑らかになりますがデータとしては重くなります。
  •  これは原図のパラメータであり、ファイルに保存する必要があるのでMasterMotifエンティティの属性とします。

mixers

  •  原図はX軸のミキサーとY軸のミキサーが出力する波形によって決定されます。したがってMasterMotifエンティティに二つのMixerエンティティを所有させます。MasterMotifが削除された時に一緒にMixerも削除される様に、削除ルールをカスケードにします。
  •  mixersは属性ではなく関連です。対多関連なので名前を複数形にしました。

x, y

  •  X軸のミキサーとY軸のミキサーを特定する為の関連です。

MasterMotifEntityProperty2.pngresolutionProperty2.png

mixersProperty2.png

xRelation2.png

yRelation2.png

Mixerの属性

 Mixerに属性はなく、全て関連となります。

oscillators

  •  ミキサーは三つの発振器の出力する波形を合成して、自身の出力とします。したがってMixerエンティティに三つのOscillatorエンティティを所有させます。Mixerが削除された時に一緒にOscillatorも削除される様に、削除ルールをカスケードにします。

osc1, osc2, osc3

  •  三つの発振器を特定するための関連です。

masterMotif

  •  mixersの逆関連として使います。
MixerEntityProperty2.pngoscillatorsProperty3.png
masterMotifProperty3.pngosc1Property.png
osc2Property.pngosc3Property.png

Oscillatorエンティティの関連名を変更する

 上の図ではMixerエンティティのoscillators関連で、逆関連を設定していますが、これはOscillatorsエンティティのlissajous関連の名前を変更したものです。

OscillatorProperty3.pngmixerProperty2.png

ソースコードを生成する

 RMGDocument.xcdatamodelを選択してモデルエディタを起動した状態で、Xcodeのファイルメニューから「新規ファイル…」を実行します。するとCocoaグループの最後に「管理オブジェクトクラス」が存在するので、これを選択して次へ進みます。

  • RMGDocument.xcdatamodelを選択していないと「管理オブジェクトクラス」が現れないので注意!

newFileAssistantMO.png

 次のページは変更する必要がないので、何もいじらずに次に進みます。

newFileAssistantMO2.png

 次にエンティティを選びます。MixerとMasterMotifを選択します。Objective-C 2.0は使いませんので「Obj-C 2.0 プロパティを生成」のチェックは外しておきます。

newFileAssistantMO3.png

生成されたインターフェイスファイル

MasterMotifCD.h

 「新規ファイル…」を実行して生成されたMasterMotifCD.hは以下の様になりました。MixerCDの前方参照が、同じものが並んでいておかしいので、重複している分を消します。

 各プロパティに対応するアクセサメソッドの宣言が並んでいます。インスタンス変数は何もありません。

//
//  MasterMotifCD.h
//  RepeatingMotifGenerator
//
//  Copyright 2008 NovemberKou. All rights reserved.
//

#import <CoreData/CoreData.h>
#import "PathHolder.h"

@class MixerCD;
@class MixerCD;
@class MixerCD;

@interface MasterMotifCD :  PathHolder  
{
}

- (NSNumber *)resolution;
- (void)setResolution:(NSNumber *)value;

// Access to-many relationship via -[NSObject mutableSetValueForKey:]
- (void)addMixersObject:(MixerCD *)value;
- (void)removeMixersObject:(MixerCD *)value;

- (MixerCD *)x;
- (void)setX:(MixerCD *)value;

- (MixerCD *)y;
- (void)setY:(MixerCD *)value;

@end

MixerCD.h

 「新規ファイル…」を実行して生成されたMixerCD.hは以下の様になりました。OscillatorCDの前方参照が、同じものが並んでいておかしいので、重複している分を消します。

 各プロパティに対応するアクセサメソッドの宣言が並んでいます。インスタンス変数は何もありません。

//
//  MixerCD.h
//  RepeatingMotifGenerator
//
//  Copyright 2008 NovemberKou. All rights reserved.
//

#import <CoreData/CoreData.h>
#import "PathHolder.h"

@class OscillatorCD;
@class OscillatorCD;
@class MasterMotifCD;
@class OscillatorCD;
@class OscillatorCD;

@interface MixerCD :  PathHolder  
{
}

// Access to-many relationship via -[NSObject mutableSetValueForKey:]
- (void)addOscillatorsObject:(OscillatorCD *)value;
- (void)removeOscillatorsObject:(OscillatorCD *)value;

- (MasterMotifCD *)masterMotif;
- (void)setMasterMotif:(MasterMotifCD *)value;

- (OscillatorCD *)osc1;
- (void)setOsc1:(OscillatorCD *)value;

- (OscillatorCD *)osc2;
- (void)setOsc2:(OscillatorCD *)value;

- (OscillatorCD *)osc3;
- (void)setOsc3:(OscillatorCD *)value;

@end

アクセサメソッドを修正する

MasterMotifCD.m

 生成されたアクセサメソッドをスーパークラスに用意したユーティリティメソッドを使って短く書き直します。スーパークラスのユーティリティメソッドについては下記リンクを参照の事。

// 
//  MasterMotifCD.m
//  RepeatingMotifGenerator
//
//  Copyright 2008 NovemberKou. All rights reserved.
//

#import "MasterMotifCD.h"

#import "MixerCD.h"

@implementation MasterMotifCD 

#pragma mark -
#pragma mark Accessor methods

#pragma mark < property >

- (NSNumber *)resolution        {return  VFK("resolution");}
- (void)setResolution:(NSNumber *)value 
{
    [self setValue:value forKey:@"resolution" action:@"setResolution"];
}

#pragma mark < relationship >

- (void)addMixersObject:(MixerCD *)value      {[self addXsObject:value forKey:@"mixers"];}
- (void)removeMixersObject:(MixerCD *)value   {[self removeXsObject:value forKey:@"mixers"];}

- (MixerCD *)x                  {return  VFK("x");}
- (void)setX:(MixerCD *)value   {[self setValue:value forKey:@"x" action:nil];}

- (MixerCD *)y                  {return  VFK("y");}
- (void)setY:(MixerCD *)value   {[self setValue:value forKey:@"y" action:nil];}

@end

MixerCD.m

 MixerCDでも同様に、生成されたアクセサメソッドをスーパークラスに用意したユーティリティメソッドを使って短く書き直します。

// 
//  MixerCD.m
//  RepeatingMotifGenerator
//
//  Copyright 2008 NovemberKou. All rights reserved.
//

#import "MixerCD.h"

#import "OscillatorCD.h"
#import "MasterMotifCD.h"

@implementation MixerCD 

#pragma mark -
#pragma mark Accessor methods

#pragma mark < relationship >

- (void)addOscillatorsObject:(OscillatorCD *)value      {[self addXsObject:value forKey:@"oscillators"];}
- (void)removeOscillatorsObject:(OscillatorCD *)value   {[self removeXsObject:value forKey:@"oscillators"];}

- (OscillatorCD *)osc1                          {return  VFK("osc1");}
- (void)setOsc1:(OscillatorCD *)value           {[self setValue:value forKey:@"osc1" action:nil];}

- (OscillatorCD *)osc2                          {return  VFK("osc2");}
- (void)setOsc2:(OscillatorCD *)value           {[self setValue:value forKey:@"osc2" action:nil];}

- (OscillatorCD *)osc3                          {return  VFK("osc3");}
- (void)setOsc3:(OscillatorCD *)value           {[self setValue:value forKey:@"osc3" action:nil];}

- (MasterMotifCD *)masterMotif                  {return  VFK("masterMotif");}
- (void)setMasterMotif:(MasterMotifCD *)value   {[self setValue:value forKey:@"masterMotif" action:nil];}

@end

OscillatorCD

 OscillatorCDではlissajousアクセサメソッドをmixerアクセサメソッドに書き直します。

//
//  OscillatorCD.h
//  RepeatingMotifGenerator
//
//  Copyright 2008 NovemberKou. All rights reserved.
//

#import <CoreData/CoreData.h>
#import "PathHolder.h"

@class MixerCD;

@interface OscillatorCD :  PathHolder  
{
}

- (NSNumber *)amplitude;
- (void)setAmplitude:(NSNumber *)value;

- (NSNumber *)frequency;
- (void)setFrequency:(NSNumber *)value;

- (NSNumber *)phaseLag;
- (void)setPhaseLag:(NSNumber *)value;

- (MixerCD *)mixer;
- (void)setMixer:(MixerCD *)value;

@end

//
//  OscillatorCD.m
//

- (MixerCD *)mixer                  {return  VFK("mixer");}
- (void)setMixer:(MixerCD *)value   {[self setValue:value forKey:@"mixer" action:nil];}