diff options
Diffstat (limited to 'indra/llcommon/lleventcoro.cpp')
| -rw-r--r-- | indra/llcommon/lleventcoro.cpp | 129 | 
1 files changed, 129 insertions, 0 deletions
| diff --git a/indra/llcommon/lleventcoro.cpp b/indra/llcommon/lleventcoro.cpp new file mode 100644 index 0000000000..d598f1cc4a --- /dev/null +++ b/indra/llcommon/lleventcoro.cpp @@ -0,0 +1,129 @@ +/** + * @file   lleventcoro.cpp + * @author Nat Goodspeed + * @date   2009-04-29 + * @brief  Implementation for lleventcoro. + *  + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * Copyright (c) 2009, Linden Research, Inc. + * $/LicenseInfo$ + */ + +// Precompiled header +#include "linden_common.h" +// associated header +#include "lleventcoro.h" +// STL headers +#include <map> +// std headers +// external library headers +// other Linden headers +#include "llsdserialize.h" +#include "llerror.h" +#include "llcoros.h" + +std::string LLEventDetail::listenerNameForCoroImpl(const void* self_id) +{ +    // First, if this coroutine was launched by LLCoros::launch(), find that name. +    std::string name(LLCoros::instance().getNameByID(self_id)); +    if (! name.empty()) +    { +        return name; +    } +    // Apparently this coroutine wasn't launched by LLCoros::launch(). Check +    // whether we have a memo for this self_id. +    typedef std::map<const void*, std::string> MapType; +    static MapType memo; +    MapType::const_iterator found = memo.find(self_id); +    if (found != memo.end()) +    { +        // this coroutine instance has called us before, reuse same name +        return found->second; +    } +    // this is the first time we've been called for this coroutine instance +    name = LLEventPump::inventName("coro"); +    memo[self_id] = name; +    LL_INFOS("LLEventCoro") << "listenerNameForCoroImpl(" << self_id << "): inventing coro name '" +                            << name << "'" << LL_ENDL; +    return name; +} + +void LLEventDetail::storeToLLSDPath(LLSD& dest, const LLSD& rawPath, const LLSD& value) +{ +    if (rawPath.isUndefined()) +    { +        // no-op case +        return; +    } + +    // Arrange to treat rawPath uniformly as an array. If it's not already an +    // array, store it as the only entry in one. +    LLSD path; +    if (rawPath.isArray()) +    { +        path = rawPath; +    } +    else +    { +        path.append(rawPath); +    } + +    // Need to indicate a current destination -- but that current destination +    // needs to change as we step through the path array. Where normally we'd +    // use an LLSD& to capture a subscripted LLSD lvalue, this time we must +    // instead use a pointer -- since it must be reassigned. +    LLSD* pdest = &dest; + +    // Now loop through that array +    for (LLSD::Integer i = 0; i < path.size(); ++i) +    { +        if (path[i].isString()) +        { +            // *pdest is an LLSD map +            pdest = &((*pdest)[path[i].asString()]); +        } +        else if (path[i].isInteger()) +        { +            // *pdest is an LLSD array +            pdest = &((*pdest)[path[i].asInteger()]); +        } +        else +        { +            // What do we do with Real or Array or Map or ...? +            // As it's a coder error -- not a user error -- rub the coder's +            // face in it so it gets fixed. +            LL_ERRS("lleventcoro") << "storeToLLSDPath(" << dest << ", " << rawPath << ", " << value +                                   << "): path[" << i << "] bad type " << path[i].type() << LL_ENDL; +        } +    } + +    // Here *pdest is where we should store value. +    *pdest = value; +} + +LLSD errorException(const LLEventWithID& result, const std::string& desc) +{ +    // If the result arrived on the error pump (pump 1), instead of +    // returning it, deliver it via exception. +    if (result.second) +    { +        throw LLErrorEvent(desc, result.first); +    } +    // That way, our caller knows a simple return must be from the reply +    // pump (pump 0). +    return result.first; +} + +LLSD errorLog(const LLEventWithID& result, const std::string& desc) +{ +    // If the result arrived on the error pump (pump 1), log it as a fatal +    // error. +    if (result.second) +    { +        LL_ERRS("errorLog") << desc << ":" << std::endl; +        LLSDSerialize::toPrettyXML(result.first, LL_CONT); +        LL_CONT << LL_ENDL; +    } +    // A simple return must therefore be from the reply pump (pump 0). +    return result.first; +} | 
