2023. 3. 14. 19:28ㆍcocos2dx
cocos2d Notification은 전체적으로 NotificationCenter singleton 에서 총괄함.
cocos2d::NotificationCenter::getInstance() 을 먼저 받아온 다음에...
여기다가 addObserver를 붙여주고, postNotification으로 해당 observer를 호출.
붙였던 observer는 Ref 객체가 사라지는 타이밍에 removeObserver로 꼭 없애 줘야 함.
----------------------------------------------------------------------------------
#1. Notiinfo.h
#ifndef __NOTIMESSAGE_H__
#define __NOTIMESSAGE_H__
#ifndef SNDNOTI(str, ...)
#define SNDNOTI(str, ...) cocos2d::NotificationCenter::getInstance()->postNotification(str, ##__VA_ARGS__)
#endif
#define MSG_BACKSTAGE2_00 "Message_Back2_phase00"
#endif
#2. LayerBackStage2.cpp
LayerBackStage2::~LayerBackStage2()
{
auto NCtr = NotificationCenter::getInstance();
NCtr->removeObserver(this, MSG_BACKSTAGE2_00);
}
bool LayerBackStage2::init()
{
if (!Layer::init()) return false;
auto NCtr = NotificationCenter::getInstance();
NCtr->addObserver(this, callfuncO_selector(LayerBackStage2::onPhase0), MSG_BACKSTAGE2_00, NULL);
scheduleUpdate();
return true;
}
#3. 아무데서나
SNDNOTI(MSG_BACKSTAGE2_00, cocos2d::Integer::create(call_func_value));
SNDNOTI(MSG_BACKSTAGE2_00);
으로 call 한다.
------------------------------------------------------------------------------
#1. postNotification 형식은
postNotification(const std::string&, Ref*),
postNotification(const std::string&) 이다.
notification을 보낼 때, 호출 메시지만 보내느냐 아니면 Ref* sender를 함께 보내느냐를 선택할 수 있다.
CCRef.h에서는 함수 등록 매크로 callfuncO_selector를
typedef void (Ref::*SEL_CallFuncO)(Ref*);
#define CC_CALLFUNCO_SELECTOR(_SELECTOR) static_cast<cocos2d::SEL_CallFuncO>(&_SELECTOR)
#define callfuncO_selector(_SELECTOR) CC_CALLFUNCO_SELECTOR(_SELECTOR)
으로 정의한다.
그렇기 때문에 옵저버로 등록 가능한 함수는 void function(cocos2d::Ref* pRef) 형식이어야만 한다.
#2. addObserver를 통해 옵저버를 등록할때는
void __NotificationCenter::addObserver(Ref *target,
SEL_CallFuncO selector,
const std::string& name,
Ref *sender)
{
if (this->observerExisted(target, name, sender))
return;
NotificationObserver *observer = new (std::nothrow) NotificationObserver(target, selector, name, sender);
if (!observer)
return;
observer->autorelease();
_observers->addObject(observer);
}
와 같은 일련의 과정을 거치는데, 일단 난 sender를 null으로 하고, 거기에 value를 넣어서 호출하는 쪽을 선호함.
등록시에 sender가 null이 아니라면, 등록한 특정 sender에서만 해당 notification을 콜 할 수 있다.
#3. addObserver를 통해 NotificationCenter에 등록된 객체와 함수는 postNotification을 통해서 호출되는데,
void __NotificationCenter::postNotification(const std::string& name, Ref *sender)
{
__Array* ObserversCopy = __Array::createWithCapacity(_observers->count());
ObserversCopy->addObjectsFromArray(_observers);
Ref* obj = nullptr;
CCARRAY_FOREACH(ObserversCopy, obj)
{
NotificationObserver* observer = static_cast<NotificationObserver*>(obj);
if (!observer)
continue;
if (observer->getName() == name && (observer->getSender() == sender || observer->getSender() == nullptr || sender == nullptr))
{
if (0 == observer->getHandler())
{
observer->performSelector(sender);
}
}
}
}
의 과정을 통해 등록된 전체 옵저버를 흩어보고, name(객체와 함께 등록한 호출 str 메시지)를 통해서 호출할 놈을 찾는다.
다음에는 sender가 등록되어 있다면 일치하는가? sender가 등록되지 않았는가? sender가 없는가? 를 확인해서
notification을 보낸다.
'cocos2dx' 카테고리의 다른 글
box2D 정리 (0) | 2023.03.14 |
---|---|
action)callfuncN을 이용한 트릭 (0) | 2023.03.14 |
ffmpeg && cocos2d 동영상 플레이어 (0) | 2023.03.14 |
좌우가 연속되는 배경 횡스크롤 (0) | 2023.03.14 |
애니메이션 재생후 셀프삭제, using schedule, CardinalSpline (0) | 2023.03.14 |