forked from project-chip/connectedhomeip
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathServerClusterInterfaceRegistry.h
136 lines (116 loc) · 5.13 KB
/
ServerClusterInterfaceRegistry.h
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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/*
* Copyright (c) 2025 Project CHIP Authors
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <app/ConcreteClusterPath.h>
#include <app/server-cluster/ServerClusterInterface.h>
#include <lib/core/CHIPError.h>
#include <lib/core/DataModelTypes.h>
namespace chip {
namespace app {
/// Represents an entry in the server cluster interface registry for
/// a specific interface.
///
/// In practice this is a single-linked list element.
struct ServerClusterRegistration
{
// A single-linked list of clusters registered for the given `endpointId`
ServerClusterInterface * const serverClusterInterface;
ServerClusterRegistration * next;
constexpr ServerClusterRegistration(ServerClusterInterface & interface, ServerClusterRegistration * next_item = nullptr) :
serverClusterInterface(&interface), next(next_item)
{}
ServerClusterRegistration(ServerClusterRegistration && other) = default;
// we generally do not want to allow copies as those may have different "next" entries.
ServerClusterRegistration(const ServerClusterRegistration & other) = delete;
ServerClusterRegistration & operator=(const ServerClusterRegistration & other) = delete;
};
/// Allows registering and retrieving ServerClusterInterface instances for specific cluster paths.
class ServerClusterInterfaceRegistry
{
public:
/// represents an iterable list of clusters
class ClustersList
{
public:
class Iterator
{
public:
Iterator(ServerClusterRegistration * interface, EndpointId endpoint) : mRegistration(interface), mEndpointId(endpoint)
{
AdvanceUntilMatchingEndpoint();
}
Iterator & operator++()
{
if (mRegistration != nullptr)
{
mRegistration = mRegistration->next;
}
AdvanceUntilMatchingEndpoint();
return *this;
}
bool operator==(const Iterator & other) const { return mRegistration == other.mRegistration; }
bool operator!=(const Iterator & other) const { return mRegistration != other.mRegistration; }
ServerClusterInterface * operator*() { return mRegistration->serverClusterInterface; }
private:
ServerClusterRegistration * mRegistration;
EndpointId mEndpointId;
void AdvanceUntilMatchingEndpoint()
{
while ((mRegistration != nullptr) && (mRegistration->serverClusterInterface->GetPath().mEndpointId != mEndpointId))
{
mRegistration = mRegistration->next;
}
}
};
constexpr ClustersList(ServerClusterRegistration * start, EndpointId endpointId) : mStart(start), mEndpointId(endpointId) {}
Iterator begin() { return { mStart, mEndpointId }; }
Iterator end() { return { nullptr, mEndpointId }; }
private:
ServerClusterRegistration * mStart;
EndpointId mEndpointId;
};
~ServerClusterInterfaceRegistry();
/// Add the given entry to the registry.
///
/// Requirements:
/// - entry MUST NOT be part of any other registration
/// - LIFETIME of entry must outlive the Registry (or entry must be unregistered)
///
/// There can be only a single registration for a given `endpointId/clusterId` path.
[[nodiscard]] CHIP_ERROR Register(ServerClusterRegistration & entry);
/// Remove an existing registration for a given endpoint/cluster path.
///
/// Returns the previous registration if any exists (or nullptr if nothing
/// to unregister)
ServerClusterInterface * Unregister(const ConcreteClusterPath & path);
/// Return the interface registered for the given cluster path or nullptr if one does not exist
ServerClusterInterface * Get(const ConcreteClusterPath & path);
/// Provides a list of clusters that are registered for the given endpoint.
///
/// ClustersList points inside the internal registrations of the registry, so
/// the list is only valid as long as the registry is not modified.
ClustersList ClustersOnEndpoint(EndpointId endpointId);
/// Unregister all registrations for the given endpoint.
void UnregisterAllFromEndpoint(EndpointId endpointId);
private:
ServerClusterRegistration * mRegistrations = nullptr;
// A one-element cache to speed up finding a cluster within an endpoint.
// The endpointId specifies which endpoint the cache belongs to.
ServerClusterInterface * mCachedInterface = nullptr;
};
} // namespace app
} // namespace chip