Viewport build

This commit is contained in:
2026-07-18 21:33:47 -07:00
parent 50ad462318
commit 160f6bdadf
3 changed files with 29 additions and 231 deletions

View File

@ -521,12 +521,17 @@ def compile(assets_only=False):
else:
log.error('Build failed')
def build(target, is_play=False, is_publish=False, is_export=False):
def build(target, is_play=False, is_publish=False, is_export=False, is_viewport=False, viewport_width=1920, viewport_height=1080):
global profile_time
profile_time = time.time()
wrd = bpy.data.worlds['Lnx']
state.is_viewport = is_viewport
if is_viewport:
state.viewport_width = viewport_width
state.viewport_height = viewport_height
if is_play and wrd.lnx_runtime == 'Hashlink':
current_os = lnx.utils.get_os()
if current_os == 'win':
@ -690,7 +695,11 @@ def run_viewport_runtime(viewport_id, width=1920, height=1080):
if not os.path.exists(path + '/krom.js'):
log.warn(f'Krom build not found at {path}/krom.js - build project first')
return None, None
if wrd.lnx_live_patch:
live_patch.start()
open(path + '/krom.patch', 'w', encoding='utf-8').close()
os.chdir(krom_location)
cmd = [krom_path, path, path_resources]
@ -725,95 +734,6 @@ _viewport_build_in_progress = False
_viewport_pending_launches = [] # List of (viewport_id, width, height) tuples
_viewport_proc_build = None # Separate process tracker for viewport builds
def build_viewport(viewport_id, width=1920, height=1080):
"""Build project for viewport"""
global _viewport_build_in_progress, _viewport_pending_launches, profile_time, scripts_mtime
wrd = bpy.data.worlds.get('Lnx')
if not wrd:
log.warn('No Lnx world found - cannot build for viewport')
return
krom_js_path = lnx.utils.get_fp_build() + '/debug/krom/krom.js'
if os.path.exists(krom_js_path) and not wrd.lnx_recompile:
log.info(f'Using cached viewport build for {viewport_id}')
run_viewport_runtime(viewport_id, width, height)
return
pending_entry = (viewport_id, width, height)
if pending_entry not in _viewport_pending_launches:
_viewport_pending_launches.append(pending_entry)
log.info(f'Queued viewport {viewport_id} for launch after build')
# If a build is already in progress and there is an actual build process, wait
# _viewport_proc_build checks viewport ,not state.proc_build (which is for play button)
if _viewport_build_in_progress:
if _viewport_proc_build is not None and _viewport_proc_build.poll() is None:
log.info(f'Build in progress, viewport {viewport_id} will launch when ready')
return
else:
log.info(f'Resetting stale viewport build state')
_viewport_build_in_progress = False
_viewport_build_in_progress = True
profile_time = time.time()
log.info(f'Starting viewport build for {len(_viewport_pending_launches)} viewport(s)')
# Set viewport mode flags but not the is_play flag meant for external launcher
state.is_viewport = True
state.viewport_width = width
state.viewport_height = height
state.target = 'krom'
state.is_play = False # NOT play mode
state.is_publish = False
state.is_export = False
# Recompile detection (matching play() behavior)
if not wrd.lnx_cache_build or \
not os.path.isfile(krom_js_path) or \
assets.khafile_defs_last != assets.khafile_defs or \
state.last_target != state.target:
wrd.lnx_recompile = True
state.last_target = state.target
# Trait sources modified
state.mod_scripts = []
script_path = lnx.utils.get_fp() + '/Sources/' + lnx.utils.safestr(wrd.lnx_project_package)
if os.path.isdir(script_path):
new_mtime = scripts_mtime
for fn in glob.iglob(os.path.join(script_path, '**', '*.hx'), recursive=True):
mtime = os.path.getmtime(fn)
if scripts_mtime < mtime:
lnx.utils.fetch_script_props(fn)
fn = fn.split('Sources/')[1]
fn = fn[:-3] #.hx
fn = fn.replace('/', '.')
state.mod_scripts.append(fn)
wrd.lnx_recompile = True
if new_mtime < mtime:
new_mtime = mtime
scripts_mtime = new_mtime
if len(state.mod_scripts) > 0:
lnx.utils.fetch_trait_props()
log.clear(clear_warnings=True, clear_errors=True)
sdk_path = lnx.utils.get_sdk_path()
fp = lnx.utils.get_fp()
os.chdir(fp)
sources_path = 'Sources/' + lnx.utils.safestr(wrd.lnx_project_package)
if not os.path.exists(sources_path):
os.makedirs(sources_path)
log.info('Exporting scene data...')
export_data(fp, sdk_path)
log.info('Starting Krom compilation for viewport...')
compile_viewport(assets_only=(not wrd.lnx_recompile))
def compile_viewport(assets_only=False):
"""Compile for viewport mode using separate process tracking."""
global _viewport_proc_build
@ -886,8 +806,8 @@ def viewport_build_done():
def play_viewport(viewport_id, width=1920, height=1080):
"""Launch Krom in a viewport"""
global _viewport_build_in_progress, _viewport_pending_launches, _viewport_proc_build, scripts_mtime
global _viewport_build_in_progress, _viewport_pending_launches, _viewport_proc_build
if not viewport_id:
log.error('No viewport_id: play_viewport requires an id')
return
@ -895,7 +815,7 @@ def play_viewport(viewport_id, width=1920, height=1080):
if 'Lnx' not in bpy.data.worlds:
log.error('No Lnx world found - cannot start viewport server')
return
wrd = bpy.data.worlds['Lnx']
krom_js_path = lnx.utils.get_fp_build() + '/debug/krom/krom.js'
@ -912,52 +832,11 @@ def play_viewport(viewport_id, width=1920, height=1080):
log.info(f'Build in progress, viewport {viewport_id} will launch when ready')
return
else:
_viewport_build_in_progress = False # Reset stale state
_viewport_build_in_progress = False
_viewport_build_in_progress = True
sdk_path = lnx.utils.get_sdk_path()
fp = lnx.utils.get_fp()
os.chdir(fp)
sources_path = 'Sources/' + lnx.utils.safestr(wrd.lnx_project_package)
if not os.path.exists(sources_path):
os.makedirs(sources_path)
# export data same as play() but without setting state.is_play
state.is_viewport = True
state.target = 'krom'
state.is_publish = False
state.is_export = False
if not wrd.lnx_cache_build or \
not os.path.isfile(krom_js_path) or \
assets.khafile_defs_last != assets.khafile_defs or \
state.last_target != state.target:
wrd.lnx_recompile = True
state.last_target = state.target
state.mod_scripts = []
script_path = lnx.utils.get_fp() + '/Sources/' + lnx.utils.safestr(wrd.lnx_project_package)
if os.path.isdir(script_path):
new_mtime = scripts_mtime
for fn in glob.iglob(os.path.join(script_path, '**', '*.hx'), recursive=True):
mtime = os.path.getmtime(fn)
if scripts_mtime < mtime:
lnx.utils.fetch_script_props(fn)
fn = fn.split('Sources/')[1]
fn = fn[:-3] #.hx
fn = fn.replace('/', '.')
state.mod_scripts.append(fn)
wrd.lnx_recompile = True
if new_mtime < mtime:
new_mtime = mtime
scripts_mtime = new_mtime
if len(state.mod_scripts) > 0:
lnx.utils.fetch_trait_props()
export_data(fp, sdk_path)
build(target='krom', is_viewport=True, viewport_width=width, viewport_height=height)
compile_viewport(assets_only=(not wrd.lnx_recompile))