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