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