Squashed 'third_party/Phoenix-frc-lib/' content from commit 666d176

Change-Id: Ibaca2fc8ffb1177e786576cc1e4cc9f7a8c98f13
git-subtree-dir: third_party/Phoenix-frc-lib
git-subtree-split: 666d176a08151793044ab74e0005f13d3732ed96
diff --git a/cpp/src/Tasking/ButtonMonitor.cpp b/cpp/src/Tasking/ButtonMonitor.cpp
new file mode 100644
index 0000000..d420e34
--- /dev/null
+++ b/cpp/src/Tasking/ButtonMonitor.cpp
@@ -0,0 +1,46 @@
+#include "ctre/phoenix/Tasking/ButtonMonitor.h"
+#include <GenericHID.h> // WPILIB
+
+#ifndef CTR_EXCLUDE_WPILIB_CLASSES
+
+namespace ctre {
+namespace phoenix {
+namespace tasking {
+
+ButtonMonitor::ButtonMonitor(frc::GenericHID * controller, int buttonIndex,
+		IButtonPressEventHandler * ButtonPressEventHandler) {
+	_gameCntrlr = controller;
+	_btnIdx = buttonIndex;
+	_handler = ButtonPressEventHandler;
+}
+ButtonMonitor::ButtonMonitor(const ButtonMonitor & rhs) {
+	_gameCntrlr = rhs._gameCntrlr;
+	_btnIdx = rhs._btnIdx;
+	_handler = rhs._handler;
+}
+
+void ButtonMonitor::Process() {
+	bool down = ((frc::GenericHID*)_gameCntrlr)->GetRawButton(_btnIdx);
+
+	if (!_isDown && down)
+		_handler->OnButtonPress(_btnIdx, down);
+
+	_isDown = down;
+}
+
+void ButtonMonitor::OnStart() {
+}
+void ButtonMonitor::OnLoop() {
+	Process();
+}
+bool ButtonMonitor::IsDone() {
+	return false;
+}
+void ButtonMonitor::OnStop() {
+}
+
+} // namespace tasking
+} // namespace phoenix
+} // namespace ctre
+
+#endif // CTR_EXCLUDE_WPILIB_CLASSES
diff --git a/cpp/src/Tasking/Schedulers/ConcurrentScheduler.cpp b/cpp/src/Tasking/Schedulers/ConcurrentScheduler.cpp
new file mode 100644
index 0000000..c8d6773
--- /dev/null
+++ b/cpp/src/Tasking/Schedulers/ConcurrentScheduler.cpp
@@ -0,0 +1,88 @@
+#include "ctre/phoenix/Tasking/Schedulers/ConcurrentScheduler.h"
+
+namespace ctre {
+namespace phoenix {
+namespace tasking {
+namespace schedulers {
+
+ConcurrentScheduler::ConcurrentScheduler() {
+}
+ConcurrentScheduler::~ConcurrentScheduler() {
+}
+void ConcurrentScheduler::Add(ILoopable *aLoop, bool enable) {
+	_loops.push_back(aLoop);
+	_enabs.push_back(enable);
+}
+void ConcurrentScheduler::RemoveAll() {
+	_loops.clear();
+	_enabs.clear();
+}
+void ConcurrentScheduler::Start(ILoopable* toStart) {
+	for (int i = 0; i < (int) _loops.size(); ++i) {
+		ILoopable* lp = (ILoopable*) _loops[i];
+
+		if (lp == toStart) {
+			_enabs[i] = true;
+			lp->OnStart();
+			return;
+		}
+	}
+
+}
+void ConcurrentScheduler::Stop(ILoopable* toStop) {
+	for (int i = 0; i < (int) _loops.size(); ++i) {
+		ILoopable* lp = (ILoopable*) _loops[i];
+
+		if (lp == toStop) {
+			_enabs[i] = false;
+			lp->OnStop();
+			return;
+		}
+	}
+}
+void ConcurrentScheduler::StartAll() {	//All Loops
+	for (auto loop : _loops) {
+		loop->OnStart();
+	}
+	for (auto enable : _enabs) {
+		enable = true;
+	}
+}
+void ConcurrentScheduler::StopAll() {	//All Loops
+	for (auto loop : _loops) {
+		loop->OnStop();
+	}
+	for (auto enable : _enabs) {
+		enable = false;
+	}
+}
+void ConcurrentScheduler::Process() {
+	for (int i = 0; i < (int) _loops.size(); ++i) {
+		ILoopable* loop = (ILoopable*) _loops[i];
+		bool en = (bool) _enabs[i];
+		if (en) {
+			loop->OnLoop();
+		} else {
+			/* Current ILoopable is turned off, don't call OnLoop for it */
+		}
+	}
+}
+/* ILoopable */
+void ConcurrentScheduler::OnStart() {
+	ConcurrentScheduler::StartAll();
+}
+void ConcurrentScheduler::OnLoop() {
+	ConcurrentScheduler::Process();
+}
+void ConcurrentScheduler::OnStop() {
+	ConcurrentScheduler::StopAll();
+}
+bool ConcurrentScheduler::IsDone() {
+	return false;
+}
+
+} // namespace schedulers
+} // namespace tasking
+} // namespace phoenix
+} // namespace ctre
+
diff --git a/cpp/src/Tasking/Schedulers/SequentialScheduler.cpp b/cpp/src/Tasking/Schedulers/SequentialScheduler.cpp
new file mode 100644
index 0000000..edac7bd
--- /dev/null
+++ b/cpp/src/Tasking/Schedulers/SequentialScheduler.cpp
@@ -0,0 +1,86 @@
+#include "ctre/phoenix/Tasking/Schedulers/SequentialScheduler.h"
+
+namespace ctre {
+namespace phoenix {
+namespace tasking {
+namespace schedulers {
+
+SequentialScheduler::SequentialScheduler() {
+}
+SequentialScheduler::~SequentialScheduler() {
+}
+void SequentialScheduler::Add(ILoopable *aLoop) {
+	_loops.push_back(aLoop);
+}
+ILoopable * SequentialScheduler::GetCurrent() {
+	ILoopable* retval = nullptr;
+	if (_idx < _loops.size()) {
+		retval = _loops[_idx];
+	}
+	return retval;
+}
+
+void SequentialScheduler::RemoveAll() {
+	_loops.clear();
+}
+void SequentialScheduler::Start() {
+	/* reset iterator regardless of loopable container */
+	_idx = 0;
+	/* do we have any to loop? */
+	if (_idx >= _loops.size()) {
+		/* there are no loopables */
+		_running = false;
+	} else {
+		/* start the first one */
+		_loops[_idx]->OnStart();
+		_running = true;
+	}
+
+}
+void SequentialScheduler::Stop() {
+	for (unsigned int i = 0; i < _loops.size(); i++) {
+		_loops[i]->OnStop();
+	}
+	_running = false;
+}
+void SequentialScheduler::Process() {
+	if (_idx < _loops.size()) {
+		if (_running) {
+			ILoopable* loop = _loops[_idx];
+			loop->OnLoop();
+			if (loop->IsDone()) {
+				/* iterate to next loopable */
+				++_idx;
+				if (_idx < _loops.size()) {
+					/* callback to start it */
+					_loops[_idx]->OnStart();
+				}
+			}
+		}
+	} else {
+		_running = false;
+	}
+}
+/* ILoopable */
+void SequentialScheduler::OnStart() {
+	SequentialScheduler::Start();
+}
+void SequentialScheduler::OnLoop() {
+	SequentialScheduler::Process();
+}
+void SequentialScheduler::OnStop() {
+	SequentialScheduler::Stop();
+}
+bool SequentialScheduler::IsDone() {
+	/* Have to return something to know if we are done */
+	if (_running == false)
+		return true;
+	else
+		return false;
+}
+
+} // namespace schedulers
+} // namespace tasking
+} // namespace phoenix
+} // namespace ctre
+