<commit_before>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2016.  All rights reserved
 */
#ifndef _Stroika_Foundation_Execution_WaitableEvent_inl_
#define _Stroika_Foundation_Execution_WaitableEvent_inl_    1

/*
 ********************************************************************************
 ***************************** Implementation Details ***************************
 ********************************************************************************
 */
#include    "Common.h"
#include    "Finally.h"
#include    "ModuleInit.h"
#include    "SpinLock.h"
#include    "Thread.h"

#if     qExecution_WaitableEvent_SupportWaitForMultipleObjects
namespace   Stroika {
    namespace   Foundation {
        namespace   Execution {
            namespace Private_ {
                struct  WaitableEvent_ModuleInit_ {
                    SpinLock    fExtraWaitableEventsMutex_;
                };
            }
        }
    }
}
namespace   {
    extern  Stroika::Foundation::Execution::ModuleInitializer<Stroika::Foundation::Execution::Private_::WaitableEvent_ModuleInit_>   _Stroika_Foundation_Execution_Private_WaitableEvent_ModuleInit_;   // this object constructed for the CTOR/DTOR per-module side-effects
}
#endif

namespace   Stroika {
    namespace   Foundation {
        namespace   Execution {

            /*
             ********************************************************************************
             ********************** Execution::WaitableEvent::WE_ ***************************
             ********************************************************************************
             */
            inline  WaitableEvent::WE_::WE_ (ResetType resetType)
                : fResetType (resetType)
            {
            }
            inline  void    WaitableEvent::WE_::Reset ()
            {
#if     qCompilerAndStdLib_make_unique_lock_IsSlow
                MACRO_LOCK_GUARD_CONTEXT (fMutex);
#else
                auto    critSec { make_unique_lock (fMutex) };
#endif
                fTriggered = false;
            }
            inline  bool    WaitableEvent::WE_::PeekIsSet () const noexcept
            {
                return fTriggered;
            }
            inline  void    WaitableEvent::WE_::Set ()
            {
#if     qCompilerAndStdLib_make_unique_lock_IsSlow
                MACRO_LOCK_GUARD_CONTEXT (fMutex);
#else
                auto    critSec { make_unique_lock (fMutex) };
#endif
                fTriggered = true;
                fConditionVariable.notify_all ();
            }

            /*
             ********************************************************************************
             *************************** Execution::WaitableEvent ***************************
             ********************************************************************************
             */
            inline  WaitableEvent::WaitableEvent (ResetType resetType)
                : fWE_ (resetType)
            {
            }
            inline  void    WaitableEvent::Reset ()
            {
                //Debug::TraceContextBumper ctx ("WaitableEvent::Reset");
                fWE_.Reset ();
            }
            inline  bool    WaitableEvent::PeekIsSet () const noexcept
            {
                return fWE_.PeekIsSet ();
            }
            inline  void    WaitableEvent::Wait (Time::DurationSecondsType timeout)
            {
                fWE_.WaitUntil (timeout + Time::GetTickCount ());
            }
            inline  bool    WaitableEvent::WaitQuietly (Time::DurationSecondsType timeout)
            {
                return fWE_.WaitUntilQuietly (timeout + Time::GetTickCount ());
            }
            inline  void    WaitableEvent::WaitUntil (Time::DurationSecondsType timeoutAt)
            {
                fWE_.WaitUntil (timeoutAt);
            }
            inline  bool    WaitableEvent::WaitUntilQuietly (Time::DurationSecondsType timeoutAt)
            {
                return fWE_.WaitUntilQuietly (timeoutAt);
            }
#if     qExecution_WaitableEvent_SupportWaitForMultipleObjects
            template    <typename CONTAINER_OF_WAITABLE_EVENTS, typename SET_OF_WAITABLE_EVENTS_RESULT>
            inline  SET_OF_WAITABLE_EVENTS_RESULT  WaitableEvent::WaitForAny (CONTAINER_OF_WAITABLE_EVENTS waitableEvents, Time::DurationSecondsType timeout)
            {
                return WaitForAnyUntil (waitableEvents, timeout + Time::GetTickCount ());
            }
            template    <typename ITERATOR_OF_WAITABLE_EVENTS, typename SET_OF_WAITABLE_EVENTS_RESULT>
            inline  SET_OF_WAITABLE_EVENTS_RESULT  WaitableEvent::WaitForAny (ITERATOR_OF_WAITABLE_EVENTS waitableEventsStart, ITERATOR_OF_WAITABLE_EVENTS waitableEventsEnd, Time::DurationSecondsType timeout)
            {
                return WaitForAnyUntil (waitableEventsStart, waitableEventsEnd, timeout + Time::GetTickCount ());
            }
            template    <typename CONTAINER_OF_WAITABLE_EVENTS, typename SET_OF_WAITABLE_EVENTS_RESULT>
            inline  SET_OF_WAITABLE_EVENTS_RESULT  WaitableEvent::WaitForAnyUntil (CONTAINER_OF_WAITABLE_EVENTS waitableEvents, Time::DurationSecondsType timeoutAt)
            {
                return WaitForAnyUntil (begin (waitableEvents), end (waitableEvents), timeoutAt);
            }
            template    <typename ITERATOR_OF_WAITABLE_EVENTS, typename SET_OF_WAITABLE_EVENTS_RESULT>
            SET_OF_WAITABLE_EVENTS_RESULT  WaitableEvent::WaitForAnyUntil (ITERATOR_OF_WAITABLE_EVENTS waitableEventsStart, ITERATOR_OF_WAITABLE_EVENTS waitableEventsEnd, Time::DurationSecondsType timeoutAt)
            {
                SET_OF_WAITABLE_EVENTS_RESULT   result;
                /*
                 *  Create another WE as shared.
                 *  Stick it onto the list for each waitablevent
                 *  Wait on 'new private fake' enevt (and if it succeeeds, then check orig events and return right now)
                 *  Either way - undo additions
                 *
                 *  <<< @todo DOCUMENT AND EXPLAIN MUTEX >>>
                 */
                shared_ptr<WE_> we  =   make_shared<WE_> (eAutoReset);
                auto&&  cleanup =   Finally (
                [we, waitableEventsStart, waitableEventsEnd] () noexcept {
                    Thread::SuppressInterruptionInContext suppressThreadInterupts;
#if     qCompilerAndStdLib_make_unique_lock_IsSlow
                    MACRO_LOCK_GUARD_CONTEXT (_Stroika_Foundation_Execution_Private_WaitableEvent_ModuleInit_.Actual ().fExtraWaitableEventsMutex_);
#else
                    auto    critSec { make_unique_lock (_Stroika_Foundation_Execution_Private_WaitableEvent_ModuleInit_.Actual ().fExtraWaitableEventsMutex_) };
#endif
                    for (ITERATOR_OF_WAITABLE_EVENTS i = waitableEventsStart; i != waitableEventsEnd; ++i) {
                        (*i)->fExtraWaitableEvents_.remove (we);
                    }
                }
                                    );
                {
#if     qCompilerAndStdLib_make_unique_lock_IsSlow
                    MACRO_LOCK_GUARD_CONTEXT (_Stroika_Foundation_Execution_Private_WaitableEvent_ModuleInit_.Actual ().fExtraWaitableEventsMutex_);
#else
                    auto    critSec { make_unique_lock (_Stroika_Foundation_Execution_Private_WaitableEvent_ModuleInit_.Actual ().fExtraWaitableEventsMutex_) };
#endif
                    for (ITERATOR_OF_WAITABLE_EVENTS i = waitableEventsStart; i != waitableEventsEnd; ++i) {
                        (*i)->fExtraWaitableEvents_.push_front (we);
                    }
                }
                while (result.empty ()) {
                    we->WaitUntil (timeoutAt);
                    for (ITERATOR_OF_WAITABLE_EVENTS i = waitableEventsStart; i != waitableEventsEnd; ++i) {
                        WaitableEvent*  we2Test =   *i;
                        if (we2Test->fWE_.fTriggered) {
                            if (we2Test->fWE_.fResetType == eAutoReset) {
                                we2Test->fWE_.Reset ();
                            }
                            result.insert (we2Test);
                        }
                    }
                }
                return result;
            }
            template    <typename CONTAINER_OF_WAITABLE_EVENTS>
            inline  void    WaitableEvent::WaitForAll (CONTAINER_OF_WAITABLE_EVENTS waitableEvents, Time::DurationSecondsType timeout)
            {
                WaitForAllUntil (waitableEvents, timeout + Time::GetTickCount ());
            }
            template    <typename ITERATOR_OF_WAITABLE_EVENTS>
            inline  void    WaitableEvent::WaitForAll (ITERATOR_OF_WAITABLE_EVENTS waitableEventsStart, ITERATOR_OF_WAITABLE_EVENTS waitableEventsEnd, Time::DurationSecondsType timeout)
            {
                WaitForAllUntil (waitableEventsStart, waitableEventsEnd, timeout + Time::GetTickCount ());
            }
            template    <typename CONTAINER_OF_WAITABLE_EVENTS>
            inline  void    WaitableEvent::WaitForAllUntil (CONTAINER_OF_WAITABLE_EVENTS waitableEvents, Time::DurationSecondsType timeoutAt)
            {
                WaitForAllUntil (begin (waitableEvents), end (waitableEvents), timeoutAt);
            }
            template    <typename ITERATOR_OF_WAITABLE_EVENTS>
            void    WaitableEvent::WaitForAllUntil (ITERATOR_OF_WAITABLE_EVENTS waitableEventsStart, ITERATOR_OF_WAITABLE_EVENTS waitableEventsEnd, Time::DurationSecondsType timeoutAt)
            {
                /*
                 *  Create another WE as shared.
                 *  Stick it onto the list for each waitablevent
                 *  Wait on 'new private fake' enevt (and if it succeeeds, then check orig events and return right now)
                 *  Either way - undo additions
                 *
                 *  <<< @todo DOCUMENT AND EXPLAIN MUTEX >>>
                 */
                shared_ptr<WE_> we  =   make_shared<WE_> (eAutoReset);
                auto&&  cleanup =   Finally (
                [we, waitableEventsStart, waitableEventsEnd] () noexcept {
                    Thread::SuppressInterruptionInContext suppressThreadInterupts;
#if     qCompilerAndStdLib_make_unique_lock_IsSlow
                    MACRO_LOCK_GUARD_CONTEXT (_Stroika_Foundation_Execution_Private_WaitableEvent_ModuleInit_.Actual ().fExtraWaitableEventsMutex_);
#else
                    auto    critSec { make_unique_lock (_Stroika_Foundation_Execution_Private_WaitableEvent_ModuleInit_.Actual ().fExtraWaitableEventsMutex_) };
#endif
                    for (ITERATOR_OF_WAITABLE_EVENTS i = waitableEventsStart; i != waitableEventsEnd; ++i) {
                        (*i)->fExtraWaitableEvents_.remove (we);
                    }
                }
                                    );
                {
#if     qCompilerAndStdLib_make_unique_lock_IsSlow
                    MACRO_LOCK_GUARD_CONTEXT (_Stroika_Foundation_Execution_Private_WaitableEvent_ModuleInit_.Actual ().fExtraWaitableEventsMutex_);
#else
                    auto    critSec { make_unique_lock (_Stroika_Foundation_Execution_Private_WaitableEvent_ModuleInit_.Actual ().fExtraWaitableEventsMutex_) };
#endif
                    for (ITERATOR_OF_WAITABLE_EVENTS i = waitableEventsStart; i != waitableEventsEnd; ++i) {
                        (*i)->fExtraWaitableEvents_.push_front (we);
                    }
                }
                while (true) {
                    we->WaitUntil (timeoutAt);
                    bool anyStillWaiting = false;
                    for (ITERATOR_OF_WAITABLE_EVENTS i = waitableEventsStart; i != waitableEventsEnd; ++i) {
                        WaitableEvent*  we2Test =   *i;
                        RequireNotNull (we2Test);
                        if (not we2Test->fWE_.fTriggered) {
                            anyStillWaiting = true;
                        }
                    }
                    if (anyStillWaiting) {
                        continue;
                    }
                    else {
                        for (ITERATOR_OF_WAITABLE_EVENTS i = waitableEventsStart; i != waitableEventsEnd; ++i) {
                            WaitableEvent*  we2Test =   *i;
                            RequireNotNull (we2Test);
                            if (we2Test->fWE_.fResetType == eAutoReset) {
                                Assert (we2Test->fWE_.fTriggered);  // we probably need some mechanism to assure this is true but we currently have no enforcement of this!
                                we2Test->fWE_.Reset ();
                            }
                        }
                        return; // success
                    }
                }
            }
#endif

        }
    }
}

#if     qExecution_WaitableEvent_SupportWaitForMultipleObjects
namespace   {
    Stroika::Foundation::Execution::ModuleInitializer<Stroika::Foundation::Execution::Private_::WaitableEvent_ModuleInit_>   _Stroika_Foundation_Execution_Private_WaitableEvent_ModuleInit_;   // this object constructed for the CTOR/DTOR per-module side-effects
}
#endif

#endif  /*_Stroika_Foundation_Execution_WaitableEvent_inl_*/
<commit_msg>workaround one final helgrind issue https://stroika.atlassian.net/browse/STK-484<commit_after>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2016.  All rights reserved
 */
#ifndef _Stroika_Foundation_Execution_WaitableEvent_inl_
#define _Stroika_Foundation_Execution_WaitableEvent_inl_    1

/*
 ********************************************************************************
 ***************************** Implementation Details ***************************
 ********************************************************************************
 */
#include    "Common.h"
#include    "Finally.h"
#include    "ModuleInit.h"
#include    "SpinLock.h"
#include    "Thread.h"

#if     qExecution_WaitableEvent_SupportWaitForMultipleObjects
namespace   Stroika {
    namespace   Foundation {
        namespace   Execution {
            namespace Private_ {
                struct  WaitableEvent_ModuleInit_ {
                    SpinLock    fExtraWaitableEventsMutex_;
                };
            }
        }
    }
}
namespace   {
    extern  Stroika::Foundation::Execution::ModuleInitializer<Stroika::Foundation::Execution::Private_::WaitableEvent_ModuleInit_>   _Stroika_Foundation_Execution_Private_WaitableEvent_ModuleInit_;   // this object constructed for the CTOR/DTOR per-module side-effects
}
#endif

namespace   Stroika {
    namespace   Foundation {
        namespace   Execution {

            /*
             ********************************************************************************
             ********************** Execution::WaitableEvent::WE_ ***************************
             ********************************************************************************
             */
            inline  WaitableEvent::WE_::WE_ (ResetType resetType)
                : fResetType (resetType)
            {
                Stroika_Foundation_Debug_ValgrindDisableHelgrind (fTriggered);  // @see https://stroika.atlassian.net/browse/STK-484
            }
            inline  void    WaitableEvent::WE_::Reset ()
            {
#if     qCompilerAndStdLib_make_unique_lock_IsSlow
                MACRO_LOCK_GUARD_CONTEXT (fMutex);
#else
                auto    critSec { make_unique_lock (fMutex) };
#endif
                fTriggered = false;
            }
            inline  bool    WaitableEvent::WE_::PeekIsSet () const noexcept
            {
                return fTriggered;
            }
            inline  void    WaitableEvent::WE_::Set ()
            {
#if     qCompilerAndStdLib_make_unique_lock_IsSlow
                MACRO_LOCK_GUARD_CONTEXT (fMutex);
#else
                auto    critSec { make_unique_lock (fMutex) };
#endif
                fTriggered = true;
                fConditionVariable.notify_all ();
            }

            /*
             ********************************************************************************
             *************************** Execution::WaitableEvent ***************************
             ********************************************************************************
             */
            inline  WaitableEvent::WaitableEvent (ResetType resetType)
                : fWE_ (resetType)
            {
            }
            inline  void    WaitableEvent::Reset ()
            {
                //Debug::TraceContextBumper ctx ("WaitableEvent::Reset");
                fWE_.Reset ();
            }
            inline  bool    WaitableEvent::PeekIsSet () const noexcept
            {
                return fWE_.PeekIsSet ();
            }
            inline  void    WaitableEvent::Wait (Time::DurationSecondsType timeout)
            {
                fWE_.WaitUntil (timeout + Time::GetTickCount ());
            }
            inline  bool    WaitableEvent::WaitQuietly (Time::DurationSecondsType timeout)
            {
                return fWE_.WaitUntilQuietly (timeout + Time::GetTickCount ());
            }
            inline  void    WaitableEvent::WaitUntil (Time::DurationSecondsType timeoutAt)
            {
                fWE_.WaitUntil (timeoutAt);
            }
            inline  bool    WaitableEvent::WaitUntilQuietly (Time::DurationSecondsType timeoutAt)
            {
                return fWE_.WaitUntilQuietly (timeoutAt);
            }
#if     qExecution_WaitableEvent_SupportWaitForMultipleObjects
            template    <typename CONTAINER_OF_WAITABLE_EVENTS, typename SET_OF_WAITABLE_EVENTS_RESULT>
            inline  SET_OF_WAITABLE_EVENTS_RESULT  WaitableEvent::WaitForAny (CONTAINER_OF_WAITABLE_EVENTS waitableEvents, Time::DurationSecondsType timeout)
            {
                return WaitForAnyUntil (waitableEvents, timeout + Time::GetTickCount ());
            }
            template    <typename ITERATOR_OF_WAITABLE_EVENTS, typename SET_OF_WAITABLE_EVENTS_RESULT>
            inline  SET_OF_WAITABLE_EVENTS_RESULT  WaitableEvent::WaitForAny (ITERATOR_OF_WAITABLE_EVENTS waitableEventsStart, ITERATOR_OF_WAITABLE_EVENTS waitableEventsEnd, Time::DurationSecondsType timeout)
            {
                return WaitForAnyUntil (waitableEventsStart, waitableEventsEnd, timeout + Time::GetTickCount ());
            }
            template    <typename CONTAINER_OF_WAITABLE_EVENTS, typename SET_OF_WAITABLE_EVENTS_RESULT>
            inline  SET_OF_WAITABLE_EVENTS_RESULT  WaitableEvent::WaitForAnyUntil (CONTAINER_OF_WAITABLE_EVENTS waitableEvents, Time::DurationSecondsType timeoutAt)
            {
                return WaitForAnyUntil (begin (waitableEvents), end (waitableEvents), timeoutAt);
            }
            template    <typename ITERATOR_OF_WAITABLE_EVENTS, typename SET_OF_WAITABLE_EVENTS_RESULT>
            SET_OF_WAITABLE_EVENTS_RESULT  WaitableEvent::WaitForAnyUntil (ITERATOR_OF_WAITABLE_EVENTS waitableEventsStart, ITERATOR_OF_WAITABLE_EVENTS waitableEventsEnd, Time::DurationSecondsType timeoutAt)
            {
                SET_OF_WAITABLE_EVENTS_RESULT   result;
                /*
                 *  Create another WE as shared.
                 *  Stick it onto the list for each waitablevent
                 *  Wait on 'new private fake' enevt (and if it succeeeds, then check orig events and return right now)
                 *  Either way - undo additions
                 *
                 *  <<< @todo DOCUMENT AND EXPLAIN MUTEX >>>
                 */
                shared_ptr<WE_> we  =   make_shared<WE_> (eAutoReset);
                auto&&  cleanup =   Finally (
                [we, waitableEventsStart, waitableEventsEnd] () noexcept {
                    Thread::SuppressInterruptionInContext suppressThreadInterupts;
#if     qCompilerAndStdLib_make_unique_lock_IsSlow
                    MACRO_LOCK_GUARD_CONTEXT (_Stroika_Foundation_Execution_Private_WaitableEvent_ModuleInit_.Actual ().fExtraWaitableEventsMutex_);
#else
                    auto    critSec { make_unique_lock (_Stroika_Foundation_Execution_Private_WaitableEvent_ModuleInit_.Actual ().fExtraWaitableEventsMutex_) };
#endif
                    for (ITERATOR_OF_WAITABLE_EVENTS i = waitableEventsStart; i != waitableEventsEnd; ++i) {
                        (*i)->fExtraWaitableEvents_.remove (we);
                    }
                }
                                    );
                {
#if     qCompilerAndStdLib_make_unique_lock_IsSlow
                    MACRO_LOCK_GUARD_CONTEXT (_Stroika_Foundation_Execution_Private_WaitableEvent_ModuleInit_.Actual ().fExtraWaitableEventsMutex_);
#else
                    auto    critSec { make_unique_lock (_Stroika_Foundation_Execution_Private_WaitableEvent_ModuleInit_.Actual ().fExtraWaitableEventsMutex_) };
#endif
                    for (ITERATOR_OF_WAITABLE_EVENTS i = waitableEventsStart; i != waitableEventsEnd; ++i) {
                        (*i)->fExtraWaitableEvents_.push_front (we);
                    }
                }
                while (result.empty ()) {
                    we->WaitUntil (timeoutAt);
                    for (ITERATOR_OF_WAITABLE_EVENTS i = waitableEventsStart; i != waitableEventsEnd; ++i) {
                        WaitableEvent*  we2Test =   *i;
                        if (we2Test->fWE_.PeekIsSet ()) {
                            if (we2Test->fWE_.fResetType == eAutoReset) {
                                we2Test->fWE_.Reset ();
                            }
                            result.insert (we2Test);
                        }
                    }
                }
                return result;
            }
            template    <typename CONTAINER_OF_WAITABLE_EVENTS>
            inline  void    WaitableEvent::WaitForAll (CONTAINER_OF_WAITABLE_EVENTS waitableEvents, Time::DurationSecondsType timeout)
            {
                WaitForAllUntil (waitableEvents, timeout + Time::GetTickCount ());
            }
            template    <typename ITERATOR_OF_WAITABLE_EVENTS>
            inline  void    WaitableEvent::WaitForAll (ITERATOR_OF_WAITABLE_EVENTS waitableEventsStart, ITERATOR_OF_WAITABLE_EVENTS waitableEventsEnd, Time::DurationSecondsType timeout)
            {
                WaitForAllUntil (waitableEventsStart, waitableEventsEnd, timeout + Time::GetTickCount ());
            }
            template    <typename CONTAINER_OF_WAITABLE_EVENTS>
            inline  void    WaitableEvent::WaitForAllUntil (CONTAINER_OF_WAITABLE_EVENTS waitableEvents, Time::DurationSecondsType timeoutAt)
            {
                WaitForAllUntil (begin (waitableEvents), end (waitableEvents), timeoutAt);
            }
            template    <typename ITERATOR_OF_WAITABLE_EVENTS>
            void    WaitableEvent::WaitForAllUntil (ITERATOR_OF_WAITABLE_EVENTS waitableEventsStart, ITERATOR_OF_WAITABLE_EVENTS waitableEventsEnd, Time::DurationSecondsType timeoutAt)
            {
                /*
                 *  Create another WE as shared.
                 *  Stick it onto the list for each waitablevent
                 *  Wait on 'new private fake' enevt (and if it succeeeds, then check orig events and return right now)
                 *  Either way - undo additions
                 *
                 *  <<< @todo DOCUMENT AND EXPLAIN MUTEX >>>
                 */
                shared_ptr<WE_> we  =   make_shared<WE_> (eAutoReset);
                auto&&  cleanup =   Finally (
                [we, waitableEventsStart, waitableEventsEnd] () noexcept {
                    Thread::SuppressInterruptionInContext suppressThreadInterupts;
#if     qCompilerAndStdLib_make_unique_lock_IsSlow
                    MACRO_LOCK_GUARD_CONTEXT (_Stroika_Foundation_Execution_Private_WaitableEvent_ModuleInit_.Actual ().fExtraWaitableEventsMutex_);
#else
                    auto    critSec { make_unique_lock (_Stroika_Foundation_Execution_Private_WaitableEvent_ModuleInit_.Actual ().fExtraWaitableEventsMutex_) };
#endif
                    for (ITERATOR_OF_WAITABLE_EVENTS i = waitableEventsStart; i != waitableEventsEnd; ++i) {
                        (*i)->fExtraWaitableEvents_.remove (we);
                    }
                }
                                    );
                {
#if     qCompilerAndStdLib_make_unique_lock_IsSlow
                    MACRO_LOCK_GUARD_CONTEXT (_Stroika_Foundation_Execution_Private_WaitableEvent_ModuleInit_.Actual ().fExtraWaitableEventsMutex_);
#else
                    auto    critSec { make_unique_lock (_Stroika_Foundation_Execution_Private_WaitableEvent_ModuleInit_.Actual ().fExtraWaitableEventsMutex_) };
#endif
                    for (ITERATOR_OF_WAITABLE_EVENTS i = waitableEventsStart; i != waitableEventsEnd; ++i) {
                        (*i)->fExtraWaitableEvents_.push_front (we);
                    }
                }
                while (true) {
                    we->WaitUntil (timeoutAt);
                    bool anyStillWaiting = false;
                    for (ITERATOR_OF_WAITABLE_EVENTS i = waitableEventsStart; i != waitableEventsEnd; ++i) {
                        WaitableEvent*  we2Test =   *i;
                        RequireNotNull (we2Test);
                        if (not we2Test->fWE_.PeekIsSet ()) {
                            anyStillWaiting = true;
                        }
                    }
                    if (anyStillWaiting) {
                        continue;
                    }
                    else {
                        for (ITERATOR_OF_WAITABLE_EVENTS i = waitableEventsStart; i != waitableEventsEnd; ++i) {
                            WaitableEvent*  we2Test =   *i;
                            RequireNotNull (we2Test);
                            if (we2Test->fWE_.fResetType == eAutoReset) {
                                Assert (we2Test->fWE_.PeekIsSet ());  // we probably need some mechanism to assure this is true but we currently have no enforcement of this!
                                we2Test->fWE_.Reset ();
                            }
                        }
                        return; // success
                    }
                }
            }
#endif

        }
    }
}

#if     qExecution_WaitableEvent_SupportWaitForMultipleObjects
namespace   {
    Stroika::Foundation::Execution::ModuleInitializer<Stroika::Foundation::Execution::Private_::WaitableEvent_ModuleInit_>   _Stroika_Foundation_Execution_Private_WaitableEvent_ModuleInit_;   // this object constructed for the CTOR/DTOR per-module side-effects
}
#endif

#endif  /*_Stroika_Foundation_Execution_WaitableEvent_inl_*/
<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit_training.C $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2017                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */

///
/// @file p9_mss_draminit_training.C
/// @brief Train dram
///
// *HWP HWP Owner: Brian Silver <bsilver@us.ibm.com>
// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 2
// *HWP Consumed by: FSP:HB

#include <fapi2.H>
#include <mss.H>

#include <p9_mss_draminit_training.H>
#include <lib/utils/count_dimm.H>
#include <lib/workarounds/dp16_workarounds.H>
#include <lib/fir/unmask.H>

using fapi2::TARGET_TYPE_MCBIST;
using fapi2::TARGET_TYPE_MCA;

extern "C"
{
    ///
    /// @brief Train dram
    /// @param[in] i_target, the McBIST of the ports of the dram you're training
    /// @param[in] i_special_training, optional CAL_STEP_ENABLE override. Used in sim, debug
    /// @param[in] i_abort_on_error, optional CAL_ABORT_ON_ERROR override. Used in sim, debug
    /// @return FAPI2_RC_SUCCESS iff ok
    ///
    fapi2::ReturnCode p9_mss_draminit_training( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target,
            const uint16_t i_special_training,
            const uint8_t i_abort_on_error)
    {
        // Keep track of the last error seen by a port
        fapi2::ReturnCode l_port_error = fapi2::FAPI2_RC_SUCCESS;
        fapi2::buffer<uint16_t> l_cal_steps_enabled = i_special_training;

        FAPI_INF("Start draminit training");

        // If there are no DIMM we don't need to bother. In fact, we can't as we didn't setup
        // attributes for the PHY, etc.
        if (mss::count_dimm(i_target) == 0)
        {
            FAPI_INF("... skipping draminit_training %s - no DIMM ...", mss::c_str(i_target));
            return fapi2::FAPI2_RC_SUCCESS;
        }

        uint8_t l_reset_disable = 0;
        FAPI_TRY( mss::mrw_reset_delay_before_cal(l_reset_disable) );

        // Configure the CCS engine.
        {
            fapi2::buffer<uint64_t> l_ccs_config;

            FAPI_TRY( mss::ccs::read_mode(i_target, l_ccs_config) );

            // It's unclear if we want to run with this true or false. Right now (10/15) this
            // has to be false. Shelton was unclear if this should be on or off in general BRS
            mss::ccs::stop_on_err(i_target, l_ccs_config, mss::LOW);
            mss::ccs::ue_disable(i_target, l_ccs_config, mss::LOW);
            mss::ccs::copy_cke_to_spare_cke(i_target, l_ccs_config, mss::HIGH);
            mss::ccs::parity_after_cmd(i_target, l_ccs_config, mss::HIGH);

            // Hm. Centaur sets this up for the longest duration possible. Can we do better?
            mss::ccs::cal_count(i_target, l_ccs_config, ~0, ~0);
            FAPI_TRY( mss::ccs::write_mode(i_target, l_ccs_config) );
        }

        // Clean out any previous calibration results, set bad-bits and configure the ranks.
        FAPI_DBG("MCA's on this McBIST: %d", mss::find_targets<TARGET_TYPE_MCA>(i_target).size());

        for( const auto& p : mss::find_targets<TARGET_TYPE_MCA>(i_target))
        {
            // Keep track of the last error seen by a rank pair
            fapi2::ReturnCode l_rank_pair_error = fapi2::FAPI2_RC_SUCCESS;

            mss::ccs::program<TARGET_TYPE_MCBIST, TARGET_TYPE_MCA> l_program;

            // Setup a series of register probes which we'll see during the polling loop
            // Leaving these probes in here as we need them from time to time, but they
            // take up a lot of sim time, so we like to remove them simply

            // Delays in the CCS instruction ARR1 for training are supposed to be 0xFFFF,
            // and we're supposed to poll for the done or timeout bit. But we don't want
            // to wait 0xFFFF cycles before we start polling - that's too long. So we put
            // in a best-guess of how long to wait. This, in a perfect world, would be the
            // time it takes one rank to train one training algorithm times the number of
            // ranks we're going to train. We fail-safe as worst-case we simply poll the
            // register too much - so we can tune this as we learn more.
            l_program.iv_poll.iv_initial_sim_delay = 200;
            l_program.iv_poll.iv_poll_count = 0xFFFF;

            // Returned from set_rank_pairs, it tells us how many rank pairs
            // we configured on this port.
            std::vector<uint64_t> l_pairs;

            FAPI_TRY( mss::putScom(p, MCA_DDRPHY_PC_INIT_CAL_ERROR_P0, 0) );
            FAPI_TRY( mss::putScom(p, MCA_DDRPHY_PC_INIT_CAL_CONFIG0_P0, 0) );

            // Disable port fails as it doesn't appear the MC handles initial cal timeouts
            // correctly (cal_length.) BRS, see conversation with Brad Michael
            FAPI_TRY( mss::change_port_fail_disable(p, mss::ON ) );

            // The following registers must be configured to the correct operating environment:

            // These are reset in phy_scominit
            // Section 5.2.5.10 SEQ ODT Write Configuration {0-3} on page 422
            // Section 5.2.6.1 WC Configuration 0 Register on page 434
            // Section 5.2.6.2 WC Configuration 1 Register on page 436
            // Section 5.2.6.3 WC Configuration 2 Register on page 438

            // Get our rank pairs.
            FAPI_TRY( mss::rank::get_rank_pairs(p, l_pairs) );

            // Setup the config register
            //
            // Grab the attribute which contains the information on what cal steps we should run
            // if the i_specal_training bits have not been specified.
            // TODO RTC:166422 update training code to set cal step enable and consume it everywhere locally
            if (i_special_training == 0)
            {
                FAPI_TRY( mss::cal_step_enable(p, l_cal_steps_enabled) );
            }

            FAPI_DBG("cal steps enabled: 0x%x special training: 0x%x", l_cal_steps_enabled, i_special_training);

            // Check to see if we're supposed to reset the delay values before starting training
            // don't reset if we're running special training - assumes there's a checkpoint which has valid state.
            if ((l_reset_disable == fapi2::ENUM_ATTR_MSS_MRW_RESET_DELAY_BEFORE_CAL_YES) && (i_special_training == 0))
            {
                FAPI_INF("resetting delay values before cal %s", mss::c_str(p));
                FAPI_TRY( mss::dp16::reset_delay_values(p, l_pairs) );
            }

            FAPI_DBG("generating calibration CCS instructions: %d rank-pairs", l_pairs.size());

            // For each rank pair we need to calibrate, pop a ccs instruction in an array and execute it.
            // NOTE: IF YOU CALIBRATE MORE THAN ONE RANK PAIR PER CCS PROGRAM, MAKE SURE TO CHANGE
            // THE PROCESSING OF THE ERRORS. (it's hard to figure out which DIMM failed, too) BRS.
            for (const auto& rp : l_pairs)
            {
                auto l_inst = mss::ccs::initial_cal_command<TARGET_TYPE_MCBIST>(rp);
                uint8_t cal_abort_on_error = i_abort_on_error;

                if (i_abort_on_error == CAL_ABORT_SENTINAL)
                {
                    FAPI_TRY( mss::cal_abort_on_error(cal_abort_on_error) );
                }

                FAPI_DBG("executing training CCS instruction: 0x%llx, 0x%llx", l_inst.arr0, l_inst.arr1);
                l_program.iv_instructions.push_back(l_inst);

                // We need to figure out how long to wait before we start polling. Each cal step has an expected
                // duration, so for each cal step which was enabled, we update the CCS program.
                FAPI_TRY( mss::cal_timer_setup(p, l_program.iv_poll, l_cal_steps_enabled) );
                FAPI_TRY( mss::setup_cal_config(p, rp, l_cal_steps_enabled) );

                // In the event of an init cal hang, CCS_STATQ(2) will assert and CCS_STATQ(3:5) = “001” to indicate a
                // timeout. Otherwise, if calibration completes, FW should inspect DDRPHY_FIR_REG bits (50) and (58)
                // for signs of a calibration error. If either bit is on, then the DDRPHY_PC_INIT_CAL_ERROR register
                // should be polled to determine which calibration step failed.

                // If we got a cal timeout, or another CCS error just leave now. If we got success, check the error
                // bits for a cal failure. We'll return the proper ReturnCode so all we need to do is FAPI_TRY.
                FAPI_TRY( mss::ccs::execute(i_target, l_program, p) );

                // Modifies the training steps, based upon workarounds - adding this here so it always gets run
                FAPI_TRY( mss::workarounds::dp16::modify_calibration_results( p ) );

                // If we're aborting on error we can just FAPI_TRY. If we're not, we don't want to exit if there's
                // an error but we want to log the error and keep on keeping on.
                if ((fapi2::current_err = mss::process_initial_cal_errors(p)) != fapi2::FAPI2_RC_SUCCESS)
                {
                    fapi2::logError(fapi2::current_err);

                    if (cal_abort_on_error)
                    {
                        goto fapi_try_exit;
                    }

                    // Keep tack of the last cal error we saw.
                    l_rank_pair_error = fapi2::current_err;
                }
            }

            // Once we've trained all the rank pairs we can record the bad bits in the attributes if we have an error
            // This error is the most recent error seen on a port, too, so we keep track of that.
            if (l_rank_pair_error != fapi2::FAPI2_RC_SUCCESS)
            {
                FAPI_TRY( mss::dp16::record_bad_bits(p) );
                l_port_error = l_rank_pair_error;
            }
        }

        // So we're calibrated the entire port. If we're here either we didn't have any errors or the last error
        // seen on a port is the error for this entire controller.
        FAPI_TRY(l_port_error, "Seeing port error, exiting training");

        // Unmask FIR
        FAPI_TRY( mss::unmask::after_draminit_training(i_target) );

    fapi_try_exit:
        FAPI_INF("End draminit training");
        return fapi2::current_err;
    }
}
<commit_msg>Set MSS blue waterfall workaround to only run after coarse rd/wr cal step<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit_training.C $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2017                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */

///
/// @file p9_mss_draminit_training.C
/// @brief Train dram
///
// *HWP HWP Owner: Brian Silver <bsilver@us.ibm.com>
// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 2
// *HWP Consumed by: FSP:HB

#include <fapi2.H>
#include <mss.H>

#include <p9_mss_draminit_training.H>
#include <lib/utils/count_dimm.H>
#include <lib/shared/mss_const.H>
#include <lib/workarounds/dp16_workarounds.H>
#include <lib/fir/unmask.H>

using fapi2::TARGET_TYPE_MCBIST;
using fapi2::TARGET_TYPE_MCA;

extern "C"
{
    ///
    /// @brief Train dram
    /// @param[in] i_target, the McBIST of the ports of the dram you're training
    /// @param[in] i_special_training, optional CAL_STEP_ENABLE override. Used in sim, debug
    /// @param[in] i_abort_on_error, optional CAL_ABORT_ON_ERROR override. Used in sim, debug
    /// @return FAPI2_RC_SUCCESS iff ok
    ///
    fapi2::ReturnCode p9_mss_draminit_training( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target,
            const uint16_t i_special_training,
            const uint8_t i_abort_on_error)
    {
        // Keep track of the last error seen by a port
        fapi2::ReturnCode l_port_error = fapi2::FAPI2_RC_SUCCESS;
        fapi2::buffer<uint16_t> l_cal_steps_enabled = i_special_training;

        FAPI_INF("Start draminit training");

        // If there are no DIMM we don't need to bother. In fact, we can't as we didn't setup
        // attributes for the PHY, etc.
        if (mss::count_dimm(i_target) == 0)
        {
            FAPI_INF("... skipping draminit_training %s - no DIMM ...", mss::c_str(i_target));
            return fapi2::FAPI2_RC_SUCCESS;
        }

        uint8_t l_reset_disable = 0;
        FAPI_TRY( mss::mrw_reset_delay_before_cal(l_reset_disable) );

        // Configure the CCS engine.
        {
            fapi2::buffer<uint64_t> l_ccs_config;

            FAPI_TRY( mss::ccs::read_mode(i_target, l_ccs_config) );

            // It's unclear if we want to run with this true or false. Right now (10/15) this
            // has to be false. Shelton was unclear if this should be on or off in general BRS
            mss::ccs::stop_on_err(i_target, l_ccs_config, mss::LOW);
            mss::ccs::ue_disable(i_target, l_ccs_config, mss::LOW);
            mss::ccs::copy_cke_to_spare_cke(i_target, l_ccs_config, mss::HIGH);
            mss::ccs::parity_after_cmd(i_target, l_ccs_config, mss::HIGH);

            // Hm. Centaur sets this up for the longest duration possible. Can we do better?
            mss::ccs::cal_count(i_target, l_ccs_config, ~0, ~0);
            FAPI_TRY( mss::ccs::write_mode(i_target, l_ccs_config) );
        }

        // Clean out any previous calibration results, set bad-bits and configure the ranks.
        FAPI_DBG("MCA's on this McBIST: %d", mss::find_targets<TARGET_TYPE_MCA>(i_target).size());

        for( const auto& p : mss::find_targets<TARGET_TYPE_MCA>(i_target))
        {
            // Keep track of the last error seen by a rank pair
            fapi2::ReturnCode l_rank_pair_error = fapi2::FAPI2_RC_SUCCESS;

            mss::ccs::program<TARGET_TYPE_MCBIST, TARGET_TYPE_MCA> l_program;

            // Setup a series of register probes which we'll see during the polling loop
            // Leaving these probes in here as we need them from time to time, but they
            // take up a lot of sim time, so we like to remove them simply

            // Delays in the CCS instruction ARR1 for training are supposed to be 0xFFFF,
            // and we're supposed to poll for the done or timeout bit. But we don't want
            // to wait 0xFFFF cycles before we start polling - that's too long. So we put
            // in a best-guess of how long to wait. This, in a perfect world, would be the
            // time it takes one rank to train one training algorithm times the number of
            // ranks we're going to train. We fail-safe as worst-case we simply poll the
            // register too much - so we can tune this as we learn more.
            l_program.iv_poll.iv_initial_sim_delay = 200;
            l_program.iv_poll.iv_poll_count = 0xFFFF;

            // Returned from set_rank_pairs, it tells us how many rank pairs
            // we configured on this port.
            std::vector<uint64_t> l_pairs;

            FAPI_TRY( mss::putScom(p, MCA_DDRPHY_PC_INIT_CAL_ERROR_P0, 0) );
            FAPI_TRY( mss::putScom(p, MCA_DDRPHY_PC_INIT_CAL_CONFIG0_P0, 0) );

            // Disable port fails as it doesn't appear the MC handles initial cal timeouts
            // correctly (cal_length.) BRS, see conversation with Brad Michael
            FAPI_TRY( mss::change_port_fail_disable(p, mss::ON ) );

            // The following registers must be configured to the correct operating environment:

            // These are reset in phy_scominit
            // Section 5.2.5.10 SEQ ODT Write Configuration {0-3} on page 422
            // Section 5.2.6.1 WC Configuration 0 Register on page 434
            // Section 5.2.6.2 WC Configuration 1 Register on page 436
            // Section 5.2.6.3 WC Configuration 2 Register on page 438

            // Get our rank pairs.
            FAPI_TRY( mss::rank::get_rank_pairs(p, l_pairs) );

            // Setup the config register
            //
            // Grab the attribute which contains the information on what cal steps we should run
            // if the i_specal_training bits have not been specified.
            // TODO RTC:166422 update training code to set cal step enable and consume it everywhere locally
            if (i_special_training == 0)
            {
                FAPI_TRY( mss::cal_step_enable(p, l_cal_steps_enabled) );
            }

            FAPI_DBG("cal steps enabled: 0x%x special training: 0x%x", l_cal_steps_enabled, i_special_training);

            // Check to see if we're supposed to reset the delay values before starting training
            // don't reset if we're running special training - assumes there's a checkpoint which has valid state.
            if ((l_reset_disable == fapi2::ENUM_ATTR_MSS_MRW_RESET_DELAY_BEFORE_CAL_YES) && (i_special_training == 0))
            {
                FAPI_INF("resetting delay values before cal %s", mss::c_str(p));
                FAPI_TRY( mss::dp16::reset_delay_values(p, l_pairs) );
            }

            FAPI_DBG("generating calibration CCS instructions: %d rank-pairs", l_pairs.size());

            // For each rank pair we need to calibrate, pop a ccs instruction in an array and execute it.
            // NOTE: IF YOU CALIBRATE MORE THAN ONE RANK PAIR PER CCS PROGRAM, MAKE SURE TO CHANGE
            // THE PROCESSING OF THE ERRORS. (it's hard to figure out which DIMM failed, too) BRS.
            for (const auto& rp : l_pairs)
            {
                auto l_inst = mss::ccs::initial_cal_command<TARGET_TYPE_MCBIST>(rp);
                uint8_t cal_abort_on_error = i_abort_on_error;

                if (i_abort_on_error == CAL_ABORT_SENTINAL)
                {
                    FAPI_TRY( mss::cal_abort_on_error(cal_abort_on_error) );
                }

                FAPI_DBG("executing training CCS instruction: 0x%llx, 0x%llx", l_inst.arr0, l_inst.arr1);
                l_program.iv_instructions.push_back(l_inst);

                // We need to figure out how long to wait before we start polling. Each cal step has an expected
                // duration, so for each cal step which was enabled, we update the CCS program.
                FAPI_TRY( mss::cal_timer_setup(p, l_program.iv_poll, l_cal_steps_enabled) );
                FAPI_TRY( mss::setup_cal_config(p, rp, l_cal_steps_enabled) );

                // In the event of an init cal hang, CCS_STATQ(2) will assert and CCS_STATQ(3:5) = “001” to indicate a
                // timeout. Otherwise, if calibration completes, FW should inspect DDRPHY_FIR_REG bits (50) and (58)
                // for signs of a calibration error. If either bit is on, then the DDRPHY_PC_INIT_CAL_ERROR register
                // should be polled to determine which calibration step failed.

                // If we got a cal timeout, or another CCS error just leave now. If we got success, check the error
                // bits for a cal failure. We'll return the proper ReturnCode so all we need to do is FAPI_TRY.
                FAPI_TRY( mss::ccs::execute(i_target, l_program, p) );

                // Modifies the training steps, based upon workarounds - only do this if we've run coarse_rd or coarse_wr
                if (l_cal_steps_enabled.getBit<mss::cal_steps::COARSE_RD>() ||
                    l_cal_steps_enabled.getBit<mss::cal_steps::COARSE_WR>())
                {
                    FAPI_TRY( mss::workarounds::dp16::modify_calibration_results( p ) );
                }

                // If we're aborting on error we can just FAPI_TRY. If we're not, we don't want to exit if there's
                // an error but we want to log the error and keep on keeping on.
                if ((fapi2::current_err = mss::process_initial_cal_errors(p)) != fapi2::FAPI2_RC_SUCCESS)
                {
                    fapi2::logError(fapi2::current_err);

                    if (cal_abort_on_error)
                    {
                        goto fapi_try_exit;
                    }

                    // Keep tack of the last cal error we saw.
                    l_rank_pair_error = fapi2::current_err;
                }
            }

            // Once we've trained all the rank pairs we can record the bad bits in the attributes if we have an error
            // This error is the most recent error seen on a port, too, so we keep track of that.
            if (l_rank_pair_error != fapi2::FAPI2_RC_SUCCESS)
            {
                FAPI_TRY( mss::dp16::record_bad_bits(p) );
                l_port_error = l_rank_pair_error;
            }
        }

        // So we're calibrated the entire port. If we're here either we didn't have any errors or the last error
        // seen on a port is the error for this entire controller.
        FAPI_TRY(l_port_error, "Seeing port error, exiting training");

        // Unmask FIR
        FAPI_TRY( mss::unmask::after_draminit_training(i_target) );

    fapi_try_exit:
        FAPI_INF("End draminit training");
        return fapi2::current_err;
    }
}
<|endoftext|>


<commit_before>
#include <gtest/gtest.h>

#include <boost/any.hpp>

#include "cyclopts/cbc_solver.h"
#include "cyclopts/function.h"
#include "cyclopts/solver.h"
#include "cyclopts/solver_interface.h"
#include "cyclopts/variable.h"

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST(CycloptsCBCSolverTests, 1VarIP) {
  // usings
  using boost::any_cast;
  using cyclus::cyclopts::SolverPtr;
  using cyclus::cyclopts::CBCSolver;
  using cyclus::cyclopts::Constraint;
  using cyclus::cyclopts::ConstraintPtr;
  using cyclus::cyclopts::ObjFuncPtr;
  using cyclus::cyclopts::SolverInterface;
  using cyclus::cyclopts::Variable;
  using cyclus::cyclopts::VariablePtr;
  using cyclus::cyclopts::IntegerVariable;
  using cyclus::cyclopts::ObjectiveFunction;

  // problem instance values
  int x_exp = 1;
  int upper = 1;
  int lower = 0;
  double obj_mod = 1.0;

  // set up solver and interface
  SolverPtr solver(new CBCSolver());
  SolverInterface csi(solver);

  // set up objective function
  ObjFuncPtr obj(new ObjectiveFunction(ObjectiveFunction::MAX));
  csi.RegisterObjFunction(obj);

  // set up variables
  VariablePtr x(new IntegerVariable(lower, upper));
  csi.RegisterVariable(x);

  // objective function
  csi.AddVarToObjFunction(x, obj_mod);

  // solve and get solution
  csi.Solve();

  // check
  EXPECT_EQ(x_exp, any_cast<int>(x->value()));
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST(CycloptsCBCSolverTests, 2VarIP) {
  // usings
  using boost::any_cast;
  using cyclus::cyclopts::SolverPtr;
  using cyclus::cyclopts::CBCSolver;
  using cyclus::cyclopts::Constraint;
  using cyclus::cyclopts::ConstraintPtr;
  using cyclus::cyclopts::ObjFuncPtr;
  using cyclus::cyclopts::SolverInterface;
  using cyclus::cyclopts::Variable;
  using cyclus::cyclopts::VariablePtr;
  using cyclus::cyclopts::IntegerVariable;
  using cyclus::cyclopts::ObjectiveFunction;

  // problem instance values
  int x_exp = 1, y_exp = 2;
  double cap_x = 3.0, cap_y = 10.0, cost_x = 1.0, cost_y = 2.0;
  double unmet_demand = 22.0;

  // set up solver and interface
  SolverPtr solver(new CBCSolver());
  SolverInterface csi(solver);

  // set up objective function
  ObjFuncPtr obj(new ObjectiveFunction(ObjectiveFunction::MIN));
  csi.RegisterObjFunction(obj);

  // set up constraint
  ConstraintPtr c(new Constraint(Constraint::GTEQ, unmet_demand));
  csi.RegisterConstraint(c);

  // set up variables
  VariablePtr x(new IntegerVariable(0, Variable::INF));
  csi.RegisterVariable(x);
  VariablePtr y(new IntegerVariable(0, Variable::INF));
  csi.RegisterVariable(y);

  // configure constraint and objective function
  csi.AddVarToConstraint(x, cap_x, c);
  csi.AddVarToConstraint(y, cap_y, c);
  csi.AddVarToObjFunction(x, cost_x);
  csi.AddVarToObjFunction(y, cost_y);

  // solve and get solution
  csi.Solve();

  // check
  EXPECT_EQ(x_exp, any_cast<int>(x->value()));
  EXPECT_EQ(y_exp, any_cast<int>(y->value()));
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST(CycloptsCBCSolverTests, 2VarIPBounded) {
  // usings
  using boost::any_cast;
  using cyclus::cyclopts::SolverPtr;
  using cyclus::cyclopts::CBCSolver;
  using cyclus::cyclopts::Constraint;
  using cyclus::cyclopts::ConstraintPtr;
  using cyclus::cyclopts::ObjFuncPtr;
  using cyclus::cyclopts::SolverInterface;
  using cyclus::cyclopts::Variable;
  using cyclus::cyclopts::VariablePtr;
  using cyclus::cyclopts::IntegerVariable;
  using cyclus::cyclopts::ObjectiveFunction;

  // problem instance values
  int x_exp = 1, y_exp = 2;
  double cap_x = 3.0, cap_y = 10.0, cost_x = 1.0, cost_y = 2.0;
  double unmet_demand = 22.0;
  int upper = 5;
  int lower = 0;

  // set up solver and interface
  SolverPtr solver(new CBCSolver());
  SolverInterface csi(solver);

  // set up objective function
  ObjFuncPtr obj(new ObjectiveFunction(ObjectiveFunction::MIN));
  csi.RegisterObjFunction(obj);

  // set up constraint
  ConstraintPtr c(new Constraint(Constraint::GTEQ, unmet_demand));
  csi.RegisterConstraint(c);

  // set up variables
  VariablePtr x(new IntegerVariable(lower, upper));
  csi.RegisterVariable(x);
  VariablePtr y(new IntegerVariable(lower, upper));
  csi.RegisterVariable(y);

  // configure constraint and objective function
  csi.AddVarToConstraint(x, cap_x, c);
  csi.AddVarToConstraint(y, cap_y, c);
  csi.AddVarToObjFunction(x, cost_x);
  csi.AddVarToObjFunction(y, cost_y);

  // solve and get solution
  csi.Solve();

  // check
  EXPECT_EQ(x_exp, any_cast<int>(x->value()));
  EXPECT_EQ(y_exp, any_cast<int>(y->value()));
}
<commit_msg>removed bounded 2 variable test, starting simple with 1 variable<commit_after>
#include <gtest/gtest.h>

#include <boost/any.hpp>

#include "CoinModel.hpp"

#include "cyclopts/cbc_solver.h"
#include "cyclopts/function.h"
#include "cyclopts/solver.h"
#include "cyclopts/solver_interface.h"
#include "cyclopts/variable.h"

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST(CycloptsCBCSolverTests, 1VarIPUnbounded) {
  // usings
  using boost::any_cast;
  using cyclus::cyclopts::SolverPtr;
  using cyclus::cyclopts::CBCSolver;
  using cyclus::cyclopts::Constraint;
  using cyclus::cyclopts::ConstraintPtr;
  using cyclus::cyclopts::ObjFuncPtr;
  using cyclus::cyclopts::SolverInterface;
  using cyclus::cyclopts::Variable;
  using cyclus::cyclopts::VariablePtr;
  using cyclus::cyclopts::IntegerVariable;
  using cyclus::cyclopts::ObjectiveFunction;

  // problem instance values
  int x_exp = 0;
  int upper = 1;
  int lower = 0;
  double obj_mod = 1.0;

  // set up solver and interface
  SolverPtr solver(new CBCSolver());
  SolverInterface csi(solver);

  // set up objective function
  ObjFuncPtr obj(new ObjectiveFunction(ObjectiveFunction::MIN));
  csi.RegisterObjFunction(obj);

  // set up variables
  VariablePtr x(new IntegerVariable(lower, Variable::INF));
  csi.RegisterVariable(x);

  // objective function
  csi.AddVarToObjFunction(x, obj_mod);

  // solve and get solution
  csi.Solve();

  // check
  EXPECT_EQ(x_exp, any_cast<int>(x->value()));
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST(CycloptsCBCSolverTests, 2VarIP) {
  // usings
  using boost::any_cast;
  using cyclus::cyclopts::SolverPtr;
  using cyclus::cyclopts::CBCSolver;
  using cyclus::cyclopts::Constraint;
  using cyclus::cyclopts::ConstraintPtr;
  using cyclus::cyclopts::ObjFuncPtr;
  using cyclus::cyclopts::SolverInterface;
  using cyclus::cyclopts::Variable;
  using cyclus::cyclopts::VariablePtr;
  using cyclus::cyclopts::IntegerVariable;
  using cyclus::cyclopts::ObjectiveFunction;

  // problem instance values
  int x_exp = 1, y_exp = 2;
  double cap_x = 3.0, cap_y = 10.0, cost_x = 1.0, cost_y = 2.0;
  double unmet_demand = 22.0;

  // set up solver and interface
  SolverPtr solver(new CBCSolver());
  SolverInterface csi(solver);

  // set up objective function
  ObjFuncPtr obj(new ObjectiveFunction(ObjectiveFunction::MIN));
  csi.RegisterObjFunction(obj);

  // set up constraint
  ConstraintPtr c(new Constraint(Constraint::GTEQ, unmet_demand));
  csi.RegisterConstraint(c);

  // set up variables
  VariablePtr x(new IntegerVariable(0, Variable::INF));
  csi.RegisterVariable(x);
  VariablePtr y(new IntegerVariable(0, Variable::INF));
  csi.RegisterVariable(y);

  // configure constraint and objective function
  csi.AddVarToConstraint(x, cap_x, c);
  csi.AddVarToConstraint(y, cap_y, c);
  csi.AddVarToObjFunction(x, cost_x);
  csi.AddVarToObjFunction(y, cost_y);

  // solve and get solution
  csi.Solve();

  // check
  EXPECT_EQ(x_exp, any_cast<int>(x->value()));
  EXPECT_EQ(y_exp, any_cast<int>(y->value()));
}
<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/nest/p9_chiplet_fabric_scominit.C $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2017                             */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
///
/// @file p9_chiplet_scominit.C
///
/// @brief apply fabric SCOM inits
///

//
// *HWP HW Owner : Joe McGill <jmcgill@us.ibm.com>
// *HWP FW Owner : Thi N. Tran <thi@us.ibm.com>
// *HWP Team : Nest
// *HWP Level : 2
// *HWP Consumed by : HB
//

//------------------------------------------------------------------------------
// Includes
//------------------------------------------------------------------------------
#include <p9_chiplet_fabric_scominit.H>
#include <p9_fbc_no_hp_scom.H>
#include <p9_fbc_ioe_tl_scom.H>
#include <p9_fbc_ioe_dl_scom.H>

#include <p9_xbus_scom_addresses.H>
#include <p9_xbus_scom_addresses_fld.H>
#include <p9_obus_scom_addresses.H>
#include <p9_obus_scom_addresses_fld.H>
#include <p9_misc_scom_addresses.H>
#include <p9_perv_scom_addresses.H>

//------------------------------------------------------------------------------
// Constant definitions
//------------------------------------------------------------------------------
const uint64_t FBC_IOE_TL_FIR_ACTION0 = 0x0000000000000000ULL;
const uint64_t FBC_IOE_TL_FIR_ACTION1 = 0x0000000000000000ULL;
const uint64_t FBC_IOE_TL_FIR_MASK    = 0xFF6DF0303FFFFF1FULL;

const uint64_t FBC_IOE_DL_FIR_ACTION0 = 0x0000000000000000ULL;
const uint64_t FBC_IOE_DL_FIR_ACTION1 = 0x0303C00000001FFCULL;
const uint64_t FBC_IOE_DL_FIR_MASK    = 0xFCFC3FFFFFFFE003ULL;

const uint64_t FBC_IOE_TL_PSAVE_CFG   = 0xF1FF01031C000000ULL;
//------------------------------------------------------------------------------
// Function definitions
//------------------------------------------------------------------------------

fapi2::ReturnCode p9_chiplet_fabric_scominit(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target)
{
    fapi2::ReturnCode l_rc;
    char l_procTargetStr[fapi2::MAX_ECMD_STRING_LEN];
    char l_chipletTargetStr[fapi2::MAX_ECMD_STRING_LEN];
    fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM;
    std::vector<fapi2::Target<fapi2::TARGET_TYPE_XBUS>> l_xbus_chiplets;
    std::vector<fapi2::Target<fapi2::TARGET_TYPE_OBUS>> l_obus_chiplets;

    fapi2::ATTR_PROC_FABRIC_OPTICS_CONFIG_MODE_Type l_fbc_optics_cfg_mode = { fapi2::ENUM_ATTR_PROC_FABRIC_OPTICS_CONFIG_MODE_SMP };
    FAPI_DBG("Start");

    // Get proc target string
    fapi2::toString(i_target, l_procTargetStr, sizeof(l_procTargetStr));

    // apply FBC non-hotplug initfile
    FAPI_DBG("Invoking p9.fbc.no_hp.scom.initfile on target %s...", l_procTargetStr);
    FAPI_EXEC_HWP(l_rc, p9_fbc_no_hp_scom, i_target, FAPI_SYSTEM);

    if (l_rc)
    {
        FAPI_ERR("Error from p9_fbc_no_hp_scom");
        fapi2::current_err = l_rc;
        goto fapi_try_exit;
    }

    // setup IOE (XBUS FBC IO) TL SCOMs
    FAPI_DBG("Invoking p9.fbc.ioe_tl.scom.initfile on target %s...", l_procTargetStr);
    FAPI_EXEC_HWP(l_rc, p9_fbc_ioe_tl_scom, i_target, FAPI_SYSTEM);

    if (l_rc)
    {
        FAPI_ERR("Error from p9_fbc_ioe_tl_scom");
        fapi2::current_err = l_rc;
        goto fapi_try_exit;
    }

    l_xbus_chiplets = i_target.getChildren<fapi2::TARGET_TYPE_XBUS>();

    if (l_xbus_chiplets.size())
    {
        FAPI_TRY(fapi2::putScom(i_target, PU_PB_IOE_FIR_ACTION0_REG, FBC_IOE_TL_FIR_ACTION0),
                 "Error from putScom (PU_PB_IOE_FIR_ACTION0_REG)");
        FAPI_TRY(fapi2::putScom(i_target, PU_PB_IOE_FIR_ACTION1_REG, FBC_IOE_TL_FIR_ACTION1),
                 "Error from putScom (PU_PB_IOE_FIR_ACTION1_REG)");
        FAPI_TRY(fapi2::putScom(i_target, PU_PB_IOE_FIR_MASK_REG, FBC_IOE_TL_FIR_MASK),
                 "Error from putScom (PU_PB_IOE_FIR_MASK_REG)");
    }

    // setup IOE (XBUS FBC IO) DL SCOMs
    for (auto l_iter = l_xbus_chiplets.begin();
         l_iter != l_xbus_chiplets.end();
         l_iter++)
    {
        fapi2::toString(*l_iter, l_chipletTargetStr, sizeof(l_chipletTargetStr));
        FAPI_DBG("Invoking p9.fbc.ioe_dl.scom.initfile on target %s...", l_chipletTargetStr);
        FAPI_EXEC_HWP(l_rc, p9_fbc_ioe_dl_scom, *l_iter, i_target);

        if (l_rc)
        {
            FAPI_ERR("Error from p9_fbc_ioe_dl_scom");
            fapi2::current_err = l_rc;
            goto fapi_try_exit;
        }

        // configure action registers & unmask
        FAPI_TRY(fapi2::putScom(*l_iter, XBUS_LL0_IOEL_FIR_ACTION0_REG, FBC_IOE_DL_FIR_ACTION0),
                 "Error from putScom (XBUS_LL0_IOEL_FIR_ACTION0_REG)");
        FAPI_TRY(fapi2::putScom(*l_iter, XBUS_LL0_IOEL_FIR_ACTION1_REG, FBC_IOE_DL_FIR_ACTION1),
                 "Error from putScom (XBUS_LL0_IOEL_FIR_ACTION1_REG)");
        FAPI_TRY(fapi2::putScom(*l_iter, XBUS_LL0_LL0_LL0_IOEL_FIR_MASK_REG, FBC_IOE_DL_FIR_MASK),
                 "Error from putScom (XBUS_LL0_LL0_LL0_IOEL_FIR_MASK_REG)");
    }

    if (l_xbus_chiplets.size())
    {
        FAPI_TRY(fapi2::putScom(i_target, PU_PB_PSAVE_CFG, FBC_IOE_TL_PSAVE_CFG),
                 "Error from putScom (PU_PB_PSAVE_CFG)");
    }

    // set FBC optics config mode attribute
    l_obus_chiplets = i_target.getChildren<fapi2::TARGET_TYPE_OBUS>();

    for (auto l_iter = l_obus_chiplets.begin();
         l_iter != l_obus_chiplets.end();
         l_iter++)
    {
        uint8_t l_unit_pos;
        FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, *l_iter, l_unit_pos),
                 "Error from FAPI_ATTR_GET(ATTR_CHIP_UNIT_POS)");
        FAPI_INF("Updating index: %d\n", l_unit_pos);
        FAPI_INF("  before: %d\n", l_fbc_optics_cfg_mode[l_unit_pos]);
        FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_OPTICS_CONFIG_MODE, *l_iter, l_fbc_optics_cfg_mode[l_unit_pos]),
                 "Error from FAPI_ATTR_GET(ATTR_OPTICS_CONFIG_MODE)");
        FAPI_INF("  after: %d\n", l_fbc_optics_cfg_mode[l_unit_pos]);
    }

    FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_PROC_FABRIC_OPTICS_CONFIG_MODE, i_target, l_fbc_optics_cfg_mode),
             "Error from FAPI_ATTR_SET(ATTR_PROC_FABRIC_OPTICS_CONFIG_MODE)");

fapi_try_exit:
    FAPI_DBG("End");
    return fapi2::current_err;
}
<commit_msg>Revert enable psave in fabric scominit<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/nest/p9_chiplet_fabric_scominit.C $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2017                             */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
///
/// @file p9_chiplet_scominit.C
///
/// @brief apply fabric SCOM inits
///

//
// *HWP HW Owner : Joe McGill <jmcgill@us.ibm.com>
// *HWP FW Owner : Thi N. Tran <thi@us.ibm.com>
// *HWP Team : Nest
// *HWP Level : 2
// *HWP Consumed by : HB
//

//------------------------------------------------------------------------------
// Includes
//------------------------------------------------------------------------------
#include <p9_chiplet_fabric_scominit.H>
#include <p9_fbc_no_hp_scom.H>
#include <p9_fbc_ioe_tl_scom.H>
#include <p9_fbc_ioe_dl_scom.H>

#include <p9_xbus_scom_addresses.H>
#include <p9_xbus_scom_addresses_fld.H>
#include <p9_obus_scom_addresses.H>
#include <p9_obus_scom_addresses_fld.H>
#include <p9_misc_scom_addresses.H>
#include <p9_perv_scom_addresses.H>

//------------------------------------------------------------------------------
// Constant definitions
//------------------------------------------------------------------------------
const uint64_t FBC_IOE_TL_FIR_ACTION0 = 0x0000000000000000ULL;
const uint64_t FBC_IOE_TL_FIR_ACTION1 = 0x0000000000000000ULL;
const uint64_t FBC_IOE_TL_FIR_MASK    = 0xFF6DF0303FFFFF1FULL;

const uint64_t FBC_IOE_DL_FIR_ACTION0 = 0x0000000000000000ULL;
const uint64_t FBC_IOE_DL_FIR_ACTION1 = 0x0303C00000001FFCULL;
const uint64_t FBC_IOE_DL_FIR_MASK    = 0xFCFC3FFFFFFFE003ULL;

//------------------------------------------------------------------------------
// Function definitions
//------------------------------------------------------------------------------

fapi2::ReturnCode p9_chiplet_fabric_scominit(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target)
{
    fapi2::ReturnCode l_rc;
    char l_procTargetStr[fapi2::MAX_ECMD_STRING_LEN];
    char l_chipletTargetStr[fapi2::MAX_ECMD_STRING_LEN];
    fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM;
    std::vector<fapi2::Target<fapi2::TARGET_TYPE_XBUS>> l_xbus_chiplets;
    std::vector<fapi2::Target<fapi2::TARGET_TYPE_OBUS>> l_obus_chiplets;

    fapi2::ATTR_PROC_FABRIC_OPTICS_CONFIG_MODE_Type l_fbc_optics_cfg_mode = { fapi2::ENUM_ATTR_PROC_FABRIC_OPTICS_CONFIG_MODE_SMP };
    FAPI_DBG("Start");

    // Get proc target string
    fapi2::toString(i_target, l_procTargetStr, sizeof(l_procTargetStr));

    // apply FBC non-hotplug initfile
    FAPI_DBG("Invoking p9.fbc.no_hp.scom.initfile on target %s...", l_procTargetStr);
    FAPI_EXEC_HWP(l_rc, p9_fbc_no_hp_scom, i_target, FAPI_SYSTEM);

    if (l_rc)
    {
        FAPI_ERR("Error from p9_fbc_no_hp_scom");
        fapi2::current_err = l_rc;
        goto fapi_try_exit;
    }

    // setup IOE (XBUS FBC IO) TL SCOMs
    FAPI_DBG("Invoking p9.fbc.ioe_tl.scom.initfile on target %s...", l_procTargetStr);
    FAPI_EXEC_HWP(l_rc, p9_fbc_ioe_tl_scom, i_target, FAPI_SYSTEM);

    if (l_rc)
    {
        FAPI_ERR("Error from p9_fbc_ioe_tl_scom");
        fapi2::current_err = l_rc;
        goto fapi_try_exit;
    }

    l_xbus_chiplets = i_target.getChildren<fapi2::TARGET_TYPE_XBUS>();

    if (l_xbus_chiplets.size())
    {
        FAPI_TRY(fapi2::putScom(i_target, PU_PB_IOE_FIR_ACTION0_REG, FBC_IOE_TL_FIR_ACTION0),
                 "Error from putScom (PU_PB_IOE_FIR_ACTION0_REG)");
        FAPI_TRY(fapi2::putScom(i_target, PU_PB_IOE_FIR_ACTION1_REG, FBC_IOE_TL_FIR_ACTION1),
                 "Error from putScom (PU_PB_IOE_FIR_ACTION1_REG)");
        FAPI_TRY(fapi2::putScom(i_target, PU_PB_IOE_FIR_MASK_REG, FBC_IOE_TL_FIR_MASK),
                 "Error from putScom (PU_PB_IOE_FIR_MASK_REG)");
    }

    // setup IOE (XBUS FBC IO) DL SCOMs
    for (auto l_iter = l_xbus_chiplets.begin();
         l_iter != l_xbus_chiplets.end();
         l_iter++)
    {
        fapi2::toString(*l_iter, l_chipletTargetStr, sizeof(l_chipletTargetStr));
        FAPI_DBG("Invoking p9.fbc.ioe_dl.scom.initfile on target %s...", l_chipletTargetStr);
        FAPI_EXEC_HWP(l_rc, p9_fbc_ioe_dl_scom, *l_iter, i_target);

        if (l_rc)
        {
            FAPI_ERR("Error from p9_fbc_ioe_dl_scom");
            fapi2::current_err = l_rc;
            goto fapi_try_exit;
        }

        // configure action registers & unmask
        FAPI_TRY(fapi2::putScom(*l_iter, XBUS_LL0_IOEL_FIR_ACTION0_REG, FBC_IOE_DL_FIR_ACTION0),
                 "Error from putScom (XBUS_LL0_IOEL_FIR_ACTION0_REG)");
        FAPI_TRY(fapi2::putScom(*l_iter, XBUS_LL0_IOEL_FIR_ACTION1_REG, FBC_IOE_DL_FIR_ACTION1),
                 "Error from putScom (XBUS_LL0_IOEL_FIR_ACTION1_REG)");
        FAPI_TRY(fapi2::putScom(*l_iter, XBUS_LL0_LL0_LL0_IOEL_FIR_MASK_REG, FBC_IOE_DL_FIR_MASK),
                 "Error from putScom (XBUS_LL0_LL0_LL0_IOEL_FIR_MASK_REG)");
    }

    // set FBC optics config mode attribute
    l_obus_chiplets = i_target.getChildren<fapi2::TARGET_TYPE_OBUS>();

    for (auto l_iter = l_obus_chiplets.begin();
         l_iter != l_obus_chiplets.end();
         l_iter++)
    {
        uint8_t l_unit_pos;
        FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, *l_iter, l_unit_pos),
                 "Error from FAPI_ATTR_GET(ATTR_CHIP_UNIT_POS)");
        FAPI_INF("Updating index: %d\n", l_unit_pos);
        FAPI_INF("  before: %d\n", l_fbc_optics_cfg_mode[l_unit_pos]);
        FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_OPTICS_CONFIG_MODE, *l_iter, l_fbc_optics_cfg_mode[l_unit_pos]),
                 "Error from FAPI_ATTR_GET(ATTR_OPTICS_CONFIG_MODE)");
        FAPI_INF("  after: %d\n", l_fbc_optics_cfg_mode[l_unit_pos]);
    }

    FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_PROC_FABRIC_OPTICS_CONFIG_MODE, i_target, l_fbc_optics_cfg_mode),
             "Error from FAPI_ATTR_SET(ATTR_PROC_FABRIC_OPTICS_CONFIG_MODE)");

fapi_try_exit:
    FAPI_DBG("End");
    return fapi2::current_err;
}
<|endoftext|>


<commit_before>/*
 *  mitkFiberBundleMapper2D.cpp
 *  mitk-all
 *
 *  Created by HAL9000 on 1/17/11.
 *  Copyright 2011 __MyCompanyName__. All rights reserved.
 *
 */

#include "mitkFiberBundleMapper2D.h"
#include <mitkBaseRenderer.h>
#include "mitkFiberBundleMapper3D.h"

#include <vtkActor.h>
#include <vtkPolyDataMapper.h>
#include <vtkPlane.h>
#include <vtkPolyData.h>
//#include <vtkPropAssembly.h>

//#include <vtkPainterPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkLookupTable.h>
#include <vtkPoints.h>
#include <vtkCamera.h>
#include <vtkPolyLine.h>
#include <vtkRenderer.h>
#include <vtkCellArray.h>
#include <vtkMatrix4x4.h>

//#include <mitkGeometry3D.h>
#include <mitkPlaneGeometry.h>
#include <mitkSliceNavigationController.h>

#include <mitkShaderRepository.h>
#include <mitkShaderProperty.h>
#include <mitkStandardFileLocations.h>

#include <QCoreApplication>

mitk::FiberBundleMapper2D::FiberBundleMapper2D()
{

}

mitk::FiberBundleMapper2D::~FiberBundleMapper2D()
{
}

const mitk::FiberBundle* mitk::FiberBundleMapper2D::GetInput()
{
    return dynamic_cast<const mitk::FiberBundle * > ( GetData() );
}

void mitk::FiberBundleMapper2D::Update(mitk::BaseRenderer * renderer)
{

    if ( !this->IsVisible( renderer ) )
    {
        return;
    }

    // Calculate time step of the input data for the specified renderer (integer value)
    // this method is implemented in mitkMapper
    this->CalculateTimeStep( renderer );

    //check if updates occured in the node or on the display
    FBLocalStorage *localStorage = m_LSH.GetLocalStorage(renderer);
    const DataNode *node = this->GetDataNode();
    if ( (localStorage->m_LastUpdateTime < node->GetMTime())
         || (localStorage->m_LastUpdateTime < node->GetPropertyList()->GetMTime()) //was a property modified?
         || (localStorage->m_LastUpdateTime < node->GetPropertyList(renderer)->GetMTime()) )
    {
        //    MITK_INFO << "UPDATE NEEDED FOR _ " << renderer->GetName();
        this->GenerateDataForRenderer( renderer );
    }

    if ((localStorage->m_LastUpdateTime < renderer->GetDisplayGeometry()->GetMTime()) ) //was the display geometry modified? e.g. zooming, panning)
    {

        this->UpdateShaderParameter(renderer);

    }

}

void mitk::FiberBundleMapper2D::UpdateShaderParameter(mitk::BaseRenderer * renderer)
{
    FBLocalStorage *localStorage = m_LSH.GetLocalStorage(renderer);
    // MITK_INFO << "uSERWAAAAAAAS, da shader brauchat a poor neue zoin";
    //get information about current position of views
    mitk::SliceNavigationController::Pointer sliceContr = renderer->GetSliceNavigationController();
    mitk::PlaneGeometry::ConstPointer planeGeo = sliceContr->GetCurrentPlaneGeometry();

    //generate according cutting planes based on the view position
    float sliceN[3], planeOrigin[3];

    // since shader uses camera coordinates, transform origin and normal from worldcoordinates to cameracoordinates

    planeOrigin[0] = (float) planeGeo->GetOrigin()[0];
    planeOrigin[1] = (float) planeGeo->GetOrigin()[1];
    planeOrigin[2] = (float) planeGeo->GetOrigin()[2];

    sliceN[0] = planeGeo->GetNormal()[0];
    sliceN[1] = planeGeo->GetNormal()[1];
    sliceN[2] = planeGeo->GetNormal()[2];

    float tmp1 = planeOrigin[0] * sliceN[0];
    float tmp2 = planeOrigin[1] * sliceN[1];
    float tmp3 = planeOrigin[2] * sliceN[2];
    float d1 = tmp1 + tmp2 + tmp3; //attention, correct normalvector

    float plane1[4];
    plane1[0] = sliceN[0];
    plane1[1] = sliceN[1];
    plane1[2] = sliceN[2];
    plane1[3] = d1;

    float thickness = 2.0;
    if(!this->GetDataNode()->GetPropertyValue("Fiber2DSliceThickness",thickness))
        MITK_INFO << "FIBER2D SLICE THICKNESS PROPERTY ERROR";

    bool fiberfading = false;
    if(!this->GetDataNode()->GetPropertyValue("Fiber2DfadeEFX",fiberfading))
        MITK_INFO << "FIBER2D SLICE FADE EFX PROPERTY ERROR";

    int fiberfading_i = 1;
    if (!fiberfading)
        fiberfading_i = 0;

    localStorage->m_PointActor->GetProperty()->AddShaderVariable("slicingPlane",4, plane1);
    localStorage->m_PointActor->GetProperty()->AddShaderVariable("fiberThickness",1, &thickness);
    localStorage->m_PointActor->GetProperty()->AddShaderVariable("fiberFadingON",1,  &fiberfading_i);

}

// ALL RAW DATA FOR VISUALIZATION IS GENERATED HERE.
// vtkActors and Mappers are feeded here
void mitk::FiberBundleMapper2D::GenerateDataForRenderer(mitk::BaseRenderer *renderer)
{

    //the handler of local storage gets feeded in this method with requested data for related renderwindow
    FBLocalStorage *localStorage = m_LSH.GetLocalStorage(renderer);

    //this procedure is depricated,
    //not needed after initializaton anymore
    mitk::DataNode* node = this->GetDataNode();
    if ( node == NULL )
    {
        MITK_INFO << "check DATANODE: ....[Fail] ";
        return;
    }
    ///////////////////////////////////

    mitk::FiberBundleMapper3D::Pointer FBMapper3D = dynamic_cast< mitk::FiberBundleMapper3D* > (node->GetMapper( 2 ));
    if ( FBMapper3D->GetInput() == NULL )
    {
        MITK_INFO << "check FBMapper3D Input: ....[Fail] ";
        return;
    }

    //feed local storage with data we want to visualize
    //  localStorage->m_SlicedResult = FBMapper3D->GetCut(planeOrigin, planeN, cutParams);
    // localStorage->m_SlicedResult = FBMapper3D->GetVtkFBPolyDataMapper();
    localStorage->m_SlicedResult = (vtkPolyData*) FBMapper3D->getVtkFiberBundleMapper()->GetInputAsDataSet();
    //MITK_INFO << renderer->GetName() << " OutputPoints#: " << localStorage->m_SlicedResult->GetNumberOfPoints();

    vtkSmartPointer<vtkLookupTable> lut = vtkLookupTable::New();
    lut->Build();
    localStorage->m_PointMapper->SetScalarModeToUsePointFieldData();
    //m_VtkFiberDataMapperGL->SelectColorArray("FaColors");
    localStorage->m_PointMapper->SelectColorArray("ColorValues");
    localStorage->m_PointMapper->SetLookupTable(lut);  //apply the properties after the slice was set
    //this->ApplyProperties( renderer );

    //setup the camera according to the actor with zooming/panning etc.
    // this->AdjustCamera( renderer, planeGeo );

    //  feed the vtk fiber mapper with point data ...TODO do in constructor
    localStorage->m_PointMapper->SetInput(localStorage->m_SlicedResult);   // in optimized version, mapper is feeded by localStorage->m_cutter->GetOutput();
    localStorage->m_PointActor->SetMapper(localStorage->m_PointMapper);
    localStorage->m_PointActor->GetProperty()->ShadingOn();

    // Applying shading properties
    {
        //Superclass::ApplyProperties( ls->m_Actor, renderer ) ;
        // VTK Properties
        //ApplyMitkPropertiesToVtkProperty( this->GetDataNode(), ls->m_Actor->GetProperty(), renderer );
        // Shaders
        mitk::ShaderRepository::GetGlobalShaderRepository()->ApplyProperties(this->GetDataNode(),localStorage->m_PointActor,renderer, localStorage->m_LastUpdateTime);
    }

    this->UpdateShaderParameter(renderer);

    // We have been modified => save this for next Update()
    localStorage->m_LastUpdateTime.Modified();

}

vtkProp* mitk::FiberBundleMapper2D::GetVtkProp(mitk::BaseRenderer *renderer)
{

    //MITK_INFO << "FiberBundleMapper2D GetVtkProp(renderer)";
    this->Update(renderer);
    return m_LSH.GetLocalStorage(renderer)->m_PointActor;

}

void mitk::FiberBundleMapper2D::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite)
{    //add shader to datano

    //####### load shader from file #########
    QString applicationDir = QCoreApplication::applicationDirPath();
    MITK_INFO << "pathAppdir: " << QCoreApplication::applicationDirPath().toStdString().c_str();
    applicationDir.append("/"); //directory to look when building installer

    mitk::StandardFileLocations::GetInstance()->AddDirectoryForSearch( applicationDir.toStdString().c_str(), false );
    mitk::ShaderRepository::Pointer shaderRepository = mitk::ShaderRepository::GetGlobalShaderRepository();

    std::string filepath = mitk::StandardFileLocations::GetInstance()->FindFile("mitkShaderFiberClipping.xml");
    if ( filepath.empty() )
    {
        applicationDir = QCoreApplication::applicationDirPath();
        applicationDir.append("/../../"); //directory to look when developing in MITK
        mitk::StandardFileLocations::GetInstance()->AddDirectoryForSearch( applicationDir.toStdString().c_str(), false );
        filepath = mitk::StandardFileLocations::GetInstance()->FindFile("mitkShaderFiberClipping.xml");

        if ( filepath.empty() )
        { //for windows systems
            applicationDir = QCoreApplication::applicationDirPath();
            applicationDir.append("\\..\\");
            mitk::StandardFileLocations::GetInstance()->AddDirectoryForSearch( applicationDir.toStdString().c_str(), false );

        }

    }

    shaderRepository->LoadShader(mitk::StandardFileLocations::GetInstance()->FindFile("mitkShaderFiberClipping.xml"));

    //####################################################################
    node->SetProperty("shader",mitk::ShaderProperty::New("mitkShaderFiberClipping"));
    mitk::ShaderRepository::GetGlobalShaderRepository()->AddDefaultProperties(node,renderer,overwrite);

    //add other parameters to propertylist
    node->AddProperty( "Fiber2DSliceThickness", mitk::FloatProperty::New(2.0f), renderer, overwrite );
    node->AddProperty( "Fiber2DfadeEFX", mitk::BoolProperty::New(true), renderer, overwrite );

    Superclass::SetDefaultProperties(node, renderer, overwrite);
}

// following methods are essential, they actually call the GetVtkProp() method
// which returns the desired actors
void mitk::FiberBundleMapper2D::MitkRenderOverlay(BaseRenderer* renderer)
{
    //   MITK_INFO << "FiberBundleMapper2D MitkRenderOVerlay(renderer)";
    if ( this->IsVisible(renderer)==false )
        return;

    if ( this->GetVtkProp(renderer)->GetVisibility() )
    {
        this->GetVtkProp(renderer)->RenderOverlay(renderer->GetVtkRenderer());
    }
}

void mitk::FiberBundleMapper2D::MitkRenderOpaqueGeometry(BaseRenderer* renderer)
{
    //  MITK_INFO << "FiberBundleMapper2D MitkRenderOpaqueGeometry(renderer)";
    if ( this->IsVisible( renderer )==false )
        return;

    if ( this->GetVtkProp(renderer)->GetVisibility() )
        this->GetVtkProp(renderer)->RenderOpaqueGeometry( renderer->GetVtkRenderer() );
}
void mitk::FiberBundleMapper2D::MitkRenderTranslucentGeometry(BaseRenderer* renderer)
{
    //  MITK_INFO << "FiberBundleMapper2D MitkRenderTranslucentGeometry(renderer)";
    if ( this->IsVisible(renderer)==false )
        return;

    //TODO is it possible to have a visible BaseRenderer AND an invisible VtkRenderer???
    if ( this->GetVtkProp(renderer)->GetVisibility() )
        this->GetVtkProp(renderer)->RenderTranslucentPolygonalGeometry(renderer->GetVtkRenderer());

}
void mitk::FiberBundleMapper2D::MitkRenderVolumetricGeometry(BaseRenderer* renderer)
{
    //  MITK_INFO << "FiberBundleMapper2D MitkRenderVolumentricGeometry(renderer)";
    if(IsVisible(renderer)==false)
        return;

    //TODO is it possible to have a visible BaseRenderer AND an invisible VtkRenderer???
    if ( GetVtkProp(renderer)->GetVisibility() )
        this->GetVtkProp(renderer)->RenderVolumetricGeometry(renderer->GetVtkRenderer());

}

mitk::FiberBundleMapper2D::FBLocalStorage::FBLocalStorage()
{
    m_PointActor = vtkSmartPointer<vtkActor>::New();
    m_PointMapper = vtkSmartPointer<vtkPolyDataMapper>::New();

}
<commit_msg>fix installer n developer path<commit_after>/*
 *  mitkFiberBundleMapper2D.cpp
 *  mitk-all
 *
 *  Created by HAL9000 on 1/17/11.
 *  Copyright 2011 __MyCompanyName__. All rights reserved.
 *
 */

#include "mitkFiberBundleMapper2D.h"
#include <mitkBaseRenderer.h>
#include "mitkFiberBundleMapper3D.h"

#include <vtkActor.h>
#include <vtkPolyDataMapper.h>
#include <vtkPlane.h>
#include <vtkPolyData.h>
//#include <vtkPropAssembly.h>

//#include <vtkPainterPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkLookupTable.h>
#include <vtkPoints.h>
#include <vtkCamera.h>
#include <vtkPolyLine.h>
#include <vtkRenderer.h>
#include <vtkCellArray.h>
#include <vtkMatrix4x4.h>

//#include <mitkGeometry3D.h>
#include <mitkPlaneGeometry.h>
#include <mitkSliceNavigationController.h>

#include <mitkShaderRepository.h>
#include <mitkShaderProperty.h>
#include <mitkStandardFileLocations.h>

#include <QCoreApplication>
#include <QFile>

mitk::FiberBundleMapper2D::FiberBundleMapper2D()
{

}

mitk::FiberBundleMapper2D::~FiberBundleMapper2D()
{
}

const mitk::FiberBundle* mitk::FiberBundleMapper2D::GetInput()
{
    return dynamic_cast<const mitk::FiberBundle * > ( GetData() );
}

void mitk::FiberBundleMapper2D::Update(mitk::BaseRenderer * renderer)
{

    if ( !this->IsVisible( renderer ) )
    {
        return;
    }

    // Calculate time step of the input data for the specified renderer (integer value)
    // this method is implemented in mitkMapper
    this->CalculateTimeStep( renderer );

    //check if updates occured in the node or on the display
    FBLocalStorage *localStorage = m_LSH.GetLocalStorage(renderer);
    const DataNode *node = this->GetDataNode();
    if ( (localStorage->m_LastUpdateTime < node->GetMTime())
         || (localStorage->m_LastUpdateTime < node->GetPropertyList()->GetMTime()) //was a property modified?
         || (localStorage->m_LastUpdateTime < node->GetPropertyList(renderer)->GetMTime()) )
    {
        //    MITK_INFO << "UPDATE NEEDED FOR _ " << renderer->GetName();
        this->GenerateDataForRenderer( renderer );
    }

    if ((localStorage->m_LastUpdateTime < renderer->GetDisplayGeometry()->GetMTime()) ) //was the display geometry modified? e.g. zooming, panning)
    {

        this->UpdateShaderParameter(renderer);

    }

}

void mitk::FiberBundleMapper2D::UpdateShaderParameter(mitk::BaseRenderer * renderer)
{
    FBLocalStorage *localStorage = m_LSH.GetLocalStorage(renderer);
    // MITK_INFO << "uSERWAAAAAAAS, da shader brauchat a poor neue zoin";
    //get information about current position of views
    mitk::SliceNavigationController::Pointer sliceContr = renderer->GetSliceNavigationController();
    mitk::PlaneGeometry::ConstPointer planeGeo = sliceContr->GetCurrentPlaneGeometry();

    //generate according cutting planes based on the view position
    float sliceN[3], planeOrigin[3];

    // since shader uses camera coordinates, transform origin and normal from worldcoordinates to cameracoordinates

    planeOrigin[0] = (float) planeGeo->GetOrigin()[0];
    planeOrigin[1] = (float) planeGeo->GetOrigin()[1];
    planeOrigin[2] = (float) planeGeo->GetOrigin()[2];

    sliceN[0] = planeGeo->GetNormal()[0];
    sliceN[1] = planeGeo->GetNormal()[1];
    sliceN[2] = planeGeo->GetNormal()[2];

    float tmp1 = planeOrigin[0] * sliceN[0];
    float tmp2 = planeOrigin[1] * sliceN[1];
    float tmp3 = planeOrigin[2] * sliceN[2];
    float d1 = tmp1 + tmp2 + tmp3; //attention, correct normalvector

    float plane1[4];
    plane1[0] = sliceN[0];
    plane1[1] = sliceN[1];
    plane1[2] = sliceN[2];
    plane1[3] = d1;

    float thickness = 2.0;
    if(!this->GetDataNode()->GetPropertyValue("Fiber2DSliceThickness",thickness))
        MITK_INFO << "FIBER2D SLICE THICKNESS PROPERTY ERROR";

    bool fiberfading = false;
    if(!this->GetDataNode()->GetPropertyValue("Fiber2DfadeEFX",fiberfading))
        MITK_INFO << "FIBER2D SLICE FADE EFX PROPERTY ERROR";

    int fiberfading_i = 1;
    if (!fiberfading)
        fiberfading_i = 0;

    localStorage->m_PointActor->GetProperty()->AddShaderVariable("slicingPlane",4, plane1);
    localStorage->m_PointActor->GetProperty()->AddShaderVariable("fiberThickness",1, &thickness);
    localStorage->m_PointActor->GetProperty()->AddShaderVariable("fiberFadingON",1,  &fiberfading_i);

}

// ALL RAW DATA FOR VISUALIZATION IS GENERATED HERE.
// vtkActors and Mappers are feeded here
void mitk::FiberBundleMapper2D::GenerateDataForRenderer(mitk::BaseRenderer *renderer)
{

    //the handler of local storage gets feeded in this method with requested data for related renderwindow
    FBLocalStorage *localStorage = m_LSH.GetLocalStorage(renderer);

    //this procedure is depricated,
    //not needed after initializaton anymore
    mitk::DataNode* node = this->GetDataNode();
    if ( node == NULL )
    {
        MITK_INFO << "check DATANODE: ....[Fail] ";
        return;
    }
    ///////////////////////////////////

    mitk::FiberBundleMapper3D::Pointer FBMapper3D = dynamic_cast< mitk::FiberBundleMapper3D* > (node->GetMapper( 2 ));
    if ( FBMapper3D->GetInput() == NULL )
    {
        MITK_INFO << "check FBMapper3D Input: ....[Fail] ";
        return;
    }

    //feed local storage with data we want to visualize
    //  localStorage->m_SlicedResult = FBMapper3D->GetCut(planeOrigin, planeN, cutParams);
    // localStorage->m_SlicedResult = FBMapper3D->GetVtkFBPolyDataMapper();
    localStorage->m_SlicedResult = (vtkPolyData*) FBMapper3D->getVtkFiberBundleMapper()->GetInputAsDataSet();
    //MITK_INFO << renderer->GetName() << " OutputPoints#: " << localStorage->m_SlicedResult->GetNumberOfPoints();

    vtkSmartPointer<vtkLookupTable> lut = vtkLookupTable::New();
    lut->Build();
    localStorage->m_PointMapper->SetScalarModeToUsePointFieldData();
    //m_VtkFiberDataMapperGL->SelectColorArray("FaColors");
    localStorage->m_PointMapper->SelectColorArray("ColorValues");
    localStorage->m_PointMapper->SetLookupTable(lut);  //apply the properties after the slice was set
    //this->ApplyProperties( renderer );

    //setup the camera according to the actor with zooming/panning etc.
    // this->AdjustCamera( renderer, planeGeo );

    //  feed the vtk fiber mapper with point data ...TODO do in constructor
    localStorage->m_PointMapper->SetInput(localStorage->m_SlicedResult);   // in optimized version, mapper is feeded by localStorage->m_cutter->GetOutput();
    localStorage->m_PointActor->SetMapper(localStorage->m_PointMapper);
    localStorage->m_PointActor->GetProperty()->ShadingOn();

    // Applying shading properties
    {
        //Superclass::ApplyProperties( ls->m_Actor, renderer ) ;
        // VTK Properties
        //ApplyMitkPropertiesToVtkProperty( this->GetDataNode(), ls->m_Actor->GetProperty(), renderer );
        // Shaders
        mitk::ShaderRepository::GetGlobalShaderRepository()->ApplyProperties(this->GetDataNode(),localStorage->m_PointActor,renderer, localStorage->m_LastUpdateTime);
    }

    this->UpdateShaderParameter(renderer);

    // We have been modified => save this for next Update()
    localStorage->m_LastUpdateTime.Modified();

}

vtkProp* mitk::FiberBundleMapper2D::GetVtkProp(mitk::BaseRenderer *renderer)
{

    //MITK_INFO << "FiberBundleMapper2D GetVtkProp(renderer)";
    this->Update(renderer);
    return m_LSH.GetLocalStorage(renderer)->m_PointActor;

}

void mitk::FiberBundleMapper2D::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite)
{    //add shader to datano

    //####### load shader from file #########
    QString applicationDir = QCoreApplication::applicationDirPath();
    MITK_INFO << "pathAppdir: " << QCoreApplication::applicationDirPath().toStdString().c_str();

    if (applicationDir.endsWith("bin"))
        applicationDir.append("/");
    else if (applicationDir.endsWith("MacOS"))
    {
        //on osx, check if path for installer or MITK development is needed
        applicationDir.append("/");
        QFile f( applicationDir+"FiberTrackingLUTBaryCoords.bin" );
        if( !f.exists() ) // if file does not exist, then look in MITK development build directory
            applicationDir.append("../../../");
    }else
        applicationDir.append("\\..\\");

//    applicationDir.append("/"); //directory to look when building installer

    mitk::StandardFileLocations::GetInstance()->AddDirectoryForSearch( applicationDir.toStdString().c_str(), false );
    mitk::ShaderRepository::Pointer shaderRepository = mitk::ShaderRepository::GetGlobalShaderRepository();

//    std::string filepath = mitk::StandardFileLocations::GetInstance()->FindFile("mitkShaderFiberClipping.xml");
//    if ( filepath.empty() )
//    {
//        applicationDir = QCoreApplication::applicationDirPath();
//        applicationDir.append("/../../"); //directory to look when developing in MITK
//        mitk::StandardFileLocations::GetInstance()->AddDirectoryForSearch( applicationDir.toStdString().c_str(), false );
//        filepath = mitk::StandardFileLocations::GetInstance()->FindFile("mitkShaderFiberClipping.xml");

//        if ( filepath.empty() )
//        { //for windows systems
//            applicationDir = QCoreApplication::applicationDirPath();
//            applicationDir.append("\\..\\");
//            mitk::StandardFileLocations::GetInstance()->AddDirectoryForSearch( applicationDir.toStdString().c_str(), false );

//        }

//    }

    shaderRepository->LoadShader(mitk::StandardFileLocations::GetInstance()->FindFile("mitkShaderFiberClipping.xml"));

    //####################################################################
    node->SetProperty("shader",mitk::ShaderProperty::New("mitkShaderFiberClipping"));
    mitk::ShaderRepository::GetGlobalShaderRepository()->AddDefaultProperties(node,renderer,overwrite);

    //add other parameters to propertylist
    node->AddProperty( "Fiber2DSliceThickness", mitk::FloatProperty::New(2.0f), renderer, overwrite );
    node->AddProperty( "Fiber2DfadeEFX", mitk::BoolProperty::New(true), renderer, overwrite );

    Superclass::SetDefaultProperties(node, renderer, overwrite);
}

// following methods are essential, they actually call the GetVtkProp() method
// which returns the desired actors
void mitk::FiberBundleMapper2D::MitkRenderOverlay(BaseRenderer* renderer)
{
    //   MITK_INFO << "FiberBundleMapper2D MitkRenderOVerlay(renderer)";
    if ( this->IsVisible(renderer)==false )
        return;

    if ( this->GetVtkProp(renderer)->GetVisibility() )
    {
        this->GetVtkProp(renderer)->RenderOverlay(renderer->GetVtkRenderer());
    }
}

void mitk::FiberBundleMapper2D::MitkRenderOpaqueGeometry(BaseRenderer* renderer)
{
    //  MITK_INFO << "FiberBundleMapper2D MitkRenderOpaqueGeometry(renderer)";
    if ( this->IsVisible( renderer )==false )
        return;

    if ( this->GetVtkProp(renderer)->GetVisibility() )
        this->GetVtkProp(renderer)->RenderOpaqueGeometry( renderer->GetVtkRenderer() );
}
void mitk::FiberBundleMapper2D::MitkRenderTranslucentGeometry(BaseRenderer* renderer)
{
    //  MITK_INFO << "FiberBundleMapper2D MitkRenderTranslucentGeometry(renderer)";
    if ( this->IsVisible(renderer)==false )
        return;

    //TODO is it possible to have a visible BaseRenderer AND an invisible VtkRenderer???
    if ( this->GetVtkProp(renderer)->GetVisibility() )
        this->GetVtkProp(renderer)->RenderTranslucentPolygonalGeometry(renderer->GetVtkRenderer());

}
void mitk::FiberBundleMapper2D::MitkRenderVolumetricGeometry(BaseRenderer* renderer)
{
    //  MITK_INFO << "FiberBundleMapper2D MitkRenderVolumentricGeometry(renderer)";
    if(IsVisible(renderer)==false)
        return;

    //TODO is it possible to have a visible BaseRenderer AND an invisible VtkRenderer???
    if ( GetVtkProp(renderer)->GetVisibility() )
        this->GetVtkProp(renderer)->RenderVolumetricGeometry(renderer->GetVtkRenderer());

}

mitk::FiberBundleMapper2D::FBLocalStorage::FBLocalStorage()
{
    m_PointActor = vtkSmartPointer<vtkActor>::New();
    m_PointMapper = vtkSmartPointer<vtkPolyDataMapper>::New();

}
<|endoftext|>