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
7 changes: 7 additions & 0 deletions include/scratchcpp/iengine.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ class Stage;
class Variable;
class List;
class Script;
class StringPtr;
class Thread;
class ITimer;
class KeyEvent;
Expand Down Expand Up @@ -182,6 +183,12 @@ class LIBSCRATCHCPP_EXPORT IEngine
/*! Call this when a target is clicked. */
virtual void clickTarget(Target *target) = 0;

/*!
* Returns the answer received from the user.
* \see questionAnswered()
*/
virtual const StringPtr *answer() const = 0;

/*! Returns the stage width. */
virtual unsigned int stageWidth() const = 0;

Expand Down
769 changes: 769 additions & 0 deletions src/blocks/sensingblocks.cpp

Large diffs are not rendered by default.

56 changes: 56 additions & 0 deletions src/blocks/sensingblocks.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,17 @@
#pragma once

#include <scratchcpp/iextension.h>
#include <vector>
#include <memory>

namespace libscratchcpp
{

class IAudioInput;
class IClock;
class ExecutionContext;
class Thread;

class SensingBlocks : public IExtension
{
public:
Expand All @@ -15,6 +22,55 @@ class SensingBlocks : public IExtension
Rgb color() const override;

void registerBlocks(IEngine *engine) override;
void onInit(IEngine *engine) override;

static void clearQuestions();
static void askQuestion(ExecutionContext *ctx, const StringPtr *question);

static inline IAudioInput *audioInput = nullptr;
static inline IClock *clock = nullptr;

private:
struct Question
{
Question(const std::string &question, Thread *thread, bool wasVisible, bool wasStage) :
question(question),
thread(thread),
wasVisible(wasVisible),
wasStage(wasStage)
{
}

std::string question;
Thread *thread = nullptr;
bool wasVisible = false;
bool wasStage = false;
};

static CompilerValue *compileTouchingObject(Compiler *compiler);
static CompilerValue *compileTouchingColor(Compiler *compiler);
static CompilerValue *compileColorIsTouchingColor(Compiler *compiler);
static CompilerValue *compileDistanceTo(Compiler *compiler);
static CompilerValue *compileAskAndWait(Compiler *compiler);
static CompilerValue *compileAnswer(Compiler *compiler);
static CompilerValue *compileKeyPressed(Compiler *compiler);
static CompilerValue *compileMouseDown(Compiler *compiler);
static CompilerValue *compileMouseX(Compiler *compiler);
static CompilerValue *compileMouseY(Compiler *compiler);
static CompilerValue *compileSetDragMode(Compiler *compiler);
static CompilerValue *compileLoudness(Compiler *compiler);
static CompilerValue *compileLoud(Compiler *compiler);
static CompilerValue *compileTimer(Compiler *compiler);
static CompilerValue *compileResetTimer(Compiler *compiler);
static CompilerValue *compileOf(Compiler *compiler);
static CompilerValue *compileCurrent(Compiler *compiler);
static CompilerValue *compileDaysSince2000(Compiler *compiler);

static void onAnswer(const std::string &answer);
static void enqueueAsk(const std::string &question, Thread *thread);
static void askNextQuestion();

static inline std::vector<std::unique_ptr<Question>> m_questions;
};

} // namespace libscratchcpp
13 changes: 13 additions & 0 deletions src/engine/internal/engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,20 @@ Engine::Engine() :
m_clock(Clock::instance().get()),
m_audioEngine(IAudioEngine::instance())
{
m_answer = string_pool_new();
string_assign_cstring(m_answer, "");

m_questionAnswered.connect([this](const std::string &answer) {
// Update answer
string_assign_cstring(m_answer, answer.c_str());
});
}

Engine::~Engine()
{
m_clones.clear();
m_sortedDrawables.clear();
string_pool_free(m_answer);
}

void Engine::clear()
Expand Down Expand Up @@ -848,6 +856,11 @@ void Engine::clickTarget(Target *target)
}
}

const StringPtr *Engine::answer() const
{
return m_answer;
}

unsigned int Engine::stageWidth() const
{
return m_stageWidth;
Expand Down
3 changes: 3 additions & 0 deletions src/engine/internal/engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ class Engine : public IEngine

void clickTarget(Target *target) override;

const StringPtr *answer() const override;

unsigned int stageWidth() const override;
void setStageWidth(unsigned int width) override;

Expand Down Expand Up @@ -273,6 +275,7 @@ class Engine : public IEngine
double m_mouseX = 0;
double m_mouseY = 0;
bool m_mousePressed = false;
StringPtr *m_answer = nullptr;
unsigned int m_stageWidth = 480;
unsigned int m_stageHeight = 360;
int m_cloneLimit = 300;
Expand Down
10 changes: 7 additions & 3 deletions src/engine/internal/llvm/instructions/functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,19 @@ LLVMInstruction *Functions::buildFunctionCall(LLVMInstruction *ins)

// Args
for (auto &arg : ins->args) {
types.push_back(m_utils.getType(arg.first));
types.push_back(m_utils.getType(arg.first, false));
args.push_back(m_utils.castValue(arg.second, arg.first));
}

llvm::Type *retType = m_utils.getType(ins->functionReturnReg ? ins->functionReturnReg->type() : Compiler::StaticType::Void);
llvm::Type *retType = m_utils.getType(ins->functionReturnReg ? ins->functionReturnReg->type() : Compiler::StaticType::Void, true);
llvm::Value *ret = m_builder.CreateCall(m_utils.functions().resolveFunction(ins->functionName, llvm::FunctionType::get(retType, types, false)), args);

if (ins->functionReturnReg) {
ins->functionReturnReg->value = ret;
if (ins->functionReturnReg->type() == Compiler::StaticType::Unknown) {
ins->functionReturnReg->value = m_utils.addAlloca(retType);
m_builder.CreateStore(ret, ins->functionReturnReg->value);
} else
ins->functionReturnReg->value = ret;

if (ins->functionReturnReg->type() == Compiler::StaticType::String)
m_utils.freeStringLater(ins->functionReturnReg->value);
Expand Down
7 changes: 5 additions & 2 deletions src/engine/internal/llvm/llvmbuildutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -496,7 +496,7 @@ llvm::Value *LLVMBuildUtils::castValue(LLVMRegister *reg, Compiler::StaticType t
}
}

llvm::Type *LLVMBuildUtils::getType(Compiler::StaticType type)
llvm::Type *LLVMBuildUtils::getType(Compiler::StaticType type, bool isReturnType)
{
switch (type) {
case Compiler::StaticType::Void:
Expand All @@ -515,7 +515,10 @@ llvm::Type *LLVMBuildUtils::getType(Compiler::StaticType type)
return m_builder.getVoidTy()->getPointerTo();

case Compiler::StaticType::Unknown:
return m_valueDataType->getPointerTo();
if (isReturnType)
return m_valueDataType;
else
return m_valueDataType->getPointerTo();

default:
assert(false);
Expand Down
2 changes: 1 addition & 1 deletion src/engine/internal/llvm/llvmbuildutils.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ class LLVMBuildUtils

llvm::Value *addAlloca(llvm::Type *type);
llvm::Value *castValue(LLVMRegister *reg, Compiler::StaticType targetType);
llvm::Type *getType(Compiler::StaticType type);
llvm::Type *getType(Compiler::StaticType type, bool isReturnType);
llvm::Value *isNaN(llvm::Value *num);
llvm::Value *removeNaN(llvm::Value *num);

Expand Down
5 changes: 4 additions & 1 deletion src/engine/internal/llvm/llvmcodebuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,10 @@ CompilerValue *LLVMCodeBuilder::addFunctionCall(const std::string &functionName,

if (returnType != Compiler::StaticType::Void) {
auto reg = std::make_shared<LLVMRegister>(returnType);
reg->isRawValue = true;

if (returnType != Compiler::StaticType::Unknown)
reg->isRawValue = true;

ins->functionReturnReg = reg.get();
return addReg(reg, ins);
}
Expand Down
1 change: 1 addition & 0 deletions test/blocks/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ if (LIBSCRATCHCPP_ENABLE_SENSING_BLOCKS)
GTest::gmock_main
scratchcpp
scratchcpp_mocks
block_test_deps
)

gtest_discover_tests(sensing_blocks_test)
Expand Down
Loading