2013-12-15 18:30:16 -05:00
|
|
|
/*----------------------------------------------------------------------------*/
|
2016-01-02 03:02:34 -08:00
|
|
|
/* Copyright (c) FIRST 2008-2016. All Rights Reserved. */
|
2013-12-15 18:30:16 -05:00
|
|
|
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
2016-01-02 03:02:34 -08:00
|
|
|
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
|
|
|
|
/* the project. */
|
2013-12-15 18:30:16 -05:00
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
#include "IterativeRobot.h"
|
|
|
|
|
|
|
|
|
|
#include "DriverStation.h"
|
2016-05-22 21:41:22 -07:00
|
|
|
#include "HAL/HAL.h"
|
2013-12-15 18:30:16 -05:00
|
|
|
#include "LiveWindow/LiveWindow.h"
|
2016-05-20 17:30:37 -07:00
|
|
|
#include "SmartDashboard/SmartDashboard.h"
|
2013-12-15 18:30:16 -05:00
|
|
|
#include "networktables/NetworkTable.h"
|
|
|
|
|
|
2016-11-01 22:33:12 -07:00
|
|
|
using namespace frc;
|
|
|
|
|
|
2013-12-15 18:30:16 -05:00
|
|
|
/**
|
|
|
|
|
* Provide an alternate "main loop" via StartCompetition().
|
2015-06-25 15:07:55 -04:00
|
|
|
*
|
|
|
|
|
* This specific StartCompetition() implements "main loop" behaviour synced with
|
2016-09-21 23:48:54 -07:00
|
|
|
* the DS packets.
|
2013-12-15 18:30:16 -05:00
|
|
|
*/
|
2015-06-25 15:07:55 -04:00
|
|
|
void IterativeRobot::StartCompetition() {
|
2016-07-09 00:24:26 -07:00
|
|
|
HAL_Report(HALUsageReporting::kResourceType_Framework,
|
|
|
|
|
HALUsageReporting::kFramework_Iterative);
|
2015-06-25 15:07:55 -04:00
|
|
|
|
2016-05-20 17:30:37 -07:00
|
|
|
LiveWindow* lw = LiveWindow::GetInstance();
|
2015-06-25 15:07:55 -04:00
|
|
|
// first and one-time initialization
|
|
|
|
|
SmartDashboard::init();
|
|
|
|
|
NetworkTable::GetTable("LiveWindow")
|
|
|
|
|
->GetSubTable("~STATUS~")
|
|
|
|
|
->PutBoolean("LW Enabled", false);
|
|
|
|
|
RobotInit();
|
|
|
|
|
|
2015-10-20 11:12:02 -07:00
|
|
|
// Tell the DS that the robot is ready to be enabled
|
2016-07-10 16:24:57 -07:00
|
|
|
HAL_ObserveUserProgramStarting();
|
2015-06-25 15:07:55 -04:00
|
|
|
|
|
|
|
|
// loop forever, calling the appropriate mode-dependent function
|
Revert changes preventing old user code from compiling.
I'm not 100% sure whether we want these, but they are a quick
find and replace to do.
Basically, there are two primary things that we have done
this summer that break existing user code:
-Changing GetInstance() calls to return references instead
of pointers. This forces users to change from doing something
like LiveWindow::GetInstance()->AddSensor() to LiveWindow::GetInstance().AddSensor().
-Making PIDGet() and related calls const, forcing users to change
the function signatures wherever they override them.
The GetInstance() calls don't really matter to me either way,
especially since there are no real ownership issues going on there,
unlike the rest of the smart pointer-related changes.
For the const stuff, it is certainly more correct to mandate that
user PIDGet() functions be const and the such, but at the same time,
I'm not sure that there is any strong need for it, and the errors
generated are not the most helpful. While this wouldn't necessarily
be an issue for more experienced teams or completely new teams (who
don't have any old code to be reusing), it may cause issues for more
average teams who aren't familiar with the intricacies of C++ anything.
Change-Id: I6e7007982069292ea70e6d0fc8ca40203340df1b
2015-07-24 19:19:40 -04:00
|
|
|
lw->SetEnabled(false);
|
2015-06-25 15:07:55 -04:00
|
|
|
while (true) {
|
2016-10-02 09:05:32 -07:00
|
|
|
// wait for driver station data so the loop doesn't hog the CPU
|
|
|
|
|
m_ds.WaitForData();
|
2015-06-25 15:07:55 -04:00
|
|
|
// Call the appropriate function depending upon the current robot mode
|
|
|
|
|
if (IsDisabled()) {
|
|
|
|
|
// call DisabledInit() if we are now just entering disabled mode from
|
|
|
|
|
// either a different mode or from power-on
|
|
|
|
|
if (!m_disabledInitialized) {
|
Revert changes preventing old user code from compiling.
I'm not 100% sure whether we want these, but they are a quick
find and replace to do.
Basically, there are two primary things that we have done
this summer that break existing user code:
-Changing GetInstance() calls to return references instead
of pointers. This forces users to change from doing something
like LiveWindow::GetInstance()->AddSensor() to LiveWindow::GetInstance().AddSensor().
-Making PIDGet() and related calls const, forcing users to change
the function signatures wherever they override them.
The GetInstance() calls don't really matter to me either way,
especially since there are no real ownership issues going on there,
unlike the rest of the smart pointer-related changes.
For the const stuff, it is certainly more correct to mandate that
user PIDGet() functions be const and the such, but at the same time,
I'm not sure that there is any strong need for it, and the errors
generated are not the most helpful. While this wouldn't necessarily
be an issue for more experienced teams or completely new teams (who
don't have any old code to be reusing), it may cause issues for more
average teams who aren't familiar with the intricacies of C++ anything.
Change-Id: I6e7007982069292ea70e6d0fc8ca40203340df1b
2015-07-24 19:19:40 -04:00
|
|
|
lw->SetEnabled(false);
|
2015-06-25 15:07:55 -04:00
|
|
|
DisabledInit();
|
|
|
|
|
m_disabledInitialized = true;
|
|
|
|
|
// reset the initialization flags for the other modes
|
|
|
|
|
m_autonomousInitialized = false;
|
|
|
|
|
m_teleopInitialized = false;
|
|
|
|
|
m_testInitialized = false;
|
|
|
|
|
}
|
2016-07-10 16:24:57 -07:00
|
|
|
HAL_ObserveUserProgramDisabled();
|
2015-06-25 15:07:55 -04:00
|
|
|
DisabledPeriodic();
|
|
|
|
|
} else if (IsAutonomous()) {
|
|
|
|
|
// call AutonomousInit() if we are now just entering autonomous mode from
|
|
|
|
|
// either a different mode or from power-on
|
|
|
|
|
if (!m_autonomousInitialized) {
|
Revert changes preventing old user code from compiling.
I'm not 100% sure whether we want these, but they are a quick
find and replace to do.
Basically, there are two primary things that we have done
this summer that break existing user code:
-Changing GetInstance() calls to return references instead
of pointers. This forces users to change from doing something
like LiveWindow::GetInstance()->AddSensor() to LiveWindow::GetInstance().AddSensor().
-Making PIDGet() and related calls const, forcing users to change
the function signatures wherever they override them.
The GetInstance() calls don't really matter to me either way,
especially since there are no real ownership issues going on there,
unlike the rest of the smart pointer-related changes.
For the const stuff, it is certainly more correct to mandate that
user PIDGet() functions be const and the such, but at the same time,
I'm not sure that there is any strong need for it, and the errors
generated are not the most helpful. While this wouldn't necessarily
be an issue for more experienced teams or completely new teams (who
don't have any old code to be reusing), it may cause issues for more
average teams who aren't familiar with the intricacies of C++ anything.
Change-Id: I6e7007982069292ea70e6d0fc8ca40203340df1b
2015-07-24 19:19:40 -04:00
|
|
|
lw->SetEnabled(false);
|
2015-06-25 15:07:55 -04:00
|
|
|
AutonomousInit();
|
|
|
|
|
m_autonomousInitialized = true;
|
|
|
|
|
// reset the initialization flags for the other modes
|
|
|
|
|
m_disabledInitialized = false;
|
|
|
|
|
m_teleopInitialized = false;
|
|
|
|
|
m_testInitialized = false;
|
|
|
|
|
}
|
2016-07-10 16:24:57 -07:00
|
|
|
HAL_ObserveUserProgramAutonomous();
|
2015-06-25 15:07:55 -04:00
|
|
|
AutonomousPeriodic();
|
|
|
|
|
} else if (IsTest()) {
|
|
|
|
|
// call TestInit() if we are now just entering test mode from
|
|
|
|
|
// either a different mode or from power-on
|
|
|
|
|
if (!m_testInitialized) {
|
Revert changes preventing old user code from compiling.
I'm not 100% sure whether we want these, but they are a quick
find and replace to do.
Basically, there are two primary things that we have done
this summer that break existing user code:
-Changing GetInstance() calls to return references instead
of pointers. This forces users to change from doing something
like LiveWindow::GetInstance()->AddSensor() to LiveWindow::GetInstance().AddSensor().
-Making PIDGet() and related calls const, forcing users to change
the function signatures wherever they override them.
The GetInstance() calls don't really matter to me either way,
especially since there are no real ownership issues going on there,
unlike the rest of the smart pointer-related changes.
For the const stuff, it is certainly more correct to mandate that
user PIDGet() functions be const and the such, but at the same time,
I'm not sure that there is any strong need for it, and the errors
generated are not the most helpful. While this wouldn't necessarily
be an issue for more experienced teams or completely new teams (who
don't have any old code to be reusing), it may cause issues for more
average teams who aren't familiar with the intricacies of C++ anything.
Change-Id: I6e7007982069292ea70e6d0fc8ca40203340df1b
2015-07-24 19:19:40 -04:00
|
|
|
lw->SetEnabled(true);
|
2015-06-25 15:07:55 -04:00
|
|
|
TestInit();
|
|
|
|
|
m_testInitialized = true;
|
|
|
|
|
// reset the initialization flags for the other modes
|
|
|
|
|
m_disabledInitialized = false;
|
|
|
|
|
m_autonomousInitialized = false;
|
|
|
|
|
m_teleopInitialized = false;
|
|
|
|
|
}
|
2016-07-10 16:24:57 -07:00
|
|
|
HAL_ObserveUserProgramTest();
|
2015-06-25 15:07:55 -04:00
|
|
|
TestPeriodic();
|
|
|
|
|
} else {
|
|
|
|
|
// call TeleopInit() if we are now just entering teleop mode from
|
|
|
|
|
// either a different mode or from power-on
|
|
|
|
|
if (!m_teleopInitialized) {
|
Revert changes preventing old user code from compiling.
I'm not 100% sure whether we want these, but they are a quick
find and replace to do.
Basically, there are two primary things that we have done
this summer that break existing user code:
-Changing GetInstance() calls to return references instead
of pointers. This forces users to change from doing something
like LiveWindow::GetInstance()->AddSensor() to LiveWindow::GetInstance().AddSensor().
-Making PIDGet() and related calls const, forcing users to change
the function signatures wherever they override them.
The GetInstance() calls don't really matter to me either way,
especially since there are no real ownership issues going on there,
unlike the rest of the smart pointer-related changes.
For the const stuff, it is certainly more correct to mandate that
user PIDGet() functions be const and the such, but at the same time,
I'm not sure that there is any strong need for it, and the errors
generated are not the most helpful. While this wouldn't necessarily
be an issue for more experienced teams or completely new teams (who
don't have any old code to be reusing), it may cause issues for more
average teams who aren't familiar with the intricacies of C++ anything.
Change-Id: I6e7007982069292ea70e6d0fc8ca40203340df1b
2015-07-24 19:19:40 -04:00
|
|
|
lw->SetEnabled(false);
|
2015-06-25 15:07:55 -04:00
|
|
|
TeleopInit();
|
|
|
|
|
m_teleopInitialized = true;
|
|
|
|
|
// reset the initialization flags for the other modes
|
|
|
|
|
m_disabledInitialized = false;
|
|
|
|
|
m_autonomousInitialized = false;
|
|
|
|
|
m_testInitialized = false;
|
Revert changes preventing old user code from compiling.
I'm not 100% sure whether we want these, but they are a quick
find and replace to do.
Basically, there are two primary things that we have done
this summer that break existing user code:
-Changing GetInstance() calls to return references instead
of pointers. This forces users to change from doing something
like LiveWindow::GetInstance()->AddSensor() to LiveWindow::GetInstance().AddSensor().
-Making PIDGet() and related calls const, forcing users to change
the function signatures wherever they override them.
The GetInstance() calls don't really matter to me either way,
especially since there are no real ownership issues going on there,
unlike the rest of the smart pointer-related changes.
For the const stuff, it is certainly more correct to mandate that
user PIDGet() functions be const and the such, but at the same time,
I'm not sure that there is any strong need for it, and the errors
generated are not the most helpful. While this wouldn't necessarily
be an issue for more experienced teams or completely new teams (who
don't have any old code to be reusing), it may cause issues for more
average teams who aren't familiar with the intricacies of C++ anything.
Change-Id: I6e7007982069292ea70e6d0fc8ca40203340df1b
2015-07-24 19:19:40 -04:00
|
|
|
Scheduler::GetInstance()->SetEnabled(true);
|
2015-06-25 15:07:55 -04:00
|
|
|
}
|
2016-07-10 16:24:57 -07:00
|
|
|
HAL_ObserveUserProgramTeleop();
|
2015-06-25 15:07:55 -04:00
|
|
|
TeleopPeriodic();
|
|
|
|
|
}
|
2016-09-13 20:25:18 -07:00
|
|
|
RobotPeriodic();
|
2015-06-25 15:07:55 -04:00
|
|
|
}
|
2013-12-15 18:30:16 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Robot-wide initialization code should go here.
|
2015-06-25 15:07:55 -04:00
|
|
|
*
|
|
|
|
|
* Users should override this method for default Robot-wide initialization which
|
2015-10-20 11:12:02 -07:00
|
|
|
* will be called when the robot is first powered on. It will be called exactly
|
|
|
|
|
* one time.
|
|
|
|
|
*
|
|
|
|
|
* Warning: the Driver Station "Robot Code" light and FMS "Robot Ready"
|
|
|
|
|
* indicators will be off until RobotInit() exits. Code in RobotInit() that
|
|
|
|
|
* waits for enable will cause the robot to never indicate that the code is
|
|
|
|
|
* ready, causing the robot to be bypassed in a match.
|
2013-12-15 18:30:16 -05:00
|
|
|
*/
|
2015-06-25 15:07:55 -04:00
|
|
|
void IterativeRobot::RobotInit() {
|
2016-06-19 00:19:45 -07:00
|
|
|
std::printf("Default %s() method... Overload me!\n", __FUNCTION__);
|
2013-12-15 18:30:16 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Initialization code for disabled mode should go here.
|
2015-06-25 15:07:55 -04:00
|
|
|
*
|
|
|
|
|
* Users should override this method for initialization code which will be
|
|
|
|
|
* called each time
|
2013-12-15 18:30:16 -05:00
|
|
|
* the robot enters disabled mode.
|
|
|
|
|
*/
|
2015-06-25 15:07:55 -04:00
|
|
|
void IterativeRobot::DisabledInit() {
|
2016-06-19 00:19:45 -07:00
|
|
|
std::printf("Default %s() method... Overload me!\n", __FUNCTION__);
|
2013-12-15 18:30:16 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Initialization code for autonomous mode should go here.
|
2015-06-25 15:07:55 -04:00
|
|
|
*
|
|
|
|
|
* Users should override this method for initialization code which will be
|
2016-05-20 17:30:37 -07:00
|
|
|
* called each time the robot enters autonomous mode.
|
2013-12-15 18:30:16 -05:00
|
|
|
*/
|
2015-06-25 15:07:55 -04:00
|
|
|
void IterativeRobot::AutonomousInit() {
|
2016-06-19 00:19:45 -07:00
|
|
|
std::printf("Default %s() method... Overload me!\n", __FUNCTION__);
|
2013-12-15 18:30:16 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Initialization code for teleop mode should go here.
|
2015-06-25 15:07:55 -04:00
|
|
|
*
|
|
|
|
|
* Users should override this method for initialization code which will be
|
2016-05-20 17:30:37 -07:00
|
|
|
* called each time the robot enters teleop mode.
|
2013-12-15 18:30:16 -05:00
|
|
|
*/
|
2015-06-25 15:07:55 -04:00
|
|
|
void IterativeRobot::TeleopInit() {
|
2016-06-19 00:19:45 -07:00
|
|
|
std::printf("Default %s() method... Overload me!\n", __FUNCTION__);
|
2013-12-15 18:30:16 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Initialization code for test mode should go here.
|
2015-06-25 15:07:55 -04:00
|
|
|
*
|
|
|
|
|
* Users should override this method for initialization code which will be
|
2016-05-20 17:30:37 -07:00
|
|
|
* called each time the robot enters test mode.
|
2013-12-15 18:30:16 -05:00
|
|
|
*/
|
2015-06-25 15:07:55 -04:00
|
|
|
void IterativeRobot::TestInit() {
|
2016-06-19 00:19:45 -07:00
|
|
|
std::printf("Default %s() method... Overload me!\n", __FUNCTION__);
|
2013-12-15 18:30:16 -05:00
|
|
|
}
|
|
|
|
|
|
2016-09-13 20:25:18 -07:00
|
|
|
/**
|
|
|
|
|
* Periodic code for all modes should go here.
|
|
|
|
|
*
|
2016-09-21 23:48:54 -07:00
|
|
|
* This function is called each time a new packet is received from the driver
|
|
|
|
|
* station.
|
2016-09-14 00:21:25 -04:00
|
|
|
*
|
2016-09-21 23:48:54 -07:00
|
|
|
* Packets are received approximately every 20ms. Fixed loop timing is not
|
|
|
|
|
* guaranteed due to network timing variability and the function may not be
|
|
|
|
|
* called at all if the Driver Station is disconnected. For most use cases the
|
|
|
|
|
* variable timing will not be an issue. If your code does require guaranteed
|
|
|
|
|
* fixed periodic timing, consider using Notifier or PIDController instead.
|
2016-09-13 20:25:18 -07:00
|
|
|
*/
|
|
|
|
|
void IterativeRobot::RobotPeriodic() {
|
|
|
|
|
static bool firstRun = true;
|
|
|
|
|
if (firstRun) {
|
|
|
|
|
std::printf("Default %s() method... Overload me!\n", __FUNCTION__);
|
|
|
|
|
firstRun = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-12-15 18:30:16 -05:00
|
|
|
/**
|
|
|
|
|
* Periodic code for disabled mode should go here.
|
2015-06-25 15:07:55 -04:00
|
|
|
*
|
2016-09-21 23:48:54 -07:00
|
|
|
* Users should override this method for code which will be called each time a
|
|
|
|
|
* new packet is received from the driver station and the robot is in disabled
|
|
|
|
|
* mode.
|
2016-09-14 00:21:25 -04:00
|
|
|
*
|
2016-09-21 23:48:54 -07:00
|
|
|
* Packets are received approximately every 20ms. Fixed loop timing is not
|
|
|
|
|
* guaranteed due to network timing variability and the function may not be
|
|
|
|
|
* called at all if the Driver Station is disconnected. For most use cases the
|
|
|
|
|
* variable timing will not be an issue. If your code does require guaranteed
|
|
|
|
|
* fixed periodic timing, consider using Notifier or PIDController instead.
|
2013-12-15 18:30:16 -05:00
|
|
|
*/
|
2015-06-25 15:07:55 -04:00
|
|
|
void IterativeRobot::DisabledPeriodic() {
|
|
|
|
|
static bool firstRun = true;
|
|
|
|
|
if (firstRun) {
|
2016-06-19 00:19:45 -07:00
|
|
|
std::printf("Default %s() method... Overload me!\n", __FUNCTION__);
|
2015-06-25 15:07:55 -04:00
|
|
|
firstRun = false;
|
|
|
|
|
}
|
2013-12-15 18:30:16 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Periodic code for autonomous mode should go here.
|
|
|
|
|
*
|
2016-09-21 23:48:54 -07:00
|
|
|
* Users should override this method for code which will be called each time a
|
|
|
|
|
* new packet is received from the driver station and the robot is in autonomous
|
|
|
|
|
* mode.
|
2016-09-14 00:21:25 -04:00
|
|
|
*
|
2016-09-21 23:48:54 -07:00
|
|
|
* Packets are received approximately every 20ms. Fixed loop timing is not
|
|
|
|
|
* guaranteed due to network timing variability and the function may not be
|
|
|
|
|
* called at all if the Driver Station is disconnected. For most use cases the
|
|
|
|
|
* variable timing will not be an issue. If your code does require guaranteed
|
|
|
|
|
* fixed periodic timing, consider using Notifier or PIDController instead.
|
2013-12-15 18:30:16 -05:00
|
|
|
*/
|
2015-06-25 15:07:55 -04:00
|
|
|
void IterativeRobot::AutonomousPeriodic() {
|
|
|
|
|
static bool firstRun = true;
|
|
|
|
|
if (firstRun) {
|
2016-06-19 00:19:45 -07:00
|
|
|
std::printf("Default %s() method... Overload me!\n", __FUNCTION__);
|
2015-06-25 15:07:55 -04:00
|
|
|
firstRun = false;
|
|
|
|
|
}
|
2013-12-15 18:30:16 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Periodic code for teleop mode should go here.
|
|
|
|
|
*
|
2016-09-21 23:48:54 -07:00
|
|
|
* Users should override this method for code which will be called each time a
|
|
|
|
|
* new packet is received from the driver station and the robot is in teleop
|
|
|
|
|
* mode.
|
2016-09-14 00:21:25 -04:00
|
|
|
*
|
2016-09-21 23:48:54 -07:00
|
|
|
* Packets are received approximately every 20ms. Fixed loop timing is not
|
|
|
|
|
* guaranteed due to network timing variability and the function may not be
|
|
|
|
|
* called at all if the Driver Station is disconnected. For most use cases the
|
|
|
|
|
* variable timing will not be an issue. If your code does require guaranteed
|
|
|
|
|
* fixed periodic timing, consider using Notifier or PIDController instead.
|
2013-12-15 18:30:16 -05:00
|
|
|
*/
|
2015-06-25 15:07:55 -04:00
|
|
|
void IterativeRobot::TeleopPeriodic() {
|
|
|
|
|
static bool firstRun = true;
|
|
|
|
|
if (firstRun) {
|
2016-06-19 00:19:45 -07:00
|
|
|
std::printf("Default %s() method... Overload me!\n", __FUNCTION__);
|
2015-06-25 15:07:55 -04:00
|
|
|
firstRun = false;
|
|
|
|
|
}
|
2013-12-15 18:30:16 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Periodic code for test mode should go here.
|
|
|
|
|
*
|
2016-09-21 23:48:54 -07:00
|
|
|
* Users should override this method for code which will be called each time a
|
|
|
|
|
* new packet is received from the driver station and the robot is in test mode.
|
2016-09-14 00:21:25 -04:00
|
|
|
*
|
2016-09-21 23:48:54 -07:00
|
|
|
* Packets are received approximately every 20ms. Fixed loop timing is not
|
|
|
|
|
* guaranteed due to network timing variability and the function may not be
|
|
|
|
|
* called at all if the Driver Station is disconnected. For most use cases the
|
|
|
|
|
* variable timing will not be an issue. If your code does require guaranteed
|
|
|
|
|
* fixed periodic timing, consider using Notifier or PIDController instead.
|
2013-12-15 18:30:16 -05:00
|
|
|
*/
|
2015-06-25 15:07:55 -04:00
|
|
|
void IterativeRobot::TestPeriodic() {
|
|
|
|
|
static bool firstRun = true;
|
|
|
|
|
if (firstRun) {
|
2016-06-19 00:19:45 -07:00
|
|
|
std::printf("Default %s() method... Overload me!\n", __FUNCTION__);
|
2015-06-25 15:07:55 -04:00
|
|
|
firstRun = false;
|
|
|
|
|
}
|
2013-12-15 18:30:16 -05:00
|
|
|
}
|