1 /*
2 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Copyright 2010, Rene Gollent, rene@gollent.com.
4 * Distributed under the terms of the MIT License.
5 */
6
7 #include "Function.h"
8
9 #include "FileSourceCode.h"
10 #include "FunctionID.h"
11
12
Function()13 Function::Function()
14 :
15 fSourceCode(NULL),
16 fSourceCodeState(FUNCTION_SOURCE_NOT_LOADED),
17 fNotificationsDisabled(0)
18 {
19 }
20
21
~Function()22 Function::~Function()
23 {
24 SetSourceCode(NULL, FUNCTION_SOURCE_NOT_LOADED);
25 if (FirstInstance() != NULL) {
26 FirstInstance()->SourceFile()->RemoveListener(this);
27 FirstInstance()->SourceFile()->ReleaseReference();
28 }
29 }
30
31
32 void
SetSourceCode(FileSourceCode * source,function_source_state state)33 Function::SetSourceCode(FileSourceCode* source, function_source_state state)
34 {
35 if (source == fSourceCode && state == fSourceCodeState)
36 return;
37
38 if (fSourceCode != NULL)
39 fSourceCode->ReleaseReference();
40
41 fSourceCode = source;
42 fSourceCodeState = state;
43
44 if (fSourceCode != NULL) {
45 fSourceCode->AcquireReference();
46
47 // unset all instances' source codes
48 fNotificationsDisabled++;
49 for (FunctionInstanceList::Iterator it = fInstances.GetIterator();
50 FunctionInstance* instance = it.Next();) {
51 instance->SetSourceCode(NULL, FUNCTION_SOURCE_NOT_LOADED);
52 }
53 fNotificationsDisabled--;
54 }
55
56 // notify listeners
57 NotifySourceCodeChanged();
58 }
59
60
61 void
AddListener(Listener * listener)62 Function::AddListener(Listener* listener)
63 {
64 fListeners.Add(listener);
65 }
66
67
68 void
RemoveListener(Listener * listener)69 Function::RemoveListener(Listener* listener)
70 {
71 fListeners.Remove(listener);
72 }
73
74
75 void
AddInstance(FunctionInstance * instance)76 Function::AddInstance(FunctionInstance* instance)
77 {
78 bool firstInstance = fInstances.IsEmpty();
79 fInstances.Add(instance);
80 if (firstInstance && SourceFile() != NULL) {
81 instance->SourceFile()->AcquireReference();
82 instance->SourceFile()->AddListener(this);
83 }
84 }
85
86
87 void
RemoveInstance(FunctionInstance * instance)88 Function::RemoveInstance(FunctionInstance* instance)
89 {
90 fInstances.Remove(instance);
91 if (fInstances.IsEmpty() && instance->SourceFile() != NULL) {
92 instance->SourceFile()->RemoveListener(this);
93 instance->SourceFile()->ReleaseReference();
94 }
95 }
96
97
98 void
NotifySourceCodeChanged()99 Function::NotifySourceCodeChanged()
100 {
101 if (fNotificationsDisabled > 0)
102 return;
103
104 for (ListenerList::Iterator it = fListeners.GetIterator();
105 Listener* listener = it.Next();) {
106 listener->FunctionSourceCodeChanged(this);
107 }
108 }
109
110
111 void
LocatableFileChanged(LocatableFile * file)112 Function::LocatableFileChanged(LocatableFile* file)
113 {
114 BString locatedPath;
115 BString path;
116 file->GetPath(path);
117 if (file->GetLocatedPath(locatedPath) && locatedPath != path) {
118 SetSourceCode(NULL, FUNCTION_SOURCE_NOT_LOADED);
119 for (FunctionInstanceList::Iterator it = fInstances.GetIterator();
120 FunctionInstance* instance = it.Next();) {
121 instance->SetSourceCode(NULL, FUNCTION_SOURCE_NOT_LOADED);
122 }
123 }
124 }
125
126
127 // #pragma mark - Listener
128
129
~Listener()130 Function::Listener::~Listener()
131 {
132 }
133
134
135 void
FunctionSourceCodeChanged(Function * function)136 Function::Listener::FunctionSourceCodeChanged(Function* function)
137 {
138 }
139