Skip to content

Commit b89e98c

Browse files
committed
add state
1 parent e7c4c07 commit b89e98c

13 files changed

+644
-11
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252

5353
[观察者模式 Observer](doc/21-观察者.md)
5454

55-
状态模式 State
55+
[状态模式 State](doc/22-状态.md)
5656

5757
策略模式 Strategy
5858

code/20_observer/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
cmake_minimum_required(VERSION 3.0)
2-
PROJECT(memento_test)
2+
PROJECT(observer_test)
33

44
include(CheckCXXCompilerFlag)
55
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)

code/21_state/CMakeLists.txt

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
cmake_minimum_required(VERSION 3.0)
2+
PROJECT(state_test)
3+
4+
include(CheckCXXCompilerFlag)
5+
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
6+
CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X)
7+
8+
# 使用变量设置编译标志
9+
if(COMPILER_SUPPORTS_CXX11)
10+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
11+
elseif(COMPILER_SUPPORTS_CXX0X)
12+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
13+
else()
14+
message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")
15+
endif()
16+
17+
18+
SET(SRC_LIST client.cpp)
19+
SET(PATTERN_SRC state_types.cpp)
20+
21+
include_directories(./)
22+
23+
ADD_EXECUTABLE(state_test ${SRC_LIST} ${PATTERN_SRC})

code/21_state/client.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#include "state_types.h"
2+
3+
int main(){
4+
std::cout<<"------------------"<<std::endl;
5+
ThreadContext context;
6+
context.start();
7+
context.acquireCPU();
8+
context.suspend();
9+
context.resume();
10+
context.acquireCPU();
11+
context.stop();
12+
std::cout<<"------------------"<<std::endl;
13+
return 1;
14+
}

code/21_state/result.png

94.9 KB
Loading

code/21_state/state_types.cpp

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
#include "state_types.h"
2+
3+
void NewState::start(ThreadContext *context)
4+
{
5+
std::cout << "call NewState::start()" << std::endl;
6+
if (stateName == ::NEW)
7+
{
8+
if (context)
9+
context->changeState(new ReadyState());
10+
}
11+
else
12+
{
13+
std::cout << "Cannot call NewState::start() since current state is not [NEW]" << std::endl;
14+
}
15+
}
16+
17+
void ReadyState::acquire(ThreadContext *context)
18+
{
19+
std::cout << "call ReadyState::acquire()" << std::endl;
20+
if (stateName == ::READY)
21+
{
22+
if (context)
23+
context->changeState(new RunningState());
24+
}
25+
else
26+
{
27+
std::cout << "Cannot call ReadyState::acquire() since current state is not [READY]" << std::endl;
28+
}
29+
}
30+
31+
void RunningState::suspend(ThreadContext *context)
32+
{
33+
std::cout << "call RunningState::suspend()" << std::endl;
34+
if (stateName == ::RUNNING)
35+
{
36+
if (context)
37+
context->changeState(new BlockedState());
38+
}
39+
else
40+
{
41+
std::cout << "Cannot call RunningState::suspend() since current state is not [RUNNING]" << std::endl;
42+
}
43+
}
44+
45+
void RunningState::stop(ThreadContext *context)
46+
{
47+
std::cout << "call RunningState::stop()" << std::endl;
48+
if (stateName == ::RUNNING)
49+
{
50+
if (context)
51+
context->changeState(new DeadState());
52+
}
53+
else
54+
{
55+
std::cout << "Cannot call RunningState::stop() since current state is not [RUNNING]" << std::endl;
56+
}
57+
}
58+
59+
void BlockedState::resume(ThreadContext *context)
60+
{
61+
std::cout << "call BlockedState::resume()" << std::endl;
62+
if (stateName == ::BLOCKED)
63+
{
64+
if (context)
65+
context->changeState(new ReadyState());
66+
}
67+
else
68+
{
69+
std::cout << "Cannot call BlockedState::resume() since current state is not [BLOCKED]" << std::endl;
70+
}
71+
}
72+
73+
void ThreadContext::changeState(ThreadState *state)
74+
{
75+
if (this->state)
76+
{
77+
delete this->state;
78+
}
79+
this->state = state;
80+
}
81+
82+
ThreadState *ThreadContext::getState()
83+
{
84+
return state;
85+
}
86+
87+
void ThreadContext::start()
88+
{
89+
if (state && state->getStateName() == ::NEW)
90+
{
91+
static_cast<NewState *>(state)->start(this);
92+
}
93+
}
94+
95+
void ThreadContext::acquireCPU()
96+
{
97+
if (state && state->getStateName() == ::READY)
98+
{
99+
static_cast<ReadyState *>(state)->acquire(this);
100+
}
101+
}
102+
103+
void ThreadContext::suspend()
104+
{
105+
if (state && state->getStateName() == ::RUNNING)
106+
{
107+
static_cast<RunningState *>(state)->suspend(this);
108+
}
109+
}
110+
111+
void ThreadContext::stop()
112+
{
113+
if (state && state->getStateName() == ::RUNNING)
114+
{
115+
static_cast<RunningState *>(state)->stop(this);
116+
}
117+
}
118+
119+
void ThreadContext::resume()
120+
{
121+
if (state && state->getStateName() == ::BLOCKED)
122+
{
123+
static_cast<BlockedState *>(state)->resume(this);
124+
}
125+
}

code/21_state/state_types.h

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
#ifndef __STATE_TYPES_H__
2+
#define __STATE_TYPES_H__
3+
4+
#include <iostream>
5+
class ThreadContext;
6+
enum ThreadStateName
7+
{
8+
NEW = 0,
9+
READY,
10+
RUNNING,
11+
BLOCKED,
12+
DEAD
13+
};
14+
15+
class ThreadState
16+
{
17+
public:
18+
ThreadState(ThreadStateName name):stateName(name)
19+
{
20+
std::cout << "Current Thread state:" << stateName << std::endl;
21+
}
22+
virtual ~ThreadState() {}
23+
inline ThreadStateName getStateName()
24+
{
25+
return stateName;
26+
}
27+
28+
protected:
29+
ThreadStateName stateName;
30+
};
31+
32+
class NewState : public ThreadState
33+
{
34+
public:
35+
NewState() : ThreadState(::NEW) {}
36+
void start(ThreadContext *context);
37+
};
38+
39+
class ReadyState : public ThreadState
40+
{
41+
public:
42+
ReadyState() : ThreadState(READY) {}
43+
void acquire(ThreadContext *context);
44+
};
45+
46+
class RunningState : public ThreadState
47+
{
48+
public:
49+
RunningState() : ThreadState(RUNNING) {}
50+
void suspend(ThreadContext *context);
51+
void stop(ThreadContext *context);
52+
};
53+
54+
class BlockedState : public ThreadState
55+
{
56+
public:
57+
BlockedState() : ThreadState(BLOCKED) {}
58+
void resume(ThreadContext *context);
59+
};
60+
61+
class DeadState : public ThreadState
62+
{
63+
public:
64+
DeadState() : ThreadState(::DEAD) {}
65+
};
66+
67+
class ThreadContext
68+
{
69+
public:
70+
ThreadContext() : state(new NewState()) {}
71+
void changeState(ThreadState *state);
72+
ThreadState *getState();
73+
void start();
74+
void acquireCPU();
75+
void suspend();
76+
void stop();
77+
void resume();
78+
79+
private:
80+
ThreadState *state;
81+
};
82+
#endif // __STATE_TYPES_H__

0 commit comments

Comments
 (0)