static void transmitted(Worklet *base) { auto packet = frg::container_of(base, &AcceptBase::worklet); packet->callback(packet->error(), packet->lane()); }
void CFreewayView::OnDraw(CDC* pDC) { CFreewayDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if (!pDoc) return; CRect rect; GetClientRect(&rect); // [pixel] const CSize carBoxSize(28, 8); const CSize carMargin(4, 0); const CSize carSize = carBoxSize - carMargin -carMargin; const double pixelPerMeter = carBoxSize.cx/m_simulation.m_carLength.m_val; const int roadMargin = 10; const int laneMargin = 2; const int laneHeight = carBoxSize.cy + 2*laneMargin; const int sectorWidth = (int)(m_simulation.SectorLen().m_val*pixelPerMeter); const int roadHeight = (1 + laneHeight)*m_simulation.nLanes() + 2*roadMargin + 1; // [Sectors] const int w = rect.Width()/sectorWidth; if (w == 0) return; const int h = (m_simulation.nSectors() + w - 1)/w; // [m] const Meters wDist = w*m_simulation.SectorLen(); // [pixel] const int laneWidth = w*sectorWidth + carBoxSize.cx; // colors const COLORREF roadColor = RGB(180, 180, 180); const COLORREF siteColor = RGB(60, 60, 60); const COLORREF marginColor = RGB(255, 255, 255); CPen border(PS_SOLID, 1, RGB(0, 0, 0)); CPen middle(PS_DASH, 1, RGB(0, 0, 0)); CBrush roadBrush(roadColor); LOGBRUSH logBrush; logBrush.lbStyle = BS_SOLID; logBrush.lbColor = roadColor; CPen lane(PS_SOLID | PS_GEOMETRIC | PS_ENDCAP_FLAT, laneHeight, &logBrush); logBrush.lbColor = siteColor; CPen construction(PS_SOLID | PS_GEOMETRIC | PS_ENDCAP_FLAT, laneHeight, &logBrush); logBrush.lbColor = marginColor; CPen noRoad(PS_SOLID | PS_GEOMETRIC | PS_ENDCAP_FLAT, laneHeight, &logBrush); int y = roadMargin; int SectorOffset = 0; SectorInfo si(0, 0); // draw road pDC->SetBkColor(roadColor); for (int i = 0; i < h; i++) { pDC->SelectObject(&border); pDC->MoveTo(0, y); pDC->LineTo(laneWidth, y); y++; for (int l = m_simulation.nLanes() - 1; l >= 0; l--) { si.m_lane = l; pDC->SelectObject(&lane); int y2 = y + laneHeight/2; pDC->MoveTo(0, y2); pDC->LineTo(laneWidth, y2); for (int j = 0; j < w; j++) { si.m_sectorNr = SectorOffset + j; if (si.m_sectorNr < m_simulation.nSectors()) { if (m_simulation.isClosed(si)) { pDC->SelectObject(&construction); pDC->MoveTo(j*sectorWidth, y2); if (j == w - 1) { pDC->LineTo(laneWidth, y2); } else { pDC->LineTo((j+1)*sectorWidth, y2); } } } else { pDC->SelectObject(noRoad); pDC->MoveTo(j*sectorWidth + carBoxSize.cx, y2); pDC->LineTo(laneWidth, y2); } } y += laneHeight; if (l > 0) { pDC->SelectObject(&middle); pDC->MoveTo(0, y); pDC->LineTo(laneWidth, y); y++; } } pDC->SelectObject(&border); pDC->MoveTo(0, y); pDC->LineTo(laneWidth, y); y += 2*roadMargin + 1; SectorOffset += w; } // draw cars auto& it = m_simulation.m_cars.begin(); while (it != m_simulation.m_cars.end()) { const Car& car = *it->get(); const Position& position = car.getPosition(); const div_t qr = div((int)(position.m_pos.m_val*pixelPerMeter), (int)(wDist.m_val*pixelPerMeter)); const int y = qr.quot*roadHeight + roadMargin + (m_simulation.nLanes() - car.getLane() - 1)*(laneHeight + 1) + 1 + laneMargin; const CRect carRect(CPoint(qr.rem, y) + carMargin, carSize); CBrush carBrush(car.getColor()); pDC->FillRect(carRect, &carBrush); it++; } }