Skip to content
Merged
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
4 changes: 2 additions & 2 deletions include/scratchcpp/dev/executablecode.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace libscratchcpp
{

class ExecutionContext;
class Target;
class Thread;

/*! \brief The ExecutableCode class represents the code of a compiled Scratch script. */
class LIBSCRATCHCPP_EXPORT ExecutableCode
Expand All @@ -31,7 +31,7 @@ class LIBSCRATCHCPP_EXPORT ExecutableCode
virtual bool isFinished(ExecutionContext *context) const = 0;

/*! Creates an execution context for the given Target. */
virtual std::shared_ptr<ExecutionContext> createExecutionContext(Target *target) const = 0;
virtual std::shared_ptr<ExecutionContext> createExecutionContext(Thread *thread) const = 0;
};

} // namespace libscratchcpp
8 changes: 5 additions & 3 deletions include/scratchcpp/dev/executioncontext.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,21 @@
namespace libscratchcpp
{

class Target;
class Thread;
class IEngine;
class Promise;
class ExecutionContextPrivate;

/*! \brief The ExecutionContext represents the execution context of a target (can be a clone) with variables, lists, etc. */
class LIBSCRATCHCPP_EXPORT ExecutionContext
{
public:
ExecutionContext(Target *target);
ExecutionContext(Thread *thread);
ExecutionContext(const ExecutionContext &) = delete;
virtual ~ExecutionContext() { }

Target *target() const;
Thread *thread() const;
IEngine *engine() const;

std::shared_ptr<Promise> promise() const;
void setPromise(std::shared_ptr<Promise> promise);
Expand Down
9 changes: 7 additions & 2 deletions include/scratchcpp/dev/test/scriptbuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@

#include <vector>

#include "../../global.h"
#include "../../spimpl.h"
#include "../../inputvalue.h"

namespace libscratchcpp
{
Expand Down Expand Up @@ -44,13 +43,19 @@ class LIBSCRATCHCPP_EXPORT ScriptBuilder
void addDropdownInput(const std::string &name, const std::string &selectedValue);
void addDropdownField(const std::string &name, const std::string &selectedValue);

void addEntityInput(const std::string &name, const std::string &entityName, InputValue::Type entityType, std::shared_ptr<Entity> entity);
void addEntityField(const std::string &name, std::shared_ptr<Entity> entity);

std::shared_ptr<Block> currentBlock();

void build();
void run();

List *capturedValues() const;

private:
void addBlock(std::shared_ptr<Block> block);
void build(std::shared_ptr<Target> target);

spimpl::unique_impl_ptr<ScriptBuilderPrivate> impl;
};
Expand Down
110 changes: 110 additions & 0 deletions src/dev/blocks/eventblocks.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
// SPDX-License-Identifier: Apache-2.0

#include <scratchcpp/iengine.h>
#include <scratchcpp/dev/compiler.h>
#include <scratchcpp/block.h>
#include <scratchcpp/field.h>
#include <scratchcpp/broadcast.h>
#include <scratchcpp/dev/executioncontext.h>
#include <scratchcpp/thread.h>
#include <scratchcpp/dev/compilerconstant.h>

#include "eventblocks.h"

using namespace libscratchcpp;
Expand All @@ -16,4 +25,105 @@ std::string libscratchcpp::EventBlocks::description() const

void EventBlocks::registerBlocks(IEngine *engine)
{
engine->addCompileFunction(this, "event_whentouchingobject", &compileWhenTouchingObject);
engine->addCompileFunction(this, "event_whenflagclicked", &compileWhenFlagClicked);
engine->addCompileFunction(this, "event_whenthisspriteclicked", &compileWhenThisSpriteClicked);
engine->addCompileFunction(this, "event_whenstageclicked", &compileWhenStageClicked);
engine->addCompileFunction(this, "event_whenbroadcastreceived", &compileWhenBroadcastReceived);
engine->addCompileFunction(this, "event_whenbackdropswitchesto", &compileWhenBackdropSwitchesTo);
engine->addCompileFunction(this, "event_whengreaterthan", &compileWhenGreaterThan);
engine->addCompileFunction(this, "event_broadcast", &compileBroadcast);
engine->addCompileFunction(this, "event_broadcastandwait", &compileBroadcastAndWait);
engine->addCompileFunction(this, "event_whenkeypressed", &compileWhenKeyPressed);
}

CompilerValue *EventBlocks::compileWhenTouchingObject(Compiler *compiler)
{
compiler->engine()->addWhenTouchingObjectScript(compiler->block());
return nullptr;
}

CompilerValue *EventBlocks::compileWhenFlagClicked(Compiler *compiler)
{
compiler->engine()->addGreenFlagScript(compiler->block());
return nullptr;
}

CompilerValue *EventBlocks::compileWhenThisSpriteClicked(Compiler *compiler)
{
compiler->engine()->addTargetClickScript(compiler->block());
return nullptr;
}

CompilerValue *EventBlocks::compileWhenStageClicked(Compiler *compiler)
{
compiler->engine()->addTargetClickScript(compiler->block());
return nullptr;
}

CompilerValue *EventBlocks::compileWhenBroadcastReceived(Compiler *compiler)
{
auto block = compiler->block();
Field *field = compiler->field("BROADCAST_OPTION");

if (field) {
auto broadcast = std::static_pointer_cast<Broadcast>(field->valuePtr());
compiler->engine()->addBroadcastScript(block, field, broadcast.get());
}

return nullptr;
}

CompilerValue *EventBlocks::compileWhenBackdropSwitchesTo(Compiler *compiler)
{
auto block = compiler->block();
Field *field = compiler->field("BACKDROP");

if (field)
compiler->engine()->addBackdropChangeScript(block, field);

return nullptr;
}

CompilerValue *EventBlocks::compileWhenGreaterThan(Compiler *compiler)
{
compiler->engine()->addWhenGreaterThanScript(compiler->block());
return nullptr;
}

CompilerValue *EventBlocks::compileBroadcast(Compiler *compiler)
{
auto input = compiler->addInput("BROADCAST_INPUT");
auto wait = compiler->addConstValue(false);
compiler->addFunctionCallWithCtx("event_broadcast", Compiler::StaticType::Void, { Compiler::StaticType::String, Compiler::StaticType::Bool }, { input, wait });
return nullptr;
}

CompilerValue *EventBlocks::compileBroadcastAndWait(Compiler *compiler)
{
auto input = compiler->addInput("BROADCAST_INPUT");
auto wait = compiler->addConstValue(true);
compiler->addFunctionCallWithCtx("event_broadcast", Compiler::StaticType::Void, { Compiler::StaticType::String, Compiler::StaticType::Bool }, { input, wait });
return nullptr;
}

CompilerValue *EventBlocks::compileWhenKeyPressed(Compiler *compiler)
{
auto block = compiler->block();
Field *field = compiler->field("KEY_OPTION");

if (field)
compiler->engine()->addKeyPressScript(block, field);

return nullptr;
}

extern "C" void event_broadcast(ExecutionContext *ctx, const char *name, bool wait)
{
Thread *thread = ctx->thread();
IEngine *engine = thread->engine();
std::vector<int> broadcasts = engine->findBroadcasts(name);

for (int index : broadcasts)
engine->broadcast(index, thread, wait);
}
12 changes: 12 additions & 0 deletions src/dev/blocks/eventblocks.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,18 @@ class EventBlocks : public IExtension
std::string description() const override;

void registerBlocks(IEngine *engine) override;

private:
static CompilerValue *compileWhenTouchingObject(Compiler *compiler);
static CompilerValue *compileWhenFlagClicked(Compiler *compiler);
static CompilerValue *compileWhenThisSpriteClicked(Compiler *compiler);
static CompilerValue *compileWhenStageClicked(Compiler *compiler);
static CompilerValue *compileWhenBroadcastReceived(Compiler *compiler);
static CompilerValue *compileWhenBackdropSwitchesTo(Compiler *compiler);
static CompilerValue *compileWhenGreaterThan(Compiler *compiler);
static CompilerValue *compileBroadcast(Compiler *compiler);
static CompilerValue *compileBroadcastAndWait(Compiler *compiler);
static CompilerValue *compileWhenKeyPressed(Compiler *compiler);
};

} // namespace libscratchcpp
17 changes: 12 additions & 5 deletions src/dev/engine/executioncontext.cpp
Original file line number Diff line number Diff line change
@@ -1,21 +1,28 @@
// SPDX-License-Identifier: Apache-2.0

#include <scratchcpp/dev/executioncontext.h>
#include <scratchcpp/thread.h>

#include "executioncontext_p.h"

using namespace libscratchcpp;

/*! Constructs ExecutionContext. */
ExecutionContext::ExecutionContext(Target *target) :
impl(spimpl::make_unique_impl<ExecutionContextPrivate>(target))
ExecutionContext::ExecutionContext(Thread *thread) :
impl(spimpl::make_unique_impl<ExecutionContextPrivate>(thread))
{
}

/*! Returns the Target of this context. */
Target *ExecutionContext::target() const
/*! Returns the thread of this context. */
Thread *ExecutionContext::thread() const
{
return impl->target;
return impl->thread;
}

/*! Returns the engine of the project. */
IEngine *ExecutionContext::engine() const
{
return impl->thread->engine();
}

/*! Returns the script promise. */
Expand Down
4 changes: 2 additions & 2 deletions src/dev/engine/executioncontext_p.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

using namespace libscratchcpp;

ExecutionContextPrivate::ExecutionContextPrivate(Target *target) :
target(target)
ExecutionContextPrivate::ExecutionContextPrivate(Thread *thread) :
thread(thread)
{
}
5 changes: 3 additions & 2 deletions src/dev/engine/executioncontext_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,15 @@
namespace libscratchcpp
{

class Thread;
class Target;
class Promise;

struct ExecutionContextPrivate
{
ExecutionContextPrivate(Target *target);
ExecutionContextPrivate(Thread *thread);

Target *target = nullptr;
Thread *thread = nullptr;
std::shared_ptr<Promise> promise;
};

Expand Down
7 changes: 4 additions & 3 deletions src/dev/engine/internal/llvm/llvmexecutablecode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <scratchcpp/stage.h>
#include <scratchcpp/iengine.h>
#include <scratchcpp/dev/promise.h>
#include <scratchcpp/thread.h>
#include <llvm/Support/Error.h>
#include <iostream>

Expand Down Expand Up @@ -64,7 +65,7 @@ void LLVMExecutableCode::run(ExecutionContext *context)

ctx->setFinished(done);
} else {
Target *target = ctx->target();
Target *target = ctx->thread()->target();
void *handle = m_mainFunction(context, target, target->variableData(), target->listData());

if (!handle)
Expand Down Expand Up @@ -95,9 +96,9 @@ bool LLVMExecutableCode::isFinished(ExecutionContext *context) const
return getContext(context)->finished();
}

std::shared_ptr<ExecutionContext> LLVMExecutableCode::createExecutionContext(Target *target) const
std::shared_ptr<ExecutionContext> LLVMExecutableCode::createExecutionContext(Thread *thread) const
{
return std::make_shared<LLVMExecutionContext>(target);
return std::make_shared<LLVMExecutionContext>(thread);
}

uint64_t LLVMExecutableCode::lookupFunction(const std::string &name)
Expand Down
2 changes: 1 addition & 1 deletion src/dev/engine/internal/llvm/llvmexecutablecode.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class LLVMExecutableCode : public ExecutableCode

bool isFinished(ExecutionContext *context) const override;

std::shared_ptr<ExecutionContext> createExecutionContext(Target *target) const override;
std::shared_ptr<ExecutionContext> createExecutionContext(Thread *thread) const override;

private:
uint64_t lookupFunction(const std::string &name);
Expand Down
4 changes: 2 additions & 2 deletions src/dev/engine/internal/llvm/llvmexecutioncontext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

using namespace libscratchcpp;

LLVMExecutionContext::LLVMExecutionContext(Target *target) :
ExecutionContext(target)
LLVMExecutionContext::LLVMExecutionContext(Thread *thread) :
ExecutionContext(thread)
{
}

Expand Down
2 changes: 1 addition & 1 deletion src/dev/engine/internal/llvm/llvmexecutioncontext.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace libscratchcpp
class LLVMExecutionContext : public ExecutionContext
{
public:
LLVMExecutionContext(Target *target);
LLVMExecutionContext(Thread *thread);

void *coroutineHandle() const;
void setCoroutineHandle(void *newCoroutineHandle);
Expand Down
Loading
Loading