[CCNotificationCenter] cannot post msg to several targets in LUA. Only one callback in the 1st registered target was executed several times.

There’s a condition when adding a new observer to a type of message:

if (this->observerExisted(target, name))

and this means one message type can only be registered once by one target(CCObject*) and can be registered by multi- targets. it’s ok if this is by design.

But in LUA script, registering one msg type to different targets will only trigger one callback multi-times but not trigger every callbacks in every targets.

This is because the func call: engine->executeNotificationEvent(...) in CCNotificationCenter::postNotification(...) will only get the first LUA function handler by the msg type:

int CCLuaEngine::executeNotificationEvent(CCNotificationCenter* pNotificationCenter, const char* pszName)
{
    int nHandler = pNotificationCenter->getObserverHandlerByName(pszName);
    if (!nHandler) return 0;
...
}

So, I changed the code:

void CCNotificationCenter::postNotification(const char *name, CCObject *object)
{
    CCArray* ObserversCopy = CCArray::createWithCapacity(m_observers->count());
    ObserversCopy->addObjectsFromArray(m_observers);
    CCObject* obj = NULL;
    CCARRAY_FOREACH(ObserversCopy, obj)
    {
        CCNotificationObserver* observer = (CCNotificationObserver*) obj;
        if (!observer)
            continue;
        
        if (!strcmp(name,observer->getName()) && (observer->getObject() == object || observer->getObject() == NULL || object == NULL))
        {
            if (0 != observer->getHandler())
            {
                CCScriptEngineProtocol* engine = CCScriptEngineManager::sharedManager()->getScriptEngine();
                //engine->executeNotificationEvent(this, name, object);

				// we just need to execute the LUA/JS function with one parameter, the CCObject, so
				engine->executeNotificationEvent(observer->getHandler(), object);
            }
            else
            {
                observer->performSelector(object);
            }
        }
    }
}

int CCLuaEngine::executeNotificationEvent(int nHandler, CCObject* pObj)
{
	if (!nHandler) return 0;

	if (pObj)
		m_stack->pushCCObject(pObj, "CCObject");
    int ret = m_stack->executeFunctionByHandler(nHandler, pObj ? 1 : 0);
    m_stack->clean();
    return ret;
}

and it works.

I think it is a bug about CCNotificationCenter lua-binding,thanks.

Hi,
@strawhat thanks for your post and code!

@samuele3hu I don’t think it’s a bug. Although it’s kind of annoying that only one Lua callback/observer per target is taken into account it’s seem to be a design choice.

Another solution would be to warp CCNotificationCenter in Lua. This is quite straightforward and we don’t have to alter cocos2dx source code. I implemented a quick solution here.
Cheers, Laurent

@laurentzubiaur I think the method that warp CCNotificationCenter in Lua is a good idea, and the real reason that didn’t to pass the object to lua call is due to missing.

@samuele3hu Thanks. BTW have you had the chance to look at the lua notification package I wrote? Any thoughts/suggestions?

I think if all related operation of notification are realized in the lua,it will be better. And, How to set the obj?