Compare commits

..

No commits in common. "3df4361779397814e0fe731d537c004ab302adff" and "ec7a8de0cfd0c5575a40e11f35516e0839f20b6b" have entirely different histories.

18 changed files with 19 additions and 305 deletions

View File

@ -11,8 +11,7 @@
"dependencies/include/SDL2", "dependencies/include/SDL2",
"dependencies/imgui", "dependencies/imgui",
"${default}" "${default}"
], ]
"cppStandard": "c++20"
} }
], ],
"version": 4 "version": 4

0
dependencies/compile_resources.sh vendored Executable file → Normal file
View File

0
dependencies/imgui.config vendored Executable file → Normal file
View File

0
dependencies/imgui.project.config vendored Executable file → Normal file
View File

0
dependencies/precompiled.config vendored Executable file → Normal file
View File

0
dependencies/resources.config vendored Executable file → Normal file
View File

View File

@ -1,9 +0,0 @@
#!/usr/bin/env bash
DEP_WORKING_DIR='src-csharp'
if [[ "$TASK" = *_dbg ]]; then
DEP_BUILD_COMMAND='dotnet build src-csharp.sln -o bin -c Debug'
else
DEP_BUILD_COMMAND='dotnet build src-csharp.sln -o bin -c Release'
fi
DEP_CLEAN_COMMAND='rm -rf bin obj'
DEP_OTHER_OUT_FILES='bin/Ougge.dll'

4
project.config Executable file → Normal file
View File

@ -6,7 +6,7 @@ PROJECT="ougge"
CMP_C="gcc" CMP_C="gcc"
CMP_CPP="g++" CMP_CPP="g++"
STD_C="c11" STD_C="c11"
STD_CPP="c++20" STD_CPP="c++17"
WARN_C="-Wall -Wno-discarded-qualifiers -Wextra -Wno-unused-parameter" WARN_C="-Wall -Wno-discarded-qualifiers -Wextra -Wno-unused-parameter"
WARN_CPP="-Wall -Wextra -Wno-unused-parameter" WARN_CPP="-Wall -Wextra -Wno-unused-parameter"
SRC_C="$(find src -name '*.c')" SRC_C="$(find src -name '*.c')"
@ -16,7 +16,7 @@ SRC_CPP="$(find src -name '*.cpp')"
# See cbuild/example_dependency_configs # See cbuild/example_dependency_configs
DEPENDENCY_CONFIGS_DIR='dependencies' DEPENDENCY_CONFIGS_DIR='dependencies'
# List of dependency config files in DEPENDENCY_CONFIGS_DIR separated by space. # List of dependency config files in DEPENDENCY_CONFIGS_DIR separated by space.
ENABLED_DEPENDENCIES='precompiled resources imgui src-csharp' ENABLED_DEPENDENCIES='precompiled resources imgui'
# OBJDIR structure: # OBJDIR structure:
# ├── objects/ - Compiled object files. Cleans on each call of build task # ├── objects/ - Compiled object files. Cleans on each call of build task

View File

@ -1,24 +0,0 @@
using System.Management.Instrumentation;
using System.Numerics;
using System.Runtime.InteropServices;
namespace Ougge;
[StructLayout(LayoutKind.Sequential)]
public struct Transform
{
Vector2 scale;
Vector2 position;
float rotation;
}
public class Component
{
GameObject owner;
}
public class GameObject
{
Transform transform { get; }
GameObject? parent;
}

View File

@ -1,4 +1,5 @@
using System; using System;
using System.Data;
namespace Ougge; namespace Ougge;

View File

@ -1,29 +0,0 @@
#include "GameObject.hpp"
std::ostream& operator<<(std::ostream& s, Transform& t){
s<<"{ position: {x: "<<t.position.x<<", y: "<<t.position.y;
s<<"}, rotation: "<<t.rotation;
s<<", scale {x: "<<t.scale.x<<", y: "<<t.scale.y<<"} }";
return s;
}
GameObject::GameObject(Mono::Object managed_obj, GameObject *parent)
: object_handle(managed_obj), parent(parent)
{}
GameObject &GameObject::operator=(GameObject &&o){
transform = o.transform;
components = std::move(o.components);
object_handle = std::move(o.object_handle);
return *this;
}
bool GameObject::tryGetComponent(const std::u16string &name, Component **out_component)
{
return false;
}
bool GameObject::tryAddComponent(const std::u16string &name, Component &&component)
{
return false;
}

View File

@ -1,41 +1,15 @@
#pragma once #pragma once
#include <map>
#include <iostream>
#include "../math.hpp" #include "../math.hpp"
#include "../UsefulException.hpp" #include <set>
#include "../Mono/Mono.hpp"
class GameObject;
class Component {
Mono::ObjectHandle object_handle;
GameObject* owner;
public:
inline Component(Mono::Object managed_obj, GameObject* owner)
: object_handle(managed_obj), owner(owner) {}
};
struct Transform {
Vec2 scale = { 1, 1 };
Vec2 position = { 0, 0 };
angle_t rotation = 0;
};
std::ostream& operator<<(std::ostream& s, Transform& t);
class GameObject { class GameObject {
Transform transform;
std::map<std::u16string, Component> components;
Mono::ObjectHandle object_handle;
GameObject* parent;
public: public:
GameObject(Mono::Object managed_obj, GameObject* parent); Vec2 scale = { 1, 1 };
Vec2 position;
GameObject& operator=(GameObject&& o); angle_t rotation;
inline Transform& getTransform(){ return transform; } private:
bool tryGetComponent(const std::u16string& name, Component** out_component); // std::set<Component> components;
bool tryAddComponent(const std::u16string& name, Component&& component);
}; };

View File

@ -1,127 +0,0 @@
#include "GameObjectPool.hpp"
#include <bit>
#include <cstring>
GameObjectPool::GameObjectPool(u32 size)
{
useful_assert(size % 64 == 0, "size of GameObjectPool must be a multiple of 64");
this->size = size;
first_unused_index = 0;
buffer = new char[size*sizeof(GameObject)];
used_indices = new u64[size/64];
std::memset(buffer, 0, size*sizeof(GameObject));
std::memset(used_indices, 0, size/8);
}
GameObjectPool::~GameObjectPool()
{
// int i = 0;
for(auto&& p : *this){
// std::cout<<"~GameObjectPool i="<<i++<<std::endl;
p.second.~GameObject();
}
delete (char*)buffer;
delete used_indices;
}
bool GameObjectPool::isIndexUsed(u32 index)
{
return ( used_indices[index/64] & (1<<(index%64)) ) != 0;
}
u32 GameObjectPool::getNearestUnusedIndex(u32 startIndex)
{
if(startIndex >= size)
return -1;
if(!isIndexUsed(startIndex))
return startIndex;
u32 i = startIndex/64;
// mark previous bits as used
u64 u = used_indices[i] | ( (1<<startIndex%64) -1 );
while(u == u64(-1)){
i++;
if(i == size/64)
return -1;
u = used_indices[i];
}
u32 bitpos = std::countr_one(u);
if(bitpos == 64)
return -1;
u32 index = i*64 + bitpos;
return index;
}
u32 GameObjectPool::getNearestUsedIndex(u32 startIndex)
{
if(startIndex >= size)
return -1;
if(isIndexUsed(startIndex))
return startIndex;
u32 i = startIndex/64;
// mark previous bits as unused
u64 u = used_indices[i] & !( (1<<startIndex%64) -1 );
while(u == 0){
i++;
if(i == size/64)
return -1;
u = used_indices[i];
}
u32 bitpos = std::countr_zero(u);
if(bitpos == 64)
return -1;
u32 index = i*64 + bitpos;
return index;
}
GameObject& GameObjectPool::get(u32 index)
{
if(index >= size)
throw UsefulException(format("index %i is out of size %i", index, size));
if(!isIndexUsed(index))
throw UsefulException(format("there is no object at index %i", index));
return ((GameObject*)buffer)[index];
}
std::pair<u32, GameObject&> GameObjectPool::put_new(GameObject&& new_obj)
{
u32 i = first_unused_index;
if(i == (u32)-1)
throw UsefulException("can't put new GameObject to GameObjectPool because it's full");
GameObject& r = ( ((GameObject*)buffer)[i] = std::move(new_obj) );
used_indices[i] |= 1<<(i%64); // mark index bit as used
first_unused_index = getNearestUnusedIndex(i+1);
return std::pair<u32, GameObject&>(i, r);
}
void GameObjectPool::remove(u32 index)
{
if(index >= size)
throw UsefulException(format("index %i is out of size %i", index, size));
if(!isIndexUsed(index))
throw UsefulException(format("there is no object at index %i", index));
((GameObject*)buffer)[index].~GameObject();
used_indices[index/64] ^= ~(1<<(index%64)); // mark index bit as unused
if(index < first_unused_index)
first_unused_index = index;
}
GameObjectPool::iterator::iterator(GameObjectPool* p, u32 index)
: p(p), index(index)
{
}
std::pair<u32, GameObject&> GameObjectPool::iterator::operator*()
{
if(index >= p->size)
throw UsefulException("can't get value of end() iterator");
GameObject& r = ((GameObject*)p->buffer)[index];
return std::pair<u32, GameObject&>(index, r);
}
GameObjectPool::iterator& GameObjectPool::iterator::operator++()
{
index = p->getNearestUsedIndex(index+1);
return *this;
}

View File

@ -1,37 +0,0 @@
#include "GameObject.hpp"
class GameObjectPool {
void* buffer;
u64* used_indices;
u32 size;
u32 first_unused_index;
bool isIndexUsed(u32 index);
u32 getNearestUnusedIndex(u32 startIndex);
u32 getNearestUsedIndex(u32 startIndex);
friend class iterator;
public:
///@param size must be a multiple of 64
GameObjectPool(u32 size);
~GameObjectPool();
GameObject& get(u32 index);
std::pair<u32, GameObject&> put_new(GameObject&& new_obj);
void remove(u32 index);
class iterator {
GameObjectPool* p;
u32 index = 0;
public:
iterator(GameObjectPool* p, u32 index);
std::pair<u32, GameObject&> operator*();
iterator& operator++();
inline bool operator!=(const iterator& o) const { return index != o.index; };
inline bool operator==(const iterator& o) const { return index == o.index; };
};
inline iterator begin() { return iterator(this, 0); }
inline iterator end() { return iterator(this, -1); }
};

View File

@ -124,25 +124,4 @@ public:
std::shared_ptr<Assembly> loadAssembly(const std::string& name); std::shared_ptr<Assembly> loadAssembly(const std::string& name);
}; };
class ObjectHandle {
Object object;
u32 gc_handle;
public:
inline ObjectHandle(Object obj) : object(obj) { gc_handle = mono_gchandle_new(obj, false); }
inline ObjectHandle(const ObjectHandle& o) = delete;
inline ObjectHandle(ObjectHandle&& o) {
object = o.object;
gc_handle = o.gc_handle;
o.gc_handle = 0;
};
inline ObjectHandle& operator=(ObjectHandle&& o) {
object = o.object;
gc_handle = o.gc_handle;
o.gc_handle = 0;
return *this;
};
inline ~ObjectHandle() { if(gc_handle) mono_gchandle_free(gc_handle); }
inline Object getObject() { return object; }
};
} }

View File

@ -18,4 +18,4 @@ public:
virtual char const* what() const noexcept; virtual char const* what() const noexcept;
}; };
#define useful_assert(EXPR, ERRMSG) if(!(EXPR)) throw UsefulException(ERRMSG); #define useful_assert(EXPR, ERRMSG) if(!EXPR) throw UsefulException(ERRMSG);

View File

@ -1,15 +1,11 @@
#define SDL_MAIN_HANDLED #define SDL_MAIN_HANDLED
#include <iostream> #include <iostream>
#include <iomanip>
#include "GUI/MainWindow.hpp" #include "GUI/MainWindow.hpp"
#include "Resources/Resources.hpp" #include "Resources/Resources.hpp"
#include "Game/Scene.hpp" #include "Game/Scene.hpp"
#include "format.hpp" #include "format.hpp"
#include "UsefulException.hpp" #include "UsefulException.hpp"
#include "Mono/Mono.hpp" #include "Mono/Mono.hpp"
#include "Game/GameObjectPool.hpp"
#include <bitset>
#include <bit>
using namespace ougge; using namespace ougge;
@ -28,24 +24,15 @@ int main(int argc, const char** argv){
Mono::RuntimeJIT mono; Mono::RuntimeJIT mono;
std::cout<<"initialized mono jit runtime"<<std::endl; std::cout<<"initialized mono jit runtime"<<std::endl;
GameObjectPool p(64*512);
auto a = mono.loadAssembly("Ougge.dll"); auto a = mono.loadAssembly("Ougge.dll");
auto gameObjectClass = a->getClass("Ougge", "GameObject"); auto c = a->getClass("Ougge", "ExampleScript");
for(int i = 0; i < 32*1024; i++){ auto scriptInstance = mono_object_new(mono.getDomain(), c);
Mono::Object gameObjectManaged = mono_object_new(mono.getDomain(), gameObjectClass); mono_runtime_object_init(scriptInstance);
p.put_new(GameObject(gameObjectManaged, nullptr)); auto scriptUpdate = Mono::Method<void(f64)>(c, "Update");
GameObject& o = p.get(0); updateCallbacks.push_back([scriptInstance, scriptUpdate](f64 deltaTime) -> void {
std::cout<<'['<<i<<"] "<<o.getTransform()<<std::endl; scriptUpdate(scriptInstance, deltaTime);
} });
return 0;
// mono_runtime_object_init(scriptInstance);
// auto scriptUpdate = Mono::Method<void(f64)>(c, "Update");
// updateCallbacks.push_back([scriptInstance, scriptUpdate](f64 deltaTime) -> void {
// scriptUpdate(scriptInstance, deltaTime);
// });
GUI::MainWindow w; GUI::MainWindow w;
w.open("ougge", update); w.open("ougge", update);

0
tasks/get_mono_files_from.sh Executable file → Normal file
View File