Skip to content

Commit 47216c9

Browse files
committed
fix #207 and other small things
1 parent 6821ec8 commit 47216c9

File tree

4 files changed

+68
-51
lines changed

4 files changed

+68
-51
lines changed

src/fields/button/ButtonManager.ts

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@ import { type ButtonConfig } from '../../config/ButtonConfig';
22
import { getUUID } from '../../utils/Utils';
33
import { ErrorCollection } from '../../utils/errors/ErrorCollection';
44
import { ErrorLevel, MetaBindButtonError } from '../../utils/errors/MetaBindErrors';
5+
import { RefCounter } from '../../utils/RefCounter';
56

67
export class ButtonManager {
7-
buttons: Map<string, Map<string, ButtonConfig>>;
8+
// filePath -> buttonId -> ref counter of buttonConfig
9+
buttons: Map<string, Map<string, RefCounter<ButtonConfig>>>;
10+
// filePath -> buttonId -> listenerId -> callback
811
buttonLoadListeners: Map<string, Map<string, Map<string, (config: ButtonConfig) => void>>>;
912
buttonTemplates: Map<string, ButtonConfig>;
1013

@@ -89,34 +92,37 @@ export class ButtonManager {
8992
throw new Error(`ButtonManager | button with id ${buttonId} does not exist`);
9093
}
9194

92-
const fileButtonLoadListeners = this.buttonLoadListeners.get(filePath);
93-
if (!fileButtonLoadListeners) {
95+
const fileLoadListeners = this.buttonLoadListeners.get(filePath);
96+
if (!fileLoadListeners) {
9497
return;
9598
}
9699

97-
const buttonLoadListeners = fileButtonLoadListeners.get(buttonId);
98-
if (!buttonLoadListeners) {
100+
const loadListeners = fileLoadListeners.get(buttonId);
101+
if (!loadListeners) {
99102
return;
100103
}
101104

102-
for (const [_, fileButtonLoadListener] of buttonLoadListeners) {
105+
for (const [_, fileButtonLoadListener] of loadListeners) {
103106
fileButtonLoadListener(config);
104107
}
105108
}
106109

107110
private removeButtonLoadListener(filePath: string, buttonId: string, listenerId: string): void {
108-
const fileButtonLoadListeners = this.buttonLoadListeners.get(filePath);
109-
if (!fileButtonLoadListeners) {
111+
const fileLoadListeners = this.buttonLoadListeners.get(filePath);
112+
if (!fileLoadListeners) {
110113
return;
111114
}
112115

113-
const buttonLoadListeners = fileButtonLoadListeners.get(buttonId);
114-
if (!buttonLoadListeners) {
116+
const loadListeners = fileLoadListeners.get(buttonId);
117+
if (!loadListeners) {
115118
return;
116119
}
117120

118-
buttonLoadListeners.delete(listenerId);
119-
if (fileButtonLoadListeners.size === 0) {
121+
loadListeners.delete(listenerId);
122+
if (loadListeners.size === 0) {
123+
fileLoadListeners.delete(buttonId);
124+
}
125+
if (fileLoadListeners.size === 0) {
120126
this.buttonLoadListeners.delete(filePath);
121127
}
122128
}
@@ -137,33 +143,37 @@ export class ButtonManager {
137143
const fileButtons = this.buttons.get(filePath)!;
138144

139145
if (fileButtons.has(button.id)) {
140-
throw new Error(`ButtonManager | button with id "${button.id}" already exists`);
146+
if (JSON.stringify(fileButtons.get(button.id)?.getValue()) === JSON.stringify(button)) {
147+
fileButtons.get(button.id)?.increment();
148+
return;
149+
} else {
150+
throw new Error(`ButtonManager | button with id "${button.id}" already exists`);
151+
}
141152
}
142153

143-
fileButtons.set(button.id, button);
154+
fileButtons.set(button.id, new RefCounter(button));
144155
this.notifyButtonLoadListeners(filePath, button.id);
145156
}
146157

147-
public getButtons(filePath: string): Map<string, ButtonConfig> | undefined {
148-
return this.buttons.get(filePath);
149-
}
150-
151158
public getButton(filePath: string, buttonId: string): ButtonConfig | undefined {
152159
if (this.buttonTemplates.has(buttonId)) {
153160
return this.buttonTemplates.get(buttonId);
154161
}
155162

156163
const fileButtons = this.buttons.get(filePath);
157164
if (fileButtons) {
158-
return fileButtons.get(buttonId);
165+
return fileButtons.get(buttonId)?.getValue();
159166
}
160167
return undefined;
161168
}
162169

163170
public removeButton(filePath: string, buttonId: string): void {
164171
const fileButtons = this.buttons.get(filePath);
165172
if (fileButtons) {
166-
fileButtons.delete(buttonId);
173+
fileButtons.get(buttonId)?.decrement();
174+
if (fileButtons.get(buttonId)?.isEmpty()) {
175+
fileButtons.delete(buttonId);
176+
}
167177

168178
if (fileButtons.size === 0) {
169179
this.buttons.delete(filePath);

src/main.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ export default class MetaBindPlugin extends Plugin implements IPlugin {
173173
if (mdrcType === undefined) {
174174
continue;
175175
}
176-
console.log(content, ctx.getSectionInfo(codeBlock)?.lineStart, ctx.getSectionInfo(codeBlock)?.lineEnd);
176+
// console.log(content, ctx.getSectionInfo(codeBlock)?.lineStart, ctx.getSectionInfo(codeBlock)?.lineEnd);
177177
InlineMDRCUtils.constructMDRC(mdrcType, content, ctx.sourcePath, codeBlock, ctx, this);
178178
}
179179
}, 1);

src/metadata/InternalMetadataSources.ts

Lines changed: 6 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -172,19 +172,11 @@ export class ScopeMetadataSource implements IMetadataSource<IMetadataCacheItem>
172172
}
173173

174174
public delete(_cacheItem: IMetadataCacheItem): void {
175-
throw new MetaBindInternalError({
176-
errorLevel: ErrorLevel.CRITICAL,
177-
effect: 'action not permitted',
178-
cause: `source 'scope' should have no cache items or subscriptions`,
179-
});
175+
// noop
180176
}
181177

182178
public getCacheItemForStoragePath(_storagePath: string): IMetadataCacheItem | undefined {
183-
throw new MetaBindInternalError({
184-
errorLevel: ErrorLevel.CRITICAL,
185-
effect: 'action not permitted',
186-
cause: `source 'scope' should have no cache items or subscriptions`,
187-
});
179+
return undefined;
188180
}
189181

190182
public iterateCacheItems(): IterableIterator<IMetadataCacheItem> {
@@ -196,27 +188,15 @@ export class ScopeMetadataSource implements IMetadataSource<IMetadataCacheItem>
196188
}
197189

198190
public readCache(_bindTarget: BindTargetDeclaration): unknown {
199-
throw new MetaBindInternalError({
200-
errorLevel: ErrorLevel.CRITICAL,
201-
effect: 'action not permitted',
202-
cause: `source 'scope' should have no cache items or subscriptions`,
203-
});
191+
return undefined;
204192
}
205193

206194
public readCacheItem(_cacheItem: IMetadataCacheItem, _propPath: PropPath): unknown {
207-
throw new MetaBindInternalError({
208-
errorLevel: ErrorLevel.CRITICAL,
209-
effect: 'action not permitted',
210-
cause: `source 'scope' should have no cache items or subscriptions`,
211-
});
195+
return undefined;
212196
}
213197

214198
public shouldDelete(_cacheItem: IMetadataCacheItem): boolean {
215-
throw new MetaBindInternalError({
216-
errorLevel: ErrorLevel.CRITICAL,
217-
effect: 'action not permitted',
218-
cause: `source 'scope' should have no cache items or subscriptions`,
219-
});
199+
return true;
220200
}
221201

222202
public subscribe(_subscription: IMetadataSubscription): IMetadataCacheItem {
@@ -248,11 +228,7 @@ export class ScopeMetadataSource implements IMetadataSource<IMetadataCacheItem>
248228
}
249229

250230
public updateEntireCache(_value: Metadata, _cacheItem: IMetadataCacheItem): void {
251-
throw new MetaBindInternalError({
252-
errorLevel: ErrorLevel.CRITICAL,
253-
effect: 'action not permitted',
254-
cause: `source 'scope' should have no cache items or subscriptions`,
255-
});
231+
// noop
256232
}
257233

258234
public readEntireCacheItem(_cacheItem: IMetadataCacheItem): Metadata {

src/utils/RefCounter.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
export class RefCounter<T> {
2+
private readonly value: T;
3+
private count: number;
4+
5+
constructor(value: T) {
6+
this.value = value;
7+
this.count = 1;
8+
}
9+
10+
getValue(): T {
11+
return this.value;
12+
}
13+
14+
increment(): number {
15+
this.count += 1;
16+
return this.count;
17+
}
18+
19+
decrement(): number {
20+
this.count -= 1;
21+
return this.count;
22+
}
23+
24+
getCount(): number {
25+
return this.count;
26+
}
27+
28+
isEmpty(): boolean {
29+
return this.count === 0;
30+
}
31+
}

0 commit comments

Comments
 (0)