Jump to content

Empfohlene Beiträge

Geschrieben

Hallo Neo,

wahrscheinlich wirst du wieder sagen dass dies nicht fuer die allgemeinheit nuetzlich ist, aber ich poste es dennoch.
Meine scripte wachsen, alles generisch und modularisiert.
Ich kann natuerlich beliebig viele module mit je einem globalen script definieren um meine scripte besser zu strukturieren, aber das macht dann bei der wiederverwendung aufwand.
Ich faende ein "include" statement wie in anderen sprachen sehr nuetzlich, womit ich abgeschlossene geteste scripten einbinden kann ohne dass das ganze unuebersichtlich wird.
Eine alternative waere, wenn du mehr als ein globales script pro modul zulassen koenntest. Das ist zwar nicht das gleiche aber ein kompromis. Vielleicht noch nicht dieses jahr relevant, aber wen mehr und mehr benutzer lua verwenden und nicht nur die EV koennte das auch andere betreffen. 
Hier ein typisches beispiel: Es sind hilfsfunktionen fuer den zugriff auf eine datenstruktur, die ampelinstallationen an kreuzungen beschreibt.
 


-- ##################################################################################################
-- 📄 PhaseAccess.lua
-- 🔵 Purpose:
-- This module defines helper functions to access and manipulate the signal phase data structures.
-- 
-- 🔵 Why:
-- 1. Encapsulates the structure of phase definitions (offPhase, blinkPhase, phases, steps, triggers).
-- 2. Allows changes to the internal data layout later without rewriting all core logic.
-- 3. Centralizes repetitive lookup patterns (finding phase groups, steps, triggers).
-- 4. Makes higher-level functions like AdvancePhase shorter, cleaner, and easier to maintain.
-- 
-- 🔵 When to use:
-- - Whenever signal states, phase groups, step triggers, green times, or emissions must be accessed.
-- - Whenever crossing timing or switching behavior must depend on the phase definition.
-- 
-- 🔵 Advantages:
-- - Reduces repeated code in phase handling logic.
-- - Isolates possible data format changes into one place.
-- - Improves code readability and debuggability.
-- 
-- ##################################################################################################


-- 🔵 Find full phase data for a given crossing type
-- Used whenever a crossing needs to load its signalPhases by type
function GetPhaseDataForType(signalPhases, crossingType)
  for i = 1, #signalPhases do
    if signalPhases[i].type == crossingType then
      return signalPhases[i]
    end
  end
  return nil
end

-- 🔵 Return offPhase array ("lights off" state) from a phase definition
-- Used when initializing crossing or setting all signals off
function GetOffPhaseFromPhaseData(phaseData)
  return phaseData and phaseData.offPhase or nil
end

-- 🔵 Return blinkPhase array ("blinking" state) from a phase definition
-- Used for crossings set to flashing yellow or emergency blinking
function GetBlinkPhaseFromPhaseData(phaseData)
  return phaseData and phaseData.blinkPhase or nil
end

-- 🔵 Get the list of phase groups ("main", "leftTurn_2", "leftTurn_4", etc.)
-- Needed whenever you want to find specific signal behavior groups
function GetPhaseGroupsFromPhaseData(phaseData)
  return phaseData and phaseData.phases or nil
end

-- 🔵 Find a single phase group by its name
-- Used to access steps for "main" or special leftTurn phases
function FindPhaseGroupByName(phaseGroups, groupName)
  if not phaseGroups then return nil end
  for i = 1, #phaseGroups do
    if phaseGroups[i].name == groupName then
      return phaseGroups[i]
    end
  end
  return nil
end

-- 🔵 Get the list of steps from a phase group
-- Needed whenever advancing or processing signal switching
function GetStepsFromPhaseGroup(phaseGroup)
  return phaseGroup and phaseGroup.steps or nil
end

-- 🔵 Return the triggers table if defined
-- Needed when checking if a special trigger (left turn, etc.) is active
function GetTriggersFromPhaseData(phaseData)
  return phaseData and phaseData.triggers or nil
end

-- 🔵 Return the timing table if defined
-- Needed when adjusting timing between signal phases
function GetTimingFromPhaseData(phaseData)
  return phaseData and phaseData.timing or nil
end

-- 🔵 Return the greenTimeMultiplier table inside timing
-- Needed for setting dynamic green times depending on phase group
function GetGreenTimeMultiplierFromTiming(timing)
  return timing and timing.greenTimeMultiplier or nil
end

-- 🔵 Return the specific green multiplier array for a group ("main", "leftTurn_2", etc.)
-- Needed to adjust how long each signal group stays green
function GetGreenMultiplierForGroup(greenMultipliers, groupName)
  return greenMultipliers and greenMultipliers[groupName] or nil
end

-- 🔵 Return the next signal state array for a group at a given step
-- Used to update multiple signals in one logical step
function GetNextStateForSignalGroup(phaseGroup, stepIndex)
  local steps = GetStepsFromPhaseGroup(phaseGroup)
  return steps and steps[stepIndex] or nil
end

-- 🔵 Return the next single signal state at a step (e.g., for S1, S2, etc.)
-- Used if only a single signal needs to be checked or updated
function GetNextStateForSignal(phaseGroup, stepIndex, signalIndex)
  local step = GetNextStateForSignalGroup(phaseGroup, stepIndex)
  return step and step[signalIndex] or nil
end

-- 🔵 Check if a trigger is defined for a specific step
-- Used to see if phase switching should wait for external events
function IsTriggerDefinedForPhase(triggers, stepIndex)
  if not triggers then return false end
  local entry = triggers[stepIndex]
  return entry and (entry.trigger ~= nil)
end

-- 🔵 Check if a phase group auto-advances (no waiting)
-- Used to decide if the crossing should immediately continue to next step
function IsGroupAutoAdvance(phaseGroup)
  return phaseGroup and phaseGroup.autoAdvance == true
end

-- 🔵 Return the target phase name triggered at a given step
-- Used to switch into left turn phases, etc.
function GetTriggerPhaseName(triggers, stepIndex)
  if not triggers then return nil end
  local entry = triggers[stepIndex]
  return entry and entry.trigger and entry.trigger.phase or nil
end

-- 🔵 Return the emitted phase name when step emits a change
-- Used when leaving special triggered phases (back to "main" etc.)
function GetEmitName(triggers, stepIndex)
  if not triggers then return nil end
  local entry = triggers[stepIndex]
  return entry and entry.emit or nil
end

-- 🔵 Advance the phase index safely (wrap around if overflow)
-- Used at the start of every AdvancePhase to move to the next step
function AdvancePhaseIndex(crossing, steps)
  crossing.phaseIndex = (crossing.phaseIndex or 0) + 1
  if not steps[crossing.phaseIndex] then
    crossing.phaseIndex = 1
  end
end

-- 🔵 Create a readable string of current step signal states
-- Used mainly for debug outputs ("3, 1, 3, 1")
function DumpSignalState(step)
  local text = ""
  for i = 1, #step do
    if i > 1 then text = text .. ", " end
    text = text .. tostring(step[i] or "nil")
  end
  return text
end

Und viele andere gruppen von generischen fuktionen
Gruss
Gmd

 

Geschrieben
vor 20 Minuten schrieb gmd:

Ich faende ein "include" statement wie in anderen sprachen sehr nuetzlich

Das hatte ich mir auch schon mal (bisher vergeblich) gewünscht. Auch ohne @gmds Ansatz wäre es nützlich, wenn man seine Library (die natürlich keine direkten Objektbezüge haben darf) einbinden könnte.

Erstelle ein Benutzerkonto oder melde dich an, um zu kommentieren

Du musst ein Benutzerkonto besitzen, um einen Kommentar verfassen zu können

Benutzerkonto erstellen

Neues Benutzerkonto für unsere Community erstellen.

Neues Benutzerkonto erstellen

Anmelden

Du hast bereits ein Benutzerkonto? Melde dich hier an.

Jetzt anmelden
×
×
  • Neu erstellen...