xref: /haiku/src/kits/debugger/debug_info/Function.cpp (revision fce4895d1884da5ae6fb299d23c735c598e690b1)
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