void Dispatcher::contextProcedure(void* ucontext) { assert(firstReusableContext == nullptr); NativeContext context; context.ucontext = ucontext; context.interrupted = false; context.next = nullptr; firstReusableContext = &context; ucontext_t* oldContext = static_cast<ucontext_t*>(context.ucontext); if (swapcontext(oldContext, static_cast<ucontext_t*>(currentContext->ucontext)) == -1) { throw std::runtime_error("Dispatcher::contextProcedure, swapcontext failed, " + lastErrorMessage()); } for (;;) { ++runningContextCount; try { context.procedure(); } catch(std::exception&) { } if (context.group != nullptr) { if (context.groupPrev != nullptr) { assert(context.groupPrev->groupNext == &context); context.groupPrev->groupNext = context.groupNext; if (context.groupNext != nullptr) { assert(context.groupNext->groupPrev == &context); context.groupNext->groupPrev = context.groupPrev; } else { assert(context.group->lastContext == &context); context.group->lastContext = context.groupPrev; } } else { assert(context.group->firstContext == &context); context.group->firstContext = context.groupNext; if (context.groupNext != nullptr) { assert(context.groupNext->groupPrev == &context); context.groupNext->groupPrev = nullptr; } else { assert(context.group->lastContext == &context); if (context.group->firstWaiter != nullptr) { if (firstResumingContext != nullptr) { assert(lastResumingContext->next == nullptr); lastResumingContext->next = context.group->firstWaiter; } else { firstResumingContext = context.group->firstWaiter; } lastResumingContext = context.group->lastWaiter; context.group->firstWaiter = nullptr; } } } pushReusableContext(context); } dispatch(); } };
void Window2_Render(Win32Window* window, float alpha, float elapsedtime) { static float time = 0; float world[16]; time += elapsedtime; DrawingItem* drawingitem = window->GetDrawingItem(); DrawingLayer& bottomlayer = drawingitem->GetBottomLayer(); { NativeContext context = bottomlayer.GetContext(); GLMatrixRotationAxis(world, -fmodf(time * 20.0f, 360.0f) * (3.14152f / 180.0f), 0, 0, 1); context.Clear(OpenGLColor(0.0f, 0.125f, 0.3f, 1.0f)); context.SetWorldTransform(world); context.SetColor(OpenGLColor(1, 1, 1, 1)); context.MoveTo(-120, 120); context.LineTo(120, 120); context.LineTo(120, -120); context.LineTo(-120, -120); context.LineTo(-120, 120); } drawingitem->RecomposeLayers(); }
void Dispatcher::contextProcedure() { assert(GetCurrentThreadId() == threadId); assert(firstReusableContext == nullptr); NativeContext context; context.interrupted = false; context.next = nullptr; context.inExecutionQueue = false; firstReusableContext = &context; SwitchToFiber(currentContext->fiber); for (;;) { ++runningContextCount; try { context.procedure(); } catch (...) { } if (context.group != nullptr) { if (context.groupPrev != nullptr) { assert(context.groupPrev->groupNext == &context); context.groupPrev->groupNext = context.groupNext; if (context.groupNext != nullptr) { assert(context.groupNext->groupPrev == &context); context.groupNext->groupPrev = context.groupPrev; } else { assert(context.group->lastContext == &context); context.group->lastContext = context.groupPrev; } } else { assert(context.group->firstContext == &context); context.group->firstContext = context.groupNext; if (context.groupNext != nullptr) { assert(context.groupNext->groupPrev == &context); context.groupNext->groupPrev = nullptr; } else { assert(context.group->lastContext == &context); if (context.group->firstWaiter != nullptr) { if (firstResumingContext != nullptr) { assert(lastResumingContext->next == nullptr); lastResumingContext->next = context.group->firstWaiter; } else { firstResumingContext = context.group->firstWaiter; } lastResumingContext = context.group->lastWaiter; context.group->firstWaiter = nullptr; } } } pushReusableContext(context); } dispatch(); } }
void THREAD_Run() { float world[16]; float time = 0; while( true ) { if( !glwindow ) continue; DrawingItem* drawingitem = glwindow->GetDrawingItem(); DrawingLayer& feedbacklayer = drawingitem->GetFeedbackLayer(); { NativeContext context = feedbacklayer.GetContext(); float bigradius = 150; float smallradius = 80; float m2pi = 6.293185f; int segments = 16; GLMatrixRotationAxis(world, fmodf(time * 20.0f, 360.0f) * (3.14152f / 180.0f), 0, 0, 1); context.Clear(OpenGLColor(0, 0, 0, 0)); context.SetWorldTransform(world); context.SetColor(OpenGLColor(0, 1, 0, 1)); context.MoveTo(0, bigradius); for( int i = 1; i <= segments; ++i ) { if( i % 2 == 1 ) { context.LineTo( sinf((m2pi / segments) * i) * smallradius, cosf((m2pi / segments) * i) * smallradius); } else { context.LineTo( sinf((m2pi / segments) * i) * bigradius, cosf((m2pi / segments) * i) * bigradius); } } } time += 0.5f; Sleep(500); // 34 } }
void Window1_Render(Win32Window* window, float alpha, float elapsedtime) { static float time = 0; float world[16]; time += elapsedtime; DrawingItem* drawingitem = window->GetDrawingItem(); DrawingLayer& bottomlayer = drawingitem->GetBottomLayer(); { NativeContext context = bottomlayer.GetContext(); float bigradius = 150; float smallradius = 80; float m2pi = 6.293185f; int segments = 16; GLMatrixRotationAxis(world, fmodf(time * 20.0f, 360.0f) * (3.14152f / 180.0f), 0, 0, 1); context.Clear(OpenGLColor(0.0f, 0.125f, 0.3f, 1.0f)); context.SetWorldTransform(world); context.MoveTo(0, bigradius); for( int i = 1; i <= segments; ++i ) { if( i % 2 == 1 ) { context.LineTo( sinf((m2pi / segments) * i) * smallradius, cosf((m2pi / segments) * i) * smallradius); } else { context.LineTo( sinf((m2pi / segments) * i) * bigradius, cosf((m2pi / segments) * i) * bigradius); } } } DrawingLayer& feedbacklayer = drawingitem->GetFeedbackLayer(); { NativeContext context = feedbacklayer.GetContext(); GLMatrixRotationAxis(world, -fmodf(time * 20.0f, 360.0f) * (3.14152f / 180.0f), 0, 0, 1); context.Clear(OpenGLColor(0, 0, 0, 0)); context.SetWorldTransform(world); context.SetColor(OpenGLColor(0, 1, 0, 1)); context.MoveTo(-120, 120); context.LineTo(120, 120); context.LineTo(120, -120); context.LineTo(-120, -120); context.LineTo(-120, 120); } drawingitem->RecomposeLayers(); }