forked from uml-robotics/ROS.NET
-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathMessageTypeRegistry.cs
114 lines (103 loc) · 4.63 KB
/
MessageTypeRegistry.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
using Microsoft.Extensions.Logging;
using System;
using System.Reflection;
using System.Threading;
namespace Uml.Robotics.Ros
{
public class MessageTypeRegistry
: TypeRegistryBase
{
private static Lazy<MessageTypeRegistry> defaultInstance = new Lazy<MessageTypeRegistry>(LazyThreadSafetyMode.ExecutionAndPublication);
public static MessageTypeRegistry Default
{
get { return defaultInstance.Value; }
}
public MessageTypeRegistry()
: base(ApplicationLogging.CreateLogger<MessageTypeRegistry>())
{
}
public RosMessage CreateMessage(string rosMessageType)
{
return base.Create<RosMessage>(rosMessageType);
}
public void ParseAssemblyAndRegisterRosMessages(Assembly assembly)
{
foreach (Type othertype in assembly.GetTypes())
{
var messageInfo = othertype.GetTypeInfo();
if (othertype == typeof(RosMessage) || !messageInfo.IsSubclassOf(typeof(RosMessage)) || othertype == typeof(InnerActionMessage))
{
continue;
}
var goalAttribute = messageInfo.GetCustomAttribute<ActionGoalMessageAttribute>();
var resultAttribute = messageInfo.GetCustomAttribute<ActionResultMessageAttribute>();
var feedbackAttribute = messageInfo.GetCustomAttribute<ActionFeedbackMessageAttribute>();
var ignoreAttribute = messageInfo.GetCustomAttribute<IgnoreRosMessageAttribute>();
RosMessage message;
if (goalAttribute != null || resultAttribute != null || feedbackAttribute != null || ignoreAttribute != null)
{
Type actionType;
if (goalAttribute != null)
{
actionType = typeof(GoalActionMessage<>);
}
else if (resultAttribute != null)
{
actionType = typeof(ResultActionMessage<>);
}
else if (feedbackAttribute != null)
{
actionType = typeof(FeedbackActionMessage<>);
}
else if (ignoreAttribute != null)
{
continue;
}
else
{
throw new InvalidOperationException($"Could create Action Message for {othertype}");
}
Type[] innerType = { othertype };
var goalMessageType = actionType.MakeGenericType(innerType);
message = (Activator.CreateInstance(goalMessageType)) as RosMessage;
}
else
{
message = Activator.CreateInstance(othertype) as RosMessage;
if ((message != null) && (message.MessageType == "undefined/unknown"))
{
throw new Exception("Invalid message type. Message type field (msgtype) was not initialized correctly.");
}
}
var packageName = message.MessageType.Split('/')[0];
if (!PackageNames.Contains(packageName))
{
PackageNames.Add(packageName);
}
Logger.LogDebug($"Register {message.MessageType}");
if (!TypeRegistry.ContainsKey(message.MessageType))
{
TypeRegistry.Add(message.MessageType, message.GetType());
}
else
{
var messageFromRegistry = CreateMessage(message.MessageType);
if (messageFromRegistry.MD5Sum() != message.MD5Sum())
{
throw new InvalidOperationException($"The message of type {message.MessageType} has already been " +
$"registered and the MD5 sums do not match. Already registered: {messageFromRegistry.MD5Sum()} " +
$"new message: {message.MD5Sum()}.");
} else
{
Logger.LogDebug($"The message of type {message.MessageType} has already been registered. Since the" +
"MD5 sums do match, the new message is ignored.");
}
}
}
}
public static void Reset()
{
defaultInstance = new Lazy<MessageTypeRegistry>(LazyThreadSafetyMode.ExecutionAndPublication);
}
}
}