1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     os_ContinuationIterator.h
4   Copyright (C)2009 Nintendo Co., Ltd.  All rights reserved.
5   These coded instructions, statements, and computer programs contain
6   proprietary information of Nintendo of America Inc. and/or Nintendo
7   Company Ltd., and are protected by Federal copyright law. They may
8   not be disclosed to third parties or copied or duplicated in any form,
9   in whole or in part, without the prior written consent of Nintendo.
10   $Rev: 20477 $
11  *---------------------------------------------------------------------------
12 
13 
14 */
15 
16 
17 #ifndef NN_OS_OS_CONTINUATIONITERATOR_H_
18 #define NN_OS_OS_CONTINUATIONITERATOR_H_
19 
20 #ifdef __cplusplus
21 
22 #include <nn.h>
23 #include <nn/Result.h>
24 #include <nn/WithInitialize.h>
25 #include <csetjmp>
26 
27 namespace nn { namespace os {
28 
29 class ContinuationIteratorBase
30 {
31 private:
32 
33     struct Context;
34 
35     static bit32 ChangeContext(bit32 retval, Context* from, Context* to);
36     static bit32 ChangeContext(bit32 retval, Context* to);
37 
38     Context* m_MainContext;
39     Context* m_IteratorContext;
40     Result m_Result;
41 
42     void RunImpl();
43     static void RunIterator(ContinuationIteratorBase* _this);
44 
45 protected:
46 
47     // Overrides the process that executes using this iterator
48     virtual Result Run() = 0;
49 
~ContinuationIteratorBase()50     ~ContinuationIteratorBase() {}
51 
52 public:
53 
54     // Specify the stack using stackBottom and initialize it
55     void Initialize(void* stackBottom);
56 
57     // Return the process to MoveNext.
58     // Can only call from inside the Run function.
59     Result Yield();
60 
61     // Runs until the next Yield or until the termination of Run.
62     // Returns 'true' if Yield was encountered; Returns 'false' if Run function terminated.
63     // If a value other than "ResultSuccess" is specified for "result", send notification to return forcibly using Run function.
64     //
65     bool MoveNext(Result result = nn::ResultSuccess());
66 
67     // Get the execution result of Run function after MoveNext returns "false".
68     // If this value is referenced before MoveNext returns "false", the behavior is undefined.
GetResult()69     Result GetResult() const { return m_Result; }
70 
71 };
72 
73 template <class T>
74 class ContinuationIterator : public ContinuationIteratorBase
75 {
76 private:
77 
78     T m_Value;
79 
80 public:
81 
82     // Sets the iterator value.
83     // Can only call from inside the Run function.
SetCurrent(const T & value)84     void SetCurrent(const T& value) { m_Value = value; }
85 
86     // Returns the iterator value.
87     // Can only call from inside the Run function.
YieldReturn(const T & value)88     Result YieldReturn(const T& value) { SetCurrent(value); return Yield(); }
89 
90     // Gets the iterator value.
GetCurrent()91     const T& GetCurrent() const { return m_Value; }
92 
93 };
94 
95 }}
96 
97 #endif
98 
99 #endif
100