상태 콜백
Bolt 0.4+는 임의의 타입에 콜백을 정의 할 수 있습니다. 이것은 콜백 메소드를 좀 더 복잡하게 만들었지만, 콜백을 설정하는 방식에 대해 더 자유롭게 할 수 있습니다.
state.AddCallback("myStateProperty", myCallbackFunction)
트리거
트리거는 C#의 Delegate 이고 사용시에 state.AddCallback()
이 필요하지 않다는 것을 참고하세요. 대신 adding to a delegate 신택스를 사용합니다. 왜냐하면 속성과 메소드 모두에서 "MyTrigger" 이름을 가질 수 없으므로 상태 트리거 콜백 등록을 위해 "OnMyTrigger" (또는 이벤트명이 "X" 인 것에 대하여 OnX") 를 사용합니다.
다음과 같이:
state.OnMyTrigger += myCallbackFunction
배열의 콜백
배열의 배열에 콜백을 다음과 같이 설정할 수 있습니다:
state.AddCallback
의 오버로드가 있는데, 이것은 (Bolt.IState, string path, Bolt.ArrayIndices indices)
형태의 3개의 파라미터를 받는 delegate 입니다.
- Bolt.IState 는 메소드 내에서 여러분의 상태 타입으로 캐스트 될 수 있습니다 (Bolt.IState는 모든 상태가 상속받는 클래스입니다).
- 강하게 타입화되지는 않았지만 (지네릭 AddCallback 메소드를 갖기 위해) 실제 상태입니다. 그것이 나의 타입으로 캐스팅 할 필요가 있는 이유입니다.
- string path 는 프로퍼터의 전체 경로입니다.
- Bolt.ArrayIndices indices 는 콜백내에서 붙인 모든 배열들의 인덱스들을 담고 있습니다.
예제 1a: 메소드를 가진 배열 콜백
state.AddCallback("stats[]", OnStatsChanged);
public void OnStatsChanged(Bolt.IState state, string path, Bolt.ArrayIndices indices)
{
int index = indices[0];
IActorState actorState = (IActorState)state;
// The changed property:
// actorState.stats[index]
}
예제 1b: 람바다를 가진 배열 콜백
state.AddCallback("stats[]", (x, y, z) => { OnStatsChanged((IActorState)x, (string)y, (Bolt.ArrayIndices)z); });
public void OnStatsChanged(IActorState state, string path, Bolt.ArrayIndices indices)
{
int index = indices[0];
}
예제 2a: 메소드를 가진 중첩 배열
state.AddCallback("vaults[].contents[]", OnVaultContentsChanged);
public void OnVaultContentsChanged(Bolt.IState state, string path, Bolt.ArrayIndices indices)
{
IActorState actorState = (IActorState)state;
int vaultIndex = indices[0];
int index = indices[1];
int itemID = actorState.vaults[vaultIndex].contents[index];
}
예제 2b: 람바다를 가진 중첩 콜백 배열
state.AddCallback("vaults[].contents[]", (x, y, z) => { OnVaultContentsChanged((IActorState)x, (string)y, (Bolt.ArrayIndices)z); });
public void OnVaultContentsChanged(IActorState state, string path, Bolt.ArrayIndices indices)
{
int vaultIndex = indices[0];
int index = indices[1];
int itemID = state.vaults[vaultIndex].contents[index];
}
예제 3: 구조체 콜백 내 메소드를 위한 룩업 케이블 사용
상태에 구조체를 정의하고 각 필드에 대해 콜백을 설정하는 대신에 단일 글로벌 콜백을 원하고 특정 속성마다 별도의 메소드를 호출하려는 경우에는 다음과 같이 switch문 보다는 룩업 테이블을 사용하는 것이 좋습니다. 이것은 필요 이상으로 최적화 된 것입니다. 또한 콜백이 많이 트리거되고 구조체에 많은 필드가 있는 경우에만 이점을 받을 수 있습니다.
액션의 룩업 테이블 정의하기:
Dictionary<string, Action> lookupTable = new Dictionary<string, Action>()
{
{ "equippedItems.head", UpdateArmor(state.equippedItems.head, 0) },
{ "equippedItems.body", UpdateArmor(state.equippedItems.body, 1) },
{ "equippedItems.arms", UpdateArmor(state.equippedItems.arms, 2) }
};
Action UpdateArmor(Item item, int index) {
return () => UpdateUMAArmor(item, index);
}
State 매개 변수가 붙여질때까지는 아규먼트에 액세스 할 수 없습니다. 그러므로 Attached() 안에서 룩업 테이블을 채우거나 지연된 접근으로 초기화되는 룩업 테이블을 작성해야합니다. 그렇지 않으면 다음의 오류가 발생하게 될 것 입니다:
오류: 객체 참조가 정적 객체가 아닌 필드, 메소드 또는 속성에 대해 필요 합니다 'Bolt.EntityBehaviour<IPlayerState>.state.get'
그리고 이것은 콜백에 추가하기 위해서 사용될 수 있습니다:
state.AddCallback("equippedItems", UpdateNewArmor);
그리고 이것이 메소드 입니다:
public void UpdateNewArmor(Bolt.IState state, string path, Bolt.ArrayIndices indices)
{
lookupTable[path]();
}