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
13Function::Function()
14	:
15	fSourceCode(NULL),
16	fSourceCodeState(FUNCTION_SOURCE_NOT_LOADED),
17	fNotificationsDisabled(0)
18{
19}
20
21
22Function::~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
32void
33Function::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
61void
62Function::AddListener(Listener* listener)
63{
64	fListeners.Add(listener);
65}
66
67
68void
69Function::RemoveListener(Listener* listener)
70{
71	fListeners.Remove(listener);
72}
73
74
75void
76Function::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
87void
88Function::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
98void
99Function::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
111void
112Function::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
130Function::Listener::~Listener()
131{
132}
133
134
135void
136Function::Listener::FunctionSourceCodeChanged(Function* function)
137{
138}
139