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