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