Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion 3rdparty/libossia
Submodule libossia updated 1 files
+1 −1 3rdparty/libremidi
53 changes: 53 additions & 0 deletions cmake/ScoreConfiguration.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -304,3 +304,56 @@ install(
DESTINATION include/score
COMPONENT Devel
OPTIONAL)

# Win32 codepage stuff
if(WIN32)
file(CONFIGURE
OUTPUT
"${PROJECT_BINARY_DIR}/score.exe.manifest"
CONTENT
[=[<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings> <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/PM</dpiAware> </windowsSettings>
<windowsSettings> <dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2,PerMonitor</dpiAwareness> </windowsSettings>
<windowsSettings> <longPathAware xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">true</longPathAware> </windowsSettings>
<windowsSettings> <activeCodePage xmlns="http://schemas.microsoft.com/SMI/2019/WindowsSettings">UTF-8</activeCodePage> </windowsSettings>
</application>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
</requestedPrivileges>
</security>
</trustInfo>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" />
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" />
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />
</application>
</compatibility>
</assembly>
]=]
)

if(MINGW)
enable_language(RC)
# 1 = CREATEPROCESS_MANIFEST_RESOURCE_ID, 24 = RT_MANIFEST (no includes needed)
file(WRITE "${PROJECT_BINARY_DIR}/score.exe.rc"
"1 24 \"${PROJECT_BINARY_DIR}/score.exe.manifest\"\n")
endif()
endif()

function(target_enable_utf8 tgt)
if(NOT SCORE_MSSTORE_DEPLOYMENT) # c.f. ScoreDeploymentWindowsStore
if(MSVC)
target_link_options(${tgt} PRIVATE
/MANIFEST:EMBED
"/MANIFESTINPUT:${CMAKE_BINARY_DIR}/score.exe.manifest")
elseif(MINGW)
target_sources(${tgt} PRIVATE "${CMAKE_BINARY_DIR}/score.exe.rc")
endif()
endif()
endfunction()
30 changes: 0 additions & 30 deletions cmake/ScoreDeploymentWindowsStore.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -2,36 +2,6 @@ if(NOT SCORE_MSSTORE_DEPLOYMENT)
return()
endif()

file(CONFIGURE
OUTPUT
"${PROJECT_BINARY_DIR}/score.exe.manifest"
CONTENT
[=[<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings> <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/PM</dpiAware> </windowsSettings>
<windowsSettings> <dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2,PerMonitor</dpiAwareness> </windowsSettings>
<windowsSettings> <longPathAware xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">true</longPathAware> </windowsSettings>
</application>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
</requestedPrivileges>
</security>
</trustInfo>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" />
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" />
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />
</application>
</compatibility>
</assembly>
]=]
)

install(
FILES
"${PROJECT_BINARY_DIR}/score.exe.manifest"
Expand Down
1 change: 1 addition & 0 deletions src/app/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ if(APPLE)
endif()

if(WIN32)
target_enable_utf8(${APPNAME})
target_link_libraries(${APPNAME} PRIVATE ntdll RuntimeObject)
endif()

Expand Down
43 changes: 42 additions & 1 deletion src/lib/score/tools/RecursiveWatch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,11 @@ void for_all_files(std::string_view root, std::function<void(std::string_view)>
{
if(auto res = algorithm::contents(pp.value()))
{
try
{
for(auto& p : res.value())
{
try {
switch(p.second.st_type)
{
#if !defined(_WIN32)
Expand All @@ -87,15 +90,46 @@ void for_all_files(std::string_view root, std::function<void(std::string_view)>
#if !defined(_WIN32)
f(r.native());
#else
f(r.generic_string());
try {
f(r.generic_string());
}
catch(...)
{
// Very inefficient but r.generic_string() sometimes throws
// filesystem error: in __wide_to_char: Illegal byte sequence
// on windows
auto s = QString::fromStdWString(r.native()).toStdString();
std::replace(s.begin(), s.end(), '\\', '/');
f(s);
}
#endif
break;
}
default:
break;
}
}
catch(const std::exception& e)
{
}
catch(...)
{
}
}
}
catch(const std::exception& e)
{
}
catch(...)
{
}
}
else
{
}
}
catch(const std::exception& e)
{
}
catch(...)
{
Expand Down Expand Up @@ -318,4 +352,11 @@ void RecursiveWatch::scanAsync(QObject* context)
send_to_main_thread();
});
}

void RecursiveWatch::reset()
{
m_root.clear();
m_watched.clear();
m_asyncWatched.clear();
}
}
7 changes: 1 addition & 6 deletions src/lib/score/tools/RecursiveWatch.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,7 @@ class SCORE_LIB_BASE_EXPORT RecursiveWatch
/// on the GUI thread via \a context's event loop.
void scanAsync(QObject* context);

void reset()
{
m_root.clear();
m_watched.clear();
m_asyncWatched.clear();
}
void reset();

private:
std::string m_root;
Expand Down
24 changes: 19 additions & 5 deletions src/plugins/score-plugin-ysfx/YSFX/ProcessModel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ void ProcessModel::setInitialScript(const QString& script)
fx.reset(ysfx_new(config.get()), ysfx_u_deleter{});
if(!ysfx_load_file(fx.get(), path_to_jsfx.c_str(), 0))
{
qDebug() << "ysfx: could not load " << script;
qDebug() << "ysfx: setInitialScript: could not load " << script;
return;
}

Expand All @@ -108,7 +108,11 @@ void ProcessModel::setInitialScript(const QString& script)

uint32_t compile_opts = 0;
if(!ysfx_compile(fx.get(), compile_opts))
{
qDebug() << "ysfx: setInitialScript: could not compile " << script;
return;
}


ysfx_init(fx.get());
ysfx_process_double(fx.get(), 0, 0, 0, 0, 0);
Expand All @@ -123,6 +127,7 @@ void ProcessModel::setInitialScript(const QString& script)
}

programChanged();
flagsChanged(); // For UI
}

void ProcessModel::recreatePorts()
Expand Down Expand Up @@ -313,7 +318,7 @@ Process::ScriptChangeResult ProcessModel::reload()
QFile tempFile{tempFilePath};
if(!tempFile.open(QIODevice::WriteOnly | QIODevice::Truncate))
{
qDebug() << "ysfx: could not write temp file" << tempFilePath;
qDebug() << "ysfx: reload: could not write temp file" << tempFilePath;
return res;
}
tempFile.write(m_text.toUtf8());
Expand All @@ -324,22 +329,25 @@ Process::ScriptChangeResult ProcessModel::reload()
ysfx_register_builtin_audio_formats(config.get());

// Set import and data roots from the original file
ysfx_guess_file_roots(config.get(), m_jsfx_path.toStdString().c_str());
const auto& c = config.get();
ysfx_guess_file_roots(c, m_jsfx_path.toStdString().c_str());
if(auto import = ysfx_get_import_root(c); !import || strlen(import) == 0)
ysfx_set_import_root(c, QFileInfo{m_jsfx_path}.dir().canonicalPath().toStdString().c_str());

// Create a new fx instance
auto new_fx = std::shared_ptr<ysfx_t>(ysfx_new(config.get()), ysfx_u_deleter{});

auto tempPath = tempFilePath.toStdString();
if(!ysfx_load_file(new_fx.get(), tempPath.c_str(), 0))
{
qDebug() << "ysfx: could not load temp file" << tempFilePath;
qDebug() << "ysfx: reload: could not load temp file" << tempFilePath;
return res;
}

uint32_t compile_opts = 0;
if(!ysfx_compile(new_fx.get(), compile_opts))
{
qDebug() << "ysfx: compilation failed";
qDebug() << "ysfx: reload: compilation failed";
return res;
}

Expand All @@ -363,7 +371,13 @@ Process::ScriptChangeResult ProcessModel::reload()

recreatePorts();

if(auto bank = ysfx_get_bank_path(this->fx.get()))
{
m_bank = ysfx_load_bank(bank);
}

programChanged();
flagsChanged(); // For UI

return res;
}
Expand Down
3 changes: 3 additions & 0 deletions src/plugins/score-plugin-ysfx/YSFX/ProcessModel.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@ class SCORE_PLUGIN_YSFX_EXPORT ProcessModel final : public Process::ProcessModel
QString m_jsfx_path;
QString m_text;

// If we reload something, to preserve state when the object doesn't create
QByteArray m_saved_state;

std::bitset<ysfx_max_sliders> m_sliderBeingChanged{};
};

Expand Down
18 changes: 13 additions & 5 deletions src/plugins/score-plugin-ysfx/YSFX/ProcessModelSerialization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,11 @@ static void loadYSFXState(ysfx_t& fx, const QByteArray& state)
template <>
void DataStreamReader::read(const YSFX::ProcessModel& proc)
{
m_stream << proc.m_jsfx_path << proc.m_text << readYSFXState(*proc.fx.get());
m_stream << proc.m_jsfx_path << proc.m_text;
if(proc.fx)
m_stream << readYSFXState(*proc.fx.get());
else
m_stream << proc.m_saved_state;

readPorts(*this, proc.m_inlets, proc.m_outlets);

Expand All @@ -94,19 +98,21 @@ void DataStreamWriter::write(YSFX::ProcessModel& proc)
{
proc.m_jsfx_path = script;
proc.m_text = text;
proc.reload();

// If we also have a file path, we may need to reload from it
// But for now, we prefer the stored text (live-coded version)
if(proc.fx)
loadYSFXState(*proc.fx.get(), dat);
}
else
{
proc.setInitialScript(script);
if(proc.fx)
loadYSFXState(*proc.fx.get(), dat);
}

if(proc.fx)
loadYSFXState(*proc.fx.get(), dat);
else
proc.m_saved_state = dat;

writePorts(
*this, components.interfaces<Process::PortFactoryList>(), proc.m_inlets,
proc.m_outlets, &proc);
Expand Down Expand Up @@ -147,6 +153,8 @@ void JSONWriter::write(YSFX::ProcessModel& proc)
auto dat = QByteArray::fromBase64(obj["Chunk"].toByteArray());
if(proc.fx)
loadYSFXState(*proc.fx.get(), dat);
else
proc.m_saved_state = dat;

writePorts(
*this, components.interfaces<Process::PortFactoryList>(), proc.m_inlets,
Expand Down
Loading