CameraServer: Remove NT-driven settings. (#467)

Unfortunately, due to the way NT synchronization is currently performed,
this has unexpected and undesirable behavior: when a dashboard (or any other
NT client) is left running between code restarts, when it reconnects, any
code settings will be overwritten by the NT synchronization process.  As
fixing this will require a fairly major NT change (and likely a user-visible
one), it's not desirable to do at this point in the year.

Instead, disable NT driven settings entirely (e.g. make the NT interface
publish only).  To emphasize the read-only nature of the NT values, attempts
to change the NT values will be immediately overridden by CameraServer.

To better inform users about the actual property names (e.g. for use in their
code), the "raw_" settings no longer have "raw_" removed from their names
(they are still placed in the "RawProperty" subtable).

This change also contains a couple of Java fixes:

* Make getInstance() thread-safe

* Properly synchronize access to m_tables between multiple threads.

* Use Hashtable instead of HashMap.
This commit is contained in:
Peter Johnson
2017-01-19 12:30:07 -07:00
committed by GitHub
parent 8f1b034b2f
commit b8537be219
2 changed files with 49 additions and 61 deletions

View File

@@ -171,7 +171,7 @@ static std::string PixelFormatToString(int pixelFormat) {
return "Unknown";
}
}
#if 0
static cs::VideoMode::PixelFormat PixelFormatFromString(llvm::StringRef str) {
if (str == "MJPEG" || str == "mjpeg" || str == "JPEG" || str == "jpeg")
return cs::VideoMode::PixelFormat::kMJPEG;
@@ -228,7 +228,7 @@ static cs::VideoMode VideoModeFromString(llvm::StringRef modeStr) {
return mode;
}
#endif
static std::string VideoModeToString(const cs::VideoMode& mode) {
std::string rv;
llvm::raw_string_ostream oss{rv};
@@ -261,9 +261,9 @@ static void PutSourcePropertyValue(ITable* table, const cs::VideoEvent& event,
llvm::SmallString<64> infoName;
if (llvm::StringRef{event.name}.startswith("raw_")) {
name = "RawProperty/";
name += llvm::StringRef{event.name}.substr(4);
name += event.name;
infoName = "RawPropertyInfo/";
infoName += llvm::StringRef{event.name}.substr(4);
infoName += event.name;
} else {
name = "Property/";
name += event.name;
@@ -427,6 +427,9 @@ CameraServer::CameraServer()
0x4fff, true};
// Listener for NetworkTable events
// We don't currently support changing settings via NT due to
// synchronization issues, so just update to current setting if someone
// else tries to change it.
llvm::SmallString<64> buf;
m_tableListener = nt::AddEntryListener(
Concatenate(kPublishName, "/", buf),
@@ -446,24 +449,16 @@ CameraServer::CameraServer()
relativeKey = relativeKey.substr(subKeyIndex + 1);
// handle standard names
llvm::SmallString<64> propNameBuf;
llvm::StringRef propName;
if (relativeKey == "mode") {
if (!value->IsString()) return;
auto mode = VideoModeFromString(value->GetString());
if (mode.pixelFormat == cs::VideoMode::PixelFormat::kUnknown ||
!sourceIt->second.SetVideoMode(mode)) {
// reset to current mode
nt::SetEntryValue(key, nt::Value::MakeString(VideoModeToString(
sourceIt->second.GetVideoMode())));
}
// reset to current mode
nt::SetEntryValue(key, nt::Value::MakeString(VideoModeToString(
sourceIt->second.GetVideoMode())));
return;
} else if (relativeKey.startswith("Property/")) {
propName = relativeKey.substr(9);
} else if (relativeKey.startswith("RawProperty/")) {
propNameBuf = "raw_";
propNameBuf += relativeKey.substr(12);
propName = propNameBuf.str();
propName = relativeKey.substr(12);
} else {
return; // ignore
}
@@ -474,17 +469,14 @@ CameraServer::CameraServer()
case cs::VideoProperty::kNone:
return;
case cs::VideoProperty::kBoolean:
if (!value->IsBoolean()) return;
property.Set(value->GetBoolean() ? 1 : 0);
nt::SetEntryValue(key, nt::Value::MakeBoolean(property.Get() != 0));
return;
case cs::VideoProperty::kInteger:
case cs::VideoProperty::kEnum:
if (!value->IsDouble()) return;
property.Set(static_cast<int>(value->GetDouble()));
nt::SetEntryValue(key, nt::Value::MakeDouble(property.Get()));
return;
case cs::VideoProperty::kString:
if (!value->IsString()) return;
property.SetString(value->GetString());
nt::SetEntryValue(key, nt::Value::MakeString(property.GetString()));
return;
default:
return;