feat(cmat): add cmake build for course material

Add a CMakeLists.txt to each exercise directory, included from
cmat/CMakeLists.txt, so every exercise and solution becomes a buildable
target. GUI exercises link the curses-based DOS_Unix implementations on
Unix-like systems; the Windows-specific DOS variants are not compiled.
Exercises without a portable path or with missing dependencies (Boost)
are reported as not available at configure time.

Targets are excluded from the default build and built by name, e.g.
`cmake --build build --target Ex11`, so intentionally buggy exercises
such as Ex21 do not break the default build.

Also fix two portability issues: rename Ex11bug/pole.h to Pole.h for
case-sensitive filesystems and drop the extra Light:: qualification in
SolutionEx71A/Light.h. Document build commands and layout in AGENTS.md.

Co-authored-by: Qwen 3.8 27B <qwen3.8_27b-q3_k_xl@lmstudio.local>
This commit is contained in:
2026-10-05 11:55:00 +02:00
co-authored by Qwen 3.8 27B
parent e8241fd1ff
commit e09540c2b2
701 changed files with 27282 additions and 16 deletions
+33 -4
View File
@@ -10,8 +10,22 @@ is added, document its layout under "Source Layout".
## Build System
No build system is set up yet. When one is added for the course examples,
document its configure, build, and test commands here.
CMake (3.21+) with Ninja.
```sh
cmake -B build -G Ninja
cmake --build build
```
Course exercises in `cmat/` are excluded from the default build; build one by
target name, e.g.:
```sh
cmake --build build --target Ex11
```
Tests (optional): configure with `-DBUILD_TESTING=ON`, then run `ninja check` in
the build directory.
## Coding Conventions
@@ -98,10 +112,25 @@ cppcourse/
README.md # Project docs
.oxfmtrc.json # oxfmt config
.agents/ # Agent skills (git workflow)
CMakeLists.txt # Build system entry point
deps/ # CMake helper modules (platform, flags, Find* deps)
cmat/ # Course material: exercises and solutions
397/ # Original copy of the course material (reference only)
```
Course content (lectures, exercises, examples) will be added as the course is
developed. Document the layout here when it takes shape.
`cmat/` layout:
- `Ex*/`: exercise starting points. Some intentionally contain bugs that
students fix during the course; their targets fail to compile (or misbehave at
runtime) until fixed.
- `SolutionEx*/`: working solutions of the exercises.
- `DOS_Unix/`: platform Keyboard/Screen implementations shared by the GUI
exercises. The DOS variants are Windows-specific; on Unix-like systems the
curses variants are built instead (linked as the `dos_unix` library).
- Each exercise directory holds a `CMakeLists.txt` that defines its target via
`cmat_add_exercise()` (see `cmat/CMakeLists.txt`). Exercises that need a
missing dependency (e.g. Boost) are reported as not available at configure
time and skipped.
## Behavioral Guidelines
+3
View File
@@ -22,6 +22,9 @@ target_compile_options(hello PRIVATE ${BASE_OPTIONS})
target_compile_definitions(hello PRIVATE ${BASE_DEFINITIONS})
target_link_libraries(hello PRIVATE fmt::fmt)
# Course material (exercises and solutions)
add_subdirectory(cmat)
option(BUILD_TESTING OFF "Build Unity/CMock test suites")
if (BUILD_TESTING AND NOT IS_EMSCRIPTEN)
set(CMAKE_SKIP_TEST_ALL_DEPENDENCY FALSE)
+145
View File
@@ -0,0 +1,145 @@
# ==============================================================================
# Course Material (cmat)
# ==============================================================================
# Exercises copied from 397. Each exercise directory holds its own
# CMakeLists.txt (included below) and defines one executable target with the
# directory's name via cmat_add_exercise().
#
# Targets are excluded from the default build; build one by name:
# cmake --build build --target Ex11
#
# Some exercises intentionally contain bugs that students fix during the
# course. Those targets fail to compile (or misbehave at runtime) until the
# bug is fixed, which is expected.
# ------------------------------------------------------------------------------
# Compile options
# ------------------------------------------------------------------------------
# Legacy course material: keep the project's warning flags but drop -Werror;
# these old sources produce warnings that must not block the build.
set(CMAT_OPTIONS "")
foreach (opt IN LISTS BASE_OPTIONS)
if (NOT opt STREQUAL "-Werror" AND NOT opt STREQUAL "/WX")
list(APPEND CMAT_OPTIONS "${opt}")
endif()
endforeach()
# ------------------------------------------------------------------------------
# Keyboard/Screen support (DOS_Unix/)
# ------------------------------------------------------------------------------
# GUI exercises use the Keyboard/Screen abstraction from DOS_Unix/. The DOS
# variants (Keyboard_DOS.cpp, Screen_DOS.cpp) are Windows-specific and are not
# compiled. On Unix-like systems the curses variants provide the same
# interface instead.
set(CMAT_GUI_LIB "")
if (IS_LINUX OR IS_MACOS)
find_package(Curses QUIET)
if (Curses_FOUND)
add_library(dos_unix STATIC
DOS_Unix/CursesObj.cpp
DOS_Unix/Keyboard_Unix.cpp
DOS_Unix/Screen_Unix.cpp
)
set_target_properties(dos_unix PROPERTIES EXCLUDE_FROM_ALL TRUE)
target_include_directories(dos_unix PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/DOS_Unix")
if (CURSES_INCLUDE_DIRS)
target_include_directories(dos_unix SYSTEM PUBLIC ${CURSES_INCLUDE_DIRS})
endif()
target_link_libraries(dos_unix PUBLIC ${CURSES_LIBRARIES})
set(CMAT_GUI_LIB dos_unix)
else()
message(STATUS "Curses not found; GUI exercises are unavailable")
endif()
else()
# Windows: only the DOS keyboard/screen implementations exist, which are
# Windows-specific; there is nothing portable to build with.
endif()
# Exercises using Boost.Serialization (system install; not fetched). CONFIG
# mode uses Boost's own CMake package, since the FindBoost module was removed
# in CMake 4.
find_package(Boost CONFIG QUIET COMPONENTS serialization)
# ------------------------------------------------------------------------------
# Target helpers
# ------------------------------------------------------------------------------
# cmat_add_exercise(<name> [GUI] [BOOST] <sources>...)
#
# Creates an executable target from the given sources. GUI links the
# Keyboard/Screen support library; BOOST links Boost.Serialization. If a
# required dependency is missing, the exercise is reported as not available
# and no target is created.
function(cmat_add_exercise name)
cmake_parse_arguments(ARG "GUI;BOOST" "" "SOURCES" ${ARGN})
if (ARG_GUI AND NOT CMAT_GUI_LIB)
cmat_unavailable(${name} "requires the Keyboard/Screen abstraction, which is Windows-specific (DOS_Unix/)")
return()
endif()
if (ARG_BOOST AND NOT Boost_FOUND)
cmat_unavailable(${name} "requires Boost.Serialization")
return()
endif()
add_executable(${name} ${ARG_SOURCES})
target_compile_features(${name} PRIVATE cxx_std_23)
target_compile_options(${name} PRIVATE ${CMAT_OPTIONS})
set_target_properties(${name} PROPERTIES EXCLUDE_FROM_ALL TRUE)
if (ARG_GUI)
target_link_libraries(${name} PRIVATE ${CMAT_GUI_LIB})
endif()
if (ARG_BOOST)
target_link_libraries(${name} PRIVATE Boost::serialization)
endif()
endfunction()
# cmat_unavailable(<name> <reason>)
#
# Reports that an exercise cannot be built on this platform. A warning (not a
# hard error) is used so the configuration completes and all other exercises
# remain available.
function(cmat_unavailable name reason)
message(WARNING "Exercise ${name} is not available on this platform: ${reason}")
endfunction()
# ------------------------------------------------------------------------------
# Exercises
# ------------------------------------------------------------------------------
add_subdirectory(Ex11)
add_subdirectory(Ex11bug)
add_subdirectory(Ex21)
add_subdirectory(Ex22)
add_subdirectory(Ex31)
add_subdirectory(Ex32)
add_subdirectory(Ex33)
add_subdirectory(Ex41)
add_subdirectory(Ex42)
add_subdirectory(Ex51)
add_subdirectory(Ex61)
add_subdirectory(Ex62)
add_subdirectory(Ex71)
add_subdirectory(Ex71A)
add_subdirectory(SolutionEx11bug)
add_subdirectory(SolutionEx21)
add_subdirectory(SolutionEx22)
add_subdirectory(SolutionEx22Bonus)
add_subdirectory(SolutionEx31)
add_subdirectory(SolutionEx31Bonus)
add_subdirectory(SolutionEx32)
add_subdirectory(SolutionEx33)
add_subdirectory(SolutionEx33Bonus)
add_subdirectory(SolutionEx41)
add_subdirectory(SolutionEx41Bonus)
add_subdirectory(SolutionEx42)
add_subdirectory(SolutionEx51)
add_subdirectory(SolutionEx51Bonus2)
add_subdirectory(SolutionEx61InterimSolution)
add_subdirectory(SolutionEx61Part1)
add_subdirectory(SolutionEx61Part2)
add_subdirectory(SolutionEx61Part2Bonus)
add_subdirectory(SolutionEx62)
add_subdirectory(SolutionEx62Bonus)
add_subdirectory(SolutionEx62Bonus2)
add_subdirectory(SolutionEx71)
add_subdirectory(SolutionEx71A)
add_subdirectory(SolutionEx71ABonus)
add_subdirectory(SolutionEx71Bonus)
+51
View File
@@ -0,0 +1,51 @@
#include "CursesObj.h"
#include "curses.h"
CursesObj::CursesObj() {
// Colours 0 to 7 are defined by curses. But we need grey as well
// Define a suitable constant here (and create the colour later)
const int COLOR_GREY = 8;
initscr(); /* initialize the curses library */
nonl(); /* tell curses not to do NL->CR/NL on output */
cbreak(); /* take input chars one at a time, no wait for \n */
nodelay(stdscr, FALSE);
noecho(); /* echo input - in color */
curs_set(0);
intrflush(stdscr, FALSE);
if (has_colors()) {
start_color();
/*
* Simple color assignment, often all we need. Color pair 0 cannot
* be redefined. This example uses the same value for the color
* pair as for the foreground color, though of course that is not
* necessary:
*/
init_pair(1, COLOR_RED, COLOR_BLACK);
init_pair(2, COLOR_GREEN, COLOR_BLACK);
init_pair(3, COLOR_YELLOW, COLOR_BLACK);
init_pair(4, COLOR_BLUE, COLOR_BLACK);
init_pair(5, COLOR_CYAN, COLOR_BLACK);
init_pair(6, COLOR_MAGENTA, COLOR_BLACK);
init_pair(7, COLOR_WHITE, COLOR_BLACK);
// Create 'grey' and then use it as foreground colour
init_color(8, 1, 333, 333);
init_pair(8, COLOR_GREY, COLOR_BLACK);
}
}
CursesObj::~CursesObj() {
clear();
refresh();
endwin();
}
CursesObj &CursesObj::Instance() {
static CursesObj instance;
return instance;
}
+13
View File
@@ -0,0 +1,13 @@
#ifndef CURSESOBJ_H
#define CURSESOBJ_H
class CursesObj {
private:
CursesObj();
~CursesObj();
public:
static CursesObj &Instance();
};
#endif
+13
View File
@@ -0,0 +1,13 @@
#ifndef KEYBOARD_H
#define KEYBOARD_H
class Keyboard {
public:
Keyboard();
bool isCharAvail();
char getChar();
private:
};
#endif
+13
View File
@@ -0,0 +1,13 @@
#include "Keyboard.h"
#include <conio.h>
Keyboard::Keyboard() {}
bool Keyboard::isCharAvail() {
// 'return kbhit()' is sufficient, but Microsoft
// issues a warning 'coercing int to bool' and encourages
// the use of '!=0' to eliminate it
return _kbhit() != 0;
}
char Keyboard::getChar() { return _getch(); }
+28
View File
@@ -0,0 +1,28 @@
#include "Keyboard.h"
#include "CursesObj.h"
#include "curses.h"
Keyboard::Keyboard() {
CursesObj::Instance(); // Force initialization
nodelay(stdscr, FALSE); // Default to block on getch
}
bool Keyboard::isCharAvail() {
nodelay(stdscr, TRUE); // getch must not block for this polling
int c; // DON'T make this 'char'; 'ERR' may be an 'int' - on some systems,
// just like 'EOF'
bool charWaiting = (c = getch()) != ERR; // If getch returns ERR, no char
// waiting, otherwise, next char is
// returned
if (charWaiting)
ungetch(c); // We got a char; put it back! (We just want to know if there
// is one waiting.)
return charWaiting;
}
char Keyboard::getChar() { return getch(); }
+19
View File
@@ -0,0 +1,19 @@
#ifndef SCREEN_H
#define SCREEN_H
#include <string>
namespace Screen {
const int BLACK = 0;
const int GRAY = 8; // FOREGROUND_INTENSITY;
const int BLUE = 9; // FOREGROUND_RED|FOREGROUND_INTENSITY
const int GREEN = 10; // FOREGROUND_GREEN|FOREGROUND_INTENSITY;
const int RED = 12; // FOREGROUND_RED|FOREGROUND_INTENSITY
const int YELLOW = RED | GREEN;
const int WHITE = RED | GREEN | BLUE;
const int BACKGROUND = 128; // OR (|) with the color value for gray background
void write(std::string s, int x, int y, int color);
};
#endif
+32
View File
@@ -0,0 +1,32 @@
#include <conio.h>
#include <string>
#include <windows.h>
using std::string;
#include "Screen.h"
namespace {
HANDLE hStdout = 0;
}
void Screen::write(string s, int x, int y, int color) {
if (hStdout == 0) {
hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
}
COORD screenPos;
screenPos.X = x;
screenPos.Y = y;
unsigned long ln;
static unsigned short attrib[80];
for (unsigned int i = 0; i < s.length(); ++i) {
attrib[i] = color;
}
WriteConsoleOutputAttribute(hStdout, attrib, s.length(), screenPos, &ln);
WriteConsoleOutputCharacter(hStdout, s.c_str(), s.length(), screenPos, &ln);
}
+66
View File
@@ -0,0 +1,66 @@
#include "Screen.h"
#include "CursesObj.h"
#include "curses.h"
#include <stdio.h>
#include <string.h>
// Forward declarations
int ConvertColour(int);
void Screen::write(std::string s, int x, int y, int color) {
CursesObj::Instance(); // Force initialization
if (color >= 128)
color -= 128; // Remove gray background - does not work on Linux
std::string blank_str(s.length(), ' ');
mvaddstr(y, x, blank_str.c_str()); // Always draw a black
refresh();
if (color != Screen::BLACK) // If colour is not black, also draw the color
{
printf("\e[%i;3%im", 0, ConvertColour(color));
fflush(stdout);
mvaddstr(y, x, s.c_str());
refresh();
}
}
typedef struct {
int pelio_colour;
int curses_color_pair;
} Entry;
// Entry null pointer
const Entry *ENTRY_NP = (Entry *)0;
typedef Entry Table[];
Table ColourTable = {{Screen::GRAY, 8}, // Display as white
{Screen::BLUE, 4}, {Screen::GREEN, 2}, {Screen::RED, 1}, {Screen::YELLOW, 3}, {Screen::WHITE, 7}};
const int LEN_TAB = sizeof ColourTable / sizeof ColourTable[0];
const Entry *TabSearch(Table t, int nEntries, int colour) {
Entry *p;
for (p = t; p < t + nEntries && p->pelio_colour != colour; p++)
; // EMPTY BODY
return (p < t + nEntries) ? p : ENTRY_NP;
}
int ConvertColour(int colour) {
int result = 0;
const Entry *p;
p = TabSearch(ColourTable, LEN_TAB, colour); // Search the table for the colour specified
if (p != ENTRY_NP) // If the colour is in the table ...
result = p->curses_color_pair; // ... return the 'int' for the associated
// curses colour pair
return result;
}
+13
View File
@@ -0,0 +1,13 @@
# Ex11
cmat_add_exercise(Ex11
GUI
SOURCES
Light.cpp
main.cpp
Pelican.cpp
PelicanTimer.cpp
Pole.cpp
Timer.cpp
TimerSet.cpp
)
Binary file not shown.
+22
View File
@@ -0,0 +1,22 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.24720.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Ex11", "Ex11.vcxproj", "{7195CF47-386C-4BF5-988B-B47FE9177122}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x86 = Debug|x86
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{7195CF47-386C-4BF5-988B-B47FE9177122}.Debug|x86.ActiveCfg = Debug|Win32
{7195CF47-386C-4BF5-988B-B47FE9177122}.Debug|x86.Build.0 = Debug|Win32
{7195CF47-386C-4BF5-988B-B47FE9177122}.Release|x86.ActiveCfg = Release|Win32
{7195CF47-386C-4BF5-988B-B47FE9177122}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
Binary file not shown.
+185
View File
@@ -0,0 +1,185 @@
<?xml version="1.0" encoding = "Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.00"
Name="Ex11"
SccProjectName="&quot;$/Course/397/Ex11&quot;, DAAAAAAA"
SccLocalPath=".">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Release|Win32"
OutputDirectory=".\Release"
IntermediateDirectory=".\Release"
ConfigurationType="1"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
InlineFunctionExpansion="1"
PreprocessorDefinitions="WIN32,NDEBUG,_CONSOLE"
StringPooling="TRUE"
RuntimeLibrary="4"
EnableFunctionLevelLinking="TRUE"
UsePrecompiledHeader="2"
PrecompiledHeaderFile=".\Release/Ex11.pch"
AssemblerListingLocation=".\Release/"
ObjectFile=".\Release/"
ProgramDataBaseFileName=".\Release/"
WarningLevel="3"
SuppressStartupBanner="TRUE"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="odbc32.lib odbccp32.lib"
OutputFile=".\Release/Ex11.exe"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
ProgramDatabaseFile=".\Release/Ex11.pdb"
SubSystem="1"/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Release/Ex11.tlb"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
</Configuration>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\Debug"
IntermediateDirectory=".\Debug"
ConfigurationType="1"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32,_DEBUG,_CONSOLE"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
RuntimeTypeInfo="TRUE"
UsePrecompiledHeader="2"
PrecompiledHeaderFile=".\Debug/Ex11.pch"
AssemblerListingLocation=".\Debug/"
ObjectFile=".\Debug/"
ProgramDataBaseFileName=".\Debug/"
WarningLevel="3"
SuppressStartupBanner="TRUE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="odbc32.lib odbccp32.lib"
OutputFile=".\Debug/Ex11.exe"
LinkIncremental="2"
SuppressStartupBanner="TRUE"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\Debug/Ex11.pdb"
SubSystem="1"/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Debug/Ex11.tlb"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
</Configuration>
</Configurations>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
<File
RelativePath=".\Light.cpp">
</File>
<File
RelativePath=".\Pelican.cpp">
</File>
<File
RelativePath=".\PelicanTimer.cpp">
</File>
<File
RelativePath=".\Timer.cpp">
</File>
<File
RelativePath="TimerSet.cpp">
</File>
<File
RelativePath=".\main.cpp">
</File>
<File
RelativePath=".\pole.cpp">
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl">
<File
RelativePath=".\Light.h">
</File>
<File
RelativePath=".\Pelican.h">
</File>
<File
RelativePath=".\PelicanTimer.h">
</File>
<File
RelativePath=".\Timer.h">
</File>
<File
RelativePath="TimerSet.h">
</File>
<File
RelativePath=".\pole.h">
</File>
</Filter>
<Filter
Name="DOS_Unix"
Filter="">
<File
RelativePath="..\DOS_Unix\Keyboard.h">
</File>
<File
RelativePath="..\DOS_Unix\Keyboard_DOS.cpp">
</File>
<File
RelativePath="..\DOS_Unix\Screen.h">
</File>
<File
RelativePath="..\DOS_Unix\Screen_DOS.cpp">
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
+144
View File
@@ -0,0 +1,144 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<SccProjectName>"$/Course/397/Ex11", DAAAAAAA</SccProjectName>
<SccLocalPath>.</SccLocalPath>
<ProjectGuid>{7195CF47-386C-4BF5-988B-B47FE9177122}</ProjectGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v140</PlatformToolset>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v140</PlatformToolset>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>14.0.24730.2</_ProjectFileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>.\Release\</OutDir>
<IntDir>.\Release\</IntDir>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>.\Debug\</OutDir>
<IntDir>.\Debug\</IntDir>
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader />
<PrecompiledHeaderOutputFile>.\Release/Ex11.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\Release/</AssemblerListingLocation>
<ObjectFileName>.\Release/</ObjectFileName>
<ProgramDataBaseFileName>.\Release/</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
</ClCompile>
<Link>
<AdditionalOptions>/MACHINE:I386 %(AdditionalOptions)</AdditionalOptions>
<AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>.\Release/Ex11.exe</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<ProgramDatabaseFile>.\Release/Ex11.pdb</ProgramDatabaseFile>
<SubSystem>Console</SubSystem>
</Link>
<Midl>
<TypeLibraryName>.\Release/Ex11.tlb</TypeLibraryName>
</Midl>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<RuntimeTypeInfo>true</RuntimeTypeInfo>
<PrecompiledHeader />
<PrecompiledHeaderOutputFile>.\Debug/Ex11.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\Debug/</AssemblerListingLocation>
<ObjectFileName>.\Debug/</ObjectFileName>
<ProgramDataBaseFileName>.\Debug/</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<AdditionalIncludeDirectories>C:\course\397\DOS_Unix;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<AdditionalOptions>/MACHINE:I386 %(AdditionalOptions)</AdditionalOptions>
<AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>.\Debug/Ex11.exe</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>.\Debug/Ex11.pdb</ProgramDatabaseFile>
<SubSystem>Console</SubSystem>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
</Link>
<Midl>
<TypeLibraryName>.\Debug/Ex11.tlb</TypeLibraryName>
</Midl>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\DOS_Unix\Keyboard_DOS.cpp" />
<ClCompile Include="..\DOS_Unix\Screen_DOS.cpp" />
<ClCompile Include="Light.cpp" />
<ClCompile Include="main.cpp" />
<ClCompile Include="Pelican.cpp" />
<ClCompile Include="PelicanTimer.cpp" />
<ClCompile Include="pole.cpp" />
<ClCompile Include="Timer.cpp" />
<ClCompile Include="TimerSet.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\DOS_Unix\Keyboard.h" />
<ClInclude Include="..\DOS_Unix\Screen.h" />
<ClInclude Include="Light.h" />
<ClInclude Include="Pelican.h" />
<ClInclude Include="PelicanTimer.h" />
<ClInclude Include="pole.h" />
<ClInclude Include="Timer.h" />
<ClInclude Include="TimerSet.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
+71
View File
@@ -0,0 +1,71 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{94250b16-82d1-4f12-8890-9942de501588}</UniqueIdentifier>
<Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{3c44361f-9161-4807-9c8e-ca3dec754b19}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl</Extensions>
</Filter>
<Filter Include="DOS_Unix">
<UniqueIdentifier>{33696874-76e6-4fed-9fae-20dbad38a143}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Light.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Pelican.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="PelicanTimer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Timer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="TimerSet.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="pole.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\DOS_Unix\Screen_DOS.cpp">
<Filter>DOS_Unix</Filter>
</ClCompile>
<ClCompile Include="..\DOS_Unix\Keyboard_DOS.cpp">
<Filter>Header Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Light.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Pelican.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="PelicanTimer.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Timer.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="TimerSet.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="pole.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\DOS_Unix\Keyboard.h">
<Filter>DOS_Unix</Filter>
</ClInclude>
<ClInclude Include="..\DOS_Unix\Screen.h">
<Filter>DOS_Unix</Filter>
</ClInclude>
</ItemGroup>
</Project>
+3
View File
@@ -0,0 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
</Project>
+20
View File
@@ -0,0 +1,20 @@
#include "Light.h"
#include "CursesObj.h"
#include "Pelican.h"
#include "Screen.h"
#include <iostream>
Light::Light(std::string name, int x, int y, int color) : x(x), y(y), c(color), name(name) {}
Light::~Light() {
std::cout << "Deleting light (" << name << ", " << x << ", " << y << ", " << c << ")" << std::endl;
std::cout.flush();
}
void Light::set(LightState newState) {
state = newState;
Screen::write(name.c_str(), x, y, state == FLASH ? (128 + c) : (state == OFF ? 0 : c));
// 128 + color was used to make a character flash (but not any more)
}
Light::LightState Light::get(void) { return state; }
+30
View File
@@ -0,0 +1,30 @@
// ======================================================
//
// Represents a light, implemented as a string written
// to a console window
//
// ======================================================
#ifndef LIGHT_H
#define LIGHT_H
#include <string>
class Light {
public:
Light(std::string name, int x, int y, int color);
~Light();
enum LightState { ON, OFF, FLASH };
void set(LightState new_state);
LightState get(void);
private:
int c; // light colour
int x, y;
std::string name;
LightState state;
};
#endif
+64
View File
@@ -0,0 +1,64 @@
#include "Pelican.h"
#include "PelicanTimer.h"
#include "Pole.h"
Pelican::Pelican(int x, int y)
: pressed(false), RED_TIME(4), YELLOW_TIME(2), GREEN_TIME(3), FLASH_TIME(5), myPole(new Pole(x, y)),
state(GREEN_IDLE) {
myTimer = new PelicanTimer(*this, &Pelican::timerExpired);
myPole->setTrafficLights(getState());
myPole->setWaitLight(isPressed());
}
Pelican::~Pelican() { delete myPole; }
void Pelican::press(void) {
if (state == GREEN_IDLE) {
state = YELLOW_STATE;
myTimer->timeoutRequest(YELLOW_TIME);
pressed = true;
myPole->setTrafficLights(getState());
myPole->setWaitLight(isPressed());
} else if (state != RED_STATE) {
pressed = true;
myPole->setTrafficLights(getState());
myPole->setWaitLight(isPressed());
}
}
void Pelican::timerExpired(void) {
switch (state) {
case RED_STATE:
state = YELLOW_FLASHING;
myTimer->timeoutRequest(FLASH_TIME);
break;
case YELLOW_FLASHING:
state = GREEN_TIMING;
myTimer->timeoutRequest(GREEN_TIME);
break;
case GREEN_TIMING:
if (pressed) {
state = YELLOW_STATE;
myTimer->timeoutRequest(YELLOW_TIME);
} else {
state = GREEN_IDLE;
}
break;
case GREEN_IDLE:
// should never happen
break;
case YELLOW_STATE:
state = RED_STATE;
pressed = false;
myTimer->timeoutRequest(RED_TIME);
break;
}
myPole->setTrafficLights(getState());
myPole->setWaitLight(isPressed());
}
+54
View File
@@ -0,0 +1,54 @@
// ======================================================
//
// Represents a Pelican crossing
//
// ======================================================
#ifndef PELICAN_H
#define PELICAN_H
class PelicanTimer;
class Pole;
class Pelican {
public:
Pelican(int x, int y);
~Pelican();
// call when the WAIT button has been pressed
void press(void);
// states that a Pelican can be in
enum PelicanState { RED_STATE, YELLOW_FLASHING, GREEN_TIMING, GREEN_IDLE, YELLOW_STATE };
bool isPressed() const { return pressed; }
PelicanState getState() const { return state; }
private:
// state that this Pelican is in
PelicanState state;
// called by PeleicanTimer when the lights need to change
void timerExpired(void);
const unsigned int RED_TIME;
const unsigned int YELLOW_TIME;
const unsigned int GREEN_TIME;
const unsigned int FLASH_TIME;
// indicates whether the WAIT light should be on
bool pressed;
Pole *myPole;
// Timer that indicates when the lights should change
PelicanTimer *myTimer;
private:
// prevent general use of copy ctor and operator=
Pelican(const Pelican &);
Pelican &operator=(const Pelican &);
};
#endif
+10
View File
@@ -0,0 +1,10 @@
#include "PelicanTimer.h"
PelicanTimer::PelicanTimer(Pelican &target, TargetFunc targetFunc) : myTarget(target), myTargetFunc(targetFunc) {}
void PelicanTimer::tick() {
if (isExpired()) {
(myTarget.*myTargetFunc)();
}
}
+27
View File
@@ -0,0 +1,27 @@
// ======================================================
//
// This class specializes the Timer to enable it to
// stimulate a Pelican
//
// ======================================================
#ifndef PELICANTIMER_H
#define PELICANTIMER_H
#include "Pelican.h"
#include "Timer.h"
class PelicanTimer : public Timer {
public:
typedef void (Pelican::*TargetFunc)();
PelicanTimer(Pelican &target, TargetFunc targetFunc);
virtual void tick();
private:
Pelican &myTarget;
TargetFunc myTargetFunc;
};
#endif
+59
View File
@@ -0,0 +1,59 @@
#include "Pole.h"
#include "Screen.h"
Pole::Pole(int x, int y) : waitLight(new Light("WAIT", x + 6, y + 12, Screen::WHITE)) {
using namespace Screen;
lights[RED_LIGHT] = new Light("*", x + 11, y + 3, RED);
lights[RED_MAN] = new Light("*<-=", x + 6, y + 4, RED);
lights[YELLOW_LIGHT] = new Light("*", x + 11, y + 5, YELLOW);
lights[GREEN_LIGHT] = new Light("*", x + 11, y + 7, GREEN);
lights[GREEN_MAN] = new Light("*|-<", x + 6, y + 7, GREEN);
write(" _____ ", x, ++y, GRAY);
write(" /___ /| ", x, ++y, GRAY);
write(" | | | ", x, ++y, GRAY);
write(" | |/| ", x, ++y, GRAY);
write(" |____| | ", x, ++y, GRAY);
write(" | |/| ", x, ++y, GRAY);
write(" | | | ", x, ++y, GRAY);
write(" |____|/ ", x, ++y, GRAY);
write(" _||__ ", x, ++y, GRAY);
write(" /___ /| ", x, ++y, GRAY);
write(" | | | ", x, ++y, GRAY);
write(" | | | ", x, ++y, GRAY);
write(" |____|/ ", x, ++y, GRAY);
write(" || ", x, ++y, GRAY);
write(" || ", x, ++y, GRAY);
write(" || ", x, ++y, GRAY);
write(" || ", x, ++y, GRAY);
write(" || ", x, ++y, GRAY);
write(" || ", x, ++y, GRAY);
write("========||===========", x, ++y, GRAY);
write(" / || / ", x, ++y, GRAY);
write("_ /_________ /_ ", x, ++y, GRAY);
write("/ / ", x, ++y, GRAY);
}
Pole::~Pole() {
for (int i = 0; i < sizeof lights / sizeof(lights[0]); ++i)
delete lights[i];
delete waitLight;
}
void Pole::setTrafficLights(Pelican::PelicanState state) {
static const Light::LightState LightStates[Pelican::YELLOW_STATE + 1][RED_MAN + 1] = {
// red yellow green green man red man
{Light::ON, Light::OFF, Light::OFF, Light::ON, Light::OFF}, // red
{Light::OFF, Light::FLASH, Light::OFF, Light::FLASH, Light::OFF}, // y flash
{Light::OFF, Light::OFF, Light::ON, Light::OFF, Light::ON}, // g time
{Light::OFF, Light::OFF, Light::ON, Light::OFF, Light::ON}, // g idle
{Light::OFF, Light::ON, Light::OFF, Light::OFF, Light::ON} // yellow
};
for (int i = RED_LIGHT; i <= RED_MAN; i++) {
lights[i]->set(LightStates[state][i]);
}
}
void Pole::setWaitLight(bool pressed) { waitLight->set(pressed ? Light::ON : Light::OFF); }
+27
View File
@@ -0,0 +1,27 @@
// ======================================================
// The Pole presenting the Pelican
// ======================================================
#ifndef POLE_H
#define POLE_H
#include "Light.h"
#include "Pelican.h"
class Pole {
public:
Pole(int x, int y);
~Pole();
void setTrafficLights(Pelican::PelicanState state);
void setWaitLight(bool pressed);
private:
enum LightName { RED_LIGHT, YELLOW_LIGHT, GREEN_LIGHT, GREEN_MAN, RED_MAN };
Light *lights[RED_MAN + 1];
Light *waitLight;
};
#endif
+17
View File
@@ -0,0 +1,17 @@
#include "Timer.h"
#include "TimerSet.h"
void Timer::timeoutRequest(int seconds) { timeToGo = seconds; }
Timer::Timer() : timeToGo(-1) { theTimerSet.addATimer(this); }
bool Timer::isExpired() {
if (timeToGo > 0) {
if (--timeToGo == 0) {
return true;
}
}
return false;
}
+27
View File
@@ -0,0 +1,27 @@
// ======================================================
//
// A general-purpose countdown timer
// To use this class, specialize it
// and override tick()
//
// ======================================================
#ifndef TIMER_H
#define TIMER_H
class Timer {
public:
Timer();
void timeoutRequest(int seconds);
virtual void tick() = 0;
protected:
bool isExpired();
private:
int timeToGo;
};
#endif
+20
View File
@@ -0,0 +1,20 @@
#include "TimerSet.h"
#include "Timer.h"
TimerSet theTimerSet;
// Member functions
TimerSet::TimerSet() : timersInUse(0), previousTime(time(&previousTime)) {}
void TimerSet::addATimer(Timer *t) { timers[timersInUse++] = t; }
void TimerSet::pollAllTimers() {
std::time_t timeNow;
if (time(&timeNow) > previousTime) {
previousTime = timeNow;
for (int i = 0; i < timersInUse; ++i) {
timers[i]->tick();
}
}
}
+23
View File
@@ -0,0 +1,23 @@
#ifndef TIMERSET_H
#define TIMERSET_H
#include <ctime>
class Timer;
class TimerSet {
public:
TimerSet();
void pollAllTimers();
void addATimer(Timer *);
private:
Timer *timers[40];
int timersInUse;
std::time_t previousTime;
};
extern TimerSet theTimerSet;
#endif
Binary file not shown.
+29
View File
@@ -0,0 +1,29 @@
#include "Keyboard.h"
#include "Pelican.h"
#include "TimerSet.h"
#include <cctype> // provides toupper()
int main() {
Keyboard kbd;
Pelican thePelican(30, 0);
char c = 0;
while (std::toupper(c) != 'Q') { // loop until 'Q' is pressed
while (!kbd.isCharAvail()) {
theTimerSet.pollAllTimers(); // no key press to process, poll the timers
}
c = kbd.getChar(); // get the character
if (c == ' ') {
// it's a space, so press the WAIT button
thePelican.press();
}
}
return 0;
}
+2
View File
@@ -0,0 +1,2 @@
BASEOBJS = \
Light.o main.o Pelican.o PelicanTimer.o Pole.o Timer.o TimerSet.o
+17
View File
@@ -0,0 +1,17 @@
COMPILER = gcc
FLAGS =
INCLUDES = -I/usr/local/include/c++/3.4.2 -I../DOS_Unix
ARCHIVES = -L/usr/local/lib/gcc/sparc-sun-solaris2.7/3.4.2 -L/usr/local/lib -L/usr/lib
UNIX_OBJS = ../DOS_Unix/CursesObj.o ../DOS_Unix/Keyboard_Unix.o ../DOS_Unix/Screen_Unix.o
include make.mk
.SUFFIXES: .cpp .o
all: pelican
.cpp.o:
$(COMPILER) $(INCLUDES) -frepo -c $(FLAGS) $*.cpp
pelican : $(BASEOBJS)
$(COMPILER) $(ARCHIVES) -o pelican -lcurses $(BASEOBJS) $(UNIX_OBJS) -lcurses -lstdc++ -static
+13
View File
@@ -0,0 +1,13 @@
# Ex11bug
cmat_add_exercise(Ex11bug
GUI
SOURCES
Light.cpp
main.cpp
Pelican.cpp
PelicanTimer.cpp
Pole.cpp
Timer.cpp
TimerSet.cpp
)
+20
View File
@@ -0,0 +1,20 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.21005.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Ex11", "Ex11.vcxproj", "{E1F2BA40-B169-8D69-78E1-868C8A785A9C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{E1F2BA40-B169-8D69-78E1-868C8A785A9C}.Debug|Win32.ActiveCfg = Debug|Win32
{E1F2BA40-B169-8D69-78E1-868C8A785A9C}.Debug|Win32.Build.0 = Debug|Win32
{E1F2BA40-B169-8D69-78E1-868C8A785A9C}.Release|Win32.ActiveCfg = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
Binary file not shown.
+185
View File
@@ -0,0 +1,185 @@
<?xml version="1.0" encoding = "Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.00"
Name="Ex11"
SccProjectName="&quot;$/Course/397/Ex11&quot;, DAAAAAAA"
SccLocalPath=".">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Release|Win32"
OutputDirectory=".\Release"
IntermediateDirectory=".\Release"
ConfigurationType="1"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
InlineFunctionExpansion="1"
PreprocessorDefinitions="WIN32,NDEBUG,_CONSOLE"
StringPooling="TRUE"
RuntimeLibrary="4"
EnableFunctionLevelLinking="TRUE"
UsePrecompiledHeader="2"
PrecompiledHeaderFile=".\Release/Ex11.pch"
AssemblerListingLocation=".\Release/"
ObjectFile=".\Release/"
ProgramDataBaseFileName=".\Release/"
WarningLevel="3"
SuppressStartupBanner="TRUE"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="odbc32.lib odbccp32.lib"
OutputFile=".\Release/Ex11.exe"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
ProgramDatabaseFile=".\Release/Ex11.pdb"
SubSystem="1"/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Release/Ex11.tlb"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
</Configuration>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\Debug"
IntermediateDirectory=".\Debug"
ConfigurationType="1"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32,_DEBUG,_CONSOLE"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
RuntimeTypeInfo="TRUE"
UsePrecompiledHeader="2"
PrecompiledHeaderFile=".\Debug/Ex11.pch"
AssemblerListingLocation=".\Debug/"
ObjectFile=".\Debug/"
ProgramDataBaseFileName=".\Debug/"
WarningLevel="3"
SuppressStartupBanner="TRUE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="odbc32.lib odbccp32.lib"
OutputFile=".\Debug/Ex11.exe"
LinkIncremental="2"
SuppressStartupBanner="TRUE"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\Debug/Ex11.pdb"
SubSystem="1"/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Debug/Ex11.tlb"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
</Configuration>
</Configurations>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
<File
RelativePath=".\Light.cpp">
</File>
<File
RelativePath=".\Pelican.cpp">
</File>
<File
RelativePath=".\PelicanTimer.cpp">
</File>
<File
RelativePath=".\Timer.cpp">
</File>
<File
RelativePath="TimerSet.cpp">
</File>
<File
RelativePath=".\main.cpp">
</File>
<File
RelativePath=".\pole.cpp">
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl">
<File
RelativePath=".\Light.h">
</File>
<File
RelativePath=".\Pelican.h">
</File>
<File
RelativePath=".\PelicanTimer.h">
</File>
<File
RelativePath=".\Timer.h">
</File>
<File
RelativePath="TimerSet.h">
</File>
<File
RelativePath=".\pole.h">
</File>
</Filter>
<Filter
Name="DOS_Unix"
Filter="">
<File
RelativePath="..\DOS_Unix\Keyboard.h">
</File>
<File
RelativePath="..\DOS_Unix\Keyboard_DOS.cpp">
</File>
<File
RelativePath="..\DOS_Unix\Screen.h">
</File>
<File
RelativePath="..\DOS_Unix\Screen_DOS.cpp">
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
+141
View File
@@ -0,0 +1,141 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<SccProjectName>
</SccProjectName>
<SccLocalPath>
</SccLocalPath>
<ProjectGuid>{E1F2BA40-B169-8D69-78E1-868C8A785A9C}</ProjectGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\Release\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\Release\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\Debug\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\Debug\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader>
</PrecompiledHeader>
<PrecompiledHeaderOutputFile>.\Release/Ex11.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\Release/</AssemblerListingLocation>
<ObjectFileName>.\Release/</ObjectFileName>
<ProgramDataBaseFileName>.\Release/</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
</ClCompile>
<Link>
<AdditionalOptions>/MACHINE:I386 %(AdditionalOptions)</AdditionalOptions>
<AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>.\Release/Ex11.exe</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<ProgramDatabaseFile>.\Release/Ex11.pdb</ProgramDatabaseFile>
<SubSystem>Console</SubSystem>
</Link>
<Midl>
<TypeLibraryName>.\Release/Ex11.tlb</TypeLibraryName>
</Midl>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<RuntimeTypeInfo>true</RuntimeTypeInfo>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<PrecompiledHeaderOutputFile>.\Debug/Ex11.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\Debug/</AssemblerListingLocation>
<ObjectFileName>.\Debug/</ObjectFileName>
<ProgramDataBaseFileName>.\Debug/</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalIncludeDirectories>C:\course\397\DOS_Unix;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<AdditionalOptions>/MACHINE:I386 %(AdditionalOptions)</AdditionalOptions>
<AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>.\Debug/Ex11.exe</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>.\Debug/Ex11.pdb</ProgramDatabaseFile>
<SubSystem>Console</SubSystem>
</Link>
<Midl>
<TypeLibraryName>.\Debug/Ex11.tlb</TypeLibraryName>
</Midl>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="Light.cpp" />
<ClCompile Include="Pelican.cpp" />
<ClCompile Include="PelicanTimer.cpp" />
<ClCompile Include="Timer.cpp" />
<ClCompile Include="TimerSet.cpp" />
<ClCompile Include="main.cpp" />
<ClCompile Include="pole.cpp" />
<ClCompile Include="..\DOS_Unix\Keyboard_DOS.cpp" />
<ClCompile Include="..\DOS_Unix\Screen_DOS.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="Light.h" />
<ClInclude Include="Pelican.h" />
<ClInclude Include="PelicanTimer.h" />
<ClInclude Include="Timer.h" />
<ClInclude Include="TimerSet.h" />
<ClInclude Include="pole.h" />
<ClInclude Include="..\DOS_Unix\Keyboard.h" />
<ClInclude Include="..\DOS_Unix\Screen.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
+71
View File
@@ -0,0 +1,71 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{b96cbaea-8ae3-4716-865e-3aaf915fd0af}</UniqueIdentifier>
<Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{f948cebc-f590-4325-a5cc-fa8c85aa7733}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl</Extensions>
</Filter>
<Filter Include="DOS_Unix">
<UniqueIdentifier>{c3395356-0a3a-4c18-8b27-851ff1f2369a}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Light.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Pelican.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="PelicanTimer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Timer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="TimerSet.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="pole.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\DOS_Unix\Keyboard_DOS.cpp">
<Filter>DOS_Unix</Filter>
</ClCompile>
<ClCompile Include="..\DOS_Unix\Screen_DOS.cpp">
<Filter>DOS_Unix</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Light.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Pelican.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="PelicanTimer.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Timer.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="TimerSet.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="pole.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\DOS_Unix\Keyboard.h">
<Filter>DOS_Unix</Filter>
</ClInclude>
<ClInclude Include="..\DOS_Unix\Screen.h">
<Filter>DOS_Unix</Filter>
</ClInclude>
</ItemGroup>
</Project>
+3
View File
@@ -0,0 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
</Project>
+22
View File
@@ -0,0 +1,22 @@
#include "Light.h"
#include "CursesObj.h"
#include "Pelican.h"
#include "Screen.h"
#include <iostream>
Light::Light(std::string name, int x, int y, int color) : x(x), y(y), c(color), name(name) {}
Light::~Light() {
std::cout << "Deleting light (" << name << ", " << x << ", " << y << ", " << c << ")" << std::endl;
std::cout.flush();
}
void Light::set(LightState newState) {
state = newState;
Screen::write(name.c_str(), x, y, state == FLASH ? (128 + c) : (state == OFF ? 0 : c));
// 128 + color was used to make a character flash (but not any more)
}
Light::LightState Light::get(void) { return state; }
+30
View File
@@ -0,0 +1,30 @@
// ======================================================
//
// Represents a light, implemented as a string written
// to a console window
//
// ======================================================
#ifndef LIGHT_H
#define LIGHT_H
#include <string>
class Light {
public:
Light(std::string name, int x, int y, int color);
~Light();
enum LightState { ON, OFF, FLASH };
void set(LightState new_state);
LightState get(void);
private:
int c; // light colour
int x, y;
std::string name;
LightState state;
};
#endif
+66
View File
@@ -0,0 +1,66 @@
#include "Pelican.h"
#include "PelicanTimer.h"
#include "Pole.h"
Pelican::Pelican(int x, int y)
: pressed(false), RED_TIME(4), YELLOW_TIME(2), GREEN_TIME(3), FLASH_TIME(5), myPole(new Pole(x, y)),
state(GREEN_IDLE) {
myTimer = new PelicanTimer(*this, &Pelican::timerExpired);
myPole->setTrafficLights(getState());
myPole->setWaitLight(isPressed() ? Light::ON : Light::OFF);
}
Pelican::~Pelican() { delete myPole; }
void Pelican::press(void) {
if (state == GREEN_IDLE) {
state = YELLOW_STATE;
myTimer->timeoutRequest(YELLOW_TIME);
pressed = true;
myPole->setTrafficLights(getState());
myPole->setWaitLight(isPressed() ? Light::ON : Light::OFF);
} else if (state != RED_STATE) {
pressed = true;
myPole->setTrafficLights(getState());
myPole->setWaitLight(isPressed() ? Light::ON : Light::OFF);
}
}
void Pelican::timerExpired(void) {
switch (state) {
case RED_STATE:
state = YELLOW_FLASHING;
myTimer->timeoutRequest(FLASH_TIME);
break;
case YELLOW_FLASHING:
state = GREEN_TIMING;
myTimer->timeoutRequest(GREEN_TIME);
break;
case GREEN_TIMING:
if (pressed) {
state = YELLOW_STATE;
myTimer->timeoutRequest(YELLOW_TIME);
} else {
state = GREEN_IDLE;
}
break;
case GREEN_IDLE:
// should never happen
break;
case YELLOW_STATE:
state = RED_STATE;
pressed = false;
myTimer->timeoutRequest(RED_TIME);
break;
}
myPole->setTrafficLights(getState());
myPole->setWaitLight(isPressed() ? Light::ON : Light::OFF);
}
+53
View File
@@ -0,0 +1,53 @@
// ======================================================
//
// Represents a Pelican crossing
//
// ======================================================
#ifndef PELICAN_H
#define PELICAN_H
class PelicanTimer;
class Pole;
class Pelican {
public:
Pelican(int x, int y);
~Pelican();
// call when the WAIT button has been pressed
void press(void);
// states that a Pelican can be in
enum PelicanState { RED_STATE, YELLOW_FLASHING, GREEN_TIMING, GREEN_IDLE, YELLOW_STATE };
bool isPressed() const { return pressed; }
PelicanState getState() const { return state; }
private:
// state that this Pelican is in
PelicanState state;
// called by PeleicanTimer when the lights need to change
void timerExpired(void);
const unsigned int RED_TIME;
const unsigned int YELLOW_TIME;
const unsigned int GREEN_TIME;
const unsigned int FLASH_TIME;
// indicates whether the WAIT light should be on
bool pressed;
Pole *myPole;
// Timer that indicates when the lights should change
PelicanTimer *myTimer;
private:
// prevent general use of copy ctor and operator=
Pelican(const Pelican &);
Pelican &operator=(const Pelican &);
};
#endif
+11
View File
@@ -0,0 +1,11 @@
#include "PelicanTimer.h"
PelicanTimer::PelicanTimer(Pelican &target, TargetFunc targetFunc) : myTarget(target), myTargetFunc(targetFunc) {}
void PelicanTimer::tick() {
if (isExpired()) {
(myTarget.*myTargetFunc)();
}
}
+27
View File
@@ -0,0 +1,27 @@
// ======================================================
//
// This class specializes the Timer to enable it to
// stimulate a Pelican
//
// ======================================================
#ifndef PELICANTIMER_H
#define PELICANTIMER_H
#include "Pelican.h"
#include "Timer.h"
class PelicanTimer : public Timer {
public:
typedef void (Pelican::*TargetFunc)();
PelicanTimer(Pelican &target, TargetFunc targetFunc);
virtual void tick();
private:
Pelican &myTarget;
TargetFunc myTargetFunc;
};
#endif
+59
View File
@@ -0,0 +1,59 @@
#include "Pole.h"
#include "Screen.h"
Pole::Pole(int x, int y) : waitLight(new Light("WAIT", x + 6, y + 12, Screen::WHITE)) {
using namespace Screen; // we will discuss namespaces in the course
lights[RED_LIGHT] = new Light("*", x + 11, y + 3, RED);
lights[RED_MAN] = new Light("*<-=", x + 6, y + 4, RED);
lights[YELLOW_LIGHT] = new Light("*", x + 11, y + 5, YELLOW);
lights[GREEN_LIGHT] = new Light("*", x + 11, y + 7, GREEN);
lights[GREEN_MAN] = new Light("*|-<", x + 6, y + 7, GREEN);
write(" _____ ", x, ++y, GRAY);
write(" /___ /| ", x, ++y, GRAY);
write(" | | | ", x, ++y, GRAY);
write(" | |/| ", x, ++y, GRAY);
write(" |____| | ", x, ++y, GRAY);
write(" | |/| ", x, ++y, GRAY);
write(" | | | ", x, ++y, GRAY);
write(" |____|/ ", x, ++y, GRAY);
write(" _||__ ", x, ++y, GRAY);
write(" /___ /| ", x, ++y, GRAY);
write(" | | | ", x, ++y, GRAY);
write(" | | | ", x, ++y, GRAY);
write(" |____|/ ", x, ++y, GRAY);
write(" || ", x, ++y, GRAY);
write(" || ", x, ++y, GRAY);
write(" || ", x, ++y, GRAY);
write(" || ", x, ++y, GRAY);
write(" || ", x, ++y, GRAY);
write(" || ", x, ++y, GRAY);
write("========||===========", x, ++y, GRAY);
write(" / || / ", x, ++y, GRAY);
write("_ /_________ /_ ", x, ++y, GRAY);
write("/ / ", x, ++y, GRAY);
}
Pole::~Pole() {
for (int i = 0; i < sizeof lights / sizeof(lights[0]); ++i)
delete lights[i];
delete waitLight;
}
void Pole::setTrafficLights(Pelican::PelicanState state) {
static const Light::LightState LightStates[Pelican::YELLOW_STATE + 1][RED_MAN + 1] = {
// red yellow green green man red man
{Light::ON, Light::OFF, Light::OFF, Light::ON, Light::OFF}, // red
{Light::OFF, Light::FLASH, Light::OFF, Light::FLASH, Light::OFF}, // y flash
{Light::OFF, Light::OFF, Light::ON, Light::OFF, Light::ON}, // g time
{Light::OFF, Light::OFF, Light::ON, Light::OFF, Light::ON}, // g idle
{Light::OFF, Light::ON, Light::OFF, Light::OFF, Light::ON} // yellow
};
for (int i = RED_LIGHT; i <= RED_MAN; i++) {
lights[i]->set(LightStates[state][i]);
}
}
void Pole::setWaitLight(bool pressed) { waitLight->set(pressed ? Light::ON : Light::OFF); }
+23
View File
@@ -0,0 +1,23 @@
#ifndef POLE_H
#define POLE_H
#include "Light.h"
#include "Pelican.h"
class Pole {
public:
Pole(int x, int y);
~Pole();
void setTrafficLights(Pelican::PelicanState state);
void setWaitLight(bool pressed);
private:
enum LightName { RED_LIGHT, YELLOW_LIGHT, GREEN_LIGHT, GREEN_MAN, RED_MAN };
Light *lights[RED_MAN + 1];
Light *waitLight;
};
#endif
+17
View File
@@ -0,0 +1,17 @@
#include "Timer.h"
#include "TimerSet.h"
void Timer::timeoutRequest(int seconds) { timeToGo = seconds; }
Timer::Timer() : timeToGo(-1) { theTimerSet.addATimer(this); }
bool Timer::isExpired() {
if (timeToGo > 0) {
if (--timeToGo == 0) {
return true;
}
}
return false;
}
+27
View File
@@ -0,0 +1,27 @@
// ======================================================
//
// A general-purpose countdown timer
// To use this class, specialize it
// and override tick()
//
// ======================================================
#ifndef TIMER_H
#define TIMER_H
class Timer {
public:
Timer();
void timeoutRequest(int seconds);
virtual void tick() = 0;
protected:
bool isExpired();
private:
int timeToGo;
};
#endif
+24
View File
@@ -0,0 +1,24 @@
#include "TimerSet.h"
#include "Timer.h"
TimerSet theTimerSet;
TimerSet::TimerSet() : timersInUse(0), previousTime(time(&previousTime)) {}
void TimerSet::addATimer(Timer *t) { timers[timersInUse++] = t; }
void TimerSet::pollAllTimers() {
std::time_t timeNow;
if (time(&timeNow) > previousTime) {
previousTime = timeNow;
for (int i = 0; i < timersInUse; ++i) {
timers[i]->tick();
}
}
}
+23
View File
@@ -0,0 +1,23 @@
#ifndef TIMERSET_H
#define TIMERSET_H
#include <ctime>
class Timer;
class TimerSet {
public:
TimerSet();
void pollAllTimers();
void addATimer(Timer *);
private:
Timer *timers[40];
int timersInUse;
std::time_t previousTime;
};
extern TimerSet theTimerSet;
#endif
+29
View File
@@ -0,0 +1,29 @@
#include "Keyboard.h"
#include "Pelican.h"
#include "TimerSet.h"
#include <cctype> // provides toupper()
int main() {
Keyboard kbd;
Pelican thePelican(30, 0);
char c = 0;
while (std::toupper(c) != 'Q') { // loop until 'Q' is pressed
while (!kbd.isCharAvail()) {
theTimerSet.pollAllTimers(); // no key press to process, poll the timers
}
c = kbd.getChar(); // get the character
if (c == ' ') {
// it's a space, so press the WAIT button
thePelican.press();
}
}
return 0;
}
+2
View File
@@ -0,0 +1,2 @@
BASEOBJS = \
Light.o main.o Pelican.o PelicanTimer.o Pole.o Timer.o TimerSet.o
+17
View File
@@ -0,0 +1,17 @@
COMPILER = gcc
FLAGS =
INCLUDES = -I/usr/local/include/c++/3.4.2 -I../DOS_Unix
ARCHIVES = -L/usr/local/lib/gcc/sparc-sun-solaris2.7/3.4.2 -L/usr/local/lib -L/usr/lib
UNIX_OBJS = ../DOS_Unix/CursesObj.o ../DOS_Unix/Keyboard_Unix.o ../DOS_Unix/Screen_Unix.o
include make.mk
.SUFFIXES: .cpp .o
all: pelican
.cpp.o:
$(COMPILER) $(INCLUDES) -frepo -c $(FLAGS) $*.cpp
pelican : $(BASEOBJS)
$(COMPILER) $(ARCHIVES) -o pelican -lcurses $(BASEOBJS) $(UNIX_OBJS) -lcurses -lstdc++ -static
+13
View File
@@ -0,0 +1,13 @@
# Ex21
cmat_add_exercise(Ex21
GUI
SOURCES
Light.cpp
Main.cpp
Pelican.cpp
PelicanTimer.cpp
Pole.cpp
Timer.cpp
TimerSet.cpp
)
+20
View File
@@ -0,0 +1,20 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.21005.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Ex21", "Ex21.vcxproj", "{AC7B29B3-9F42-7C36-686F-2F829309B86D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{AC7B29B3-9F42-7C36-686F-2F829309B86D}.Debug|Win32.ActiveCfg = Debug|Win32
{AC7B29B3-9F42-7C36-686F-2F829309B86D}.Debug|Win32.Build.0 = Debug|Win32
{AC7B29B3-9F42-7C36-686F-2F829309B86D}.Release|Win32.ActiveCfg = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
Binary file not shown.
+185
View File
@@ -0,0 +1,185 @@
<?xml version="1.0" encoding = "Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.00"
Name="Ex21"
SccProjectName="&quot;$/Course/397/Ex21&quot;, DCAAAAAA"
SccLocalPath=".">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Release|Win32"
OutputDirectory=".\Release"
IntermediateDirectory=".\Release"
ConfigurationType="1"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
InlineFunctionExpansion="1"
PreprocessorDefinitions="WIN32,NDEBUG,_CONSOLE"
StringPooling="TRUE"
RuntimeLibrary="4"
EnableFunctionLevelLinking="TRUE"
UsePrecompiledHeader="2"
PrecompiledHeaderFile=".\Release/Ex21.pch"
AssemblerListingLocation=".\Release/"
ObjectFile=".\Release/"
ProgramDataBaseFileName=".\Release/"
WarningLevel="3"
SuppressStartupBanner="TRUE"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="odbc32.lib odbccp32.lib"
OutputFile=".\Release/Ex21.exe"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
ProgramDatabaseFile=".\Release/Ex21.pdb"
SubSystem="1"/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Release/Ex21.tlb"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
</Configuration>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\Debug"
IntermediateDirectory=".\Debug"
ConfigurationType="1"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32,_DEBUG,_CONSOLE"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
RuntimeTypeInfo="TRUE"
UsePrecompiledHeader="2"
PrecompiledHeaderFile=".\Debug/Ex21.pch"
AssemblerListingLocation=".\Debug/"
ObjectFile=".\Debug/"
ProgramDataBaseFileName=".\Debug/"
WarningLevel="3"
SuppressStartupBanner="TRUE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="odbc32.lib odbccp32.lib"
OutputFile=".\Debug/Ex21.exe"
LinkIncremental="2"
SuppressStartupBanner="TRUE"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\Debug/Ex21.pdb"
SubSystem="1"/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Debug/Ex21.tlb"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
</Configuration>
</Configurations>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
<File
RelativePath=".\Light.cpp">
</File>
<File
RelativePath=".\Main.cpp">
</File>
<File
RelativePath=".\Pelican.cpp">
</File>
<File
RelativePath=".\PelicanTimer.cpp">
</File>
<File
RelativePath="Pole.cpp">
</File>
<File
RelativePath=".\Timer.cpp">
</File>
<File
RelativePath=".\TimerSet.cpp">
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl">
<File
RelativePath=".\Light.h">
</File>
<File
RelativePath=".\Pelican.h">
</File>
<File
RelativePath=".\PelicanTimer.h">
</File>
<File
RelativePath="Pole.h">
</File>
<File
RelativePath=".\Timer.h">
</File>
<File
RelativePath=".\TimerSet.h">
</File>
</Filter>
<Filter
Name="DOS_Unix"
Filter="">
<File
RelativePath="..\DOS_Unix\Keyboard.h">
</File>
<File
RelativePath="..\DOS_Unix\Keyboard_DOS.cpp">
</File>
<File
RelativePath="..\DOS_Unix\Screen.h">
</File>
<File
RelativePath="..\DOS_Unix\Screen_DOS.cpp">
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
+141
View File
@@ -0,0 +1,141 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<SccProjectName>
</SccProjectName>
<SccLocalPath>
</SccLocalPath>
<ProjectGuid>{AC7B29B3-9F42-7C36-686F-2F829309B86D}</ProjectGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\Release\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\Release\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\Debug\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\Debug\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader>
</PrecompiledHeader>
<PrecompiledHeaderOutputFile>.\Release/Ex21.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\Release/</AssemblerListingLocation>
<ObjectFileName>.\Release/</ObjectFileName>
<ProgramDataBaseFileName>.\Release/</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
</ClCompile>
<Link>
<AdditionalOptions>/MACHINE:I386 %(AdditionalOptions)</AdditionalOptions>
<AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>.\Release/Ex21.exe</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<ProgramDatabaseFile>.\Release/Ex21.pdb</ProgramDatabaseFile>
<SubSystem>Console</SubSystem>
</Link>
<Midl>
<TypeLibraryName>.\Release/Ex21.tlb</TypeLibraryName>
</Midl>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<RuntimeTypeInfo>true</RuntimeTypeInfo>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<PrecompiledHeaderOutputFile>.\Debug/Ex21.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\Debug/</AssemblerListingLocation>
<ObjectFileName>.\Debug/</ObjectFileName>
<ProgramDataBaseFileName>.\Debug/</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalIncludeDirectories>C:\course\397\DOS_Unix;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<AdditionalOptions>/MACHINE:I386 %(AdditionalOptions)</AdditionalOptions>
<AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>.\Debug/Ex21.exe</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>.\Debug/Ex21.pdb</ProgramDatabaseFile>
<SubSystem>Console</SubSystem>
</Link>
<Midl>
<TypeLibraryName>.\Debug/Ex21.tlb</TypeLibraryName>
</Midl>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="Light.cpp" />
<ClCompile Include="Main.cpp" />
<ClCompile Include="Pelican.cpp" />
<ClCompile Include="PelicanTimer.cpp" />
<ClCompile Include="Pole.cpp" />
<ClCompile Include="Timer.cpp" />
<ClCompile Include="TimerSet.cpp" />
<ClCompile Include="..\DOS_Unix\Keyboard_DOS.cpp" />
<ClCompile Include="..\DOS_Unix\Screen_DOS.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="Light.h" />
<ClInclude Include="Pelican.h" />
<ClInclude Include="PelicanTimer.h" />
<ClInclude Include="Pole.h" />
<ClInclude Include="Timer.h" />
<ClInclude Include="TimerSet.h" />
<ClInclude Include="..\DOS_Unix\Keyboard.h" />
<ClInclude Include="..\DOS_Unix\Screen.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
+71
View File
@@ -0,0 +1,71 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4b16368f-6693-40c4-8fcf-13a85f344069}</UniqueIdentifier>
<Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{2ec889ee-bec0-46c7-8125-b8c144b9328a}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl</Extensions>
</Filter>
<Filter Include="DOS_Unix">
<UniqueIdentifier>{a57625e1-03b9-42e5-93c8-03d083fc7d09}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Light.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Pelican.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="PelicanTimer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Pole.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Timer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="TimerSet.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\DOS_Unix\Keyboard_DOS.cpp">
<Filter>DOS_Unix</Filter>
</ClCompile>
<ClCompile Include="..\DOS_Unix\Screen_DOS.cpp">
<Filter>DOS_Unix</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Light.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Pelican.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="PelicanTimer.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Pole.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Timer.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="TimerSet.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\DOS_Unix\Keyboard.h">
<Filter>DOS_Unix</Filter>
</ClInclude>
<ClInclude Include="..\DOS_Unix\Screen.h">
<Filter>DOS_Unix</Filter>
</ClInclude>
</ItemGroup>
</Project>
+3
View File
@@ -0,0 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
</Project>
+19
View File
@@ -0,0 +1,19 @@
#include "Light.h"
#include "Pelican.h"
#include "Screen.h"
#include <iostream>
Light::Light(std::string name, int x, int y, int color) : x(x), y(y), c(color), name(name) {}
Light::~Light() {
std::cout << "Deleting light (" << name << ", " << x << ", " << y << ", " << c << ")"
<< "\n";
}
void Light::set(LightState newState) {
state = newState;
Screen::write(name.c_str(), x, y, state == FLASH ? (128 + c) : (state == OFF ? 0 : c));
// 128 + color was used to make a character flash (but not any more)
}
Light::LightState Light::get(void) { return state; }
+30
View File
@@ -0,0 +1,30 @@
// ======================================================
//
// Represents a light, implemented as a string written
// to a console window
//
// ======================================================
#ifndef LIGHT_H
#define LIGHT_H
#include <string>
class Light {
public:
Light(std::string name, int x, int y, int color);
~Light();
enum LightState { ON, OFF, FLASH };
void set(LightState new_state);
LightState get(void);
private:
int c; // light colour
int x, y;
std::string name;
LightState state;
};
#endif
+31
View File
@@ -0,0 +1,31 @@
#include "Keyboard.h"
#include "Pelican.h"
#include "TimerSet.h"
#include <cctype> // provides toupper()
static TimerSet theTimerSet;
int main() {
Keyboard kbd;
Pelican thePelican(30, 0);
char c = 0;
while (std::toupper(c) != 'Q') { // loop until 'Q' is pressed
while (!kbd.isCharAvail()) {
theTimerSet.pollAllTimers(); // no key press to process, poll the timers
}
c = kbd.getChar(); // get the character
if (c == ' ') {
// it's a space, so press the WAIT button
thePelican.press();
}
}
return 0;
}
+65
View File
@@ -0,0 +1,65 @@
#include "Pelican.h"
#include "PelicanTimer.h"
#include "Pole.h"
Pelican::Pelican(int x, int y)
: pressed(false), RED_TIME(4), YELLOW_TIME(2), GREEN_TIME(3), FLASH_TIME(5), myPole(new Pole(x, y)),
state(GREEN_IDLE) {
myTimer = new PelicanTimer(*this, &Pelican::timerExpired);
myPole->setTrafficLights(getState());
myPole->setWaitLight(isPressed());
}
Pelican::~Pelican() { delete myPole; }
void Pelican::press(void) {
if (state == GREEN_IDLE) {
state = YELLOW_STATE;
myTimer->timeoutRequest(YELLOW_TIME);
pressed = true;
myPole->setTrafficLights(getState());
myPole->setWaitLight(isPressed());
} else if (state != RED_STATE) {
pressed = true;
myPole->setTrafficLights(getState());
myPole->setWaitLight(isPressed());
}
}
void Pelican::timerExpired(void) {
switch (state) {
case RED_STATE:
state = YELLOW_FLASHING;
myTimer->timeoutRequest(FLASH_TIME);
break;
case YELLOW_FLASHING:
state = GREEN_TIMING;
myTimer->timeoutRequest(GREEN_TIME);
break;
case GREEN_TIMING:
if (pressed) {
state = YELLOW_STATE;
myTimer->timeoutRequest(YELLOW_TIME);
} else {
state = GREEN_IDLE;
}
break;
case GREEN_IDLE:
// should never happen
break;
case YELLOW_STATE:
state = RED_STATE;
pressed = false;
myTimer->timeoutRequest(RED_TIME);
break;
}
myPole->setTrafficLights(getState());
myPole->setWaitLight(isPressed());
}
+53
View File
@@ -0,0 +1,53 @@
// ======================================================
//
// Represents a Pelican crossing
//
// ======================================================
#ifndef PELICAN_H
#define PELICAN_H
class PelicanTimer;
class Pole;
class Pelican {
public:
Pelican(int x, int y);
~Pelican();
// call when the WAIT button has been pressed
void press(void);
// states that a Pelican can be in
enum PelicanState { RED_STATE, YELLOW_FLASHING, GREEN_TIMING, GREEN_IDLE, YELLOW_STATE };
bool isPressed() const { return pressed; }
PelicanState getState() const { return state; }
private:
// state that this Pelican is in
PelicanState state;
// called by PeleicanTimer when the lights need to change
void timerExpired(void);
const unsigned int RED_TIME;
const unsigned int YELLOW_TIME;
const unsigned int GREEN_TIME;
const unsigned int FLASH_TIME;
// indicates whether the WAIT light should be on
bool pressed;
Pole *myPole;
// Timer that indicates when the lights should change
PelicanTimer *myTimer;
private:
// prevent general use of copy ctor and operator=
Pelican(const Pelican &);
Pelican &operator=(const Pelican &);
};
#endif
+10
View File
@@ -0,0 +1,10 @@
#include "PelicanTimer.h"
PelicanTimer::PelicanTimer(Pelican &target, TargetFunc targetFunc) : myTarget(target), myTargetFunc(targetFunc) {}
void PelicanTimer::tick() {
if (isExpired()) {
(myTarget.*myTargetFunc)();
}
}
+31
View File
@@ -0,0 +1,31 @@
// ======================================================
//
// This class specializes the Timer to enable it to
// stimulate a Pelican
//
// ======================================================
#ifndef PELICANTIMER_H
#define PELICANTIMER_H
#include "Pelican.h"
#include "Timer.h"
class PelicanTimer : public Timer {
public:
typedef void (Pelican::*TargetFunc)();
PelicanTimer(Pelican &target, TargetFunc targetFunc);
// TODO: Remove this function
virtual void tick();
// TODO: Add override of virtual function Timer::doExpired
// (this is the "primitive step" of the template method pattern)
private:
Pelican &myTarget;
TargetFunc myTargetFunc;
};
#endif
+59
View File
@@ -0,0 +1,59 @@
#include "Pole.h"
#include "Screen.h"
Pole::Pole(int x, int y) : waitLight(new Light("WAIT", x + 6, y + 12, Screen::WHITE)) {
using namespace Screen;
lights[RED_LIGHT] = new Light("*", x + 11, y + 3, RED);
lights[RED_MAN] = new Light("*<-=", x + 6, y + 4, RED);
lights[YELLOW_LIGHT] = new Light("*", x + 11, y + 5, YELLOW);
lights[GREEN_LIGHT] = new Light("*", x + 11, y + 7, GREEN);
lights[GREEN_MAN] = new Light("*|-<", x + 6, y + 7, GREEN);
write(" _____ ", x, ++y, GRAY);
write(" /___ /| ", x, ++y, GRAY);
write(" | | | ", x, ++y, GRAY);
write(" | |/| ", x, ++y, GRAY);
write(" |____| | ", x, ++y, GRAY);
write(" | |/| ", x, ++y, GRAY);
write(" | | | ", x, ++y, GRAY);
write(" |____|/ ", x, ++y, GRAY);
write(" _||__ ", x, ++y, GRAY);
write(" /___ /| ", x, ++y, GRAY);
write(" | | | ", x, ++y, GRAY);
write(" | | | ", x, ++y, GRAY);
write(" |____|/ ", x, ++y, GRAY);
write(" || ", x, ++y, GRAY);
write(" || ", x, ++y, GRAY);
write(" || ", x, ++y, GRAY);
write(" || ", x, ++y, GRAY);
write(" || ", x, ++y, GRAY);
write(" || ", x, ++y, GRAY);
write("========||===========", x, ++y, GRAY);
write(" / || / ", x, ++y, GRAY);
write("_ /_________ /_ ", x, ++y, GRAY);
write("/ / ", x, ++y, GRAY);
}
Pole::~Pole() {
for (int i = 0; i < sizeof lights / sizeof(lights[0]); ++i)
delete lights[i];
delete waitLight;
}
void Pole::setTrafficLights(Pelican::PelicanState state) {
static const Light::LightState LightStates[Pelican::YELLOW_STATE + 1][RED_MAN + 1] = {
// red yellow green green man red man
{Light::ON, Light::OFF, Light::OFF, Light::ON, Light::OFF}, // red
{Light::OFF, Light::FLASH, Light::OFF, Light::FLASH, Light::OFF}, // y flash
{Light::OFF, Light::OFF, Light::ON, Light::OFF, Light::ON}, // g time
{Light::OFF, Light::OFF, Light::ON, Light::OFF, Light::ON}, // g idle
{Light::OFF, Light::ON, Light::OFF, Light::OFF, Light::ON} // yellow
};
for (int i = RED_LIGHT; i <= RED_MAN; i++) {
lights[i]->set(LightStates[state][i]);
}
}
void Pole::setWaitLight(bool pressed) { waitLight->set(pressed ? Light::ON : Light::OFF); }
+23
View File
@@ -0,0 +1,23 @@
#ifndef POLE_H
#define POLE_H
#include "Light.h"
#include "Pelican.h"
class Pole {
public:
Pole(int x, int y);
~Pole();
void setTrafficLights(Pelican::PelicanState state);
void setWaitLight(bool pressed);
private:
enum LightName { RED_LIGHT, YELLOW_LIGHT, GREEN_LIGHT, GREEN_MAN, RED_MAN };
Light *lights[RED_MAN + 1];
Light *waitLight;
};
#endif
+18
View File
@@ -0,0 +1,18 @@
#include "Timer.h"
#include "TimerSet.h"
static TimerSet theTimerSet;
void Timer::timeoutRequest(int seconds) { timeToGo = seconds; }
Timer::Timer() : timeToGo(-1) { theTimerSet.addATimer(this); }
bool Timer::isExpired() {
if (timeToGo > 0) {
if (--timeToGo == 0) {
return true;
}
}
return false;
}
+27
View File
@@ -0,0 +1,27 @@
// ======================================================
//
// A general-purpose countdown timer
// To use this class, specialize it
// and override tick()
//
// ======================================================
#ifndef TIMER_H
#define TIMER_H
class Timer {
public:
Timer();
void timeoutRequest(int seconds);
virtual void tick() = 0;
protected:
bool isExpired();
private:
int timeToGo;
};
#endif
+22
View File
@@ -0,0 +1,22 @@
// TODO: Add Singleton code
#include "TimerSet.h"
#include "Timer.h"
TimerSet::TimerSet() : timersInUse(0), previousTime(time(&previousTime)) {}
void TimerSet::addATimer(Timer *t) { timers[timersInUse++] = t; }
void TimerSet::pollAllTimers() {
std::time_t timeNow;
if (time(&timeNow) > previousTime) {
previousTime = timeNow;
for (int i = 0; i < timersInUse; ++i) {
timers[i]->tick();
}
}
}
+23
View File
@@ -0,0 +1,23 @@
#ifndef TIMERSET_H
#define TIMERSET_H
#include <ctime>
class Timer;
class TimerSet {
public:
TimerSet();
void pollAllTimers();
void addATimer(Timer *);
private:
Timer *timers[40];
int timersInUse;
std::time_t previousTime;
};
extern TimerSet theTimerSet;
#endif
+13
View File
@@ -0,0 +1,13 @@
# Ex22
cmat_add_exercise(Ex22
GUI
SOURCES
Light.cpp
main.cpp
Pelican.cpp
PelicanTimer.cpp
Pole.cpp
Timer.cpp
TimerSet.cpp
)
+20
View File
@@ -0,0 +1,20 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.21005.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Ex22", "Ex22.vcxproj", "{C2EDBD25-9006-0438-220A-8766E6F352A8}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{C2EDBD25-9006-0438-220A-8766E6F352A8}.Debug|Win32.ActiveCfg = Debug|Win32
{C2EDBD25-9006-0438-220A-8766E6F352A8}.Debug|Win32.Build.0 = Debug|Win32
{C2EDBD25-9006-0438-220A-8766E6F352A8}.Release|Win32.ActiveCfg = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
Binary file not shown.
+182
View File
@@ -0,0 +1,182 @@
<?xml version="1.0" encoding = "Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.00"
Name="Ex22"
SccProjectName="&quot;$/Course/397/Ex22&quot;, UHAAAAAA"
SccLocalPath=".">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\Debug"
IntermediateDirectory=".\Debug"
ConfigurationType="1"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32,_DEBUG,_CONSOLE"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
RuntimeTypeInfo="TRUE"
UsePrecompiledHeader="2"
PrecompiledHeaderFile=".\Debug/Ex22.pch"
AssemblerListingLocation=".\Debug/"
ObjectFile=".\Debug/"
ProgramDataBaseFileName=".\Debug/"
WarningLevel="3"
SuppressStartupBanner="TRUE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="odbc32.lib odbccp32.lib"
OutputFile=".\Debug/Ex22.exe"
LinkIncremental="2"
SuppressStartupBanner="TRUE"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\Debug/Ex22.pdb"
SubSystem="1"/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Debug/Ex22.tlb"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory=".\Release"
IntermediateDirectory=".\Release"
ConfigurationType="1"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
InlineFunctionExpansion="1"
PreprocessorDefinitions="WIN32,NDEBUG,_CONSOLE"
StringPooling="TRUE"
RuntimeLibrary="4"
EnableFunctionLevelLinking="TRUE"
UsePrecompiledHeader="2"
PrecompiledHeaderFile=".\Release/Ex22.pch"
AssemblerListingLocation=".\Release/"
ObjectFile=".\Release/"
ProgramDataBaseFileName=".\Release/"
WarningLevel="3"
SuppressStartupBanner="TRUE"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="odbc32.lib odbccp32.lib"
OutputFile=".\Release/Ex22.exe"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
ProgramDatabaseFile=".\Release/Ex22.pdb"
SubSystem="1"/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Release/Ex22.tlb"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
</Configuration>
</Configurations>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
<File
RelativePath="Light.cpp">
</File>
<File
RelativePath="Pelican.cpp">
</File>
<File
RelativePath="PelicanTimer.cpp">
</File>
<File
RelativePath="Pole.cpp">
</File>
<File
RelativePath="Timer.cpp">
</File>
<File
RelativePath="TimerSet.cpp">
</File>
<File
RelativePath=".\main.cpp">
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl">
<File
RelativePath="Pelican.h">
</File>
<File
RelativePath="PelicanTimer.h">
</File>
<File
RelativePath="Pole.h">
</File>
<File
RelativePath="Timer.h">
</File>
<File
RelativePath="TimerSet.h">
</File>
</Filter>
<Filter
Name="DOS_Unix"
Filter="">
<File
RelativePath="..\DOS_Unix\Keyboard.h">
</File>
<File
RelativePath="..\DOS_Unix\Keyboard_DOS.cpp">
</File>
<File
RelativePath="..\DOS_Unix\Screen.h">
</File>
<File
RelativePath="..\DOS_Unix\Screen_DOS.cpp">
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
+141
View File
@@ -0,0 +1,141 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<SccProjectName>
</SccProjectName>
<SccLocalPath>
</SccLocalPath>
<ProjectGuid>{C2EDBD25-9006-0438-220A-8766E6F352A8}</ProjectGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\Debug\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\Debug\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\Release\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\Release\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<RuntimeTypeInfo>true</RuntimeTypeInfo>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<PrecompiledHeaderOutputFile>.\Debug/Ex22.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\Debug/</AssemblerListingLocation>
<ObjectFileName>.\Debug/</ObjectFileName>
<ProgramDataBaseFileName>.\Debug/</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalIncludeDirectories>C:\course\397\DOS_Unix;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<AdditionalOptions>/MACHINE:I386 %(AdditionalOptions)</AdditionalOptions>
<AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>.\Debug/Ex22.exe</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>.\Debug/Ex22.pdb</ProgramDatabaseFile>
<SubSystem>Console</SubSystem>
</Link>
<Midl>
<TypeLibraryName>.\Debug/Ex22.tlb</TypeLibraryName>
</Midl>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader>
</PrecompiledHeader>
<PrecompiledHeaderOutputFile>.\Release/Ex22.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\Release/</AssemblerListingLocation>
<ObjectFileName>.\Release/</ObjectFileName>
<ProgramDataBaseFileName>.\Release/</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
</ClCompile>
<Link>
<AdditionalOptions>/MACHINE:I386 %(AdditionalOptions)</AdditionalOptions>
<AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>.\Release/Ex22.exe</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<ProgramDatabaseFile>.\Release/Ex22.pdb</ProgramDatabaseFile>
<SubSystem>Console</SubSystem>
</Link>
<Midl>
<TypeLibraryName>.\Release/Ex22.tlb</TypeLibraryName>
</Midl>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="Light.cpp" />
<ClCompile Include="Pelican.cpp" />
<ClCompile Include="PelicanTimer.cpp" />
<ClCompile Include="Pole.cpp" />
<ClCompile Include="Timer.cpp" />
<ClCompile Include="TimerSet.cpp" />
<ClCompile Include="main.cpp" />
<ClCompile Include="..\DOS_Unix\Keyboard_DOS.cpp" />
<ClCompile Include="..\DOS_Unix\Screen_DOS.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="Light.h" />
<ClInclude Include="Pelican.h" />
<ClInclude Include="PelicanTimer.h" />
<ClInclude Include="Pole.h" />
<ClInclude Include="Timer.h" />
<ClInclude Include="TimerSet.h" />
<ClInclude Include="..\DOS_Unix\Keyboard.h" />
<ClInclude Include="..\DOS_Unix\Screen.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
+71
View File
@@ -0,0 +1,71 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{17deccef-8801-49d5-8ba1-c5db56fa73c0}</UniqueIdentifier>
<Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{eaf1391b-78b1-4db8-adb1-2585eaedd6e7}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl</Extensions>
</Filter>
<Filter Include="DOS_Unix">
<UniqueIdentifier>{f8ec245a-126d-413b-8f31-4f57d4342719}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Light.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Pelican.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="PelicanTimer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Pole.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Timer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="TimerSet.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\DOS_Unix\Keyboard_DOS.cpp">
<Filter>DOS_Unix</Filter>
</ClCompile>
<ClCompile Include="..\DOS_Unix\Screen_DOS.cpp">
<Filter>DOS_Unix</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Pelican.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="PelicanTimer.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Pole.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Timer.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="TimerSet.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\DOS_Unix\Keyboard.h">
<Filter>DOS_Unix</Filter>
</ClInclude>
<ClInclude Include="..\DOS_Unix\Screen.h">
<Filter>DOS_Unix</Filter>
</ClInclude>
<ClInclude Include="Light.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>
+3
View File
@@ -0,0 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
</Project>
+21
View File
@@ -0,0 +1,21 @@
#include "Light.h"
#include "Pelican.h"
#include "Screen.h"
#include <iostream>
Light::Light(std::string name, int x, int y, int color) : x(x), y(y), c(color), name(name) {}
Light::~Light() {
std::cout << "Deleting light (" << name << ", " << x << ", " << y << ", " << c << ")"
<< "\n";
}
void Light::set(LightState newState) {
state = newState;
Screen::write(name.c_str(), x, y, state == FLASH ? (128 + c) : (state == OFF ? 0 : c));
// 128 + color was used to make a character flash (but not any more)
}
Light::LightState Light::get(void) { return state; }
+30
View File
@@ -0,0 +1,30 @@
// ======================================================
//
// Represents a light, implemented as a string written
// to a console window
//
// ======================================================
#ifndef LIGHT_H
#define LIGHT_H
#include <string>
class Light {
public:
Light(std::string name, int x, int y, int color);
~Light();
enum LightState { ON, OFF, FLASH };
void set(LightState new_state);
LightState get(void);
private:
int c; // light colour
int x, y;
std::string name;
LightState state;
};
#endif
+66
View File
@@ -0,0 +1,66 @@
#include "Pelican.h"
#include "PelicanTimer.h"
#include "Pole.h"
Pelican::Pelican(int x, int y)
: pressed(false), RED_TIME(4), YELLOW_TIME(2), GREEN_TIME(3), FLASH_TIME(5), myPole(new Pole(x, y)),
state(GREEN_IDLE) {
myTimer = new PelicanTimer(*this, &Pelican::timerExpired);
myPole->setTrafficLights(getState());
myPole->setWaitLight(isPressed());
}
Pelican::~Pelican() { delete myPole; }
void Pelican::press(void) {
if (state == GREEN_IDLE) {
state = YELLOW_STATE;
myTimer->timeoutRequest(YELLOW_TIME);
pressed = true;
myPole->setTrafficLights(getState());
myPole->setWaitLight(isPressed());
} else if (state != RED_STATE) {
pressed = true;
myPole->setTrafficLights(getState());
myPole->setWaitLight(isPressed());
}
}
void Pelican::timerExpired(void) {
switch (state) {
case RED_STATE:
state = YELLOW_FLASHING;
myTimer->timeoutRequest(FLASH_TIME);
break;
case YELLOW_FLASHING:
state = GREEN_TIMING;
myTimer->timeoutRequest(GREEN_TIME);
break;
case GREEN_TIMING:
if (pressed) {
state = YELLOW_STATE;
myTimer->timeoutRequest(YELLOW_TIME);
} else {
state = GREEN_IDLE;
}
break;
case GREEN_IDLE:
// should never happen
break;
case YELLOW_STATE:
state = RED_STATE;
pressed = false;
myTimer->timeoutRequest(RED_TIME);
break;
}
myPole->setTrafficLights(getState());
myPole->setWaitLight(isPressed());
}
+53
View File
@@ -0,0 +1,53 @@
// ======================================================
//
// Represents a Pelican crossing
//
// ======================================================
#ifndef PELICAN_H
#define PELICAN_H
class PelicanTimer;
class Pole;
class Pelican {
public:
Pelican(int x, int y);
~Pelican();
// call when the WAIT button has been pressed
void press(void);
// states that a Pelican can be in
enum PelicanState { RED_STATE, YELLOW_FLASHING, GREEN_TIMING, GREEN_IDLE, YELLOW_STATE };
bool isPressed() const { return pressed; }
PelicanState getState() const { return state; }
private:
// state that this Pelican is in
PelicanState state;
// called by PeleicanTimer when the lights need to change
void timerExpired(void);
const unsigned int RED_TIME;
const unsigned int YELLOW_TIME;
const unsigned int GREEN_TIME;
const unsigned int FLASH_TIME;
// indicates whether the WAIT light should be on
bool pressed;
Pole *myPole;
// Timer that indicates when the lights should change
PelicanTimer *myTimer;
private:
// prevent general use of copy ctor and operator=
Pelican(const Pelican &);
Pelican &operator=(const Pelican &);
};
#endif
+11
View File
@@ -0,0 +1,11 @@
#include "PelicanTimer.h"
PelicanTimer::PelicanTimer(Pelican &target, TargetFunc targetFunc) : myTarget(target), myTargetFunc(targetFunc) {}
void PelicanTimer::tick() {
if (isExpired()) {
(myTarget.*myTargetFunc)();
}
}
+28
View File
@@ -0,0 +1,28 @@
// ======================================================
//
// This class specializes the Timer to enable it to
// stimulate a Pelican
//
// ======================================================
#ifndef PELICANTIMER_H
#define PELICANTIMER_H
#include "Pelican.h"
#include "Timer.h"
class PelicanTimer : public Timer {
public:
typedef void (Pelican::*TargetFunc)();
PelicanTimer(Pelican &target, TargetFunc targetFunc);
// TODO: Rename this function to doExpired. The parameters and return type are unchanged.
virtual void tick();
private:
Pelican &myTarget;
TargetFunc myTargetFunc;
};
#endif
+59
View File
@@ -0,0 +1,59 @@
#include "Pole.h"
#include "Screen.h"
Pole::Pole(int x, int y) : waitLight(new Light("WAIT", x + 6, y + 12, Screen::WHITE)) {
using namespace Screen; // we will discuss namespaces in the course
lights[RED_LIGHT] = new Light("*", x + 11, y + 3, RED);
lights[RED_MAN] = new Light("*<-=", x + 6, y + 4, RED);
lights[YELLOW_LIGHT] = new Light("*", x + 11, y + 5, YELLOW);
lights[GREEN_LIGHT] = new Light("*", x + 11, y + 7, GREEN);
lights[GREEN_MAN] = new Light("*|-<", x + 6, y + 7, GREEN);
write(" _____ ", x, ++y, GRAY);
write(" /___ /| ", x, ++y, GRAY);
write(" | | | ", x, ++y, GRAY);
write(" | |/| ", x, ++y, GRAY);
write(" |____| | ", x, ++y, GRAY);
write(" | |/| ", x, ++y, GRAY);
write(" | | | ", x, ++y, GRAY);
write(" |____|/ ", x, ++y, GRAY);
write(" _||__ ", x, ++y, GRAY);
write(" /___ /| ", x, ++y, GRAY);
write(" | | | ", x, ++y, GRAY);
write(" | | | ", x, ++y, GRAY);
write(" |____|/ ", x, ++y, GRAY);
write(" || ", x, ++y, GRAY);
write(" || ", x, ++y, GRAY);
write(" || ", x, ++y, GRAY);
write(" || ", x, ++y, GRAY);
write(" || ", x, ++y, GRAY);
write(" || ", x, ++y, GRAY);
write("========||===========", x, ++y, GRAY);
write(" / || / ", x, ++y, GRAY);
write("_ /_________ /_ ", x, ++y, GRAY);
write("/ / ", x, ++y, GRAY);
}
Pole::~Pole() {
for (int i = 0; i < sizeof lights / sizeof(lights[0]); ++i)
delete lights[i];
delete waitLight;
}
void Pole::setTrafficLights(Pelican::PelicanState state) {
static const Light::LightState LightStates[Pelican::YELLOW_STATE + 1][RED_MAN + 1] = {
// red yellow green green man red man
{Light::ON, Light::OFF, Light::OFF, Light::ON, Light::OFF}, // red
{Light::OFF, Light::FLASH, Light::OFF, Light::FLASH, Light::OFF}, // y flash
{Light::OFF, Light::OFF, Light::ON, Light::OFF, Light::ON}, // g time
{Light::OFF, Light::OFF, Light::ON, Light::OFF, Light::ON}, // g idle
{Light::OFF, Light::ON, Light::OFF, Light::OFF, Light::ON} // yellow
};
for (int i = RED_LIGHT; i <= RED_MAN; i++) {
lights[i]->set(LightStates[state][i]);
}
}
void Pole::setWaitLight(bool pressed) { waitLight->set(pressed ? Light::ON : Light::OFF); }
+24
View File
@@ -0,0 +1,24 @@
#ifndef POLE_H
#define POLE_H
#include "Light.h"
#include "Pelican.h"
class Pole {
public:
Pole(int x, int y);
~Pole();
void setTrafficLights(Pelican::PelicanState state);
void setWaitLight(bool pressed);
private:
enum LightName { RED_LIGHT, YELLOW_LIGHT, GREEN_LIGHT, GREEN_MAN, RED_MAN };
Light *lights[RED_MAN + 1];
Light *waitLight;
};
#endif
+17
View File
@@ -0,0 +1,17 @@
#include "Timer.h"
#include "TimerSet.h"
void Timer::timeoutRequest(int seconds) { timeToGo = seconds; }
Timer::Timer() : timeToGo(-1) { TimerSet::Instance().addATimer(this); }
bool Timer::isExpired() {
if (timeToGo > 0) {
if (--timeToGo == 0) {
return true;
}
}
return false;
}
+27
View File
@@ -0,0 +1,27 @@
// ======================================================
//
// A general-purpose countdown timer
// To use this class, specialize it
// and override tick()
//
// ======================================================
#ifndef timer_H
#define timer_H
class Timer {
public:
Timer();
void timeoutRequest(int seconds);
virtual void tick() = 0;
protected:
bool isExpired();
private:
int timeToGo;
};
#endif
+23
View File
@@ -0,0 +1,23 @@
#include "TimerSet.h"
#include "Timer.h"
#include <iostream>
TimerSet::TimerSet() : timersInUse(0), previousTime(time(NULL)) {}
void TimerSet::addATimer(Timer *t) { timers[timersInUse++] = t; }
void TimerSet::pollAllTimers() {
std::time_t timeNow;
if (time(&timeNow) > previousTime) {
previousTime = timeNow;
for (int i = 0; i < timersInUse; ++i) {
timers[i]->tick();
}
}
}
TimerSet &TimerSet::Instance() {
// Meyer's Singleton implementation
static TimerSet pInstance;
return pInstance;
}
+29
View File
@@ -0,0 +1,29 @@
#ifndef TIMERSET_H
#define TIMERSET_H
#include <ctime>
class Timer;
class TimerSet {
public:
void pollAllTimers();
void addATimer(Timer *);
private:
TimerSet();
Timer *timers[40];
int timersInUse;
std::time_t previousTime;
// Meyer's singleton
public:
static TimerSet &Instance();
private:
// prevent copying and assignment of the singleton
TimerSet(const TimerSet &);
TimerSet &operator=(const TimerSet &);
};
#endif
+29
View File
@@ -0,0 +1,29 @@
#include "Keyboard.h"
#include "Pelican.h"
#include "TimerSet.h"
#include <cctype> // provides toupper()
int main() {
Keyboard kbd;
Pelican thePelican(30, 0);
char c = 0;
while (std::toupper(c) != 'Q') { // loop until 'Q' is pressed
while (!kbd.isCharAvail()) {
TimerSet::Instance().pollAllTimers(); // no key press to process, poll the timers
}
c = kbd.getChar(); // get the character
if (c == ' ') {
// it's a space, so press the WAIT button
thePelican.press();
}
}
return 0;
}
Binary file not shown.
+6
View File
@@ -0,0 +1,6 @@
# Ex31
cmat_add_exercise(Ex31
SOURCES
Main.cpp
)
+20
View File
@@ -0,0 +1,20 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.21005.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Ex31", "Ex31.vcxproj", "{8F266BE3-8B4C-8EDD-744B-50A12A4E07CF}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{8F266BE3-8B4C-8EDD-744B-50A12A4E07CF}.Debug|Win32.ActiveCfg = Debug|Win32
{8F266BE3-8B4C-8EDD-744B-50A12A4E07CF}.Debug|Win32.Build.0 = Debug|Win32
{8F266BE3-8B4C-8EDD-744B-50A12A4E07CF}.Release|Win32.ActiveCfg = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

Some files were not shown because too many files have changed in this diff Show More