00001 #include "context.hpp"
00002 #include "stream.hpp"
00003 #include "threads.hpp"
00004
00005
00007
00008 Context* Context::Create(
00009 const char* output_device,
00010 const char* parameters,
00011 IFileSystem* file_system)
00012 {
00013 ADR_GUARD("Context::Create");
00014
00015 Context* context = new Context();
00016 if (context->Initialize(output_device, parameters, file_system)) {
00017 return context;
00018 } else {
00019 ADR_LOG("deleting context object");
00020 delete context;
00021 return 0;
00022 }
00023 }
00024
00026
00027 Context::Context()
00028 {
00029 m_ref_count = 0;
00030 m_thread_should_die = false;
00031 m_thread_exists = false;
00032 m_file_system = 0;
00033 m_output_context = 0;
00034 }
00035
00037
00038 Context::~Context()
00039 {
00040 ADR_GUARD("Context::~Context");
00041
00042 if (m_thread_exists) {
00043 ADR_LOG("asking thread to die...");
00044
00045
00046 m_thread_should_die = true;
00047
00048
00049 while (m_thread_should_die) {
00050 AI_Sleep(50);
00051 }
00052
00053 ADR_LOG("thread is dead");
00054 }
00055
00056 delete m_output_context;
00057 delete m_file_system;
00058 }
00059
00061
00062 bool
00063 Context::Initialize(
00064 const char* output_device,
00065 const char* parameters,
00066 IFileSystem* file_system)
00067 {
00068 m_ref_count = 1;
00069 m_thread_should_die = false;
00070 m_thread_exists = false;
00071
00072 m_file_system = file_system;
00073
00074 m_output_context = OpenContext(output_device, parameters);
00075 if (!m_output_context) {
00076 ADR_LOG("could not open output context");
00077 return false;
00078 }
00079
00080 ADR_LOG("creating thread...");
00081
00082
00083
00084
00085
00086
00087
00088 bool result = AI_CreateThread(ThreadRoutine, this, 0);
00089 if (!result) {
00090 ADR_LOG("thread creation failed!");
00091 delete m_output_context;
00092 return false;
00093 }
00094
00095 ADR_LOG("thread creation succeeded");
00096 return true;
00097 }
00098
00100
00101 void
00102 Context::AddRef()
00103 {
00104 ++m_ref_count;
00105 }
00106
00108
00109 void
00110 Context::Release()
00111 {
00112 ADR_GUARD("Context::Release");
00113
00114 if (--m_ref_count == 0) {
00115 delete this;
00116 }
00117 }
00118
00120
00121 void
00122 Context::ThreadRoutine(void* opaque)
00123 {
00124 Context* context = reinterpret_cast<Context*>(opaque);
00125 context->ThreadRoutine();
00126 }
00127
00129
00130 void
00131 Context::ThreadRoutine()
00132 {
00133 m_thread_exists = true;
00134
00135
00136 while (!m_thread_should_die) {
00137 ADR_LOG("Updating output context...");
00138 ::AI_Lock l__(this);
00139 m_output_context->Update();
00140 }
00141
00142
00143 m_thread_should_die = false;
00144 m_thread_exists = false;
00145 }
00146
00148
00149 Stream*
00150 Context::OpenStream(const char* filename)
00151 {
00152 ADR_GUARD("Context::OpenStream");
00153
00154 AI_Lock l__(this);
00155
00156 Stream* stream = new Stream();
00157 if (stream->Initialize(this, filename)) {
00158 return stream;
00159 } else {
00160 delete stream;
00161 return 0;
00162 }
00163 }
00164